Commit 1b5e0d0c authored by Jesse Vincent's avatar Jesse Vincent
Browse files

Better handling of apparently bogus email; rationalize mail gateway error codes

parent cd75ec35
......@@ -455,7 +455,7 @@ if ( $content !~ /^(ok|not ok)/ ) {
# It's not the server's fault if the mail is bogus. We just want to know that
# *something* came out of the server.
die <<EOF
warn <<EOF;
RT server error.
The RT server which handled your email did not behave as expected. It
......@@ -464,8 +464,13 @@ said:
$content
EOF
exit EX_TEMPFAIL;
}
exit;
sub check_failure {
my $r = shift;
return if $r->is_success();
......@@ -496,6 +501,7 @@ Usual invocation (from MTA):
rt-mailgate --action (correspond|comment) --queue queuename
--url http://your.rt.server/
[ --debug ]
[ --extension (queue|action|ticket)
See C<man rt-mailgate> for more.
......@@ -527,6 +533,10 @@ submitted to will be set to the value of $EXTENSION. By specifying
is related to. "action" will allow the user to specify either "comment" or
"correspond" in the address extension.
=item C<--debug> OPTIONAL
Print debugging output to standard error
=head1 DESCRIPTION
......
......@@ -34,7 +34,10 @@ my ( $status, $error, $Ticket ) = RT::Interface::Email::Gateway(\%ARGS);
<%flags>
inherit => undef # inhibit UTF8 conversion done in /autohandler
</%flags>
% if ($status) {
% if ($status == -75 ) {
temporary failure
% }
% elsif ($status == 1) {
ok
% if ( $Ticket->Id ) {
Ticket: <% $Ticket->Id %>
......
......@@ -153,6 +153,7 @@ sub MailError {
Subject => 'There has been an error',
Explanation => 'Unexplained error',
MIMEObj => undef,
Attach => undef,
LogLevel => 'crit',
@_);
......@@ -175,7 +176,13 @@ sub MailError {
$mimeobj->sync_headers();
$entity->add_part($mimeobj);
}
if ($args{'Attach'}) {
$entity->attach(Data => $args{'Attach'}, Type => 'message/rfc822');
}
if ($RT::MailCommand eq 'sendmailpipe') {
open (MAIL, "|$RT::SendmailPath $RT::SendmailArguments") || return(0);
print MAIL $entity->as_string;
......@@ -363,10 +370,34 @@ sub ParseAddressFromHeader{
=head2 Gateway ARGSREF
Takes parameters:
action
queue
message
This performs all the "guts" of the mail rt-mailgate program, and is
designed to be called from the web interface with a message, user
object, and so on.
Returns:
An array of:
(status code, message, optional ticket object)
status code is a numeric value.
for temporary failures, status code should be -75
for permanent failures which are handled by RT, status code should be 0
for succces, the status code should be 1
=cut
sub Gateway {
......@@ -382,7 +413,9 @@ sub Gateway {
unless ( $args{'action'} =~ /^(comment|correspond|action)$/ ) {
# Can't safely loc this. What object do we loc around?
return ( 0, "Invalid 'action' parameter", undef );
$RT::Logger->crit("Mail gateway called with an invalid action paramenter '".$args{'action'}."' for queue '".$args{'queue'}."'");
return ( -75, "Invalid 'action' parameter", undef );
}
my $parser = RT::EmailParser->new();
......@@ -395,19 +428,39 @@ sub Gateway {
last if ( $fh, $temp_file ) = eval { File::Temp::tempfile(undef, UNLINK => 0) };
sleep 1;
}
unless ($fh) {
return (0, "Unable to create a temporary file to store the message in. Temporary failure");
if ($fh) {
binmode $fh; #thank you, windows
$fh->autoflush(1);
print $fh $args{'message'};
close($fh);
if ( -f $temp_file ) {
$parser->ParseMIMEEntityFromFile($temp_file);
File::Temp::unlink0( $fh, $temp_file );
if ($parser->Entity) {
delete $args{'message'};
}
}
}
binmode $fh; #thank you, windows
$fh->autoflush(1);
print $fh $args{'message'};
close($fh);
#If for some reason we weren't able to parse the message using a temp file
# try it with a scalar
if ($args{'message'}) {
$parser->ParseMIMEEntityFromScalar($args{'message'});
}
if (!$parser->Entity()) {
MailError(
To => $RT::OwnerEmail,
Subject => "RT Bounce: Unparseable message",
Explanation => "RT couldn't process the message below",
Attach => $args{'message'}
);
delete $args{'message'};
$parser->ParseMIMEEntityFromFile($temp_file);
File::Temp::unlink0( $fh, $temp_file )
|| return ( 0, "Failed to unlink a temporary file for the message" );
return(0,"Failed to parse this message. Something is likely badly wrong with the message");
}
my $Message = $parser->Entity();
my $head = $Message->head;
......@@ -440,13 +493,7 @@ sub Gateway {
# We can safely have no queue of we have a known-good ticket
unless ( $args{'ticket'} || $SystemQueueObj->id ) {
MailError(
To => $RT::OwnerEmail,
Subject => "RT Bounce: $Subject",
Explanation => "RT couldn't find the queue: " . $args{'queue'},
MIMEObj => $Message
);
return ( 0, "RT couldn't find the queue: " . $args{'queue'}, undef );
return ( -75, "RT couldn't find the queue: " . $args{'queue'}, undef );
}
# Authentication Level
......@@ -699,7 +746,7 @@ EOT
);
$RT::Logger->crit( $args{'action'} . " type unknown for $MessageId" );
return (
0,
-75,
"Configuration error: "
. $args{'action'}
. " not a recognized action",
......
......@@ -319,24 +319,30 @@ sub Parse {
my $parser = MIME::Parser->new();
# Setup output directory for files. from RT::EmailParser::_SetupMIMEParser
if (my $AttachmentDir = eval { File::Temp::tempdir( TMPDIR => 1, CLEANUP => 1 ) }) {
# Set up output directory for files:
$parser->output_dir("$AttachmentDir");
if ( my $AttachmentDir =
eval { File::Temp::tempdir( TMPDIR => 1, CLEANUP => 1 ) } )
{
# Set up output directory for files:
$parser->output_dir("$AttachmentDir");
}
else {
# On some situations TMPDIR is non-writable. sad but true.
$parser->output_to_core(1);
$parser->tmp_to_core(1);
$RT::Logger->error("Couldn't write attachments to temp dir on disk. using more memory and processor.");
# On some situations TMPDIR is non-writable. sad but true.
$parser->output_to_core(1);
$parser->tmp_to_core(1);
}
#If someone includes a message, don't extract it
$parser->extract_nested_messages(1);
# Set up the prefix for files with auto-generated names:
$parser->output_prefix("part");
# If content length is <= 50000 bytes, store each msg as in-core scalar;
# Else, write to a disk file (the default action):
$parser->output_to_core(50000);
### Should we forgive normally-fatal errors?
$parser->ignore_errors(1);
$self->{'MIMEObj'} = eval { $parser->parse_data($content) };
......@@ -351,7 +357,6 @@ sub Parse {
$self->{'MIMEObj'}->head->unfold();
return ( 1, $self->loc("Template parsed") );
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment