summaryrefslogtreecommitdiffstats
path: root/tls/tests
diff options
context:
space:
mode:
authorWilliam Joye <wjoye@cfa.harvard.edu>2019-01-03 17:00:00 (GMT)
committerWilliam Joye <wjoye@cfa.harvard.edu>2019-01-03 17:00:00 (GMT)
commit68fa646bdcb53bfe8ec99f39e951bca5160cd9d6 (patch)
treec0b5a34c8133eac42398916fd1a74577d88071c1 /tls/tests
parent647e9b1a5bcfafcb6c4545e2e4fb43cf93ef1ef6 (diff)
parent15cf84c34642af290d1fdf16011f9290c941fa13 (diff)
downloadblt-68fa646bdcb53bfe8ec99f39e951bca5160cd9d6.zip
blt-68fa646bdcb53bfe8ec99f39e951bca5160cd9d6.tar.gz
blt-68fa646bdcb53bfe8ec99f39e951bca5160cd9d6.tar.bz2
Merge commit '15cf84c34642af290d1fdf16011f9290c941fa13' as 'tls'
Diffstat (limited to 'tls/tests')
-rw-r--r--tls/tests/all.tcl56
-rw-r--r--tls/tests/certs/README.txt9
-rw-r--r--tls/tests/certs/ca.pem18
-rw-r--r--tls/tests/certs/client.key15
-rw-r--r--tls/tests/certs/client.pem14
-rw-r--r--tls/tests/certs/client.req11
-rw-r--r--tls/tests/certs/file.srl1
-rw-r--r--tls/tests/certs/privkey.pem18
-rw-r--r--tls/tests/certs/server.key15
-rw-r--r--tls/tests/certs/server.pem14
-rw-r--r--tls/tests/certs/server.req11
-rw-r--r--tls/tests/ciphers.test159
-rw-r--r--tls/tests/keytest1.tcl23
-rw-r--r--tls/tests/keytest2.tcl8
-rwxr-xr-xtls/tests/remote.tcl185
-rwxr-xr-xtls/tests/simpleClient.tcl113
-rwxr-xr-xtls/tests/simpleServer.tcl90
-rwxr-xr-xtls/tests/tlsIO.test2072
18 files changed, 2832 insertions, 0 deletions
diff --git a/tls/tests/all.tcl b/tls/tests/all.tcl
new file mode 100644
index 0000000..aeb37a8
--- /dev/null
+++ b/tls/tests/all.tcl
@@ -0,0 +1,56 @@
+# all.tcl --
+#
+# This file contains a top-level script to run all of the Tcl
+# tests. Execute it by invoking "source all.test" when running tcltest
+# in this directory.
+#
+# Copyright (c) 1998-2000 by Ajuba Solutions.
+# All rights reserved.
+#
+# RCS: @(#) $Id: all.tcl,v 1.5 2000/08/15 18:45:01 hobbs Exp $
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import ::tcltest::*
+}
+
+set ::tcltest::testSingleFile false
+set ::tcltest::testsDirectory [file dir [info script]]
+
+# We should ensure that the testsDirectory is absolute.
+# This was introduced in Tcl 8.3+'s tcltest, so we need a catch.
+catch {::tcltest::normalizePath ::tcltest::testsDirectory}
+
+puts stdout "Tests running in interp: [info nameofexecutable]"
+puts stdout "Tests running in working dir: $::tcltest::testsDirectory"
+if {[llength $::tcltest::skip] > 0} {
+ puts stdout "Skipping tests that match: $::tcltest::skip"
+}
+if {[llength $::tcltest::match] > 0} {
+ puts stdout "Only running tests that match: $::tcltest::match"
+}
+
+if {[llength $::tcltest::skipFiles] > 0} {
+ puts stdout "Skipping test files that match: $::tcltest::skipFiles"
+}
+if {[llength $::tcltest::matchFiles] > 0} {
+ puts stdout "Only sourcing test files that match: $::tcltest::matchFiles"
+}
+
+set timeCmd {clock format [clock seconds]}
+puts stdout "Tests began at [eval $timeCmd]"
+
+# source each of the specified tests
+foreach file [lsort [::tcltest::getMatchingFiles]] {
+ set tail [file tail $file]
+ puts stdout $tail
+ if {[catch {source $file} msg]} {
+ puts stdout $msg
+ }
+}
+
+# cleanup
+puts stdout "\nTests ended at [eval $timeCmd]"
+::tcltest::cleanupTests 1
+return
+
diff --git a/tls/tests/certs/README.txt b/tls/tests/certs/README.txt
new file mode 100644
index 0000000..74beaa9
--- /dev/null
+++ b/tls/tests/certs/README.txt
@@ -0,0 +1,9 @@
+These files were generated with openssl v0.9.6a-engine based on the
+instructions at http://www-itg.lbl.gov/~boverhof/openssl_certs.html.
+The file names match the examples used above.
+
+The PEM password is 'sample' with the basic CA info being:
+
+subject=/C=CA/ST=British Columbia/L=Vancouver/O=Sample Certs Intl
+
+These are for testing use only.
diff --git a/tls/tests/certs/ca.pem b/tls/tests/certs/ca.pem
new file mode 100644
index 0000000..b64683d
--- /dev/null
+++ b/tls/tests/certs/ca.pem
@@ -0,0 +1,18 @@
+-----BEGIN CERTIFICATE-----
+MIIC2jCCAkOgAwIBAgIBADANBgkqhkiG9w0BAQQFADBYMQswCQYDVQQGEwJDQTEZ
+MBcGA1UECBMQQnJpdGlzaCBDb2x1bWJpYTESMBAGA1UEBxMJVmFuY291dmVyMRow
+GAYDVQQKExFTYW1wbGUgQ2VydHMgSW50bDAeFw0wMTA2MjEyMDI2MDRaFw0wMTA3
+MjEyMDI2MDRaMFgxCzAJBgNVBAYTAkNBMRkwFwYDVQQIExBCcml0aXNoIENvbHVt
+YmlhMRIwEAYDVQQHEwlWYW5jb3V2ZXIxGjAYBgNVBAoTEVNhbXBsZSBDZXJ0cyBJ
+bnRsMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDJeHe1yfuw7YCx6nZ4hcyl
+qe1JgOXSMqAzHwfHf/EdGtQUhsfsmgx9cZCKgtuZaoRKidl60MFeW2zq12ORuPUB
+w90mQh46KDPRNWm1jViI/xmKUY+so6F5P/c6aA0QYqcpDhM7GgMvaAbEuY70gQ0l
+uhxMv75mKMWC4RuzFyVVjwIDAQABo4GzMIGwMB0GA1UdDgQWBBTwwtcIvZ/wpImV
+VC/e3C/I9qXWVTCBgAYDVR0jBHkwd4AU8MLXCL2f8KSJlVQv3twvyPal1lWhXKRa
+MFgxCzAJBgNVBAYTAkNBMRkwFwYDVQQIExBCcml0aXNoIENvbHVtYmlhMRIwEAYD
+VQQHEwlWYW5jb3V2ZXIxGjAYBgNVBAoTEVNhbXBsZSBDZXJ0cyBJbnRsggEAMAwG
+A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEANprDWDEI9/UUkIL4kxvK8Woy
+akWYabFR3s2RnxwCMDi0d7eKh+8k+NHLjD1FnWt9VNmub3sd8+PdTMk41PlLfroG
+lCAd31HnYqoi498ivgpczwFj3BQSssmhld+aCFyE83KVIeMuP55fcp44vxQuEmcn
+EWnH66cMUxI1D3jcQWE=
+-----END CERTIFICATE-----
diff --git a/tls/tests/certs/client.key b/tls/tests/certs/client.key
new file mode 100644
index 0000000..6c27df7
--- /dev/null
+++ b/tls/tests/certs/client.key
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXgIBAAKBgQDByy+QiN7Gde+Pf6Wvjk4OZlXfbV68mzmLh/xrXIdGQL5KqRhi
+ydUZSUU87TZ/poZAFGA8kds0pmD1TWy4lGiJjoU5pxeIvl8d08Sqbh6Srxv1CKJm
+J7RIp4RvEpviOSaDUC0wkLMvAAaAu2ZpNEncsotV4eSaE/WhvCHamBjpSwIDAQAB
+AoGAP0q48h+Bgpep8dfiqP91BsbtbNcvhbG8jZGQIxBJLeyfOYsYZ8s7SdLgRhHD
+JtWgKvV8qMuKKBvetr7erznpGdHcDDw1wutL2PagET756BjAtxcZ0lEx129eXThH
+10+09QEbSlO9XRd1OvAdLCb80H97+jZXMVJ6eb/uMuVzUMECQQDzikOjJLK678fa
+haesVYBqmsFAihGIUK+7Ki1F8wS6/oKLHWKDdFYoI/3Zve0qdFGFdvZicFqLAjKl
+QOXxBGrpAkEAy7Vf1nmp8FAj2p1/0383EuIhjmMjQw2SHYMbTaCwbnYGJrPoeMwE
+dwaaWwfgmXFeoc6lzBRUeDVz2EE6EyzqEwJBAO9XR4eSrlAHDFsWlSVJVg3ujtO1
+nOthmIKRPbML1O9M5tB/DWzxLSb/0B9ohyb8740Bz7wIfQM2Ir3DXPeThtkCQQDH
+zSYrHznnUzNXgZOWxfgmtVVkayhy5CSkfauSAEIMlgaCf4NMuA7JD9jl4FwTJHdF
+DYLhIC+ZmBP/0Do+BJexAkEAjrF928xMKcsrVmr7zlEhl+4B75kDkXm8TDV42PQI
+WzmYuHZHwWZApU42VVlWEToIog2s0RVBOyHdiQsNwrL6Rw==
+-----END RSA PRIVATE KEY-----
diff --git a/tls/tests/certs/client.pem b/tls/tests/certs/client.pem
new file mode 100644
index 0000000..4dcafe4
--- /dev/null
+++ b/tls/tests/certs/client.pem
@@ -0,0 +1,14 @@
+-----BEGIN CERTIFICATE-----
+MIICHzCCAYgCAQEwDQYJKoZIhvcNAQEEBQAwWDELMAkGA1UEBhMCQ0ExGTAXBgNV
+BAgTEEJyaXRpc2ggQ29sdW1iaWExEjAQBgNVBAcTCVZhbmNvdXZlcjEaMBgGA1UE
+ChMRU2FtcGxlIENlcnRzIEludGwwHhcNMDEwNjIxMjAyOTU4WhcNMDEwNzIxMjAy
+OTU4WjBYMQswCQYDVQQGEwJDQTEZMBcGA1UECBMQQnJpdGlzaCBDb2x1bWJpYTES
+MBAGA1UEBxMJVmFuY291dmVyMRowGAYDVQQKExFTYW1wbGUgQ2VydHMgSW50bDCB
+nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwcsvkIjexnXvj3+lr45ODmZV321e
+vJs5i4f8a1yHRkC+SqkYYsnVGUlFPO02f6aGQBRgPJHbNKZg9U1suJRoiY6FOacX
+iL5fHdPEqm4ekq8b9QiiZie0SKeEbxKb4jkmg1AtMJCzLwAGgLtmaTRJ3LKLVeHk
+mhP1obwh2pgY6UsCAwEAATANBgkqhkiG9w0BAQQFAAOBgQC9llXASadBxwkaEIZ7
+bmCYMWIB6+jjxa0YCY2jYgqCslny/bkLgIuxIcxf83ouFfXU52r/mq04jfuRfyRt
+zCT8C+Z9nhKHdHA0cVYJ+tNuZfssQ+cFHUfjDOsCEFTJ1OoooafnIHpPXub1FcYr
+SCLdcK0BwPbCcJUZrIHwu3Nu7g==
+-----END CERTIFICATE-----
diff --git a/tls/tests/certs/client.req b/tls/tests/certs/client.req
new file mode 100644
index 0000000..2bdc56e
--- /dev/null
+++ b/tls/tests/certs/client.req
@@ -0,0 +1,11 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIIBmDCCAQECAQAwWDELMAkGA1UEBhMCQ0ExGTAXBgNVBAgTEEJyaXRpc2ggQ29s
+dW1iaWExEjAQBgNVBAcTCVZhbmNvdXZlcjEaMBgGA1UEChMRU2FtcGxlIENlcnRz
+IEludGwwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMHLL5CI3sZ1749/pa+O
+Tg5mVd9tXrybOYuH/Gtch0ZAvkqpGGLJ1RlJRTztNn+mhkAUYDyR2zSmYPVNbLiU
+aImOhTmnF4i+Xx3TxKpuHpKvG/UIomYntEinhG8Sm+I5JoNQLTCQsy8ABoC7Zmk0
+Sdyyi1Xh5JoT9aG8IdqYGOlLAgMBAAGgADANBgkqhkiG9w0BAQQFAAOBgQB8xq+d
+On5JqJBZcc9rW70jmSU7AlSZ48UQlmNmlUSj4YznWUCbDawEfHWv0Xpfho+bio+L
+hFuzt0WsotTW1sboFpG3csHyCpGmIxw5Lacv2x5+dDx0jRbyI426+CUn+ZPv5pv8
+iiVrlyiX2P3jifQjhv39Kgbs5cOr/Ic8KKz5rg==
+-----END CERTIFICATE REQUEST-----
diff --git a/tls/tests/certs/file.srl b/tls/tests/certs/file.srl
new file mode 100644
index 0000000..9e22bcb
--- /dev/null
+++ b/tls/tests/certs/file.srl
@@ -0,0 +1 @@
+02
diff --git a/tls/tests/certs/privkey.pem b/tls/tests/certs/privkey.pem
new file mode 100644
index 0000000..423b9ed
--- /dev/null
+++ b/tls/tests/certs/privkey.pem
@@ -0,0 +1,18 @@
+-----BEGIN RSA PRIVATE KEY-----
+Proc-Type: 4,ENCRYPTED
+DEK-Info: DES-EDE3-CBC,E5670F088D470CF8
+
+j53yMhP9QC8ZElMlyTENZ9rI6mq9hjQepTGBhku8W0JuGIDSQTbDieGNJ7myTLEo
+AckDGFndIPMJFxz3GU2OYZ40sZE7CL6lkc5JsgSvt2QEp5qK30l9Ij6NnXN/BfpQ
+ETliDPzDNWD0ILM43C2J/sNwgwu2SgAMj7BIn2adNuT5AN1nNXdxUg+tbGrEeH39
+eiHKTBRS+40t6KMxW1ftl85zl6WRSRM+3/URdNKUbVq0DQmpFpXT1XcKGxv4GVao
+X4jyj6pE5L610cIiT3vy0qK3B3UKsQNOE8Z7aTV9eKvGk7F4LVSQpFz+DDgv/nLb
+f2CLIR75MAv7FhcD/Ko+RzxfExPJB0BBsYZGarZcyd1R3rVl/rQAmd+xnZZfM5kV
+iRtl7ux8NldaFkZ7XU71ZkLIiivHPDEY6gKWXe3ANsXzVxSO3Zh9okT1P7jyMaNt
+Ucz7xD0T7+hnmIV4EU10h849o99F37eN3Ygjjy2xZmMsCfs/Qaem1mlJF0d87472
+7pZcOd+PgBpV2W2O9NTerd6+TPhyqGhgtucrQLID7B+eheLXaexAjgBYwHv9LbOo
+uCYPS9s4DBJgvoPhz+IZ/PEZVpY/w5QJ9DsBe0xOv+KWWt9KdcA0SWRYtJUznNSS
+YX3eVKZD0C3d5hgr0vSDUe/p6nsgvubHH/v/9EbruXql6PCVu0akO34n+91374pi
+85G3EWEuzUwxmKDCr228W5NB2bqFet9CgtHycnQ8cjM61AYpLZx4iTCxH8s6m+lY
+WRr1sFm38il8oTODZTQ6o/w91RELhyMd9MTJUZNEqqsgN4y0/r7Dww==
+-----END RSA PRIVATE KEY-----
diff --git a/tls/tests/certs/server.key b/tls/tests/certs/server.key
new file mode 100644
index 0000000..c95d6c5
--- /dev/null
+++ b/tls/tests/certs/server.key
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXAIBAAKBgQDCE6cHPOkPnOSpobuRDKTLcvjdmh1vAYmwOvXLcBkpN+PkN443
+2KURytg0rw4w7+HDS+KV13pAF5D5mSl/OOsfwQzi/dQKSVF0zlbz5L7rcBqIt2cG
+Xz7gsX8VRMycXH0XC3QAAZUW32zYeo0G28uCttAh6wt8YCKu99+TNhRIWQIDAQAB
+AoGAaMHQ48BGEO5gIwwwwW+wuDycBom8n4GV/7EjoaclfbE0aqhuNMjU+RCjuXRQ
+Vav2EcOxT65ax6Ow1nmNA6YGi1GUAcktgMmY+Cl72iVyEqz8kUwUS1TBj0EqysCW
+E57CJo6S9Htnhq9/qrJL1LvW2iH9mWobZnMbI6+jN8C/eTECQQDmrnS72ZzNJcLc
+yU9uahH5BaX2vUWpWdurjYend3L9sHII3hZznYTOBn5a4kCfF2CD1FYlL7LMuV4q
+qab8O5QNAkEA12CzTV3lpK8LOFX5CTT4gM5XAZvP0+YiThnRrGh15JRgZoV6Larn
+X+Tvk8qYGRZdjILnNaOCqp9j3z7Mpvt2fQJAR+Z6dg6m4/5wFTcd7fFbtr1+9EAc
+VWOvp3IOpTEDA3WapY7reo/PVBQMEDHTKIM1zwFA9IhAd7UTV8LXTGkZhQJAVUBU
+mLojDRWwdkMpiShreOiz7dIT6Ic+avWzVfAfQjQtGEebPfpZDU8cOb7Gh5+ftd+W
+z1eCgDEJIjPEZBBDLQJBAKnXJh9w47et8NZHsXjdqV/nWiZ2uzxijbEBCQTgLhcT
+e4oSQidcpEPRAB5jsCZAa5czv74kDIRqYCjFL8fAT+4=
+-----END RSA PRIVATE KEY-----
diff --git a/tls/tests/certs/server.pem b/tls/tests/certs/server.pem
new file mode 100644
index 0000000..a5d9614
--- /dev/null
+++ b/tls/tests/certs/server.pem
@@ -0,0 +1,14 @@
+-----BEGIN CERTIFICATE-----
+MIICHzCCAYgCAQAwDQYJKoZIhvcNAQEEBQAwWDELMAkGA1UEBhMCQ0ExGTAXBgNV
+BAgTEEJyaXRpc2ggQ29sdW1iaWExEjAQBgNVBAcTCVZhbmNvdXZlcjEaMBgGA1UE
+ChMRU2FtcGxlIENlcnRzIEludGwwHhcNMDEwNjIxMjAyODUyWhcNMDEwNzIxMjAy
+ODUyWjBYMQswCQYDVQQGEwJDQTEZMBcGA1UECBMQQnJpdGlzaCBDb2x1bWJpYTES
+MBAGA1UEBxMJVmFuY291dmVyMRowGAYDVQQKExFTYW1wbGUgQ2VydHMgSW50bDCB
+nzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwhOnBzzpD5zkqaG7kQyky3L43Zod
+bwGJsDr1y3AZKTfj5DeON9ilEcrYNK8OMO/hw0vildd6QBeQ+ZkpfzjrH8EM4v3U
+CklRdM5W8+S+63AaiLdnBl8+4LF/FUTMnFx9Fwt0AAGVFt9s2HqNBtvLgrbQIesL
+fGAirvffkzYUSFkCAwEAATANBgkqhkiG9w0BAQQFAAOBgQBXJZfVMqZw9T4EgXQo
+nM0geAByeqyOCoR+4dPv4hipf/c1m8sZgG1SxrXVThey4i4UkZenKz+VlPGDX0++
+sJBKod+aa24wcR5IQBTDuxzwduwuKkbjzGG+zdBXjOgxdcLxw7ozNciSSALYVnez
+0uX7n/lAP92SlcEXhoUroMjeLQ==
+-----END CERTIFICATE-----
diff --git a/tls/tests/certs/server.req b/tls/tests/certs/server.req
new file mode 100644
index 0000000..b7b9d26
--- /dev/null
+++ b/tls/tests/certs/server.req
@@ -0,0 +1,11 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIIBmDCCAQECAQAwWDELMAkGA1UEBhMCQ0ExGTAXBgNVBAgTEEJyaXRpc2ggQ29s
+dW1iaWExEjAQBgNVBAcTCVZhbmNvdXZlcjEaMBgGA1UEChMRU2FtcGxlIENlcnRz
+IEludGwwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMITpwc86Q+c5Kmhu5EM
+pMty+N2aHW8BibA69ctwGSk34+Q3jjfYpRHK2DSvDjDv4cNL4pXXekAXkPmZKX84
+6x/BDOL91ApJUXTOVvPkvutwGoi3ZwZfPuCxfxVEzJxcfRcLdAABlRbfbNh6jQbb
+y4K20CHrC3xgIq7335M2FEhZAgMBAAGgADANBgkqhkiG9w0BAQQFAAOBgQBsiv9V
+OdF/lp3ovGfYj3DF3QyfH6p0fCuUADKgReLKOilMDPR77WE/kExxqRR9dTzlTY4n
+dEmvzfmV3Vbj8KKs3L9NoLo6vF/ZeSt+RyJQlJblzXuFqxMlpZJoYcFSZO1E0Jl8
+iHe6QMOI58MBe/waEPxvIyFo2L30wScEyy/Ynw==
+-----END CERTIFICATE REQUEST-----
diff --git a/tls/tests/ciphers.test b/tls/tests/ciphers.test
new file mode 100644
index 0000000..f79eec1
--- /dev/null
+++ b/tls/tests/ciphers.test
@@ -0,0 +1,159 @@
+# Commands covered: tls::ciphers
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+
+# All rights reserved.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import ::tcltest::*
+}
+
+# The build dir is added as the first element of $PATH
+set auto_path [linsert $auto_path 0 [lindex [split $env(PATH) ";:"] 0]]
+
+package require tls
+
+# One of these should == 1, depending on what type of ssl library
+# tls was compiled against. (RSA BSAFE SSL-C or OpenSSL).
+#
+set ::tcltest::testConstraints(rsabsafe) 0
+set ::tcltest::testConstraints(openssl) [string match "OpenSSL*" [tls::version]]
+
+set ::EXPECTEDCIPHERS(rsabsafe) {
+ EDH-DSS-RC4-SHA
+ EDH-RSA-DES-CBC3-SHA
+ EDH-DSS-DES-CBC3-SHA
+ DES-CBC3-SHA
+ RC4-SHA
+ RC4-MD5
+ EDH-RSA-DES-CBC-SHA
+ EDH-DSS-DES-CBC-SHA
+ DES-CBC-SHA
+ EXP-EDH-DSS-DES-56-SHA
+ EXP-EDH-DSS-RC4-56-SHA
+ EXP-DES-56-SHA
+ EXP-RC4-56-SHA
+ EXP-EDH-RSA-DES-CBC-SHA
+ EXP-EDH-DSS-DES-CBC-SHA
+ EXP-DES-CBC-SHA
+ EXP-RC2-CBC-MD5
+ EXP-RC4-MD5
+}
+
+set ::EXPECTEDCIPHERS(openssl) {
+ AES128-SHA
+ AES256-SHA
+ DES-CBC-SHA
+ DES-CBC3-SHA
+ DHE-DSS-AES128-SHA
+ DHE-DSS-AES256-SHA
+ DHE-DSS-RC4-SHA
+ DHE-RSA-AES128-SHA
+ DHE-RSA-AES256-SHA
+ EDH-DSS-DES-CBC-SHA
+ EDH-DSS-DES-CBC3-SHA
+ EDH-RSA-DES-CBC-SHA
+ EDH-RSA-DES-CBC3-SHA
+ EXP-DES-CBC-SHA
+ EXP-EDH-DSS-DES-CBC-SHA
+ EXP-EDH-RSA-DES-CBC-SHA
+ EXP-RC2-CBC-MD5
+ EXP-RC4-MD5
+ EXP1024-DES-CBC-SHA
+ EXP1024-DHE-DSS-DES-CBC-SHA
+ EXP1024-DHE-DSS-RC4-SHA
+ EXP1024-RC2-CBC-MD5
+ EXP1024-RC4-MD5
+ EXP1024-RC4-SHA
+ IDEA-CBC-SHA
+ RC4-MD5
+ RC4-SHA
+}
+
+set ::EXPECTEDCIPHERS(openssl0.9.8) {
+ DHE-RSA-AES256-SHA
+ DHE-DSS-AES256-SHA
+ AES256-SHA
+ EDH-RSA-DES-CBC3-SHA
+ EDH-DSS-DES-CBC3-SHA
+ DES-CBC3-SHA
+ DHE-RSA-AES128-SHA
+ DHE-DSS-AES128-SHA
+ AES128-SHA
+ IDEA-CBC-SHA
+ RC4-SHA
+ RC4-MD5
+ EDH-RSA-DES-CBC-SHA
+ EDH-DSS-DES-CBC-SHA
+ DES-CBC-SHA
+ EXP-EDH-RSA-DES-CBC-SHA
+ EXP-EDH-DSS-DES-CBC-SHA
+ EXP-DES-CBC-SHA
+ EXP-RC2-CBC-MD5
+ EXP-RC4-MD5
+}
+
+set version ""
+if {[string match "OpenSSL*" [tls::version]]} {
+ regexp {OpenSSL ([\d\.]+)} [tls::version] -> version
+}
+if {![info exists ::EXPECTEDCIPHERS(openssl$version)]} {
+ set version ""
+}
+
+proc listcompare {wants haves} {
+ array set want {}
+ array set have {}
+ foreach item $wants { set want($item) 1 }
+ foreach item $haves { set have($item) 1 }
+ foreach item [lsort -dictionary [array names have]] {
+ if {[info exists want($item)]} {
+ unset want($item) have($item)
+ }
+ }
+ if {[array size want] || [array size have]} {
+ return [list MISSING [array names want] UNEXPECTED [array names have]]
+ }
+}
+
+test ciphers-1.1 {Tls::ciphers for ssl3} {rsabsafe} {
+ # This will fail if you compiled against OpenSSL.
+ # Change the constraint setting above.
+ listcompare $::EXPECTEDCIPHERS(rsabsafe) [tls::ciphers ssl3]
+} {}
+
+test ciphers-1.2 {Tls::ciphers for tls1} {rsabsafe} {
+ # This will fail if you compiled against OpenSSL.
+ # Change the constraint setting above.
+ listcompare $::EXPECTEDCIPHERS(rsabsafe) [tls::ciphers tls1]
+} {}
+
+test ciphers-1.3 {Tls::ciphers for ssl3} {openssl} {
+ # This will fail if you compiled against RSA bsafe or with a
+ # different set of defines than the default.
+ # Change the constraint setting above.
+ listcompare $::EXPECTEDCIPHERS(openssl$version) [tls::ciphers ssl3]
+} {}
+
+# This version of the test is correct for OpenSSL only.
+# An equivalent test for the RSA BSAFE SSL-C is earlier in this file.
+
+test ciphers-1.4 {Tls::ciphers for tls1} {openssl} {
+ # This will fail if you compiled against RSA bsafe or with a
+ # different set of defines than the default.
+ # Change the constraint setting in all.tcl
+ listcompare $::EXPECTEDCIPHERS(openssl$version) [tls::ciphers tls1]
+} {}
+
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/tls/tests/keytest1.tcl b/tls/tests/keytest1.tcl
new file mode 100644
index 0000000..4076d69
--- /dev/null
+++ b/tls/tests/keytest1.tcl
@@ -0,0 +1,23 @@
+#!/bin/sh
+# The next line is executed by /bin/sh, but not tcl \
+exec tclsh "$0" ${1+"$@"}
+
+package require tls
+
+proc creadable {s} {
+ puts "LINE=[gets $s]"
+ after 2000
+ exit
+}
+
+proc myserv {s args} {
+ fileevent $s readable [list creadable $s]
+}
+
+tls::misc req 1024 $keyfile $certfile [list C CCC ST STTT L LLLL O OOOO OU OUUUU CN CNNNN Email some@email.com days 730 serial 12]
+
+tls::socket -keyfile $keyfile -certfile $certfile -server myserv 12300
+
+puts "Now run keytest2.tcl"
+vwait forever
+
diff --git a/tls/tests/keytest2.tcl b/tls/tests/keytest2.tcl
new file mode 100644
index 0000000..7b717d6
--- /dev/null
+++ b/tls/tests/keytest2.tcl
@@ -0,0 +1,8 @@
+package require tls
+
+set s [tls::socket 127.0.0.1 12300]
+puts $s "A line"
+flush $s
+puts [join [tls::status $s] \n]
+exit
+
diff --git a/tls/tests/remote.tcl b/tls/tests/remote.tcl
new file mode 100755
index 0000000..5e454bb
--- /dev/null
+++ b/tls/tests/remote.tcl
@@ -0,0 +1,185 @@
+# This file contains Tcl code to implement a remote server that can be
+# used during testing of Tcl socket code. This server is used by some
+# of the tests in socket.test.
+#
+# Source this file in the remote server you are using to test Tcl against.
+#
+# Copyright (c) 1995-1996 Sun Microsystems, Inc.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# RCS: @(#) $Id: remote.tcl,v 1.6 2004/02/11 22:41:25 razzell Exp $
+
+# load tls package
+package require tls
+
+# Initialize message delimitor
+
+# Initialize command array
+catch {unset command}
+set command(0) ""
+set callerSocket ""
+
+# Detect whether we should print out connection messages etc.
+# set VERBOSE 1
+if {![info exists VERBOSE]} {
+ set VERBOSE 0
+}
+
+proc __doCommands__ {l s} {
+ global callerSocket VERBOSE
+
+ if {$VERBOSE} {
+ puts "--- Server executing the following for socket $s:"
+ puts $l
+ puts "---"
+ }
+ if {0} {
+ set fd [open remoteServer.log a]
+ catch {puts $fd "skey: $serverKey"}
+ puts $fd "--- Server executing the following for socket $s:"
+ puts $fd $l
+ puts $fd "---"
+ close $fd
+ }
+ set callerSocket $s
+ if {[catch {uplevel #0 $l} msg]} {
+ if {0} {
+ set fd [open remoteServer.log a]
+ puts $fd "error: $msg"
+ close $fd
+ }
+ list error $msg
+ } else {
+ list success $msg
+ }
+}
+
+proc __readAndExecute__ {s} {
+ global command VERBOSE
+
+ set l [gets $s]
+ if {[string compare $l "--Marker--Marker--Marker--"] == 0} {
+ if {[info exists command($s)]} {
+ puts $s [list error incomplete_command]
+ }
+ puts $s "--Marker--Marker--Marker--"
+ return
+ }
+ if {[string compare $l ""] == 0} {
+ if {[eof $s]} {
+ if {$VERBOSE} {
+ puts "Server closing $s, eof from client"
+ }
+ close $s
+ }
+ return
+ }
+ append command($s) $l "\n"
+ if {[info complete $command($s)]} {
+ set cmds $command($s)
+ unset command($s)
+ puts $s [__doCommands__ $cmds $s]
+ }
+ if {[eof $s]} {
+ if {$VERBOSE} {
+ puts "Server closing $s, eof from client"
+ }
+ close $s
+ }
+}
+
+proc __accept__ {s a p} {
+ global VERBOSE
+
+ if {$VERBOSE} {
+ puts "Server accepts new connection from $a:$p on $s"
+ }
+ tls::handshake $s
+ fileevent $s readable [list __readAndExecute__ $s]
+ fconfigure $s -buffering line -translation crlf
+}
+
+set serverIsSilent 0
+for {set i 0} {$i < $argc} {incr i} {
+ if {[string compare -serverIsSilent [lindex $argv $i]] == 0} {
+ set serverIsSilent 1
+ break
+ }
+}
+if {![info exists serverPort]} {
+ if {[info exists env(serverPort)]} {
+ set serverPort $env(serverPort)
+ }
+}
+if {![info exists serverPort]} {
+ for {set i 0} {$i < $argc} {incr i} {
+ if {[string compare -port [lindex $argv $i]] == 0} {
+ if {$i < [expr $argc - 1]} {
+ set serverPort [lindex $argv [expr $i + 1]]
+ }
+ break
+ }
+ }
+}
+if {![info exists serverPort]} {
+ set serverPort 8048
+}
+
+if {![info exists serverAddress]} {
+ if {[info exists env(serverAddress)]} {
+ set serverAddress $env(serverAddress)
+ }
+}
+if {![info exists serverAddress]} {
+ for {set i 0} {$i < $argc} {incr i} {
+ if {[string compare -address [lindex $argv $i]] == 0} {
+ if {$i < [expr $argc - 1]} {
+ set serverAddress [lindex $argv [expr $i + 1]]
+ }
+ break
+ }
+ }
+}
+if {![info exists serverAddress]} {
+ set serverAddress 0.0.0.0
+}
+
+if {$serverIsSilent == 0} {
+ set l "Remote server listening on port $serverPort, IP $serverAddress."
+ puts ""
+ puts $l
+ for {set c [string length $l]} {$c > 0} {incr c -1} {puts -nonewline "-"}
+ puts ""
+ puts ""
+ puts "You have set the Tcl variables serverAddress to $serverAddress and"
+ puts "serverPort to $serverPort. You can set these with the -address and"
+ puts "-port command line options, or as environment variables in your"
+ puts "shell."
+ puts ""
+ puts "NOTE: The tests will not work properly if serverAddress is set to"
+ puts "\"localhost\" or 127.0.0.1."
+ puts ""
+ puts "When you invoke tcltest to run the tests, set the variables"
+ puts "remoteServerPort to $serverPort and remoteServerIP to"
+ puts "[info hostname]. You can set these as environment variables"
+ puts "from the shell. The tests will not work properly if you set"
+ puts "remoteServerIP to \"localhost\" or 127.0.0.1."
+ puts ""
+ puts -nonewline "Type Ctrl-C to terminate--> "
+ flush stdout
+}
+
+set certsDir [file join [file dirname [info script]] certs]
+set serverCert [file join $certsDir server.pem]
+set caCert [file join $certsDir cacert.pem]
+set serverKey [file join $certsDir server.key]
+if {[catch {set serverSocket \
+ [tls::socket -myaddr $serverAddress -server __accept__ \
+ -cafile $caCert -certfile $serverCert -keyfile $serverKey \
+ $serverPort]} msg]} {
+ puts "Server on $serverAddress:$serverPort cannot start: $msg"
+} else {
+ vwait __server_wait_variable__
+}
diff --git a/tls/tests/simpleClient.tcl b/tls/tests/simpleClient.tcl
new file mode 100755
index 0000000..6325ff1
--- /dev/null
+++ b/tls/tests/simpleClient.tcl
@@ -0,0 +1,113 @@
+#!/bin/sh
+# The next line is executed by /bin/sh, but not tcl \
+exec tclsh8.3 "$0" ${1+"$@"}
+
+package require tls
+
+set dir [file join [file dirname [info script]] ../tests/certs]
+set OPTS(-cafile) [file join $dir ca.pem]
+set OPTS(-cert) [file join $dir client.pem]
+set OPTS(-key) [file join $dir client.key]
+
+set OPTS(-host) lorax
+set OPTS(-port) 2468
+set OPTS(-debug) 1
+set OPTS(-count) 8
+set OPTS(-parallel) 1
+
+foreach {key val} $argv {
+ if {![info exists OPTS($key)]} {
+ puts stderr "Usage: $argv0 ?options?\
+ \n\t-debug boolean Debugging on or off ($OPTS(-debug))\
+ \n\t-cafile file Cert. Auth. File ($OPTS(-cafile))\
+ \n\t-client file Client Cert ($OPTS(-cert))\
+ \n\t-ckey file Client Key ($OPTS(-key))\
+ \n\t-count num No of sync. connections to make per client ($OPTS(-count))\
+ \n\t-parallel num No of parallel clients to run ($OPTS(-parallel))\
+ \n\t-host hostname Server hostname ($OPTS(-host))\
+ \n\t-port num Server port ($OPTS(-port))"
+ exit
+ }
+ set OPTS($key) $val
+}
+
+if {$OPTS(-parallel) > 1} {
+ # If they wanted parallel, we just spawn ourselves several times
+ # with the right args.
+
+ set cmd [info nameofexecutable]
+ set script [info script]
+ for {set i 0} {$i < $OPTS(-parallel)} {incr i} {
+ eval [list exec $cmd $script] [array get OPTS] [list -parallel 0] &
+ }
+ exit
+}
+
+# Local handler for any background errors.
+proc bgerror {msg} { puts "BGERROR: $msg" }
+
+# debugging helper code
+proc shortstr {str} {
+ return "[string replace $str 10 end ...] [string length $str]b"
+}
+proc dputs {msg} { if {$::OPTS(-debug)} { puts stderr $msg ; flush stderr } }
+
+set OPTS(openports) 0
+
+# Define what we want to feed down the pipe
+set megadata [string repeat [string repeat A 76]\n 1000]
+
+proc drain {chan} {
+ global OPTS
+ if {[catch {read $chan} data]} {
+ #dputs "EOF $chan ([shortstr $data])"
+ incr OPTS(openports) -1
+ catch {close $chan}
+ return
+ }
+ #if {$data != ""} { dputs "got $chan ([shortstr $data])" }
+ if {[string match *CLOSE\n $data]} {
+ dputs "CLOSE $chan"
+ incr OPTS(openports) -1
+ close $chan
+ return
+ } elseif {[eof $chan]} {
+ # client gone or finished
+ dputs "EOF $chan"
+ incr OPTS(openports) -1
+ close $chan
+ return
+ }
+}
+
+proc feed {sock} {
+ dputs "feed $sock ([shortstr $::megadata])"
+ puts $sock $::megadata
+ flush $sock
+ puts $sock CLOSE
+ flush $sock
+ fileevent $sock writable {}
+}
+
+proc go {} {
+ global OPTS
+ for {set num $OPTS(-count)} {$num > 0} {incr num -1} {
+ set sock [tls::socket $OPTS(-host) $OPTS(-port)]
+ incr OPTS(openports)
+ fconfigure $sock -blocking 0 -buffersize 4096
+ fileevent $sock writable [list feed $sock ]
+ fileevent $sock readable [list drain $sock]
+ dputs "created $sock"
+ }
+ while {1} {
+ # Make sure to wait until all our sockets close down.
+ vwait OPTS(openports)
+ if {$OPTS(openports) == 0} {
+ exit 0
+ }
+ }
+}
+
+tls::init -cafile $OPTS(-cafile) -certfile $OPTS(-cert) -keyfile $OPTS(-key)
+
+go
diff --git a/tls/tests/simpleServer.tcl b/tls/tests/simpleServer.tcl
new file mode 100755
index 0000000..4450d28
--- /dev/null
+++ b/tls/tests/simpleServer.tcl
@@ -0,0 +1,90 @@
+#!/bin/sh
+# The next line is executed by /bin/sh, but not tcl \
+exec tclsh8.3 "$0" ${1+"$@"}
+
+package require tls
+
+set dir [file join [file dirname [info script]] ../tests/certs]
+set OPTS(-cafile) [file join $dir ca.pem]
+set OPTS(-cert) [file join $dir server.pem]
+set OPTS(-key) [file join $dir server.key]
+
+set OPTS(-port) 2468
+set OPTS(-debug) 1
+set OPTS(-require) 1
+
+foreach {key val} $argv {
+ if {![info exists OPTS($key)]} {
+ puts stderr "Usage: $argv0 ?options?\
+ \n\t-debug boolean Debugging on or off ($OPTS(-debug))\
+ \n\t-cafile file Cert. Auth. File ($OPTS(-cafile))\
+ \n\t-cert file Server Cert ($OPTS(-cert))\
+ \n\t-key file Server Key ($OPTS(-key))\
+ \n\t-require boolean Require Certification ($OPTS(-require))\
+ \n\t-port num Port to listen on ($OPTS(-port))"
+ exit
+ }
+ set OPTS($key) $val
+}
+
+# Catch any background errors.
+proc bgerror {msg} { puts stderr "BGERROR: $msg" }
+
+# debugging helper code
+proc shortstr {str} {
+ return "[string replace $str 10 end ...] [string length $str]b"
+}
+proc dputs {msg} { if {$::OPTS(-debug)} { puts stderr $msg ; flush stderr } }
+
+# As a response we just echo the data sent to us.
+#
+proc respond {chan} {
+ if {[catch {read $chan} data]} {
+ #dputs "EOF $chan ([shortstr $data)"
+ catch {close $chan}
+ return
+ }
+ #if {$data != ""} { dputs "got $chan ([shortstr $data])" }
+ if {[eof $chan]} {
+ # client gone or finished
+ dputs "EOF $chan"
+ close $chan ;# release the port
+ return
+ }
+ puts -nonewline $chan $data
+ flush $chan
+ #dputs "sent $chan ([shortstr $data])"
+}
+
+# Once connection is established, we need to ensure handshake.
+#
+proc handshake {s cmd} {
+ if {[eof $s]} {
+ dputs "handshake eof $s"
+ close $s
+ } elseif {[catch {tls::handshake $s} result]} {
+ # Some errors are normal. Specifically, I (hobbs) believe that
+ # TLS throws EAGAINs when it may not need to (or is inappropriate).
+ dputs "handshake error $s: $result"
+ } elseif {$result == 1} {
+ # Handshake complete
+ dputs "handshake complete $s"
+ fileevent $s readable [list $cmd $s]
+ }
+}
+
+# Callback proc to accept a connection from a client.
+#
+proc accept { chan ip port } {
+ dputs "[info level 0] [fconfigure $chan]"
+ fconfigure $chan -blocking 0
+ fileevent $chan readable [list handshake $chan respond]
+}
+
+tls::init -cafile $OPTS(-cafile) -certfile $OPTS(-cert) -keyfile $OPTS(-key)
+set chan [tls::socket -server accept -require $OPTS(-require) $OPTS(-port)]
+
+puts "Server waiting connection on $chan ($OPTS(-port))"
+puts [fconfigure $chan]
+
+vwait __forever__
diff --git a/tls/tests/tlsIO.test b/tls/tests/tlsIO.test
new file mode 100755
index 0000000..e1d855a
--- /dev/null
+++ b/tls/tests/tlsIO.test
@@ -0,0 +1,2072 @@
+# Commands tested in this file: socket. -*- tcl -*-
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1994-1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-2000 Ajuba Solutions.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# RCS: @(#) $Id: tlsIO.test,v 1.24 2015/06/06 09:07:08 apnadkarni Exp $
+
+# Running socket tests with a remote server:
+# ------------------------------------------
+#
+# Some tests in socket.test depend on the existence of a remote server to
+# which they connect. The remote server must be an instance of tcltest and it
+# must run the script found in the file "remote.tcl" in this directory. You
+# can start the remote server on any machine reachable from the machine on
+# which you want to run the socket tests, by issuing:
+#
+# tcltest remote.tcl -port 8048 # Or choose another port number.
+#
+# If the machine you are running the remote server on has several IP
+# interfaces, you can choose which interface the server listens on for
+# connections by specifying the -address command line flag, so:
+#
+# tcltest remote.tcl -address your.machine.com
+#
+# These options can also be set by environment variables. On Unix, you can
+# type these commands to the shell from which the remote server is started:
+#
+# shell% setenv serverPort 8048
+# shell% setenv serverAddress your.machine.com
+#
+# and subsequently you can start the remote server with:
+#
+# tcltest remote.tcl
+#
+# to have it listen on port 8048 on the interface your.machine.com.
+#
+# When the server starts, it prints out a detailed message containing its
+# configuration information, and it will block until killed with a Ctrl-C.
+# Once the remote server exists, you can run the tests in socket.test with
+# the server by setting two Tcl variables:
+#
+# % set remoteServerIP <name or address of machine on which server runs>
+# % set remoteServerPort 8048
+#
+# These variables are also settable from the environment. On Unix, you can:
+#
+# shell% setenv remoteServerIP machine.where.server.runs
+# shell% setenv remoteServerPort 8048
+#
+# The preamble of the socket.test file checks to see if the variables are set
+# either in Tcl or in the environment; if they are, it attempts to connect to
+# the server. If the connection is successful, the tests using the remote
+# server will be performed; otherwise, it will attempt to start the remote
+# server (via exec) on platforms that support this, on the local host,
+# listening at port 8048. If all fails, a message is printed and the tests
+# using the remote server are not performed.
+
+proc dputs {msg} { return ; puts stderr $msg ; flush stderr }
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import -force ::tcltest::*
+}
+
+# The build dir is added as the first element of $PATH
+set auto_path [linsert $auto_path 0 [lindex [split $env(PATH) ";:"] 0]]
+# Load the tls package
+package require tls 1.6
+
+set tlsServerPort 8048
+
+# Specify where the certificates are
+
+set certsDir [file join [file dirname [info script]] certs]
+set serverCert [file join $certsDir server.pem]
+set clientCert [file join $certsDir client.pem]
+set caCert [file join $certsDir ca.pem]
+set serverKey [file join $certsDir server.key]
+set clientKey [file join $certsDir client.key]
+
+# Some tests require the testthread and exec commands
+
+set ::tcltest::testConstraints(testthread) \
+ [expr {[info commands testthread] != {}}]
+set ::tcltest::testConstraints(exec) [expr {[info commands exec] != {}}]
+
+#
+# If remoteServerIP or remoteServerPort are not set, check in the
+# environment variables for externally set values.
+#
+
+if {![info exists remoteServerIP]} {
+ if {[info exists env(remoteServerIP)]} {
+ set remoteServerIP $env(remoteServerIP)
+ }
+}
+if {![info exists remoteServerPort]} {
+ if {[info exists env(remoteServerPort)]} {
+ set remoteServerPort $env(remoteServerPort)
+ } else {
+ if {[info exists remoteServerIP]} {
+ set remoteServerPort $tlsServerPort
+ }
+ }
+}
+
+proc do_handshake {s {type readable} {cmd {}} args} {
+ if {[eof $s]} {
+ close $s
+ dputs "handshake: eof"
+ set ::do_handshake "eof"
+ } elseif {[catch {tls::handshake $s} result]} {
+ # Some errors are normal.
+ dputs "handshake: $result"
+ } elseif {$result == 1} {
+ # Handshake complete
+ if {[llength $args]} { eval [list fconfigure $s] $args }
+ if {$cmd == ""} {
+ fileevent $s $type ""
+ } else {
+ fileevent $s $type "$cmd [list $s]"
+ }
+ dputs "handshake: complete"
+ set ::do_handshake "complete"
+ } else {
+ dputs "handshake: in progress"
+ }
+}
+
+#
+# Check if we're supposed to do tests against the remote server
+#
+
+set doTestsWithRemoteServer 1
+if {![info exists remoteServerIP] && ($tcl_platform(platform) != "macintosh")} {
+ set remoteServerIP 127.0.0.1
+}
+if {($doTestsWithRemoteServer == 1) && (![info exists remoteServerPort])} {
+ set remoteServerPort $tlsServerPort
+}
+
+# Attempt to connect to a remote server if one is already running. If it
+# is not running or for some other reason the connect fails, attempt to
+# start the remote server on the local host listening on port 8048. This
+# is only done on platforms that support exec (i.e. not on the Mac). On
+# platforms that do not support exec, the remote server must be started
+# by the user before running the tests.
+
+set remoteProcChan ""
+set commandSocket ""
+if {$doTestsWithRemoteServer} {
+ catch {close $commandSocket}
+ if {[catch {set commandSocket [tls::socket \
+ -certfile $clientCert -cafile $caCert -keyfile $clientKey \
+ $remoteServerIP $remoteServerPort]}] != 0} {
+ if {[info commands exec] == ""} {
+ set noRemoteTestReason "can't exec"
+ set doTestsWithRemoteServer 0
+ } else {
+ set remoteServerIP 127.0.0.1
+ set remoteFile [file join [pwd] remote.tcl]
+ if {[catch {set remoteProcChan \
+ [open "|[list $::tcltest::tcltest $remoteFile \
+ -serverIsSilent -port $remoteServerPort \
+ -address $remoteServerIP]" w+]} msg] == 0} {
+ after 1000
+ if {[catch {set commandSocket [tls::socket -cafile $caCert \
+ -certfile $clientCert -keyfile $clientKey \
+ $remoteServerIP $remoteServerPort]} msg] == 0} {
+ fconfigure $commandSocket -translation crlf -buffering line
+ } else {
+ set noRemoteTestReason $msg
+ set doTestsWithRemoteServer 0
+ }
+ } else {
+ set noRemoteTestReason "$msg $::tcltest::tcltest"
+ set doTestsWithRemoteServer 0
+ }
+ }
+ } else {
+ fconfigure $commandSocket -translation crlf -buffering line
+ }
+}
+
+# Some tests are run only if we are doing testing against a remote server.
+set ::tcltest::testConstraints(doTestsWithRemoteServer) $doTestsWithRemoteServer
+if {$doTestsWithRemoteServer == 0} {
+ if {[string first s $::tcltest::verbose] != -1} {
+ puts "Skipping tests with remote server. See tests/socket.test for"
+ puts "information on how to run remote server."
+ puts "Reason for not doing remote tests: $noRemoteTestReason"
+ }
+}
+
+#
+# If we do the tests, define a command to send a command to the
+# remote server.
+#
+
+if {$doTestsWithRemoteServer == 1} {
+ proc sendCommand {c} {
+ global commandSocket
+
+ if {[eof $commandSocket]} {
+ error "remote server disappeared"
+ }
+
+ if {[catch {puts $commandSocket $c} msg]} {
+ error "remote server disappeared: $msg"
+ }
+ if {[catch {puts $commandSocket "--Marker--Marker--Marker--"} msg]} {
+ error "remote server disappeared: $msg"
+ }
+
+ set resp ""
+ while {1} {
+ set line [gets $commandSocket]
+ if {[eof $commandSocket]} {
+ error "remote server disappeared"
+ }
+ if {[string compare $line "--Marker--Marker--Marker--"] == 0} {
+ if {[string compare [lindex $resp 0] error] == 0} {
+ error [lindex $resp 1]
+ } else {
+ return [lindex $resp 1]
+ }
+ } else {
+ append resp $line "\n"
+ }
+ }
+ }
+
+ sendCommand [list proc dputs [info args dputs] [info body dputs]]
+
+ proc sendCertValues {} {
+ # We need to be able to send certificate values that normalize
+ # filenames across platforms
+ sendCommand {
+ set certsDir [file join [file dirname [info script]] certs]
+ set serverCert [file join $certsDir server.pem]
+ set clientCert [file join $certsDir client.pem]
+ set caCert [file join $certsDir cacert.pem]
+ set serverKey [file join $certsDir server.key]
+ set clientKey [file join $certsDir client.key]
+ }
+ }
+}
+
+test tlsIO-1.1 {arg parsing for socket command} {socket} {
+ list [catch {tls::socket -server} msg] $msg
+} {1 {wrong # args: should be "tls::socket -server command ?options? port"}}
+
+test tlsIO-1.2 {arg parsing for socket command} {socket} {
+ list [catch {tls::socket -server foo} msg] $msg
+} {1 {wrong # args: should be "tls::socket -server command ?options? port"}}
+
+test tlsIO-1.3 {arg parsing for socket command} {socket} {
+ list [catch {tls::socket -myaddr} msg] $msg
+} {1 {wrong # args: should be "tls::socket ?options? host port"}}
+
+test tlsIO-1.4 {arg parsing for socket command} {socket} {
+ list [catch {tls::socket -myaddr 127.0.0.1} msg] $msg
+} {1 {wrong # args: should be "tls::socket ?options? host port"}}
+
+test tlsIO-1.5 {arg parsing for socket command} {socket} {
+ list [catch {tls::socket -myport} msg] $msg
+} {1 {wrong # args: should be "tls::socket ?options? host port"}}
+
+test tlsIO-1.6 {arg parsing for socket command} {socket} {
+ list [catch {tls::socket -myport xxxx} msg] $msg
+} {1 {wrong # args: should be "tls::socket ?options? host port"}}
+
+test tlsIO-1.7 {arg parsing for socket command} {socket} {
+ list [catch {tls::socket -myport 2522} msg] $msg
+} {1 {wrong # args: should be "tls::socket ?options? host port"}}
+
+test tlsIO-1.8 {arg parsing for socket command} {socket} {
+ list [catch {tls::socket -froboz} msg] $msg
+} {1 {wrong # args: should be "tls::socket ?options? host port"}}
+
+test tlsIO-1.9 {arg parsing for socket command} {socket} {
+ list [catch {tls::socket -server foo -myport 2521 3333} msg] $msg
+} {1 {wrong # args: should be "tls::socket -server command ?options? port"}}
+
+test tlsIO-1.10 {arg parsing for socket command} {socket} {
+ list [catch {tls::socket host 2528 -junk} msg] $msg
+} {1 {wrong # args: should be "tls::socket ?options? host port"}}
+
+test tlsIO-1.11 {arg parsing for socket command} {socket} {
+ list [catch {tls::socket -server callback 2520 --} msg] $msg
+} {1 {wrong # args: should be "tls::socket -server command ?options? port"}}
+
+test tlsIO-1.12 {arg parsing for socket command} {socket} {
+ list [catch {tls::socket foo badport} msg] $msg
+} {1 {expected integer but got "badport"}}
+
+test tlsIO-2.1 {tcp connection} {socket stdio} {
+ removeFile script
+ set f [open script w]
+ puts $f {
+ set auto_path [linsert $auto_path 0 [lindex [split $env(PATH) ";:"] 0]]
+ package require tls
+ set timer [after 2000 "set x timed_out"]
+ }
+ puts $f "set f \[tls::socket -server accept -certfile $serverCert -cafile $caCert -keyfile $serverKey 8828 \]"
+ puts $f {
+ proc accept {file addr port} {
+ global x
+ set x done
+ close $file
+ }
+ puts ready
+ vwait x
+ after cancel $timer
+ close $f
+ puts $x
+ }
+ close $f
+ set f [open "|[list $::tcltest::tcltest script]" r]
+ gets $f x
+ if {[catch {tls::socket -certfile $clientCert -cafile $caCert \
+ -keyfile $clientKey 127.0.0.1 8828} msg]} {
+ set x $msg
+ } else {
+ lappend x [gets $f]
+ close $msg
+ }
+ lappend x [gets $f]
+ close $f
+ set x
+} {ready done {}}
+
+if [info exists port] {
+ incr port
+} else {
+ set port [expr {$tlsServerPort + [pid]%1024}]
+}
+
+test tlsIO-2.2 {tcp connection with client port specified} {socket stdio} {
+ removeFile script
+ set f [open script w]
+ puts $f {
+ set auto_path [linsert $auto_path 0 [lindex [split $env(PATH) ";:"] 0]]
+ package require tls
+ set timer [after 2000 "set x done"]
+ }
+ puts $f "set f \[tls::socket -server accept -certfile $serverCert -cafile $caCert -keyfile $serverKey 8829 \]"
+ puts $f {
+ proc accept {sock addr port} {
+ global x
+ puts "[gets $sock] $port"
+ close $sock
+ set x done
+ }
+ puts ready
+ vwait x
+ after cancel $timer
+ close $f
+ }
+ close $f
+ set f [open "|[list $::tcltest::tcltest script]" r]
+ gets $f x
+ global port
+ if {[catch {tls::socket -myport $port \
+ -certfile $clientCert -cafile $caCert \
+ -keyfile $clientKey 127.0.0.1 8829} sock]} {
+ set x $sock
+ catch {close [tls::socket 127.0.0.1 8829]}
+ } else {
+ puts $sock hello
+ flush $sock
+ lappend x [gets $f]
+ close $sock
+ }
+ close $f
+ set x
+} [list ready "hello $port"]
+
+test tlsIO-2.3 {tcp connection with client interface specified} {socket stdio} {
+ removeFile script
+ set f [open script w]
+ puts $f {
+ set auto_path [linsert $auto_path 0 [lindex [split $env(PATH) ";:"] 0]]
+ package require tls
+ set timer [after 2000 "set x done"]
+ }
+ puts $f "set f \[tls::socket -server accept -certfile $serverCert -cafile $caCert -keyfile $serverKey 8830 \]"
+ puts $f {
+ proc accept {sock addr port} {
+ global x
+ puts "[gets $sock] $addr"
+ close $sock
+ set x done
+ }
+ puts ready
+ vwait x
+ after cancel $timer
+ close $f
+ }
+ close $f
+ set f [open "|[list $::tcltest::tcltest script]" r]
+ gets $f x
+ if {[catch {tls::socket -myaddr 127.0.0.1 \
+ -certfile $clientCert -cafile $caCert \
+ -keyfile $clientKey 127.0.0.1 8830} sock]} {
+ set x $sock
+ } else {
+ puts $sock hello
+ catch {flush $sock}
+ lappend x [gets $f]
+ close $sock
+ }
+ close $f
+ set x
+} {ready {hello 127.0.0.1}}
+
+test tlsIO-2.4 {tcp connection with server interface specified} {socket stdio} {
+ removeFile script
+ set f [open script w]
+ puts $f {
+ set auto_path [linsert $auto_path 0 [lindex [split $env(PATH) ";:"] 0]]
+ package require tls
+ set timer [after 2000 "set x done"]
+ }
+ puts $f "set f \[tls::socket -server accept -certfile $serverCert -cafile $caCert -keyfile $serverKey -myaddr [info hostname] 8831 \]"
+ puts $f {
+ proc accept {sock addr port} {
+ global x
+ puts "[gets $sock]"
+ close $sock
+ set x done
+ }
+ puts ready
+ vwait x
+ after cancel $timer
+ close $f
+ }
+ close $f
+ set f [open "|[list $::tcltest::tcltest script]" r]
+ gets $f x
+ if {[catch {tls::socket -certfile $clientCert -cafile $caCert \
+ -keyfile $clientKey [info hostname] 8831} sock]} {
+ set x $sock
+ } else {
+ puts $sock hello
+ flush $sock
+ lappend x [gets $f]
+ close $sock
+ }
+ close $f
+ set x
+} {ready hello}
+
+test tlsIO-2.5 {tcp connection with redundant server port} {socket stdio} {
+ removeFile script
+ set f [open script w]
+ puts $f {
+ set auto_path [linsert $auto_path 0 [lindex [split $env(PATH) ";:"] 0]]
+ package require tls
+ set timer [after 2000 "set x done"]
+ }
+ puts $f "set f \[tls::socket -server accept -certfile $serverCert -cafile $caCert -keyfile $serverKey 8832 \]"
+ puts $f {
+ proc accept {sock addr port} {
+ global x
+ puts "[gets $sock]"
+ close $sock
+ set x done
+ }
+ puts ready
+ vwait x
+ after cancel $timer
+ close $f
+ }
+ close $f
+ set f [open "|[list $::tcltest::tcltest script]" r]
+ gets $f x
+ if {[catch {tls::socket -certfile $clientCert -cafile $caCert \
+ -keyfile $clientKey 127.0.0.1 8832} sock]} {
+ set x $sock
+ } else {
+ puts $sock hello
+ flush $sock
+ lappend x [gets $f]
+ close $sock
+ }
+ close $f
+ set x
+} {ready hello}
+test tlsIO-2.6 {tcp connection} {socket} {
+ set status ok
+ if {![catch {set sock [tls::socket 127.0.0.1 8833]}]} {
+ if {![catch {gets $sock}]} {
+ set status broken
+ }
+ close $sock
+ }
+ set status
+} ok
+
+test tlsIO-2.7 {echo server, one line} {socket stdio} {
+ removeFile script
+ set f [open script w]
+ puts $f {
+ set auto_path [linsert $auto_path 0 [lindex [split $env(PATH) ";:"] 0]]
+ package require tls
+ set timer [after 2000 "set x done"]
+ }
+ puts $f "set f \[tls::socket -server accept -certfile $serverCert -cafile $caCert -keyfile $serverKey 8834 \]"
+ puts $f {
+ proc accept {s a p} {
+ fileevent $s readable [list echo $s]
+ fconfigure $s -translation lf -buffering line
+ }
+ proc echo {s} {
+ set l [gets $s]
+ if {[eof $s]} {
+ global x
+ close $s
+ set x done
+ } else {
+ puts $s $l
+ }
+ }
+ puts ready
+ vwait x
+ after cancel $timer
+ close $f
+ puts done
+ }
+ close $f
+ set f [open "|[list $::tcltest::tcltest script]" r]
+ gets $f
+ set s [tls::socket -certfile $clientCert -cafile $caCert \
+ -keyfile $clientKey 127.0.0.1 8834]
+ fconfigure $s -buffering line -translation lf
+ puts $s "hello abcdefghijklmnop"
+ after 1000
+ set x [gets $s]
+ close $s
+ set y [gets $f]
+ close $f
+ list $x $y
+} {{hello abcdefghijklmnop} done}
+
+test tlsIO-2.8 {echo server, loop 50 times, single connection} {socket stdio} {
+ set f [open script w]
+ puts $f {
+ set auto_path [linsert $auto_path 0 [lindex [split $env(PATH) ";:"] 0]]
+ package require tls
+ }
+ puts $f "set f \[tls::socket -server accept -certfile $serverCert -cafile $caCert -keyfile $serverKey 8835 \]"
+ puts $f {
+ proc accept {s a p} {
+ fileevent $s readable [list echo $s]
+ fconfigure $s -buffering line
+ }
+ proc echo {s} {
+ global i
+ set l [gets $s]
+ if {[eof $s]} {
+ global x
+ close $s
+ set x done
+ } else {
+ incr i
+ puts $s $l
+ }
+ }
+ set i 0
+ puts ready
+ set timer [after 20000 "set x done"]
+ vwait x
+ after cancel $timer
+ close $f
+ puts "done $i"
+ }
+ close $f
+ set f [open "|[list $::tcltest::tcltest script]" r]
+ gets $f
+ set s [tls::socket -certfile $clientCert -cafile $caCert \
+ -keyfile $clientKey 127.0.0.1 8835]
+ fconfigure $s -buffering line
+ catch {
+ for {set x 0} {$x < 50} {incr x} {
+ puts $s "hello abcdefghijklmnop"
+ gets $s
+ }
+ }
+ close $s
+ catch {set x [gets $f]}
+ close $f
+ set x
+} {done 50}
+
+test tlsIO-2.9 {socket conflict} {socket stdio} {
+ set s [tls::socket -server accept 8828]
+ removeFile script
+ set f [open script w]
+ puts -nonewline $f {
+ set auto_path [linsert $auto_path 0 [lindex [split $env(PATH) ";:"] 0]]
+ package require tls
+ tls::socket -server accept 8828
+ }
+ close $f
+ set f [open "|[list $::tcltest::tcltest script]" r]
+ gets $f
+ after 100
+ set x [list [catch {close $f} msg] [string range $msg 0 43]]
+ close $s
+ set x
+} {1 {couldn't open socket: address already in use}}
+
+test tlsIO-2.10 {close on accept, accepted socket lives} {socket} {
+ set done 0
+ set timer [after 20000 "set done timed_out"]
+ set ss [tls::socket -server accept -certfile $serverCert -cafile $caCert \
+ -keyfile $serverKey 8830]
+ proc accept {s a p} {
+ global ss
+ close $ss
+ fileevent $s readable "readit $s"
+ fconfigure $s -trans lf
+ }
+ proc readit {s} {
+ global done
+ gets $s
+ close $s
+ set done 1
+ }
+ set cs [tls::socket -certfile $clientCert -cafile $caCert \
+ -keyfile $clientKey [info hostname] 8830]
+ close $cs
+
+ vwait done
+ after cancel $timer
+ set done
+} 1
+
+test tlsIO-2.11 {detecting new data} {socket} {
+ proc accept {s a p} {
+ global sock
+ # when doing an in-process client/server test, both sides need
+ # to be non-blocking for the TLS handshake. Also make sure
+ # to return the channel to line buffering mode.
+ fconfigure $s -blocking 0 -buffering line
+ set sock $s
+ fileevent $s readable [list do_handshake $s]
+ }
+
+ set s [tls::socket -server accept \
+ -certfile $serverCert -cafile $caCert -keyfile $serverKey 8400]
+ set sock ""
+ set s2 [tls::socket -certfile $clientCert -cafile $caCert \
+ -keyfile $clientKey 127.0.0.1 8400]
+ # when doing an in-process client/server test, both sides need
+ # to be non-blocking for the TLS handshake Also make sure to
+ # return the channel to line buffering mode (TLS sets it to 'none').
+ fconfigure $s2 -blocking 0 -buffering line
+ vwait sock
+ puts $s2 one
+ flush $s2
+ # need update to complete TLS handshake in-process
+ update
+ after 500
+ fconfigure $sock -blocking 0
+ set result a:[gets $sock]
+ lappend result b:[gets $sock]
+ fconfigure $sock -blocking 1
+ puts $s2 two
+ flush $s2
+ fconfigure $sock -blocking 0
+ lappend result c:[gets $sock]
+ fconfigure $sock -blocking 1
+ close $s2
+ close $s
+ close $sock
+ set result
+} {a:one b: c:two}
+
+test tlsIO-2.12 {tcp connection; no certificates specified} \
+ {socket stdio unixOnly} {
+ # There is a debug assertion on Windows/SSL that causes a crash when the
+ # certificate isn't specified.
+ removeFile script
+ set f [open script w]
+ puts $f {
+ set auto_path [linsert $auto_path 0 [lindex [split $env(PATH) ";:"] 0]]
+ package require tls
+ set timer [after 2000 "set x timed_out"]
+ set f [tls::socket -server accept 8828]
+ proc accept {file addr port} {
+ global x
+ set x done
+ close $file
+ }
+ puts ready
+ vwait x
+ after cancel $timer
+ close $f
+ puts $x
+ }
+ close $f
+ set f [open "|[list $::tcltest::tcltest script]" r]
+ gets $f x
+ if {[catch {tls::socket 127.0.0.1 8828} msg]} {
+ set x $msg
+ } else {
+ lappend x [gets $f]
+ close $msg
+ }
+ lappend x [gets $f]
+ close $f
+ set x
+} {ready done {}}
+
+test tlsIO-3.1 {socket conflict} {socket stdio} {
+ removeFile script
+ set f [open script w]
+ puts $f {
+ set auto_path [linsert $auto_path 0 [lindex [split $env(PATH) ";:"] 0]]
+ package require tls
+ }
+ puts $f "set f \[tls::socket -server accept -certfile $serverCert -cafile $caCert -keyfile $serverKey 8828 \]"
+ puts $f {
+ puts ready
+ gets stdin
+ close $f
+ }
+ close $f
+ set f [open "|[list $::tcltest::tcltest script]" r+]
+ gets $f
+ set x [list [catch {tls::socket \
+ -certfile $clientCert -cafile $caCert -keyfile $clientKey \
+ -server accept 8828} msg] \
+ $msg]
+ puts $f bye
+ close $f
+ set x
+} {1 {couldn't open socket: address already in use}}
+
+test tlsIO-3.2 {server with several clients} {socket stdio} {
+ removeFile script
+ set f [open script w]
+ puts $f {
+ set auto_path [linsert $auto_path 0 [lindex [split $env(PATH) ";:"] 0]]
+ package require tls
+ set t1 [after 30000 "set x timed_out"]
+ set t2 [after 31000 "set x timed_out"]
+ set t3 [after 32000 "set x timed_out"]
+ set counter 0
+ }
+ puts $f "set s \[tls::socket -server accept -certfile $serverCert -cafile $caCert -keyfile $serverKey 8828 \]"
+ puts $f {
+ proc accept {s a p} {
+ fileevent $s readable [list echo $s]
+ fconfigure $s -buffering line
+ }
+ proc echo {s} {
+ global x
+ set l [gets $s]
+ if {[eof $s]} {
+ close $s
+ set x done
+ } else {
+ puts $s $l
+ }
+ }
+ puts ready
+ vwait x
+ after cancel $t1
+ vwait x
+ after cancel $t2
+ vwait x
+ after cancel $t3
+ close $s
+ puts $x
+ }
+ close $f
+ set f [open "|[list $::tcltest::tcltest script]" r+]
+ set x [gets $f]
+ set s1 [tls::socket \
+ -certfile $clientCert -cafile $caCert -keyfile $clientKey \
+ 127.0.0.1 8828]
+ fconfigure $s1 -buffering line
+ set s2 [tls::socket \
+ -certfile $clientCert -cafile $caCert -keyfile $clientKey \
+ 127.0.0.1 8828]
+ fconfigure $s2 -buffering line
+ set s3 [tls::socket \
+ -certfile $clientCert -cafile $caCert -keyfile $clientKey \
+ 127.0.0.1 8828]
+ fconfigure $s3 -buffering line
+ for {set i 0} {$i < 100} {incr i} {
+ puts $s1 hello,s1
+ gets $s1
+ puts $s2 hello,s2
+ gets $s2
+ puts $s3 hello,s3
+ gets $s3
+ }
+ close $s1
+ close $s2
+ close $s3
+ lappend x [gets $f]
+ close $f
+ set x
+} {ready done}
+
+test tlsIO-4.1 {server with several clients} {socket stdio} {
+ # have seen intermittent hangs on Windows
+ removeFile script
+ set f [open script w]
+ puts $f {
+ set auto_path [linsert $auto_path 0 [lindex [split $env(PATH) ";:"] 0]]
+ package require tls
+ gets stdin
+ }
+ puts $f "set s \[tls::socket -certfile $clientCert -cafile $caCert -keyfile $clientKey 127.0.0.1 8828 \]"
+ puts $f {
+ fconfigure $s -buffering line
+ for {set i 0} {$i < 100} {incr i} {
+ puts $s hello
+ gets $s
+ }
+ close $s
+ puts bye
+ gets stdin
+ }
+ close $f
+ set p1 [open "|[list $::tcltest::tcltest script]" r+]
+ fconfigure $p1 -buffering line
+ set p2 [open "|[list $::tcltest::tcltest script]" r+]
+ fconfigure $p2 -buffering line
+ set p3 [open "|[list $::tcltest::tcltest script]" r+]
+ fconfigure $p3 -buffering line
+ proc accept {s a p} {
+ fconfigure $s -buffering line
+ fileevent $s readable [list echo $s]
+ }
+ proc echo {s} {
+ global x
+ set l [gets $s]
+ if {[eof $s]} {
+ close $s
+ set x done
+ } else {
+ puts $s $l
+ }
+ }
+ set t1 [after 30000 "set x timed_out"]
+ set t2 [after 31000 "set x timed_out"]
+ set t3 [after 32000 "set x timed_out"]
+ set s [tls::socket \
+ -certfile $serverCert -cafile $caCert -keyfile $serverKey \
+ -server accept 8828]
+ puts $p1 open
+ puts $p2 open
+ puts $p3 open
+ vwait x
+ vwait x
+ vwait x
+ after cancel $t1
+ after cancel $t2
+ after cancel $t3
+ close $s
+ set l ""
+ lappend l [list p1 [gets $p1] $x]
+ lappend l [list p2 [gets $p2] $x]
+ lappend l [list p3 [gets $p3] $x]
+ puts $p1 bye
+ puts $p2 bye
+ puts $p3 bye
+ close $p1
+ close $p2
+ close $p3
+ set l
+} {{p1 bye done} {p2 bye done} {p3 bye done}}
+
+test tlsIO-4.2 {byte order problems, socket numbers, htons} {socket} {
+ set x ok
+ if {[catch {tls::socket -server dodo 0x3000} msg]} {
+ set x $msg
+ } else {
+ close $msg
+ }
+ set x
+} ok
+
+test tlsIO-5.1 {byte order problems, socket numbers, htons} \
+ {socket unixOnly notRoot} {
+ set x {couldn't open socket: not owner}
+ if {![catch {tls::socket -server dodo 0x1} msg]} {
+ set x {htons problem, should be disallowed, are you running as SU?}
+ close $msg
+ }
+ set x
+} {couldn't open socket: not owner}
+test tlsIO-5.2 {byte order problems, socket numbers, htons} {socket} {
+ set x {couldn't open socket: port number too high}
+ if {![catch {tls::socket -server dodo 0x10000} msg]} {
+ set x {port resolution problem, should be disallowed}
+ close $msg
+ }
+ set x
+} {couldn't open socket: port number too high}
+test tlsIO-5.3 {byte order problems, socket numbers, htons} \
+ {socket unixOnly notRoot} {
+ set x {couldn't open socket: not owner}
+ if {![catch {tls::socket -server dodo 21} msg]} {
+ set x {htons problem, should be disallowed, are you running as SU?}
+ close $msg
+ }
+ set x
+} {couldn't open socket: not owner}
+
+test tlsIO-6.1 {accept callback error} {socket stdio} {
+ # There is a debug assertion on Windows/SSL that causes a crash when the
+ # certificate isn't specified.
+ removeFile script
+ set f [open script w]
+ puts $f {
+ set auto_path [linsert $auto_path 0 [lindex [split $env(PATH) ";:"] 0]]
+ package require tls
+ gets stdin
+ }
+ puts $f [list tls::socket -cafile $caCert 127.0.0.1 8848]
+ close $f
+ set f [open "|[list $::tcltest::tcltest script]" r+]
+ proc bgerror args {
+ global x
+ set x $args
+ }
+ proc accept {s a p} {expr 10 / 0}
+ set s [tls::socket -server accept \
+ -certfile $serverCert -cafile $caCert -keyfile $serverKey 8848]
+ puts $f hello
+ close $f
+ set timer [after 10000 "set x timed_out"]
+ vwait x
+ after cancel $timer
+ close $s
+ rename bgerror {}
+ set x
+} {{divide by zero}}
+
+test tlsIO-7.1 {testing socket specific options} {socket stdio} {
+ removeFile script
+ set f [open script w]
+ puts $f {
+ set auto_path [linsert $auto_path 0 [lindex [split $env(PATH) ";:"] 0]]
+ package require tls
+ }
+ puts $f [list tls::socket -server accept \
+ -certfile $serverCert -cafile $caCert -keyfile $serverKey 8820]
+ puts $f {
+ proc accept args {
+ global x
+ set x done
+ }
+ puts ready
+ set timer [after 10000 "set x timed_out"]
+ vwait x
+ after cancel $timer
+ }
+ close $f
+ set f [open "|[list $::tcltest::tcltest script]" r]
+ gets $f
+ set s [tls::socket \
+ -certfile $clientCert -cafile $caCert -keyfile $clientKey \
+ 127.0.0.1 8820]
+ set p [fconfigure $s -peername]
+ close $s
+ close $f
+ set l ""
+ lappend l [string compare [lindex $p 0] 127.0.0.1]
+ lappend l [string compare [lindex $p 2] 8820]
+ lappend l [llength $p]
+} {0 0 3}
+
+test tlsIO-7.2 {testing socket specific options} {socket stdio} {
+ removeFile script
+ set f [open script w]
+ puts $f {
+ set auto_path [linsert $auto_path 0 [lindex [split $env(PATH) ";:"] 0]]
+ package require tls
+ }
+ puts $f "tls::socket -server accept -certfile $serverCert -cafile $caCert -keyfile $serverKey 8821"
+ puts $f {
+ proc accept args {
+ global x
+ set x done
+ }
+ puts ready
+ set timer [after 10000 "set x timed_out"]
+ vwait x
+ after cancel $timer
+ }
+ close $f
+ set f [open "|[list $::tcltest::tcltest script]" r]
+ gets $f
+ set s [tls::socket \
+ -certfile $clientCert -cafile $caCert -keyfile $clientKey \
+ 127.0.0.1 8821]
+ set p [fconfigure $s -sockname]
+ close $s
+ close $f
+ set l ""
+ lappend l [llength $p]
+ lappend l [lindex $p 0]
+ lappend l [string equal [lindex $p 2] 8821]
+} {3 127.0.0.1 0}
+
+test tlsIO-7.3 {testing socket specific options} {socket} {
+ set s [tls::socket \
+ -certfile $serverCert -cafile $caCert -keyfile $serverKey \
+ -server accept 8822]
+ set l [llength [fconfigure $s]]
+ close $s
+ update
+ # A bug fixed in fconfigure for 8.3.4+ make this return 14 normally,
+ # but 12 in older versions.
+ expr {$l >= 12 && (($l % 2) == 0)}
+} 1
+
+# bug report #5812 fconfigure doesn't return value for '-sockname'
+
+test tlsIO-7.4 {testing socket specific options} {socket} {
+ set s [tls::socket \
+ -certfile $serverCert -cafile $caCert -keyfile $serverKey \
+ -server accept 8823]
+ proc accept {s a p} {
+ global x
+ set x [fconfigure $s -sockname]
+ close $s
+ }
+ set s1 [tls::socket \
+ -certfile $clientCert -cafile $caCert -keyfile $clientKey \
+ [info hostname] 8823]
+ set timer [after 10000 "set x timed_out"]
+ vwait x
+ after cancel $timer
+ close $s
+ close $s1
+ set l ""
+ lappend l [lindex $x 2] [llength $x]
+} {8823 3}
+
+# bug report #5812 fconfigure doesn't return value for '-sockname'
+
+test tlsIO-7.5 {testing socket specific options} {socket unixOrPc} {
+ set s [tls::socket \
+ -certfile $serverCert -cafile $caCert -keyfile $serverKey \
+ -server accept 8829]
+ proc accept {s a p} {
+ global x
+ set x [fconfigure $s -sockname]
+ close $s
+ }
+ set s1 [tls::socket \
+ -certfile $clientCert -cafile $caCert -keyfile $clientKey \
+ 127.0.0.1 8829]
+ set timer [after 10000 "set x timed_out"]
+ vwait x
+ after cancel $timer
+ close $s
+ close $s1
+ set l ""
+ lappend l [lindex $x 0] [lindex $x 2] [llength $x]
+} {127.0.0.1 8829 3}
+
+test tlsIO-8.1 {testing -async flag on sockets} {socket} {
+ # NOTE: This test may fail on some Solaris 2.4 systems.
+ # See notes in Tcl's socket.test.
+ set s [tls::socket \
+ -certfile $serverCert -cafile $caCert -keyfile $serverKey \
+ -server accept 8830]
+ proc accept {s a p} {
+ global x
+ # when doing an in-process client/server test, both sides need
+ # to be non-blocking for the TLS handshake. Also make sure
+ # to return the channel to line buffering mode.
+ fconfigure $s -blocking 0 -buffering line
+ puts $s bye
+ # Only OpenSSL 0.9.5a on Windows seems to need the after (delayed)
+ # close, but it works just the same for all others. -hobbs
+ after 500 close $s
+ set x done
+ }
+ set s1 [tls::socket \
+ -certfile $clientCert -cafile $caCert -keyfile $clientKey \
+ -async [info hostname] 8830]
+ # when doing an in-process client/server test, both sides need
+ # to be non-blocking for the TLS handshake Also make sure to
+ # return the channel to line buffering mode (TLS sets it to 'none').
+ fconfigure $s1 -blocking 0 -buffering line
+ vwait x
+ # TLS handshaking needs one byte from the client...
+ puts $s1 a
+ # need update to complete TLS handshake in-process
+ update
+ set z [gets $s1]
+ close $s
+ close $s1
+ set z
+} bye
+
+test tlsIO-9.1 {testing spurious events} {socket} {
+ set len 0
+ set spurious 0
+ set done 0
+ proc readlittle {s} {
+ global spurious done len
+ set l [read $s 1]
+ if {[string length $l] == 0} {
+ if {![eof $s]} {
+ incr spurious
+ } else {
+ close $s
+ set done 1
+ }
+ } else {
+ incr len [string length $l]
+ }
+ }
+ proc accept {s a p} {
+ fconfigure $s -blocking 0
+ fileevent $s readable [list do_handshake $s readable readlittle \
+ -buffering none]
+ }
+ set s [tls::socket \
+ -certfile $serverCert -cafile $caCert -keyfile $serverKey \
+ -server accept 8831]
+ set c [tls::socket \
+ -certfile $clientCert -cafile $caCert -keyfile $clientKey \
+ [info hostname] 8831]
+ # This differs from socket-9.1 in that both sides need to be
+ # non-blocking because of TLS' required handshake
+ fconfigure $c -blocking 0
+ puts -nonewline $c 01234567890123456789012345678901234567890123456789
+ close $c
+ set timer [after 10000 "set done timed_out"]
+ vwait done
+ after cancel $timer
+ close $s
+ list $spurious $len
+} {0 50}
+
+test tlsIO-9.2 {testing async write, fileevents, flush on close} {socket} {
+ set firstblock [string repeat a 31]
+ set secondblock [string repeat b 65535]
+ proc accept {s a p} {
+ fconfigure $s -blocking 0
+ fileevent $s readable [list do_handshake $s readable readable \
+ -translation lf -buffersize 16384 -buffering line]
+ }
+ proc readable {s} {
+ set l [gets $s]
+ dputs "got \"[string replace $l 10 end-3 ...]\" \
+ ([string length $l]) from $s"
+ fileevent $s readable {}
+ after 1000 respond $s
+ }
+ proc respond {s} {
+ global firstblock
+ dputs "send \"[string replace $firstblock 10 end-3 ...]\" \
+ ([string length $firstblock]) down $s"
+ puts -nonewline $s $firstblock
+ after 1000 writedata $s
+ }
+ proc writedata {s} {
+ global secondblock
+ dputs "send \"[string replace $secondblock 10 end-3 ...]\" \
+ ([string length $secondblock]) down $s"
+ puts -nonewline $s $secondblock
+ close $s
+ }
+ set s [tls::socket \
+ -certfile $serverCert -cafile $caCert -keyfile $serverKey \
+ -server accept 8832]
+ set c [tls::socket \
+ -certfile $clientCert -cafile $caCert -keyfile $clientKey \
+ [info hostname] 8832]
+ fconfigure $c -blocking 0 -trans lf -buffering line
+ set count 0
+ puts $c hello
+ proc readit {s} {
+ global count done
+ set data [read $s]
+ dputs "read \"[string replace $data 10 end-3 ...]\" \
+ ([string length $data]) from $s"
+ incr count [string length $data]
+ if {[eof $s]} {
+ close $s
+ set done 1
+ }
+ }
+ fileevent $c readable "readit $c"
+ set done 0
+ set timer [after 10000 "set done timed_out"]
+ vwait done
+ after cancel $timer
+ close $s
+ list $count $done
+} {65566 1}
+
+test tlsIO-9.3 {testing EOF stickyness} {unexplainedFailure socket} {
+ # HOBBS: never worked correctly
+ proc count_to_eof {s} {
+ global count done timer
+ set l [gets $s]
+ if {[eof $s]} {
+ incr count
+ if {$count > 9} {
+ close $s
+ set done true
+ set count {eof is sticky}
+ after cancel $timer
+ }
+ }
+ }
+ proc timerproc {} {
+ global done count c
+ set done true
+ set count {timer went off, eof is not sticky}
+ close $c
+ }
+ set count 0
+ set done false
+ proc write_then_close {s} {
+ puts $s bye
+ close $s
+ }
+ proc accept {s a p} {
+ fconfigure $s -blocking 0 -buffering line -translation lf
+ fileevent $s writable [list do_handshake $s writable write_then_close \
+ -buffering line -translation lf]
+ }
+ set s [tls::socket \
+ -certfile $serverCert -cafile $caCert -keyfile $serverKey \
+ -server accept 8833]
+ set c [tls::socket \
+ -certfile $clientCert -cafile $caCert -keyfile $clientKey \
+ [info hostname] 8833]
+ fconfigure $c -blocking 0 -buffering line -translation lf
+ fileevent $c readable "count_to_eof $c"
+ set timer [after 2000 timerproc]
+ vwait done
+ close $s
+ set count
+} {eof is sticky}
+
+removeFile script
+
+test tlsIO-10.1 {testing socket accept callback error handling} {socket} {
+ set goterror 0
+ proc bgerror args {global goterror; set goterror 1}
+ set s [tls::socket -cafile $caCert -server accept 8898]
+ proc accept {s a p} {close $s; error}
+ set c [tls::socket -cafile $caCert 127.0.0.1 8898]
+ vwait goterror
+ close $s
+ close $c
+ set goterror
+} 1
+
+test tlsIO-11.1 {tcp connection} {socket doTestsWithRemoteServer} {
+ sendCertValues
+ sendCommand {
+ set socket9_1_test_server [tls::socket -server accept \
+ -certfile $serverCert -cafile $caCert -keyfile $serverKey 8834]
+ proc accept {s a p} {
+ tls::handshake $s
+ puts $s done
+ close $s
+ }
+ }
+ set s [tls::socket \
+ -certfile $clientCert -cafile $caCert -keyfile $clientKey \
+ $remoteServerIP 8834]
+ set r [gets $s]
+ close $s
+ sendCommand {close $socket9_1_test_server}
+ set r
+} done
+
+test tlsIO-11.2 {client specifies its port} {socket doTestsWithRemoteServer} {
+ if {[info exists port]} {
+ incr port
+ } else {
+ set port [expr {$tlsServerPort + [pid]%1024}]
+ }
+ sendCertValues
+ sendCommand {
+ set socket9_2_test_server [tls::socket -server accept \
+ -certfile $serverCert -cafile $caCert -keyfile $serverKey 8835]
+ proc accept {s a p} {
+ tls::handshake $s
+ puts $s $p
+ close $s
+ }
+ }
+ set s [tls::socket \
+ -certfile $clientCert -cafile $caCert -keyfile $clientKey \
+ -myport $port $remoteServerIP 8835]
+ set r [gets $s]
+ close $s
+ sendCommand {close $socket9_2_test_server}
+ if {$r == $port} {
+ set result ok
+ } else {
+ set result broken
+ }
+ set result
+} ok
+
+test tlsIO-11.3 {trying to connect, no server} {socket doTestsWithRemoteServer} {
+ set status ok
+ if {![catch {set s [tls::socket \
+ -certfile $clientCert -cafile $caCert -keyfile $clientKey \
+ $remoteServerIp 8836]}]} {
+ if {![catch {gets $s}]} {
+ set status broken
+ }
+ close $s
+ }
+ set status
+} ok
+
+test tlsIO-11.4 {remote echo, one line} {socket doTestsWithRemoteServer} {
+ sendCertValues
+ sendCommand {
+ set socket10_6_test_server [tls::socket \
+ -certfile $serverCert -cafile $caCert -keyfile $serverKey \
+ -server accept 8836]
+ proc accept {s a p} {
+ tls::handshake $s
+ fileevent $s readable [list echo $s]
+ fconfigure $s -buffering line -translation crlf
+ }
+ proc echo {s} {
+ set l [gets $s]
+ if {[eof $s]} {
+ close $s
+ } else {
+ puts $s $l
+ }
+ }
+ }
+ set f [tls::socket \
+ -certfile $clientCert -cafile $caCert -keyfile $clientKey \
+ $remoteServerIP 8836]
+ fconfigure $f -translation crlf -buffering line
+ puts $f hello
+ set r [gets $f]
+ close $f
+ sendCommand {close $socket10_6_test_server}
+ set r
+} hello
+
+test tlsIO-11.5 {remote echo, 50 lines} {socket doTestsWithRemoteServer} {
+ sendCertValues
+ sendCommand {
+ set socket10_7_test_server [tls::socket -server accept \
+ -certfile $serverCert -cafile $caCert -keyfile $serverKey 8836]
+ proc accept {s a p} {
+ tls::handshake $s
+ fileevent $s readable [list echo $s]
+ fconfigure $s -buffering line -translation crlf
+ }
+ proc echo {s} {
+ set l [gets $s]
+ if {[eof $s]} {
+ close $s
+ } else {
+ puts $s $l
+ }
+ }
+ }
+ set f [tls::socket \
+ -certfile $clientCert -cafile $caCert -keyfile $clientKey \
+ $remoteServerIP 8836]
+ fconfigure $f -translation crlf -buffering line
+ for {set cnt 0} {$cnt < 50} {incr cnt} {
+ puts $f "hello, $cnt"
+ if {[string compare [gets $f] "hello, $cnt"] != 0} {
+ break
+ }
+ }
+ close $f
+ sendCommand {close $socket10_7_test_server}
+ set cnt
+} 50
+
+# Macintosh sockets can have more than one server per port
+if {$tcl_platform(platform) == "macintosh"} {
+ set conflictResult {0 8836}
+} else {
+ set conflictResult {1 {couldn't open socket: address already in use}}
+}
+
+test tlsIO-11.6 {socket conflict} {socket doTestsWithRemoteServer} {
+ set s1 [tls::socket \
+ -certfile $serverCert -cafile $caCert -keyfile $serverKey \
+ -server accept 8836]
+ if {[catch {set s2 [tls::socket \
+ -certfile $serverCert -cafile $caCert -keyfile $serverKey \
+ -server accept 8836]} msg]} {
+ set result [list 1 $msg]
+ } else {
+ set result [list 0 [lindex [fconfigure $s2 -sockname] 2]]
+ close $s2
+ }
+ close $s1
+ set result
+} $conflictResult
+
+test tlsIO-11.7 {server with several clients} {socket doTestsWithRemoteServer} {
+ sendCertValues
+ sendCommand {
+ set socket10_9_test_server [tls::socket \
+ -certfile $serverCert -cafile $caCert -keyfile $serverKey \
+ -server accept 8836]
+ proc accept {s a p} {
+ fconfigure $s -buffering line
+ fileevent $s readable [list echo $s]
+ }
+ proc echo {s} {
+ set l [gets $s]
+ if {[eof $s]} {
+ close $s
+ } else {
+ puts $s $l
+ }
+ }
+ }
+ set s1 [tls::socket \
+ -certfile $clientCert -cafile $caCert -keyfile $clientKey \
+ $remoteServerIP 8836]
+ fconfigure $s1 -buffering line
+ set s2 [tls::socket \
+ -certfile $clientCert -cafile $caCert -keyfile $clientKey \
+ $remoteServerIP 8836]
+ fconfigure $s2 -buffering line
+ set s3 [tls::socket \
+ -certfile $clientCert -cafile $caCert -keyfile $clientKey \
+ $remoteServerIP 8836]
+ fconfigure $s3 -buffering line
+ for {set i 0} {$i < 100} {incr i} {
+ puts $s1 hello,s1
+ gets $s1
+ puts $s2 hello,s2
+ gets $s2
+ puts $s3 hello,s3
+ gets $s3
+ }
+ close $s1
+ close $s2
+ close $s3
+ sendCommand {close $socket10_9_test_server}
+ set i
+} 100
+
+test tlsIO-11.8 {client with several servers} {socket doTestsWithRemoteServer} {
+ sendCertValues
+ sendCommand {
+ tls::init -certfile $serverCert -cafile $caCert -keyfile $serverKey
+ set s1 [tls::socket -server "accept 4003" 4003]
+ set s2 [tls::socket -server "accept 4004" 4004]
+ set s3 [tls::socket -server "accept 4005" 4005]
+ proc handshake {s mp} {
+ if {[eof $s]} {
+ close $s
+ } elseif {[catch {tls::handshake $s} result]} {
+ # Some errors are normal.
+ } elseif {$result == 1} {
+ # Handshake complete
+ fileevent $s readable ""
+ puts $s $mp
+ close $s
+ }
+ }
+ proc accept {mp s a p} {
+ # These have to accept non-blocking, because the handshaking
+ # order isn't deterministic
+ fconfigure $s -blocking 0 -buffering line
+ fileevent $s readable [list handshake $s $mp]
+ }
+ }
+ tls::init -certfile $clientCert -cafile $caCert -keyfile $clientKey
+ set s1 [tls::socket $remoteServerIP 4003]
+ set s2 [tls::socket $remoteServerIP 4004]
+ set s3 [tls::socket $remoteServerIP 4005]
+ set l ""
+ lappend l [gets $s1] [gets $s1] [eof $s1] [gets $s2] [gets $s2] [eof $s2] \
+ [gets $s3] [gets $s3] [eof $s3]
+ close $s1
+ close $s2
+ close $s3
+ sendCommand {
+ close $s1
+ close $s2
+ close $s3
+ }
+ set l
+} {4003 {} 1 4004 {} 1 4005 {} 1}
+
+test tlsIO-11.9 {accept callback error} {socket doTestsWithRemoteServer} {
+ set s [tls::socket \
+ -certfile $serverCert -cafile $caCert -keyfile $serverKey \
+ -server accept 8836]
+ proc accept {s a p} {expr 10 / 0}
+ proc bgerror args {
+ global x
+ set x $args
+ }
+ sendCertValues
+ if {[catch {sendCommand {
+ set peername [fconfigure $callerSocket -peername]
+ set s [tls::socket \
+ -certfile $clientCert -cafile $caCert -keyfile $clientKey \
+ [lindex $peername 0] 8836]
+ close $s
+ }} msg]} {
+ close $s
+ error $msg
+ }
+ set timer [after 10000 "set x timed_out"]
+ vwait x
+ after cancel $timer
+ close $s
+ rename bgerror {}
+ set x
+} {{divide by zero}}
+
+test tlsIO-11.10 {testing socket specific options} {socket doTestsWithRemoteServer} {
+ sendCertValues
+ sendCommand {
+ set socket10_12_test_server [tls::socket \
+ -certfile $serverCert -cafile $caCert -keyfile $serverKey \
+ -server accept 8836]
+ proc accept {s a p} {close $s}
+ }
+ set s [tls::socket \
+ -certfile $clientCert -cafile $caCert -keyfile $clientKey \
+ $remoteServerIP 8836]
+ set p [fconfigure $s -peername]
+ set n [fconfigure $s -sockname]
+ set l ""
+ lappend l [lindex $p 2] [llength $p] [llength $p]
+ close $s
+ sendCommand {close $socket10_12_test_server}
+ set l
+} {8836 3 3}
+
+test tlsIO-11.11 {testing spurious events} {socket doTestsWithRemoteServer} {
+ # remote equivalent of 9.1
+ sendCertValues
+ sendCommand {
+ set socket_test_server [tls::socket -server accept \
+ -certfile $serverCert -cafile $caCert -keyfile $serverKey 8836]
+ proc handshake {s} {
+ if {[eof $s]} {
+ close $s
+ } elseif {[catch {tls::handshake $s} result]} {
+ # Some errors are normal.
+ } elseif {$result == 1} {
+ # Handshake complete
+ fileevent $s writable ""
+ after 100 writesome $s
+ }
+ }
+ proc accept {s a p} {
+ fconfigure $s -translation "auto lf"
+ fileevent $s writable [list handshake $s]
+ }
+ proc writesome {s} {
+ for {set i 0} {$i < 100} {incr i} {
+ puts $s "line $i from remote server"
+ }
+ close $s
+ }
+ }
+ set len 0
+ set spurious 0
+ set done 0
+ proc readlittle {s} {
+ global spurious done len
+ set l [read $s 1]
+ if {[string length $l] == 0} {
+ if {![eof $s]} {
+ incr spurious
+ } else {
+ close $s
+ set done 1
+ }
+ } else {
+ incr len [string length $l]
+ }
+ }
+ set c [tls::socket \
+ -certfile $clientCert -cafile $caCert -keyfile $clientKey \
+ $remoteServerIP 8836]
+ # Get the buffering corrected
+ fconfigure $c -buffering line
+ # Put a byte into the client pipe to trigger TLS handshaking
+ puts $c a
+ fileevent $c readable [list readlittle $c]
+ set timer [after 10000 "set done timed_out"]
+ vwait done
+ after cancel $timer
+ sendCommand {close $socket_test_server}
+ list $spurious $len
+} {0 2690}
+
+test tlsIO-11.12 {testing EOF stickyness} {unexplainedFailure socket doTestsWithRemoteServer} {
+ # remote equivalent of 9.3
+ # HOBBS: never worked correctly
+ set counter 0
+ set done 0
+ proc count_up {s} {
+ global counter done after_id
+ set l [gets $s]
+ if {[eof $s]} {
+ incr counter
+ if {$counter > 9} {
+ set done {EOF is sticky}
+ after cancel $after_id
+ close $s
+ }
+ }
+ }
+ proc timed_out {} {
+ global c done
+ set done {timed_out, EOF is not sticky}
+ close $c
+ }
+ sendCertValues
+ sendCommand {
+ set socket10_14_test_server [tls::socket \
+ -certfile $serverCert -cafile $caCert -keyfile $serverKey \
+ -server accept 8836]
+ proc accept {s a p} {
+ tls::handshake $s
+ after 100 close $s
+ }
+ }
+ set c [tls::socket \
+ -certfile $clientCert -cafile $caCert -keyfile $clientKey \
+ $remoteServerIP 8836]
+ fileevent $c readable "count_up $c"
+ set after_id [after 1000 timed_out]
+ vwait done
+ sendCommand {close $socket10_14_test_server}
+ set done
+} {EOF is sticky}
+
+test tlsIO-11.13 {testing async write, async flush, async close} \
+ {socket doTestsWithRemoteServer} {
+ proc readit {s} {
+ global count done
+ set l [read $s]
+ incr count [string length $l]
+ if {[eof $s]} {
+ close $s
+ set done 1
+ }
+ }
+ sendCertValues
+ sendCommand {
+ set firstblock [string repeat a 31]
+ set secondblock [string repeat b 65535]
+ set l [tls::socket \
+ -certfile $serverCert -cafile $caCert -keyfile $serverKey \
+ -server accept 8845]
+ proc accept {s a p} {
+ tls::handshake $s
+ fconfigure $s -blocking 0 -translation lf -buffersize 16384 \
+ -buffering line
+ fileevent $s readable "readable $s"
+ }
+ proc readable {s} {
+ set l [gets $s]
+ fileevent $s readable {}
+ after 1000 respond $s
+ }
+ proc respond {s} {
+ global firstblock
+ puts -nonewline $s $firstblock
+ after 1000 writedata $s
+ }
+ proc writedata {s} {
+ global secondblock
+ puts -nonewline $s $secondblock
+ close $s
+ }
+ }
+ set s [tls::socket \
+ -certfile $clientCert -cafile $caCert -keyfile $clientKey \
+ $remoteServerIP 8845]
+ fconfigure $s -blocking 0 -translation lf -buffering line
+ set count 0
+ puts $s hello
+ fileevent $s readable "readit $s"
+ set timer [after 10000 "set done timed_out"]
+ vwait done
+ after cancel $timer
+ sendCommand {close $l}
+ set count
+} 65566
+
+proc getdata {type file} {
+ # Read handler on the accepted socket.
+ global x
+ global failed
+ set status [catch {read $file} data]
+ if {$status != 0} {
+ set x "read failed, error was $data"
+ catch { close $file }
+ } elseif {[string compare {} $data]} {
+ } elseif {[fblocked $file]} {
+ } elseif {[eof $file]} {
+ if {$failed} {
+ set x "$type socket was inherited"
+ } else {
+ set x "$type socket was not inherited"
+ }
+ catch { close $file }
+ } else {
+ set x {impossible case}
+ catch { close $file }
+ }
+ return
+}
+
+test tlsIO-12.1 {testing inheritance of server sockets} {socket exec} {
+ makeFile {} script1
+ makeFile {} script2
+
+ # Script1 is just a 10 second delay. If the server socket
+ # is inherited, it will be held open for 10 seconds
+
+ set f [open script1 w]
+ puts $f {
+ after 10000 exit
+ vwait forever
+ }
+ close $f
+
+ # Script2 creates the server socket, launches script1,
+ # waits a second, and exits. The server socket will now
+ # be closed unless script1 inherited it.
+
+ set f [open script2 w]
+ puts $f [list set tclsh $::tcltest::tcltest]
+ puts $f {
+ set auto_path [linsert $auto_path 0 [lindex [split $env(PATH) ";:"] 0]]
+ package require tls
+ }
+ puts $f "set f \[tls::socket -server accept \
+ -certfile $serverCert -cafile $caCert -keyfile $serverKey 8828\]"
+ puts $f {
+ proc accept { file addr port } {
+ close $file
+ }
+ exec $tclsh script1 &
+ close $f
+ after 1000 exit
+ vwait forever
+ }
+ close $f
+
+ # Launch script2 and wait 5 seconds
+
+ exec $::tcltest::tcltest script2 &
+ after 5000 { set ok_to_proceed 1 }
+ vwait ok_to_proceed
+
+ # If we can still connect to the server, the socket got inherited.
+
+ if {[catch {tls::socket \
+ -certfile $clientCert -cafile $caCert -keyfile $clientKey \
+ 127.0.0.1 8828} msg]} {
+ set x {server socket was not inherited}
+ } else {
+ close $msg
+ set x {server socket was inherited}
+ }
+
+ set x
+} {server socket was not inherited}
+
+test tlsIO-12.2 {testing inheritance of client sockets} {socket exec} {
+ makeFile {} script1
+ makeFile {} script2
+
+ # Script1 is just a 10 second delay. If the server socket
+ # is inherited, it will be held open for 10 seconds
+
+ set f [open script1 w]
+ puts $f {
+ after 10000 exit
+ vwait forever
+ }
+ close $f
+
+ # Script2 opens the client socket and writes to it. It then
+ # launches script1 and exits. If the child process inherited the
+ # client socket, the socket will still be open.
+
+ set f [open script2 w]
+ puts $f [list set tclsh $::tcltest::tcltest]
+ puts $f {
+ set auto_path [linsert $auto_path 0 [lindex [split $env(PATH) ";:"] 0]]
+ package require tls
+ }
+ puts $f "set f \[tls::socket -certfile $clientCert -cafile $caCert \
+ -keyfile $clientKey 127.0.0.1 8829\]"
+ puts $f {
+ exec $tclsh script1 &
+ puts $f testing
+ flush $f
+ after 1000 exit
+ vwait forever
+ }
+ close $f
+
+ # Create the server socket
+
+ set server [tls::socket \
+ -certfile $serverCert -cafile $caCert -keyfile $serverKey \
+ -server accept 8829]
+ proc accept { file host port } {
+ # When the client connects, establish the read handler
+ global server
+ close $server
+ fconfigure $file -blocking 0
+ fileevent $file readable [list do_handshake $file readable \
+ [list getdata client] -buffering line]
+ return
+ }
+
+ # If the socket doesn't hit end-of-file in 5 seconds, the
+ # script1 process must have inherited the client.
+
+ set failed 0
+ after 5000 [list set failed 1]
+
+ # Launch the script2 process
+
+ exec $::tcltest::tcltest script2 &
+
+ vwait x
+ if {!$failed} {
+ vwait failed
+ }
+ set x
+} {client socket was not inherited}
+
+test tlsIO-12.3 {testing inheritance of accepted sockets} \
+ {socket exec unixOnly} {
+ makeFile {} script1
+ makeFile {} script2
+
+ set f [open script1 w]
+ puts $f {
+ after 10000 exit
+ vwait forever
+ }
+ close $f
+
+ set f [open script2 w]
+ puts $f [list set tclsh $::tcltest::tcltest]
+ puts $f {
+ set auto_path [linsert $auto_path 0 [lindex [split $env(PATH) ";:"] 0]]
+ package require tls
+ }
+ puts $f "set f \[tls::socket -server accept \
+ -certfile $serverCert -cafile $caCert -keyfile $serverKey 8930\]"
+ puts $f {
+ proc accept { file host port } {
+ global tclsh
+ fconfigure $file -buffering line
+ puts $file {test data on socket}
+ exec $tclsh script1 &
+ after 1000 exit
+ }
+ vwait forever
+ }
+ close $f
+
+ # Launch the script2 process and connect to it. See how long
+ # the socket stays open
+
+ exec $::tcltest::tcltest script2 &
+
+ after 2000 set ok_to_proceed 1
+ vwait ok_to_proceed
+
+ set f [tls::socket \
+ -certfile $clientCert -cafile $caCert -keyfile $clientKey \
+ 127.0.0.1 8930]
+ fconfigure $f -buffering full -blocking 0
+ # We need to put a byte into the read queue, otherwise the
+ # TLS handshake doesn't finish
+ puts $f a; flush $f
+ fileevent $f readable [list getdata accepted $f]
+
+ # If the socket is still open after 5 seconds, the script1 process
+ # must have inherited the accepted socket.
+
+ set failed 0
+ after 5000 set failed 1
+
+ vwait x
+ set x
+} {accepted socket was not inherited}
+
+test tlsIO-13.1 {Testing use of shared socket between two threads} \
+ {socket testthread} {
+ # HOBBS: never tested
+ removeFile script
+ threadReap
+
+ makeFile {
+ set auto_path [linsert $auto_path 0 [lindex [split $env(PATH) ";:"] 0]]
+ package require tls
+ set f [tls::socket -server accept 8828]
+ proc accept {s a p} {
+ fileevent $s readable [list echo $s]
+ fconfigure $s -buffering line
+ }
+ proc echo {s} {
+ global i
+ set l [gets $s]
+ if {[eof $s]} {
+ global x
+ close $s
+ set x done
+ } else {
+ incr i
+ puts $s $l
+ }
+ }
+ set i 0
+ vwait x
+ close $f
+
+ # thread cleans itself up.
+ testthread exit
+ } script
+
+ # create a thread
+ set serverthread [testthread create { source script } ]
+ update
+
+ after 1000
+ set s [tls::socket 127.0.0.1 8828]
+ fconfigure $s -buffering line
+
+ catch {
+ puts $s "hello"
+ gets $s result
+ }
+ close $s
+ update
+
+ after 2000
+ lappend result [threadReap]
+
+ set result
+
+} {hello 1}
+
+test tlsIO-14.1 {test tls::unimport} {socket} {
+ list [catch {tls::unimport} msg] $msg
+} {1 {wrong # args: should be "tls::unimport channel"}}
+test tlsIO-14.2 {test tls::unimport} {socket} {
+ list [catch {tls::unimport foo bar} msg] $msg
+} {1 {wrong # args: should be "tls::unimport channel"}}
+test tlsIO-14.3 {test tls::unimport} {socket} {
+ list [catch {tls::unimport bogus} msg] $msg
+} {1 {can not find channel named "bogus"}}
+test tlsIO-14.4 {test tls::unimport} {socket} {
+ # stdin can take different names as the "top" channel
+ list [catch {tls::unimport stdin} msg] \
+ [string match {bad channel "*": not a TLS channel} $msg]
+} {1 1}
+test tlsIO-14.5 {test tls::unimport} {socket} {
+ set len 0
+ set spurious 0
+ set done 0
+ proc readlittle {s} {
+ global spurious done len
+ set l [read $s 1]
+ if {[string length $l] == 0} {
+ if {![eof $s]} {
+ incr spurious
+ } else {
+ close $s
+ set done 1
+ }
+ } else {
+ incr len [string length $l]
+ }
+ }
+ proc accept {s a p} {
+ fconfigure $s -blocking 0
+ fileevent $s readable [list do_handshake $s readable readlittle \
+ -buffering none]
+ }
+ set s [tls::socket \
+ -certfile $serverCert -cafile $caCert -keyfile $serverKey \
+ -server accept 8831]
+ set c [tls::socket \
+ -certfile $clientCert -cafile $caCert -keyfile $clientKey \
+ [info hostname] 8831]
+ # only the client gets tls::import
+ set res [tls::unimport $c]
+ list $res [catch {close $c} err] $err \
+ [catch {close $s} err] $err
+} {{} 0 {} 0 {}}
+
+test tls-bug58-1.0 {test protocol negotiation failure} {socket} {
+ # Following code is based on what was reported in bug #58. Prior
+ # to fix the program would crash with a segfault.
+ proc Accept {sock args} {
+ fconfigure $sock -blocking 0;
+ fileevent $sock readable [list Handshake $sock]
+ }
+ proc Handshake {sock} {
+ set ::done HAND
+ catch {tls::handshake $sock} msg
+ set ::done $msg
+ }
+ # NOTE: when doing an in-process client/server test, both sides need
+ # to be non-blocking for the TLS handshake
+
+ # Server - Only accept TLS 1 or higher
+ set s [tls::socket \
+ -certfile $serverCert -cafile $caCert -keyfile $serverKey \
+ -request 0 -require 0 -ssl2 0 -ssl3 0 -tls1 1 -tls1.1 1 -tls1.2 1 \
+ -server Accept 8831]
+ # Client - Only propose SSL3
+ set c [tls::socket -async \
+ -cafile $caCert \
+ -request 0 -require 0 -ssl2 0 -ssl3 1 -tls1 0 -tls1.1 0 -tls1.2 0 \
+ [info hostname] 8831]
+ fconfigure $c -blocking 0
+ puts $c a ; flush $c
+ after 5000 [list set ::done timeout]
+ vwait ::done
+ set ::done
+} {handshake failed: wrong version number}
+
+# cleanup
+if {[string match sock* $commandSocket] == 1} {
+ puts $commandSocket exit
+ flush $commandSocket
+}
+catch {close $commandSocket}
+catch {close $remoteProcChan}
+::tcltest::cleanupTests
+flush stdout
+return