sisimai 5.4.0 → 5.5.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/codecovio.yml +1 -1
- data/.github/workflows/rake-test.yml +1 -1
- data/ChangeLog.md +45 -0
- data/Makefile +2 -4
- data/README-JA.md +23 -20
- data/README.md +23 -20
- data/lib/sisimai/address.rb +92 -44
- data/lib/sisimai/arf.rb +7 -8
- data/lib/sisimai/datetime.rb +2 -2
- data/lib/sisimai/fact/json.rb +1 -2
- data/lib/sisimai/fact/yaml.rb +1 -2
- data/lib/sisimai/fact.rb +60 -35
- data/lib/sisimai/lda.rb +2 -2
- data/lib/sisimai/lhost/activehunter.rb +4 -5
- data/lib/sisimai/lhost/amazonses.rb +3 -4
- data/lib/sisimai/lhost/apachejames.rb +2 -2
- data/lib/sisimai/lhost/biglobe.rb +6 -6
- data/lib/sisimai/lhost/courier.rb +7 -7
- data/lib/sisimai/lhost/domino.rb +6 -6
- data/lib/sisimai/lhost/dragonfly.rb +5 -5
- data/lib/sisimai/lhost/einsundeins.rb +4 -4
- data/lib/sisimai/lhost/exchange2003.rb +7 -7
- data/lib/sisimai/lhost/exchange2007.rb +3 -3
- data/lib/sisimai/lhost/exim.rb +7 -7
- data/lib/sisimai/lhost/ezweb.rb +3 -2
- data/lib/sisimai/lhost/fml.rb +9 -9
- data/lib/sisimai/lhost/gmail.rb +9 -9
- data/lib/sisimai/lhost/gmx.rb +3 -3
- data/lib/sisimai/lhost/googlegroups.rb +6 -7
- data/lib/sisimai/lhost/googleworkspace.rb +5 -6
- data/lib/sisimai/lhost/imailserver.rb +4 -4
- data/lib/sisimai/lhost/kddi.rb +4 -4
- data/lib/sisimai/lhost/mailfoundry.rb +3 -3
- data/lib/sisimai/lhost/{mailmarshalsmtp.rb → mailmarshal.rb} +5 -5
- data/lib/sisimai/lhost/messagingserver.rb +8 -8
- data/lib/sisimai/lhost/mfilter.rb +8 -4
- data/lib/sisimai/lhost/mimecast.rb +105 -0
- data/lib/sisimai/lhost/notes.rb +5 -5
- data/lib/sisimai/lhost/opensmtpd.rb +5 -5
- data/lib/sisimai/lhost/postfix.rb +38 -32
- data/lib/sisimai/lhost/qmail.rb +6 -6
- data/lib/sisimai/lhost/sendmail.rb +13 -13
- data/lib/sisimai/lhost/{interscanmss.rb → trendmicro.rb} +8 -9
- data/lib/sisimai/lhost/v5sendmail.rb +7 -7
- data/lib/sisimai/lhost/verizon.rb +3 -3
- data/lib/sisimai/lhost/x1.rb +7 -4
- data/lib/sisimai/lhost/x2.rb +40 -12
- data/lib/sisimai/lhost/x3.rb +3 -3
- data/lib/sisimai/lhost/x6.rb +2 -2
- data/lib/sisimai/lhost/zoho.rb +5 -5
- data/lib/sisimai/lhost.rb +18 -17
- data/lib/sisimai/mail/maildir.rb +4 -4
- data/lib/sisimai/mail/mbox.rb +4 -4
- data/lib/sisimai/mail/memory.rb +1 -1
- data/lib/sisimai/mail/stdin.rb +2 -2
- data/lib/sisimai/message.rb +34 -34
- data/lib/sisimai/order.rb +5 -4
- data/lib/sisimai/reason/authfailure.rb +1 -1
- data/lib/sisimai/reason/badreputation.rb +1 -1
- data/lib/sisimai/reason/blocked.rb +2 -1
- data/lib/sisimai/reason/contenterror.rb +1 -2
- data/lib/sisimai/reason/exceedlimit.rb +1 -1
- data/lib/sisimai/reason/expired.rb +1 -1
- data/lib/sisimai/reason/failedstarttls.rb +1 -1
- data/lib/sisimai/reason/filtered.rb +1 -1
- data/lib/sisimai/reason/hasmoved.rb +1 -1
- data/lib/sisimai/reason/hostunknown.rb +2 -2
- data/lib/sisimai/reason/mailboxfull.rb +1 -1
- data/lib/sisimai/reason/mailererror.rb +1 -1
- data/lib/sisimai/reason/mesgtoobig.rb +1 -1
- data/lib/sisimai/reason/networkerror.rb +1 -1
- data/lib/sisimai/reason/norelaying.rb +2 -2
- data/lib/sisimai/reason/notaccept.rb +2 -3
- data/lib/sisimai/reason/notcompliantrfc.rb +1 -1
- data/lib/sisimai/reason/policyviolation.rb +2 -4
- data/lib/sisimai/reason/rejected.rb +5 -3
- data/lib/sisimai/reason/requireptr.rb +1 -1
- data/lib/sisimai/reason/securityerror.rb +1 -1
- data/lib/sisimai/reason/spamdetected.rb +1 -1
- data/lib/sisimai/reason/speeding.rb +1 -1
- data/lib/sisimai/reason/suspend.rb +2 -1
- data/lib/sisimai/reason/systemerror.rb +1 -1
- data/lib/sisimai/reason/systemfull.rb +1 -1
- data/lib/sisimai/reason/toomanyconn.rb +1 -1
- data/lib/sisimai/reason/userunknown.rb +4 -3
- data/lib/sisimai/reason/vacation.rb +1 -1
- data/lib/sisimai/reason/virusdetected.rb +1 -1
- data/lib/sisimai/reason.rb +12 -12
- data/lib/sisimai/rfc1123.rb +58 -18
- data/lib/sisimai/rfc1894.rb +6 -8
- data/lib/sisimai/rfc2045.rb +25 -13
- data/lib/sisimai/rfc3464/thirdparty.rb +2 -3
- data/lib/sisimai/rfc3464.rb +6 -6
- data/lib/sisimai/rfc3834.rb +18 -8
- data/lib/sisimai/rfc5322.rb +9 -9
- data/lib/sisimai/rfc791.rb +2 -2
- data/lib/sisimai/rhost/aol.rb +4 -1
- data/lib/sisimai/rhost/apple.rb +11 -7
- data/lib/sisimai/rhost/cox.rb +9 -5
- data/lib/sisimai/rhost/facebook.rb +9 -3
- data/lib/sisimai/rhost/franceptt.rb +86 -37
- data/lib/sisimai/rhost/godaddy.rb +10 -1
- data/lib/sisimai/rhost/google.rb +26 -22
- data/lib/sisimai/rhost/gsuite.rb +1 -1
- data/lib/sisimai/rhost/kddi.rb +1 -1
- data/lib/sisimai/rhost/messagelabs.rb +160 -2
- data/lib/sisimai/rhost/microsoft.rb +80 -29
- data/lib/sisimai/rhost/mimecast.rb +30 -21
- data/lib/sisimai/rhost/nttdocomo.rb +69 -89
- data/lib/sisimai/rhost/outlook.rb +1 -1
- data/lib/sisimai/rhost/spectrum.rb +1 -1
- data/lib/sisimai/rhost/tencent.rb +5 -4
- data/lib/sisimai/rhost/yahooinc.rb +2 -2
- data/lib/sisimai/rhost/zoho.rb +72 -0
- data/lib/sisimai/rhost.rb +5 -4
- data/lib/sisimai/smtp/command.rb +2 -2
- data/lib/sisimai/smtp/reply.rb +11 -4
- data/lib/sisimai/smtp/status.rb +17 -8
- data/lib/sisimai/smtp/transcript.rb +3 -3
- data/lib/sisimai/string.rb +6 -10
- data/lib/sisimai/version.rb +1 -1
- data/lib/sisimai.rb +1 -1
- data/set-of-emails/maildir/bsd/lhost-exim-56.eml +40 -40
- data/set-of-emails/maildir/bsd/lhost-mfilter-05.eml +41 -0
- data/set-of-emails/maildir/bsd/lhost-mimecast-01.eml +46 -0
- data/set-of-emails/maildir/bsd/lhost-mimecast-02.eml +59 -0
- data/set-of-emails/maildir/bsd/lhost-postfix-79.eml +81 -0
- data/set-of-emails/maildir/bsd/lhost-postfix-80.eml +84 -0
- data/set-of-emails/maildir/bsd/lhost-x1-03.eml +26 -0
- data/set-of-emails/maildir/bsd/lhost-x1-04.eml +45 -0
- data/set-of-emails/maildir/bsd/lhost-x2-07.eml +30 -0
- data/set-of-emails/maildir/bsd/rfc3464-66.eml +170 -0
- data/set-of-emails/maildir/bsd/rfc3834-06.eml +59 -0
- data/set-of-emails/maildir/bsd/rhost-apple-05.eml +96 -0
- data/set-of-emails/maildir/bsd/rhost-zoho-01.eml +88 -0
- data/set-of-emails/maildir/bsd/rhost-zoho-02.eml +86 -0
- data/set-of-emails/maildir/bsd/rhost-zoho-03.eml +87 -0
- data/set-of-emails/maildir/bsd/rhost-zoho-04.eml +86 -0
- data/set-of-emails/maildir/not/rb-issue-368-bug.eml +39 -0
- data/sisimai-java.gemspec +1 -1
- data/sisimai.gemspec +1 -1
- metadata +27 -9
- /data/set-of-emails/maildir/bsd/{lhost-mailmarshalsmtp-02.eml → lhost-mailmarshal-02.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-interscanmss-01.eml → lhost-trendmicro-01.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-interscanmss-02.eml → lhost-trendmicro-02.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-interscanmss-03.eml → lhost-trendmicro-03.eml} +0 -0
|
@@ -74,14 +74,14 @@ module Sisimai::Lhost
|
|
|
74
74
|
throw :EXCHANGE_OR_NOT if mhead['received'].empty?
|
|
75
75
|
mhead['received'].each do |e|
|
|
76
76
|
# Received: by ***.**.** with Internet Mail Service (5.5.2657.72)
|
|
77
|
-
next
|
|
77
|
+
next if e.include?(' with Internet Mail Service (') == false
|
|
78
78
|
match += 1
|
|
79
79
|
throw :EXCHANGE_OR_NOT
|
|
80
80
|
end
|
|
81
81
|
break
|
|
82
82
|
end
|
|
83
83
|
end
|
|
84
|
-
return nil
|
|
84
|
+
return nil if match == 0
|
|
85
85
|
|
|
86
86
|
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]; v = nil
|
|
87
87
|
emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
|
|
@@ -160,26 +160,26 @@ module Sisimai::Lhost
|
|
|
160
160
|
#
|
|
161
161
|
if e.start_with?(' To: ') || e.start_with?(' To: ')
|
|
162
162
|
# To: shironeko@example.jp
|
|
163
|
-
next
|
|
163
|
+
next if connheader['to'].empty? == false
|
|
164
164
|
connheader['to'] = e[e.rindex(' ') + 1, e.size]
|
|
165
165
|
connvalues += 1
|
|
166
166
|
|
|
167
167
|
elsif e.start_with?(' Subject: ') || e.start_with?(' Subject: ')
|
|
168
168
|
# Subject: ...
|
|
169
|
-
next
|
|
169
|
+
next if connheader['subject'].empty? == false
|
|
170
170
|
connheader['subject'] = e[e.rindex(' ') + 1, e.size]
|
|
171
171
|
connvalues += 1
|
|
172
172
|
|
|
173
173
|
elsif e.start_with?(' Sent: ') || e.start_with?(' Sent: ')
|
|
174
174
|
# Sent: Thu, 29 Apr 2010 18:14:35 +0000
|
|
175
175
|
# Sent: 4/29/99 9:19:59 AM
|
|
176
|
-
next
|
|
176
|
+
next if connheader['date'].empty? == false
|
|
177
177
|
connheader['date'] = e[e.index(':') + 2, e.size]
|
|
178
178
|
connvalues += 1
|
|
179
179
|
end
|
|
180
180
|
end
|
|
181
181
|
end
|
|
182
|
-
return nil
|
|
182
|
+
return nil if recipients == 0
|
|
183
183
|
|
|
184
184
|
dscontents.each do |e|
|
|
185
185
|
e.delete('msexch')
|
|
@@ -193,7 +193,7 @@ module Sisimai::Lhost
|
|
|
193
193
|
|
|
194
194
|
ErrorCodes.each_key do |r|
|
|
195
195
|
# Find captured code from the error code table
|
|
196
|
-
next
|
|
196
|
+
next if ErrorCodes[r].index(capturedcode).nil?
|
|
197
197
|
e['reason'] = r
|
|
198
198
|
e['status'] = Sisimai::SMTP::Status.code(r)
|
|
199
199
|
break
|
|
@@ -26,7 +26,7 @@ module Sisimai::Lhost
|
|
|
26
26
|
rhost: [
|
|
27
27
|
"DSN generated by:",
|
|
28
28
|
"Generating server", # en-US
|
|
29
|
-
"Serveur de g", # fr-FR/Serveur de
|
|
29
|
+
"Serveur de g", # fr-FR/Serveur de gènèration
|
|
30
30
|
"Server di generazione", # it-CH
|
|
31
31
|
"Genererande server", # sv-SE
|
|
32
32
|
]
|
|
@@ -143,11 +143,11 @@ module Sisimai::Lhost
|
|
|
143
143
|
p3 = emailparts[0].index("\n", p2 + 20); break if p3.nil?
|
|
144
144
|
cv = Sisimai::Address.s3s4(emailparts[0][p2 + 20, p3 - p2 - 20])
|
|
145
145
|
|
|
146
|
-
break
|
|
146
|
+
break if Sisimai::Address.is_emailaddress(cv) == false
|
|
147
147
|
dscontents[0]["recipient"] = cv
|
|
148
148
|
recipients += 1
|
|
149
149
|
end
|
|
150
|
-
return nil
|
|
150
|
+
return nil if recipients == 0
|
|
151
151
|
|
|
152
152
|
dscontents.each do |e|
|
|
153
153
|
# Tidy up the error message in $e->{'diagnosis'}, Try to detect the bounce reason.
|
data/lib/sisimai/lhost/exim.rb
CHANGED
|
@@ -190,7 +190,7 @@ module Sisimai::Lhost
|
|
|
190
190
|
if StartingOf["message"].any? { |a| e.include?(a) }
|
|
191
191
|
# Check the message defined in StartingOf["message"], ["frozen"]
|
|
192
192
|
readcursor |= Indicators[:deliverystatus]
|
|
193
|
-
next
|
|
193
|
+
next if StartingOf["frozen"].none? { |a| e.include?(a) }
|
|
194
194
|
end
|
|
195
195
|
end
|
|
196
196
|
next if (readcursor & Indicators[:deliverystatus]) == 0 || e.empty?
|
|
@@ -269,7 +269,7 @@ module Sisimai::Lhost
|
|
|
269
269
|
# generated by userx@myhost.test.ex
|
|
270
270
|
e.split(" ").each do |f|
|
|
271
271
|
# Find the alias address
|
|
272
|
-
next
|
|
272
|
+
next if f.include?('@') == false
|
|
273
273
|
v["alias"] = Sisimai::Address.s3s4(f)
|
|
274
274
|
end
|
|
275
275
|
else
|
|
@@ -289,7 +289,7 @@ module Sisimai::Lhost
|
|
|
289
289
|
if o[3] == "addr"
|
|
290
290
|
# Final-Recipient: rfc822; kijitora@example.jp
|
|
291
291
|
# X-Actual-Recipient: rfc822; kijitora@example.co.jp
|
|
292
|
-
next
|
|
292
|
+
next if o[0] != "final-recipient"
|
|
293
293
|
if v["spec"].empty?
|
|
294
294
|
v["spec"] = o[2].include?('@') ? "SMTP" : "X-UNIX"
|
|
295
295
|
end
|
|
@@ -301,7 +301,7 @@ module Sisimai::Lhost
|
|
|
301
301
|
|
|
302
302
|
else
|
|
303
303
|
# Other DSN fields defined in RFC3464
|
|
304
|
-
next
|
|
304
|
+
next if FieldTable[o[0]].nil?
|
|
305
305
|
v[FieldTable[o[0]]] = o[2]
|
|
306
306
|
end
|
|
307
307
|
else
|
|
@@ -311,7 +311,7 @@ module Sisimai::Lhost
|
|
|
311
311
|
# Content-type: message/delivery-status
|
|
312
312
|
nextcursor = true if e.start_with?(StartingOf["deliverystatus"][0])
|
|
313
313
|
v["alterrors"] ||= ''
|
|
314
|
-
v["alterrors"] += "#{e} "
|
|
314
|
+
v["alterrors"] += "#{e} " if e.start_with?(" ")
|
|
315
315
|
end
|
|
316
316
|
else
|
|
317
317
|
# There is no boundary string in $boundary00
|
|
@@ -322,7 +322,7 @@ module Sisimai::Lhost
|
|
|
322
322
|
# Error message when email address above does not include '@' and domain part
|
|
323
323
|
# pipe to |/path/to/prog ...
|
|
324
324
|
# generated by kijitora@example.com
|
|
325
|
-
next
|
|
325
|
+
next if e.start_with?(" ") == false
|
|
326
326
|
v["diagnosis"] += "#{e} "
|
|
327
327
|
end
|
|
328
328
|
end
|
|
@@ -439,7 +439,7 @@ module Sisimai::Lhost
|
|
|
439
439
|
# Try to match the error message with each message pattern
|
|
440
440
|
MessagesOf.each_key do |r|
|
|
441
441
|
# Check each message pattern
|
|
442
|
-
next
|
|
442
|
+
next if MessagesOf[r].none? { |a| e["diagnosis"].include?(a) }
|
|
443
443
|
e["reason"] = r
|
|
444
444
|
break
|
|
445
445
|
end
|
data/lib/sisimai/lhost/ezweb.rb
CHANGED
|
@@ -116,7 +116,7 @@ module Sisimai::Lhost
|
|
|
116
116
|
end
|
|
117
117
|
end
|
|
118
118
|
end
|
|
119
|
-
return nil
|
|
119
|
+
return nil if recipients == 0
|
|
120
120
|
|
|
121
121
|
dscontents.each do |e|
|
|
122
122
|
# Check each value of DeliveryMatter{}, try to detect the bounce reason.
|
|
@@ -127,6 +127,7 @@ module Sisimai::Lhost
|
|
|
127
127
|
# Content-Type: text/plain; ..., X-SPASIGN: NG (spamghetti, au by EZweb)
|
|
128
128
|
# Filtered recipient returns message that include 'X-SPASIGN' header
|
|
129
129
|
e['reason'] = 'filtered'
|
|
130
|
+
e['toxic'] = true
|
|
130
131
|
else
|
|
131
132
|
# There is no X-SPASIGN header or the value of the header is not "NG"
|
|
132
133
|
catch :FINDREASON do
|
|
@@ -134,7 +135,7 @@ module Sisimai::Lhost
|
|
|
134
135
|
# Try to match with each session error message
|
|
135
136
|
Messagesof[r].each do |f|
|
|
136
137
|
# Check each error message pattern
|
|
137
|
-
next
|
|
138
|
+
next if e['diagnosis'].include?(f) == false
|
|
138
139
|
e['reason'] = r
|
|
139
140
|
throw :FINDREASON
|
|
140
141
|
end
|
data/lib/sisimai/lhost/fml.rb
CHANGED
|
@@ -30,12 +30,12 @@ module Sisimai::Lhost
|
|
|
30
30
|
'reject spammers:',
|
|
31
31
|
'You are not a member of this mailing list',
|
|
32
32
|
],
|
|
33
|
+
'notcompliantrfc' => ['Duplicated Message-ID'],
|
|
34
|
+
'securityerror' => ['Security alert:'],
|
|
33
35
|
'systemerror' => [
|
|
34
36
|
' has detected a loop condition so that',
|
|
35
|
-
'Duplicated Message-ID',
|
|
36
37
|
'Loop Back Warning:',
|
|
37
38
|
],
|
|
38
|
-
'securityerror' => ['Security alert:'],
|
|
39
39
|
}.freeze
|
|
40
40
|
|
|
41
41
|
# @abstract Decodes the bounce message from fml mailling list server/manager
|
|
@@ -45,9 +45,9 @@ module Sisimai::Lhost
|
|
|
45
45
|
# @return [Nil] it failed to decode or the arguments are missing
|
|
46
46
|
# @since v4.22.3
|
|
47
47
|
def inquire(mhead, mbody)
|
|
48
|
-
return nil
|
|
49
|
-
return nil
|
|
50
|
-
return nil
|
|
48
|
+
return nil if mhead['x-mlserver'].nil?
|
|
49
|
+
return nil if mhead['from'].include?('-admin@') == false
|
|
50
|
+
return nil if mhead['message-id'].index('.FML') < 2
|
|
51
51
|
|
|
52
52
|
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]; v = nil
|
|
53
53
|
emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
|
|
@@ -81,22 +81,22 @@ module Sisimai::Lhost
|
|
|
81
81
|
v['diagnosis'] += e
|
|
82
82
|
end
|
|
83
83
|
end
|
|
84
|
-
return nil
|
|
84
|
+
return nil if recipients == 0
|
|
85
85
|
|
|
86
86
|
dscontents.each do |e|
|
|
87
87
|
e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
|
|
88
88
|
ErrorTable.each_key do |f|
|
|
89
89
|
# Try to match with error messages defined in ErrorTable
|
|
90
|
-
next
|
|
90
|
+
next if ErrorTable[f].none? { |a| e['diagnosis'].include?(a) }
|
|
91
91
|
e['reason'] = f
|
|
92
92
|
break
|
|
93
93
|
end
|
|
94
94
|
|
|
95
|
-
|
|
95
|
+
if e['reason'].nil?
|
|
96
96
|
# Error messages in the message body did not matched
|
|
97
97
|
ErrorTitle.each_key do |f|
|
|
98
98
|
# Try to match with the Subject string
|
|
99
|
-
next
|
|
99
|
+
next if ErrorTitle[f].none? { |a| mhead["subject"].include?(a) }
|
|
100
100
|
e['reason'] = f
|
|
101
101
|
break
|
|
102
102
|
end
|
data/lib/sisimai/lhost/gmail.rb
CHANGED
|
@@ -52,7 +52,7 @@ module Sisimai::Lhost
|
|
|
52
52
|
# We recommend contacting the other email provider for further information about the
|
|
53
53
|
# cause of this error. The error that the other server returned was:
|
|
54
54
|
# 500 Remote server does not support SMTP Authenticated Relay (state 12).
|
|
55
|
-
'12' => { 'command' => 'AUTH', 'reason' => '
|
|
55
|
+
'12' => { 'command' => 'AUTH', 'reason' => 'norelaying' },
|
|
56
56
|
|
|
57
57
|
# Technical details of permanent failure:
|
|
58
58
|
# Google tried to deliver your message, but it was rejected by the recipient domain.
|
|
@@ -148,8 +148,8 @@ module Sisimai::Lhost
|
|
|
148
148
|
# The error that the other server returned was:
|
|
149
149
|
# 550 5.1.1 <userunknown@example.jp>... User Unknown
|
|
150
150
|
#
|
|
151
|
-
return nil
|
|
152
|
-
return nil
|
|
151
|
+
return nil if mhead['from'].end_with?('<mailer-daemon@googlemail.com>') == false
|
|
152
|
+
return nil if mhead['subject'].start_with?('Delivery Status Notification') == false
|
|
153
153
|
|
|
154
154
|
require 'sisimai/address'
|
|
155
155
|
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]; v = nil
|
|
@@ -193,14 +193,14 @@ module Sisimai::Lhost
|
|
|
193
193
|
end
|
|
194
194
|
|
|
195
195
|
r = Sisimai::Address.s3s4(e[e.rindex(' ') + 1, e.size])
|
|
196
|
-
next
|
|
196
|
+
next if Sisimai::Address.is_emailaddress(r) == false
|
|
197
197
|
v['recipient'] = r
|
|
198
198
|
recipients += 1
|
|
199
199
|
else
|
|
200
200
|
v["diagnosis"] += "#{e }"
|
|
201
201
|
end
|
|
202
202
|
end
|
|
203
|
-
return nil
|
|
203
|
+
return nil if recipients == 0
|
|
204
204
|
|
|
205
205
|
require 'sisimai/string'
|
|
206
206
|
require 'sisimai/rfc1123'
|
|
@@ -222,12 +222,12 @@ module Sisimai::Lhost
|
|
|
222
222
|
|
|
223
223
|
while true do
|
|
224
224
|
# Find "(state 18)" and pick "18" as a key of statetable
|
|
225
|
-
p1 = e['diagnosis'].rindex(' (state '); break
|
|
226
|
-
p2 = e['diagnosis'].rindex(')'); break
|
|
225
|
+
p1 = e['diagnosis'].rindex(' (state '); break if p1.nil?
|
|
226
|
+
p2 = e['diagnosis'].rindex(')'); break if p2.nil?
|
|
227
227
|
break if p1 > p2
|
|
228
228
|
cu = e['diagnosis'][p1 + 8, p2 - p1 - 8]
|
|
229
229
|
break if cu.empty?
|
|
230
|
-
break
|
|
230
|
+
break if StateTable[cu].nil?
|
|
231
231
|
e['reason'] = StateTable[cu]['reason']
|
|
232
232
|
e['command'] = StateTable[cu]['command']
|
|
233
233
|
break
|
|
@@ -237,7 +237,7 @@ module Sisimai::Lhost
|
|
|
237
237
|
# There is no no state code in the error message
|
|
238
238
|
MessagesOf.each_key do |r|
|
|
239
239
|
# Verify each regular expression of session errors
|
|
240
|
-
next
|
|
240
|
+
next if MessagesOf[r].none? { |a| e['diagnosis'].include?(a) }
|
|
241
241
|
e['reason'] = r
|
|
242
242
|
break
|
|
243
243
|
end
|
data/lib/sisimai/lhost/gmx.rb
CHANGED
|
@@ -20,7 +20,7 @@ module Sisimai::Lhost
|
|
|
20
20
|
# X-GMX-Antispam: 0 (Mail was not recognized as spam); Detail=V3;
|
|
21
21
|
# X-GMX-Antivirus: 0 (no virus found)
|
|
22
22
|
# X-UI-Out-Filterresults: unknown:0;
|
|
23
|
-
return nil
|
|
23
|
+
return nil if mhead['x-gmx-antispam'].nil?
|
|
24
24
|
|
|
25
25
|
require 'sisimai/smtp/command'
|
|
26
26
|
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]; v = nil
|
|
@@ -79,14 +79,14 @@ module Sisimai::Lhost
|
|
|
79
79
|
v['diagnosis'] += "#{e }"
|
|
80
80
|
end
|
|
81
81
|
end
|
|
82
|
-
return nil
|
|
82
|
+
return nil if recipients == 0
|
|
83
83
|
|
|
84
84
|
dscontents.each do |e|
|
|
85
85
|
e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'].tr("\n", ' '))
|
|
86
86
|
|
|
87
87
|
MessagesOf.each_key do |r|
|
|
88
88
|
# Verify each regular expression of session errors
|
|
89
|
-
next
|
|
89
|
+
next if MessagesOf[r].none? { |a| e['diagnosis'].include?(a) }
|
|
90
90
|
e['reason'] = r
|
|
91
91
|
break
|
|
92
92
|
end
|
|
@@ -13,11 +13,10 @@ module Sisimai::Lhost
|
|
|
13
13
|
# @return [Nil] it failed to decode or the arguments are missing
|
|
14
14
|
# @since v4.25.6
|
|
15
15
|
def inquire(mhead, mbody)
|
|
16
|
-
return nil
|
|
17
|
-
return nil
|
|
18
|
-
return nil
|
|
19
|
-
return nil
|
|
20
|
-
return nil unless mhead['x-google-smtp-source']
|
|
16
|
+
return nil if mbody.include?("Google Groups") == false
|
|
17
|
+
return nil if mhead['from'].end_with?('<mailer-daemon@googlemail.com>') == false
|
|
18
|
+
return nil if mhead['subject'].start_with?('Delivery Status Notification') == false
|
|
19
|
+
return nil if mhead['x-failed-recipients'].nil? || mhead['x-google-smtp-source'].nil?
|
|
21
20
|
|
|
22
21
|
# Hello kijitora@libsisimai.org,
|
|
23
22
|
#
|
|
@@ -55,7 +54,7 @@ module Sisimai::Lhost
|
|
|
55
54
|
|
|
56
55
|
mhead['x-failed-recipients'].split(',').each do |e|
|
|
57
56
|
# X-Failed-Recipients: neko@example.jp, nyaan@example.org, ...
|
|
58
|
-
next
|
|
57
|
+
next if Sisimai::Address.is_emailaddress(e) == false
|
|
59
58
|
|
|
60
59
|
if v["recipient"] != ""
|
|
61
60
|
# There are multiple recipient addresses in the message body.
|
|
@@ -66,7 +65,7 @@ module Sisimai::Lhost
|
|
|
66
65
|
recipients += 1
|
|
67
66
|
recordwide.each_key { |r| v[r] = recordwide[r] }
|
|
68
67
|
end
|
|
69
|
-
return nil
|
|
68
|
+
return nil if recipients == 0
|
|
70
69
|
return { 'ds' => dscontents, 'rfc822' => emailparts[1] }
|
|
71
70
|
end
|
|
72
71
|
def description; return 'Google Groups: https://groups.google.com'; end
|
|
@@ -26,10 +26,9 @@ module Sisimai::Lhost
|
|
|
26
26
|
# @return [Nil] it failed to decode or the arguments are missing
|
|
27
27
|
# @see https://workspace.google.com/.
|
|
28
28
|
def inquire(mhead, mbody)
|
|
29
|
-
return nil if
|
|
30
|
-
return nil if
|
|
31
|
-
return nil
|
|
32
|
-
return nil unless mhead["subject"].include?("Delivery Status Notification")
|
|
29
|
+
return nil if mbody.include?("\nDiagnostic-Code:") || mbody.include?("\nFinal-Recipient:")
|
|
30
|
+
return nil if mhead["from"].include?('<mailer-daemon@googlemail.com>') == false
|
|
31
|
+
return nil if mhead["subject"].include?("Delivery Status Notification") == false
|
|
33
32
|
|
|
34
33
|
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
|
|
35
34
|
emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
|
|
@@ -64,7 +63,7 @@ module Sisimai::Lhost
|
|
|
64
63
|
while recipients == 0 do
|
|
65
64
|
# Pick the recipient address from the value of To: header of the original message after
|
|
66
65
|
# Content-Type: message/rfc822 field
|
|
67
|
-
p0 = emailparts[1].index("\nTo:"); break
|
|
66
|
+
p0 = emailparts[1].index("\nTo:"); break if p0.nil?
|
|
68
67
|
p1 = emailparts[1].index("\n", p0 + 2)
|
|
69
68
|
cv = Sisimai::Address.s3s4(emailparts[1][p0 + 4, p1 - p0])
|
|
70
69
|
dscontents[0]["recipient"] = cv
|
|
@@ -78,7 +77,7 @@ module Sisimai::Lhost
|
|
|
78
77
|
e["diagnosis"] = Sisimai::String.sweep(e["diagnosis"])
|
|
79
78
|
MessagesOf.each_key do |r|
|
|
80
79
|
# Guess an reason of the bounce
|
|
81
|
-
next
|
|
80
|
+
next if MessagesOf[r].none? { |a| e["diagnosis"].include?(a) }
|
|
82
81
|
e["reason"] = r
|
|
83
82
|
break
|
|
84
83
|
end
|
|
@@ -27,7 +27,7 @@ module Sisimai::Lhost
|
|
|
27
27
|
match = 0
|
|
28
28
|
match += 1 if mhead['subject'].start_with?('Undeliverable Mail ')
|
|
29
29
|
match += 1 if mhead['x-mailer'].to_s.start_with?('<SMTP32 v')
|
|
30
|
-
return nil
|
|
30
|
+
return nil if match == 0
|
|
31
31
|
|
|
32
32
|
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]; v = nil
|
|
33
33
|
emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
|
|
@@ -61,11 +61,11 @@ module Sisimai::Lhost
|
|
|
61
61
|
v['alterrors'] = e if e.include?(StartingOf[:error][0])
|
|
62
62
|
end
|
|
63
63
|
end
|
|
64
|
-
return nil
|
|
64
|
+
return nil if recipients == 0
|
|
65
65
|
|
|
66
66
|
require 'sisimai/smtp/command'
|
|
67
67
|
dscontents.each do |e|
|
|
68
|
-
|
|
68
|
+
if e['alterrors'].nil? == false && e['alterrors'].empty? == false
|
|
69
69
|
# Copy alternative error message
|
|
70
70
|
e['diagnosis'] = if e['diagnosis']
|
|
71
71
|
"#{e['alterrors']} #{e['diagnosis']}"
|
|
@@ -80,7 +80,7 @@ module Sisimai::Lhost
|
|
|
80
80
|
|
|
81
81
|
MessagesOf.each_key do |r|
|
|
82
82
|
# Verify each regular expression of session errors
|
|
83
|
-
next
|
|
83
|
+
next if MessagesOf[r].none? { |a| e['diagnosis'].include?(a) }
|
|
84
84
|
e['reason'] = r
|
|
85
85
|
break
|
|
86
86
|
end
|
data/lib/sisimai/lhost/kddi.rb
CHANGED
|
@@ -26,7 +26,7 @@ module Sisimai::Lhost
|
|
|
26
26
|
match += 1 if mhead['reply-to'].to_s == 'no-reply@app.auone-net.jp'
|
|
27
27
|
match += 1 if mhead['received'].any? { |a| a.include?('ezweb.ne.jp (') }
|
|
28
28
|
match += 1 if mhead['received'].any? { |a| a.include?('.au.com (') }
|
|
29
|
-
return nil
|
|
29
|
+
return nil if match == 0
|
|
30
30
|
|
|
31
31
|
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]; v = nil
|
|
32
32
|
emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
|
|
@@ -55,7 +55,7 @@ module Sisimai::Lhost
|
|
|
55
55
|
v = dscontents[-1]
|
|
56
56
|
end
|
|
57
57
|
r = Sisimai::Address.s3s4(e[e.index('<') + 1, e.size])
|
|
58
|
-
next
|
|
58
|
+
next if Sisimai::Address.is_emailaddress(r) == false
|
|
59
59
|
v['recipient'] = r
|
|
60
60
|
recipients += 1
|
|
61
61
|
|
|
@@ -67,7 +67,7 @@ module Sisimai::Lhost
|
|
|
67
67
|
v['diagnosis'] += "#{e} " if e.start_with?(' ')
|
|
68
68
|
end
|
|
69
69
|
end
|
|
70
|
-
return nil
|
|
70
|
+
return nil if recipients == 0
|
|
71
71
|
|
|
72
72
|
require 'sisimai/smtp/command'
|
|
73
73
|
dscontents.each do |e|
|
|
@@ -86,7 +86,7 @@ module Sisimai::Lhost
|
|
|
86
86
|
# SMTP command is not RCPT
|
|
87
87
|
MessagesOf.each_key do |r|
|
|
88
88
|
# Verify each regular expression of session errors
|
|
89
|
-
next
|
|
89
|
+
next if MessagesOf[r].none? { |a| e['diagnosis'].include?(a) }
|
|
90
90
|
e['reason'] = r
|
|
91
91
|
break
|
|
92
92
|
end
|
|
@@ -18,8 +18,8 @@ module Sisimai::Lhost
|
|
|
18
18
|
# @return [Hash] Bounce data list and message/rfc822 part
|
|
19
19
|
# @return [Nil] it failed to decode or the arguments are missing
|
|
20
20
|
def inquire(mhead, mbody)
|
|
21
|
-
return nil
|
|
22
|
-
return nil
|
|
21
|
+
return nil if mhead['subject'] != 'Message delivery has failed'
|
|
22
|
+
return nil if mhead['received'].none? { |a| a.include?('(MAILFOUNDRY) id ') }
|
|
23
23
|
|
|
24
24
|
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]; v = nil
|
|
25
25
|
emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
|
|
@@ -64,7 +64,7 @@ module Sisimai::Lhost
|
|
|
64
64
|
end
|
|
65
65
|
end
|
|
66
66
|
end
|
|
67
|
-
return nil
|
|
67
|
+
return nil if recipients == 0
|
|
68
68
|
|
|
69
69
|
dscontents.each { |e| e['diagnosis'] = Sisimai::String.sweep(e['diagnosis']) }
|
|
70
70
|
return { 'ds' => dscontents, 'rfc822' => emailparts[1] }
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
module Sisimai::Lhost
|
|
2
|
-
# Sisimai::Lhost::
|
|
2
|
+
# Sisimai::Lhost::MailMarshal decodes a bounce email which created by Trustwave Secure Email
|
|
3
3
|
# Gateway: formerly MailMarshal SMTP https://www.trustwave.com/en-us/services/email-security/.
|
|
4
4
|
# Methods in the module are called from only Sisimai::Message.
|
|
5
|
-
module
|
|
5
|
+
module MailMarshal
|
|
6
6
|
class << self
|
|
7
7
|
require 'sisimai/lhost'
|
|
8
8
|
|
|
@@ -14,13 +14,13 @@ module Sisimai::Lhost
|
|
|
14
14
|
rcpts: ['The following recipients were affected:'],
|
|
15
15
|
}.freeze
|
|
16
16
|
|
|
17
|
-
# @abstract Decodes the bounce message from Trustwave Secure Email Gateway (Formerly
|
|
17
|
+
# @abstract Decodes the bounce message from Trustwave Secure Email Gateway (Formerly MailMarshal)
|
|
18
18
|
# @param [Hash] mhead Message headers of a bounce email
|
|
19
19
|
# @param [String] mbody Message body of a bounce email
|
|
20
20
|
# @return [Hash] Bounce data list and message/rfc822 part
|
|
21
21
|
# @return [Nil] it failed to decode or the arguments are missing
|
|
22
22
|
def inquire(mhead, mbody)
|
|
23
|
-
return nil
|
|
23
|
+
return nil if mhead['subject'].start_with?('Undeliverable Mail: "') == false
|
|
24
24
|
|
|
25
25
|
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]; v = nil
|
|
26
26
|
emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
|
|
@@ -109,7 +109,7 @@ module Sisimai::Lhost
|
|
|
109
109
|
end
|
|
110
110
|
end
|
|
111
111
|
end
|
|
112
|
-
return nil
|
|
112
|
+
return nil if recipients == 0
|
|
113
113
|
|
|
114
114
|
dscontents.each { |e| e['diagnosis'] = Sisimai::String.sweep(e['diagnosis']) }
|
|
115
115
|
return { 'ds' => dscontents, 'rfc822' => emailparts[1] }
|
|
@@ -20,7 +20,7 @@ module Sisimai::Lhost
|
|
|
20
20
|
match = 0
|
|
21
21
|
match += 1 if mhead['content-type'].include?('Boundary_(ID_')
|
|
22
22
|
match += 1 if mhead['subject'].start_with?('Delivery Notification: ')
|
|
23
|
-
return nil
|
|
23
|
+
return nil if match == 0
|
|
24
24
|
|
|
25
25
|
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]; v = nil
|
|
26
26
|
emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
|
|
@@ -63,7 +63,7 @@ module Sisimai::Lhost
|
|
|
63
63
|
# Recipient address: @smtp.example.net:kijitora@server
|
|
64
64
|
# Original address: kijitora@example.jp
|
|
65
65
|
cv = Sisimai::Address.s3s4(e[e.rindex(' ') + 1, e.size])
|
|
66
|
-
next
|
|
66
|
+
next if Sisimai::Address.is_emailaddress(cv) == false
|
|
67
67
|
|
|
68
68
|
if v["recipient"] != "" && cv != v['recipient']
|
|
69
69
|
# There are multiple recipient addresses in the message body.
|
|
@@ -99,9 +99,9 @@ module Sisimai::Lhost
|
|
|
99
99
|
|
|
100
100
|
# The value does not include ".", use IP address instead.
|
|
101
101
|
# (TCP|17.111.174.67|47323|192.0.2.225|25)
|
|
102
|
-
next
|
|
102
|
+
next if sessionlog[0] != '(TCP'
|
|
103
103
|
v['lhost'] = sessionlog[1]
|
|
104
|
-
v['rhost'] = sessionlog[3]
|
|
104
|
+
v['rhost'] = sessionlog[3] if remotehost.index('.') < 2
|
|
105
105
|
else
|
|
106
106
|
# Original-envelope-id: 0NFC009FLKOUVMA0@mr21p30im-asmtp004.me.com
|
|
107
107
|
# Reporting-MTA: dns;mr21p30im-asmtp004.me.com (tcp-daemon)
|
|
@@ -118,7 +118,7 @@ module Sisimai::Lhost
|
|
|
118
118
|
if e.start_with?('Status: ')
|
|
119
119
|
# Status: 5.1.1 (Remote SMTP server has rejected address)
|
|
120
120
|
p1 = e.index(':')
|
|
121
|
-
p2 = e.index('(')
|
|
121
|
+
p2 = e.index('('); next if p2.nil?
|
|
122
122
|
v['status'] = e[p1 + 2, p2 - p1 - 3]
|
|
123
123
|
v['diagnosis'] = e[p2 + 1, e[e.index(')') - p2 - 1]] if v["diagnosis"].empty?
|
|
124
124
|
|
|
@@ -130,17 +130,17 @@ module Sisimai::Lhost
|
|
|
130
130
|
# Reporting-MTA: dns;mr21p30im-asmtp004.me.com (tcp-daemon)
|
|
131
131
|
localhost = e[e.index(';') + 1, e.size]
|
|
132
132
|
v['lhost'] = localhost if v["lhost"].empty?
|
|
133
|
-
v['lhost'] = localhost
|
|
133
|
+
v['lhost'] = localhost if v['lhost'].index('.') < 1
|
|
134
134
|
end
|
|
135
135
|
end
|
|
136
136
|
end
|
|
137
|
-
return nil
|
|
137
|
+
return nil if recipients == 0
|
|
138
138
|
|
|
139
139
|
dscontents.each do |e|
|
|
140
140
|
e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
|
|
141
141
|
MessagesOf.each_key do |r|
|
|
142
142
|
# Verify each regular expression of session errors
|
|
143
|
-
next
|
|
143
|
+
next if MessagesOf[r].none? { |a| e['diagnosis'].include?(a) }
|
|
144
144
|
e['reason'] = r
|
|
145
145
|
break
|
|
146
146
|
end
|
|
@@ -19,8 +19,12 @@ module Sisimai::Lhost
|
|
|
19
19
|
# @return [Nil] it failed to decode or the arguments are missing
|
|
20
20
|
def inquire(mhead, mbody)
|
|
21
21
|
# X-Mailer: m-FILTER
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
proceedsto = false
|
|
23
|
+
proceedsto = true if mhead['x-mailer'].to_s == 'm-FILTER'
|
|
24
|
+
proceedsto = true if Boundaries.any? { |a| mbody.include?(a) }
|
|
25
|
+
proceedsto = true if StartingOf[:error].any? { |a| mbody.include?(a) }
|
|
26
|
+
proceedsto = true if StartingOf[:command].any? { |a| mbody.include?(a) }
|
|
27
|
+
return nil if proceedsto == false
|
|
24
28
|
|
|
25
29
|
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]; v = nil
|
|
26
30
|
emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
|
|
@@ -91,7 +95,7 @@ module Sisimai::Lhost
|
|
|
91
95
|
end
|
|
92
96
|
end
|
|
93
97
|
end
|
|
94
|
-
return nil
|
|
98
|
+
return nil if recipients == 0
|
|
95
99
|
|
|
96
100
|
dscontents.each do |e|
|
|
97
101
|
e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
|
|
@@ -105,7 +109,7 @@ module Sisimai::Lhost
|
|
|
105
109
|
e['lhost'] = Sisimai::RFC5322.received(rheads[0]).shift if e["lhost"].empty?
|
|
106
110
|
[rhosts[0], rhosts[1]].each do |ee|
|
|
107
111
|
# Avoid "... by m-FILTER"
|
|
108
|
-
next
|
|
112
|
+
next if ee.include?('.') == false
|
|
109
113
|
e['rhost'] = ee
|
|
110
114
|
end
|
|
111
115
|
end
|