~ubuntu-branches/ubuntu/hardy/tcltls/hardy

« back to all changes in this revision

Viewing changes to tests/tlsIO.test

  • Committer: Bazaar Package Importer
  • Author(s): Søren Boll Overgaard
  • Date: 2004-06-16 19:22:30 UTC
  • Revision ID: james.westby@ubuntu.com-20040616192230-tv159811lsnerauf
Tags: upstream-1.5.0
Import upstream version 1.5.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Commands tested in this file: socket.
 
2
#
 
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.
 
6
#
 
7
# Copyright (c) 1994-1996 Sun Microsystems, Inc.
 
8
# Copyright (c) 1998-2000 Ajuba Solutions. 
 
9
#
 
10
# See the file "license.terms" for information on usage and redistribution
 
11
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 
12
#
 
13
# RCS: @(#) $Id: tlsIO.test,v 1.21 2004/02/11 22:41:25 razzell Exp $
 
14
 
 
15
# Running socket tests with a remote server:
 
16
# ------------------------------------------
 
17
 
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:
 
23
 
24
#     tcltest remote.tcl -port 8048     # Or choose another port number.
 
25
 
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:
 
29
 
30
#     tcltest remote.tcl -address your.machine.com
 
31
 
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:
 
34
 
35
#     shell% setenv serverPort 8048
 
36
#     shell% setenv serverAddress your.machine.com
 
37
 
38
# and subsequently you can start the remote server with:
 
39
 
40
#     tcltest remote.tcl
 
41
 
42
# to have it listen on port 8048 on the interface your.machine.com.
 
43
#     
 
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:
 
48
 
49
#     % set remoteServerIP <name or address of machine on which server runs>
 
50
#     % set remoteServerPort 8048
 
51
 
52
# These variables are also settable from the environment. On Unix, you can:
 
53
 
54
#     shell% setenv remoteServerIP machine.where.server.runs
 
55
#     shell% setenv remoteServerPort 8048
 
56
 
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.
 
64
 
 
65
proc dputs {msg} { return ; puts stderr $msg ; flush stderr }
 
66
 
 
67
if {[lsearch [namespace children] ::tcltest] == -1} {
 
68
    package require tcltest
 
69
    namespace import -force ::tcltest::*
 
70
}
 
71
 
 
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
 
76
 
 
77
set tlsServerPort 8048
 
78
 
 
79
# Specify where the certificates are
 
80
 
 
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]
 
87
 
 
88
# Some tests require the testthread and exec commands
 
89
 
 
90
set ::tcltest::testConstraints(testthread) \
 
91
        [expr {[info commands testthread] != {}}]
 
92
set ::tcltest::testConstraints(exec) [expr {[info commands exec] != {}}]
 
93
 
 
94
#
 
95
# If remoteServerIP or remoteServerPort are not set, check in the
 
96
# environment variables for externally set values.
 
97
#
 
98
 
 
99
if {![info exists remoteServerIP]} {
 
100
    if {[info exists env(remoteServerIP)]} {
 
101
        set remoteServerIP $env(remoteServerIP)
 
102
    }
 
103
}
 
104
if {![info exists remoteServerPort]} {
 
105
    if {[info exists env(remoteServerPort)]} {
 
106
        set remoteServerPort $env(remoteServerPort)
 
107
    } else {
 
108
        if {[info exists remoteServerIP]} {
 
109
            set remoteServerPort $tlsServerPort
 
110
        }
 
111
    }
 
112
}
 
113
 
 
114
proc do_handshake {s {type readable} {cmd {}} args} {
 
115
    if {[eof $s]} {
 
116
        close $s
 
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} {
 
123
        # Handshake complete
 
124
        if {[llength $args]} { eval [list fconfigure $s] $args }
 
125
        if {$cmd == ""} {
 
126
            fileevent $s $type ""
 
127
        } else {
 
128
            fileevent $s $type "$cmd [list $s]"
 
129
        }
 
130
        dputs "handshake: complete"
 
131
        set ::do_handshake "complete"
 
132
    } else {
 
133
        dputs "handshake: in progress"
 
134
    }
 
135
}
 
136
 
 
137
#
 
138
# Check if we're supposed to do tests against the remote server
 
139
#
 
140
 
 
141
set doTestsWithRemoteServer 1
 
142
if {![info exists remoteServerIP] && ($tcl_platform(platform) != "macintosh")} {
 
143
    set remoteServerIP 127.0.0.1
 
144
}
 
145
if {($doTestsWithRemoteServer == 1) && (![info exists remoteServerPort])} {
 
146
    set remoteServerPort $tlsServerPort
 
147
}
 
148
 
 
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.
 
155
 
 
156
set remoteProcChan ""
 
157
set commandSocket ""
 
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
 
166
        } else {
 
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} {
 
173
                after 1000
 
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
 
178
                } else {
 
179
                    set noRemoteTestReason $msg
 
180
                    set doTestsWithRemoteServer 0
 
181
                }
 
182
            } else {
 
183
                set noRemoteTestReason "$msg $::tcltest::tcltest"
 
184
                set doTestsWithRemoteServer 0
 
185
            }
 
186
        }
 
187
    } else {
 
188
        fconfigure $commandSocket -translation crlf -buffering line
 
189
    }
 
190
}
 
191
 
 
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"
 
199
    }
 
200
}
 
201
 
 
202
#
 
203
# If we do the tests, define a command to send a command to the
 
204
# remote server.
 
205
#
 
206
 
 
207
if {$doTestsWithRemoteServer == 1} {
 
208
    proc sendCommand {c} {
 
209
        global commandSocket
 
210
 
 
211
        if {[eof $commandSocket]} {
 
212
            error "remote server disappeared"
 
213
        }
 
214
 
 
215
        if {[catch {puts $commandSocket $c} msg]} {
 
216
            error "remote server disappeared: $msg"
 
217
        }
 
218
        if {[catch {puts $commandSocket "--Marker--Marker--Marker--"} msg]} {
 
219
            error "remote server disappeared: $msg"
 
220
        }
 
221
 
 
222
        set resp ""
 
223
        while {1} {
 
224
            set line [gets $commandSocket]
 
225
            if {[eof $commandSocket]} {
 
226
                error "remote server disappeared"
 
227
            }
 
228
            if {[string compare $line "--Marker--Marker--Marker--"] == 0} {
 
229
                if {[string compare [lindex $resp 0] error] == 0} {
 
230
                    error [lindex $resp 1]
 
231
                } else {
 
232
                    return [lindex $resp 1]
 
233
                }
 
234
            } else {
 
235
                append resp $line "\n"
 
236
            }
 
237
        }
 
238
    }
 
239
 
 
240
    sendCommand [list proc dputs [info args dputs] [info body dputs]]
 
241
 
 
242
    proc sendCertValues {} {
 
243
        # We need to be able to send certificate values that normalize
 
244
        # filenames across platforms
 
245
        sendCommand {
 
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]
 
252
        }
 
253
    }
 
254
}
 
255
 
 
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"}}
 
259
 
 
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"}}
 
263
 
 
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"}}
 
267
 
 
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"}}
 
271
 
 
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"}}
 
275
 
 
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"}}
 
279
 
 
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"}}
 
283
 
 
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"}}
 
287
 
 
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"}}
 
291
 
 
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"}}
 
295
 
 
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"}}
 
299
 
 
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"}}
 
303
 
 
304
test tlsIO-2.1 {tcp connection} {socket stdio} {
 
305
    removeFile script
 
306
    set f [open script w]
 
307
    puts $f {
 
308
        set auto_path [linsert $auto_path 0 [lindex [split $env(PATH) ";:"] 0]]
 
309
        package require tls
 
310
        set timer [after 2000 "set x timed_out"]
 
311
    }
 
312
    puts $f "set f \[tls::socket -server accept -certfile $serverCert -cafile $caCert -keyfile $serverKey 8828 \]"
 
313
    puts $f {
 
314
        proc accept {file addr port} {
 
315
            global x
 
316
            set x done
 
317
            close $file
 
318
        }
 
319
        puts ready
 
320
        vwait x
 
321
        after cancel $timer
 
322
        close $f
 
323
        puts $x
 
324
    }
 
325
    close $f
 
326
    set f [open "|[list $::tcltest::tcltest script]" r]
 
327
    gets $f x
 
328
    if {[catch {tls::socket -certfile $clientCert -cafile $caCert \
 
329
        -keyfile $clientKey 127.0.0.1 8828} msg]} {
 
330
        set x $msg
 
331
    } else {
 
332
        lappend x [gets $f]
 
333
        close $msg
 
334
    }
 
335
    lappend x [gets $f]
 
336
    close $f
 
337
    set x
 
338
} {ready done {}}
 
339
 
 
340
if [info exists port] {
 
341
    incr port
 
342
} else { 
 
343
    set port [expr $tlsServerPort + [pid]%1024]
 
344
}
 
345
 
 
346
test tlsIO-2.2 {tcp connection with client port specified} {socket stdio} {
 
347
    removeFile script
 
348
    set f [open script w]
 
349
    puts $f {
 
350
        set auto_path [linsert $auto_path 0 [lindex [split $env(PATH) ";:"] 0]]
 
351
        package require tls
 
352
        set timer [after 2000 "set x done"]
 
353
    }
 
354
    puts $f "set f \[tls::socket -server accept -certfile $serverCert -cafile $caCert -keyfile $serverKey 8829 \]"
 
355
    puts $f {
 
356
        proc accept {sock addr port} {
 
357
            global x
 
358
            puts "[gets $sock] $port"
 
359
            close $sock
 
360
            set x done
 
361
        }
 
362
        puts ready
 
363
        vwait x
 
364
        after cancel $timer
 
365
        close $f
 
366
    }
 
367
    close $f
 
368
    set f [open "|[list $::tcltest::tcltest script]" r]
 
369
    gets $f x
 
370
    global port
 
371
    if {[catch {tls::socket -myport $port \
 
372
        -certfile $clientCert -cafile $caCert \
 
373
        -keyfile $clientKey 127.0.0.1 8829} sock]} {
 
374
        set x $sock
 
375
        catch {close [tls::socket 127.0.0.1 8829]}
 
376
    } else {
 
377
        puts $sock hello
 
378
        flush $sock
 
379
        lappend x [gets $f]
 
380
        close $sock
 
381
    }
 
382
    close $f
 
383
    set x
 
384
} [list ready "hello $port"]
 
385
 
 
386
test tlsIO-2.3 {tcp connection with client interface specified} {socket stdio} {
 
387
    removeFile script
 
388
    set f [open script w]
 
389
    puts $f {
 
390
        set auto_path [linsert $auto_path 0 [lindex [split $env(PATH) ";:"] 0]]
 
391
        package require tls
 
392
        set timer [after 2000 "set x done"]
 
393
    }
 
394
    puts $f "set f \[tls::socket -server accept -certfile $serverCert -cafile $caCert -keyfile $serverKey 8830 \]"
 
395
    puts $f {
 
396
        proc accept {sock addr port} {
 
397
            global x
 
398
            puts "[gets $sock] $addr"
 
399
            close $sock
 
400
            set x done
 
401
        }
 
402
        puts ready
 
403
        vwait x
 
404
        after cancel $timer
 
405
        close $f
 
406
    }
 
407
    close $f
 
408
    set f [open "|[list $::tcltest::tcltest script]" r]
 
409
    gets $f x
 
410
    if {[catch {tls::socket -myaddr 127.0.0.1 \
 
411
        -certfile $clientCert -cafile $caCert \
 
412
        -keyfile $clientKey 127.0.0.1 8830} sock]} {
 
413
        set x $sock
 
414
    } else {
 
415
        puts $sock hello
 
416
        catch {flush $sock}
 
417
        lappend x [gets $f]
 
418
        close $sock
 
419
    }
 
420
    close $f
 
421
    set x
 
422
} {ready {hello 127.0.0.1}}
 
423
 
 
424
test tlsIO-2.4 {tcp connection with server interface specified} {socket stdio} {
 
425
    removeFile script
 
426
    set f [open script w]
 
427
    puts $f {
 
428
        set auto_path [linsert $auto_path 0 [lindex [split $env(PATH) ";:"] 0]]
 
429
        package require tls
 
430
        set timer [after 2000 "set x done"]
 
431
    }
 
432
    puts $f "set f \[tls::socket -server accept -certfile $serverCert -cafile $caCert -keyfile $serverKey -myaddr [info hostname] 8831 \]"
 
433
    puts $f {
 
434
        proc accept {sock addr port} {
 
435
            global x
 
436
            puts "[gets $sock]"
 
437
            close $sock
 
438
            set x done
 
439
        }
 
440
        puts ready
 
441
        vwait x
 
442
        after cancel $timer
 
443
        close $f
 
444
    }
 
445
    close $f
 
446
    set f [open "|[list $::tcltest::tcltest script]" r]
 
447
    gets $f x
 
448
    if {[catch {tls::socket -certfile $clientCert -cafile $caCert \
 
449
        -keyfile $clientKey [info hostname] 8831} sock]} {
 
450
        set x $sock
 
451
    } else {
 
452
        puts $sock hello
 
453
        flush $sock
 
454
        lappend x [gets $f]
 
455
        close $sock
 
456
    }
 
457
    close $f
 
458
    set x
 
459
} {ready hello}
 
460
 
 
461
test tlsIO-2.5 {tcp connection with redundant server port} {socket stdio} {
 
462
    removeFile script
 
463
    set f [open script w]
 
464
    puts $f {
 
465
        set auto_path [linsert $auto_path 0 [lindex [split $env(PATH) ";:"] 0]]
 
466
        package require tls
 
467
        set timer [after 2000 "set x done"]
 
468
    }
 
469
    puts $f "set f \[tls::socket -server accept -certfile $serverCert -cafile $caCert -keyfile $serverKey 8832 \]"
 
470
    puts $f {
 
471
        proc accept {sock addr port} {
 
472
            global x
 
473
            puts "[gets $sock]"
 
474
            close $sock
 
475
            set x done
 
476
        }
 
477
        puts ready
 
478
        vwait x
 
479
        after cancel $timer
 
480
        close $f
 
481
    }
 
482
    close $f
 
483
    set f [open "|[list $::tcltest::tcltest script]" r]
 
484
    gets $f x
 
485
    if {[catch {tls::socket -certfile $clientCert -cafile $caCert \
 
486
        -keyfile $clientKey 127.0.0.1 8832} sock]} {
 
487
        set x $sock
 
488
    } else {
 
489
        puts $sock hello
 
490
        flush $sock
 
491
        lappend x [gets $f]
 
492
        close $sock
 
493
    }
 
494
    close $f
 
495
    set x
 
496
} {ready hello}
 
497
test tlsIO-2.6 {tcp connection} {socket} {
 
498
    set status ok
 
499
    if {![catch {set sock [tls::socket 127.0.0.1 8833]}]} {
 
500
        if {![catch {gets $sock}]} {
 
501
            set status broken
 
502
        }
 
503
        close $sock
 
504
    }
 
505
    set status
 
506
} ok
 
507
 
 
508
test tlsIO-2.7 {echo server, one line} {socket stdio} {
 
509
    removeFile script
 
510
    set f [open script w]
 
511
    puts $f {
 
512
        set auto_path [linsert $auto_path 0 [lindex [split $env(PATH) ";:"] 0]]
 
513
        package require tls
 
514
        set timer [after 2000 "set x done"]
 
515
    }
 
516
    puts $f "set f \[tls::socket -server accept -certfile $serverCert -cafile $caCert -keyfile $serverKey 8834 \]"
 
517
    puts $f {
 
518
        proc accept {s a p} {
 
519
            fileevent $s readable [list echo $s]
 
520
            fconfigure $s -translation lf -buffering line
 
521
        }
 
522
        proc echo {s} {
 
523
             set l [gets $s]
 
524
             if {[eof $s]} {
 
525
                 global x
 
526
                 close $s
 
527
                 set x done
 
528
             } else {
 
529
                 puts $s $l
 
530
             }
 
531
        }
 
532
        puts ready
 
533
        vwait x
 
534
        after cancel $timer
 
535
        close $f
 
536
        puts done
 
537
    }
 
538
    close $f
 
539
    set f [open "|[list $::tcltest::tcltest script]" r]
 
540
    gets $f
 
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"
 
545
    after 1000
 
546
    set x [gets $s]
 
547
    close $s
 
548
    set y [gets $f]
 
549
    close $f
 
550
    list $x $y
 
551
} {{hello abcdefghijklmnop} done}
 
552
 
 
553
test tlsIO-2.8 {echo server, loop 50 times, single connection} {socket stdio} {
 
554
    set f [open script w]
 
555
    puts $f {
 
556
        set auto_path [linsert $auto_path 0 [lindex [split $env(PATH) ";:"] 0]]
 
557
        package require tls
 
558
    }
 
559
    puts $f "set f \[tls::socket -server accept -certfile $serverCert -cafile $caCert -keyfile $serverKey 8835 \]"
 
560
    puts $f {
 
561
        proc accept {s a p} {
 
562
            fileevent $s readable [list echo $s]
 
563
            fconfigure $s -buffering line
 
564
        }
 
565
        proc echo {s} {
 
566
             global i
 
567
             set l [gets $s]
 
568
             if {[eof $s]} {
 
569
                 global x
 
570
                 close $s
 
571
                 set x done
 
572
             } else { 
 
573
                 incr i
 
574
                 puts $s $l
 
575
             }
 
576
        }
 
577
        set i 0
 
578
        puts ready
 
579
        set timer [after 20000 "set x done"]
 
580
        vwait x
 
581
        after cancel $timer
 
582
        close $f
 
583
        puts "done $i"
 
584
    }
 
585
    close $f
 
586
    set f [open "|[list $::tcltest::tcltest script]" r]
 
587
    gets $f
 
588
    set s [tls::socket -certfile $clientCert -cafile $caCert \
 
589
        -keyfile $clientKey 127.0.0.1 8835]
 
590
    fconfigure $s -buffering line
 
591
    catch {
 
592
        for {set x 0} {$x < 50} {incr x} {
 
593
            puts $s "hello abcdefghijklmnop"
 
594
            gets $s
 
595
        }
 
596
    }
 
597
    close $s
 
598
    catch {set x [gets $f]}
 
599
    close $f
 
600
    set x
 
601
} {done 50}
 
602
 
 
603
test tlsIO-2.9 {socket conflict} {socket stdio} {
 
604
    set s [tls::socket -server accept 8828]
 
605
    removeFile script
 
606
    set f [open script w]
 
607
    puts -nonewline $f {
 
608
        set auto_path [linsert $auto_path 0 [lindex [split $env(PATH) ";:"] 0]]
 
609
        package require tls
 
610
        tls::socket -server accept 8828
 
611
    }
 
612
    close $f
 
613
    set f [open "|[list $::tcltest::tcltest script]" r]
 
614
    gets $f
 
615
    after 100
 
616
    set x [list [catch {close $f} msg] [string range $msg 0 43]]
 
617
    close $s
 
618
    set x
 
619
} {1 {couldn't open socket: address already in use}}
 
620
 
 
621
test tlsIO-2.10 {close on accept, accepted socket lives} {socket} {
 
622
    set done 0
 
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} {
 
627
        global ss
 
628
        close $ss
 
629
        fileevent $s readable "readit $s"
 
630
        fconfigure $s -trans lf
 
631
    }
 
632
    proc readit {s} {
 
633
        global done
 
634
        gets $s
 
635
        close $s
 
636
        set done 1
 
637
    }
 
638
    set cs [tls::socket -certfile $clientCert -cafile $caCert \
 
639
        -keyfile $clientKey [info hostname] 8830]
 
640
    close $cs
 
641
 
 
642
    vwait done
 
643
    after cancel $timer
 
644
    set done
 
645
} 1
 
646
 
 
647
test tlsIO-2.11 {detecting new data} {socket} {
 
648
    proc accept {s a p} {
 
649
        global sock
 
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
 
654
        set sock $s
 
655
        fileevent $s readable [list do_handshake $s]
 
656
    }
 
657
 
 
658
    set s [tls::socket -server accept \
 
659
            -certfile $serverCert -cafile $caCert -keyfile $serverKey 8400]
 
660
    set sock ""
 
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
 
667
    vwait sock
 
668
    puts $s2 one
 
669
    flush $s2
 
670
    # need update to complete TLS handshake in-process
 
671
    update
 
672
    after 500
 
673
    fconfigure $sock -blocking 0
 
674
    set result a:[gets $sock]
 
675
    lappend result b:[gets $sock]
 
676
    fconfigure $sock -blocking 1
 
677
    puts $s2 two
 
678
    flush $s2
 
679
    fconfigure $sock -blocking 0
 
680
    lappend result c:[gets $sock]
 
681
    fconfigure $sock -blocking 1
 
682
    close $s2
 
683
    close $s
 
684
    close $sock
 
685
    set result
 
686
} {a:one b: c:two}
 
687
 
 
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.
 
692
    removeFile script
 
693
    set f [open script w]
 
694
    puts $f {
 
695
        set auto_path [linsert $auto_path 0 [lindex [split $env(PATH) ";:"] 0]]
 
696
        package require tls
 
697
        set timer [after 2000 "set x timed_out"]
 
698
        set f [tls::socket -server accept 8828]
 
699
        proc accept {file addr port} {
 
700
            global x
 
701
            set x done
 
702
            close $file
 
703
        }
 
704
        puts ready
 
705
        vwait x
 
706
        after cancel $timer
 
707
        close $f
 
708
        puts $x
 
709
    }
 
710
    close $f
 
711
    set f [open "|[list $::tcltest::tcltest script]" r]
 
712
    gets $f x
 
713
    if {[catch {tls::socket 127.0.0.1 8828} msg]} {
 
714
        set x $msg
 
715
    } else {
 
716
        lappend x [gets $f]
 
717
        close $msg
 
718
    }
 
719
    lappend x [gets $f]
 
720
    close $f
 
721
    set x
 
722
} {ready done {}}
 
723
 
 
724
test tlsIO-3.1 {socket conflict} {socket stdio} {
 
725
    removeFile script
 
726
    set f [open script w]
 
727
    puts $f {
 
728
        set auto_path [linsert $auto_path 0 [lindex [split $env(PATH) ";:"] 0]]
 
729
        package require tls
 
730
    }
 
731
    puts $f "set f \[tls::socket -server accept -certfile $serverCert -cafile $caCert -keyfile $serverKey 8828 \]"
 
732
    puts $f {
 
733
        puts ready
 
734
        gets stdin
 
735
        close $f
 
736
    }
 
737
    close $f
 
738
    set f [open "|[list $::tcltest::tcltest script]" r+]
 
739
    gets $f
 
740
    set x [list [catch {tls::socket \
 
741
            -certfile $clientCert -cafile $caCert -keyfile $clientKey \
 
742
        -server accept 8828} msg] \
 
743
                $msg]
 
744
    puts $f bye
 
745
    close $f
 
746
    set x
 
747
} {1 {couldn't open socket: address already in use}}
 
748
 
 
749
test tlsIO-3.2 {server with several clients} {socket stdio} {
 
750
    removeFile script
 
751
    set f [open script w]
 
752
    puts $f {
 
753
        set auto_path [linsert $auto_path 0 [lindex [split $env(PATH) ";:"] 0]]
 
754
        package require tls
 
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"]
 
758
        set counter 0
 
759
    }
 
760
    puts $f "set s \[tls::socket -server accept -certfile $serverCert -cafile $caCert -keyfile $serverKey 8828 \]"
 
761
    puts $f {
 
762
        proc accept {s a p} {
 
763
            fileevent $s readable [list echo $s]
 
764
            fconfigure $s -buffering line
 
765
        }
 
766
        proc echo {s} {
 
767
             global x
 
768
             set l [gets $s]
 
769
             if {[eof $s]} {
 
770
                 close $s
 
771
                 set x done
 
772
             } else {
 
773
                 puts $s $l
 
774
             }
 
775
        }
 
776
        puts ready
 
777
        vwait x
 
778
        after cancel $t1
 
779
        vwait x
 
780
        after cancel $t2
 
781
        vwait x
 
782
        after cancel $t3
 
783
        close $s
 
784
        puts $x
 
785
    }
 
786
    close $f
 
787
    set f [open "|[list $::tcltest::tcltest script]" r+]
 
788
    set x [gets $f]
 
789
    set s1 [tls::socket \
 
790
            -certfile $clientCert -cafile $caCert -keyfile $clientKey \
 
791
            127.0.0.1 8828]
 
792
    fconfigure $s1 -buffering line
 
793
    set s2 [tls::socket \
 
794
            -certfile $clientCert -cafile $caCert -keyfile $clientKey \
 
795
            127.0.0.1 8828]
 
796
    fconfigure $s2 -buffering line
 
797
    set s3 [tls::socket \
 
798
            -certfile $clientCert -cafile $caCert -keyfile $clientKey \
 
799
            127.0.0.1 8828]
 
800
    fconfigure $s3 -buffering line
 
801
    for {set i 0} {$i < 100} {incr i} {
 
802
        puts $s1 hello,s1
 
803
        gets $s1
 
804
        puts $s2 hello,s2
 
805
        gets $s2
 
806
        puts $s3 hello,s3
 
807
        gets $s3
 
808
    }
 
809
    close $s1
 
810
    close $s2
 
811
    close $s3
 
812
    lappend x [gets $f]
 
813
    close $f
 
814
    set x
 
815
} {ready done}
 
816
 
 
817
test tlsIO-4.1 {server with several clients} {socket stdio} {
 
818
    # have seen intermittent hangs on Windows
 
819
    removeFile script
 
820
    set f [open script w]
 
821
    puts $f {
 
822
        set auto_path [linsert $auto_path 0 [lindex [split $env(PATH) ";:"] 0]]
 
823
        package require tls
 
824
        gets stdin
 
825
    }
 
826
    puts $f "set s \[tls::socket -certfile $clientCert -cafile $caCert -keyfile $clientKey 127.0.0.1 8828 \]"
 
827
    puts $f {
 
828
        fconfigure $s -buffering line
 
829
        for {set i 0} {$i < 100} {incr i} {
 
830
            puts $s hello
 
831
            gets $s
 
832
        }
 
833
        close $s
 
834
        puts bye
 
835
        gets stdin
 
836
    }
 
837
    close $f
 
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]
 
847
    }
 
848
    proc echo {s} {
 
849
        global x
 
850
        set l [gets $s]
 
851
        if {[eof $s]} {
 
852
            close $s
 
853
            set x done
 
854
        } else {
 
855
            puts $s $l
 
856
        }
 
857
    }
 
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"]
 
861
    set s [tls::socket \
 
862
            -certfile $serverCert -cafile $caCert -keyfile $serverKey \
 
863
            -server accept 8828]
 
864
    puts $p1 open
 
865
    puts $p2 open
 
866
    puts $p3 open
 
867
    vwait x
 
868
    vwait x
 
869
    vwait x
 
870
    after cancel $t1
 
871
    after cancel $t2
 
872
    after cancel $t3
 
873
    close $s
 
874
    set l ""
 
875
    lappend l [list p1 [gets $p1] $x]
 
876
    lappend l [list p2 [gets $p2] $x]
 
877
    lappend l [list p3 [gets $p3] $x]
 
878
    puts $p1 bye
 
879
    puts $p2 bye
 
880
    puts $p3 bye
 
881
    close $p1
 
882
    close $p2
 
883
    close $p3
 
884
    set l
 
885
} {{p1 bye done} {p2 bye done} {p3 bye done}}
 
886
 
 
887
test tlsIO-4.2 {byte order problems, socket numbers, htons} {socket} {
 
888
    set x ok
 
889
    if {[catch {tls::socket -server dodo 0x3000} msg]} {
 
890
        set x $msg
 
891
    } else {
 
892
        close $msg
 
893
    }
 
894
    set x
 
895
} ok
 
896
 
 
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?}
 
902
        close $msg
 
903
    }
 
904
    set x
 
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}
 
910
        close $msg
 
911
    }
 
912
    set x
 
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?}
 
919
        close $msg
 
920
    }
 
921
    set x
 
922
} {couldn't open socket: not owner}
 
923
 
 
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.
 
927
    removeFile script
 
928
    set f [open script w]
 
929
    puts $f {
 
930
        set auto_path [linsert $auto_path 0 [lindex [split $env(PATH) ";:"] 0]]
 
931
        package require tls
 
932
        gets stdin
 
933
    }
 
934
    puts $f [list tls::socket -cafile $caCert 127.0.0.1 8848]
 
935
    close $f
 
936
    set f [open "|[list $::tcltest::tcltest script]" r+]
 
937
    proc bgerror args {
 
938
        global x
 
939
        set x $args
 
940
    }
 
941
    proc accept {s a p} {expr 10 / 0}
 
942
    set s [tls::socket -server accept \
 
943
            -certfile $serverCert -cafile $caCert -keyfile $serverKey 8848]
 
944
    puts $f hello
 
945
    close $f
 
946
    set timer [after 10000 "set x timed_out"]
 
947
    vwait x
 
948
    after cancel $timer
 
949
    close $s
 
950
    rename bgerror {}
 
951
    set x
 
952
} {{divide by zero}}
 
953
 
 
954
test tlsIO-7.1 {testing socket specific options} {socket stdio} {
 
955
    removeFile script
 
956
    set f [open script w]
 
957
    puts $f {
 
958
        set auto_path [linsert $auto_path 0 [lindex [split $env(PATH) ";:"] 0]]
 
959
        package require tls
 
960
    }
 
961
    puts $f [list tls::socket -server accept \
 
962
            -certfile $serverCert -cafile $caCert -keyfile $serverKey 8820]
 
963
    puts $f {
 
964
        proc accept args {
 
965
            global x
 
966
            set x done
 
967
        }
 
968
        puts ready
 
969
        set timer [after 10000 "set x timed_out"]
 
970
        vwait x
 
971
        after cancel $timer
 
972
    }
 
973
    close $f
 
974
    set f [open "|[list $::tcltest::tcltest script]" r]
 
975
    gets $f
 
976
    set s [tls::socket \
 
977
            -certfile $clientCert -cafile $caCert -keyfile $clientKey \
 
978
            127.0.0.1 8820]
 
979
    set p [fconfigure $s -peername]
 
980
    close $s
 
981
    close $f
 
982
    set l ""
 
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]
 
986
} {0 0 3}
 
987
 
 
988
test tlsIO-7.2 {testing socket specific options} {socket stdio} {
 
989
    removeFile script
 
990
    set f [open script w]
 
991
    puts $f {
 
992
        set auto_path [linsert $auto_path 0 [lindex [split $env(PATH) ";:"] 0]]
 
993
        package require tls
 
994
    }
 
995
    puts $f "tls::socket -server accept -certfile $serverCert -cafile $caCert -keyfile $serverKey 8821"
 
996
    puts $f {
 
997
        proc accept args {
 
998
            global x
 
999
            set x done
 
1000
        }
 
1001
        puts ready
 
1002
        set timer [after 10000 "set x timed_out"]
 
1003
        vwait x
 
1004
        after cancel $timer
 
1005
    }
 
1006
    close $f
 
1007
    set f [open "|[list $::tcltest::tcltest script]" r]
 
1008
    gets $f
 
1009
    set s [tls::socket \
 
1010
            -certfile $clientCert -cafile $caCert -keyfile $clientKey \
 
1011
            127.0.0.1 8821]
 
1012
    set p [fconfigure $s -sockname]
 
1013
    close $s
 
1014
    close $f
 
1015
    set l ""
 
1016
    lappend l [llength $p]
 
1017
    lappend l [lindex $p 0]
 
1018
    lappend l [string equal [lindex $p 2] 8821]
 
1019
} {3 127.0.0.1 0}
 
1020
 
 
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]]
 
1026
    close $s
 
1027
    update
 
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)}
 
1031
} 1
 
1032
 
 
1033
# bug report #5812 fconfigure doesn't return value for '-sockname'
 
1034
 
 
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} {
 
1040
        global x
 
1041
        set x [fconfigure $s -sockname]
 
1042
        close $s
 
1043
    }
 
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"]
 
1048
    vwait x
 
1049
    after cancel $timer
 
1050
    close $s
 
1051
    close $s1
 
1052
    set l ""
 
1053
    lappend l [lindex $x 2] [llength $x]
 
1054
} {8823 3}
 
1055
 
 
1056
# bug report #5812 fconfigure doesn't return value for '-sockname'
 
1057
 
 
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} {
 
1063
        global x
 
1064
        set x [fconfigure $s -sockname]
 
1065
        close $s
 
1066
    }
 
1067
    set s1 [tls::socket \
 
1068
            -certfile $clientCert -cafile $caCert -keyfile $clientKey \
 
1069
            127.0.0.1 8829]
 
1070
    set timer [after 10000 "set x timed_out"]
 
1071
    vwait x
 
1072
    after cancel $timer
 
1073
    close $s
 
1074
    close $s1
 
1075
    set l ""
 
1076
    lappend l [lindex $x 0] [lindex $x 2] [llength $x]
 
1077
} {127.0.0.1 8829 3}
 
1078
 
 
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} {
 
1086
        global x
 
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
 
1091
        puts $s bye
 
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
 
1094
        after 500 close $s
 
1095
        set x done
 
1096
    }
 
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
 
1104
    vwait x
 
1105
    # TLS handshaking needs one byte from the client...
 
1106
    puts $s1 a
 
1107
    # need update to complete TLS handshake in-process
 
1108
    update
 
1109
    set z [gets $s1]
 
1110
    close $s
 
1111
    close $s1
 
1112
    set z
 
1113
} bye
 
1114
 
 
1115
test tlsIO-9.1 {testing spurious events} {socket} {
 
1116
    set len 0
 
1117
    set spurious 0
 
1118
    set done 0
 
1119
    proc readlittle {s} {
 
1120
        global spurious done len
 
1121
        set l [read $s 1]
 
1122
        if {[string length $l] == 0} {
 
1123
            if {![eof $s]} {
 
1124
                incr spurious
 
1125
            } else {
 
1126
                close $s
 
1127
                set done 1
 
1128
            }
 
1129
        } else {
 
1130
            incr len [string length $l]
 
1131
        }
 
1132
    }
 
1133
    proc accept {s a p} {
 
1134
        fconfigure $s -blocking 0
 
1135
        fileevent $s readable [list do_handshake $s readable readlittle \
 
1136
                -buffering none]
 
1137
    }
 
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
 
1148
    close $c
 
1149
    set timer [after 10000 "set done timed_out"]
 
1150
    vwait done
 
1151
    after cancel $timer
 
1152
    close $s
 
1153
    list $spurious $len
 
1154
} {0 50}
 
1155
 
 
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]
 
1163
    }
 
1164
    proc readable {s} {
 
1165
        set l [gets $s]
 
1166
        dputs "got \"[string replace $l 10 end-3 ...]\" \
 
1167
                ([string length $l]) from $s"
 
1168
        fileevent $s readable {}
 
1169
        after 1000 respond $s
 
1170
    }
 
1171
    proc respond {s} {
 
1172
        global firstblock
 
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
 
1177
    }
 
1178
    proc writedata {s} {
 
1179
        global secondblock
 
1180
        dputs "send \"[string replace $secondblock 10 end-3 ...]\" \
 
1181
                ([string length $secondblock]) down $s"
 
1182
        puts -nonewline $s $secondblock
 
1183
        close $s
 
1184
    }
 
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
 
1192
    set count 0
 
1193
    puts $c hello
 
1194
    proc readit {s} {
 
1195
        global count done
 
1196
        set data [read $s]
 
1197
        dputs "read \"[string replace $data 10 end-3 ...]\" \
 
1198
                ([string length $data]) from $s"
 
1199
        incr count [string length $data]
 
1200
        if {[eof $s]} {
 
1201
            close $s
 
1202
            set done 1
 
1203
        }
 
1204
    }
 
1205
    fileevent $c readable "readit $c"
 
1206
    set done 0
 
1207
    set timer [after 10000 "set done timed_out"]
 
1208
    vwait done
 
1209
    after cancel $timer
 
1210
    close $s
 
1211
    list $count $done
 
1212
} {65566 1}
 
1213
 
 
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
 
1218
        set l [gets $s]
 
1219
        if {[eof $s]} {
 
1220
            incr count
 
1221
            if {$count > 9} {
 
1222
                close $s
 
1223
                set done true
 
1224
                set count {eof is sticky}
 
1225
                after cancel $timer
 
1226
            }
 
1227
        }
 
1228
    }
 
1229
    proc timerproc {} {
 
1230
        global done count c
 
1231
        set done true
 
1232
        set count {timer went off, eof is not sticky}
 
1233
        close $c
 
1234
    }   
 
1235
    set count 0
 
1236
    set done false
 
1237
    proc write_then_close {s} {
 
1238
        puts $s bye
 
1239
        close $s
 
1240
    }
 
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]
 
1245
    }
 
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]
 
1255
    vwait done
 
1256
    close $s
 
1257
    set count
 
1258
} {eof is sticky}
 
1259
 
 
1260
removeFile script
 
1261
 
 
1262
test tlsIO-10.1 {testing socket accept callback error handling} {socket} {
 
1263
    set goterror 0
 
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]
 
1268
    vwait goterror
 
1269
    close $s
 
1270
    close $c
 
1271
    set goterror
 
1272
} 1
 
1273
 
 
1274
test tlsIO-11.1 {tcp connection} {socket doTestsWithRemoteServer} {
 
1275
    sendCertValues
 
1276
    sendCommand {
 
1277
        set socket9_1_test_server [tls::socket -server accept \
 
1278
                -certfile $serverCert -cafile $caCert -keyfile $serverKey 8834]
 
1279
        proc accept {s a p} {
 
1280
            tls::handshake $s
 
1281
            puts $s done
 
1282
            close $s
 
1283
        }
 
1284
    }
 
1285
    set s [tls::socket \
 
1286
            -certfile $clientCert -cafile $caCert -keyfile $clientKey \
 
1287
            $remoteServerIP 8834]
 
1288
    set r [gets $s]
 
1289
    close $s
 
1290
    sendCommand {close $socket9_1_test_server}
 
1291
    set r
 
1292
} done
 
1293
 
 
1294
test tlsIO-11.2 {client specifies its port} {socket doTestsWithRemoteServer} {
 
1295
    if {[info exists port]} {
 
1296
        incr port
 
1297
    } else {
 
1298
        set port [expr {$tlsServerPort + [pid]%1024}]
 
1299
    }
 
1300
    sendCertValues
 
1301
    sendCommand {
 
1302
        set socket9_2_test_server [tls::socket -server accept \
 
1303
                -certfile $serverCert -cafile $caCert -keyfile $serverKey 8835]
 
1304
        proc accept {s a p} {
 
1305
            tls::handshake $s
 
1306
            puts $s $p
 
1307
            close $s
 
1308
        }
 
1309
    }
 
1310
    set s [tls::socket \
 
1311
            -certfile $clientCert -cafile $caCert -keyfile $clientKey \
 
1312
            -myport $port $remoteServerIP 8835]
 
1313
    set r [gets $s]
 
1314
    close $s
 
1315
    sendCommand {close $socket9_2_test_server}
 
1316
    if {$r == $port} {
 
1317
        set result ok
 
1318
    } else {
 
1319
        set result broken
 
1320
    }
 
1321
    set result
 
1322
} ok
 
1323
 
 
1324
test tlsIO-11.3 {trying to connect, no server} {socket doTestsWithRemoteServer} {
 
1325
    set status ok
 
1326
    if {![catch {set s [tls::socket \
 
1327
            -certfile $clientCert -cafile $caCert -keyfile $clientKey \
 
1328
            $remoteServerIp 8836]}]} {
 
1329
        if {![catch {gets $s}]} {
 
1330
            set status broken
 
1331
        }
 
1332
        close $s
 
1333
    }
 
1334
    set status
 
1335
} ok
 
1336
 
 
1337
test tlsIO-11.4 {remote echo, one line} {socket doTestsWithRemoteServer} {
 
1338
    sendCertValues
 
1339
    sendCommand {
 
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} {
 
1344
            tls::handshake $s
 
1345
            fileevent $s readable [list echo $s]
 
1346
            fconfigure $s -buffering line -translation crlf
 
1347
        }
 
1348
        proc echo {s} {
 
1349
            set l [gets $s]
 
1350
            if {[eof $s]} {
 
1351
                close $s
 
1352
            } else {
 
1353
                puts $s $l
 
1354
            }
 
1355
        }
 
1356
    }
 
1357
    set f [tls::socket \
 
1358
            -certfile $clientCert -cafile $caCert -keyfile $clientKey \
 
1359
            $remoteServerIP 8836]
 
1360
    fconfigure $f -translation crlf -buffering line
 
1361
    puts $f hello
 
1362
    set r [gets $f]
 
1363
    close $f
 
1364
    sendCommand {close $socket10_6_test_server}
 
1365
    set r
 
1366
} hello
 
1367
 
 
1368
test tlsIO-11.5 {remote echo, 50 lines} {socket doTestsWithRemoteServer} {
 
1369
    sendCertValues
 
1370
    sendCommand {
 
1371
        set socket10_7_test_server [tls::socket -server accept \
 
1372
                -certfile $serverCert -cafile $caCert -keyfile $serverKey 8836]
 
1373
        proc accept {s a p} {
 
1374
            tls::handshake $s
 
1375
            fileevent $s readable [list echo $s]
 
1376
            fconfigure $s -buffering line -translation crlf
 
1377
        }
 
1378
        proc echo {s} {
 
1379
            set l [gets $s]
 
1380
            if {[eof $s]} {
 
1381
                close $s
 
1382
            } else {
 
1383
                puts $s $l
 
1384
            }
 
1385
        }
 
1386
    }
 
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} {
 
1394
            break
 
1395
        }
 
1396
    }
 
1397
    close $f
 
1398
    sendCommand {close $socket10_7_test_server}
 
1399
    set cnt
 
1400
} 50
 
1401
 
 
1402
# Macintosh sockets can have more than one server per port
 
1403
if {$tcl_platform(platform) == "macintosh"} {
 
1404
    set conflictResult {0 8836}
 
1405
} else {
 
1406
    set conflictResult {1 {couldn't open socket: address already in use}}
 
1407
}
 
1408
 
 
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]
 
1417
    } else {
 
1418
        set result [list 0 [lindex [fconfigure $s2 -sockname] 2]]
 
1419
        close $s2
 
1420
    }
 
1421
    close $s1
 
1422
    set result
 
1423
} $conflictResult
 
1424
 
 
1425
test tlsIO-11.7 {server with several clients} {socket doTestsWithRemoteServer} {
 
1426
    sendCertValues
 
1427
    sendCommand {
 
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]
 
1434
        }
 
1435
        proc echo {s} {
 
1436
            set l [gets $s]
 
1437
            if {[eof $s]} {
 
1438
                close $s
 
1439
            } else {
 
1440
                puts $s $l
 
1441
            }
 
1442
        }
 
1443
    }
 
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} {
 
1457
        puts $s1 hello,s1
 
1458
        gets $s1
 
1459
        puts $s2 hello,s2
 
1460
        gets $s2
 
1461
        puts $s3 hello,s3
 
1462
        gets $s3
 
1463
    }
 
1464
    close $s1
 
1465
    close $s2
 
1466
    close $s3
 
1467
    sendCommand {close $socket10_9_test_server}
 
1468
    set i
 
1469
} 100    
 
1470
 
 
1471
test tlsIO-11.8 {client with several servers} {socket doTestsWithRemoteServer} {
 
1472
    sendCertValues
 
1473
    sendCommand {
 
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} {
 
1479
            if {[eof $s]} {
 
1480
                close $s
 
1481
            } elseif {[catch {tls::handshake $s} result]} {
 
1482
                # Some errors are normal.
 
1483
            } elseif {$result == 1} {
 
1484
                # Handshake complete
 
1485
                fileevent $s readable ""
 
1486
                puts $s $mp
 
1487
                close $s
 
1488
            }
 
1489
        }
 
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]
 
1495
        }
 
1496
    }
 
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]
 
1501
    set l ""
 
1502
    lappend l [gets $s1] [gets $s1] [eof $s1] [gets $s2] [gets $s2] [eof $s2] \
 
1503
        [gets $s3] [gets $s3] [eof $s3]
 
1504
    close $s1
 
1505
    close $s2
 
1506
    close $s3
 
1507
    sendCommand {
 
1508
        close $s1
 
1509
        close $s2
 
1510
        close $s3
 
1511
    }
 
1512
    set l
 
1513
} {4003 {} 1 4004 {} 1 4005 {} 1}
 
1514
 
 
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}
 
1520
    proc bgerror args {
 
1521
        global x
 
1522
        set x $args
 
1523
    }
 
1524
    sendCertValues
 
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]
 
1530
            close $s
 
1531
         }} msg]} {
 
1532
        close $s
 
1533
        error $msg
 
1534
    }
 
1535
    set timer [after 10000 "set x timed_out"]
 
1536
    vwait x
 
1537
    after cancel $timer
 
1538
    close $s
 
1539
    rename bgerror {}
 
1540
    set x
 
1541
} {{divide by zero}}
 
1542
 
 
1543
test tlsIO-11.10 {testing socket specific options} {socket doTestsWithRemoteServer} {
 
1544
    sendCertValues
 
1545
    sendCommand {
 
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}
 
1550
    }
 
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]
 
1556
    set l ""
 
1557
    lappend l [lindex $p 2] [llength $p] [llength $p]
 
1558
    close $s
 
1559
    sendCommand {close $socket10_12_test_server}
 
1560
    set l
 
1561
} {8836 3 3}
 
1562
 
 
1563
test tlsIO-11.11 {testing spurious events} {socket doTestsWithRemoteServer} {
 
1564
    # remote equivalent of 9.1
 
1565
    sendCertValues
 
1566
    sendCommand {
 
1567
        set socket_test_server [tls::socket -server accept \
 
1568
                -certfile $serverCert -cafile $caCert -keyfile $serverKey 8836]
 
1569
        proc handshake {s} {
 
1570
            if {[eof $s]} {
 
1571
                close $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
 
1578
            }
 
1579
        }
 
1580
        proc accept {s a p} {
 
1581
            fconfigure $s -translation "auto lf"
 
1582
            fileevent $s writable [list handshake $s]
 
1583
        }
 
1584
        proc writesome {s} {
 
1585
            for {set i 0} {$i < 100} {incr i} {
 
1586
                puts $s "line $i from remote server"
 
1587
            }
 
1588
            close $s
 
1589
        }
 
1590
    }
 
1591
    set len 0
 
1592
    set spurious 0
 
1593
    set done 0
 
1594
    proc readlittle {s} {
 
1595
        global spurious done len
 
1596
        set l [read $s 1]
 
1597
        if {[string length $l] == 0} {
 
1598
            if {![eof $s]} {
 
1599
                incr spurious
 
1600
            } else {
 
1601
                close $s
 
1602
                set done 1
 
1603
            }
 
1604
        } else {
 
1605
            incr len [string length $l]
 
1606
        }
 
1607
    }
 
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
 
1614
    puts $c a
 
1615
    fileevent $c readable [list readlittle $c]
 
1616
    set timer [after 10000 "set done timed_out"]
 
1617
    vwait done
 
1618
    after cancel $timer
 
1619
    sendCommand {close $socket_test_server}
 
1620
    list $spurious $len
 
1621
} {0 2690}
 
1622
 
 
1623
test tlsIO-11.12 {testing EOF stickyness} {unexplainedFailure socket doTestsWithRemoteServer} {
 
1624
    # remote equivalent of 9.3
 
1625
    # HOBBS: never worked correctly
 
1626
    set counter 0
 
1627
    set done 0
 
1628
    proc count_up {s} {
 
1629
        global counter done after_id
 
1630
        set l [gets $s]
 
1631
        if {[eof $s]} {
 
1632
            incr counter
 
1633
            if {$counter > 9} {
 
1634
                set done {EOF is sticky}
 
1635
                after cancel $after_id
 
1636
                close $s
 
1637
            }
 
1638
        }
 
1639
    }
 
1640
    proc timed_out {} {
 
1641
        global c done
 
1642
        set done {timed_out, EOF is not sticky}
 
1643
        close $c
 
1644
    }
 
1645
    sendCertValues
 
1646
    sendCommand {
 
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} {
 
1651
            tls::handshake $s
 
1652
            after 100 close $s
 
1653
        }
 
1654
    }
 
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]
 
1660
    vwait done
 
1661
    sendCommand {close $socket10_14_test_server}
 
1662
    set done
 
1663
} {EOF is sticky}
 
1664
 
 
1665
test tlsIO-11.13 {testing async write, async flush, async close} \
 
1666
        {socket doTestsWithRemoteServer} {
 
1667
    proc readit {s} {
 
1668
        global count done
 
1669
        set l [read $s]
 
1670
        incr count [string length $l]
 
1671
        if {[eof $s]} {
 
1672
            close $s
 
1673
            set done 1
 
1674
        }
 
1675
    }
 
1676
    sendCertValues
 
1677
    sendCommand {
 
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} {
 
1684
            tls::handshake $s
 
1685
            fconfigure $s -blocking 0 -translation lf -buffersize 16384 \
 
1686
                    -buffering line
 
1687
            fileevent $s readable "readable $s"
 
1688
        }
 
1689
        proc readable {s} {
 
1690
            set l [gets $s]
 
1691
            fileevent $s readable {}
 
1692
            after 1000 respond $s
 
1693
        }
 
1694
        proc respond {s} {
 
1695
            global firstblock
 
1696
            puts -nonewline $s $firstblock
 
1697
            after 1000 writedata $s
 
1698
        }
 
1699
        proc writedata {s} {
 
1700
            global secondblock
 
1701
            puts -nonewline $s $secondblock
 
1702
            close $s
 
1703
        }
 
1704
    }
 
1705
    set s [tls::socket \
 
1706
            -certfile $clientCert -cafile $caCert -keyfile $clientKey \
 
1707
            $remoteServerIP 8845]
 
1708
    fconfigure $s -blocking 0 -translation lf -buffering line
 
1709
    set count 0
 
1710
    puts $s hello
 
1711
    fileevent $s readable "readit $s"
 
1712
    set timer [after 10000 "set done timed_out"]
 
1713
    vwait done
 
1714
    after cancel $timer
 
1715
    sendCommand {close $l}
 
1716
    set count
 
1717
} 65566
 
1718
 
 
1719
proc getdata {type file} {
 
1720
    # Read handler on the accepted socket.
 
1721
    global x
 
1722
    global failed
 
1723
    set status [catch {read $file} data]
 
1724
    if {$status != 0} {
 
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]} {
 
1730
        if {$failed} {
 
1731
            set x "$type socket was inherited"
 
1732
        } else {
 
1733
            set x "$type socket was not inherited"
 
1734
        }
 
1735
        catch { close $file }
 
1736
    } else {
 
1737
        set x {impossible case}
 
1738
        catch { close $file }
 
1739
    }
 
1740
    return
 
1741
}
 
1742
 
 
1743
test tlsIO-12.1 {testing inheritance of server sockets} {socket exec} {
 
1744
    makeFile {} script1
 
1745
    makeFile {} script2
 
1746
 
 
1747
    # Script1 is just a 10 second delay.  If the server socket
 
1748
    # is inherited, it will be held open for 10 seconds
 
1749
 
 
1750
    set f [open script1 w]
 
1751
    puts $f {
 
1752
        after 10000 exit
 
1753
        vwait forever
 
1754
    }
 
1755
    close $f
 
1756
 
 
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.
 
1760
 
 
1761
    set f [open script2 w]
 
1762
    puts $f [list set tclsh $::tcltest::tcltest]
 
1763
    puts $f {
 
1764
        set auto_path [linsert $auto_path 0 [lindex [split $env(PATH) ";:"] 0]]
 
1765
        package require tls
 
1766
    }
 
1767
    puts $f "set f \[tls::socket -server accept \
 
1768
            -certfile $serverCert -cafile $caCert -keyfile $serverKey 8828\]"
 
1769
    puts $f {
 
1770
        proc accept { file addr port } {
 
1771
            close $file
 
1772
        }
 
1773
        exec $tclsh script1 &
 
1774
        close $f
 
1775
        after 1000 exit
 
1776
        vwait forever
 
1777
    }
 
1778
    close $f
 
1779
        
 
1780
    # Launch script2 and wait 5 seconds
 
1781
 
 
1782
    exec $::tcltest::tcltest script2 &
 
1783
    after 5000 { set ok_to_proceed 1 }
 
1784
    vwait ok_to_proceed
 
1785
 
 
1786
    # If we can still connect to the server, the socket got inherited.
 
1787
 
 
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}
 
1792
    } else {
 
1793
        close $msg
 
1794
        set x {server socket was inherited}
 
1795
    }
 
1796
 
 
1797
    set x
 
1798
} {server socket was not inherited}
 
1799
 
 
1800
test tlsIO-12.2 {testing inheritance of client sockets} {socket exec} {
 
1801
    makeFile {} script1
 
1802
    makeFile {} script2
 
1803
 
 
1804
    # Script1 is just a 10 second delay.  If the server socket
 
1805
    # is inherited, it will be held open for 10 seconds
 
1806
 
 
1807
    set f [open script1 w]
 
1808
    puts $f {
 
1809
        after 10000 exit
 
1810
        vwait forever
 
1811
    }
 
1812
    close $f
 
1813
 
 
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.
 
1817
 
 
1818
    set f [open script2 w]
 
1819
    puts $f [list set tclsh $::tcltest::tcltest]
 
1820
    puts $f {
 
1821
        set auto_path [linsert $auto_path 0 [lindex [split $env(PATH) ";:"] 0]]
 
1822
        package require tls
 
1823
    }
 
1824
    puts $f "set f \[tls::socket -certfile $clientCert -cafile $caCert \
 
1825
            -keyfile $clientKey 127.0.0.1 8829\]"
 
1826
    puts $f {
 
1827
        exec $tclsh script1 &
 
1828
        puts $f testing
 
1829
        flush $f
 
1830
        after 1000 exit
 
1831
        vwait forever
 
1832
    }
 
1833
    close $f
 
1834
 
 
1835
    # Create the server socket
 
1836
 
 
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
 
1842
        global server
 
1843
        close $server
 
1844
        fconfigure $file -blocking 0
 
1845
        fileevent $file readable [list do_handshake $file readable \
 
1846
                [list getdata client] -buffering line]
 
1847
        return
 
1848
    }
 
1849
 
 
1850
    # If the socket doesn't hit end-of-file in 5 seconds, the
 
1851
    # script1 process must have inherited the client.
 
1852
 
 
1853
    set failed 0
 
1854
    after 5000 [list set failed 1]
 
1855
 
 
1856
    # Launch the script2 process
 
1857
 
 
1858
    exec $::tcltest::tcltest script2 &
 
1859
 
 
1860
    vwait x
 
1861
    if {!$failed} {
 
1862
        vwait failed
 
1863
    }
 
1864
    set x
 
1865
} {client socket was not inherited}
 
1866
 
 
1867
test tlsIO-12.3 {testing inheritance of accepted sockets} \
 
1868
        {socket exec unixOnly} {
 
1869
    makeFile {} script1
 
1870
    makeFile {} script2
 
1871
 
 
1872
    set f [open script1 w]
 
1873
    puts $f {
 
1874
        after 10000 exit
 
1875
        vwait forever
 
1876
    }
 
1877
    close $f
 
1878
 
 
1879
    set f [open script2 w]
 
1880
    puts $f [list set tclsh $::tcltest::tcltest]
 
1881
    puts $f {
 
1882
        set auto_path [linsert $auto_path 0 [lindex [split $env(PATH) ";:"] 0]]
 
1883
        package require tls
 
1884
    }
 
1885
    puts $f "set f \[tls::socket -server accept \
 
1886
            -certfile $serverCert -cafile $caCert -keyfile $serverKey 8930\]"
 
1887
    puts $f {
 
1888
        proc accept { file host port } {
 
1889
            global tclsh
 
1890
            fconfigure $file -buffering line
 
1891
            puts $file {test data on socket}
 
1892
            exec $tclsh script1 &
 
1893
            after 1000 exit
 
1894
        }
 
1895
        vwait forever
 
1896
    }
 
1897
    close $f
 
1898
 
 
1899
    # Launch the script2 process and connect to it.  See how long
 
1900
    # the socket stays open
 
1901
 
 
1902
    exec $::tcltest::tcltest script2 &
 
1903
 
 
1904
    after 2000 set ok_to_proceed 1
 
1905
    vwait ok_to_proceed
 
1906
 
 
1907
    set f [tls::socket \
 
1908
            -certfile $clientCert -cafile $caCert -keyfile $clientKey \
 
1909
            127.0.0.1 8930]
 
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
 
1913
    puts $f a; flush $f
 
1914
    fileevent $f readable [list getdata accepted $f]
 
1915
 
 
1916
    # If the socket is still open after 5 seconds, the script1 process
 
1917
    # must have inherited the accepted socket.
 
1918
 
 
1919
    set failed 0
 
1920
    after 5000 set failed 1
 
1921
 
 
1922
    vwait x
 
1923
    set x
 
1924
} {accepted socket was not inherited}
 
1925
 
 
1926
test tlsIO-13.1 {Testing use of shared socket between two threads} \
 
1927
        {socket testthread} {
 
1928
    # HOBBS: never tested
 
1929
    removeFile script
 
1930
    threadReap
 
1931
 
 
1932
    makeFile {
 
1933
        set auto_path [linsert $auto_path 0 [lindex [split $env(PATH) ";:"] 0]]
 
1934
        package require tls
 
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
 
1939
        }
 
1940
        proc echo {s} {
 
1941
             global i
 
1942
             set l [gets $s]
 
1943
             if {[eof $s]} {
 
1944
                 global x
 
1945
                 close $s
 
1946
                 set x done
 
1947
             } else { 
 
1948
                 incr i
 
1949
                 puts $s $l
 
1950
             }
 
1951
        }
 
1952
        set i 0
 
1953
        vwait x
 
1954
        close $f
 
1955
 
 
1956
        # thread cleans itself up.
 
1957
        testthread exit
 
1958
    } script
 
1959
    
 
1960
    # create a thread
 
1961
    set serverthread [testthread create { source script } ]
 
1962
    update
 
1963
    
 
1964
    after 1000
 
1965
    set s [tls::socket 127.0.0.1 8828]
 
1966
    fconfigure $s -buffering line
 
1967
 
 
1968
    catch {
 
1969
        puts $s "hello"
 
1970
        gets $s result
 
1971
    }
 
1972
    close $s
 
1973
    update
 
1974
 
 
1975
    after 2000
 
1976
    lappend result [threadReap]
 
1977
    
 
1978
    set result
 
1979
 
 
1980
} {hello 1}
 
1981
 
 
1982
# cleanup
 
1983
if {[string match sock* $commandSocket] == 1} {
 
1984
   puts $commandSocket exit
 
1985
   flush $commandSocket
 
1986
}
 
1987
catch {close $commandSocket}
 
1988
catch {close $remoteProcChan}
 
1989
::tcltest::cleanupTests
 
1990
flush stdout
 
1991
return