Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

pull please! #1

Closed
wants to merge 3 commits into from

4 participants

Robert Alex Vandiver Best Practical Solutions bremner
Robert

These are three changes I've applied from patches that were submitted by others. They look sane to me.

bremner and others added some commits
bremner bremner Add support for gpg agent.
This is is controlled by a flag use_agent to the new() method.

This has been mainly tested with the decrypt operation.
582df2c
bremner bremner Add test for gpg-agent handling.
The only real fragile bit is that gpg-preset-passphrase is installed
in different places on different OSes, and often not in the user path.
For the moment, hard-code a FHS compliant path, and allow the location
to be set by an environment variable.

This is just a copy of the "roundtrip.t" test that already exists,
with agent handling attached to the front. It could probably be made
shorter since some of the tests here do not rely on passphrases.

Also, it might be desirable to re-order the tests.
5887789
Andrew Ruthven Add always-trust support to Mail::GnuPG.
Tue Dec 06 04:09:31 2011: Request 73036 was acted upon.
Transaction: Ticket created by PUCK
       Queue: Mail-GnuPG
     Subject: Add always-trust support to Mail::GnuPG.
   Broken in: 0.16
    Severity: Wishlist
       Owner: Nobody
  Requestors: PUCK@cpan.org
      Status: new
 Ticket <URL: https://rt.cpan.org/Ticket/Display.html?id=73036 >

Hi,

I need to be able to send out some encrypted emails using peoples GPG
public keys that have been provided in a manual method.  And I don't
want to have to setup specific key for automatically creating trust
signatures which might leak out into the wild.

Fortunately gpg has a solution to this called always-trust.  And
GnuPG::Interface exposes this.

The attached patch makes Mail::GnuPG expose it as well.  It would be
very handy to have this rolled into Mail::GnuPG.

Cheers!
fe51acc
Alex Vandiver
Owner

I see from https://rt.cpan.org/Public/Bug/Display.html?id=73036 that we're not actually upstream anymore. I've pulled from DDB and pushed into our repo, to make it less out of date, at very least.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Showing 3 unique commits by 3 authors.

Sep 27, 2010
bremner bremner Add support for gpg agent.
This is is controlled by a flag use_agent to the new() method.

This has been mainly tested with the decrypt operation.
582df2c
bremner bremner Add test for gpg-agent handling.
The only real fragile bit is that gpg-preset-passphrase is installed
in different places on different OSes, and often not in the user path.
For the moment, hard-code a FHS compliant path, and allow the location
to be set by an environment variable.

This is just a copy of the "roundtrip.t" test that already exists,
with agent handling attached to the front. It could probably be made
shorter since some of the tests here do not rely on passphrases.

Also, it might be desirable to re-order the tests.
5887789
Dec 08, 2011
Andrew Ruthven Add always-trust support to Mail::GnuPG.
Tue Dec 06 04:09:31 2011: Request 73036 was acted upon.
Transaction: Ticket created by PUCK
       Queue: Mail-GnuPG
     Subject: Add always-trust support to Mail::GnuPG.
   Broken in: 0.16
    Severity: Wishlist
       Owner: Nobody
  Requestors: PUCK@cpan.org
      Status: new
 Ticket <URL: https://rt.cpan.org/Ticket/Display.html?id=73036 >

Hi,

I need to be able to send out some encrypted emails using peoples GPG
public keys that have been provided in a manual method.  And I don't
want to have to setup specific key for automatically creating trust
signatures which might leak out into the wild.

Fortunately gpg has a solution to this called always-trust.  And
GnuPG::Interface exposes this.

The attached patch makes Mail::GnuPG expose it as well.  It would be
very handy to have this rolled into Mail::GnuPG.

Cheers!
fe51acc
This page is out of date. Refresh to see the latest.

Showing 2 changed files with 138 additions and 6 deletions. Show diff stats Hide diff stats

  1. +17 6 GnuPG.pm
  2. +121 0 t/agent.t
23 GnuPG.pm
@@ -44,7 +44,8 @@ use Errno qw(EPIPE);
44 44 key => gpg key id
45 45 keydir => gpg configuration/key directory
46 46 passphrase => primary key password
47   -
  47 + use_agent => use gpg-agent if non-zero
  48 + always_trust => always trust a public key
48 49 # FIXME: we need more things here, maybe primary key id.
49 50
50 51
@@ -58,6 +59,7 @@ sub new {
58 59 keydir => undef,
59 60 passphrase => "",
60 61 gpg_path => "gpg",
  62 + use_agent => 0,
61 63 @_
62 64 };
63 65 $self->{last_message} = [];
@@ -77,6 +79,10 @@ sub _set_options {
77 79 # ( defined $self->{passphrase} ?
78 80 # ( passphrase => $self->{passphrase} ) : () ),
79 81 );
  82 +
  83 + if (defined $self->{always_trust}) {
  84 + $gnupg->options->always_trust($self->{always_trust})
  85 + }
80 86 $gnupg->call( $self->{gpg_path} ) if defined $self->{gpg_path};
81 87 }
82 88
@@ -114,6 +120,11 @@ sub _set_options {
114 120
115 121 =cut
116 122
  123 +sub _agent_args{
  124 + my $self=shift;
  125 + return $self->{use_agent} ? ('command_args' => ['--use-agent']) : ();
  126 +}
  127 +
117 128 sub decrypt {
118 129 my ($self, $message) = @_;
119 130 my $ciphertext = "";
@@ -161,7 +172,7 @@ sub decrypt {
161 172 );
162 173
163 174 # this sets up the communication
164   - my $pid = $gnupg->decrypt( handles => $handles );
  175 + my $pid = $gnupg->decrypt( handles => $handles , $self->_agent_args );
165 176
166 177 die "NO PASSPHRASE" unless defined $passphrase_fh;
167 178 my $read = _communicate([$output, $error, $status_fh],
@@ -542,7 +553,7 @@ sub mime_sign {
542 553 passphrase => $passphrase_fh,
543 554 status => $status_fh,
544 555 );
545   - my $pid = $gnupg->detach_sign( handles => $handles );
  556 + my $pid = $gnupg->detach_sign( handles => $handles, $self->_agent_args );
546 557 die "NO PASSPHRASE" unless defined $passphrase_fh;
547 558
548 559 # this passes in the plaintext
@@ -641,7 +652,7 @@ sub clear_sign {
641 652 stderr => $error,
642 653 );
643 654
644   - my $pid = $gnupg->clearsign ( handles => $handles );
  655 + my $pid = $gnupg->clearsign ( handles => $handles, $self->_agent_args );
645 656
646 657 my $plaintext = $body->as_string;
647 658
@@ -744,7 +755,7 @@ sub _ascii_encrypt {
744 755
745 756 my $pid = do {
746 757 if ( $sign ) {
747   - $gnupg->sign_and_encrypt ( handles => $handles );
  758 + $gnupg->sign_and_encrypt ( handles => $handles, $self->_agent_args );
748 759 } else {
749 760 $gnupg->encrypt ( handles => $handles );
750 761 }
@@ -844,7 +855,7 @@ sub _mime_encrypt {
844 855
845 856 my $pid = do {
846 857 if ($sign) {
847   - $gnupg->sign_and_encrypt( handles => $handles );
  858 + $gnupg->sign_and_encrypt( handles => $handles, $self->_agent_args );
848 859 } else {
849 860 $gnupg->encrypt( handles => $handles );
850 861 }
121 t/agent.t
... ... @@ -0,0 +1,121 @@
  1 +# -*- perl -*-
  2 +
  3 +use Test::More;
  4 +use File::Temp qw(tempdir);
  5 +use Mail::GnuPG;
  6 +use MIME::Entity;
  7 +use strict;
  8 +no warnings 'redefine'; # fix this later
  9 +
  10 +my $KEY = "EFEA4EAD"; # 49539D60EFEA4EAD
  11 +my $WHO = "Mail::GnuPG Test Key <mail\@gnupg.dom>";
  12 +
  13 +unless ( 0 == system("gpg --version 2>&1 >/dev/null") &&
  14 + 0 == system("gpg-agent --version 2>&1 >/dev/null")) {
  15 + plan skip_all => "gpg, gpg-agent in path required for testing agent";
  16 + goto end;
  17 +}
  18 +
  19 +my $preset=$ENV{GPG_PRESET_PASSPHRASE} || "/usr/lib/gnupg2/gpg-preset-passphrase";
  20 +
  21 +unless (0 == system("$preset --version 2>&1 >/dev/null")) {
  22 + plan skip_all => "gpg-preset-passphrase not found; set GPG_PRESET_PASSPHRASE in environment to location of binary";
  23 + goto end;
  24 +}
  25 +
  26 +my $tmpdir = tempdir( "mgtXXXXX", CLEANUP => 1);
  27 +
  28 +unless ( 0 == system("gpg --homedir $tmpdir --trusted-key 0x49539D60EFEA4EAD --import t/test-key.pgp 2>&1 >/dev/null")) {
  29 + plan skip_all => "unable to import testing keys";
  30 + goto end;
  31 +}
  32 +
  33 +unless (open AGENT, "gpg-agent --disable-scdaemon --allow-preset --daemon|") {
  34 + plan skip_all =>"unable to start gpg-agent";
  35 + goto end;
  36 +}
  37 +
  38 +my ($agent_pid,$agent_info);
  39 +while (<AGENT>){
  40 + if (m/GPG_AGENT_INFO=([^;]*);/){
  41 + $agent_info=$1;
  42 + $ENV{'GPG_AGENT_INFO'}=$agent_info;
  43 + my @parts=split(':',$agent_info);
  44 + $agent_pid=$parts[1];
  45 + }
  46 +}
  47 +
  48 +# gpg-preset-passphrase uses the fingerprint of the subkey, rather than the id.
  49 +unless ( 0 == system ("$preset --preset -P passphrase " .
  50 + "576AE2D0BC6974C083705EE033A736779FE08E94")
  51 + && 0 == system ("$preset --preset -P passphrase " .
  52 + "8E136E6F34C0D4CD941A9DB749539D60EFEA4EAD") ){
  53 + plan skip_all =>"unable to cache passphrase";
  54 + goto end;
  55 +}
  56 +
  57 +plan tests => 20;
  58 +
  59 +
  60 +my $mg = new Mail::GnuPG( key => '49539D60EFEA4EAD',
  61 + keydir => $tmpdir,
  62 + use_agent => 1);
  63 +
  64 +isa_ok($mg,"Mail::GnuPG");
  65 +
  66 +my $line = "x\n";
  67 +my $string = $line x 100000;
  68 +
  69 +my $copy;
  70 +my $me = MIME::Entity->build(From => 'me@myhost.com',
  71 + To => 'you@yourhost.com',
  72 + Subject => "Hello, nurse!",
  73 + Data => [$string]);
  74 +# Test MIME Signing Round Trip
  75 +
  76 +$copy = $me->dup;
  77 +
  78 +is( 0, $mg->mime_sign( $copy ) );
  79 +
  80 +my ($verify,$key,$who) = $mg->verify($copy);
  81 +is( 0, $verify );
  82 +is( $KEY, $key );
  83 +is( $WHO, $who );
  84 +
  85 +is( 1, $mg->is_signed($copy) );
  86 +is( 0, $mg->is_encrypted($copy) );
  87 +
  88 +# Test Clear Signing Round Trip
  89 +
  90 +$copy = $me->dup;
  91 +
  92 +is( 0, $mg->clear_sign( $copy ) );
  93 +
  94 +{ my ($verify,$key,$who) = $mg->verify($copy);
  95 +is( 0, $verify );
  96 +is( $KEY, $key );
  97 +is( $WHO, $who );
  98 +
  99 +is( 1, $mg->is_signed($copy) );
  100 +is( 0, $mg->is_encrypted($copy) );
  101 +}
  102 +# Test MIME Encryption Round Trip
  103 +
  104 +$copy = $me->dup;
  105 +
  106 +is( 0, $mg->ascii_encrypt( $copy, $KEY ));
  107 +is( 0, $mg->is_signed($copy) );
  108 +is( 1, $mg->is_encrypted($copy) );
  109 +
  110 +($verify,$key,$who) = $mg->decrypt($copy);
  111 +
  112 +is( 0, $verify );
  113 +is( undef, $key );
  114 +is( undef, $who );
  115 +
  116 +is_deeply($mg->{decrypted}->body,$me->body);
  117 +
  118 +end:
  119 +kill 15,$agent_pid if (defined($agent_pid));
  120 +
  121 +

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.