nss: import at 3.0.1 beta 1
[mozilla-nss.git] / security / nss / tests / iopr / server_scr / client.cgi
blob5d711d52f1317b2d2b49452badc0c21b5bcd4a11
1 #!/usr/bin/perl
3 #--------------------------------------------------------------
4 # cgi script that parses request argument to appropriate
5 # open ssl or tstclntw options and starts ssl client.
8 use CGI qw/:standard/;
10 use subs qw(debug);
12 #--------------------------------------------------------------
13 # Prints out an error string and exits the script with an
14 # exitStatus.
15 # Param:
16 # str : an error string
17 # exitStat: an exit status of the program
19 sub svr_error {
20 my ($str, $exitStat) = @_;
22 if (!defined $str || $str eq "") {
23 $str = $ERR;
25 print "SERVER ERROR: $str\n";
26 if ($exitStat) {
27 print end_html if ($osDataArr{wservRun});
28 exit $exitStat;
32 #--------------------------------------------------------------
33 # Prints out a debug message
34 # Params:
35 # str: debug message
36 # inVal: additional value to print(optional)
38 sub debug {
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.
49 sub init {
50 %osDataArr = (
51 loadSupportedCipthersFn => \&osSpecific,
52 cipherIsSupportedFn => \&verifyCipherSupport,
53 cipherListFn => \&convertCipher,
54 buildCipherTableFn => \&buildCipherTable,
55 execCmdFn => \&osSpecific,
58 $scriptName = $ENV{'SCRIPT_NAME'};
59 if (!defined $scriptName) {
60 $DEBUG=1;
61 debug "Debug is ON";
63 $DEBUG=1;
65 $svrSoft = $ENV{'SERVER_SOFTWARE'};
66 if (defined $svrSoft) {
67 $_ = $svrSoft;
68 /.*Microsoft.*/ && ($osDataArr{wserv} = "IIS");
69 /.*Apache.*/ && ($osDataArr{wserv} = "Apache");
70 $osDataArr{wservRun} = 1;
71 } else {
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.
80 # Returns:
81 # always returns 0(failure)
83 sub osSpecific {
84 $ERR = "This function should be swapped to os specific function.";
85 return 0;
88 #--------------------------------------------------------------
89 # Sets os specific execution context values.
90 # Returns:
91 # 1 upon success, or 0 upon failure(if OS was not recognized)
93 sub setFunctRefs {
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;
109 } else {
110 $ERR = "Unknown Web Server type.";
111 return 0;
113 return 1;
116 #--------------------------------------------------------------
117 # Parses data from HTTP request. Will print a form if request
118 # does not contain sufficient number of parameters.
119 # Returns:
120 # 1 if request has sufficient number of parameters
121 # 0 if not.
122 sub getReqData {
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}) {
130 $in_host="goa1";
131 $in_port="443";
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") {
139 $DEBUG = 1;
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 ']),
154 submit,
155 end_form,
157 } else {
158 print "Printing html form to get client arguments\n";
160 $ERR = "the following parameters are required: host, port, cert";
161 return 0;
162 } else {
163 print "<pre>" if ($osDataArr{wservRun});
164 return 1;
169 #--------------------------------------------------------------
170 # Building cipher conversion table from file based on the OS.
171 # Params:
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;
178 my %table, %rtable;
179 my $strCount = 0;
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.";
186 return 0;
188 foreach (<TFILE>) {
189 chop;
190 /^#.*/ && next;
191 /^\s*$/ && next;
192 if ($strCount++ == 0) {
193 my @sysArr = split /\s+/;
194 $colCount = 0;
195 for (;$colCount <= $#sysArr;$colCount++) {
196 last if ($sysArr[$colCount] =~ /(.*:|^)$sysName.*/);
198 next;
200 my @ciphArr = split /\s+/, $_;
201 $table{$ciphArr[0]} = $ciphArr[$colCount];
202 $rtable{$ciphArr[$colCount]} = $ciphArr[0];
204 close(TFILE);
205 $cipherTablePtr[0] = \%table;
206 $cipherTablePtr[1] = \%rtable;
207 return 1
210 #--------------------------------------------------------------
211 # Client configuration function. Loads client configuration file.
212 # Initiates cipher table. Loads cipher list supported by ssl client.
214 sub configClient {
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);
223 foreach (<CFILE>) {
224 /^#.*/ && next;
225 chop;
226 eval $_;
228 close(CFILE);
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.
242 # Params:
243 # checkCipher: cipher name
244 # Returns:
245 # 1 - cipher is supported(also echos the cipher).
246 # 0 - not supported.
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.";
257 return 0;
260 #--------------------------------------------------------------
261 # Converts long(?name of the type?) cipher name to
262 # openssl/tstclntw cipher name.
263 # Returns:
264 # 0 if cipher was not listed. 1 upon success.
266 sub convertCipher {
267 my ($cipher) = @_;
268 my @retList;
269 my $resStr;
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.";
277 return 0;
279 &{$osDataArr{'cipherIsSupportedFn'}}($cphr) || return 0;
280 $ciphers = "$cphr";
281 return 1;
283 return 0;
286 #################################################################
287 # UNIX Apache Specific functions
288 #----------------------------------------------------------------
290 #--------------------------------------------------------------
291 # Executes ssl client command to get a list of ciphers supported
292 # by client.
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.";
302 return 0;
304 @arr = <OUT>;
305 chop $arr[0];
306 @suppCiphersTable = split /:/, $arr[0];
307 debug("Supported ciphers", $arr[0]);
308 $suppCiphersTablePrt = \@suppCiphersTable;
309 close(OUT);
310 return 1;
313 #--------------------------------------------------------------
314 # Lunches ssl client command in response to a request.
317 sub execClientCmd_Unix {
318 my $proto;
319 local $ciphers;
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";
336 return 0;
339 my @cmdOutArr = <CMD_OUT>;
341 foreach (@cmdOutArr) {
342 print $_;
345 my $haveVerify = 0;
346 my $haveErrors = 0;
347 foreach (@cmdOutArr) {
348 chop;
349 if (/unknown option/) {
350 $haveErrors++;
351 svr_error "unknown option\n";
352 next;
354 if (/:no ciphers available/) {
355 $haveErrors++;
356 svr_error "no cipthers available\n";
357 next;
359 if (/verify error:/) {
360 $haveErrors++;
361 svr_error "unable to do verification\n";
362 next;
364 if (/alert certificate revoked:/) {
365 $haveErrors++;
366 svr_error "attempt to connect with revoked sertificate\n";
367 next;
369 if (/(error|ERROR)/) {
370 $haveErrors++;
371 svr_error "found errors in server log\n";
372 next;
374 /verify return:1/ && ($haveVerify = 1);
376 if ($haveVerify == 0) {
377 svr_error "no 'verify return:1' found in server log\n";
378 $haveErrors++;
381 if ($haveErrors > 0) {
382 $ERR = "Have $haveErrors server errors";
383 debug "Exiting execClientCmd_Unix";
384 return 0;
386 debug "Exiting execClientCmd_Unix";
387 return 1;
390 #################################################################
391 # Windows IIS Specific functions
392 #----------------------------------------------------------------
394 #--------------------------------------------------------------
395 # Executes ssl client command to get a list of ciphers supported
396 # by client.
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.";
406 return 0;
408 my $startCipherList = 0;
409 foreach (<OUT>) {
410 chop;
411 if ($startCipherList) {
412 /^([a-zA-Z])\s+/ && push @suppCiphersTable, $1;
413 next;
415 /.*from list below.*/ && ($startCipherList = 1);
417 debug("Supported ciphers", join ':', @suppCiphersTable);
418 $suppCiphersTablePrt = \@suppCiphersTable;
419 close(OUT);
420 return 1;
423 #--------------------------------------------------------------
424 # Lunches ssl client command in response to a request.
427 sub execClientCmd_Win {
428 my $proto;
429 local $ciphers;
431 debug "Entering execClientCmd_Win";
432 if (defined $in_cipher && $in_cipher ne "") {
433 my @arr = split /_/, $in_cipher, 2;
434 $proto = "-2 -3 -T";
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";
448 return 0;
451 my @cmdOutArr = <CMD_OUT>;
453 foreach (@cmdOutArr) {
454 print $_;
457 my $haveVerify = 0;
458 my $haveErrors = 0;
459 foreach (@cmdOutArr) {
460 chop;
461 if (/unknown option/) {
462 $haveErrors++;
463 svr_error "unknown option\n";
464 next;
466 if (/Error performing handshake/) {
467 $haveErrors++;
468 svr_error "Error performing handshake\n";
469 next;
471 if (/Error creating credentials/) {
472 $haveErrors++;
473 svr_error "Error creating credentials\n";
474 next;
476 if (/Error .* authenticating server credentials!/) {
477 $haveErrors++;
478 svr_error "Error authenticating server credentials\n";
479 next;
481 if (/(error|ERROR|Error)/) {
482 $haveErrors++;
483 svr_error "found errors in server log\n";
484 next;
488 if ($haveErrors > 0) {
489 $ERR = "Have $haveErrors server errors";
490 debug "Exiting execClientCmd_Win";
491 return 0;
493 debug "Exiting execClientCmd_Win";
494 return 1;
497 #################################################################
498 # Main line of execution
499 #----------------------------------------------------------------
500 &init;
502 if ($osDataArr{wservRun}) {
503 print header('text/html').
504 start_html('iopr client');
507 print "SCRIPT=OK\n";
509 if (!&getReqData) {
510 svr_error($ERR, 1);
513 if (!&configClient) {
514 svr_error($ERR, 1);
517 &{$osDataArr{'execCmdFn'}} || svr_error;
519 if ($osDataArr{wservRun}) {
520 print "</pre>";
521 print end_html;