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