Index: postgresql/src/backend/postmaster/be-secure.c diff -c postgresql/src/backend/postmaster/be-secure.c:1.4 postgresql/src/backend/postmaster/be-secure.c:1.5 *** postgresql/src/backend/postmaster/be-secure.c:1.4 Fri May 24 21:44:30 2002 --- postgresql/src/backend/postmaster/be-secure.c Fri May 24 22:24:02 2002 *************** *** 11,18 **** * * * IDENTIFICATION ! * $Header: /usr/local/cvsroot/postgresql/src/backend/postmaster/be-secure.c,v 1.4 2002/05/25 03:44:30 bear Exp $ * * PATCH LEVEL * milestone 1: fix basic coding errors * [*] existing SSL code pulled out of existing files. --- 11,30 ---- * * * IDENTIFICATION ! * $Header: /usr/local/cvsroot/postgresql/src/backend/postmaster/be-secure.c,v 1.5 2002/05/25 04:24:02 bear Exp $ * + * NOTES + * + * To make it much harder for an attacker to predict our + * "random" keys, we load the entropy file $DataDir/.rand + * if it exists. This file can be created with "openssl rand ...." + * This file should be updated by destroy_SSL(), but since + * that secure_destroy() isn't called yet we temporarily + * handle this in close_SSL(). + * + * If the entropy file does not exist, but the system has + * /dev/urandom, we read some random data from it instead. + * * PATCH LEVEL * milestone 1: fix basic coding errors * [*] existing SSL code pulled out of existing files. *************** *** 24,30 **** * [*] client verifies server hostname * * milestone 3: improve confidentially, support perfect forward secrecy ! * [ ] use 'random' file, read from '/dev/urandom?' * [ ] emphermal DH keys, default values * [ ] periodic renegotiation * --- 36,42 ---- * [*] client verifies server hostname * * milestone 3: improve confidentially, support perfect forward secrecy ! * [*] use 'random' file, read from '/dev/urandom?' * [ ] emphermal DH keys, default values * [ ] periodic renegotiation * *************** *** 48,53 **** --- 60,66 ---- #include #include #include + #include #include "libpq/libpq.h" #include "libpq/pqsignal.h" *************** *** 73,78 **** --- 86,92 ---- #ifdef USE_SSL #include + #include #include #endif *************** *** 251,256 **** --- 265,271 ---- static int initialize_SSL (void) { + struct stat buf; char fnbuf[2048]; if (!SSL_context) *************** *** 290,295 **** --- 305,329 ---- } } + /* load entropy file, if it exists */ + snprintf(fnbuf, sizeof fnbuf, "%s/.rand", DataDir); + if (!stat(fnbuf, &buf) && !RAND_load_file(fnbuf, 1024 * 1024)) + { + postmaster_error("could not read entropy file (%s): %s", + fnbuf, SSLerrmessage()); + ExitPostmaster(1); + } + else + { + strncpy(fnbuf, "/dev/urandom", sizeof fnbuf); + if (!stat(fnbuf, &buf) && !RAND_load_file(fnbuf, 16 * 1024)) + { + postmaster_error("could not read entropy file (%s): %s", + fnbuf, SSLerrmessage()); + ExitPostmaster(1); + } + } + return 0; } *************** *** 330,337 **** --- 364,377 ---- static void close_SSL (Port *port) { + struct stat buf; + char fnbuf[2048]; + if (port->ssl) { + snprintf(fnbuf, sizeof fnbuf, "%s/.rand", DataDir); + if (stat(fnbuf, &buf) == 0) + RAND_write_file(fnbuf); SSL_shutdown(port->ssl); SSL_free(port->ssl); port->ssl = NULL; Index: postgresql/src/interfaces/libpq/fe-secure.c diff -c postgresql/src/interfaces/libpq/fe-secure.c:1.5 postgresql/src/interfaces/libpq/fe-secure.c:1.6 *** postgresql/src/interfaces/libpq/fe-secure.c:1.5 Fri May 24 21:44:30 2002 --- postgresql/src/interfaces/libpq/fe-secure.c Fri May 24 22:24:02 2002 *************** *** 11,17 **** * * * IDENTIFICATION ! * $Header: /usr/local/cvsroot/postgresql/src/interfaces/libpq/fe-secure.c,v 1.5 2002/05/25 03:44:30 bear Exp $ * * NOTES * The client *requires* a valid server certificate. Since --- 11,17 ---- * * * IDENTIFICATION ! * $Header: /usr/local/cvsroot/postgresql/src/interfaces/libpq/fe-secure.c,v 1.6 2002/05/25 04:24:02 bear Exp $ * * NOTES * The client *requires* a valid server certificate. Since *************** *** 45,50 **** --- 45,62 ---- * backend works (especially that pre-SSL negotiation) to identify * a fix. * + * ... + * + * To make it much harder for an attacker to predict our + * "random" keys, we load the entropy file $HOME/.postgresql/.rand + * if it exists. This file can be created with "openssl rand ...." + * This file should be updated by destroy_SSL(), but since + * that secure_destroy() isn't called yet we temporarily + * handle this in close_SSL(). + * + * If the entropy file does not exist, but the system has + * /dev/urandom, we read some random data from it instead. + * * OS DEPENDENCIES * The code currently assumes a POSIX password entry. How should * Windows and Mac users be handled? *************** *** 60,66 **** * [*] client verifies server hostname * * milestone 3: improve confidentially, support perfect forward secrecy ! * [ ] use 'random' file, read from '/dev/urandom?' * [ ] emphermal DH keys, default values * * milestone 4: provide endpoint authentication (client) --- 72,78 ---- * [*] client verifies server hostname * * milestone 3: improve confidentially, support perfect forward secrecy ! * [*] use 'random' file, read from '/dev/urandom?' * [ ] emphermal DH keys, default values * * milestone 4: provide endpoint authentication (client) *************** *** 112,117 **** --- 124,130 ---- #ifdef USE_SSL #include + #include #include #endif /* USE_SSL */ *************** *** 443,448 **** --- 456,482 ---- fnbuf, SSLerrmessage()); return -1; } + + /* load entropy file, if it exists */ + snprintf(fnbuf, sizeof fnbuf, "%s/.postgresql/.rand", pwd->pw_dir); + if (!stat(fnbuf, &buf) && !RAND_load_file(fnbuf, 1024 * 1024)) + { + printfPQExpBuffer(&conn->errorMessage, + libpq_gettext("could not read entropy file (%s): %s"), + fnbuf, SSLerrmessage()); + return -1; + } + else + { + strncpy(fnbuf, "/dev/urandom", sizeof fnbuf); + if (!stat(fnbuf, &buf) && !RAND_load_file(fnbuf, 16 * 1024)) + { + printfPQExpBuffer(&conn->errorMessage, + libpq_gettext("could not read entropy file (%s): %s"), + fnbuf, SSLerrmessage()); + return -1; + } + } } SSL_CTX_set_verify(SSL_context, *************** *** 460,465 **** --- 494,500 ---- { if (SSL_context) { + /* should save entropy file here, not in close_SSL()... */ SSL_CTX_free(SSL_context); SSL_context = NULL; } *************** *** 535,542 **** --- 570,587 ---- static void close_SSL (PGconn *conn) { + struct stat buf; + struct passwd *pwd; + char fnbuf[2048]; + if (conn->ssl) { + if ((pwd = getpwuid(getuid())) != NULL) + { + snprintf(fnbuf, sizeof fnbuf, "%s/.postgresql/.rand", pwd->pw_dir); + if (stat(fnbuf, &buf) == 0) + RAND_write_file(fnbuf); + } SSL_shutdown(conn->ssl); SSL_free(conn->ssl); conn->ssl = NULL;