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