123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478 |
- #***************************************************************************
- # _ _ ____ _
- # Project ___| | | | _ \| |
- # / __| | | | |_) | |
- # | (__| |_| | _ <| |___
- # \___|\___/|_| \_\_____|
- #
- # Copyright (C) 1998 - 2022, Daniel Stenberg, <daniel@haxx.se>, et al.
- #
- # This software is licensed as described in the file COPYING, which
- # you should have received as part of this distribution. The terms
- # are also available at https://curl.se/docs/copyright.html.
- #
- # You may opt to use, copy, modify, merge, publish, distribute and/or sell
- # copies of the Software, and permit persons to whom the Software is
- # furnished to do so, under the terms of the COPYING file.
- #
- # This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- # KIND, either express or implied.
- #
- # SPDX-License-Identifier: curl
- #
- #***************************************************************************
- package sshhelp;
- use strict;
- use warnings;
- use Exporter;
- use File::Spec;
- #***************************************************************************
- # Global symbols allowed without explicit package name
- #
- use vars qw(
- @ISA
- @EXPORT_OK
- $sshdexe
- $sshexe
- $sftpsrvexe
- $sftpexe
- $sshkeygenexe
- $httptlssrvexe
- $sshdconfig
- $sshconfig
- $sftpconfig
- $knownhosts
- $sshdlog
- $sshlog
- $sftplog
- $sftpcmds
- $hstprvkeyf
- $hstpubkeyf
- $hstpubmd5f
- $hstpubsha256f
- $cliprvkeyf
- $clipubkeyf
- @sftppath
- @httptlssrvpath
- );
- #***************************************************************************
- # Inherit Exporter's capabilities
- #
- @ISA = qw(Exporter);
- #***************************************************************************
- # Global symbols this module will export upon request
- #
- @EXPORT_OK = qw(
- $sshdexe
- $sshexe
- $sftpsrvexe
- $sftpexe
- $sshkeygenexe
- $sshdconfig
- $sshconfig
- $sftpconfig
- $knownhosts
- $sshdlog
- $sshlog
- $sftplog
- $sftpcmds
- $hstprvkeyf
- $hstpubkeyf
- $hstpubmd5f
- $hstpubsha256f
- $cliprvkeyf
- $clipubkeyf
- display_sshdconfig
- display_sshconfig
- display_sftpconfig
- display_sshdlog
- display_sshlog
- display_sftplog
- dump_array
- exe_ext
- find_sshd
- find_ssh
- find_sftpsrv
- find_sftp
- find_sshkeygen
- find_httptlssrv
- logmsg
- sshversioninfo
- );
- #***************************************************************************
- # Global variables initialization
- #
- $sshdexe = 'sshd' .exe_ext('SSH'); # base name and ext of ssh daemon
- $sshexe = 'ssh' .exe_ext('SSH'); # base name and ext of ssh client
- $sftpsrvexe = 'sftp-server' .exe_ext('SSH'); # base name and ext of sftp-server
- $sftpexe = 'sftp' .exe_ext('SSH'); # base name and ext of sftp client
- $sshkeygenexe = 'ssh-keygen' .exe_ext('SSH'); # base name and ext of ssh-keygen
- $httptlssrvexe = 'gnutls-serv' .exe_ext('SSH'); # base name and ext of gnutls-serv
- $sshdconfig = 'curl_sshd_config'; # ssh daemon config file
- $sshconfig = 'curl_ssh_config'; # ssh client config file
- $sftpconfig = 'curl_sftp_config'; # sftp client config file
- $sshdlog = undef; # ssh daemon log file
- $sshlog = undef; # ssh client log file
- $sftplog = undef; # sftp client log file
- $sftpcmds = 'curl_sftp_cmds'; # sftp client commands batch file
- $knownhosts = 'curl_client_knownhosts'; # ssh knownhosts file
- $hstprvkeyf = 'curl_host_rsa_key'; # host private key file
- $hstpubkeyf = 'curl_host_rsa_key.pub'; # host public key file
- $hstpubmd5f = 'curl_host_rsa_key.pub_md5'; # md5 hash of host public key
- $hstpubsha256f = 'curl_host_rsa_key.pub_sha256'; # sha256 hash of host public key
- $cliprvkeyf = 'curl_client_key'; # client private key file
- $clipubkeyf = 'curl_client_key.pub'; # client public key file
- #***************************************************************************
- # Absolute paths where to look for sftp-server plugin, when not in PATH
- #
- @sftppath = qw(
- /usr/lib/openssh
- /usr/libexec/openssh
- /usr/libexec
- /usr/local/libexec
- /opt/local/libexec
- /usr/lib/ssh
- /usr/libexec/ssh
- /usr/sbin
- /usr/lib
- /usr/lib/ssh/openssh
- /usr/lib64/ssh
- /usr/lib64/misc
- /usr/lib/misc
- /usr/local/sbin
- /usr/freeware/bin
- /usr/freeware/sbin
- /usr/freeware/libexec
- /opt/ssh/sbin
- /opt/ssh/libexec
- );
- #***************************************************************************
- # Absolute paths where to look for httptlssrv (gnutls-serv), when not in PATH
- #
- @httptlssrvpath = qw(
- /usr/sbin
- /usr/libexec
- /usr/lib
- /usr/lib/misc
- /usr/lib64/misc
- /usr/local/bin
- /usr/local/sbin
- /usr/local/libexec
- /opt/local/bin
- /opt/local/sbin
- /opt/local/libexec
- /usr/freeware/bin
- /usr/freeware/sbin
- /usr/freeware/libexec
- /opt/gnutls/bin
- /opt/gnutls/sbin
- /opt/gnutls/libexec
- );
- #***************************************************************************
- # Return file extension for executable files on this operating system
- #
- sub exe_ext {
- my ($component, @arr) = @_;
- if ($ENV{'CURL_TEST_EXE_EXT'}) {
- return $ENV{'CURL_TEST_EXE_EXT'};
- }
- if ($ENV{'CURL_TEST_EXE_EXT_'.$component}) {
- return $ENV{'CURL_TEST_EXE_EXT_'.$component};
- }
- if ($^O eq 'MSWin32' || $^O eq 'cygwin' || $^O eq 'msys' ||
- $^O eq 'dos' || $^O eq 'os2') {
- return '.exe';
- }
- }
- #***************************************************************************
- # Create or overwrite the given file with lines from an array of strings
- #
- sub dump_array {
- my ($filename, @arr) = @_;
- my $error;
- if(!$filename) {
- $error = 'Error: Missing argument 1 for dump_array()';
- }
- elsif(open(TEXTFH, ">$filename")) {
- foreach my $line (@arr) {
- $line .= "\n" unless($line =~ /\n$/);
- print TEXTFH $line;
- }
- if(!close(TEXTFH)) {
- $error = "Error: cannot close file $filename";
- }
- }
- else {
- $error = "Error: cannot write file $filename";
- }
- return $error;
- }
- #***************************************************************************
- # Display a message
- #
- sub logmsg {
- my ($line) = @_;
- chomp $line if($line);
- $line .= "\n";
- print "$line";
- }
- #***************************************************************************
- # Display contents of the given file
- #
- sub display_file {
- my $filename = $_[0];
- print "=== Start of file $filename\n";
- if(open(DISPLAYFH, "<$filename")) {
- while(my $line = <DISPLAYFH>) {
- print "$line";
- }
- close DISPLAYFH;
- }
- print "=== End of file $filename\n";
- }
- #***************************************************************************
- # Display contents of the ssh daemon config file
- #
- sub display_sshdconfig {
- display_file($sshdconfig);
- }
- #***************************************************************************
- # Display contents of the ssh client config file
- #
- sub display_sshconfig {
- display_file($sshconfig);
- }
- #***************************************************************************
- # Display contents of the sftp client config file
- #
- sub display_sftpconfig {
- display_file($sftpconfig);
- }
- #***************************************************************************
- # Display contents of the ssh daemon log file
- #
- sub display_sshdlog {
- die "error: \$sshdlog uninitialized" if(not defined $sshdlog);
- display_file($sshdlog);
- }
- #***************************************************************************
- # Display contents of the ssh client log file
- #
- sub display_sshlog {
- die "error: \$sshlog uninitialized" if(not defined $sshlog);
- display_file($sshlog);
- }
- #***************************************************************************
- # Display contents of the sftp client log file
- #
- sub display_sftplog {
- die "error: \$sftplog uninitialized" if(not defined $sftplog);
- display_file($sftplog);
- }
- #***************************************************************************
- # Find a file somewhere in the given path
- #
- sub find_file {
- my $fn = $_[0];
- shift;
- my @path = @_;
- foreach (@path) {
- my $file = File::Spec->catfile($_, $fn);
- if(-e $file && ! -d $file) {
- return $file;
- }
- }
- }
- #***************************************************************************
- # Find an executable file somewhere in the given path
- #
- sub find_exe_file {
- my $fn = $_[0];
- shift;
- my @path = @_;
- my $xext = exe_ext('SSH');
- foreach (@path) {
- my $file = File::Spec->catfile($_, $fn);
- if(-e $file && ! -d $file) {
- return $file if(-x $file);
- return $file if(($xext) && (lc($file) =~ /\Q$xext\E$/));
- }
- }
- }
- #***************************************************************************
- # Find a file in environment path or in our sftppath
- #
- sub find_file_spath {
- my $filename = $_[0];
- my @spath;
- push(@spath, File::Spec->path());
- push(@spath, @sftppath);
- return find_file($filename, @spath);
- }
- #***************************************************************************
- # Find an executable file in environment path or in our httptlssrvpath
- #
- sub find_exe_file_hpath {
- my $filename = $_[0];
- my @hpath;
- push(@hpath, File::Spec->path());
- push(@hpath, @httptlssrvpath);
- return find_exe_file($filename, @hpath);
- }
- #***************************************************************************
- # Find ssh daemon and return canonical filename
- #
- sub find_sshd {
- return find_file_spath($sshdexe);
- }
- #***************************************************************************
- # Find ssh client and return canonical filename
- #
- sub find_ssh {
- return find_file_spath($sshexe);
- }
- #***************************************************************************
- # Find sftp-server plugin and return canonical filename
- #
- sub find_sftpsrv {
- return find_file_spath($sftpsrvexe);
- }
- #***************************************************************************
- # Find sftp client and return canonical filename
- #
- sub find_sftp {
- return find_file_spath($sftpexe);
- }
- #***************************************************************************
- # Find ssh-keygen and return canonical filename
- #
- sub find_sshkeygen {
- return find_file_spath($sshkeygenexe);
- }
- #***************************************************************************
- # Find httptlssrv (gnutls-serv) and return canonical filename
- #
- sub find_httptlssrv {
- return find_exe_file_hpath($httptlssrvexe);
- }
- #***************************************************************************
- # Return version info for the given ssh client or server binaries
- #
- sub sshversioninfo {
- my $sshbin = $_[0]; # canonical filename
- my $major;
- my $minor;
- my $patch;
- my $sshid;
- my $versnum;
- my $versstr;
- my $error;
- if(!$sshbin) {
- $error = 'Error: Missing argument 1 for sshversioninfo()';
- }
- elsif(! -x $sshbin) {
- $error = "Error: cannot read or execute $sshbin";
- }
- else {
- my $cmd = ($sshbin =~ /$sshdexe$/) ? "\"$sshbin\" -?" : "\"$sshbin\" -V";
- $error = "$cmd\n";
- foreach my $tmpstr (qx($cmd 2>&1)) {
- if($tmpstr =~ /OpenSSH[_-](\d+)\.(\d+)(\.(\d+))*/i) {
- $major = $1;
- $minor = $2;
- $patch = $4?$4:0;
- $sshid = 'OpenSSH';
- $versnum = (100*$major) + (10*$minor) + $patch;
- $versstr = "$sshid $major.$minor.$patch";
- $error = undef;
- last;
- }
- if($tmpstr =~ /OpenSSH[_-]for[_-]Windows[_-](\d+)\.(\d+)(\.(\d+))*/i) {
- $major = $1;
- $minor = $2;
- $patch = $4?$4:0;
- $sshid = 'OpenSSH-Windows';
- $versnum = (100*$major) + (10*$minor) + $patch;
- $versstr = "$sshid $major.$minor.$patch";
- $error = undef;
- last;
- }
- if($tmpstr =~ /Sun[_-]SSH[_-](\d+)\.(\d+)(\.(\d+))*/i) {
- $major = $1;
- $minor = $2;
- $patch = $4?$4:0;
- $sshid = 'SunSSH';
- $versnum = (100*$major) + (10*$minor) + $patch;
- $versstr = "$sshid $major.$minor.$patch";
- $error = undef;
- last;
- }
- $error .= $tmpstr;
- }
- chomp $error if($error);
- }
- return ($sshid, $versnum, $versstr, $error);
- }
- #***************************************************************************
- # End of library
- 1;
|