%PDF-1.5 %���� ºaâÚÎΞ-ÌE1ÍØÄ÷{òò2ÿ ÛÖ^ÔÀá TÎ{¦?§®¥kuµùÕ5sLOšuY
Server IP : 49.231.201.246 / Your IP : 216.73.216.248 Web Server : Apache/2.4.18 (Ubuntu) System : Linux 246 4.4.0-210-generic #242-Ubuntu SMP Fri Apr 16 09:57:56 UTC 2021 x86_64 User : root ( 0) PHP Version : 7.0.33-0ubuntu0.16.04.16 Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority, MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : ON Directory : /usr/share/webmin/sshd/ |
Upload File : |
#!/usr/bin/perl # sshd-lib.pl # Common functions for the ssh daemon config file BEGIN { push(@INC, ".."); }; use WebminCore; &init_config(); # Get version information if (!&read_file("$module_config_directory/version", \%version)) { %version = &get_sshd_version(); } # get_sshd_version() # Returns a hash containing the version type, number and full version sub get_sshd_version { local %version; local $out = &backquote_command( "e_path($config{'sshd_path'})." -h 2>&1 </dev/null"); if ($config{'sshd_version'}) { # Forced version $version{'type'} = 'openssh'; $version{'number'} = $version{'full'} = $config{'sshd_version'}; } elsif ($out =~ /(sshd\s+version\s+([0-9\.]+))/i || $out =~ /(ssh\s+secure\s+shell\s+([0-9\.]+))/i) { # Classic commercial SSH $version{'type'} = 'ssh'; $version{'number'} = $2; $version{'full'} = $1; } elsif ($out =~ /(OpenSSH.([0-9\.]+))/i) { # OpenSSH .. assume all versions are supported $version{'type'} = 'openssh'; $version{'number'} = $2; $version{'full'} = $1; } elsif ($out =~ /(Sun_SSH_([0-9\.]+))/i) { # Solaris 9 SSH is actually OpenSSH 2.x $version{'type'} = 'openssh'; $version{'number'} = 2.0; $version{'full'} = $1; } elsif (($out = $config{'sshd_version'}) && ($out =~ /(Sun_SSH_([0-9\.]+))/i)) { # Probably Solaris 10 SSHD that didn't display version. Use it. $version{'type'} = 'openssh'; $version{'number'} = 2.0; $version{'full'} = $1; } return %version; } # get_sshd_config() # Returns a reference to an array of SSHD config file options sub get_sshd_config { local @rv = ( { 'dummy' => 1, 'indent' => 0, 'file' => $config{'sshd_config'}, 'line' => -1, 'eline' => -1 } ); local $lnum = 0; open(CONF, "<".$config{'sshd_config'}); while(<CONF>) { s/\r|\n//g; s/^\s*#.*$//g; local ($name, @values) = split(/\s+/, $_); if ($name) { local $dir = { 'name' => $name, 'values' => \@values, 'file' => $config{'sshd_config'}, 'line' => $lnum }; push(@rv, $dir); } $lnum++; } close(CONF); return \@rv; } # find_value(name, &config) sub find_value { foreach $c (@{$_[1]}) { if (lc($c->{'name'}) eq lc($_[0])) { return wantarray ? @{$c->{'values'}} : $c->{'values'}->[0]; } } return wantarray ? ( ) : undef; } # find(value, &config) sub find { local @rv; foreach $c (@{$_[1]}) { if (lc($c->{'name'}) eq lc($_[0])) { push(@rv, $c); } } return wantarray ? @rv : $rv[0]; } # save_directive(name, &config, [value*|&values], [before]) sub save_directive { local @o = &find($_[0], $_[1]); local @n = ref($_[2]) ? grep { defined($_) } @{$_[2]} : grep { defined($_) } @_[2..@_-1]; local $lref = &read_file_lines($_[1]->[0]->{'file'}); local $id = ("\t" x $_[1]->[0]->{'indent'}); local $i; local $before = $_[3] && ref($_[2]) ? &find($_[3], $_[1]) : undef; for($i=0; $i<@o || $i<@n; $i++) { if (defined($o[$i]) && defined($n[$i])) { # Replacing a line $lref->[$o[$i]->{'line'}] = "$id$_[0] $n[$i]"; } elsif (defined($o[$i])) { # Removing a line splice(@$lref, $o[$i]->{'line'}, 1); foreach $c (@{$_[1]}) { if ($c->{'line'} > $o[$i]->{'line'}) { $c->{'line'}--; } } } elsif (defined($n[$i]) && !$before) { # Adding a line at the end, but before the first Match directive local $ll = $_[1]->[@{$_[1]}-1]->{'line'}; foreach my $m (&find("Match", $_[1])) { $ll = $m->{'line'} - 1; last; } splice(@$lref, $ll+1, 0, "$id$_[0] $n[$i]"); } elsif (defined($n[$i]) && $before) { # Adding a line before the first instance of some directive splice(@$lref, $before->{'line'}, 0, "$id$_[0] $n[$i]"); foreach $c (@{$_[1]}) { if ($c->{'line'} >= $before->{'line'}) { $c->{'line'}--; } } } } } # save_socket(ports, listens) sub save_socket { my ($ports, $listens) = @_; return if ($version{'number'} < 6.7); return if (!&foreign_available('init')); &foreign_require('init'); my $default_port = 22; my $socket_unit = &get_ssh_socket(); return if (!$socket_unit); # Extend listens with IPs from default socket configuration if set my $socket_details = &init::cat_systemd($socket_unit, 'ListenStream'); my ($socket_conf_file, $socket_conf_dir); my @default_streams; foreach my $entry (@$socket_details) { next if ($entry->{'file'} =~ m{^/run}); # Skip runtime files my $streams = $entry->{'sections'}{'Socket'}{'ListenStream'}; if ($entry->{'file'} =~ m{^/etc}) { if (defined($streams)) { # Determine the socket configuration file and # directory from the custom config that defines # ListenStream to support multiple socket # override files (edge case) ($socket_conf_dir, $socket_conf_file) = $entry->{'file'} =~ m|^(.*/)([^/]+)$|; $socket_conf_dir =~ s|/$|| if ($socket_conf_dir); } next; } if ($streams) { foreach my $stream (@$streams) { if ($stream =~ /^(?:\[(.+?)\]|([^:]+)):\d+$/) { my $address = defined($1) ? "[$1]" : $2; push(@default_streams, $address) } } } } my @result; # Set default port if empty $ports = [$default_port] if (!@$ports); # Check if port is different from default my $port = @$ports == 1 && $ports->[0] == $default_port; if (@$listens) { # Process listens foreach my $listen (@$listens) { if ($listen =~ /:\d+$/) { # If listen already contains a port, keep it as is push(@result, $listen); } elsif ($listen =~ /^\[.*\]$/) { # IPv6 address without a port push(@result, map { "$listen:$_" } @$ports); } else { # IPv4 address or hostname without a port push(@result, map { "$listen:$_" } @$ports); } } } # Add ports not already in @result if (!$port || @result) { foreach my $port (@$ports) { unless (grep { /:$port$/ } @result) { if (@default_streams) { push(@result, map { "$_:$port" } @default_streams); } else { push(@result, $port); } } } } # Update socket if @results not empty my $socket_conf = { 'Socket' => {} }; if (@result) { unshift(@result, ''); $socket_conf = { 'Socket' => { 'ListenStream' => \@result, }, }; } &init::edit_systemd($socket_unit, $socket_conf, $socket_conf_file, $socket_conf_dir); } # scmd(double) sub scmd { if ($cmd_count % 2 == 0) { print "<tr>\n"; } elsif ($_[0]) { print "<td colspan=2></td> </tr>\n"; print "<tr>\n"; $cmd_count = 0; } $cmd_count += ($_[0] ? 2 : 1); } # ecmd() sub ecmd { if ($cmd_count % 2 == 0) { print "</tr>\n"; } } # get_client_config() # Returns a list of structures, one for each host sub get_client_config { local @rv = ( { 'dummy' => 1, 'indent' => 0, 'file' => $config{'client_config'}, 'line' => -1, 'eline' => -1 } ); local $host; local $lnum = 0; open(CLIENT, "<".$config{'client_config'}); while(<CLIENT>) { s/\r|\n//g; s/^\s*#.*$//g; s/^\s*//g; local ($name, @values) = split(/\s+/, $_); if (lc($name) eq 'host') { # Start of new host $host = { 'name' => $name, 'values' => \@values, 'file' => $config{'client_config'}, 'line' => $lnum, 'eline' => $lnum, 'members' => [ { 'dummy' => 1, 'indent' => 1, 'file' => $config{'client_config'}, 'line' => $lnum } ] }; push(@rv, $host); } elsif ($name) { # A directive inside a host local $dir = { 'name' => $name, 'values' => \@values, 'file' => $config{'client_config'}, 'line' => $lnum }; push(@{$host->{'members'}}, $dir); $host->{'eline'} = $lnum; } $lnum++; } close(CLIENT); return \@rv; } # create_host(&host) sub create_host { local $lref = &read_file_lines($config{'client_config'}); $_[0]->{'line'} = $_[0]->{'eline'} = scalar(@$lref); push(@$lref, "Host ".join(" ", @{$_[0]->{'values'}})); $_[0]->{'members'} = [ { 'dummy' => 1, 'indent' => 1, 'file' => $config{'client_config'}, 'line' => $_[0]->{'line'} } ]; } # modify_host(&host) sub modify_host { local $lref = &read_file_lines($config{'client_config'}); $lref->[$_[0]->{'line'}] = "Host ".join(" ", @{$_[0]->{'values'}}); } # delete_host(&host) sub delete_host { local $lref = &read_file_lines($config{'client_config'}); splice(@$lref, $_[0]->{'line'}, $_[0]->{'eline'} - $_[0]->{'line'} + 1); } # get_ssh_socket() sub get_ssh_socket { return undef if ($version{'number'} < 6.7); return undef if (!&foreign_available('init')); &foreign_require('init'); return undef if ($init::init_mode ne 'systemd'); my @socket_units = ('ssh.socket', 'sshd.socket'); my $socket_unit; foreach (@socket_units) { if (&init::action_status($_) == 2) { $socket_unit = $_; last; } } return $socket_unit if ($socket_unit); return undef; } # restart_sshd() # Re-starts the SSH server, and returns an error message on failure or # undef on success sub restart_sshd { if (my $ssh_socket = &get_ssh_socket()) { &init::restart_action($ssh_socket); } elsif ($config{'restart_cmd'}) { local $out = `$config{'restart_cmd'} 2>&1 </dev/null`; return "<pre>$out</pre>" if ($?); } else { local $pid = &get_sshd_pid(); $pid || return $text{'apply_epid'}; &kill_logged('HUP', $pid); } return undef; } # stop_sshd() # Kills the SSH server, and returns an error message on failure or # undef on success sub stop_sshd { if (my $ssh_socket = &get_ssh_socket()) { &init::stop_action($ssh_socket); } elsif ($config{'stop_cmd'}) { local $out = `$config{'stop_cmd'} 2>&1 </dev/null`; return "<pre>$out</pre>" if ($?); } else { local $pid = &get_sshd_pid(); $pid || return $text{'apply_epid'}; &kill_logged('TERM', $pid); } return undef; } # start_sshd() # Attempts to start the SSH server, returning undef on success or an error # message on failure. sub start_sshd { # Remove PID file if invalid if (-f $config{'pid_file'} && !&check_pid_file($config{'pid_file'})) { &unlink_file($config{'pid_file'}); } if (my $ssh_socket = &get_ssh_socket()) { &init::start_action($ssh_socket); } elsif ($config{'start_cmd'}) { $out = &backquote_logged("$config{'start_cmd'} 2>&1 </dev/null"); if ($?) { return "<pre>$out</pre>"; } } else { $out = &backquote_logged("$config{'sshd_path'} 2>&1 </dev/null"); if ($?) { return "<pre>$out</pre>"; } } return undef; } # get_pid_file() # Returns the SSH server PID file sub get_pid_file { local $conf = &get_sshd_config(); local $pidfile = &find_value("PidFile", $conf); $pidfile ||= $config{'pid_file'}; return $pidfile; } # get_sshd_pid() # Returns the PID of the running SSHd process sub get_sshd_pid { local $file = &get_pid_file(); if ($file) { return &check_pid_file($file); } else { local ($rv) = &find_byname("sshd"); return $rv; } } # get_mlvalues(file, id, [splitchar]) # Return an array with values from a file, where the # values are one per line with an id preceding them sub get_mlvalues { local @rv; local $_; local $split = defined($_[2]) ? $_[2] : " "; local $realfile = &translate_filename($_[0]); &open_readfile(ARFILE, $_[0]) || return 0; while(<ARFILE>) { chomp; local $hash = index($_, "#"); local $eq = index($_, $split); if ($hash != 0 && $eq >= 0) { local $n = substr($_, 0, $eq); local $v = substr($_, $eq+1); chomp($v); if ($n eq $_[1]) { push(@rv, $v); } } } close(ARFILE); return @rv; } # list_syslog_facilities() # Returns an upper-case list of syslog facility names sub list_syslog_facilities { local @facils; if (&foreign_check("syslog")) { local %sconfig = &foreign_config("syslog"); @facils = map { uc($_) } split(/\s+/, $sconfig{'facilities'}); } if (!@facils) { @facils = ( 'DAEMON', 'USER', 'AUTH', 'AUTHPRIV', 'LOCAL0', 'LOCAL1', 'LOCAL2', 'LOCAL3', 'LOCAL4', 'LOCAL5', 'LOCAL6', 'LOCAL7' ); } return @facils; } sub list_logging_levels { return ('QUIET', 'FATAL', 'ERROR', 'INFO', 'VERBOSE', 'DEBUG'); } sub yes_no_default_radio { local ($name, $val) = @_; return &ui_radio($name, (lc($val) eq 'yes' || $val =~ /^\d+$/ && $val > 0) ? 1 : (lc($val) eq 'no' || $val =~ /^\d+$/) ? 0 : 2, [ [ 1, $text{'yes'} ], [ 0, $text{'no'} ], [ 2, $text{'default'} ] ]); } sub get_preferred_key_type { if ($version{'type'} eq 'openssh' && $version{'number'} >= 6.5) { return "ed25519"; } if ($version{'type'} eq 'openssh' && $version{'number'} >= 3.2) { return "rsa1"; } return undef; } 1;