sisimai 5.5.0 → 5.7.0
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/.github/workflows/rake-test.yml +0 -4
- data/ChangeLog.md +53 -0
- data/LICENSE +1 -1
- data/README-JA.md +26 -20
- data/README.md +30 -25
- data/lib/sisimai/address.rb +8 -31
- data/lib/sisimai/arf.rb +3 -5
- data/lib/sisimai/fact.rb +26 -36
- data/lib/sisimai/lhost/activehunter.rb +0 -2
- data/lib/sisimai/lhost/amazonses.rb +7 -9
- data/lib/sisimai/lhost/apachejames.rb +0 -1
- data/lib/sisimai/lhost/biglobe.rb +0 -16
- data/lib/sisimai/lhost/courier.rb +5 -4
- data/lib/sisimai/lhost/deutschetelekom.rb +120 -0
- data/lib/sisimai/lhost/domino.rb +0 -3
- data/lib/sisimai/lhost/dragonfly.rb +0 -27
- data/lib/sisimai/lhost/einsundeins.rb +1 -10
- data/lib/sisimai/lhost/exchange2003.rb +4 -4
- data/lib/sisimai/lhost/exchange2007.rb +5 -6
- data/lib/sisimai/lhost/exim.rb +35 -85
- data/lib/sisimai/lhost/ezweb.rb +12 -49
- data/lib/sisimai/lhost/fml.rb +4 -29
- data/lib/sisimai/lhost/gmail.rb +0 -23
- data/lib/sisimai/lhost/gmx.rb +7 -24
- data/lib/sisimai/lhost/googlegroups.rb +3 -3
- data/lib/sisimai/lhost/googleworkspace.rb +0 -4
- data/lib/sisimai/lhost/imailserver.rb +3 -9
- data/lib/sisimai/lhost/kddi.rb +6 -20
- data/lib/sisimai/lhost/mailfoundry.rb +0 -2
- data/lib/sisimai/lhost/mailmarshal.rb +1 -3
- data/lib/sisimai/lhost/messagingserver.rb +4 -15
- data/lib/sisimai/lhost/mfilter.rb +0 -1
- data/lib/sisimai/lhost/mimecast.rb +0 -1
- data/lib/sisimai/lhost/notes.rb +1 -2
- data/lib/sisimai/lhost/opensmtpd.rb +0 -40
- data/lib/sisimai/lhost/postfix.rb +10 -11
- data/lib/sisimai/lhost/qmail.rb +14 -81
- data/lib/sisimai/lhost/sendmail.rb +4 -4
- data/lib/sisimai/lhost/trendmicro.rb +3 -3
- data/lib/sisimai/lhost/v5sendmail.rb +0 -1
- data/lib/sisimai/lhost/verizon.rb +1 -2
- data/lib/sisimai/lhost/x1.rb +1 -2
- data/lib/sisimai/lhost/x2.rb +0 -2
- data/lib/sisimai/lhost/x3.rb +4 -9
- data/lib/sisimai/lhost/x6.rb +0 -1
- data/lib/sisimai/lhost/zoho.rb +0 -12
- data/lib/sisimai/lhost.rb +38 -19
- data/lib/sisimai/message.rb +3 -1
- data/lib/sisimai/order.rb +4 -1
- data/lib/sisimai/reason/authfailure.rb +9 -13
- data/lib/sisimai/reason/badreputation.rb +7 -7
- data/lib/sisimai/reason/blocked.rb +57 -83
- data/lib/sisimai/reason/contenterror.rb +16 -8
- data/lib/sisimai/reason/{mesgtoobig.rb → emailtoolarge.rb} +22 -25
- data/lib/sisimai/reason/expired.rb +27 -23
- data/lib/sisimai/reason/filtered.rb +13 -17
- data/lib/sisimai/reason/hasmoved.rb +2 -1
- data/lib/sisimai/reason/hostunknown.rb +25 -19
- data/lib/sisimai/reason/mailboxfull.rb +28 -49
- data/lib/sisimai/reason/networkerror.rb +28 -16
- data/lib/sisimai/reason/norelaying.rb +21 -20
- data/lib/sisimai/reason/notaccept.rb +13 -8
- data/lib/sisimai/reason/notcompliantrfc.rb +6 -9
- data/lib/sisimai/reason/policyviolation.rb +17 -26
- data/lib/sisimai/reason/ratelimited.rb +62 -0
- data/lib/sisimai/reason/rejected.rb +51 -59
- data/lib/sisimai/reason/requireptr.rb +13 -25
- data/lib/sisimai/reason/securityerror.rb +14 -19
- data/lib/sisimai/reason/spamdetected.rb +51 -101
- data/lib/sisimai/reason/suspend.rb +30 -24
- data/lib/sisimai/reason/syntaxerror.rb +1 -8
- data/lib/sisimai/reason/systemerror.rb +37 -23
- data/lib/sisimai/reason/systemfull.rb +1 -1
- data/lib/sisimai/reason/userunknown.rb +81 -112
- data/lib/sisimai/reason/virusdetected.rb +6 -8
- data/lib/sisimai/reason.rb +15 -15
- data/lib/sisimai/rfc1123.rb +1 -1
- data/lib/sisimai/rfc1894.rb +7 -6
- data/lib/sisimai/rfc2045.rb +2 -2
- data/lib/sisimai/rfc3464/thirdparty.rb +1 -1
- data/lib/sisimai/rfc3464.rb +10 -14
- data/lib/sisimai/rfc3834.rb +3 -4
- data/lib/sisimai/rfc791.rb +3 -38
- data/lib/sisimai/rhost/apple.rb +5 -5
- data/lib/sisimai/rhost/cloudflare.rb +2 -0
- data/lib/sisimai/rhost/cox.rb +22 -20
- data/lib/sisimai/rhost/facebook.rb +16 -16
- data/lib/sisimai/rhost/franceptt.rb +8 -3
- data/lib/sisimai/rhost/godaddy.rb +33 -15
- data/lib/sisimai/rhost/google.rb +63 -64
- data/lib/sisimai/rhost/iua.rb +1 -1
- data/lib/sisimai/rhost/messagelabs.rb +12 -12
- data/lib/sisimai/rhost/microsoft.rb +86 -86
- data/lib/sisimai/rhost/mimecast.rb +34 -34
- data/lib/sisimai/rhost/nttdocomo.rb +2 -2
- data/lib/sisimai/rhost/spectrum.rb +7 -7
- data/lib/sisimai/rhost/tencent.rb +9 -11
- data/lib/sisimai/rhost/yahooinc.rb +7 -8
- data/lib/sisimai/rhost.rb +1 -1
- data/lib/sisimai/smtp/command.rb +2 -0
- data/lib/sisimai/smtp/status.rb +73 -109
- data/lib/sisimai/string.rb +0 -27
- data/lib/sisimai/version.rb +1 -1
- data/set-of-emails/maildir/bsd/lhost-deutschetelekom-01.eml +66 -0
- data/set-of-emails/maildir/bsd/lhost-deutschetelekom-02.eml +68 -0
- data/set-of-emails/maildir/bsd/lhost-deutschetelekom-03.eml +50 -0
- data/set-of-emails/should-not-crash/p5-664-iomart-mail-filter.eml +258 -0
- data/set-of-emails/to-be-debugged-because/sisimai-cannot-parse-yet/.gitkeep +0 -0
- metadata +10 -6
- data/lib/sisimai/reason/exceedlimit.rb +0 -47
- data/lib/sisimai/reason/speeding.rb +0 -47
- data/lib/sisimai/reason/toomanyconn.rb +0 -59
data/lib/sisimai/lhost/qmail.rb
CHANGED
|
@@ -66,59 +66,9 @@ module Sisimai::Lhost
|
|
|
66
66
|
"DATA" => [" failed on DATA command", " failed after I sent the message"],
|
|
67
67
|
}.freeze
|
|
68
68
|
|
|
69
|
-
# qmail-send.c:922| ... (&dline[c],"I'm not going to try again; this message has been in the queue too long.\n")) nomem();
|
|
70
|
-
# qmail-remote-fallback.patch
|
|
71
|
-
HasExpired = "this message has been in the queue too long.".freeze
|
|
72
|
-
OnHoldPair = [" does not like recipient.", "this message has been in the queue too long."].freeze
|
|
73
|
-
FailOnLDAP = {
|
|
74
|
-
# qmail-ldap-1.03-20040101.patch:19817 - 19866
|
|
75
|
-
"exceedlimit" => ["The message exeeded the maximum size the user accepts"], # 5.2.3
|
|
76
|
-
"userunknown" => ["Sorry, no mailbox here by that name"], # 5.1.1
|
|
77
|
-
"suspend" => [ # 5.2.1
|
|
78
|
-
"Mailaddress is administrativly disabled",
|
|
79
|
-
"Mailaddress is administrativley disabled",
|
|
80
|
-
"Mailaddress is administratively disabled",
|
|
81
|
-
"Mailaddress is administrativeley disabled",
|
|
82
|
-
],
|
|
83
|
-
"systemerror" => [
|
|
84
|
-
"Automatic homedir creator crashed", # 4.3.0
|
|
85
|
-
"Illegal value in LDAP attribute", # 5.3.5
|
|
86
|
-
"LDAP attribute is not given but mandatory", # 5.3.5
|
|
87
|
-
"Timeout while performing search on LDAP server", # 4.4.3
|
|
88
|
-
"Too many results returned but needs to be unique", # 5.3.5
|
|
89
|
-
"Permanent error while executing qmail-forward", # 5.4.4
|
|
90
|
-
"Temporary error in automatic homedir creation", # 4.3.0 or 5.3.0
|
|
91
|
-
"Temporary error while executing qmail-forward", # 4.4.4
|
|
92
|
-
"Temporary failure in LDAP lookup", # 4.4.3
|
|
93
|
-
"Unable to contact LDAP server", # 4.4.3
|
|
94
|
-
"Unable to login into LDAP server, bad credentials",# 4.4.3
|
|
95
|
-
],
|
|
96
|
-
}.freeze
|
|
97
69
|
MessagesOf = {
|
|
98
|
-
#
|
|
99
|
-
|
|
100
|
-
"hostunknown" => ["Sorry, I couldn't find any host "],
|
|
101
|
-
# error_str.c:192| X(EDQUOT,"disk quota exceeded")
|
|
102
|
-
"mailboxfull" => ["disk quota exceeded"],
|
|
103
|
-
# qmail-qmtpd.c:233| ... result = "Dsorry, that message size exceeds my databytes limit (#5.3.4)";
|
|
104
|
-
# qmail-smtpd.c:391| ... out("552 sorry, that message size exceeds my databytes limit (#5.3.4)\r\n"); return;
|
|
105
|
-
"mesgtoobig" => ["Message size exceeds fixed maximum message size:"],
|
|
106
|
-
"networkerror"=> [
|
|
107
|
-
"Sorry, I wasn't able to establish an SMTP connection",
|
|
108
|
-
"Sorry. Although I'm listed as a best-preference MX or A for that host",
|
|
109
|
-
],
|
|
110
|
-
"notaccept" => [
|
|
111
|
-
# notqmail 1.08 returns the following error message when the destination MX is NullMX
|
|
112
|
-
"Sorry, I couldn't find a mail exchanger or IP address",
|
|
113
|
-
],
|
|
114
|
-
"systemerror" => [
|
|
115
|
-
"bad interpreter: No such file or directory",
|
|
116
|
-
"system error",
|
|
117
|
-
"Unable to",
|
|
118
|
-
],
|
|
119
|
-
"systemfull" => ["Requested action not taken: mailbox unavailable (not enough free space)"],
|
|
120
|
-
# qmail-local.c:589| strerr_die1x(100,"Sorry, no mailbox here by that name. (#5.1.1)");
|
|
121
|
-
# qmail-remote.c:253| out("s"); outhost(); out(" does not like recipient.\n");
|
|
70
|
+
# notqmail 1.08 returns the following error message when the destination MX is NullMX
|
|
71
|
+
"notaccept" => ["Sorry, I couldn't find a mail exchanger or IP address"],
|
|
122
72
|
"userunknown" => ["no mailbox here by that name"],
|
|
123
73
|
}.freeze
|
|
124
74
|
|
|
@@ -186,7 +136,7 @@ module Sisimai::Lhost
|
|
|
186
136
|
cm = r.size
|
|
187
137
|
p2 = e.index(" ", p1 + cm + 1) || p2 = e.rindex(".")
|
|
188
138
|
|
|
189
|
-
v["rhost"] =
|
|
139
|
+
v["rhost"] = e[p1 + cm, p2 - p1 - cm]
|
|
190
140
|
break
|
|
191
141
|
end
|
|
192
142
|
end
|
|
@@ -194,9 +144,6 @@ module Sisimai::Lhost
|
|
|
194
144
|
return nil if recipients == 0
|
|
195
145
|
|
|
196
146
|
dscontents.each do |e|
|
|
197
|
-
# Tidy up the error message in e['diagnosis'], Try to detect the bounce reason.
|
|
198
|
-
e["diagnosis"] = Sisimai::String.sweep(e["diagnosis"])
|
|
199
|
-
|
|
200
147
|
# Get the SMTP command name for the session
|
|
201
148
|
CommandSet.each_key do |r|
|
|
202
149
|
# Get the last SMTP command
|
|
@@ -216,32 +163,18 @@ module Sisimai::Lhost
|
|
|
216
163
|
e["reason"] = "blocked"
|
|
217
164
|
else
|
|
218
165
|
# Try to match with each error message in the table
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
#
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
# The key is a bounce reason name
|
|
230
|
-
next if MessagesOf[r].none? { |a| f.include?(a) }
|
|
231
|
-
e["reason"] = r
|
|
232
|
-
break
|
|
233
|
-
end
|
|
234
|
-
break if e["reason"]
|
|
235
|
-
|
|
236
|
-
FailOnLDAP.each_key do |r|
|
|
237
|
-
# The key is a bounce reason name
|
|
238
|
-
next if FailOnLDAP[r].none? { |a| f.include?(a) }
|
|
239
|
-
e["reason"] = r
|
|
240
|
-
break
|
|
241
|
-
end
|
|
242
|
-
break if e["reason"]
|
|
243
|
-
e["reason"] = "expired" if e["diagnosis"].include?(HasExpired)
|
|
166
|
+
# Check that the error message includes any of message patterns or not
|
|
167
|
+
[e["alterrors"], e["diagnosis"]].each do |f|
|
|
168
|
+
# Try to detect an error reason
|
|
169
|
+
break if e["reason"] != ""
|
|
170
|
+
next if f.nil?
|
|
171
|
+
MessagesOf.each_key do |r|
|
|
172
|
+
# The key is a bounce reason name
|
|
173
|
+
next if MessagesOf[r].none? { |a| f.include?(a) }
|
|
174
|
+
e["reason"] = r
|
|
175
|
+
break
|
|
244
176
|
end
|
|
177
|
+
break if e["reason"]
|
|
245
178
|
end
|
|
246
179
|
end
|
|
247
180
|
|
|
@@ -67,7 +67,8 @@ module Sisimai::Lhost
|
|
|
67
67
|
o = Sisimai::RFC1894.field(e) || next
|
|
68
68
|
v = dscontents[-1]
|
|
69
69
|
|
|
70
|
-
|
|
70
|
+
case o[3]
|
|
71
|
+
when "addr"
|
|
71
72
|
# Final-Recipient: rfc822; kijitora@example.jp
|
|
72
73
|
# X-Actual-Recipient: rfc822; kijitora@example.co.jp
|
|
73
74
|
if o[0] == 'final-recipient'
|
|
@@ -83,7 +84,7 @@ module Sisimai::Lhost
|
|
|
83
84
|
# X-Actual-Recipient: rfc822; kijitora@example.co.jp
|
|
84
85
|
v['alias'] = o[2]
|
|
85
86
|
end
|
|
86
|
-
|
|
87
|
+
when "code"
|
|
87
88
|
# Diagnostic-Code: SMTP; 550 5.1.1 <userunknown@example.jp>... User Unknown
|
|
88
89
|
v['spec'] = o[1]
|
|
89
90
|
v['diagnosis'] = o[2]
|
|
@@ -159,7 +160,7 @@ module Sisimai::Lhost
|
|
|
159
160
|
# Continued line of the value of Diagnostic-Code field
|
|
160
161
|
next if readslices[-2].start_with?('Diagnostic-Code:') == false
|
|
161
162
|
next if e.start_with?(' ') == false
|
|
162
|
-
v['diagnosis'] += "
|
|
163
|
+
v['diagnosis'] += " " + e
|
|
163
164
|
readslices[-1] = "Diagnostic-Code: #{e}"
|
|
164
165
|
end
|
|
165
166
|
end
|
|
@@ -186,7 +187,6 @@ module Sisimai::Lhost
|
|
|
186
187
|
break
|
|
187
188
|
end
|
|
188
189
|
|
|
189
|
-
e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
|
|
190
190
|
e["command"] = thecommand if e["command"].empty?
|
|
191
191
|
e["command"] = Sisimai::SMTP::Command.find(e['diagnosis']) if e["command"].empty?
|
|
192
192
|
e["command"] = "EHLO" if e["command"].empty? && esmtpreply.size > 0
|
|
@@ -55,11 +55,12 @@ module Sisimai::Lhost
|
|
|
55
55
|
recipients = dscontents.size
|
|
56
56
|
end
|
|
57
57
|
|
|
58
|
-
|
|
58
|
+
case
|
|
59
|
+
when e.start_with?('Sent <<< ')
|
|
59
60
|
# Sent <<< RCPT TO:<kijitora@example.co.jp>
|
|
60
61
|
v['command'] = Sisimai::SMTP::Command.find(e)
|
|
61
62
|
|
|
62
|
-
|
|
63
|
+
when e.start_with?('Received >>> ')
|
|
63
64
|
# Received >>> 550 5.1.1 <kijitora@example.co.jp>... user unknown
|
|
64
65
|
v['diagnosis'] = e[e.index(' >>> ') + 4, e.size]
|
|
65
66
|
else
|
|
@@ -72,7 +73,6 @@ module Sisimai::Lhost
|
|
|
72
73
|
return nil if recipients == 0
|
|
73
74
|
|
|
74
75
|
dscontents.each do |e|
|
|
75
|
-
e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
|
|
76
76
|
e['reason'] = 'userunknown' if e['diagnosis'].include?('Unable to deliver')
|
|
77
77
|
end
|
|
78
78
|
return { 'ds' => dscontents, 'rfc822' => emailparts[1] }
|
|
@@ -161,7 +161,6 @@ module Sisimai::Lhost
|
|
|
161
161
|
j = 0; dscontents.each do |e|
|
|
162
162
|
# Tidy up the error message in e.Diagnosis
|
|
163
163
|
e["diagnosis"] = anotherone[j] if e["diagnosis"].empty?
|
|
164
|
-
e["diagnosis"] = Sisimai::String.sweep(e["diagnosis"])
|
|
165
164
|
e["command"] = Sisimai::SMTP::Command.find(e["diagnosis"]) if e["command"].empty?
|
|
166
165
|
e["replycode"] = Sisimai::SMTP::Reply.find(e["diagnosis"])
|
|
167
166
|
e["replycode"] = Sisimai::SMTP::Reply.find(anotherone[j]) if e["replycode"].empty?
|
|
@@ -126,7 +126,7 @@ module Sisimai::Lhost
|
|
|
126
126
|
else
|
|
127
127
|
# Message could not be delivered to mobile.
|
|
128
128
|
# Error: No valid recipients for this MM
|
|
129
|
-
v['diagnosis'] =
|
|
129
|
+
v['diagnosis'] = e[7, e.size] if e.start_with?('Error: ')
|
|
130
130
|
end
|
|
131
131
|
end
|
|
132
132
|
end
|
|
@@ -137,7 +137,6 @@ module Sisimai::Lhost
|
|
|
137
137
|
emailparts[1] += "Subject: #{subjecttxt}\n" if emailparts[1].include?("\nSubject: ") == false
|
|
138
138
|
|
|
139
139
|
dscontents.each do |e|
|
|
140
|
-
e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
|
|
141
140
|
messagesof.each_key do |r|
|
|
142
141
|
# Verify each regular expression of session errors
|
|
143
142
|
next if messagesof[r].none? { |a| e['diagnosis'].include?(a) }
|
data/lib/sisimai/lhost/x1.rb
CHANGED
|
@@ -67,8 +67,7 @@ module Sisimai::Lhost
|
|
|
67
67
|
return nil if recipients == 0
|
|
68
68
|
|
|
69
69
|
dscontents.each do |e|
|
|
70
|
-
e['
|
|
71
|
-
e['date'] = datestring || ''
|
|
70
|
+
e['date'] = datestring || ''
|
|
72
71
|
end
|
|
73
72
|
|
|
74
73
|
return {"ds" => dscontents, "rfc822" => emailparts[1]}
|
data/lib/sisimai/lhost/x2.rb
CHANGED
|
@@ -88,8 +88,6 @@ module Sisimai::Lhost
|
|
|
88
88
|
end
|
|
89
89
|
end
|
|
90
90
|
return nil if recipients == 0
|
|
91
|
-
|
|
92
|
-
dscontents.each { |e| e['diagnosis'] = Sisimai::String.sweep(e['diagnosis']) }
|
|
93
91
|
return {"ds" => dscontents, "rfc822" => emailparts[1]}
|
|
94
92
|
end
|
|
95
93
|
def description; return 'Unknown MTA #2'; end
|
data/lib/sisimai/lhost/x3.rb
CHANGED
|
@@ -64,28 +64,23 @@ module Sisimai::Lhost
|
|
|
64
64
|
recipients += 1
|
|
65
65
|
else
|
|
66
66
|
# Detect error message
|
|
67
|
-
|
|
67
|
+
case
|
|
68
|
+
when e.start_with?('SMTP:')
|
|
68
69
|
# SMTP:RCPT host 192.0.2.8: 553 5.3.0 <kijitora@example.com>... No such user here
|
|
69
70
|
v['command'] = Sisimai::SMTP::Command.find(e)
|
|
70
71
|
v['diagnosis'] = e
|
|
71
72
|
|
|
72
|
-
|
|
73
|
+
when e.start_with?('Routing: ')
|
|
73
74
|
# Routing: Could not find a gateway for kijitora@example.co.jp
|
|
74
75
|
v['diagnosis'] = e[9, e.size]
|
|
75
76
|
|
|
76
|
-
|
|
77
|
+
when e.start_with?('Diagnostic-Code: smtp; ')
|
|
77
78
|
# Diagnostic-Code: smtp; 552 5.2.2 Over quota
|
|
78
79
|
v['diagnosis'] = e[e.index(';') + 2, e.size]
|
|
79
80
|
end
|
|
80
81
|
end
|
|
81
82
|
end
|
|
82
83
|
return nil if recipients == 0
|
|
83
|
-
|
|
84
|
-
dscontents.each do |e|
|
|
85
|
-
e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
|
|
86
|
-
e['status'] = Sisimai::SMTP::Status.find(e['diagnosis'])
|
|
87
|
-
end
|
|
88
|
-
|
|
89
84
|
return {"ds" => dscontents, "rfc822" => emailparts[1]}
|
|
90
85
|
end
|
|
91
86
|
def description; return 'Unknown MTA #3'; end
|
data/lib/sisimai/lhost/x6.rb
CHANGED
data/lib/sisimai/lhost/zoho.rb
CHANGED
|
@@ -8,7 +8,6 @@ module Sisimai::Lhost
|
|
|
8
8
|
Indicators = Sisimai::Lhost.INDICATORS
|
|
9
9
|
Boundaries = ['Received: from mail.zoho.com by mx.zohomail.com'].freeze
|
|
10
10
|
StartingOf = {message: ['This message was created automatically by mail delivery']}.freeze
|
|
11
|
-
MessagesOf = {'expired' => ['Host not reachable']}.freeze
|
|
12
11
|
|
|
13
12
|
# @abstract Decodes the bounce message from Zoho Mail
|
|
14
13
|
# @param [Hash] mhead Message headers of a bounce email
|
|
@@ -88,17 +87,6 @@ module Sisimai::Lhost
|
|
|
88
87
|
end
|
|
89
88
|
end
|
|
90
89
|
return nil if recipients == 0
|
|
91
|
-
|
|
92
|
-
dscontents.each do |e|
|
|
93
|
-
e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'].tr("\n", ' '))
|
|
94
|
-
MessagesOf.each_key do |r|
|
|
95
|
-
# Verify each regular expression of session errors
|
|
96
|
-
next if MessagesOf[r].none? { |a| e['diagnosis'].include?(a) }
|
|
97
|
-
e['reason'] = r
|
|
98
|
-
break
|
|
99
|
-
end
|
|
100
|
-
end
|
|
101
|
-
|
|
102
90
|
return {"ds" => dscontents, "rfc822" => emailparts[1]}
|
|
103
91
|
end
|
|
104
92
|
def description; return 'Zoho Mail: https://www.zoho.com'; end
|
data/lib/sisimai/lhost.rb
CHANGED
|
@@ -9,21 +9,20 @@ module Sisimai
|
|
|
9
9
|
# @private
|
|
10
10
|
def DELIVERYSTATUS
|
|
11
11
|
return {
|
|
12
|
-
'spec' => "",
|
|
13
|
-
'date' => "",
|
|
14
|
-
'rhost' => "",
|
|
15
|
-
'lhost' => "",
|
|
16
|
-
'alias' => "",
|
|
17
|
-
'agent' => "",
|
|
18
|
-
'action' => "",
|
|
19
|
-
'status' => "",
|
|
20
|
-
'reason' => "",
|
|
21
|
-
'command' => "",
|
|
22
|
-
'replycode' => "",
|
|
23
|
-
'diagnosis' => "",
|
|
24
|
-
'recipient' => "",
|
|
25
|
-
'feedbacktype' => "",
|
|
26
|
-
'toxic' => false, # EXPERIMENTAL
|
|
12
|
+
'spec' => "", # Protocl specification
|
|
13
|
+
'date' => "", # The value of Last-Attempt-Date header
|
|
14
|
+
'rhost' => "", # The value of Remote-MTA header
|
|
15
|
+
'lhost' => "", # The value of Received-From-MTA header
|
|
16
|
+
'alias' => "", # The value of alias entry(RHS)
|
|
17
|
+
'agent' => "", # MTA module name
|
|
18
|
+
'action' => "", # The value of Action header
|
|
19
|
+
'status' => "", # The value of Status header
|
|
20
|
+
'reason' => "", # Temporary reason of bounce
|
|
21
|
+
'command' => "", # SMTP command in the message body
|
|
22
|
+
'replycode' => "", # SMTP Reply code
|
|
23
|
+
'diagnosis' => "", # The value of Diagnostic-Code header
|
|
24
|
+
'recipient' => "", # The value of Final-Recipient header
|
|
25
|
+
'feedbacktype' => "", # Feedback Type
|
|
27
26
|
}
|
|
28
27
|
end
|
|
29
28
|
|
|
@@ -37,14 +36,34 @@ module Sisimai
|
|
|
37
36
|
}
|
|
38
37
|
end
|
|
39
38
|
|
|
39
|
+
# @abstract Banners defined in Smail 3 and Deutsche Telekom
|
|
40
|
+
# @return [Array] Banner strings
|
|
41
|
+
# @private
|
|
42
|
+
def BannerDTAG
|
|
43
|
+
return [
|
|
44
|
+
# smail-3.2.0.108/src/
|
|
45
|
+
# notify.c:61|static char *log_banner = "\
|
|
46
|
+
# notify.c:62||------------------------- Message log follows: -------------------------|\n";
|
|
47
|
+
# notify.c:63|static char *addr_error_banner = "\
|
|
48
|
+
# notify.c:64||------------------------- Failed addresses follow: ---------------------|\n";
|
|
49
|
+
# notify.c:65|static char *text_banner = "\
|
|
50
|
+
# notify.c:66||------------------------- Message text follows: ------------------------|\n";
|
|
51
|
+
"|------------------------- Message log follows: -------------------------|", # 0. Smail 3
|
|
52
|
+
"|------------------------- Failed addresses follow: ---------------------|", # 1. Smail 3
|
|
53
|
+
"|------------------------- Message text follows: ------------------------|", # 2. Smail 3
|
|
54
|
+
"|------------------------- Message header follows: ----------------------|", # 3. Deutsche Telekom
|
|
55
|
+
# "|----------- Message text follows: (body too large, truncated) ----------|", # 4. Deutsche Telekom
|
|
56
|
+
]
|
|
57
|
+
end
|
|
58
|
+
|
|
40
59
|
# @abstract MTA list
|
|
41
60
|
# @return [Array] MTA list with order
|
|
42
61
|
def index
|
|
43
62
|
return %w[
|
|
44
|
-
Activehunter AmazonSES ApacheJames Biglobe Courier Domino DragonFly EZweb
|
|
45
|
-
Exchange2007 Exim FML GMX GoogleWorkspace GoogleGroups Gmail
|
|
46
|
-
MailMarshal MessagingServer Notes OpenSMTPD Postfix
|
|
47
|
-
X1 X2 X3 X6 Zoho MFILTER Qmail
|
|
63
|
+
Activehunter AmazonSES ApacheJames Biglobe Courier Domino DeutscheTelekom DragonFly EZweb
|
|
64
|
+
EinsUndEins Exchange2003 Exchange2007 Exim FML GMX GoogleWorkspace GoogleGroups Gmail
|
|
65
|
+
IMailServer KDDI MailFoundry Mimecast MailMarshal MessagingServer Notes OpenSMTPD Postfix
|
|
66
|
+
Sendmail TrendMicro V5sendmail Verizon X1 X2 X3 X6 Zoho MFILTER Qmail
|
|
48
67
|
]
|
|
49
68
|
end
|
|
50
69
|
|
data/lib/sisimai/message.rb
CHANGED
|
@@ -66,7 +66,7 @@ module Sisimai
|
|
|
66
66
|
# Remove "Fwd:" string from the Subject: header
|
|
67
67
|
if p1
|
|
68
68
|
# Delete quoted strings, quote symbols(>)
|
|
69
|
-
cq =
|
|
69
|
+
cq = cq[cq.index(':') + 1, cq.size]
|
|
70
70
|
aftersplit[2] = aftersplit[2].gsub(/^[>][ ]/, '').gsub(/^[>]$/, '')
|
|
71
71
|
end
|
|
72
72
|
thing['header']['subject'] = cq
|
|
@@ -297,6 +297,8 @@ module Sisimai
|
|
|
297
297
|
email += sprintf("%s: %s\n", fn, bf)
|
|
298
298
|
end
|
|
299
299
|
|
|
300
|
+
# 5. Convert the lower-cased SMTP command to the upper-cased.
|
|
301
|
+
email = email.gsub("after end of data:", "after end of DATA:")
|
|
300
302
|
email += "\n" if email.end_with?("\n\n") == false
|
|
301
303
|
return email
|
|
302
304
|
end
|
data/lib/sisimai/order.rb
CHANGED
|
@@ -11,11 +11,12 @@ module Sisimai
|
|
|
11
11
|
'Sisimai::Lhost::Sendmail',
|
|
12
12
|
'Sisimai::Lhost::Exchange2007',
|
|
13
13
|
'Sisimai::Lhost::Exchange2003',
|
|
14
|
+
'Sisimai::Lhost::AmazonSES',
|
|
14
15
|
'Sisimai::Lhost::TrendMicro',
|
|
16
|
+
'Sisimai::Lhost::DeutscheTelekom',
|
|
15
17
|
'Sisimai::Lhost::KDDI',
|
|
16
18
|
'Sisimai::Lhost::FML',
|
|
17
19
|
'Sisimai::Lhost::Verizon',
|
|
18
|
-
'Sisimai::Lhost::AmazonSES',
|
|
19
20
|
'Sisimai::Lhost::ApacheJames',
|
|
20
21
|
'Sisimai::Lhost::X2',
|
|
21
22
|
].freeze
|
|
@@ -83,8 +84,10 @@ module Sisimai
|
|
|
83
84
|
'Sisimai::Lhost::GMX',
|
|
84
85
|
'Sisimai::Lhost::Zoho',
|
|
85
86
|
'Sisimai::Lhost::EinsUndEins',
|
|
87
|
+
'Sisimai::Lhost::DeutscheTelekom',
|
|
86
88
|
],
|
|
87
89
|
'mail-could' => ['Sisimai::Lhost::TrendMicro'],
|
|
90
|
+
'mail-failed' => ['Sisimai::Lhost::DeutscheTelekom'],
|
|
88
91
|
'mail-failure' => ['Sisimai::Lhost::Exim'],
|
|
89
92
|
'mail-system' => ['Sisimai::Lhost::EZweb'],
|
|
90
93
|
'message-delivery' => ['Sisimai::Lhost::MailFoundry'],
|
|
@@ -12,23 +12,19 @@ module Sisimai
|
|
|
12
12
|
# Diagnostic-Code: smtp; 550 5.7.1 Email rejected per DMARC policy for example.org
|
|
13
13
|
module AuthFailure
|
|
14
14
|
class << self
|
|
15
|
-
require 'sisimai/string'
|
|
16
|
-
|
|
17
15
|
Index = [
|
|
18
|
-
|
|
19
|
-
'
|
|
20
|
-
|
|
16
|
+
"//spf.pobox.com",
|
|
17
|
+
"5322.From address doesn't meet the authentication requirements",
|
|
18
|
+
"bad spf records for",
|
|
19
|
+
"dmarc policy",
|
|
21
20
|
"doesn't meet the required authentication level",
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
'spf (sender policy framework) domain authentication fail',
|
|
26
|
-
'spf check: fail',
|
|
27
|
-
"the 5322.From address doesn't meet the authentication requirements defined for the sender",
|
|
21
|
+
"please inspect your spf settings",
|
|
22
|
+
"sender policy framework",
|
|
23
|
+
"spf check: fail",
|
|
28
24
|
].freeze
|
|
29
25
|
Pairs = [
|
|
30
|
-
[
|
|
31
|
-
[
|
|
26
|
+
["spf: ", " is not allowed to send "],
|
|
27
|
+
["is not allowed to send ", " spf "],
|
|
32
28
|
].freeze
|
|
33
29
|
|
|
34
30
|
def text; return 'authfailure'; end
|
|
@@ -15,13 +15,13 @@ module Sisimai
|
|
|
15
15
|
module BadReputation
|
|
16
16
|
class << self
|
|
17
17
|
Index = [
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
'
|
|
24
|
-
"
|
|
18
|
+
"has been temporarily rate limited due to ip reputation",
|
|
19
|
+
"ip/domain reputation problems",
|
|
20
|
+
"likely suspicious due to the very low reputation",
|
|
21
|
+
"none/bad reputation", # t-online.de
|
|
22
|
+
"poor email reputation score",
|
|
23
|
+
"sending mta's poor reputation",
|
|
24
|
+
"temporarily deferred due to unexpected volume or user complaints", # Yahoo Inc.
|
|
25
25
|
].freeze
|
|
26
26
|
def text; return 'badreputation'; end
|
|
27
27
|
def description; return 'Email rejected due to an IP address reputation'; end
|