summaryrefslogtreecommitdiffstats
path: root/src/interfaces/libpq
diff options
context:
space:
mode:
Diffstat (limited to 'src/interfaces/libpq')
-rw-r--r--src/interfaces/libpq/fe-connect.c16
-rw-r--r--src/interfaces/libpq/fe-misc.c39
-rw-r--r--src/interfaces/libpq/fe-secure-openssl.c45
-rw-r--r--src/interfaces/libpq/po/ru.po80
-rw-r--r--src/interfaces/libpq/pthread-win32.c26
5 files changed, 103 insertions, 103 deletions
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index a809013..47dcb37 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -7443,24 +7443,8 @@ static void
default_threadlock(int acquire)
{
#ifdef ENABLE_THREAD_SAFETY
-#ifndef WIN32
static pthread_mutex_t singlethread_lock = PTHREAD_MUTEX_INITIALIZER;
-#else
- static pthread_mutex_t singlethread_lock = NULL;
- static long mutex_initlock = 0;
- if (singlethread_lock == NULL)
- {
- while (InterlockedExchange(&mutex_initlock, 1) == 1)
- /* loop, another thread own the lock */ ;
- if (singlethread_lock == NULL)
- {
- if (pthread_mutex_init(&singlethread_lock, NULL))
- Assert(false);
- }
- InterlockedExchange(&mutex_initlock, 0);
- }
-#endif
if (acquire)
{
if (pthread_mutex_lock(&singlethread_lock))
diff --git a/src/interfaces/libpq/fe-misc.c b/src/interfaces/libpq/fe-misc.c
index d76bb39..128f056 100644
--- a/src/interfaces/libpq/fe-misc.c
+++ b/src/interfaces/libpq/fe-misc.c
@@ -1233,13 +1233,14 @@ static void
libpq_binddomain(void)
{
/*
- * If multiple threads come through here at about the same time, it's okay
- * for more than one of them to call bindtextdomain(). But it's not okay
- * for any of them to return to caller before bindtextdomain() is
- * complete, so don't set the flag till that's done. Use "volatile" just
- * to be sure the compiler doesn't try to get cute.
+ * At least on Windows, there are gettext implementations that fail if
+ * multiple threads call bindtextdomain() concurrently. Use a mutex and
+ * flag variable to ensure that we call it just once per process. It is
+ * not known that similar bugs exist on non-Windows platforms, but we
+ * might as well do it the same way everywhere.
*/
static volatile bool already_bound = false;
+ static pthread_mutex_t binddomain_mutex = PTHREAD_MUTEX_INITIALIZER;
if (!already_bound)
{
@@ -1249,14 +1250,26 @@ libpq_binddomain(void)
#else
int save_errno = errno;
#endif
- const char *ldir;
-
- /* No relocatable lookup here because the binary could be anywhere */
- ldir = getenv("PGLOCALEDIR");
- if (!ldir)
- ldir = LOCALEDIR;
- bindtextdomain(PG_TEXTDOMAIN("libpq"), ldir);
- already_bound = true;
+
+ (void) pthread_mutex_lock(&binddomain_mutex);
+
+ if (!already_bound)
+ {
+ const char *ldir;
+
+ /*
+ * No relocatable lookup here because the calling executable could
+ * be anywhere
+ */
+ ldir = getenv("PGLOCALEDIR");
+ if (!ldir)
+ ldir = LOCALEDIR;
+ bindtextdomain(PG_TEXTDOMAIN("libpq"), ldir);
+ already_bound = true;
+ }
+
+ (void) pthread_mutex_unlock(&binddomain_mutex);
+
#ifdef WIN32
SetLastError(save_errno);
#else
diff --git a/src/interfaces/libpq/fe-secure-openssl.c b/src/interfaces/libpq/fe-secure-openssl.c
index 61f3767..47c8e0b 100644
--- a/src/interfaces/libpq/fe-secure-openssl.c
+++ b/src/interfaces/libpq/fe-secure-openssl.c
@@ -96,12 +96,7 @@ static bool ssl_lib_initialized = false;
#ifdef ENABLE_THREAD_SAFETY
static long crypto_open_connections = 0;
-#ifndef WIN32
static pthread_mutex_t ssl_config_mutex = PTHREAD_MUTEX_INITIALIZER;
-#else
-static pthread_mutex_t ssl_config_mutex = NULL;
-static long win32_ssl_create_mutex = 0;
-#endif
#endif /* ENABLE_THREAD_SAFETY */
static PQsslKeyPassHook_OpenSSL_type PQsslKeyPassHook = NULL;
@@ -777,20 +772,6 @@ int
pgtls_init(PGconn *conn, bool do_ssl, bool do_crypto)
{
#ifdef ENABLE_THREAD_SAFETY
-#ifdef WIN32
- /* Also see similar code in fe-connect.c, default_threadlock() */
- if (ssl_config_mutex == NULL)
- {
- while (InterlockedExchange(&win32_ssl_create_mutex, 1) == 1)
- /* loop, another thread own the lock */ ;
- if (ssl_config_mutex == NULL)
- {
- if (pthread_mutex_init(&ssl_config_mutex, NULL))
- return -1;
- }
- InterlockedExchange(&win32_ssl_create_mutex, 0);
- }
-#endif
if (pthread_mutex_lock(&ssl_config_mutex))
return -1;
@@ -881,7 +862,6 @@ static void
destroy_ssl_system(void)
{
#if defined(ENABLE_THREAD_SAFETY) && defined(HAVE_CRYPTO_LOCK)
- /* Mutex is created in pgtls_init() */
if (pthread_mutex_lock(&ssl_config_mutex))
return;
@@ -929,7 +909,6 @@ initialize_SSL(PGconn *conn)
bool have_homedir;
bool have_cert;
bool have_rootcert;
- EVP_PKEY *pkey = NULL;
/*
* We'll need the home directory if any of the relevant parameters are
@@ -1265,6 +1244,7 @@ initialize_SSL(PGconn *conn)
/* Colon, but not in second character, treat as engine:key */
char *engine_str = strdup(conn->sslkey);
char *engine_colon;
+ EVP_PKEY *pkey;
if (engine_str == NULL)
{
@@ -1677,10 +1657,11 @@ pgtls_close(PGconn *conn)
* Obtain reason string for passed SSL errcode
*
* ERR_get_error() is used by caller to get errcode to pass here.
+ * The result must be freed after use, using SSLerrfree.
*
- * Some caution is needed here since ERR_reason_error_string will
- * return NULL if it doesn't recognize the error code. We don't
- * want to return NULL ever.
+ * Some caution is needed here since ERR_reason_error_string will return NULL
+ * if it doesn't recognize the error code, or (in OpenSSL >= 3) if the code
+ * represents a system errno value. We don't want to return NULL ever.
*/
static char ssl_nomem[] = "out of memory allocating error description";
@@ -1706,6 +1687,22 @@ SSLerrmessage(unsigned long ecode)
strlcpy(errbuf, errreason, SSL_ERR_LEN);
return errbuf;
}
+
+ /*
+ * In OpenSSL 3.0.0 and later, ERR_reason_error_string randomly refuses to
+ * map system errno values. We can cover that shortcoming with this bit
+ * of code. Older OpenSSL versions don't have the ERR_SYSTEM_ERROR macro,
+ * but that's okay because they don't have the shortcoming either.
+ */
+#ifdef ERR_SYSTEM_ERROR
+ if (ERR_SYSTEM_ERROR(ecode))
+ {
+ strlcpy(errbuf, strerror(ERR_GET_REASON(ecode)), SSL_ERR_LEN);
+ return errbuf;
+ }
+#endif
+
+ /* No choice but to report the numeric ecode */
snprintf(errbuf, SSL_ERR_LEN, libpq_gettext("SSL error code %lu"), ecode);
return errbuf;
}
diff --git a/src/interfaces/libpq/po/ru.po b/src/interfaces/libpq/po/ru.po
index 78affba..50925d0 100644
--- a/src/interfaces/libpq/po/ru.po
+++ b/src/interfaces/libpq/po/ru.po
@@ -10,7 +10,7 @@ msgid ""
msgstr ""
"Project-Id-Version: libpq (PostgreSQL current)\n"
"Report-Msgid-Bugs-To: pgsql-bugs@lists.postgresql.org\n"
-"POT-Creation-Date: 2024-02-02 18:11+0300\n"
+"POT-Creation-Date: 2024-05-04 10:36+0300\n"
"PO-Revision-Date: 2023-08-30 15:09+0300\n"
"Last-Translator: Alexander Lakhin <exclusion@gmail.com>\n"
"Language-Team: Russian <pgsql-ru-general@postgresql.org>\n"
@@ -81,7 +81,7 @@ msgstr "не удалось сгенерировать разовый код\n"
#: fe-exec.c:4139 fe-exec.c:4304 fe-gssapi-common.c:111 fe-lobj.c:884
#: fe-protocol3.c:968 fe-protocol3.c:983 fe-protocol3.c:1016
#: fe-protocol3.c:1724 fe-protocol3.c:2127 fe-secure-common.c:112
-#: fe-secure-gssapi.c:500 fe-secure-openssl.c:460 fe-secure-openssl.c:1272
+#: fe-secure-gssapi.c:500 fe-secure-openssl.c:455 fe-secure-openssl.c:1252
msgid "out of memory\n"
msgstr "нехватка памяти\n"
@@ -896,7 +896,7 @@ msgstr "функция pqPutInt не поддерживает integer разме
msgid "connection not open\n"
msgstr "соединение не открыто\n"
-#: fe-misc.c:755 fe-secure-openssl.c:218 fe-secure-openssl.c:331
+#: fe-misc.c:755 fe-secure-openssl.c:213 fe-secure-openssl.c:326
#: fe-secure.c:262 fe-secure.c:430
#, c-format
msgid ""
@@ -1123,81 +1123,81 @@ msgstr "ошибка проверки размера в GSSAPI"
msgid "GSSAPI context establishment error"
msgstr "ошибка установления контекста в GSSAPI"
-#: fe-secure-openssl.c:223 fe-secure-openssl.c:336 fe-secure-openssl.c:1512
+#: fe-secure-openssl.c:218 fe-secure-openssl.c:331 fe-secure-openssl.c:1492
#, c-format
msgid "SSL SYSCALL error: %s\n"
msgstr "ошибка SSL SYSCALL: %s\n"
-#: fe-secure-openssl.c:230 fe-secure-openssl.c:343 fe-secure-openssl.c:1516
+#: fe-secure-openssl.c:225 fe-secure-openssl.c:338 fe-secure-openssl.c:1496
msgid "SSL SYSCALL error: EOF detected\n"
msgstr "ошибка SSL SYSCALL: конец файла (EOF)\n"
-#: fe-secure-openssl.c:241 fe-secure-openssl.c:354 fe-secure-openssl.c:1525
+#: fe-secure-openssl.c:236 fe-secure-openssl.c:349 fe-secure-openssl.c:1505
#, c-format
msgid "SSL error: %s\n"
msgstr "ошибка SSL: %s\n"
-#: fe-secure-openssl.c:256 fe-secure-openssl.c:369
+#: fe-secure-openssl.c:251 fe-secure-openssl.c:364
msgid "SSL connection has been closed unexpectedly\n"
msgstr "SSL-соединение было неожиданно закрыто\n"
-#: fe-secure-openssl.c:262 fe-secure-openssl.c:375 fe-secure-openssl.c:1575
+#: fe-secure-openssl.c:257 fe-secure-openssl.c:370 fe-secure-openssl.c:1555
#, c-format
msgid "unrecognized SSL error code: %d\n"
msgstr "нераспознанный код ошибки SSL: %d\n"
-#: fe-secure-openssl.c:420
+#: fe-secure-openssl.c:415
msgid "could not determine server certificate signature algorithm\n"
msgstr "не удалось определить алгоритм подписи сертификата сервера\n"
-#: fe-secure-openssl.c:441
+#: fe-secure-openssl.c:436
#, c-format
msgid "could not find digest for NID %s\n"
msgstr "не удалось найти алгоритм хеширования по NID %s\n"
-#: fe-secure-openssl.c:451
+#: fe-secure-openssl.c:446
msgid "could not generate peer certificate hash\n"
msgstr "не удалось сгенерировать хеш сертификата сервера\n"
-#: fe-secure-openssl.c:508
+#: fe-secure-openssl.c:503
msgid "SSL certificate's name entry is missing\n"
msgstr "в SSL-сертификате отсутствует запись имени\n"
-#: fe-secure-openssl.c:543
+#: fe-secure-openssl.c:538
msgid "SSL certificate's address entry is missing\n"
msgstr "в SSL-сертификате отсутствует запись адреса\n"
-#: fe-secure-openssl.c:961
+#: fe-secure-openssl.c:940
#, c-format
msgid "could not create SSL context: %s\n"
msgstr "не удалось создать контекст SSL: %s\n"
-#: fe-secure-openssl.c:1000
+#: fe-secure-openssl.c:979
#, c-format
msgid "invalid value \"%s\" for minimum SSL protocol version\n"
msgstr "неверное значение \"%s\" для минимальной версии протокола SSL\n"
-#: fe-secure-openssl.c:1011
+#: fe-secure-openssl.c:990
#, c-format
msgid "could not set minimum SSL protocol version: %s\n"
msgstr "не удалось задать минимальную версию протокола SSL: %s\n"
-#: fe-secure-openssl.c:1029
+#: fe-secure-openssl.c:1008
#, c-format
msgid "invalid value \"%s\" for maximum SSL protocol version\n"
msgstr "неверное значение \"%s\" для максимальной версии протокола SSL\n"
-#: fe-secure-openssl.c:1040
+#: fe-secure-openssl.c:1019
#, c-format
msgid "could not set maximum SSL protocol version: %s\n"
msgstr "не удалось задать максимальную версию протокола SSL: %s\n"
-#: fe-secure-openssl.c:1076
+#: fe-secure-openssl.c:1055
#, c-format
msgid "could not read root certificate file \"%s\": %s\n"
msgstr "не удалось прочитать файл корневых сертификатов \"%s\": %s\n"
-#: fe-secure-openssl.c:1129
+#: fe-secure-openssl.c:1108
msgid ""
"could not get home directory to locate root certificate file\n"
"Either provide the file or change sslmode to disable server certificate "
@@ -1207,7 +1207,7 @@ msgstr ""
"Укажите полный путь к файлу или отключите проверку сертификата сервера, "
"изменив sslmode.\n"
-#: fe-secure-openssl.c:1133
+#: fe-secure-openssl.c:1112
#, c-format
msgid ""
"root certificate file \"%s\" does not exist\n"
@@ -1218,63 +1218,63 @@ msgstr ""
"Укажите полный путь к файлу или отключите проверку сертификата сервера, "
"изменив sslmode.\n"
-#: fe-secure-openssl.c:1164
+#: fe-secure-openssl.c:1143
#, c-format
msgid "could not open certificate file \"%s\": %s\n"
msgstr "не удалось открыть файл сертификата \"%s\": %s\n"
-#: fe-secure-openssl.c:1183
+#: fe-secure-openssl.c:1162
#, c-format
msgid "could not read certificate file \"%s\": %s\n"
msgstr "не удалось прочитать файл сертификата \"%s\": %s\n"
-#: fe-secure-openssl.c:1208
+#: fe-secure-openssl.c:1187
#, c-format
msgid "could not establish SSL connection: %s\n"
msgstr "не удалось установить SSL-соединение: %s\n"
-#: fe-secure-openssl.c:1242
+#: fe-secure-openssl.c:1221
#, c-format
msgid "could not set SSL Server Name Indication (SNI): %s\n"
msgstr ""
"не удалось задать SNI (Server Name Indication) для SSL-подключения: %s\n"
-#: fe-secure-openssl.c:1288
+#: fe-secure-openssl.c:1268
#, c-format
msgid "could not load SSL engine \"%s\": %s\n"
msgstr "не удалось загрузить модуль SSL ENGINE \"%s\": %s\n"
-#: fe-secure-openssl.c:1300
+#: fe-secure-openssl.c:1280
#, c-format
msgid "could not initialize SSL engine \"%s\": %s\n"
msgstr "не удалось инициализировать модуль SSL ENGINE \"%s\": %s\n"
-#: fe-secure-openssl.c:1316
+#: fe-secure-openssl.c:1296
#, c-format
msgid "could not read private SSL key \"%s\" from engine \"%s\": %s\n"
msgstr "не удалось прочитать закрытый ключ SSL \"%s\" из модуля \"%s\": %s\n"
-#: fe-secure-openssl.c:1330
+#: fe-secure-openssl.c:1310
#, c-format
msgid "could not load private SSL key \"%s\" from engine \"%s\": %s\n"
msgstr "не удалось загрузить закрытый ключ SSL \"%s\" из модуля \"%s\": %s\n"
-#: fe-secure-openssl.c:1368
+#: fe-secure-openssl.c:1348
#, c-format
msgid "certificate present, but not private key file \"%s\"\n"
msgstr "при наличии сертификата отсутствует файл закрытого ключа \"%s\"\n"
-#: fe-secure-openssl.c:1372
+#: fe-secure-openssl.c:1352
#, c-format
msgid "could not stat private key file \"%s\": %m\n"
msgstr "не удалось получить информацию о файле закрытого ключа \"%s\": %m\n"
-#: fe-secure-openssl.c:1381
+#: fe-secure-openssl.c:1361
#, c-format
msgid "private key file \"%s\" is not a regular file\n"
msgstr "файл закрытого ключа \"%s\" - не обычный файл\n"
-#: fe-secure-openssl.c:1414
+#: fe-secure-openssl.c:1394
#, c-format
msgid ""
"private key file \"%s\" has group or world access; file must have "
@@ -1286,17 +1286,17 @@ msgstr ""
"текущему пользователю, либо u=rw,g=r (0640) или более строгие, если он "
"принадлежит root\n"
-#: fe-secure-openssl.c:1439
+#: fe-secure-openssl.c:1419
#, c-format
msgid "could not load private key file \"%s\": %s\n"
msgstr "не удалось загрузить файл закрытого ключа \"%s\": %s\n"
-#: fe-secure-openssl.c:1456
+#: fe-secure-openssl.c:1436
#, c-format
msgid "certificate does not match private key file \"%s\": %s\n"
msgstr "сертификат не соответствует файлу закрытого ключа \"%s\": %s\n"
-#: fe-secure-openssl.c:1558
+#: fe-secure-openssl.c:1538
#, c-format
msgid ""
"This may indicate that the server does not support any SSL protocol version "
@@ -1305,22 +1305,22 @@ msgstr ""
"Это может указывать на то, что сервер не поддерживает ни одну версию "
"протокола SSL между %s и %s.\n"
-#: fe-secure-openssl.c:1594
+#: fe-secure-openssl.c:1574
#, c-format
msgid "certificate could not be obtained: %s\n"
msgstr "не удалось получить сертификат: %s\n"
-#: fe-secure-openssl.c:1700
+#: fe-secure-openssl.c:1681
#, c-format
msgid "no SSL error reported"
msgstr "нет сообщения об ошибке SSL"
-#: fe-secure-openssl.c:1709
+#: fe-secure-openssl.c:1706
#, c-format
msgid "SSL error code %lu"
msgstr "код ошибки SSL: %lu"
-#: fe-secure-openssl.c:1988
+#: fe-secure-openssl.c:1985
#, c-format
msgid "WARNING: sslpassword truncated\n"
msgstr "ПРЕДУПРЕЖДЕНИЕ: значение sslpassword усечено\n"
diff --git a/src/interfaces/libpq/pthread-win32.c b/src/interfaces/libpq/pthread-win32.c
index c0e056e..c9609c0 100644
--- a/src/interfaces/libpq/pthread-win32.c
+++ b/src/interfaces/libpq/pthread-win32.c
@@ -34,27 +34,33 @@ pthread_getspecific(pthread_key_t key)
int
pthread_mutex_init(pthread_mutex_t *mp, void *attr)
{
- *mp = (CRITICAL_SECTION *) malloc(sizeof(CRITICAL_SECTION));
- if (!*mp)
- return 1;
- InitializeCriticalSection(*mp);
+ mp->initstate = 0;
return 0;
}
int
pthread_mutex_lock(pthread_mutex_t *mp)
{
- if (!*mp)
- return 1;
- EnterCriticalSection(*mp);
+ /* Initialize the csection if not already done */
+ if (mp->initstate != 1)
+ {
+ LONG istate;
+
+ while ((istate = InterlockedExchange(&mp->initstate, 2)) == 2)
+ Sleep(0); /* wait, another thread is doing this */
+ if (istate != 1)
+ InitializeCriticalSection(&mp->csection);
+ InterlockedExchange(&mp->initstate, 1);
+ }
+ EnterCriticalSection(&mp->csection);
return 0;
}
int
pthread_mutex_unlock(pthread_mutex_t *mp)
{
- if (!*mp)
- return 1;
- LeaveCriticalSection(*mp);
+ if (mp->initstate != 1)
+ return EINVAL;
+ LeaveCriticalSection(&mp->csection);
return 0;
}