Dear Postgresql Hackers, as of now, pg_hba.conf allows us to enable authentification by certificate through the auth-method "cert", in which case the user must provide a valid certificate with a certificate common name(CN) matching the database user's name or an entry in a pg_ident map.
Additionaly, for every other auth-method it is possible to set the auth-option "clientcert=1", so clients must present a valid certificate at login. The logic behind this only checks the validity of the certificate itself, but the certificate common name(CN) is not relevant. I wrote a very small patch that adds another auth-option: - clientcert=verify-full (analogous to server certificates; you could also use 2 instead of verify-full for backwards compatibility, or verify-ca instead of 1) which also checks the certificate common name, so all 3 factors get checked: 1.) auth-method, e.g. scram or md5 password passes 2.) client cert is in truststore 3.) CN is correct. (The patch simply makes use of the function that is used for auth- method "cert" to avoid code duplication). Have a nice weekend, Julian Markwort
diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c index 3014b17a..5757aa99 100644 --- a/src/backend/libpq/auth.c +++ b/src/backend/libpq/auth.c @@ -347,6 +347,7 @@ void ClientAuthentication(Port *port) { int status = STATUS_ERROR; + int status_verify_cert_full = STATUS_ERROR; char *logdetail = NULL; /* @@ -600,10 +601,23 @@ ClientAuthentication(Port *port) break; } + if(port->hba->clientcert_verify_full) + { +#ifdef USE_SSL + status_verify_cert_full = CheckCertAuth(port); +#else + Assert(false); +#endif + } + else + { + status_verify_cert_full = STATUS_OK; + } + if (ClientAuthentication_hook) (*ClientAuthentication_hook) (port, status); - if (status == STATUS_OK) + if (status == STATUS_OK && status_verify_cert_full == STATUS_OK) sendAuthRequest(port, AUTH_REQ_OK, NULL, 0); else auth_failed(port, status, logdetail); diff --git a/src/backend/libpq/hba.c b/src/backend/libpq/hba.c index acf625e4..a5b0683d 100644 --- a/src/backend/libpq/hba.c +++ b/src/backend/libpq/hba.c @@ -1675,10 +1675,17 @@ parse_hba_auth_opt(char *name, char *val, HbaLine *hbaline, *err_msg = "clientcert can only be configured for \"hostssl\" rows"; return false; } - if (strcmp(val, "1") == 0) + if (strcmp(val, "1") == 0 + || strcmp(val, "verify-ca") == 0) { hbaline->clientcert = true; } + else if(strcmp(val, "2") == 0 + || strcmp(val, "verify-full") == 0) + { + hbaline->clientcert = true; + hbaline->clientcert_verify_full = true; + } else { if (hbaline->auth_method == uaCert) diff --git a/src/include/libpq/hba.h b/src/include/libpq/hba.h index 5f68f4c6..309db47d 100644 --- a/src/include/libpq/hba.h +++ b/src/include/libpq/hba.h @@ -87,6 +87,7 @@ typedef struct HbaLine char *ldapprefix; char *ldapsuffix; bool clientcert; + bool clientcert_verify_full; char *krb_realm; bool include_realm; bool compat_realm;
smime.p7s
Description: S/MIME cryptographic signature