@@ -93,6 +93,12 @@ static void SSLerrfree(char *buf);
93
93
94
94
static bool pq_init_ssl_lib = true;
95
95
static bool pq_init_crypto_lib = true;
96
+
97
+ /*
98
+ * SSL_context is currently shared between threads and therefore we need to be
99
+ * careful to lock around any usage of it when providing thread safety.
100
+ * ssl_config_mutex is the mutex that we use to protect it.
101
+ */
96
102
static SSL_CTX * SSL_context = NULL ;
97
103
98
104
#ifdef ENABLE_THREAD_SAFETY
@@ -254,6 +260,10 @@ pqsecure_open_client(PGconn *conn)
254
260
/* We cannot use MSG_NOSIGNAL to block SIGPIPE when using SSL */
255
261
conn -> sigpipe_flag = false;
256
262
263
+ #ifdef ENABLE_THREAD_SAFETY
264
+ if (pthread_mutex_lock (& ssl_config_mutex ))
265
+ return -1 ;
266
+ #endif
257
267
/* Create a connection-specific SSL object */
258
268
if (!(conn -> ssl = SSL_new (SSL_context ))||
259
269
!SSL_set_app_data (conn -> ssl ,conn )||
@@ -266,9 +276,14 @@ pqsecure_open_client(PGconn *conn)
266
276
err );
267
277
SSLerrfree (err );
268
278
close_SSL (conn );
279
+ #ifdef ENABLE_THREAD_SAFETY
280
+ pthread_mutex_unlock (& ssl_config_mutex );
281
+ #endif
269
282
return PGRES_POLLING_FAILED ;
270
283
}
271
-
284
+ #ifdef ENABLE_THREAD_SAFETY
285
+ pthread_mutex_unlock (& ssl_config_mutex );
286
+ #endif
272
287
/*
273
288
* Load client certificate, private key, and trusted CA certs.
274
289
*/
@@ -998,8 +1013,9 @@ destroy_ssl_system(void)
998
1013
CRYPTO_set_id_callback (NULL );
999
1014
1000
1015
/*
1001
- * We don't free the lock array. If we get another connection in this
1002
- * process, we will just re-use it with the existing mutexes.
1016
+ * We don't free the lock array or the SSL_context. If we get another
1017
+ * connection in this process, we will just re-use them with the
1018
+ * existing mutexes.
1003
1019
*
1004
1020
* This means we leak a little memory on repeated load/unload of the
1005
1021
* library.
@@ -1088,7 +1104,15 @@ initialize_SSL(PGconn *conn)
1088
1104
* understands which subject cert to present, in case different
1089
1105
* sslcert settings are used for different connections in the same
1090
1106
* process.
1107
+ *
1108
+ * NOTE: This function may also modify our SSL_context and therefore
1109
+ * we have to lock around this call and any places where we use the
1110
+ * SSL_context struct.
1091
1111
*/
1112
+ #ifdef ENABLE_THREAD_SAFETY
1113
+ if (pthread_mutex_lock (& ssl_config_mutex ))
1114
+ return -1 ;
1115
+ #endif
1092
1116
if (SSL_CTX_use_certificate_chain_file (SSL_context ,fnbuf )!= 1 )
1093
1117
{
1094
1118
char * err = SSLerrmessage ();
@@ -1097,8 +1121,13 @@ initialize_SSL(PGconn *conn)
1097
1121
libpq_gettext ("could not read certificate file \"%s\": %s\n" ),
1098
1122
fnbuf ,err );
1099
1123
SSLerrfree (err );
1124
+
1125
+ #ifdef ENABLE_THREAD_SAFETY
1126
+ pthread_mutex_unlock (& ssl_config_mutex );
1127
+ #endif
1100
1128
return -1 ;
1101
1129
}
1130
+
1102
1131
if (SSL_use_certificate_file (conn -> ssl ,fnbuf ,SSL_FILETYPE_PEM )!= 1 )
1103
1132
{
1104
1133
char * err = SSLerrmessage ();
@@ -1107,10 +1136,18 @@ initialize_SSL(PGconn *conn)
1107
1136
libpq_gettext ("could not read certificate file \"%s\": %s\n" ),
1108
1137
fnbuf ,err );
1109
1138
SSLerrfree (err );
1139
+ #ifdef ENABLE_THREAD_SAFETY
1140
+ pthread_mutex_unlock (& ssl_config_mutex );
1141
+ #endif
1110
1142
return -1 ;
1111
1143
}
1144
+
1112
1145
/* need to load the associated private key, too */
1113
1146
have_cert = true;
1147
+
1148
+ #ifdef ENABLE_THREAD_SAFETY
1149
+ pthread_mutex_unlock (& ssl_config_mutex );
1150
+ #endif
1114
1151
}
1115
1152
1116
1153
/*
@@ -1286,6 +1323,10 @@ initialize_SSL(PGconn *conn)
1286
1323
{
1287
1324
X509_STORE * cvstore ;
1288
1325
1326
+ #ifdef ENABLE_THREAD_SAFETY
1327
+ if (pthread_mutex_lock (& ssl_config_mutex ))
1328
+ return -1 ;
1329
+ #endif
1289
1330
if (SSL_CTX_load_verify_locations (SSL_context ,fnbuf ,NULL )!= 1 )
1290
1331
{
1291
1332
char * err = SSLerrmessage ();
@@ -1294,6 +1335,9 @@ initialize_SSL(PGconn *conn)
1294
1335
libpq_gettext ("could not read root certificate file \"%s\": %s\n" ),
1295
1336
fnbuf ,err );
1296
1337
SSLerrfree (err );
1338
+ #ifdef ENABLE_THREAD_SAFETY
1339
+ pthread_mutex_unlock (& ssl_config_mutex );
1340
+ #endif
1297
1341
return -1 ;
1298
1342
}
1299
1343
@@ -1321,11 +1365,17 @@ initialize_SSL(PGconn *conn)
1321
1365
libpq_gettext ("SSL library does not support CRL certificates (file \"%s\")\n" ),
1322
1366
fnbuf );
1323
1367
SSLerrfree (err );
1368
+ #ifdef ENABLE_THREAD_SAFETY
1369
+ pthread_mutex_unlock (& ssl_config_mutex );
1370
+ #endif
1324
1371
return -1 ;
1325
1372
#endif
1326
1373
}
1327
1374
/* if not found, silently ignore; we do not require CRL */
1328
1375
}
1376
+ #ifdef ENABLE_THREAD_SAFETY
1377
+ pthread_mutex_unlock (& ssl_config_mutex );
1378
+ #endif
1329
1379
1330
1380
SSL_set_verify (conn -> ssl ,SSL_VERIFY_PEER ,verify_cb );
1331
1381
}