quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

sshhelp.pm (12435B)


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