Compare commits

..

2 Commits

10 changed files with 142 additions and 139 deletions

View File

@@ -422,10 +422,6 @@ details.ui_hidden_table_start > summary::-webkit-details-marker {
color: #a1acc0;
}
details:not([open]).on-hover:not(:hover) summary::after {
visibility: hidden !important;
}
details.inline {
cursor: pointer;
padding: 0;
@@ -823,20 +819,7 @@ body > .mode > b[data-mode="server-manager"] > a > .ff-cloudmin {
filter: grayscale(1) contrast(1);
}
.not-secure {
color: #c40000;
color: #f00a38;
float: right;
}
.inherit-color::after,
.inherit-color::before,
.inherit-color:focus::after,
.inherit-color:focus::before,
.inherit-color:active::after,
.inherit-color:active::before,
.inherit-color:hover::after,
.inherit-color:hover::before,
.inherit-color:focus,
.inherit-color:active,
.inherit-color:hover,
.inherit-color {
color: inherit !important;
cursor: help;
}

View File

@@ -335,13 +335,11 @@ elsif ($init_mode eq "systemd" && $access{'bootup'}) {
&select_invert_link("d"),
&ui_link("edit_systemd.cgi?new=1", $text{'index_sadd'}) );
print &ui_links_row(\@links);
print &ui_columns_start([ "", $text{'systemd_name'},
$config{'desc'} ? $text{'systemd_desc'} : (),
$text{'systemd_type'},
$text{'systemd_status'},
$text{'systemd_boot'},
$text{'index_ustatus'} ]);
my $units_piped = join('|', map { quotemeta } &get_systemd_unit_types());
print &ui_columns_start([ "", $text{'index_uname'},
$text{'index_udesc'},
$text{'index_ucstatus'},
$text{'index_uboot'},
$text{'index_ustatus'}, ]);
foreach $u (&list_systemd_services()) {
if ($u->{'legacy'}) {
$l = "edit_action.cgi?0+".&urlize($u->{'name'});
@@ -349,23 +347,12 @@ elsif ($init_mode eq "systemd" && $access{'bootup'}) {
else {
$l = "edit_systemd.cgi?name=".&urlize($u->{'name'});
}
my $sname = $u->{'name'};
my ($type) = $sname =~ /\.([^.]+)$/;
if (defined($type) && $type =~ /^(?:$units_piped)$/) {
$sname =~ s/\.$type$//;
}
else {
$type = '';
}
my $title = ($u->{'boot'} == -1 ?
&html_escape($sname) :
&ui_link($l, &html_escape($sname)));
my $desc = $config{'desc'} ? &html_escape($u->{'desc'}) : undef;
print &ui_columns_row([
&ui_checkbox("d", $u->{'name'}, undef),
$title,
$desc // (),
$type,
$u->{'boot'} == -1 ?
&html_escape($u->{'name'}) :
&ui_link($l, &html_escape($u->{'name'})),
&html_escape($u->{'desc'}),
$u->{'fullstatus'} || "<i>$text{'index_unknown'}</i>",
$u->{'boot'} == 1 ?
&ui_text_color("$text{'yes'}", 'success') :

View File

@@ -207,7 +207,7 @@ unless full unit name is passed
sub action_unit
{
my ($unit) = @_;
my $units_piped = join('|', &get_systemd_unit_types());
my $units_piped = &get_systemd_unit_types('|');
$unit .= ".service"
if ($unit !~ /\.($units_piped)$/);
return $unit;
@@ -2128,7 +2128,7 @@ if (@list_systemd_services_cache && !$noinit) {
return @list_systemd_services_cache;
}
my $units_piped = join('|', &get_systemd_unit_types());
my $units_piped = &get_systemd_unit_types('|');
# Get all systemd unit names
my $out = &backquote_command("systemctl list-units --full --all -t service --no-legend");
@@ -2181,7 +2181,7 @@ while(@units) {
while(@args < 100 && @units) {
push(@args, shift(@units));
}
my $out = &backquote_command("systemctl show --property=Id,Description,UnitFileState,ActiveState,SubState,ExecStart,ExecStop,ExecReload,ExecMainPID,FragmentPath,DropInPaths ".join(" ", @args)." 2>/dev/null");
my $out = &backquote_command("systemctl show --property=Id,Description,UnitFileState,ActiveState,SubState,ExecStart,ExecStop,ExecReload,ExecMainPID,FragmentPath ".join(" ", @args)." 2>/dev/null");
my @lines = split(/\r?\n/, $out);
my $curr;
my @units;
@@ -2415,7 +2415,7 @@ my ($name) = @_;
&restart_systemd();
}
=head2 get_systemd_unit_types()
=head2 get_systemd_unit_types([return-as-string-separated])
Returns a list of all systemd unit types. Returns a string
instead if separator param is set.
@@ -2423,8 +2423,14 @@ instead if separator param is set.
=cut
sub get_systemd_unit_types
{
return ('target', 'service', 'socket', 'device', 'mount', 'automount',
'swap', 'path', 'timer', 'snapshot', 'slice', 'scope', 'busname');
my ($str_separator) = @_;
my @systemd_types = ('target', 'service', 'socket', 'device',
'mount', 'automount', 'swap', 'path',
'timer', 'snapshot', 'slice', 'scope',
'busname');
return $str_separator ?
join($str_separator, @systemd_types) :
@systemd_types;
}
=head2 is_systemd_service(name)
@@ -2435,7 +2441,7 @@ Returns 1 if some service is managed by systemd
sub is_systemd_service
{
my ($name) = @_;
my $units_piped = join('|', &get_systemd_unit_types());
my $units_piped = &get_systemd_unit_types('|');
foreach my $s (&list_systemd_services(1)) {
if (($s->{'name'} eq $name ||
$s->{'name'} =~
@@ -2461,10 +2467,22 @@ my $systemd_unit_dir2 = "/lib/systemd/system";
if ($name) {
foreach my $p ($systemd_local_conf, $systemd_unit_dir1,
$systemd_unit_dir2) {
foreach my $t (&get_systemd_unit_types()) {
return $p if (-r "$p/$name.$t");
if (-r "$p/$name.service" ||
-r "$p/$name" ||
-r "$p/$name.target" ||
-r "$p/$name.socket" ||
-r "$p/$name.device" ||
-r "$p/$name.mount" ||
-r "$p/$name.automount" ||
-r "$p/$name.swap" ||
-r "$p/$name.path" ||
-r "$p/$name.timer" ||
-r "$p/$name.snapshot" ||
-r "$p/$name.slice" ||
-r "$p/$name.scope" ||
-r "$p/$name.busname") {
return $p;
}
return $p if (-r "$p/$name");
}
}
# Always use /etc/systemd/system for locally created units
@@ -2901,12 +2919,4 @@ my ($name) = @_;
return $name =~ /\./ ? $name : "com.webmin.".$name;
}
# config_pre_load(mod-info, [mod-order])
# Check if some config options are conditional
sub config_pre_load
{
my ($modconf_info, $modconf_order) = @_;
$modconf_info->{'desc'} =~ s/2-[^,]+,// if ($init_mode eq "systemd");
}
1;

View File

@@ -221,30 +221,29 @@ upstart_eserver2=Server command does not exist
upstart_eserver3=Only one server command can be entered
upstart_return=upstart service
systemd_title1=Create Systemd Unit
systemd_title2=Edit Systemd Unit
systemd_egone=Unit no longer exists!
systemd_elegacy=Not a systemd unit!
systemd_header=Systemd unit details
systemd_name=Unit name
systemd_type=Unit type
systemd_title1=Create Systemd Service
systemd_title2=Edit Systemd Service
systemd_egone=Service no longer exists!
systemd_elegacy=Not a systemd service!
systemd_header=Systemd service details
systemd_name=Service name
systemd_file=Configuration file
systemd_desc=Unit description
systemd_desc=Service description
systemd_start=Commands to run on startup
systemd_stop=Commands to run on shutdown
systemd_conf=Systemd unit configuration
systemd_conf=Systemd configuration
systemd_boot=Start at boot time?
systemd_status=Current status
systemd_status0=Not running
systemd_status1=Running with PID $1
systemd_status2=Running
systemd_status3=Unknown!
systemd_err=Failed to save systemd unit
systemd_ename=Missing or invalid-lookup systemd unit name
systemd_eclash=A unit with the same name already exists
systemd_edesc=Missing unit description
systemd_return=systemd unit
systemd_econf=No systemd unit configuration entered
systemd_err=Failed to save systemd service
systemd_ename=Missing or invalid-lookup systemd service name
systemd_eclash=A service with the same name already exists
systemd_edesc=Missing service description
systemd_return=systemd service
systemd_econf=No systemd configuration entered
systemd_estart=Missing commands to run on startup
launchd_title1=Create Launchd Agent

View File

@@ -190,7 +190,7 @@ pam_login=Continue
pam_restart=Restart
login_notsecure=Not Secure
login_notsecure_desc=This connection is not secure and could let a man-in-the-middle attack intercept your password or session cookie. Click this badge to switch to an HTTPS connection, unless you are on a trusted local network or behind a secure reverse proxy.
login_notsecure_desc=This connection is not secure and could let a man-in-the-middle attack intercept your password or session cookie. Use HTTPS unless you are on a trusted local network or behind a secure reverse proxy.
acl_root=Root directory for file chooser
acl_otherdirs=Other visible directories in file chooser

View File

@@ -383,7 +383,12 @@ foreach $mod (split(/\s+/, $config{'preuse'})) {
}
# Open debug log if set
&open_debug_to_log("miniserv.pl starting ..\n");
if ($config{'debuglog'}) {
open(DEBUG, ">>$config{'debuglog'}");
chmod(0700, $config{'debuglog'});
select(DEBUG); $| = 1; select(STDOUT);
print DEBUG "miniserv.pl starting ..\n";
}
# Write out (empty) blocked hosts file
&write_blocked_file();
@@ -590,16 +595,9 @@ if ($config{'logclear'}) {
# need to clear log
$write_logtime = 1;
unlink($config{'logfile'});
unlink($config{'errorlog'})
if ($config{'errorlog'} &&
$config{'errorlog'} ne '-');
unlink($config{'debuglog'})
if ($config{'debuglog'});
}
}
else {
$write_logtime = 1;
}
else { $write_logtime = 1; }
if ($write_logtime) {
open(LOGTIME, ">$config{'logfile'}.time");
print LOGTIME time(),"\n";
@@ -612,6 +610,53 @@ if ($config{'logclear'}) {
push(@childpids, $logclearer);
}
# session_state(session-id, set-state)
# Sets or gets the active state of the client, which is used to determine
# whether the client is away or not. This is used to allow for the session to
# expire after a period of inactivity in case a client has opened connections or
# makes HTTP requests in the background. Returns 1 if the client is currently
# not away (ie. active), or 0 if it is away.
sub session_state
{
my ($sid, $set) = @_;
return 1 if (!$sid);
# Check session database
my %sessiondb;
dbmopen(%sessiondb, $config{'sessiondb'}, 0700);
if ($@) {
dbmclose(%sessiondb);
eval "use NDBM_File";
dbmopen(%sessiondb, $config{'sessiondb'}, 0700);
}
# Get current record
my $skey = &hash_session_id($sid);
my ($user, $ltime, $ip, $lifetime, $active);
if (exists($sessiondb{$skey})) {
($user, $ltime, $ip, $lifetime, $active) =
split(/\s+/, $sessiondb{$skey});
$lifetime //= 0; # preserve or default to 0
$active //= 1; # default to 'alive'
}
# Update flag if caller supplied a value
if ($user && $ltime && $ip && defined($set)) {
$active = $set ? 1 : 0;
$sessiondb{$skey} = join(' ', $user, $ltime, $ip, $lifetime, $active);
print DEBUG "websocket updated status for $sid to $active\n";
}
else {
print DEBUG "websocket current status for $sid is $active\n";
}
# Save the record back to the database
dbmclose(%sessiondb);
# Return the active state
return $active;
}
# Setup the logout time dbm if needed
if ($config{'session'}) {
eval "use SDBM_File";
@@ -636,16 +681,6 @@ local $remove_session_count = 0;
$need_pipes = $config{'passdelay'} || $config{'session'};
$cron_runs = 0;
while(1) {
# Periodically re-open error and debug logs if deleted via regular
# log clearing
if ($config{'errorlog'} && $config{'errorlog'} ne '-' &&
!-e $config{'errorlog'}) {
&redirect_stderr_to_log();
}
if ($config{'debuglog'} && !-e $config{'debuglog'}) {
&open_debug_to_log();
}
# Check if any webmin cron jobs are ready to run
&execute_ready_webmin_crons($cron_runs++);
@@ -1116,10 +1151,11 @@ while(1) {
}
$userlast{$1} = $time_now;
}
elsif ($inline =~ /^verify\s+(\S+)\s+(\S+)/) {
elsif ($inline =~ /^verify\s+(\S+)\s+(\S+)\s+(\S+)/) {
# Verifying a session ID
local $session_id = $1;
local $vip = $2;
local $notimeout = $2;
local $vip = $3;
local $skey = $sessiondb{$session_id} ?
$session_id :
&hash_session_id($session_id);
@@ -1128,11 +1164,14 @@ while(1) {
print $outfd "0 0\n";
}
else {
local ($user, $ltime, $ip, $lifetime) =
local ($user, $ltime, $ip, $lifetime, $state) =
split(/\s+/, $sessiondb{$skey});
$lifetime //= 0;
$state //= 1;
local $lot = &get_logout_time($user, $session_id);
if ($lot &&
$time_now - $ltime > $lot*60) {
$time_now - $ltime > $lot*60 &&
!$notimeout) {
# Session has timed out due to
# idle time being hit
print $outfd "1 ",($time_now - $ltime),"\n";
@@ -1157,7 +1196,7 @@ while(1) {
# Session is OK, update last time
# and remote IP
print $outfd "2 $user\n";
$sessiondb{$skey} = "$user $time_now $vip";
$sessiondb{$skey} = "$user $time_now $vip $lifetime $state";
}
}
}
@@ -1861,7 +1900,7 @@ if ($config{'session'} && !$deny_authentication &&
&http_error(500, "Invalid session",
"Session ID contains invalid characters");
}
print $PASSINw "verify $sid $acptip\n";
print $PASSINw "verify $sid 0 $acptip\n";
<$PASSOUTr> =~ /^(\d+)\s+(\S+)/;
if ($1 != 2) {
&http_error(500, "Invalid session",
@@ -2032,7 +2071,9 @@ if ($config{'session'} && !$validated) {
local $cookie = $header{'cookie'};
while($cookie =~ s/(^|\s|;)$sidname=([a-f0-9]+)//) {
$session_id = $2;
print $PASSINw "verify $session_id $acptip\n";
local $notimeout =
$in{'webmin_notimeout'} ? 1 : 0;
print $PASSINw "verify $session_id $notimeout $acptip\n";
<$PASSOUTr> =~ /(\d+)\s+(\S+)/;
if ($1 == 2) {
# Valid session continuation
@@ -5549,7 +5590,14 @@ foreach my $pe (split(/\t+/, $config{'expires_paths'})) {
}
# Re-open debug log
&open_debug_to_log();
close(DEBUG);
if ($config{'debuglog'}) {
open(DEBUG, ">>$config{'debuglog'}");
select(DEBUG); $| = 1; select(STDOUT);
}
else {
open(DEBUG, ">/dev/null");
}
# Reset cache of sudo checks
undef(%sudocache);
@@ -5933,10 +5981,11 @@ while(1) {
syswrite($fh, $buf, length($buf)) || last;
}
my $now = time();
if ($now - $last_session_check_time > 10) {
if ($now - $last_session_check_time > 10 &&
&session_state($session_id) == 1) {
# Re-validate the browser session every 10 seconds
print DEBUG "verifying websockets session $session_id\n";
print $PASSINw "verify $session_id $acptip\n";
print $PASSINw "verify $session_id 0 $acptip\n";
<$PASSOUTr> =~ /(\d+)\s+(\S+)/;
if ($1 != 2) {
print DEBUG "session $session_id has expired!\n";
@@ -6698,7 +6747,6 @@ else {
sub redirect_stderr_to_log
{
if ($config{'errorlog'} ne '-') {
close(STDERR);
open(STDERR, ">>$config{'errorlog'}") ||
die "failed to open $config{'errorlog'} : $!";
if ($config{'logperms'}) {
@@ -6708,23 +6756,6 @@ if ($config{'errorlog'} ne '-') {
select(STDERR); $| = 1; select(STDOUT);
}
# open_debug_to_log([msg])
# Direct the DEBUG file handle somewhere
sub open_debug_to_log
{
my ($msg) = @_;
close(DEBUG);
if ($config{'debuglog'}) {
open(DEBUG, ">>$config{'debuglog'}");
chmod(0700, $config{'debuglog'});
select(DEBUG); $| = 1; select(STDOUT);
print DEBUG $msg if ($msg);
}
else {
open(DEBUG, ">/dev/null");
}
}
# should_gzip_file(filename)
# Returns 1 if some path should be gzipped
sub should_gzip_file

View File

@@ -74,13 +74,7 @@ print &ui_hidden("cid", $in{'cid'});
my $not_secure;
if ($ENV{'HTTPS'} ne 'ON') {
my $link = ui_tag('a', "&#9888; $text{'login_notsecure'}",
{ 'href' => "javascript:void(0);",
'class' => 'inherit-color',
'onclick' => "window.location.href = ".
"window.location.href.replace(/^http:/, 'https:'); return false;",
});
$not_secure = ui_tag('span', $link,
$not_secure = ui_tag('span', "&#9888; $text{'login_notsecure'}",
{ class => 'not-secure', title => $text{'login_notsecure_desc'} });
}

View File

@@ -94,13 +94,7 @@ print &ui_hidden("page", $in{'page'});
my $not_secure;
if ($ENV{'HTTPS'} ne 'ON') {
my $link = ui_tag('a', "&#9888; $text{'login_notsecure'}",
{ 'href' => "javascript:void(0);",
'class' => 'inherit-color',
'onclick' => "window.location.href = ".
"window.location.href.replace(/^http:/, 'https:'); return false;",
});
$not_secure = ui_tag('span', $link,
$not_secure = ui_tag('span', "&#9888; $text{'login_notsecure'}",
{ class => 'not-secure', title => $text{'login_notsecure_desc'} });
}

View File

@@ -406,7 +406,6 @@ else {
'errorlog' => "$var_dir/miniserv.error",
'pidfile' => "$var_dir/miniserv.pid",
'logtime' => 168,
'logclear' => 1,
'ppath' => $ppath,
'ssl' => $ssl,
'no_ssl2' => 1,
@@ -779,13 +778,12 @@ else {
}
system("$perl ".&quote_path("$wadir/copyconfig.pl")." ".&quote_path("$os_type/$real_os_type")." ".&quote_path("$os_version/$real_os_version")." ".&quote_path($wadir)." ".$config_directory." \"\" ".$allmods . " >/dev/null 2>&1");
if (!$upgrading) {
# Store the OS and version, and enable log and log clearing
# Store the OS and version
&read_file("$config_directory/config", \%gconfig);
$gconfig{'os_type'} = $os_type;
$gconfig{'os_version'} = $os_version;
$gconfig{'real_os_type'} = $real_os_type;
$gconfig{'real_os_version'} = $real_os_version;
$gconfig{'logclear'} = 1;
$gconfig{'log'} = 1;
&write_file("$config_directory/config", \%gconfig);
}

View File

@@ -829,6 +829,13 @@ if [ "$upgrading" != 1 ]; then
# Disallow unknown referers by default
echo "referers_none=1" >>$config_dir/config
else
# Enable log rotation if not set
grep logclear= $config_dir/miniserv.conf >/dev/null
if [ "$?" != "0" ]; then
echo "logclear=1" >> $config_dir/miniserv.conf
echo "logclear=1" >> $config_dir/config
fi
# Enable HSTS by default if not set
grep ssl_hsts= $config_dir/miniserv.conf >/dev/null
if [ "$?" != "0" ]; then