mirror of
https://github.com/postgres/postgres.git
synced 2025-04-27 22:56:53 +03:00
Add PQinitOpenSSL() function to support applications that use libcrypto
but not OpenSSL (or perhaps vice versa, if that's possible). Andrew Chernow, with minor editorialization by me.
This commit is contained in:
parent
c9aa8a62c0
commit
97503a5200
@ -1,4 +1,4 @@
|
|||||||
<!-- $PostgreSQL: pgsql/doc/src/sgml/libpq.sgml,v 1.280 2009/03/28 01:36:11 momjian Exp $ -->
|
<!-- $PostgreSQL: pgsql/doc/src/sgml/libpq.sgml,v 1.281 2009/03/31 01:41:27 tgl Exp $ -->
|
||||||
|
|
||||||
<chapter id="libpq">
|
<chapter id="libpq">
|
||||||
<title><application>libpq</application> - C Library</title>
|
<title><application>libpq</application> - C Library</title>
|
||||||
@ -6168,20 +6168,6 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough)
|
|||||||
environment variables <envar>PGSSLCERT</> and <envar>PGSSLKEY</>.
|
environment variables <envar>PGSSLCERT</> and <envar>PGSSLKEY</>.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
|
||||||
If your application initializes <literal>libssl</> or
|
|
||||||
<literal>libcrypto</> libraries and <application>libpq</application>
|
|
||||||
is built with <acronym>SSL</> support, you should call
|
|
||||||
<function>PQinitSSL(0)</> to tell <application>libpq</application>
|
|
||||||
that the <literal>libssl</> and <literal>libcrypto</> libraries
|
|
||||||
have been initialized by your application so
|
|
||||||
<application>libpq</application> will not initialize those libraries.
|
|
||||||
<!-- If this URL changes replace it with a URL to www.archive.org. -->
|
|
||||||
See <ulink
|
|
||||||
url="http://h71000.www7.hp.com/doc/83final/BA554_90007/ch04.html"></ulink>
|
|
||||||
for details on the SSL API.
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<table id="libpq-ssl-file-usage">
|
<table id="libpq-ssl-file-usage">
|
||||||
<title>Libpq/Client SSL File Usage</title>
|
<title>Libpq/Client SSL File Usage</title>
|
||||||
<tgroup cols="3">
|
<tgroup cols="3">
|
||||||
@ -6225,6 +6211,93 @@ myEventProc(PGEventId evtId, void *evtInfo, void *passThrough)
|
|||||||
</tgroup>
|
</tgroup>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
If your application initializes <literal>libssl</> and/or
|
||||||
|
<literal>libcrypto</> libraries and <application>libpq</application>
|
||||||
|
is built with <acronym>SSL</> support, you should call
|
||||||
|
<function>PQinitOpenSSL</> to tell <application>libpq</application>
|
||||||
|
that the <literal>libssl</> and/or <literal>libcrypto</> libraries
|
||||||
|
have been initialized by your application, so that
|
||||||
|
<application>libpq</application> will not also initialize those libraries.
|
||||||
|
<!-- If this URL changes replace it with a URL to www.archive.org. -->
|
||||||
|
See <ulink
|
||||||
|
url="http://h71000.www7.hp.com/doc/83final/BA554_90007/ch04.html"></ulink>
|
||||||
|
for details on the SSL API.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
<variablelist>
|
||||||
|
<varlistentry>
|
||||||
|
<term>
|
||||||
|
<function>PQinitOpenSSL</function>
|
||||||
|
<indexterm>
|
||||||
|
<primary>PQinitOpenSSL</primary>
|
||||||
|
</indexterm>
|
||||||
|
</term>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Allows applications to select which security libraries to initialize.
|
||||||
|
<synopsis>
|
||||||
|
void PQinitOpenSSL(int do_ssl, init do_crypto);
|
||||||
|
</synopsis>
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
When <parameter>do_ssl</> is non-zero, <application>libpq</application>
|
||||||
|
will initialize the <application>OpenSSL</> library before first
|
||||||
|
opening a database connection. When <parameter>do_crypto</> is
|
||||||
|
non-zero, the <literal>libcrypto</> library will be initialized. By
|
||||||
|
default (if <function>PQinitOpenSSL</> is not called), both libraries
|
||||||
|
are initialized. When SSL support is not compiled in, this function is
|
||||||
|
present but does nothing.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
If your application uses and initializes either <application>OpenSSL</>
|
||||||
|
or its underlying <literal>libcrypto</> library, you <emphasis>must</>
|
||||||
|
call this function with zeroes for the appropriate parameter(s)
|
||||||
|
before first opening a database connection. Also be sure that you
|
||||||
|
have done that initialization before opening a database connection.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term>
|
||||||
|
<function>PQinitSSL</function>
|
||||||
|
<indexterm>
|
||||||
|
<primary>PQinitSSL</primary>
|
||||||
|
</indexterm>
|
||||||
|
</term>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Allows applications to select which security libraries to initialize.
|
||||||
|
<synopsis>
|
||||||
|
void PQinitSSL(int do_ssl);
|
||||||
|
</synopsis>
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
This function is equivalent to
|
||||||
|
<literal>PQinitOpenSSL(do_ssl, do_ssl)</>.
|
||||||
|
It is sufficient for applications that initialize both or neither
|
||||||
|
of <application>OpenSSL</> and <literal>libcrypto</>.
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
<function>PQinitSSL</> has been present since
|
||||||
|
<productname>PostgreSQL</> 8.0, while <function>PQinitOpenSSL</>
|
||||||
|
was added in <productname>PostgreSQL</> 8.4, so <function>PQinitSSL</>
|
||||||
|
might be preferable for applications that need to work with older
|
||||||
|
versions of <application>libpq</application>.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
</variablelist>
|
||||||
|
</para>
|
||||||
|
|
||||||
</sect1>
|
</sect1>
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# $PostgreSQL: pgsql/src/interfaces/libpq/exports.txt,v 1.22 2008/09/22 13:55:14 tgl Exp $
|
# $PostgreSQL: pgsql/src/interfaces/libpq/exports.txt,v 1.23 2009/03/31 01:41:27 tgl Exp $
|
||||||
# Functions to be exported by libpq DLLs
|
# Functions to be exported by libpq DLLs
|
||||||
PQconnectdb 1
|
PQconnectdb 1
|
||||||
PQsetdbLogin 2
|
PQsetdbLogin 2
|
||||||
@ -152,3 +152,4 @@ PQresultInstanceData 149
|
|||||||
PQresultSetInstanceData 150
|
PQresultSetInstanceData 150
|
||||||
PQfireResultCreateEvents 151
|
PQfireResultCreateEvents 151
|
||||||
PQconninfoParse 152
|
PQconninfoParse 152
|
||||||
|
PQinitOpenSSL 153
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/interfaces/libpq/fe-secure.c,v 1.121 2009/03/28 18:48:55 momjian Exp $
|
* $PostgreSQL: pgsql/src/interfaces/libpq/fe-secure.c,v 1.122 2009/03/31 01:41:27 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
*
|
*
|
||||||
@ -99,10 +99,11 @@ static char *SSLerrmessage(void);
|
|||||||
static void SSLerrfree(char *buf);
|
static void SSLerrfree(char *buf);
|
||||||
|
|
||||||
static bool pq_init_ssl_lib = true;
|
static bool pq_init_ssl_lib = true;
|
||||||
|
static bool pq_init_crypto_lib = true;
|
||||||
static SSL_CTX *SSL_context = NULL;
|
static SSL_CTX *SSL_context = NULL;
|
||||||
|
|
||||||
#ifdef ENABLE_THREAD_SAFETY
|
#ifdef ENABLE_THREAD_SAFETY
|
||||||
static int ssl_open_connections = 0;
|
static long ssl_open_connections = 0;
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
static pthread_mutex_t ssl_config_mutex = PTHREAD_MUTEX_INITIALIZER;
|
static pthread_mutex_t ssl_config_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
@ -171,9 +172,29 @@ static long win32_ssl_create_mutex = 0;
|
|||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
PQinitSSL(int do_init)
|
PQinitSSL(int do_init)
|
||||||
|
{
|
||||||
|
PQinitOpenSSL(do_init, do_init);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Exported function to allow application to tell us it's already
|
||||||
|
* initialized OpenSSL and/or libcrypto.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
PQinitOpenSSL(int do_ssl, int do_crypto)
|
||||||
{
|
{
|
||||||
#ifdef USE_SSL
|
#ifdef USE_SSL
|
||||||
pq_init_ssl_lib = do_init;
|
#ifdef ENABLE_THREAD_SAFETY
|
||||||
|
/*
|
||||||
|
* Disallow changing the flags while we have open connections, else
|
||||||
|
* we'd get completely confused.
|
||||||
|
*/
|
||||||
|
if (ssl_open_connections != 0)
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
pq_init_ssl_lib = do_ssl;
|
||||||
|
pq_init_crypto_lib = do_crypto;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -810,10 +831,10 @@ pq_lockingcallback(int mode, int n, const char *file, int line)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize SSL system. In threadsafe mode, this includes setting
|
* Initialize SSL system. In threadsafe mode, this includes setting
|
||||||
* up OpenSSL callback functions to do thread locking.
|
* up libcrypto callback functions to do thread locking.
|
||||||
*
|
*
|
||||||
* If the caller has told us (through PQinitSSL) that he's taking care
|
* If the caller has told us (through PQinitOpenSSL) that he's taking care
|
||||||
* of SSL, we expect that callbacks are already set, and won't try to
|
* of libcrypto, we expect that callbacks are already set, and won't try to
|
||||||
* override it.
|
* override it.
|
||||||
*
|
*
|
||||||
* The conn parameter is only used to be able to pass back an error
|
* The conn parameter is only used to be able to pass back an error
|
||||||
@ -840,11 +861,11 @@ init_ssl_system(PGconn *conn)
|
|||||||
if (pthread_mutex_lock(&ssl_config_mutex))
|
if (pthread_mutex_lock(&ssl_config_mutex))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (pq_init_ssl_lib)
|
if (pq_init_crypto_lib)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* If necessary, set up an array to hold locks for OpenSSL. OpenSSL will
|
* If necessary, set up an array to hold locks for libcrypto.
|
||||||
* tell us how big to make this array.
|
* libcrypto will tell us how big to make this array.
|
||||||
*/
|
*/
|
||||||
if (pq_lockarray == NULL)
|
if (pq_lockarray == NULL)
|
||||||
{
|
{
|
||||||
@ -870,8 +891,7 @@ init_ssl_system(PGconn *conn)
|
|||||||
|
|
||||||
if (ssl_open_connections++ == 0)
|
if (ssl_open_connections++ == 0)
|
||||||
{
|
{
|
||||||
/* This is actually libcrypto, not libssl. */
|
/* These are only required for threaded libcrypto applications */
|
||||||
/* These are only required for threaded SSL applications */
|
|
||||||
CRYPTO_set_id_callback(pq_threadidcallback);
|
CRYPTO_set_id_callback(pq_threadidcallback);
|
||||||
CRYPTO_set_locking_callback(pq_lockingcallback);
|
CRYPTO_set_locking_callback(pq_lockingcallback);
|
||||||
}
|
}
|
||||||
@ -913,9 +933,10 @@ init_ssl_system(PGconn *conn)
|
|||||||
/*
|
/*
|
||||||
* This function is needed because if the libpq library is unloaded
|
* This function is needed because if the libpq library is unloaded
|
||||||
* from the application, the callback functions will no longer exist when
|
* from the application, the callback functions will no longer exist when
|
||||||
* SSL used by other parts of the system. For this reason,
|
* libcrypto is used by other parts of the system. For this reason,
|
||||||
* we unregister the SSL callback functions when the last libpq
|
* we unregister the callback functions when the last libpq
|
||||||
* connection is closed.
|
* connection is closed. (The same would apply for OpenSSL callbacks
|
||||||
|
* if we had any.)
|
||||||
*
|
*
|
||||||
* Callbacks are only set when we're compiled in threadsafe mode, so
|
* Callbacks are only set when we're compiled in threadsafe mode, so
|
||||||
* we only need to remove them in this case.
|
* we only need to remove them in this case.
|
||||||
@ -928,28 +949,24 @@ destroy_ssl_system(void)
|
|||||||
if (pthread_mutex_lock(&ssl_config_mutex))
|
if (pthread_mutex_lock(&ssl_config_mutex))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (pq_init_ssl_lib)
|
if (pq_init_crypto_lib && ssl_open_connections > 0)
|
||||||
{
|
|
||||||
if (ssl_open_connections > 0)
|
|
||||||
--ssl_open_connections;
|
--ssl_open_connections;
|
||||||
|
|
||||||
if (ssl_open_connections == 0)
|
if (pq_init_crypto_lib && ssl_open_connections == 0)
|
||||||
{
|
{
|
||||||
/* This is actually libcrypto, not libssl. */
|
/* No connections left, unregister libcrypto callbacks */
|
||||||
/* No connections left, unregister all callbacks */
|
|
||||||
CRYPTO_set_locking_callback(NULL);
|
CRYPTO_set_locking_callback(NULL);
|
||||||
CRYPTO_set_id_callback(NULL);
|
CRYPTO_set_id_callback(NULL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We don't free the lock array. If we get another connection
|
* We don't free the lock array. If we get another connection
|
||||||
* from the same caller, we will just re-use it with the existing
|
* in this process, we will just re-use it with the existing
|
||||||
* mutexes.
|
* mutexes.
|
||||||
*
|
*
|
||||||
* This means we leak a little memory on repeated load/unload
|
* This means we leak a little memory on repeated load/unload
|
||||||
* of the library.
|
* of the library.
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
pthread_mutex_unlock(&ssl_config_mutex);
|
pthread_mutex_unlock(&ssl_config_mutex);
|
||||||
#endif
|
#endif
|
||||||
@ -995,8 +1012,6 @@ initialize_SSL(PGconn *conn)
|
|||||||
homedir[0] = '\0';
|
homedir[0] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (conn->sslrootcert)
|
if (conn->sslrootcert)
|
||||||
strncpy(fnbuf, conn->sslrootcert, sizeof(fnbuf));
|
strncpy(fnbuf, conn->sslrootcert, sizeof(fnbuf));
|
||||||
else
|
else
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/interfaces/libpq/libpq-fe.h,v 1.145 2009/01/01 17:24:03 momjian Exp $
|
* $PostgreSQL: pgsql/src/interfaces/libpq/libpq-fe.h,v 1.146 2009/03/31 01:41:27 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -302,6 +302,9 @@ extern void *PQgetssl(PGconn *conn);
|
|||||||
/* Tell libpq whether it needs to initialize OpenSSL */
|
/* Tell libpq whether it needs to initialize OpenSSL */
|
||||||
extern void PQinitSSL(int do_init);
|
extern void PQinitSSL(int do_init);
|
||||||
|
|
||||||
|
/* More detailed way to tell libpq whether it needs to initialize OpenSSL */
|
||||||
|
extern void PQinitOpenSSL(int do_ssl, int do_crypto);
|
||||||
|
|
||||||
/* Set verbosity for PQerrorMessage and PQresultErrorMessage */
|
/* Set verbosity for PQerrorMessage and PQresultErrorMessage */
|
||||||
extern PGVerbosity PQsetErrorVerbosity(PGconn *conn, PGVerbosity verbosity);
|
extern PGVerbosity PQsetErrorVerbosity(PGconn *conn, PGVerbosity verbosity);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user