SSL cert client authentication - Mailing list pgsql-patches
From | Gleb Kouzmenko |
---|---|
Subject | SSL cert client authentication |
Date | |
Msg-id | 455D79D0.5070404@abra.ru Whole thread Raw |
List | pgsql-patches |
I propose to authenticate client via verification of its SSL certificate. IDEA. Recent versions of PostgreSQL database server can verify client's SSL certificate (via server's root.crt now). Server gets 'subject' line of verified client certificate ( in src/backend/libpq/be-secure.c:open_server_SSL ), stores it in port->peer_dn, and never uses it after that. We can treat this verification as some kind of IDENT authentication method. The idea is to use client's 'subject' as ident-username key during ident map lookup. EXAMPLE. pg_hba.conf: hostssl all koug 0/0 ident sslcert hostssl all dba 0/0 ident sslcert pg_ident.conf: sslcert "/C=RU/ST=Tmutarakan/O=Kremlin/CN=Gleb Kouzmenko/emailAddress=undisclosed@domain.org" koug sslcert "/C=RU/ST=Tmutarakan/O=Kremlin/CN=Gleb Kouzmenko/emailAddress=undisclosed@domain.org" dba Client that have valid certificate with this 'subject' line can make secure connection to database server as koug or dba - without having IDENT server on his computer. DRAWBACK. It becomes impossible to use ssl connection and IDENT via TCP/IP protocol at the same time. I think it's positive consequence of the method proposed. It's rather strange to rely on insecure IDENT via TCP/IP for authentication of secured connection. SOLUTION. Only one function src/backend/libpq/hba.c:authident should be modified. Patch attached has been made for 8.2beta3. Same modification of authident has been tested against 8.1.5 too. Gleb Kouzmenko *** src/backend/libpq/hba.c 2006-11-06 01:42:08.000000000 +0300 --- src/backend/libpq/hba.c 2006-11-16 15:42:29.000000000 +0300 *************** *** 1587,1593 **** int authident(hbaPort *port) { ! char ident_user[IDENT_USERNAME_MAX + 1]; switch (port->raddr.addr.ss_family) { --- 1587,1594 ---- int authident(hbaPort *port) { ! char buf[IDENT_USERNAME_MAX + 1]; ! char *ident_user = buf; switch (port->raddr.addr.ss_family) { *************** *** 1595,1608 **** --- 1596,1625 ---- #ifdef HAVE_IPV6 case AF_INET6: #endif + #ifdef USE_SSL + if (port->peer != NULL) + { + ident_user = port->peer_dn; + ereport(DEBUG2, + (errmsg("Client SSL certificate subject identifies remote user as \"%s\"", + ident_user))); + break; + } + #endif if (!ident_inet(port->raddr, port->laddr, ident_user)) return STATUS_ERROR; + ereport(DEBUG2, + (errmsg("Ident protocol identifies remote user as \"%s\"", + ident_user))); break; #ifdef HAVE_UNIX_SOCKETS case AF_UNIX: if (!ident_unix(port->sock, ident_user)) return STATUS_ERROR; + ereport(DEBUG2, + (errmsg("Local kernel identifies user as \"%s\"", + ident_user))); break; #endif *************** *** 1610,1618 **** return STATUS_ERROR; } - ereport(DEBUG2, - (errmsg("Ident protocol identifies remote user as \"%s\"", - ident_user))); if (check_ident_usermap(port->auth_arg, port->user_name, ident_user)) return STATUS_OK; --- 1627,1632 ----
pgsql-patches by date: