1
# Commands tested in this file: socket.
3
# This file contains a collection of tests for one or more of the Tcl
4
# built-in commands. Sourcing this file into Tcl runs the tests and
5
# generates output for errors. No output means no errors were found.
7
# Copyright (c) 1994-1996 Sun Microsystems, Inc.
8
# Copyright (c) 1998-2000 Ajuba Solutions.
10
# See the file "license.terms" for information on usage and redistribution
11
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
13
# RCS: @(#) $Id: tlsIO.test,v 1.21 2004/02/11 22:41:25 razzell Exp $
15
# Running socket tests with a remote server:
16
# ------------------------------------------
18
# Some tests in socket.test depend on the existence of a remote server to
19
# which they connect. The remote server must be an instance of tcltest and it
20
# must run the script found in the file "remote.tcl" in this directory. You
21
# can start the remote server on any machine reachable from the machine on
22
# which you want to run the socket tests, by issuing:
24
# tcltest remote.tcl -port 8048 # Or choose another port number.
26
# If the machine you are running the remote server on has several IP
27
# interfaces, you can choose which interface the server listens on for
28
# connections by specifying the -address command line flag, so:
30
# tcltest remote.tcl -address your.machine.com
32
# These options can also be set by environment variables. On Unix, you can
33
# type these commands to the shell from which the remote server is started:
35
# shell% setenv serverPort 8048
36
# shell% setenv serverAddress your.machine.com
38
# and subsequently you can start the remote server with:
42
# to have it listen on port 8048 on the interface your.machine.com.
44
# When the server starts, it prints out a detailed message containing its
45
# configuration information, and it will block until killed with a Ctrl-C.
46
# Once the remote server exists, you can run the tests in socket.test with
47
# the server by setting two Tcl variables:
49
# % set remoteServerIP <name or address of machine on which server runs>
50
# % set remoteServerPort 8048
52
# These variables are also settable from the environment. On Unix, you can:
54
# shell% setenv remoteServerIP machine.where.server.runs
55
# shell% setenv remoteServerPort 8048
57
# The preamble of the socket.test file checks to see if the variables are set
58
# either in Tcl or in the environment; if they are, it attempts to connect to
59
# the server. If the connection is successful, the tests using the remote
60
# server will be performed; otherwise, it will attempt to start the remote
61
# server (via exec) on platforms that support this, on the local host,
62
# listening at port 8048. If all fails, a message is printed and the tests
63
# using the remote server are not performed.
65
proc dputs {msg} { return ; puts stderr $msg ; flush stderr }
67
if {[lsearch [namespace children] ::tcltest] == -1} {
68
package require tcltest
69
namespace import -force ::tcltest::*
72
# The build dir is added as the first element of $PATH
73
set auto_path [linsert $auto_path 0 [lindex [split $env(PATH) ";:"] 0]]
74
# Load the tls package
75
package require tls 1.5
77
set tlsServerPort 8048
79
# Specify where the certificates are
81
set certsDir [file join [file dirname [info script]] certs]
82
set serverCert [file join $certsDir server.pem]
83
set clientCert [file join $certsDir client.pem]
84
set caCert [file join $certsDir ca.pem]
85
set serverKey [file join $certsDir server.key]
86
set clientKey [file join $certsDir client.key]
88
# Some tests require the testthread and exec commands
90
set ::tcltest::testConstraints(testthread) \
91
[expr {[info commands testthread] != {}}]
92
set ::tcltest::testConstraints(exec) [expr {[info commands exec] != {}}]
95
# If remoteServerIP or remoteServerPort are not set, check in the
96
# environment variables for externally set values.
99
if {![info exists remoteServerIP]} {
100
if {[info exists env(remoteServerIP)]} {
101
set remoteServerIP $env(remoteServerIP)
104
if {![info exists remoteServerPort]} {
105
if {[info exists env(remoteServerPort)]} {
106
set remoteServerPort $env(remoteServerPort)
108
if {[info exists remoteServerIP]} {
109
set remoteServerPort $tlsServerPort
114
proc do_handshake {s {type readable} {cmd {}} args} {
117
dputs "handshake: eof"
118
set ::do_handshake "eof"
119
} elseif {[catch {tls::handshake $s} result]} {
120
# Some errors are normal.
121
dputs "handshake: $result"
122
} elseif {$result == 1} {
124
if {[llength $args]} { eval [list fconfigure $s] $args }
126
fileevent $s $type ""
128
fileevent $s $type "$cmd [list $s]"
130
dputs "handshake: complete"
131
set ::do_handshake "complete"
133
dputs "handshake: in progress"
138
# Check if we're supposed to do tests against the remote server
141
set doTestsWithRemoteServer 1
142
if {![info exists remoteServerIP] && ($tcl_platform(platform) != "macintosh")} {
143
set remoteServerIP 127.0.0.1
145
if {($doTestsWithRemoteServer == 1) && (![info exists remoteServerPort])} {
146
set remoteServerPort $tlsServerPort
149
# Attempt to connect to a remote server if one is already running. If it
150
# is not running or for some other reason the connect fails, attempt to
151
# start the remote server on the local host listening on port 8048. This
152
# is only done on platforms that support exec (i.e. not on the Mac). On
153
# platforms that do not support exec, the remote server must be started
154
# by the user before running the tests.
156
set remoteProcChan ""
158
if {$doTestsWithRemoteServer} {
159
catch {close $commandSocket}
160
if {[catch {set commandSocket [tls::socket \
161
-certfile $clientCert -cafile $caCert -keyfile $clientKey \
162
$remoteServerIP $remoteServerPort]}] != 0} {
163
if {[info commands exec] == ""} {
164
set noRemoteTestReason "can't exec"
165
set doTestsWithRemoteServer 0
167
set remoteServerIP 127.0.0.1
168
set remoteFile [file join [pwd] remote.tcl]
169
if {[catch {set remoteProcChan \
170
[open "|[list $::tcltest::tcltest $remoteFile \
171
-serverIsSilent -port $remoteServerPort \
172
-address $remoteServerIP]" w+]} msg] == 0} {
174
if {[catch {set commandSocket [tls::socket -cafile $caCert \
175
-certfile $clientCert -keyfile $clientKey \
176
$remoteServerIP $remoteServerPort]} msg] == 0} {
177
fconfigure $commandSocket -translation crlf -buffering line
179
set noRemoteTestReason $msg
180
set doTestsWithRemoteServer 0
183
set noRemoteTestReason "$msg $::tcltest::tcltest"
184
set doTestsWithRemoteServer 0
188
fconfigure $commandSocket -translation crlf -buffering line
192
# Some tests are run only if we are doing testing against a remote server.
193
set ::tcltest::testConstraints(doTestsWithRemoteServer) $doTestsWithRemoteServer
194
if {$doTestsWithRemoteServer == 0} {
195
if {[string first s $::tcltest::verbose] != -1} {
196
puts "Skipping tests with remote server. See tests/socket.test for"
197
puts "information on how to run remote server."
198
puts "Reason for not doing remote tests: $noRemoteTestReason"
203
# If we do the tests, define a command to send a command to the
207
if {$doTestsWithRemoteServer == 1} {
208
proc sendCommand {c} {
211
if {[eof $commandSocket]} {
212
error "remote server disappeared"
215
if {[catch {puts $commandSocket $c} msg]} {
216
error "remote server disappeared: $msg"
218
if {[catch {puts $commandSocket "--Marker--Marker--Marker--"} msg]} {
219
error "remote server disappeared: $msg"
224
set line [gets $commandSocket]
225
if {[eof $commandSocket]} {
226
error "remote server disappeared"
228
if {[string compare $line "--Marker--Marker--Marker--"] == 0} {
229
if {[string compare [lindex $resp 0] error] == 0} {
230
error [lindex $resp 1]
232
return [lindex $resp 1]
235
append resp $line "\n"
240
sendCommand [list proc dputs [info args dputs] [info body dputs]]
242
proc sendCertValues {} {
243
# We need to be able to send certificate values that normalize
244
# filenames across platforms
246
set certsDir [file join [file dirname [info script]] certs]
247
set serverCert [file join $certsDir server.pem]
248
set clientCert [file join $certsDir client.pem]
249
set caCert [file join $certsDir cacert.pem]
250
set serverKey [file join $certsDir server.key]
251
set clientKey [file join $certsDir client.key]
256
test tlsIO-1.1 {arg parsing for socket command} {socket} {
257
list [catch {tls::socket -server} msg] $msg
258
} {1 {wrong # args: should be "tls::socket -server command ?options? port"}}
260
test tlsIO-1.2 {arg parsing for socket command} {socket} {
261
list [catch {tls::socket -server foo} msg] $msg
262
} {1 {wrong # args: should be "tls::socket -server command ?options? port"}}
264
test tlsIO-1.3 {arg parsing for socket command} {socket} {
265
list [catch {tls::socket -myaddr} msg] $msg
266
} {1 {wrong # args: should be "tls::socket ?options? host port"}}
268
test tlsIO-1.4 {arg parsing for socket command} {socket} {
269
list [catch {tls::socket -myaddr 127.0.0.1} msg] $msg
270
} {1 {wrong # args: should be "tls::socket ?options? host port"}}
272
test tlsIO-1.5 {arg parsing for socket command} {socket} {
273
list [catch {tls::socket -myport} msg] $msg
274
} {1 {wrong # args: should be "tls::socket ?options? host port"}}
276
test tlsIO-1.6 {arg parsing for socket command} {socket} {
277
list [catch {tls::socket -myport xxxx} msg] $msg
278
} {1 {wrong # args: should be "tls::socket ?options? host port"}}
280
test tlsIO-1.7 {arg parsing for socket command} {socket} {
281
list [catch {tls::socket -myport 2522} msg] $msg
282
} {1 {wrong # args: should be "tls::socket ?options? host port"}}
284
test tlsIO-1.8 {arg parsing for socket command} {socket} {
285
list [catch {tls::socket -froboz} msg] $msg
286
} {1 {wrong # args: should be "tls::socket ?options? host port"}}
288
test tlsIO-1.9 {arg parsing for socket command} {socket} {
289
list [catch {tls::socket -server foo -myport 2521 3333} msg] $msg
290
} {1 {wrong # args: should be "tls::socket -server command ?options? port"}}
292
test tlsIO-1.10 {arg parsing for socket command} {socket} {
293
list [catch {tls::socket host 2528 -junk} msg] $msg
294
} {1 {wrong # args: should be "tls::socket ?options? host port"}}
296
test tlsIO-1.11 {arg parsing for socket command} {socket} {
297
list [catch {tls::socket -server callback 2520 --} msg] $msg
298
} {1 {wrong # args: should be "tls::socket -server command ?options? port"}}
300
test tlsIO-1.12 {arg parsing for socket command} {socket} {
301
list [catch {tls::socket foo badport} msg] $msg
302
} {1 {expected integer but got "badport"}}
304
test tlsIO-2.1 {tcp connection} {socket stdio} {
306
set f [open script w]
308
set auto_path [linsert $auto_path 0 [lindex [split $env(PATH) ";:"] 0]]
310
set timer [after 2000 "set x timed_out"]
312
puts $f "set f \[tls::socket -server accept -certfile $serverCert -cafile $caCert -keyfile $serverKey 8828 \]"
314
proc accept {file addr port} {
326
set f [open "|[list $::tcltest::tcltest script]" r]
328
if {[catch {tls::socket -certfile $clientCert -cafile $caCert \
329
-keyfile $clientKey 127.0.0.1 8828} msg]} {
340
if [info exists port] {
343
set port [expr $tlsServerPort + [pid]%1024]
346
test tlsIO-2.2 {tcp connection with client port specified} {socket stdio} {
348
set f [open script w]
350
set auto_path [linsert $auto_path 0 [lindex [split $env(PATH) ";:"] 0]]
352
set timer [after 2000 "set x done"]
354
puts $f "set f \[tls::socket -server accept -certfile $serverCert -cafile $caCert -keyfile $serverKey 8829 \]"
356
proc accept {sock addr port} {
358
puts "[gets $sock] $port"
368
set f [open "|[list $::tcltest::tcltest script]" r]
371
if {[catch {tls::socket -myport $port \
372
-certfile $clientCert -cafile $caCert \
373
-keyfile $clientKey 127.0.0.1 8829} sock]} {
375
catch {close [tls::socket 127.0.0.1 8829]}
384
} [list ready "hello $port"]
386
test tlsIO-2.3 {tcp connection with client interface specified} {socket stdio} {
388
set f [open script w]
390
set auto_path [linsert $auto_path 0 [lindex [split $env(PATH) ";:"] 0]]
392
set timer [after 2000 "set x done"]
394
puts $f "set f \[tls::socket -server accept -certfile $serverCert -cafile $caCert -keyfile $serverKey 8830 \]"
396
proc accept {sock addr port} {
398
puts "[gets $sock] $addr"
408
set f [open "|[list $::tcltest::tcltest script]" r]
410
if {[catch {tls::socket -myaddr 127.0.0.1 \
411
-certfile $clientCert -cafile $caCert \
412
-keyfile $clientKey 127.0.0.1 8830} sock]} {
422
} {ready {hello 127.0.0.1}}
424
test tlsIO-2.4 {tcp connection with server interface specified} {socket stdio} {
426
set f [open script w]
428
set auto_path [linsert $auto_path 0 [lindex [split $env(PATH) ";:"] 0]]
430
set timer [after 2000 "set x done"]
432
puts $f "set f \[tls::socket -server accept -certfile $serverCert -cafile $caCert -keyfile $serverKey -myaddr [info hostname] 8831 \]"
434
proc accept {sock addr port} {
446
set f [open "|[list $::tcltest::tcltest script]" r]
448
if {[catch {tls::socket -certfile $clientCert -cafile $caCert \
449
-keyfile $clientKey [info hostname] 8831} sock]} {
461
test tlsIO-2.5 {tcp connection with redundant server port} {socket stdio} {
463
set f [open script w]
465
set auto_path [linsert $auto_path 0 [lindex [split $env(PATH) ";:"] 0]]
467
set timer [after 2000 "set x done"]
469
puts $f "set f \[tls::socket -server accept -certfile $serverCert -cafile $caCert -keyfile $serverKey 8832 \]"
471
proc accept {sock addr port} {
483
set f [open "|[list $::tcltest::tcltest script]" r]
485
if {[catch {tls::socket -certfile $clientCert -cafile $caCert \
486
-keyfile $clientKey 127.0.0.1 8832} sock]} {
497
test tlsIO-2.6 {tcp connection} {socket} {
499
if {![catch {set sock [tls::socket 127.0.0.1 8833]}]} {
500
if {![catch {gets $sock}]} {
508
test tlsIO-2.7 {echo server, one line} {socket stdio} {
510
set f [open script w]
512
set auto_path [linsert $auto_path 0 [lindex [split $env(PATH) ";:"] 0]]
514
set timer [after 2000 "set x done"]
516
puts $f "set f \[tls::socket -server accept -certfile $serverCert -cafile $caCert -keyfile $serverKey 8834 \]"
518
proc accept {s a p} {
519
fileevent $s readable [list echo $s]
520
fconfigure $s -translation lf -buffering line
539
set f [open "|[list $::tcltest::tcltest script]" r]
541
set s [tls::socket -certfile $clientCert -cafile $caCert \
542
-keyfile $clientKey 127.0.0.1 8834]
543
fconfigure $s -buffering line -translation lf
544
puts $s "hello abcdefghijklmnop"
551
} {{hello abcdefghijklmnop} done}
553
test tlsIO-2.8 {echo server, loop 50 times, single connection} {socket stdio} {
554
set f [open script w]
556
set auto_path [linsert $auto_path 0 [lindex [split $env(PATH) ";:"] 0]]
559
puts $f "set f \[tls::socket -server accept -certfile $serverCert -cafile $caCert -keyfile $serverKey 8835 \]"
561
proc accept {s a p} {
562
fileevent $s readable [list echo $s]
563
fconfigure $s -buffering line
579
set timer [after 20000 "set x done"]
586
set f [open "|[list $::tcltest::tcltest script]" r]
588
set s [tls::socket -certfile $clientCert -cafile $caCert \
589
-keyfile $clientKey 127.0.0.1 8835]
590
fconfigure $s -buffering line
592
for {set x 0} {$x < 50} {incr x} {
593
puts $s "hello abcdefghijklmnop"
598
catch {set x [gets $f]}
603
test tlsIO-2.9 {socket conflict} {socket stdio} {
604
set s [tls::socket -server accept 8828]
606
set f [open script w]
608
set auto_path [linsert $auto_path 0 [lindex [split $env(PATH) ";:"] 0]]
610
tls::socket -server accept 8828
613
set f [open "|[list $::tcltest::tcltest script]" r]
616
set x [list [catch {close $f} msg] [string range $msg 0 43]]
619
} {1 {couldn't open socket: address already in use}}
621
test tlsIO-2.10 {close on accept, accepted socket lives} {socket} {
623
set timer [after 20000 "set done timed_out"]
624
set ss [tls::socket -server accept -certfile $serverCert -cafile $caCert \
625
-keyfile $serverKey 8830]
626
proc accept {s a p} {
629
fileevent $s readable "readit $s"
630
fconfigure $s -trans lf
638
set cs [tls::socket -certfile $clientCert -cafile $caCert \
639
-keyfile $clientKey [info hostname] 8830]
647
test tlsIO-2.11 {detecting new data} {socket} {
648
proc accept {s a p} {
650
# when doing an in-process client/server test, both sides need
651
# to be non-blocking for the TLS handshake. Also make sure
652
# to return the channel to line buffering mode.
653
fconfigure $s -blocking 0 -buffering line
655
fileevent $s readable [list do_handshake $s]
658
set s [tls::socket -server accept \
659
-certfile $serverCert -cafile $caCert -keyfile $serverKey 8400]
661
set s2 [tls::socket -certfile $clientCert -cafile $caCert \
662
-keyfile $clientKey 127.0.0.1 8400]
663
# when doing an in-process client/server test, both sides need
664
# to be non-blocking for the TLS handshake Also make sure to
665
# return the channel to line buffering mode (TLS sets it to 'none').
666
fconfigure $s2 -blocking 0 -buffering line
670
# need update to complete TLS handshake in-process
673
fconfigure $sock -blocking 0
674
set result a:[gets $sock]
675
lappend result b:[gets $sock]
676
fconfigure $sock -blocking 1
679
fconfigure $sock -blocking 0
680
lappend result c:[gets $sock]
681
fconfigure $sock -blocking 1
688
test tlsIO-2.12 {tcp connection; no certificates specified} \
689
{socket stdio unixOnly} {
690
# There is a debug assertion on Windows/SSL that causes a crash when the
691
# certificate isn't specified.
693
set f [open script w]
695
set auto_path [linsert $auto_path 0 [lindex [split $env(PATH) ";:"] 0]]
697
set timer [after 2000 "set x timed_out"]
698
set f [tls::socket -server accept 8828]
699
proc accept {file addr port} {
711
set f [open "|[list $::tcltest::tcltest script]" r]
713
if {[catch {tls::socket 127.0.0.1 8828} msg]} {
724
test tlsIO-3.1 {socket conflict} {socket stdio} {
726
set f [open script w]
728
set auto_path [linsert $auto_path 0 [lindex [split $env(PATH) ";:"] 0]]
731
puts $f "set f \[tls::socket -server accept -certfile $serverCert -cafile $caCert -keyfile $serverKey 8828 \]"
738
set f [open "|[list $::tcltest::tcltest script]" r+]
740
set x [list [catch {tls::socket \
741
-certfile $clientCert -cafile $caCert -keyfile $clientKey \
742
-server accept 8828} msg] \
747
} {1 {couldn't open socket: address already in use}}
749
test tlsIO-3.2 {server with several clients} {socket stdio} {
751
set f [open script w]
753
set auto_path [linsert $auto_path 0 [lindex [split $env(PATH) ";:"] 0]]
755
set t1 [after 30000 "set x timed_out"]
756
set t2 [after 31000 "set x timed_out"]
757
set t3 [after 32000 "set x timed_out"]
760
puts $f "set s \[tls::socket -server accept -certfile $serverCert -cafile $caCert -keyfile $serverKey 8828 \]"
762
proc accept {s a p} {
763
fileevent $s readable [list echo $s]
764
fconfigure $s -buffering line
787
set f [open "|[list $::tcltest::tcltest script]" r+]
789
set s1 [tls::socket \
790
-certfile $clientCert -cafile $caCert -keyfile $clientKey \
792
fconfigure $s1 -buffering line
793
set s2 [tls::socket \
794
-certfile $clientCert -cafile $caCert -keyfile $clientKey \
796
fconfigure $s2 -buffering line
797
set s3 [tls::socket \
798
-certfile $clientCert -cafile $caCert -keyfile $clientKey \
800
fconfigure $s3 -buffering line
801
for {set i 0} {$i < 100} {incr i} {
817
test tlsIO-4.1 {server with several clients} {socket stdio} {
818
# have seen intermittent hangs on Windows
820
set f [open script w]
822
set auto_path [linsert $auto_path 0 [lindex [split $env(PATH) ";:"] 0]]
826
puts $f "set s \[tls::socket -certfile $clientCert -cafile $caCert -keyfile $clientKey 127.0.0.1 8828 \]"
828
fconfigure $s -buffering line
829
for {set i 0} {$i < 100} {incr i} {
838
set p1 [open "|[list $::tcltest::tcltest script]" r+]
839
fconfigure $p1 -buffering line
840
set p2 [open "|[list $::tcltest::tcltest script]" r+]
841
fconfigure $p2 -buffering line
842
set p3 [open "|[list $::tcltest::tcltest script]" r+]
843
fconfigure $p3 -buffering line
844
proc accept {s a p} {
845
fconfigure $s -buffering line
846
fileevent $s readable [list echo $s]
858
set t1 [after 30000 "set x timed_out"]
859
set t2 [after 31000 "set x timed_out"]
860
set t3 [after 32000 "set x timed_out"]
862
-certfile $serverCert -cafile $caCert -keyfile $serverKey \
875
lappend l [list p1 [gets $p1] $x]
876
lappend l [list p2 [gets $p2] $x]
877
lappend l [list p3 [gets $p3] $x]
885
} {{p1 bye done} {p2 bye done} {p3 bye done}}
887
test tlsIO-4.2 {byte order problems, socket numbers, htons} {socket} {
889
if {[catch {tls::socket -server dodo 0x3000} msg]} {
897
test tlsIO-5.1 {byte order problems, socket numbers, htons} \
898
{socket unixOnly notRoot} {
899
set x {couldn't open socket: not owner}
900
if {![catch {tls::socket -server dodo 0x1} msg]} {
901
set x {htons problem, should be disallowed, are you running as SU?}
905
} {couldn't open socket: not owner}
906
test tlsIO-5.2 {byte order problems, socket numbers, htons} {socket} {
907
set x {couldn't open socket: port number too high}
908
if {![catch {tls::socket -server dodo 0x10000} msg]} {
909
set x {port resolution problem, should be disallowed}
913
} {couldn't open socket: port number too high}
914
test tlsIO-5.3 {byte order problems, socket numbers, htons} \
915
{socket unixOnly notRoot} {
916
set x {couldn't open socket: not owner}
917
if {![catch {tls::socket -server dodo 21} msg]} {
918
set x {htons problem, should be disallowed, are you running as SU?}
922
} {couldn't open socket: not owner}
924
test tlsIO-6.1 {accept callback error} {socket stdio} {
925
# There is a debug assertion on Windows/SSL that causes a crash when the
926
# certificate isn't specified.
928
set f [open script w]
930
set auto_path [linsert $auto_path 0 [lindex [split $env(PATH) ";:"] 0]]
934
puts $f [list tls::socket -cafile $caCert 127.0.0.1 8848]
936
set f [open "|[list $::tcltest::tcltest script]" r+]
941
proc accept {s a p} {expr 10 / 0}
942
set s [tls::socket -server accept \
943
-certfile $serverCert -cafile $caCert -keyfile $serverKey 8848]
946
set timer [after 10000 "set x timed_out"]
954
test tlsIO-7.1 {testing socket specific options} {socket stdio} {
956
set f [open script w]
958
set auto_path [linsert $auto_path 0 [lindex [split $env(PATH) ";:"] 0]]
961
puts $f [list tls::socket -server accept \
962
-certfile $serverCert -cafile $caCert -keyfile $serverKey 8820]
969
set timer [after 10000 "set x timed_out"]
974
set f [open "|[list $::tcltest::tcltest script]" r]
977
-certfile $clientCert -cafile $caCert -keyfile $clientKey \
979
set p [fconfigure $s -peername]
983
lappend l [string compare [lindex $p 0] 127.0.0.1]
984
lappend l [string compare [lindex $p 2] 8820]
985
lappend l [llength $p]
988
test tlsIO-7.2 {testing socket specific options} {socket stdio} {
990
set f [open script w]
992
set auto_path [linsert $auto_path 0 [lindex [split $env(PATH) ";:"] 0]]
995
puts $f "tls::socket -server accept -certfile $serverCert -cafile $caCert -keyfile $serverKey 8821"
1002
set timer [after 10000 "set x timed_out"]
1007
set f [open "|[list $::tcltest::tcltest script]" r]
1009
set s [tls::socket \
1010
-certfile $clientCert -cafile $caCert -keyfile $clientKey \
1012
set p [fconfigure $s -sockname]
1016
lappend l [llength $p]
1017
lappend l [lindex $p 0]
1018
lappend l [string equal [lindex $p 2] 8821]
1021
test tlsIO-7.3 {testing socket specific options} {socket} {
1022
set s [tls::socket \
1023
-certfile $serverCert -cafile $caCert -keyfile $serverKey \
1024
-server accept 8822]
1025
set l [llength [fconfigure $s]]
1028
# A bug fixed in fconfigure for 8.3.4+ make this return 14 normally,
1029
# but 12 in older versions.
1030
expr {$l >= 12 && (($l % 2) == 0)}
1033
# bug report #5812 fconfigure doesn't return value for '-sockname'
1035
test tlsIO-7.4 {testing socket specific options} {socket} {
1036
set s [tls::socket \
1037
-certfile $serverCert -cafile $caCert -keyfile $serverKey \
1038
-server accept 8823]
1039
proc accept {s a p} {
1041
set x [fconfigure $s -sockname]
1044
set s1 [tls::socket \
1045
-certfile $clientCert -cafile $caCert -keyfile $clientKey \
1046
[info hostname] 8823]
1047
set timer [after 10000 "set x timed_out"]
1053
lappend l [lindex $x 2] [llength $x]
1056
# bug report #5812 fconfigure doesn't return value for '-sockname'
1058
test tlsIO-7.5 {testing socket specific options} {socket unixOrPc} {
1059
set s [tls::socket \
1060
-certfile $serverCert -cafile $caCert -keyfile $serverKey \
1061
-server accept 8829]
1062
proc accept {s a p} {
1064
set x [fconfigure $s -sockname]
1067
set s1 [tls::socket \
1068
-certfile $clientCert -cafile $caCert -keyfile $clientKey \
1070
set timer [after 10000 "set x timed_out"]
1076
lappend l [lindex $x 0] [lindex $x 2] [llength $x]
1077
} {127.0.0.1 8829 3}
1079
test tlsIO-8.1 {testing -async flag on sockets} {socket} {
1080
# NOTE: This test may fail on some Solaris 2.4 systems.
1081
# See notes in Tcl's socket.test.
1082
set s [tls::socket \
1083
-certfile $serverCert -cafile $caCert -keyfile $serverKey \
1084
-server accept 8830]
1085
proc accept {s a p} {
1087
# when doing an in-process client/server test, both sides need
1088
# to be non-blocking for the TLS handshake. Also make sure
1089
# to return the channel to line buffering mode.
1090
fconfigure $s -blocking 0 -buffering line
1092
# Only OpenSSL 0.9.5a on Windows seems to need the after (delayed)
1093
# close, but it works just the same for all others. -hobbs
1097
set s1 [tls::socket \
1098
-certfile $clientCert -cafile $caCert -keyfile $clientKey \
1099
-async [info hostname] 8830]
1100
# when doing an in-process client/server test, both sides need
1101
# to be non-blocking for the TLS handshake Also make sure to
1102
# return the channel to line buffering mode (TLS sets it to 'none').
1103
fconfigure $s1 -blocking 0 -buffering line
1105
# TLS handshaking needs one byte from the client...
1107
# need update to complete TLS handshake in-process
1115
test tlsIO-9.1 {testing spurious events} {socket} {
1119
proc readlittle {s} {
1120
global spurious done len
1122
if {[string length $l] == 0} {
1130
incr len [string length $l]
1133
proc accept {s a p} {
1134
fconfigure $s -blocking 0
1135
fileevent $s readable [list do_handshake $s readable readlittle \
1138
set s [tls::socket \
1139
-certfile $serverCert -cafile $caCert -keyfile $serverKey \
1140
-server accept 8831]
1141
set c [tls::socket \
1142
-certfile $clientCert -cafile $caCert -keyfile $clientKey \
1143
[info hostname] 8831]
1144
# This differs from socket-9.1 in that both sides need to be
1145
# non-blocking because of TLS' required handshake
1146
fconfigure $c -blocking 0
1147
puts -nonewline $c 01234567890123456789012345678901234567890123456789
1149
set timer [after 10000 "set done timed_out"]
1156
test tlsIO-9.2 {testing async write, fileevents, flush on close} {socket} {
1157
set firstblock [string repeat a 31]
1158
set secondblock [string repeat b 65535]
1159
proc accept {s a p} {
1160
fconfigure $s -blocking 0
1161
fileevent $s readable [list do_handshake $s readable readable \
1162
-translation lf -buffersize 16384 -buffering line]
1166
dputs "got \"[string replace $l 10 end-3 ...]\" \
1167
([string length $l]) from $s"
1168
fileevent $s readable {}
1169
after 1000 respond $s
1173
dputs "send \"[string replace $firstblock 10 end-3 ...]\" \
1174
([string length $firstblock]) down $s"
1175
puts -nonewline $s $firstblock
1176
after 1000 writedata $s
1178
proc writedata {s} {
1180
dputs "send \"[string replace $secondblock 10 end-3 ...]\" \
1181
([string length $secondblock]) down $s"
1182
puts -nonewline $s $secondblock
1185
set s [tls::socket \
1186
-certfile $serverCert -cafile $caCert -keyfile $serverKey \
1187
-server accept 8832]
1188
set c [tls::socket \
1189
-certfile $clientCert -cafile $caCert -keyfile $clientKey \
1190
[info hostname] 8832]
1191
fconfigure $c -blocking 0 -trans lf -buffering line
1197
dputs "read \"[string replace $data 10 end-3 ...]\" \
1198
([string length $data]) from $s"
1199
incr count [string length $data]
1205
fileevent $c readable "readit $c"
1207
set timer [after 10000 "set done timed_out"]
1214
test tlsIO-9.3 {testing EOF stickyness} {unexplainedFailure socket} {
1215
# HOBBS: never worked correctly
1216
proc count_to_eof {s} {
1217
global count done timer
1224
set count {eof is sticky}
1232
set count {timer went off, eof is not sticky}
1237
proc write_then_close {s} {
1241
proc accept {s a p} {
1242
fconfigure $s -blocking 0 -buffering line -translation lf
1243
fileevent $s writable [list do_handshake $s writable write_then_close \
1244
-buffering line -translation lf]
1246
set s [tls::socket \
1247
-certfile $serverCert -cafile $caCert -keyfile $serverKey \
1248
-server accept 8833]
1249
set c [tls::socket \
1250
-certfile $clientCert -cafile $caCert -keyfile $clientKey \
1251
[info hostname] 8833]
1252
fconfigure $c -blocking 0 -buffering line -translation lf
1253
fileevent $c readable "count_to_eof $c"
1254
set timer [after 2000 timerproc]
1262
test tlsIO-10.1 {testing socket accept callback error handling} {socket} {
1264
proc bgerror args {global goterror; set goterror 1}
1265
set s [tls::socket -cafile $caCert -server accept 8898]
1266
proc accept {s a p} {close $s; error}
1267
set c [tls::socket -cafile $caCert 127.0.0.1 8898]
1274
test tlsIO-11.1 {tcp connection} {socket doTestsWithRemoteServer} {
1277
set socket9_1_test_server [tls::socket -server accept \
1278
-certfile $serverCert -cafile $caCert -keyfile $serverKey 8834]
1279
proc accept {s a p} {
1285
set s [tls::socket \
1286
-certfile $clientCert -cafile $caCert -keyfile $clientKey \
1287
$remoteServerIP 8834]
1290
sendCommand {close $socket9_1_test_server}
1294
test tlsIO-11.2 {client specifies its port} {socket doTestsWithRemoteServer} {
1295
if {[info exists port]} {
1298
set port [expr {$tlsServerPort + [pid]%1024}]
1302
set socket9_2_test_server [tls::socket -server accept \
1303
-certfile $serverCert -cafile $caCert -keyfile $serverKey 8835]
1304
proc accept {s a p} {
1310
set s [tls::socket \
1311
-certfile $clientCert -cafile $caCert -keyfile $clientKey \
1312
-myport $port $remoteServerIP 8835]
1315
sendCommand {close $socket9_2_test_server}
1324
test tlsIO-11.3 {trying to connect, no server} {socket doTestsWithRemoteServer} {
1326
if {![catch {set s [tls::socket \
1327
-certfile $clientCert -cafile $caCert -keyfile $clientKey \
1328
$remoteServerIp 8836]}]} {
1329
if {![catch {gets $s}]} {
1337
test tlsIO-11.4 {remote echo, one line} {socket doTestsWithRemoteServer} {
1340
set socket10_6_test_server [tls::socket \
1341
-certfile $serverCert -cafile $caCert -keyfile $serverKey \
1342
-server accept 8836]
1343
proc accept {s a p} {
1345
fileevent $s readable [list echo $s]
1346
fconfigure $s -buffering line -translation crlf
1357
set f [tls::socket \
1358
-certfile $clientCert -cafile $caCert -keyfile $clientKey \
1359
$remoteServerIP 8836]
1360
fconfigure $f -translation crlf -buffering line
1364
sendCommand {close $socket10_6_test_server}
1368
test tlsIO-11.5 {remote echo, 50 lines} {socket doTestsWithRemoteServer} {
1371
set socket10_7_test_server [tls::socket -server accept \
1372
-certfile $serverCert -cafile $caCert -keyfile $serverKey 8836]
1373
proc accept {s a p} {
1375
fileevent $s readable [list echo $s]
1376
fconfigure $s -buffering line -translation crlf
1387
set f [tls::socket \
1388
-certfile $clientCert -cafile $caCert -keyfile $clientKey \
1389
$remoteServerIP 8836]
1390
fconfigure $f -translation crlf -buffering line
1391
for {set cnt 0} {$cnt < 50} {incr cnt} {
1392
puts $f "hello, $cnt"
1393
if {[string compare [gets $f] "hello, $cnt"] != 0} {
1398
sendCommand {close $socket10_7_test_server}
1402
# Macintosh sockets can have more than one server per port
1403
if {$tcl_platform(platform) == "macintosh"} {
1404
set conflictResult {0 8836}
1406
set conflictResult {1 {couldn't open socket: address already in use}}
1409
test tlsIO-11.6 {socket conflict} {socket doTestsWithRemoteServer} {
1410
set s1 [tls::socket \
1411
-certfile $serverCert -cafile $caCert -keyfile $serverKey \
1412
-server accept 8836]
1413
if {[catch {set s2 [tls::socket \
1414
-certfile $serverCert -cafile $caCert -keyfile $serverKey \
1415
-server accept 8836]} msg]} {
1416
set result [list 1 $msg]
1418
set result [list 0 [lindex [fconfigure $s2 -sockname] 2]]
1425
test tlsIO-11.7 {server with several clients} {socket doTestsWithRemoteServer} {
1428
set socket10_9_test_server [tls::socket \
1429
-certfile $serverCert -cafile $caCert -keyfile $serverKey \
1430
-server accept 8836]
1431
proc accept {s a p} {
1432
fconfigure $s -buffering line
1433
fileevent $s readable [list echo $s]
1444
set s1 [tls::socket \
1445
-certfile $clientCert -cafile $caCert -keyfile $clientKey \
1446
$remoteServerIP 8836]
1447
fconfigure $s1 -buffering line
1448
set s2 [tls::socket \
1449
-certfile $clientCert -cafile $caCert -keyfile $clientKey \
1450
$remoteServerIP 8836]
1451
fconfigure $s2 -buffering line
1452
set s3 [tls::socket \
1453
-certfile $clientCert -cafile $caCert -keyfile $clientKey \
1454
$remoteServerIP 8836]
1455
fconfigure $s3 -buffering line
1456
for {set i 0} {$i < 100} {incr i} {
1467
sendCommand {close $socket10_9_test_server}
1471
test tlsIO-11.8 {client with several servers} {socket doTestsWithRemoteServer} {
1474
tls::init -certfile $serverCert -cafile $caCert -keyfile $serverKey
1475
set s1 [tls::socket -server "accept 4003" 4003]
1476
set s2 [tls::socket -server "accept 4004" 4004]
1477
set s3 [tls::socket -server "accept 4005" 4005]
1478
proc handshake {s mp} {
1481
} elseif {[catch {tls::handshake $s} result]} {
1482
# Some errors are normal.
1483
} elseif {$result == 1} {
1484
# Handshake complete
1485
fileevent $s readable ""
1490
proc accept {mp s a p} {
1491
# These have to accept non-blocking, because the handshaking
1492
# order isn't deterministic
1493
fconfigure $s -blocking 0 -buffering line
1494
fileevent $s readable [list handshake $s $mp]
1497
tls::init -certfile $clientCert -cafile $caCert -keyfile $clientKey
1498
set s1 [tls::socket $remoteServerIP 4003]
1499
set s2 [tls::socket $remoteServerIP 4004]
1500
set s3 [tls::socket $remoteServerIP 4005]
1502
lappend l [gets $s1] [gets $s1] [eof $s1] [gets $s2] [gets $s2] [eof $s2] \
1503
[gets $s3] [gets $s3] [eof $s3]
1513
} {4003 {} 1 4004 {} 1 4005 {} 1}
1515
test tlsIO-11.9 {accept callback error} {socket doTestsWithRemoteServer} {
1516
set s [tls::socket \
1517
-certfile $serverCert -cafile $caCert -keyfile $serverKey \
1518
-server accept 8836]
1519
proc accept {s a p} {expr 10 / 0}
1525
if {[catch {sendCommand {
1526
set peername [fconfigure $callerSocket -peername]
1527
set s [tls::socket \
1528
-certfile $clientCert -cafile $caCert -keyfile $clientKey \
1529
[lindex $peername 0] 8836]
1535
set timer [after 10000 "set x timed_out"]
1541
} {{divide by zero}}
1543
test tlsIO-11.10 {testing socket specific options} {socket doTestsWithRemoteServer} {
1546
set socket10_12_test_server [tls::socket \
1547
-certfile $serverCert -cafile $caCert -keyfile $serverKey \
1548
-server accept 8836]
1549
proc accept {s a p} {close $s}
1551
set s [tls::socket \
1552
-certfile $clientCert -cafile $caCert -keyfile $clientKey \
1553
$remoteServerIP 8836]
1554
set p [fconfigure $s -peername]
1555
set n [fconfigure $s -sockname]
1557
lappend l [lindex $p 2] [llength $p] [llength $p]
1559
sendCommand {close $socket10_12_test_server}
1563
test tlsIO-11.11 {testing spurious events} {socket doTestsWithRemoteServer} {
1564
# remote equivalent of 9.1
1567
set socket_test_server [tls::socket -server accept \
1568
-certfile $serverCert -cafile $caCert -keyfile $serverKey 8836]
1569
proc handshake {s} {
1572
} elseif {[catch {tls::handshake $s} result]} {
1573
# Some errors are normal.
1574
} elseif {$result == 1} {
1575
# Handshake complete
1576
fileevent $s writable ""
1577
after 100 writesome $s
1580
proc accept {s a p} {
1581
fconfigure $s -translation "auto lf"
1582
fileevent $s writable [list handshake $s]
1584
proc writesome {s} {
1585
for {set i 0} {$i < 100} {incr i} {
1586
puts $s "line $i from remote server"
1594
proc readlittle {s} {
1595
global spurious done len
1597
if {[string length $l] == 0} {
1605
incr len [string length $l]
1608
set c [tls::socket \
1609
-certfile $clientCert -cafile $caCert -keyfile $clientKey \
1610
$remoteServerIP 8836]
1611
# Get the buffering corrected
1612
fconfigure $c -buffering line
1613
# Put a byte into the client pipe to trigger TLS handshaking
1615
fileevent $c readable [list readlittle $c]
1616
set timer [after 10000 "set done timed_out"]
1619
sendCommand {close $socket_test_server}
1623
test tlsIO-11.12 {testing EOF stickyness} {unexplainedFailure socket doTestsWithRemoteServer} {
1624
# remote equivalent of 9.3
1625
# HOBBS: never worked correctly
1629
global counter done after_id
1634
set done {EOF is sticky}
1635
after cancel $after_id
1642
set done {timed_out, EOF is not sticky}
1647
set socket10_14_test_server [tls::socket \
1648
-certfile $serverCert -cafile $caCert -keyfile $serverKey \
1649
-server accept 8836]
1650
proc accept {s a p} {
1655
set c [tls::socket \
1656
-certfile $clientCert -cafile $caCert -keyfile $clientKey \
1657
$remoteServerIP 8836]
1658
fileevent $c readable "count_up $c"
1659
set after_id [after 1000 timed_out]
1661
sendCommand {close $socket10_14_test_server}
1665
test tlsIO-11.13 {testing async write, async flush, async close} \
1666
{socket doTestsWithRemoteServer} {
1670
incr count [string length $l]
1678
set firstblock [string repeat a 31]
1679
set secondblock [string repeat b 65535]
1680
set l [tls::socket \
1681
-certfile $serverCert -cafile $caCert -keyfile $serverKey \
1682
-server accept 8845]
1683
proc accept {s a p} {
1685
fconfigure $s -blocking 0 -translation lf -buffersize 16384 \
1687
fileevent $s readable "readable $s"
1691
fileevent $s readable {}
1692
after 1000 respond $s
1696
puts -nonewline $s $firstblock
1697
after 1000 writedata $s
1699
proc writedata {s} {
1701
puts -nonewline $s $secondblock
1705
set s [tls::socket \
1706
-certfile $clientCert -cafile $caCert -keyfile $clientKey \
1707
$remoteServerIP 8845]
1708
fconfigure $s -blocking 0 -translation lf -buffering line
1711
fileevent $s readable "readit $s"
1712
set timer [after 10000 "set done timed_out"]
1715
sendCommand {close $l}
1719
proc getdata {type file} {
1720
# Read handler on the accepted socket.
1723
set status [catch {read $file} data]
1725
set x "read failed, error was $data"
1726
catch { close $file }
1727
} elseif {[string compare {} $data]} {
1728
} elseif {[fblocked $file]} {
1729
} elseif {[eof $file]} {
1731
set x "$type socket was inherited"
1733
set x "$type socket was not inherited"
1735
catch { close $file }
1737
set x {impossible case}
1738
catch { close $file }
1743
test tlsIO-12.1 {testing inheritance of server sockets} {socket exec} {
1747
# Script1 is just a 10 second delay. If the server socket
1748
# is inherited, it will be held open for 10 seconds
1750
set f [open script1 w]
1757
# Script2 creates the server socket, launches script1,
1758
# waits a second, and exits. The server socket will now
1759
# be closed unless script1 inherited it.
1761
set f [open script2 w]
1762
puts $f [list set tclsh $::tcltest::tcltest]
1764
set auto_path [linsert $auto_path 0 [lindex [split $env(PATH) ";:"] 0]]
1767
puts $f "set f \[tls::socket -server accept \
1768
-certfile $serverCert -cafile $caCert -keyfile $serverKey 8828\]"
1770
proc accept { file addr port } {
1773
exec $tclsh script1 &
1780
# Launch script2 and wait 5 seconds
1782
exec $::tcltest::tcltest script2 &
1783
after 5000 { set ok_to_proceed 1 }
1786
# If we can still connect to the server, the socket got inherited.
1788
if {[catch {tls::socket \
1789
-certfile $clientCert -cafile $caCert -keyfile $clientKey \
1790
127.0.0.1 8828} msg]} {
1791
set x {server socket was not inherited}
1794
set x {server socket was inherited}
1798
} {server socket was not inherited}
1800
test tlsIO-12.2 {testing inheritance of client sockets} {socket exec} {
1804
# Script1 is just a 10 second delay. If the server socket
1805
# is inherited, it will be held open for 10 seconds
1807
set f [open script1 w]
1814
# Script2 opens the client socket and writes to it. It then
1815
# launches script1 and exits. If the child process inherited the
1816
# client socket, the socket will still be open.
1818
set f [open script2 w]
1819
puts $f [list set tclsh $::tcltest::tcltest]
1821
set auto_path [linsert $auto_path 0 [lindex [split $env(PATH) ";:"] 0]]
1824
puts $f "set f \[tls::socket -certfile $clientCert -cafile $caCert \
1825
-keyfile $clientKey 127.0.0.1 8829\]"
1827
exec $tclsh script1 &
1835
# Create the server socket
1837
set server [tls::socket \
1838
-certfile $serverCert -cafile $caCert -keyfile $serverKey \
1839
-server accept 8829]
1840
proc accept { file host port } {
1841
# When the client connects, establish the read handler
1844
fconfigure $file -blocking 0
1845
fileevent $file readable [list do_handshake $file readable \
1846
[list getdata client] -buffering line]
1850
# If the socket doesn't hit end-of-file in 5 seconds, the
1851
# script1 process must have inherited the client.
1854
after 5000 [list set failed 1]
1856
# Launch the script2 process
1858
exec $::tcltest::tcltest script2 &
1865
} {client socket was not inherited}
1867
test tlsIO-12.3 {testing inheritance of accepted sockets} \
1868
{socket exec unixOnly} {
1872
set f [open script1 w]
1879
set f [open script2 w]
1880
puts $f [list set tclsh $::tcltest::tcltest]
1882
set auto_path [linsert $auto_path 0 [lindex [split $env(PATH) ";:"] 0]]
1885
puts $f "set f \[tls::socket -server accept \
1886
-certfile $serverCert -cafile $caCert -keyfile $serverKey 8930\]"
1888
proc accept { file host port } {
1890
fconfigure $file -buffering line
1891
puts $file {test data on socket}
1892
exec $tclsh script1 &
1899
# Launch the script2 process and connect to it. See how long
1900
# the socket stays open
1902
exec $::tcltest::tcltest script2 &
1904
after 2000 set ok_to_proceed 1
1907
set f [tls::socket \
1908
-certfile $clientCert -cafile $caCert -keyfile $clientKey \
1910
fconfigure $f -buffering full -blocking 0
1911
# We need to put a byte into the read queue, otherwise the
1912
# TLS handshake doesn't finish
1914
fileevent $f readable [list getdata accepted $f]
1916
# If the socket is still open after 5 seconds, the script1 process
1917
# must have inherited the accepted socket.
1920
after 5000 set failed 1
1924
} {accepted socket was not inherited}
1926
test tlsIO-13.1 {Testing use of shared socket between two threads} \
1927
{socket testthread} {
1928
# HOBBS: never tested
1933
set auto_path [linsert $auto_path 0 [lindex [split $env(PATH) ";:"] 0]]
1935
set f [tls::socket -server accept 8828]
1936
proc accept {s a p} {
1937
fileevent $s readable [list echo $s]
1938
fconfigure $s -buffering line
1956
# thread cleans itself up.
1961
set serverthread [testthread create { source script } ]
1965
set s [tls::socket 127.0.0.1 8828]
1966
fconfigure $s -buffering line
1976
lappend result [threadReap]
1983
if {[string match sock* $commandSocket] == 1} {
1984
puts $commandSocket exit
1985
flush $commandSocket
1987
catch {close $commandSocket}
1988
catch {close $remoteProcChan}
1989
::tcltest::cleanupTests