Fix to handle HTTPS update sources with outbound SSL fallback

This commit is contained in:
Ilia Ross
2026-04-10 18:56:41 +02:00
parent 995f4fa6c1
commit ac8cbf57f9
10 changed files with 83 additions and 40 deletions

File diff suppressed because one or more lines are too long

View File

@@ -12,14 +12,11 @@ if ($in{'source'} == 0) {
$host = $update_host;
$port = $update_port;
$page = $update_page;
$ssl = $update_ssl;
}
else {
$in{'other'} =~ /^(http|https):\/\/([^:\/]+)(:(\d+))?(\/\S+)$/ ||
&error($text{'update_eurl'});
$ssl = $1 eq 'https';
$host = $2;
$port = $3 ? $4 : $ssl ? 443 : 80;
$page = $5;
($host, $port, $page, $ssl) = &parse_http_url($in{'other'});
$host && $ssl != 2 || &error($text{'update_eurl'});
}
# Retrieve the updates list (format is module version url support description )
@@ -114,7 +111,10 @@ print &text('update_none'),"<br>\n" if (!$count);
# Check if a new version of webmin itself is available
$file = &transname();
&http_download('webmin.com', 80, '/index6.html', $file);
my ($index_host, $index_port, $index_page, $index_ssl) =
&parse_http_url($latest_page_url);
&http_download($index_host, $index_port, $index_page, $file,
undef, undef, $index_ssl);
open(FILE, "<$file");
while(<FILE>) {
if (/usermin-([0-9\.]+)\.tar\.gz/) {

View File

@@ -8,14 +8,13 @@ if (!-r "$config{'usermin_dir'}/miniserv.conf") {
# Usermin not installed
exit(0);
}
my $ssl = $update_ssl;
# Get the update source
if ($config{'upsource'}) {
$config{'upsource'} =~ /^http:\/\/([^:\/]+)(:(\d+))?(\/\S+)$/ ||
die "Invalid update source URL!";
$host = $1;
$port = $2 ? $3 : 80;
$page = $4;
($host, $port, $page, $ssl) =
&parse_http_url($config{'upsource'});
$host && $ssl != 2 || die "Invalid update source URL!";
}
else {
$host = $update_host;
@@ -25,7 +24,7 @@ else {
# Retrieve the updates list (format is module version url support description )
$temp = &transname();
&http_download($host, $port, $page, $temp);
&http_download($host, $port, $page, $temp, undef, undef, $ssl);
open(UPDATES, "<".$temp);
while(<UPDATES>) {
if (/^([^\t]+)\t+([^\t]+)\t+([^\t]+)\t+([^\t]+)\t+(.*)/) {
@@ -73,23 +72,33 @@ foreach $u (@updates) {
$rv .= &text('update_mok', $u->[0], $u->[1])."\n".
$text{'update_fixes'}." : ".$u->[4]."\n\n";
if ($u->[2] =~ /^http:\/\/([^:\/]+)(:(\d+))?(\/\S+)$/) {
$mssl = 0;
$mhost = $1;
$mport = $2 ? $3 : 80;
$mpage = $4;
}
elsif ($u->[2] =~ /^https:\/\/([^:\/]+)(:(\d+))?(\/\S+)$/) {
$mssl = 1;
$mhost = $1;
$mport = $2 ? $3 : 443;
$mpage = $4;
}
elsif ($u->[2] =~ /^\/\S+$/) {
$mssl = $ssl;
$mhost = $host;
$mport = $port;
$mpage = $u->[2];
}
else {
$mssl = $ssl;
$mhost = $host;
$mport = $port;
($mpage = $page) =~ s/[^\/]+$//;
$mpage .= $u->[2];
}
$mtemp = &transname();
&http_download($mhost, $mport, $mpage, $mtemp, \$error);
&http_download($mhost, $mport, $mpage, $mtemp,
\$error, undef, $mssl);
if ($error) {
$rv .= "$error\n\n";
last;
@@ -110,7 +119,10 @@ foreach $u (@updates) {
# Check if a new version of usermin itself is available
$file = &transname();
&http_download('webmin.com', 80, '/index6.html', $file);
my ($index_host, $index_port, $index_page, $index_ssl) =
&parse_http_url($latest_page_url);
&http_download($index_host, $index_port, $index_page, $file,
undef, undef, $index_ssl);
open(FILE, "<".$file);
while(<FILE>) {
if (/usermin-([0-9\.]+)\.tar\.gz/) {
@@ -133,7 +145,9 @@ if ($config{'upemail'} && $rv && &foreign_check("mailboxes")) {
local $version = $gconfig{'real_os_version'} || $gconfig{'os_version'};
local $myhost = &get_system_hostname();
$data .= "$myhost ($type $version)\n\n";
$data .= &text('update_rv', "http://$host:$port$page")."\n\n";
$data .= &text('update_rv',
($ssl ? "https://" : "http://").
"$host:$port$page")."\n\n";
$data .= $rv;
&mailboxes::send_text_mail(&mailboxes::get_from_address(),
$config{'upemail'},

View File

@@ -14,8 +14,8 @@ if ($in{'source'} == 0) {
$config{'upsource'} = undef;
}
else {
$in{'other'} =~ /^http:\/\/([^:\/]+)(:(\d+))?(\/\S+)$/ ||
&error($text{'update_eurl'});
my ($host, $port, $page, $ssl) = &parse_http_url($in{'other'});
$host && $ssl != 2 || &error($text{'update_eurl'});
$config{'upsource'} = $in{'other'};
}
$config{'update'} = $in{'enabled'};

View File

@@ -48,7 +48,10 @@ elsif ($in{'source'} == 2) {
# find latest version at webmin.com by looking at index page
&error_setup($text{'upgrade_err3'});
$file = &transname();
&http_download('webmin.com', 80, '/index6.html', $file, \$error);
my ($index_host, $index_port, $index_page, $index_ssl) =
&parse_http_url($latest_page_url);
&http_download($index_host, $index_port, $index_page, $file, \$error,
undef, $index_ssl);
$error && &inst_error($error);
open(FILE, "<$file");
while(<FILE>) {
@@ -150,7 +153,7 @@ $qfile = quotemeta($file);
# Get list of updates
$updatestemp = &transname();
&http_download($update_host, $update_port, $update_page, $updatestemp,
\$updates_error);
\$updates_error, undef, $update_ssl);
if ($in{'mode'} eq 'rpm') {
# Check if it is an RPM package

View File

@@ -25,17 +25,21 @@ if (!defined($gconfig{'noselfwebminup'})) {
else {
$access{'upgrade'} = !$gconfig{'noselfwebminup'};
}
my $can_http_ssl = &can_use_http_ssl();
my $http_proto = $can_http_ssl ? "https" : "http";
$usermin_miniserv_config = "$config{'usermin_dir'}/miniserv.conf";
$usermin_config = "$config{'usermin_dir'}/config";
$update_host = "www.webmin.com";
$update_port = 80;
$update_host = "webmin.com";
$update_ssl = $can_http_ssl;
$update_port = $update_ssl ? 443 : 80;
$update_page = "/uupdates/uupdates.txt";
$standard_usermin_dir = "/etc/usermin";
$latest_rpm = "http://www.webmin.com/download/usermin-latest.noarch.rpm";
$latest_tgz = "http://www.webmin.com/download/usermin-latest.tar.gz";
$latest_page_url = "$http_proto://$update_host/index6.html";
$latest_rpm = "$http_proto://$update_host/download/usermin-latest.noarch.rpm";
$latest_tgz = "$http_proto://$update_host/download/usermin-latest.tar.gz";
$default_key_size = 2048;

View File

@@ -9456,6 +9456,21 @@ else {
}
}
=head2 can_use_http_ssl()
Returns 1 if this Webmin process can make outbound HTTPS connections, or 0
if the required Net::SSLeay Perl module is not available.
=cut
my $can_use_http_ssl_cache;
sub can_use_http_ssl
{
return $can_use_http_ssl_cache if (defined($can_use_http_ssl_cache));
eval "use Net::SSLeay";
$can_use_http_ssl_cache = $@ ? 0 : 1;
return $can_use_http_ssl_cache;
}
=head2 make_http_connection(host, port, ssl, method, page, [&headers],
[&certreqs])
@@ -9497,8 +9512,7 @@ if (&is_readonly_mode()) {
my $rv = { 'fh' => time().$$ };
if ($ssl) {
# Connect using SSL
eval "use Net::SSLeay";
$@ && return $text{'link_essl'};
&can_use_http_ssl() || return $text{'link_essl'};
eval "Net::SSLeay::SSLeay_add_ssl_algorithms()";
eval "Net::SSLeay::OpenSSL_add_all_algorithms()";
eval "Net::SSLeay::load_error_strings()";

View File

@@ -29,7 +29,7 @@ get_miniserv_config(\%miniserv);
$@ = undef;
eval "use Net::SSLeay";
if ($@) {
print text('ssl_essl', "http://www.webmin.com/ssl.html"),"<p>\n";
print text('ssl_essl', "https://webmin.com/ssl.html"),"<p>\n";
if (foreign_available("cpan")) {
print text('ssl_cpan', "../cpan/download.cgi?source=3&cpan=Net::SSLeay&mode=2&return=/$module_name/&returndesc=".urlize($text{'index_return'})),"<p>\n";
}

View File

@@ -187,7 +187,10 @@ if ($in{'sig'}) {
if ($in{'source'} == 2) {
# Download the key for this tar.gz
my ($sigtemp, $sigerror);
&http_download($update_host, $update_port, "/download/sigs/webmin-${full}${mini_type}.tar.gz-sig.asc", \$sigtemp, \$sigerror);
&http_download($update_host, $update_port,
"/download/sigs/webmin-${full}${mini_type}.tar.gz-sig.asc",
\$sigtemp, \$sigerror,
undef, $update_ssl);
if ($sigerror) {
$ec = 4;
$emsg = &text('upgrade_edownsig',

View File

@@ -23,23 +23,27 @@ use Socket;
our @cs_codes = ( 'cs_page', 'cs_text', 'cs_table', 'cs_header', 'cs_link' );
our @cs_names = map { $text{$_} } @cs_codes;
my $can_http_ssl = &can_use_http_ssl();
my $http_proto = $can_http_ssl ? "https" : "http";
our $osdn_host = "prdownloads.sourceforge.net";
our $osdn_port = 80;
our $update_host = "download.webmin.com";
our $update_port = 80;
our $update_ssl = $can_http_ssl;
our $update_port = $update_ssl ? 443 : 80;
our $update_page = "/updates/updates.txt";
our $update_url = "http://$update_host:$update_port$update_page";
our $redirect_host = "www.webmin.com";
our $redirect_url = "http://$redirect_host/cgi-bin/redirect.cgi";
our $update_url = "$http_proto://$update_host:$update_port$update_page";
our $redirect_host = "webmin.com";
our $redirect_url = "$http_proto://$redirect_host/cgi-bin/redirect.cgi";
our $update_cache = "$module_config_directory/update-cache";
if (!-r $update_cache) {
$update_cache = "$module_var_directory/update-cache";
}
our $primary_host = "www.webmin.com";
our $primary_port = 80;
our $primary_host = "webmin.com";
our $primary_ssl = $can_http_ssl;
our $primary_port = $primary_ssl ? 443 : 80;
our $webmin_key_email = "jcameron\@webmin.com";
our $webmin_key_fingerprint = "1719 003A CE3E 5A41 E2DE 70DF D97A 3AE9 11F6 3C51";
@@ -53,12 +57,12 @@ our $authentic_key_fingerprint = "EC60 F3DA 9CB7 9ADC CF56 0D1F 121E 166D D9C8
our $standard_host = $primary_host;
our $standard_port = $primary_port;
our $standard_page = "/download/modules/standard.txt";
our $standard_ssl = 0;
our $standard_ssl = $primary_ssl;
our $third_host = $primary_host;
our $third_port = $primary_port;
our $third_page = "/cgi-bin/third.cgi";
our $third_ssl = 0;
our $third_ssl = $primary_ssl;
our $default_key_size = "2048";
@@ -776,7 +780,7 @@ return (0);
=head2 list_standard_modules
Returns a list containing the short names, URLs and descriptions of the
standard Webmin modules from www.webmin.com. If an error occurs, returns the
standard Webmin modules from webmin.com. If an error occurs, returns the
message instead.
=cut
@@ -2488,7 +2492,7 @@ return wantarray ? (\%installed, \@changed) : \%installed;
=head2 get_latest_webmin_version
Returns 1 and the latest version of Webmin available on www.webmin.com, or
Returns 1 and the latest version of Webmin available on webmin.com, or
0 and an error message
=cut
@@ -2496,7 +2500,8 @@ sub get_latest_webmin_version
{
my $file = &transname();
my ($error, $version, $release);
&http_download($primary_host, $primary_port, '/', $file, \$error, undef, 0,
&http_download($primary_host, $primary_port, '/', $file, \$error, undef,
$primary_ssl,
undef, undef, 5);
return (0, $error) if ($error);
open(FILE, "<".$file);