File Coverage

lib/Sisimai/Reason/Rejected.pm
Criterion Covered Total %
statement 35 35 100.0
branch 24 24 100.0
condition 16 17 94.1
subroutine 7 7 100.0
pod 2 4 50.0
total 84 87 96.5


line stmt bran cond sub pod time code
1             package Sisimai::Reason::Rejected;
2 59     59   1470 use v5.26;
  59         184  
3 59     59   224 use strict;
  59         74  
  59         1277  
4 59     59   194 use warnings;
  59         85  
  59         26770  
5              
6 113     113 1 1158 sub text { 'rejected' }
7 4     4 0 18 sub description { "Email rejected due to a sender's email address (envelope from)" }
8             sub match {
9             # Try to match that the given text and regular expressions
10             # @param [String] argv1 String to be matched with regular expressions
11             # @return [Integer] 0: Did not match
12             # 1: Matched
13             # @since v4.0.0
14 1294     1294 1 3654 my $class = shift;
15 1294   100     2767 my $argv1 = shift // return 0;
16              
17 1293         1556 state $isnot = [
18             "5.1.0 address rejected",
19             "ip address ",
20             "recipient address rejected",
21             ];
22 1293         1787 state $index = [
23             "access denied (in reply to mail from command)",
24             "administrative prohibition",
25             "all recipient addresses rejected : access denied",
26             "badsendermx", # BadSenderMX
27             "backscatter protection detected an invalid or expired email address", # MDaemon
28             "by non-member to a members-only list",
29             "can't determine purported responsible address",
30             "connections not accepted from servers without a valid sender domain",
31             "denied by secumail valid-address-filter", # SecuMail
32             "domain of sender address ",
33             "email address is on senderfilterconfig list",
34             "emetteur invalide",
35             "empty email address",
36             "empty envelope senders not allowed",
37             "from: domain is invalid. please provide a valid from:",
38             "fully qualified email address required", # McAfee
39             "has an outgoing mail suspension",
40             "invalid sender",
41             "is not a registered gateway user",
42             "mail from not owned by user",
43             "mailfrom domain is listed in spamhaus",
44             "not member article from ", # FML
45             "null sender is not allowed",
46             "returned mail not accepted here",
47             "sending this from a different address or alias using the ",
48             "sender is spammer",
49             "sender not pre-approved",
50             "sender domain is empty",
51             "sender domain listed at ",
52             "sender verify failed", # Exim callout
53             "sendernoa", # SenderNoA
54             "server does not accept mail from",
55             "spam reporting address", # SendGrid|a message to an address has previously been marked as Spam by the recipient.
56             "too many spam complaints",
57             "unroutable sender address",
58             "you are not allowed to post to this mailing list",
59             "your access to submit messages to this e-mail system has been rejected",
60             "your email address has been blacklisted", # MessageLabs
61             ];
62 1293         1474 state $pairs = [
63             ["after end of data:", ".", " does not exist"],
64             ["after mail from:", ".", " does not exist"],
65             ["domain ", " is a dead domain"],
66             ["email address ", "is not "],
67             ["reject mail from ", "@"], # FML
68             ["send", "blacklisted"],
69             ["sender", " rejected"],
70             ["sender is", " list"],
71             ];
72              
73 1293 100       1867 return 0 if grep { rindex($argv1, $_) > -1 } @$isnot;
  3879         7479  
74 1132 100       2209 return 1 if grep { rindex($argv1, $_) > -1 } @$index;
  43016         48356  
75 1094 100       1864 return 1 if grep { Sisimai::String->aligned(\$argv1, $_) } @$pairs;
  8752         11372  
76 1074         2230 return 0;
77             }
78              
79             sub true {
80             # Rejected by the envelope sender address or not
81             # @param [Sisimai::Fact] argvs Object to be detected the reason
82             # @return [Integer] 1: is rejected
83             # 0: is not rejected by the sender
84             # @since v4.0.0
85             # @see http://www.ietf.org/rfc/rfc2822.txt
86 1001     1001 0 1451 my $class = shift;
87 1001   100     3419 my $argvs = shift // return 0;
88              
89 1000 100       3571 return 1 if $argvs->{'reason'} eq 'rejected';
90 999   100     2149 my $tempreason = Sisimai::SMTP::Status->name($argvs->{'deliverystatus'}) || 'undefined';
91 999 100       2030 return 1 if $tempreason eq 'rejected'; # Delivery status code points "rejected".
92              
93             # Check the value of Diagnosic-Code: header with patterns
94 943         2025 my $issuedcode = lc $argvs->{'diagnosticcode'};
95 943   100     2909 my $thecommand = $argvs->{'command'} || '';
96 943 100 66     9392 if( $thecommand eq 'MAIL' ) {
    100 100        
    100 100        
97             # The session was rejected at 'MAIL FROM' command
98 87 100       256 return 1 if __PACKAGE__->match($issuedcode);
99              
100             } elsif( $thecommand eq 'DATA' ) {
101             # The session was rejected at 'DATA' command
102 98 100       250 if( $tempreason ne 'userunknown' ) {
103             # Except "userunknown"
104 97 100       301 return 1 if __PACKAGE__->match($issuedcode);
105             }
106             } elsif( $tempreason eq 'onhold' || $tempreason eq 'undefined' ||
107             $tempreason eq 'securityerror' || $tempreason eq 'systemerror' ) {
108             # Try to match with message patterns when the temporary reason is "onhold", "undefined",
109             # "securityerror", or "systemerror"
110 554 100       1489 return 1 if __PACKAGE__->match($issuedcode);
111             }
112 886         2133 return 0;
113             }
114              
115             1;
116             __END__