]> granicus.if.org Git - postgresql/blob - src/interfaces/libpq/fe-secure.c
Update CVS HEAD for 2007 copyright. Back branches are typically not
[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-2007, 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.90 2007/01/05 22:20:01 momjian Exp $
15  *
16  * NOTES
17  *        [ Most of these notes are wrong/obsolete, but perhaps not all ]
18  *
19  *        The client *requires* a valid server certificate.  Since
20  *        SSH tunnels provide anonymous confidentiality, the presumption
21  *        is that sites that want endpoint authentication will use the
22  *        direct SSL support, while sites that are comfortable with
23  *        anonymous connections will use SSH tunnels.
24  *
25  *        This code verifies the server certificate, to detect simple
26  *        "man-in-the-middle" and "impersonation" attacks.      The
27  *        server certificate, or better yet the CA certificate used
28  *        to sign the server certificate, should be present in the
29  *        "~/.postgresql/root.crt" file.  If this file isn't
30  *        readable, or the server certificate can't be validated,
31  *        pqsecure_open_client() will return an error code.
32  *
33  *        Additionally, the server certificate's "common name" must
34  *        resolve to the other end of the socket.  This makes it
35  *        substantially harder to pull off a "man-in-the-middle" or
36  *        "impersonation" attack even if the server's private key
37  *        has been stolen.      This check limits acceptable network
38  *        layers to Unix sockets (weird, but legal), TCPv4 and TCPv6.
39  *
40  *        Unfortunately neither the current front- or back-end handle
41  *        failure gracefully, resulting in the backend hiccupping.
42  *        This points out problems in each (the frontend shouldn't even
43  *        try to do SSL if pqsecure_initialize() fails, and the backend
44  *        shouldn't crash/recover if an SSH negotiation fails.  The
45  *        backend definitely needs to be fixed, to prevent a "denial
46  *        of service" attack, but I don't know enough about how the
47  *        backend works (especially that pre-SSL negotiation) to identify
48  *        a fix.
49  *
50  *        ...
51  *
52  *        Unlike the server's static private key, the client's
53  *        static private key (~/.postgresql/postgresql.key)
54  *        should normally be stored encrypted.  However we still
55  *        support EPH since it's useful for other reasons.
56  *
57  *        ...
58  *
59  *        Client certificates are supported, if the server requests
60  *        or requires them.  Client certificates can be used for
61  *        authentication, to prevent sessions from being hijacked,
62  *        or to allow "road warriors" to access the database while
63  *        keeping it closed to everyone else.
64  *
65  *        The user's certificate and private key are located in
66  *              ~/.postgresql/postgresql.crt
67  *        and
68  *              ~/.postgresql/postgresql.key
69  *        respectively.
70  *
71  *        ...
72  *
73  *        We don't provide informational callbacks here (like
74  *        info_cb() in be-secure.c), since there's mechanism to
75  *        display that information to the client.
76  *
77  *-------------------------------------------------------------------------
78  */
79
80 #include "postgres_fe.h"
81
82 #include <signal.h>
83 #include <fcntl.h>
84 #include <ctype.h>
85
86 #include "libpq-fe.h"
87 #include "fe-auth.h"
88 #include "pqsignal.h"
89
90 #ifdef WIN32
91 #include "win32.h"
92 #else
93 #include <sys/socket.h>
94 #include <unistd.h>
95 #include <netdb.h>
96 #include <netinet/in.h>
97 #ifdef HAVE_NETINET_TCP_H
98 #include <netinet/tcp.h>
99 #endif
100 #include <arpa/inet.h>
101 #endif
102 #include <sys/stat.h>
103
104 #ifdef ENABLE_THREAD_SAFETY
105 #ifdef WIN32
106 #include "pthread-win32.h"
107 #else
108 #include <pthread.h>
109 #endif
110 #endif
111
112 #ifdef USE_SSL
113 #include <openssl/ssl.h>
114 #endif   /* USE_SSL */
115
116
117 #ifdef USE_SSL
118
119 #ifndef WIN32
120 #define USER_CERT_FILE          ".postgresql/postgresql.crt"
121 #define USER_KEY_FILE           ".postgresql/postgresql.key"
122 #define ROOT_CERT_FILE          ".postgresql/root.crt"
123 #define ROOT_CRL_FILE           ".postgresql/root.crl"
124 #else
125 /* On Windows, the "home" directory is already PostgreSQL-specific */
126 #define USER_CERT_FILE          "postgresql.crt"
127 #define USER_KEY_FILE           "postgresql.key"
128 #define ROOT_CERT_FILE          "root.crt"
129 #define ROOT_CRL_FILE           "root.crl"
130 #endif
131
132 #ifdef NOT_USED
133 static int      verify_peer(PGconn *);
134 #endif
135 static int      verify_cb(int ok, X509_STORE_CTX *ctx);
136 static int      client_cert_cb(SSL *, X509 **, EVP_PKEY **);
137 static int      init_ssl_system(PGconn *conn);
138 static int      initialize_SSL(PGconn *);
139 static void destroy_SSL(void);
140 static PostgresPollingStatusType open_client_SSL(PGconn *);
141 static void close_SSL(PGconn *);
142 static char *SSLerrmessage(void);
143 static void SSLerrfree(char *buf);
144 #endif
145
146 #ifdef USE_SSL
147 static bool pq_initssllib = true;
148
149 static SSL_CTX *SSL_context = NULL;
150 #endif
151
152 /* ------------------------------------------------------------ */
153 /*                       Procedures common to all secure sessions                       */
154 /* ------------------------------------------------------------ */
155
156
157 /*
158  *      Exported function to allow application to tell us it's already
159  *      initialized OpenSSL.
160  */
161 void
162 PQinitSSL(int do_init)
163 {
164 #ifdef USE_SSL
165         pq_initssllib = do_init;
166 #endif
167 }
168
169 /*
170  *      Initialize global context
171  */
172 int
173 pqsecure_initialize(PGconn *conn)
174 {
175         int                     r = 0;
176
177 #ifdef USE_SSL
178         r = initialize_SSL(conn);
179 #endif
180
181         return r;
182 }
183
184 /*
185  *      Destroy global context
186  */
187 void
188 pqsecure_destroy(void)
189 {
190 #ifdef USE_SSL
191         destroy_SSL();
192 #endif
193 }
194
195 /*
196  *      Attempt to negotiate secure session.
197  */
198 PostgresPollingStatusType
199 pqsecure_open_client(PGconn *conn)
200 {
201 #ifdef USE_SSL
202         /* First time through? */
203         if (conn->ssl == NULL)
204         {
205                 if (!(conn->ssl = SSL_new(SSL_context)) ||
206                         !SSL_set_app_data(conn->ssl, conn) ||
207                         !SSL_set_fd(conn->ssl, conn->sock))
208                 {
209                         char       *err = SSLerrmessage();
210
211                         printfPQExpBuffer(&conn->errorMessage,
212                                    libpq_gettext("could not establish SSL connection: %s\n"),
213                                                           err);
214                         SSLerrfree(err);
215                         close_SSL(conn);
216                         return PGRES_POLLING_FAILED;
217                 }
218
219                 /*
220                  * Initialize errorMessage to empty.  This allows open_client_SSL() to
221                  * detect whether client_cert_cb() has stored a message.
222                  */
223                 resetPQExpBuffer(&conn->errorMessage);
224         }
225         /* Begin or continue the actual handshake */
226         return open_client_SSL(conn);
227 #else
228         /* shouldn't get here */
229         return PGRES_POLLING_FAILED;
230 #endif
231 }
232
233 /*
234  *      Close secure session.
235  */
236 void
237 pqsecure_close(PGconn *conn)
238 {
239 #ifdef USE_SSL
240         if (conn->ssl)
241                 close_SSL(conn);
242 #endif
243 }
244
245 /*
246  *      Read data from a secure connection.
247  */
248 ssize_t
249 pqsecure_read(PGconn *conn, void *ptr, size_t len)
250 {
251         ssize_t         n;
252
253 #ifdef USE_SSL
254         if (conn->ssl)
255         {
256                 int                     err;
257
258 rloop:
259                 n = SSL_read(conn->ssl, ptr, len);
260                 err = SSL_get_error(conn->ssl, n);
261                 switch (err)
262                 {
263                         case SSL_ERROR_NONE:
264                                 break;
265                         case SSL_ERROR_WANT_READ:
266                                 n = 0;
267                                 break;
268                         case SSL_ERROR_WANT_WRITE:
269
270                                 /*
271                                  * Returning 0 here would cause caller to wait for read-ready,
272                                  * which is not correct since what SSL wants is wait for
273                                  * write-ready.  The former could get us stuck in an infinite
274                                  * wait, so don't risk it; busy-loop instead.
275                                  */
276                                 goto rloop;
277                         case SSL_ERROR_SYSCALL:
278                                 {
279                                         char            sebuf[256];
280
281                                         if (n == -1)
282                                                 printfPQExpBuffer(&conn->errorMessage,
283                                                                         libpq_gettext("SSL SYSCALL error: %s\n"),
284                                                         SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
285                                         else
286                                         {
287                                                 printfPQExpBuffer(&conn->errorMessage,
288                                                  libpq_gettext("SSL SYSCALL error: EOF detected\n"));
289
290                                                 SOCK_ERRNO_SET(ECONNRESET);
291                                                 n = -1;
292                                         }
293                                         break;
294                                 }
295                         case SSL_ERROR_SSL:
296                                 {
297                                         char       *err = SSLerrmessage();
298
299                                         printfPQExpBuffer(&conn->errorMessage,
300                                                                           libpq_gettext("SSL error: %s\n"), err);
301                                         SSLerrfree(err);
302                                 }
303                                 /* fall through */
304                         case SSL_ERROR_ZERO_RETURN:
305                                 SOCK_ERRNO_SET(ECONNRESET);
306                                 n = -1;
307                                 break;
308                         default:
309                                 printfPQExpBuffer(&conn->errorMessage,
310                                                   libpq_gettext("unrecognized SSL error code: %d\n"),
311                                                                   err);
312                                 n = -1;
313                                 break;
314                 }
315         }
316         else
317 #endif
318                 n = recv(conn->sock, ptr, len, 0);
319
320         return n;
321 }
322
323 /*
324  *      Write data to a secure connection.
325  */
326 ssize_t
327 pqsecure_write(PGconn *conn, const void *ptr, size_t len)
328 {
329         ssize_t         n;
330
331 #ifndef WIN32
332 #ifdef ENABLE_THREAD_SAFETY
333         sigset_t        osigmask;
334         bool            sigpipe_pending;
335         bool            got_epipe = false;
336
337
338         if (pq_block_sigpipe(&osigmask, &sigpipe_pending) < 0)
339                 return -1;
340 #else
341         pqsigfunc       oldsighandler = pqsignal(SIGPIPE, SIG_IGN);
342 #endif   /* ENABLE_THREAD_SAFETY */
343 #endif   /* WIN32 */
344
345 #ifdef USE_SSL
346         if (conn->ssl)
347         {
348                 int                     err;
349
350                 n = SSL_write(conn->ssl, ptr, len);
351                 err = SSL_get_error(conn->ssl, n);
352                 switch (err)
353                 {
354                         case SSL_ERROR_NONE:
355                                 break;
356                         case SSL_ERROR_WANT_READ:
357
358                                 /*
359                                  * Returning 0 here causes caller to wait for write-ready,
360                                  * which is not really the right thing, but it's the best we
361                                  * can do.
362                                  */
363                                 n = 0;
364                                 break;
365                         case SSL_ERROR_WANT_WRITE:
366                                 n = 0;
367                                 break;
368                         case SSL_ERROR_SYSCALL:
369                                 {
370                                         char            sebuf[256];
371
372                                         if (n == -1)
373                                         {
374 #if defined(ENABLE_THREAD_SAFETY) && !defined(WIN32)
375                                                 if (SOCK_ERRNO == EPIPE)
376                                                         got_epipe = true;
377 #endif
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 #if defined(ENABLE_THREAD_SAFETY) && !defined(WIN32)
417                 if (n < 0 && SOCK_ERRNO == EPIPE)
418                         got_epipe = true;
419 #endif
420         }
421
422 #ifndef WIN32
423 #ifdef ENABLE_THREAD_SAFETY
424         pq_reset_sigpipe(&osigmask, sigpipe_pending, got_epipe);
425 #else
426         pqsignal(SIGPIPE, oldsighandler);
427 #endif   /* ENABLE_THREAD_SAFETY */
428 #endif   /* WIN32 */
429
430         return n;
431 }
432
433 /* ------------------------------------------------------------ */
434 /*                                                SSL specific code                                             */
435 /* ------------------------------------------------------------ */
436 #ifdef USE_SSL
437
438 /*
439  *      Certificate verification callback
440  *
441  *      This callback allows us to log intermediate problems during
442  *      verification, but there doesn't seem to be a clean way to get
443  *      our PGconn * structure.  So we can't log anything!
444  *
445  *      This callback also allows us to override the default acceptance
446  *      criteria (e.g., accepting self-signed or expired certs), but
447  *      for now we accept the default checks.
448  */
449 static int
450 verify_cb(int ok, X509_STORE_CTX *ctx)
451 {
452         return ok;
453 }
454
455 #ifdef NOT_USED
456 /*
457  *      Verify that common name resolves to peer.
458  */
459 static int
460 verify_peer(PGconn *conn)
461 {
462         struct hostent *h = NULL;
463         struct sockaddr addr;
464         struct sockaddr_in *sin;
465         ACCEPT_TYPE_ARG3 len;
466         char      **s;
467         unsigned long l;
468
469         /* get the address on the other side of the socket */
470         len = sizeof(addr);
471         if (getpeername(conn->sock, &addr, &len) == -1)
472         {
473                 char            sebuf[256];
474
475                 printfPQExpBuffer(&conn->errorMessage,
476                                                   libpq_gettext("error querying socket: %s\n"),
477                                                   SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
478                 return -1;
479         }
480
481         /* weird, but legal case */
482         if (addr.sa_family == AF_UNIX)
483                 return 0;
484
485         {
486                 struct hostent hpstr;
487                 char            buf[BUFSIZ];
488                 int                     herrno = 0;
489
490                 /*
491                  * Currently, pqGethostbyname() is used only on platforms that don't
492                  * have getaddrinfo().  If you enable this function, you should
493                  * convert the pqGethostbyname() function call to use getaddrinfo().
494                  */
495                 pqGethostbyname(conn->peer_cn, &hpstr, buf, sizeof(buf),
496                                                 &h, &herrno);
497         }
498
499         /* what do we know about the peer's common name? */
500         if (h == NULL)
501         {
502                 printfPQExpBuffer(&conn->errorMessage,
503                   libpq_gettext("could not get information about host \"%s\": %s\n"),
504                                                   conn->peer_cn, hstrerror(h_errno));
505                 return -1;
506         }
507
508         /* does the address match? */
509         switch (addr.sa_family)
510         {
511                 case AF_INET:
512                         sin = (struct sockaddr_in *) & addr;
513                         for (s = h->h_addr_list; *s != NULL; s++)
514                         {
515                                 if (!memcmp(&sin->sin_addr.s_addr, *s, h->h_length))
516                                         return 0;
517                         }
518                         break;
519
520                 default:
521                         printfPQExpBuffer(&conn->errorMessage,
522                                                           libpq_gettext("unsupported protocol\n"));
523                         return -1;
524         }
525
526         /*
527          * the prior test should be definitive, but in practice it sometimes
528          * fails.  So we also check the aliases.
529          */
530         for (s = h->h_aliases; *s != NULL; s++)
531         {
532                 if (pg_strcasecmp(conn->peer_cn, *s) == 0)
533                         return 0;
534         }
535
536         /* generate protocol-aware error message */
537         switch (addr.sa_family)
538         {
539                 case AF_INET:
540                         sin = (struct sockaddr_in *) & addr;
541                         l = ntohl(sin->sin_addr.s_addr);
542                         printfPQExpBuffer(&conn->errorMessage,
543                                                           libpq_gettext(
544                                                                                         "server common name \"%s\" does not resolve to %ld.%ld.%ld.%ld\n"),
545                                                  conn->peer_cn, (l >> 24) % 0x100, (l >> 16) % 0x100,
546                                                           (l >> 8) % 0x100, l % 0x100);
547                         break;
548                 default:
549                         printfPQExpBuffer(&conn->errorMessage,
550                                                           libpq_gettext(
551                          "server common name \"%s\" does not resolve to peer address\n"),
552                                                           conn->peer_cn);
553         }
554
555         return -1;
556 }
557 #endif   /* NOT_USED */
558
559 /*
560  *      Callback used by SSL to load client cert and key.
561  *      This callback is only called when the server wants a
562  *      client cert.
563  *
564  *      Must return 1 on success, 0 on no data or error.
565  */
566 static int
567 client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
568 {
569         char            homedir[MAXPGPATH];
570         struct stat buf;
571
572 #ifndef WIN32
573         struct stat buf2;
574 #endif
575         char            fnbuf[MAXPGPATH];
576         FILE       *fp;
577         PGconn     *conn = (PGconn *) SSL_get_app_data(ssl);
578         int                     (*cb) () = NULL;        /* how to read user password */
579         char            sebuf[256];
580
581         if (!pqGetHomeDirectory(homedir, sizeof(homedir)))
582         {
583                 printfPQExpBuffer(&conn->errorMessage,
584                                                   libpq_gettext("could not get user information\n"));
585                 return 0;
586         }
587
588         /* read the user certificate */
589         snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, USER_CERT_FILE);
590         if ((fp = fopen(fnbuf, "r")) == NULL)
591         {
592                 printfPQExpBuffer(&conn->errorMessage,
593                            libpq_gettext("could not open certificate file \"%s\": %s\n"),
594                                                   fnbuf, pqStrerror(errno, sebuf, sizeof(sebuf)));
595                 return 0;
596         }
597         if (PEM_read_X509(fp, x509, NULL, NULL) == NULL)
598         {
599                 char       *err = SSLerrmessage();
600
601                 printfPQExpBuffer(&conn->errorMessage,
602                            libpq_gettext("could not read certificate file \"%s\": %s\n"),
603                                                   fnbuf, err);
604                 SSLerrfree(err);
605                 fclose(fp);
606                 return 0;
607         }
608         fclose(fp);
609
610         /* read the user key */
611         snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, USER_KEY_FILE);
612         if (stat(fnbuf, &buf) == -1)
613         {
614                 printfPQExpBuffer(&conn->errorMessage,
615                                                   libpq_gettext("certificate present, but not private key file \"%s\"\n"),
616                                                   fnbuf);
617                 return 0;
618         }
619 #ifndef WIN32
620         if (!S_ISREG(buf.st_mode) || (buf.st_mode & 0077) ||
621                 buf.st_uid != geteuid())
622         {
623                 printfPQExpBuffer(&conn->errorMessage,
624                         libpq_gettext("private key file \"%s\" has wrong permissions\n"),
625                                                   fnbuf);
626                 return 0;
627         }
628 #endif
629         if ((fp = fopen(fnbuf, "r")) == NULL)
630         {
631                 printfPQExpBuffer(&conn->errorMessage,
632                            libpq_gettext("could not open private key file \"%s\": %s\n"),
633                                                   fnbuf, pqStrerror(errno, sebuf, sizeof(sebuf)));
634                 return 0;
635         }
636 #ifndef WIN32
637         if (fstat(fileno(fp), &buf2) == -1 ||
638                 buf.st_dev != buf2.st_dev || buf.st_ino != buf2.st_ino)
639         {
640                 printfPQExpBuffer(&conn->errorMessage,
641                                                   libpq_gettext("private key file \"%s\" changed during execution\n"), fnbuf);
642                 return 0;
643         }
644 #endif
645         if (PEM_read_PrivateKey(fp, pkey, cb, NULL) == NULL)
646         {
647                 char       *err = SSLerrmessage();
648
649                 printfPQExpBuffer(&conn->errorMessage,
650                            libpq_gettext("could not read private key file \"%s\": %s\n"),
651                                                   fnbuf, err);
652                 SSLerrfree(err);
653                 fclose(fp);
654                 return 0;
655         }
656         fclose(fp);
657
658         /* verify that the cert and key go together */
659         if (!X509_check_private_key(*x509, *pkey))
660         {
661                 char       *err = SSLerrmessage();
662
663                 printfPQExpBuffer(&conn->errorMessage,
664                                                   libpq_gettext("certificate does not match private key file \"%s\": %s\n"),
665                                                   fnbuf, err);
666                 SSLerrfree(err);
667                 return 0;
668         }
669
670         return 1;
671 }
672
673 #ifdef ENABLE_THREAD_SAFETY
674
675 static unsigned long
676 pq_threadidcallback(void)
677 {
678         /*
679          * This is not standards-compliant.  pthread_self() returns pthread_t, and
680          * shouldn't be cast to unsigned long, but CRYPTO_set_id_callback requires
681          * it, so we have to do it.
682          */
683         return (unsigned long) pthread_self();
684 }
685
686 static pthread_mutex_t *pq_lockarray;
687
688 static void
689 pq_lockingcallback(int mode, int n, const char *file, int line)
690 {
691         if (mode & CRYPTO_LOCK)
692                 pthread_mutex_lock(&pq_lockarray[n]);
693         else
694                 pthread_mutex_unlock(&pq_lockarray[n]);
695 }
696 #endif   /* ENABLE_THREAD_SAFETY */
697
698 static int
699 init_ssl_system(PGconn *conn)
700 {
701 #ifdef ENABLE_THREAD_SAFETY
702 #ifndef WIN32
703         static pthread_mutex_t init_mutex = PTHREAD_MUTEX_INITIALIZER;
704 #else
705         static pthread_mutex_t init_mutex = NULL;
706         static long mutex_initlock = 0;
707
708         if (init_mutex == NULL)
709         {
710                 while (InterlockedExchange(&mutex_initlock, 1) == 1)
711                          /* loop, another thread own the lock */ ;
712                 if (init_mutex == NULL)
713                         pthread_mutex_init(&init_mutex, NULL);
714                 InterlockedExchange(&mutex_initlock, 0);
715         }
716 #endif
717         pthread_mutex_lock(&init_mutex);
718
719         if (pq_initssllib && pq_lockarray == NULL)
720         {
721                 int                     i;
722
723                 CRYPTO_set_id_callback(pq_threadidcallback);
724
725                 pq_lockarray = malloc(sizeof(pthread_mutex_t) * CRYPTO_num_locks());
726                 if (!pq_lockarray)
727                 {
728                         pthread_mutex_unlock(&init_mutex);
729                         return -1;
730                 }
731                 for (i = 0; i < CRYPTO_num_locks(); i++)
732                         pthread_mutex_init(&pq_lockarray[i], NULL);
733
734                 CRYPTO_set_locking_callback(pq_lockingcallback);
735         }
736 #endif
737         if (!SSL_context)
738         {
739                 if (pq_initssllib)
740                 {
741                         SSL_library_init();
742                         SSL_load_error_strings();
743                 }
744                 SSL_context = SSL_CTX_new(TLSv1_method());
745                 if (!SSL_context)
746                 {
747                         char       *err = SSLerrmessage();
748
749                         printfPQExpBuffer(&conn->errorMessage,
750                                                  libpq_gettext("could not create SSL context: %s\n"),
751                                                           err);
752                         SSLerrfree(err);
753 #ifdef ENABLE_THREAD_SAFETY
754                         pthread_mutex_unlock(&init_mutex);
755 #endif
756                         return -1;
757                 }
758         }
759 #ifdef ENABLE_THREAD_SAFETY
760         pthread_mutex_unlock(&init_mutex);
761 #endif
762         return 0;
763 }
764
765 /*
766  *      Initialize global SSL context.
767  */
768 static int
769 initialize_SSL(PGconn *conn)
770 {
771         struct stat buf;
772         char            homedir[MAXPGPATH];
773         char            fnbuf[MAXPGPATH];
774
775         if (init_ssl_system(conn))
776                 return -1;
777
778         /* Set up to verify server cert, if root.crt is present */
779         if (pqGetHomeDirectory(homedir, sizeof(homedir)))
780         {
781                 snprintf(fnbuf, sizeof(fnbuf), "%s/%s", homedir, ROOT_CERT_FILE);
782                 if (stat(fnbuf, &buf) == 0)
783                 {
784                         X509_STORE *cvstore;
785
786                         if (!SSL_CTX_load_verify_locations(SSL_context, fnbuf, NULL))
787                         {
788                                 char       *err = SSLerrmessage();
789
790                                 printfPQExpBuffer(&conn->errorMessage,
791                                                                   libpq_gettext("could not read root certificate file \"%s\": %s\n"),
792                                                                   fnbuf, err);
793                                 SSLerrfree(err);
794                                 return -1;
795                         }
796
797                         if ((cvstore = SSL_CTX_get_cert_store(SSL_context)) != NULL)
798                         {
799                                 /* setting the flags to check against the complete CRL chain */
800                                 if (X509_STORE_load_locations(cvstore, ROOT_CRL_FILE, NULL) != 0)
801 /* OpenSSL 0.96 does not support X509_V_FLAG_CRL_CHECK */
802 #ifdef X509_V_FLAG_CRL_CHECK
803                                         X509_STORE_set_flags(cvstore,
804                                                   X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
805                                 /* if not found, silently ignore;  we do not require CRL */
806 #else
807                                 {
808                                         char       *err = SSLerrmessage();
809
810                                         printfPQExpBuffer(&conn->errorMessage,
811                                                                           libpq_gettext("SSL library does not support CRL certificates (file \"%s\")\n"),
812                                                                           fnbuf);
813                                         SSLerrfree(err);
814                                         return -1;
815                                 }
816 #endif
817                         }
818
819                         SSL_CTX_set_verify(SSL_context, SSL_VERIFY_PEER, verify_cb);
820                 }
821         }
822
823         /* set up mechanism to provide client certificate, if available */
824         SSL_CTX_set_client_cert_cb(SSL_context, client_cert_cb);
825
826         return 0;
827 }
828
829 /*
830  *      Destroy global SSL context.
831  */
832 static void
833 destroy_SSL(void)
834 {
835         if (SSL_context)
836         {
837                 SSL_CTX_free(SSL_context);
838                 SSL_context = NULL;
839         }
840 }
841
842 /*
843  *      Attempt to negotiate SSL connection.
844  */
845 static PostgresPollingStatusType
846 open_client_SSL(PGconn *conn)
847 {
848         int                     r;
849
850         r = SSL_connect(conn->ssl);
851         if (r <= 0)
852         {
853                 int                     err = SSL_get_error(conn->ssl, r);
854
855                 switch (err)
856                 {
857                         case SSL_ERROR_WANT_READ:
858                                 return PGRES_POLLING_READING;
859
860                         case SSL_ERROR_WANT_WRITE:
861                                 return PGRES_POLLING_WRITING;
862
863                         case SSL_ERROR_SYSCALL:
864                                 {
865                                         char            sebuf[256];
866
867                                         if (r == -1)
868                                                 printfPQExpBuffer(&conn->errorMessage,
869                                                                         libpq_gettext("SSL SYSCALL error: %s\n"),
870                                                         SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
871                                         else
872                                                 printfPQExpBuffer(&conn->errorMessage,
873                                                  libpq_gettext("SSL SYSCALL error: EOF detected\n"));
874                                         close_SSL(conn);
875                                         return PGRES_POLLING_FAILED;
876                                 }
877                         case SSL_ERROR_SSL:
878                                 {
879                                         /*
880                                          * If there are problems with the local certificate files,
881                                          * these will be detected by client_cert_cb() which is
882                                          * called from SSL_connect().  We want to return that
883                                          * error message and not the rather unhelpful error that
884                                          * OpenSSL itself returns.      So check to see if an error
885                                          * message was already stored.
886                                          */
887                                         if (conn->errorMessage.len == 0)
888                                         {
889                                                 char       *err = SSLerrmessage();
890
891                                                 printfPQExpBuffer(&conn->errorMessage,
892                                                                                   libpq_gettext("SSL error: %s\n"),
893                                                                                   err);
894                                                 SSLerrfree(err);
895                                         }
896                                         close_SSL(conn);
897                                         return PGRES_POLLING_FAILED;
898                                 }
899
900                         default:
901                                 printfPQExpBuffer(&conn->errorMessage,
902                                                   libpq_gettext("unrecognized SSL error code: %d\n"),
903                                                                   err);
904                                 close_SSL(conn);
905                                 return PGRES_POLLING_FAILED;
906                 }
907         }
908
909         /* check the certificate chain of the server */
910
911 #ifdef NOT_USED
912         /* CLIENT CERTIFICATES NOT REQUIRED  bjm 2002-09-26 */
913
914         /*
915          * this eliminates simple man-in-the-middle attacks and simple
916          * impersonations
917          */
918         r = SSL_get_verify_result(conn->ssl);
919         if (r != X509_V_OK)
920         {
921                 printfPQExpBuffer(&conn->errorMessage,
922                                    libpq_gettext("certificate could not be validated: %s\n"),
923                                                   X509_verify_cert_error_string(r));
924                 close_SSL(conn);
925                 return PGRES_POLLING_FAILED;
926         }
927 #endif
928
929         /* pull out server distinguished and common names */
930         conn->peer = SSL_get_peer_certificate(conn->ssl);
931         if (conn->peer == NULL)
932         {
933                 char       *err = SSLerrmessage();
934
935                 printfPQExpBuffer(&conn->errorMessage,
936                                         libpq_gettext("certificate could not be obtained: %s\n"),
937                                                   err);
938                 SSLerrfree(err);
939                 close_SSL(conn);
940                 return PGRES_POLLING_FAILED;
941         }
942
943         X509_NAME_oneline(X509_get_subject_name(conn->peer),
944                                           conn->peer_dn, sizeof(conn->peer_dn));
945         conn->peer_dn[sizeof(conn->peer_dn) - 1] = '\0';
946
947         X509_NAME_get_text_by_NID(X509_get_subject_name(conn->peer),
948                                                           NID_commonName, conn->peer_cn, SM_USER);
949         conn->peer_cn[SM_USER] = '\0';
950
951         /* verify that the common name resolves to peer */
952
953 #ifdef NOT_USED
954         /* CLIENT CERTIFICATES NOT REQUIRED  bjm 2002-09-26 */
955
956         /*
957          * this is necessary to eliminate man-in-the-middle attacks and
958          * impersonations where the attacker somehow learned the server's private
959          * key
960          */
961         if (verify_peer(conn) == -1)
962         {
963                 close_SSL(conn);
964                 return PGRES_POLLING_FAILED;
965         }
966 #endif
967
968         /* SSL handshake is complete */
969         return PGRES_POLLING_OK;
970 }
971
972 /*
973  *      Close SSL connection.
974  */
975 static void
976 close_SSL(PGconn *conn)
977 {
978         if (conn->ssl)
979         {
980                 SSL_shutdown(conn->ssl);
981                 SSL_free(conn->ssl);
982                 conn->ssl = NULL;
983         }
984
985         if (conn->peer)
986         {
987                 X509_free(conn->peer);
988                 conn->peer = NULL;
989         }
990 }
991
992 /*
993  * Obtain reason string for last SSL error
994  *
995  * Some caution is needed here since ERR_reason_error_string will
996  * return NULL if it doesn't recognize the error code.  We don't
997  * want to return NULL ever.
998  */
999 static char ssl_nomem[] = "out of memory allocating error description";
1000
1001 #define SSL_ERR_LEN 128
1002
1003 static char *
1004 SSLerrmessage(void)
1005 {
1006         unsigned long errcode;
1007         const char *errreason;
1008         char       *errbuf;
1009
1010         errbuf = malloc(SSL_ERR_LEN);
1011         if (!errbuf)
1012                 return ssl_nomem;
1013         errcode = ERR_get_error();
1014         if (errcode == 0)
1015         {
1016                 snprintf(errbuf, SSL_ERR_LEN, libpq_gettext("no SSL error reported"));
1017                 return errbuf;
1018         }
1019         errreason = ERR_reason_error_string(errcode);
1020         if (errreason != NULL)
1021         {
1022                 strncpy(errbuf, errreason, SSL_ERR_LEN - 1);
1023                 errbuf[SSL_ERR_LEN - 1] = '\0';
1024                 return errbuf;
1025         }
1026         snprintf(errbuf, SSL_ERR_LEN, libpq_gettext("SSL error code %lu"), errcode);
1027         return errbuf;
1028 }
1029
1030 static void
1031 SSLerrfree(char *buf)
1032 {
1033         if (buf != ssl_nomem)
1034                 free(buf);
1035 }
1036
1037 /*
1038  *      Return pointer to OpenSSL object.
1039  */
1040 void *
1041 PQgetssl(PGconn *conn)
1042 {
1043         if (!conn)
1044                 return NULL;
1045         return conn->ssl;
1046 }
1047 #else                                                   /* !USE_SSL */
1048
1049 void *
1050 PQgetssl(PGconn *conn)
1051 {
1052         return NULL;
1053 }
1054 #endif   /* USE_SSL */
1055
1056 #if defined(ENABLE_THREAD_SAFETY) && !defined(WIN32)
1057
1058 /*
1059  *      Block SIGPIPE for this thread.  This prevents send()/write() from exiting
1060  *      the application.
1061  */
1062 int
1063 pq_block_sigpipe(sigset_t *osigset, bool *sigpipe_pending)
1064 {
1065         sigset_t        sigpipe_sigset;
1066         sigset_t        sigset;
1067
1068         sigemptyset(&sigpipe_sigset);
1069         sigaddset(&sigpipe_sigset, SIGPIPE);
1070
1071         /* Block SIGPIPE and save previous mask for later reset */
1072         SOCK_ERRNO_SET(pthread_sigmask(SIG_BLOCK, &sigpipe_sigset, osigset));
1073         if (SOCK_ERRNO)
1074                 return -1;
1075
1076         /* We can have a pending SIGPIPE only if it was blocked before */
1077         if (sigismember(osigset, SIGPIPE))
1078         {
1079                 /* Is there a pending SIGPIPE? */
1080                 if (sigpending(&sigset) != 0)
1081                         return -1;
1082
1083                 if (sigismember(&sigset, SIGPIPE))
1084                         *sigpipe_pending = true;
1085                 else
1086                         *sigpipe_pending = false;
1087         }
1088         else
1089                 *sigpipe_pending = false;
1090
1091         return 0;
1092 }
1093
1094 /*
1095  *      Discard any pending SIGPIPE and reset the signal mask.
1096  *
1097  * Note: we are effectively assuming here that the C library doesn't queue
1098  * up multiple SIGPIPE events.  If it did, then we'd accidentally leave
1099  * ours in the queue when an event was already pending and we got another.
1100  * As long as it doesn't queue multiple events, we're OK because the caller
1101  * can't tell the difference.
1102  *
1103  * The caller should say got_epipe = FALSE if it is certain that it
1104  * didn't get an EPIPE error; in that case we'll skip the clear operation
1105  * and things are definitely OK, queuing or no.  If it got one or might have
1106  * gotten one, pass got_epipe = TRUE.
1107  *
1108  * We do not want this to change errno, since if it did that could lose
1109  * the error code from a preceding send().      We essentially assume that if
1110  * we were able to do pq_block_sigpipe(), this can't fail.
1111  */
1112 void
1113 pq_reset_sigpipe(sigset_t *osigset, bool sigpipe_pending, bool got_epipe)
1114 {
1115         int                     save_errno = SOCK_ERRNO;
1116         int                     signo;
1117         sigset_t        sigset;
1118
1119         /* Clear SIGPIPE only if none was pending */
1120         if (got_epipe && !sigpipe_pending)
1121         {
1122                 if (sigpending(&sigset) == 0 &&
1123                         sigismember(&sigset, SIGPIPE))
1124                 {
1125                         sigset_t        sigpipe_sigset;
1126
1127                         sigemptyset(&sigpipe_sigset);
1128                         sigaddset(&sigpipe_sigset, SIGPIPE);
1129
1130                         sigwait(&sigpipe_sigset, &signo);
1131                 }
1132         }
1133
1134         /* Restore saved block mask */
1135         pthread_sigmask(SIG_SETMASK, osigset, NULL);
1136
1137         SOCK_ERRNO_SET(save_errno);
1138 }
1139
1140 #endif   /* ENABLE_THREAD_SAFETY */