Compare commits

..

55 Commits

Author SHA1 Message Date
Ilia Ross
76efb4ee10 Fix not to show runlevels config option for systemd 2025-07-12 19:40:04 +03:00
Ilia Ross
ed42dd5822 Fix to always show description 2025-07-11 15:25:02 +03:00
Ilia Ross
9dc877910f Fix to always show summary arrow when opened 2025-07-06 02:27:13 +03:00
Ilia Ross
a65f9f5d6c Fix to respect config option and show no description 2025-07-05 18:57:23 +03:00
Ilia Ross
4d417ea4bf Fix to put lengthy descriptions to a nice details element 2025-07-05 16:38:55 +03:00
Ilia Ross
2e245a1035 Add a separate "Unit type" column 2025-07-05 16:03:47 +03:00
Ilia Ross
049542b7ed Add DropInPaths property 2025-07-05 15:43:26 +03:00
Ilia Ross
780cc982b7 Revert "Fix to show .service unit type"
72621c2929 (commitcomment-161382677)

This reverts commit 37f9ce4bb4.
2025-07-04 01:18:58 +03:00
Jamie Cameron
848422d256 Merge branch 'master' of github.com:webmin/webmin 2025-07-03 15:15:20 -07:00
Jamie Cameron
f1e96e3097 Re-open the debug and error logs if cleared periodically 2025-07-03 15:11:10 -07:00
Ilia Ross
90f4265389 Fix to use unit term for systemd systems 2025-07-03 13:28:55 +03:00
Ilia Ross
37f9ce4bb4 Fix to show .service unit type
72621c2929 (commitcomment-161316248)
2025-07-03 13:10:00 +03:00
Jamie Cameron
ceb3e583a3 Reduce duplication in list of unit types 2025-07-02 16:51:17 -07:00
Jamie Cameron
436d6f70bb Its cleaner for the API to always return a list 2025-07-02 16:48:39 -07:00
Jamie Cameron
72621c2929 No need to show the .service suffix 2025-07-02 16:44:21 -07:00
Jamie Cameron
af07c6c9d9 The notimeout flag is never set 2025-07-02 16:21:11 -07:00
Jamie Cameron
740f5b9d49 delete support for the webmin_notimeout param, which as far as I can tell is never used 2025-07-02 15:10:19 -07:00
Jamie Cameron
cb1368f07c The need for this hack is long gone 2025-07-02 14:54:49 -07:00
Ilia Ross
755325f9a5 Fix to enable log clearing similar to packaged version 2025-07-02 22:08:26 +03:00
Ilia Ross
dd914c7ecf Fix to partially revert a fix to enable log rotation for Webmin logs
This reverts commit 58580b7f4b.

58580b7f4b (r161290315)
2025-07-02 21:39:36 +03:00
Ilia Ross
489583708e Add support for clickable badge for insecure connection on login page 2025-07-02 16:37:48 +03:00
Ilia Ross
58580b7f4b Fix to enable log rotation for Webmin logs 2025-07-01 15:10:49 +03:00
Ilia Ross
d9a120c760 Fix to remove non-breakable spaces that don't belong in values within parentheses 2025-07-01 14:33:27 +03:00
Ilia Ross
fb832eff82 Fix to always enable HSTS 2025-06-30 14:08:54 +03:00
Ilia Ross
75b0a6f7bb Fix sending HSTS over plain HTTP does nothing
* Note: per the spec (RFC 6797), HSTS only takes effect when delivered on an HTTPS response

https://datatracker.ietf.org/doc/html/rfc6797#section-7.2
2025-06-30 13:43:46 +03:00
Ilia Ross
40707d8602 Update changelog 2025-06-29 23:04:51 +03:00
Ilia Ross
ac45266ee4 Add missing referenced variable 2025-06-29 22:28:42 +03:00
Ilia Ross
522aeb5264 Fix to consider ancient systems 2025-06-29 22:28:30 +03:00
Ilia Ross
1d24db1686 Add a warning to the login pages if the connection is not secure 2025-06-29 13:42:02 +03:00
Jamie Cameron
527043b54d Merge pull request #2506 from webmin/dev/fix-support-for-ssleay-1.93+
Fix latest SSLeay support for redirects to SSL work
2025-06-28 18:20:24 -07:00
Ilia Ross
56b62346b4 Fix not to use SSL unless clients wants it explicitly 2025-06-29 01:04:30 +03:00
Ilia Ross
ee39f99d23 Fix not to print unnecessary horizontal line
* Note: we're already inside the container
2025-06-28 15:02:23 +03:00
Ilia Ross
a223243db4 Fix comment for clarity 2025-06-27 04:01:15 +03:00
Ilia Ross
b59bdc4f1a Fix latest SSLeay support for redirects to SSL work 2025-06-27 03:57:06 +03:00
Ilia Ross
d087f9f024 Fix to correctly concatenate if string is empty 2025-06-24 13:33:26 +03:00
Jamie Cameron
1607a59239 Handle case where mime_header_checks is not set
https://forum.virtualmin.com/t/double-header-checks/133851/8
2025-06-23 16:52:26 -07:00
Jamie Cameron
70589cf88a Fix regexp to match actual output
https://github.com/webmin/webmin/issues/2501
2025-06-22 15:58:07 -07:00
Jamie Cameron
c429fbb202 Merge branch 'master' of github.com:webmin/webmin 2025-06-22 14:11:53 -07:00
Jamie Cameron
f24375e13a Deal with DNF5 format
https://github.com/webmin/webmin/issues/2501
2025-06-22 14:11:43 -07:00
Ilia Ross
d428f4d4c1 Fix comment
49ceeebbf8 (commitcomment-160355697)
2025-06-22 01:02:51 +03:00
Ilia Ross
f0e07518c9 Fix setting innodb_file_per_table option as it's always enabled by default 2025-06-21 22:45:17 +03:00
Ilia Ross
29709c3c51 Update changelog for another minor release 2025-06-21 21:05:07 +03:00
Ilia Ross
fb71fbd5ae Fix to show output properly without redirecting prematurely 2025-06-21 20:49:55 +03:00
Ilia Ross
a1f06c5548 Fix text consistency 2025-06-21 20:49:33 +03:00
Jamie Cameron
10e8a420c0 Filter out instances of the same version 2025-06-21 10:39:35 -07:00
Jamie Cameron
8149eef10a Add status monitor for PHP FPM
https://github.com/webmin/webmin/issues/2499
2025-06-20 21:53:14 -07:00
Jamie Cameron
c4b98ef376 Nut UPS is no longer supported 2025-06-19 21:31:41 -07:00
Jamie Cameron
621d5c22bc CFengine is no longer supported 2025-06-19 21:30:34 -07:00
Jamie Cameron
98000bb007 BIND 4 is no longer supported 2025-06-19 21:29:46 -07:00
Jamie Cameron
d90a33bb0c Jabber is no longer supported by Webmin 2025-06-19 21:27:45 -07:00
Jamie Cameron
d795fc7d60 Merge branch 'master' of github.com:webmin/webmin 2025-06-19 21:23:30 -07:00
Jamie Cameron
b397ece0ab Most options have moved away from set-variable
https://github.com/webmin/webmin/issues/2497
2025-06-19 21:21:47 -07:00
Jamie Cameron
0a11f182b0 Merge pull request #2498 from webmin/dev/musthost-redirect
Add ability to redirect to enforced host
2025-06-18 12:32:05 -07:00
Ilia Ross
7c05368e8f Add UI API to mask sensitive text unless specifically hovered 2025-06-18 16:53:55 +03:00
Ilia Ross
49ceeebbf8 Add ability to redirect to enforced host 2025-06-17 20:28:49 +03:00
32 changed files with 381 additions and 309 deletions

View File

@@ -1,5 +1,13 @@
## Changelog
#### 2.403 (June 30, 2025)
* Add support for the Webmin webserver to work in both HTTP and HTTPS modes at the same time
* Add status monitor for PHP FPM #2499
* Add support for redirecting to the enforced domain when the `musthost_redirect` directive is set
* Add a UI API to mask sensitive text—like displayed passwords, unless hovered over container
* Fix MySQL/MariaDB to remove obsolete `set-variable` options that break modern config files #2497
#### 2.402 (June 16, 2025)
* Update the Authentic theme to the latest version with various fixes and improvements
* Fix support for EL10-based systems

File diff suppressed because one or more lines are too long

View File

@@ -422,6 +422,10 @@ 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;
@@ -818,3 +822,21 @@ body > .mode > b[data-mode="server-manager"] > a > .ff-cloudmin {
[data-pro-disabled$="-elem"] a:hover {
filter: grayscale(1) contrast(1);
}
.not-secure {
color: #c40000;
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;
}

View File

@@ -335,11 +335,13 @@ 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{'index_uname'},
$text{'index_udesc'},
$text{'index_ucstatus'},
$text{'index_uboot'},
$text{'index_ustatus'}, ]);
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());
foreach $u (&list_systemd_services()) {
if ($u->{'legacy'}) {
$l = "edit_action.cgi?0+".&urlize($u->{'name'});
@@ -347,12 +349,23 @@ 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),
$u->{'boot'} == -1 ?
&html_escape($u->{'name'}) :
&ui_link($l, &html_escape($u->{'name'})),
&html_escape($u->{'desc'}),
$title,
$desc // (),
$type,
$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 = &get_systemd_unit_types('|');
my $units_piped = join('|', &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 = &get_systemd_unit_types('|');
my $units_piped = join('|', &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 ".join(" ", @args)." 2>/dev/null");
my $out = &backquote_command("systemctl show --property=Id,Description,UnitFileState,ActiveState,SubState,ExecStart,ExecStop,ExecReload,ExecMainPID,FragmentPath,DropInPaths ".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([return-as-string-separated])
=head2 get_systemd_unit_types()
Returns a list of all systemd unit types. Returns a string
instead if separator param is set.
@@ -2423,14 +2423,8 @@ instead if separator param is set.
=cut
sub get_systemd_unit_types
{
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;
return ('target', 'service', 'socket', 'device', 'mount', 'automount',
'swap', 'path', 'timer', 'snapshot', 'slice', 'scope', 'busname');
}
=head2 is_systemd_service(name)
@@ -2441,7 +2435,7 @@ Returns 1 if some service is managed by systemd
sub is_systemd_service
{
my ($name) = @_;
my $units_piped = &get_systemd_unit_types('|');
my $units_piped = join('|', &get_systemd_unit_types());
foreach my $s (&list_systemd_services(1)) {
if (($s->{'name'} eq $name ||
$s->{'name'} =~
@@ -2467,22 +2461,10 @@ my $systemd_unit_dir2 = "/lib/systemd/system";
if ($name) {
foreach my $p ($systemd_local_conf, $systemd_unit_dir1,
$systemd_unit_dir2) {
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;
foreach my $t (&get_systemd_unit_types()) {
return $p if (-r "$p/$name.$t");
}
return $p if (-r "$p/$name");
}
}
# Always use /etc/systemd/system for locally created units
@@ -2919,4 +2901,12 @@ 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,29 +221,30 @@ upstart_eserver2=Server command does not exist
upstart_eserver3=Only one server command can be entered
upstart_return=upstart service
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_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_file=Configuration file
systemd_desc=Service description
systemd_desc=Unit description
systemd_start=Commands to run on startup
systemd_stop=Commands to run on shutdown
systemd_conf=Systemd configuration
systemd_conf=Systemd unit 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 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_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_estart=Missing commands to run on startup
launchd_title1=Create Launchd Agent

View File

@@ -189,6 +189,9 @@ pam_mesg2=You must respond to the question below to login.
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.
acl_root=Root directory for file chooser
acl_otherdirs=Other visible directories in file chooser
acl_nodot=Hide dot files in file chooser?

View File

@@ -285,7 +285,7 @@ if (exists($minfo{'deb_requires'})) {
foreach my $debrequire (split(/\s+/, $minfo{'deb_requires'})) {
push(@rrequires, $debrequire);
}
$rdeps .= ", " . join(", ", @rrequires) if (@rrequires);
$rdeps .= ($rdeps ? ', ' : '') . join(", ", @rrequires) if (@rrequires);
}
# Build (append) list of recommended packages (not Webmin modules)
@@ -294,7 +294,8 @@ if (exists($minfo{'deb_recommends'})) {
foreach my $debrecommend (split(/\s+/, $minfo{'deb_recommends'})) {
push(@rrecommends, $debrecommend);
}
$rrecom .= ", " . join(", ", @rrecommends) if (@rrecommends);
$rrecom .= ($rrecom ? ', ' : '') . join(", ", @rrecommends)
if (@rrecommends);
}
# Build (standalone) list of suggested packages (not Webmin modules)

View File

@@ -312,7 +312,7 @@ if (exists($minfo{'rpm_requires'})) {
foreach my $rpmrequire (split(/\s+/, $minfo{'rpm_requires'})) {
push(@rrequires, $rpmrequire);
}
$rdeps .= " " . join(" ", @rrequires) if (@rrequires);
$rdeps .= ($rdeps ? ' ' : '') . join(" ", @rrequires) if (@rrequires);
}
# Build (append) list of recommended packages (not Webmin modules)
@@ -321,7 +321,8 @@ if (exists($minfo{'rpm_recommends'})) {
foreach my $rpmrecommend (split(/\s+/, $minfo{'rpm_recommends'})) {
push(@rrecommends, $rpmrecommend);
}
$rrecom .= " " . join(" ", @rrecommends) if (@rrecommends);
$rrecom .= ($rrecom ? ' ' : '') . join(" ", @rrecommends)
if (@rrecommends);
}
# Build (standalone) list of suggested packages (not Webmin modules)

View File

@@ -383,12 +383,7 @@ foreach $mod (split(/\s+/, $config{'preuse'})) {
}
# Open debug log if set
if ($config{'debuglog'}) {
open(DEBUG, ">>$config{'debuglog'}");
chmod(0700, $config{'debuglog'});
select(DEBUG); $| = 1; select(STDOUT);
print DEBUG "miniserv.pl starting ..\n";
}
&open_debug_to_log("miniserv.pl starting ..\n");
# Write out (empty) blocked hosts file
&write_blocked_file();
@@ -595,9 +590,16 @@ 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";
@@ -634,6 +636,16 @@ 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++);
@@ -918,11 +930,27 @@ while(1) {
# Initialize SSL for this connection
if ($use_ssl) {
($ssl_con, $ssl_certfile,
$ssl_keyfile) = &ssl_connection_for_ip(
SOCK, $ipv6fhs{$s});
print DEBUG "ssl_con returned $ssl_con\n";
$ssl_con || exit;
my $byte = '';
# Look at the first byte of the socket
# buffer but don't consume it
recv(SOCK, $byte, 1, MSG_PEEK);
if (length($byte) &&
# Check if the first byte is a TLS
(ord($byte) == 0x16 ||
# Check if the first byte is SSL
(ord($byte) & 0x80))) {
($ssl_con,
$ssl_certfile,
$ssl_keyfile) =
&ssl_connection_for_ip(
SOCK, $ipv6fhs{$s});
print DEBUG "ssl_con returned ".
"$ssl_con\n";
$ssl_con || exit;
}
else {
$use_ssl = 0;
}
}
print DEBUG
@@ -1088,11 +1116,10 @@ while(1) {
}
$userlast{$1} = $time_now;
}
elsif ($inline =~ /^verify\s+(\S+)\s+(\S+)\s+(\S+)/) {
elsif ($inline =~ /^verify\s+(\S+)\s+(\S+)/) {
# Verifying a session ID
local $session_id = $1;
local $notimeout = $2;
local $vip = $3;
local $vip = $2;
local $skey = $sessiondb{$session_id} ?
$session_id :
&hash_session_id($session_id);
@@ -1105,8 +1132,7 @@ while(1) {
split(/\s+/, $sessiondb{$skey});
local $lot = &get_logout_time($user, $session_id);
if ($lot &&
$time_now - $ltime > $lot*60 &&
!$notimeout) {
$time_now - $ltime > $lot*60) {
# Session has timed out due to
# idle time being hit
print $outfd "1 ",($time_now - $ltime),"\n";
@@ -1520,7 +1546,8 @@ if (defined($header{'host'})) {
else {
$host = $header{'host'};
}
if ($config{'musthost'} && $host ne $config{'musthost'}) {
if ($config{'musthost'} && $host ne $config{'musthost'} &&
!$config{'musthost_redirect'}) {
# Disallowed hostname used
&http_error(400, "Invalid HTTP hostname");
}
@@ -1543,6 +1570,22 @@ if ($config{'redirect_prefix'}) {
}
$prot = $ssl ? "https" : "http";
# Redirect to the configured "musthost", if "musthost_redirect" is set, rather
# than showing an error
if ($config{'musthost'} && $host ne $config{'musthost'} &&
$config{'musthost_redirect'}) {
&write_data("HTTP/1.0 302 Moved Temporarily\r\n");
&write_data("Date: $datestr\r\n");
&write_data("Server: @{[&server_info()]}\r\n");
&write_data("Location: $prot://$config{'musthost'}:$redirport\r\n");
&write_keep_alive(0);
&write_data("\r\n");
&log_request($loghost, $authuser, $reqline, 302, 0) if $reqline;
shutdown(SOCK, 1);
close(SOCK);
return;
}
undef(%in);
if ($page =~ /^([^\?]+)\?(.*)$/) {
# There is some query string information
@@ -1818,7 +1861,7 @@ if ($config{'session'} && !$deny_authentication &&
&http_error(500, "Invalid session",
"Session ID contains invalid characters");
}
print $PASSINw "verify $sid 0 $acptip\n";
print $PASSINw "verify $sid $acptip\n";
<$PASSOUTr> =~ /^(\d+)\s+(\S+)/;
if ($1 != 2) {
&http_error(500, "Invalid session",
@@ -1989,9 +2032,7 @@ if ($config{'session'} && !$validated) {
local $cookie = $header{'cookie'};
while($cookie =~ s/(^|\s|;)$sidname=([a-f0-9]+)//) {
$session_id = $2;
local $notimeout =
$in{'webmin_notimeout'} ? 1 : 0;
print $PASSINw "verify $session_id $notimeout $acptip\n";
print $PASSINw "verify $session_id $acptip\n";
<$PASSOUTr> =~ /(\d+)\s+(\S+)/;
if ($1 == 2) {
# Valid session continuation
@@ -5508,14 +5549,7 @@ foreach my $pe (split(/\t+/, $config{'expires_paths'})) {
}
# Re-open debug log
close(DEBUG);
if ($config{'debuglog'}) {
open(DEBUG, ">>$config{'debuglog'}");
select(DEBUG); $| = 1; select(STDOUT);
}
else {
open(DEBUG, ">/dev/null");
}
&open_debug_to_log();
# Reset cache of sudo checks
undef(%sudocache);
@@ -5902,7 +5936,7 @@ while(1) {
if ($now - $last_session_check_time > 10) {
# Re-validate the browser session every 10 seconds
print DEBUG "verifying websockets session $session_id\n";
print $PASSINw "verify $session_id 0 $acptip\n";
print $PASSINw "verify $session_id $acptip\n";
<$PASSOUTr> =~ /(\d+)\s+(\S+)/;
if ($1 != 2) {
print DEBUG "session $session_id has expired!\n";
@@ -6664,6 +6698,7 @@ 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'}) {
@@ -6673,6 +6708,23 @@ 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

@@ -50,9 +50,10 @@ print &ui_table_row($text{'cnf_stor'},
'NDB', 'ARCHIVE', 'CSV',
'BLACKHOLE' ], 1, 0, 1));
my $ifpt_def_off = &get_innodb_file_per_table_default() ? 0 : 1;
$fpt = &find_value("innodb_file_per_table", $mems);
print &ui_table_row($text{'cnf_fpt'},
&ui_yesno_radio("fpt", $fpt));
&ui_yesno_radio("fpt", $fpt // $ifpt_def_off));
$ilt = &find_value("innodb_lock_wait_timeout", $mems);
print &ui_table_row($text{'cnf_ilt'},

View File

@@ -88,20 +88,13 @@ if ($mysql_version =~ /mariadb/i) {
}
&fix_mysql_text(\%text);
if (&compare_version_numbers($mysql_version, "5.5") >= 0) {
@mysql_set_variables = ( "key_buffer_size", "sort_buffer_size",
"net_buffer_length" );
}
else {
@mysql_set_variables = ( "key_buffer", "sort_buffer",
"net_buffer_length" );
}
if (&compare_version_numbers($mysql_version, "5.6") >= 0) {
@mysql_number_variables = ( "table_open_cache", "max_connections" );
}
else {
@mysql_number_variables = ( "table_cache", "max_connections" );
}
@mysql_byte_variables = ( "max_allowed_packet" );
my $mysql8_optout = &compare_version_numbers($mysql_version, "8.0") >= 0 && $mysql_version !~ /maria/i;
if (!$mysql8_optout) {
@@ -115,6 +108,15 @@ else {
push(@mysql_set_variables, "myisam_sort_buffer_size");
}
if (&compare_version_numbers($mysql_version, "5.5") >= 0) {
push(@mysql_byte_variables, "key_buffer_size", "sort_buffer_size",
"net_buffer_length");
}
else {
@mysql_set_variables = ( "key_buffer", "sort_buffer",
"net_buffer_length" );
}
# make_authstr([login], [pass], [host], [port], [sock], [unix-user], [ssl])
# Returns a string to pass to MySQL commands to login to the database
sub make_authstr
@@ -1766,6 +1768,18 @@ return
$variant eq "mysql" && &compare_version_numbers($ver, "8.0") >= 0;
}
# get_innodb_file_per_table_default()
# Returns 1 if the InnoDB file-per-table option is disabled by default
sub get_innodb_file_per_table_default
{
my ($ver, $variant) = &get_remote_mysql_variant();
return
($variant eq 'mariadb' && &compare_version_numbers($ver, '10.1.0') < 0) ||
($variant eq 'mysql' && &compare_version_numbers($ver, '5.6.6') < 0)
? 1
: 0;
}
# get_plugin_sql(version, variant, plainpass, plugin)
# Get the right query for setting user password with plugin
sub get_plugin_sql

View File

@@ -18,7 +18,7 @@ else {
$mysql_login ? "<tt>$mysql_login</tt>"
: "<label>$text{'root_auto'}</label>");
print &ui_table_row($text{'root_pass'},
$mysql_pass ? "<tt>$mysql_pass</tt>"
$mysql_pass ? "<tt>".&ui_text_mask($mysql_pass)."</tt>"
: &ui_text_color($text{'root_none'}, 'danger'));
print &ui_table_row($text{'root_newpass1'},
&ui_password("newpass1", undef, 20));

View File

@@ -13,6 +13,7 @@ foreach my $l (&get_all_mysqld_files()) {
$conf = &get_mysql_config();
($mysqld) = grep { $_->{'name'} eq 'mysqld' } @$conf;
$mysqld || &error($text{'cnf_emysqld'});
$mems = $mysqld->{'members'};
# Parse mysql server inputs
if ($in{'port_def'}) {
@@ -53,11 +54,9 @@ else {
&save_directive($conf, $mysqld, "default-storage-engine",
$in{'stor'} ? [ $in{'stor'} ] : [ ]);
$fpt = &find_value("innodb_file_per_table", $mems);
if ($fpt || $in{'fpt'}) {
&save_directive($conf, $mysqld, "innodb_file_per_table",
[ $in{'fpt'} ]);
}
my $ifpt_def_off = &get_innodb_file_per_table_default();
&save_directive($conf, $mysqld, "innodb_file_per_table",
[ $in{'fpt'} ? ($ifpt_def_off ? 1 : undef) : 0 ]);
if ($in{'ilt_def'}) {
&save_directive($conf, $mysqld, "innodb_lock_wait_timeout", [ ]);

View File

@@ -72,7 +72,19 @@ print "$text{'pam_prefix'}\n";
print &ui_form_start("@{[&get_webprefix()]}/pam_login.cgi", "post");
print &ui_hidden("cid", $in{'cid'});
print &ui_table_start($text{'pam_header'},
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,
{ class => 'not-secure', title => $text{'login_notsecure_desc'} });
}
print &ui_table_start($text{'pam_header'} . $not_secure,
"width=40% class='loginform'", 2);
if ($gconfig{'realname'}) {

View File

@@ -27,7 +27,8 @@ print &ui_form_end([ [ undef, $text{'opts_save'} ] ]);
# Header map contents
print &ui_hr();
if (&get_real_value("header_checks") eq "") {
my $hc = &get_real_value("mime_header_checks");
if ($hc eq "") {
print $text{'opts_header_checks_no_map'},"<p>\n";
} else {
&generate_map_edit("header_checks", $text{'map_click'}." ".
@@ -37,8 +38,11 @@ if (&get_real_value("header_checks") eq "") {
# MIME header map contents
print &ui_hr();
if (&get_real_value("mime_header_checks") eq "") {
my $mhc = &get_real_value("mime_header_checks");
if ($mhc eq "") {
print $text{'opts_mime_header_checks_no_map'},"<p>\n";
} elsif ($mhc eq $hc) {
print $text{'opts_mime_header_checks_same_map'},"<p>\n";
} else {
&generate_map_edit("mime_header_checks", $text{'map_click'}." ".
&hlink($text{'help_map_format'}, "header"), 1,

View File

@@ -654,6 +654,7 @@ opts_header_checks=Header checking tables
opts_mime_header_checks=MIME header checking tables
opts_header_checks_no_map=(No header checking map is currently defined. Define a map first, then you can edit it)
opts_mime_header_checks_no_map=(No MIME header checking map is currently defined. Define a map first, then you can edit it)
opts_mime_header_checks_same_map=(MIME header checks are the same as regular header checks. Define a different map first, then you can edit it)
header_name=Regular expression
header_value=Action for matches
header_discard=Discard (with log message..)

View File

@@ -91,7 +91,20 @@ print "$text{'session_prefix'}\n";
print &ui_form_start("@{[&get_webprefix()]}/session_login.cgi", "post");
print &ui_hidden("page", $in{'page'});
print &ui_table_start($text{'session_header'},
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,
{ class => 'not-secure', title => $text{'login_notsecure_desc'} });
}
print &ui_table_start($text{'session_header'} . $not_secure,
"width=40% class='loginform'", 2);
# Login message

View File

@@ -406,6 +406,7 @@ else {
'errorlog' => "$var_dir/miniserv.error",
'pidfile' => "$var_dir/miniserv.pid",
'logtime' => 168,
'logclear' => 1,
'ppath' => $ppath,
'ssl' => $ssl,
'no_ssl2' => 1,
@@ -778,12 +779,13 @@ 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
# Store the OS and version, and enable log and log clearing
&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

@@ -819,15 +819,20 @@ if [ "$upgrading" != 1 ]; then
echo licence_module=$licence_module >>$config_dir/config
fi
# Enable log rotation by default
echo "logclear=1" >> $config_dir/miniserv.conf
echo "logclear=1" >> $config_dir/config
# Enable HSTS by default
echo "ssl_hsts=1" >> $config_dir/miniserv.conf
# Disallow unknown referers by default
echo "referers_none=1" >>$config_dir/config
else
# one-off hack to set log variable in config from miniserv.conf
grep log= $config_dir/config >/dev/null
if [ "$?" = "1" ]; then
grep log= $config_dir/miniserv.conf >> $config_dir/config
grep logtime= $config_dir/miniserv.conf >> $config_dir/config
grep logclear= $config_dir/miniserv.conf >> $config_dir/config
# Enable HSTS by default if not set
grep ssl_hsts= $config_dir/miniserv.conf >/dev/null
if [ "$?" != "0" ]; then
echo "ssl_hsts=1" >> $config_dir/miniserv.conf
fi
# Disallow unknown referers if not set

View File

@@ -97,7 +97,6 @@ if ($in{'need_unlink'}) {
"delete_file.cgi?file=".
&urlize($in{'file'})),"<p>\n";
}
print &ui_hr();
&ui_print_footer("", $text{'index_return'});
exit;
}

View File

@@ -119,6 +119,13 @@ while(<CMD>) {
$pkg =~ s/\-\d.*$//; # Strip version number from end
push(@rv, $pkg);
}
elsif (/\]\s+(Upgrading|Installing)\s+(\S+)/) {
# Line like :
# [3/8] Upgrading libcurl-0:8.11.1-5.fc42 100% ...
local $pkg = $2;
$pkg =~ s/:\d.*$//; # Strip version number from end
push(@rv, $pkg);
}
if (!/ETA/ && !/\%\s+done\s+\d+\/\d+\s*$/) {
print &html_escape($_."\n");
}

View File

@@ -1,24 +0,0 @@
# cfengine-monitor.pl
# Monitor the cfengine daemon on this host
# Check the PID file to see if cfd is running
sub get_cfengine_status
{
local %cconfig = &foreign_config($_[1]);
&has_command($cconfig{'cfd'}) || return { 'up' => -1 };
local @pids = &find_byname("cfd");
if (@pids) {
return { 'up' => 1 };
}
else {
return { 'up' => 0 };
}
}
sub parse_cfengine_dialog
{
&depends_check($_[0], "cfengine");
}
1;

View File

@@ -33,7 +33,5 @@ else {
&reset_environment();
&webmin_log("refresh");
print $text{'refresh_done'},"<p>\n";
print &js_redirect("index.cgi");
&ui_print_footer("", $text{'index_return'});
}

View File

@@ -1,28 +0,0 @@
# dnsadmin-monitor.pl
# Monitor the BIND 4 DNS server on this host
# Check the PID file to see if BIND is running
sub get_dnsadmin_status
{
return { 'up' => -1 } if (!&foreign_check($_[1]));
&foreign_require($_[1], "dns-lib.pl");
local %dconfig = &foreign_config($_[1]);
return { 'up' => -1 } if (!-r $dconfig{'named_boot_file'});
if (open(PID, "<".$dconfig{'named_pid_file'}) && <PID> =~ /(\d+)/ && kill(0, $1)) {
close(PID);
local @st = stat($dconfig{'named_pid_file'});
return { 'up' => 1,
'desc' => &text('up_since', scalar(localtime($st[9]))) };
}
else {
return { 'up' => 0 };
}
}
sub parse_dnsadmin_dialog
{
&depends_check($_[0], "dnsadmin");
}
1;

View File

@@ -1,28 +0,0 @@
# jabber-monitor.pl
# Monitor the jabber server on this host
# Check the PID file to see if mon is running
sub get_jabber_status
{
return { 'up' => -1 } if (!&foreign_check($_[1]));
local %jconfig = &foreign_config($_[1]);
-r $jconfig{'jabber_config'} || return { 'up' => -1 };
&foreign_require($_[1], "jabber-lib.pl");
local $pidfile = &foreign_call($_[1], "jabber_pid_file");
if (open(PID, "<".$pidfile) && ($pid = int(<PID>)) && kill(0, $pid)) {
return { 'up' => 1 };
}
else {
return { 'up' => 0 };
}
}
sub parse_jabber_dialog
{
&depends_check($_[0], "jabber");
eval "use XML::Parser";
&error(&text('jabber_eparser', "<tt>XML::Parser</tt>")) if ($@);
}
1;

View File

@@ -25,7 +25,6 @@ type_inetd=Internet and RPC Server
type_xinetd=Extended Internet Server
type_squid=Squid Proxy Server
type_bind8=BIND DNS Server
type_dnsadmin=BIND 4 DNS Server
type_dhcpd=DHCP Server
type_tcp=TCP Connection
type_http=HTTP Request
@@ -51,12 +50,10 @@ type_change=File or Directory Change
type_oldfile=File Not Changed
type_qmailadmin=QMail Server
type_mon=MON Service Monitor
type_jabber=Jabber IM Server
type_usermin=Usermin Webserver
type_portsentry=Portsentry Daemon
type_hostsentry=Hostsentry Daemon
type_webmin=Webmin Webserver
type_cfengine=Configuration Engine Daemon
type_memory=Free Memory
type_proftpd=ProFTPD Server
type_dovecot=Dovecot IMAP/POP3 Server
@@ -66,7 +63,6 @@ type_raid=RAID Device Status
type_iface=Network Interface Status
type_init=Bootup Action
type_sensors=LM Sensor Status
type_nut=NUT UPS Value
type_mailq=Mail Queue Size
type_dns=DNS Lookup
type_query=SQL Query
@@ -78,6 +74,7 @@ type_smtp=SMTP Connection
type_imap=IMAP Connection
type_firewalld=FirewallD Server
type_reboot=Reboot Required
type_phpini=PHP-FPM Server
mon_create=Create Monitor
mon_edit=Edit Monitor
@@ -333,8 +330,6 @@ acl_sched=Can change scheduled monitoring?
change_file=File or directory to monitor (fail if changed)
jabber_eparser=The Perl module $1 is not installed on your system.
memory_min2=Minimum free real memory
memory_emin=Missing or invalid amount of free real memory
memory_eproc=Webmin does not know how to check free memory on your operating system
@@ -374,7 +369,7 @@ init_eaction=No action selected
refresh_title=Refresh Status
refresh_doing=Refreshing the status of all monitors ..
refresh_doing2=Refreshing the status of $1 selected monitors ..
refresh_done=.. done.
refresh_done=.. done
sensors_name=Sensor to check
sensors_value=Failed when
@@ -387,17 +382,6 @@ sensors_cur=$1 (currently $2 $3)
sensors_emin=Missing or invalid minimum value
sensors_emax=Missing or invalid maximum value
nut_ups=NUT UPS to check
nut_name=Attribute to check
nut_value=Failed when
nut_value1=Value is below $1
nut_value2=Value is above $1
nut_cmd=The command <tt>upsc</tt> is not installed on your system. This monitor requires the NUT package be installed and configured to operate.
nut_eups=No USP to check entered
nut_cur=$1 (currently $2)
nut_emin=Missing or invalid minimum value
nut_emax=Missing or invalid maximum value
mailq_system=Mail server
mailq_qmailadmin=Qmail
mailq_postfix=Postfix
@@ -622,4 +606,11 @@ imap_euser=Missing IMAP login
reboot_pkgs=Package updates require a reboot
phpini_file=PHP-FPM version
phpini_nofile=PHP-FPM configuration file not found!
phpini_efile=No PHP-FPM version selected!
phpini_noinit=No bootup action found for PHP-FPM version
phpini_noinit2=Bootup action $1 does not exist!
phpini_downinit=Bootup action $1 is down
__norefs=1

View File

@@ -1,89 +0,0 @@
# Check if some NUT value is too low or high
sub get_nut_status
{
return { 'up' => -1 } if (!&has_command("upsc"));
local @sens = &get_ups_values($_[0]->{'ups'});
local ($sens) = grep { $_->{'name'} eq $_[0]->{'name'} } @sens;
return { 'up' => 1 } if (!$sens);
if ($_[0]->{'mode'} == 1) {
return $sens->{'value'} < $_[0]->{'min'} ? { 'up' => 0 }
: { 'up' => 1 };
}
elsif ($_[0]->{'mode'} == 2) {
return $sens->{'value'} > $_[0]->{'max'} ? { 'up' => 0 }
: { 'up' => 1 };
}
}
sub show_nut_dialog
{
if (!&has_command("upsc")) {
print &ui_table_row(undef, $text{'nut_cmd'}, 4);
}
else {
# UPS name
print &ui_table_row($text{'nut_ups'},
&ui_textbox("ups", $_[0]->{'ups'}, 20));
# Value to check
local @sens = &get_ups_values();
if (@sens) {
print &ui_table_row($text{'nut_name'},
&ui_select("name", $_[0]->{'name'},
[ map { [ $_->{'name'},
&text('nut_cur', $_->{'name'}, $_->{'value'}) ] }
@sens ]));
}
else {
print &ui_table_row($text{'nut_name'},
&ui_textbox("name", $_[0]->{'name'}, 20));
}
# Expected value
print &ui_table_row($text{'nut_value'},
&ui_radio("mode", $_[0]->{'mode'} || 1,
[ [ 1, &text('sensors_value1',
&ui_textbox("min", $_[0]->{'min'}, 8)) ],
[ 2, &text('sensors_value2',
&ui_textbox("max", $_[0]->{'max'}, 8)) ] ]),
3);
}
}
sub parse_nut_dialog
{
&has_command("upsc") || &error($text{'nut_cmd'});
$in{'ups'} =~ /^\S+$/ || &error($text{'nut_eups'});
$_[0]->{'ups'} = $in{'ups'};
$_[0]->{'name'} = $in{'name'};
$_[0]->{'mode'} = $in{'mode'};
$_[0]->{'max'} = $in{'max'};
$_[0]->{'min'} = $in{'min'};
if ($in{'mode'} == 1) {
$in{'min'} =~ /^[0-9\.\+\-]+$/ || &error($text{'nut_emin'});
}
elsif ($in{'mode'} == 2) {
$in{'max'} =~ /^[0-9\.\+\-]+$/ || &error($text{'nut_emax'});
}
}
# get_ups_values(ups)
# Returns a list of NUT attribute names and values for some UPS
sub get_ups_values
{
if (!scalar(@get_ups_cache)) {
local @rv;
open(SENS, "upsc ".quotemeta($_[0])." 2>/dev/null |");
while(<SENS>) {
if (/^(\S+):\s+(.*)/) {
push(@rv, { 'name' => $1,
'value' => $2 });
}
}
close(SENS);
@get_ups_cache = @rv;
}
return @get_ups_cache;
}

51
status/phpini-monitor.pl Normal file
View File

@@ -0,0 +1,51 @@
# phpini-monitor.pl
# Monitor a FPM-FPM server
sub get_phpini_status
{
my ($serv, $mod) = @_;
return { 'up' => -1 } if (!&foreign_check("phpini"));
return { 'up' => -1 } if (!&foreign_check("init"));
&foreign_require("phpini");
my @files = &phpini::list_php_configs();
my ($file) = grep { $_->[0] eq $serv->{'inifile'} } @files;
return { 'up' => -1,
'desc' => $text{'phpini_nofile'} } if (!$file);
my $init = &phpini::get_php_ini_bootup($serv->{'inifile'});
return { 'up' => -1,
'desc' => $text{'phpini_noinit'} } if (!$init);
&foreign_require("init");
my $st = &init::status_action($init);
if ($st < 0) {
return { 'up' => -1,
'desc' => &text('phpini_noinit2', $init) };
}
elsif ($st > 0) {
return { 'up' => 1 };
}
else {
return { 'up' => 0,
'desc' => &text('phpini_downinit', $init) };
}
}
sub show_phpini_dialog
{
my ($serv) = @_;
&foreign_require("phpini");
my @files = grep { $_->[1] }
map { [ $_->[0], &phpini::get_php_ini_version($_->[0]) ] }
&phpini::list_php_configs();
my %donever;
@files = grep { !$donever{$_->[1]}++ } @files;
print &ui_table_row($text{'phpini_file'},
&ui_select("inifile", $serv->{'inifile'}, \@files));
}
sub parse_phpini_dialog
{
my ($serv) = @_;
$in{'inifile'} || &error($text{'phpini_efile'});
$serv->{'inifile'} = $in{'inifile'};
}

View File

@@ -3760,5 +3760,56 @@ my ($content, $attrs) = @_;
return ui_tag('p', $content, $attrs);
}
=head2 ui_text_mask(text, [tag], [extra_class])
Returns an HTML string with the given text hidden inside a tag that only shows
on hover. If a second parameter is given, it is used as the outer tag that
triggers the hover (default is "td"). If a third parameter is provided,
it is added as an extra class to both the tag and its style.
=cut
sub ui_text_mask
{
return &theme_ui_text_mask(@_) if (defined(&theme_ui_text_mask));
my ($text, $tag, $extra_class) = @_;
my $class = 'hover-mask';
my $classcss = ".$class";
if ($extra_class) {
$class .= " $extra_class";
$classcss .= ".$extra_class";
}
$tag ||= 'td';
my $style_content = <<"CSS";
x-ui-text-mask${classcss} {
position: relative;
display: inline-block;
color: transparent;
transition:color .25s ease;
}
x-ui-text-mask${classcss}::after{
content: attr(data-mask);
position: absolute;
inset: 0;
color: var(--ui-password-mask-color, #000);
pointer-events: none;
transition: opacity .25s ease;
}
$tag:has(>*>x-ui-text-mask${classcss}):hover x-ui-text-mask${classcss},
$tag:has(>x-ui-text-mask${classcss}):hover x-ui-text-mask${classcss}{
color: inherit;
}
$tag:has(>*>x-ui-text-mask${classcss}):hover x-ui-text-mask${classcss}::after,
$tag:has(>x-ui-text-mask${classcss}):hover x-ui-text-mask${classcss}::after{
opacity: 0;
}
CSS
my $rv = '';
$rv .= &ui_tag('style', $style_content, { type => 'text/css' })
if (!$main::ui_text_mask_donecss->{"$tag$class"}++);
$rv .= &ui_tag('x-ui-text-mask', $text,
{ 'class' => $class, 'data-mask' => '••••••••' });
return $rv;
}
1;

View File

@@ -1077,11 +1077,13 @@ sub PrintHeader
{
my ($cs, $mt, $headers) = @_;
$mt ||= "text/html";
if ($ENV{'SSL_HSTS'} == 1 && uc($ENV{'HTTPS'}) eq "ON") {
print "Strict-Transport-Security: max-age=31536000;\n";
}
elsif (uc($ENV{'HTTPS'}) ne "ON") {
print "Strict-Transport-Security: max-age=0;\n";
if (uc($ENV{'HTTPS'}) eq "ON") {
if ($ENV{'SSL_HSTS'}) {
print "Strict-Transport-Security: max-age=31536000;\n";
}
else {
print "Strict-Transport-Security: max-age=0;\n";
}
}
if ($pragma_no_cache || $gconfig{'pragma_no_cache'}) {
print "pragma: no-cache\n";

View File

@@ -28,7 +28,7 @@ print &ui_table_row($text{'debug_file'},
print &ui_table_row($text{'debug_size'},
&ui_radio("debug_size_def", $gconfig{'debug_size'} ? 0 : 1,
[ [ 1, $text{'default'}.
" (".&nice_size($main::default_debug_log_size).")" ],
" (".&html_strip(&nice_size($main::default_debug_log_size)).")" ],
[ 0, &ui_bytesbox("debug_size", $gconfig{'debug_size'}) ] ]
), undef, [ "valign=middle","valign=middle" ]);