Commit 253f1025 authored by Bruce Momjian's avatar Bruce Momjian

Overhaul pg_hba.conf clientcert's API

Since PG 12, clientcert no longer supported only on/off, so remove 1/0
as possible values, and instead support only the text strings
'verify-ca' and 'verify-full'.

Remove support for 'no-verify' since that is possible by just not
specifying clientcert.

Also, throw an error if 'verify-ca' is used and 'cert' authentication is
used, since cert authentication requires verify-full.

Also improve the docs.

THIS IS A BACKWARD INCOMPATIBLE API CHANGE.

Reported-by: Kyotaro Horiguchi

Discussion: https://postgr.es/m/20200716.093012.1627751694396009053.horikyota.ntt@gmail.com

Author: Kyotaro Horiguchi

Backpatch-through: master
parent 18c170a0
...@@ -2044,13 +2044,10 @@ host ... radius radiusservers="server1,server2" radiussecrets="""secret one"","" ...@@ -2044,13 +2044,10 @@ host ... radius radiusservers="server1,server2" radiussecrets="""secret one"",""
</para> </para>
<para> <para>
In a <filename>pg_hba.conf</filename> record specifying certificate It is redundant to use the <literal>clientcert</literal> option with
authentication, the authentication option <literal>clientcert</literal> is <literal>cert</literal> authentication because <literal>cert</literal>
assumed to be <literal>verify-ca</literal> or <literal>verify-full</literal>, authentication is effectively <literal>trust</literal> authentication
and it cannot be turned off since a client certificate is necessary for this with <literal>clientcert=verify-full</literal>.
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.
</para> </para>
</sect1> </sect1>
......
...@@ -2345,9 +2345,8 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433 ...@@ -2345,9 +2345,8 @@ pg_dumpall -p 5432 | psql -d postgres -p 5433
The <literal>clientcert</literal> authentication option is available for The <literal>clientcert</literal> authentication option is available for
all authentication methods, but only in <filename>pg_hba.conf</filename> lines all authentication methods, but only in <filename>pg_hba.conf</filename> lines
specified as <literal>hostssl</literal>. When <literal>clientcert</literal> is specified as <literal>hostssl</literal>. When <literal>clientcert</literal> is
not specified or is set to <literal>no-verify</literal>, the server will still not specified, the server verifies the client certificate against its CA
verify any presented client certificates against its CA file, if one is file only if a client certificate is presented and the CA is configured.
configured &mdash; but it will not insist that a client certificate be presented.
</para> </para>
<para> <para>
......
...@@ -1730,29 +1730,25 @@ parse_hba_auth_opt(char *name, char *val, HbaLine *hbaline, ...@@ -1730,29 +1730,25 @@ parse_hba_auth_opt(char *name, char *val, HbaLine *hbaline,
*err_msg = "clientcert can only be configured for \"hostssl\" rows"; *err_msg = "clientcert can only be configured for \"hostssl\" rows";
return false; return false;
} }
if (strcmp(val, "1") == 0
|| strcmp(val, "verify-ca") == 0) if (strcmp(val, "verify-full") == 0)
{
hbaline->clientcert = clientCertCA;
}
else if (strcmp(val, "verify-full") == 0)
{ {
hbaline->clientcert = clientCertFull; hbaline->clientcert = clientCertFull;
} }
else if (strcmp(val, "0") == 0 else if (strcmp(val, "verify-ca") == 0)
|| strcmp(val, "no-verify") == 0)
{ {
if (hbaline->auth_method == uaCert) if (hbaline->auth_method == uaCert)
{ {
ereport(elevel, ereport(elevel,
(errcode(ERRCODE_CONFIG_FILE_ERROR), (errcode(ERRCODE_CONFIG_FILE_ERROR),
errmsg("clientcert cannot be set to \"no-verify\" when using \"cert\" authentication"), errmsg("clientcert only accepts \"verify-full\" when using \"cert\" authentication"),
errcontext("line %d of configuration file \"%s\"", errcontext("line %d of configuration file \"%s\"",
line_num, HbaFileName))); line_num, HbaFileName)));
*err_msg = "clientcert cannot be set to \"no-verify\" when using \"cert\" authentication"; *err_msg = "clientcert can only be set to \"verify-full\" when using \"cert\" authentication";
return false; return false;
} }
hbaline->clientcert = clientCertOff;
hbaline->clientcert = clientCertCA;
} }
else else
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment