sisimai 5.6.0-java → 5.7.1-java
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 +47 -0
- data/README-JA.md +19 -16
- data/README.md +23 -21
- data/lib/sisimai/address.rb +8 -31
- data/lib/sisimai/arf.rb +5 -6
- data/lib/sisimai/eb.rb +116 -0
- data/lib/sisimai/fact.rb +33 -51
- data/lib/sisimai/lda.rb +20 -18
- data/lib/sisimai/lhost/activehunter.rb +0 -2
- data/lib/sisimai/lhost/amazonses.rb +17 -18
- data/lib/sisimai/lhost/apachejames.rb +0 -1
- data/lib/sisimai/lhost/biglobe.rb +0 -16
- data/lib/sisimai/lhost/courier.rb +9 -7
- data/lib/sisimai/lhost/deutschetelekom.rb +120 -0
- data/lib/sisimai/lhost/domino.rb +2 -4
- data/lib/sisimai/lhost/dragonfly.rb +0 -27
- data/lib/sisimai/lhost/einsundeins.rb +4 -12
- data/lib/sisimai/lhost/exchange2003.rb +12 -11
- data/lib/sisimai/lhost/exchange2007.rb +17 -17
- data/lib/sisimai/lhost/exim.rb +34 -81
- data/lib/sisimai/lhost/ezweb.rb +15 -51
- data/lib/sisimai/lhost/fml.rb +8 -32
- data/lib/sisimai/lhost/gmail.rb +10 -32
- data/lib/sisimai/lhost/gmx.rb +7 -24
- data/lib/sisimai/lhost/googlegroups.rb +6 -5
- data/lib/sisimai/lhost/googleworkspace.rb +2 -5
- data/lib/sisimai/lhost/imailserver.rb +4 -9
- data/lib/sisimai/lhost/kddi.rb +8 -21
- 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 +3 -3
- data/lib/sisimai/lhost/opensmtpd.rb +0 -40
- data/lib/sisimai/lhost/postfix.rb +14 -14
- data/lib/sisimai/lhost/qmail.rb +23 -89
- data/lib/sisimai/lhost/sendmail.rb +8 -7
- data/lib/sisimai/lhost/trendmicro.rb +5 -4
- data/lib/sisimai/lhost/v5sendmail.rb +2 -2
- data/lib/sisimai/lhost/verizon.rb +4 -4
- 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 +1 -1
- data/lib/sisimai/order.rb +4 -1
- data/lib/sisimai/reason/authfailure.rb +8 -7
- data/lib/sisimai/reason/badreputation.rb +5 -4
- data/lib/sisimai/reason/blocked.rb +6 -5
- data/lib/sisimai/reason/contenterror.rb +8 -5
- data/lib/sisimai/reason/delivered.rb +3 -2
- data/lib/sisimai/reason/emailtoolarge.rb +7 -6
- data/lib/sisimai/reason/expired.rb +16 -4
- 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 +14 -4
- data/lib/sisimai/reason/mailboxfull.rb +10 -8
- data/lib/sisimai/reason/mailererror.rb +3 -2
- data/lib/sisimai/reason/networkerror.rb +16 -3
- data/lib/sisimai/reason/norelaying.rb +8 -6
- data/lib/sisimai/reason/notaccept.rb +15 -7
- data/lib/sisimai/reason/notcompliantrfc.rb +5 -3
- data/lib/sisimai/reason/onhold.rb +8 -7
- data/lib/sisimai/reason/policyviolation.rb +11 -5
- data/lib/sisimai/reason/ratelimited.rb +5 -4
- data/lib/sisimai/reason/rejected.rb +24 -14
- data/lib/sisimai/reason/requireptr.rb +5 -4
- data/lib/sisimai/reason/securityerror.rb +5 -3
- data/lib/sisimai/reason/spamdetected.rb +6 -5
- data/lib/sisimai/reason/suppressed.rb +4 -3
- data/lib/sisimai/reason/suspend.rb +8 -3
- data/lib/sisimai/reason/syntaxerror.rb +5 -11
- data/lib/sisimai/reason/systemerror.rb +21 -2
- data/lib/sisimai/reason/systemfull.rb +4 -3
- data/lib/sisimai/reason/undefined.rb +2 -1
- data/lib/sisimai/reason/userunknown.rb +15 -9
- data/lib/sisimai/reason/vacation.rb +2 -1
- data/lib/sisimai/reason/virusdetected.rb +6 -5
- data/lib/sisimai/reason.rb +47 -42
- data/lib/sisimai/rfc1123.rb +1 -1
- data/lib/sisimai/rfc1894.rb +15 -8
- data/lib/sisimai/rfc2045.rb +8 -5
- data/lib/sisimai/rfc3464/thirdparty.rb +11 -10
- data/lib/sisimai/rfc3464.rb +10 -14
- data/lib/sisimai/rfc3834.rb +6 -5
- data/lib/sisimai/rfc791.rb +3 -38
- 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 +37 -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/rhost.rb +1 -1
- 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 +164 -159
- data/lib/sisimai/smtp/transcript.rb +3 -2
- data/lib/sisimai/string.rb +0 -12
- data/lib/sisimai/version.rb +1 -1
- data/lib/sisimai.rb +2 -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/maildir/bsd/lhost-postfix-81.eml +130 -0
- data/set-of-emails/should-not-crash/go-423-deeply-nested-mime-parts.eml +20050 -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 +11 -2
data/lib/sisimai/lhost/gmail.rb
CHANGED
|
@@ -3,6 +3,7 @@ module Sisimai::Lhost
|
|
|
3
3
|
# Methods in the module are called from only Sisimai::Message.
|
|
4
4
|
module Gmail
|
|
5
5
|
class << self
|
|
6
|
+
require 'sisimai/eb'
|
|
6
7
|
require 'sisimai/lhost'
|
|
7
8
|
|
|
8
9
|
Indicators = Sisimai::Lhost.INDICATORS
|
|
@@ -11,24 +12,13 @@ module Sisimai::Lhost
|
|
|
11
12
|
message: ['Delivery to the following recipient'],
|
|
12
13
|
error: ['The error that the other server returned was:'],
|
|
13
14
|
}.freeze
|
|
14
|
-
MessagesOf = {
|
|
15
|
-
'expired' => [
|
|
16
|
-
'DNS Error: Could not contact DNS servers',
|
|
17
|
-
'Delivery to the following recipient has been delayed',
|
|
18
|
-
'The recipient server did not accept our requests to connect',
|
|
19
|
-
],
|
|
20
|
-
'hostunknown' => [
|
|
21
|
-
'DNS Error: Domain name not found',
|
|
22
|
-
'DNS Error: DNS server returned answer with no data',
|
|
23
|
-
],
|
|
24
|
-
}.freeze
|
|
25
15
|
StateTable = {
|
|
26
16
|
# Technical details of permanent failure:
|
|
27
17
|
# Google tried to deliver your message, but it was rejected by the recipient domain.
|
|
28
18
|
# We recommend contacting the other email provider for further information about the
|
|
29
19
|
# cause of this error. The error that the other server returned was:
|
|
30
20
|
# 500 Remote server does not support TLS (state 6).
|
|
31
|
-
'6' => { 'command' =>
|
|
21
|
+
'6' => { 'command' => Sisimai::Eb::CeMAIL, 'reason' => Sisimai::Eb::ReTTLS },
|
|
32
22
|
|
|
33
23
|
# https://www.google.td/support/forum/p/gmail/thread?tid=08a60ebf5db24f7b&hl=en
|
|
34
24
|
# Technical details of permanent failure:
|
|
@@ -36,7 +26,7 @@ module Sisimai::Lhost
|
|
|
36
26
|
# We recommend contacting the other email provider for further information about the
|
|
37
27
|
# cause of this error. The error that the other server returned was:
|
|
38
28
|
# 535 SMTP AUTH failed with the remote server. (state 8).
|
|
39
|
-
'8' => { 'command' =>
|
|
29
|
+
'8' => { 'command' => Sisimai::Eb::CeAUTH, 'reason' => Sisimai::Eb::RePROC },
|
|
40
30
|
|
|
41
31
|
# https://www.google.co.nz/support/forum/p/gmail/thread?tid=45208164dbca9d24&hl=en
|
|
42
32
|
# Technical details of temporary failure:
|
|
@@ -44,7 +34,7 @@ module Sisimai::Lhost
|
|
|
44
34
|
# We recommend contacting the other email provider for further information about the
|
|
45
35
|
# cause of this error. The error that the other server returned was:
|
|
46
36
|
# 454 454 TLS missing certificate: error:0200100D:system library:fopen:Permission denied (#4.3.0) (state 9).
|
|
47
|
-
'9' => { 'command' =>
|
|
37
|
+
'9' => { 'command' => Sisimai::Eb::CeAUTH, 'reason' => Sisimai::Eb::ReTTLS },
|
|
48
38
|
|
|
49
39
|
# https://www.google.com/support/forum/p/gmail/thread?tid=5cfab8c76ec88638&hl=en
|
|
50
40
|
# Technical details of permanent failure:
|
|
@@ -52,14 +42,14 @@ module Sisimai::Lhost
|
|
|
52
42
|
# We recommend contacting the other email provider for further information about the
|
|
53
43
|
# cause of this error. The error that the other server returned was:
|
|
54
44
|
# 500 Remote server does not support SMTP Authenticated Relay (state 12).
|
|
55
|
-
'12' => { 'command' =>
|
|
45
|
+
'12' => { 'command' => Sisimai::Eb::CeAUTH, 'reason' => Sisimai::Eb::RePASS },
|
|
56
46
|
|
|
57
47
|
# Technical details of permanent failure:
|
|
58
48
|
# Google tried to deliver your message, but it was rejected by the recipient domain.
|
|
59
49
|
# We recommend contacting the other email provider for further information about the
|
|
60
50
|
# cause of this error. The error that the other server returned was:
|
|
61
51
|
# 550 550 5.7.1 <****@gmail.com>... Access denied (state 13).
|
|
62
|
-
'13' => { 'command' =>
|
|
52
|
+
'13' => { 'command' => Sisimai::Eb::CeEHLO, 'reason' => Sisimai::Eb::ReBLOC },
|
|
63
53
|
|
|
64
54
|
# Technical details of permanent failure:
|
|
65
55
|
# Google tried to deliver your message, but it was rejected by the recipient domain.
|
|
@@ -68,7 +58,7 @@ module Sisimai::Lhost
|
|
|
68
58
|
# 550 550 5.1.1 <******@*********.**>... User Unknown (state 14).
|
|
69
59
|
# 550 550 5.2.2 <*****@****.**>... Mailbox Full (state 14).
|
|
70
60
|
#
|
|
71
|
-
'14' => { 'command' =>
|
|
61
|
+
'14' => { 'command' => Sisimai::Eb::CeRCPT, 'reason' => Sisimai::Eb::ReUSER },
|
|
72
62
|
|
|
73
63
|
# https://www.google.cz/support/forum/p/gmail/thread?tid=7090cbfd111a24f9&hl=en
|
|
74
64
|
# Technical details of permanent failure:
|
|
@@ -77,7 +67,7 @@ module Sisimai::Lhost
|
|
|
77
67
|
# cause of this error. The error that the other server returned was:
|
|
78
68
|
# 550 550 5.7.1 SPF unauthorized mail is prohibited. (state 15).
|
|
79
69
|
# 554 554 Error: no valid recipients (state 15).
|
|
80
|
-
'15' => { 'command' =>
|
|
70
|
+
'15' => { 'command' => Sisimai::Eb::CeDATA, 'reason' => Sisimai::Eb::ReFILT },
|
|
81
71
|
|
|
82
72
|
# https://www.google.com/support/forum/p/Google%20Apps/thread?tid=0aac163bc9c65d8e&hl=en
|
|
83
73
|
# Technical details of permanent failure:
|
|
@@ -86,14 +76,14 @@ module Sisimai::Lhost
|
|
|
86
76
|
# cause of this error. The error that the other server returned was:
|
|
87
77
|
# 550 550 <****@***.**> No such user here (state 17).
|
|
88
78
|
# 550 550 #5.1.0 Address rejected ***@***.*** (state 17).
|
|
89
|
-
'17' => { 'command' =>
|
|
79
|
+
'17' => { 'command' => Sisimai::Eb::CeDATA, 'reason' => Sisimai::Eb::ReFILT },
|
|
90
80
|
|
|
91
81
|
# Technical details of permanent failure:
|
|
92
82
|
# Google tried to deliver your message, but it was rejected by the recipient domain.
|
|
93
83
|
# We recommend contacting the other email provider for further information about the
|
|
94
84
|
# cause of this error. The error that the other server returned was:
|
|
95
85
|
# 550 550 Unknown user *****@***.**.*** (state 18).
|
|
96
|
-
'18' => { 'command' =>
|
|
86
|
+
'18' => { 'command' => Sisimai::Eb::CeDATA, 'reason' => Sisimai::Eb::ReFILT },
|
|
97
87
|
}.freeze
|
|
98
88
|
|
|
99
89
|
# @abstract Decodes the bounce message from Gmail
|
|
@@ -205,8 +195,6 @@ module Sisimai::Lhost
|
|
|
205
195
|
require 'sisimai/string'
|
|
206
196
|
require 'sisimai/rfc1123'
|
|
207
197
|
dscontents.each do |e|
|
|
208
|
-
e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
|
|
209
|
-
|
|
210
198
|
if Sisimai::String.aligned(e['diagnosis'], [' by ', '. [', ']. '])
|
|
211
199
|
# Get the value of remote host
|
|
212
200
|
# Google tried to deliver your message, but it was rejected by the server for the recipient
|
|
@@ -232,16 +220,6 @@ module Sisimai::Lhost
|
|
|
232
220
|
e['command'] = StateTable[cu]['command']
|
|
233
221
|
break
|
|
234
222
|
end
|
|
235
|
-
|
|
236
|
-
if e['reason'].empty?
|
|
237
|
-
# There is no no state code in the error message
|
|
238
|
-
MessagesOf.each_key do |r|
|
|
239
|
-
# Verify each regular expression of session errors
|
|
240
|
-
next if MessagesOf[r].none? { |a| e['diagnosis'].include?(a) }
|
|
241
|
-
e['reason'] = r
|
|
242
|
-
break
|
|
243
|
-
end
|
|
244
|
-
end
|
|
245
223
|
next if e['reason'].empty?
|
|
246
224
|
|
|
247
225
|
# Set pseudo status code
|
data/lib/sisimai/lhost/gmx.rb
CHANGED
|
@@ -8,7 +8,6 @@ module Sisimai::Lhost
|
|
|
8
8
|
Indicators = Sisimai::Lhost.INDICATORS
|
|
9
9
|
Boundaries = ['--- The header of the original message is following. ---'].freeze
|
|
10
10
|
StartingOf = {message: ['This message was created automatically by mail delivery software']}.freeze
|
|
11
|
-
MessagesOf = {'expired' => ['delivery retry timeout exceeded']}.freeze
|
|
12
11
|
|
|
13
12
|
# @abstract Decodes the bounce message from GMX
|
|
14
13
|
# @param [Hash] mhead Message headers of a bounce email
|
|
@@ -65,33 +64,17 @@ module Sisimai::Lhost
|
|
|
65
64
|
end
|
|
66
65
|
v['recipient'] = Sisimai::Address.s3s4(e)
|
|
67
66
|
recipients += 1
|
|
68
|
-
|
|
69
|
-
elsif e.start_with?('SMTP error ')
|
|
70
|
-
# SMTP error from remote server after RCPT command:
|
|
71
|
-
v['command'] = Sisimai::SMTP::Command.find(e)
|
|
72
|
-
|
|
73
|
-
elsif e.start_with?('host:')
|
|
74
|
-
# host: mx.example.jp
|
|
75
|
-
v['rhost'] = e[6, e.size]
|
|
76
67
|
else
|
|
77
|
-
#
|
|
78
|
-
|
|
79
|
-
|
|
68
|
+
# - SMTP error from remote server after RCPT command:
|
|
69
|
+
# - host: mx.example.jp
|
|
70
|
+
case
|
|
71
|
+
when e.start_with?('SMTP error ') then v['command'] = Sisimai::SMTP::Command.find(e)
|
|
72
|
+
when e.start_with?('host:') then v['rhost'] = e[6, e.size]
|
|
73
|
+
else v['diagnosis'] += "#{e }" if e.empty? == false
|
|
74
|
+
end
|
|
80
75
|
end
|
|
81
76
|
end
|
|
82
77
|
return nil if recipients == 0
|
|
83
|
-
|
|
84
|
-
dscontents.each do |e|
|
|
85
|
-
e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'].tr("\n", ' '))
|
|
86
|
-
|
|
87
|
-
MessagesOf.each_key do |r|
|
|
88
|
-
# Verify each regular expression of session errors
|
|
89
|
-
next if MessagesOf[r].none? { |a| e['diagnosis'].include?(a) }
|
|
90
|
-
e['reason'] = r
|
|
91
|
-
break
|
|
92
|
-
end
|
|
93
|
-
end
|
|
94
|
-
|
|
95
78
|
return {"ds" => dscontents, "rfc822" => emailparts[1]}
|
|
96
79
|
end
|
|
97
80
|
def description; return 'GMX: https://www.gmx.net'; end
|
|
@@ -3,6 +3,7 @@ module Sisimai::Lhost
|
|
|
3
3
|
# Methods in the module are called from only Sisimai::Message.
|
|
4
4
|
module GoogleGroups
|
|
5
5
|
class << self
|
|
6
|
+
require 'sisimai/eb'
|
|
6
7
|
require 'sisimai/lhost'
|
|
7
8
|
Boundaries = ['----- Original message -----', 'Content-Type: message/rfc822'].freeze
|
|
8
9
|
|
|
@@ -13,10 +14,10 @@ module Sisimai::Lhost
|
|
|
13
14
|
# @return [Nil] it failed to decode or the arguments are missing
|
|
14
15
|
# @since v4.25.6
|
|
15
16
|
def inquire(mhead, mbody)
|
|
16
|
-
return nil if mbody.include?("Google
|
|
17
|
+
return nil if mbody.include?("Google Group") == false
|
|
17
18
|
return nil if mhead['from'].end_with?('<mailer-daemon@googlemail.com>') == false
|
|
18
19
|
return nil if mhead['subject'].start_with?('Delivery Status Notification') == false
|
|
19
|
-
return nil if mhead['x-failed-recipients'].nil?
|
|
20
|
+
return nil if mhead['x-failed-recipients'].nil?
|
|
20
21
|
|
|
21
22
|
# Hello kijitora@libsisimai.org,
|
|
22
23
|
#
|
|
@@ -46,11 +47,11 @@ module Sisimai::Lhost
|
|
|
46
47
|
entiremesg = emailparts[0].split(/\n\n/, 5).slice(0, 4).join(' ').tr("\n", ' ');
|
|
47
48
|
receivedby = mhead['received'] || []
|
|
48
49
|
recordwide = {
|
|
49
|
-
'diagnosis' =>
|
|
50
|
-
'reason' =>
|
|
50
|
+
'diagnosis' => entiremesg,
|
|
51
|
+
'reason' => Sisimai::Eb::Re___1,
|
|
51
52
|
'rhost' => Sisimai::RFC5322.received(receivedby[0])[1],
|
|
52
53
|
}
|
|
53
|
-
recordwide['reason'] =
|
|
54
|
+
recordwide['reason'] = Sisimai::Eb::ReFROM if emailparts[0].scan(/^[ ]?[*][ ]?/).size == 4
|
|
54
55
|
|
|
55
56
|
mhead['x-failed-recipients'].split(',').each do |e|
|
|
56
57
|
# X-Failed-Recipients: neko@example.jp, nyaan@example.org, ...
|
|
@@ -3,6 +3,7 @@ module Sisimai::Lhost
|
|
|
3
3
|
# Methods in the module are called only from Sisimai::Message.
|
|
4
4
|
module GoogleWorkspace
|
|
5
5
|
class << self
|
|
6
|
+
require 'sisimai/eb'
|
|
6
7
|
require 'sisimai/lhost'
|
|
7
8
|
require 'sisimai/string'
|
|
8
9
|
require 'sisimai/address'
|
|
@@ -14,9 +15,7 @@ module Sisimai::Lhost
|
|
|
14
15
|
error: ["The response was:", "The response from the remote server was:"],
|
|
15
16
|
}.freeze
|
|
16
17
|
MessagesOf = {
|
|
17
|
-
|
|
18
|
-
"notaccept" => ["Null MX"],
|
|
19
|
-
"networkerror" => [" had no relevant answers.", " responded with code NXDOMAIN"],
|
|
18
|
+
Sisimai::Eb::ReUSER => ["because the address couldn't be found. Check for typos or unnecessary spaces and try again."],
|
|
20
19
|
}.freeze
|
|
21
20
|
|
|
22
21
|
# @abstract Decodes the bounce message from Google Workspace
|
|
@@ -73,8 +72,6 @@ module Sisimai::Lhost
|
|
|
73
72
|
|
|
74
73
|
dscontents[0]["diagnosis"] = entiremesg
|
|
75
74
|
dscontents.each do |e|
|
|
76
|
-
# Tidy up the error message in e["diagnosis"], Try to detect the bounce reason.
|
|
77
|
-
e["diagnosis"] = Sisimai::String.sweep(e["diagnosis"])
|
|
78
75
|
MessagesOf.each_key do |r|
|
|
79
76
|
# Guess an reason of the bounce
|
|
80
77
|
next if MessagesOf[r].none? { |a| e["diagnosis"].include?(a) }
|
|
@@ -4,17 +4,14 @@ module Sisimai::Lhost
|
|
|
4
4
|
# Methods in the module are called from only Sisimai::Message.
|
|
5
5
|
module IMailServer
|
|
6
6
|
class << self
|
|
7
|
+
require 'sisimai/eb'
|
|
7
8
|
require 'sisimai/lhost'
|
|
8
9
|
|
|
9
10
|
Boundaries = ['Original message follows.'].freeze
|
|
10
11
|
StartingOf = {error: ['Body of message generated response:']}.freeze
|
|
11
12
|
MessagesOf = {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
'mailboxfull' => ['User mailbox exceeds allowed size'],
|
|
15
|
-
'virusdetected' => ['Requested action not taken: virus detected'],
|
|
16
|
-
'spamdetected' => ['Blacklisted URL in message'],
|
|
17
|
-
'expired' => ['Delivery failed '],
|
|
13
|
+
Sisimai::Eb::ReUSER => ['Unknown user', 'Invalid final delivery userid'],
|
|
14
|
+
Sisimai::Eb::ReTIME => ['Delivery failed '],
|
|
18
15
|
}.freeze
|
|
19
16
|
|
|
20
17
|
# @abstract Decodes the bounce message from Progress iMail Server
|
|
@@ -72,11 +69,9 @@ module Sisimai::Lhost
|
|
|
72
69
|
else
|
|
73
70
|
e['alterrors']
|
|
74
71
|
end
|
|
75
|
-
e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
|
|
76
72
|
e.delete('alterrors')
|
|
77
73
|
end
|
|
78
|
-
e['
|
|
79
|
-
e['command'] = Sisimai::SMTP::Command.find(e['diagnosis'])
|
|
74
|
+
e['command'] = Sisimai::SMTP::Command.find(e['diagnosis'])
|
|
80
75
|
|
|
81
76
|
MessagesOf.each_key do |r|
|
|
82
77
|
# Verify each regular expression of session errors
|
data/lib/sisimai/lhost/kddi.rb
CHANGED
|
@@ -3,16 +3,12 @@ module Sisimai::Lhost
|
|
|
3
3
|
# Methods in the module are called from only Sisimai::Message.
|
|
4
4
|
module KDDI
|
|
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 mail sent on:', 'Your mail attempted to be delivered on:']}.freeze
|
|
11
|
-
MessagesOf = {
|
|
12
|
-
'mailboxfull' => ['As their mailbox is full'],
|
|
13
|
-
'norelaying' => ['Due to the following SMTP relay error'],
|
|
14
|
-
'hostunknown' => ['As the remote domain doesnt exist'],
|
|
15
|
-
}.freeze
|
|
16
12
|
|
|
17
13
|
# @abstract Decodes the bounce message from au by KDDI
|
|
18
14
|
# @param [Hash] mhead Message headers of a bounce email
|
|
@@ -45,7 +41,8 @@ module Sisimai::Lhost
|
|
|
45
41
|
next if (readcursor & Indicators[:deliverystatus]) == 0 || e.empty?
|
|
46
42
|
|
|
47
43
|
v = dscontents[-1]
|
|
48
|
-
|
|
44
|
+
case
|
|
45
|
+
when e.include?(' Could not be delivered to: <')
|
|
49
46
|
# Your mail sent on: Thu, 29 Apr 2010 11:04:47 +0900
|
|
50
47
|
# Could not be delivered to: <******@**.***.**>
|
|
51
48
|
# As their mailbox is full.
|
|
@@ -59,7 +56,7 @@ module Sisimai::Lhost
|
|
|
59
56
|
v['recipient'] = r
|
|
60
57
|
recipients += 1
|
|
61
58
|
|
|
62
|
-
|
|
59
|
+
when e.include?('Your mail sent on: ')
|
|
63
60
|
# Your mail sent on: Thu, 29 Apr 2010 11:04:47 +0900
|
|
64
61
|
v['date'] = e[19, e.size]
|
|
65
62
|
else
|
|
@@ -71,26 +68,16 @@ module Sisimai::Lhost
|
|
|
71
68
|
|
|
72
69
|
require 'sisimai/smtp/command'
|
|
73
70
|
dscontents.each do |e|
|
|
74
|
-
e['diagnosis'] = Sisimai::String.sweep(e['diagnosis']) || ''
|
|
75
71
|
e['command'] = Sisimai::SMTP::Command.find(e['diagnosis'])
|
|
76
72
|
|
|
77
73
|
if mhead['x-spasign'].to_s == 'NG'
|
|
78
74
|
# Content-Type: text/plain; ..., X-SPASIGN: NG (spamghetti, au by KDDI)
|
|
79
75
|
# Filtered recipient returns message that include 'X-SPASIGN' header
|
|
80
|
-
e['reason'] =
|
|
76
|
+
e['reason'] = Sisimai::Eb::ReFILT
|
|
81
77
|
else
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
else
|
|
86
|
-
# SMTP command is not RCPT
|
|
87
|
-
MessagesOf.each_key do |r|
|
|
88
|
-
# Verify each regular expression of session errors
|
|
89
|
-
next if MessagesOf[r].none? { |a| e['diagnosis'].include?(a) }
|
|
90
|
-
e['reason'] = r
|
|
91
|
-
break
|
|
92
|
-
end
|
|
93
|
-
end
|
|
78
|
+
# There is no X-SPASIGN: header in the bounce message
|
|
79
|
+
# set "UserUnknown" when the remote server rejected after RCPT command.
|
|
80
|
+
e['reason'] = Sisimai::Eb::ReUSER if e['command'] == Sisimai::Eb::CeRCPT
|
|
94
81
|
end
|
|
95
82
|
end
|
|
96
83
|
|
|
@@ -65,8 +65,6 @@ module Sisimai::Lhost
|
|
|
65
65
|
end
|
|
66
66
|
end
|
|
67
67
|
return nil if recipients == 0
|
|
68
|
-
|
|
69
|
-
dscontents.each { |e| e['diagnosis'] = Sisimai::String.sweep(e['diagnosis']) }
|
|
70
68
|
return { 'ds' => dscontents, 'rfc822' => emailparts[1] }
|
|
71
69
|
end
|
|
72
70
|
def description; return 'MailFoundry'; end
|
|
@@ -103,15 +103,13 @@ module Sisimai::Lhost
|
|
|
103
103
|
p1 = e.index(' From:') || e.index(' Subject:')
|
|
104
104
|
p2 = e.index(':')
|
|
105
105
|
cf = e[p1 + 1, p2 - p1 - 1]
|
|
106
|
-
cv =
|
|
106
|
+
cv = e[p2 + 1, e.size]
|
|
107
107
|
emailparts[1] += sprintf("%s: %s\n", cf, cv)
|
|
108
108
|
end
|
|
109
109
|
end
|
|
110
110
|
end
|
|
111
111
|
end
|
|
112
112
|
return nil if recipients == 0
|
|
113
|
-
|
|
114
|
-
dscontents.each { |e| e['diagnosis'] = Sisimai::String.sweep(e['diagnosis']) }
|
|
115
113
|
return { 'ds' => dscontents, 'rfc822' => emailparts[1] }
|
|
116
114
|
end
|
|
117
115
|
def description; return 'Trustwave Secure Email Gateway'; end
|
|
@@ -9,7 +9,6 @@ module Sisimai::Lhost
|
|
|
9
9
|
Indicators = Sisimai::Lhost.INDICATORS
|
|
10
10
|
Boundaries = ['Content-Type: message/rfc822', 'Return-path: '].freeze
|
|
11
11
|
StartingOf = {message: ['This report relates to a message you sent with the following header fields:']}.freeze
|
|
12
|
-
MessagesOf = {'hostunknown' => ['Illegal host/domain name found']}.freeze
|
|
13
12
|
|
|
14
13
|
# @abstract Decodes the bounce message from MessagingServer
|
|
15
14
|
# @param [Hash] mhead Message headers of a bounce email
|
|
@@ -115,18 +114,19 @@ module Sisimai::Lhost
|
|
|
115
114
|
# (6jo.example.jp ESMTP SENDMAIL-VM)
|
|
116
115
|
# Diagnostic-code: smtp;550 5.1.1 <kijitora@example.jp>... User Unknown
|
|
117
116
|
#
|
|
118
|
-
|
|
117
|
+
case
|
|
118
|
+
when e.start_with?('Status: ')
|
|
119
119
|
# Status: 5.1.1 (Remote SMTP server has rejected address)
|
|
120
120
|
p1 = e.index(':')
|
|
121
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
|
|
|
125
|
-
|
|
125
|
+
when e.start_with?('Arrival-Date: ')
|
|
126
126
|
# Arrival-date: Thu, 29 Apr 2014 23:34:45 +0000 (GMT)
|
|
127
127
|
v['date'] = e[e.index(':') + 2, e.size] if v["date"].empty?
|
|
128
128
|
|
|
129
|
-
|
|
129
|
+
when e.start_with?('Reporting-MTA: ')
|
|
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?
|
|
@@ -135,17 +135,6 @@ module Sisimai::Lhost
|
|
|
135
135
|
end
|
|
136
136
|
end
|
|
137
137
|
return nil if recipients == 0
|
|
138
|
-
|
|
139
|
-
dscontents.each do |e|
|
|
140
|
-
e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
|
|
141
|
-
MessagesOf.each_key do |r|
|
|
142
|
-
# Verify each regular expression of session errors
|
|
143
|
-
next if MessagesOf[r].none? { |a| e['diagnosis'].include?(a) }
|
|
144
|
-
e['reason'] = r
|
|
145
|
-
break
|
|
146
|
-
end
|
|
147
|
-
end
|
|
148
|
-
|
|
149
138
|
return {"ds" => dscontents, "rfc822" => emailparts[1]}
|
|
150
139
|
end
|
|
151
140
|
def description; return 'Oracle Communications Messaging Server'; end
|
|
@@ -93,7 +93,6 @@ module Sisimai::Lhost
|
|
|
93
93
|
dscontents.each do |e|
|
|
94
94
|
# Set default values if each value is empty.
|
|
95
95
|
permessage.each_key { |a| e[a] ||= permessage[a] || '' }
|
|
96
|
-
e['diagnosis'] = Sisimai::String.sweep(e['diagnosis']) || ''
|
|
97
96
|
end
|
|
98
97
|
|
|
99
98
|
return { 'ds' => dscontents, 'rfc822' => emailparts[1] }
|
data/lib/sisimai/lhost/notes.rb
CHANGED
|
@@ -3,17 +3,17 @@ module Sisimai::Lhost
|
|
|
3
3
|
# (formerly Lotus Notes Server)). Methods in the module are called from only Sisimai::Message.
|
|
4
4
|
module Notes
|
|
5
5
|
class << self
|
|
6
|
+
require 'sisimai/eb'
|
|
6
7
|
require 'sisimai/lhost'
|
|
7
8
|
|
|
8
9
|
Indicators = Sisimai::Lhost.INDICATORS
|
|
9
10
|
Boundaries = ['------- Returned Message --------'].freeze
|
|
10
11
|
StartingOf = {message: ['------- Failure Reasons ']}.freeze
|
|
11
12
|
MessagesOf = {
|
|
12
|
-
|
|
13
|
+
Sisimai::Eb::ReUSER => [
|
|
13
14
|
'User not listed in public Name & Address Book',
|
|
14
15
|
'ディレクトリのリストにありません',
|
|
15
16
|
],
|
|
16
|
-
'networkerror' => ['Message has exceeded maximum hop count'],
|
|
17
17
|
}.freeze
|
|
18
18
|
|
|
19
19
|
# @abstract Decodes the bounce messages from HCL Notes (Formerly IBM Notes (Formerly Lotus Notes))
|
|
@@ -101,7 +101,7 @@ module Sisimai::Lhost
|
|
|
101
101
|
return nil if recipients == 0
|
|
102
102
|
|
|
103
103
|
dscontents.each do |e|
|
|
104
|
-
e['diagnosis'] =
|
|
104
|
+
e['diagnosis'] = e['diagnosis'].split.join(" ")
|
|
105
105
|
e['recipient'] = Sisimai::Address.s3s4(e['recipient'])
|
|
106
106
|
|
|
107
107
|
MessagesOf.each_key do |r|
|
|
@@ -35,36 +35,6 @@ module Sisimai::Lhost
|
|
|
35
35
|
# bounce.c/339:
|
|
36
36
|
message: [' This is the MAILER-DAEMON, please DO NOT REPLY to this '],
|
|
37
37
|
}.freeze
|
|
38
|
-
MessagesOf = {
|
|
39
|
-
# smtpd/queue.c:221| envelope_set_errormsg(&evp, "Envelope expired");
|
|
40
|
-
'expired' => ['Envelope expired'],
|
|
41
|
-
# smtpd/mta.c:976| relay->failstr = "Invalid domain name";
|
|
42
|
-
# smtpd/mta.c:980| relay->failstr = "Domain does not exist";
|
|
43
|
-
'hostunknown' => [
|
|
44
|
-
'Invalid domain name',
|
|
45
|
-
'Domain does not exist',
|
|
46
|
-
],
|
|
47
|
-
# smtp/mta.c:1085| relay->failstr = "Destination seem to reject all mails";
|
|
48
|
-
'notaccept' => [
|
|
49
|
-
'Destination seem to reject all mails',
|
|
50
|
-
'No MX found for domain',
|
|
51
|
-
'No MX found for destination',
|
|
52
|
-
],
|
|
53
|
-
# smtpd/mta.c:972| relay->failstr = "Temporary failure in MX lookup";
|
|
54
|
-
'networkerror' => [
|
|
55
|
-
'Address family mismatch on destination MXs',
|
|
56
|
-
'All routes to destination blocked',
|
|
57
|
-
'bad DNS lookup error code',
|
|
58
|
-
'Could not retrieve source address',
|
|
59
|
-
'Loop detected',
|
|
60
|
-
'Network error on destination MXs',
|
|
61
|
-
'No valid route to remote MX',
|
|
62
|
-
'No valid route to destination',
|
|
63
|
-
'Temporary failure in MX lookup',
|
|
64
|
-
],
|
|
65
|
-
# smtpd/mta.c:1013| relay->failstr = "Could not retrieve credentials";
|
|
66
|
-
'securityerror' => ['Could not retrieve credentials'],
|
|
67
|
-
}.freeze
|
|
68
38
|
|
|
69
39
|
# @abstract Decodes the bounce message from OpenSMTPD
|
|
70
40
|
# @param [Hash] mhead Message headers of a bounce email
|
|
@@ -117,16 +87,6 @@ module Sisimai::Lhost
|
|
|
117
87
|
end
|
|
118
88
|
end
|
|
119
89
|
return nil if recipients == 0
|
|
120
|
-
|
|
121
|
-
dscontents.each do |e|
|
|
122
|
-
e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
|
|
123
|
-
MessagesOf.each_key do |r|
|
|
124
|
-
# Verify each regular expression of session errors
|
|
125
|
-
next if MessagesOf[r].none? { |a| e['diagnosis'].include?(a) }
|
|
126
|
-
e['reason'] = r
|
|
127
|
-
break
|
|
128
|
-
end
|
|
129
|
-
end
|
|
130
90
|
return { 'ds' => dscontents, 'rfc822' => emailparts[1] }
|
|
131
91
|
end
|
|
132
92
|
def description; return 'OpenSMTPD'; end
|
|
@@ -3,6 +3,7 @@ module Sisimai::Lhost
|
|
|
3
3
|
# Methods in the module are called from only Sisimai::Message.
|
|
4
4
|
module Postfix
|
|
5
5
|
class << self
|
|
6
|
+
require 'sisimai/eb'
|
|
6
7
|
require 'sisimai/lhost'
|
|
7
8
|
require 'sisimai/rfc1123'
|
|
8
9
|
require 'sisimai/smtp/reply'
|
|
@@ -63,15 +64,14 @@ module Sisimai::Lhost
|
|
|
63
64
|
v ||= dscontents[-1]
|
|
64
65
|
p = e['response']
|
|
65
66
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
elsif e['command'] == 'MAIL'
|
|
67
|
+
case e["command"]
|
|
68
|
+
# Use the argument of EHLO/HELO command as a value of "lhost"
|
|
69
|
+
when Sisimai::Eb::CeHELO, Sisimai::Eb::CeEHLO then v['lhost'] = e['argument']
|
|
70
|
+
when Sisimai::Eb::CeMAIL
|
|
71
71
|
# Set the argument of "MAIL" command to pseudo To: header of the original message
|
|
72
72
|
emailparts[1] += sprintf("To: %s\n", e['argument']) if emailparts[1].size == 0
|
|
73
73
|
|
|
74
|
-
|
|
74
|
+
when Sisimai::Eb::CeRCPT
|
|
75
75
|
# RCPT TO: <...>
|
|
76
76
|
if v["recipient"] != ""
|
|
77
77
|
# There are multiple recipient addresses in the transcript of session
|
|
@@ -110,7 +110,8 @@ module Sisimai::Lhost
|
|
|
110
110
|
next unless o = Sisimai::RFC1894.field(e)
|
|
111
111
|
v = dscontents[-1]
|
|
112
112
|
|
|
113
|
-
|
|
113
|
+
case o[3]
|
|
114
|
+
when "addr"
|
|
114
115
|
# Final-Recipient: rfc822; kijitora@example.jp
|
|
115
116
|
# X-Actual-Recipient: rfc822; kijitora@example.co.jp
|
|
116
117
|
if Sisimai::Address.is_emailaddress(o[2])
|
|
@@ -130,7 +131,7 @@ module Sisimai::Lhost
|
|
|
130
131
|
v['alias'] = o[2]
|
|
131
132
|
end
|
|
132
133
|
end
|
|
133
|
-
|
|
134
|
+
when "code"
|
|
134
135
|
# Diagnostic-Code: SMTP; 550 5.1.1 <userunknown@example.jp>... User Unknown
|
|
135
136
|
v['spec'] = o[1]
|
|
136
137
|
v['spec'] = 'SMTP' if v['spec'].upcase == 'X-POSTFIX'
|
|
@@ -154,7 +155,7 @@ module Sisimai::Lhost
|
|
|
154
155
|
# 5.1.1 <userunknown@example.co.jp>... User Unknown (in reply to RCPT TO command)
|
|
155
156
|
if readslices[-2].start_with?('Diagnostic-Code:') && e.include?(' ')
|
|
156
157
|
# Continued line of the value of Diagnostic-Code header
|
|
157
|
-
v['diagnosis'] += "
|
|
158
|
+
v['diagnosis'] += " " + e.split.join(" ")
|
|
158
159
|
readslices[-1] = "Diagnostic-Code: #{e}"
|
|
159
160
|
|
|
160
161
|
elsif Sisimai::String.aligned(e, ['X-Postfix-Sender:', 'rfc822;', '@'])
|
|
@@ -238,7 +239,7 @@ module Sisimai::Lhost
|
|
|
238
239
|
|
|
239
240
|
if anotherset['diagnosis']
|
|
240
241
|
# Copy alternative error message
|
|
241
|
-
anotherset['diagnosis'] =
|
|
242
|
+
anotherset['diagnosis'] = anotherset['diagnosis'].split.join(" ")
|
|
242
243
|
e['diagnosis'] = anotherset['diagnosis'] if e['diagnosis'].nil? || e['diagnosis'].empty?
|
|
243
244
|
|
|
244
245
|
if e['diagnosis'] =~ /\A\d+\z/
|
|
@@ -277,10 +278,9 @@ module Sisimai::Lhost
|
|
|
277
278
|
end
|
|
278
279
|
end
|
|
279
280
|
|
|
280
|
-
e['
|
|
281
|
-
e['command']
|
|
282
|
-
e['
|
|
283
|
-
e['spec'] = 'SMTP' if e["spec"].empty? && Sisimai::String.aligned(e['diagnosis'], ['host ', ' said:'])
|
|
281
|
+
e['command'] = commandset.shift || Sisimai::SMTP::Command.find(e['diagnosis'])
|
|
282
|
+
e['command'] = Sisimai::Eb::CeHELO if e["command"].empty? && e['diagnosis'].include?('refused to talk to me:')
|
|
283
|
+
e['spec'] = 'SMTP' if e["spec"].empty? && Sisimai::String.aligned(e['diagnosis'], ['host ', ' said:'])
|
|
284
284
|
end
|
|
285
285
|
|
|
286
286
|
return { 'ds' => dscontents, 'rfc822' => emailparts[1] }
|