Package: dpkg-sig Version: 0.12 Severity: grave Tags: patch Line 1627 of /usr/bin/dpkg-sig reads:
$DEBUG && (open (LOG, ">", "/tmp/dpkg-sig.log") || die _die("Couldn't open log: $!")); This is assuming that this file does not exist, is not a symlink and so on. This is a security hole and should be fixed by using a safe filename. Patch attached. Other comments while I'm here: (1) You don't need the & in front of sub names; they'll work quite happily without it. (2) -o for a remote ssh port number is a horrid choice: -o is normally an output file; -P would be much better (matching scp, for example). Julian
--- /usr/bin/dpkg-sig 2005-11-01 08:57:42.000000000 +0000 +++ /tmp/dpkg-sig 2006-02-13 20:08:53.000000000 +0000 @@ -42,6 +42,7 @@ use IPC::Open2; use IPC::Open3; use File::Temp qw(tempdir); +use File::Spec; use File::Copy qw(move); use File::Basename qw(dirname basename); $| = 1; @@ -65,7 +66,7 @@ #In client mode, we wait for commands and STDIN, we don't need the rest: if ($client) { - print "Welcome. This is dpkg-sig in client mode. Protocol version 6\n"; + print "Welcome. This is dpkg-sig in client mode. Protocol version 7\n"; &read_cmds(); exit; } @@ -208,8 +209,11 @@ } #Clean our ssh connections: -for (values %ssh_connections) { - my ($pid, $readerfh, $writerfh) = @$_; +while (my ($host, $val) = each %ssh_connections) { + if ($DEBUG) { + print "Debug log for $host saved on remote machine in " . get_tempfile_name($host) . "\n"; + } + my ($pid, $readerfh, $writerfh) = @$val; print $writerfh "quit\n"; sleep 1; @@ -1414,6 +1418,44 @@ =pod +=head2 I<$filename> = get_tempfile_name (I<$host>) + +Returns the name of the tempfile on host I<$host>. I<$host> must be a key +in the I<%ssh_connections> hash. + +=cut + +sub get_tempfile_name { + my $host = shift; + my $user; + + if ($host =~ /^(.*)\@(.*)$/) { + ($user, $host) = ($1, $2); + } + + my ($readerfh, $writerfh, $prot_version) = get_ssh_connection($user, $host); + + if ($prot_version < 7) { + print "W: remote dpkg-sig on $host is too old and can't return the needed data. Remote logfile name not known."; + return 'an unknown location'; + } + + print $writerfh "tempfile_name\n"; + + my ($response, $t); + $response = ''; + do { read($readerfh, $t, 1); $response .= $t } while ($t ne "\n"); + chomp($response); + + if ($response =~ /^200 tempfile: (.+) /) { + return $1; + } else { + die _die("remote dpkg-sig on $host returned \"$response\""); + } +} + +=pod + =head2 I<@ssh_uri_parts> = split_ssh_uri (I<$uri>) Splits an ssh URI $uri into a B<$user>, B<$host> and B<$path> part. @@ -1453,11 +1495,12 @@ sub get_ssh_connection { my ($user, $host) = @_; + my $caller = (caller)[2]; my $connection_id = (defined ($user))?"[EMAIL PROTECTED]":$host; $remote_ssh_port ||= ""; - $remote_ssh_port =~ s/^\s*(\d+)\s*$/-p $&/; + $remote_ssh_port =~ s/^\s*(\d+)\s*$/-p $1/; if (! $ssh_connections{$connection_id} ) { my ($readerfh, $writerfh); die _die("No ssh installed, we need it to connect to the remote host.") if (not `which ssh`); @@ -1477,8 +1520,8 @@ } } - if ($response !~ /protocol version (\d+)$/i || $1 < 6) { - die _die("dpkg-sig on $host is too old (we need protocol version 6)"); + if ($response !~ /protocol version (\d+)$/i || $1 < 7) { + die _die("dpkg-sig on $host is too old (we need protocol version 7)"); } $ssh_connections{$connection_id} = [$pid, $readerfh, $writerfh, $1]; @@ -1624,12 +1667,19 @@ } sub read_cmds { - $DEBUG && (open (LOG, ">", "/tmp/dpkg-sig.log") || die _die("Couldn't open log: $!")); - $DEBUG && select LOG; $|=1; - $DEBUG && select STDOUT; + our $logfh; + + if ($DEBUG) { + $logfh = new File::Temp(DIR => File::Spec->tmpdir(), + TEMPLATE => 'dpkg-sig.XXXXXX', + UNLINK => 0) || + die _die("Couldn't open log: $!"); + select $logfh; $|=1; + select STDOUT; + } - sub send { print STDOUT @_; $DEBUG && print LOG "Sent: ", @_; } - sub read { $_ = <STDIN>; $DEBUG && print LOG "Received: ", $_; return $_ } ; + sub send { print STDOUT @_; $DEBUG && print $logfh "Sent: ", @_; } + sub read { $_ = <STDIN>; $DEBUG && print $logfh "Received: ", $_; return $_ } ; while ($_ = &read()) { chomp; @@ -1795,15 +1845,20 @@ &send("200 ok $file written. New md5sum, size: $r[0] $r[1]\n"); } + } elsif (/^tempfile_name\s*$/) { + &send("200 tempfile: $logfh \n"); + } elsif (/^quit\s*$/) { &send("200 ok Bye!\n"); + $DEBUG && close $logfh; exit; } else { &send("501 unknown command ".(split / /, $_)[0]."\n"); } } - $DEBUG && close LOG; + # Shouldn't be necessary, but just in case we get to here... + $DEBUG && close $logfh; } sub process_cli_options {