"cert" + clientcert=verify-ca in pg_hba.conf? - Mailing list pgsql-hackers

From Kyotaro Horiguchi
Subject "cert" + clientcert=verify-ca in pg_hba.conf?
Date
Msg-id 20200716.093012.1627751694396009053.horikyota.ntt@gmail.com
Whole thread Raw
Responses Re: "cert" + clientcert=verify-ca in pg_hba.conf?
List pgsql-hackers
Hello.

The "Certificate Authentication" section in the doc for PG12 and later
describes the relation ship with clientcert as follows.

> In a pg_hba.conf record specifying certificate authentication, the
> authentication option clientcert is assumed to be verify-ca or
> verify-full, and it cannot be turned off since a client certificate
> is necessary for this method. What the cert method adds to the basic
> clientcert certificate validity test is a check that the cn
> attribute matches the database user name.

In reality, cert method is assumed as "vefiry-full" and does not add
anything to verify-full and cannot be degraded or turned off. It seems
to be a mistake on rewriting it when clientcert was changed to accept
verify-ca/full at PG12.

Related to that, pg_hba.conf accepts the combination of "cert" method
and the option clientcert="verify-ca" but it is ignored. We should
reject that combination the same way with "cert"+"no-verify".

regards.

-- 
Kyotaro Horiguchi
NTT Open Source Software Center
From d7e24df379f29e55adc41c6a98602f2434f5b07e Mon Sep 17 00:00:00 2001
From: Kyotaro Horiguchi <horikyoga.ntt@gmail.com>
Date: Wed, 15 Jul 2020 21:00:20 +0900
Subject: [PATCH] Fix behavior for "cert"+"verify-ca" in pg_hba.conf

"cert" method in a line in pg_hba.conf is assumed as
clientcert="verify_full" and if we set it to "verify-ca", it is just
ignored. Since we explicitly reject "no-verify" in that case so we
should reject verify-ca as well.
---
 doc/src/sgml/client-auth.sgml |  7 ++-----
 src/backend/libpq/hba.c       | 10 ++++++++++
 2 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/doc/src/sgml/client-auth.sgml b/doc/src/sgml/client-auth.sgml
index 5cd88b462d..5ea45d5b87 100644
--- a/doc/src/sgml/client-auth.sgml
+++ b/doc/src/sgml/client-auth.sgml
@@ -2044,11 +2044,8 @@ host ... radius radiusservers="server1,server2" radiussecrets="""secret one"",""
    <para>
     In a <filename>pg_hba.conf</filename> record specifying certificate
     authentication, the authentication option <literal>clientcert</literal> is
-    assumed to be <literal>verify-ca</literal> or <literal>verify-full</literal>,
-    and it cannot be turned off since a client certificate is necessary for this
-    method. What the <literal>cert</literal> method adds to the basic
-    <literal>clientcert</literal> certificate validity test is a check that the
-    <literal>cn</literal> attribute matches the database user name.
+    assumed to be <literal>verify-full</literal>,
+    and it cannot be degradated to verify-ca nor turned off.
    </para>
   </sect1>
 
diff --git a/src/backend/libpq/hba.c b/src/backend/libpq/hba.c
index 9d63830553..18ef385405 100644
--- a/src/backend/libpq/hba.c
+++ b/src/backend/libpq/hba.c
@@ -1711,6 +1711,16 @@ parse_hba_auth_opt(char *name, char *val, HbaLine *hbaline,
         if (strcmp(val, "1") == 0
             || strcmp(val, "verify-ca") == 0)
         {
+            if (hbaline->auth_method == uaCert)
+            {
+                ereport(elevel,
+                        (errcode(ERRCODE_CONFIG_FILE_ERROR),
+                         errmsg("clientcert can not be set to \"verify-ca\" when using \"cert\" authentication"),
+                         errcontext("line %d of configuration file \"%s\"",
+                                    line_num, HbaFileName)));
+                *err_msg = "clientcert can not be set to \"verify-ca\" when using \"cert\" authentication";
+                return false;
+            }
             hbaline->clientcert = clientCertCA;
         }
         else if (strcmp(val, "verify-full") == 0)
-- 
2.18.4


pgsql-hackers by date:

Previous
From: Tom Lane
Date:
Subject: Re: sys_siglist[] is causing us trouble again
Next
From: Andres Freund
Date:
Subject: Re: Improving connection scalability: GetSnapshotData()