init III
This commit is contained in:
206
Perl OTRS/Kernel/cpan-lib/Sisimai/Rhost/ExchangeOnline.pm
Normal file
206
Perl OTRS/Kernel/cpan-lib/Sisimai/Rhost/ExchangeOnline.pm
Normal file
@@ -0,0 +1,206 @@
|
||||
package Sisimai::Rhost::ExchangeOnline;
|
||||
use feature ':5.10';
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
# https://technet.microsoft.com/en-us/library/bb232118
|
||||
my $StatusList = {
|
||||
'4.3.1' => [{ 'reason' => 'systemfull', 'string' => 'Insufficient system resources' }],
|
||||
'4.3.2' => [{ 'reason' => 'notaccept', 'string' => 'System not accepting network messages' }],
|
||||
'4.4.2' => [{ 'reason' => 'blocked', 'string' => 'Connection dropped' }],
|
||||
'4.7.26' => [{
|
||||
'reason' => 'securityerror',
|
||||
'string' => 'must pass either SPF or DKIM validation, this message is not signed'
|
||||
}],
|
||||
'5.0.0' => [{ 'reason' => 'blocked', 'string' => 'HELO / EHLO requires domain address' }],
|
||||
'5.1.4' => [{ 'reason' => 'systemerror', 'string' => 'Destination mailbox address ambiguous' }],
|
||||
'5.2.1' => [{ 'reason' => 'suspend', 'string' => 'Mailbox cannot be accessed' }],
|
||||
'5.2.2' => [{ 'reason' => 'mailboxfull', 'string' => 'Mailbox full' }],
|
||||
'5.2.3' => [{ 'reason' => 'exceedlimit', 'string' => 'Message too large' }],
|
||||
'5.2.4' => [{ 'reason' => 'systemerror', 'string' => 'Mailing list expansion problem' }],
|
||||
'5.3.3' => [{ 'reason' => 'systemfull', 'string' => 'Unrecognized command' }],
|
||||
'5.3.4' => [{ 'reason' => 'mesgtoobig', 'string' => 'Message too big for system' }],
|
||||
'5.3.5' => [{ 'reason' => 'systemerror', 'string' => 'System incorrectly configured' }],
|
||||
'5.4.1' => [{ 'reason' => 'userunknown', 'string' => 'Recipient address rejected: Access denied' }],
|
||||
'5.4.14' => [{ 'reason' => 'networkerror','string' => 'Hop count exceeded' }],
|
||||
'5.5.2' => [{ 'reason' => 'syntaxerror', 'string' => 'Send hello first' }],
|
||||
'5.5.3' => [{ 'reason' => 'syntaxerror', 'string' => 'Too many recipients' }],
|
||||
'5.5.4' => [{ 'reason' => 'filtered', 'string' => 'Invalid domain name' }],
|
||||
'5.5.6' => [{ 'reason' => 'contenterror','string' => 'Invalid message content' }],
|
||||
'5.7.1' => [
|
||||
{ 'reason' => 'securityerror', 'string' => 'Delivery not authorized' },
|
||||
{ 'reason' => 'securityerror', 'string' => 'Client was not authenticated' },
|
||||
{ 'reason' => 'norelaying', 'string' => 'Unable to relay' },
|
||||
],
|
||||
'5.7.25' => [{ 'reason' => 'blocked', 'string' => 'must have a reverse DNS record' }],
|
||||
'5.7.506' => [{ 'reason' => 'blocked', 'string' => 'Bad HELO' }],
|
||||
'5.7.508' => [{ 'reason' => 'toomanyconn', 'string' => 'has exceeded permitted limits within ' }],
|
||||
'5.7.509' => [{ 'reason' => 'rejected', 'string' => 'does not pass DMARC verification' }],
|
||||
'5.7.510' => [{ 'reason' => 'notaccept', 'string' => 'does not accept email over IPv6' }],
|
||||
'5.7.511' => [{ 'reason' => 'blocked', 'string' => 'banned sender' }],
|
||||
'5.7.512' => [{ 'reason' => 'contenterror', 'string' => 'message must be RFC 5322' }],
|
||||
};
|
||||
my $ReStatuses = {
|
||||
qr/\A4[.]4[.][17]\z/ => [
|
||||
{ 'reason' => 'expired', 'string' => ['Connection timed out', 'Message expired'] }
|
||||
],
|
||||
qr/\A4[.]7[.][568]\d\d\z/ => [
|
||||
{ 'reason' => 'securityerror', 'string' => ['Access denied, please try again later'] }
|
||||
],
|
||||
qr/\A5[.]1[.][07]\z/ => [
|
||||
{ 'reason' => 'rejected', 'string' => ['Sender denied', 'Invalid address'] }
|
||||
],
|
||||
qr/\A5[.]1[.][123]\z/ => [{
|
||||
'reason' => 'userunknown',
|
||||
'string' => [
|
||||
'Bad destination mailbox address',
|
||||
'Invalid X.400 address',
|
||||
'Invalid recipient address',
|
||||
]
|
||||
}],
|
||||
qr/\A5[.]4[.][46]\z/ => [{
|
||||
'reason' => 'networkerror',
|
||||
'string' => ['Invalid arguments', 'Routing loop detected'],
|
||||
}],
|
||||
qr/\A5[.]7[.][13]\z/ => [{
|
||||
'reason' => 'securityerror',
|
||||
'string' => ['Delivery not authorized', 'Not Authorized'],
|
||||
}],
|
||||
qr/\A5[.]7[.]50[1-3]\z/ => [{
|
||||
'reason' => 'spamdetected',
|
||||
'string' => [
|
||||
'Access denied, spam abuse detected',
|
||||
'Access denied, banned sender'
|
||||
],
|
||||
}],
|
||||
qr/\A5[.]7[.]50[457]\z/ => [{
|
||||
'reason' => 'filtered',
|
||||
'string' => [
|
||||
'Recipient address rejected: Access denied',
|
||||
'Access denied, banned recipient',
|
||||
'Access denied, rejected by recipient'
|
||||
]
|
||||
}],
|
||||
qr/\A5[.]7[.]6\d\d\z/ => [
|
||||
{ 'reason' => 'blocked', 'string' => ['Access denied, banned sending IP '] }
|
||||
],
|
||||
qr/\A5[.]7[.]7\d\d\z/ => [
|
||||
{ 'reason' => 'toomanyconn', 'string' => ['Access denied, tenant has exceeded threshold'] }
|
||||
],
|
||||
};
|
||||
my $MessagesOf = {
|
||||
# Copied and converted from Sisimai::Bite::Email::Exchange2007
|
||||
'expired' => ['QUEUE.Expired'],
|
||||
'hostunknown' => ['SMTPSEND.DNS.NonExistentDomain'],
|
||||
'mesgtoobig' => ['RESOLVER.RST.RecipSizeLimit', 'RESOLVER.RST.RecipientSizeLimit'],
|
||||
'networkerror' => ['SMTPSEND.DNS.MxLoopback'],
|
||||
'rejected' => ['RESOLVER.RST.NotAuthorized'],
|
||||
'securityerror' => ['RESOLVER.RST.AuthRequired'],
|
||||
'systemerror' => ['RESOLVER.ADR.Ambiguous', 'RESOLVER.ADR.BadPrimary', 'RESOLVER.ADR.InvalidInSmtp'],
|
||||
'toomanyconn' => ['RESOLVER.ADR.RecipLimit', 'RESOLVER.ADR.RecipientLimit'],
|
||||
'userunknown' => [
|
||||
'RESOLVER.ADR.RecipNotFound',
|
||||
'RESOLVER.ADR.RecipientNotFound',
|
||||
'RESOLVER.ADR.ExRecipNotFound',
|
||||
'RESOLVER.ADR.ExRecipientNotFound',
|
||||
],
|
||||
};
|
||||
|
||||
sub get {
|
||||
# Detect bounce reason from Exchange 2013 and Office 365
|
||||
# @param [Sisimai::Data] argvs Parsed email object
|
||||
# @return [String] The bounce reason for Exchange Online
|
||||
# @see https://technet.microsoft.com/en-us/library/bb232118
|
||||
my $class = shift;
|
||||
my $argvs = shift // return undef;
|
||||
return $argvs->reason if $argvs->reason;
|
||||
|
||||
my $statuscode = $argvs->deliverystatus;
|
||||
my $statusmesg = $argvs->diagnosticcode;
|
||||
my $reasontext = '';
|
||||
|
||||
for my $e ( keys %$StatusList ) {
|
||||
# Try to compare with each status code as a key
|
||||
next unless $statuscode eq $e;
|
||||
for my $f ( @{ $StatusList->{ $e } } ) {
|
||||
# Try to compare with each string of error messages
|
||||
next if index($statusmesg, $f->{'string'}) == -1;
|
||||
$reasontext = $f->{'reason'};
|
||||
last;
|
||||
}
|
||||
last if $reasontext;
|
||||
}
|
||||
|
||||
if( not $reasontext ) {
|
||||
for my $e ( keys %$ReStatuses ) {
|
||||
# Try to compare with each string of delivery status codes
|
||||
next unless $statuscode =~ $e;
|
||||
for my $f ( @{ $ReStatuses->{ $e } } ) {
|
||||
# Try to compare with each string of error messages
|
||||
for my $g ( @{ $f->{'string'} } ) {
|
||||
next if index($statusmesg, $g) == -1;
|
||||
$reasontext = $f->{'reason'};
|
||||
last;
|
||||
}
|
||||
last if $reasontext;
|
||||
}
|
||||
last if $reasontext;
|
||||
}
|
||||
|
||||
if( not $reasontext ) {
|
||||
# D.S.N. included in the error message did not matched with any key
|
||||
# in $StatusList, $ReStatuses
|
||||
for my $e ( keys %$MessagesOf ) {
|
||||
# Try to compare with error messages defined in MessagesOf
|
||||
for my $f ( @{ $MessagesOf->{ $e } } ) {
|
||||
next if index($statusmesg, $f) == -1;
|
||||
$reasontext = $e;
|
||||
last;
|
||||
}
|
||||
last if $reasontext;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $reasontext;
|
||||
}
|
||||
|
||||
1;
|
||||
__END__
|
||||
|
||||
=encoding utf-8
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Sisimai::Rhost::ExchangeOnline - Detect the bounce reason returned from on-premises
|
||||
Exchange 2013 and Office 365.
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use Sisimai::Rhost;
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
Sisimai::Rhost detects the bounce reason from the content of Sisimai::Data
|
||||
object as an argument of get() method when the value of C<rhost> of the object
|
||||
is "*.protection.outlook.com". This class is called only Sisimai::Data class.
|
||||
|
||||
=head1 CLASS METHODS
|
||||
|
||||
=head2 C<B<get(I<Sisimai::Data Object>)>>
|
||||
|
||||
C<get()> detects the bounce reason.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
azumakuniyuki
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright (C) 2016-2018 azumakuniyuki, All rights reserved.
|
||||
|
||||
=head1 LICENSE
|
||||
|
||||
This software is distributed under The BSD 2-Clause License.
|
||||
|
||||
=cut
|
||||
|
||||
90
Perl OTRS/Kernel/cpan-lib/Sisimai/Rhost/FrancePTT.pm
Normal file
90
Perl OTRS/Kernel/cpan-lib/Sisimai/Rhost/FrancePTT.pm
Normal file
@@ -0,0 +1,90 @@
|
||||
package Sisimai::Rhost::FrancePTT;
|
||||
use feature ':5.10';
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
my $ErrorCodes = {
|
||||
'103' => 'blocked', # Service refuse. Veuillez essayer plus tard.
|
||||
'104' => 'toomanyconn', # Too many connections, slow down. LPN105_104
|
||||
'105' => undef, # Veuillez essayer plus tard.
|
||||
'109' => undef, # Veuillez essayer plus tard. LPN003_109
|
||||
'201' => undef, # Veuillez essayer plus tard. OFR004_201
|
||||
'305' => 'securityerror', # 550 5.7.0 Code d'authentification invalide OFR_305
|
||||
'401' => 'blocked', # 550 5.5.0 SPF: *** is not allowed to send mail. LPN004_401
|
||||
'402' => 'securityerror', # 550 5.5.0 Authentification requise. Authentication Required. LPN105_402
|
||||
'403' => 'rejected', # 5.0.1 Emetteur invalide. Invalid Sender.
|
||||
'405' => 'rejected', # 5.0.1 Emetteur invalide. Invalid Sender. LPN105_405
|
||||
'415' => 'rejected', # Emetteur invalide. Invalid Sender. OFR_415
|
||||
'416' => 'userunknown', # 550 5.1.1 Adresse d au moins un destinataire invalide. Invalid recipient. LPN416
|
||||
'417' => 'mailboxfull', # 552 5.1.1 Boite du destinataire pleine. Recipient overquota.
|
||||
'418' => 'userunknown', # Adresse d au moins un destinataire invalide
|
||||
'420' => 'suspend', # Boite du destinataire archivee. Archived recipient.
|
||||
'421' => 'rejected', # 5.5.3 Mail from not owned by user. LPN105_421.
|
||||
'423' => undef, # Service refused, please try later. LPN105_423
|
||||
'424' => undef, # Veuillez essayer plus tard. LPN105_424
|
||||
'506' => 'spamdetected', # Mail rejete. Mail rejected. OFR_506 [506]
|
||||
'510' => 'blocked', # Veuillez essayer plus tard. service refused, please try later. LPN004_510
|
||||
'513' => undef, # Mail rejete. Mail rejected. OUK_513
|
||||
'514' => 'mesgtoobig', # Taille limite du message atteinte
|
||||
};
|
||||
|
||||
sub get {
|
||||
# Detect bounce reason from Orange and La Poste
|
||||
# @param [Sisimai::Data] argvs Parsed email object
|
||||
# @return [String] The bounce reason for Orange, La Poste
|
||||
my $class = shift;
|
||||
my $argvs = shift // return undef;
|
||||
return $argvs->reason if $argvs->reason;
|
||||
|
||||
my $statusmesg = $argvs->diagnosticcode;
|
||||
my $reasontext = '';
|
||||
|
||||
if( $statusmesg =~ /\b(LPN|OFR|OUK)(_[0-9]{3}|[0-9]{3}[-_][0-9]{3})\b/ ) {
|
||||
# OUK_513, LPN105-104, OFR102-104
|
||||
my $v = sprintf("%03d", substr($1.$2, -3, 3));
|
||||
$reasontext = $ErrorCodes->{ $v } || 'undefined';
|
||||
}
|
||||
return $reasontext;
|
||||
}
|
||||
|
||||
1;
|
||||
__END__
|
||||
|
||||
=encoding utf-8
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Sisimai::Rhost::FrancePTT - Detect the bounce reason returned from Orange and
|
||||
La Poste.
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use Sisimai::Rhost;
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
Sisimai::Rhost detects the bounce reason from the content of Sisimai::Data
|
||||
object as an argument of get() method when the value of C<rhost> of the object
|
||||
end with "laposte.net" or "orange.fr".
|
||||
This class is called only Sisimai::Data class.
|
||||
|
||||
=head1 CLASS METHODS
|
||||
|
||||
=head2 C<B<get(I<Sisimai::Data Object>)>>
|
||||
|
||||
C<get()> detects the bounce reason.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
azumakuniyuki
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright (C) 2017-2018 azumakuniyuki, All rights reserved.
|
||||
|
||||
=head1 LICENSE
|
||||
|
||||
This software is distributed under The BSD 2-Clause License.
|
||||
|
||||
=cut
|
||||
|
||||
106
Perl OTRS/Kernel/cpan-lib/Sisimai/Rhost/GoDaddy.pm
Normal file
106
Perl OTRS/Kernel/cpan-lib/Sisimai/Rhost/GoDaddy.pm
Normal file
@@ -0,0 +1,106 @@
|
||||
package Sisimai::Rhost::GoDaddy;
|
||||
use feature ':5.10';
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
# https://www.godaddy.com/help/what-does-my-email-bounceback-mean-3568
|
||||
my $ErrorCodes = {
|
||||
'IB103' => 'blocked', # 554 Connection refused. This IP has a poor reputation on Cloudmark Sender Intelligence (CSI). IB103
|
||||
'IB104' => 'blocked', # 554 Connection refused. This IP is listed on the Spamhaus Block List (SBL). IB104
|
||||
'IB105' => 'blocked', # 554 Connection refused. This IP is listed on the Exploits Block List (XBL). IB105
|
||||
'IB106' => 'blocked', # 554 Connection refused. This IP is listed on the Policy Block List (PBL). IB106
|
||||
'IB007' => 'toomanyconn', # 421 Connection refused, too many sessions from This IP. Please lower the number of concurrent sessions. IB007
|
||||
'IB101' => 'expired', # 421 Server temporarily unavailable. Try again later. IB101
|
||||
'IB108' => 'blocked', # 421 Temporarily rejected. Reverse DNS for this IP failed. IB108
|
||||
'IB110' => 'blocked', # 554 This IP has been temporarily blocked for attempting to send too many messages containing content judged to be spam by the Internet community. IB110
|
||||
'IB111' => 'blocked', # 554 This IP has been blocked for the day, for attempting to send too many messages containing content judged to be spam by the Internet community. IB111
|
||||
'IB112' => 'blocked', # 554 This IP has been temporarily blocked for attempting to mail too many invalid recipients. IB112
|
||||
'IB113' => 'blocked', # 554 This IP has been blocked for the day, for attempting to mail too many invalid recipients. IB113
|
||||
'IB212' => 'spamdetected', # 552 This message has been rejected due to content judged to be spam by the Internet community. IB212
|
||||
'IB401' => 'securityerror', # 535 Authentication not allowed on IBSMTP Servers. IB401
|
||||
'IB501' => 'rejected', # 550 holly@coolexample.com Blank From: addresses are not allowed. Please provide a valid From. IB501
|
||||
'IB502' => 'rejected', # 550 holly@coolexample.com IP addresses are not allowed as a From: Address. Please provide a valid From. IB502
|
||||
'IB504' => 'toomanyconn', # 550 This IP has sent too many messages this hour. IB504
|
||||
'IB506' => 'rejected', # 550 coolexample.com From: Domain is invalid. Please provide a valid From: IB506
|
||||
'IB508' => 'rejected', # 550 holly@coolexample.com Invalid SPF record. Please inspect your SPF settings, and try again. IB508
|
||||
'IB510' => 'toomanyconn', # 550 This message has exceeded the max number of messages per session. Please open a new session and try again. IB510
|
||||
'IB607' => 'toomanyconn', # 550 This IP has sent too many to too many recipients this hour. IB607
|
||||
'IB705' => 'virusdetected', # 552 Virus infected message rejected. IB705
|
||||
|
||||
};
|
||||
my $MessagesOf = {
|
||||
'blocked' => ['553 http://www.spamhaus.org/query/bl?ip=', '554 RBL Reject.'],
|
||||
'expired' => ['Delivery timeout', "451 Sorry, I wasn't able to establish an SMTP connection."],
|
||||
'suspend' => ['Account disabled'],
|
||||
'mailboxfull' => ['Account storage limit'],
|
||||
'userunknown' => ['Account does not exist', '550 Recipient not found.'],
|
||||
};
|
||||
|
||||
sub get {
|
||||
# Detect bounce reason from GoDaddy (smtp.secureserver.net)
|
||||
# @param [Sisimai::Data] argvs Parsed email object
|
||||
# @return [String] The bounce reason for GoDaddy
|
||||
# @see https://www.godaddy.com/help/what-does-my-email-bounceback-mean-3568
|
||||
my $class = shift;
|
||||
my $argvs = shift // return undef;
|
||||
return $argvs->reason if $argvs->reason;
|
||||
|
||||
my $statusmesg = $argvs->diagnosticcode;
|
||||
my $reasontext = '';
|
||||
|
||||
if( $statusmesg =~ /\s(IB\d{3})\b/ ) {
|
||||
# 192.0.2.22 has sent to too many recipients this hour. IB607 ...
|
||||
$reasontext = $ErrorCodes->{ $1 };
|
||||
} else {
|
||||
# 553 http://www.spamhaus.org/query/bl?ip=192.0.0.222
|
||||
for my $e ( keys %$MessagesOf ) {
|
||||
for my $f ( @{ $MessagesOf->{ $e } } ) {
|
||||
next if index($statusmesg, $f) == -1;
|
||||
$reasontext = $e;
|
||||
last
|
||||
}
|
||||
last if $reasontext;
|
||||
}
|
||||
}
|
||||
return $reasontext;
|
||||
}
|
||||
|
||||
1;
|
||||
__END__
|
||||
|
||||
=encoding utf-8
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Sisimai::Rhost::GoDaddy - Detect the bounce reason returned from GoDaddy.
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use Sisimai::Rhost;
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
Sisimai::Rhost detects the bounce reason from the content of Sisimai::Data
|
||||
object as an argument of get() method when the value of C<rhost> of the object
|
||||
end with "secureserver.net". This class is called only Sisimai::Data class.
|
||||
|
||||
=head1 CLASS METHODS
|
||||
|
||||
=head2 C<B<get(I<Sisimai::Data Object>)>>
|
||||
|
||||
C<get()> detects the bounce reason.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
azumakuniyuki
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright (C) 2017-2018 azumakuniyuki, All rights reserved.
|
||||
|
||||
=head1 LICENSE
|
||||
|
||||
This software is distributed under The BSD 2-Clause License.
|
||||
|
||||
=cut
|
||||
|
||||
167
Perl OTRS/Kernel/cpan-lib/Sisimai/Rhost/GoogleApps.pm
Normal file
167
Perl OTRS/Kernel/cpan-lib/Sisimai/Rhost/GoogleApps.pm
Normal file
@@ -0,0 +1,167 @@
|
||||
package Sisimai::Rhost::GoogleApps;
|
||||
use feature ':5.10';
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
my $StatusList = {
|
||||
# https://support.google.com/a/answer/3726730
|
||||
'X.1.1' => [{ 'reason' => 'userunknown', 'string' => ['The email account that you tried to reach does not exist.'] }],
|
||||
'X.1.2' => [{ 'reason' => 'hostunknown', 'string' => ["We weren't able to find the recipient domain."] }],
|
||||
'X.2.1' => [
|
||||
{ 'reason' => 'suspend', 'string' => ['The email account that you tried to reach is disabled.'] },
|
||||
{ 'reason' => 'undefined', 'string' => ['The user you are trying to contact is receiving mail '] },
|
||||
],
|
||||
'X.2.2' => [{ 'reason' => 'mailboxfull', 'string' => ['The email account that you tried to reach is over quota.'] }],
|
||||
'X.2.3' => [{ 'reason' => 'exceedlimit', 'string' => ["Your message exceeded Google's message size limits."] }],
|
||||
'X.3.0' => [
|
||||
{ 'reason' => 'syntaxerror', 'string' => ['Multiple destination domains per transaction is unsupported.'] },
|
||||
{ 'reason' => 'undefined', 'string' => ['Mail server temporarily rejected message.'] },
|
||||
],
|
||||
'X.4.2' => [{ 'reason' => 'expired', 'string' => ['Timeout - closing connection.'] }],
|
||||
'X.4.5' => [
|
||||
{ 'reason' => 'exceedlimit', 'string' => ['Daily sending quota exceeded.'] },
|
||||
{ 'reason' => 'undefined', 'string' => ['Server busy, try again later.'] },
|
||||
],
|
||||
'X.5.0' => [{ 'reason' => 'syntaxerror', 'string' => ['SMTP protocol violation'] }],
|
||||
'X.5.1' => [
|
||||
{ 'reason' => 'securityerror', 'string' => ['Authentication Required.'] },
|
||||
{
|
||||
'reason' => 'syntaxerror',
|
||||
'string' => [
|
||||
'STARTTLS may not be repeated',
|
||||
'Too many unrecognized commands, goodbye.',
|
||||
'Unimplemented command.',
|
||||
'Unrecognized command.',
|
||||
'EHLO/HELO first.',
|
||||
'MAIL first.',
|
||||
'RCPT first.',
|
||||
],
|
||||
},
|
||||
],
|
||||
'X.5.2' => [
|
||||
{ 'reason' => 'securityerror', 'string' => ['Cannot Decode response.'] }, # 2FA related error, maybe.
|
||||
{ 'reason' => 'syntaxerror', 'string' => ['Syntax error.'] },
|
||||
],
|
||||
'X.5.3' => [
|
||||
{ 'reason' => 'mailboxfull', 'string' => ['Domain policy size per transaction exceeded,'] },
|
||||
{ 'reason' => 'policyviolation','string' => ['Your message has too many recipients.'] },
|
||||
],
|
||||
'X.5.4' => [{ 'reason' => 'syntaxerror', 'string' => ['Optional Argument not permitted for that AUTH mode.'] }],
|
||||
'X.6.0' => [
|
||||
{ 'reason' => 'contenterror', 'string' => ['Mail message is malformed.'] },
|
||||
{ 'reason' => 'networkerror', 'string' => ['Message exceeded 50 hops'] }
|
||||
],
|
||||
'X.7.0' => [
|
||||
{
|
||||
'reason' => 'blocked',
|
||||
'string' => [
|
||||
'IP not in whitelist for RCPT domain, closing connection.',
|
||||
'Our system has detected an unusual rate of unsolicited mail originating from your IP address.',
|
||||
],
|
||||
},
|
||||
{
|
||||
'reason' => 'expired',
|
||||
'string' => [
|
||||
'Temporary System Problem. Try again later.',
|
||||
'Try again later, closing connection.',
|
||||
],
|
||||
},
|
||||
{
|
||||
'reason' => 'securityerror',
|
||||
'string' => [
|
||||
'TLS required for RCPT domain, closing connection.',
|
||||
'No identity changes permitted.',
|
||||
'Must issue a STARTTLS command first.',
|
||||
'Too Many Unauthenticated commands.',
|
||||
],
|
||||
},
|
||||
{ 'reason' => 'systemerror', 'string' => ['Cannot authenticate due to temporary system problem.'] },
|
||||
{ 'reason' => 'norelaying', 'string' => ['Mail relay denied.'] },
|
||||
{ 'reason' => 'rejected', 'string' => ['Mail Sending denied.'] },
|
||||
],
|
||||
'X.7.1' => [
|
||||
{ 'reason' => 'mailboxfull', 'string' => ['Email quota exceeded.'] },
|
||||
{
|
||||
'reason' => 'securityerror',
|
||||
'string' => [
|
||||
'Application-specific password required.',
|
||||
'Please log in with your web browser and then try again.',
|
||||
'Username and Password not accepted.',
|
||||
],
|
||||
},
|
||||
{
|
||||
'reason' => 'blocked',
|
||||
'string' => [
|
||||
'Our system has detected an unusual rate of unsolicited mail originating from your IP address.',
|
||||
"The IP you're using to send mail is not authorized to send email directly to our servers.",
|
||||
],
|
||||
},
|
||||
{ 'reason' => 'spamdetected', 'string' => ['Our system has detected that this message is likely unsolicited mail.'] },
|
||||
{ 'reason' => 'policyviolation','string' => ['The user or domain that you are sending to (or from) has a policy'] },
|
||||
{ 'reason' => 'rejected', 'string' => ['Unauthenticated email is not accepted from this domain.'] },
|
||||
],
|
||||
'X.7.4' => [{ 'reason' => 'syntaxerror', 'string' => ['Unrecognized Authentication Type.'] }],
|
||||
};
|
||||
|
||||
sub get {
|
||||
# Detect bounce reason from Google Apps
|
||||
# @param [Sisimai::Data] argvs Parsed email object
|
||||
# @return [String] The bounce reason for Google Apps
|
||||
# @see https://support.google.com/a/answer/3726730?hl=en
|
||||
my $class = shift;
|
||||
my $argvs = shift // return undef;
|
||||
return $argvs->reason if $argvs->reason;
|
||||
|
||||
my $reasontext = '';
|
||||
my $statuscode = $argvs->deliverystatus;
|
||||
|
||||
substr($statuscode, 0, 1, 'X');
|
||||
return '' unless scalar @{ $StatusList->{ $statuscode } };
|
||||
|
||||
for my $e ( @{ $StatusList->{ $statuscode } } ) {
|
||||
# Try to match
|
||||
next unless grep { rindex($argvs->diagnosticcode, $_) > -1 } @{ $e->{'string'} };
|
||||
$reasontext = $e->{'reason'};
|
||||
last;
|
||||
}
|
||||
return $reasontext;
|
||||
}
|
||||
|
||||
1;
|
||||
__END__
|
||||
|
||||
=encoding utf-8
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Sisimai::Rhost::GoogleApps - Detect the bounce reason returned from Google Apps.
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use Sisimai::Rhost;
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
Sisimai::Rhost detects the bounce reason from the content of Sisimai::Data
|
||||
object as an argument of get() method when the value of C<rhost> of the object
|
||||
is "aspmx.l.google.com". This class is called only Sisimai::Data class.
|
||||
|
||||
=head1 CLASS METHODS
|
||||
|
||||
=head2 C<B<get(I<Sisimai::Data Object>)>>
|
||||
|
||||
C<get()> detects the bounce reason.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
azumakuniyuki
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright (C) 2014-2016,2018 azumakuniyuki, All rights reserved.
|
||||
|
||||
=head1 LICENSE
|
||||
|
||||
This software is distributed under The BSD 2-Clause License.
|
||||
|
||||
=cut
|
||||
69
Perl OTRS/Kernel/cpan-lib/Sisimai/Rhost/KDDI.pm
Normal file
69
Perl OTRS/Kernel/cpan-lib/Sisimai/Rhost/KDDI.pm
Normal file
@@ -0,0 +1,69 @@
|
||||
package Sisimai::Rhost::KDDI;
|
||||
use feature ':5.10';
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
my $MessagesOf = {
|
||||
'filtered' => '550 : User unknown', # The response was: 550 : User unknown
|
||||
'userunknown' => '>: User unknown', # The response was: 550 <...>: User unknown
|
||||
};
|
||||
|
||||
sub get {
|
||||
# Detect bounce reason from au(KDDI)
|
||||
# @param [Sisimai::Data] argvs Parsed email object
|
||||
# @return [String] The bounce reason au.com and ezweb.ne.jp
|
||||
my $class = shift;
|
||||
my $argvs = shift // return undef;
|
||||
|
||||
my $statusmesg = $argvs->diagnosticcode;
|
||||
my $reasontext = '';
|
||||
|
||||
for my $e ( keys %$MessagesOf ) {
|
||||
# Try to match the error message with message patterns defined in $MessagesOf
|
||||
next unless rindex($statusmesg, $MessagesOf->{ $e }) > -1;
|
||||
$reasontext = $e;
|
||||
last;
|
||||
}
|
||||
return $reasontext;
|
||||
}
|
||||
|
||||
1;
|
||||
__END__
|
||||
|
||||
=encoding utf-8
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Sisimai::Rhost::KDDI - Detect the bounce reason returned from au (KDDI).
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use Sisimai::Rhost;
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
Sisimai::Rhost detects the bounce reason from the content of Sisimai::Data
|
||||
object as an argument of get() method when the value of C<rhost> of the object
|
||||
is "msmx.au.com" or "lsean.ezweb.ne.jp".
|
||||
This class is called only Sisimai::Data class.
|
||||
|
||||
=head1 CLASS METHODS
|
||||
|
||||
=head2 C<B<get(I<Sisimai::Data Object>)>>
|
||||
|
||||
C<get()> detects the bounce reason.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
azumakuniyuki
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright (C) 2018 azumakuniyuki, All rights reserved.
|
||||
|
||||
=head1 LICENSE
|
||||
|
||||
This software is distributed under The BSD 2-Clause License.
|
||||
|
||||
=cut
|
||||
|
||||
Reference in New Issue
Block a user