~ubuntu-branches/ubuntu/lucid/postgresql-8.4/lucid-proposed

« back to all changes in this revision

Viewing changes to src/interfaces/libpq/fe-secure.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2009-03-20 12:00:13 UTC
  • Revision ID: james.westby@ubuntu.com-20090320120013-hogj7egc5mjncc5g
Tags: upstream-8.4~0cvs20090328
ImportĀ upstreamĀ versionĀ 8.4~0cvs20090328

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*-------------------------------------------------------------------------
 
2
 *
 
3
 * fe-secure.c
 
4
 *        functions related to setting up a secure connection to the backend.
 
5
 *        Secure connections are expected to provide confidentiality,
 
6
 *        message integrity and endpoint authentication.
 
7
 *
 
8
 *
 
9
 * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
 
10
 * Portions Copyright (c) 1994, Regents of the University of California
 
11
 *
 
12
 *
 
13
 * IDENTIFICATION
 
14
 *        $PostgreSQL$
 
15
 *
 
16
 * NOTES
 
17
 *
 
18
 *        We don't provide informational callbacks here (like
 
19
 *        info_cb() in be-secure.c), since there's mechanism to
 
20
 *        display that information to the client.
 
21
 *
 
22
 *-------------------------------------------------------------------------
 
23
 */
 
24
 
 
25
#include "postgres_fe.h"
 
26
 
 
27
#include <signal.h>
 
28
#include <fcntl.h>
 
29
#include <ctype.h>
 
30
 
 
31
#include "libpq-fe.h"
 
32
#include "fe-auth.h"
 
33
#include "pqsignal.h"
 
34
 
 
35
#ifdef WIN32
 
36
#include "win32.h"
 
37
#else
 
38
#include <sys/socket.h>
 
39
#include <unistd.h>
 
40
#include <netdb.h>
 
41
#include <netinet/in.h>
 
42
#ifdef HAVE_NETINET_TCP_H
 
43
#include <netinet/tcp.h>
 
44
#endif
 
45
#include <arpa/inet.h>
 
46
#endif
 
47
 
 
48
#include <sys/stat.h>
 
49
 
 
50
#ifdef ENABLE_THREAD_SAFETY
 
51
#ifdef WIN32
 
52
#include "pthread-win32.h"
 
53
#else
 
54
#include <pthread.h>
 
55
#endif
 
56
#endif
 
57
 
 
58
#ifdef USE_SSL
 
59
 
 
60
#include <openssl/ssl.h>
 
61
#include <openssl/bio.h>
 
62
#if (SSLEAY_VERSION_NUMBER >= 0x00907000L)
 
63
#include <openssl/conf.h>
 
64
#endif
 
65
#if (SSLEAY_VERSION_NUMBER >= 0x00907000L) && !defined(OPENSSL_NO_ENGINE)
 
66
#include <openssl/engine.h>
 
67
#endif
 
68
 
 
69
 
 
70
#ifndef WIN32
 
71
#define USER_CERT_FILE          ".postgresql/postgresql.crt"
 
72
#define USER_KEY_FILE           ".postgresql/postgresql.key"
 
73
#define ROOT_CERT_FILE          ".postgresql/root.crt"
 
74
#define ROOT_CRL_FILE           ".postgresql/root.crl"
 
75
#else
 
76
/* On Windows, the "home" directory is already PostgreSQL-specific */
 
77
#define USER_CERT_FILE          "postgresql.crt"
 
78
#define USER_KEY_FILE           "postgresql.key"
 
79
#define ROOT_CERT_FILE          "root.crt"
 
80
#define ROOT_CRL_FILE           "root.crl"
 
81
#endif
 
82
 
 
83
#ifndef HAVE_ERR_SET_MARK
 
84
/* These don't exist in OpenSSL before 0.9.8 */
 
85
#define ERR_set_mark()          ((void) 0)
 
86
#define ERR_pop_to_mark()       ((void) 0)
 
87
#endif
 
88
 
 
89
static bool verify_peer_name_matches_certificate(PGconn *);
 
90
static int      verify_cb(int ok, X509_STORE_CTX *ctx);
 
91
static int      client_cert_cb(SSL *, X509 **, EVP_PKEY **);
 
92
static int      init_ssl_system(PGconn *conn);
 
93
static void destroy_ssl_system(void);
 
94
static int      initialize_SSL(PGconn *);
 
95
static void destroySSL(void);
 
96
static PostgresPollingStatusType open_client_SSL(PGconn *);
 
97
static void close_SSL(PGconn *);
 
98
static char *SSLerrmessage(void);
 
99
static void SSLerrfree(char *buf);
 
100
 
 
101
static bool pq_init_ssl_lib = true;
 
102
static SSL_CTX *SSL_context = NULL;
 
103
 
 
104
#ifdef ENABLE_THREAD_SAFETY
 
105
static int ssl_open_connections = 0;
 
106
 
 
107
#ifndef WIN32
 
108
static pthread_mutex_t ssl_config_mutex = PTHREAD_MUTEX_INITIALIZER;
 
109
#else
 
110
static pthread_mutex_t ssl_config_mutex = NULL;
 
111
static long win32_ssl_create_mutex = 0;
 
112
#endif
 
113
 
 
114
#endif  /* ENABLE_THREAD_SAFETY */
 
115
 
 
116
#endif /* SSL */
 
117
 
 
118
 
 
119
/*
 
120
 * Macros to handle disabling and then restoring the state of SIGPIPE handling.
 
121
 * Note that DISABLE_SIGPIPE() must appear at the start of a block.
 
122
 */
 
123
 
 
124
#ifndef WIN32
 
125
#ifdef ENABLE_THREAD_SAFETY
 
126
 
 
127
#define DISABLE_SIGPIPE(failaction) \
 
128
        sigset_t        osigmask; \
 
129
        bool            sigpipe_pending; \
 
130
        bool            got_epipe = false; \
 
131
\
 
132
        if (pq_block_sigpipe(&osigmask, &sigpipe_pending) < 0) \
 
133
                failaction
 
134
 
 
135
#define REMEMBER_EPIPE(cond) \
 
136
        do { \
 
137
                if (cond) \
 
138
                        got_epipe = true; \
 
139
        } while (0)
 
140
 
 
141
#define RESTORE_SIGPIPE() \
 
142
        pq_reset_sigpipe(&osigmask, sigpipe_pending, got_epipe)
 
143
 
 
144
#else   /* !ENABLE_THREAD_SAFETY */
 
145
 
 
146
#define DISABLE_SIGPIPE(failaction) \
 
147
        pqsigfunc       oldsighandler = pqsignal(SIGPIPE, SIG_IGN)
 
148
 
 
149
#define REMEMBER_EPIPE(cond)
 
150
 
 
151
#define RESTORE_SIGPIPE() \
 
152
        pqsignal(SIGPIPE, oldsighandler)
 
153
 
 
154
#endif  /* ENABLE_THREAD_SAFETY */
 
155
#else   /* WIN32 */
 
156
 
 
157
#define DISABLE_SIGPIPE(failaction)
 
158
#define REMEMBER_EPIPE(cond)
 
159
#define RESTORE_SIGPIPE()
 
160
 
 
161
#endif  /* WIN32 */
 
162
 
 
163
/* ------------------------------------------------------------ */
 
164
/*                       Procedures common to all secure sessions                       */
 
165
/* ------------------------------------------------------------ */
 
166
 
 
167
 
 
168
/*
 
169
 *      Exported function to allow application to tell us it's already
 
170
 *      initialized OpenSSL.
 
171
 */
 
172
void
 
173
PQinitSSL(int do_init)
 
174
{
 
175
#ifdef USE_SSL
 
176
        pq_init_ssl_lib = do_init;
 
177
#endif
 
178
}
 
179
 
 
180
/*
 
181
 *      Initialize global context
 
182
 */
 
183
int
 
184
pqsecure_initialize(PGconn *conn)
 
185
{
 
186
        int                     r = 0;
 
187
 
 
188
#ifdef USE_SSL
 
189
        r = initialize_SSL(conn);
 
190
#endif
 
191
 
 
192
        return r;
 
193
}
 
194
 
 
195
/*
 
196
 *      Destroy global context
 
197
 */
 
198
void
 
199
pqsecure_destroy(void)
 
200
{
 
201
#ifdef USE_SSL
 
202
        destroySSL();
 
203
#endif
 
204
}
 
205
 
 
206
/*
 
207
 *      Attempt to negotiate secure session.
 
208
 */
 
209
PostgresPollingStatusType
 
210
pqsecure_open_client(PGconn *conn)
 
211
{
 
212
#ifdef USE_SSL
 
213
        /* First time through? */
 
214
        if (conn->ssl == NULL)
 
215
        {
 
216
                if (!(conn->ssl = SSL_new(SSL_context)) ||
 
217
                        !SSL_set_app_data(conn->ssl, conn) ||
 
218
                        !SSL_set_fd(conn->ssl, conn->sock))
 
219
                {
 
220
                        char       *err = SSLerrmessage();
 
221
 
 
222
                        printfPQExpBuffer(&conn->errorMessage,
 
223
                                   libpq_gettext("could not establish SSL connection: %s\n"),
 
224
                                                          err);
 
225
                        SSLerrfree(err);
 
226
                        close_SSL(conn);
 
227
                        return PGRES_POLLING_FAILED;
 
228
                }
 
229
 
 
230
                /*
 
231
                 * Initialize errorMessage to empty.  This allows open_client_SSL() to
 
232
                 * detect whether client_cert_cb() has stored a message.
 
233
                 */
 
234
                resetPQExpBuffer(&conn->errorMessage);
 
235
        }
 
236
        /* Begin or continue the actual handshake */
 
237
        return open_client_SSL(conn);
 
238
#else
 
239
        /* shouldn't get here */
 
240
        return PGRES_POLLING_FAILED;
 
241
#endif
 
242
}
 
243
 
 
244
/*
 
245
 *      Close secure session.
 
246
 */
 
247
void
 
248
pqsecure_close(PGconn *conn)
 
249
{
 
250
#ifdef USE_SSL
 
251
        if (conn->ssl)
 
252
                close_SSL(conn);
 
253
#endif
 
254
}
 
255
 
 
256
/*
 
257
 *      Read data from a secure connection.
 
258
 */
 
259
ssize_t
 
260
pqsecure_read(PGconn *conn, void *ptr, size_t len)
 
261
{
 
262
        ssize_t         n;
 
263
 
 
264
#ifdef USE_SSL
 
265
        if (conn->ssl)
 
266
        {
 
267
                int                     err;
 
268
 
 
269
                /* SSL_read can write to the socket, so we need to disable SIGPIPE */
 
270
                DISABLE_SIGPIPE(return -1);
 
271
 
 
272
rloop:
 
273
                n = SSL_read(conn->ssl, ptr, len);
 
274
                err = SSL_get_error(conn->ssl, n);
 
275
                switch (err)
 
276
                {
 
277
                        case SSL_ERROR_NONE:
 
278
                                break;
 
279
                        case SSL_ERROR_WANT_READ:
 
280
                                n = 0;
 
281
                                break;
 
282
                        case SSL_ERROR_WANT_WRITE:
 
283
 
 
284
                                /*
 
285
                                 * Returning 0 here would cause caller to wait for read-ready,
 
286
                                 * which is not correct since what SSL wants is wait for
 
287
                                 * write-ready.  The former could get us stuck in an infinite
 
288
                                 * wait, so don't risk it; busy-loop instead.
 
289
                                 */
 
290
                                goto rloop;
 
291
                        case SSL_ERROR_SYSCALL:
 
292
                                {
 
293
                                        char            sebuf[256];
 
294
 
 
295
                                        if (n == -1)
 
296
                                        {
 
297
                                                REMEMBER_EPIPE(SOCK_ERRNO == EPIPE);
 
298
                                                printfPQExpBuffer(&conn->errorMessage,
 
299
                                                                        libpq_gettext("SSL SYSCALL error: %s\n"),
 
300
                                                        SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
 
301
                                        }
 
302
                                        else
 
303
                                        {
 
304
                                                printfPQExpBuffer(&conn->errorMessage,
 
305
                                                 libpq_gettext("SSL SYSCALL error: EOF detected\n"));
 
306
 
 
307
                                                SOCK_ERRNO_SET(ECONNRESET);
 
308
                                                n = -1;
 
309
                                        }
 
310
                                        break;
 
311
                                }
 
312
                        case SSL_ERROR_SSL:
 
313
                                {
 
314
                                        char       *err = SSLerrmessage();
 
315
 
 
316
                                        printfPQExpBuffer(&conn->errorMessage,
 
317
                                                                          libpq_gettext("SSL error: %s\n"), err);
 
318
                                        SSLerrfree(err);
 
319
                                }
 
320
                                /* fall through */
 
321
                        case SSL_ERROR_ZERO_RETURN:
 
322
                                SOCK_ERRNO_SET(ECONNRESET);
 
323
                                n = -1;
 
324
                                break;
 
325
                        default:
 
326
                                printfPQExpBuffer(&conn->errorMessage,
 
327
                                                  libpq_gettext("unrecognized SSL error code: %d\n"),
 
328
                                                                  err);
 
329
                                n = -1;
 
330
                                break;
 
331
                }
 
332
 
 
333
                RESTORE_SIGPIPE();
 
334
        }
 
335
        else
 
336
#endif
 
337
                n = recv(conn->sock, ptr, len, 0);
 
338
 
 
339
        return n;
 
340
}
 
341
 
 
342
/*
 
343
 *      Write data to a secure connection.
 
344
 */
 
345
ssize_t
 
346
pqsecure_write(PGconn *conn, const void *ptr, size_t len)
 
347
{
 
348
        ssize_t         n;
 
349
 
 
350
        DISABLE_SIGPIPE(return -1);
 
351
 
 
352
#ifdef USE_SSL
 
353
        if (conn->ssl)
 
354
        {
 
355
                int                     err;
 
356
 
 
357
                n = SSL_write(conn->ssl, ptr, len);
 
358
                err = SSL_get_error(conn->ssl, n);
 
359
                switch (err)
 
360
                {
 
361
                        case SSL_ERROR_NONE:
 
362
                                break;
 
363
                        case SSL_ERROR_WANT_READ:
 
364
 
 
365
                                /*
 
366
                                 * Returning 0 here causes caller to wait for write-ready,
 
367
                                 * which is not really the right thing, but it's the best we
 
368
                                 * can do.
 
369
                                 */
 
370
                                n = 0;
 
371
                                break;
 
372
                        case SSL_ERROR_WANT_WRITE:
 
373
                                n = 0;
 
374
                                break;
 
375
                        case SSL_ERROR_SYSCALL:
 
376
                                {
 
377
                                        char            sebuf[256];
 
378
 
 
379
                                        if (n == -1)
 
380
                                        {
 
381
                                                REMEMBER_EPIPE(SOCK_ERRNO == EPIPE);
 
382
                                                printfPQExpBuffer(&conn->errorMessage,
 
383
                                                                        libpq_gettext("SSL SYSCALL error: %s\n"),
 
384
                                                        SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
 
385
                                        }
 
386
                                        else
 
387
                                        {
 
388
                                                printfPQExpBuffer(&conn->errorMessage,
 
389
                                                 libpq_gettext("SSL SYSCALL error: EOF detected\n"));
 
390
                                                SOCK_ERRNO_SET(ECONNRESET);
 
391
                                                n = -1;
 
392
                                        }
 
393
                                        break;
 
394
                                }
 
395
                        case SSL_ERROR_SSL:
 
396
                                {
 
397
                                        char       *err = SSLerrmessage();
 
398
 
 
399
                                        printfPQExpBuffer(&conn->errorMessage,
 
400
                                                                          libpq_gettext("SSL error: %s\n"), err);
 
401
                                        SSLerrfree(err);
 
402
                                }
 
403
                                /* fall through */
 
404
                        case SSL_ERROR_ZERO_RETURN:
 
405
                                SOCK_ERRNO_SET(ECONNRESET);
 
406
                                n = -1;
 
407
                                break;
 
408
                        default:
 
409
                                printfPQExpBuffer(&conn->errorMessage,
 
410
                                                  libpq_gettext("unrecognized SSL error code: %d\n"),
 
411
                                                                  err);
 
412
                                n = -1;
 
413
                                break;
 
414
                }
 
415
        }
 
416
        else
 
417
#endif
 
418
        {
 
419
                n = send(conn->sock, ptr, len, 0);
 
420
                REMEMBER_EPIPE(n < 0 && SOCK_ERRNO == EPIPE);
 
421
        }
 
422
 
 
423
        RESTORE_SIGPIPE();
 
424
 
 
425
        return n;
 
426
}
 
427
 
 
428
/* ------------------------------------------------------------ */
 
429
/*                                                SSL specific code                                             */
 
430
/* ------------------------------------------------------------ */
 
431
#ifdef USE_SSL
 
432
 
 
433
/*
 
434
 *      Certificate verification callback
 
435
 *
 
436
 *      This callback allows us to log intermediate problems during
 
437
 *      verification, but there doesn't seem to be a clean way to get
 
438
 *      our PGconn * structure.  So we can't log anything!
 
439
 *
 
440
 *      This callback also allows us to override the default acceptance
 
441
 *      criteria (e.g., accepting self-signed or expired certs), but
 
442
 *      for now we accept the default checks.
 
443
 */
 
444
static int
 
445
verify_cb(int ok, X509_STORE_CTX *ctx)
 
446
{
 
447
        return ok;
 
448
}
 
449
 
 
450
 
 
451
/*
 
452
 * Check if a wildcard certificate matches the server hostname.
 
453
 *
 
454
 * The rule for this is:
 
455
 *  1. We only match the '*' character as wildcard
 
456
 *  2. We match only wildcards at the start of the string
 
457
 *  3. The '*' character does *not* match '.', meaning that we match only
 
458
 *     a single pathname component.
 
459
 *  4. We don't support more than one '*' in a single pattern.
 
460
 *
 
461
 * This is roughly in line with RFC2818, but contrary to what most browsers
 
462
 * appear to be implementing (point 3 being the difference)
 
463
 *
 
464
 * Matching is always cone case-insensitive, since DNS is case insensitive.
 
465
 */
 
466
static int
 
467
wildcard_certificate_match(const char *pattern, const char *string)
 
468
{
 
469
        int lenpat = strlen(pattern);
 
470
        int lenstr = strlen(string);
 
471
 
 
472
        /* If we don't start with a wildcard, it's not a match (rule 1 & 2) */
 
473
        if (lenpat < 3 ||
 
474
                pattern[0] != '*' ||
 
475
                pattern[1] != '.')
 
476
                return 0;
 
477
 
 
478
        if (lenpat > lenstr)
 
479
                /* If pattern is longer than the string, we can never match */
 
480
                return 0;
 
481
 
 
482
        if (pg_strcasecmp(pattern+1, string+lenstr-lenpat+1) != 0)
 
483
                /* If string does not end in pattern (minus the wildcard), we don't match */
 
484
                return 0;
 
485
 
 
486
        if (strchr(string, '.') < string+lenstr-lenpat)
 
487
                /* If there is a dot left of where the pattern started to match, we don't match (rule 3) */
 
488
                return 0;
 
489
 
 
490
        /* String ended with pattern, and didn't have a dot before, so we match */
 
491
        return 1;
 
492
}
 
493
 
 
494
 
 
495
/*
 
496
 *      Verify that common name resolves to peer.
 
497
 */
 
498
static bool
 
499
verify_peer_name_matches_certificate(PGconn *conn)
 
500
{
 
501
        /*
 
502
         * If told not to verify the peer name, don't do it. Return
 
503
         * 0 indicating that the verification was successful.
 
504
         */
 
505
        if(strcmp(conn->sslverify, "cn") != 0)
 
506
                return true;
 
507
 
 
508
        if (conn->pghostaddr)
 
509
        {
 
510
                printfPQExpBuffer(&conn->errorMessage,
 
511
                                                  libpq_gettext("verified SSL connections are only supported when connecting to a host name"));
 
512
                return false;
 
513
        }
 
514
        else
 
515
        {
 
516
                /*
 
517
                 * Connect by hostname.
 
518
                 *
 
519
                 * XXX: Should support alternate names here
 
520
                 */
 
521
                if (pg_strcasecmp(conn->peer_cn, conn->pghost) == 0)
 
522
                        /* Exact name match */
 
523
                        return true;
 
524
                else if (wildcard_certificate_match(conn->peer_cn, conn->pghost))
 
525
                        /* Matched wildcard certificate */
 
526
                        return true;
 
527
                else
 
528
                {
 
529
                        printfPQExpBuffer(&conn->errorMessage,
 
530
                                                          libpq_gettext("server common name \"%s\" does not match host name \"%s\""),
 
531
                                                          conn->peer_cn, conn->pghost);
 
532
                        return false;
 
533
                }
 
534
        }
 
535
}
 
536
 
 
537
/*
 
538
 *      Callback used by SSL to load client cert and key.
 
539
 *      This callback is only called when the server wants a
 
540
 *      client cert.
 
541
 *
 
542
 *      Since BIO functions can set OpenSSL error codes, we must
 
543
 *      reset the OpenSSL error stack on *every* exit from this
 
544
 *      function once we've started using BIO.
 
545
 *
 
546
 *      Must return 1 on success, 0 on no data or error.
 
547
 */
 
548
static int
 
549
client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
 
550
{
 
551
        char            homedir[MAXPGPATH];
 
552
        struct stat buf;
 
553
 
 
554
#ifndef WIN32
 
555
        struct stat buf2;
 
556
        FILE       *fp;
 
557
#endif
 
558
        char            fnbuf[MAXPGPATH];
 
559
        BIO                *bio;
 
560
        PGconn     *conn = (PGconn *) SSL_get_app_data(ssl);
 
561
        char            sebuf[256];
 
562
 
 
563
        /*
 
564
         * If conn->sslcert  or conn->sslkey is not set, we don't need the home
 
565
         * directory to find the required files.
 
566
         */
 
567
        if (!conn->sslcert || !conn->sslkey)
 
568
        {
 
569
                if (!pqGetHomeDirectory(homedir, sizeof(homedir)))
 
570
                {
 
571
                        printfPQExpBuffer(&conn->errorMessage,
 
572
                                                          libpq_gettext("could not get home directory to locate client certificate files"));
 
573
                        return 0;
 
574
                }
 
575
        }
 
576
 
 
577
        /* read the user certificate */
 
578
        if (conn->sslcert)
 
579
                strncpy(fnbuf, conn->sslcert, sizeof(fnbuf));
 
580
        else
 
581
                snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, USER_CERT_FILE);
 
582
 
 
583
        /*
 
584
         * OpenSSL <= 0.9.8 lacks error stack handling, which means it's likely to
 
585
         * report wrong error messages if access to the cert file fails. Do our
 
586
         * own check for the readability of the file to catch the majority of such
 
587
         * problems before OpenSSL gets involved.
 
588
         */
 
589
#ifndef HAVE_ERR_SET_MARK
 
590
        {
 
591
                FILE       *fp2;
 
592
 
 
593
                if ((fp2 = fopen(fnbuf, "r")) == NULL)
 
594
                {
 
595
                        printfPQExpBuffer(&conn->errorMessage,
 
596
                           libpq_gettext("could not open certificate file \"%s\": %s\n"),
 
597
                                                          fnbuf, pqStrerror(errno, sebuf, sizeof(sebuf)));
 
598
                        return 0;
 
599
                }
 
600
                fclose(fp2);
 
601
        }
 
602
#endif
 
603
 
 
604
        /* save OpenSSL error stack */
 
605
        ERR_set_mark();
 
606
 
 
607
        if ((bio = BIO_new_file(fnbuf, "r")) == NULL)
 
608
        {
 
609
                printfPQExpBuffer(&conn->errorMessage,
 
610
                           libpq_gettext("could not open certificate file \"%s\": %s\n"),
 
611
                                                  fnbuf, pqStrerror(errno, sebuf, sizeof(sebuf)));
 
612
                ERR_pop_to_mark();
 
613
                return 0;
 
614
        }
 
615
 
 
616
        if (PEM_read_bio_X509(bio, x509, NULL, NULL) == NULL)
 
617
        {
 
618
                char       *err = SSLerrmessage();
 
619
 
 
620
                printfPQExpBuffer(&conn->errorMessage,
 
621
                           libpq_gettext("could not read certificate file \"%s\": %s\n"),
 
622
                                                  fnbuf, err);
 
623
                SSLerrfree(err);
 
624
                BIO_free(bio);
 
625
                ERR_pop_to_mark();
 
626
                return 0;
 
627
        }
 
628
 
 
629
        BIO_free(bio);
 
630
 
 
631
        /*
 
632
         * Read the SSL key. If a key is specified, treat it as an engine:key combination
 
633
         * if there is colon present - we don't support files with colon in the name. The
 
634
         * exception is if the second character is a colon, in which case it can be a Windows
 
635
         * filename with drive specification.
 
636
         */
 
637
        if (conn->sslkey && strlen(conn->sslkey) > 0)
 
638
        {
 
639
#if (SSLEAY_VERSION_NUMBER >= 0x00907000L) && !defined(OPENSSL_NO_ENGINE)
 
640
                if (strchr(conn->sslkey, ':')
 
641
#ifdef WIN32
 
642
                        && conn->sslkey[1] != ':'
 
643
#endif
 
644
                   )
 
645
                {
 
646
                        /* Colon, but not in second character, treat as engine:key */
 
647
                        ENGINE     *engine_ptr;
 
648
                        char       *engine_str = strdup(conn->sslkey);
 
649
                        char       *engine_colon = strchr(engine_str, ':');
 
650
 
 
651
                        *engine_colon = '\0';   /* engine_str now has engine name */
 
652
                        engine_colon++;                 /* engine_colon now has key name */
 
653
 
 
654
                        engine_ptr = ENGINE_by_id(engine_str);
 
655
                        if (engine_ptr == NULL)
 
656
                        {
 
657
                                char       *err = SSLerrmessage();
 
658
 
 
659
                                printfPQExpBuffer(&conn->errorMessage,
 
660
                                                                  libpq_gettext("could not load SSL engine \"%s\": %s\n"),
 
661
                                                                  engine_str, err);
 
662
                                SSLerrfree(err);
 
663
                                free(engine_str);
 
664
                                ERR_pop_to_mark();
 
665
                                return 0;
 
666
                        }
 
667
 
 
668
                        *pkey = ENGINE_load_private_key(engine_ptr, engine_colon,
 
669
                                                                                        NULL, NULL);
 
670
                        if (*pkey == NULL)
 
671
                        {
 
672
                                char       *err = SSLerrmessage();
 
673
 
 
674
                                printfPQExpBuffer(&conn->errorMessage,
 
675
                                                                  libpq_gettext("could not read private SSL key \"%s\" from engine \"%s\": %s\n"),
 
676
                                                                  engine_colon, engine_str, err);
 
677
                                SSLerrfree(err);
 
678
                                free(engine_str);
 
679
                                ERR_pop_to_mark();
 
680
                                return 0;
 
681
                        }
 
682
                        free(engine_str);
 
683
 
 
684
                        fnbuf[0] = '\0'; /* indicate we're not going to load from a file */
 
685
                }
 
686
                else
 
687
#endif /* support for SSL engines */
 
688
                {
 
689
                        /* PGSSLKEY is not an engine, treat it as a filename */
 
690
                        strncpy(fnbuf, conn->sslkey, sizeof(fnbuf));
 
691
                }
 
692
        }
 
693
        else
 
694
        {
 
695
                /* No PGSSLKEY specified, load default file */
 
696
                snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, USER_KEY_FILE);
 
697
        }
 
698
 
 
699
        if (fnbuf[0] != '\0')
 
700
        {
 
701
                /* read the user key from file */
 
702
 
 
703
                if (stat(fnbuf, &buf) != 0)
 
704
                {
 
705
                        printfPQExpBuffer(&conn->errorMessage,
 
706
                                                          libpq_gettext("certificate present, but not private key file \"%s\"\n"),
 
707
                                                          fnbuf);
 
708
                        ERR_pop_to_mark();
 
709
                        return 0;
 
710
                }
 
711
#ifndef WIN32
 
712
                if (!S_ISREG(buf.st_mode) || buf.st_mode & (S_IRWXG | S_IRWXO))
 
713
                {
 
714
                        printfPQExpBuffer(&conn->errorMessage,
 
715
                        libpq_gettext("private key file \"%s\" has group or world access; permissions should be u=rw (0600) or less\n"),
 
716
                                                          fnbuf);
 
717
                        ERR_pop_to_mark();
 
718
                        return 0;
 
719
                }
 
720
#endif
 
721
 
 
722
                if ((bio = BIO_new_file(fnbuf, "r")) == NULL)
 
723
                {
 
724
                        printfPQExpBuffer(&conn->errorMessage,
 
725
                           libpq_gettext("could not open private key file \"%s\": %s\n"),
 
726
                                                          fnbuf, pqStrerror(errno, sebuf, sizeof(sebuf)));
 
727
                        ERR_pop_to_mark();
 
728
                        return 0;
 
729
                }
 
730
#ifndef WIN32
 
731
                BIO_get_fp(bio, &fp);
 
732
                if (fstat(fileno(fp), &buf2) == -1 ||
 
733
                        buf.st_dev != buf2.st_dev || buf.st_ino != buf2.st_ino)
 
734
                {
 
735
                        printfPQExpBuffer(&conn->errorMessage,
 
736
                                                          libpq_gettext("private key file \"%s\" changed during execution\n"), fnbuf);
 
737
                        ERR_pop_to_mark();
 
738
                        return 0;
 
739
                }
 
740
#endif
 
741
 
 
742
                if (PEM_read_bio_PrivateKey(bio, pkey, NULL, NULL) == NULL)
 
743
                {
 
744
                        char       *err = SSLerrmessage();
 
745
 
 
746
                        printfPQExpBuffer(&conn->errorMessage,
 
747
                           libpq_gettext("could not read private key file \"%s\": %s\n"),
 
748
                                                          fnbuf, err);
 
749
                        SSLerrfree(err);
 
750
 
 
751
                        BIO_free(bio);
 
752
                        ERR_pop_to_mark();
 
753
                        return 0;
 
754
                }
 
755
 
 
756
                BIO_free(bio);
 
757
        }
 
758
 
 
759
        /* verify that the cert and key go together */
 
760
        if (X509_check_private_key(*x509, *pkey) != 1)
 
761
        {
 
762
                char       *err = SSLerrmessage();
 
763
 
 
764
                printfPQExpBuffer(&conn->errorMessage,
 
765
                                                  libpq_gettext("certificate does not match private key file \"%s\": %s\n"),
 
766
                                                  fnbuf, err);
 
767
                SSLerrfree(err);
 
768
                ERR_pop_to_mark();
 
769
                return 0;
 
770
        }
 
771
 
 
772
        ERR_pop_to_mark();
 
773
 
 
774
        return 1;
 
775
}
 
776
 
 
777
#ifdef ENABLE_THREAD_SAFETY
 
778
/*
 
779
 *      Callback functions for OpenSSL internal locking
 
780
 */
 
781
 
 
782
static unsigned long
 
783
pq_threadidcallback(void)
 
784
{
 
785
        /*
 
786
         * This is not standards-compliant.  pthread_self() returns pthread_t, and
 
787
         * shouldn't be cast to unsigned long, but CRYPTO_set_id_callback requires
 
788
         * it, so we have to do it.
 
789
         */
 
790
        return (unsigned long) pthread_self();
 
791
}
 
792
 
 
793
static pthread_mutex_t *pq_lockarray;
 
794
 
 
795
static void
 
796
pq_lockingcallback(int mode, int n, const char *file, int line)
 
797
{
 
798
        if (mode & CRYPTO_LOCK)
 
799
        {
 
800
                if (pthread_mutex_lock(&pq_lockarray[n]))
 
801
                        PGTHREAD_ERROR("failed to lock mutex");
 
802
        }
 
803
        else
 
804
        {
 
805
                if (pthread_mutex_unlock(&pq_lockarray[n]))
 
806
                        PGTHREAD_ERROR("failed to unlock mutex");
 
807
        }
 
808
}
 
809
#endif   /* ENABLE_THREAD_SAFETY */
 
810
 
 
811
/*
 
812
 * Initialize SSL system. In threadsafe mode, this includes setting
 
813
 * up OpenSSL callback functions to do thread locking.
 
814
 *
 
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
 
817
 * override it.
 
818
 *
 
819
 * The conn parameter is only used to be able to pass back an error
 
820
 * message - no connection local setup is made.
 
821
 */
 
822
static int
 
823
init_ssl_system(PGconn *conn)
 
824
{
 
825
#ifdef ENABLE_THREAD_SAFETY
 
826
#ifdef WIN32
 
827
        /* Also see similar code in fe-connect.c, default_threadlock() */
 
828
        if (ssl_config_mutex == NULL)
 
829
        {
 
830
                while (InterlockedExchange(&win32_ssl_create_mutex, 1) == 1)
 
831
                         /* loop, another thread own the lock */ ;
 
832
                if (ssl_config_mutex == NULL)
 
833
                {
 
834
                        if (pthread_mutex_init(&ssl_config_mutex, NULL))
 
835
                                return -1;
 
836
                }
 
837
                InterlockedExchange(&win32_ssl_create_mutex, 0);
 
838
        }
 
839
#endif
 
840
        if (pthread_mutex_lock(&ssl_config_mutex))
 
841
                return -1;
 
842
 
 
843
        if (pq_init_ssl_lib)
 
844
        {
 
845
                /*
 
846
                 * If necessary, set up an array to hold locks for OpenSSL. OpenSSL will
 
847
                 * tell us how big to make this array.
 
848
                 */
 
849
                if (pq_lockarray == NULL)
 
850
                {
 
851
                        int i;
 
852
 
 
853
                        pq_lockarray = malloc(sizeof(pthread_mutex_t) * CRYPTO_num_locks());
 
854
                        if (!pq_lockarray)
 
855
                        {
 
856
                                pthread_mutex_unlock(&ssl_config_mutex);
 
857
                                return -1;
 
858
                        }
 
859
                        for (i = 0; i < CRYPTO_num_locks(); i++)
 
860
                        {
 
861
                                if (pthread_mutex_init(&pq_lockarray[i], NULL))
 
862
                                {
 
863
                                        free(pq_lockarray);
 
864
                                        pq_lockarray = NULL;
 
865
                                        pthread_mutex_unlock(&ssl_config_mutex);
 
866
                                        return -1;
 
867
                                }
 
868
                        }
 
869
                }
 
870
 
 
871
                if (ssl_open_connections++ == 0)
 
872
                {
 
873
                        /* This is actually libcrypto, not libssl. */
 
874
                        /* These are only required for threaded SSL applications */
 
875
                        CRYPTO_set_id_callback(pq_threadidcallback);
 
876
                        CRYPTO_set_locking_callback(pq_lockingcallback);
 
877
                }
 
878
        }
 
879
#endif /* ENABLE_THREAD_SAFETY */
 
880
 
 
881
        if (!SSL_context)
 
882
        {
 
883
                if (pq_init_ssl_lib)
 
884
                {
 
885
#if SSLEAY_VERSION_NUMBER >= 0x00907000L
 
886
                        OPENSSL_config(NULL);
 
887
#endif
 
888
                        SSL_library_init();
 
889
                        SSL_load_error_strings();
 
890
                }
 
891
                SSL_context = SSL_CTX_new(TLSv1_method());
 
892
                if (!SSL_context)
 
893
                {
 
894
                        char       *err = SSLerrmessage();
 
895
 
 
896
                        printfPQExpBuffer(&conn->errorMessage,
 
897
                                                 libpq_gettext("could not create SSL context: %s\n"),
 
898
                                                          err);
 
899
                        SSLerrfree(err);
 
900
#ifdef ENABLE_THREAD_SAFETY
 
901
                        pthread_mutex_unlock(&ssl_config_mutex);
 
902
#endif
 
903
                        return -1;
 
904
                }
 
905
        }
 
906
 
 
907
#ifdef ENABLE_THREAD_SAFETY
 
908
        pthread_mutex_unlock(&ssl_config_mutex);
 
909
#endif
 
910
        return 0;
 
911
}
 
912
 
 
913
/*
 
914
 *      This function is needed because if the libpq library is unloaded
 
915
 *      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.
 
919
 *
 
920
 *      Callbacks are only set when we're compiled in threadsafe mode, so
 
921
 *      we only need to remove them in this case.
 
922
 */
 
923
static void
 
924
destroy_ssl_system(void)
 
925
{
 
926
#ifdef ENABLE_THREAD_SAFETY
 
927
        /* Mutex is created in initialize_ssl_system() */
 
928
        if (pthread_mutex_lock(&ssl_config_mutex))
 
929
                return;
 
930
 
 
931
        if (pq_init_ssl_lib)
 
932
        {
 
933
                if (ssl_open_connections > 0)
 
934
                        --ssl_open_connections;
 
935
 
 
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
                }
 
952
        }
 
953
 
 
954
        pthread_mutex_unlock(&ssl_config_mutex);
 
955
#endif
 
956
        return;
 
957
}
 
958
 
 
959
/*
 
960
 *      Initialize SSL context.
 
961
 */
 
962
static int
 
963
initialize_SSL(PGconn *conn)
 
964
{
 
965
        struct stat buf;
 
966
        char            homedir[MAXPGPATH];
 
967
        char            fnbuf[MAXPGPATH];
 
968
 
 
969
        if (init_ssl_system(conn))
 
970
                return -1;
 
971
 
 
972
        /*
 
973
         * If sslverify is set to anything other than "none", perform certificate
 
974
         * verification. If set to "cn" we will also do further verifications after
 
975
         * the connection has been completed.
 
976
         *
 
977
         * If we are going to look for either root certificate or CRL in the home directory,
 
978
         * we need pqGetHomeDirectory() to succeed. In other cases, we don't need to
 
979
         * get the home directory explicitly.
 
980
         */
 
981
        if (!conn->sslrootcert || !conn->sslcrl)
 
982
        {
 
983
                if (!pqGetHomeDirectory(homedir, sizeof(homedir)))
 
984
                {
 
985
                        if (strcmp(conn->sslverify, "none") != 0)
 
986
                        {
 
987
                                printfPQExpBuffer(&conn->errorMessage,
 
988
                                                                  libpq_gettext("could not get home directory to locate root certificate file"));
 
989
                                return -1;
 
990
                        }
 
991
                }
 
992
        }
 
993
        else
 
994
        {
 
995
                homedir[0] = '\0';
 
996
        }
 
997
 
 
998
 
 
999
 
 
1000
        if (conn->sslrootcert)
 
1001
                strncpy(fnbuf, conn->sslrootcert, sizeof(fnbuf));
 
1002
        else
 
1003
                snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, ROOT_CERT_FILE);
 
1004
 
 
1005
        if (stat(fnbuf, &buf) == 0)
 
1006
        {
 
1007
                X509_STORE *cvstore;
 
1008
 
 
1009
                if (SSL_CTX_load_verify_locations(SSL_context, fnbuf, NULL) != 1)
 
1010
                {
 
1011
                        char       *err = SSLerrmessage();
 
1012
 
 
1013
                        printfPQExpBuffer(&conn->errorMessage,
 
1014
                                                          libpq_gettext("could not read root certificate file \"%s\": %s\n"),
 
1015
                                                          fnbuf, err);
 
1016
                        SSLerrfree(err);
 
1017
                        return -1;
 
1018
                }
 
1019
 
 
1020
                if ((cvstore = SSL_CTX_get_cert_store(SSL_context)) != NULL)
 
1021
                {
 
1022
                        if (conn->sslcrl)
 
1023
                                strncpy(fnbuf, conn->sslcrl, sizeof(fnbuf));
 
1024
                        else
 
1025
                                snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, ROOT_CRL_FILE);
 
1026
 
 
1027
                        /* setting the flags to check against the complete CRL chain */
 
1028
                        if (X509_STORE_load_locations(cvstore, fnbuf, NULL) == 1)
 
1029
/* OpenSSL 0.96 does not support X509_V_FLAG_CRL_CHECK */
 
1030
#ifdef X509_V_FLAG_CRL_CHECK
 
1031
                                X509_STORE_set_flags(cvstore,
 
1032
                                          X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
 
1033
                        /* if not found, silently ignore;  we do not require CRL */
 
1034
#else
 
1035
                        {
 
1036
                                char       *err = SSLerrmessage();
 
1037
 
 
1038
                                printfPQExpBuffer(&conn->errorMessage,
 
1039
                                                                  libpq_gettext("SSL library does not support CRL certificates (file \"%s\")\n"),
 
1040
                                                                  fnbuf);
 
1041
                                SSLerrfree(err);
 
1042
                                return -1;
 
1043
                        }
 
1044
#endif
 
1045
                }
 
1046
 
 
1047
                SSL_CTX_set_verify(SSL_context, SSL_VERIFY_PEER, verify_cb);
 
1048
        }
 
1049
        else
 
1050
        {
 
1051
                /* stat() failed; assume cert file doesn't exist */
 
1052
                if (strcmp(conn->sslverify, "none") != 0)
 
1053
                {
 
1054
                        printfPQExpBuffer(&conn->errorMessage,
 
1055
                                                          libpq_gettext("root certificate file \"%s\" does not exist"), fnbuf);
 
1056
                        return -1;
 
1057
                }
 
1058
        }
 
1059
 
 
1060
        /* set up mechanism to provide client certificate, if available */
 
1061
        SSL_CTX_set_client_cert_cb(SSL_context, client_cert_cb);
 
1062
 
 
1063
        return 0;
 
1064
}
 
1065
 
 
1066
static void
 
1067
destroySSL(void)
 
1068
{
 
1069
        destroy_ssl_system();
 
1070
}
 
1071
 
 
1072
/*
 
1073
 *      Attempt to negotiate SSL connection.
 
1074
 */
 
1075
static PostgresPollingStatusType
 
1076
open_client_SSL(PGconn *conn)
 
1077
{
 
1078
        int                     r;
 
1079
 
 
1080
        r = SSL_connect(conn->ssl);
 
1081
        if (r <= 0)
 
1082
        {
 
1083
                int                     err = SSL_get_error(conn->ssl, r);
 
1084
 
 
1085
                switch (err)
 
1086
                {
 
1087
                        case SSL_ERROR_WANT_READ:
 
1088
                                return PGRES_POLLING_READING;
 
1089
 
 
1090
                        case SSL_ERROR_WANT_WRITE:
 
1091
                                return PGRES_POLLING_WRITING;
 
1092
 
 
1093
                        case SSL_ERROR_SYSCALL:
 
1094
                                {
 
1095
                                        char            sebuf[256];
 
1096
 
 
1097
                                        if (r == -1)
 
1098
                                                printfPQExpBuffer(&conn->errorMessage,
 
1099
                                                                        libpq_gettext("SSL SYSCALL error: %s\n"),
 
1100
                                                        SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
 
1101
                                        else
 
1102
                                                printfPQExpBuffer(&conn->errorMessage,
 
1103
                                                 libpq_gettext("SSL SYSCALL error: EOF detected\n"));
 
1104
                                        close_SSL(conn);
 
1105
                                        return PGRES_POLLING_FAILED;
 
1106
                                }
 
1107
                        case SSL_ERROR_SSL:
 
1108
                                {
 
1109
                                        /*
 
1110
                                         * If there are problems with the local certificate files,
 
1111
                                         * these will be detected by client_cert_cb() which is
 
1112
                                         * called from SSL_connect().  We want to return that
 
1113
                                         * error message and not the rather unhelpful error that
 
1114
                                         * OpenSSL itself returns.      So check to see if an error
 
1115
                                         * message was already stored.
 
1116
                                         */
 
1117
                                        if (conn->errorMessage.len == 0)
 
1118
                                        {
 
1119
                                                char       *err = SSLerrmessage();
 
1120
 
 
1121
                                                printfPQExpBuffer(&conn->errorMessage,
 
1122
                                                                                  libpq_gettext("SSL error: %s\n"),
 
1123
                                                                                  err);
 
1124
                                                SSLerrfree(err);
 
1125
                                        }
 
1126
                                        close_SSL(conn);
 
1127
                                        return PGRES_POLLING_FAILED;
 
1128
                                }
 
1129
 
 
1130
                        default:
 
1131
                                printfPQExpBuffer(&conn->errorMessage,
 
1132
                                                  libpq_gettext("unrecognized SSL error code: %d\n"),
 
1133
                                                                  err);
 
1134
                                close_SSL(conn);
 
1135
                                return PGRES_POLLING_FAILED;
 
1136
                }
 
1137
        }
 
1138
 
 
1139
        /*
 
1140
         * We already checked the server certificate in initialize_SSL()
 
1141
         * using SSL_CTX_set_verify() if root.crt exists.
 
1142
         */
 
1143
 
 
1144
        /* pull out server distinguished and common names */
 
1145
        conn->peer = SSL_get_peer_certificate(conn->ssl);
 
1146
        if (conn->peer == NULL)
 
1147
        {
 
1148
                char       *err = SSLerrmessage();
 
1149
 
 
1150
                printfPQExpBuffer(&conn->errorMessage,
 
1151
                                        libpq_gettext("certificate could not be obtained: %s\n"),
 
1152
                                                  err);
 
1153
                SSLerrfree(err);
 
1154
                close_SSL(conn);
 
1155
                return PGRES_POLLING_FAILED;
 
1156
        }
 
1157
 
 
1158
        X509_NAME_oneline(X509_get_subject_name(conn->peer),
 
1159
                                          conn->peer_dn, sizeof(conn->peer_dn));
 
1160
        conn->peer_dn[sizeof(conn->peer_dn) - 1] = '\0';
 
1161
 
 
1162
        X509_NAME_get_text_by_NID(X509_get_subject_name(conn->peer),
 
1163
                                                          NID_commonName, conn->peer_cn, SM_USER);
 
1164
        conn->peer_cn[SM_USER] = '\0';
 
1165
 
 
1166
        if (!verify_peer_name_matches_certificate(conn))
 
1167
        {
 
1168
                close_SSL(conn);
 
1169
                return PGRES_POLLING_FAILED;
 
1170
        }
 
1171
 
 
1172
        /* SSL handshake is complete */
 
1173
        return PGRES_POLLING_OK;
 
1174
}
 
1175
 
 
1176
/*
 
1177
 *      Close SSL connection.
 
1178
 */
 
1179
static void
 
1180
close_SSL(PGconn *conn)
 
1181
{
 
1182
        if (conn->ssl)
 
1183
        {
 
1184
                DISABLE_SIGPIPE((void) 0);
 
1185
                SSL_shutdown(conn->ssl);
 
1186
                SSL_free(conn->ssl);
 
1187
                conn->ssl = NULL;
 
1188
                pqsecure_destroy();
 
1189
                /* We have to assume we got EPIPE */
 
1190
                REMEMBER_EPIPE(true);
 
1191
                RESTORE_SIGPIPE();
 
1192
        }
 
1193
 
 
1194
        if (conn->peer)
 
1195
        {
 
1196
                X509_free(conn->peer);
 
1197
                conn->peer = NULL;
 
1198
        }
 
1199
}
 
1200
 
 
1201
/*
 
1202
 * Obtain reason string for last SSL error
 
1203
 *
 
1204
 * Some caution is needed here since ERR_reason_error_string will
 
1205
 * return NULL if it doesn't recognize the error code.  We don't
 
1206
 * want to return NULL ever.
 
1207
 */
 
1208
static char ssl_nomem[] = "out of memory allocating error description";
 
1209
 
 
1210
#define SSL_ERR_LEN 128
 
1211
 
 
1212
static char *
 
1213
SSLerrmessage(void)
 
1214
{
 
1215
        unsigned long errcode;
 
1216
        const char *errreason;
 
1217
        char       *errbuf;
 
1218
 
 
1219
        errbuf = malloc(SSL_ERR_LEN);
 
1220
        if (!errbuf)
 
1221
                return ssl_nomem;
 
1222
        errcode = ERR_get_error();
 
1223
        if (errcode == 0)
 
1224
        {
 
1225
                snprintf(errbuf, SSL_ERR_LEN, libpq_gettext("no SSL error reported"));
 
1226
                return errbuf;
 
1227
        }
 
1228
        errreason = ERR_reason_error_string(errcode);
 
1229
        if (errreason != NULL)
 
1230
        {
 
1231
                strlcpy(errbuf, errreason, SSL_ERR_LEN);
 
1232
                return errbuf;
 
1233
        }
 
1234
        snprintf(errbuf, SSL_ERR_LEN, libpq_gettext("SSL error code %lu"), errcode);
 
1235
        return errbuf;
 
1236
}
 
1237
 
 
1238
static void
 
1239
SSLerrfree(char *buf)
 
1240
{
 
1241
        if (buf != ssl_nomem)
 
1242
                free(buf);
 
1243
}
 
1244
 
 
1245
/*
 
1246
 *      Return pointer to OpenSSL object.
 
1247
 */
 
1248
void *
 
1249
PQgetssl(PGconn *conn)
 
1250
{
 
1251
        if (!conn)
 
1252
                return NULL;
 
1253
        return conn->ssl;
 
1254
}
 
1255
#else                                                   /* !USE_SSL */
 
1256
 
 
1257
void *
 
1258
PQgetssl(PGconn *conn)
 
1259
{
 
1260
        return NULL;
 
1261
}
 
1262
#endif   /* USE_SSL */
 
1263
 
 
1264
 
 
1265
#if defined(ENABLE_THREAD_SAFETY) && !defined(WIN32)
 
1266
 
 
1267
/*
 
1268
 *      Block SIGPIPE for this thread.  This prevents send()/write() from exiting
 
1269
 *      the application.
 
1270
 */
 
1271
int
 
1272
pq_block_sigpipe(sigset_t *osigset, bool *sigpipe_pending)
 
1273
{
 
1274
        sigset_t        sigpipe_sigset;
 
1275
        sigset_t        sigset;
 
1276
 
 
1277
        sigemptyset(&sigpipe_sigset);
 
1278
        sigaddset(&sigpipe_sigset, SIGPIPE);
 
1279
 
 
1280
        /* Block SIGPIPE and save previous mask for later reset */
 
1281
        SOCK_ERRNO_SET(pthread_sigmask(SIG_BLOCK, &sigpipe_sigset, osigset));
 
1282
        if (SOCK_ERRNO)
 
1283
                return -1;
 
1284
 
 
1285
        /* We can have a pending SIGPIPE only if it was blocked before */
 
1286
        if (sigismember(osigset, SIGPIPE))
 
1287
        {
 
1288
                /* Is there a pending SIGPIPE? */
 
1289
                if (sigpending(&sigset) != 0)
 
1290
                        return -1;
 
1291
 
 
1292
                if (sigismember(&sigset, SIGPIPE))
 
1293
                        *sigpipe_pending = true;
 
1294
                else
 
1295
                        *sigpipe_pending = false;
 
1296
        }
 
1297
        else
 
1298
                *sigpipe_pending = false;
 
1299
 
 
1300
        return 0;
 
1301
}
 
1302
 
 
1303
/*
 
1304
 *      Discard any pending SIGPIPE and reset the signal mask.
 
1305
 *
 
1306
 * Note: we are effectively assuming here that the C library doesn't queue
 
1307
 * up multiple SIGPIPE events.  If it did, then we'd accidentally leave
 
1308
 * ours in the queue when an event was already pending and we got another.
 
1309
 * As long as it doesn't queue multiple events, we're OK because the caller
 
1310
 * can't tell the difference.
 
1311
 *
 
1312
 * The caller should say got_epipe = FALSE if it is certain that it
 
1313
 * didn't get an EPIPE error; in that case we'll skip the clear operation
 
1314
 * and things are definitely OK, queuing or no.  If it got one or might have
 
1315
 * gotten one, pass got_epipe = TRUE.
 
1316
 *
 
1317
 * We do not want this to change errno, since if it did that could lose
 
1318
 * the error code from a preceding send().      We essentially assume that if
 
1319
 * we were able to do pq_block_sigpipe(), this can't fail.
 
1320
 */
 
1321
void
 
1322
pq_reset_sigpipe(sigset_t *osigset, bool sigpipe_pending, bool got_epipe)
 
1323
{
 
1324
        int                     save_errno = SOCK_ERRNO;
 
1325
        int                     signo;
 
1326
        sigset_t        sigset;
 
1327
 
 
1328
        /* Clear SIGPIPE only if none was pending */
 
1329
        if (got_epipe && !sigpipe_pending)
 
1330
        {
 
1331
                if (sigpending(&sigset) == 0 &&
 
1332
                        sigismember(&sigset, SIGPIPE))
 
1333
                {
 
1334
                        sigset_t        sigpipe_sigset;
 
1335
 
 
1336
                        sigemptyset(&sigpipe_sigset);
 
1337
                        sigaddset(&sigpipe_sigset, SIGPIPE);
 
1338
 
 
1339
                        sigwait(&sigpipe_sigset, &signo);
 
1340
                }
 
1341
        }
 
1342
 
 
1343
        /* Restore saved block mask */
 
1344
        pthread_sigmask(SIG_SETMASK, osigset, NULL);
 
1345
 
 
1346
        SOCK_ERRNO_SET(save_errno);
 
1347
}
 
1348
 
 
1349
#endif   /* ENABLE_THREAD_SAFETY && !WIN32 */