diff options
Diffstat (limited to 'rt/t/mail/smime')
-rw-r--r-- | rt/t/mail/smime/incoming.t | 202 | ||||
-rw-r--r-- | rt/t/mail/smime/other-signed.t | 135 | ||||
-rw-r--r-- | rt/t/mail/smime/outgoing.t | 80 | ||||
-rw-r--r-- | rt/t/mail/smime/realmail.t | 125 | ||||
-rw-r--r-- | rt/t/mail/smime/reject_on_unencrypted.t | 137 |
5 files changed, 679 insertions, 0 deletions
diff --git a/rt/t/mail/smime/incoming.t b/rt/t/mail/smime/incoming.t new file mode 100644 index 0000000..918844a --- /dev/null +++ b/rt/t/mail/smime/incoming.t @@ -0,0 +1,202 @@ +use strict; +use warnings; + +use RT::Test::SMIME tests => undef, actual_server => 1; +my $test = 'RT::Test::SMIME'; + +use IPC::Run3 'run3'; +use String::ShellQuote 'shell_quote'; +use RT::Tickets; +use Test::Warn; + +my ($url, $m) = RT::Test->started_ok; +ok $m->login, "logged in"; + +# configure key for General queue +RT::Test::SMIME->import_key('sender@example.com'); +my $queue = RT::Test->load_or_create_queue( + Name => 'General', + CorrespondAddress => 'sender@example.com', + CommentAddress => 'sender@example.com', +); +ok $queue && $queue->id, 'loaded or created queue'; + +my $user = RT::Test->load_or_create_user( + Name => 'root@example.com', + EmailAddress => 'root@example.com', +); +RT::Test::SMIME->import_key('root@example.com.crt', $user); +RT::Test->add_rights( Principal => $user, Right => 'SuperUser', Object => RT->System ); + +my $mail = RT::Test->open_mailgate_ok($url); +print $mail <<EOF; +From: root\@localhost +To: rt\@$RT::rtname +Subject: This is a test of new ticket creation as root + +Blah! +Foob! +EOF +RT::Test->close_mailgate_ok($mail); + +{ + my $tick = RT::Test->last_ticket; + is( $tick->Subject, + 'This is a test of new ticket creation as root', + "Created the ticket" + ); + my $txn = $tick->Transactions->First; + like( + $txn->Attachments->First->Headers, + qr/^X-RT-Incoming-Encryption: Not encrypted/m, + 'recorded incoming mail that is not encrypted' + ); + like( $txn->Attachments->First->Content, qr'Blah'); +} + +{ + # test for encrypted mail + my $buf = ''; + run3( + shell_quote( + qw(openssl smime -encrypt -des3), + -from => 'root@example.com', + -to => 'sender@example.com', + -subject => "Encrypted message for queue", + $test->key_path('sender@example.com.crt'), + ), + \"Subject: test\n\norzzzzzz", + \$buf, + \*STDERR + ); + + my ($status, $tid) = RT::Test->send_via_mailgate( $buf ); + is ($status >> 8, 0, "The mail gateway exited normally"); + + my $tick = RT::Ticket->new( $RT::SystemUser ); + $tick->Load( $tid ); + is( $tick->Subject, 'Encrypted message for queue', + "Created the ticket" + ); + + my $txn = $tick->Transactions->First; + my ($msg, $attach, $orig) = @{$txn->Attachments->ItemsArrayRef}; + is( $msg->GetHeader('X-RT-Incoming-Encryption'), + 'Success', + 'recorded incoming mail that is encrypted' + ); + is( $msg->GetHeader('X-RT-Privacy'), + 'SMIME', + 'recorded incoming mail that is encrypted' + ); + like( $attach->Content, qr'orz'); + + is( $orig->GetHeader('Content-Type'), 'application/x-rt-original-message'); +} + +{ + my $buf = ''; + + run3( + join( + ' ', + shell_quote( + RT->Config->Get('SMIME')->{'OpenSSL'}, + qw( smime -sign -nodetach -passin pass:123456), + -signer => $test->key_path('root@example.com.crt'), + -inkey => $test->key_path('root@example.com.key'), + ), + '|', + shell_quote( + qw(openssl smime -encrypt -des3), + -from => 'root@example.com', + -to => 'sender@example.com', + -subject => "Encrypted and signed message for queue", + $test->key_path('sender@example.com.crt'), + )), + \"Subject: test\n\norzzzzzz", + \$buf, + \*STDERR + ); + + my ($status, $tid) = RT::Test->send_via_mailgate( $buf ); + + my $tick = RT::Ticket->new( $RT::SystemUser ); + $tick->Load( $tid ); + ok( $tick->Id, "found ticket " . $tick->Id ); + is( $tick->Subject, 'Encrypted and signed message for queue', + "Created the ticket" + ); + + my $txn = $tick->Transactions->First; + my ($msg, $attach, $orig) = @{$txn->Attachments->ItemsArrayRef}; + is( $msg->GetHeader('X-RT-Incoming-Encryption'), + 'Success', + 'recorded incoming mail that is encrypted' + ); + like( $attach->Content, qr'orzzzz'); +} + +{ + my $buf = ''; + + run3( + shell_quote( + RT->Config->Get('SMIME')->{'OpenSSL'}, + qw( smime -sign -passin pass:123456), + -signer => $test->key_path('root@example.com.crt'), + -inkey => $test->key_path('root@example.com.key'), + ), + \"Content-type: text/plain\n\nThis is the body", + \$buf, + \*STDERR + ); + $buf = "Subject: Signed email\n" + . "From: root\@example.com\n" + . $buf; + + { + my ($status, $tid) = RT::Test->send_via_mailgate( $buf ); + + my $tick = RT::Ticket->new( $RT::SystemUser ); + $tick->Load( $tid ); + ok( $tick->Id, "found ticket " . $tick->Id ); + is( $tick->Subject, 'Signed email', + "Created the ticket" + ); + + my $txn = $tick->Transactions->First; + my ($msg, $attach, $orig) = @{$txn->Attachments->ItemsArrayRef}; + is( $msg->GetHeader('X-RT-Incoming-Signature'), + '"Enoch Root" <root@example.com>', + "Message was signed" + ); + like( $attach->Content, qr/This is the body/ ); + } + + # Make the signature not match + $buf =~ s/This is the body/This is not the body/; + + warning_like { + my ($status, $tid) = RT::Test->send_via_mailgate( $buf ); + + my $tick = RT::Ticket->new( $RT::SystemUser ); + $tick->Load( $tid ); + ok( $tick->Id, "found ticket " . $tick->Id ); + is( $tick->Subject, 'Signed email', + "Created the ticket" + ); + + my $txn = $tick->Transactions->First; + my ($msg, $attach, $orig) = @{$txn->Attachments->ItemsArrayRef}; + isnt( $msg->GetHeader('X-RT-Incoming-Signature'), + '"Enoch Root" <root@example.com>', + "Message was not marked signed" + ); + like( $attach->Content, qr/This is not the body/ ); + } qr/Failure during SMIME verify: The signature did not verify/; + +} + +undef $m; +done_testing; diff --git a/rt/t/mail/smime/other-signed.t b/rt/t/mail/smime/other-signed.t new file mode 100644 index 0000000..4e97e71 --- /dev/null +++ b/rt/t/mail/smime/other-signed.t @@ -0,0 +1,135 @@ +use strict; +use warnings; + +use RT::Test::SMIME tests => undef; +my $test = 'RT::Test::SMIME'; + +use IPC::Run3 'run3'; +use String::ShellQuote 'shell_quote'; +use RT::Tickets; +use Test::Warn; + +# configure key for General queue +RT::Test::SMIME->import_key('sender@example.com'); +my $queue = RT::Test->load_or_create_queue( + Name => 'General', + CorrespondAddress => 'sender@example.com', + CommentAddress => 'sender@example.com', +); +ok $queue && $queue->id, 'loaded or created queue'; + +my $user = RT::Test->load_or_create_user( + Name => 'root@example.com', + EmailAddress => 'root@example.com', +); +RT::Test::SMIME->import_key('root@example.com.crt', $user); +RT::Test->add_rights( Principal => $user, Right => 'SuperUser', Object => RT->System ); + +my $buf = ''; + +run3( + shell_quote( + RT->Config->Get('SMIME')->{'OpenSSL'}, + qw( smime -sign -passin pass:123456), + -signer => $test->key_path('root@example.com.crt'), + -inkey => $test->key_path('root@example.com.key'), + ), + \"Content-type: text/plain\n\nThis is the body", + \$buf, + \*STDERR +); +$buf = "Subject: Signed email\n" + . "From: root\@example.com\n" + . $buf; + +my $send_mail = sub { + my %args = ( CAPath => undef, AcceptUntrustedCAs => undef, @_ ); + + RT->Config->Get('SMIME')->{$_} = $args{$_} for keys %args; + + my ($status, $tid) = RT::Test->send_via_mailgate( $buf ); + + my $tick = RT::Ticket->new( $RT::SystemUser ); + $tick->Load( $tid ); + ok( $tick->Id, "found ticket " . $tick->Id ); + is( $tick->Subject, 'Signed email', + "Created the ticket" + ); + + my $txn = $tick->Transactions->First; + my ($msg, $attach, $orig) = @{$txn->Attachments->ItemsArrayRef}; + + ($status) = RT::Crypt->ParseStatus( + Protocol => 'SMIME', + Status => $msg->GetHeader('X-RT-SMIME-Status') + ); + + return ($msg, $status); +}; + +# Test with no CA path; should not be marked as signed +warning_like { + my ($msg, $status) = $send_mail->( CAPath => undef ); + is( $msg->GetHeader('X-RT-Incoming-Signature'), + undef, + "Message was not marked as signed" + ); + + is($status->{Operation}, "Verify", "Found the Verify operation"); + is($status->{Status}, "BAD", "Verify was a failure"); + is($status->{Trust}, "NONE", "Noted the no trust level"); + like($status->{Message}, qr/not trusted/, "Verify was a failure"); +} qr/Failure during SMIME verify: The signing CA was not trusted/; + +# Test with the correct CA path; marked as signed, trusted +{ + my ($msg, $status) = $send_mail->( CAPath => $test->key_path . "/demoCA/cacert.pem" ); + is( $msg->GetHeader('X-RT-Incoming-Signature'), + '"Enoch Root" <root@example.com>', "Message is signed" ); + + is($status->{Operation}, "Verify", "Found the Verify operation"); + is($status->{Status}, "DONE", "Verify was a success"); + is($status->{Trust}, "FULL", "Noted the full trust level"); +} + +# Test with the other CA +warning_like { + my ($msg, $status) = $send_mail->( CAPath => $test->key_path . "/otherCA/cacert.pem" ); + is( $msg->GetHeader('X-RT-Incoming-Signature'), + undef, + "Message was not marked as signed" + ); + + is($status->{Operation}, "Verify", "Found the Verify operation"); + is($status->{Status}, "BAD", "Verify was a failure"); + is($status->{Trust}, "NONE", "Noted the no trust level"); + like($status->{Message}, qr/not trusted/, "Verify was a failure"); +} qr/Failure during SMIME verify: The signing CA was not trusted/; + +# Other CA, but allow all CAs +{ + my ($msg, $status) = $send_mail->( CAPath => $test->key_path . "/otherCA/cacert.pem", AcceptUntrustedCAs => 1 ); + is( $msg->GetHeader('X-RT-Incoming-Signature'), + '"Enoch Root" <root@example.com>', + "Message was marked as signed" + ); + + is($status->{Operation}, "Verify", "Found the Verify operation"); + is($status->{Status}, "DONE", "Verify was a success"); + is($status->{Trust}, "NONE", "Noted the no trust level"); +} + +# No CA path, but allow all CAs +{ + my ($msg, $status) = $send_mail->( CAPath => undef, AcceptUntrustedCAs => 1 ); + is( $msg->GetHeader('X-RT-Incoming-Signature'), + '"Enoch Root" <root@example.com>', + "Message was marked as signed" + ); + + is($status->{Operation}, "Verify", "Found the Verify operation"); + is($status->{Status}, "DONE", "Verify was a success"); + is($status->{Trust}, "UNKNOWN", "Noted the no trust level"); +} + +done_testing; diff --git a/rt/t/mail/smime/outgoing.t b/rt/t/mail/smime/outgoing.t new file mode 100644 index 0000000..6f6b00d --- /dev/null +++ b/rt/t/mail/smime/outgoing.t @@ -0,0 +1,80 @@ +use strict; +use warnings; + +use RT::Test::SMIME tests => undef; +my $test = 'RT::Test::SMIME'; + +use IPC::Run3 'run3'; +use RT::Interface::Email; + +my ($url, $m) = RT::Test->started_ok; +ok $m->login, "logged in"; + +my $queue = RT::Test->load_or_create_queue( + Name => 'General', + CorrespondAddress => 'sender@example.com', + CommentAddress => 'sender@example.com', +); +ok $queue && $queue->id, 'loaded or created queue'; + +{ + my ($status, $msg) = $queue->SetEncrypt(1); + ok $status, "turn on encyption by default" + or diag "error: $msg"; +} + +my $user; +{ + $user = RT::User->new($RT::SystemUser); + ok($user->LoadByEmail('root@localhost'), "Loaded user 'root'"); + ok($user->Load('root'), "Loaded user 'root'"); + is($user->EmailAddress, 'root@localhost'); + + RT::Test::SMIME->import_key( 'root@example.com.crt' => $user ); +} + +RT::Test->clean_caught_mails; + +{ + my $mail = <<END; +From: root\@localhost +To: rt\@example.com +Subject: This is a test of new ticket creation as an unknown user + +Blah! +Foob! + +END + + my ($status, $id) = RT::Test->send_via_mailgate( + $mail, queue => $queue->Name, + ); + is $status >> 8, 0, "successfuly executed mailgate"; + + my $ticket = RT::Ticket->new($RT::SystemUser); + $ticket->Load( $id ); + ok ($ticket->id, "found ticket ". $ticket->id); +} + +{ + my @mails = RT::Test->fetch_caught_mails; + is scalar @mails, 1, "autoreply"; + + my ($buf, $err); + local $@; + ok(eval { + run3([ + qw(openssl smime -decrypt -passin pass:123456), + '-inkey', $test->key_path('root@example.com.key'), + '-recip', $test->key_path('root@example.com.crt') + ], \$mails[0], \$buf, \$err ) + }, 'can decrypt' + ); + diag $@ if $@; + diag $err if $err; + diag "Error code: $?" if $?; + like($buf, qr'This message has been automatically generated in response'); +} + +undef $m; +done_testing; diff --git a/rt/t/mail/smime/realmail.t b/rt/t/mail/smime/realmail.t new file mode 100644 index 0000000..be157aa --- /dev/null +++ b/rt/t/mail/smime/realmail.t @@ -0,0 +1,125 @@ +use strict; +use warnings; + +use RT::Test::SMIME tests => undef; +use Digest::MD5 qw(md5_hex); + +my $test = 'RT::Test::SMIME'; +my $mails = $test->mail_set_path; + +RT->Config->Get('SMIME')->{AcceptUntrustedCAs} = 1; + +RT::Test::SMIME->import_key('root@example.com'); +RT::Test::SMIME->import_key('sender@example.com'); + +my ($baseurl, $m) = RT::Test->started_ok; +ok $m->login, 'we did log in'; +$m->get_ok( '/Admin/Queues/'); +$m->follow_link_ok( {text => 'General'} ); +$m->submit_form( form_number => 3, + fields => { CorrespondAddress => 'root@example.com' } ); + +diag "load Everyone group" if $ENV{'TEST_VERBOSE'}; +my $everyone; +{ + $everyone = RT::Group->new( $RT::SystemUser ); + $everyone->LoadSystemInternalGroup('Everyone'); + ok $everyone->id, "loaded 'everyone' group"; +} + +RT::Test->set_rights( + Principal => $everyone, + Right => ['CreateTicket'], +); + + +my $eid = 0; +for my $usage (qw/signed encrypted signed&encrypted/) { + for my $attachment (qw/plain text-attachment binary-attachment/) { + ++$eid; + diag "Email $eid: $usage, $attachment email" if $ENV{TEST_VERBOSE}; + eval { email_ok($eid, $usage, $attachment) }; + } +} + +undef $m; +done_testing; + +sub email_ok { + my ($eid, $usage, $attachment) = @_; + diag "email_ok $eid: $usage, $attachment" if $ENV{'TEST_VERBOSE'}; + + my ($file) = glob("$mails/$eid-*"); + my $mail = RT::Test->file_content($file); + + my ($status, $id) = RT::Test->send_via_mailgate($mail); + is ($status >> 8, 0, "$eid: The mail gateway exited normally"); + ok ($id, "$eid: got id of a newly created ticket - $id"); + + my $tick = RT::Ticket->new( $RT::SystemUser ); + $tick->Load( $id ); + ok ($tick->id, "$eid: loaded ticket #$id"); + + is ($tick->Subject, + "Test Email ID:$eid", + "$eid: Created the ticket" + ); + + my $txn = $tick->Transactions->First; + my ($msg, @attachments) = @{$txn->Attachments->ItemsArrayRef}; + + is( $msg->GetHeader('X-RT-Privacy'), + 'SMIME', + "$eid: recorded incoming mail that is secured" + ); + + if ($usage =~ /encrypted/) { + is( $msg->GetHeader('X-RT-Incoming-Encryption'), + 'Success', + "$eid: recorded incoming mail that is encrypted" + ); + like( $attachments[0]->Content, qr/ID:$eid/, + "$eid: incoming mail did NOT have original body" + ); + } + else { + is( $msg->GetHeader('X-RT-Incoming-Encryption'), + 'Not encrypted', + "$eid: recorded incoming mail that is not encrypted" + ); + like( $msg->Content || $attachments[0]->Content, qr/ID:$eid/, + "$eid: got original content" + ); + } + + if ($usage =~ /signed/) { + is( $msg->GetHeader('X-RT-Incoming-Signature'), + '"sender" <sender@example.com>', + "$eid: recorded incoming mail that is signed" + ); + } + else { + is( $msg->GetHeader('X-RT-Incoming-Signature'), + undef, + "$eid: recorded incoming mail that is not signed" + ); + } + + if ($attachment =~ /attachment/) { + my ($a) = grep $_->Filename, @attachments; + ok ($a && $a->Id, "$eid: found attachment with filename"); + + my $acontent = $a->Content; + if ($attachment =~ /binary/) + { + is(md5_hex($acontent), '1e35f1aa90c98ca2bab85c26ae3e1ba7', "$eid: The binary attachment's md5sum matches"); + } + else + { + like($acontent, qr/zanzibar/, "$eid: The attachment isn't screwed up in the database."); + } + } + + return 0; +} + diff --git a/rt/t/mail/smime/reject_on_unencrypted.t b/rt/t/mail/smime/reject_on_unencrypted.t new file mode 100644 index 0000000..ab62d83 --- /dev/null +++ b/rt/t/mail/smime/reject_on_unencrypted.t @@ -0,0 +1,137 @@ +use strict; +use warnings; + +use RT::Test::SMIME tests => undef, actual_server => 1, config => 'Set( %Crypt, RejectOnUnencrypted => 1 );'; +my $test = 'RT::Test::SMIME'; + +use IPC::Run3 'run3'; +use String::ShellQuote 'shell_quote'; +use RT::Tickets; + +my ($url, $m) = RT::Test->started_ok; +ok $m->login, "logged in"; + +# configure key for General queue +RT::Test::SMIME->import_key('sender@example.com'); +my $queue = RT::Test->load_or_create_queue( + Name => 'General', + CorrespondAddress => 'sender@example.com', + CommentAddress => 'sender@example.com', +); +ok $queue && $queue->id, 'loaded or created queue'; + +my $user = RT::Test->load_or_create_user( + Name => 'root@example.com', + EmailAddress => 'root@example.com', +); +RT::Test::SMIME->import_key('root@example.com.crt', $user); +RT::Test->add_rights( Principal => $user, Right => 'SuperUser', Object => RT->System ); + +my $mail = RT::Test->open_mailgate_ok($url); +print $mail <<EOF; +From: root\@localhost +To: rt\@$RT::rtname +Subject: This is a test of new ticket creation as root + +Blah! +Foob! +EOF +RT::Test->close_mailgate_ok($mail); + +{ + ok(!RT::Test->last_ticket, 'A ticket was not created'); + my ($mail) = RT::Test->fetch_caught_mails; + like( + $mail, + qr/^Subject: RT requires that all incoming mail be encrypted/m, + 'rejected mail that is not encrypted' + ); + my ($warning) = $m->get_warnings; + like($warning, qr/rejected because the message is unencrypted/); +} + +{ + # test for encrypted mail + my $buf = ''; + run3( + shell_quote( + qw(openssl smime -encrypt -des3), + -from => 'root@example.com', + -to => 'sender@example.com', + -subject => "Encrypted message for queue", + $test->key_path('sender@example.com.crt' ), + ), + \"Subject: test\n\norzzzzzz", + \$buf, + \*STDERR + ); + + my ($status, $tid) = RT::Test->send_via_mailgate( $buf ); + is ($status >> 8, 0, "The mail gateway exited normally"); + + my $tick = RT::Ticket->new( $RT::SystemUser ); + $tick->Load( $tid ); + is( $tick->Subject, 'Encrypted message for queue', + "Created the ticket" + ); + + my $txn = $tick->Transactions->First; + my ($msg, $attach, $orig) = @{$txn->Attachments->ItemsArrayRef}; + is( $msg->GetHeader('X-RT-Incoming-Encryption'), + 'Success', + 'recorded incoming mail that is encrypted' + ); + is( $msg->GetHeader('X-RT-Privacy'), + 'SMIME', + 'recorded incoming mail that is encrypted' + ); + like( $attach->Content, qr'orz'); + + is( $orig->GetHeader('Content-Type'), 'application/x-rt-original-message'); +} + +{ + my $buf = ''; + + run3( + join( + ' ', + shell_quote( + RT->Config->Get('SMIME')->{'OpenSSL'}, + qw( smime -sign -nodetach -passin pass:123456), + -signer => $test->key_path('root@example.com.crt' ), + -inkey => $test->key_path('root@example.com.key' ), + ), + '|', + shell_quote( + qw(openssl smime -encrypt -des3), + -from => 'root@example.com', + -to => 'sender@example.com', + -subject => "Encrypted and signed message for queue", + $test->key_path('sender@example.com.crt' ), + )), + \"Subject: test\n\norzzzzzz", + \$buf, + \*STDERR + ); + + my ($status, $tid) = RT::Test->send_via_mailgate( $buf ); + + my $tick = RT::Ticket->new( $RT::SystemUser ); + $tick->Load( $tid ); + ok( $tick->Id, "found ticket " . $tick->Id ); + is( $tick->Subject, 'Encrypted and signed message for queue', + "Created the ticket" + ); + + my $txn = $tick->Transactions->First; + my ($msg, $attach, $orig) = @{$txn->Attachments->ItemsArrayRef}; + is( $msg->GetHeader('X-RT-Incoming-Encryption'), + 'Success', + 'recorded incoming mail that is encrypted' + ); + like( $attach->Content, qr'orzzzz'); +} + +undef $m; +done_testing; |