I have a TCL script that spawns an openssl process to do a get to a
URL and looks for a valid response. I've omitted large portions of
the code to keep this post from being too large. I'm very confident
in the rest of the code, it's only the particular proceedure (below)
that seems to be causing me grief.
---snip---
set cn "www.mydomain.com"
set check_url "/healthcheck.htm"
set valid_response "\r\nHTTP/1.1 200 OK\r"
match_max 10000
proc do_ssl {host port cn check_url valid_response} {
spawn openssl s_client -quiet -verify 0 -connect $host:$port
expect {
timeout {
puts "$host $port is paused - Connect to $host failed."
}
"$cn" {
}
}
send "GET $check_url HTTP/1.1\rHost: $cn\r\n\r\n"
expect {
timeout {
puts "$host $port is paused - SSL to $host failed."
}
"$valid_response" {
puts "$host $port unpaused - SSL to $host succeeded."
exit
}
send "quit\r"
}
}; # proc do_ssl
---snip---
When doing a debug, (#!/usr/bin/expect -d) this is the result...
---snip---
expect: does "\r\nGET /healthcheck.htm HTTP/1.1\r\n[removed for
brevity and privacy]\r\nHTTP/1.1 200 OK\r\r\nContent-Type: text/html;
charset=utf-8\r\r\nSet-Cookie: [removed]\r\r\nPragma: no-cache\r\r
\nCache-Control: no-store\r\r\nExpires: -1\r\r\nTransfer-Encoding:
chunked\r\r\n\r\r\n" (spawn_id exp5) match glob pattern "\r\nHTTP/1.1
200 OK\r"? yes
expect: set expect_out(0,string) "\r\nHTTP/1.1 200 OK\r"
expect: set expect_out(spawn_id) "exp5"
expect: set expect_out(buffer) "\r\nGET /healthcheck.htm HTTP/1.1\r
\nHost: www.mydomain.com\r\n\r\n\r\n\r\nverify error:num=20:unable to
get local issuer certificate\r\nverify return:1\r\ndepth=0 /C=[Removed
for brevity and privacy]/CN=www.mydomain.com\r\nverify
error:num=21:unable to verify the first certificate\r\nverify return:
1\r\nHTTP/1.1 200 OK\r"
207.17.137.200 443 unpaused - SSL to 207.17.137.200 succeeded.
write() failed to write anything - will sleep(1) and retry...
write() failed to write anything - will sleep(1) and retry...
---snip---
There are supposed to be two servers that are checked via OpenSSL.
The rest of the script that gets that information seems to work. As a
matter of fact, the OpenSSL portion of the script works too, if the
healthcheck fails (in other words, the result doesn't match 200 OK).
If there is a mismatch, the script correctly reports that the first
server is down, and moves onto the second server. It will then hang
on the second server, or end normally, if the second server also fails
to match the valid_response. This is what leads me to believe this is
more of a TCL problem than an OpenSSL problem.
For the TCL folks: I've done some searches for this "write() failed to
write anything - will sleep(1) and retry..." message, but it appears
fairly rare, and I couldn't find anything useful. Any thoughts? The
first portion works fine, I match the CN and send my GET, as you can
see, I seem to get a regexp match on the valid_response portion, but
it just hangs after that.
For the OpenSSH folks: Is there something wrong with my parameters I'm
using when calling OpenSSL (openssl s_client -quiet -verify 0 -connect
$host:$port)? Is there some cleaner way to do this?
Thanks in advance for any assistance.
Dan Rabb
>Apologies for cross-posting, but I'm not sure if this is a TCL/Expect
>problem or an OpenSSL problem.
>
>I have a TCL script that spawns an openssl process to do a get to a
>URL and looks for a valid response. I've omitted large portions of
>the code to keep this post from being too large. I'm very confident
>in the rest of the code, it's only the particular proceedure (below)
>that seems to be causing me grief.
Why don't you use the http package with the tls extension.
package require http
package require tls
http::register https 443 ::tls::socket
set tok [http::geturl https://secure.example.com/ -timeout 30000]
set data [http::data $tok]
... and so on
--
Pat Thoyts http://www.patthoyts.tk/
To reply, rot13 the return address or read the X-Address header.
PGP fingerprint 2C 6E 98 07 2C 59 C8 97 10 CE 11 E6 04 E0 B9 DD