Diff

Differences From Artifact [0307107ef1]:

To Artifact [ee125cf739]:


1
2
3
4

5
6
7
8
9
10
11
1
2
3

4
5
6
7
8
9
10
11



-
+







#
# Copyright (C) 1997-2000 Matt Newman <[email protected]>
#
# $Header: /home/rkeene/tmp/cvs2fossil/../tcltls/tls/tls/tls.tcl,v 1.2 2000/01/20 01:51:05 aborr Exp $
# $Header: /home/rkeene/tmp/cvs2fossil/../tcltls/tls/tls/tls.tcl,v 1.2.2.1 2000/07/21 05:32:56 hobbs Exp $
#
namespace eval tls {
    variable logcmd tclLog
    variable debug 0
 
    # Default flags passed to tls::import
    variable defaults {}
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
















67
68
69
70
71
72
73
74
75
76

77
78
79
80
81
82
83
44
45
46
47
48
49
50
















51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84







-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+










+







    set argc [llength $args]
    set sopts {}
    set iopts [concat [list -server $server] ${tls::defaults}]	;# Import options

    for {set idx 0} {$idx < $argc} {incr idx} {
	set arg [lindex $args $idx]
	switch -glob -- $server,$arg {
	0,-myport	-
	*,-myaddr	{lappend sopts $arg [lindex $args [incr idx]]}
	0,-async	{lappend sopts $arg}
	*,-cipher	-
	*,-cadir	-
	*,-cafile	-
	*,-certfile	-
	*,-keyfile	-
	*,-command	-
	*,-request	-
	*,-require	-
	*,-ssl2		-
	*,-ssl3		-
	*,-tls1		{lappend iopts $arg [lindex $args [incr idx]]}
	-*		{return -code error "bad option \"$arg\": must be one of $options"}
	default	{break}
	    0,-myport	-
	    *,-myaddr	{lappend sopts $arg [lindex $args [incr idx]]}
	    0,-async	{lappend sopts $arg}
	    *,-cipher	-
	    *,-cadir	-
	    *,-cafile	-
	    *,-certfile	-
	    *,-keyfile	-
	    *,-command	-
	    *,-request	-
	    *,-require	-
	    *,-ssl2	-
	    *,-ssl3	-
	    *,-tls1	{lappend iopts $arg [lindex $args [incr idx]]}
	    -*		{return -code error "bad option \"$arg\": must be one of $options"}
	    default	{break}
	}
    }
    if {$server} {
	if {($idx + 1) != $argc} {
	    return -code error $usage
	}
	set uid [incr ::tls::srvuid]

	set port [lindex $args [expr {$argc-1}]]
	lappend sopts $port
	#set sopts [linsert $sopts 0 -server $callback]
	set sopts [linsert $sopts 0 -server [list tls::_accept $iopts $callback]]
	#set sopts [linsert $sopts 0 -server [list tls::_accept $uid $callback]]
    } else {
	if {($idx + 2) != $argc} {
	    return -code error $usage
	}
	set host [lindex $args [expr {$argc-2}]]
96
97
98
99
100
101
102
















103
104
105
106
107
108
109
110
111
112
113

114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133


134
135
136
137
138
139





140
141

142
143
144
145
146
147
148
149
150
151
152
153
154
155
156














157
158
159
160
161
162
163






164
165
166
167
168
169






170

171
172
173
174
175
176
177
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149


150
151
152





153
154
155
156
157
158

159
160














161
162
163
164
165
166
167
168
169
170
171
172
173
174
175






176
177
178
179
180
181
182





183
184
185
186
187
188

189
190
191
192
193
194
195
196







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+











+


















-
-
+
+

-
-
-
-
-
+
+
+
+
+

-
+

-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+

-
-
-
-
-
-
+
+
+
+
+
+

-
-
-
-
-
+
+
+
+
+
+
-
+







    } err]} {
	set info ${::errorInfo}
	catch {close $chan}
	return -code error -errorinfo $info $err
    }
    return $chan
}

# tls::_accept --
#
#   This is the actual accept that TLS sockets use, which then calls
#   the callback registered by tls::socket.
#
# Arguments:
#   iopts	tls::import opts
#   callback	server callback to invoke
#   chan	socket channel to accept/deny
#   ipaddr	calling IP address
#   port	calling port
#
# Results:
#   Returns an error if the callback throws one.
#
proc tls::_accept { iopts callback chan ipaddr port } {
    log 2 [list tls::_accept $iopts $callback $chan $ipaddr $port]

    set chan [eval [list tls::import $chan] $iopts]

    lappend callback $chan $ipaddr $port
    if {[catch {
	uplevel #0 $callback
    } err]} {
	log 1 "tls::_accept error: ${::errorInfo}"
	close $chan
	error $err $::errorInfo $::errorCode
    } else {
	log 2 "tls::_accept - called \"$callback\" succeeded"
    }
}
#
# Sample callback for hooking: -
#
# error
# info
# password
# verify
#
proc tls::callback {option args} {
    variable debug

    #log 2 [concat $option $args]

    switch -- $option {
    "error"	{
	foreach {chan msg} $args break
	"error"	{
	    foreach {chan msg} $args break

	log 0 "TLS/$chan: error: $msg"
    }
    "verify"	{
	# poor man's lassign
	foreach {chan depth cert rc err} $args break
	    log 0 "TLS/$chan: error: $msg"
	}
	"verify"	{
	    # poor man's lassign
	    foreach {chan depth cert rc err} $args break

	array set c $cert
	    array set c $cert

	if {$rc != "1"} {
	    log 1 "TLS/$chan: verify/$depth: Bad Cert: $err (rc = $rc)"
	} else {
	    log 2 "TLS/$chan: verify/$depth: $c(subject)"
	}
	if {$debug > 0} {
	    return 1;	# FORCE OK
	} else {
	    return $rc
	}
    }
    "info"	{
	# poor man's lassign
	foreach {chan major minor state msg} $args break
	    if {$rc != "1"} {
		log 1 "TLS/$chan: verify/$depth: Bad Cert: $err (rc = $rc)"
	    } else {
		log 2 "TLS/$chan: verify/$depth: $c(subject)"
	    }
	    if {$debug > 0} {
		return 1;	# FORCE OK
	    } else {
		return $rc
	    }
	}
	"info"	{
	    # poor man's lassign
	    foreach {chan major minor state msg} $args break

	if {$msg != ""} {
	    append state ": $msg"
	}
	# For tracing
	upvar #0 tls::$chan cb
	set cb($major) $minor
	    if {$msg != ""} {
		append state ": $msg"
	    }
	    # For tracing
	    upvar #0 tls::$chan cb
	    set cb($major) $minor

	log 2 "TLS/$chan: $major/$minor: $state"
    }
    default	{
	return -code error "bad option \"$option\": must be one of error, info, or verify"
    }
	    log 2 "TLS/$chan: $major/$minor: $state"
	}
	default	{
	    return -code error "bad option \"$option\":\
		    must be one of error, info, or verify"
	}
    };#sw
    }
}

proc tls::xhandshake {chan} {
    upvar #0 tls::$chan cb

    if {[info exists cb(handshake)] && \
	$cb(handshake) == "done"} {