Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  client.cgi   Sprache: unbekannt

 
#!/usr/bin/perl

# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.

#--------------------------------------------------------------
# cgi script that parses request argument to appropriate 
# open ssl or tstclntw options and starts ssl client.
#

use CGI qw/:standard/;

use subs qw(debug);

#--------------------------------------------------------------
# Prints out an error string and exits the script with an
# exitStatus.
# Param:
#    str : an error string
#    exitStat: an exit status of the program
#
sub svr_error {
    my ($str, $exitStat) = @_;

    if (!defined $str || $str eq "") {
        $str = $ERR;
    }
    print "SERVER ERROR: $str\n";
    if ($exitStat) {
        print end_html if ($osDataArr{wservRun});
        exit $exitStat;
    }
}

#--------------------------------------------------------------
# Prints out a debug message
# Params:
#     str: debug message
#     inVal: additional value to print(optional)
#
sub debug {
    my ($str, $inVal) = @_;
    
    print "-- DEBUG: $str ($inVal)\n" if ($DEBUG == 1);
}


#--------------------------------------------------------------
# Initializes execution context depending on a webserver the
# script is running under.
#
sub init {
    %osDataArr = (
                  loadSupportedCipthersFn => \&osSpecific,
                  cipherIsSupportedFn => \&verifyCipherSupport,
                  cipherListFn => \&convertCipher,
                  buildCipherTableFn => \&buildCipherTable,
                  execCmdFn => \&osSpecific,
                  );

    $scriptName = $ENV{'SCRIPT_NAME'};
    if (!defined $scriptName) {
        $DEBUG=1;
        debug "Debug is ON";
    }
    $DEBUG=1;
    
    $svrSoft = $ENV{'SERVER_SOFTWARE'};
    if (defined $svrSoft) {
        $_ = $svrSoft;
        /.*Microsoft.*/ && ($osDataArr{wserv} = "IIS");
        /.*Apache.*/ && ($osDataArr{wserv} = "Apache");
        $osDataArr{wservRun} = 1;
    } else {
        $osDataArr{wserv} = "Apache";
        $osDataArr{wservRun} = 0;
    }
}

#--------------------------------------------------------------
# Function-spigot to handle errors is OS specific functions are
# not implemented for a particular OS.
# Returns:
#   always returns 0(failure)
#
sub osSpecific {
    $ERR = "This function should be swapped to os specific function.";
    return 0;
}

#--------------------------------------------------------------
# Sets os specific execution context values.
# Returns:
#    1 upon success, or 0 upon failure(if OS was not recognized)
#
sub setFunctRefs {
    
    debug("Entering setFunctRefs function", $osDataArr{wserv});

    if ($osDataArr{wserv} eq "Apache") {
        $osDataArr{osConfigFile} = "apache_unix.cfg";
        $osDataArr{suppCiphersCmd} = '$opensslb ciphers ALL:NULL';
        $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';
        $osDataArr{loadSupportedCipthersFn} = \&getSupportedCipherList_Unix;
        $osDataArr{execCmdFn} = \&execClientCmd_Unix;
    } elsif ($osDataArr{wserv} eq "IIS") {
        $osDataArr{osConfigFile} = "iis_windows.cfg";
        $osDataArr{suppCiphersCmd} = '$tstclntwb';
        $osDataArr{clientRunCmd} = '$tstclntwb -h $in_host -p $in_port -n $in_cert $proto $ciphers < $reqFile';
        $osDataArr{loadSupportedCipthersFn} = \&getSupportedCipherList_Win;
        $osDataArr{execCmdFn} = \&execClientCmd_Win;
    } else {
        $ERR = "Unknown Web Server  type.";
        return 0;
    }
    return 1;
}

#--------------------------------------------------------------
# Parses data from HTTP request. Will print a form if request
# does not contain sufficient number of parameters.
# Returns: 
#     1 if request has sufficient number of parameters
#     0 if not.
sub getReqData {
    my $debug = param('debug');
    $in_host = param('host');
    $in_port = param('port');
    $in_cert = param('cert');
    $in_cipher = param('cipher');

    if (!$osDataArr{wservRun}) {
        $in_host="goa1";
        $in_port="443";
        $in_cert="TestUser511";
        $in_cipher = "SSL3_RSA_WITH_NULL_SHA";
    }

    debug("Entering getReqData function", "$in_port:$in_host:$in_cert:$in_cipher");

    if (defined $debug && $debug == "debug on") {
        $DEBUG = 1;
    }

    if (!defined $in_host || $in_host eq "" ||
        !defined $in_port || $in_port eq "" ||
        !defined $in_cert || $in_cert eq "") {
        if ($osDataArr{wservRun}) {
            print h1('Command description form:'),
            start_form(-method=>"get"),
            "Host: ",textfield('host'),p,
            "Port: ",textfield('port'),p,
            "Cert: ",textfield('cert'),p,
            "Cipher: ",textfield('cipher'),p,
            checkbox_group(-name=>'debug',
                           -values=>['debug on  ']),
            submit,
            end_form,
            hr;
        } else {
            print "Printing html form to get client arguments\n";
        }
        $ERR = "the following parameters are required: host, port, cert";
        return 0;
    } else {
        print "<pre>" if ($osDataArr{wservRun});
        return 1;
    }
}


#--------------------------------------------------------------
# Building cipher conversion table from file based on the OS.
# Params:
#     tfile: cipher conversion file.
#     sysName: system name
#     tblPrt: returned pointer to a table.
sub buildCipherTable {
    my ($tfile, $sysName, $tblPrt) = @_;
    my @retArr = @$tblPrt;
    my %table, %rtable;
    my $strCount = 0;

    debug("Entering getReqData function", "$tfile:$sysName:$tblPrt");

    ($ERR = "No system name supplied" && return 0) if ($sysName =~ /^$/);
    if (!open(TFILE, "$tfile")) {
        $ERR = "Missing cipher conversion table file.";
        return 0;
    }
    foreach (<TFILE>) {
        chop;
        /^#.*/ && next;
        /^\s*$/ && next;
        if ($strCount++ == 0) {
            my @sysArr =  split /\s+/;
            $colCount = 0;
            for (;$colCount <= $#sysArr;$colCount++) {
                last if ($sysArr[$colCount] =~ /(.*:|^)$sysName.*/);
            }
            next;
        }
        my @ciphArr =  split /\s+/, $_;
        $table{$ciphArr[0]} = $ciphArr[$colCount];
        $rtable{$ciphArr[$colCount]} = $ciphArr[0];
    }
    close(TFILE);
    $cipherTablePtr[0] = \%table;
    $cipherTablePtr[1] = \%rtable;
    return 1
}

#--------------------------------------------------------------
# Client configuration function. Loads client configuration file.
# Initiates cipher table. Loads cipher list supported by ssl client.
#
sub configClient {

    debug "Entering configClient function";

    my $res = &setFunctRefs();
    return $res if (!$res);

    open(CFILE, $osDataArr{'osConfigFile'}) ||
        ($ERR = "Missing configuration file." && return 0);
    foreach (<CFILE>) {
        /^#.*/ && next;
        chop;
        eval $_;
    }
    close(CFILE);
   
    local @cipherTablePtr = ();
    $osDataArr{'buildCipherTableFn'}->($cipherTableFile, $clientSys) || return 0;
    $osDataArr{cipherTable} = $cipherTablePtr[0];
    $osDataArr{rcipherTable} = $cipherTablePtr[1];
    
    local $suppCiphersTablePrt;
    &{$osDataArr{'loadSupportedCipthersFn'}} || return 0;
    $osDataArr{suppCiphersTable} = $suppCiphersTablePrt;
}

#--------------------------------------------------------------
# Verifies that a particular cipher is supported.
# Params:
#    checkCipher: cipher name
# Returns:
#    1 - cipher is supported(also echos the cipher).
#    0 - not supported.
#
sub verifyCipherSupport {
    my ($checkCipher) = @_;
    my @suppCiphersTable = @{$osDataArr{suppCiphersTable}};

    debug("Entering verifyCipherSupport", $checkCipher);
    foreach (@suppCiphersTable) {
        return 1 if ($checkCipher eq $_);
    }
    $ERR = "cipher is not supported.";
    return 0;
}

#--------------------------------------------------------------
# Converts long(?name of the type?) cipher name to 
# openssl/tstclntw cipher name.
# Returns:
#   0 if cipher was not listed. 1 upon success.
#
sub convertCipher {
    my ($cipher) = @_;
    my @retList;
    my $resStr;
    my %cipherTable = %{$osDataArr{cipherTable}};

    debug("Entering convertCipher", $cipher);
    if (defined $cipher) {
        my $cphr = $cipherTable{$cipher};
        if (!defined $cphr) {
            $ERR = "cipher is not listed.";
            return 0;
        }        
        &{$osDataArr{'cipherIsSupportedFn'}}($cphr) || return 0;
        $ciphers = "$cphr";
        return 1;
    }
    return 0;
}

#################################################################
#  UNIX Apache Specific functions
#----------------------------------------------------------------

#--------------------------------------------------------------
# Executes ssl client command to get a list of ciphers supported
# by client.
#
sub getSupportedCipherList_Unix {
    my @arr, @suppCiphersTable;

    debug "Entering getSupportedCipherList_Unix function";

    eval '$sLisrCmd = "'.$osDataArr{'suppCiphersCmd'}.'"';
    if (!open (OUT, "$sLisrCmd|")) {
        $ERR="Can not run command to verify supported cipher list.";
        return 0;
    }
    @arr = <OUT>;
    chop $arr[0];
    @suppCiphersTable = split /:/, $arr[0];
    debug("Supported ciphers", $arr[0]);
    $suppCiphersTablePrt = \@suppCiphersTable;
    close(OUT);
    return 1;
}

#--------------------------------------------------------------
# Lunches ssl client command in response to a request.
#
#
sub execClientCmd_Unix {
    my $proto;
    local $ciphers;

    debug "Entering execClientCmd_Unix";
    if (defined $in_cipher && $in_cipher ne "") {
        my @arr = split /_/, $in_cipher, 2;
        $proto = "-".$arr[0];
        $proto =~ tr /SLT/slt/;
        $proto = "-tls1" if ($proto eq "-tls");
        return 0 if (!&{$osDataArr{'cipherListFn'}}($in_cipher));
        $ciphers = "-cipher $ciphers";
        debug("Return from cipher conversion", "$ciphers");
    }

    eval '$command = "'.$osDataArr{'clientRunCmd'}.'"';
    debug("Executing command", $command);
    if (!open CMD_OUT, "$command 2>&1 |") {
       $ERR = "can not launch client";
       return 0;
    }

    my @cmdOutArr = <CMD_OUT>;
    
    foreach (@cmdOutArr) {
        print $_;
    }

    my $haveVerify = 0;
    my $haveErrors = 0;
    foreach (@cmdOutArr) {
        chop;
        if (/unknown option/) {
            $haveErrors++;
            svr_error "unknown option\n";
            next;
        }
        if (/:no ciphers available/) {
            $haveErrors++;
            svr_error "no cipthers available\n";
            next;
        }
        if (/verify error:/) {
            $haveErrors++;
            svr_error "unable to do verification\n";
            next;
        }
        if (/alert certificate revoked:/) {
            $haveErrors++;
            svr_error "attempt to connect with revoked sertificate\n";
            next;
        }
        if (/(error|ERROR)/) {
            $haveErrors++;
            svr_error "found errors in server log\n";
            next;
        }
        /verify return:1/ && ($haveVerify = 1);
    }
     if ($haveVerify == 0) {
         svr_error "no 'verify return:1' found in server log\n";
         $haveErrors++;
     }

    if ($haveErrors > 0) {
        $ERR = "Have $haveErrors server errors";
        debug "Exiting execClientCmd_Unix";
        return 0;
    }
    debug "Exiting execClientCmd_Unix";
    return 1;
}

#################################################################
#  Windows IIS Specific functions
#----------------------------------------------------------------

#--------------------------------------------------------------
# Executes ssl client command to get a list of ciphers supported
# by client.
#
sub getSupportedCipherList_Win {
    my @arr, @suppCiphersTable;

    debug "Entering getSupportedCipherList_Win function";

    eval '$sLisrCmd = "'.$osDataArr{'suppCiphersCmd'}.'"';
    if (!open (OUT, "$sLisrCmd|")) {
        $ERR="Can not run command to verify supported cipher list.";
        return 0;
    }
    my $startCipherList = 0;
    foreach (<OUT>) {
        chop;
        if ($startCipherList) {
            /^([a-zA-Z])\s+/ && push @suppCiphersTable, $1;
            next;
        }
        /.*from list below.*/ && ($startCipherList = 1);
    }
    debug("Supported ciphers", join ':', @suppCiphersTable);
    $suppCiphersTablePrt = \@suppCiphersTable;
    close(OUT);
    return 1;
}

#--------------------------------------------------------------
# Lunches ssl client command in response to a request.
#
#
sub execClientCmd_Win {
    my $proto;
    local $ciphers;

    debug "Entering execClientCmd_Win";
    if (defined $in_cipher && $in_cipher ne "") {
        my @arr = split /_/, $in_cipher, 2;
        $proto = "-2 -3 -T";

        $proto =~ s/-T// if ($arr[0] eq "TLS");
        $proto =~ s/-3// if ($arr[0] eq "SSL3");
        $proto =~ s/-2// if ($arr[0] eq "SSL2");
 return 0 if (!&{$osDataArr{'cipherListFn'}}($in_cipher));
        $ciphers = "-c $ciphers";
        debug("Return from cipher conversion", $ciphers);
    }

    eval '$command = "'.$osDataArr{'clientRunCmd'}.'"';
    debug("Executing command", $command);
    if (!open CMD_OUT, "$command 2>&1 |") {
        $ERR = "can not launch client";
        return 0;
    }

    my @cmdOutArr = <CMD_OUT>;
    
    foreach (@cmdOutArr) {
        print $_;
    }

    my $haveVerify = 0;
    my $haveErrors = 0;
    foreach (@cmdOutArr) {
        chop;
        if (/unknown option/) {
            $haveErrors++;
            svr_error "unknown option\n";
            next;
        }
        if (/Error performing handshake/) {
            $haveErrors++;
            svr_error "Error performing handshake\n";
            next;
        }
        if (/Error creating credentials/) {
            $haveErrors++;
            svr_error "Error creating credentials\n";
            next;
        }
        if (/Error .* authenticating server credentials!/) {
            $haveErrors++;
            svr_error "Error authenticating server credentials\n";
            next;
        }
        if (/(error|ERROR|Error)/) {
            $haveErrors++;
            svr_error "found errors in server log\n";
            next;
        }
    }

    if ($haveErrors > 0) {
        $ERR = "Have $haveErrors server errors";
        debug "Exiting execClientCmd_Win";
        return 0;
    }
    debug "Exiting execClientCmd_Win";
    return 1;
}

#################################################################
#  Main line of execution
#----------------------------------------------------------------
&init;

if ($osDataArr{wservRun}) {
    print header('text/html').
        start_html('iopr client');
}
 
print "SCRIPT=OK\n";

if (!&getReqData) { 
    svr_error($ERR, 1);
}

if (!&configClient) { 
    svr_error($ERR, 1);
}

&{$osDataArr{'execCmdFn'}} || svr_error;

if ($osDataArr{wservRun}) {
    print "</pre>";
    print end_html;
}

[ Dauer der Verarbeitung: 0.27 Sekunden  (vorverarbeitet)  ]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge