$NetBSD: patch-ab,v 1.4 2011/10/25 19:38:10 spz Exp $ - add sanity checks for the pgp program call - make the pgp program path configurable instead of assuming it in the (smallish) path - perl 5.14 qw() in for* fixes --- lib/RT/Crypt/GnuPG.pm.orig 2011-04-14 00:32:21.000000000 +0000 +++ lib/RT/Crypt/GnuPG.pm @@ -434,6 +434,7 @@ sub SignEncryptRFC3156 { ); my $gnupg = new GnuPG::Interface; + $gnupg->call(RT->Config->Get('GnuPG')->{'Call'}) if RT->Config->Get('GnuPG')->{'Call'}; my %opt = RT->Config->Get('GnuPGOptions'); # handling passphrase in GnuPGOptions @@ -484,12 +485,12 @@ sub SignEncryptRFC3156 { waitpid $pid, 0; }; my $err = $@; - my @signature = readline $handle{'stdout'}; + my @signature = readline $handle{'stdout'} if $handle{'stdout'}->opened ; close $handle{'stdout'}; $res{'exit_code'} = $?; foreach ( qw(stderr logger status) ) { - $res{$_} = do { local $/; readline $handle{$_} }; + $res{$_} = do { local $/; readline $handle{$_} if $handle{$_}->opened }; delete $res{$_} unless $res{$_} && $res{$_} =~ /\S/s; close $handle{$_}; } @@ -545,7 +546,7 @@ sub SignEncryptRFC3156 { $res{'exit_code'} = $?; foreach ( qw(stderr logger status) ) { - $res{$_} = do { local $/; readline $handle{$_} }; + $res{$_} = do { local $/; readline $handle{$_} if $handle{$_}->opened }; delete $res{$_} unless $res{$_} && $res{$_} =~ /\S/s; close $handle{$_}; } @@ -616,6 +617,7 @@ sub _SignEncryptTextInline { return unless $args{'Sign'} || $args{'Encrypt'}; my $gnupg = new GnuPG::Interface; + $gnupg->call(RT->Config->Get('GnuPG')->{'Call'}) if RT->Config->Get('GnuPG')->{'Call'}; my %opt = RT->Config->Get('GnuPGOptions'); # handling passphrase in GnupGOptions @@ -670,7 +672,7 @@ sub _SignEncryptTextInline { my $err = $@; foreach ( qw(stderr logger status) ) { - $res{$_} = do { local $/; readline $handle{$_} }; + $res{$_} = do { local $/; readline $handle{$_} if $handle{$_}->opened }; delete $res{$_} unless $res{$_} && $res{$_} =~ /\S/s; close $handle{$_}; } @@ -704,6 +706,7 @@ sub _SignEncryptAttachmentInline { return unless $args{'Sign'} || $args{'Encrypt'}; my $gnupg = new GnuPG::Interface; + $gnupg->call(RT->Config->Get('GnuPG')->{'Call'}) if RT->Config->Get('GnuPG')->{'Call'}; my %opt = RT->Config->Get('GnuPGOptions'); # handling passphrase in GnupGOptions @@ -757,7 +760,7 @@ sub _SignEncryptAttachmentInline { my $err = $@; foreach ( qw(stderr logger status) ) { - $res{$_} = do { local $/; readline $handle{$_} }; + $res{$_} = do { local $/; readline $handle{$_} if $handle{$_}->opened }; delete $res{$_} unless $res{$_} && $res{$_} =~ /\S/s; close $handle{$_}; } @@ -806,6 +809,7 @@ sub SignEncryptContent { return unless $args{'Sign'} || $args{'Encrypt'}; my $gnupg = new GnuPG::Interface; + $gnupg->call(RT->Config->Get('GnuPG')->{'Call'}) if RT->Config->Get('GnuPG')->{'Call'}; my %opt = RT->Config->Get('GnuPGOptions'); # handling passphrase in GnupGOptions @@ -858,7 +862,7 @@ sub SignEncryptContent { my $err = $@; foreach ( qw(stderr logger status) ) { - $res{$_} = do { local $/; readline $handle{$_} }; + $res{$_} = do { local $/; readline $handle{$_} if $handle{$_}->opened }; delete $res{$_} unless $res{$_} && $res{$_} =~ /\S/s; close $handle{$_}; } @@ -1093,6 +1097,7 @@ sub VerifyAttachment { my %args = ( Data => undef, Signature => undef, Top => undef, @_ ); my $gnupg = new GnuPG::Interface; + $gnupg->call(RT->Config->Get('GnuPG')->{'Call'}) if RT->Config->Get('GnuPG')->{'Call'}; my %opt = RT->Config->Get('GnuPGOptions'); $opt{'digest-algo'} ||= 'SHA1'; $gnupg->options->hash_init( @@ -1130,7 +1135,7 @@ sub VerifyAttachment { }; $res{'exit_code'} = $?; foreach ( qw(stderr logger status) ) { - $res{$_} = do { local $/; readline $handle{$_} }; + $res{$_} = do { local $/; readline $handle{$_} if $handle{$_}->opened }; delete $res{$_} unless $res{$_} && $res{$_} =~ /\S/s; close $handle{$_}; } @@ -1147,6 +1152,7 @@ sub VerifyRFC3156 { my %args = ( Data => undef, Signature => undef, Top => undef, @_ ); my $gnupg = new GnuPG::Interface; + $gnupg->call(RT->Config->Get('GnuPG')->{'Call'}) if RT->Config->Get('GnuPG')->{'Call'}; my %opt = RT->Config->Get('GnuPGOptions'); $opt{'digest-algo'} ||= 'SHA1'; $gnupg->options->hash_init( @@ -1177,7 +1183,7 @@ sub VerifyRFC3156 { }; $res{'exit_code'} = $?; foreach ( qw(stderr logger status) ) { - $res{$_} = do { local $/; readline $handle{$_} }; + $res{$_} = do { local $/; readline $handle{$_} if $handle{$_}->opened }; delete $res{$_} unless $res{$_} && $res{$_} =~ /\S/s; close $handle{$_}; } @@ -1200,6 +1206,7 @@ sub DecryptRFC3156 { ); my $gnupg = new GnuPG::Interface; + $gnupg->call(RT->Config->Get('GnuPG')->{'Call'}) if RT->Config->Get('GnuPG')->{'Call'}; my %opt = RT->Config->Get('GnuPGOptions'); # handling passphrase in GnupGOptions @@ -1242,7 +1249,7 @@ sub DecryptRFC3156 { }; $res{'exit_code'} = $?; foreach ( qw(stderr logger status) ) { - $res{$_} = do { local $/; readline $handle{$_} }; + $res{$_} = do { local $/; readline $handle{$_} if $handle{$_}->opened }; delete $res{$_} unless $res{$_} && $res{$_} =~ /\S/s; close $handle{$_}; } @@ -1253,6 +1260,11 @@ sub DecryptRFC3156 { # if the decryption is fine but the signature is bad, then without this # status check we lose the decrypted text # XXX: add argument to the function to control this check + if ( !defined $res{'status'} ) { + $res{'message'} = $@? $@: "gpg failed ". ($? >> 8); + seek $tmp_fh, 0, 0; + return ($tmp_fh, $tmp_fn, %res); + } if ( $res{'status'} !~ /DECRYPTION_OKAY/ ) { if ( $@ || $? ) { $res{'message'} = $@? $@: "gpg exitted with error code ". ($? >> 8); @@ -1278,6 +1290,7 @@ sub DecryptInline { ); my $gnupg = new GnuPG::Interface; + $gnupg->call(RT->Config->Get('GnuPG')->{'Call'}) if RT->Config->Get('GnuPG')->{'Call'}; my %opt = RT->Config->Get('GnuPGOptions'); # handling passphrase in GnuPGOptions @@ -1406,7 +1419,7 @@ sub _DecryptInlineBlock { }; $res{'exit_code'} = $?; foreach ( qw(stderr logger status) ) { - $res{$_} = do { local $/; readline $handle{$_} }; + $res{$_} = do { local $/; readline $handle{$_} if $handle{$_}->opened }; delete $res{$_} unless $res{$_} && $res{$_} =~ /\S/s; close $handle{$_}; } @@ -1417,6 +1430,11 @@ sub _DecryptInlineBlock { # if the decryption is fine but the signature is bad, then without this # status check we lose the decrypted text # XXX: add argument to the function to control this check + if ( !defined $res{'status'} ) { + $res{'message'} = $@? $@: "gpg failed ". ($? >> 8); + seek $tmp_fh, 0, 0; + return ($tmp_fh, $tmp_fn, %res); + } if ( $res{'status'} !~ /DECRYPTION_OKAY/ ) { if ( $@ || $? ) { $res{'message'} = $@? $@: "gpg exitted with error code ". ($? >> 8); @@ -1437,6 +1455,7 @@ sub DecryptAttachment { ); my $gnupg = new GnuPG::Interface; + $gnupg->call(RT->Config->Get('GnuPG')->{'Call'}) if RT->Config->Get('GnuPG')->{'Call'}; my %opt = RT->Config->Get('GnuPGOptions'); # handling passphrase in GnuPGOptions @@ -1488,6 +1507,7 @@ sub DecryptContent { ); my $gnupg = new GnuPG::Interface; + $gnupg->call(RT->Config->Get('GnuPG')->{'Call'}) if RT->Config->Get('GnuPG')->{'Call'}; my %opt = RT->Config->Get('GnuPGOptions'); # handling passphrase in GnupGOptions @@ -1526,7 +1546,7 @@ sub DecryptContent { }; $res{'exit_code'} = $?; foreach ( qw(stderr logger status) ) { - $res{$_} = do { local $/; readline $handle{$_} }; + $res{$_} = do { local $/; readline $handle{$_} if $handle{$_}->opened }; delete $res{$_} unless $res{$_} && $res{$_} =~ /\S/s; close $handle{$_}; } @@ -1537,6 +1557,11 @@ sub DecryptContent { # if the decryption is fine but the signature is bad, then without this # status check we lose the decrypted text # XXX: add argument to the function to control this check + if ( !defined $res{'status'} ) { + $res{'message'} = $@? $@: "gpg failed ". ($? >> 8); + seek $tmp_fh, 0, 0; + return ($tmp_fh, $tmp_fn, %res); + } if ( $res{'status'} !~ /DECRYPTION_OKAY/ ) { if ( $@ || $? ) { $res{'message'} = $@? $@: "gpg exitted with error code ". ($? >> 8); @@ -2077,6 +2102,7 @@ sub GetKeysInfo { } my $gnupg = new GnuPG::Interface; + $gnupg->call(RT->Config->Get('GnuPG')->{'Call'}) if RT->Config->Get('GnuPG')->{'Call'}; my %opt = RT->Config->Get('GnuPGOptions'); $opt{'digest-algo'} ||= 'SHA1'; $opt{'with-colons'} = undef; # parseable format @@ -2101,12 +2127,12 @@ sub GetKeysInfo { waitpid $pid, 0; }; - my @info = readline $handle{'stdout'}; + my @info = readline $handle{'stdout'} if $handle{'stdout'}->opened ; close $handle{'stdout'}; $res{'exit_code'} = $?; foreach ( qw(stderr logger status) ) { - $res{$_} = do { local $/; readline $handle{$_} }; + $res{$_} = do { local $/; readline $handle{$_} if $handle{$_}->opened }; delete $res{$_} unless $res{$_} && $res{$_} =~ /\S/s; close $handle{$_}; } @@ -2158,7 +2184,7 @@ sub ParseKeysInfo { @info{qw(OwnerTrust OwnerTrustTerse OwnerTrustLevel)} = _ConvertTrustChar( $info{'OwnerTrustChar'} ); $info{ $_ } = _ParseDate( $info{ $_ } ) - foreach qw(Created Expire); + foreach ( qw(Created Expire) ); push @res, \%info; } elsif ( $tag eq 'sec' ) { @@ -2171,7 +2197,7 @@ sub ParseKeysInfo { @info{qw(OwnerTrust OwnerTrustTerse OwnerTrustLevel)} = _ConvertTrustChar( $info{'OwnerTrustChar'} ); $info{ $_ } = _ParseDate( $info{ $_ } ) - foreach qw(Created Expire); + foreach ( qw(Created Expire) ); push @res, \%info; } elsif ( $tag eq 'uid' ) { @@ -2179,7 +2205,7 @@ sub ParseKeysInfo { @info{ qw(Trust Created Expire String) } = (split /:/, $line)[0,4,5,8]; $info{ $_ } = _ParseDate( $info{ $_ } ) - foreach qw(Created Expire); + foreach ( qw(Created Expire) ); push @{ $res[-1]{'User'} ||= [] }, \%info; } elsif ( $tag eq 'fpr' ) { @@ -2276,6 +2302,7 @@ sub DeleteKey { my $key = shift; my $gnupg = new GnuPG::Interface; + $gnupg->call(RT->Config->Get('GnuPG')->{'Call'}) if RT->Config->Get('GnuPG')->{'Call'}; my %opt = RT->Config->Get('GnuPGOptions'); $gnupg->options->hash_init( _PrepareGnuPGOptions( %opt ), @@ -2307,7 +2334,7 @@ sub DeleteKey { my %res; $res{'exit_code'} = $?; foreach ( qw(stderr logger status) ) { - $res{$_} = do { local $/; readline $handle{$_} }; + $res{$_} = do { local $/; readline $handle{$_} if $handle{$_}->opened }; delete $res{$_} unless $res{$_} && $res{$_} =~ /\S/s; close $handle{$_}; } @@ -2324,6 +2351,7 @@ sub ImportKey { my $key = shift; my $gnupg = new GnuPG::Interface; + $gnupg->call(RT->Config->Get('GnuPG')->{'Call'}) if RT->Config->Get('GnuPG')->{'Call'}; my %opt = RT->Config->Get('GnuPGOptions'); $gnupg->options->hash_init( _PrepareGnuPGOptions( %opt ), @@ -2350,7 +2378,7 @@ sub ImportKey { my %res; $res{'exit_code'} = $?; foreach ( qw(stderr logger status) ) { - $res{$_} = do { local $/; readline $handle{$_} }; + $res{$_} = do { local $/; readline $handle{$_} if $handle{$_}->opened }; delete $res{$_} unless $res{$_} && $res{$_} =~ /\S/s; close $handle{$_}; } @@ -2407,6 +2435,7 @@ properly (and false otherwise). sub Probe { my $gnupg = new GnuPG::Interface; + $gnupg->call(RT->Config->Get('GnuPG')->{'Call'}) if RT->Config->Get('GnuPG')->{'Call'}; my %opt = RT->Config->Get('GnuPGOptions'); $gnupg->options->hash_init( _PrepareGnuPGOptions( %opt ),