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 {

Reply via email to