#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
use IO::Handle;
use GnuPG::Interface;
use RT::EmailParser ();
-use RT::Util 'safe_run_child';
+use RT::Util 'safe_run_child', 'mime_recommended_filename';
=head1 NAME
=item --homedir
-The GnuPG home directory, by default it is set to F</opt/rt3/var/data/gpg>.
+The GnuPG home directory, by default it is set to F</opt/rt4/var/data/gpg>.
You can manage this data with the 'gpg' commandline utility
using the GNUPGHOME environment variable or --homedir option.
verbose
);
+our $RE_FILE_EXTENSIONS = qr/pgp|asc/i;
+
# DEV WARNING: always pass all STD* handles to GnuPG interface even if we don't
-# need them, just pass 'new IO::Handle' and then close it after safe_run_child.
+# need them, just pass 'IO::Handle->new()' and then close it after safe_run_child.
# we don't want to leak anything into FCGI/Apache/MP handles, this break things.
# So code should look like:
# my $handles = GnuPG::Handles->new(
-# stdin => ($handle{'stdin'} = new IO::Handle),
-# stdout => ($handle{'stdout'} = new IO::Handle),
-# stderr => ($handle{'stderr'} = new IO::Handle),
+# stdin => ($handle{'stdin'} = IO::Handle->new()),
+# stdout => ($handle{'stdout'} = IO::Handle->new()),
+# stderr => ($handle{'stderr'} = IO::Handle->new()),
# ...
# );
@_
);
- my $gnupg = new GnuPG::Interface;
+ my $gnupg = GnuPG::Interface->new();
my %opt = RT->Config->Get('GnuPGOptions');
# handling passphrase in GnuPGOptions
);
return unless $args{'Sign'} || $args{'Encrypt'};
- my $gnupg = new GnuPG::Interface;
+ my $gnupg = GnuPG::Interface->new();
my %opt = RT->Config->Get('GnuPGOptions');
# handling passphrase in GnupGOptions
return %res;
}
- $entity->bodyhandle( new MIME::Body::File $tmp_fn );
+ $entity->bodyhandle( MIME::Body::File->new( $tmp_fn) );
$entity->{'__store_tmp_handle_to_avoid_early_cleanup'} = $tmp_fh;
return %res;
);
return unless $args{'Sign'} || $args{'Encrypt'};
- my $gnupg = new GnuPG::Interface;
+ my $gnupg = GnuPG::Interface->new();
my %opt = RT->Config->Get('GnuPGOptions');
# handling passphrase in GnupGOptions
return %res;
}
- my $filename = $entity->head->recommended_filename || 'no_name';
+ my $filename = mime_recommended_filename( $entity ) || 'no_name';
if ( $args{'Sign'} && !$args{'Encrypt'} ) {
$entity->make_multipart;
$entity->attach(
Disposition => 'attachment',
);
} else {
- $entity->bodyhandle( new MIME::Body::File $tmp_fn );
+ $entity->bodyhandle(MIME::Body::File->new( $tmp_fn) );
$entity->effective_type('application/octet-stream');
$entity->head->mime_attr( $_ => "$filename.pgp" )
foreach (qw(Content-Type.name Content-Disposition.filename));
);
return unless $args{'Sign'} || $args{'Encrypt'};
- my $gnupg = new GnuPG::Interface;
+ my $gnupg = GnuPG::Interface->new();
my %opt = RT->Config->Get('GnuPGOptions');
# handling passphrase in GnupGOptions
# inline PGP block, only in singlepart
unless ( $entity->is_multipart ) {
+ my $file = ($entity->head->recommended_filename||'') =~ /\.${RE_FILE_EXTENSIONS}$/;
+
my $io = $entity->open('r');
unless ( $io ) {
$RT::Logger->warning( "Entity of type ". $entity->effective_type ." has no body" );
$RT::Logger->debug("Found $type inline part");
return {
Type => $type,
- Format => 'Inline',
- Data => $entity,
+ Format => !$file || $type eq 'signed'? 'Inline' : 'Attachment',
+ Data => $entity,
};
}
$io->close;
# attachments with inline encryption
my @encrypted_indices =
- grep {($entity->parts($_)->head->recommended_filename || '') =~ /\.pgp$/}
+ grep {($entity->parts($_)->head->recommended_filename || '') =~ /\.${RE_FILE_EXTENSIONS}$/}
0 .. $entity->parts - 1;
foreach my $i ( @encrypted_indices ) {
sub VerifyAttachment {
my %args = ( Data => undef, Signature => undef, Top => undef, @_ );
- my $gnupg = new GnuPG::Interface;
+ my $gnupg = GnuPG::Interface->new();
my %opt = RT->Config->Get('GnuPGOptions');
$opt{'digest-algo'} ||= 'SHA1';
$gnupg->options->hash_init(
sub VerifyRFC3156 {
my %args = ( Data => undef, Signature => undef, Top => undef, @_ );
- my $gnupg = new GnuPG::Interface;
+ my $gnupg = GnuPG::Interface->new();
my %opt = RT->Config->Get('GnuPGOptions');
$opt{'digest-algo'} ||= 'SHA1';
$gnupg->options->hash_init(
@_
);
- my $gnupg = new GnuPG::Interface;
+ my $gnupg = GnuPG::Interface->new();
my %opt = RT->Config->Get('GnuPGOptions');
# handling passphrase in GnupGOptions
}
seek $tmp_fh, 0, 0;
- my $parser = new RT::EmailParser;
+ my $parser = RT::EmailParser->new();
my $decrypted = $parser->ParseMIMEEntityFromFileHandle( $tmp_fh, 0 );
$decrypted->{'__store_link_to_object_to_avoid_early_cleanup'} = $parser;
$args{'Top'}->parts( [] );
@_
);
- my $gnupg = new GnuPG::Interface;
+ my $gnupg = GnuPG::Interface->new();
my %opt = RT->Config->Get('GnuPGOptions');
# handling passphrase in GnuPGOptions
}
seek $tmp_fh, 0, 0;
- $args{'Data'}->bodyhandle( new MIME::Body::File $tmp_fn );
+ $args{'Data'}->bodyhandle(MIME::Body::File->new( $tmp_fn ));
$args{'Data'}->{'__store_tmp_handle_to_avoid_early_cleanup'} = $tmp_fh;
return %res;
}
@_
);
- my $gnupg = new GnuPG::Interface;
+ my $gnupg = GnuPG::Interface->new();
my %opt = RT->Config->Get('GnuPGOptions');
# handling passphrase in GnuPGOptions
);
return %res unless $res_fh;
- $args{'Data'}->bodyhandle( new MIME::Body::File $res_fn );
+ $args{'Data'}->bodyhandle(MIME::Body::File->new($res_fn) );
$args{'Data'}->{'__store_tmp_handle_to_avoid_early_cleanup'} = $res_fh;
- my $filename = $args{'Data'}->head->recommended_filename;
- $filename =~ s/\.pgp$//i;
- $args{'Data'}->head->mime_attr( $_ => $filename )
+ my $head = $args{'Data'}->head;
+
+ # we can not trust original content type
+ # TODO: and don't have way to detect, so we just use octet-stream
+ # some clients may send .asc files (encryped) as text/plain
+ $head->mime_attr( "Content-Type" => 'application/octet-stream' );
+
+ my $filename = $head->recommended_filename;
+ $filename =~ s/\.${RE_FILE_EXTENSIONS}$//i;
+ $head->mime_attr( $_ => $filename )
foreach (qw(Content-Type.name Content-Disposition.filename));
return %res;
@_
);
- my $gnupg = new GnuPG::Interface;
+ my $gnupg = GnuPG::Interface->new();
my %opt = RT->Config->Get('GnuPGOptions');
# handling passphrase in GnupGOptions
=back
-This parser is based on information from GnuPG distribution, see also
-F<docs/design_docs/gnupg_details_on_output_formats> in the RT distribution.
+This parser is based on information from GnuPG distribution.
=cut
# good, one suitable and trusted key
next;
}
- my $user = RT::User->new( $RT::SystemUser );
+ my $user = RT::User->new( RT->SystemUser );
$user->LoadByEmail( $address );
# it's possible that we have no User record with the email
$user = undef unless $user->id;
return (exit_code => 0) unless $force;
}
- my $gnupg = new GnuPG::Interface;
+ my $gnupg = GnuPG::Interface->new();
my %opt = RT->Config->Get('GnuPGOptions');
$opt{'digest-algo'} ||= 'SHA1';
$opt{'with-colons'} = undef; # parseable format
return $value unless $value;
require RT::Date;
- my $obj = RT::Date->new( $RT::SystemUser );
+ my $obj = RT::Date->new( RT->SystemUser );
# unix time
if ( $value =~ /^\d+$/ ) {
$obj->Set( Value => $value );
sub DeleteKey {
my $key = shift;
- my $gnupg = new GnuPG::Interface;
+ my $gnupg = GnuPG::Interface->new();
my %opt = RT->Config->Get('GnuPGOptions');
$gnupg->options->hash_init(
_PrepareGnuPGOptions( %opt ),
eval {
local $SIG{'CHLD'} = 'DEFAULT';
- local @ENV{'LANG', 'LC_ALL'} = ('C', 'C');
my $pid = safe_run_child { $gnupg->wrap_call(
handles => $handles,
commands => ['--delete-secret-and-public-key'],
sub ImportKey {
my $key = shift;
- my $gnupg = new GnuPG::Interface;
+ my $gnupg = GnuPG::Interface->new();
my %opt = RT->Config->Get('GnuPGOptions');
$gnupg->options->hash_init(
_PrepareGnuPGOptions( %opt ),
eval {
local $SIG{'CHLD'} = 'DEFAULT';
- local @ENV{'LANG', 'LC_ALL'} = ('C', 'C');
my $pid = safe_run_child { $gnupg->wrap_call(
handles => $handles,
commands => ['--import'],
sub Probe {
- my $gnupg = new GnuPG::Interface;
+ my $gnupg = GnuPG::Interface->new();
my %opt = RT->Config->Get('GnuPGOptions');
$gnupg->options->hash_init(
_PrepareGnuPGOptions( %opt ),