Index: doc/tls.html
==================================================================
--- doc/tls.html
+++ doc/tls.html
@@ -452,22 +452,19 @@
-
-
info channel major minor message type
-
Index: generic/tls.c
==================================================================
--- generic/tls.c
+++ generic/tls.c
@@ -171,20 +171,10 @@
dprintf("Called");
if (statePtr->callback == (Tcl_Obj*)NULL)
return;
-#if 0
- if (where & SSL_CB_ALERT) {
- sev = SSL_alert_type_string_long(ret);
- if (strcmp(sev, "fatal")==0) { /* Map to error */
- Tls_Error(statePtr, SSL_ERROR(ssl, 0));
- return;
- }
- }
-#endif
-
if (where & SSL_CB_HANDSHAKE_START) {
major = "handshake";
minor = "start";
} else if (where & SSL_CB_HANDSHAKE_DONE) {
major = "handshake";
@@ -306,12 +296,11 @@
/*
*-------------------------------------------------------------------
*
* Tls_Error --
*
- * Calls callback with $fd and $msg - so the callback can decide
- * what to do with errors.
+ * Calls callback with list of errors.
*
* Side effects:
* The err field of the currently operative State is set
* to a string describing the SSL negotiation failure reason
*
@@ -318,30 +307,38 @@
*-------------------------------------------------------------------
*/
void
Tls_Error(State *statePtr, char *msg) {
Tcl_Interp *interp = statePtr->interp;
- Tcl_Obj *cmdPtr;
+ Tcl_Obj *cmdPtr, listPtr;
+ unsigned long err;
+ statePtr->err = msg;
dprintf("Called");
if (statePtr->callback == (Tcl_Obj*)NULL)
return;
- if (msg && *msg) {
- Tcl_SetErrorCode(interp, "SSL", msg, (char *)NULL);
- } else {
- msg = Tcl_GetStringFromObj(Tcl_GetObjResult(interp), NULL);
- }
- statePtr->err = msg;
-
- /* Create command to eval from callback */
+ /* Create command to eval */
cmdPtr = Tcl_DuplicateObj(statePtr->callback);
Tcl_ListObjAppendElement(interp, cmdPtr, Tcl_NewStringObj("error", -1));
Tcl_ListObjAppendElement(interp, cmdPtr,
Tcl_NewStringObj(Tcl_GetChannelName(statePtr->self), -1));
- Tcl_ListObjAppendElement(interp, cmdPtr, Tcl_NewStringObj(msg, -1));
+ if (msg != NULL) {
+ Tcl_ListObjAppendElement(interp, cmdPtr, Tcl_NewStringObj(msg, -1));
+ /* Tcl_SetErrorCode(interp, "SSL", msg, (char *)NULL); */
+
+ } else if ((msg = Tcl_GetStringFromObj(Tcl_GetObjResult(interp), NULL)) != NULL) {
+ 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, cmdPtr, listPtr);
+ }
/* Eval callback command */
Tcl_IncrRefCount(cmdPtr);
EvalCallback(interp, statePtr, cmdPtr);
Tcl_DecrRefCount(cmdPtr);
@@ -962,10 +959,12 @@
if (objc != 1) {
Tcl_WrongNumArgs(interp, 1, objv, "");
return TCL_ERROR;
}
+
+ ERR_clear_error();
objPtr = Tcl_NewListObj(0, NULL);
#if OPENSSL_VERSION_NUMBER < 0x10100000L && !defined(NO_SSL2) && !defined(OPENSSL_NO_SSL2)
Tcl_ListObjAppendElement(interp, objPtr, Tcl_NewStringObj(protocols[TLS_SSL2], -1));
@@ -1018,10 +1017,12 @@
if (objc != 2) {
Tcl_WrongNumArgs(interp, 1, objv, "channel");
return(TCL_ERROR);
}
+
+ ERR_clear_error();
chan = Tcl_GetChannel(interp, Tcl_GetStringFromObj(objv[1], NULL), NULL);
if (chan == (Tcl_Channel) NULL) {
return(TCL_ERROR);
}
@@ -1138,10 +1139,12 @@
if (objc < 2) {
Tcl_WrongNumArgs(interp, 1, objv, "channel ?options?");
return TCL_ERROR;
}
+
+ ERR_clear_error();
chan = Tcl_GetChannel(interp, Tcl_GetStringFromObj(objv[1], NULL), NULL);
if (chan == (Tcl_Channel) NULL) {
return TCL_ERROR;
}
@@ -2221,10 +2224,12 @@
return TCL_ERROR;
}
if (Tcl_GetIndexFromObj(interp, objv[1], commands, "command", 0,&cmd) != TCL_OK) {
return TCL_ERROR;
}
+
+ ERR_clear_error();
isStr = (cmd == C_STRREQ);
switch ((enum command) cmd) {
case C_REQ:
case C_STRREQ: {