Index: ChangeLog ================================================================== --- ChangeLog +++ ChangeLog @@ -1,5 +1,17 @@ +2007-06-22 Jeff Hobbs + + * tlsIO.c (TlsInputProc, TlsOutputProc, TlsWatchProc): + * tls.c (VerifyCallback): add an state flag in the verify callback + that prevents possibly recursion (on 'update'). [Bug 1652380] + + * tests/ciphers.test: reworked to make test output cleaner to + understand missing ciphers (if any) + + * Makefile.in, tclconfig/tcl.m4: update to TEA 3.6 + * configure, configure.in: using autoconf-2.59 + 2007-02-28 Pat Thoyts * win/makefile.vc: Rebase the DLL sensibly. Additional libs for static link of openssl. * tls.tcl: bug #1579837 - TIP 278 bug (possibly) - fixed. Index: tls.c ================================================================== --- tls.c +++ tls.c @@ -3,11 +3,11 @@ * some modifications: * Copyright (C) 2000 Ajuba Solutions * Copyright (C) 2002 ActiveState Corporation * Copyright (C) 2004 Starfish Systems * - * $Header: /home/rkeene/tmp/cvs2fossil/../tcltls/tls/tls/tls.c,v 1.24 2004/12/17 16:01:44 patthoyts Exp $ + * $Header: /home/rkeene/tmp/cvs2fossil/../tcltls/tls/tls/tls.c,v 1.25 2007/06/22 21:20:38 hobbs2 Exp $ * * TLS (aka SSL) Channel - can be layered on any bi-directional * Tcl_Channel (Note: Requires Trf Core Patch) * * This was built (almost) from scratch based upon observation of @@ -286,10 +286,12 @@ Tcl_NewStringObj( errStr ? errStr : "", -1) ); Tcl_Preserve( (ClientData) statePtr->interp); Tcl_Preserve( (ClientData) statePtr); + statePtr->flags |= TLS_TCL_CALLBACK; + Tcl_IncrRefCount( cmdPtr); if (Tcl_GlobalEvalObj(statePtr->interp, cmdPtr) != TCL_OK) { /* It got an error - reject the certificate. */ Tcl_BackgroundError( statePtr->interp); ok = 0; @@ -303,10 +305,12 @@ ok = 0; } } } Tcl_DecrRefCount( cmdPtr); + + statePtr->flags &= ~(TLS_TCL_CALLBACK); Tcl_Release( (ClientData) statePtr); Tcl_Release( (ClientData) statePtr->interp); return(ok); /* By default, leave verification unchanged. */ @@ -737,27 +741,15 @@ if (CAfile && !*CAfile) CAfile = NULL; if (CAdir && !*CAdir) CAdir = NULL; /* new SSL state */ statePtr = (State *) ckalloc((unsigned) sizeof(State)); - statePtr->self = (Tcl_Channel)NULL; - statePtr->timer = (Tcl_TimerToken)NULL; + memset(statePtr, 0, sizeof(State)); statePtr->flags = flags; - statePtr->watchMask = 0; - statePtr->mode = 0; - statePtr->interp = interp; - statePtr->callback = (Tcl_Obj *)0; - statePtr->password = (Tcl_Obj *)0; - statePtr->vflags = verify; - statePtr->ssl = (SSL*)0; - statePtr->ctx = (SSL_CTX*)0; - statePtr->bio = (BIO*)0; - statePtr->p_bio = (BIO*)0; - statePtr->err = ""; /* allocate script */ if (script) { char *tmp = Tcl_GetStringFromObj(script, NULL); Index: tlsIO.c ================================================================== --- tlsIO.c +++ tlsIO.c @@ -1,10 +1,10 @@ /* * Copyright (C) 1997-2000 Matt Newman * Copyright (C) 2000 Ajuba Solutions * - * $Header: /home/rkeene/tmp/cvs2fossil/../tcltls/tls/tls/tlsIO.c,v 1.15 2004/06/29 11:07:08 patthoyts Exp $ + * $Header: /home/rkeene/tmp/cvs2fossil/../tcltls/tls/tls/tlsIO.c,v 1.16 2007/06/22 21:20:38 hobbs2 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 @@ -333,10 +333,16 @@ int bytesRead; /* How many bytes were read? */ *errorCodePtr = 0; dprintf(stderr,"\nBIO_read(%d)", bufSize); + + if (statePtr->flags & TLS_TCL_CALLBACK) { + /* don't process any bytes while verify callback is running */ + bytesRead = 0; + goto input; + } if (!SSL_is_init_finished(statePtr->ssl)) { bytesRead = Tls_WaitForConnect(statePtr, errorCodePtr); if (bytesRead <= 0) { goto input; @@ -411,10 +417,17 @@ int written, err; *errorCodePtr = 0; dprintf(stderr,"\nBIO_write(0x%x, %d)", (unsigned int) statePtr, toWrite); + + if (statePtr->flags & TLS_TCL_CALLBACK) { + /* don't process any bytes while verify callback is running */ + written = -1; + *errorCodePtr = EAGAIN; + goto output; + } if (!SSL_is_init_finished(statePtr->ssl)) { written = Tls_WaitForConnect(statePtr, errorCodePtr); if (written <= 0) { goto output; @@ -579,10 +592,16 @@ * combination of TCL_READABLE, * TCL_WRITABLE and TCL_EXCEPTION. */ { State *statePtr = (State *) instanceData; + dprintf(stderr, "TlsWatchProc(0x%x)\n", 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; } + if (channelTypeVersion == TLS_CHANNEL_VERSION_2) { Tcl_Channel downChan; statePtr->watchMask = mask; Index: tlsInt.h ================================================================== --- tlsInt.h +++ tlsInt.h @@ -1,9 +1,9 @@ /* * Copyright (C) 1997-2000 Matt Newman * - * $Header: /home/rkeene/tmp/cvs2fossil/../tcltls/tls/tls/tlsInt.h,v 1.14 2004/06/29 11:07:08 patthoyts Exp $ + * $Header: /home/rkeene/tmp/cvs2fossil/../tcltls/tls/tls/tlsInt.h,v 1.15 2007/06/22 21:20:38 hobbs2 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 @@ -88,10 +88,12 @@ */ #define TLS_TCL_ASYNC (1<<0) /* non-blocking mode */ #define TLS_TCL_SERVER (1<<1) /* Server-Side */ #define TLS_TCL_INIT (1<<2) /* Initializing connection */ #define TLS_TCL_DEBUG (1<<3) /* Show debug tracing */ +#define TLS_TCL_CALLBACK (1<<4) /* In a callback, prevent update + * looping problem. [Bug 1652380] */ #define TLS_TCL_DELAY (5) /* * This structure describes the per-instance state @@ -101,11 +103,11 @@ */ typedef struct State { Tcl_Channel self; /* this socket channel */ Tcl_TimerToken timer; - int flags; /* currently only CHANNEL_ASYNC */ + int flags; /* see State.flags above */ int watchMask; /* current WatchProc mask */ int mode; /* current mode of parent channel */ Tcl_Interp *interp; /* interpreter in which this resides */ Tcl_Obj *callback; /* script called for tracing, verifying and errors */