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