diff --git a/libhttp/ssl.c b/libhttp/ssl.c index d2788dd..b96f9d9 100644 --- a/libhttp/ssl.c +++ b/libhttp/ssl.c @@ -136,6 +136,9 @@ int (*SSL_write)(SSL *, const void *, int); SSL_METHOD * (*SSLv23_server_method)(void); X509 * (*d2i_X509)(X509 **px, const unsigned char **in, int len); void (*X509_free)(X509 *a); +int (*x_SSL_CTX_set_cipher_list)(SSL_CTX *ctx, const char *str); +void (*x_sk_zero)(void *st); +void * (*x_SSL_COMP_get_compression_methods)(void); #endif static void sslDestroyCachedContext(void *ssl_, char *context_) { @@ -308,7 +311,9 @@ static void loadSSL(void) { { { &SSL_write }, "SSL_write" }, { { &SSLv23_server_method }, "SSLv23_server_method" }, { { &d2i_X509 }, "d2i_X509" }, - { { &X509_free }, "X509_free" } + { { &X509_free }, "X509_free" }, + { { &x_SSL_CTX_set_cipher_list }, "SSL_CTX_set_cipher_list" }, + { { &x_sk_zero }, "sk_zero" } }; for (unsigned i = 0; i < sizeof(symbols)/sizeof(symbols[0]); i++) { if (!(*symbols[i].var = loadSymbol(path_libssl, symbols[i].fn))) { @@ -320,6 +325,10 @@ static void loadSSL(void) { return; } } + // These are optional + x_SSL_COMP_get_compression_methods = loadSymbol(path_libssl, "SSL_COMP_get_compression_methods"); + // ends + SSL_library_init(); dcheck(!ERR_peek_error()); debug("Loaded SSL suppport"); @@ -583,6 +592,32 @@ static int sslSetCertificateFromFile(SSL_CTX *context, } #endif +static SSL_CTX *sslMakeContext(void) { + SSL_CTX *context; + check(context = SSL_CTX_new(SSLv23_server_method())); + SSL_CTX_set_options(context, SSL_OP_ALL); + SSL_CTX_set_options(context, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3); +#ifdef SSL_OP_NO_COMPRESSION + SSL_CTX_set_options(context, SSL_OP_NO_COMPRESSION); +#endif +#if defined(HAVE_DLOPEN) + if (SSL_COMP_get_compression_methods) { + sk_SSL_COMP_zero(SSL_COMP_get_compression_methods()); + } +#elif OPENSSL_VERSION_NUMBER >= 0x00908000L + sk_SSL_COMP_zero(SSL_COMP_get_compression_methods()); +#endif + SSL_CTX_set_options(context, SSL_OP_SINGLE_DH_USE); +#ifdef SSL_OP_SINGLE_ECDH_USE + SSL_CTX_set_options(context, SSL_OP_SINGLE_ECDH_USE); +#endif +#ifdef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION + SSL_CTX_set_options(context, SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION); +#endif + check(SSL_CTX_set_cipher_list(context, "HIGH:MEDIUM:!aNULL:!MD5")); + return context; +} + #ifdef HAVE_TLSEXT static int sslSNICallback(SSL *sslHndl, int *al ATTR_UNUSED, struct SSLSupport *ssl) { @@ -619,7 +654,7 @@ static int sslSNICallback(SSL *sslHndl, int *al ATTR_UNUSED, serverName+1, NULL); if (context == NULL) { - check(context = SSL_CTX_new(SSLv23_server_method())); + context = sslMakeContext(); check(ssl->sniCertificatePattern); char *certificate = stringPrintfUnchecked(NULL, ssl->sniCertificatePattern, @@ -697,7 +732,7 @@ void sslSetCertificate(struct SSLSupport *ssl, const char *filename, } // Try to set the default certificate. If necessary, (re-)generate it. - check(ssl->sslContext = SSL_CTX_new(SSLv23_server_method())); + ssl->sslContext = sslMakeContext(); if (autoGenerateMissing) { if (sslSetCertificateFromFile(ssl->sslContext, defaultCertificate) < 0) { char hostname[256], buf[4096]; @@ -781,7 +816,7 @@ static char *sslFdToFilename(int fd) { void sslSetCertificateFd(struct SSLSupport *ssl, int fd) { #ifdef HAVE_OPENSSL - check(ssl->sslContext = SSL_CTX_new(SSLv23_server_method())); + ssl->sslContext = sslMakeContext(); char *filename = sslFdToFilename(fd); if (!sslSetCertificateFromFd(ssl->sslContext, fd)) { fatal("Cannot read valid certificate from %s. Check file format.", diff --git a/libhttp/ssl.h b/libhttp/ssl.h index 62d585b..e1477ab 100644 --- a/libhttp/ssl.h +++ b/libhttp/ssl.h @@ -111,6 +111,9 @@ extern int (*x_SSL_write)(SSL *, const void *, int); extern SSL_METHOD *(*x_SSLv23_server_method)(void); extern X509 * (*x_d2i_X509)(X509 **px, const unsigned char **in, int len); extern void (*x_X509_free)(X509 *a); +extern int (*x_SSL_CTX_set_cipher_list)(SSL_CTX *ctx, const char *str); +extern void (*x_sk_zero)(void *st); +extern void *(*x_SSL_COMP_get_compression_methods)(void); #define BIO_ctrl x_BIO_ctrl #define BIO_f_buffer x_BIO_f_buffer @@ -151,6 +154,9 @@ extern void (*x_X509_free)(X509 *a); #define SSLv23_server_method x_SSLv23_server_method #define d2i_X509 x_d2i_X509 #define X509_free x_X509_free +#define SSL_CTX_set_cipher_list x_SSL_CTX_set_cipher_list +#define sk_zero x_sk_zero +#define SSL_COMP_get_compression_methods x_SSL_COMP_get_compression_methods #undef BIO_set_buffer_read_data #undef SSL_CTX_set_tlsext_servername_arg diff --git a/shellinabox/shell_in_a_box.jspp b/shellinabox/shell_in_a_box.jspp index de7e5be..5b3825a 100644 --- a/shellinabox/shell_in_a_box.jspp +++ b/shellinabox/shell_in_a_box.jspp @@ -164,6 +164,7 @@ ShellInABox.prototype.sendRequest = function(request) { request = new XMLHttpRequest(); } request.open('POST', this.url + '?', true); + request.timeout = 30000; // Don't leave POST pending forever: force 30s timeout to prevent HTTP Proxy thread hijack request.setRequestHeader('Cache-Control', 'no-cache'); request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=utf-8'); @@ -202,8 +203,12 @@ ShellInABox.prototype.onReadyStateChange = function(request) { this.sendRequest(request); } } else if (request.status == 0) { - // Time Out - this.sendRequest(request); + // Time Out or other connection problems: retry after 1s to prevent release CPU before retry + setTimeout(function(shellInABox) { + return function() { + shellInABox.sendRequest(); + }; + }(this), 1000); } else { this.sessionClosed(); }