1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-28 23:42:10 +03:00

Add support for using SSL client certificates to authenticate to the

database (only for SSL connections, obviously).
This commit is contained in:
Magnus Hagander
2008-11-20 11:48:26 +00:00
parent 3c486fbd1c
commit f179d5ea99
6 changed files with 120 additions and 14 deletions

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/libpq/auth.c,v 1.172 2008/11/20 09:29:36 mha Exp $
* $PostgreSQL: pgsql/src/backend/libpq/auth.c,v 1.173 2008/11/20 11:48:26 mha Exp $
*
*-------------------------------------------------------------------------
*/
@ -113,6 +113,14 @@ ULONG(*__ldap_start_tls_sA) (
static int CheckLDAPAuth(Port *port);
#endif /* USE_LDAP */
/*----------------------------------------------------------------
* Cert authentication
*----------------------------------------------------------------
*/
#ifdef USE_SSL
static int CheckCertAuth(Port *port);
#endif
/*----------------------------------------------------------------
* Kerberos and GSSAPI GUCs
@ -431,6 +439,14 @@ ClientAuthentication(Port *port)
#endif
break;
case uaCert:
#ifdef USE_SSL
status = CheckCertAuth(port);
#else
Assert(false);
#endif
break;
case uaTrust:
status = STATUS_OK;
break;
@ -2120,3 +2136,28 @@ CheckLDAPAuth(Port *port)
}
#endif /* USE_LDAP */
/*----------------------------------------------------------------
* SSL client certificate authentication
*----------------------------------------------------------------
*/
#ifdef USE_SSL
static int
CheckCertAuth(Port *port)
{
Assert(port->ssl);
/* Make sure we have received a username in the certificate */
if (port->peer_cn == NULL ||
strlen(port->peer_cn) <= 0)
{
ereport(LOG,
(errmsg("Certificate login failed for user \"%s\": client certificate contains no username",
port->user_name)));
return STATUS_ERROR;
}
/* Just pass the certificate CN to the usermap check */
return check_usermap(port->hba->usermap, port->user_name, port->peer_cn, false);
}
#endif

View File

@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/libpq/hba.c,v 1.173 2008/11/20 09:29:36 mha Exp $
* $PostgreSQL: pgsql/src/backend/libpq/hba.c,v 1.174 2008/11/20 11:48:26 mha Exp $
*
*-------------------------------------------------------------------------
*/
@ -858,6 +858,12 @@ parse_hba_line(List *line, int line_num, HbaLine *parsedline)
parsedline->auth_method = uaLDAP;
#else
unsupauth = "ldap";
#endif
else if (strcmp(token, "cert") == 0)
#ifdef USE_SSL
parsedline->auth_method = uaCert;
#else
unsupauth = "cert";
#endif
else
{
@ -893,6 +899,17 @@ parse_hba_line(List *line, int line_num, HbaLine *parsedline)
return false;
}
if (parsedline->conntype != ctHostSSL &&
parsedline->auth_method == uaCert)
{
ereport(LOG,
(errcode(ERRCODE_CONFIG_FILE_ERROR),
errmsg("cert authentication is only supported on hostssl connections"),
errcontext("line %d of configuration file \"%s\"",
line_num, HbaFileName)));
return false;
}
/* Parse remaining arguments */
while ((line_item = lnext(line_item)) != NULL)
{
@ -923,8 +940,9 @@ parse_hba_line(List *line, int line_num, HbaLine *parsedline)
if (parsedline->auth_method != uaIdent &&
parsedline->auth_method != uaKrb5 &&
parsedline->auth_method != uaGSS &&
parsedline->auth_method != uaSSPI)
INVALID_AUTH_OPTION("map", "ident, krb5, gssapi and sspi");
parsedline->auth_method != uaSSPI &&
parsedline->auth_method != uaCert)
INVALID_AUTH_OPTION("map", "ident, krb5, gssapi, sspi and cert");
parsedline->usermap = pstrdup(c);
}
else if (strcmp(token, "clientcert") == 0)
@ -957,7 +975,18 @@ parse_hba_line(List *line, int line_num, HbaLine *parsedline)
parsedline->clientcert = true;
}
else
{
if (parsedline->auth_method == uaCert)
{
ereport(LOG,
(errcode(ERRCODE_CONFIG_FILE_ERROR),
errmsg("clientcert can not be set to 0 when using \"cert\" authentication"),
errcontext("line %d of configuration file \"%s\"",
line_num, HbaFileName)));
return false;
}
parsedline->clientcert = false;
}
}
else if (strcmp(token, "pamservice") == 0)
{
@ -1021,6 +1050,14 @@ parse_hba_line(List *line, int line_num, HbaLine *parsedline)
{
MANDATORY_AUTH_ARG(parsedline->ldapserver, "ldapserver", "ldap");
}
/*
* Enforce any parameters implied by other settings.
*/
if (parsedline->auth_method == uaCert)
{
parsedline->clientcert = true;
}
return true;
}

View File

@ -35,7 +35,7 @@
# an IP address and netmask in separate columns to specify the set of hosts.
#
# METHOD can be "trust", "reject", "md5", "crypt", "password", "gss", "sspi",
# "krb5", "ident", "pam" or "ldap". Note that "password" sends passwords
# "krb5", "ident", "pam", "ldap" or "cert". Note that "password" sends passwords
# in clear text; "md5" is preferred since it sends encrypted passwords.
#
# OPTIONS are a set of options for the authentication in the format

View File

@ -4,7 +4,7 @@
* Interface to hba.c
*
*
* $PostgreSQL: pgsql/src/include/libpq/hba.h,v 1.52 2008/11/20 09:29:36 mha Exp $
* $PostgreSQL: pgsql/src/include/libpq/hba.h,v 1.53 2008/11/20 11:48:26 mha Exp $
*
*-------------------------------------------------------------------------
*/
@ -26,7 +26,8 @@ typedef enum UserAuth
uaGSS,
uaSSPI,
uaPAM,
uaLDAP
uaLDAP,
uaCert
} UserAuth;
typedef enum ConnType