sisimai 5.7.0 → 5.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/ChangeLog.md +15 -0
- data/README-JA.md +8 -8
- data/README.md +8 -8
- data/lib/sisimai/arf.rb +2 -1
- data/lib/sisimai/eb.rb +116 -0
- data/lib/sisimai/fact.rb +24 -17
- data/lib/sisimai/lda.rb +20 -18
- data/lib/sisimai/lhost/amazonses.rb +11 -10
- data/lib/sisimai/lhost/courier.rb +4 -3
- data/lib/sisimai/lhost/domino.rb +2 -1
- data/lib/sisimai/lhost/einsundeins.rb +3 -2
- data/lib/sisimai/lhost/exchange2003.rb +8 -7
- data/lib/sisimai/lhost/exchange2007.rb +14 -13
- data/lib/sisimai/lhost/exim.rb +7 -6
- data/lib/sisimai/lhost/ezweb.rb +4 -3
- data/lib/sisimai/lhost/fml.rb +4 -3
- data/lib/sisimai/lhost/gmail.rb +10 -9
- data/lib/sisimai/lhost/googlegroups.rb +3 -2
- data/lib/sisimai/lhost/googleworkspace.rb +2 -1
- data/lib/sisimai/lhost/imailserver.rb +3 -2
- data/lib/sisimai/lhost/kddi.rb +4 -3
- data/lib/sisimai/lhost/notes.rb +2 -1
- data/lib/sisimai/lhost/postfix.rb +7 -6
- data/lib/sisimai/lhost/qmail.rb +10 -9
- data/lib/sisimai/lhost/sendmail.rb +4 -3
- data/lib/sisimai/lhost/trendmicro.rb +2 -1
- data/lib/sisimai/lhost/v5sendmail.rb +2 -1
- data/lib/sisimai/lhost/verizon.rb +3 -2
- data/lib/sisimai/reason/authfailure.rb +6 -5
- data/lib/sisimai/reason/badreputation.rb +5 -4
- data/lib/sisimai/reason/blocked.rb +6 -5
- data/lib/sisimai/reason/contenterror.rb +6 -5
- data/lib/sisimai/reason/delivered.rb +3 -2
- data/lib/sisimai/reason/emailtoolarge.rb +6 -5
- data/lib/sisimai/reason/expired.rb +3 -2
- data/lib/sisimai/reason/failedstarttls.rb +5 -3
- data/lib/sisimai/reason/feedback.rb +2 -1
- data/lib/sisimai/reason/filtered.rb +9 -8
- data/lib/sisimai/reason/hasmoved.rb +5 -4
- data/lib/sisimai/reason/hostunknown.rb +5 -4
- data/lib/sisimai/reason/mailboxfull.rb +7 -6
- data/lib/sisimai/reason/mailererror.rb +3 -2
- data/lib/sisimai/reason/networkerror.rb +3 -2
- data/lib/sisimai/reason/norelaying.rb +4 -3
- data/lib/sisimai/reason/notaccept.rb +5 -4
- data/lib/sisimai/reason/notcompliantrfc.rb +4 -3
- data/lib/sisimai/reason/onhold.rb +8 -7
- data/lib/sisimai/reason/policyviolation.rb +7 -6
- data/lib/sisimai/reason/ratelimited.rb +5 -4
- data/lib/sisimai/reason/rejected.rb +18 -14
- data/lib/sisimai/reason/requireptr.rb +5 -4
- data/lib/sisimai/reason/securityerror.rb +4 -3
- data/lib/sisimai/reason/spamdetected.rb +6 -5
- data/lib/sisimai/reason/suppressed.rb +4 -3
- data/lib/sisimai/reason/suspend.rb +4 -3
- data/lib/sisimai/reason/syntaxerror.rb +4 -3
- data/lib/sisimai/reason/systemerror.rb +3 -2
- data/lib/sisimai/reason/systemfull.rb +4 -3
- data/lib/sisimai/reason/undefined.rb +2 -1
- data/lib/sisimai/reason/userunknown.rb +13 -9
- data/lib/sisimai/reason/vacation.rb +2 -1
- data/lib/sisimai/reason/virusdetected.rb +6 -5
- data/lib/sisimai/reason.rb +45 -40
- data/lib/sisimai/rfc1894.rb +8 -2
- data/lib/sisimai/rfc2045.rb +6 -3
- data/lib/sisimai/rfc3464/thirdparty.rb +10 -9
- data/lib/sisimai/rfc3834.rb +4 -2
- data/lib/sisimai/rhost/aol.rb +3 -2
- data/lib/sisimai/rhost/apple.rb +12 -11
- data/lib/sisimai/rhost/cloudflare.rb +3 -2
- data/lib/sisimai/rhost/cox.rb +38 -37
- data/lib/sisimai/rhost/facebook.rb +17 -16
- data/lib/sisimai/rhost/franceptt.rb +39 -38
- data/lib/sisimai/rhost/godaddy.rb +35 -34
- data/lib/sisimai/rhost/google.rb +22 -21
- data/lib/sisimai/rhost/gsuite.rb +8 -7
- data/lib/sisimai/rhost/iua.rb +11 -10
- data/lib/sisimai/rhost/kddi.rb +3 -2
- data/lib/sisimai/rhost/messagelabs.rb +13 -12
- data/lib/sisimai/rhost/microsoft.rb +33 -32
- data/lib/sisimai/rhost/mimecast.rb +18 -17
- data/lib/sisimai/rhost/nttdocomo.rb +10 -9
- data/lib/sisimai/rhost/outlook.rb +3 -2
- data/lib/sisimai/rhost/spectrum.rb +19 -18
- data/lib/sisimai/rhost/tencent.rb +10 -9
- data/lib/sisimai/rhost/yahooinc.rb +11 -10
- data/lib/sisimai/rhost/zoho.rb +8 -7
- data/lib/sisimai/smtp/command.rb +13 -8
- data/lib/sisimai/smtp/failure.rb +9 -8
- data/lib/sisimai/smtp/reply.rb +23 -22
- data/lib/sisimai/smtp/status.rb +141 -140
- data/lib/sisimai/smtp/transcript.rb +3 -2
- data/lib/sisimai/version.rb +1 -1
- data/lib/sisimai.rb +2 -1
- data/set-of-emails/maildir/bsd/lhost-postfix-81.eml +130 -0
- data/set-of-emails/should-not-crash/go-423-deeply-nested-mime-parts.eml +20050 -0
- metadata +5 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: fe26d7361ec6d30cae438f4ee17e01a533d4ce63079f37e3d3912f7addd438a6
|
|
4
|
+
data.tar.gz: 915a7f5d1543537380a0919f2d7300cbe2899fb80fe33fa402d5b94f131d5375
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b5a929ebc2d9ee903c1374e27f235753646dcbed777a096d0fe03ca69658041d9afcb064b8d16fb0b42e68ba87f4a5590900053781eb004aa1c637e0d157722b
|
|
7
|
+
data.tar.gz: 9dd782811c37de36a02073ec339a191381574897d4e579422b583e7dd23625ed61424486245fd9efc1c705f2be506b5d91706617a3446da857241063116990aa
|
data/ChangeLog.md
CHANGED
|
@@ -4,6 +4,21 @@ RELEASE NOTES for Ruby version of Sisimai
|
|
|
4
4
|
- download: "https://rubygems.org/gems/sisimai"
|
|
5
5
|
- document: "https://libsisimai.org/"
|
|
6
6
|
|
|
7
|
+
v5.7.1
|
|
8
|
+
---------------------------------------------------------------------------------------------------
|
|
9
|
+
- release: "Fri, 17 Jul 2026 13:22:22 +0900 (JST)"
|
|
10
|
+
- version: "5.7.1"
|
|
11
|
+
- changes:
|
|
12
|
+
- **Bug fixes**
|
|
13
|
+
- Fix duplicated SMTP command `HELO` in `Sisimai::SMTP::Command`.
|
|
14
|
+
- **Mitigation for potential DoS vectors**
|
|
15
|
+
- #441 Limit the nesting depth of MIME parts in Sisimai::RFC2045 class.
|
|
16
|
+
- **Code improvements**
|
|
17
|
+
- New class `Sisimai::Eb` for keeping constants.
|
|
18
|
+
- #443 `Sisimai::Eb::Re****` Bounce reason names.
|
|
19
|
+
- #447 `Sisimai::Eb::Ce****` SMTP commands.
|
|
20
|
+
- #448 `Sisimai::Eb::Ae****` Action field values.
|
|
21
|
+
|
|
7
22
|
v5.7.0
|
|
8
23
|
---------------------------------------------------------------------------------------------------
|
|
9
24
|
- release: "Mon, 22 Jun 2026 16:22:22 +0900 (JST)"
|
data/README-JA.md
CHANGED
|
@@ -116,10 +116,10 @@ Install
|
|
|
116
116
|
### From RubyGems.org
|
|
117
117
|
```shell
|
|
118
118
|
$ sudo gem install sisimai
|
|
119
|
-
Fetching: sisimai-5.7.
|
|
120
|
-
Successfully installed sisimai-5.7.
|
|
121
|
-
Parsing documentation for sisimai-5.7.
|
|
122
|
-
Installing ri documentation for sisimai-5.7.
|
|
119
|
+
Fetching: sisimai-5.7.1.gem (100%)
|
|
120
|
+
Successfully installed sisimai-5.7.1
|
|
121
|
+
Parsing documentation for sisimai-5.7.1
|
|
122
|
+
Installing ri documentation for sisimai-5.7.1
|
|
123
123
|
Done installing documentation for sisimai after 6 seconds
|
|
124
124
|
1 gem installed
|
|
125
125
|
```
|
|
@@ -147,13 +147,13 @@ if [ -d "/usr/local/jr" ]; then \
|
|
|
147
147
|
...
|
|
148
148
|
3 gems installed
|
|
149
149
|
/opt/local/bin/rake install
|
|
150
|
-
sisimai 5.7.
|
|
151
|
-
sisimai (5.7.
|
|
150
|
+
sisimai 5.7.1 built to pkg/sisimai-5.7.1.gem.
|
|
151
|
+
sisimai (5.7.1) installed.
|
|
152
152
|
if [ -d "/usr/local/jr" ]; then \
|
|
153
153
|
PATH="/usr/local/jr/bin:$PATH" /usr/local/jr/bin/rake install; \
|
|
154
154
|
fi
|
|
155
|
-
sisimai 5.7.
|
|
156
|
-
sisimai (5.7.
|
|
155
|
+
sisimai 5.7.1 built to pkg/sisimai-5.7.1-java.gem.
|
|
156
|
+
sisimai (5.7.1) installed.
|
|
157
157
|
```
|
|
158
158
|
|
|
159
159
|
Usage
|
data/README.md
CHANGED
|
@@ -115,10 +115,10 @@ Install
|
|
|
115
115
|
### From RubyGems
|
|
116
116
|
```shell
|
|
117
117
|
$ sudo gem install sisimai
|
|
118
|
-
Fetching: sisimai-5.7.
|
|
119
|
-
Successfully installed sisimai-5.7.
|
|
120
|
-
Parsing documentation for sisimai-5.7.
|
|
121
|
-
Installing ri documentation for sisimai-5.7.
|
|
118
|
+
Fetching: sisimai-5.7.1.gem (100%)
|
|
119
|
+
Successfully installed sisimai-5.7.1
|
|
120
|
+
Parsing documentation for sisimai-5.7.1
|
|
121
|
+
Installing ri documentation for sisimai-5.7.1
|
|
122
122
|
Done installing documentation for sisimai after 6 seconds
|
|
123
123
|
1 gem installed
|
|
124
124
|
```
|
|
@@ -146,13 +146,13 @@ if [ -d "/usr/local/jr" ]; then \
|
|
|
146
146
|
...
|
|
147
147
|
3 gems installed
|
|
148
148
|
/opt/local/bin/rake install
|
|
149
|
-
sisimai 5.7.
|
|
150
|
-
sisimai (5.7.
|
|
149
|
+
sisimai 5.7.1 built to pkg/sisimai-5.7.1.gem.
|
|
150
|
+
sisimai (5.7.1) installed.
|
|
151
151
|
if [ -d "/usr/local/jr" ]; then \
|
|
152
152
|
PATH="/usr/local/jr/bin:$PATH" /usr/local/jr/bin/rake install; \
|
|
153
153
|
fi
|
|
154
|
-
sisimai 5.7.
|
|
155
|
-
sisimai (5.7.
|
|
154
|
+
sisimai 5.7.1 built to pkg/sisimai-5.7.1-java.gem.
|
|
155
|
+
sisimai (5.7.1) installed.
|
|
156
156
|
```
|
|
157
157
|
|
|
158
158
|
Usage
|
data/lib/sisimai/arf.rb
CHANGED
|
@@ -2,6 +2,7 @@ module Sisimai
|
|
|
2
2
|
# Sisimai::ARF is a decoder for the email returned as a FeedBack Loop report message.
|
|
3
3
|
module ARF
|
|
4
4
|
class << self
|
|
5
|
+
require 'sisimai/eb'
|
|
5
6
|
require 'sisimai/lhost'
|
|
6
7
|
require 'sisimai/rfc5322'
|
|
7
8
|
|
|
@@ -220,7 +221,7 @@ module Sisimai
|
|
|
220
221
|
# Tidy up the error message in e.Diagnosis, Try to detect the bounce reason.
|
|
221
222
|
j += 1
|
|
222
223
|
e["diagnosis"] = e["diagnosis"] + anotherone
|
|
223
|
-
e["reason"] =
|
|
224
|
+
e["reason"] = Sisimai::Eb::ReFEED
|
|
224
225
|
e["rhost"] = remotehost
|
|
225
226
|
e["lhost"] = reportedby
|
|
226
227
|
e["date"] = timestamp0
|
data/lib/sisimai/eb.rb
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
module Sisimai
|
|
2
|
+
# Sisimai::Eb - Package "eb" provides constants for the email bounce.
|
|
3
|
+
module Eb
|
|
4
|
+
# _ ______
|
|
5
|
+
# ___| |__ / / _ \ ___ __ _ ___ ___ _ __
|
|
6
|
+
# / _ \ '_ \ / /| |_) / _ \/ _` / __|/ _ \| '_ \
|
|
7
|
+
# | __/ |_) / / | _ < __/ (_| \__ \ (_) | | | |
|
|
8
|
+
# \___|_.__/_/ |_| \_\___|\__,_|___/\___/|_| |_|
|
|
9
|
+
# bounce reason names
|
|
10
|
+
ReAUTH = "AuthFailure"
|
|
11
|
+
ReFAMA = "BadReputation"
|
|
12
|
+
ReBLOC = "Blocked"
|
|
13
|
+
ReBODY = "ContentError"
|
|
14
|
+
ReSENT = "Delivered"
|
|
15
|
+
ReSIZE = "EmailTooLarge"
|
|
16
|
+
ReTIME = "Expired"
|
|
17
|
+
ReTTLS = "FailedSTARTTLS"
|
|
18
|
+
ReFEED = "Feedback"
|
|
19
|
+
ReFILT = "Filtered"
|
|
20
|
+
ReMOVE = "HasMoved"
|
|
21
|
+
ReHOST = "HostUnknown"
|
|
22
|
+
ReFULL = "MailboxFull"
|
|
23
|
+
ReUNIX = "MailerError"
|
|
24
|
+
ReINET = "NetworkError"
|
|
25
|
+
RePASS = "NoRelaying"
|
|
26
|
+
Re00MX = "NotAccept"
|
|
27
|
+
ReNRFC = "NotCompliantRFC"
|
|
28
|
+
Re___1 = "OnHold"
|
|
29
|
+
ReWONT = "PolicyViolation"
|
|
30
|
+
ReFROM = "Rejected"
|
|
31
|
+
ReQPTR = "RequirePTR"
|
|
32
|
+
ReRATE = "RateLimited"
|
|
33
|
+
ReSAFE = "SecurityError"
|
|
34
|
+
ReSPAM = "SpamDetected"
|
|
35
|
+
ReSTOP = "Suppressed"
|
|
36
|
+
ReQUIT = "Suspend"
|
|
37
|
+
ReCOMM = "SyntaxError"
|
|
38
|
+
RePROC = "SystemError"
|
|
39
|
+
ReDISK = "SystemFull"
|
|
40
|
+
Re___0 = "Undefined"
|
|
41
|
+
ReUSER = "UserUnknown"
|
|
42
|
+
ReAWAY = "Vacation"
|
|
43
|
+
ReEXEC = "VirusDetected"
|
|
44
|
+
|
|
45
|
+
# _ ______ _
|
|
46
|
+
# ___| |__ / / ___|___ _ __ ___ _ __ ___ __ _ _ __ __| |
|
|
47
|
+
# / _ \ '_ \ / / | / _ \| '_ ` _ \| '_ ` _ \ / _` | '_ \ / _` |
|
|
48
|
+
# | __/ |_) / /| |__| (_) | | | | | | | | | | | (_| | | | | (_| |
|
|
49
|
+
# \___|_.__/_/ \____\___/|_| |_| |_|_| |_| |_|\__,_|_| |_|\__,_|
|
|
50
|
+
CeHELO = "HELO"
|
|
51
|
+
CeEHLO = "EHLO"
|
|
52
|
+
CeMAIL = "MAIL"
|
|
53
|
+
CeRCPT = "RCPT"
|
|
54
|
+
CeDATA = "DATA"
|
|
55
|
+
CeQUIT = "QUIT"
|
|
56
|
+
CeRSET = "RSET"
|
|
57
|
+
CeNOOP = "NOOP"
|
|
58
|
+
CeVRFY = "VRFY"
|
|
59
|
+
CeETRN = "ETRN"
|
|
60
|
+
CeEXPN = "EXPN"
|
|
61
|
+
CeHELP = "HELP"
|
|
62
|
+
CeAUTH = "AUTH"
|
|
63
|
+
CeTTLS = "STARTTLS"
|
|
64
|
+
CeXFWD = "XFORWARD"
|
|
65
|
+
CeCONN = "CONN" # CONN is a pseudo SMTP command used only in Sisimai
|
|
66
|
+
|
|
67
|
+
# _ ___ _ _
|
|
68
|
+
# ___| |__ / / \ ___| |_(_) ___ _ __
|
|
69
|
+
# / _ \ '_ \ / / _ \ / __| __| |/ _ \| '_ \
|
|
70
|
+
# | __/ |_) / / ___ \ (__| |_| | (_) | | | |
|
|
71
|
+
# \___|_.__/_/_/ \_\___|\__|_|\___/|_| |_|
|
|
72
|
+
#
|
|
73
|
+
# https://datatracker.ietf.org/doc/html/rfc3464#page-16
|
|
74
|
+
# 2.3.3 Action field
|
|
75
|
+
# The Action field indicates the action performed by the Reporting-MTA as a result of its attempt
|
|
76
|
+
# to deliver the message to this recipient address. This field MUST be present for each recipient
|
|
77
|
+
# named in the DSN.
|
|
78
|
+
#
|
|
79
|
+
# The syntax for the action-field is:
|
|
80
|
+
# action-field = "Action" ":" action-value
|
|
81
|
+
# action-value = "failed" / "delayed" / "delivered" / "relayed" / "expanded"
|
|
82
|
+
#
|
|
83
|
+
# The action-value may be spelled in any combination of upper and lower case characters.
|
|
84
|
+
#
|
|
85
|
+
# "failed" indicates that the message could not be delivered to the recipient.
|
|
86
|
+
# The Reporting MTA has abandoned any attempts to deliver the message to this
|
|
87
|
+
# recipient. No further notifications should be expected.
|
|
88
|
+
#
|
|
89
|
+
# "delayed" indicates that the Reporting MTA has so far been unable to deliver or relay the
|
|
90
|
+
# message, but it will continue to attempt to do so. Additional notification
|
|
91
|
+
# messages may be issued as the message is further delayed or successfully
|
|
92
|
+
# delivered, or if delivery attempts are later abandoned.
|
|
93
|
+
#
|
|
94
|
+
# "delivered" indicates that the message was successfully delivered to the recipient address
|
|
95
|
+
# specified by the sender, which includes "delivery" to a mailing list exploder.
|
|
96
|
+
# It does not indicate that the message has been read. This is a terminal state
|
|
97
|
+
# and no further DSN for this recipient should be expected.
|
|
98
|
+
#
|
|
99
|
+
# "relayed" indicates that the message has been relayed or gatewayed into an environment
|
|
100
|
+
# that does not accept responsibility for generating DSNs upon successful delivery.
|
|
101
|
+
# This action-value SHOULD NOT be used unless the sender has requested notification
|
|
102
|
+
# of successful delivery for this recipient.
|
|
103
|
+
#
|
|
104
|
+
# "expanded" indicates that the message has been successfully delivered to the recipient
|
|
105
|
+
# address as specified by the sender, and forwarded by the Reporting-MTA beyond
|
|
106
|
+
# that destination to multiple additional recipient addresses. An action-value of
|
|
107
|
+
# "expanded" differs from "delivered" in that "expanded" is not a terminal state.
|
|
108
|
+
# Further "failed" and/or "delayed" notifications may be provided.
|
|
109
|
+
AeFAIL = "failed"
|
|
110
|
+
AeSTAY = "delayed"
|
|
111
|
+
AeSENT = "delivered"
|
|
112
|
+
AePASS = "relayed"
|
|
113
|
+
AeEXPN = "expanded"
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
data/lib/sisimai/fact.rb
CHANGED
|
@@ -15,6 +15,7 @@ module Sisimai
|
|
|
15
15
|
require 'sisimai/string'
|
|
16
16
|
require 'sisimai/rhost'
|
|
17
17
|
require 'sisimai/lda'
|
|
18
|
+
require 'sisimai/eb'
|
|
18
19
|
|
|
19
20
|
@@rwaccessors = [
|
|
20
21
|
:action, # [String] The value of Action: header
|
|
@@ -122,7 +123,7 @@ module Sisimai
|
|
|
122
123
|
while e = deliveries.shift do
|
|
123
124
|
# Create parameters for each Sisimai::Fact object
|
|
124
125
|
next if e['recipient'].size < 5
|
|
125
|
-
next if ! argvs[:vacation] && e['reason'] ==
|
|
126
|
+
next if ! argvs[:vacation] && e['reason'] == Sisimai::Eb::ReAWAY
|
|
126
127
|
next if ! argvs[:delivered] && e['status'].start_with?('2.')
|
|
127
128
|
|
|
128
129
|
thing = {} # To be passed to each accessor of Sisimai::Fact
|
|
@@ -353,7 +354,7 @@ module Sisimai
|
|
|
353
354
|
piece['diagnosticcode'] = piece['diagnosticcode'].force_encoding('UTF-8').scrub('?')
|
|
354
355
|
end
|
|
355
356
|
|
|
356
|
-
piece["diagnostictype"] = "X-UNIX" if piece["reason"] ==
|
|
357
|
+
piece["diagnostictype"] = "X-UNIX" if piece["reason"] == Sisimai::Eb::ReUNIX
|
|
357
358
|
if piece["diagnostictype"].empty?
|
|
358
359
|
piece["diagnostictype"] = "SMTP" if %w[feedback vacation].include?(piece["reason"]) == false
|
|
359
360
|
end
|
|
@@ -363,7 +364,7 @@ module Sisimai
|
|
|
363
364
|
# - <<< 503-5.5.1 RCPT first. A mail transaction protocol command was issued ...
|
|
364
365
|
# - RCPT first (in reply to DATA command)
|
|
365
366
|
piece['command'] = '' if Sisimai::SMTP::Command.test(piece['command']) == false
|
|
366
|
-
piece['command'] =
|
|
367
|
+
piece['command'] = Sisimai::Eb::CeRCPT if piece['diagnosticcode'].include?('RCPT first')
|
|
367
368
|
|
|
368
369
|
# Create parameters for the constructor
|
|
369
370
|
as = Sisimai::Address.new(piece['addresser']) || next; next if as.void
|
|
@@ -384,14 +385,14 @@ module Sisimai
|
|
|
384
385
|
ea.each { |q| thing[q] = piece[q] if thing[q].nil? || thing[q].empty? }
|
|
385
386
|
|
|
386
387
|
# Other accessors
|
|
387
|
-
thing['bogus'] =
|
|
388
|
+
thing['bogus'] = -1
|
|
388
389
|
thing['catch'] = piece['catch'] || nil
|
|
389
390
|
thing["feedbackid"] = ""
|
|
390
391
|
thing['hardbounce'] = piece['hardbounce']
|
|
391
392
|
thing['replycode'] = Sisimai::SMTP::Reply.find(piece['diagnosticcode']) if thing['replycode'].empty?
|
|
392
393
|
thing['timestamp'] = TimeModule.parse(::Time.at(piece['timestamp']).to_s)
|
|
393
394
|
thing['timezoneoffset'] = piece['timezoneoffset'] || '+0000'
|
|
394
|
-
thing['toxic'] =
|
|
395
|
+
thing['toxic'] = -1
|
|
395
396
|
ea.each { |q| thing[q] = piece[q] if thing[q].empty? }
|
|
396
397
|
|
|
397
398
|
# ALIAS
|
|
@@ -422,25 +423,30 @@ module Sisimai
|
|
|
422
423
|
while true
|
|
423
424
|
if thing["reason"].empty? || RetryIndex[thing["reason"]]
|
|
424
425
|
# The value of "reason" is empty or is needed to check with other values again
|
|
425
|
-
re = thing["reason"].empty? ?
|
|
426
|
+
re = thing["reason"].empty? ? Sisimai::Eb::Re___0 : thing["reason"]
|
|
426
427
|
cr = Sisimai::LDA.find(thing); if Sisimai::Reason.is_explicit(cr) then thing["reason"] = cr; break; end
|
|
427
428
|
cr = Sisimai::Rhost.find(thing); if Sisimai::Reason.is_explicit(cr) then thing["reason"] = cr; break; end
|
|
428
429
|
cr = Sisimai::Reason.find(thing); if Sisimai::Reason.is_explicit(cr) then thing["reason"] = cr; break; end
|
|
429
|
-
thing["reason"] = thing["diagnosticcode"].size > 0 ?
|
|
430
|
+
thing["reason"] = thing["diagnosticcode"].size > 0 ? Sisimai::Eb::Re___1 : re
|
|
430
431
|
break
|
|
431
432
|
end
|
|
432
433
|
break
|
|
433
434
|
end
|
|
434
435
|
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
thing['
|
|
439
|
-
|
|
440
|
-
|
|
436
|
+
while true
|
|
437
|
+
# HARDBOUNCE: Set the value of "hardbounce", default value of "bouncebounce" is false
|
|
438
|
+
break if thing['reason'] == Sisimai::Eb::ReSENT
|
|
439
|
+
if thing['reason'] == Sisimai::Eb::ReFEED || thing['reason'] == Sisimai::Eb::ReAWAY
|
|
440
|
+
# Delete the value of ReplyCode when the Reason is "Feedback" or "Vacation"
|
|
441
|
+
thing['replycode'] = ""
|
|
442
|
+
break
|
|
443
|
+
end
|
|
444
|
+
|
|
445
|
+
# The reason is not "Delivered", or "Feedback", or "Vacation"
|
|
441
446
|
smtperrors = "#{piece['deliverystatus']} #{piece['diagnosticcode']}"
|
|
442
447
|
smtperrors = '' if smtperrors.size < 4
|
|
443
448
|
thing['hardbounce'] = Sisimai::SMTP::Failure.is_hardbounce(thing['reason'], smtperrors)
|
|
449
|
+
break
|
|
444
450
|
end
|
|
445
451
|
|
|
446
452
|
# DELIVERYSTATUS: Set a pseudo status code if the value of "deliverystatus" is empty
|
|
@@ -472,10 +478,10 @@ module Sisimai
|
|
|
472
478
|
thing['action'] = ox[2]
|
|
473
479
|
end
|
|
474
480
|
end
|
|
475
|
-
thing["action"] = ""
|
|
476
|
-
thing["action"] =
|
|
477
|
-
thing["action"] =
|
|
478
|
-
thing["action"] =
|
|
481
|
+
thing["action"] = "" if thing["action"].nil?
|
|
482
|
+
thing["action"] = Sisimai::Eb::AeSENT if thing["action"].empty? && thing["reason"] == Sisimai::Eb::ReSENT
|
|
483
|
+
thing["action"] = Sisimai::Eb::AeSTAY if thing["action"].empty? && thing["reason"] == Sisimai::Eb::ReTIME
|
|
484
|
+
thing["action"] = Sisimai::Eb::AeFAIL if thing["action"].empty? && cx[0] == "4" || cx[0] == "5"
|
|
479
485
|
|
|
480
486
|
if thing["replycode"].size > 0
|
|
481
487
|
# Fill empty values: ["SMTP Command", "DSN", "Reason"]
|
|
@@ -489,6 +495,7 @@ module Sisimai
|
|
|
489
495
|
|
|
490
496
|
# Feedback-ID: 1.us-west-2.QHuyeCQrGtIIMGKQfVdUhP9hCQR2LglVOrRamBc+Prk=:AmazonSES
|
|
491
497
|
thing["feedbackid"] = rfc822data["feedback-id"] || ""
|
|
498
|
+
thing["reason"] = thing["reason"].downcase
|
|
492
499
|
|
|
493
500
|
listoffact << Sisimai::Fact.new(thing)
|
|
494
501
|
end
|
data/lib/sisimai/lda.rb
CHANGED
|
@@ -2,6 +2,8 @@ module Sisimai
|
|
|
2
2
|
# Sisimai::LDA - Error message decoder for LDA
|
|
3
3
|
module LDA
|
|
4
4
|
class << self
|
|
5
|
+
require 'sisimai/eb'
|
|
6
|
+
|
|
5
7
|
LocalAgent = {
|
|
6
8
|
# Each error message should be a lower-cased string
|
|
7
9
|
# dovecot/src/deliver/deliver.c
|
|
@@ -19,20 +21,20 @@ module Sisimai
|
|
|
19
21
|
# Each error message should be a lower-cased string
|
|
20
22
|
"dovecot" => {
|
|
21
23
|
# dovecot/src/deliver/mail-send.c:94
|
|
22
|
-
|
|
24
|
+
Sisimai::Eb::ReFULL => [
|
|
23
25
|
"not enough disk space",
|
|
24
26
|
"quota exceeded", # Dovecot 1.2 dovecot/src/plugins/quota/quota.c
|
|
25
27
|
"quota exceeded (mailbox for user is full)", # dovecot/src/plugins/quota/quota.c
|
|
26
28
|
],
|
|
27
|
-
|
|
29
|
+
Sisimai::Eb::ReUSER => ["mailbox doesn't exist: "],
|
|
28
30
|
},
|
|
29
31
|
"mail.local" => {
|
|
30
|
-
|
|
32
|
+
Sisimai::Eb::ReFULL => [
|
|
31
33
|
"disc quota exceeded",
|
|
32
34
|
"mailbox full or quota exceeded",
|
|
33
35
|
],
|
|
34
|
-
|
|
35
|
-
|
|
36
|
+
Sisimai::Eb::RePROC => ["temporary file write error"],
|
|
37
|
+
Sisimai::Eb::ReUSER => [
|
|
36
38
|
": invalid mailbox path",
|
|
37
39
|
": unknown user:",
|
|
38
40
|
": user missing home directory",
|
|
@@ -40,23 +42,23 @@ module Sisimai
|
|
|
40
42
|
],
|
|
41
43
|
},
|
|
42
44
|
"procmail" => {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
45
|
+
Sisimai::Eb::ReFULL => ["quota exceeded while writing", "user over quota"],
|
|
46
|
+
Sisimai::Eb::RePROC => ["service unavailable"],
|
|
47
|
+
Sisimai::Eb::ReDISK => ["no space left to finish writing"],
|
|
46
48
|
},
|
|
47
49
|
"maildrop" => {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
+
Sisimai::Eb::ReUSER => ["cannot find system user", "invalid user specified."],
|
|
51
|
+
Sisimai::Eb::ReFULL => ["maildir over quota."],
|
|
50
52
|
},
|
|
51
53
|
"vpopmail" => {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
54
|
+
Sisimai::Eb::ReFILT => ["user does not exist, but will deliver to "],
|
|
55
|
+
Sisimai::Eb::ReFULL => ["domain is over quota", "user is over quota"],
|
|
56
|
+
Sisimai::Eb::ReQUIT => ["account is locked email bounced"],
|
|
57
|
+
Sisimai::Eb::ReUSER => ["sorry, no mailbox here by that name."],
|
|
56
58
|
},
|
|
57
59
|
"vmailmgr" => {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
+
Sisimai::Eb::ReFULL => ["delivery failed due to system quota violation"],
|
|
61
|
+
Sisimai::Eb::ReUSER => [
|
|
60
62
|
"invalid or unknown base user or domain",
|
|
61
63
|
"invalid or unknown virtual user",
|
|
62
64
|
"user name does not refer to a virtual user",
|
|
@@ -70,7 +72,7 @@ module Sisimai
|
|
|
70
72
|
def find(argvs)
|
|
71
73
|
return "" if argvs.nil?
|
|
72
74
|
return "" if argvs["diagnosticcode"].empty?
|
|
73
|
-
return "" if argvs["command"] != "" && argvs["command"] !=
|
|
75
|
+
return "" if argvs["command"] != "" && argvs["command"] != Sisimai::Eb::CeDATA
|
|
74
76
|
|
|
75
77
|
deliversby = "" # [String] Local Delivery Agent name
|
|
76
78
|
reasontext = "" # [String] Error reason
|
|
@@ -89,7 +91,7 @@ module Sisimai
|
|
|
89
91
|
reasontext = e; break
|
|
90
92
|
end
|
|
91
93
|
|
|
92
|
-
reasontext =
|
|
94
|
+
reasontext = Sisimai::Eb::ReUNIX if reasontext.empty?
|
|
93
95
|
return reasontext
|
|
94
96
|
end
|
|
95
97
|
end
|
|
@@ -42,16 +42,17 @@ module Sisimai::Lhost
|
|
|
42
42
|
# Transient/ContentRejected -- message you sent contains content that the provider doesn't allow
|
|
43
43
|
# Transient/AttachmentRejected the message contained an unacceptable attachment
|
|
44
44
|
class << self
|
|
45
|
+
require 'sisimai/eb'
|
|
45
46
|
require 'sisimai/lhost'
|
|
46
47
|
|
|
47
48
|
ReasonPair = {
|
|
48
|
-
"Suppressed" =>
|
|
49
|
-
"OnAccountSuppressionList" =>
|
|
50
|
-
"General" =>
|
|
51
|
-
"MailboxFull" =>
|
|
52
|
-
"MessageTooLarge" =>
|
|
53
|
-
"ContentRejected" =>
|
|
54
|
-
"AttachmentRejected" =>
|
|
49
|
+
"Suppressed" => Sisimai::Eb::ReSTOP,
|
|
50
|
+
"OnAccountSuppressionList" => Sisimai::Eb::ReSTOP,
|
|
51
|
+
"General" => Sisimai::Eb::Re___1,
|
|
52
|
+
"MailboxFull" => Sisimai::Eb::ReFULL,
|
|
53
|
+
"MessageTooLarge" => Sisimai::Eb::ReSIZE,
|
|
54
|
+
"ContentRejected" => Sisimai::Eb::ReBODY,
|
|
55
|
+
"AttachmentRejected" => Sisimai::Eb::ReSAFE,
|
|
55
56
|
}.freeze
|
|
56
57
|
|
|
57
58
|
# @abstract Decodes the bounce message from Amazon SES
|
|
@@ -164,7 +165,7 @@ module Sisimai::Lhost
|
|
|
164
165
|
v = dscontents[-1]
|
|
165
166
|
end
|
|
166
167
|
v["recipient"] = e["emailAddress"]
|
|
167
|
-
v["reason"] =
|
|
168
|
+
v["reason"] = Sisimai::Eb::ReFEED
|
|
168
169
|
v["feedbacktype"] = p["complaintFeedbackType"]
|
|
169
170
|
v["date"] = p["timestamp"]
|
|
170
171
|
v["diagnosis"] = sprintf('"feedbackid":"%s", "useragent":"%s"}', p["feedbackId"], p["userAgent"])
|
|
@@ -181,8 +182,8 @@ module Sisimai::Lhost
|
|
|
181
182
|
v = dscontents[-1]
|
|
182
183
|
end
|
|
183
184
|
v["recipient"] = e
|
|
184
|
-
v["reason"] =
|
|
185
|
-
v["action"] =
|
|
185
|
+
v["reason"] = Sisimai::Eb::ReSENT
|
|
186
|
+
v["action"] = Sisimai::Eb::AeSENT
|
|
186
187
|
v["date"] = p["timestamp"]
|
|
187
188
|
v["lhost"] = Sisimai::RFC1123.find(p["reportingMTA"])
|
|
188
189
|
v["diagnosis"] = p["smtpResponse"]
|
|
@@ -3,6 +3,7 @@ module Sisimai::Lhost
|
|
|
3
3
|
# Methods in the module are called from only Sisimai::Message.
|
|
4
4
|
module Courier
|
|
5
5
|
class << self
|
|
6
|
+
require 'sisimai/eb'
|
|
6
7
|
require 'sisimai/lhost'
|
|
7
8
|
|
|
8
9
|
# https://www.courier-mta.org/courierdsn.html
|
|
@@ -14,12 +15,12 @@ module Sisimai::Lhost
|
|
|
14
15
|
}.freeze
|
|
15
16
|
MessagesOf = {
|
|
16
17
|
# courier/module.esmtp/esmtpclient.c:526| hard_error(del, ctf, "No such domain.");
|
|
17
|
-
|
|
18
|
+
Sisimai::Eb::ReHOST => ['No such domain.'],
|
|
18
19
|
# courier/module.esmtp/esmtpclient.c:531| hard_error(del, ctf,
|
|
19
20
|
# courier/module.esmtp/esmtpclient.c:532| "This domain's DNS violates RFC 1035.");
|
|
20
|
-
|
|
21
|
+
Sisimai::Eb::RePROC => ["This domain's DNS violates RFC 1035."],
|
|
21
22
|
# courier/module.esmtp/esmtpclient.c:535| soft_error(del, ctf, "DNS lookup failed.");
|
|
22
|
-
|
|
23
|
+
Sisimai::Eb::ReINET => ['DNS lookup failed.'],
|
|
23
24
|
}.freeze
|
|
24
25
|
|
|
25
26
|
# @abstract Decodes the bounce message from Courier MTA
|
data/lib/sisimai/lhost/domino.rb
CHANGED
|
@@ -3,13 +3,14 @@ module Sisimai::Lhost
|
|
|
3
3
|
# Methods in the module are called from only Sisimai::Message.
|
|
4
4
|
module Domino
|
|
5
5
|
class << self
|
|
6
|
+
require 'sisimai/eb'
|
|
6
7
|
require 'sisimai/lhost'
|
|
7
8
|
|
|
8
9
|
Indicators = Sisimai::Lhost.INDICATORS
|
|
9
10
|
Boundaries = ['Content-Type: message/rfc822'].freeze
|
|
10
11
|
StartingOf = {message: ['Your message']}.freeze
|
|
11
12
|
MessagesOf = {
|
|
12
|
-
|
|
13
|
+
Sisimai::Eb::ReUSER => [
|
|
13
14
|
"not listed in Domino Directory",
|
|
14
15
|
"not listed in public Name & Address Book",
|
|
15
16
|
"non répertorié dans l'annuaire Domino",
|
|
@@ -3,6 +3,7 @@ module Sisimai::Lhost
|
|
|
3
3
|
# Methods in the module are called from only Sisimai::Message.
|
|
4
4
|
module EinsUndEins
|
|
5
5
|
class << self
|
|
6
|
+
require 'sisimai/eb'
|
|
6
7
|
require 'sisimai/lhost'
|
|
7
8
|
|
|
8
9
|
Indicators = Sisimai::Lhost.INDICATORS
|
|
@@ -90,8 +91,8 @@ module Sisimai::Lhost
|
|
|
90
91
|
p2 = e['diagnosis'].index(' reason:')
|
|
91
92
|
|
|
92
93
|
e['rhost'] = e['diagnosis'][p1 + 6, p2 - p1 - 6]
|
|
93
|
-
e['command'] =
|
|
94
|
-
e['spec'] = 'SMTP'
|
|
94
|
+
e['command'] = Sisimai::Eb::CeDATA if e['diagnosis'].include?('for TEXT command')
|
|
95
|
+
e['spec'] = 'SMTP' if e['diagnosis'].include?('SMTP error')
|
|
95
96
|
e['status'] = Sisimai::SMTP::Status.find(e['diagnosis'])
|
|
96
97
|
else
|
|
97
98
|
# For the following reason:
|
|
@@ -4,6 +4,7 @@ module Sisimai::Lhost
|
|
|
4
4
|
# Methods in the module are called from only Sisimai::Message.
|
|
5
5
|
module Exchange2003
|
|
6
6
|
class << self
|
|
7
|
+
require 'sisimai/eb'
|
|
7
8
|
require 'sisimai/lhost'
|
|
8
9
|
|
|
9
10
|
Indicators = Sisimai::Lhost.INDICATORS
|
|
@@ -13,29 +14,29 @@ module Sisimai::Lhost
|
|
|
13
14
|
error: ['did not reach the following recipient(s):'],
|
|
14
15
|
}.freeze
|
|
15
16
|
ErrorCodes = {
|
|
16
|
-
|
|
17
|
+
Sisimai::Eb::Re___1 => [
|
|
17
18
|
'000B099C', # Host Unknown, Message exceeds size limit, ...
|
|
18
19
|
'000B09AA', # Unable to relay for, Message exceeds size limit,...
|
|
19
20
|
'000B09B6', # Error messages by remote MTA
|
|
20
21
|
],
|
|
21
|
-
|
|
22
|
+
Sisimai::Eb::ReUSER => [
|
|
22
23
|
'000C05A6', # Unknown Recipient,
|
|
23
24
|
],
|
|
24
|
-
|
|
25
|
+
Sisimai::Eb::RePROC => [
|
|
25
26
|
'00010256', # Too many recipients.
|
|
26
27
|
'000D06B5', # No proxy for recipient (non-smtp mail?)
|
|
27
28
|
],
|
|
28
|
-
|
|
29
|
+
Sisimai::Eb::ReINET => [
|
|
29
30
|
'00120270', # Too Many Hops
|
|
30
31
|
],
|
|
31
|
-
|
|
32
|
+
Sisimai::Eb::ReBODY => [
|
|
32
33
|
'00050311', # Conversion to Internet format failed
|
|
33
34
|
'000502CC', # Conversion to Internet format failed
|
|
34
35
|
],
|
|
35
|
-
|
|
36
|
+
Sisimai::Eb::ReSAFE => [
|
|
36
37
|
'000B0981', # 502 Server does not support AUTH
|
|
37
38
|
],
|
|
38
|
-
|
|
39
|
+
Sisimai::Eb::ReFILT => [
|
|
39
40
|
'000C0595', # Ambiguous Recipient
|
|
40
41
|
],
|
|
41
42
|
}.freeze
|
|
@@ -4,6 +4,7 @@ module Sisimai::Lhost
|
|
|
4
4
|
# Methods in the module are called from only Sisimai::Message.
|
|
5
5
|
module Exchange2007
|
|
6
6
|
class << self
|
|
7
|
+
require 'sisimai/eb'
|
|
7
8
|
require 'sisimai/lhost'
|
|
8
9
|
|
|
9
10
|
Indicators = Sisimai::Lhost.INDICATORS
|
|
@@ -32,19 +33,19 @@ module Sisimai::Lhost
|
|
|
32
33
|
]
|
|
33
34
|
}.freeze
|
|
34
35
|
NDRSubject = {
|
|
35
|
-
"SMTPSEND.DNS.NonExistentDomain" =>
|
|
36
|
-
"SMTPSEND.DNS.MxLoopback" =>
|
|
37
|
-
"RESOLVER.ADR.BadPrimary" =>
|
|
38
|
-
"RESOLVER.ADR.RecipNotFound" =>
|
|
39
|
-
"RESOLVER.ADR.RecipientNotFound" =>
|
|
40
|
-
"RESOLVER.ADR.ExRecipNotFound" =>
|
|
41
|
-
"RESOLVER.ADR.RecipLimit" =>
|
|
42
|
-
"RESOLVER.ADR.InvalidInSmtp" =>
|
|
43
|
-
"RESOLVER.ADR.Ambiguous" =>
|
|
44
|
-
"RESOLVER.RST.AuthRequired" =>
|
|
45
|
-
"RESOLVER.RST.NotAuthorized" =>
|
|
46
|
-
"RESOLVER.RST.RecipSizeLimit" =>
|
|
47
|
-
"QUEUE.Expired" =>
|
|
36
|
+
"SMTPSEND.DNS.NonExistentDomain" => Sisimai::Eb::ReHOST, # 554 5.4.4 SMTPSEND.DNS.NonExistentDomain
|
|
37
|
+
"SMTPSEND.DNS.MxLoopback" => Sisimai::Eb::ReINET, # 554 5.4.4 SMTPSEND.DNS.MxLoopback
|
|
38
|
+
"RESOLVER.ADR.BadPrimary" => Sisimai::Eb::RePROC, # 550 5.2.0 RESOLVER.ADR.BadPrimary
|
|
39
|
+
"RESOLVER.ADR.RecipNotFound" => Sisimai::Eb::ReUSER, # 550 5.1.1 RESOLVER.ADR.RecipNotFound
|
|
40
|
+
"RESOLVER.ADR.RecipientNotFound" => Sisimai::Eb::ReUSER, # 550 5.1.1 RESOLVER.ADR.RecipientNotFound
|
|
41
|
+
"RESOLVER.ADR.ExRecipNotFound" => Sisimai::Eb::ReUSER, # 550 5.1.1 RESOLVER.ADR.ExRecipNotFound
|
|
42
|
+
"RESOLVER.ADR.RecipLimit" => Sisimai::Eb::ReRATE, # 550 5.5.3 RESOLVER.ADR.RecipLimit
|
|
43
|
+
"RESOLVER.ADR.InvalidInSmtp" => Sisimai::Eb::RePROC, # 550 5.1.0 RESOLVER.ADR.InvalidInSmtp
|
|
44
|
+
"RESOLVER.ADR.Ambiguous" => Sisimai::Eb::RePROC, # 550 5.1.4 RESOLVER.ADR.Ambiguous, 420 4.2.0 RESOLVER.ADR.Ambiguous
|
|
45
|
+
"RESOLVER.RST.AuthRequired" => Sisimai::Eb::ReSAFE, # 550 5.7.1 RESOLVER.RST.AuthRequired
|
|
46
|
+
"RESOLVER.RST.NotAuthorized" => Sisimai::Eb::ReFROM, # 550 5.7.1 RESOLVER.RST.NotAuthorized
|
|
47
|
+
"RESOLVER.RST.RecipSizeLimit" => Sisimai::Eb::ReSIZE, # 550 5.2.3 RESOLVER.RST.RecipSizeLimit
|
|
48
|
+
"QUEUE.Expired" => Sisimai::Eb::ReTIME, # 550 4.4.7 QUEUE.Expired
|
|
48
49
|
}.freeze
|
|
49
50
|
MailSender = ["postmaster@outlook.com", ".onmicrosoft.com"].freeze
|
|
50
51
|
EmailTitle = [
|