applied!  thanks ;)
https://issues.apache.org/SpamAssassin/show_bug.cgi?id=5798

Daniel Albers writes:
> Hi Justin,
> 
> Justin Mason wrote:
> 
> >> +      no re 'taint';
> >> +      my $username = ( $username =~ /^([-:,[EMAIL PROTECTED])$/ ? $1 : 
> >> undef );
> > 
> > A better way to do that is to leave taint active, and instead do this:
> > 
> >      if ($username =~ /^([-:,[EMAIL PROTECTED])$/) {
> >        # note, separate variable for untainted value
> >        $untainted_user = $1;        
> >        # ...use that
> >      }
> > 
> > it's a minor difference, but it allows taint to stay on inside the rest
> > of that scope.
> 
> not sure if your concern is the "no re 'taint'" or overwriting 
> $username, but I agree that both isn't exactly elegant. Therefore I'm 
> now enabling "re 'taint'" after using the untainted $1.
> Also variables were split up as suggested, although I inverted the 
> naming for $vpopusername + $vpopusername_tainted. IMO that's ok, as the 
> scope of both is limited to handle_user_vpopmail().
> 
> > regarding the use of the timeout:
> > 
> >> +  $vptimer->run(sub {
> >> +    my $vpopusername = $username;
> >> +    local $SIG{ALRM} = sub { die "failed to resolve vpopmail user/alias 
> >> '$username' in time ($vpoptimeout seconds)" };
> >> +    do {
> >> +      $vpopusername = `$vpopdir/bin/valias \Q$vpopusername\E`;
> >> +      if ($vpopusername =~ /.+ -> &?(.+)/) {
> >> +        $vpopusername = $1;
> > 
> > it's important that $SIG{ALRM} not be modified inside the timeout scope --
> > since the Timeout class uses it.  Instead I recommend calling that die()
> > after the run() call, in the timed_out() action.
> 
> And I also removed the alarm 0; I forgot...
> 
> Thanks for commenting,
> 
> Cheers, Daniel
> part 2     text/x-patch              2782
> Index: spamd/spamd.raw
> ===================================================================
> --- spamd/spamd.raw     (revision 673160)
> +++ spamd/spamd.raw     (working copy)
> @@ -2084,6 +2084,18 @@
> 
>      if ($prefsfrom eq $suidto) {
>        $userdir = $suiddir;      # reuse the already-looked-up info
> +    } elsif ( $opt{'vpopmail'} ) {
> +      #
> +      # If vpopmail config enabled then set $userdir to virtual homedir
> +      #
> +      no re 'taint';
> +      my $username_untainted = ( $username =~ /^([-:,[EMAIL PROTECTED])$/ ? 
> $1 : undef );
> +      use re 'taint';
> +      my $vpopdir = $suiddir; # This should work with common vpopmail setups
> +      $userdir = `$vpopdir/bin/vuserinfo -d \Q$username_untainted\E`;
> +      if ($? != 0) {
> +        $userdir = handle_user_vpopmail($username_untainted,$vpopdir);
> +      }
>      } else {
>        $userdir = (getpwnam($prefsfrom))[7];
>      }
> @@ -2105,28 +2117,44 @@
>    handle_user_set_user_prefs($userdir, $username);
>  }
> 
> -sub handle_user_set_user_prefs {
> -  my ($dir, $username) = @_;
> +sub handle_user_vpopmail {
> +  #
> +  # If vuserinfo failed $username could be an alias
> +  # As the alias could be an alias itself we'll try to resolve it recursively
> +  # Because we're mistrusting vpopmail we'll set off an alarm
> +  #
> +  my $username = shift;
> +  my $vpopdir = shift;
> +  my $userdir;
> +  my $vpoptimeout = 5;
> +  my $vptimer = Mail::SpamAssassin::Timeout->new({ secs => $vpoptimeout });
> 
> -  # If vpopmail config enabled then set $dir to virtual homedir
> -  #
> -  if ( $opt{'vpopmail'} ) {
> -    my $vpopdir = $dir;
> -    $dir = `$vpopdir/bin/vuserinfo -d \Q$username\E`;
> -    if ($? != 0) {
> -      #
> -      # If vuserinfo failed $username could be an alias
> -      #
> -      $dir = `$vpopdir/bin/valias \Q$username\E`;
> -      if ($? == 0 && $dir !~ /.+ -> &/) {
> -        $dir =~ s,.+ -> (/.+)/Maildir/,$1,;
> +  $vptimer->run(sub {
> +    my $vpopusername = $username;
> +    do {
> +      my $vpopusername_tainted = `$vpopdir/bin/valias \Q$vpopusername\E`;
> +      no re 'taint';
> +      if ($vpopusername_tainted =~ /.+ -> &?(.+)/) {
> +        $vpopusername = $1;
>        } else {
> -        undef($dir);
> +        die "failed to resolve vpopmail user/alias '$username' using 
> vuserinfo/valias";
>        }
> -    }
> -    chomp($dir);
> +    } until (($userdir = `$vpopdir/bin/vuserinfo -d \Q$vpopusername\E`) && 
> $? == 0);
> +    $userdir =~ s,.+ -> (/.+)/Maildir/,$1,;
> +  });
> +
> +  if ($vptimer->timed_out()) {
> +    undef $userdir;
> +    die "failed to resolve vpopmail user/alias '$username' in time 
> ($vpoptimeout seconds)";
> +  } else {
> +    chomp($userdir);
>    }
> +  return $userdir;
> +}
> 
> +sub handle_user_set_user_prefs {
> +  my ($dir, $username) = @_;
> +
>    # don't do this if we weren't passed a directory
>    if ($dir) {
>      my $cf_file = $dir . "/.spamassassin/user_prefs";

Reply via email to