security/nss/tests/iopr/server_scr/client.cgi

changeset 0
6474c204b198
     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 +}

mercurial