diff -rcN ../pgsql-20060830/doc/src/sgml/config.sgml ./doc/src/sgml/config.sgml
*** ../pgsql-20060830/doc/src/sgml/config.sgml 2006-08-30 16:01:12.000000000 +0400
--- ./doc/src/sgml/config.sgml 2006-09-01 11:13:34.000000000 +0400
***************
*** 555,561 ****
!
password_encryption (boolean)
--- 555,575 ----
!
! ssl_ciphers> (string)
!
! ssl_ciphers> configuration parameter
!
!
!
! Specifies list of SSL> ciphers, which can be used to
! establish secure connection. See manual page for
! openssl ciphers
! command to find list of allowed values and their semantics.
!
!
!
!
password_encryption (boolean)
diff -rcN ../pgsql-20060830/doc/src/sgml/libpq.sgml ./doc/src/sgml/libpq.sgml
*** ../pgsql-20060830/doc/src/sgml/libpq.sgml 2006-08-30 16:01:12.000000000 +0400
--- ./doc/src/sgml/libpq.sgml 2006-09-01 12:30:33.000000000 +0400
***************
*** 3942,3947 ****
--- 3942,3959 ----
+ PGSSLKEY
+
+ PGSSLKEY
+ specifies hardware token which store secret key of the client
+ certificate, instead of file. Value of this variable should consist of
+ colon separated engine name (engines are loadable modules of
+ OpenSSL>) and engine-specific key identifier.
+
+
+
+
+
PGKRBSRVNAME
PGKRBSRVNAME sets the Kerberos service name to use when
***************
*** 4139,4158 ****
for increased security. See for details
about the server-side SSL> functionality.
!
If the server demands a client certificate,
libpq
will send the certificate stored in file
~/.postgresql/postgresql.crt> within the user's home directory.
A matching private key file ~/.postgresql/postgresql.key>
! must also be present, and must not be world-readable.
(On Microsoft Windows these files are named
%APPDATA%\postgresql\postgresql.crt and
%APPDATA%\postgresql\postgresql.key.)
If the file ~/.postgresql/root.crt> is present in the user's
home directory,
libpq will use the certificate list stored
--- 4151,4194 ----
for increased security. See for details
about the server-side SSL> functionality.
!
! libpq reads system-wide
! OpenSSL configuration file. By default this
! file is named openssl.cnf and located in the
! directory, which is reported by command:
!
! openssl version -d
!
! This default can be overriden by setting environment variable
! OPENSSL_CONF to the name of desired configuration file.
!
If the server demands a client certificate,
libpq
will send the certificate stored in file
~/.postgresql/postgresql.crt> within the user's home directory.
A matching private key file ~/.postgresql/postgresql.key>
! must also be present, and must not be world-readable, unless secret
! key is stored on hardware token, specified by
! PGSSLKEY.
(On Microsoft Windows these files are named
%APPDATA%\postgresql\postgresql.crt and
%APPDATA%\postgresql\postgresql.key.)
+ If environment variable PGSSLKEY is set, its value
+ should consist of colon separated engine name and key identifier. In this
+ case, libpq would load specified engine,
+ i.e. OpenSSL> module which supports special hardware
+ and obtain reference to key with specified identifier. Identifiers
+ are engine-specific. Typically, cryptography hardware tokens do not
+ reveal secret keys to the application. Instead, application delegates
+ all cryptography operations which require secret key, to the
+ hardware token.
+
+
+
If the file ~/.postgresql/root.crt> is present in the user's
home directory,
libpq will use the certificate list stored
diff -rcN ../pgsql-20060830/doc/src/sgml/runtime.sgml ./doc/src/sgml/runtime.sgml
*** ../pgsql-20060830/doc/src/sgml/runtime.sgml 2006-08-30 16:01:12.000000000 +0400
--- ./doc/src/sgml/runtime.sgml 2006-09-01 12:30:34.000000000 +0400
***************
*** 1516,1521 ****
--- 1516,1540 ----
+ OpenSSL supports wide range of ciphers
+ and authentication algorithms, which strength varies significantly.
+ You can restrict list of ciphers which can be used to connect to
+ your server using parameter.
+
+
+ PostgreSQL reads system-wide
+ OpenSSL configuration file. By default this
+ file is named openssl.cnf and located in the
+ directory, which is reported by command:
+
+ openssl version -d
+
+
+ This default can be overriden by setting environment variable
+ OPENSSL_CONF to the name of desired configuration file.
+
+
+
For details on how to create your server private key and certificate,
refer to the OpenSSL> documentation. A
self-signed certificate can be used for testing, but a
diff -rcN ../pgsql-20060830/src/backend/libpq/be-secure.c ./src/backend/libpq/be-secure.c
*** ../pgsql-20060830/src/backend/libpq/be-secure.c 2006-08-30 16:01:28.000000000 +0400
--- ./src/backend/libpq/be-secure.c 2006-09-01 11:59:16.000000000 +0400
***************
*** 92,97 ****
--- 92,101 ----
#ifdef USE_SSL
#include
#include
+ #if SSLEAY_VERSION_NUMBER >= 0x0907000L
+ #include
+ #endif
+
#endif
#include "libpq/libpq.h"
***************
*** 125,130 ****
--- 129,138 ----
#define RENEGOTIATION_LIMIT (512 * 1024 * 1024)
static SSL_CTX *SSL_context = NULL;
+
+ /* GUC variable controlling SSL cipher list*/
+ extern char *SSLCipherSuites;
+
#endif
/* ------------------------------------------------------------ */
***************
*** 717,722 ****
--- 725,733 ----
if (!SSL_context)
{
+ #if SSLEAY_VERSION_NUMBER >= 0x0907000L
+ OPENSSL_config(NULL);
+ #endif
SSL_library_init();
SSL_load_error_strings();
SSL_context = SSL_CTX_new(SSLv23_method());
***************
*** 778,784 ****
SSL_CTX_set_options(SSL_context, SSL_OP_SINGLE_DH_USE | SSL_OP_NO_SSLv2);
/* setup the allowed cipher list */
! if (SSL_CTX_set_cipher_list(SSL_context, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH") != 1)
elog(FATAL, "could not set the cipher list (no valid ciphers available)");
/*
--- 789,795 ----
SSL_CTX_set_options(SSL_context, SSL_OP_SINGLE_DH_USE | SSL_OP_NO_SSLv2);
/* setup the allowed cipher list */
! if (SSL_CTX_set_cipher_list(SSL_context, SSLCipherSuites) != 1)
elog(FATAL, "could not set the cipher list (no valid ciphers available)");
/*
diff -rcN ../pgsql-20060830/src/backend/postmaster/postmaster.c ./src/backend/postmaster/postmaster.c
*** ../pgsql-20060830/src/backend/postmaster/postmaster.c 2006-08-30 16:01:32.000000000 +0400
--- ./src/backend/postmaster/postmaster.c 2006-09-01 11:16:03.000000000 +0400
***************
*** 186,191 ****
--- 186,192 ----
/* still more option variables */
bool EnableSSL = false;
+ char * SSLCipherSuites;
bool SilentMode = false; /* silent mode (-S) */
int PreAuthDelay = 0;
diff -rcN ../pgsql-20060830/src/backend/utils/misc/guc.c ./src/backend/utils/misc/guc.c
*** ../pgsql-20060830/src/backend/utils/misc/guc.c 2006-08-30 16:01:36.000000000 +0400
--- ./src/backend/utils/misc/guc.c 2006-09-01 11:17:04.000000000 +0400
***************
*** 2233,2239 ****
&external_pid_file,
NULL, assign_canonical_path, NULL
},
!
/* End-of-list marker */
{
{NULL, 0, 0, NULL, NULL}, NULL, NULL, NULL, NULL
--- 2233,2248 ----
&external_pid_file,
NULL, assign_canonical_path, NULL
},
! {
! {"ssl_ciphers", PGC_POSTMASTER, CONN_AUTH_SECURITY,
! gettext_noop("List of allowed SSL ciphersuites"),
! NULL,
! GUC_SUPERUSER_ONLY
! },
! &SSLCipherSuites,
! "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH",NULL,NULL
! },
!
/* End-of-list marker */
{
{NULL, 0, 0, NULL, NULL}, NULL, NULL, NULL, NULL
diff -rcN ../pgsql-20060830/src/backend/utils/misc/postgresql.conf.sample ./src/backend/utils/misc/postgresql.conf.sample
*** ../pgsql-20060830/src/backend/utils/misc/postgresql.conf.sample 2006-08-30 16:01:36.000000000 +0400
--- ./src/backend/utils/misc/postgresql.conf.sample 2006-09-01 11:17:04.000000000 +0400
***************
*** 71,76 ****
--- 71,77 ----
#authentication_timeout = 60 # 1-600, in seconds
#ssl = off # (change requires restart)
+ #ssl_ciphers = 'ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH' # List of ciphers to use
#password_encryption = on
#db_user_namespace = off
diff -rcN ../pgsql-20060830/src/include/postmaster/postmaster.h ./src/include/postmaster/postmaster.h
*** ../pgsql-20060830/src/include/postmaster/postmaster.h 2006-08-30 16:01:42.000000000 +0400
--- ./src/include/postmaster/postmaster.h 2006-09-01 11:17:04.000000000 +0400
***************
*** 15,20 ****
--- 15,21 ----
/* GUC options */
extern bool EnableSSL;
+ extern char *SSLCipherSuites;
extern bool SilentMode;
extern int ReservedBackends;
extern int PostPortNumber;
diff -rcN ../pgsql-20060830/src/interfaces/libpq/fe-secure.c ./src/interfaces/libpq/fe-secure.c
*** ../pgsql-20060830/src/interfaces/libpq/fe-secure.c 2006-08-30 16:01:45.000000000 +0400
--- ./src/interfaces/libpq/fe-secure.c 2006-08-30 21:03:28.000000000 +0400
***************
*** 115,120 ****
--- 115,126 ----
#ifdef USE_SSL
#include
+ #if (SSLEAY_VERSION_NUMBER >= 0x00907000L)
+ #include
+ #endif
+ #if (SSLEAY_VERSION_NUMBER >= 0x00907000L) && !defined(OPENSSL_NO_ENGINE)
+ #include
+ #endif
#endif /* USE_SSL */
***************
*** 611,664 ****
}
fclose(fp);
! /* read the user key */
! snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, USER_KEY_FILE);
! if (stat(fnbuf, &buf) == -1)
! {
! printfPQExpBuffer(&conn->errorMessage,
! libpq_gettext("certificate present, but not private key file \"%s\"\n"),
! fnbuf);
! return 0;
! }
! #ifndef WIN32
! if (!S_ISREG(buf.st_mode) || (buf.st_mode & 0077) ||
! buf.st_uid != geteuid())
! {
! printfPQExpBuffer(&conn->errorMessage,
! libpq_gettext("private key file \"%s\" has wrong permissions\n"),
! fnbuf);
! return 0;
! }
! #endif
! if ((fp = fopen(fnbuf, "r")) == NULL)
! {
! printfPQExpBuffer(&conn->errorMessage,
! libpq_gettext("could not open private key file \"%s\": %s\n"),
! fnbuf, pqStrerror(errno, sebuf, sizeof(sebuf)));
! return 0;
! }
! #ifndef WIN32
! if (fstat(fileno(fp), &buf2) == -1 ||
! buf.st_dev != buf2.st_dev || buf.st_ino != buf2.st_ino)
! {
! printfPQExpBuffer(&conn->errorMessage,
! libpq_gettext("private key file \"%s\" changed during execution\n"), fnbuf);
! return 0;
! }
! #endif
! if (PEM_read_PrivateKey(fp, pkey, cb, NULL) == NULL)
! {
! char *err = SSLerrmessage();
! printfPQExpBuffer(&conn->errorMessage,
! libpq_gettext("could not read private key file \"%s\": %s\n"),
! fnbuf, err);
! SSLerrfree(err);
fclose(fp);
- return 0;
}
- fclose(fp);
-
/* verify that the cert and key go together */
if (!X509_check_private_key(*x509, *pkey))
{
--- 617,707 ----
}
fclose(fp);
! #if (SSLEAY_VERSION_NUMBER >= 0x00907000L) && !defined(OPENSSL_NO_ENGINE)
! if (getenv("PGSSLKEY")) {
! /* read the user key from engine */
! ENGINE *e = NULL;
! char *engine_id;
! char *l = getenv("PGSSLKEY");
! char *p = strchr(l,':');
! if (!p) {
! printfPQExpBuffer(&conn->errorMessage,libpq_gettext("Invalid value of PGSSLKEY environment variable\n"));
! return 0;
! }
! engine_id = malloc(p-l+1);
! strncpy(engine_id,l,p-l);
! engine_id[p-l]=0;
! e = ENGINE_by_id(engine_id);
! if (!e) {
! char *err = SSLerrmessage();
! printfPQExpBuffer(&conn->errorMessage,libpq_gettext("Couldn't load engine \"%s\":%s\n"),engine_id,err);
! free(engine_id);
! SSLerrfree(err);
! return 0;
! }
! *pkey = ENGINE_load_private_key(e,p+1,NULL,NULL);
! if (!*pkey) {
! char *err = SSLerrmessage();
! printfPQExpBuffer(&conn->errorMessage,
! libpq_gettext("could not read prevate key %s from engine \"%s\": %s\n"),
! p+1,engine_id, err);
! SSLerrfree(err);
! free(engine_id);
! return 0;
! }
! free(engine_id);
! } else {
! #else
! {
! #endif
! /* read the user key from file*/
! snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, USER_KEY_FILE);
! if (stat(fnbuf, &buf) == -1)
! {
! printfPQExpBuffer(&conn->errorMessage,
! libpq_gettext("certificate present, but not private key file \"%s\"\n"),
! fnbuf);
! return 0;
! }
! #ifndef WIN32
! if (!S_ISREG(buf.st_mode) || (buf.st_mode & 0077) ||
! buf.st_uid != geteuid())
! {
! printfPQExpBuffer(&conn->errorMessage,
! libpq_gettext("private key file \"%s\" has wrong permissions\n"),
! fnbuf);
! return 0;
! }
! #endif
! if ((fp = fopen(fnbuf, "r")) == NULL)
! {
! printfPQExpBuffer(&conn->errorMessage,
! libpq_gettext("could not open private key file \"%s\": %s\n"),
! fnbuf, pqStrerror(errno, sebuf, sizeof(sebuf)));
! return 0;
! }
! #ifndef WIN32
! if (fstat(fileno(fp), &buf2) == -1 ||
! buf.st_dev != buf2.st_dev || buf.st_ino != buf2.st_ino)
! {
! printfPQExpBuffer(&conn->errorMessage,
! libpq_gettext("private key file \"%s\" changed during execution\n"), fnbuf);
! return 0;
! }
! #endif
! if (PEM_read_PrivateKey(fp, pkey, cb, NULL) == NULL)
! {
! char *err = SSLerrmessage();
! printfPQExpBuffer(&conn->errorMessage,
! libpq_gettext("could not read private key file \"%s\": %s\n"),
! fnbuf, err);
! SSLerrfree(err);
! fclose(fp);
! return 0;
! }
fclose(fp);
}
/* verify that the cert and key go together */
if (!X509_check_private_key(*x509, *pkey))
{
***************
*** 742,747 ****
--- 785,793 ----
{
if (pq_initssllib)
{
+ #if (SSLEAY_VERSION_NUMBER >= 0x00907000L)
+ OPENSSL_config(NULL);
+ #endif
SSL_library_init();
SSL_load_error_strings();
}