1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/nss/tests/iopr/server_scr/client.cgi Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,526 @@ 1.4 +#!/usr/bin/perl 1.5 + 1.6 +# This Source Code Form is subject to the terms of the Mozilla Public 1.7 +# License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 +# file, You can obtain one at http://mozilla.org/MPL/2.0/. 1.9 + 1.10 +#-------------------------------------------------------------- 1.11 +# cgi script that parses request argument to appropriate 1.12 +# open ssl or tstclntw options and starts ssl client. 1.13 +# 1.14 + 1.15 +use CGI qw/:standard/; 1.16 + 1.17 +use subs qw(debug); 1.18 + 1.19 +#-------------------------------------------------------------- 1.20 +# Prints out an error string and exits the script with an 1.21 +# exitStatus. 1.22 +# Param: 1.23 +# str : an error string 1.24 +# exitStat: an exit status of the program 1.25 +# 1.26 +sub svr_error { 1.27 + my ($str, $exitStat) = @_; 1.28 + 1.29 + if (!defined $str || $str eq "") { 1.30 + $str = $ERR; 1.31 + } 1.32 + print "SERVER ERROR: $str\n"; 1.33 + if ($exitStat) { 1.34 + print end_html if ($osDataArr{wservRun}); 1.35 + exit $exitStat; 1.36 + } 1.37 +} 1.38 + 1.39 +#-------------------------------------------------------------- 1.40 +# Prints out a debug message 1.41 +# Params: 1.42 +# str: debug message 1.43 +# inVal: additional value to print(optional) 1.44 +# 1.45 +sub debug { 1.46 + my ($str, $inVal) = @_; 1.47 + 1.48 + print "-- DEBUG: $str ($inVal)\n" if ($DEBUG == 1); 1.49 +} 1.50 + 1.51 + 1.52 +#-------------------------------------------------------------- 1.53 +# Initializes execution context depending on a webserver the 1.54 +# script is running under. 1.55 +# 1.56 +sub init { 1.57 + %osDataArr = ( 1.58 + loadSupportedCipthersFn => \&osSpecific, 1.59 + cipherIsSupportedFn => \&verifyCipherSupport, 1.60 + cipherListFn => \&convertCipher, 1.61 + buildCipherTableFn => \&buildCipherTable, 1.62 + execCmdFn => \&osSpecific, 1.63 + ); 1.64 + 1.65 + $scriptName = $ENV{'SCRIPT_NAME'}; 1.66 + if (!defined $scriptName) { 1.67 + $DEBUG=1; 1.68 + debug "Debug is ON"; 1.69 + } 1.70 + $DEBUG=1; 1.71 + 1.72 + $svrSoft = $ENV{'SERVER_SOFTWARE'}; 1.73 + if (defined $svrSoft) { 1.74 + $_ = $svrSoft; 1.75 + /.*Microsoft.*/ && ($osDataArr{wserv} = "IIS"); 1.76 + /.*Apache.*/ && ($osDataArr{wserv} = "Apache"); 1.77 + $osDataArr{wservRun} = 1; 1.78 + } else { 1.79 + $osDataArr{wserv} = "Apache"; 1.80 + $osDataArr{wservRun} = 0; 1.81 + } 1.82 +} 1.83 + 1.84 +#-------------------------------------------------------------- 1.85 +# Function-spigot to handle errors is OS specific functions are 1.86 +# not implemented for a particular OS. 1.87 +# Returns: 1.88 +# always returns 0(failure) 1.89 +# 1.90 +sub osSpecific { 1.91 + $ERR = "This function should be swapped to os specific function."; 1.92 + return 0; 1.93 +} 1.94 + 1.95 +#-------------------------------------------------------------- 1.96 +# Sets os specific execution context values. 1.97 +# Returns: 1.98 +# 1 upon success, or 0 upon failure(if OS was not recognized) 1.99 +# 1.100 +sub setFunctRefs { 1.101 + 1.102 + debug("Entering setFunctRefs function", $osDataArr{wserv}); 1.103 + 1.104 + if ($osDataArr{wserv} eq "Apache") { 1.105 + $osDataArr{osConfigFile} = "apache_unix.cfg"; 1.106 + $osDataArr{suppCiphersCmd} = '$opensslb ciphers ALL:NULL'; 1.107 + $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'; 1.108 + $osDataArr{loadSupportedCipthersFn} = \&getSupportedCipherList_Unix; 1.109 + $osDataArr{execCmdFn} = \&execClientCmd_Unix; 1.110 + } elsif ($osDataArr{wserv} eq "IIS") { 1.111 + $osDataArr{osConfigFile} = "iis_windows.cfg"; 1.112 + $osDataArr{suppCiphersCmd} = '$tstclntwb'; 1.113 + $osDataArr{clientRunCmd} = '$tstclntwb -h $in_host -p $in_port -n $in_cert $proto $ciphers < $reqFile'; 1.114 + $osDataArr{loadSupportedCipthersFn} = \&getSupportedCipherList_Win; 1.115 + $osDataArr{execCmdFn} = \&execClientCmd_Win; 1.116 + } else { 1.117 + $ERR = "Unknown Web Server type."; 1.118 + return 0; 1.119 + } 1.120 + return 1; 1.121 +} 1.122 + 1.123 +#-------------------------------------------------------------- 1.124 +# Parses data from HTTP request. Will print a form if request 1.125 +# does not contain sufficient number of parameters. 1.126 +# Returns: 1.127 +# 1 if request has sufficient number of parameters 1.128 +# 0 if not. 1.129 +sub getReqData { 1.130 + my $debug = param('debug'); 1.131 + $in_host = param('host'); 1.132 + $in_port = param('port'); 1.133 + $in_cert = param('cert'); 1.134 + $in_cipher = param('cipher'); 1.135 + 1.136 + if (!$osDataArr{wservRun}) { 1.137 + $in_host="goa1"; 1.138 + $in_port="443"; 1.139 + $in_cert="TestUser511"; 1.140 + $in_cipher = "SSL3_RSA_WITH_NULL_SHA"; 1.141 + } 1.142 + 1.143 + debug("Entering getReqData function", "$in_port:$in_host:$in_cert:$in_cipher"); 1.144 + 1.145 + if (defined $debug && $debug == "debug on") { 1.146 + $DEBUG = 1; 1.147 + } 1.148 + 1.149 + if (!defined $in_host || $in_host eq "" || 1.150 + !defined $in_port || $in_port eq "" || 1.151 + !defined $in_cert || $in_cert eq "") { 1.152 + if ($osDataArr{wservRun}) { 1.153 + print h1('Command description form:'), 1.154 + start_form(-method=>"get"), 1.155 + "Host: ",textfield('host'),p, 1.156 + "Port: ",textfield('port'),p, 1.157 + "Cert: ",textfield('cert'),p, 1.158 + "Cipher: ",textfield('cipher'),p, 1.159 + checkbox_group(-name=>'debug', 1.160 + -values=>['debug on ']), 1.161 + submit, 1.162 + end_form, 1.163 + hr; 1.164 + } else { 1.165 + print "Printing html form to get client arguments\n"; 1.166 + } 1.167 + $ERR = "the following parameters are required: host, port, cert"; 1.168 + return 0; 1.169 + } else { 1.170 + print "<pre>" if ($osDataArr{wservRun}); 1.171 + return 1; 1.172 + } 1.173 +} 1.174 + 1.175 + 1.176 +#-------------------------------------------------------------- 1.177 +# Building cipher conversion table from file based on the OS. 1.178 +# Params: 1.179 +# tfile: cipher conversion file. 1.180 +# sysName: system name 1.181 +# tblPrt: returned pointer to a table. 1.182 +sub buildCipherTable { 1.183 + my ($tfile, $sysName, $tblPrt) = @_; 1.184 + my @retArr = @$tblPrt; 1.185 + my %table, %rtable; 1.186 + my $strCount = 0; 1.187 + 1.188 + debug("Entering getReqData function", "$tfile:$sysName:$tblPrt"); 1.189 + 1.190 + ($ERR = "No system name supplied" && return 0) if ($sysName =~ /^$/); 1.191 + if (!open(TFILE, "$tfile")) { 1.192 + $ERR = "Missing cipher conversion table file."; 1.193 + return 0; 1.194 + } 1.195 + foreach (<TFILE>) { 1.196 + chop; 1.197 + /^#.*/ && next; 1.198 + /^\s*$/ && next; 1.199 + if ($strCount++ == 0) { 1.200 + my @sysArr = split /\s+/; 1.201 + $colCount = 0; 1.202 + for (;$colCount <= $#sysArr;$colCount++) { 1.203 + last if ($sysArr[$colCount] =~ /(.*:|^)$sysName.*/); 1.204 + } 1.205 + next; 1.206 + } 1.207 + my @ciphArr = split /\s+/, $_; 1.208 + $table{$ciphArr[0]} = $ciphArr[$colCount]; 1.209 + $rtable{$ciphArr[$colCount]} = $ciphArr[0]; 1.210 + } 1.211 + close(TFILE); 1.212 + $cipherTablePtr[0] = \%table; 1.213 + $cipherTablePtr[1] = \%rtable; 1.214 + return 1 1.215 +} 1.216 + 1.217 +#-------------------------------------------------------------- 1.218 +# Client configuration function. Loads client configuration file. 1.219 +# Initiates cipher table. Loads cipher list supported by ssl client. 1.220 +# 1.221 +sub configClient { 1.222 + 1.223 + debug "Entering configClient function"; 1.224 + 1.225 + my $res = &setFunctRefs(); 1.226 + return $res if (!$res); 1.227 + 1.228 + open(CFILE, $osDataArr{'osConfigFile'}) || 1.229 + ($ERR = "Missing configuration file." && return 0); 1.230 + foreach (<CFILE>) { 1.231 + /^#.*/ && next; 1.232 + chop; 1.233 + eval $_; 1.234 + } 1.235 + close(CFILE); 1.236 + 1.237 + local @cipherTablePtr = (); 1.238 + $osDataArr{'buildCipherTableFn'}->($cipherTableFile, $clientSys) || return 0; 1.239 + $osDataArr{cipherTable} = $cipherTablePtr[0]; 1.240 + $osDataArr{rcipherTable} = $cipherTablePtr[1]; 1.241 + 1.242 + local $suppCiphersTablePrt; 1.243 + &{$osDataArr{'loadSupportedCipthersFn'}} || return 0; 1.244 + $osDataArr{suppCiphersTable} = $suppCiphersTablePrt; 1.245 +} 1.246 + 1.247 +#-------------------------------------------------------------- 1.248 +# Verifies that a particular cipher is supported. 1.249 +# Params: 1.250 +# checkCipher: cipher name 1.251 +# Returns: 1.252 +# 1 - cipher is supported(also echos the cipher). 1.253 +# 0 - not supported. 1.254 +# 1.255 +sub verifyCipherSupport { 1.256 + my ($checkCipher) = @_; 1.257 + my @suppCiphersTable = @{$osDataArr{suppCiphersTable}}; 1.258 + 1.259 + debug("Entering verifyCipherSupport", $checkCipher); 1.260 + foreach (@suppCiphersTable) { 1.261 + return 1 if ($checkCipher eq $_); 1.262 + } 1.263 + $ERR = "cipher is not supported."; 1.264 + return 0; 1.265 +} 1.266 + 1.267 +#-------------------------------------------------------------- 1.268 +# Converts long(?name of the type?) cipher name to 1.269 +# openssl/tstclntw cipher name. 1.270 +# Returns: 1.271 +# 0 if cipher was not listed. 1 upon success. 1.272 +# 1.273 +sub convertCipher { 1.274 + my ($cipher) = @_; 1.275 + my @retList; 1.276 + my $resStr; 1.277 + my %cipherTable = %{$osDataArr{cipherTable}}; 1.278 + 1.279 + debug("Entering convertCipher", $cipher); 1.280 + if (defined $cipher) { 1.281 + my $cphr = $cipherTable{$cipher}; 1.282 + if (!defined $cphr) { 1.283 + $ERR = "cipher is not listed."; 1.284 + return 0; 1.285 + } 1.286 + &{$osDataArr{'cipherIsSupportedFn'}}($cphr) || return 0; 1.287 + $ciphers = "$cphr"; 1.288 + return 1; 1.289 + } 1.290 + return 0; 1.291 +} 1.292 + 1.293 +################################################################# 1.294 +# UNIX Apache Specific functions 1.295 +#---------------------------------------------------------------- 1.296 + 1.297 +#-------------------------------------------------------------- 1.298 +# Executes ssl client command to get a list of ciphers supported 1.299 +# by client. 1.300 +# 1.301 +sub getSupportedCipherList_Unix { 1.302 + my @arr, @suppCiphersTable; 1.303 + 1.304 + debug "Entering getSupportedCipherList_Unix function"; 1.305 + 1.306 + eval '$sLisrCmd = "'.$osDataArr{'suppCiphersCmd'}.'"'; 1.307 + if (!open (OUT, "$sLisrCmd|")) { 1.308 + $ERR="Can not run command to verify supported cipher list."; 1.309 + return 0; 1.310 + } 1.311 + @arr = <OUT>; 1.312 + chop $arr[0]; 1.313 + @suppCiphersTable = split /:/, $arr[0]; 1.314 + debug("Supported ciphers", $arr[0]); 1.315 + $suppCiphersTablePrt = \@suppCiphersTable; 1.316 + close(OUT); 1.317 + return 1; 1.318 +} 1.319 + 1.320 +#-------------------------------------------------------------- 1.321 +# Lunches ssl client command in response to a request. 1.322 +# 1.323 +# 1.324 +sub execClientCmd_Unix { 1.325 + my $proto; 1.326 + local $ciphers; 1.327 + 1.328 + debug "Entering execClientCmd_Unix"; 1.329 + if (defined $in_cipher && $in_cipher ne "") { 1.330 + my @arr = split /_/, $in_cipher, 2; 1.331 + $proto = "-".$arr[0]; 1.332 + $proto =~ tr /SLT/slt/; 1.333 + $proto = "-tls1" if ($proto eq "-tls"); 1.334 + return 0 if (!&{$osDataArr{'cipherListFn'}}($in_cipher)); 1.335 + $ciphers = "-cipher $ciphers"; 1.336 + debug("Return from cipher conversion", "$ciphers"); 1.337 + } 1.338 + 1.339 + eval '$command = "'.$osDataArr{'clientRunCmd'}.'"'; 1.340 + debug("Executing command", $command); 1.341 + if (!open CMD_OUT, "$command 2>&1 |") { 1.342 + $ERR = "can not launch client"; 1.343 + return 0; 1.344 + } 1.345 + 1.346 + my @cmdOutArr = <CMD_OUT>; 1.347 + 1.348 + foreach (@cmdOutArr) { 1.349 + print $_; 1.350 + } 1.351 + 1.352 + my $haveVerify = 0; 1.353 + my $haveErrors = 0; 1.354 + foreach (@cmdOutArr) { 1.355 + chop; 1.356 + if (/unknown option/) { 1.357 + $haveErrors++; 1.358 + svr_error "unknown option\n"; 1.359 + next; 1.360 + } 1.361 + if (/:no ciphers available/) { 1.362 + $haveErrors++; 1.363 + svr_error "no cipthers available\n"; 1.364 + next; 1.365 + } 1.366 + if (/verify error:/) { 1.367 + $haveErrors++; 1.368 + svr_error "unable to do verification\n"; 1.369 + next; 1.370 + } 1.371 + if (/alert certificate revoked:/) { 1.372 + $haveErrors++; 1.373 + svr_error "attempt to connect with revoked sertificate\n"; 1.374 + next; 1.375 + } 1.376 + if (/(error|ERROR)/) { 1.377 + $haveErrors++; 1.378 + svr_error "found errors in server log\n"; 1.379 + next; 1.380 + } 1.381 + /verify return:1/ && ($haveVerify = 1); 1.382 + } 1.383 + if ($haveVerify == 0) { 1.384 + svr_error "no 'verify return:1' found in server log\n"; 1.385 + $haveErrors++; 1.386 + } 1.387 + 1.388 + if ($haveErrors > 0) { 1.389 + $ERR = "Have $haveErrors server errors"; 1.390 + debug "Exiting execClientCmd_Unix"; 1.391 + return 0; 1.392 + } 1.393 + debug "Exiting execClientCmd_Unix"; 1.394 + return 1; 1.395 +} 1.396 + 1.397 +################################################################# 1.398 +# Windows IIS Specific functions 1.399 +#---------------------------------------------------------------- 1.400 + 1.401 +#-------------------------------------------------------------- 1.402 +# Executes ssl client command to get a list of ciphers supported 1.403 +# by client. 1.404 +# 1.405 +sub getSupportedCipherList_Win { 1.406 + my @arr, @suppCiphersTable; 1.407 + 1.408 + debug "Entering getSupportedCipherList_Win function"; 1.409 + 1.410 + eval '$sLisrCmd = "'.$osDataArr{'suppCiphersCmd'}.'"'; 1.411 + if (!open (OUT, "$sLisrCmd|")) { 1.412 + $ERR="Can not run command to verify supported cipher list."; 1.413 + return 0; 1.414 + } 1.415 + my $startCipherList = 0; 1.416 + foreach (<OUT>) { 1.417 + chop; 1.418 + if ($startCipherList) { 1.419 + /^([a-zA-Z])\s+/ && push @suppCiphersTable, $1; 1.420 + next; 1.421 + } 1.422 + /.*from list below.*/ && ($startCipherList = 1); 1.423 + } 1.424 + debug("Supported ciphers", join ':', @suppCiphersTable); 1.425 + $suppCiphersTablePrt = \@suppCiphersTable; 1.426 + close(OUT); 1.427 + return 1; 1.428 +} 1.429 + 1.430 +#-------------------------------------------------------------- 1.431 +# Lunches ssl client command in response to a request. 1.432 +# 1.433 +# 1.434 +sub execClientCmd_Win { 1.435 + my $proto; 1.436 + local $ciphers; 1.437 + 1.438 + debug "Entering execClientCmd_Win"; 1.439 + if (defined $in_cipher && $in_cipher ne "") { 1.440 + my @arr = split /_/, $in_cipher, 2; 1.441 + $proto = "-2 -3 -T"; 1.442 + 1.443 + $proto =~ s/-T// if ($arr[0] eq "TLS"); 1.444 + $proto =~ s/-3// if ($arr[0] eq "SSL3"); 1.445 + $proto =~ s/-2// if ($arr[0] eq "SSL2"); 1.446 + return 0 if (!&{$osDataArr{'cipherListFn'}}($in_cipher)); 1.447 + $ciphers = "-c $ciphers"; 1.448 + debug("Return from cipher conversion", $ciphers); 1.449 + } 1.450 + 1.451 + eval '$command = "'.$osDataArr{'clientRunCmd'}.'"'; 1.452 + debug("Executing command", $command); 1.453 + if (!open CMD_OUT, "$command 2>&1 |") { 1.454 + $ERR = "can not launch client"; 1.455 + return 0; 1.456 + } 1.457 + 1.458 + my @cmdOutArr = <CMD_OUT>; 1.459 + 1.460 + foreach (@cmdOutArr) { 1.461 + print $_; 1.462 + } 1.463 + 1.464 + my $haveVerify = 0; 1.465 + my $haveErrors = 0; 1.466 + foreach (@cmdOutArr) { 1.467 + chop; 1.468 + if (/unknown option/) { 1.469 + $haveErrors++; 1.470 + svr_error "unknown option\n"; 1.471 + next; 1.472 + } 1.473 + if (/Error performing handshake/) { 1.474 + $haveErrors++; 1.475 + svr_error "Error performing handshake\n"; 1.476 + next; 1.477 + } 1.478 + if (/Error creating credentials/) { 1.479 + $haveErrors++; 1.480 + svr_error "Error creating credentials\n"; 1.481 + next; 1.482 + } 1.483 + if (/Error .* authenticating server credentials!/) { 1.484 + $haveErrors++; 1.485 + svr_error "Error authenticating server credentials\n"; 1.486 + next; 1.487 + } 1.488 + if (/(error|ERROR|Error)/) { 1.489 + $haveErrors++; 1.490 + svr_error "found errors in server log\n"; 1.491 + next; 1.492 + } 1.493 + } 1.494 + 1.495 + if ($haveErrors > 0) { 1.496 + $ERR = "Have $haveErrors server errors"; 1.497 + debug "Exiting execClientCmd_Win"; 1.498 + return 0; 1.499 + } 1.500 + debug "Exiting execClientCmd_Win"; 1.501 + return 1; 1.502 +} 1.503 + 1.504 +################################################################# 1.505 +# Main line of execution 1.506 +#---------------------------------------------------------------- 1.507 +&init; 1.508 + 1.509 +if ($osDataArr{wservRun}) { 1.510 + print header('text/html'). 1.511 + start_html('iopr client'); 1.512 +} 1.513 + 1.514 +print "SCRIPT=OK\n"; 1.515 + 1.516 +if (!&getReqData) { 1.517 + svr_error($ERR, 1); 1.518 +} 1.519 + 1.520 +if (!&configClient) { 1.521 + svr_error($ERR, 1); 1.522 +} 1.523 + 1.524 +&{$osDataArr{'execCmdFn'}} || svr_error; 1.525 + 1.526 +if ($osDataArr{wservRun}) { 1.527 + print "</pre>"; 1.528 + print end_html; 1.529 +}