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:
Ilia Ross
2026-10-15 16:36:32 +02:00
parent 24cd92a061
commit 0678fbfa6b
2 changed files with 23 additions and 4 deletions

View File

@@ -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);

View File

@@ -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 : $!");