]> andersk Git - test.git/blame - libhttp/ssl.c
Removed compiler warning when building without SSL support.
[test.git] / libhttp / ssl.c
CommitLineData
7460295f 1// ssl.c -- Support functions that find and load SSL support, if available
e0bb8a33 2// Copyright (C) 2008-2009 Markus Gutschke <markus@shellinabox.com>
7460295f
MG
3//
4// This program is free software; you can redistribute it and/or modify
5// it under the terms of the GNU General Public License version 2 as
6// published by the Free Software Foundation.
7//
8// This program is distributed in the hope that it will be useful,
9// but WITHOUT ANY WARRANTY; without even the implied warranty of
10// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11// GNU General Public License for more details.
12//
13// You should have received a copy of the GNU General Public License along
14// with this program; if not, write to the Free Software Foundation, Inc.,
15// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16//
17// In addition to these license terms, the author grants the following
18// additional rights:
19//
20// If you modify this program, or any covered work, by linking or
21// combining it with the OpenSSL project's OpenSSL library (or a
22// modified version of that library), containing parts covered by the
23// terms of the OpenSSL or SSLeay licenses, the author
24// grants you additional permission to convey the resulting work.
25// Corresponding Source for a non-source form of such a combination
26// shall include the source code for the parts of OpenSSL used as well
27// as that of the covered work.
28//
29// You may at your option choose to remove this additional permission from
30// the work, or from any part of it.
31//
32// It is possible to build this program in a way that it loads OpenSSL
33// libraries at run-time. If doing so, the following notices are required
34// by the OpenSSL and SSLeay licenses:
35//
36// This product includes software developed by the OpenSSL Project
37// for use in the OpenSSL Toolkit. (http://www.openssl.org/)
38//
39// This product includes cryptographic software written by Eric Young
40// (eay@cryptsoft.com)
41//
42//
43// The most up-to-date version of this program is always available from
44// http://shellinabox.com
45
46#define _GNU_SOURCE
bdd01e84 47#include "config.h"
7460295f 48
c593cf68
MG
49#define pthread_once x_pthread_once
50#define pthread_sigmask x_pthread_sigmask
51
7460295f
MG
52#include <dlfcn.h>
53#include <errno.h>
ad24d9a9 54#include <fcntl.h>
7460295f
MG
55#include <netdb.h>
56#include <signal.h>
57#include <stdlib.h>
58#include <string.h>
ad24d9a9
MG
59#include <sys/types.h>
60#include <sys/stat.h>
7460295f
MG
61#include <unistd.h>
62
63#include "libhttp/ssl.h"
64#include "libhttp/httpconnection.h"
65#include "logging/logging.h"
66
c593cf68
MG
67#undef pthread_once
68#undef pthread_sigmask
69
bdd01e84
MG
70#if defined(HAVE_OPENSSL) && !defined(OPENSSL_NO_TLSEXT) && \
71 defined(TLSEXT_NAMETYPE_host_name) && defined(SSL_TLSEXT_ERR_OK)
d04f7ca7
MG
72#define HAVE_TLSEXT
73#endif
74
7460295f
MG
75#if defined(HAVE_PTHREAD_H)
76// Pthread support is optional. Only enable it, if the library has been
77// linked into the program
78#include <pthread.h>
bf1ec4d2 79#if defined(__linux__)
7460295f 80extern int pthread_once(pthread_once_t *, void (*)(void))__attribute__((weak));
bf1ec4d2 81#endif
7460295f
MG
82extern int pthread_sigmask(int, const sigset_t *, sigset_t *)
83 __attribute__((weak));
84
85#endif
86
bf1ec4d2 87#if defined(HAVE_DLOPEN)
7460295f 88// SSL support is optional. Only enable it, if the library can be loaded.
03cd76e1
MG
89long (*BIO_ctrl)(BIO *, int, long, void *);
90BIO_METHOD * (*BIO_f_buffer)(void);
91void (*BIO_free_all)(BIO *);
92BIO * (*BIO_new)(BIO_METHOD *);
93BIO * (*BIO_new_socket)(int, int);
94BIO * (*BIO_pop)(BIO *);
95BIO * (*BIO_push)(BIO *, BIO *);
96void (*ERR_clear_error)(void);
97void (*ERR_clear_error)(void);
98unsigned long (*ERR_peek_error)(void);
99unsigned long (*ERR_peek_error)(void);
100long (*SSL_CTX_callback_ctrl)(SSL_CTX *, int, void (*)(void));
101int (*SSL_CTX_check_private_key)(const SSL_CTX *);
102long (*SSL_CTX_ctrl)(SSL_CTX *, int, long, void *);
103void (*SSL_CTX_free)(SSL_CTX *);
104SSL_CTX * (*SSL_CTX_new)(SSL_METHOD *);
105int (*SSL_CTX_use_PrivateKey_file)(SSL_CTX *, const char *, int);
dc6575f2
MG
106int (*SSL_CTX_use_PrivateKey_ASN1)(int, SSL_CTX *,
107 const unsigned char *, long);
03cd76e1 108int (*SSL_CTX_use_certificate_file)(SSL_CTX *, const char *, int);
dc6575f2
MG
109int (*SSL_CTX_use_certificate_ASN1)(SSL_CTX *, long,
110 const unsigned char *);
03cd76e1
MG
111long (*SSL_ctrl)(SSL *, int, long, void *);
112void (*SSL_free)(SSL *);
113int (*SSL_get_error)(const SSL *, int);
114void * (*SSL_get_ex_data)(const SSL *, int);
115BIO * (*SSL_get_rbio)(const SSL *);
116const char * (*SSL_get_servername)(const SSL *, int);
117BIO * (*SSL_get_wbio)(const SSL *);
118int (*SSL_library_init)(void);
119SSL * (*SSL_new)(SSL_CTX *);
120int (*SSL_read)(SSL *, void *, int);
121SSL_CTX * (*SSL_set_SSL_CTX)(SSL *, SSL_CTX *);
122void (*SSL_set_accept_state)(SSL *);
123void (*SSL_set_bio)(SSL *, BIO *, BIO *);
124int (*SSL_set_ex_data)(SSL *, int, void *);
125int (*SSL_shutdown)(SSL *);
126int (*SSL_write)(SSL *, const void *, int);
127SSL_METHOD * (*SSLv23_server_method)(void);
ad24d9a9
MG
128X509 * (*d2i_X509)(X509 **px, const unsigned char **in, int len);
129void (*X509_free)(X509 *a);
bf1ec4d2 130#endif
7460295f
MG
131
132static void sslDestroyCachedContext(void *ssl_, char *context_) {
133 struct SSLSupport *ssl = (struct SSLSupport *)ssl_;
134 SSL_CTX *context = (SSL_CTX *)context_;
03cd76e1 135#if defined(HAVE_OPENSSL)
7460295f
MG
136 if (context != ssl->sslContext) {
137 SSL_CTX_free(context);
138 }
03cd76e1
MG
139#else
140 check(!context);
141 check(!ssl->sslContext);
142#endif
7460295f
MG
143}
144
145struct SSLSupport *newSSL(void) {
146 struct SSLSupport *ssl;
147 check(ssl = malloc(sizeof(struct SSLSupport)));
148 initSSL(ssl);
149 return ssl;
150}
151
152void initSSL(struct SSLSupport *ssl) {
153 ssl->enabled = serverSupportsSSL();
154 ssl->sslContext = NULL;
155 ssl->sniCertificatePattern = NULL;
156 ssl->generateMissing = 0;
157 initTrie(&ssl->sniContexts, sslDestroyCachedContext, ssl);
158}
159
160void destroySSL(struct SSLSupport *ssl) {
161 if (ssl) {
162 free(ssl->sniCertificatePattern);
163 destroyTrie(&ssl->sniContexts);
03cd76e1 164#if defined(HAVE_OPENSSL)
7460295f
MG
165 if (ssl->sslContext) {
166 dcheck(!ERR_peek_error());
167 SSL_CTX_free(ssl->sslContext);
168 }
03cd76e1
MG
169#else
170 check(!ssl->sslContext);
171#endif
7460295f
MG
172 }
173}
174
175void deleteSSL(struct SSLSupport *ssl) {
176 destroySSL(ssl);
177 free(ssl);
178}
179
bf1ec4d2 180#if defined(HAVE_OPENSSL) && defined(HAVE_DLOPEN)
10d0a6b0
MG
181static int maybeLoadCrypto(void) {
182 // Some operating systems cannot automatically load dependent dynamic
183 // libraries. As libssl.so can depend on libcrypto.so, we try to load
184 // it, iff we haven't tried loading it before and iff libssl.so does not
185 // work by itself.
186 static int crypto;
187 if (!crypto++) {
188#ifdef RTLD_NOLOAD
189 if (dlopen("libcrypto.so", RTLD_LAZY|RTLD_GLOBAL|RTLD_NOLOAD))
190 return 1;
191 else
192#endif
193 if (dlopen("libcrypto.so", RTLD_LAZY|RTLD_GLOBAL))
194 return 1;
195 }
196 return 0;
197}
198
7460295f 199static void *loadSymbol(const char *lib, const char *fn) {
10d0a6b0
MG
200 int err = NOINTR(dup(2));
201 if (err > 2) {
202 int null = NOINTR(open("/dev/null", O_WRONLY));
203 if (null >= 0) {
204 NOINTR(dup2(null, 2));
205 NOINTR(close(null));
206 }
207 }
7460295f
MG
208 void *dl = RTLD_DEFAULT;
209 void *rc = dlsym(dl, fn);
210 if (!rc) {
10d0a6b0 211 for (int i = 0; i < 2; i++) {
47e62a9c 212#ifdef RTLD_NOLOAD
10d0a6b0 213 dl = dlopen(lib, RTLD_LAZY|RTLD_GLOBAL|RTLD_NOLOAD);
47e62a9c 214#else
10d0a6b0 215 dl = NULL;
47e62a9c 216#endif
10d0a6b0
MG
217 if (dl == NULL) {
218 dl = dlopen(lib, RTLD_LAZY|RTLD_GLOBAL);
219 }
220 if (dl != NULL || !maybeLoadCrypto()) {
221 break;
222 }
7460295f
MG
223 }
224 if (dl != NULL) {
10d0a6b0
MG
225 rc = dlsym(RTLD_DEFAULT, fn);
226 if (rc == NULL && maybeLoadCrypto()) {
227 rc = dlsym(RTLD_DEFAULT, fn);
228 }
7460295f
MG
229 }
230 }
10d0a6b0
MG
231 if (err > 2) {
232 NOINTR(dup2(err, 2));
233 }
234 NOINTR(close(err));
7460295f
MG
235 return rc;
236}
237
238static void loadSSL(void) {
239 check(!SSL_library_init);
240 struct {
88b579e2
MG
241 union {
242 void *avoid_gcc_warning_about_type_punning;
243 void **var;
244 };
7460295f
MG
245 const char *fn;
246 } symbols[] = {
03cd76e1
MG
247 { { &BIO_ctrl }, "BIO_ctrl" },
248 { { &BIO_f_buffer }, "BIO_f_buffer" },
249 { { &BIO_free_all }, "BIO_free_all" },
250 { { &BIO_new }, "BIO_new" },
251 { { &BIO_new_socket }, "BIO_new_socket" },
252 { { &BIO_pop }, "BIO_pop" },
253 { { &BIO_push }, "BIO_push" },
254 { { &ERR_clear_error }, "ERR_clear_error" },
255 { { &ERR_clear_error }, "ERR_clear_error" },
256 { { &ERR_peek_error }, "ERR_peek_error" },
257 { { &ERR_peek_error }, "ERR_peek_error" },
258 { { &SSL_CTX_callback_ctrl }, "SSL_CTX_callback_ctrl" },
259 { { &SSL_CTX_check_private_key }, "SSL_CTX_check_private_key" },
260 { { &SSL_CTX_ctrl }, "SSL_CTX_ctrl" },
261 { { &SSL_CTX_free }, "SSL_CTX_free" },
262 { { &SSL_CTX_new }, "SSL_CTX_new" },
263 { { &SSL_CTX_use_PrivateKey_file }, "SSL_CTX_use_PrivateKey_file" },
dc6575f2 264 { { &SSL_CTX_use_PrivateKey_ASN1 }, "SSL_CTX_use_PrivateKey_ASN1" },
03cd76e1 265 { { &SSL_CTX_use_certificate_file },"SSL_CTX_use_certificate_file"},
dc6575f2 266 { { &SSL_CTX_use_certificate_ASN1 },"SSL_CTX_use_certificate_ASN1"},
03cd76e1
MG
267 { { &SSL_ctrl }, "SSL_ctrl" },
268 { { &SSL_free }, "SSL_free" },
269 { { &SSL_get_error }, "SSL_get_error" },
270 { { &SSL_get_ex_data }, "SSL_get_ex_data" },
271 { { &SSL_get_rbio }, "SSL_get_rbio" },
d04f7ca7 272#ifdef HAVE_TLSEXT
03cd76e1 273 { { &SSL_get_servername }, "SSL_get_servername" },
a42d111c 274#endif
03cd76e1
MG
275 { { &SSL_get_wbio }, "SSL_get_wbio" },
276 { { &SSL_library_init }, "SSL_library_init" },
277 { { &SSL_new }, "SSL_new" },
278 { { &SSL_read }, "SSL_read" },
d04f7ca7 279#ifdef HAVE_TLSEXT
03cd76e1 280 { { &SSL_set_SSL_CTX }, "SSL_set_SSL_CTX" },
a42d111c 281#endif
03cd76e1
MG
282 { { &SSL_set_accept_state }, "SSL_set_accept_state" },
283 { { &SSL_set_bio }, "SSL_set_bio" },
284 { { &SSL_set_ex_data }, "SSL_set_ex_data" },
285 { { &SSL_shutdown }, "SSL_shutdown" },
286 { { &SSL_write }, "SSL_write" },
ad24d9a9
MG
287 { { &SSLv23_server_method }, "SSLv23_server_method" },
288 { { &d2i_X509 }, "d2i_X509" },
289 { { &X509_free }, "X509_free" }
7460295f
MG
290 };
291 for (int i = 0; i < sizeof(symbols)/sizeof(symbols[0]); i++) {
292 if (!(*symbols[i].var = loadSymbol("libssl.so", symbols[i].fn))) {
293 debug("Failed to load SSL support. Could not find \"%s\"",
294 symbols[i].fn);
295 for (int j = 0; j < sizeof(symbols)/sizeof(symbols[0]); j++) {
296 *symbols[j].var = NULL;
297 }
298 return;
299 }
300 }
301 SSL_library_init();
302 dcheck(!ERR_peek_error());
303 debug("Loaded SSL suppport");
304}
305#endif
306
307int serverSupportsSSL(void) {
bf1ec4d2
MG
308#if defined(HAVE_OPENSSL) && !defined(HAVE_DLOPEN)
309 return SSL_library_init();
310#else
7460295f
MG
311#if defined(HAVE_OPENSSL)
312 // We want to call loadSSL() exactly once. For single-threaded applications,
313 // this is straight-forward. For threaded applications, we need to call
314 // pthread_once(), instead. We perform run-time checks for whether we are
315 // single- or multi-threaded, so that the same code can be used.
a3876a41 316 // This currently only works on Linux.
9d758d39 317#if defined(HAVE_PTHREAD_H) && defined(__linux__) && defined(__i386__)
7460295f
MG
318 if (!!&pthread_once) {
319 static pthread_once_t once = PTHREAD_ONCE_INIT;
320 pthread_once(&once, loadSSL);
321 } else
322#endif
323 {
324 static int initialized;
325 if (!initialized) {
326 initialized = 1;
327 loadSSL();
328 }
329 }
330 return !!SSL_library_init;
331#else
332 return 0;
333#endif
bf1ec4d2 334#endif
7460295f
MG
335}
336
bdd01e84 337#if defined(HAVE_OPENSSL)
39e8401e
MG
338static void sslGenerateCertificate(const char *certificate,
339 const char *serverName) {
7460295f
MG
340 debug("Auto-generating missing certificate \"%s\" for \"%s\"",
341 certificate, serverName);
342 char *cmd = stringPrintf(NULL,
343 "set -e; "
344 "exec 2>/dev/null </dev/null; "
345 "umask 0377; "
10d0a6b0 346 "PATH=/usr/bin:/usr/sbin "
7460295f
MG
347 "openssl req -x509 -nodes -days 7300 -newkey rsa:1024 -keyout /dev/stdout "
348 "-out /dev/stdout -subj '/CN=%s/' | cat>'%s'",
349 serverName, certificate);
350 if (system(cmd)) {
351 warn("Failed to generate self-signed certificate \"%s\"", certificate);
352 }
353 free(cmd);
354}
ad24d9a9
MG
355
356static const unsigned char *sslSecureReadASCIIFileToMem(int fd) {
357 size_t inc = 16384;
358 size_t bufSize = inc;
359 size_t len = 0;
360 unsigned char *buf;
361 check((buf = malloc(bufSize)) != NULL);
362 for (;;) {
363 check(len < bufSize - 1);
364 size_t readLen = bufSize - len - 1;
365 ssize_t bytesRead = NOINTR(read(fd, buf + len, readLen));
366 if (bytesRead > 0) {
367 len += bytesRead;
368 }
369 if (bytesRead != readLen) {
370 break;
371 }
372
373 // Instead of calling realloc(), allocate a new buffer, copy the data,
374 // and then clear the old buffer. This way, we are not accidentally
375 // leaving key material in memory.
376 unsigned char *newBuf;
377 check((newBuf = malloc(bufSize + inc)) != NULL);
378 memcpy(newBuf, buf, len);
379 memset(buf, 0, bufSize);
380 free(buf);
381 buf = newBuf;
382 bufSize += inc;
383 }
384 check(len < bufSize);
385 buf[len] = '\000';
386 return buf;
387}
388
389static const unsigned char *sslPEMtoASN1(const unsigned char *pem,
390 const char *record,
391 long *size,
392 const unsigned char **eor) {
393 if (eor) {
394 *eor = NULL;
395 }
396 *size = 0;
397 char *marker;
398 check((marker = stringPrintf(NULL, "-----BEGIN %s-----",record))!=NULL);
399 unsigned char *ptr = (unsigned char *)strstr((char *)pem, marker);
400 if (!ptr) {
401 free(marker);
402 return NULL;
403 } else {
404 ptr += strlen(marker);
405 }
406 *marker = '\000';
407 check((marker = stringPrintf(marker, "-----END %s-----",record))!=NULL);
408 unsigned char *end = (unsigned char *)strstr((char *)ptr, marker);
409 if (eor) {
410 *eor = end + strlen(marker);
411 }
412 free(marker);
413 if (!end) {
414 return NULL;
415 }
416 unsigned char *ret;
417 size_t maxSize = (((end - ptr)*6)+7)/8;
418 check((ret = malloc(maxSize)) != NULL);
419 unsigned char *out = ret;
420 unsigned bits = 0;
421 int count = 0;
422 while (ptr < end) {
423 unsigned char ch = *ptr++;
424 if (ch >= 'A' && ch <= 'Z') {
425 ch -= 'A';
426 } else if (ch >= 'a' && ch <= 'z') {
427 ch -= 'a' - 26;
428 } else if (ch >= '0' && ch <= '9') {
429 ch += 52 - '0';
430 } else if (ch == '+') {
431 ch += 62 - '+';
432 } else if (ch == '/') {
433 ch += 63 - '/';
434 } else if (ch == '=') {
435 while (ptr < end) {
436 if ((ch = *ptr++) != '=' && ch > ' ') {
437 goto err;
438 }
439 }
440 break;
441 } else if (ch <= ' ') {
442 continue;
443 } else {
444 err:
445 free(ret);
446 return NULL;
447 }
448 check(ch <= 63);
449 check(count >= 0);
450 check(count <= 6);
451 bits = (bits << 6) | ch;
452 count += 6;
453 if (count >= 8) {
454 *out++ = (bits >> (count -= 8)) & 0xFF;
455 }
456 }
457 check(out - ret <= maxSize);
458 *size = out - ret;
459 return ret;
460}
461
462static int sslSetCertificateFromFd(SSL_CTX *context, int fd) {
463 int rc = 0;
464 check(serverSupportsSSL());
465 check(fd >= 0);
466 const unsigned char *data = sslSecureReadASCIIFileToMem(fd);
467 check(!NOINTR(close(fd)));
468 long dataSize = (long)strlen((const char *)data);
469 long certSize, rsaSize, dsaSize, ecSize;
470 const unsigned char *record;
471 const unsigned char *cert = sslPEMtoASN1(data, "CERTIFICATE", &certSize,
472 &record);
473 const unsigned char *rsa = sslPEMtoASN1(data, "RSA PRIVATE KEY",&rsaSize,
474 NULL);
475 const unsigned char *dsa = sslPEMtoASN1(data, "DSA PRIVATE KEY",&dsaSize,
476 NULL);
477 const unsigned char *ec = sslPEMtoASN1(data, "EC PRIVATE KEY", &ecSize,
478 NULL);
479 if (certSize && (rsaSize || dsaSize
480#ifdef EVP_PKEY_EC
481 || ecSize
482#endif
483 ) &&
484 SSL_CTX_use_certificate_ASN1(context, certSize, cert) &&
485 (!rsaSize ||
486 SSL_CTX_use_PrivateKey_ASN1(EVP_PKEY_RSA, context, rsa, rsaSize)) &&
487 (!dsaSize ||
488 SSL_CTX_use_PrivateKey_ASN1(EVP_PKEY_DSA, context, dsa, dsaSize))
489#ifdef EVP_PKEY_EC
490 &&
491 (!ecSize ||
492 SSL_CTX_use_PrivateKey_ASN1(EVP_PKEY_EC, context, ec, ecSize))
493#endif
494 ) {
495 memset((char *)cert, 0, certSize);
496 free((char *)cert);
497 while (record) {
498 cert = sslPEMtoASN1(record, "CERTIFICATE", &certSize,
499 &record);
500 if (cert) {
501 X509 *x509;
502 const unsigned char *c = cert;
503 check(x509 = d2i_X509(NULL, &c, certSize));
504 memset((char *)cert, 0, certSize);
505 free((char *)cert);
506 if (!SSL_CTX_add_extra_chain_cert(context, x509)) {
507 X509_free(x509);
508 break;
509 }
510 }
511 }
512 if (!record && SSL_CTX_check_private_key(context)) {
513 rc = 1;
514 }
515 dcheck(!ERR_peek_error());
516 ERR_clear_error();
517 } else {
518 memset((char *)cert, 0, certSize);
519 free((char *)cert);
520 }
521 memset((char *)data, 0, dataSize);
522 free((char *)data);
523 memset((char *)rsa, 0, rsaSize);
524 free((char *)rsa);
525 memset((char *)dsa, 0, dsaSize);
526 free((char *)dsa);
527 memset((char *)ec, 0, ecSize);
528 free((char *)ec);
529 return rc;
530}
531
532static int sslSetCertificateFromFile(SSL_CTX *context,
533 const char *filename) {
534 int fd = open(filename, O_RDONLY);
535 if (fd < 0) {
536 return -1;
537 }
538 int rc = sslSetCertificateFromFd(context, fd);
ad24d9a9
MG
539 return rc;
540}
bdd01e84 541#endif
7460295f 542
d04f7ca7 543#ifdef HAVE_TLSEXT
7460295f
MG
544static int sslSNICallback(SSL *sslHndl, int *al, struct SSLSupport *ssl) {
545 check(!ERR_peek_error());
546 const char *name = SSL_get_servername(sslHndl,
547 TLSEXT_NAMETYPE_host_name);
548 if (name == NULL || !*name) {
549 return SSL_TLSEXT_ERR_OK;
550 }
551 struct HttpConnection *http =
552 (struct HttpConnection *)SSL_get_app_data(sslHndl);
553 debug("Received SNI callback for virtual host \"%s\" from \"%s:%d\"",
554 name, httpGetPeerName(http), httpGetPort(http));
555 char *serverName;
556 check(serverName = malloc(strlen(name)+2));
557 serverName[0] = '-';
558 for (int i = 0;;) {
559 char ch = name[i];
560 if (ch >= 'A' && ch <= 'Z') {
561 ch |= 0x20;
562 } else if (ch != '\000' && ch != '.' && ch != '-' &&
563 (ch < '0' ||(ch > '9' && ch < 'A') || (ch > 'Z' &&
564 ch < 'a')|| ch > 'z')) {
565 i++;
566 continue;
567 }
568 serverName[++i] = ch;
569 if (!ch) {
570 break;
571 }
572 }
573 if (!*serverName) {
574 free(serverName);
575 return SSL_TLSEXT_ERR_OK;
576 }
577 SSL_CTX *context = (SSL_CTX *)getFromTrie(&ssl->sniContexts,
578 serverName+1,
579 NULL);
580 if (context == NULL) {
581 check(context = SSL_CTX_new(SSLv23_server_method()));
582 check(ssl->sniCertificatePattern);
9b850878
MG
583 char *certificate = stringPrintfUnchecked(NULL,
584 ssl->sniCertificatePattern,
585 serverName);
ad24d9a9 586 if (sslSetCertificateFromFile(context, certificate) < 0) {
7460295f
MG
587 if (ssl->generateMissing) {
588 sslGenerateCertificate(certificate, serverName + 1);
ad24d9a9
MG
589
590 // No need to check the certificate. If we fail to set it, we will use
591 // the default certificate, instead.
592 sslSetCertificateFromFile(context, certificate);
7460295f 593 } else {
7460295f
MG
594 warn("Could not find matching certificate \"%s\" for \"%s\"",
595 certificate, serverName + 1);
596 SSL_CTX_free(context);
597 context = ssl->sslContext;
598 }
599 }
600 ERR_clear_error();
601 free(certificate);
602 addToTrie(&ssl->sniContexts, serverName+1, (char *)context);
603 }
604 free(serverName);
605 if (context != ssl->sslContext) {
606 check(SSL_set_SSL_CTX(sslHndl, context) > 0);
607 }
608 check(!ERR_peek_error());
609 return SSL_TLSEXT_ERR_OK;
610}
611#endif
612
e027583c 613#if defined(HAVE_OPENSSL)
572ac014
MG
614// This is a not-thread-safe replacement for gethostbyname_r()
615#define gethostbyname_r x_gethostbyname_r
616static int gethostbyname_r(const char *name, struct hostent *ret,
617 char *buf, size_t buflen,
618 struct hostent **result, int *h_errnop) {
619 if (result) {
620 *result = NULL;
621 }
622 if (h_errnop) {
623 *h_errnop = ERANGE;
624 }
625 if (!ret) {
626 return -1;
627 }
628 struct hostent *he = gethostbyname(name);
629 *ret = *he;
630 if (result) {
631 *result = ret;
632 }
633 if (h_errnop) {
634 *h_errnop = h_errno;
635 }
636 return 0;
637}
638#endif
639
7460295f
MG
640void sslSetCertificate(struct SSLSupport *ssl, const char *filename,
641 int autoGenerateMissing) {
642#if defined(HAVE_OPENSSL)
643 check(serverSupportsSSL());
644
645 char *defaultCertificate;
646 check(defaultCertificate = strdup(filename));
647 char *ptr = strchr(defaultCertificate, '%');
648 if (ptr != NULL) {
649 check(!strchr(ptr+1, '%'));
650 check(ptr[1] == 's');
651 memmove(ptr, ptr + 2, strlen(ptr)-1);
652 }
653
ad24d9a9 654 // Try to set the default certificate. If necessary, (re-)generate it.
7460295f
MG
655 check(ssl->sslContext = SSL_CTX_new(SSLv23_server_method()));
656 if (autoGenerateMissing) {
ad24d9a9 657 if (sslSetCertificateFromFile(ssl->sslContext, defaultCertificate) < 0) {
7460295f
MG
658 char hostname[256], buf[4096];
659 check(!gethostname(hostname, sizeof(hostname)));
660 struct hostent he_buf, *he;
661 int h_err;
662 if (gethostbyname_r(hostname, &he_buf, buf, sizeof(buf),
663 &he, &h_err)) {
664 sslGenerateCertificate(defaultCertificate, hostname);
665 } else {
666 sslGenerateCertificate(defaultCertificate, he->h_name);
667 }
668 } else {
669 goto valid_certificate;
670 }
671 }
ad24d9a9 672 if (sslSetCertificateFromFile(ssl->sslContext, defaultCertificate) < 0) {
7460295f
MG
673 fatal("Cannot read valid certificate from \"%s\". "
674 "Check file permissions and file format.", defaultCertificate);
675 }
676 valid_certificate:
677 free(defaultCertificate);
678
ad24d9a9
MG
679 // Enable SNI support so that we can set a different certificate, if the
680 // client asked for it.
d04f7ca7 681#ifdef HAVE_TLSEXT
7460295f
MG
682 if (ptr != NULL) {
683 check(ssl->sniCertificatePattern = strdup(filename));
684 check(SSL_CTX_set_tlsext_servername_callback(ssl->sslContext,
685 sslSNICallback));
686 check(SSL_CTX_set_tlsext_servername_arg(ssl->sslContext, ssl));
687 }
688#endif
689 dcheck(!ERR_peek_error());
690 ERR_clear_error();
691
692 ssl->generateMissing = autoGenerateMissing;
693#endif
694}
695
ad24d9a9
MG
696// Convert the file descriptor to a human-readable format. Attempts to
697// retrieve the original file name where possible.
dc6575f2 698#ifdef HAVE_OPENSSL
ad24d9a9
MG
699static char *sslFdToFilename(int fd) {
700 char *proc, *buf;
701 int len = 128;
702 check(proc = stringPrintf(NULL, "/proc/self/fd/%d", fd));
703 check(buf = malloc(len));
dc6575f2 704 for (;;) {
ad24d9a9
MG
705 ssize_t i;
706 if ((i = readlink(proc, buf + 1, len-3)) < 0) {
707 free(proc);
708 free(buf);
709 check(buf = stringPrintf(NULL, "fd %d", fd));
710 return buf;
711 } else if (i >= len-3) {
712 len += 512;
713 check(buf = realloc(buf, len));
dc6575f2 714 } else {
ad24d9a9
MG
715 free(proc);
716 check(i >= 0 && i < len);
717 buf[i+1] = '\000';
718 struct stat sb;
719 if (!stat(buf + 1, &sb) && S_ISREG(sb.st_mode)) {
720 *buf = '"';
721 buf[i + 1] = '"';
722 buf[i + 2] = '\000';
723 return buf;
724 } else {
725 free(buf);
726 check(buf = stringPrintf(NULL, "fd %d", fd));
727 return buf;
728 }
dc6575f2
MG
729 }
730 }
dc6575f2
MG
731}
732#endif
733
734void sslSetCertificateFd(struct SSLSupport *ssl, int fd) {
735#ifdef HAVE_OPENSSL
ad24d9a9 736 check(ssl->sslContext = SSL_CTX_new(SSLv23_server_method()));
48f25965 737 char *filename = sslFdToFilename(fd);
ad24d9a9
MG
738 if (!sslSetCertificateFromFd(ssl->sslContext, fd)) {
739 fatal("Cannot read valid certificate from %s. Check file format.",
48f25965 740 filename);
dc6575f2 741 }
48f25965 742 free(filename);
ad24d9a9 743 ssl->generateMissing = 0;
dc6575f2
MG
744#endif
745}
746
7460295f
MG
747int sslEnable(struct SSLSupport *ssl, int enabled) {
748 int old = ssl->enabled;
749 ssl->enabled = enabled;
750 return old;
751}
752
753void sslBlockSigPipe(void) {
754 sigset_t set;
755 sigemptyset(&set);
756 sigaddset(&set, SIGPIPE);
9d758d39 757#if defined(HAVE_PTHREAD_H) && defined(__linux__) && defined(__i386__)
c593cf68
MG
758 if (&pthread_sigmask) {
759 dcheck(!pthread_sigmask(SIG_BLOCK, &set, NULL));
9d758d39
MG
760 } else
761#endif
762 {
c593cf68
MG
763 dcheck(!sigprocmask(SIG_BLOCK, &set, NULL));
764 }
7460295f
MG
765}
766
572ac014
MG
767#ifndef HAVE_SIGWAIT
768// This is a non-thread-safe replacement for sigwait()
769static int dummysignalno;
770static void dummysignal(int signo) {
771 dummysignalno = signo;
772}
773
774#define sigwait x_sigwait
775static int sigwait(const sigset_t *set, int *sig) {
776 sigset_t mask, old_mask;
777 sigfillset(&mask);
9d758d39 778#if defined(HAVE_PTHREAD_H) && defined(__linux__) && defined(__i386__)
572ac014
MG
779 if (&pthread_sigmask) {
780 dcheck(!pthread_sigmask(SIG_BLOCK, &mask, &old_mask));
9d758d39
MG
781 } else
782#endif
783 {
572ac014
MG
784 dcheck(!sigprocmask(SIG_BLOCK, &mask, &old_mask));
785 }
786 #ifndef NSIG
787 #define NSIG 32
788 #endif
789 struct sigaction sa[NSIG];
790 memset(sa, 0, sizeof(sa));
791 sa->sa_handler = dummysignal;
792 for (int i = 1; i <= NSIG; i++) {
793 if (sigismember(set, i)) {
794 sigdelset(&mask, i);
795 sigaction(i, sa, sa + i);
796 }
797 }
798 dummysignalno = -1;
799 sigsuspend(&mask);
9d758d39 800#if defined(HAVE_PTHREAD_H) && defined(__linux__) && defined(__i386__)
572ac014
MG
801 if (&pthread_sigmask) {
802 dcheck(!pthread_sigmask(SIG_SETMASK, &old_mask, NULL));
9d758d39
MG
803 } else
804#endif
805 {
572ac014
MG
806 dcheck(!sigprocmask(SIG_BLOCK, &old_mask, NULL));
807 }
808 return dummysignalno;
809}
810#endif
811
7460295f
MG
812int sslUnblockSigPipe(void) {
813 int signum = 0;
814 sigset_t set;
815 check(!sigpending(&set));
816 if (sigismember(&set, SIGPIPE)) {
817 sigwait(&set, &signum);
818 }
819 sigemptyset(&set);
820 sigaddset(&set, SIGPIPE);
9d758d39 821#if defined(HAVE_PTHREAD_H) && defined(__linux__) && defined(__i386__)
c593cf68
MG
822 if (&pthread_sigmask) {
823 dcheck(!pthread_sigmask(SIG_UNBLOCK, &set, NULL));
9d758d39
MG
824 } else
825#endif
826 {
c593cf68
MG
827 dcheck(!sigprocmask(SIG_UNBLOCK, &set, NULL));
828 }
7460295f
MG
829 return signum;
830}
831
832int sslPromoteToSSL(struct SSLSupport *ssl, SSL **sslHndl, int fd,
833 const char *buf, int len) {
834#if defined(HAVE_OPENSSL)
835 sslBlockSigPipe();
836 int rc = 0;
837 check(!*sslHndl);
838 dcheck(!ERR_peek_error());
839 dcheck(*sslHndl = SSL_new(ssl->sslContext));
840 if (*sslHndl == NULL) {
841 ERR_clear_error();
842 errno = EINVAL;
843 rc = -1;
844 } else {
845 SSL_set_mode(*sslHndl, SSL_MODE_ENABLE_PARTIAL_WRITE);
846 BIO *writeBIO = BIO_new_socket(fd, 0);
847 BIO *readBIO = writeBIO;
848 if (len > 0) {
849 readBIO = BIO_new(BIO_f_buffer());
850 BIO_push(readBIO, writeBIO);
851 check(BIO_set_buffer_read_data(readBIO, (char *)buf, len));
852 }
853 SSL_set_bio(*sslHndl, readBIO, writeBIO);
854 SSL_set_accept_state(*sslHndl);
855 dcheck(!ERR_peek_error());
856 }
857 sslUnblockSigPipe();
858 return rc;
859#else
860 errno = EINVAL;
861 return -1;
862#endif
863}
864
865void sslFreeHndl(SSL **sslHndl) {
866#if defined(HAVE_OPENSSL)
867 if (*sslHndl) {
868 // OpenSSL does not always correctly perform reference counting for stacked
869 // BIOs. This is particularly a problem if an SSL connection has two
870 // different BIOs for the read and the write end, with one being a stacked
871 // derivative of the other. Unfortunately, this is exactly the scenario
872 // that we set up.
873 // As a work-around, we un-stack the BIOs prior to freeing the SSL
874 // connection.
875 ERR_clear_error();
876 BIO *writeBIO, *readBIO;
877 check(writeBIO = SSL_get_wbio(*sslHndl));
878 check(readBIO = SSL_get_rbio(*sslHndl));
879 if (writeBIO != readBIO) {
880 if (readBIO->next_bio == writeBIO) {
881 // OK, that's exactly the bug we are looking for. We know how to
882 // fix it.
883 check(BIO_pop(readBIO) == writeBIO);
884 check(readBIO->references == 1);
885 check(writeBIO->references == 1);
886 check(!readBIO->next_bio);
887 check(!writeBIO->prev_bio);
888 } else if (readBIO->next_bio == writeBIO->next_bio &&
889 writeBIO->next_bio->prev_bio == writeBIO) {
890 // Things get even more confused, if the SSL handshake is aborted
891 // prematurely.
892 // OpenSSL appears to internally stack a BIO onto the read end that
893 // does not get removed afterwards. We end up with the original
894 // socket BIO having two different BIOs prepended to it (one for
895 // reading and one for writing). In this case, not only is the
896 // reference count wrong, but the chain of next_bio/prev_bio pairs
897 // is corrupted, too.
898 BIO *sockBIO;
899 check(sockBIO = BIO_pop(readBIO));
900 check(sockBIO == BIO_pop(writeBIO));
901 check(readBIO->references == 1);
902 check(writeBIO->references == 1);
903 check(sockBIO->references == 1);
904 check(!readBIO->next_bio);
905 check(!writeBIO->next_bio);
906 check(!sockBIO->prev_bio);
907 BIO_free_all(sockBIO);
908 } else {
909 // We do not know, how to fix this situation. Something must have
910 // changed in the OpenSSL internals. Either, this is a new bug, or
911 // somebody fixed the code in a way that we did not anticipate.
912 fatal("Unexpected corruption of OpenSSL data structures");
913 }
914 }
915 SSL_free(*sslHndl);
916 dcheck(!ERR_peek_error());
917 }
918#endif
919 *sslHndl = NULL;
920}
This page took 0.650166 seconds and 5 git commands to generate.