142
141
#define RESTORE_SIGPIPE() \
143
142
pq_reset_sigpipe(&osigmask, sigpipe_pending, got_epipe)
145
#else /* !ENABLE_THREAD_SAFETY */
143
#else /* !ENABLE_THREAD_SAFETY */
147
145
#define DISABLE_SIGPIPE(failaction) \
148
146
pqsigfunc oldsighandler = pqsignal(SIGPIPE, SIG_IGN)
152
150
#define RESTORE_SIGPIPE() \
153
151
pqsignal(SIGPIPE, oldsighandler)
155
#endif /* ENABLE_THREAD_SAFETY */
152
#endif /* ENABLE_THREAD_SAFETY */
158
155
#define DISABLE_SIGPIPE(failaction)
159
156
#define REMEMBER_EPIPE(cond)
160
157
#define RESTORE_SIGPIPE()
164
160
/* ------------------------------------------------------------ */
165
161
/* Procedures common to all secure sessions */
180
176
* Exported function to allow application to tell us it's already
181
177
* initialized OpenSSL and/or libcrypto.
184
180
PQinitOpenSSL(int do_ssl, int do_crypto)
187
183
#ifdef ENABLE_THREAD_SAFETY
189
* Disallow changing the flags while we have open connections, else
190
* we'd get completely confused.
186
* Disallow changing the flags while we have open connections, else we'd
187
* get completely confused.
192
189
if (ssl_open_connections != 0)
473
470
* Check if a wildcard certificate matches the server hostname.
475
472
* The rule for this is:
476
* 1. We only match the '*' character as wildcard
477
* 2. We match only wildcards at the start of the string
478
* 3. The '*' character does *not* match '.', meaning that we match only
479
* a single pathname component.
480
* 4. We don't support more than one '*' in a single pattern.
473
* 1. We only match the '*' character as wildcard
474
* 2. We match only wildcards at the start of the string
475
* 3. The '*' character does *not* match '.', meaning that we match only
476
* a single pathname component.
477
* 4. We don't support more than one '*' in a single pattern.
482
479
* This is roughly in line with RFC2818, but contrary to what most browsers
483
480
* appear to be implementing (point 3 being the difference)
488
485
wildcard_certificate_match(const char *pattern, const char *string)
490
int lenpat = strlen(pattern);
491
int lenstr = strlen(string);
487
int lenpat = strlen(pattern);
488
int lenstr = strlen(string);
493
490
/* If we don't start with a wildcard, it's not a match (rule 1 & 2) */
494
491
if (lenpat < 3 ||
500
497
/* If pattern is longer than the string, we can never match */
503
if (pg_strcasecmp(pattern+1, string+lenstr-lenpat+1) != 0)
504
/* If string does not end in pattern (minus the wildcard), we don't match */
500
if (pg_strcasecmp(pattern + 1, string + lenstr - lenpat + 1) != 0)
503
* If string does not end in pattern (minus the wildcard), we don't
507
if (strchr(string, '.') < string+lenstr-lenpat)
508
/* If there is a dot left of where the pattern started to match, we don't match (rule 3) */
508
if (strchr(string, '.') < string + lenstr - lenpat)
511
* If there is a dot left of where the pattern started to match, we
512
* don't match (rule 3)
511
516
/* String ended with pattern, and didn't have a dot before, so we match */
520
525
verify_peer_name_matches_certificate(PGconn *conn)
523
* If told not to verify the peer name, don't do it. Return
524
* 0 indicating that the verification was successful.
528
* If told not to verify the peer name, don't do it. Return 0 indicating
529
* that the verification was successful.
526
531
if (strcmp(conn->sslmode, "verify-full") != 0)
653
* Read the SSL key. If a key is specified, treat it as an engine:key combination
654
* if there is colon present - we don't support files with colon in the name. The
655
* exception is if the second character is a colon, in which case it can be a Windows
656
* filename with drive specification.
658
* Read the SSL key. If a key is specified, treat it as an engine:key
659
* combination if there is colon present - we don't support files with
660
* colon in the name. The exception is if the second character is a colon,
661
* in which case it can be a Windows filename with drive specification.
658
663
if (conn->sslkey && strlen(conn->sslkey) > 0)
660
#if (SSLEAY_VERSION_NUMBER >= 0x00907000L) && !defined(OPENSSL_NO_ENGINE)
665
#ifdef USE_SSL_ENGINE
661
666
if (strchr(conn->sslkey, ':')
663
668
&& conn->sslkey[1] != ':'
667
672
/* Colon, but not in second character, treat as engine:key */
669
673
char *engine_str = strdup(conn->sslkey);
670
674
char *engine_colon = strchr(engine_str, ':');
672
*engine_colon = '\0'; /* engine_str now has engine name */
673
engine_colon++; /* engine_colon now has key name */
675
engine_ptr = ENGINE_by_id(engine_str);
676
if (engine_ptr == NULL)
678
char *err = SSLerrmessage();
680
printfPQExpBuffer(&conn->errorMessage,
681
libpq_gettext("could not load SSL engine \"%s\": %s\n"),
689
*pkey = ENGINE_load_private_key(engine_ptr, engine_colon,
676
*engine_colon = '\0'; /* engine_str now has engine name */
677
engine_colon++; /* engine_colon now has key name */
679
conn->engine = ENGINE_by_id(engine_str);
680
if (conn->engine == NULL)
682
char *err = SSLerrmessage();
684
printfPQExpBuffer(&conn->errorMessage,
685
libpq_gettext("could not load SSL engine \"%s\": %s\n"),
693
if (ENGINE_init(conn->engine) == 0)
695
char *err = SSLerrmessage();
697
printfPQExpBuffer(&conn->errorMessage,
698
libpq_gettext("could not initialize SSL engine \"%s\": %s\n"),
701
ENGINE_free(conn->engine);
708
*pkey = ENGINE_load_private_key(conn->engine, engine_colon,
691
710
if (*pkey == NULL)
696
715
libpq_gettext("could not read private SSL key \"%s\" from engine \"%s\": %s\n"),
697
716
engine_colon, engine_str, err);
718
ENGINE_finish(conn->engine);
719
ENGINE_free(conn->engine);
699
721
free(engine_str);
700
722
ERR_pop_to_mark();
703
725
free(engine_str);
705
fnbuf[0] = '\0'; /* indicate we're not going to load from a file */
727
fnbuf[0] = '\0'; /* indicate we're not going to load from a
708
#endif /* support for SSL engines */
731
#endif /* support for SSL engines */
710
733
/* PGSSLKEY is not an engine, treat it as a filename */
711
734
strncpy(fnbuf, conn->sslkey, sizeof(fnbuf));
733
756
if (!S_ISREG(buf.st_mode) || buf.st_mode & (S_IRWXG | S_IRWXO))
735
758
printfPQExpBuffer(&conn->errorMessage,
736
libpq_gettext("private key file \"%s\" has group or world access; permissions should be u=rw (0600) or less\n"),
759
libpq_gettext("private key file \"%s\" has group or world access; permissions should be u=rw (0600) or less\n"),
738
761
ERR_pop_to_mark();
959
982
CRYPTO_set_id_callback(NULL);
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
985
* We don't free the lock array. If we get another connection in this
986
* process, we will just re-use it with the existing mutexes.
966
* This means we leak a little memory on repeated load/unload
988
* This means we leak a little memory on repeated load/unload of the
991
1013
* verification. If set to "verify-full" we will also do further
992
1014
* verification after the connection has been completed.
994
* If we are going to look for either root certificate or CRL in the home directory,
995
* we need pqGetHomeDirectory() to succeed. In other cases, we don't need to
996
* get the home directory explicitly.
1016
* If we are going to look for either root certificate or CRL in the home
1017
* directory, we need pqGetHomeDirectory() to succeed. In other cases, we
1018
* don't need to get the home directory explicitly.
998
1020
if (!conn->sslrootcert || !conn->sslcrl)
1000
1022
if (!pqGetHomeDirectory(homedir, sizeof(homedir)))
1002
if (conn->sslmode[0] == 'v') /* "verify-ca" or "verify-full" */
1024
if (conn->sslmode[0] == 'v') /* "verify-ca" or
1004
1027
printfPQExpBuffer(&conn->errorMessage,
1005
1028
libpq_gettext("could not get home directory to locate root certificate file"));
1044
1067
/* OpenSSL 0.96 does not support X509_V_FLAG_CRL_CHECK */
1045
1068
#ifdef X509_V_FLAG_CRL_CHECK
1046
1069
X509_STORE_set_flags(cvstore,
1047
X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
1070
X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
1048
1071
/* if not found, silently ignore; we do not require CRL */
1066
1089
/* stat() failed; assume cert file doesn't exist */
1067
if (conn->sslmode[0] == 'v') /* "verify-ca" or "verify-full" */
1090
if (conn->sslmode[0] == 'v') /* "verify-ca" or "verify-full" */
1069
1092
printfPQExpBuffer(&conn->errorMessage,
1070
libpq_gettext("root certificate file \"%s\" does not exist\n"
1093
libpq_gettext("root certificate file \"%s\" does not exist\n"
1071
1094
"Either provide the file or change sslmode to disable server certificate verification.\n"), fnbuf);