Index: generic/tls.c ================================================================== --- generic/tls.c +++ generic/tls.c @@ -2748,38 +2748,26 @@ * *------------------------------------------------------------------- */ void Tls_Clean(State *statePtr) { dprintf("Called"); + + if (statePtr->ssl) { + /* Send close_notify message */ + dprintf("SSL_shutdown(%p)", statePtr->ssl); + SSL_shutdown(statePtr->ssl); + } /* * we're assuming here that we're single-threaded */ if (statePtr->timer != (Tcl_TimerToken) NULL) { Tcl_DeleteTimerHandler(statePtr->timer); statePtr->timer = NULL; } - if (statePtr->protos) { - ckfree(statePtr->protos); - statePtr->protos = NULL; - } - if (statePtr->bio) { - /* This will call SSL_shutdown. Bug 1414045 */ - dprintf("BIO_free_all(%p)", statePtr->bio); - BIO_free_all(statePtr->bio); - statePtr->bio = NULL; - } - if (statePtr->ssl) { - dprintf("SSL_free(%p)", statePtr->ssl); - SSL_free(statePtr->ssl); - statePtr->ssl = NULL; - } - if (statePtr->ctx) { - SSL_CTX_free(statePtr->ctx); - statePtr->ctx = NULL; - } + /* Remove callbacks */ if (statePtr->callback) { Tcl_DecrRefCount(statePtr->callback); statePtr->callback = NULL; } if (statePtr->password) { @@ -2788,10 +2776,33 @@ } if (statePtr->vcmd) { Tcl_DecrRefCount(statePtr->vcmd); statePtr->vcmd = NULL; } + + if (statePtr->protos) { + ckfree(statePtr->protos); + statePtr->protos = NULL; + } + + if (statePtr->bio) { + /* This will call SSL_shutdown. Bug 1414045 */ + dprintf("BIO_free_all(%p)", statePtr->bio); + BIO_free_all(statePtr->bio); + statePtr->bio = NULL; + } + + if (statePtr->ssl) { + dprintf("SSL_free(%p)", statePtr->ssl); + SSL_free(statePtr->ssl); + statePtr->ssl = NULL; + } + + if (statePtr->ctx) { + SSL_CTX_free(statePtr->ctx); + statePtr->ctx = NULL; + } dprintf("Returning"); } /* @@ -2878,21 +2889,39 @@ } /* *------------------------------------------------------* * + * TlsLibShutdown -- + * + * Shutdown SSL library once per application + * + * Results: + * A standard TCL result + * + * Side effects: + * Shutdown SSL library + * + *------------------------------------------------------* + */ +static int TlsLibShutdown(ClientData clientData) { + BIO_cleanup(); + return TCL_OK; +} + +/* + *------------------------------------------------------* + * * TlsLibInit -- * - * ------------------------------------------------* * Initializes SSL library once per application - * ------------------------------------------------* * - * Side effects: - * initializes SSL library + * Results: + * A standard Tcl result * - * Result: - * none + * Side effects: + * Initializes SSL library * *------------------------------------------------------* */ static int TlsLibInit() { static int initialized = 0; @@ -2906,13 +2935,14 @@ | OPENSSL_INIT_LOAD_CONFIG | OPENSSL_INIT_ASYNC, NULL)) { return TCL_ERROR; } /* Create BIO handlers */ - if (BIO_new_tcl(NULL, 0) == NULL) { - return TCL_ERROR; - } + BIO_new_tcl(NULL, 0); + + /* Create exit handler */ + Tcl_CreateExitHandler(TlsLibShutdown, NULL); initialized = 1; } return TCL_OK; } @@ -2925,16 +2955,17 @@ *------------------------------------------------------------------- * * Tls_Init -- * * This is a package initialization procedure, which is called - * by Tcl when this package is to be added to an interpreter. + * by TCL when this package is to be added to an interpreter. * - * Results: Ssl configured and loaded + * Results: + * Initializes structures and creates commands. * * Side effects: - * create the ssl command, initialize ssl context + * Create the commands * *------------------------------------------------------------------- */ #if TCL_MAJOR_VERSION > 8 @@ -2980,26 +3011,23 @@ return Tcl_PkgProvide(interp, PACKAGE_NAME, PACKAGE_VERSION); } /* - *------------------------------------------------------* + *------------------------------------------------------------------- * * Tls_SafeInit -- * - * ------------------------------------------------* - * Standard procedure required by 'load'. - * Initializes this extension for a safe interpreter. - * ------------------------------------------------* - * - * Side effects: - * As of 'Tls_Init' - * - * Result: - * A standard Tcl error code. - * - *------------------------------------------------------* + * This is a package initialization procedure for safe interps. + * + * Results: + * Same as of 'Tls_Init' + * + * Side effects: + * Same as of 'Tls_Init' + * + *------------------------------------------------------------------- */ DLLEXPORT int Tls_SafeInit(Tcl_Interp *interp) { dprintf("Called"); return Tls_Init(interp); }