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
