mirror of
https://github.com/webmin/webmin.git
synced 2026-10-30 07:01:10 +00:00
Fix Fast RPC transfer authentication
This PR fixes unauthenticated Fast RPC transfer sockets by requiring the transfer connection to present the active RPC session ID before file data moves. Patched peers use authentication, while mixed-version transfers retain existing behavior for compatibility. ANT-2026-1G97HEC6: Reported by Adam email on October 11 2026 at 12:08.
This commit is contained in:
19
fastrpc.cgi
19
fastrpc.cgi
@@ -211,6 +211,12 @@ while(1) {
|
||||
elsif ($use_ipv6 && vec($rmask, fileno($tsock6), 1)) {
|
||||
accept(TRANS, $tsock6) || exit;
|
||||
}
|
||||
if ($arg->{'xferauth'}) {
|
||||
my $auth = <TRANS>;
|
||||
exit if (!defined($auth));
|
||||
chomp($auth);
|
||||
exit if ($auth ne $sid);
|
||||
}
|
||||
print STDERR "fastrpc[$$]: tcpwrite $file accepted\n" if ($gconfig{'rpcdebug'});
|
||||
my $buf;
|
||||
my $err;
|
||||
@@ -240,7 +246,9 @@ while(1) {
|
||||
$xfer_kids{$cpid} = 1;
|
||||
print STDERR "fastrpc[$$]: tcpwrite $file started\n"
|
||||
if ($gconfig{'rpcdebug'});
|
||||
$rv = { 'status' => 1, 'rv' => [ $file, $tport ] };
|
||||
$rv = { 'status' => 1,
|
||||
'rv' => [ $file, $tport,
|
||||
$arg->{'xferauth'} ? $sid : undef ] };
|
||||
}
|
||||
close($tsock);
|
||||
close($tsock6) if ($use_ipv6);
|
||||
@@ -295,6 +303,12 @@ while(1) {
|
||||
elsif (vec($rmask, fileno($tsock6), 1)) {
|
||||
accept(TRANS, $tsock6) || exit;
|
||||
}
|
||||
if ($arg->{'xferauth'}) {
|
||||
my $auth = <TRANS>;
|
||||
exit if (!defined($auth));
|
||||
chomp($auth);
|
||||
exit if ($auth ne $sid);
|
||||
}
|
||||
my $buf;
|
||||
while(read(FILE, $buf, 1024) > 0) {
|
||||
print TRANS $buf;
|
||||
@@ -309,7 +323,8 @@ while(1) {
|
||||
"started\n"
|
||||
if ($gconfig{'rpcdebug'});
|
||||
$rv = { 'status' => 1,
|
||||
'rv' => [ $arg->{'file'}, $tport ] };
|
||||
'rv' => [ $arg->{'file'}, $tport,
|
||||
$arg->{'xferauth'} ? $sid : undef ] };
|
||||
}
|
||||
close(FILE);
|
||||
close($tsock);
|
||||
|
||||
@@ -9020,12 +9020,14 @@ else {
|
||||
my ($data, $got);
|
||||
my $rv = &remote_rpc_call($host, { 'action' => 'tcpwrite',
|
||||
'file' => $remotefile,
|
||||
'name' => $remotebase } );
|
||||
'name' => $remotebase,
|
||||
'xferauth' => 1 } );
|
||||
my $error;
|
||||
my $serv = !ref($host) ? $host : ($host->{'ip'} || $host->{'host'});
|
||||
&open_socket($serv || "localhost", $rv->[1], TWRITE, \$error);
|
||||
return &$main::remote_error_handler("Failed to transfer file : $error")
|
||||
if ($error);
|
||||
print TWRITE $rv->[2],"\n" if ($rv->[2]);
|
||||
open(FILE, "<".$localfile) ||
|
||||
return &$main::remote_error_handler("Failed to open $localfile : $!");
|
||||
my $bs = &get_buffer_size();
|
||||
@@ -9072,7 +9074,8 @@ if ($sn eq "" && ref($s) && $s->{'local'}) {
|
||||
}
|
||||
else {
|
||||
my $rv = &remote_rpc_call($host, { 'action' => 'tcpread',
|
||||
'file' => $remotefile } );
|
||||
'file' => $remotefile,
|
||||
'xferauth' => 1 } );
|
||||
if (!$rv->[0]) {
|
||||
return &$main::remote_error_handler("Failed to transfer file : $rv->[1]");
|
||||
}
|
||||
@@ -9081,6 +9084,7 @@ else {
|
||||
&open_socket($serv || "localhost", $rv->[1], TREAD, \$error);
|
||||
return &$main::remote_error_handler("Failed to transfer file : $error")
|
||||
if ($error);
|
||||
print TREAD $rv->[2],"\n" if ($rv->[2]);
|
||||
my $got;
|
||||
open(FILE, ">$localfile") ||
|
||||
return &$main::remote_error_handler("Failed to open $localfile : $!");
|
||||
|
||||
Reference in New Issue
Block a user