]> granicus.if.org Git - postgresql/blob - src/interfaces/libpq/fe-secure.c
init_ssl_system will return 0 on success and -1 on failure, which will
[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-2003, 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.41 2004/06/03 00:13:19 momjian Exp $
15  *
16  * NOTES
17  *        The client *requires* a valid server certificate.  Since
18  *        SSH tunnels provide anonymous confidentiality, the presumption
19  *        is that sites that want endpoint authentication will use the
20  *        direct SSL support, while sites that are comfortable with
21  *        anonymous connections will use SSH tunnels.
22  *
23  *        This code verifies the server certificate, to detect simple
24  *        "man-in-the-middle" and "impersonation" attacks.      The
25  *        server certificate, or better yet the CA certificate used
26  *        to sign the server certificate, should be present in the
27  *        "$HOME/.postgresql/root.crt" file.  If this file isn't
28  *        readable, or the server certificate can't be validated,
29  *        pqsecure_open_client() will return an error code.
30  *
31  *        Additionally, the server certificate's "common name" must
32  *        resolve to the other end of the socket.  This makes it
33  *        substantially harder to pull off a "man-in-the-middle" or
34  *        "impersonation" attack even if the server's private key
35  *        has been stolen.      This check limits acceptable network
36  *        layers to Unix sockets (weird, but legal), TCPv4 and TCPv6.
37  *
38  *        Unfortunately neither the current front- or back-end handle
39  *        failure gracefully, resulting in the backend hiccupping.
40  *        This points out problems in each (the frontend shouldn't even
41  *        try to do SSL if pqsecure_initialize() fails, and the backend
42  *        shouldn't crash/recover if an SSH negotiation fails.  The
43  *        backend definitely needs to be fixed, to prevent a "denial
44  *        of service" attack, but I don't know enough about how the
45  *        backend works (especially that pre-SSL negotiation) to identify
46  *        a fix.
47  *
48  *        ...
49  *
50  *        Unlike the server's static private key, the client's
51  *        static private key ($HOME/.postgresql/postgresql.key)
52  *        should normally be stored encrypted.  However we still
53  *        support EPH since it's useful for other reasons.
54  *
55  *        ...
56  *
57  *        Client certificates are supported, if the server requests
58  *        or requires them.  Client certificates can be used for
59  *        authentication, to prevent sessions from being hijacked,
60  *        or to allow "road warriors" to access the database while
61  *        keeping it closed to everyone else.
62  *
63  *        The user's certificate and private key are located in
64  *              $HOME/.postgresql/postgresql.crt
65  *        and
66  *              $HOME/.postgresql/postgresql.key
67  *        respectively.
68  *
69  *        ...
70  *
71  *        We don't provide informational callbacks here (like
72  *        info_cb() in be-secure.c), since there's mechanism to
73  *        display that information to the client.
74  *
75  * OS DEPENDENCIES
76  *        The code currently assumes a POSIX password entry.  How should
77  *        Windows and Mac users be handled?
78  *
79  *-------------------------------------------------------------------------
80  */
81
82 #include "postgres_fe.h"
83
84 #include <sys/types.h>
85 #include <signal.h>
86 #include <fcntl.h>
87 #include <errno.h>
88 #include <ctype.h>
89 #include <string.h>
90
91 #include "libpq-fe.h"
92 #include "libpq-int.h"
93 #include "fe-auth.h"
94 #include "pqsignal.h"
95
96 #ifdef WIN32
97 #include "win32.h"
98 #else
99 #include <sys/socket.h>
100 #include <unistd.h>
101 #include <netdb.h>
102 #include <netinet/in.h>
103 #ifdef HAVE_NETINET_TCP_H
104 #include <netinet/tcp.h>
105 #endif
106 #include <arpa/inet.h>
107 #endif
108
109 #ifdef ENABLE_THREAD_SAFETY
110 #include <pthread.h>
111 #endif
112
113 #ifndef HAVE_STRDUP
114 #include "strdup.h"
115 #endif
116
117 #ifndef WIN32
118 #include <pwd.h>
119 #endif
120 #include <sys/stat.h>
121
122 #ifdef USE_SSL
123 #include <openssl/ssl.h>
124 #include <openssl/dh.h>
125 #endif   /* USE_SSL */
126
127
128 #ifdef USE_SSL
129 static int      verify_cb(int ok, X509_STORE_CTX *ctx);
130
131 #ifdef NOT_USED
132 static int      verify_peer(PGconn *);
133 #endif
134 static DH  *load_dh_file(int keylength);
135 static DH  *load_dh_buffer(const char *, size_t);
136 static DH  *tmp_dh_cb(SSL *s, int is_export, int keylength);
137 static int      client_cert_cb(SSL *, X509 **, EVP_PKEY **);
138 static int      init_ssl_system(PGconn *conn);
139 static int      initialize_SSL(PGconn *);
140 static void destroy_SSL(void);
141 static PostgresPollingStatusType open_client_SSL(PGconn *);
142 static void close_SSL(PGconn *);
143 static char *SSLerrmessage(void);
144 static void SSLerrfree(char *buf);
145 #endif
146
147 #ifdef USE_SSL
148 bool pq_initssllib = true;
149
150 static SSL_CTX *SSL_context = NULL;
151 #endif
152
153 #ifdef ENABLE_THREAD_SAFETY
154 static void sigpipe_handler_ignore_send(int signo);
155 pthread_key_t thread_in_send;
156 #endif
157
158 /* ------------------------------------------------------------ */
159 /*                                               Hardcoded values                                               */
160 /* ------------------------------------------------------------ */
161
162 /*
163  *      Hardcoded DH parameters, used in empheral DH keying.
164  *      As discussed above, EDH protects the confidentiality of
165  *      sessions even if the static private key is compromised,
166  *      so we are *highly* motivated to ensure that we can use
167  *      EDH even if the user... or an attacker... deletes the
168  *      $HOME/.postgresql/dh*.pem files.
169  *
170  *      It's not critical that users have EPH keys, but it doesn't
171  *      hurt and if it's missing someone will demand it, so....
172  */
173 #ifdef USE_SSL
174
175 static const char file_dh512[] =
176 "-----BEGIN DH PARAMETERS-----\n\
177 MEYCQQD1Kv884bEpQBgRjXyEpwpy1obEAxnIByl6ypUM2Zafq9AKUJsCRtMIPWak\n\
178 XUGfnHy9iUsiGSa6q6Jew1XpKgVfAgEC\n\
179 -----END DH PARAMETERS-----\n";
180
181 static const char file_dh1024[] =
182 "-----BEGIN DH PARAMETERS-----\n\
183 MIGHAoGBAPSI/VhOSdvNILSd5JEHNmszbDgNRR0PfIizHHxbLY7288kjwEPwpVsY\n\
184 jY67VYy4XTjTNP18F1dDox0YbN4zISy1Kv884bEpQBgRjXyEpwpy1obEAxnIByl6\n\
185 ypUM2Zafq9AKUJsCRtMIPWakXUGfnHy9iUsiGSa6q6Jew1XpL3jHAgEC\n\
186 -----END DH PARAMETERS-----\n";
187
188 static const char file_dh2048[] =
189 "-----BEGIN DH PARAMETERS-----\n\
190 MIIBCAKCAQEA9kJXtwh/CBdyorrWqULzBej5UxE5T7bxbrlLOCDaAadWoxTpj0BV\n\
191 89AHxstDqZSt90xkhkn4DIO9ZekX1KHTUPj1WV/cdlJPPT2N286Z4VeSWc39uK50\n\
192 T8X8dryDxUcwYc58yWb/Ffm7/ZFexwGq01uejaClcjrUGvC/RgBYK+X0iP1YTknb\n\
193 zSC0neSRBzZrM2w4DUUdD3yIsxx8Wy2O9vPJI8BD8KVbGI2Ou1WMuF040zT9fBdX\n\
194 Q6MdGGzeMyEstSr/POGxKUAYEY18hKcKctaGxAMZyAcpesqVDNmWn6vQClCbAkbT\n\
195 CD1mpF1Bn5x8vYlLIhkmuquiXsNV6TILOwIBAg==\n\
196 -----END DH PARAMETERS-----\n";
197
198 static const char file_dh4096[] =
199 "-----BEGIN DH PARAMETERS-----\n\
200 MIICCAKCAgEA+hRyUsFN4VpJ1O8JLcCo/VWr19k3BCgJ4uk+d+KhehjdRqNDNyOQ\n\
201 l/MOyQNQfWXPeGKmOmIig6Ev/nm6Nf9Z2B1h3R4hExf+zTiHnvVPeRBhjdQi81rt\n\
202 Xeoh6TNrSBIKIHfUJWBh3va0TxxjQIs6IZOLeVNRLMqzeylWqMf49HsIXqbcokUS\n\
203 Vt1BkvLdW48j8PPv5DsKRN3tloTxqDJGo9tKvj1Fuk74A+Xda1kNhB7KFlqMyN98\n\
204 VETEJ6c7KpfOo30mnK30wqw3S8OtaIR/maYX72tGOno2ehFDkq3pnPtEbD2CScxc\n\
205 alJC+EL7RPk5c/tgeTvCngvc1KZn92Y//EI7G9tPZtylj2b56sHtMftIoYJ9+ODM\n\
206 sccD5Piz/rejE3Ome8EOOceUSCYAhXn8b3qvxVI1ddd1pED6FHRhFvLrZxFvBEM9\n\
207 ERRMp5QqOaHJkM+Dxv8Cj6MqrCbfC4u+ZErxodzuusgDgvZiLF22uxMZbobFWyte\n\
208 OvOzKGtwcTqO/1wV5gKkzu1ZVswVUQd5Gg8lJicwqRWyyNRczDDoG9jVDxmogKTH\n\
209 AaqLulO7R8Ifa1SwF2DteSGVtgWEN8gDpN3RBmmPTDngyF2DHb5qmpnznwtFKdTL\n\
210 KWbuHn491xNO25CQWMtem80uKw+pTnisBRF/454n1Jnhub144YRBoN8CAQI=\n\
211 -----END DH PARAMETERS-----\n";
212 #endif
213
214 /* ------------------------------------------------------------ */
215 /*                       Procedures common to all secure sessions                       */
216 /* ------------------------------------------------------------ */
217
218 /*
219  *      Initialize global context
220  */
221 int
222 pqsecure_initialize(PGconn *conn)
223 {
224         int                     r = 0;
225
226 #ifdef USE_SSL
227         r = initialize_SSL(conn);
228 #endif
229
230         return r;
231 }
232
233 /*
234  *      Destroy global context
235  */
236 void
237 pqsecure_destroy(void)
238 {
239 #ifdef USE_SSL
240         destroy_SSL();
241 #endif
242 }
243
244 /*
245  *      Attempt to negotiate secure session.
246  */
247 PostgresPollingStatusType
248 pqsecure_open_client(PGconn *conn)
249 {
250 #ifdef USE_SSL
251         /* First time through? */
252         if (conn->ssl == NULL)
253         {
254                 if (!(conn->ssl = SSL_new(SSL_context)) ||
255                         !SSL_set_app_data(conn->ssl, conn) ||
256                         !SSL_set_fd(conn->ssl, conn->sock))
257                 {
258                         char *err = SSLerrmessage();
259                         printfPQExpBuffer(&conn->errorMessage,
260                            libpq_gettext("could not establish SSL connection: %s\n"),
261                                                           err);
262                         SSLerrfree(err);
263                         close_SSL(conn);
264                         return PGRES_POLLING_FAILED;
265                 }
266         }
267         /* Begin or continue the actual handshake */
268         return open_client_SSL(conn);
269 #else
270         /* shouldn't get here */
271         return PGRES_POLLING_FAILED;
272 #endif
273 }
274
275 /*
276  *      Close secure session.
277  */
278 void
279 pqsecure_close(PGconn *conn)
280 {
281 #ifdef USE_SSL
282         if (conn->ssl)
283                 close_SSL(conn);
284 #endif
285 }
286
287 /*
288  *      Read data from a secure connection.
289  */
290 ssize_t
291 pqsecure_read(PGconn *conn, void *ptr, size_t len)
292 {
293         ssize_t         n;
294
295 #ifdef USE_SSL
296         if (conn->ssl)
297         {
298 rloop:
299                 n = SSL_read(conn->ssl, ptr, len);
300                 switch (SSL_get_error(conn->ssl, n))
301                 {
302                         case SSL_ERROR_NONE:
303                                 break;
304                         case SSL_ERROR_WANT_READ:
305                                 n = 0;
306                                 break;
307                         case SSL_ERROR_WANT_WRITE:
308
309                                 /*
310                                  * Returning 0 here would cause caller to wait for
311                                  * read-ready, which is not correct since what SSL wants
312                                  * is wait for write-ready.  The former could get us stuck
313                                  * in an infinite wait, so don't risk it; busy-loop
314                                  * instead.
315                                  */
316                                 goto rloop;
317                         case SSL_ERROR_SYSCALL:
318                                 {
319                                         char            sebuf[256];
320
321                                         if (n == -1)
322                                                 printfPQExpBuffer(&conn->errorMessage,
323                                                                 libpq_gettext("SSL SYSCALL error: %s\n"),
324                                                 SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
325                                         else
326                                         {
327                                                 printfPQExpBuffer(&conn->errorMessage,
328                                                                                   libpq_gettext("SSL SYSCALL error: EOF detected\n"));
329
330                                                 SOCK_ERRNO_SET(ECONNRESET);
331                                                 n = -1;
332                                         }
333                                         break;
334                                 }
335                         case SSL_ERROR_SSL:
336                                 {
337                                         char *err = SSLerrmessage();
338                                         printfPQExpBuffer(&conn->errorMessage,
339                                                   libpq_gettext("SSL error: %s\n"), err);
340                                         SSLerrfree(err);
341                                 }
342                                 /* fall through */
343                         case SSL_ERROR_ZERO_RETURN:
344                                 SOCK_ERRNO_SET(ECONNRESET);
345                                 n = -1;
346                                 break;
347                         default:
348                                 printfPQExpBuffer(&conn->errorMessage,
349                                                           libpq_gettext("unrecognized SSL error code\n"));
350                                 n = -1;
351                                 break;
352                 }
353         }
354         else
355 #endif
356                 n = recv(conn->sock, ptr, len, 0);
357
358         return n;
359 }
360
361 /*
362  *      Write data to a secure connection.
363  */
364 ssize_t
365 pqsecure_write(PGconn *conn, const void *ptr, size_t len)
366 {
367         ssize_t         n;
368
369 #ifdef ENABLE_THREAD_SAFETY
370         pthread_setspecific(thread_in_send, "t");
371 #else
372 #ifndef WIN32
373         pqsigfunc       oldsighandler = pqsignal(SIGPIPE, SIG_IGN);
374 #endif
375 #endif
376
377 #ifdef USE_SSL
378         if (conn->ssl)
379         {
380                 n = SSL_write(conn->ssl, ptr, len);
381                 switch (SSL_get_error(conn->ssl, n))
382                 {
383                         case SSL_ERROR_NONE:
384                                 break;
385                         case SSL_ERROR_WANT_READ:
386
387                                 /*
388                                  * Returning 0 here causes caller to wait for write-ready,
389                                  * which is not really the right thing, but it's the best
390                                  * we can do.
391                                  */
392                                 n = 0;
393                                 break;
394                         case SSL_ERROR_WANT_WRITE:
395                                 n = 0;
396                                 break;
397                         case SSL_ERROR_SYSCALL:
398                                 {
399                                         char            sebuf[256];
400
401                                         if (n == -1)
402                                                 printfPQExpBuffer(&conn->errorMessage,
403                                                                 libpq_gettext("SSL SYSCALL error: %s\n"),
404                                                 SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
405                                         else
406                                         {
407                                                 printfPQExpBuffer(&conn->errorMessage,
408                                                                                   libpq_gettext("SSL SYSCALL error: EOF detected\n"));
409                                                 SOCK_ERRNO_SET(ECONNRESET);
410                                                 n = -1;
411                                         }
412                                         break;
413                                 }
414                         case SSL_ERROR_SSL:
415                                 {
416                                         char *err = SSLerrmessage();
417                                         printfPQExpBuffer(&conn->errorMessage,
418                                                   libpq_gettext("SSL error: %s\n"), err);
419                                         SSLerrfree(err);
420                                 }
421                                 /* fall through */
422                         case SSL_ERROR_ZERO_RETURN:
423                                 SOCK_ERRNO_SET(ECONNRESET);
424                                 n = -1;
425                                 break;
426                         default:
427                                 printfPQExpBuffer(&conn->errorMessage,
428                                                           libpq_gettext("unrecognized SSL error code\n"));
429                                 n = -1;
430                                 break;
431                 }
432         }
433         else
434 #endif
435                 n = send(conn->sock, ptr, len, 0);
436
437 #ifdef ENABLE_THREAD_SAFETY
438         pthread_setspecific(thread_in_send, "f");
439 #else
440 #ifndef WIN32
441         pqsignal(SIGPIPE, oldsighandler);
442 #endif
443 #endif
444
445         return n;
446 }
447
448 /* ------------------------------------------------------------ */
449 /*                                                SSL specific code                                             */
450 /* ------------------------------------------------------------ */
451 #ifdef USE_SSL
452 /*
453  *      Certificate verification callback
454  *
455  *      This callback allows us to log intermediate problems during
456  *      verification, but there doesn't seem to be a clean way to get
457  *      our PGconn * structure.  So we can't log anything!
458  *
459  *      This callback also allows us to override the default acceptance
460  *      criteria (e.g., accepting self-signed or expired certs), but
461  *      for now we accept the default checks.
462  */
463 static int
464 verify_cb(int ok, X509_STORE_CTX *ctx)
465 {
466         return ok;
467 }
468
469 #ifdef NOT_USED
470 /*
471  *      Verify that common name resolves to peer.
472  */
473 static int
474 verify_peer(PGconn *conn)
475 {
476         struct hostent *h = NULL;
477         struct sockaddr addr;
478         struct sockaddr_in *sin;
479         socklen_t       len;
480         char      **s;
481         unsigned long l;
482
483         /* get the address on the other side of the socket */
484         len = sizeof(addr);
485         if (getpeername(conn->sock, &addr, &len) == -1)
486         {
487                 char            sebuf[256];
488
489                 printfPQExpBuffer(&conn->errorMessage,
490                                                   libpq_gettext("error querying socket: %s\n"),
491                                                 SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
492                 return -1;
493         }
494
495         /* weird, but legal case */
496         if (addr.sa_family == AF_UNIX)
497                 return 0;
498
499         {
500                 struct hostent hpstr;
501                 char            buf[BUFSIZ];
502                 int                     herrno = 0;
503                 
504                 /*
505                  *      Currently, pqGethostbyname() is used only on platforms that
506                  *      don't have getaddrinfo().  If you enable this function,
507                  *      you should convert the pqGethostbyname() function call to
508                  *      use getaddrinfo().
509                  */
510                 pqGethostbyname(conn->peer_cn, &hpstr, buf, sizeof(buf),
511                                                 &h, &herrno);
512         }
513
514         /* what do we know about the peer's common name? */
515         if (h == NULL)
516         {
517                 printfPQExpBuffer(&conn->errorMessage,
518                 libpq_gettext("could not get information about host (%s): %s\n"),
519                                                   conn->peer_cn, hstrerror(h_errno));
520                 return -1;
521         }
522
523         /* does the address match? */
524         switch (addr.sa_family)
525         {
526                 case AF_INET:
527                         sin = (struct sockaddr_in *) & addr;
528                         for (s = h->h_addr_list; *s != NULL; s++)
529                         {
530                                 if (!memcmp(&sin->sin_addr.s_addr, *s, h->h_length))
531                                         return 0;
532                         }
533                         break;
534
535                 default:
536                         printfPQExpBuffer(&conn->errorMessage,
537                                                           libpq_gettext("unsupported protocol\n"));
538                         return -1;
539         }
540
541         /*
542          * the prior test should be definitive, but in practice it sometimes
543          * fails.  So we also check the aliases.
544          */
545         for (s = h->h_aliases; *s != NULL; s++)
546         {
547                 if (pg_strcasecmp(conn->peer_cn, *s) == 0)
548                         return 0;
549         }
550
551         /* generate protocol-aware error message */
552         switch (addr.sa_family)
553         {
554                 case AF_INET:
555                         sin = (struct sockaddr_in *) & addr;
556                         l = ntohl(sin->sin_addr.s_addr);
557                         printfPQExpBuffer(&conn->errorMessage,
558                                                           libpq_gettext(
559                                                                                         "server common name \"%s\" does not resolve to %ld.%ld.%ld.%ld\n"),
560                                          conn->peer_cn, (l >> 24) % 0x100, (l >> 16) % 0x100,
561                                                           (l >> 8) % 0x100, l % 0x100);
562                         break;
563                 default:
564                         printfPQExpBuffer(&conn->errorMessage,
565                                                           libpq_gettext(
566                                                                                         "server common name \"%s\" does not resolve to peer address\n"),
567                                                           conn->peer_cn);
568         }
569
570         return -1;
571 }
572 #endif
573
574 /*
575  *      Load precomputed DH parameters.
576  *
577  *      To prevent "downgrade" attacks, we perform a number of checks
578  *      to verify that the DBA-generated DH parameters file contains
579  *      what we expect it to contain.
580  */
581 static DH  *
582 load_dh_file(int keylength)
583 {
584 #ifdef WIN32
585     return NULL;
586 #else
587         char            pwdbuf[BUFSIZ];
588         struct passwd pwdstr;
589         struct passwd *pwd = NULL;
590         FILE       *fp;
591         char            fnbuf[2048];
592         DH                 *dh = NULL;
593         int                     codes;
594
595         if (pqGetpwuid(getuid(), &pwdstr, pwdbuf, sizeof(pwdbuf), &pwd) == 0)
596                 return NULL;
597
598         /* attempt to open file.  It's not an error if it doesn't exist. */
599         snprintf(fnbuf, sizeof fnbuf, "%s/.postgresql/dh%d.pem",
600                          pwd->pw_dir, keylength);
601
602         if ((fp = fopen(fnbuf, "r")) == NULL)
603                 return NULL;
604
605 /*      flock(fileno(fp), LOCK_SH); */
606         dh = PEM_read_DHparams(fp, NULL, NULL, NULL);
607 /*      flock(fileno(fp), LOCK_UN); */
608         fclose(fp);
609
610         /* is the prime the correct size? */
611         if (dh != NULL && 8 * DH_size(dh) < keylength)
612                 dh = NULL;
613
614         /* make sure the DH parameters are usable */
615         if (dh != NULL)
616         {
617                 if (DH_check(dh, &codes))
618                         return NULL;
619                 if (codes & DH_CHECK_P_NOT_PRIME)
620                         return NULL;
621                 if ((codes & DH_NOT_SUITABLE_GENERATOR) &&
622                         (codes & DH_CHECK_P_NOT_SAFE_PRIME))
623                         return NULL;
624         }
625
626         return dh;
627 #endif
628 }
629
630 /*
631  *      Load hardcoded DH parameters.
632  *
633  *      To prevent problems if the DH parameters files don't even
634  *      exist, we can load DH parameters hardcoded into this file.
635  */
636 static DH  *
637 load_dh_buffer(const char *buffer, size_t len)
638 {
639         BIO                *bio;
640         DH                 *dh = NULL;
641
642         bio = BIO_new_mem_buf((char *) buffer, len);
643         if (bio == NULL)
644                 return NULL;
645         dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
646         BIO_free(bio);
647
648         return dh;
649 }
650
651 /*
652  *      Generate an empheral DH key.  Because this can take a long
653  *      time to compute, we can use precomputed parameters of the
654  *      common key sizes.
655  *
656  *      Since few sites will bother to precompute these parameter
657  *      files, we also provide a fallback to the parameters provided
658  *      by the OpenSSL project.
659  *
660  *      These values can be static (once loaded or computed) since
661  *      the OpenSSL library can efficiently generate random keys from
662  *      the information provided.
663  */
664 static DH  *
665 tmp_dh_cb(SSL *s, int is_export, int keylength)
666 {
667         DH                 *r = NULL;
668         static DH  *dh = NULL;
669         static DH  *dh512 = NULL;
670         static DH  *dh1024 = NULL;
671         static DH  *dh2048 = NULL;
672         static DH  *dh4096 = NULL;
673
674         switch (keylength)
675         {
676                 case 512:
677                         if (dh512 == NULL)
678                                 dh512 = load_dh_file(keylength);
679                         if (dh512 == NULL)
680                                 dh512 = load_dh_buffer(file_dh512, sizeof file_dh512);
681                         r = dh512;
682                         break;
683
684                 case 1024:
685                         if (dh1024 == NULL)
686                                 dh1024 = load_dh_file(keylength);
687                         if (dh1024 == NULL)
688                                 dh1024 = load_dh_buffer(file_dh1024, sizeof file_dh1024);
689                         r = dh1024;
690                         break;
691
692                 case 2048:
693                         if (dh2048 == NULL)
694                                 dh2048 = load_dh_file(keylength);
695                         if (dh2048 == NULL)
696                                 dh2048 = load_dh_buffer(file_dh2048, sizeof file_dh2048);
697                         r = dh2048;
698                         break;
699
700                 case 4096:
701                         if (dh4096 == NULL)
702                                 dh4096 = load_dh_file(keylength);
703                         if (dh4096 == NULL)
704                                 dh4096 = load_dh_buffer(file_dh4096, sizeof file_dh4096);
705                         r = dh4096;
706                         break;
707
708                 default:
709                         if (dh == NULL)
710                                 dh = load_dh_file(keylength);
711                         r = dh;
712         }
713
714         /* this may take a long time, but it may be necessary... */
715         if (r == NULL || 8 * DH_size(r) < keylength)
716                 r = DH_generate_parameters(keylength, DH_GENERATOR_2, NULL, NULL);
717
718         return r;
719 }
720
721 /*
722  *      Callback used by SSL to load client cert and key.
723  *      This callback is only called when the server wants a
724  *      client cert.
725  *
726  *      Returns 1 on success, 0 on no data, -1 on error.
727  */
728 static int
729 client_cert_cb(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
730 {
731 #ifdef WIN32
732    return 0;
733 #else
734         char            pwdbuf[BUFSIZ];
735         struct passwd pwdstr;
736         struct passwd *pwd = NULL;
737         struct stat buf,
738                                 buf2;
739         char            fnbuf[2048];
740         FILE       *fp;
741         PGconn     *conn = (PGconn *) SSL_get_app_data(ssl);
742         int                     (*cb) () = NULL;        /* how to read user password */
743         char            sebuf[256];
744
745
746         if (pqGetpwuid(getuid(), &pwdstr, pwdbuf, sizeof(pwdbuf), &pwd) == 0)
747         {
748                 printfPQExpBuffer(&conn->errorMessage,
749                                           libpq_gettext("could not get user information\n"));
750                 return -1;
751         }
752
753         /* read the user certificate */
754         snprintf(fnbuf, sizeof fnbuf, "%s/.postgresql/postgresql.crt",
755                          pwd->pw_dir);
756         if (stat(fnbuf, &buf) == -1)
757                 return 0;
758         if ((fp = fopen(fnbuf, "r")) == NULL)
759         {
760                 printfPQExpBuffer(&conn->errorMessage,
761                                   libpq_gettext("could not open certificate (%s): %s\n"),
762                                                   fnbuf, pqStrerror(errno, sebuf, sizeof(sebuf)));
763                 return -1;
764         }
765         if (PEM_read_X509(fp, x509, NULL, NULL) == NULL)
766         {
767                 char *err = SSLerrmessage();
768                 printfPQExpBuffer(&conn->errorMessage,
769                                   libpq_gettext("could not read certificate (%s): %s\n"),
770                                                   fnbuf, err);
771                 SSLerrfree(err);
772                 fclose(fp);
773                 return -1;
774         }
775         fclose(fp);
776
777         /* read the user key */
778         snprintf(fnbuf, sizeof fnbuf, "%s/.postgresql/postgresql.key",
779                          pwd->pw_dir);
780         if (stat(fnbuf, &buf) == -1)
781         {
782                 printfPQExpBuffer(&conn->errorMessage,
783                 libpq_gettext("certificate present, but not private key (%s)\n"),
784                                                   fnbuf);
785                 X509_free(*x509);
786                 return 0;
787         }
788         if (!S_ISREG(buf.st_mode) || (buf.st_mode & 0077) ||
789                 buf.st_uid != getuid())
790         {
791                 printfPQExpBuffer(&conn->errorMessage,
792                 libpq_gettext("private key (%s) has wrong permissions\n"), fnbuf);
793                 X509_free(*x509);
794                 return -1;
795         }
796         if ((fp = fopen(fnbuf, "r")) == NULL)
797         {
798                 printfPQExpBuffer(&conn->errorMessage,
799                          libpq_gettext("could not open private key file (%s): %s\n"),
800                                                   fnbuf, pqStrerror(errno, sebuf, sizeof(sebuf)));
801                 X509_free(*x509);
802                 return -1;
803         }
804         if (fstat(fileno(fp), &buf2) == -1 ||
805                 buf.st_dev != buf2.st_dev || buf.st_ino != buf2.st_ino)
806         {
807                 printfPQExpBuffer(&conn->errorMessage,
808                                                   libpq_gettext("private key (%s) changed during execution\n"), fnbuf);
809                 X509_free(*x509);
810                 return -1;
811         }
812         if (PEM_read_PrivateKey(fp, pkey, cb, NULL) == NULL)
813         {
814                 char *err = SSLerrmessage();
815                 printfPQExpBuffer(&conn->errorMessage,
816                                   libpq_gettext("could not read private key (%s): %s\n"),
817                                                   fnbuf, err);
818                 SSLerrfree(err);
819                 X509_free(*x509);
820                 fclose(fp);
821                 return -1;
822         }
823         fclose(fp);
824
825         /* verify that the cert and key go together */
826         if (!X509_check_private_key(*x509, *pkey))
827         {
828                 char *err = SSLerrmessage();
829                 printfPQExpBuffer(&conn->errorMessage,
830                         libpq_gettext("certificate/private key mismatch (%s): %s\n"),
831                                                   fnbuf, err);
832                 SSLerrfree(err);
833                 X509_free(*x509);
834                 EVP_PKEY_free(*pkey);
835                 return -1;
836         }
837
838         return 1;
839 #endif
840 }
841
842 #ifdef ENABLE_THREAD_SAFETY
843
844 static unsigned long
845 pq_threadidcallback(void)
846 {
847         return (unsigned long)pthread_self();
848 }
849
850 static pthread_mutex_t *pq_lockarray;
851 static void
852 pq_lockingcallback(int mode, int n, const char *file, int line)
853 {
854         if (mode & CRYPTO_LOCK) {
855                 pthread_mutex_lock(&pq_lockarray[n]);
856         } else {
857                 pthread_mutex_unlock(&pq_lockarray[n]);
858         }
859 }
860
861 #endif /* ENABLE_THREAD_SAFETY */
862
863 static int
864 init_ssl_system(PGconn *conn)
865 {
866 #ifdef ENABLE_THREAD_SAFETY
867 static pthread_mutex_t init_mutex = PTHREAD_MUTEX_INITIALIZER;
868
869         pthread_mutex_lock(&init_mutex);
870         
871         if (pq_initssllib && pq_lockarray == NULL) {
872                 int i;
873                 CRYPTO_set_id_callback(pq_threadidcallback);
874
875                 pq_lockarray = malloc(sizeof(pthread_mutex_t)*CRYPTO_num_locks());
876                 if (!pq_lockarray) {
877                         pthread_mutex_unlock(&init_mutex);
878                         return -1;
879                 }
880                 for (i=0;i<CRYPTO_num_locks();i++)
881                         pthread_mutex_init(&pq_lockarray[i], NULL);
882
883                 CRYPTO_set_locking_callback(pq_lockingcallback);
884         }
885 #endif
886         if (!SSL_context)
887         {
888                 if (pq_initssllib) {
889                         SSL_library_init();
890                         SSL_load_error_strings();
891                 }
892                 SSL_context = SSL_CTX_new(TLSv1_method());
893                 if (!SSL_context)
894                 {
895                         char *err = SSLerrmessage();
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(&init_mutex);
902 #endif
903                         return -1;
904                 }
905         }
906 #ifdef ENABLE_THREAD_SAFETY
907         pthread_mutex_unlock(&init_mutex);
908 #endif
909         return 0;
910 }
911 /*
912  *      Initialize global SSL context.
913  */
914 static int
915 initialize_SSL(PGconn *conn)
916 {
917 #ifndef WIN32
918         struct stat buf;
919         char            pwdbuf[BUFSIZ];
920         struct passwd pwdstr;
921         struct passwd *pwd = NULL;
922         char            fnbuf[2048];
923 #endif
924
925         if(init_ssl_system(conn))
926                 return -1;
927
928 #ifndef WIN32
929         if (pqGetpwuid(getuid(), &pwdstr, pwdbuf, sizeof(pwdbuf), &pwd) == 0)
930         {
931                 snprintf(fnbuf, sizeof fnbuf, "%s/.postgresql/root.crt",
932                                  pwd->pw_dir);
933                 if (stat(fnbuf, &buf) == -1)
934                 {
935                         return 0;
936 #ifdef NOT_USED
937                         char            sebuf[256];
938
939                         /* CLIENT CERTIFICATES NOT REQUIRED  bjm 2002-09-26 */
940                         printfPQExpBuffer(&conn->errorMessage,
941                                                           libpq_gettext("could not read root certificate list (%s): %s\n"),
942                                                  fnbuf, pqStrerror(errno, sebuf, sizeof(sebuf)));
943                         return -1;
944 #endif
945                 }
946                 if (!SSL_CTX_load_verify_locations(SSL_context, fnbuf, 0))
947                 {
948                         char *err = SSLerrmessage();
949                         printfPQExpBuffer(&conn->errorMessage,
950                                                           libpq_gettext("could not read root certificate list (%s): %s\n"),
951                                                           fnbuf, err);
952                         SSLerrfree(err);
953                         return -1;
954                 }
955         }
956
957         SSL_CTX_set_verify(SSL_context,
958                    SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, verify_cb);
959         SSL_CTX_set_verify_depth(SSL_context, 1);
960
961         /* set up empheral DH keys */
962         SSL_CTX_set_tmp_dh_callback(SSL_context, tmp_dh_cb);
963         SSL_CTX_set_options(SSL_context, SSL_OP_SINGLE_DH_USE);
964
965         /* set up mechanism to provide client certificate, if available */
966         SSL_CTX_set_client_cert_cb(SSL_context, client_cert_cb);
967 #endif
968
969         return 0;
970 }
971
972 /*
973  *      Destroy global SSL context.
974  */
975 static void
976 destroy_SSL(void)
977 {
978         if (SSL_context)
979         {
980                 SSL_CTX_free(SSL_context);
981                 SSL_context = NULL;
982         }
983 }
984
985 /*
986  *      Attempt to negotiate SSL connection.
987  */
988 static PostgresPollingStatusType
989 open_client_SSL(PGconn *conn)
990 {
991         int                     r;
992
993         r = SSL_connect(conn->ssl);
994         if (r <= 0)
995         {
996                 switch (SSL_get_error(conn->ssl, r))
997                 {
998                         case SSL_ERROR_WANT_READ:
999                                 return PGRES_POLLING_READING;
1000
1001                         case SSL_ERROR_WANT_WRITE:
1002                                 return PGRES_POLLING_WRITING;
1003
1004                         case SSL_ERROR_SYSCALL:
1005                                 {
1006                                         char            sebuf[256];
1007
1008                                         if (r == -1)
1009                                                 printfPQExpBuffer(&conn->errorMessage,
1010                                                                 libpq_gettext("SSL SYSCALL error: %s\n"),
1011                                                 SOCK_STRERROR(SOCK_ERRNO, sebuf, sizeof(sebuf)));
1012                                         else
1013                                                 printfPQExpBuffer(&conn->errorMessage,
1014                                                                                   libpq_gettext("SSL SYSCALL error: EOF detected\n"));
1015                                         close_SSL(conn);
1016                                         return PGRES_POLLING_FAILED;
1017                                 }
1018                         case SSL_ERROR_SSL:
1019                                 {
1020                                         char *err = SSLerrmessage();
1021                                         printfPQExpBuffer(&conn->errorMessage,
1022                                                   libpq_gettext("SSL error: %s\n"), err);
1023                                         SSLerrfree(err);
1024                                         close_SSL(conn);
1025                                         return PGRES_POLLING_FAILED;
1026                                 }
1027
1028                         default:
1029                                 printfPQExpBuffer(&conn->errorMessage,
1030                                                           libpq_gettext("unrecognized SSL error code\n"));
1031                                 close_SSL(conn);
1032                                 return PGRES_POLLING_FAILED;
1033                 }
1034         }
1035
1036         /* check the certificate chain of the server */
1037
1038 #ifdef NOT_USED
1039         /* CLIENT CERTIFICATES NOT REQUIRED  bjm 2002-09-26 */
1040
1041         /*
1042          * this eliminates simple man-in-the-middle attacks and simple
1043          * impersonations
1044          */
1045         r = SSL_get_verify_result(conn->ssl);
1046         if (r != X509_V_OK)
1047         {
1048                 printfPQExpBuffer(&conn->errorMessage,
1049                            libpq_gettext("certificate could not be validated: %s\n"),
1050                                                   X509_verify_cert_error_string(r));
1051                 close_SSL(conn);
1052                 return PGRES_POLLING_FAILED;
1053         }
1054 #endif
1055
1056         /* pull out server distinguished and common names */
1057         conn->peer = SSL_get_peer_certificate(conn->ssl);
1058         if (conn->peer == NULL)
1059         {
1060                 char *err = SSLerrmessage();
1061                 printfPQExpBuffer(&conn->errorMessage,
1062                                 libpq_gettext("certificate could not be obtained: %s\n"),
1063                                                   err);
1064                 SSLerrfree(err);
1065                 close_SSL(conn);
1066                 return PGRES_POLLING_FAILED;
1067         }
1068
1069         X509_NAME_oneline(X509_get_subject_name(conn->peer),
1070                                           conn->peer_dn, sizeof(conn->peer_dn));
1071         conn->peer_dn[sizeof(conn->peer_dn) - 1] = '\0';
1072
1073         X509_NAME_get_text_by_NID(X509_get_subject_name(conn->peer),
1074                                                           NID_commonName, conn->peer_cn, SM_USER);
1075         conn->peer_cn[SM_USER] = '\0';
1076
1077         /* verify that the common name resolves to peer */
1078
1079 #ifdef NOT_USED
1080         /* CLIENT CERTIFICATES NOT REQUIRED  bjm 2002-09-26 */
1081
1082         /*
1083          * this is necessary to eliminate man-in-the-middle attacks and
1084          * impersonations where the attacker somehow learned the server's
1085          * private key
1086          */
1087         if (verify_peer(conn) == -1)
1088         {
1089                 close_SSL(conn);
1090                 return PGRES_POLLING_FAILED;
1091         }
1092 #endif
1093
1094         /* SSL handshake is complete */
1095         return PGRES_POLLING_OK;
1096 }
1097
1098 /*
1099  *      Close SSL connection.
1100  */
1101 static void
1102 close_SSL(PGconn *conn)
1103 {
1104         if (conn->ssl)
1105         {
1106                 SSL_shutdown(conn->ssl);
1107                 SSL_free(conn->ssl);
1108                 conn->ssl = NULL;
1109         }
1110
1111         if (conn->peer)
1112         {
1113                 X509_free(conn->peer);
1114                 conn->peer = NULL;
1115         }
1116 }
1117
1118 /*
1119  * Obtain reason string for last SSL error
1120  *
1121  * Some caution is needed here since ERR_reason_error_string will
1122  * return NULL if it doesn't recognize the error code.  We don't
1123  * want to return NULL ever.
1124  */
1125 static char ssl_nomem[] = "Out of memory allocating error description";
1126 #define SSL_ERR_LEN     128
1127
1128 static char *
1129 SSLerrmessage(void)
1130 {
1131         unsigned long errcode;
1132         const char *errreason;
1133         char *errbuf;
1134
1135         errbuf = malloc(SSL_ERR_LEN);
1136         if (!errbuf)
1137                 return ssl_nomem;
1138         errcode = ERR_get_error();
1139         if (errcode == 0) {
1140                 strcpy(errbuf, "No SSL error reported");
1141                 return errbuf;
1142         }
1143         errreason = ERR_reason_error_string(errcode);
1144         if (errreason != NULL) {
1145                 strncpy(errbuf, errreason, SSL_ERR_LEN-1);
1146                 errbuf[SSL_ERR_LEN-1] = '\0';
1147                 return errbuf;
1148         }
1149         snprintf(errbuf, SSL_ERR_LEN, "SSL error code %lu", errcode);
1150         return errbuf;
1151 }
1152
1153 static void
1154 SSLerrfree(char *buf)
1155 {
1156         if (buf != ssl_nomem)
1157                 free(buf);
1158 }
1159 /*
1160  *      Return pointer to SSL object.
1161  */
1162 SSL *
1163 PQgetssl(PGconn *conn)
1164 {
1165         if (!conn)
1166                 return NULL;
1167         return conn->ssl;
1168 }
1169
1170 #endif   /* USE_SSL */
1171
1172
1173 #ifdef ENABLE_THREAD_SAFETY
1174 /*
1175  *      Check SIGPIPE handler and perhaps install our own.
1176  */
1177 void
1178 check_sigpipe_handler(void)
1179 {
1180         pqsigfunc pipehandler;
1181
1182         /*
1183          *      If the app hasn't set a SIGPIPE handler, define our own
1184          *      that ignores SIGPIPE on libpq send() and does SIG_DFL
1185          *      for other SIGPIPE cases.
1186          */
1187         pipehandler = pqsignalinquire(SIGPIPE);
1188         if (pipehandler == SIG_DFL)     /* not set by application */
1189         {
1190                 /*
1191                  *      Create key first because the signal handler might be called
1192                  *      right after being installed.
1193                  */
1194                 pthread_key_create(&thread_in_send, NULL);      
1195                 pqsignal(SIGPIPE, sigpipe_handler_ignore_send);
1196         }
1197 }
1198
1199 /*
1200  *      Threaded SIGPIPE signal handler
1201  */
1202 void
1203 sigpipe_handler_ignore_send(int signo)
1204 {
1205         /*
1206          *      If we have gotten a SIGPIPE outside send(), exit.
1207          *      Synchronous signals are delivered to the thread
1208          *      that caused the signal.
1209          */
1210         if (!PQinSend())
1211                 exit(128 + SIGPIPE);    /* typical return value for SIG_DFL */
1212 }
1213 #endif
1214  
1215 /*
1216  *      Indicates whether the current thread is in send()
1217  *      For use by SIGPIPE signal handlers;  they should
1218  *      ignore SIGPIPE when libpq is in send().  This means
1219  *      that the backend has died unexpectedly.
1220  */
1221 pqbool
1222 PQinSend(void)
1223 {
1224 #ifdef ENABLE_THREAD_SAFETY
1225         return (pthread_getspecific(thread_in_send) /* has it been set? */ &&
1226                         *(char *)pthread_getspecific(thread_in_send) == 't') ? true : false;
1227 #else
1228         /*
1229          *      No threading: our code ignores SIGPIPE around send().
1230          *      Therefore, we can't be in send() if we are checking
1231          *      from a SIGPIPE signal handler.
1232          */
1233         return false;   
1234 #endif
1235 }