113498266Sopenharmony_ci#*************************************************************************** 213498266Sopenharmony_ci# _ _ ____ _ 313498266Sopenharmony_ci# Project ___| | | | _ \| | 413498266Sopenharmony_ci# / __| | | | |_) | | 513498266Sopenharmony_ci# | (__| |_| | _ <| |___ 613498266Sopenharmony_ci# \___|\___/|_| \_\_____| 713498266Sopenharmony_ci# 813498266Sopenharmony_ci# Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. 913498266Sopenharmony_ci# 1013498266Sopenharmony_ci# This software is licensed as described in the file COPYING, which 1113498266Sopenharmony_ci# you should have received as part of this distribution. The terms 1213498266Sopenharmony_ci# are also available at https://curl.se/docs/copyright.html. 1313498266Sopenharmony_ci# 1413498266Sopenharmony_ci# You may opt to use, copy, modify, merge, publish, distribute and/or sell 1513498266Sopenharmony_ci# copies of the Software, and permit persons to whom the Software is 1613498266Sopenharmony_ci# furnished to do so, under the terms of the COPYING file. 1713498266Sopenharmony_ci# 1813498266Sopenharmony_ci# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 1913498266Sopenharmony_ci# KIND, either express or implied. 2013498266Sopenharmony_ci# 2113498266Sopenharmony_ci# SPDX-License-Identifier: curl 2213498266Sopenharmony_ci# 2313498266Sopenharmony_ci#*************************************************************************** 2413498266Sopenharmony_ci 2513498266Sopenharmony_cipackage sshhelp; 2613498266Sopenharmony_ci 2713498266Sopenharmony_ciuse strict; 2813498266Sopenharmony_ciuse warnings; 2913498266Sopenharmony_ci 3013498266Sopenharmony_ciBEGIN { 3113498266Sopenharmony_ci use base qw(Exporter); 3213498266Sopenharmony_ci 3313498266Sopenharmony_ci our @EXPORT_OK = qw( 3413498266Sopenharmony_ci $sshdexe 3513498266Sopenharmony_ci $sshexe 3613498266Sopenharmony_ci $sftpsrvexe 3713498266Sopenharmony_ci $sftpexe 3813498266Sopenharmony_ci $sshkeygenexe 3913498266Sopenharmony_ci $sshdconfig 4013498266Sopenharmony_ci $sshconfig 4113498266Sopenharmony_ci $sftpconfig 4213498266Sopenharmony_ci $knownhosts 4313498266Sopenharmony_ci $sshdlog 4413498266Sopenharmony_ci $sshlog 4513498266Sopenharmony_ci $sftplog 4613498266Sopenharmony_ci $sftpcmds 4713498266Sopenharmony_ci $hstprvkeyf 4813498266Sopenharmony_ci $hstpubkeyf 4913498266Sopenharmony_ci $hstpubmd5f 5013498266Sopenharmony_ci $hstpubsha256f 5113498266Sopenharmony_ci $cliprvkeyf 5213498266Sopenharmony_ci $clipubkeyf 5313498266Sopenharmony_ci display_sshdconfig 5413498266Sopenharmony_ci display_sshconfig 5513498266Sopenharmony_ci display_sftpconfig 5613498266Sopenharmony_ci display_sshdlog 5713498266Sopenharmony_ci display_sshlog 5813498266Sopenharmony_ci display_sftplog 5913498266Sopenharmony_ci dump_array 6013498266Sopenharmony_ci find_sshd 6113498266Sopenharmony_ci find_ssh 6213498266Sopenharmony_ci find_sftpsrv 6313498266Sopenharmony_ci find_sftp 6413498266Sopenharmony_ci find_sshkeygen 6513498266Sopenharmony_ci find_httptlssrv 6613498266Sopenharmony_ci sshversioninfo 6713498266Sopenharmony_ci ); 6813498266Sopenharmony_ci} 6913498266Sopenharmony_ci 7013498266Sopenharmony_ciuse File::Spec; 7113498266Sopenharmony_ci 7213498266Sopenharmony_ciuse pathhelp qw( 7313498266Sopenharmony_ci exe_ext 7413498266Sopenharmony_ci ); 7513498266Sopenharmony_ci 7613498266Sopenharmony_ci#*************************************************************************** 7713498266Sopenharmony_ci# Global variables initialization 7813498266Sopenharmony_ci# 7913498266Sopenharmony_ciour $sshdexe = 'sshd' .exe_ext('SSH'); # base name and ext of ssh daemon 8013498266Sopenharmony_ciour $sshexe = 'ssh' .exe_ext('SSH'); # base name and ext of ssh client 8113498266Sopenharmony_ciour $sftpsrvexe = 'sftp-server' .exe_ext('SSH'); # base name and ext of sftp-server 8213498266Sopenharmony_ciour $sftpexe = 'sftp' .exe_ext('SSH'); # base name and ext of sftp client 8313498266Sopenharmony_ciour $sshkeygenexe = 'ssh-keygen' .exe_ext('SSH'); # base name and ext of ssh-keygen 8413498266Sopenharmony_ciour $httptlssrvexe = 'gnutls-serv' .exe_ext('SSH'); # base name and ext of gnutls-serv 8513498266Sopenharmony_ciour $sshdconfig = 'curl_sshd_config'; # ssh daemon config file 8613498266Sopenharmony_ciour $sshconfig = 'curl_ssh_config'; # ssh client config file 8713498266Sopenharmony_ciour $sftpconfig = 'curl_sftp_config'; # sftp client config file 8813498266Sopenharmony_ciour $sshdlog = undef; # ssh daemon log file 8913498266Sopenharmony_ciour $sshlog = undef; # ssh client log file 9013498266Sopenharmony_ciour $sftplog = undef; # sftp client log file 9113498266Sopenharmony_ciour $sftpcmds = 'curl_sftp_cmds'; # sftp client commands batch file 9213498266Sopenharmony_ciour $knownhosts = 'curl_client_knownhosts'; # ssh knownhosts file 9313498266Sopenharmony_ciour $hstprvkeyf = 'curl_host_rsa_key'; # host private key file 9413498266Sopenharmony_ciour $hstpubkeyf = 'curl_host_rsa_key.pub'; # host public key file 9513498266Sopenharmony_ciour $hstpubmd5f = 'curl_host_rsa_key.pub_md5'; # md5 hash of host public key 9613498266Sopenharmony_ciour $hstpubsha256f = 'curl_host_rsa_key.pub_sha256'; # sha256 hash of host public key 9713498266Sopenharmony_ciour $cliprvkeyf = 'curl_client_key'; # client private key file 9813498266Sopenharmony_ciour $clipubkeyf = 'curl_client_key.pub'; # client public key file 9913498266Sopenharmony_ci 10013498266Sopenharmony_ci 10113498266Sopenharmony_ci#*************************************************************************** 10213498266Sopenharmony_ci# Absolute paths where to look for sftp-server plugin, when not in PATH 10313498266Sopenharmony_ci# 10413498266Sopenharmony_ciour @sftppath = qw( 10513498266Sopenharmony_ci /usr/lib/openssh 10613498266Sopenharmony_ci /usr/libexec/openssh 10713498266Sopenharmony_ci /usr/libexec 10813498266Sopenharmony_ci /usr/local/libexec 10913498266Sopenharmony_ci /opt/local/libexec 11013498266Sopenharmony_ci /usr/lib/ssh 11113498266Sopenharmony_ci /usr/libexec/ssh 11213498266Sopenharmony_ci /usr/sbin 11313498266Sopenharmony_ci /usr/lib 11413498266Sopenharmony_ci /usr/lib/ssh/openssh 11513498266Sopenharmony_ci /usr/lib64/ssh 11613498266Sopenharmony_ci /usr/lib64/misc 11713498266Sopenharmony_ci /usr/lib/misc 11813498266Sopenharmony_ci /usr/local/sbin 11913498266Sopenharmony_ci /usr/freeware/bin 12013498266Sopenharmony_ci /usr/freeware/sbin 12113498266Sopenharmony_ci /usr/freeware/libexec 12213498266Sopenharmony_ci /opt/ssh/sbin 12313498266Sopenharmony_ci /opt/ssh/libexec 12413498266Sopenharmony_ci ); 12513498266Sopenharmony_ci 12613498266Sopenharmony_ci 12713498266Sopenharmony_ci#*************************************************************************** 12813498266Sopenharmony_ci# Absolute paths where to look for httptlssrv (gnutls-serv), when not in PATH 12913498266Sopenharmony_ci# 13013498266Sopenharmony_ciour @httptlssrvpath = qw( 13113498266Sopenharmony_ci /usr/sbin 13213498266Sopenharmony_ci /usr/libexec 13313498266Sopenharmony_ci /usr/lib 13413498266Sopenharmony_ci /usr/lib/misc 13513498266Sopenharmony_ci /usr/lib64/misc 13613498266Sopenharmony_ci /usr/local/bin 13713498266Sopenharmony_ci /usr/local/sbin 13813498266Sopenharmony_ci /usr/local/libexec 13913498266Sopenharmony_ci /opt/local/bin 14013498266Sopenharmony_ci /opt/local/sbin 14113498266Sopenharmony_ci /opt/local/libexec 14213498266Sopenharmony_ci /usr/freeware/bin 14313498266Sopenharmony_ci /usr/freeware/sbin 14413498266Sopenharmony_ci /usr/freeware/libexec 14513498266Sopenharmony_ci /opt/gnutls/bin 14613498266Sopenharmony_ci /opt/gnutls/sbin 14713498266Sopenharmony_ci /opt/gnutls/libexec 14813498266Sopenharmony_ci ); 14913498266Sopenharmony_ci 15013498266Sopenharmony_ci 15113498266Sopenharmony_ci#*************************************************************************** 15213498266Sopenharmony_ci# Create or overwrite the given file with lines from an array of strings 15313498266Sopenharmony_ci# 15413498266Sopenharmony_cisub dump_array { 15513498266Sopenharmony_ci my ($filename, @arr) = @_; 15613498266Sopenharmony_ci my $error; 15713498266Sopenharmony_ci 15813498266Sopenharmony_ci if(!$filename) { 15913498266Sopenharmony_ci $error = 'Error: Missing argument 1 for dump_array()'; 16013498266Sopenharmony_ci } 16113498266Sopenharmony_ci elsif(open(my $textfh, ">", $filename)) { 16213498266Sopenharmony_ci foreach my $line (@arr) { 16313498266Sopenharmony_ci $line .= "\n" if($line !~ /\n$/); 16413498266Sopenharmony_ci print $textfh $line; 16513498266Sopenharmony_ci } 16613498266Sopenharmony_ci if(!close($textfh)) { 16713498266Sopenharmony_ci $error = "Error: cannot close file $filename"; 16813498266Sopenharmony_ci } 16913498266Sopenharmony_ci } 17013498266Sopenharmony_ci else { 17113498266Sopenharmony_ci $error = "Error: cannot write file $filename"; 17213498266Sopenharmony_ci } 17313498266Sopenharmony_ci return $error; 17413498266Sopenharmony_ci} 17513498266Sopenharmony_ci 17613498266Sopenharmony_ci 17713498266Sopenharmony_ci#*************************************************************************** 17813498266Sopenharmony_ci# Display contents of the given file 17913498266Sopenharmony_ci# 18013498266Sopenharmony_cisub display_file { 18113498266Sopenharmony_ci my $filename = $_[0]; 18213498266Sopenharmony_ci print "=== Start of file $filename\n"; 18313498266Sopenharmony_ci if(open(my $displayfh, "<", "$filename")) { 18413498266Sopenharmony_ci while(my $line = <$displayfh>) { 18513498266Sopenharmony_ci print "$line"; 18613498266Sopenharmony_ci } 18713498266Sopenharmony_ci close $displayfh; 18813498266Sopenharmony_ci } 18913498266Sopenharmony_ci print "=== End of file $filename\n"; 19013498266Sopenharmony_ci} 19113498266Sopenharmony_ci 19213498266Sopenharmony_ci 19313498266Sopenharmony_ci#*************************************************************************** 19413498266Sopenharmony_ci# Display contents of the ssh daemon config file 19513498266Sopenharmony_ci# 19613498266Sopenharmony_cisub display_sshdconfig { 19713498266Sopenharmony_ci display_file($sshdconfig); 19813498266Sopenharmony_ci} 19913498266Sopenharmony_ci 20013498266Sopenharmony_ci 20113498266Sopenharmony_ci#*************************************************************************** 20213498266Sopenharmony_ci# Display contents of the ssh client config file 20313498266Sopenharmony_ci# 20413498266Sopenharmony_cisub display_sshconfig { 20513498266Sopenharmony_ci display_file($sshconfig); 20613498266Sopenharmony_ci} 20713498266Sopenharmony_ci 20813498266Sopenharmony_ci 20913498266Sopenharmony_ci#*************************************************************************** 21013498266Sopenharmony_ci# Display contents of the sftp client config file 21113498266Sopenharmony_ci# 21213498266Sopenharmony_cisub display_sftpconfig { 21313498266Sopenharmony_ci display_file($sftpconfig); 21413498266Sopenharmony_ci} 21513498266Sopenharmony_ci 21613498266Sopenharmony_ci 21713498266Sopenharmony_ci#*************************************************************************** 21813498266Sopenharmony_ci# Display contents of the ssh daemon log file 21913498266Sopenharmony_ci# 22013498266Sopenharmony_cisub display_sshdlog { 22113498266Sopenharmony_ci die "error: \$sshdlog uninitialized" if(not defined $sshdlog); 22213498266Sopenharmony_ci display_file($sshdlog); 22313498266Sopenharmony_ci} 22413498266Sopenharmony_ci 22513498266Sopenharmony_ci 22613498266Sopenharmony_ci#*************************************************************************** 22713498266Sopenharmony_ci# Display contents of the ssh client log file 22813498266Sopenharmony_ci# 22913498266Sopenharmony_cisub display_sshlog { 23013498266Sopenharmony_ci die "error: \$sshlog uninitialized" if(not defined $sshlog); 23113498266Sopenharmony_ci display_file($sshlog); 23213498266Sopenharmony_ci} 23313498266Sopenharmony_ci 23413498266Sopenharmony_ci 23513498266Sopenharmony_ci#*************************************************************************** 23613498266Sopenharmony_ci# Display contents of the sftp client log file 23713498266Sopenharmony_ci# 23813498266Sopenharmony_cisub display_sftplog { 23913498266Sopenharmony_ci die "error: \$sftplog uninitialized" if(not defined $sftplog); 24013498266Sopenharmony_ci display_file($sftplog); 24113498266Sopenharmony_ci} 24213498266Sopenharmony_ci 24313498266Sopenharmony_ci 24413498266Sopenharmony_ci#*************************************************************************** 24513498266Sopenharmony_ci# Find a file somewhere in the given path 24613498266Sopenharmony_ci# 24713498266Sopenharmony_cisub find_file { 24813498266Sopenharmony_ci my $fn = $_[0]; 24913498266Sopenharmony_ci shift; 25013498266Sopenharmony_ci my @path = @_; 25113498266Sopenharmony_ci foreach (@path) { 25213498266Sopenharmony_ci my $file = File::Spec->catfile($_, $fn); 25313498266Sopenharmony_ci if(-e $file && ! -d $file) { 25413498266Sopenharmony_ci return $file; 25513498266Sopenharmony_ci } 25613498266Sopenharmony_ci } 25713498266Sopenharmony_ci return ""; 25813498266Sopenharmony_ci} 25913498266Sopenharmony_ci 26013498266Sopenharmony_ci 26113498266Sopenharmony_ci#*************************************************************************** 26213498266Sopenharmony_ci# Find an executable file somewhere in the given path 26313498266Sopenharmony_ci# 26413498266Sopenharmony_cisub find_exe_file { 26513498266Sopenharmony_ci my $fn = $_[0]; 26613498266Sopenharmony_ci shift; 26713498266Sopenharmony_ci my @path = @_; 26813498266Sopenharmony_ci my $xext = exe_ext('SSH'); 26913498266Sopenharmony_ci foreach (@path) { 27013498266Sopenharmony_ci my $file = File::Spec->catfile($_, $fn); 27113498266Sopenharmony_ci if(-e $file && ! -d $file) { 27213498266Sopenharmony_ci return $file if(-x $file); 27313498266Sopenharmony_ci return $file if(($xext) && (lc($file) =~ /\Q$xext\E$/)); 27413498266Sopenharmony_ci } 27513498266Sopenharmony_ci } 27613498266Sopenharmony_ci return ""; 27713498266Sopenharmony_ci} 27813498266Sopenharmony_ci 27913498266Sopenharmony_ci 28013498266Sopenharmony_ci#*************************************************************************** 28113498266Sopenharmony_ci# Find a file in environment path or in our sftppath 28213498266Sopenharmony_ci# 28313498266Sopenharmony_cisub find_file_spath { 28413498266Sopenharmony_ci my $filename = $_[0]; 28513498266Sopenharmony_ci my @spath; 28613498266Sopenharmony_ci push(@spath, File::Spec->path()); 28713498266Sopenharmony_ci push(@spath, @sftppath); 28813498266Sopenharmony_ci return find_file($filename, @spath); 28913498266Sopenharmony_ci} 29013498266Sopenharmony_ci 29113498266Sopenharmony_ci 29213498266Sopenharmony_ci#*************************************************************************** 29313498266Sopenharmony_ci# Find an executable file in environment path or in our httptlssrvpath 29413498266Sopenharmony_ci# 29513498266Sopenharmony_cisub find_exe_file_hpath { 29613498266Sopenharmony_ci my $filename = $_[0]; 29713498266Sopenharmony_ci my @hpath; 29813498266Sopenharmony_ci push(@hpath, File::Spec->path()); 29913498266Sopenharmony_ci push(@hpath, @httptlssrvpath); 30013498266Sopenharmony_ci return find_exe_file($filename, @hpath); 30113498266Sopenharmony_ci} 30213498266Sopenharmony_ci 30313498266Sopenharmony_ci 30413498266Sopenharmony_ci#*************************************************************************** 30513498266Sopenharmony_ci# Find ssh daemon and return canonical filename 30613498266Sopenharmony_ci# 30713498266Sopenharmony_cisub find_sshd { 30813498266Sopenharmony_ci return find_file_spath($sshdexe); 30913498266Sopenharmony_ci} 31013498266Sopenharmony_ci 31113498266Sopenharmony_ci 31213498266Sopenharmony_ci#*************************************************************************** 31313498266Sopenharmony_ci# Find ssh client and return canonical filename 31413498266Sopenharmony_ci# 31513498266Sopenharmony_cisub find_ssh { 31613498266Sopenharmony_ci return find_file_spath($sshexe); 31713498266Sopenharmony_ci} 31813498266Sopenharmony_ci 31913498266Sopenharmony_ci 32013498266Sopenharmony_ci#*************************************************************************** 32113498266Sopenharmony_ci# Find sftp-server plugin and return canonical filename 32213498266Sopenharmony_ci# 32313498266Sopenharmony_cisub find_sftpsrv { 32413498266Sopenharmony_ci return find_file_spath($sftpsrvexe); 32513498266Sopenharmony_ci} 32613498266Sopenharmony_ci 32713498266Sopenharmony_ci 32813498266Sopenharmony_ci#*************************************************************************** 32913498266Sopenharmony_ci# Find sftp client and return canonical filename 33013498266Sopenharmony_ci# 33113498266Sopenharmony_cisub find_sftp { 33213498266Sopenharmony_ci return find_file_spath($sftpexe); 33313498266Sopenharmony_ci} 33413498266Sopenharmony_ci 33513498266Sopenharmony_ci 33613498266Sopenharmony_ci#*************************************************************************** 33713498266Sopenharmony_ci# Find ssh-keygen and return canonical filename 33813498266Sopenharmony_ci# 33913498266Sopenharmony_cisub find_sshkeygen { 34013498266Sopenharmony_ci return find_file_spath($sshkeygenexe); 34113498266Sopenharmony_ci} 34213498266Sopenharmony_ci 34313498266Sopenharmony_ci 34413498266Sopenharmony_ci#*************************************************************************** 34513498266Sopenharmony_ci# Find httptlssrv (gnutls-serv) and return canonical filename 34613498266Sopenharmony_ci# 34713498266Sopenharmony_cisub find_httptlssrv { 34813498266Sopenharmony_ci my $p = find_exe_file_hpath($httptlssrvexe); 34913498266Sopenharmony_ci if($p) { 35013498266Sopenharmony_ci my @o = `"$p" -l`; 35113498266Sopenharmony_ci my $found; 35213498266Sopenharmony_ci for(@o) { 35313498266Sopenharmony_ci if(/Key exchange: SRP/) { 35413498266Sopenharmony_ci $found = 1; 35513498266Sopenharmony_ci last; 35613498266Sopenharmony_ci } 35713498266Sopenharmony_ci } 35813498266Sopenharmony_ci return $p if($found); 35913498266Sopenharmony_ci } 36013498266Sopenharmony_ci return ""; 36113498266Sopenharmony_ci} 36213498266Sopenharmony_ci 36313498266Sopenharmony_ci 36413498266Sopenharmony_ci#*************************************************************************** 36513498266Sopenharmony_ci# Return version info for the given ssh client or server binaries 36613498266Sopenharmony_ci# 36713498266Sopenharmony_cisub sshversioninfo { 36813498266Sopenharmony_ci my $sshbin = $_[0]; # canonical filename 36913498266Sopenharmony_ci my $major; 37013498266Sopenharmony_ci my $minor; 37113498266Sopenharmony_ci my $patch; 37213498266Sopenharmony_ci my $sshid; 37313498266Sopenharmony_ci my $versnum; 37413498266Sopenharmony_ci my $versstr; 37513498266Sopenharmony_ci my $error; 37613498266Sopenharmony_ci 37713498266Sopenharmony_ci if(!$sshbin) { 37813498266Sopenharmony_ci $error = 'Error: Missing argument 1 for sshversioninfo()'; 37913498266Sopenharmony_ci } 38013498266Sopenharmony_ci elsif(! -x $sshbin) { 38113498266Sopenharmony_ci $error = "Error: cannot read or execute $sshbin"; 38213498266Sopenharmony_ci } 38313498266Sopenharmony_ci else { 38413498266Sopenharmony_ci my $cmd = ($sshbin =~ /$sshdexe$/) ? "\"$sshbin\" -?" : "\"$sshbin\" -V"; 38513498266Sopenharmony_ci $error = "$cmd\n"; 38613498266Sopenharmony_ci foreach my $tmpstr (qx($cmd 2>&1)) { 38713498266Sopenharmony_ci if($tmpstr =~ /OpenSSH[_-](\d+)\.(\d+)(\.(\d+))*/i) { 38813498266Sopenharmony_ci $major = $1; 38913498266Sopenharmony_ci $minor = $2; 39013498266Sopenharmony_ci $patch = $4?$4:0; 39113498266Sopenharmony_ci $sshid = 'OpenSSH'; 39213498266Sopenharmony_ci $versnum = (100*$major) + (10*$minor) + $patch; 39313498266Sopenharmony_ci $versstr = "$sshid $major.$minor.$patch"; 39413498266Sopenharmony_ci $error = undef; 39513498266Sopenharmony_ci last; 39613498266Sopenharmony_ci } 39713498266Sopenharmony_ci if($tmpstr =~ /OpenSSH[_-]for[_-]Windows[_-](\d+)\.(\d+)(\.(\d+))*/i) { 39813498266Sopenharmony_ci $major = $1; 39913498266Sopenharmony_ci $minor = $2; 40013498266Sopenharmony_ci $patch = $4?$4:0; 40113498266Sopenharmony_ci $sshid = 'OpenSSH-Windows'; 40213498266Sopenharmony_ci $versnum = (100*$major) + (10*$minor) + $patch; 40313498266Sopenharmony_ci $versstr = "$sshid $major.$minor.$patch"; 40413498266Sopenharmony_ci $error = undef; 40513498266Sopenharmony_ci last; 40613498266Sopenharmony_ci } 40713498266Sopenharmony_ci if($tmpstr =~ /Sun[_-]SSH[_-](\d+)\.(\d+)(\.(\d+))*/i) { 40813498266Sopenharmony_ci $major = $1; 40913498266Sopenharmony_ci $minor = $2; 41013498266Sopenharmony_ci $patch = $4?$4:0; 41113498266Sopenharmony_ci $sshid = 'SunSSH'; 41213498266Sopenharmony_ci $versnum = (100*$major) + (10*$minor) + $patch; 41313498266Sopenharmony_ci $versstr = "$sshid $major.$minor.$patch"; 41413498266Sopenharmony_ci $error = undef; 41513498266Sopenharmony_ci last; 41613498266Sopenharmony_ci } 41713498266Sopenharmony_ci $error .= $tmpstr; 41813498266Sopenharmony_ci } 41913498266Sopenharmony_ci chomp $error if($error); 42013498266Sopenharmony_ci } 42113498266Sopenharmony_ci return ($sshid, $versnum, $versstr, $error); 42213498266Sopenharmony_ci} 42313498266Sopenharmony_ci 42413498266Sopenharmony_ci 42513498266Sopenharmony_ci#*************************************************************************** 42613498266Sopenharmony_ci# End of library 42713498266Sopenharmony_ci1; 428