| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package Sisimai::RFC3464::ThirdParty; |
|
2
|
32
|
|
|
32
|
|
406
|
use v5.26; |
|
|
32
|
|
|
|
|
126
|
|
|
3
|
32
|
|
|
32
|
|
169
|
use strict; |
|
|
32
|
|
|
|
|
92
|
|
|
|
32
|
|
|
|
|
954
|
|
|
4
|
32
|
|
|
32
|
|
167
|
use warnings; |
|
|
32
|
|
|
|
|
55
|
|
|
|
32
|
|
|
|
|
10850
|
|
|
5
|
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
state $ThirdParty = { |
|
7
|
|
|
|
|
|
|
#"Aol" => ["X-Outbound-Mail-Relay-"], # X-Outbound-Mail-Relay-(Queue-ID|Sender) |
|
8
|
|
|
|
|
|
|
"PowerMTA" => ["X-PowerMTA-"], # X-PowerMTA-(VirtualMTA|BounceCategory) |
|
9
|
|
|
|
|
|
|
#"Yandex" => ["X-Yandex-"], # X-Yandex-(Queue-ID|Sender) |
|
10
|
|
|
|
|
|
|
}; |
|
11
|
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
sub is3rdparty { |
|
13
|
|
|
|
|
|
|
# is3rdparty() returns true if the argument is a line generated by a MTA which have fields defined |
|
14
|
|
|
|
|
|
|
# in RFC3464 inside of a bounce mail the MTA returns |
|
15
|
|
|
|
|
|
|
# @param string argv1 A line of a bounce mail |
|
16
|
|
|
|
|
|
|
# @return bool The line indicates that a bounce mail generated by the 3rd party MTA |
|
17
|
238
|
|
|
238
|
1
|
492
|
my $class = shift; |
|
18
|
238
|
100
|
50
|
|
|
805
|
my $argv1 = shift || return 0; return __PACKAGE__->returnedby($argv1) ? 1 : 0; |
|
|
238
|
|
|
|
|
759
|
|
|
19
|
|
|
|
|
|
|
} |
|
20
|
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
sub returnedby { |
|
22
|
|
|
|
|
|
|
# returnedby() returns an MTA name of the 3rd party |
|
23
|
|
|
|
|
|
|
# @param string argv1 A line of a bounce mail |
|
24
|
|
|
|
|
|
|
# @return string An MTA name of the 3rd party |
|
25
|
270
|
|
|
270
|
0
|
464
|
my $class = shift; |
|
26
|
270
|
50
|
50
|
|
|
682
|
my $argv1 = shift || return 0; return 0 unless index($argv1, "X-") == 0; |
|
|
270
|
|
|
|
|
773
|
|
|
27
|
|
|
|
|
|
|
|
|
28
|
270
|
|
|
|
|
742
|
for my $e ( keys %$ThirdParty ) { |
|
29
|
|
|
|
|
|
|
# Does the argument include the 3rd party specific field? |
|
30
|
270
|
100
|
|
|
|
1090
|
return $e if index($argv1, $ThirdParty->{ $e }->[0]) == 0; |
|
31
|
|
|
|
|
|
|
} |
|
32
|
206
|
|
|
|
|
1064
|
return "" |
|
33
|
|
|
|
|
|
|
} |
|
34
|
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
sub xfield { |
|
36
|
|
|
|
|
|
|
# xfield() returns rfc1894.Field() compatible slice for the specific field of the 3rd party MTA |
|
37
|
|
|
|
|
|
|
# @param string argv1 A line of the error message |
|
38
|
|
|
|
|
|
|
# @return [] RFC1894->field() compatible array |
|
39
|
|
|
|
|
|
|
# @see Sisimai::RFC1894 |
|
40
|
32
|
|
|
32
|
0
|
37
|
my $class = shift; |
|
41
|
32
|
|
50
|
|
|
60
|
my $argv1 = shift || return []; |
|
42
|
32
|
50
|
|
|
|
73
|
my $party = __PACKAGE__->returnedby($argv1); return [] unless $party; |
|
|
32
|
|
|
|
|
65
|
|
|
43
|
32
|
|
|
|
|
133
|
return sprintf("Sisimai::RFC3464::ThirdParty::%s", $party)->xfield($argv1); |
|
44
|
|
|
|
|
|
|
} |
|
45
|
|
|
|
|
|
|
1; |
|
46
|
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
# ------------------------------------------------------------------------------------------------- |
|
48
|
|
|
|
|
|
|
package Sisimai::RFC3464::ThirdParty::PowerMTA; |
|
49
|
32
|
|
|
32
|
|
541
|
use v5.26; |
|
|
32
|
|
|
|
|
166
|
|
|
50
|
32
|
|
|
32
|
|
196
|
use strict; |
|
|
32
|
|
|
|
|
62
|
|
|
|
32
|
|
|
|
|
970
|
|
|
51
|
32
|
|
|
32
|
|
145
|
use warnings; |
|
|
32
|
|
|
|
|
65
|
|
|
|
32
|
|
|
|
|
13109
|
|
|
52
|
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
state $FieldGroup = { |
|
54
|
|
|
|
|
|
|
"x-powermta-virtualmta" => "host", # X-PowerMTA-VirtualMTA: mx22.neko.example.jp |
|
55
|
|
|
|
|
|
|
"x-powermta-bouncecategory" => "text", # X-PowerMTA-BounceCategory: bad-mailbox |
|
56
|
|
|
|
|
|
|
}; |
|
57
|
|
|
|
|
|
|
state $MessagesOf = { |
|
58
|
|
|
|
|
|
|
"bad-domain" => "hostunknown", |
|
59
|
|
|
|
|
|
|
"bad-mailbox" => "userunknown", |
|
60
|
|
|
|
|
|
|
"inactive-mailbox" => "suspend", |
|
61
|
|
|
|
|
|
|
"message-expired" => "expired", |
|
62
|
|
|
|
|
|
|
"no-answer-from-host" => "networkerror", |
|
63
|
|
|
|
|
|
|
"policy-related" => "policyviolation", |
|
64
|
|
|
|
|
|
|
"quota-issues" => "mailboxfull", |
|
65
|
|
|
|
|
|
|
"routing-errors" => "systemerror", |
|
66
|
|
|
|
|
|
|
"spam-related" => "spamdetected", |
|
67
|
|
|
|
|
|
|
}; |
|
68
|
|
|
|
|
|
|
|
|
69
|
|
|
|
|
|
|
sub xfield { |
|
70
|
|
|
|
|
|
|
# Returns an array which is compatible with the value returned from Sisimai::RFC1894->field() |
|
71
|
|
|
|
|
|
|
# @param string argv1 A line of the error message |
|
72
|
|
|
|
|
|
|
# @return Array ["field-name", "value-type", "value", "field-group", "comment"] |
|
73
|
|
|
|
|
|
|
# @see https://bird.com/email/power-mta |
|
74
|
32
|
|
|
32
|
|
45
|
my $class = shift; |
|
75
|
32
|
|
50
|
|
|
50
|
my $argv1 = shift || return []; |
|
76
|
|
|
|
|
|
|
|
|
77
|
32
|
|
|
|
|
94
|
my $fieldparts = [split(":", $argv1, 2)]; # ["Final-Recipient", " rfc822; "] |
|
78
|
32
|
|
|
|
|
64
|
my $xfieldname = lc $fieldparts->[0]; # "final-recipient" |
|
79
|
32
|
50
|
|
|
|
53
|
my $xgroupname = $FieldGroup->{ $xfieldname }; return [] unless $xgroupname; |
|
|
32
|
|
|
|
|
62
|
|
|
80
|
32
|
|
|
|
|
85
|
my $xfieldlist = ["", "", Sisimai::String->sweep($fieldparts->[1]), $xgroupname, "", "PowerMTA"]; |
|
81
|
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
# - 0: Field-Name |
|
83
|
|
|
|
|
|
|
# - 1: Sub Type: RFC822, DNS, X-Unix, and so on) |
|
84
|
|
|
|
|
|
|
# - 2: Value |
|
85
|
|
|
|
|
|
|
# - 3: Field Group(addr, code, date, host, stat, text) |
|
86
|
|
|
|
|
|
|
# - 4: Comment |
|
87
|
|
|
|
|
|
|
# - 5: 3rd Party MTA-Name |
|
88
|
32
|
100
|
|
|
|
86
|
if( $xfieldname eq "x-powermta-bouncecategory" ) { |
|
|
|
50
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
# X-PowerMTA-BounceCategory: bad-mailbox |
|
90
|
|
|
|
|
|
|
# Set the bounce reason picked from the value of the field |
|
91
|
16
|
|
|
|
|
30
|
$xfieldlist->[0] = $xfieldname; |
|
92
|
16
|
|
50
|
|
|
92
|
$xfieldlist->[4] = sprintf("reason:%s", $MessagesOf->{ $xfieldlist->[2] } || ""); |
|
93
|
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
} elsif( $xfieldname eq "x-powermta-virtualmta" ) { |
|
95
|
|
|
|
|
|
|
# X-PowerMTA-VirtualMTA: mx22.neko.example.jp |
|
96
|
16
|
|
|
|
|
34
|
$xfieldlist->[0] = "Reporting-MTA"; |
|
97
|
|
|
|
|
|
|
} |
|
98
|
|
|
|
|
|
|
|
|
99
|
32
|
|
|
|
|
79
|
return $xfieldlist; |
|
100
|
|
|
|
|
|
|
} |
|
101
|
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
1; |
|
103
|
|
|
|
|
|
|
|
|
104
|
|
|
|
|
|
|
__END__ |