@@ -1,11 +1,9 @@ /* * Copyright (C) 1997-2000 Matt Newman * Copyright (C) 2000 Ajuba Solutions * - * $Header: /home/rkeene/tmp/cvs2fossil/../tcltls/tls/tls/tlsIO.c,v 1.19 2015/06/06 09:07:08 apnadkarni Exp $ - * * TLS (aka SSL) Channel - can be layered on any bi-directional * Tcl_Channel (Note: Requires Trf Core Patch) * * This was built from scratch based upon observation of OpenSSL 0.9.2B * @@ -284,11 +282,11 @@ TlsCloseProc(ClientData instanceData, /* The socket to close. */ Tcl_Interp *interp) /* For error reporting - unused. */ { State *statePtr = (State *) instanceData; - dprintf(stderr,"\nTlsCloseProc(0x%x)", (unsigned int) statePtr); + dprintf("TlsCloseProc(%p)", (void *) statePtr); if (channelTypeVersion == TLS_CHANNEL_VERSION_1) { /* * Remove event handler to underlying channel, this could * be because we are closing for real, or being "unstacked". @@ -332,29 +330,35 @@ State *statePtr = (State *) instanceData; int bytesRead; /* How many bytes were read? */ *errorCodePtr = 0; - dprintf(stderr,"\nBIO_read(%d)", bufSize); + dprintf("BIO_read(%d)", bufSize); if (statePtr->flags & TLS_TCL_CALLBACK) { /* don't process any bytes while verify callback is running */ + dprintf("Callback is running, reading 0 bytes"); + bytesRead = 0; goto input; } if (!SSL_is_init_finished(statePtr->ssl)) { bytesRead = Tls_WaitForConnect(statePtr, errorCodePtr); if (bytesRead <= 0) { + dprintf("Got an error (bytesRead = %i)", bytesRead); + if (*errorCodePtr == ECONNRESET) { + dprintf("Got connection reset"); /* Soft EOF */ *errorCodePtr = 0; bytesRead = 0; } goto input; } } + if (statePtr->flags & TLS_TCL_INIT) { statePtr->flags &= ~(TLS_TCL_INIT); } /* * We need to clear the SSL error stack now because we sometimes reach @@ -367,20 +371,20 @@ * functions play with the retry flags though, and this seems to work * correctly. Similar fix in TlsOutputProc. - hobbs */ ERR_clear_error(); bytesRead = BIO_read(statePtr->bio, buf, bufSize); - dprintf(stderr,"\nBIO_read -> %d", bytesRead); + dprintf("BIO_read -> %d", bytesRead); if (bytesRead < 0) { int err = SSL_get_error(statePtr->ssl, bytesRead); if (err == SSL_ERROR_SSL) { Tls_Error(statePtr, SSL_ERROR(statePtr->ssl, bytesRead)); *errorCodePtr = ECONNABORTED; } else if (BIO_should_retry(statePtr->bio)) { - dprintf(stderr,"RE! "); + dprintf("RE! "); *errorCodePtr = EAGAIN; } else { *errorCodePtr = Tcl_GetErrno(); if (*errorCodePtr == ECONNRESET) { /* Soft EOF */ @@ -388,11 +392,11 @@ bytesRead = 0; } } } input: - dprintf(stderr, "\nInput(%d) -> %d [%d]", bufSize, bytesRead, *errorCodePtr); + dprintf("Input(%d) -> %d [%d]", bufSize, bytesRead, *errorCodePtr); return bytesRead; } /* *------------------------------------------------------------------- @@ -421,11 +425,11 @@ State *statePtr = (State *) instanceData; int written, err; *errorCodePtr = 0; - dprintf(stderr,"\nBIO_write(0x%x, %d)", (unsigned int) statePtr, toWrite); + dprintf("BIO_write(%p, %d)", (void *) statePtr, toWrite); if (statePtr->flags & TLS_TCL_CALLBACK) { /* don't process any bytes while verify callback is running */ written = -1; *errorCodePtr = EAGAIN; @@ -433,18 +437,20 @@ } if (!SSL_is_init_finished(statePtr->ssl)) { written = Tls_WaitForConnect(statePtr, errorCodePtr); if (written <= 0) { + dprintf("Tls_WaitForConnect returned %i (err = %i)", written, *errorCodePtr); + goto output; } } if (statePtr->flags & TLS_TCL_INIT) { statePtr->flags &= ~(TLS_TCL_INIT); } if (toWrite == 0) { - dprintf(stderr, "zero-write\n"); + dprintf("zero-write"); BIO_flush(statePtr->bio); written = 0; goto output; } else { /* @@ -458,51 +464,51 @@ * BIO functions play with the retry flags though, and this seems to * work correctly. Similar fix in TlsInputProc. - hobbs */ ERR_clear_error(); written = BIO_write(statePtr->bio, buf, toWrite); - dprintf(stderr,"\nBIO_write(0x%x, %d) -> [%d]", - (unsigned int) statePtr, toWrite, written); + dprintf("BIO_write(%p, %d) -> [%d]", + (void *) statePtr, toWrite, written); } if (written <= 0) { switch ((err = SSL_get_error(statePtr->ssl, written))) { case SSL_ERROR_NONE: if (written < 0) { written = 0; } break; case SSL_ERROR_WANT_WRITE: - dprintf(stderr," write W BLOCK"); + dprintf(" write W BLOCK"); break; case SSL_ERROR_WANT_READ: - dprintf(stderr," write R BLOCK"); + dprintf(" write R BLOCK"); break; case SSL_ERROR_WANT_X509_LOOKUP: - dprintf(stderr," write X BLOCK"); + dprintf(" write X BLOCK"); break; case SSL_ERROR_ZERO_RETURN: - dprintf(stderr," closed\n"); + dprintf(" closed"); written = 0; break; case SSL_ERROR_SYSCALL: *errorCodePtr = Tcl_GetErrno(); - dprintf(stderr," [%d] syscall errr: %d", + dprintf(" [%d] syscall errr: %d", written, *errorCodePtr); written = -1; break; case SSL_ERROR_SSL: Tls_Error(statePtr, SSL_ERROR(statePtr->ssl, written)); *errorCodePtr = ECONNABORTED; written = -1; break; default: - dprintf(stderr," unknown err: %d\n", err); + dprintf(" unknown err: %d", err); break; } } output: - dprintf(stderr, "\nOutput(%d) -> %d", toWrite, written); + dprintf("Output(%d) -> %d", toWrite, written); return written; } /* *------------------------------------------------------------------- @@ -551,16 +557,16 @@ /* * Request for a specific option has to fail, we don't have any. */ return TCL_ERROR; } else { +#if 0 size_t len = 0; if (optionName != (char *) NULL) { len = strlen(optionName); } -#if 0 if ((len == 0) || ((len > 1) && (optionName[1] == 'c') && (strncmp(optionName, "-cipher", len) == 0))) { if (len == 0) { Tcl_DStringAppendElement(dsPtr, "-cipher"); } @@ -597,11 +603,11 @@ * combination of TCL_READABLE, * TCL_WRITABLE and TCL_EXCEPTION. */ { State *statePtr = (State *) instanceData; - dprintf(stderr, "TlsWatchProc(0x%x)\n", mask); + dprintf("TlsWatchProc(0x%x)", mask); /* Pretend to be dead as long as the verify callback is running. * Otherwise that callback could be invoked recursively. */ if (statePtr->flags & TLS_TCL_CALLBACK) { return; } @@ -738,13 +744,13 @@ return 0; } if (statePtr->flags & TLS_TCL_INIT && !SSL_is_init_finished(statePtr->ssl)) { - int errorCode; - if (Tls_WaitForConnect(statePtr, &errorCode) <= 0 - && errorCode == EAGAIN) { + int errorCode = 0; + if (Tls_WaitForConnect(statePtr, &errorCode) <= 0 && errorCode == EAGAIN) { + dprintf("Async flag could be set (didn't check) and errorCode == EAGAIN"); return 0; } } return mask; @@ -776,11 +782,11 @@ ClientData clientData; int mask; { State *statePtr = (State *) clientData; -dprintf(stderr, "HANDLER(0x%x)\n", mask); + dprintf("HANDLER(0x%x)", mask); Tcl_Preserve( (ClientData)statePtr); if (mask & TCL_READABLE) { BIO_set_flags(statePtr->p_bio, BIO_FLAGS_READ); } else { @@ -885,11 +891,11 @@ State *statePtr; int *errorCodePtr; /* Where to store error code. */ { int err; - dprintf(stderr,"\nWaitForConnect(0x%x)", (unsigned int) statePtr); + dprintf("WaitForConnect(%p)", (void *) statePtr); if (statePtr->flags & TLS_TCL_HANDSHAKE_FAILED) { /* * We choose ECONNRESET over ECONNABORTED here because some server * side code, on the wiki for example, sets up a read handler that @@ -904,41 +910,47 @@ } for (;;) { /* Not initialized yet! */ if (statePtr->flags & TLS_TCL_SERVER) { + dprintf("Calling SSL_accept()"); err = SSL_accept(statePtr->ssl); } else { + dprintf("Calling SSL_connect()"); err = SSL_connect(statePtr->ssl); } + /*SSL_write(statePtr->ssl, (char*)&err, 0); HACK!!! */ if (err > 0) { + dprintf("That seems to have gone okay"); BIO_flush(statePtr->bio); - } - - if (err <= 0) { + } else { int rc = SSL_get_error(statePtr->ssl, err); + + dprintf("Got error: %i (rc = %i)", err, rc); if (rc == SSL_ERROR_SSL) { Tls_Error(statePtr, (char *)ERR_reason_error_string(ERR_get_error())); statePtr->flags |= TLS_TCL_HANDSHAKE_FAILED; *errorCodePtr = ECONNABORTED; return -1; } else if (BIO_should_retry(statePtr->bio)) { if (statePtr->flags & TLS_TCL_ASYNC) { - dprintf(stderr,"E! "); + dprintf("E! "); *errorCodePtr = EAGAIN; return -1; } else { continue; } } else if (err == 0) { if (Tcl_Eof(statePtr->self)) { + dprintf("Error = 0 and EOF is set, returning with 0"); + return 0; } - dprintf(stderr,"CR! "); + dprintf("CR! "); *errorCodePtr = ECONNRESET; return -1; } if (statePtr->flags & TLS_TCL_SERVER) { err = SSL_get_verify_result(statePtr->ssl); @@ -949,14 +961,14 @@ *errorCodePtr = ECONNABORTED; return -1; } } *errorCodePtr = Tcl_GetErrno(); - dprintf(stderr,"ERR(%d, %d) ", rc, *errorCodePtr); + dprintf("ERR(%d, %d) ", rc, *errorCodePtr); return -1; } - dprintf(stderr,"R0! "); + dprintf("R0! "); return 1; } } Tcl_Channel