Index: postgresql/src/backend/postmaster/be-secure.c diff -c postgresql/src/backend/postmaster/be-secure.c:1.2 postgresql/src/backend/postmaster/be-secure.c:1.3 *** postgresql/src/backend/postmaster/be-secure.c:1.2 Fri May 24 16:45:00 2002 --- postgresql/src/backend/postmaster/be-secure.c Fri May 24 17:32:24 2002 *************** *** 11,17 **** * * * IDENTIFICATION ! * $Header: /usr/local/cvsroot/postgresql/src/backend/postmaster/be-secure.c,v 1.2 2002/05/24 22:45:00 bear Exp $ * * PATCH LEVEL * milestone 1: fix basic coding errors --- 11,17 ---- * * * IDENTIFICATION ! * $Header: /usr/local/cvsroot/postgresql/src/backend/postmaster/be-secure.c,v 1.3 2002/05/24 23:32:24 bear Exp $ * * PATCH LEVEL * milestone 1: fix basic coding errors *************** *** 20,26 **** * SSL_shutdown(), default to TLSv1. * * milestone 2: provide endpoint authentication (server) ! * [ ] client verifies server cert * [ ] client verifies server hostname * * milestone 3: improve confidentially, support perfect forward secrecy --- 20,26 ---- * SSL_shutdown(), default to TLSv1. * * milestone 2: provide endpoint authentication (server) ! * [*] client verifies server cert * [ ] client verifies server hostname * * milestone 3: improve confidentially, support perfect forward secrecy Index: postgresql/src/interfaces/libpq/fe-secure.c diff -c postgresql/src/interfaces/libpq/fe-secure.c:1.2 postgresql/src/interfaces/libpq/fe-secure.c:1.3 *** postgresql/src/interfaces/libpq/fe-secure.c:1.2 Fri May 24 16:45:00 2002 --- postgresql/src/interfaces/libpq/fe-secure.c Fri May 24 17:32:24 2002 *************** *** 11,18 **** * * * IDENTIFICATION ! * $Header: /usr/local/cvsroot/postgresql/src/interfaces/libpq/fe-secure.c,v 1.2 2002/05/24 22:45:00 bear Exp $ * * PATCH LEVEL * milestone 1: fix basic coding errors * [*] existing SSL code pulled out of existing files. --- 11,28 ---- * * * IDENTIFICATION ! * $Header: /usr/local/cvsroot/postgresql/src/interfaces/libpq/fe-secure.c,v 1.3 2002/05/24 23:32:24 bear Exp $ * + * NOTES + * The server cert, or better yet the cert that was used to + * sign the server cert (hence allowing the DBA to easily add + * additional servers, modify certs, etc.) should be in the + * "$HOME/.postgresql/root.crt" file. + * + * OS DEPENDENCIES + * The code currently assumes a POSIX password entry. How should + * Windows and Mac users be handled? + * * PATCH LEVEL * milestone 1: fix basic coding errors * [*] existing SSL code pulled out of existing files. *************** *** 20,26 **** * SSL_shutdown(), default to TLSv1. * * milestone 2: provide endpoint authentication (server) ! * [ ] client verifies server cert * [ ] client verifies server hostname * * milestone 3: improve confidentially, support perfect forward secrecy --- 30,36 ---- * SSL_shutdown(), default to TLSv1. * * milestone 2: provide endpoint authentication (server) ! * [*] client verifies server cert * [ ] client verifies server hostname * * milestone 3: improve confidentially, support perfect forward secrecy *************** *** 66,76 **** #include #endif - #ifndef HAVE_STRDUP #include "strdup.h" #endif #ifdef USE_SSL #include #include --- 76,88 ---- #include #endif #ifndef HAVE_STRDUP #include "strdup.h" #endif + #include + #include + #ifdef USE_SSL #include #include *************** *** 84,89 **** --- 96,102 ---- ssize_t secure_write(PGconn *, const void *ptr, size_t len); #ifdef USE_SSL + static int verify_cb(int ok, X509_STORE_CTX *ctx); static int initialize_SSL(PGconn *); static void destroy_SSL(void); static int open_client_SSL(PGconn *); *************** *** 247,257 **** --- 260,291 ---- /* ------------------------------------------------------------ */ #ifdef USE_SSL /* + * Certificate verification callback + * + * This callback allows us to log intermediate problems during + * verification, but there doesn't seem to be a clean way to get + * our PGconn * structure. So we can't log anything! + * + * This callback also allows us to override the default acceptance + * criteria (e.g., accepting self-signed or expired certs), but + * for now we accept the default checks. + */ + static int + verify_cb (int ok, X509_STORE_CTX *ctx) + { + return ok; + } + + /* * Initialize global SSL context. */ static int initialize_SSL (PGconn *conn) { + struct stat buf; + struct passwd *pwd; + char fnbuf[2048]; + if (!SSL_context) { SSL_library_init(); *************** *** 266,271 **** --- 300,324 ---- } } + if ((pwd = getpwuid(getuid())) != NULL) + { + snprintf(fnbuf, sizeof fnbuf, "%s/.postgresql/root.crt", + pwd->pw_dir); + if (stat(fnbuf, &buf) != -1) + { + if (!SSL_CTX_load_verify_locations(SSL_context, fnbuf, 0)) + { + printfPQExpBuffer(&conn->errorMessage, + libpq_gettext("could not read root cert list (%s): %s"), + fnbuf, SSLerrmessage()); + return -1; + } + } + } + + SSL_CTX_set_verify(SSL_context, SSL_VERIFY_PEER, verify_cb); + SSL_CTX_set_verify_depth(SSL_context, 1); + return 0; } *************** *** 288,293 **** --- 341,348 ---- static int open_client_SSL (PGconn *conn) { + int r; + if (!(conn->ssl = SSL_new(SSL_context)) || !SSL_set_fd(conn->ssl, conn->sock) || SSL_connect(conn->ssl) <= 0) *************** *** 295,300 **** --- 350,366 ---- printfPQExpBuffer(&conn->errorMessage, libpq_gettext("could not establish SSL connection: %s\n"), SSLerrmessage()); + close_SSL(conn); + return -1; + } + + /* check the certificate chain of the server */ + r = SSL_get_verify_result(conn->ssl); + if (r != X509_V_OK) + { + printfPQExpBuffer(&conn->errorMessage, + libpq_gettext("certificate could not be validated: %s\n"), + X509_verify_cert_error_string(r)); close_SSL(conn); return -1; }