︙ | | | ︙ | |
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
* 0 if successful or POSIX error code if failed.
*
* Side effects:
* Sets the device into blocking or nonblocking mode.
*
*-----------------------------------------------------------------------------
*/
static int TlsBlockModeProc(ClientData instanceData, int mode) {
State *statePtr = (State *) instanceData;
if (mode == TCL_MODE_NONBLOCKING) {
statePtr->flags |= TLS_TCL_ASYNC;
} else {
statePtr->flags &= ~(TLS_TCL_ASYNC);
}
|
|
|
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
* 0 if successful or POSIX error code if failed.
*
* Side effects:
* Sets the device into blocking or nonblocking mode.
*
*-----------------------------------------------------------------------------
*/
static int TlsBlockModeProc(void *instanceData, int mode) {
State *statePtr = (State *) instanceData;
if (mode == TCL_MODE_NONBLOCKING) {
statePtr->flags |= TLS_TCL_ASYNC;
} else {
statePtr->flags &= ~(TLS_TCL_ASYNC);
}
|
︙ | | | ︙ | |
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
* 0 if successful or POSIX error code if failed.
*
* Side effects:
* Closes the socket of the channel.
*
*-----------------------------------------------------------------------------
*/
static int TlsCloseProc(ClientData instanceData, Tcl_Interp *interp) {
State *statePtr = (State *) instanceData;
dprintf("TlsCloseProc(%p)", (void *) statePtr);
/* Flush any pending data */
/* Send shutdown notification. Will return 0 while in process, then 1 when complete. */
/* Closes the write direction of the connection; the read direction is closed by the peer. */
/* Does not affect socket state. Don't call after fatal error. */
if (statePtr->ssl != NULL && !(statePtr->flags & TLS_TCL_HANDSHAKE_FAILED)) {
SSL_shutdown(statePtr->ssl);
}
/* Tls_Free calls Tls_Clean */
Tcl_EventuallyFree((ClientData)statePtr, Tls_Free);
return 0;
}
/*
*-----------------------------------------------------------------------------
*
* TlsClose2Proc --
*
* Similar to TlsCloseProc, but allows for separate close read and write
* side of channel.
*
*-----------------------------------------------------------------------------
*/
static int TlsClose2Proc(ClientData instanceData, /* The socket state. */
Tcl_Interp *interp, /* For errors - can be NULL. */
int flags) /* Flags to close read and/or write side of channel */
{
State *statePtr = (State *) instanceData;
dprintf("TlsClose2Proc(%p)", (void *) statePtr);
|
|
|
|
|
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
* 0 if successful or POSIX error code if failed.
*
* Side effects:
* Closes the socket of the channel.
*
*-----------------------------------------------------------------------------
*/
static int TlsCloseProc(void *instanceData, Tcl_Interp *interp) {
State *statePtr = (State *) instanceData;
dprintf("TlsCloseProc(%p)", (void *) statePtr);
/* Flush any pending data */
/* Send shutdown notification. Will return 0 while in process, then 1 when complete. */
/* Closes the write direction of the connection; the read direction is closed by the peer. */
/* Does not affect socket state. Don't call after fatal error. */
if (statePtr->ssl != NULL && !(statePtr->flags & TLS_TCL_HANDSHAKE_FAILED)) {
SSL_shutdown(statePtr->ssl);
}
/* Tls_Free calls Tls_Clean */
Tcl_EventuallyFree((void *)statePtr, Tls_Free);
return 0;
}
/*
*-----------------------------------------------------------------------------
*
* TlsClose2Proc --
*
* Similar to TlsCloseProc, but allows for separate close read and write
* side of channel.
*
*-----------------------------------------------------------------------------
*/
static int TlsClose2Proc(void *instanceData, /* The socket state. */
Tcl_Interp *interp, /* For errors - can be NULL. */
int flags) /* Flags to close read and/or write side of channel */
{
State *statePtr = (State *) instanceData;
dprintf("TlsClose2Proc(%p)", (void *) statePtr);
|
︙ | | | ︙ | |
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
|
*
* Data is received in whole blocks known as records from the peer. A whole
* record is processed (e.g. decrypted) in one go and is buffered by OpenSSL
* until it is read by the application via a call to SSL_read.
*
*-----------------------------------------------------------------------------
*/
static int TlsInputProc(ClientData instanceData, char *buf, int bufSize, int *errorCodePtr) {
unsigned long backingError;
State *statePtr = (State *) instanceData;
int bytesRead, err;
*errorCodePtr = 0;
dprintf("Read(%d)", bufSize);
|
|
|
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
|
*
* Data is received in whole blocks known as records from the peer. A whole
* record is processed (e.g. decrypted) in one go and is buffered by OpenSSL
* until it is read by the application via a call to SSL_read.
*
*-----------------------------------------------------------------------------
*/
static int TlsInputProc(void *instanceData, char *buf, int bufSize, int *errorCodePtr) {
unsigned long backingError;
State *statePtr = (State *) instanceData;
int bytesRead, err;
*errorCodePtr = 0;
dprintf("Read(%d)", bufSize);
|
︙ | | | ︙ | |
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
|
* to a POSIX error code if an error occurred, or 0 if none.
*
* Side effects:
* Writes output on the output device of the channel.
*
*-----------------------------------------------------------------------------
*/
static int TlsOutputProc(ClientData instanceData, const char *buf, int toWrite, int *errorCodePtr) {
unsigned long backingError;
State *statePtr = (State *) instanceData;
int written, err;
*errorCodePtr = 0;
dprintf("Write(%p, %d)", (void *) statePtr, toWrite);
dprintBuffer(buf, toWrite);
|
|
|
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
|
* to a POSIX error code if an error occurred, or 0 if none.
*
* Side effects:
* Writes output on the output device of the channel.
*
*-----------------------------------------------------------------------------
*/
static int TlsOutputProc(void *instanceData, const char *buf, int toWrite, int *errorCodePtr) {
unsigned long backingError;
State *statePtr = (State *) instanceData;
int written, err;
*errorCodePtr = 0;
dprintf("Write(%p, %d)", (void *) statePtr, toWrite);
dprintBuffer(buf, toWrite);
|
︙ | | | ︙ | |
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
|
*
* Side effects:
* Updates channel option to new value.
*
*-----------------------------------------------------------------------------
*/
static int
TlsSetOptionProc(ClientData instanceData, /* Socket state. */
Tcl_Interp *interp, /* For errors - can be NULL. */
const char *optionName, /* Name of the option to set the value for, or
* NULL to get all options and their values. */
const char *optionValue) /* Value for option. */
{
State *statePtr = (State *) instanceData;
Tcl_Channel parent = Tls_GetParent(statePtr, TLS_TCL_FASTPATH);
|
|
|
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
|
*
* Side effects:
* Updates channel option to new value.
*
*-----------------------------------------------------------------------------
*/
static int
TlsSetOptionProc(void *instanceData, /* Socket state. */
Tcl_Interp *interp, /* For errors - can be NULL. */
const char *optionName, /* Name of the option to set the value for, or
* NULL to get all options and their values. */
const char *optionValue) /* Value for option. */
{
State *statePtr = (State *) instanceData;
Tcl_Channel parent = Tls_GetParent(statePtr, TLS_TCL_FASTPATH);
|
︙ | | | ︙ | |
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
|
*
* Side effects:
* None.
*
*-------------------------------------------------------------------
*/
static int
TlsGetOptionProc(ClientData instanceData, /* Socket state. */
Tcl_Interp *interp, /* For errors - can be NULL. */
const char *optionName, /* Name of the option to retrieve the value for, or
* NULL to get all options and their values. */
Tcl_DString *optionValue) /* Where to store the computed value initialized by caller. */
{
State *statePtr = (State *) instanceData;
Tcl_Channel parent = Tls_GetParent(statePtr, TLS_TCL_FASTPATH);
|
|
|
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
|
*
* Side effects:
* None.
*
*-------------------------------------------------------------------
*/
static int
TlsGetOptionProc(void *instanceData, /* Socket state. */
Tcl_Interp *interp, /* For errors - can be NULL. */
const char *optionName, /* Name of the option to retrieve the value for, or
* NULL to get all options and their values. */
Tcl_DString *optionValue) /* Where to store the computed value initialized by caller. */
{
State *statePtr = (State *) instanceData;
Tcl_Channel parent = Tls_GetParent(statePtr, TLS_TCL_FASTPATH);
|
︙ | | | ︙ | |
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
|
* None.
*
* Side effects:
* Creates notification event.
*
*-----------------------------------------------------------------------------
*/
static void TlsChannelHandlerTimer(ClientData clientData) {
State *statePtr = (State *) clientData;
int mask = statePtr->want; /* Init to SSL_ERROR_WANT_READ and SSL_ERROR_WANT_WRITE */
dprintf("Called");
statePtr->timer = (Tcl_TimerToken) NULL;
|
|
|
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
|
* None.
*
* Side effects:
* Creates notification event.
*
*-----------------------------------------------------------------------------
*/
static void TlsChannelHandlerTimer(void *clientData) {
State *statePtr = (State *) clientData;
int mask = statePtr->want; /* Init to SSL_ERROR_WANT_READ and SSL_ERROR_WANT_WRITE */
dprintf("Called");
statePtr->timer = (Tcl_TimerToken) NULL;
|
︙ | | | ︙ | |
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
|
* Side effects:
* Sets up the time-based notifier so that future events on the channel
* will be seen by TCL.
*
*-----------------------------------------------------------------------------
*/
static void
TlsWatchProc(ClientData instanceData, /* The socket state. */
int mask) /* Events of interest; an OR-ed combination of
* TCL_READABLE, TCL_WRITABLE and TCL_EXCEPTION. */
{
Tcl_Channel parent;
State *statePtr = (State *) instanceData;
Tcl_DriverWatchProc *watchProc;
int pending = 0;
|
|
|
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
|
* Side effects:
* Sets up the time-based notifier so that future events on the channel
* will be seen by TCL.
*
*-----------------------------------------------------------------------------
*/
static void
TlsWatchProc(void *instanceData, /* The socket state. */
int mask) /* Events of interest; an OR-ed combination of
* TCL_READABLE, TCL_WRITABLE and TCL_EXCEPTION. */
{
Tcl_Channel parent;
State *statePtr = (State *) instanceData;
Tcl_DriverWatchProc *watchProc;
int pending = 0;
|
︙ | | | ︙ | |
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
|
statePtr->timer = (Tcl_TimerToken) NULL;
}
} else {
/* Add timer, if none */
if (statePtr->timer == (Tcl_TimerToken) NULL) {
dprintf("Creating a new timer since data appears to be waiting");
statePtr->timer = Tcl_CreateTimerHandler(TLS_TCL_DELAY, TlsChannelHandlerTimer, (ClientData) statePtr);
}
}
}
/*
*-----------------------------------------------------------------------------
*
* TlsGetHandleProc --
*
* This procedure is invoked by the generic IO level to retrieve an OS
* specific handle associated with the channel. Not used for transforms.
*
* Results:
* The appropriate Tcl_File handle or NULL if none.
*
* Side effects:
* None.
*
*-----------------------------------------------------------------------------
*/
static int TlsGetHandleProc(ClientData instanceData, /* Socket state. */
int direction, /* TCL_READABLE or TCL_WRITABLE */
ClientData *handlePtr) /* Handle associated with the channel */
{
State *statePtr = (State *) instanceData;
return Tcl_GetChannelHandle(Tls_GetParent(statePtr, TLS_TCL_FASTPATH), direction, handlePtr);
}
/*
|
|
|
|
|
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
|
statePtr->timer = (Tcl_TimerToken) NULL;
}
} else {
/* Add timer, if none */
if (statePtr->timer == (Tcl_TimerToken) NULL) {
dprintf("Creating a new timer since data appears to be waiting");
statePtr->timer = Tcl_CreateTimerHandler(TLS_TCL_DELAY, TlsChannelHandlerTimer, (void *) statePtr);
}
}
}
/*
*-----------------------------------------------------------------------------
*
* TlsGetHandleProc --
*
* This procedure is invoked by the generic IO level to retrieve an OS
* specific handle associated with the channel. Not used for transforms.
*
* Results:
* The appropriate Tcl_File handle or NULL if none.
*
* Side effects:
* None.
*
*-----------------------------------------------------------------------------
*/
static int TlsGetHandleProc(void *instanceData, /* Socket state. */
int direction, /* TCL_READABLE or TCL_WRITABLE */
void **handlePtr) /* Handle associated with the channel */
{
State *statePtr = (State *) instanceData;
return Tcl_GetChannelHandle(Tls_GetParent(statePtr, TLS_TCL_FASTPATH), direction, handlePtr);
}
/*
|
︙ | | | ︙ | |
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
|
* Type of event or 0 if failed
*
* Side effects:
* May process the incoming event by itself.
*
*-----------------------------------------------------------------------------
*/
static int TlsNotifyProc(ClientData instanceData, /* Socket state. */
int mask) /* type of event that occurred:
* OR-ed combination of TCL_READABLE or TCL_WRITABLE */
{
State *statePtr = (State *) instanceData;
int errorCode = 0;
dprintf("Called");
|
|
|
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
|
* Type of event or 0 if failed
*
* Side effects:
* May process the incoming event by itself.
*
*-----------------------------------------------------------------------------
*/
static int TlsNotifyProc(void *instanceData, /* Socket state. */
int mask) /* type of event that occurred:
* OR-ed combination of TCL_READABLE or TCL_WRITABLE */
{
State *statePtr = (State *) instanceData;
int errorCode = 0;
dprintf("Called");
|
︙ | | | ︙ | |