Authentication fails for md5 connections if ~/.postgresql/postgresql.{crt and key} exist

Started by Jim Jonesabout 3 years ago16 messages
#1Jim Jones
jim.jones@uni-muenster.de
1 attachment(s)

Dear PostgreSQL Hackers,

Some time ago we faced a small issue in libpq regarding connections
configured in the pg_hba.conf as type *hostssl* and using *md5* as
authentication method.

One of our users placed the client certificates in ~/.postgresql/
(*postgresql.crt,**postgresql.key*), so that libpq sends them to the
server without having to manually set *sslcert* and *sslkey* - which is
quite convenient. However, there are other servers where the same user
authenticates with password (md5), but libpq still sends the client
certificates for authentication by default. This causes the
authentication to fail even before the user has the chance to enter his
password, since he has no certificate registered in the server.

To make it clearer:

Although the connection is configured as ...

*host  all  dummyuser 192.168.178.42/32  md5
*

... and the client uses the following connection string ...

*psql "host=myserver dbname=db user=***dummyuser*" *

... the server tries to authenticate the user using the client
certificates in *~/.postgresql/* and, as expected, the authentication fails:

*psql: error: connection to server at "myserver" (xx.xx.xx.xx), port
5432 failed: SSL error: tlsv1 alert unknown ca*

Server log:
**

*2022-12-09 10:50:59.376 UTC [13896] LOG:  could not accept SSL
connection: certificate verify failed
*

Am I missing something?**

Obviously it would suffice to just remove or rename
*~/.postgresql/**postgresql.{crt,key}*, but the user needs them to
authenticate in other servers. So we came up with the workaround to
create a new sslmode (no-clientcert) to make libpq explicitly ignore the
client certificates, so that we can avoid ssl authentication errors.
These small changes can be seen in the patch file attached.

*psql "host=myserver dbname=db user=****dummyuser**
sslrootcert=server.crt sslmode=no-clientcert"*

Any better ideas to make libpq ignore
*~/.postgresql/**postgresql.{crt,key}***? Preferably without having to
change the source code :) Thanks in advance!

Best,

Jim

Attachments:

v1-0001-add-sslmode-no-clientcert.patchtext/x-patch; charset=UTF-8; name=v1-0001-add-sslmode-no-clientcert.patchDownload
From 8013619a1ee2187fce289054a846e17a5414801d Mon Sep 17 00:00:00 2001
From: Jim Jones <jim.jones@uni-muenster.de>
Date: Mon, 21 Nov 2022 15:05:33 +0100
Subject: [PATCH v1] add sslmode no-clientcert

---
 doc/src/sgml/libpq.sgml                  | 11 +++++++++
 src/interfaces/libpq/fe-connect.c        |  1 +
 src/interfaces/libpq/fe-secure-openssl.c | 29 +++++++++++++++++++++++-
 3 files changed, 40 insertions(+), 1 deletion(-)

diff --git a/doc/src/sgml/libpq.sgml b/doc/src/sgml/libpq.sgml
index f9558dec3b..aa14253f7e 100644
--- a/doc/src/sgml/libpq.sgml
+++ b/doc/src/sgml/libpq.sgml
@@ -8638,6 +8638,17 @@ ldap://ldap.acme.com/cn=dbserver,cn=hosts?pgconnectinfo?base?(objectclass=*)
       </entry>
      </row>
 
+     <row>
+      <entry><literal>no-clientcert</literal></entry>
+      <entry>Yes</entry>
+      <entry>Depends on CA policy</entry>
+      <entry>I want my data encrypted, and I accept the overhead. I want to be
+       sure that I connect to a server that I trust, but I do not wish to 
+       authenticate the client using ssl certificates.
+      </entry>
+     </row>
+     
+     
      <row>
       <entry><literal>verify-ca</literal></entry>
       <entry>Yes</entry>
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index f88d672c6c..08c7f21ec1 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -1268,6 +1268,7 @@ connectOptions2(PGconn *conn)
 			&& strcmp(conn->sslmode, "allow") != 0
 			&& strcmp(conn->sslmode, "prefer") != 0
 			&& strcmp(conn->sslmode, "require") != 0
+			&& strcmp(conn->sslmode, "no-clientcert") != 0
 			&& strcmp(conn->sslmode, "verify-ca") != 0
 			&& strcmp(conn->sslmode, "verify-full") != 0)
 		{
diff --git a/src/interfaces/libpq/fe-secure-openssl.c b/src/interfaces/libpq/fe-secure-openssl.c
index bad85359b6..c092020c5e 100644
--- a/src/interfaces/libpq/fe-secure-openssl.c
+++ b/src/interfaces/libpq/fe-secure-openssl.c
@@ -1098,7 +1098,34 @@ initialize_SSL(PGconn *conn)
 	if (conn->sslcert && strlen(conn->sslcert) > 0)
 		strlcpy(fnbuf, conn->sslcert, sizeof(fnbuf));
 	else if (have_homedir)
-		snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, USER_CERT_FILE);
+	{
+
+		/* sslmode no-clientcert */
+		if (conn->sslmode[0] == 'n')
+		{
+
+			/*
+			 * The option "no-clientcert" ignores the client certificate in case they are
+			 * stored in ~/.postgresql/postgresql.crt and ~/.postgresql/postgresql.key,
+			 * and therefore automatically sent to the server. This is useful for
+			 * pg_hba.conf entries of type "hostssl" without "cert" as authentication
+			 * method - e.g. using "md5" or "scram-sha-256" - as they will fail if
+			 * the client certificate is sent to the server in the background and it
+			 * does not exist in the server's 'ssl_ca_file'.
+			 */
+
+			fnbuf[0] = '\0';
+
+		}
+		else
+		{
+
+			snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, USER_CERT_FILE);
+
+		}
+
+
+	}
 	else
 		fnbuf[0] = '\0';
 
-- 
2.25.1

#2Jelte Fennema
postgres@jeltef.nl
In reply to: Jim Jones (#1)
Re: Authentication fails for md5 connections if ~/.postgresql/postgresql.{crt and key} exist

The easiest way to achieve the same (without patching libpq) is by setting
sslcert to something non-existent. While maybe not the most obvious way, I
would consider this the recommended approach.

(sorry for the resend Jim, my original message got blocked to the wider
mailing list)

On Fri, 6 Jan 2023 at 09:15, Jim Jones <jim.jones@uni-muenster.de> wrote:

Show quoted text

Dear PostgreSQL Hackers,

Some time ago we faced a small issue in libpq regarding connections
configured in the pg_hba.conf as type *hostssl* and using *md5* as
authentication method.

One of our users placed the client certificates in ~/.postgresql/ (
*postgresql.crt,**postgresql.key*), so that libpq sends them to the
server without having to manually set *sslcert* and *sslkey* - which is
quite convenient. However, there are other servers where the same user
authenticates with password (md5), but libpq still sends the client
certificates for authentication by default. This causes the authentication
to fail even before the user has the chance to enter his password, since he
has no certificate registered in the server.

To make it clearer:

Although the connection is configured as ...

*host all dummyuser 192.168.178.42/32 <http://192.168.178.42/32&gt; md5 *

... and the client uses the following connection string ...

*psql "host=myserver dbname=db user=**dummyuser" *

... the server tries to authenticate the user using the client
certificates in *~/.postgresql/* and, as expected, the authentication
fails:

*psql: error: connection to server at "myserver" (xx.xx.xx.xx), port 5432
failed: SSL error: tlsv1 alert unknown ca*

Server log:

*2022-12-09 10:50:59.376 UTC [13896] LOG: could not accept SSL
connection: certificate verify failed *

Am I missing something?

Obviously it would suffice to just remove or rename *~/.postgresql/*
*postgresql.{crt,key}*, but the user needs them to authenticate in other
servers. So we came up with the workaround to create a new sslmode
(no-clientcert) to make libpq explicitly ignore the client certificates, so
that we can avoid ssl authentication errors. These small changes can be
seen in the patch file attached.

*psql "host=myserver dbname=db user=**dummyuser sslrootcert=server.crt
sslmode=no-clientcert"*

Any better ideas to make libpq ignore *~/.postgresql/*
*postgresql.{crt,key}*? Preferably without having to change the source
code :) Thanks in advance!

Best,

Jim

#3Jim Jones
jim.jones@uni-muenster.de
In reply to: Jim Jones (#1)
Re: Authentication fails for md5 connections if ~/.postgresql/postgresql.{crt and key} exist

Hi Jelte, thanks for the message. You're right, an invalid cert path
does solve the issue - I even use it for tests. Although it solves the
authentication issue it still looks in my eyes like a non intuitive
workaround/hack. Perhaps a new sslmode isn't the right place for this
"feature"? Thanks again for the suggestion!

Jim

Show quoted text

On 06.01.23 09:32, Jelte Fennema wrote:

The easiest way to achieve the same (without patching libpq) is by
setting sslcert to something non-existent. While maybe not the most
obvious way, I would consider this the recommended approach.

On Fri, 6 Jan 2023 at 09:15, Jim Jones <jim.jones@uni-muenster.de> wrote:

Dear PostgreSQL Hackers,

Some time ago we faced a small issue in libpq regarding
connections configured in the pg_hba.conf as type *hostssl* and
using *md5* as authentication method.

One of our users placed the client certificates in ~/.postgresql/
(*postgresql.crt,**postgresql.key*), so that libpq sends them to
the server without having to manually set *sslcert* and *sslkey* -
which is quite convenient. However, there are other servers where
the same user authenticates with password (md5), but libpq still
sends the client certificates for authentication by default. This
causes the authentication to fail even before the user has the
chance to enter his password, since he has no certificate
registered in the server.

To make it clearer:

Although the connection is configured as ...

*host  all  dummyuser 192.168.178.42/32
<http://192.168.178.42/32&gt;  md5
*

... and the client uses the following connection string ...

*psql "host=myserver dbname=db user=***dummyuser*" *

... the server tries to authenticate the user using the client
certificates in *~/.postgresql/* and, as expected, the
authentication fails:

*psql: error: connection to server at "myserver" (xx.xx.xx.xx),
port 5432 failed: SSL error: tlsv1 alert unknown ca*

Server log:
**

*2022-12-09 10:50:59.376 UTC [13896] LOG:  could not accept SSL
connection: certificate verify failed
*

Am I missing something?**

Obviously it would suffice to just remove or rename
*~/.postgresql/**postgresql.{crt,key}*, but the user needs them to
authenticate in other servers. So we came up with the workaround
to create a new sslmode (no-clientcert) to make libpq explicitly
ignore the client certificates, so that we can avoid ssl
authentication errors. These small changes can be seen in the
patch file attached.

*psql "host=myserver dbname=db user=****dummyuser**
sslrootcert=server.crt sslmode=no-clientcert"*

Any better ideas to make libpq ignore
*~/.postgresql/**postgresql.{crt,key}*? Preferably without having
to change the source code :) Thanks in advance!

Best,

Jim

#4Israel Barth Rubio
barthisrael@gmail.com
In reply to: Jim Jones (#3)
Re: Authentication fails for md5 connections if ~/.postgresql/postgresql.{crt and key} exist

Hello Jim,

Hi Jelte, thanks for the message. You're right, an invalid cert path
does solve the issue - I even use it for tests. Although it solves the
authentication issue it still looks in my eyes like a non intuitive
workaround/hack. Perhaps a new sslmode isn't the right place for this
"feature"? Thanks again for the suggestion!

I do not think it is worth it to change the current behavior of PostgreSQL
in that sense.

PostgreSQL looks for the cert and key under `~/.postgresql` as a facility.
These files do not exist by default, so if PostgreSQL finds something in
there it assumes you want to use it.

I also think it is correct in the sense of choosing the certificate over
a password based authentication when it finds a certificate as the cert
based would provide you with stronger checks.

I believe that using libpq services would be a better approach if you
want to connect to several PostgreSQL clusters from the very same
source machine. That way you would specify whatever is specific to each
target cluster in a centralized configuration file and just reference each
target cluster by its service name in the connection string. It would
require that you move the SSL cert and key from `~/.postgresql` to somewhere
else and specify `sslcert` and `sslkey` in the expected service in the
`~/.pg_service.conf` file.

More info about that can be found at:

https://www.postgresql.org/docs/current/libpq-pgservice.html

Best regards,
Israel.

Show quoted text
#5Jim Jones
jim.jones@uni-muenster.de
In reply to: Israel Barth Rubio (#4)
1 attachment(s)
Re: Authentication fails for md5 connections if ~/.postgresql/postgresql.{crt and key} exist

Hello Israel,

Thanks a lot for the suggestion!

I do not think it is worth it to change the current behavior of

PostgreSQL

in that sense.

Well, I am not suggesting to change the current behavior of PostgreSQL in
that matter. Quite the contrary, I find this feature very convenient,
specially when you need to deal with many different clusters. What I am
proposing is rather the possibility to disable it on demand :) I mean,
in case I do not want libpq to try to authenticate using the certificates
in `~/.postgresql`.

PostgreSQL looks for the cert and key under `~/.postgresql` as a

facility.

These files do not exist by default, so if PostgreSQL finds something in
there it assumes you want to use it.

Yes. I'm just trying to find an elegant way to disable this assumption
on demand.

I also think it is correct in the sense of choosing the certificate over
a password based authentication when it finds a certificate as the cert
based would provide you with stronger checks.

I couldn't agree more.

It would require that you move the SSL cert and key from

`~/.postgresql` to

somewhere else and specify `sslcert` and `sslkey` in the expected

service in the

`~/.pg_service.conf` file.

That's exactly what I am trying to avoid. IOW, I want to avoid having to
move
the cert files to another path and consequently having to configure 30
different entries in the pg_service.conf because of a single server that
does not support ssl authentication.

I do realize that this patch is a big ask, since probably nobody except
me "needs it" :D

Thanks again for the message. Much appreciated!

Best,

Jim

Attachments:

smime.p7sapplication/pkcs7-signature; name=smime.p7sDownload
#6Jacob Champion
jchampion@timescale.com
In reply to: Jim Jones (#5)
Re: Authentication fails for md5 connections if ~/.postgresql/postgresql.{crt and key} exist

On Fri, Jan 20, 2023 at 11:09 AM Jim Jones <jim.jones@uni-muenster.de> wrote:

Well, I am not suggesting to change the current behavior of PostgreSQL in
that matter. Quite the contrary, I find this feature very convenient,
specially when you need to deal with many different clusters. What I am
proposing is rather the possibility to disable it on demand :) I mean,
in case I do not want libpq to try to authenticate using the certificates
in `~/.postgresql`.

I think the sslcertmode=disable option that I introduced in [1]/messages/by-id/CAAWbhmi4V9zEAvfUSCDFx1pOr3ZWrV9fuxkv_2maRqvyc-m9PQ@mail.gmail.com solves
this issue too; would it work for your case? That whole patchset is
meant to tackle the general case of the problem you've described.

(Eventually I'd like to teach the server not to ask for a client
certificate if it's not going to use it.)

I do realize that this patch is a big ask, since probably nobody except
me "needs it" :D

I'd imagine other people have run into it too; it's just a matter of
how palatable the workarounds were to them. :)

--Jacob

[1]: /messages/by-id/CAAWbhmi4V9zEAvfUSCDFx1pOr3ZWrV9fuxkv_2maRqvyc-m9PQ@mail.gmail.com

#7Jim Jones
jim.jones@uni-muenster.de
In reply to: Jacob Champion (#6)
Re: Authentication fails for md5 connections if ~/.postgresql/postgresql.{crt and key} exist

Hi Jacob,

I think the sslcertmode=disable option that I introduced in [1]

solves this issue too;

Well, I see there is indeed a significant overlap between our patches -
but yours has a much more comprehensive approach! If I got it right,
the new slcertmode=disable would indeed cancel the existing certs in
'~/.postgresql/ in case they exist. Right?

+    if (conn->sslcertmode[0] == 'd') /* disable */
+    {
+        /* don't send a client cert even if we have one */
+        have_cert = false;
+    }
+    else if (fnbuf[0] == '\0')

My idea was rather to use the existing sslmode with a new option
"no-clientcert" that does actually the same:

    /* sslmode no-clientcert */
    if (conn->sslmode[0] == 'n')
    {

        fnbuf[0] = '\0';

    }

    ...

    if (fnbuf[0] == '\0')
    {
        /* no home directory, proceed without a client cert */
        have_cert = false;
    }

I wish I had found your patchset some months ago. Now I hate myself
for the duplication of efforts :D

What is the status of your patchset?

Cheers
Jim

#8Jacob Champion
jchampion@timescale.com
In reply to: Jim Jones (#7)
Re: Authentication fails for md5 connections if ~/.postgresql/postgresql.{crt and key} exist

On Sat, Jan 21, 2023 at 4:35 AM Jim Jones <jim.jones@uni-muenster.de> wrote:

Well, I see there is indeed a significant overlap between our patches -
but yours has a much more comprehensive approach! If I got it right,
the new slcertmode=disable would indeed cancel the existing certs in
'~/.postgresql/ in case they exist. Right?

Right!

I wish I had found your patchset some months ago. Now I hate myself
for the duplication of efforts :D

It's a big list... I missed your thread back when you first posted it.

What is the status of your patchset?

Currently waiting for a committer to sign on. But it's now being
discussed in another feature thread [1]/messages/by-id/CA+TgmoZbFiYJWqxakw0fcNrPSPCqc_QnF8iCdXZqyM=d5jA-KA@mail.gmail.com, coincidentally, so I think
the odds are fairly good.

--Jacob

[1]: /messages/by-id/CA+TgmoZbFiYJWqxakw0fcNrPSPCqc_QnF8iCdXZqyM=d5jA-KA@mail.gmail.com

#9Israel Barth Rubio
barthisrael@gmail.com
In reply to: Jacob Champion (#8)
Re: Authentication fails for md5 connections if ~/.postgresql/postgresql.{crt and key} exist

Hello Jim/Jacob,

I do not think it is worth it to change the current behavior of

PostgreSQL

in that sense.

Well, I am not suggesting to change the current behavior of PostgreSQL in
that matter. Quite the contrary, I find this feature very convenient,
specially when you need to deal with many different clusters. What I am
proposing is rather the possibility to disable it on demand :) I mean,
in case I do not want libpq to try to authenticate using the certificates
in `~/.postgresql`.

PostgreSQL looks for the cert and key under `~/.postgresql` as a

facility.

These files do not exist by default, so if PostgreSQL finds something in
there it assumes you want to use it.

Yes. I'm just trying to find an elegant way to disable this assumption
on demand.

Right, I do understand your proposal. I was just thinking out loud and
wondering about the broad audience of such a mode in the sslmode
argument.

Something else that came to my mind is that sslmode itself seems more
like an argument covering the client expectations regarding the connection
to the server, I mean, if it expects channel encryption and/or validation
of the
server identity.

I wonder if we are willing to add some functionality around the expectations
regarding the client certificate, if it wouldn't make more sense to be
controlled
through something like the clientcert option of pg_hba? If so, the downside
of
that is the fact that the client would still send the certificate even if
it would not
be used at all by the server. Again, just thinking out loud about what your
goal
is and possible ways of accomplishing that:)

I do realize that this patch is a big ask, since probably nobody except
me "needs it" :D

I'd imagine other people have run into it too; it's just a matter of
how palatable the workarounds were to them. :)

I imagine more people might have already hit a similar situation too. While
the
workaround can seem a bit weird, in my very humble opinion the user/client
is
somehow still the one to blame in this case as it is providing the "wrong"
file in
a path that is checked by libpq. With that in mind I would be inclined to
say it is
an acceptable workaround.

I think the sslcertmode=disable option that I introduced in [1]

solves this issue too;

Well, I see there is indeed a significant overlap between our patches -
but yours has a much more comprehensive approach! If I got it right,
the new slcertmode=disable would indeed cancel the existing certs in
'~/.postgresql/ in case they exist. Right?

+    if (conn->sslcertmode[0] == 'd') /* disable */
+    {
+        /* don't send a client cert even if we have one */
+        have_cert = false;
+    }
+    else if (fnbuf[0] == '\0')

My idea was rather to use the existing sslmode with a new option
"no-clientcert" that does actually the same:

/* sslmode no-clientcert */
if (conn->sslmode[0] == 'n')
{
fnbuf[0] = '\0';
}

...

if (fnbuf[0] == '\0')
{
/* no home directory, proceed without a client cert */
have_cert = false;
}

I wish I had found your patchset some months ago. Now I hate myself
for the duplication of efforts :D

Although both patches achieve a similar goal regarding not sending the
client certificate there is still a slight but in my opinion important
difference
between them: sslmode=disable will also disable channel encryption. It
may or may not be acceptable depending on how the connection is between
your client and the server.

Kind regards,
Israel.

#10Jacob Champion
jchampion@timescale.com
In reply to: Israel Barth Rubio (#9)
Re: Authentication fails for md5 connections if ~/.postgresql/postgresql.{crt and key} exist

On Wed, Jan 25, 2023 at 7:47 AM Israel Barth Rubio
<barthisrael@gmail.com> wrote:

I imagine more people might have already hit a similar situation too. While the
workaround can seem a bit weird, in my very humble opinion the user/client is
somehow still the one to blame in this case as it is providing the "wrong" file in
a path that is checked by libpq. With that in mind I would be inclined to say it is
an acceptable workaround.

I'm not sure how helpful it is to assign "blame" here. I think the
requested improvement is reasonable -- it should be possible to
override the default for a particular connection, without having to
pick a junk value that you hope doesn't match up with an actual file
on the disk.

Although both patches achieve a similar goal regarding not sending the
client certificate there is still a slight but in my opinion important difference
between them: sslmode=disable will also disable channel encryption. It
may or may not be acceptable depending on how the connection is between
your client and the server.

sslmode=disable isn't used in either of our proposals, though. Unless
I'm missing what you mean?

--Jacob

#11Israel Barth Rubio
barthisrael@gmail.com
In reply to: Jacob Champion (#10)
Re: Authentication fails for md5 connections if ~/.postgresql/postgresql.{crt and key} exist

Hello Jacob,

I'm not sure how helpful it is to assign "blame" here. I think the
requested improvement is reasonable -- it should be possible to
override the default for a particular connection, without having to
pick a junk value that you hope doesn't match up with an actual file
on the disk.

Right, I agree we can look for improvements. "blame" was likely
not the best word to express myself in that message.

sslmode=disable isn't used in either of our proposals, though. Unless
I'm missing what you mean?

Sorry about the noise, I misread the code snippet shared earlier
(sslmode x sslcertmode). I just took a closer read at the previously
mentioned patch about sslcertmode and it seems a bit
more elegant way of achieving something similar to what has
been proposed here.

Best regards,
Israel.

Em qua., 25 de jan. de 2023 às 14:09, Jacob Champion <
jchampion@timescale.com> escreveu:

Show quoted text

On Wed, Jan 25, 2023 at 7:47 AM Israel Barth Rubio
<barthisrael@gmail.com> wrote:

I imagine more people might have already hit a similar situation too.

While the

workaround can seem a bit weird, in my very humble opinion the

user/client is

somehow still the one to blame in this case as it is providing the

"wrong" file in

a path that is checked by libpq. With that in mind I would be inclined

to say it is

an acceptable workaround.

I'm not sure how helpful it is to assign "blame" here. I think the
requested improvement is reasonable -- it should be possible to
override the default for a particular connection, without having to
pick a junk value that you hope doesn't match up with an actual file
on the disk.

Although both patches achieve a similar goal regarding not sending the
client certificate there is still a slight but in my opinion important

difference

between them: sslmode=disable will also disable channel encryption. It
may or may not be acceptable depending on how the connection is between
your client and the server.

sslmode=disable isn't used in either of our proposals, though. Unless
I'm missing what you mean?

--Jacob

#12Cary Huang
cary.huang@highgo.ca
In reply to: Israel Barth Rubio (#11)
Re: Authentication fails for md5 connections if ~/.postgresql/postgresql.{crt and key} exist

I think the sslcertmode=disable option that I introduced in [1] solves
this issue too; would it work for your case? That whole patchset is
meant to tackle the general case of the problem you've described.

(Eventually I'd like to teach the server not to ask for a client
  certificate if it's not going to use it.)

there is an option in pg_hba.conf on the server side called "clientcert"
that can be specified besides the auth method that controls if certain
client connections are required to send client certificate for
additional verification. The value of "clientcert" can be "verify-ca" or
"verify-full". For example:

hostssl    all             all             127.0.0.1/32 md5
clientcert=verify-full

If clientcert is not requested by the server, but yet the client still
sends the certificate, the server will still verify it. This is the case
in this discussion.

I agree that it is a more elegant approach to add "sslcertmode=disable"
on the client side to prevent sending default certificate.

But, if the server does request clientcert but client uses
"sslcertmode=disable" to connect and not give a certificate, it would
also result in authentication failure. In this case, we actually would
want to ignore "sslcertmode=disable" and send default certificates if found.

It would perhaps to better change the parameter to
"defaultclientcert=on-demand" on the client side that will:

1. not send the existing default certificate if server does not request
a certificate
2. send the existing default certificate if server does request a
certificate while the client does not use "sslcert" parameter to specify
another non-default certificate

I put "default" in the parameter name to indicate that it only applies
to default certificate. If user specifies a non-default certificate
using "sslcert" parameter, "defaultclientcert" should not be used and
client should give error if both exists.

Cary Huang
--------------------------------
HighGo Software Canada
www.highgo.ca

#13Jim Jones
jim.jones@uni-muenster.de
In reply to: Cary Huang (#12)
1 attachment(s)
Re: Authentication fails for md5 connections if ~/.postgresql/postgresql.{crt and key} exist

On 27.01.23 21:13, Cary Huang wrote:

I agree that it is a more elegant approach to add
"sslcertmode=disable" on the client side to prevent sending default
certificate.

But, if the server does request clientcert but client uses
"sslcertmode=disable" to connect and not give a certificate, it would
also result in authentication failure. In this case, we actually would
want to ignore "sslcertmode=disable" and send default certificates if
found.

Those are all very good points.

But, if the server does request clientcert but client uses

"sslcertmode=disable" to connect and not give a certificate, it would
also result in authentication failure. In this case, we actually would
want to ignore "sslcertmode=disable" and send default certificates if
found.

I'm just wondering if this is really necessary. If the server asks for a
certificate and the user explicitly says "I don't want to send it",
shouldn't it be ok for the server return an authentication failure? I
mean, wouldn't it defeat the purpose of "sslcertmode=disable"? Although
it might be indeed quite handy I'm not sure how I feel about explicitly
telling the client to not send a certificate and having it being sent
anyway :)

Best, Jim

Attachments:

smime.p7sapplication/pkcs7-signature; name=smime.p7sDownload
#14Jacob Champion
jchampion@timescale.com
In reply to: Cary Huang (#12)
Re: Authentication fails for md5 connections if ~/.postgresql/postgresql.{crt and key} exist

On Fri, Jan 27, 2023 at 12:13 PM Cary Huang <cary.huang@highgo.ca> wrote:

(Eventually I'd like to teach the server not to ask for a client
certificate if it's not going to use it.)

If clientcert is not requested by the server, but yet the client still
sends the certificate, the server will still verify it. This is the case
in this discussion.

I think this is maybe conflating the application-level behavior with
the protocol-level behavior. A client certificate is requested by the
server if ssl_ca_file is set, whether clientcert is set in the HBA or
not. It's this disconnect between the intuitive behavior and the
actual behavior that I'd like to eventually improve.

--Jacob

#15Jacob Champion
jchampion@timescale.com
In reply to: Jim Jones (#13)
Re: Authentication fails for md5 connections if ~/.postgresql/postgresql.{crt and key} exist

On Sun, Jan 29, 2023 at 5:02 AM Jim Jones <jim.jones@uni-muenster.de> wrote:

On 27.01.23 21:13, Cary Huang wrote:

But, if the server does request clientcert but client uses

"sslcertmode=disable" to connect and not give a certificate, it would
also result in authentication failure. In this case, we actually would
want to ignore "sslcertmode=disable" and send default certificates if
found.

I'm just wondering if this is really necessary. If the server asks for a
certificate and the user explicitly says "I don't want to send it",
shouldn't it be ok for the server return an authentication failure? I
mean, wouldn't it defeat the purpose of "sslcertmode=disable"?

+1. In my opinion, if I tell libpq not to share my certificate with
the server, and it then fails to authenticate, that's intended and
useful behavior. (I don't really want libpq to try to find more ways
to authenticate me; that causes other security issues [1, 2].)

--Jacob

[1]: /messages/by-id/0adf992619e7bf138eb4119622d37e3efb6515d5.camel@j-davis.com
[2]: /messages/by-id/46562.1637695110@sss.pgh.pa.us

#16Jim Jones
jim.jones@uni-muenster.de
In reply to: Jacob Champion (#15)
1 attachment(s)
Re: Authentication fails for md5 connections if ~/.postgresql/postgresql.{crt and key} exist

I'm withdrawing this patch, as the same feature was already implemented
in a different patch written by Jacob[1]

Thanks everyone!

Best, Jim

1-
/messages/by-id/CAAWbhmi4V9zEAvfUSCDFx1pOr3ZWrV9fuxkv_2maRqvyc-m9PQ@mail.gmail.com

Attachments:

smime.p7sapplication/pkcs7-signature; name=smime.p7sDownload