1111 *
1212 *
1313 * IDENTIFICATION
14- * $PostgreSQL: pgsql/src/interfaces/libpq/fe-secure.c,v 1.121 2009/03/28 18:48:55 momjian Exp $
14+ * $PostgreSQL: pgsql/src/interfaces/libpq/fe-secure.c,v 1.122 2009/03/31 01:41:27 tgl Exp $
1515 *
1616 * NOTES
1717 *
@@ -99,10 +99,11 @@ static char *SSLerrmessage(void);
9999static void SSLerrfree (char * buf );
100100
101101static bool pq_init_ssl_lib = true;
102+ static bool pq_init_crypto_lib = true;
102103static SSL_CTX * SSL_context = NULL ;
103104
104105#ifdef ENABLE_THREAD_SAFETY
105- static int ssl_open_connections = 0 ;
106+ static long ssl_open_connections = 0 ;
106107
107108#ifndef WIN32
108109static pthread_mutex_t ssl_config_mutex = PTHREAD_MUTEX_INITIALIZER ;
@@ -171,9 +172,29 @@ static long win32_ssl_create_mutex = 0;
171172 */
172173void
173174PQinitSSL (int do_init )
175+ {
176+ PQinitOpenSSL (do_init , do_init );
177+ }
178+
179+ /*
180+ * Exported function to allow application to tell us it's already
181+ * initialized OpenSSL and/or libcrypto.
182+ */
183+ void
184+ PQinitOpenSSL (int do_ssl , int do_crypto )
174185{
175186#ifdef USE_SSL
176- pq_init_ssl_lib = do_init ;
187+ #ifdef ENABLE_THREAD_SAFETY
188+ /*
189+ * Disallow changing the flags while we have open connections, else
190+ * we'd get completely confused.
191+ */
192+ if (ssl_open_connections != 0 )
193+ return ;
194+ #endif
195+
196+ pq_init_ssl_lib = do_ssl ;
197+ pq_init_crypto_lib = do_crypto ;
177198#endif
178199}
179200
@@ -810,10 +831,10 @@ pq_lockingcallback(int mode, int n, const char *file, int line)
810831
811832/*
812833 * Initialize SSL system. In threadsafe mode, this includes setting
813- * up OpenSSL callback functions to do thread locking.
834+ * up libcrypto callback functions to do thread locking.
814835 *
815- * If the caller has told us (through PQinitSSL ) that he's taking care
816- * of SSL , we expect that callbacks are already set, and won't try to
836+ * If the caller has told us (through PQinitOpenSSL ) that he's taking care
837+ * of libcrypto , we expect that callbacks are already set, and won't try to
817838 * override it.
818839 *
819840 * The conn parameter is only used to be able to pass back an error
@@ -840,11 +861,11 @@ init_ssl_system(PGconn *conn)
840861 if (pthread_mutex_lock (& ssl_config_mutex ))
841862 return -1 ;
842863
843- if (pq_init_ssl_lib )
864+ if (pq_init_crypto_lib )
844865 {
845866 /*
846- * If necessary, set up an array to hold locks for OpenSSL. OpenSSL will
847- * tell us how big to make this array.
867+ * If necessary, set up an array to hold locks for libcrypto.
868+ * libcrypto will tell us how big to make this array.
848869 */
849870 if (pq_lockarray == NULL )
850871 {
@@ -870,8 +891,7 @@ init_ssl_system(PGconn *conn)
870891
871892 if (ssl_open_connections ++ == 0 )
872893 {
873- /* This is actually libcrypto, not libssl. */
874- /* These are only required for threaded SSL applications */
894+ /* These are only required for threaded libcrypto applications */
875895 CRYPTO_set_id_callback (pq_threadidcallback );
876896 CRYPTO_set_locking_callback (pq_lockingcallback );
877897 }
@@ -913,9 +933,10 @@ init_ssl_system(PGconn *conn)
913933/*
914934 * This function is needed because if the libpq library is unloaded
915935 * from the application, the callback functions will no longer exist when
916- * SSL used by other parts of the system. For this reason,
917- * we unregister the SSL callback functions when the last libpq
918- * connection is closed.
936+ * libcrypto is used by other parts of the system. For this reason,
937+ * we unregister the callback functions when the last libpq
938+ * connection is closed. (The same would apply for OpenSSL callbacks
939+ * if we had any.)
919940 *
920941 * Callbacks are only set when we're compiled in threadsafe mode, so
921942 * we only need to remove them in this case.
@@ -928,27 +949,23 @@ destroy_ssl_system(void)
928949 if (pthread_mutex_lock (& ssl_config_mutex ))
929950 return ;
930951
931- if (pq_init_ssl_lib )
952+ if (pq_init_crypto_lib && ssl_open_connections > 0 )
953+ -- ssl_open_connections ;
954+
955+ if (pq_init_crypto_lib && ssl_open_connections == 0 )
932956 {
933- if (ssl_open_connections > 0 )
934- -- ssl_open_connections ;
957+ /* No connections left, unregister libcrypto callbacks */
958+ CRYPTO_set_locking_callback (NULL );
959+ CRYPTO_set_id_callback (NULL );
935960
936- if (ssl_open_connections == 0 )
937- {
938- /* This is actually libcrypto, not libssl. */
939- /* No connections left, unregister all callbacks */
940- CRYPTO_set_locking_callback (NULL );
941- CRYPTO_set_id_callback (NULL );
942-
943- /*
944- * We don't free the lock array. If we get another connection
945- * from the same caller, we will just re-use it with the existing
946- * mutexes.
947- *
948- * This means we leak a little memory on repeated load/unload
949- * of the library.
950- */
951- }
961+ /*
962+ * We don't free the lock array. If we get another connection
963+ * in this process, we will just re-use it with the existing
964+ * mutexes.
965+ *
966+ * This means we leak a little memory on repeated load/unload
967+ * of the library.
968+ */
952969 }
953970
954971 pthread_mutex_unlock (& ssl_config_mutex );
@@ -995,8 +1012,6 @@ initialize_SSL(PGconn *conn)
9951012 homedir [0 ] = '\0' ;
9961013 }
9971014
998-
999-
10001015 if (conn -> sslrootcert )
10011016 strncpy (fnbuf , conn -> sslrootcert , sizeof (fnbuf ));
10021017 else
0 commit comments