mirror of
https://github.com/webmin/webmin.git
synced 2026-02-05 07:02:14 +00:00
Compare commits
36 Commits
2.402
...
dev/sessio
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f6b62525f8 | ||
|
|
57138d505b | ||
|
|
58580b7f4b | ||
|
|
d9a120c760 | ||
|
|
fb832eff82 | ||
|
|
75b0a6f7bb | ||
|
|
40707d8602 | ||
|
|
ac45266ee4 | ||
|
|
522aeb5264 | ||
|
|
1d24db1686 | ||
|
|
527043b54d | ||
|
|
56b62346b4 | ||
|
|
ee39f99d23 | ||
|
|
a223243db4 | ||
|
|
b59bdc4f1a | ||
|
|
d087f9f024 | ||
|
|
1607a59239 | ||
|
|
70589cf88a | ||
|
|
c429fbb202 | ||
|
|
f24375e13a | ||
|
|
d428f4d4c1 | ||
|
|
f0e07518c9 | ||
|
|
29709c3c51 | ||
|
|
fb71fbd5ae | ||
|
|
a1f06c5548 | ||
|
|
10e8a420c0 | ||
|
|
8149eef10a | ||
|
|
c4b98ef376 | ||
|
|
621d5c22bc | ||
|
|
98000bb007 | ||
|
|
d90a33bb0c | ||
|
|
d795fc7d60 | ||
|
|
b397ece0ab | ||
|
|
0a11f182b0 | ||
|
|
7c05368e8f | ||
|
|
49ceeebbf8 |
@@ -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
@@ -818,3 +818,8 @@ body > .mode > b[data-mode="server-manager"] > a > .ff-cloudmin {
|
||||
[data-pro-disabled$="-elem"] a:hover {
|
||||
filter: grayscale(1) contrast(1);
|
||||
}
|
||||
.not-secure {
|
||||
color: #f00a38;
|
||||
float: right;
|
||||
cursor: help;
|
||||
}
|
||||
|
||||
3
lang/en
3
lang/en
@@ -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. 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
|
||||
acl_nodot=Hide dot files in file chooser?
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
101
miniserv.pl
101
miniserv.pl
@@ -610,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";
|
||||
@@ -918,11 +965,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
|
||||
@@ -1101,8 +1164,10 @@ 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 &&
|
||||
@@ -1131,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";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1520,7 +1585,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 +1609,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
|
||||
@@ -5899,7 +5981,8 @@ 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 0 $acptip\n";
|
||||
|
||||
@@ -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'},
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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", [ ]);
|
||||
|
||||
@@ -72,7 +72,13 @@ 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') {
|
||||
$not_secure = ui_tag('span', "⚠ $text{'login_notsecure'}",
|
||||
{ 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'}) {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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..)
|
||||
|
||||
@@ -91,7 +91,14 @@ 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') {
|
||||
$not_secure = ui_tag('span', "⚠ $text{'login_notsecure'}",
|
||||
{ class => 'not-secure', title => $text{'login_notsecure_desc'} });
|
||||
}
|
||||
|
||||
print &ui_table_start($text{'session_header'} . $not_secure,
|
||||
"width=40% class='loginform'", 2);
|
||||
|
||||
# Login message
|
||||
|
||||
24
setup.sh
24
setup.sh
@@ -819,15 +819,27 @@ 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 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
|
||||
echo "ssl_hsts=1" >> $config_dir/miniserv.conf
|
||||
fi
|
||||
|
||||
# Disallow unknown referers if not set
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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'});
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
51
status/phpini-monitor.pl
Normal 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'};
|
||||
}
|
||||
|
||||
51
ui-lib.pl
51
ui-lib.pl
@@ -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;
|
||||
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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" ]);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user