"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "libhttp/ssl.c" between
shellinabox-2.19.tar.gz and shellinabox-2.20.tar.gz

About: shellinabox implements a web server that can export arbitrary command line tools to a web based terminal emulator. This emulator is accessible to any JavaScript and CSS enabled web browser. Fork of the no longer maintained original version on https://shellinabox.com/ respectively https://code.google.com/archive/p/shellinabox/.

ssl.c  (shellinabox-2.19):ssl.c  (shellinabox-2.20)
skipping to change at line 103 skipping to change at line 103
#endif #endif
#if defined(HAVE_DLOPEN) #if defined(HAVE_DLOPEN)
// SSL support is optional. Only enable it, if the library can be loaded. // SSL support is optional. Only enable it, if the library can be loaded.
long (*BIO_ctrl)(BIO *, int, long, void *); long (*BIO_ctrl)(BIO *, int, long, void *);
BIO_METHOD * (*BIO_f_buffer)(void); BIO_METHOD * (*BIO_f_buffer)(void);
void (*BIO_free_all)(BIO *); void (*BIO_free_all)(BIO *);
BIO * (*BIO_new)(BIO_METHOD *); BIO * (*BIO_new)(BIO_METHOD *);
BIO * (*BIO_new_socket)(int, int); BIO * (*BIO_new_socket)(int, int);
BIO * (*BIO_next)(BIO *);
BIO * (*BIO_pop)(BIO *); BIO * (*BIO_pop)(BIO *);
BIO * (*BIO_push)(BIO *, BIO *); BIO * (*BIO_push)(BIO *, BIO *);
#if defined(HAVE_OPENSSL_EC) #if defined(HAVE_OPENSSL_EC)
void (*EC_KEY_free)(EC_KEY *); void (*EC_KEY_free)(EC_KEY *);
EC_KEY * (*EC_KEY_new_by_curve_name)(int); EC_KEY * (*EC_KEY_new_by_curve_name)(int);
#endif #endif
void (*ERR_clear_error)(void); void (*ERR_clear_error)(void);
unsigned long (*ERR_peek_error)(void); unsigned long (*ERR_peek_error)(void);
long (*SSL_CTX_callback_ctrl)(SSL_CTX *, int, void (*)(void)); long (*SSL_CTX_callback_ctrl)(SSL_CTX *, int, void (*)(void));
int (*SSL_CTX_check_private_key)(const SSL_CTX *); int (*SSL_CTX_check_private_key)(const SSL_CTX *);
skipping to change at line 283 skipping to change at line 284
void *avoid_gcc_warning_about_type_punning; void *avoid_gcc_warning_about_type_punning;
void **var; void **var;
}; };
const char *fn; const char *fn;
} symbols[] = { } symbols[] = {
{ { &BIO_ctrl }, "BIO_ctrl" }, { { &BIO_ctrl }, "BIO_ctrl" },
{ { &BIO_f_buffer }, "BIO_f_buffer" }, { { &BIO_f_buffer }, "BIO_f_buffer" },
{ { &BIO_free_all }, "BIO_free_all" }, { { &BIO_free_all }, "BIO_free_all" },
{ { &BIO_new }, "BIO_new" }, { { &BIO_new }, "BIO_new" },
{ { &BIO_new_socket }, "BIO_new_socket" }, { { &BIO_new_socket }, "BIO_new_socket" },
{ { &BIO_next }, "BIO_next" },
{ { &BIO_pop }, "BIO_pop" }, { { &BIO_pop }, "BIO_pop" },
{ { &BIO_push }, "BIO_push" }, { { &BIO_push }, "BIO_push" },
{ { &ERR_clear_error }, "ERR_clear_error" }, { { &ERR_clear_error }, "ERR_clear_error" },
{ { &ERR_clear_error }, "ERR_clear_error" }, { { &ERR_clear_error }, "ERR_clear_error" },
{ { &ERR_peek_error }, "ERR_peek_error" }, { { &ERR_peek_error }, "ERR_peek_error" },
{ { &ERR_peek_error }, "ERR_peek_error" }, { { &ERR_peek_error }, "ERR_peek_error" },
#ifdef HAVE_OPENSSL_EC #ifdef HAVE_OPENSSL_EC
{ { &EC_KEY_free }, "EC_KEY_free" }, { { &EC_KEY_free }, "EC_KEY_free" },
{ { &EC_KEY_new_by_curve_name }, "EC_KEY_new_by_curve_name" }, { { &EC_KEY_new_by_curve_name }, "EC_KEY_new_by_curve_name" },
#endif #endif
skipping to change at line 1015 skipping to change at line 1017
dcheck(!ERR_peek_error()); dcheck(!ERR_peek_error());
} }
sslUnblockSigPipe(); sslUnblockSigPipe();
return rc; return rc;
#else #else
errno = EINVAL; errno = EINVAL;
return -1; return -1;
#endif #endif
} }
BIO *sslGetNextBIO(BIO *b) {
#if OPENSSL_VERSION_NUMBER <= 0x10100000L
return b->next_bio;
#else
return BIO_next(b);
#endif
}
void sslFreeHndl(SSL **sslHndl) { void sslFreeHndl(SSL **sslHndl) {
#if defined(HAVE_OPENSSL) #if defined(HAVE_OPENSSL)
if (*sslHndl) { if (*sslHndl) {
// OpenSSL does not always correctly perform reference counting for stacked // OpenSSL does not always correctly perform reference counting for stacked
// BIOs. This is particularly a problem if an SSL connection has two // BIOs. This is particularly a problem if an SSL connection has two
// different BIOs for the read and the write end, with one being a stacked // different BIOs for the read and the write end, with one being a stacked
// derivative of the other. Unfortunately, this is exactly the scenario // derivative of the other. Unfortunately, this is exactly the scenario
// that we set up. // that we set up with call to "BIO_push(readBIO, writeBIO)" in function
// "sslPromoteToSSL()".
// As a work-around, we un-stack the BIOs prior to freeing the SSL // As a work-around, we un-stack the BIOs prior to freeing the SSL
// connection. // connection.
debug("[ssl] Freeing SSL handle.");
ERR_clear_error(); ERR_clear_error();
BIO *writeBIO, *readBIO; BIO *writeBIO, *readBIO;
check(writeBIO = SSL_get_wbio(*sslHndl)); check(writeBIO = SSL_get_wbio(*sslHndl));
check(readBIO = SSL_get_rbio(*sslHndl)); check(readBIO = SSL_get_rbio(*sslHndl));
if (writeBIO != readBIO) { if (writeBIO != readBIO) {
if (readBIO->next_bio == writeBIO) { if (sslGetNextBIO(readBIO) == writeBIO) {
// OK, that's exactly the bug we are looking for. We know how to // OK, that's exactly the bug we are looking for. We know that
// fix it. // writeBIO needs to be removed from readBIO chain.
debug("[ssl] Removing stacked write BIO!");
check(BIO_pop(readBIO) == writeBIO); check(BIO_pop(readBIO) == writeBIO);
check(readBIO->references == 1); check(!sslGetNextBIO(readBIO));
check(writeBIO->references == 1); } else if (sslGetNextBIO(readBIO) == sslGetNextBIO(writeBIO)) {
check(!readBIO->next_bio);
check(!writeBIO->prev_bio);
} else if (readBIO->next_bio == writeBIO->next_bio &&
writeBIO->next_bio->prev_bio == writeBIO) {
// Things get even more confused, if the SSL handshake is aborted // Things get even more confused, if the SSL handshake is aborted
// prematurely. // prematurely.
// OpenSSL appears to internally stack a BIO onto the read end that // OpenSSL appears to internally stack a BIO onto the read end that
// does not get removed afterwards. We end up with the original // does not get removed afterwards. We end up with the original
// socket BIO having two different BIOs prepended to it (one for // socket BIO having two different BIOs prepended to it (one for
// reading and one for writing). In this case, not only is the // reading and one for writing). In this case, not only is the
// reference count wrong, but the chain of next_bio/prev_bio pairs // reference count wrong, but the chain of next_bio/prev_bio pairs
// is corrupted, too. // is corrupted, too.
warn("[ssl] Removing stacked socket BIO!");
BIO *sockBIO; BIO *sockBIO;
check(sockBIO = BIO_pop(readBIO)); check(sockBIO = BIO_pop(readBIO));
check(sockBIO == BIO_pop(writeBIO)); check(sockBIO == BIO_pop(writeBIO));
check(readBIO->references == 1); check(!sslGetNextBIO(readBIO));
check(writeBIO->references == 1); check(!sslGetNextBIO(writeBIO));
check(sockBIO->references == 1); check(!sslGetNextBIO(sockBIO));
check(!readBIO->next_bio);
check(!writeBIO->next_bio);
check(!sockBIO->prev_bio);
BIO_free_all(sockBIO); BIO_free_all(sockBIO);
} else { } else {
// We do not know, how to fix this situation. Something must have // We do not know, how to fix this situation. Something must have
// changed in the OpenSSL internals. Either, this is a new bug, or // changed in the OpenSSL internals. Either, this is a new bug, or
// somebody fixed the code in a way that we did not anticipate. // somebody fixed the code in a way that we did not anticipate.
fatal("[ssl] Unexpected corruption of OpenSSL data structures"); fatal("[ssl] Unexpected corruption of OpenSSL data structures");
} }
} }
SSL_free(*sslHndl); SSL_free(*sslHndl);
dcheck(!ERR_peek_error()); dcheck(!ERR_peek_error());
 End of changes. 9 change blocks. 
16 lines changed or deleted 23 lines changed or added

Home  |  About  |  All  |  Newest  |  Fossies Dox  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTPS