Index: generic/tls.c ================================================================== --- generic/tls.c +++ generic/tls.c @@ -280,18 +280,19 @@ Tcl_ListObjAppendElement(interp, cmdPtr, Tls_NewX509Obj(interp, cert)); Tcl_ListObjAppendElement(interp, cmdPtr, Tcl_NewIntObj(ok)); Tcl_ListObjAppendElement(interp, cmdPtr, Tcl_NewStringObj((char*)X509_verify_cert_error_string(err), -1)); - statePtr->flags |= TLS_TCL_CALLBACK; + /* Prevent I/O while callback is in progress */ + /* statePtr->flags |= TLS_TCL_CALLBACK; */ /* Eval callback command */ Tcl_IncrRefCount(cmdPtr); ok = EvalCallback(interp, statePtr, cmdPtr); Tcl_DecrRefCount(cmdPtr); - statePtr->flags &= ~(TLS_TCL_CALLBACK); + /* statePtr->flags &= ~(TLS_TCL_CALLBACK); */ return(ok); /* By default, leave verification unchanged. */ } /* *------------------------------------------------------------------- @@ -307,11 +308,11 @@ *------------------------------------------------------------------- */ void Tls_Error(State *statePtr, char *msg) { Tcl_Interp *interp = statePtr->interp; - Tcl_Obj *cmdPtr, listPtr; + Tcl_Obj *cmdPtr, *listPtr; unsigned long err; statePtr->err = msg; dprintf("Called"); @@ -331,11 +332,11 @@ Tcl_ListObjAppendElement(interp, cmdPtr, Tcl_NewStringObj(msg, -1)); } else { listPtr = Tcl_NewListObj(0, NULL); while ((err = ERR_get_error()) != 0) { - Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewStringObj(ERR_reason_error_string(err, -1)); + Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewStringObj(ERR_reason_error_string(err), -1)); } Tcl_ListObjAppendElement(interp, cmdPtr, listPtr); } /* Eval callback command */ @@ -357,10 +358,13 @@ *------------------------------------------------------------------- */ void KeyLogCallback(const SSL *ssl, const char *line) { char *str = getenv(SSLKEYLOGFILE); FILE *fd; + + dprintf("Called"); + if (str) { fd = fopen(str, "a"); fprintf(fd, "%s\n",line); fclose(fd); } @@ -384,10 +388,11 @@ Tcl_Obj *cmdPtr; int code; dprintf("Called"); + /* If no callback, use default callback */ if (statePtr->password == NULL) { if (Tcl_EvalEx(interp, "tls::password", -1, TCL_EVAL_GLOBAL) == TCL_OK) { char *ret = (char *) Tcl_GetStringResult(interp); strncpy(buf, ret, (size_t) size); return (int)strlen(ret); Index: generic/tlsIO.c ================================================================== --- generic/tlsIO.c +++ generic/tlsIO.c @@ -16,10 +16,11 @@ * SSLtcl (Peter Antman) * */ #include "tlsInt.h" +#include /* * Forward declarations */ static void TlsChannelHandlerTimer(ClientData clientData); @@ -109,17 +110,17 @@ */ int Tls_WaitForConnect(State *statePtr, int *errorCodePtr, int handshakeFailureIsPermanent) { unsigned long backingError; int err, rc; int bioShouldRetry; + *errorCodePtr = 0; dprintf("WaitForConnect(%p)", (void *) statePtr); dprintFlags(statePtr); if (!(statePtr->flags & TLS_TCL_INIT)) { dprintf("Tls_WaitForConnect called on already initialized channel -- returning with immediate success"); - *errorCodePtr = 0; return(0); } if (statePtr->flags & TLS_TCL_HANDSHAKE_FAILED) { /* @@ -193,19 +194,19 @@ dprintf("We have either completely established the session or completely failed it -- there is no more need to ever retry it though"); break; } - *errorCodePtr = EINVAL; - switch (rc) { case SSL_ERROR_NONE: /* The connection is up, we are done here */ dprintf("The connection is up"); + *errorCodePtr = 0; break; case SSL_ERROR_ZERO_RETURN: - dprintf("SSL_ERROR_ZERO_RETURN: Connect returned an invalid value...") + dprintf("SSL_ERROR_ZERO_RETURN: Connect returned an invalid value..."); + *errorCodePtr = EINVAL; return(-1); case SSL_ERROR_SYSCALL: backingError = ERR_get_error(); if (backingError == 0 && err == 0) { @@ -306,10 +307,11 @@ dprintf("Calling Tls_WaitForConnect"); tlsConnect = Tls_WaitForConnect(statePtr, errorCodePtr, 0); if (tlsConnect < 0) { dprintf("Got an error waiting to connect (tlsConnect = %i, *errorCodePtr = %i)", tlsConnect, *errorCodePtr); + Tls_Error(statePtr, strerror(*errorCodePtr)); bytesRead = -1; if (*errorCodePtr == ECONNRESET) { dprintf("Got connection reset"); /* Soft EOF */ @@ -393,10 +395,13 @@ *errorCodePtr = 0; bytesRead = 0; break; } + if (*errorCodePtr < 0) { + Tls_Error(statePtr, strerror(*errorCodePtr)); + } dprintf("Input(%d) -> %d [%d]", bufSize, bytesRead, *errorCodePtr); return(bytesRead); } /* @@ -436,10 +441,11 @@ dprintf("Calling Tls_WaitForConnect"); tlsConnect = Tls_WaitForConnect(statePtr, errorCodePtr, 1); if (tlsConnect < 0) { dprintf("Got an error waiting to connect (tlsConnect = %i, *errorCodePtr = %i)", tlsConnect, *errorCodePtr); + Tls_Error(statePtr, strerror(*errorCodePtr)); written = -1; if (*errorCodePtr == ECONNRESET) { dprintf("Got connection reset"); /* Soft EOF */ @@ -536,10 +542,13 @@ default: dprintf(" unknown err: %d", err); break; } + if (*errorCodePtr < 0) { + Tls_Error(statePtr, strerror(*errorCodePtr)); + } dprintf("Output(%d) -> %d", toWrite, written); return(written); } /* @@ -775,10 +784,11 @@ } dprintf("Calling Tls_WaitForConnect"); errorCode = 0; if (Tls_WaitForConnect(statePtr, &errorCode, 1) < 0) { + Tls_Error(statePtr, strerror(errorCode)); if (errorCode == EAGAIN) { dprintf("Async flag could be set (didn't check) and errorCode == EAGAIN: Returning 0"); return 0; }