Hi,

> > > > It implements a security feature: to hide the password when printing
> > > > the command line to screen.
> > >
> > > I suggest to add a warning to usage() that passing the password in
> > > a command-line argument may make it visible to other local OS users.
> >
> > Do you mean that showing a warning message would be preferable to
> > actually fixing the problem?
>
> No.  I think the warning and the asterisking are independent changes;
> I suppose we should make both of them.

This is the second version of the patch, including the suggestion from
Daniel.

Log message:
[[[
Do not print password to screen in svn_load_dirs.pl.

* contrib/client-side/svn_load_dirs/svn_load_dirs.pl.in
  (sanitize_pwd): New function.
  (safe_read_from_pipe, read_from_process): Update the sites printing
   the command line to screen to use sanitize_pwd.
  (usage): Warn that other local OS users may be able to see the
   password passed on the command-line.

  Fix indentation; that is, replace the 2 tab occurrences by 8 spaces.
]]]

Index: contrib/client-side/svn_load_dirs/svn_load_dirs.pl.in
===================================================================
--- contrib/client-side/svn_load_dirs/svn_load_dirs.pl.in	(revision 1863003)
+++ contrib/client-side/svn_load_dirs/svn_load_dirs.pl.in	(working copy)
@@ -196,7 +196,7 @@
       {
         if ( /^global-ignores\s*=\s*(.*?)\s*$/ )
           {
-	    $ignores_str = $1;
+            $ignores_str = $1;
             last;
           }
       }
@@ -1344,6 +1344,8 @@
       "  -p filename    table listing properties to apply to matching files\n",
       "  -svn_username  username to perform commits as\n",
       "  -svn_password  password to supply to svn commit\n",
+      "                 WARNING: passing the password in a command-line argument\n",
+      "                 may make it visible to other local OS users\n",
       "  -t tag_dir     create a tag copy in tag_dir, relative to svn_url\n",
       "  -v             increase program verbosity, multiple -v's allowed\n",
       "  -wc path       use the already checked-out working copy at path\n",
@@ -1500,6 +1502,18 @@
   return '?';
 }
 
+# Copy arguments and replace what follows --password with '*'s.
+sub sanitize_pwd
+{
+  my @str = @_;
+  my $hide_next = 0;
+  foreach(@str) {
+    $_ = '*' x length if ( $hide_next );
+    $hide_next = ($_ eq '--password');
+  }
+  @str;
+}
+
 # Start a child process safely without using /bin/sh.
 sub safe_read_from_pipe
 {
@@ -1511,7 +1525,7 @@
   my $openfork_available = "MSWin32" ne $OSNAME;
   if ($openfork_available)
     {
-      print "Running @_\n";
+      print join(' ', &sanitize_pwd("Running", @_, "\n") );
       my $pid = open(SAFE_READ, "-|");
       unless (defined $pid)
         {
@@ -1523,7 +1537,9 @@
           open(STDERR, ">&STDOUT")
             or die "$0: cannot dup STDOUT: $!\n";
           exec(@_)
-            or die "$0: cannot exec '@_': $!\n";
+            or die "$0: cannot exec '"
+              . join(' ', &sanitize_pwd(@_) )
+              . "': $!\n";
         }
     }
   else
@@ -1560,7 +1576,7 @@
             }
         }
 
-      print "Running @commandline\n";
+      print join(' ', &sanitize_pwd("Running", @commandline, "\n") );
       if ( $comment ) { print $comment; }
 
       # Now do the pipe.
@@ -1582,7 +1598,9 @@
   my $cd     = $result & 128 ? "with core dump" : "";
   if ($signal or $cd)
     {
-      warn "$0: pipe from '@_' failed $cd: exit=$exit signal=$signal\n";
+      warn "$0: pipe from '"
+        . join(' ', &sanitize_pwd(@_) )
+        . "' failed $cd: exit=$exit signal=$signal\n";
     }
   if (wantarray)
     {
@@ -1605,8 +1623,9 @@
   my ($status, @output) = &safe_read_from_pipe(@_);
   if ($status)
     {
-      print STDERR "$0: @_ failed with this output:\n", join("\n", @output),
-                   "\n";
+      print STDERR
+        join(' ', &sanitize_pwd("$0:", @_, "failed with this output:\n") ),
+        join("\n", @output), "\n";
       unless ($opt_no_user_input)
         {
           print STDERR
@@ -1658,7 +1677,7 @@
     };
   find({no_chdir   => 1,
         preprocess => sub
-	  {
+          {
             grep
               {
                 my $ok=1;

Reply via email to