1 // ssl.c -- Support functions that find and load SSL support, if available
2 // Copyright (C) 2008-2010 Markus Gutschke <markus@shellinabox.com>
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.
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.
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.
17 // In addition to these license terms, the author grants the following
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.
29 // You may at your option choose to remove this additional permission from
30 // the work, or from any part of it.
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:
36 // This product includes software developed by the OpenSSL Project
37 // for use in the OpenSSL Toolkit. (http://www.openssl.org/)
39 // This product includes cryptographic software written by Eric Young
40 // (eay@cryptsoft.com)
43 // The most up-to-date version of this program is always available from
44 // http://shellinabox.com
49 #define pthread_once x_pthread_once
50 #define pthread_sigmask x_pthread_sigmask
59 #include <sys/types.h>
64 #include "libhttp/ssl.h"
65 #include "libhttp/httpconnection.h"
66 #include "logging/logging.h"
69 #defined ATTR_UNUSED __attribute__((unused))
70 #defined UNUSED(x) do { } while (0)
73 #define UNUSED(x) do { (void)(x); } while (0)
77 #undef pthread_sigmask
79 #if defined(HAVE_OPENSSL) && !defined(OPENSSL_NO_TLSEXT) && \
80 defined(TLSEXT_NAMETYPE_host_name) && defined(SSL_TLSEXT_ERR_OK)
84 #if defined(HAVE_PTHREAD_H)
85 // Pthread support is optional. Only enable it, if the library has been
86 // linked into the program
88 #if defined(__linux__)
89 extern int pthread_once(pthread_once_t *, void (*)(void))__attribute__((weak));
91 extern int pthread_sigmask(int, const sigset_t *, sigset_t *)
92 __attribute__((weak));
96 #if defined(HAVE_DLOPEN)
97 // SSL support is optional. Only enable it, if the library can be loaded.
98 long (*BIO_ctrl)(BIO *, int, long, void *);
99 BIO_METHOD * (*BIO_f_buffer)(void);
100 void (*BIO_free_all)(BIO *);
101 BIO * (*BIO_new)(BIO_METHOD *);
102 BIO * (*BIO_new_socket)(int, int);
103 BIO * (*BIO_pop)(BIO *);
104 BIO * (*BIO_push)(BIO *, BIO *);
105 void (*ERR_clear_error)(void);
106 void (*ERR_clear_error)(void);
107 unsigned long (*ERR_peek_error)(void);
108 unsigned long (*ERR_peek_error)(void);
109 long (*SSL_CTX_callback_ctrl)(SSL_CTX *, int, void (*)(void));
110 int (*SSL_CTX_check_private_key)(const SSL_CTX *);
111 long (*SSL_CTX_ctrl)(SSL_CTX *, int, long, void *);
112 void (*SSL_CTX_free)(SSL_CTX *);
113 SSL_CTX * (*SSL_CTX_new)(SSL_METHOD *);
114 int (*SSL_CTX_use_PrivateKey_file)(SSL_CTX *, const char *, int);
115 int (*SSL_CTX_use_PrivateKey_ASN1)(int, SSL_CTX *,
116 const unsigned char *, long);
117 int (*SSL_CTX_use_certificate_file)(SSL_CTX *, const char *, int);
118 int (*SSL_CTX_use_certificate_ASN1)(SSL_CTX *, long,
119 const unsigned char *);
120 long (*SSL_ctrl)(SSL *, int, long, void *);
121 void (*SSL_free)(SSL *);
122 int (*SSL_get_error)(const SSL *, int);
123 void * (*SSL_get_ex_data)(const SSL *, int);
124 BIO * (*SSL_get_rbio)(const SSL *);
125 const char * (*SSL_get_servername)(const SSL *, int);
126 BIO * (*SSL_get_wbio)(const SSL *);
127 int (*SSL_library_init)(void);
128 SSL * (*SSL_new)(SSL_CTX *);
129 int (*SSL_read)(SSL *, void *, int);
130 SSL_CTX * (*SSL_set_SSL_CTX)(SSL *, SSL_CTX *);
131 void (*SSL_set_accept_state)(SSL *);
132 void (*SSL_set_bio)(SSL *, BIO *, BIO *);
133 int (*SSL_set_ex_data)(SSL *, int, void *);
134 int (*SSL_shutdown)(SSL *);
135 int (*SSL_write)(SSL *, const void *, int);
136 SSL_METHOD * (*SSLv23_server_method)(void);
137 X509 * (*d2i_X509)(X509 **px, const unsigned char **in, int len);
138 void (*X509_free)(X509 *a);
141 static void sslDestroyCachedContext(void *ssl_, char *context_) {
142 struct SSLSupport *ssl = (struct SSLSupport *)ssl_;
143 SSL_CTX *context = (SSL_CTX *)context_;
144 #if defined(HAVE_OPENSSL)
145 if (context != ssl->sslContext) {
146 SSL_CTX_free(context);
150 check(!ssl->sslContext);
154 struct SSLSupport *newSSL(void) {
155 struct SSLSupport *ssl;
156 check(ssl = malloc(sizeof(struct SSLSupport)));
161 void initSSL(struct SSLSupport *ssl) {
162 ssl->enabled = serverSupportsSSL();
163 ssl->sslContext = NULL;
164 ssl->sniCertificatePattern = NULL;
165 ssl->generateMissing = 0;
166 initTrie(&ssl->sniContexts, sslDestroyCachedContext, ssl);
169 void destroySSL(struct SSLSupport *ssl) {
171 free(ssl->sniCertificatePattern);
172 destroyTrie(&ssl->sniContexts);
173 #if defined(HAVE_OPENSSL)
174 if (ssl->sslContext) {
175 dcheck(!ERR_peek_error());
176 SSL_CTX_free(ssl->sslContext);
179 check(!ssl->sslContext);
184 void deleteSSL(struct SSLSupport *ssl) {
189 #if defined(HAVE_OPENSSL) && defined(HAVE_DLOPEN)
190 static int maybeLoadCrypto(void) {
191 // Some operating systems cannot automatically load dependent dynamic
192 // libraries. As libssl.so can depend on libcrypto.so, we try to load
193 // it, iff we haven't tried loading it before and iff libssl.so does not
198 if (dlopen("libcrypto.so", RTLD_LAZY|RTLD_GLOBAL|RTLD_NOLOAD))
202 if (dlopen("libcrypto.so", RTLD_LAZY|RTLD_GLOBAL))
208 static void *loadSymbol(const char *lib, const char *fn) {
209 int err = NOINTR(dup(2));
211 int null = NOINTR(open("/dev/null", O_WRONLY));
213 NOINTR(dup2(null, 2));
217 void *dl = RTLD_DEFAULT;
218 void *rc = dlsym(dl, fn);
220 for (int i = 0; i < 2; i++) {
222 dl = dlopen(lib, RTLD_LAZY|RTLD_GLOBAL|RTLD_NOLOAD);
227 dl = dlopen(lib, RTLD_LAZY|RTLD_GLOBAL);
229 if (dl != NULL || !maybeLoadCrypto()) {
234 rc = dlsym(RTLD_DEFAULT, fn);
235 if (rc == NULL && maybeLoadCrypto()) {
236 rc = dlsym(RTLD_DEFAULT, fn);
241 NOINTR(dup2(err, 2));
247 static void loadSSL(void) {
248 check(!SSL_library_init);
251 void *avoid_gcc_warning_about_type_punning;
256 { { &BIO_ctrl }, "BIO_ctrl" },
257 { { &BIO_f_buffer }, "BIO_f_buffer" },
258 { { &BIO_free_all }, "BIO_free_all" },
259 { { &BIO_new }, "BIO_new" },
260 { { &BIO_new_socket }, "BIO_new_socket" },
261 { { &BIO_pop }, "BIO_pop" },
262 { { &BIO_push }, "BIO_push" },
263 { { &ERR_clear_error }, "ERR_clear_error" },
264 { { &ERR_clear_error }, "ERR_clear_error" },
265 { { &ERR_peek_error }, "ERR_peek_error" },
266 { { &ERR_peek_error }, "ERR_peek_error" },
267 { { &SSL_CTX_callback_ctrl }, "SSL_CTX_callback_ctrl" },
268 { { &SSL_CTX_check_private_key }, "SSL_CTX_check_private_key" },
269 { { &SSL_CTX_ctrl }, "SSL_CTX_ctrl" },
270 { { &SSL_CTX_free }, "SSL_CTX_free" },
271 { { &SSL_CTX_new }, "SSL_CTX_new" },
272 { { &SSL_CTX_use_PrivateKey_file }, "SSL_CTX_use_PrivateKey_file" },
273 { { &SSL_CTX_use_PrivateKey_ASN1 }, "SSL_CTX_use_PrivateKey_ASN1" },
274 { { &SSL_CTX_use_certificate_file },"SSL_CTX_use_certificate_file"},
275 { { &SSL_CTX_use_certificate_ASN1 },"SSL_CTX_use_certificate_ASN1"},
276 { { &SSL_ctrl }, "SSL_ctrl" },
277 { { &SSL_free }, "SSL_free" },
278 { { &SSL_get_error }, "SSL_get_error" },
279 { { &SSL_get_ex_data }, "SSL_get_ex_data" },
280 { { &SSL_get_rbio }, "SSL_get_rbio" },
282 { { &SSL_get_servername }, "SSL_get_servername" },
284 { { &SSL_get_wbio }, "SSL_get_wbio" },
285 { { &SSL_library_init }, "SSL_library_init" },
286 { { &SSL_new }, "SSL_new" },
287 { { &SSL_read }, "SSL_read" },
289 { { &SSL_set_SSL_CTX }, "SSL_set_SSL_CTX" },
291 { { &SSL_set_accept_state }, "SSL_set_accept_state" },
292 { { &SSL_set_bio }, "SSL_set_bio" },
293 { { &SSL_set_ex_data }, "SSL_set_ex_data" },
294 { { &SSL_shutdown }, "SSL_shutdown" },
295 { { &SSL_write }, "SSL_write" },
296 { { &SSLv23_server_method }, "SSLv23_server_method" },
297 { { &d2i_X509 }, "d2i_X509" },
298 { { &X509_free }, "X509_free" }
300 for (unsigned i = 0; i < sizeof(symbols)/sizeof(symbols[0]); i++) {
301 if (!(*symbols[i].var = loadSymbol("libssl.so", symbols[i].fn))) {
302 debug("Failed to load SSL support. Could not find \"%s\"",
304 for (unsigned j = 0; j < sizeof(symbols)/sizeof(symbols[0]); j++) {
305 *symbols[j].var = NULL;
311 dcheck(!ERR_peek_error());
312 debug("Loaded SSL suppport");
316 int serverSupportsSSL(void) {
317 #if defined(HAVE_OPENSSL) && !defined(HAVE_DLOPEN)
318 return SSL_library_init();
320 #if defined(HAVE_OPENSSL)
321 // We want to call loadSSL() exactly once. For single-threaded applications,
322 // this is straight-forward. For threaded applications, we need to call
323 // pthread_once(), instead. We perform run-time checks for whether we are
324 // single- or multi-threaded, so that the same code can be used.
325 // This currently only works on Linux.
326 #if defined(HAVE_PTHREAD_H) && defined(__linux__) && defined(__i386__)
327 if (!!&pthread_once) {
328 static pthread_once_t once = PTHREAD_ONCE_INIT;
329 pthread_once(&once, loadSSL);
333 static int initialized;
339 return !!SSL_library_init;
346 #if defined(HAVE_OPENSSL)
347 static void sslGenerateCertificate(const char *certificate,
348 const char *serverName) {
349 debug("Auto-generating missing certificate \"%s\" for \"%s\"",
350 certificate, serverName);
354 warn("Failed to generate self-signed certificate \"%s\"", certificate);
355 } else if (pid == 0) {
356 int fd = NOINTR(open("/dev/null", O_RDONLY));
358 check(NOINTR(dup2(fd, STDERR_FILENO)) == STDERR_FILENO);
359 check(NOINTR(close(fd)) == 0);
360 fd = NOINTR(open("/dev/null", O_WRONLY));
362 check(NOINTR(dup2(fd, STDIN_FILENO)) == STDIN_FILENO);
363 check(NOINTR(close(fd)) == 0);
365 check(setenv("PATH", "/usr/bin:/usr/sbin", 1) == 0);
366 execlp("openssl", "openssl", "req", "-x509", "-nodes", "-days", "7300",
367 "-newkey", "rsa:2048", "-keyout", certificate, "-out", certificate,
368 "-subj", stringPrintf(NULL, "/CN=%s/", serverName),
373 check(NOINTR(waitpid(pid, &status, 0)) == pid);
374 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
375 warn("Failed to generate self-signed certificate \"%s\"", certificate);
379 static const unsigned char *sslSecureReadASCIIFileToMem(int fd) {
381 size_t bufSize = inc;
384 check((buf = malloc(bufSize)) != NULL);
386 check(len < bufSize - 1);
387 ssize_t readLen = bufSize - len - 1;
388 ssize_t bytesRead = NOINTR(read(fd, buf + len, readLen));
392 if (bytesRead != readLen) {
396 // Instead of calling realloc(), allocate a new buffer, copy the data,
397 // and then clear the old buffer. This way, we are not accidentally
398 // leaving key material in memory.
399 unsigned char *newBuf;
400 check((newBuf = malloc(bufSize + inc)) != NULL);
401 memcpy(newBuf, buf, len);
402 memset(buf, 0, bufSize);
407 check(len < bufSize);
412 static const unsigned char *sslPEMtoASN1(const unsigned char *pem,
415 const unsigned char **eor) {
421 check((marker = stringPrintf(NULL, "-----BEGIN %s-----",record))!=NULL);
422 unsigned char *ptr = (unsigned char *)strstr((char *)pem, marker);
427 ptr += strlen(marker);
430 check((marker = stringPrintf(marker, "-----END %s-----",record))!=NULL);
431 unsigned char *end = (unsigned char *)strstr((char *)ptr, marker);
433 *eor = end + strlen(marker);
440 ssize_t maxSize = (((end - ptr)*6)+7)/8;
441 check((ret = malloc(maxSize)) != NULL);
442 unsigned char *out = ret;
446 unsigned char ch = *ptr++;
447 if (ch >= 'A' && ch <= 'Z') {
449 } else if (ch >= 'a' && ch <= 'z') {
451 } else if (ch >= '0' && ch <= '9') {
453 } else if (ch == '+') {
455 } else if (ch == '/') {
457 } else if (ch == '=') {
459 if ((ch = *ptr++) != '=' && ch > ' ') {
464 } else if (ch <= ' ') {
474 bits = (bits << 6) | ch;
477 *out++ = (bits >> (count -= 8)) & 0xFF;
480 check(out - ret <= maxSize);
485 static int sslSetCertificateFromFd(SSL_CTX *context, int fd) {
487 check(serverSupportsSSL());
489 const unsigned char *data = sslSecureReadASCIIFileToMem(fd);
490 check(!NOINTR(close(fd)));
491 long dataSize = (long)strlen((const char *)data);
492 long certSize, rsaSize, dsaSize, ecSize, notypeSize;
493 const unsigned char *record;
494 const unsigned char *cert = sslPEMtoASN1(data, "CERTIFICATE", &certSize,
496 const unsigned char *rsa = sslPEMtoASN1(data, "RSA PRIVATE KEY",&rsaSize,
498 const unsigned char *dsa = sslPEMtoASN1(data, "DSA PRIVATE KEY",&dsaSize,
500 const unsigned char *ec = sslPEMtoASN1(data, "EC PRIVATE KEY", &ecSize,
502 const unsigned char *notype = sslPEMtoASN1(data, "PRIVATE KEY", ¬ypeSize,
504 if (certSize && (rsaSize || dsaSize
509 SSL_CTX_use_certificate_ASN1(context, certSize, cert) &&
511 SSL_CTX_use_PrivateKey_ASN1(EVP_PKEY_RSA, context, rsa, rsaSize)) &&
513 SSL_CTX_use_PrivateKey_ASN1(EVP_PKEY_DSA, context, dsa, dsaSize)) &&
516 SSL_CTX_use_PrivateKey_ASN1(EVP_PKEY_EC, context, ec, ecSize)) &&
518 // Assume a private key is RSA if the header does not specify a type.
519 // (e.g. BEGIN PRIVATE KEY)
521 SSL_CTX_use_PrivateKey_ASN1(EVP_PKEY_RSA, context, notype, notypeSize))
523 memset((char *)cert, 0, certSize);
526 cert = sslPEMtoASN1(record, "CERTIFICATE", &certSize,
530 const unsigned char *c = cert;
531 check(x509 = d2i_X509(NULL, &c, certSize));
532 memset((char *)cert, 0, certSize);
534 if (!SSL_CTX_add_extra_chain_cert(context, x509)) {
540 if (!record && SSL_CTX_check_private_key(context)) {
543 dcheck(!ERR_peek_error());
546 memset((char *)cert, 0, certSize);
549 memset((char *)data, 0, dataSize);
551 memset((char *)rsa, 0, rsaSize);
553 memset((char *)dsa, 0, dsaSize);
555 memset((char *)ec, 0, ecSize);
557 memset((char *)notype, 0, notypeSize);
558 free((char *)notype);
562 static int sslSetCertificateFromFile(SSL_CTX *context,
563 const char *filename) {
564 int fd = open(filename, O_RDONLY);
568 int rc = sslSetCertificateFromFd(context, fd);
574 static int sslSNICallback(SSL *sslHndl, int *al ATTR_UNUSED,
575 struct SSLSupport *ssl) {
577 check(!ERR_peek_error());
578 const char *name = SSL_get_servername(sslHndl,
579 TLSEXT_NAMETYPE_host_name);
580 if (name == NULL || !*name) {
581 return SSL_TLSEXT_ERR_OK;
583 struct HttpConnection *http =
584 (struct HttpConnection *)SSL_get_app_data(sslHndl);
585 debug("Received SNI callback for virtual host \"%s\" from \"%s:%d\"",
586 name, httpGetPeerName(http), httpGetPort(http));
588 check(serverName = malloc(strlen(name)+2));
592 if (ch >= 'A' && ch <= 'Z') {
594 } else if (ch != '\000' && ch != '.' && ch != '-' &&
595 (ch < '0' ||(ch > '9' && ch < 'A') || (ch > 'Z' &&
596 ch < 'a')|| ch > 'z')) {
598 return SSL_TLSEXT_ERR_OK;
600 serverName[++i] = ch;
605 SSL_CTX *context = (SSL_CTX *)getFromTrie(&ssl->sniContexts,
608 if (context == NULL) {
609 check(context = SSL_CTX_new(SSLv23_server_method()));
610 check(ssl->sniCertificatePattern);
611 char *certificate = stringPrintfUnchecked(NULL,
612 ssl->sniCertificatePattern,
614 if (sslSetCertificateFromFile(context, certificate) < 0) {
615 if (ssl->generateMissing) {
616 sslGenerateCertificate(certificate, serverName + 1);
618 // No need to check the certificate. If we fail to set it, we will use
619 // the default certificate, instead.
620 sslSetCertificateFromFile(context, certificate);
622 warn("Could not find matching certificate \"%s\" for \"%s\"",
623 certificate, serverName + 1);
624 SSL_CTX_free(context);
625 context = ssl->sslContext;
630 addToTrie(&ssl->sniContexts, serverName+1, (char *)context);
633 if (context != ssl->sslContext) {
634 check(SSL_set_SSL_CTX(sslHndl, context));
636 check(!ERR_peek_error());
637 return SSL_TLSEXT_ERR_OK;
641 #if defined(HAVE_OPENSSL) && !defined(HAVE_GETHOSTBYNAME_R)
642 // This is a not-thread-safe replacement for gethostbyname_r()
643 #define gethostbyname_r x_gethostbyname_r
644 static int gethostbyname_r(const char *name, struct hostent *ret,
645 char *buf ATTR_UNUSED, size_t buflen ATTR_UNUSED,
646 struct hostent **result, int *h_errnop) {
658 struct hostent *he = gethostbyname(name);
672 void sslSetCertificate(struct SSLSupport *ssl, const char *filename,
673 int autoGenerateMissing) {
674 #if defined(HAVE_OPENSSL)
675 check(serverSupportsSSL());
677 char *defaultCertificate;
678 check(defaultCertificate = strdup(filename));
679 char *ptr = strchr(defaultCertificate, '%');
681 check(!strchr(ptr+1, '%'));
682 check(ptr[1] == 's');
683 memmove(ptr, ptr + 2, strlen(ptr)-1);
686 // Try to set the default certificate. If necessary, (re-)generate it.
687 check(ssl->sslContext = SSL_CTX_new(SSLv23_server_method()));
688 if (autoGenerateMissing) {
689 if (sslSetCertificateFromFile(ssl->sslContext, defaultCertificate) < 0) {
690 char hostname[256], buf[4096];
691 check(!gethostname(hostname, sizeof(hostname)));
692 struct hostent he_buf, *he;
694 int ret = gethostbyname_r(hostname, &he_buf, buf, sizeof(buf), &he, &h_err);
695 if (!ret && he && he->h_name) {
696 sslGenerateCertificate(defaultCertificate, he->h_name);
699 warn("Error getting host information: \"%s\".", hstrerror(h_err));
701 sslGenerateCertificate(defaultCertificate, hostname);
704 goto valid_certificate;
707 if (sslSetCertificateFromFile(ssl->sslContext, defaultCertificate) < 0) {
708 fatal("Cannot read valid certificate from \"%s\". "
709 "Check file permissions and file format.", defaultCertificate);
712 free(defaultCertificate);
714 // Enable SNI support so that we can set a different certificate, if the
715 // client asked for it.
718 check(ssl->sniCertificatePattern = strdup(filename));
719 check(SSL_CTX_set_tlsext_servername_callback(ssl->sslContext,
721 check(SSL_CTX_set_tlsext_servername_arg(ssl->sslContext, ssl));
724 dcheck(!ERR_peek_error());
727 ssl->generateMissing = autoGenerateMissing;
731 // Convert the file descriptor to a human-readable format. Attempts to
732 // retrieve the original file name where possible.
734 static char *sslFdToFilename(int fd) {
737 check(proc = stringPrintf(NULL, "/proc/self/fd/%d", fd));
738 check(buf = malloc(len));
741 if ((i = readlink(proc, buf + 1, len-3)) < 0) {
744 check(buf = stringPrintf(NULL, "fd %d", fd));
746 } else if (i >= len-3) {
748 check(buf = realloc(buf, len));
751 check(i >= 0 && i < len);
754 if (!stat(buf + 1, &sb) && S_ISREG(sb.st_mode)) {
761 check(buf = stringPrintf(NULL, "fd %d", fd));
769 void sslSetCertificateFd(struct SSLSupport *ssl, int fd) {
771 check(ssl->sslContext = SSL_CTX_new(SSLv23_server_method()));
772 char *filename = sslFdToFilename(fd);
773 if (!sslSetCertificateFromFd(ssl->sslContext, fd)) {
774 fatal("Cannot read valid certificate from %s. Check file format.",
778 ssl->generateMissing = 0;
782 int sslEnable(struct SSLSupport *ssl, int enabled) {
783 int old = ssl->enabled;
784 ssl->enabled = enabled;
788 void sslBlockSigPipe(void) {
791 sigaddset(&set, SIGPIPE);
792 #if defined(HAVE_PTHREAD_H) && defined(__linux__) && defined(__i386__)
793 if (&pthread_sigmask) {
794 dcheck(!pthread_sigmask(SIG_BLOCK, &set, NULL));
798 dcheck(!sigprocmask(SIG_BLOCK, &set, NULL));
803 // This is a non-thread-safe replacement for sigwait()
804 static int dummysignalno;
805 static void dummysignal(int signo) {
806 dummysignalno = signo;
809 #define sigwait x_sigwait
810 static int sigwait(const sigset_t *set, int *sig) {
811 sigset_t mask, old_mask;
813 #if defined(HAVE_PTHREAD_H) && defined(__linux__) && defined(__i386__)
814 if (&pthread_sigmask) {
815 dcheck(!pthread_sigmask(SIG_BLOCK, &mask, &old_mask));
819 dcheck(!sigprocmask(SIG_BLOCK, &mask, &old_mask));
824 struct sigaction sa[NSIG];
825 memset(sa, 0, sizeof(sa));
826 sa->sa_handler = dummysignal;
827 for (int i = 1; i <= NSIG; i++) {
828 if (sigismember(set, i)) {
830 sigaction(i, sa, sa + i);
835 #if defined(HAVE_PTHREAD_H) && defined(__linux__) && defined(__i386__)
836 if (&pthread_sigmask) {
837 dcheck(!pthread_sigmask(SIG_SETMASK, &old_mask, NULL));
841 dcheck(!sigprocmask(SIG_BLOCK, &old_mask, NULL));
843 return dummysignalno;
847 int sslUnblockSigPipe(void) {
850 check(!sigpending(&set));
851 if (sigismember(&set, SIGPIPE)) {
852 sigwait(&set, &signum);
855 sigaddset(&set, SIGPIPE);
856 #if defined(HAVE_PTHREAD_H) && defined(__linux__) && defined(__i386__)
857 if (&pthread_sigmask) {
858 dcheck(!pthread_sigmask(SIG_UNBLOCK, &set, NULL));
862 dcheck(!sigprocmask(SIG_UNBLOCK, &set, NULL));
867 int sslPromoteToSSL(struct SSLSupport *ssl, SSL **sslHndl, int fd,
868 const char *buf, int len) {
869 #if defined(HAVE_OPENSSL)
873 dcheck(!ERR_peek_error());
874 dcheck(*sslHndl = SSL_new(ssl->sslContext));
875 if (*sslHndl == NULL) {
880 SSL_set_mode(*sslHndl, SSL_MODE_ENABLE_PARTIAL_WRITE);
881 BIO *writeBIO = BIO_new_socket(fd, 0);
882 BIO *readBIO = writeBIO;
884 readBIO = BIO_new(BIO_f_buffer());
885 BIO_push(readBIO, writeBIO);
886 check(BIO_set_buffer_read_data(readBIO, (char *)buf, len));
888 SSL_set_bio(*sslHndl, readBIO, writeBIO);
889 SSL_set_accept_state(*sslHndl);
890 dcheck(!ERR_peek_error());
900 void sslFreeHndl(SSL **sslHndl) {
901 #if defined(HAVE_OPENSSL)
903 // OpenSSL does not always correctly perform reference counting for stacked
904 // BIOs. This is particularly a problem if an SSL connection has two
905 // different BIOs for the read and the write end, with one being a stacked
906 // derivative of the other. Unfortunately, this is exactly the scenario
908 // As a work-around, we un-stack the BIOs prior to freeing the SSL
911 BIO *writeBIO, *readBIO;
912 check(writeBIO = SSL_get_wbio(*sslHndl));
913 check(readBIO = SSL_get_rbio(*sslHndl));
914 if (writeBIO != readBIO) {
915 if (readBIO->next_bio == writeBIO) {
916 // OK, that's exactly the bug we are looking for. We know how to
918 check(BIO_pop(readBIO) == writeBIO);
919 check(readBIO->references == 1);
920 check(writeBIO->references == 1);
921 check(!readBIO->next_bio);
922 check(!writeBIO->prev_bio);
923 } else if (readBIO->next_bio == writeBIO->next_bio &&
924 writeBIO->next_bio->prev_bio == writeBIO) {
925 // Things get even more confused, if the SSL handshake is aborted
927 // OpenSSL appears to internally stack a BIO onto the read end that
928 // does not get removed afterwards. We end up with the original
929 // socket BIO having two different BIOs prepended to it (one for
930 // reading and one for writing). In this case, not only is the
931 // reference count wrong, but the chain of next_bio/prev_bio pairs
932 // is corrupted, too.
934 check(sockBIO = BIO_pop(readBIO));
935 check(sockBIO == BIO_pop(writeBIO));
936 check(readBIO->references == 1);
937 check(writeBIO->references == 1);
938 check(sockBIO->references == 1);
939 check(!readBIO->next_bio);
940 check(!writeBIO->next_bio);
941 check(!sockBIO->prev_bio);
942 BIO_free_all(sockBIO);
944 // We do not know, how to fix this situation. Something must have
945 // changed in the OpenSSL internals. Either, this is a new bug, or
946 // somebody fixed the code in a way that we did not anticipate.
947 fatal("Unexpected corruption of OpenSSL data structures");
951 dcheck(!ERR_peek_error());