mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-01-12 18:34:36 +08:00
Add support for using SSL client certificates to authenticate to the
database (only for SSL connections, obviously).
This commit is contained in:
parent
3c486fbd1c
commit
f179d5ea99
@ -1,4 +1,4 @@
|
||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/client-auth.sgml,v 1.111 2008/11/18 13:10:20 petere Exp $ -->
|
||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/client-auth.sgml,v 1.112 2008/11/20 11:48:26 mha Exp $ -->
|
||||
|
||||
<chapter id="client-authentication">
|
||||
<title>Client Authentication</title>
|
||||
@ -387,6 +387,16 @@ hostnossl <replaceable>database</replaceable> <replaceable>user</replaceable>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><literal>cert</></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Authenticate using SSL client certificates. See
|
||||
<xref linkend="auth-cert"> for details.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><literal>pam</></term>
|
||||
<listitem>
|
||||
@ -1114,6 +1124,25 @@ ldapserver=ldap.example.net prefix="cn=" suffix="dc=example, dc=net"
|
||||
|
||||
</sect2>
|
||||
|
||||
<sect2 id="auth-cert">
|
||||
<title>Certificate authentication</title>
|
||||
|
||||
<indexterm zone="auth-cert">
|
||||
<primary>Certificate</primary>
|
||||
</indexterm>
|
||||
|
||||
<para>
|
||||
This authentication method uses SSL client certificates to perform
|
||||
authentication. It is therefore only available for SSL connections.
|
||||
When using this authentication method, the server will require that
|
||||
the client provide a certificate. No password prompt will be sent
|
||||
to the client. The <literal>cn</literal> attribute of the certificate
|
||||
will be matched with the username the user is trying to log in as,
|
||||
and if they match the login will be allowed. Username mapping can be
|
||||
used if the usernames don't match.
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
<sect2 id="auth-pam">
|
||||
<title>PAM authentication</title>
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/runtime.sgml,v 1.421 2008/11/20 09:29:35 mha Exp $ -->
|
||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/runtime.sgml,v 1.422 2008/11/20 11:48:26 mha Exp $ -->
|
||||
|
||||
<chapter Id="runtime">
|
||||
<title>Operating System Environment</title>
|
||||
@ -1674,11 +1674,9 @@ $ <userinput>kill -INT `head -1 /usr/local/pgsql/data/postmaster.pid`</userinput
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<productname>PostgreSQL</> currently does not support authentication
|
||||
using client certificates, since it cannot differentiate between
|
||||
different users. As long as the user holds any certificate issued
|
||||
by a trusted CA it will be accepted, regardless of what account the
|
||||
user is trying to connect with.
|
||||
You can use the authentication method <literal>cert</> to use the
|
||||
client certificate for authenticating users. See
|
||||
<xref linkend="auth-cert"> for details.
|
||||
</para>
|
||||
</sect2>
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user