Home | History | Annotate | Download | only in tests
      1 #***************************************************************************
      2 #                                  _   _ ____  _
      3 #  Project                     ___| | | |  _ \| |
      4 #                             / __| | | | |_) | |
      5 #                            | (__| |_| |  _ <| |___
      6 #                             \___|\___/|_| \_\_____|
      7 #
      8 # Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel (at] haxx.se>, et al.
      9 #
     10 # This software is licensed as described in the file COPYING, which
     11 # you should have received as part of this distribution. The terms
     12 # are also available at https://curl.haxx.se/docs/copyright.html.
     13 #
     14 # You may opt to use, copy, modify, merge, publish, distribute and/or sell
     15 # copies of the Software, and permit persons to whom the Software is
     16 # furnished to do so, under the terms of the COPYING file.
     17 #
     18 # This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
     19 # KIND, either express or implied.
     20 #
     21 #***************************************************************************
     22 
     23 package sshhelp;
     24 
     25 use strict;
     26 use warnings;
     27 use Exporter;
     28 use File::Spec;
     29 
     30 
     31 #***************************************************************************
     32 # Global symbols allowed without explicit package name
     33 #
     34 use vars qw(
     35     @ISA
     36     @EXPORT_OK
     37     $sshdexe
     38     $sshexe
     39     $sftpsrvexe
     40     $sftpexe
     41     $sshkeygenexe
     42     $httptlssrvexe
     43     $sshdconfig
     44     $sshconfig
     45     $sftpconfig
     46     $knownhosts
     47     $sshdlog
     48     $sshlog
     49     $sftplog
     50     $sftpcmds
     51     $hstprvkeyf
     52     $hstpubkeyf
     53     $cliprvkeyf
     54     $clipubkeyf
     55     @sftppath
     56     @httptlssrvpath
     57     );
     58 
     59 
     60 #***************************************************************************
     61 # Inherit Exporter's capabilities
     62 #
     63 @ISA = qw(Exporter);
     64 
     65 
     66 #***************************************************************************
     67 # Global symbols this module will export upon request
     68 #
     69 @EXPORT_OK = qw(
     70     $sshdexe
     71     $sshexe
     72     $sftpsrvexe
     73     $sftpexe
     74     $sshkeygenexe
     75     $sshdconfig
     76     $sshconfig
     77     $sftpconfig
     78     $knownhosts
     79     $sshdlog
     80     $sshlog
     81     $sftplog
     82     $sftpcmds
     83     $hstprvkeyf
     84     $hstpubkeyf
     85     $cliprvkeyf
     86     $clipubkeyf
     87     display_sshdconfig
     88     display_sshconfig
     89     display_sftpconfig
     90     display_sshdlog
     91     display_sshlog
     92     display_sftplog
     93     dump_array
     94     exe_ext
     95     find_sshd
     96     find_ssh
     97     find_sftpsrv
     98     find_sftp
     99     find_sshkeygen
    100     find_httptlssrv
    101     logmsg
    102     sshversioninfo
    103     );
    104 
    105 
    106 #***************************************************************************
    107 # Global variables initialization
    108 #
    109 $sshdexe         = 'sshd'        .exe_ext(); # base name and ext of ssh daemon
    110 $sshexe          = 'ssh'         .exe_ext(); # base name and ext of ssh client
    111 $sftpsrvexe      = 'sftp-server' .exe_ext(); # base name and ext of sftp-server
    112 $sftpexe         = 'sftp'        .exe_ext(); # base name and ext of sftp client
    113 $sshkeygenexe    = 'ssh-keygen'  .exe_ext(); # base name and ext of ssh-keygen
    114 $httptlssrvexe   = 'gnutls-serv' .exe_ext(); # base name and ext of gnutls-serv
    115 $sshdconfig      = 'curl_sshd_config';       # ssh daemon config file
    116 $sshconfig       = 'curl_ssh_config';        # ssh client config file
    117 $sftpconfig      = 'curl_sftp_config';       # sftp client config file
    118 $sshdlog         = undef;                    # ssh daemon log file
    119 $sshlog          = undef;                    # ssh client log file
    120 $sftplog         = undef;                    # sftp client log file
    121 $sftpcmds        = 'curl_sftp_cmds';         # sftp client commands batch file
    122 $knownhosts      = 'curl_client_knownhosts'; # ssh knownhosts file
    123 $hstprvkeyf      = 'curl_host_rsa_key';      # host private key file
    124 $hstpubkeyf      = 'curl_host_rsa_key.pub';  # host public key file
    125 $cliprvkeyf      = 'curl_client_key';        # client private key file
    126 $clipubkeyf      = 'curl_client_key.pub';    # client public key file
    127 
    128 
    129 #***************************************************************************
    130 # Absolute paths where to look for sftp-server plugin, when not in PATH
    131 #
    132 @sftppath = qw(
    133     /usr/lib/openssh
    134     /usr/libexec/openssh
    135     /usr/libexec
    136     /usr/local/libexec
    137     /opt/local/libexec
    138     /usr/lib/ssh
    139     /usr/libexec/ssh
    140     /usr/sbin
    141     /usr/lib
    142     /usr/lib/ssh/openssh
    143     /usr/lib64/ssh
    144     /usr/lib64/misc
    145     /usr/lib/misc
    146     /usr/local/sbin
    147     /usr/freeware/bin
    148     /usr/freeware/sbin
    149     /usr/freeware/libexec
    150     /opt/ssh/sbin
    151     /opt/ssh/libexec
    152     );
    153 
    154 
    155 #***************************************************************************
    156 # Absolute paths where to look for httptlssrv (gnutls-serv), when not in PATH
    157 #
    158 @httptlssrvpath = qw(
    159     /usr/sbin
    160     /usr/libexec
    161     /usr/lib
    162     /usr/lib/misc
    163     /usr/lib64/misc
    164     /usr/local/bin
    165     /usr/local/sbin
    166     /usr/local/libexec
    167     /opt/local/bin
    168     /opt/local/sbin
    169     /opt/local/libexec
    170     /usr/freeware/bin
    171     /usr/freeware/sbin
    172     /usr/freeware/libexec
    173     /opt/gnutls/bin
    174     /opt/gnutls/sbin
    175     /opt/gnutls/libexec
    176     );
    177 
    178 
    179 #***************************************************************************
    180 # Return file extension for executable files on this operating system
    181 #
    182 sub exe_ext {
    183     if ($^O eq 'MSWin32' || $^O eq 'cygwin' || $^O eq 'msys' ||
    184         $^O eq 'dos' || $^O eq 'os2') {
    185         return '.exe';
    186     }
    187 }
    188 
    189 
    190 #***************************************************************************
    191 # Create or overwrite the given file with lines from an array of strings
    192 #
    193 sub dump_array {
    194     my ($filename, @arr) = @_;
    195     my $error;
    196 
    197     if(!$filename) {
    198         $error = 'Error: Missing argument 1 for dump_array()';
    199     }
    200     elsif(open(TEXTFH, ">$filename")) {
    201         foreach my $line (@arr) {
    202             $line .= "\n" unless($line =~ /\n$/);
    203             print TEXTFH $line;
    204         }
    205         if(!close(TEXTFH)) {
    206             $error = "Error: cannot close file $filename";
    207         }
    208     }
    209     else {
    210         $error = "Error: cannot write file $filename";
    211     }
    212     return $error;
    213 }
    214 
    215 
    216 #***************************************************************************
    217 # Display a message
    218 #
    219 sub logmsg {
    220     my ($line) = @_;
    221     chomp $line if($line);
    222     $line .= "\n";
    223     print "$line";
    224 }
    225 
    226 
    227 #***************************************************************************
    228 # Display contents of the given file
    229 #
    230 sub display_file {
    231     my $filename = $_[0];
    232     print "=== Start of file $filename\n";
    233     if(open(DISPLAYFH, "<$filename")) {
    234         while(my $line = <DISPLAYFH>) {
    235             print "$line";
    236         }
    237         close DISPLAYFH;
    238     }
    239     print "=== End of file $filename\n";
    240 }
    241 
    242 
    243 #***************************************************************************
    244 # Display contents of the ssh daemon config file
    245 #
    246 sub display_sshdconfig {
    247     display_file($sshdconfig);
    248 }
    249 
    250 
    251 #***************************************************************************
    252 # Display contents of the ssh client config file
    253 #
    254 sub display_sshconfig {
    255     display_file($sshconfig);
    256 }
    257 
    258 
    259 #***************************************************************************
    260 # Display contents of the sftp client config file
    261 #
    262 sub display_sftpconfig {
    263     display_file($sftpconfig);
    264 }
    265 
    266 
    267 #***************************************************************************
    268 # Display contents of the ssh daemon log file
    269 #
    270 sub display_sshdlog {
    271     die "error: \$sshdlog uninitialized" if(not defined $sshdlog);
    272     display_file($sshdlog);
    273 }
    274 
    275 
    276 #***************************************************************************
    277 # Display contents of the ssh client log file
    278 #
    279 sub display_sshlog {
    280     die "error: \$sshlog uninitialized" if(not defined $sshlog);
    281     display_file($sshlog);
    282 }
    283 
    284 
    285 #***************************************************************************
    286 # Display contents of the sftp client log file
    287 #
    288 sub display_sftplog {
    289     die "error: \$sftplog uninitialized" if(not defined $sftplog);
    290     display_file($sftplog);
    291 }
    292 
    293 
    294 #***************************************************************************
    295 # Find a file somewhere in the given path
    296 #
    297 sub find_file {
    298     my $fn = $_[0];
    299     shift;
    300     my @path = @_;
    301     foreach (@path) {
    302         my $file = File::Spec->catfile($_, $fn);
    303         if(-e $file && ! -d $file) {
    304             return $file;
    305         }
    306     }
    307 }
    308 
    309 
    310 #***************************************************************************
    311 # Find an executable file somewhere in the given path
    312 #
    313 sub find_exe_file {
    314     my $fn = $_[0];
    315     shift;
    316     my @path = @_;
    317     my $xext = exe_ext();
    318     foreach (@path) {
    319         my $file = File::Spec->catfile($_, $fn);
    320         if(-e $file && ! -d $file) {
    321             return $file if(-x $file);
    322             return $file if(($xext) && (lc($file) =~ /\Q$xext\E$/));
    323         }
    324     }
    325 }
    326 
    327 
    328 #***************************************************************************
    329 # Find a file in environment path or in our sftppath
    330 #
    331 sub find_file_spath {
    332     my $filename = $_[0];
    333     my @spath;
    334     push(@spath, File::Spec->path());
    335     push(@spath, @sftppath);
    336     return find_file($filename, @spath);
    337 }
    338 
    339 
    340 #***************************************************************************
    341 # Find an executable file in environment path or in our httptlssrvpath
    342 #
    343 sub find_exe_file_hpath {
    344     my $filename = $_[0];
    345     my @hpath;
    346     push(@hpath, File::Spec->path());
    347     push(@hpath, @httptlssrvpath);
    348     return find_exe_file($filename, @hpath);
    349 }
    350 
    351 
    352 #***************************************************************************
    353 # Find ssh daemon and return canonical filename
    354 #
    355 sub find_sshd {
    356     return find_file_spath($sshdexe);
    357 }
    358 
    359 
    360 #***************************************************************************
    361 # Find ssh client and return canonical filename
    362 #
    363 sub find_ssh {
    364     return find_file_spath($sshexe);
    365 }
    366 
    367 
    368 #***************************************************************************
    369 # Find sftp-server plugin and return canonical filename
    370 #
    371 sub find_sftpsrv {
    372     return find_file_spath($sftpsrvexe);
    373 }
    374 
    375 
    376 #***************************************************************************
    377 # Find sftp client and return canonical filename
    378 #
    379 sub find_sftp {
    380     return find_file_spath($sftpexe);
    381 }
    382 
    383 
    384 #***************************************************************************
    385 # Find ssh-keygen and return canonical filename
    386 #
    387 sub find_sshkeygen {
    388     return find_file_spath($sshkeygenexe);
    389 }
    390 
    391 
    392 #***************************************************************************
    393 # Find httptlssrv (gnutls-serv) and return canonical filename
    394 #
    395 sub find_httptlssrv {
    396     return find_exe_file_hpath($httptlssrvexe);
    397 }
    398 
    399 
    400 #***************************************************************************
    401 # Return version info for the given ssh client or server binaries
    402 #
    403 sub sshversioninfo {
    404     my $sshbin = $_[0]; # canonical filename
    405     my $major;
    406     my $minor;
    407     my $patch;
    408     my $sshid;
    409     my $versnum;
    410     my $versstr;
    411     my $error;
    412 
    413     if(!$sshbin) {
    414         $error = 'Error: Missing argument 1 for sshversioninfo()';
    415     }
    416     elsif(! -x $sshbin) {
    417         $error = "Error: cannot read or execute $sshbin";
    418     }
    419     else {
    420         my $cmd = ($sshbin =~ /$sshdexe$/) ? "\"$sshbin\" -?" : "\"$sshbin\" -V";
    421         $error = "$cmd\n";
    422         foreach my $tmpstr (qx($cmd 2>&1)) {
    423             if($tmpstr =~ /OpenSSH[_-](\d+)\.(\d+)(\.(\d+))*/i) {
    424                 $major = $1;
    425                 $minor = $2;
    426                 $patch = $4?$4:0;
    427                 $sshid = 'OpenSSH';
    428                 $versnum = (100*$major) + (10*$minor) + $patch;
    429                 $versstr = "$sshid $major.$minor.$patch";
    430                 $error = undef;
    431                 last;
    432             }
    433             if($tmpstr =~ /Sun[_-]SSH[_-](\d+)\.(\d+)(\.(\d+))*/i) {
    434                 $major = $1;
    435                 $minor = $2;
    436                 $patch = $4?$4:0;
    437                 $sshid = 'SunSSH';
    438                 $versnum = (100*$major) + (10*$minor) + $patch;
    439                 $versstr = "$sshid $major.$minor.$patch";
    440                 $error = undef;
    441                 last;
    442             }
    443             $error .= $tmpstr;
    444         }
    445         chomp $error if($error);
    446     }
    447     return ($sshid, $versnum, $versstr, $error);
    448 }
    449 
    450 
    451 #***************************************************************************
    452 # End of library
    453 1;
    454 
    455