3 #--------------------------------------------------------------
4 # cgi script that parses request argument to appropriate
5 # open ssl or tstclntw options and starts ssl client.
12 #--------------------------------------------------------------
13 # Prints out an error string and exits the script with an
16 # str : an error string
17 # exitStat: an exit status of the program
20 my ($str, $exitStat) = @_;
22 if (!defined $str || $str eq "") {
25 print "SERVER ERROR: $str\n";
27 print end_html
if ($osDataArr{wservRun
});
32 #--------------------------------------------------------------
33 # Prints out a debug message
36 # inVal: additional value to print(optional)
39 my ($str, $inVal) = @_;
41 print "-- DEBUG: $str ($inVal)\n" if ($DEBUG == 1);
45 #--------------------------------------------------------------
46 # Initializes execution context depending on a webserver the
47 # script is running under.
51 loadSupportedCipthersFn
=> \
&osSpecific
,
52 cipherIsSupportedFn
=> \
&verifyCipherSupport
,
53 cipherListFn
=> \
&convertCipher
,
54 buildCipherTableFn
=> \
&buildCipherTable
,
55 execCmdFn
=> \
&osSpecific
,
58 $scriptName = $ENV{'SCRIPT_NAME'};
59 if (!defined $scriptName) {
65 $svrSoft = $ENV{'SERVER_SOFTWARE'};
66 if (defined $svrSoft) {
68 /.*Microsoft.*/ && ($osDataArr{wserv
} = "IIS");
69 /.*Apache.*/ && ($osDataArr{wserv
} = "Apache");
70 $osDataArr{wservRun
} = 1;
72 $osDataArr{wserv
} = "Apache";
73 $osDataArr{wservRun
} = 0;
77 #--------------------------------------------------------------
78 # Function-spigot to handle errors is OS specific functions are
79 # not implemented for a particular OS.
81 # always returns 0(failure)
84 $ERR = "This function should be swapped to os specific function.";
88 #--------------------------------------------------------------
89 # Sets os specific execution context values.
91 # 1 upon success, or 0 upon failure(if OS was not recognized)
95 debug
("Entering setFunctRefs function", $osDataArr{wserv
});
97 if ($osDataArr{wserv
} eq "Apache") {
98 $osDataArr{osConfigFile
} = "apache_unix.cfg";
99 $osDataArr{suppCiphersCmd
} = '$opensslb ciphers ALL:NULL';
100 $osDataArr{clientRunCmd
} = '$opensslb s_client -host $in_host -port $in_port -cert $certDir/$in_cert.crt -key $certDir/$in_cert.key -CAfile $caCertFile $proto $ciphers -ign_eof < $reqFile';
101 $osDataArr{loadSupportedCipthersFn
} = \
&getSupportedCipherList_Unix
;
102 $osDataArr{execCmdFn
} = \
&execClientCmd_Unix
;
103 } elsif ($osDataArr{wserv
} eq "IIS") {
104 $osDataArr{osConfigFile
} = "iis_windows.cfg";
105 $osDataArr{suppCiphersCmd
} = '$tstclntwb';
106 $osDataArr{clientRunCmd
} = '$tstclntwb -h $in_host -p $in_port -n $in_cert $proto $ciphers < $reqFile';
107 $osDataArr{loadSupportedCipthersFn
} = \
&getSupportedCipherList_Win
;
108 $osDataArr{execCmdFn
} = \
&execClientCmd_Win
;
110 $ERR = "Unknown Web Server type.";
116 #--------------------------------------------------------------
117 # Parses data from HTTP request. Will print a form if request
118 # does not contain sufficient number of parameters.
120 # 1 if request has sufficient number of parameters
123 my $debug = param
('debug');
124 $in_host = param
('host');
125 $in_port = param
('port');
126 $in_cert = param
('cert');
127 $in_cipher = param
('cipher');
129 if (!$osDataArr{wservRun
}) {
132 $in_cert="TestUser511";
133 $in_cipher = "SSL3_RSA_WITH_NULL_SHA";
136 debug
("Entering getReqData function", "$in_port:$in_host:$in_cert:$in_cipher");
138 if (defined $debug && $debug == "debug on") {
142 if (!defined $in_host || $in_host eq "" ||
143 !defined $in_port || $in_port eq "" ||
144 !defined $in_cert || $in_cert eq "") {
145 if ($osDataArr{wservRun
}) {
146 print h1
('Command description form:'),
147 start_form
(-method
=>"get"),
148 "Host: ",textfield
('host'),p
,
149 "Port: ",textfield
('port'),p
,
150 "Cert: ",textfield
('cert'),p
,
151 "Cipher: ",textfield
('cipher'),p
,
152 checkbox_group
(-name
=>'debug',
153 -values=>['debug on ']),
158 print "Printing html form to get client arguments\n";
160 $ERR = "the following parameters are required: host, port, cert";
163 print "<pre>" if ($osDataArr{wservRun
});
169 #--------------------------------------------------------------
170 # Building cipher conversion table from file based on the OS.
172 # tfile: cipher conversion file.
173 # sysName: system name
174 # tblPrt: returned pointer to a table.
175 sub buildCipherTable
{
176 my ($tfile, $sysName, $tblPrt) = @_;
177 my @retArr = @
$tblPrt;
181 debug
("Entering getReqData function", "$tfile:$sysName:$tblPrt");
183 ($ERR = "No system name supplied" && return 0) if ($sysName =~ /^$/);
184 if (!open(TFILE
, "$tfile")) {
185 $ERR = "Missing cipher conversion table file.";
192 if ($strCount++ == 0) {
193 my @sysArr = split /\s+/;
195 for (;$colCount <= $#sysArr;$colCount++) {
196 last if ($sysArr[$colCount] =~ /(.*:|^)$sysName.*/);
200 my @ciphArr = split /\s+/, $_;
201 $table{$ciphArr[0]} = $ciphArr[$colCount];
202 $rtable{$ciphArr[$colCount]} = $ciphArr[0];
205 $cipherTablePtr[0] = \
%table;
206 $cipherTablePtr[1] = \
%rtable;
210 #--------------------------------------------------------------
211 # Client configuration function. Loads client configuration file.
212 # Initiates cipher table. Loads cipher list supported by ssl client.
216 debug
"Entering configClient function";
218 my $res = &setFunctRefs
();
219 return $res if (!$res);
221 open(CFILE
, $osDataArr{'osConfigFile'}) ||
222 ($ERR = "Missing configuration file." && return 0);
230 local @cipherTablePtr = ();
231 $osDataArr{'buildCipherTableFn'}->($cipherTableFile, $clientSys) || return 0;
232 $osDataArr{cipherTable
} = $cipherTablePtr[0];
233 $osDataArr{rcipherTable
} = $cipherTablePtr[1];
235 local $suppCiphersTablePrt;
236 &{$osDataArr{'loadSupportedCipthersFn'}} || return 0;
237 $osDataArr{suppCiphersTable
} = $suppCiphersTablePrt;
240 #--------------------------------------------------------------
241 # Verifies that a particular cipher is supported.
243 # checkCipher: cipher name
245 # 1 - cipher is supported(also echos the cipher).
248 sub verifyCipherSupport
{
249 my ($checkCipher) = @_;
250 my @suppCiphersTable = @
{$osDataArr{suppCiphersTable
}};
252 debug
("Entering verifyCipherSupport", $checkCipher);
253 foreach (@suppCiphersTable) {
254 return 1 if ($checkCipher eq $_);
256 $ERR = "cipher is not supported.";
260 #--------------------------------------------------------------
261 # Converts long(?name of the type?) cipher name to
262 # openssl/tstclntw cipher name.
264 # 0 if cipher was not listed. 1 upon success.
270 my %cipherTable = %{$osDataArr{cipherTable
}};
272 debug
("Entering convertCipher", $cipher);
273 if (defined $cipher) {
274 my $cphr = $cipherTable{$cipher};
275 if (!defined $cphr) {
276 $ERR = "cipher is not listed.";
279 &{$osDataArr{'cipherIsSupportedFn'}}($cphr) || return 0;
286 #################################################################
287 # UNIX Apache Specific functions
288 #----------------------------------------------------------------
290 #--------------------------------------------------------------
291 # Executes ssl client command to get a list of ciphers supported
294 sub getSupportedCipherList_Unix
{
295 my @arr, @suppCiphersTable;
297 debug
"Entering getSupportedCipherList_Unix function";
299 eval '$sLisrCmd = "'.$osDataArr{'suppCiphersCmd'}.'"';
300 if (!open (OUT
, "$sLisrCmd|")) {
301 $ERR="Can not run command to verify supported cipher list.";
306 @suppCiphersTable = split /:/, $arr[0];
307 debug
("Supported ciphers", $arr[0]);
308 $suppCiphersTablePrt = \
@suppCiphersTable;
313 #--------------------------------------------------------------
314 # Lunches ssl client command in response to a request.
317 sub execClientCmd_Unix
{
321 debug
"Entering execClientCmd_Unix";
322 if (defined $in_cipher && $in_cipher ne "") {
323 my @arr = split /_/, $in_cipher, 2;
324 $proto = "-".$arr[0];
325 $proto =~ tr
/SLT/slt
/;
326 $proto = "-tls1" if ($proto eq "-tls");
327 return 0 if (!&{$osDataArr{'cipherListFn'}}($in_cipher));
328 $ciphers = "-cipher $ciphers";
329 debug
("Return from cipher conversion", "$ciphers");
332 eval '$command = "'.$osDataArr{'clientRunCmd'}.'"';
333 debug
("Executing command", $command);
334 if (!open CMD_OUT
, "$command 2>&1 |") {
335 $ERR = "can not launch client";
339 my @cmdOutArr = <CMD_OUT
>;
341 foreach (@cmdOutArr) {
347 foreach (@cmdOutArr) {
349 if (/unknown option/) {
351 svr_error
"unknown option\n";
354 if (/:no ciphers available/) {
356 svr_error
"no cipthers available\n";
359 if (/verify error:/) {
361 svr_error
"unable to do verification\n";
364 if (/alert certificate revoked:/) {
366 svr_error
"attempt to connect with revoked sertificate\n";
369 if (/(error|ERROR)/) {
371 svr_error
"found errors in server log\n";
374 /verify return:1/ && ($haveVerify = 1);
376 if ($haveVerify == 0) {
377 svr_error
"no 'verify return:1' found in server log\n";
381 if ($haveErrors > 0) {
382 $ERR = "Have $haveErrors server errors";
383 debug
"Exiting execClientCmd_Unix";
386 debug
"Exiting execClientCmd_Unix";
390 #################################################################
391 # Windows IIS Specific functions
392 #----------------------------------------------------------------
394 #--------------------------------------------------------------
395 # Executes ssl client command to get a list of ciphers supported
398 sub getSupportedCipherList_Win
{
399 my @arr, @suppCiphersTable;
401 debug
"Entering getSupportedCipherList_Win function";
403 eval '$sLisrCmd = "'.$osDataArr{'suppCiphersCmd'}.'"';
404 if (!open (OUT
, "$sLisrCmd|")) {
405 $ERR="Can not run command to verify supported cipher list.";
408 my $startCipherList = 0;
411 if ($startCipherList) {
412 /^([a-zA-Z])\s+/ && push @suppCiphersTable, $1;
415 /.*from list below.*/ && ($startCipherList = 1);
417 debug
("Supported ciphers", join ':', @suppCiphersTable);
418 $suppCiphersTablePrt = \
@suppCiphersTable;
423 #--------------------------------------------------------------
424 # Lunches ssl client command in response to a request.
427 sub execClientCmd_Win
{
431 debug
"Entering execClientCmd_Win";
432 if (defined $in_cipher && $in_cipher ne "") {
433 my @arr = split /_/, $in_cipher, 2;
436 $proto =~ s/-T// if ($arr[0] eq "TLS");
437 $proto =~ s/-3// if ($arr[0] eq "SSL3");
438 $proto =~ s/-2// if ($arr[0] eq "SSL2");
439 return 0 if (!&{$osDataArr{'cipherListFn'}}($in_cipher));
440 $ciphers = "-c $ciphers";
441 debug
("Return from cipher conversion", $ciphers);
444 eval '$command = "'.$osDataArr{'clientRunCmd'}.'"';
445 debug
("Executing command", $command);
446 if (!open CMD_OUT
, "$command 2>&1 |") {
447 $ERR = "can not launch client";
451 my @cmdOutArr = <CMD_OUT
>;
453 foreach (@cmdOutArr) {
459 foreach (@cmdOutArr) {
461 if (/unknown option/) {
463 svr_error
"unknown option\n";
466 if (/Error performing handshake/) {
468 svr_error
"Error performing handshake\n";
471 if (/Error creating credentials/) {
473 svr_error
"Error creating credentials\n";
476 if (/Error .* authenticating server credentials!/) {
478 svr_error
"Error authenticating server credentials\n";
481 if (/(error|ERROR|Error)/) {
483 svr_error
"found errors in server log\n";
488 if ($haveErrors > 0) {
489 $ERR = "Have $haveErrors server errors";
490 debug
"Exiting execClientCmd_Win";
493 debug
"Exiting execClientCmd_Win";
497 #################################################################
498 # Main line of execution
499 #----------------------------------------------------------------
502 if ($osDataArr{wservRun
}) {
503 print header
('text/html').
504 start_html
('iopr client');
513 if (!&configClient
) {
517 &{$osDataArr{'execCmdFn'}} || svr_error
;
519 if ($osDataArr{wservRun
}) {