sisimai 5.4.1-java → 5.6.0-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/codecovio.yml +1 -1
- data/.github/workflows/rake-test.yml +1 -1
- data/ChangeLog.md +56 -0
- data/LICENSE +1 -1
- data/Makefile +2 -4
- data/README-JA.md +29 -23
- data/README.md +30 -24
- 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 +76 -36
- data/lib/sisimai/lda.rb +2 -2
- data/lib/sisimai/lhost/activehunter.rb +4 -5
- data/lib/sisimai/lhost/amazonses.rb +4 -5
- 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 +5 -5
- data/lib/sisimai/lhost/exchange2003.rb +7 -7
- data/lib/sisimai/lhost/exchange2007.rb +5 -5
- data/lib/sisimai/lhost/exim.rb +13 -15
- 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 +11 -11
- 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 +36 -34
- data/lib/sisimai/order.rb +5 -4
- data/lib/sisimai/reason/authfailure.rb +10 -14
- data/lib/sisimai/reason/badreputation.rb +8 -8
- data/lib/sisimai/reason/blocked.rb +58 -83
- data/lib/sisimai/reason/contenterror.rb +15 -10
- data/lib/sisimai/reason/{mesgtoobig.rb → emailtoolarge.rb} +23 -26
- data/lib/sisimai/reason/expired.rb +17 -24
- data/lib/sisimai/reason/failedstarttls.rb +1 -1
- data/lib/sisimai/reason/filtered.rb +14 -18
- data/lib/sisimai/reason/hasmoved.rb +3 -2
- data/lib/sisimai/reason/hostunknown.rb +18 -21
- data/lib/sisimai/reason/mailboxfull.rb +28 -50
- data/lib/sisimai/reason/mailererror.rb +1 -1
- data/lib/sisimai/reason/networkerror.rb +17 -17
- data/lib/sisimai/reason/norelaying.rb +20 -20
- data/lib/sisimai/reason/notaccept.rb +7 -10
- data/lib/sisimai/reason/notcompliantrfc.rb +6 -10
- data/lib/sisimai/reason/policyviolation.rb +12 -28
- data/lib/sisimai/reason/ratelimited.rb +62 -0
- data/lib/sisimai/reason/rejected.rb +46 -58
- data/lib/sisimai/reason/requireptr.rb +14 -26
- data/lib/sisimai/reason/securityerror.rb +14 -20
- data/lib/sisimai/reason/spamdetected.rb +52 -102
- data/lib/sisimai/reason/suspend.rb +27 -24
- data/lib/sisimai/reason/systemerror.rb +20 -24
- data/lib/sisimai/reason/systemfull.rb +2 -2
- data/lib/sisimai/reason/userunknown.rb +82 -114
- data/lib/sisimai/reason/vacation.rb +1 -1
- data/lib/sisimai/reason/virusdetected.rb +7 -9
- data/lib/sisimai/reason.rb +26 -26
- 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 +15 -11
- data/lib/sisimai/rhost/cloudflare.rb +2 -0
- data/lib/sisimai/rhost/cox.rb +31 -25
- data/lib/sisimai/rhost/facebook.rb +24 -18
- data/lib/sisimai/rhost/franceptt.rb +92 -38
- data/lib/sisimai/rhost/godaddy.rb +34 -7
- data/lib/sisimai/rhost/google.rb +69 -70
- data/lib/sisimai/rhost/gsuite.rb +1 -1
- data/lib/sisimai/rhost/iua.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 +154 -107
- data/lib/sisimai/rhost/mimecast.rb +64 -55
- data/lib/sisimai/rhost/nttdocomo.rb +70 -90
- data/lib/sisimai/rhost/outlook.rb +1 -1
- data/lib/sisimai/rhost/spectrum.rb +8 -8
- data/lib/sisimai/rhost/tencent.rb +12 -13
- data/lib/sisimai/rhost/yahooinc.rb +9 -10
- data/lib/sisimai/rhost/zoho.rb +72 -0
- data/lib/sisimai/rhost.rb +4 -3
- data/lib/sisimai/smtp/command.rb +4 -2
- data/lib/sisimai/smtp/reply.rb +11 -4
- data/lib/sisimai/smtp/status.rb +67 -98
- data/lib/sisimai/smtp/transcript.rb +3 -3
- data/lib/sisimai/string.rb +4 -23
- 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-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 +28 -13
- 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/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
|
@@ -7,8 +7,8 @@ module Sisimai
|
|
|
7
7
|
class << self
|
|
8
8
|
MessagesOf = {
|
|
9
9
|
'mailboxfull' => ['552 too much mail data'],
|
|
10
|
+
'ratelimited' => ['552 too many recipients'],
|
|
10
11
|
'syntaxerror' => ['503 bad sequence of commands', '504 command parameter not implemented'],
|
|
11
|
-
'toomanyconn' => ['552 too many recipients'],
|
|
12
12
|
'userunknown' => ['550 unknown user'],
|
|
13
13
|
}.freeze
|
|
14
14
|
|
|
@@ -16,106 +16,86 @@ module Sisimai
|
|
|
16
16
|
# @param [Sisimai::Fact] argvs Decoded email object
|
|
17
17
|
# @return [String] The bounce reason for docomo.ne.jp
|
|
18
18
|
def find(argvs)
|
|
19
|
-
return argvs['reason']
|
|
19
|
+
return argvs['reason'] if argvs['reason'].empty? == false
|
|
20
20
|
statuscode = argvs['deliverystatus'] || ''
|
|
21
21
|
thecommand = argvs['command'] || ''
|
|
22
22
|
esmtperror = argvs['diagnosticcode'].downcase || ''
|
|
23
|
-
reasontext = ''
|
|
24
23
|
|
|
25
24
|
# Check the value of Status: field, an SMTP Reply Code, and the SMTP Command
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
reasontext = 'filtered'
|
|
25
|
+
#
|
|
26
|
+
# ----- Transcript of session follows -----
|
|
27
|
+
# ... while talking to mfsmax.docomo.ne.jp.:
|
|
28
|
+
# >>> RCPT To:<***@docomo.ne.jp>
|
|
29
|
+
# <<< 550 Unknown user ***@docomo.ne.jp
|
|
30
|
+
# 550 5.1.1 <***@docomo.ne.jp>... User unknown
|
|
31
|
+
# >>> DATA
|
|
32
|
+
# <<< 503 Bad sequence of commands
|
|
33
|
+
# ---------------------------------------------------------------------------------------
|
|
34
|
+
# ----- The following addresses had permanent fatal errors -----
|
|
35
|
+
# <***@docomo.ne.jp>
|
|
36
|
+
# (reason: 550 Unknown user ***@docomo.ne.jp)
|
|
37
|
+
#
|
|
38
|
+
# ----- Transcript of session follows -----
|
|
39
|
+
# ... while talking to mfsmax.docomo.ne.jp.:
|
|
40
|
+
# >>> DATA
|
|
41
|
+
# <<< 550 Unknown user ***@docomo.ne.jp
|
|
42
|
+
# 554 5.0.0 Service unavailable
|
|
43
|
+
# ...
|
|
44
|
+
# Final-Recipient: RFC822; ***@docomo.ne.jp
|
|
45
|
+
# Action: failed
|
|
46
|
+
# Status: 5.2.0
|
|
47
|
+
return 'userunknown' if statuscode == '5.1.1' || statuscode == '5.9.213'
|
|
48
|
+
return 'filtered' if statuscode == '5.2.0'
|
|
51
49
|
|
|
52
|
-
|
|
50
|
+
MessagesOf.each_key do |e|
|
|
53
51
|
# The value of "Diagnostic-Code:" field is not empty
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
next unless MessagesOf[e].any? { |a| esmtperror.include?(a) }
|
|
62
|
-
reasontext = e
|
|
63
|
-
break
|
|
64
|
-
end
|
|
52
|
+
# - The key name is a bounce reason name
|
|
53
|
+
# - https://github.com/sisimai/go-sisimai/issues/64
|
|
54
|
+
# - After March 12, 2025, if an error message contains "550 Unknown user", the
|
|
55
|
+
# bounce reason will be definitively "userunknown". This is because NTT DOCOMO
|
|
56
|
+
# no longer rejects emails via SMTP for domain-specific rejection or specified
|
|
57
|
+
# reception filters.
|
|
58
|
+
return e if MessagesOf[e].any? { |a| esmtperror.include?(a) }
|
|
65
59
|
end
|
|
66
60
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
# Status: 5.0.0
|
|
96
|
-
# Remote-MTA: dns; mfsmax.docomo.ne.jp
|
|
97
|
-
# Diagnostic-Code: smtp; 550 Unknown user ***@docomo.ne.jp
|
|
98
|
-
reasontext = 'rejected'
|
|
99
|
-
|
|
100
|
-
else
|
|
101
|
-
# Rejected by other SMTP commands: AUTH, MAIL,
|
|
102
|
-
# もしもこのブロックを通過するNTTドコモからのエラーメッセージを見つけたら
|
|
103
|
-
# https://github.com/sisimai/rb-sisimai/issues からご連絡ねがいます。
|
|
104
|
-
#
|
|
105
|
-
# If you found a error message from mfsmax.docomo.ne.jp which passes this block,
|
|
106
|
-
# please open an issue at https://github.com/sisimai/rb-sisimai/issues .
|
|
107
|
-
end
|
|
108
|
-
else
|
|
109
|
-
# Status: field is neither 5.0.0 nor values defined in code above
|
|
110
|
-
# もしもこのブロックを通過するNTTドコモからのエラーメッセージを見つけたら
|
|
111
|
-
# https://github.com/sisimai/rb-sisimai/issues からご連絡ねがいます。
|
|
112
|
-
#
|
|
113
|
-
# If you found a error message from mfsmax.docomo.ne.jp which passes this block,
|
|
114
|
-
#
|
|
115
|
-
end
|
|
61
|
+
# A bounce reason did not decide from a status code, an error message.
|
|
62
|
+
if statuscode == '5.0.0'
|
|
63
|
+
# Your message to the following recipients cannot be delivered:
|
|
64
|
+
#
|
|
65
|
+
# <***@docomo.ne.jp>:
|
|
66
|
+
# mfsmax.docomo.ne.jp [203.138.181.112]:
|
|
67
|
+
# >>> RCPT TO:<***@docomo.ne.jp>
|
|
68
|
+
# <<< 550 Unknown user ***@docomo.ne.jp
|
|
69
|
+
# ...
|
|
70
|
+
#
|
|
71
|
+
# Final-Recipient: rfc822; ***@docomo.ne.jp
|
|
72
|
+
# Action: failed
|
|
73
|
+
# Status: 5.0.0
|
|
74
|
+
# Remote-MTA: dns; mfsmax.docomo.ne.jp [203.138.181.112]
|
|
75
|
+
# Diagnostic-Code: smtp; 550 Unknown user ***@docomo.ne.jp
|
|
76
|
+
# -------------------------------------------------------------------------------------
|
|
77
|
+
# <***@docomo.ne.jp>: host mfsmax.docomo.ne.jp[203.138.181.240] said:
|
|
78
|
+
# 550 Unknown user ***@docomo.ne.jp (in reply to end of DATA
|
|
79
|
+
# command)
|
|
80
|
+
# ...
|
|
81
|
+
# Final-Recipient: rfc822; ***@docomo.ne.jp
|
|
82
|
+
# Original-Recipient: rfc822;***@docomo.ne.jp
|
|
83
|
+
# Action: failed
|
|
84
|
+
# Status: 5.0.0
|
|
85
|
+
# Remote-MTA: dns; mfsmax.docomo.ne.jp
|
|
86
|
+
# Diagnostic-Code: smtp; 550 Unknown user ***@docomo.ne.jp
|
|
87
|
+
return 'userunknown' if thecommand == 'RCPT'
|
|
88
|
+
return 'rejected' if thecommand == 'DATA'
|
|
116
89
|
end
|
|
117
90
|
|
|
118
|
-
|
|
91
|
+
# 1. Rejected by other SMTP commands: AUTH, MAIL,
|
|
92
|
+
# 2. Status: field is neither 5.0.0 nor values defined in code above
|
|
93
|
+
# もしもこのブロックを通過するNTTドコモからのエラーメッセージを見つけたら
|
|
94
|
+
# https://github.com/sisimai/rb-sisimai/issues からご連絡ねがいます。
|
|
95
|
+
#
|
|
96
|
+
# If you found a error message from mfsmax.docomo.ne.jp which passes this block,
|
|
97
|
+
# please open an issue at https://github.com/sisimai/rb-sisimai/issues .
|
|
98
|
+
return ""
|
|
119
99
|
end
|
|
120
100
|
|
|
121
101
|
end
|
|
@@ -21,7 +21,7 @@ module Sisimai
|
|
|
21
21
|
|
|
22
22
|
MessagesOf.each_key do |e|
|
|
23
23
|
# Try to match the error message with message patterns defined in $MessagesOf
|
|
24
|
-
next
|
|
24
|
+
next if MessagesOf[e].none? { |a| issuedcode.include?(a) }
|
|
25
25
|
reasontext = e
|
|
26
26
|
break
|
|
27
27
|
end
|
|
@@ -62,11 +62,11 @@ module Sisimai
|
|
|
62
62
|
# 1300 Spectrum limits the number of concurrent connections from a sender, as well as the
|
|
63
63
|
# 1340 total number of connections allowed. Limits vary based on the reputation of the IP
|
|
64
64
|
# address. Reduce your number of connections and try again later.
|
|
65
|
-
[1300, 1340, '
|
|
65
|
+
[1300, 1340, 'ratelimited'],
|
|
66
66
|
|
|
67
67
|
# 1350 Spectrum limits emails by the number of messages sent, amount of recipients,
|
|
68
68
|
# 1490 potential for spam and invalid recipients.
|
|
69
|
-
[1350, 1490, '
|
|
69
|
+
[1350, 1490, 'ratelimited'],
|
|
70
70
|
|
|
71
71
|
# 1500 Your email was rejected for attempting to send as a different email address than you
|
|
72
72
|
# signed in under. Check that you're sending emails from the address you signed in with.
|
|
@@ -77,23 +77,23 @@ module Sisimai
|
|
|
77
77
|
[1520, 0, 'rejected'],
|
|
78
78
|
|
|
79
79
|
# 1530 Your email was rejected because it's larger than the maximum size of 20MB.
|
|
80
|
-
[1530, 0, '
|
|
80
|
+
[1530, 0, 'emailtoolarge'],
|
|
81
81
|
|
|
82
82
|
# 1540 Your emails were deferred for attempting to send too many in a single session.
|
|
83
83
|
# Reconnect and try reducing the number of emails you send at one time.
|
|
84
|
-
[1540, 0, '
|
|
84
|
+
[1540, 0, 'ratelimited'],
|
|
85
85
|
|
|
86
86
|
# 1550 Your email was rejected for having too many recipients in one message. Reduce the
|
|
87
87
|
# number of recipients and try again later.
|
|
88
|
-
[1550, 0, '
|
|
88
|
+
[1550, 0, 'ratelimited'],
|
|
89
89
|
|
|
90
90
|
# 1560 Your email was rejected for having too many invalid recipients. Check your outgoing
|
|
91
91
|
# email addresses and try again later.
|
|
92
|
-
[1560, 0, '
|
|
92
|
+
[1560, 0, 'ratelimited'],
|
|
93
93
|
|
|
94
94
|
# 1580 You've tried to send messages to too many recipients in a short period of time.
|
|
95
95
|
# Wait a little while and try again later.
|
|
96
|
-
[1580, 0, '
|
|
96
|
+
[1580, 0, 'ratelimited'],
|
|
97
97
|
].freeze
|
|
98
98
|
|
|
99
99
|
# Detect bounce reason from https://www.spectrum.com/
|
|
@@ -101,7 +101,7 @@ module Sisimai
|
|
|
101
101
|
# @return [String, Nil] The bounce reason at Spectrum
|
|
102
102
|
# @since v4.25.8
|
|
103
103
|
def find(argvs)
|
|
104
|
-
return argvs['reason']
|
|
104
|
+
return argvs['reason'] if argvs['reason'].empty? == false
|
|
105
105
|
issuedcode = argvs['diagnosticcode']
|
|
106
106
|
reasontext = ''
|
|
107
107
|
codenumber = if cv = issuedcode.match(/AUP#[-A-Za-z]*(\d{4})/) then cv[1].to_i else 0 end
|
|
@@ -15,32 +15,31 @@ module Sisimai
|
|
|
15
15
|
'suspected spam ip', # https://service.mail.qq.com/detail/122/66
|
|
16
16
|
'connection denied', # https://service.mail.qq.com/detail/122/170
|
|
17
17
|
],
|
|
18
|
-
'
|
|
18
|
+
'emailtoolarge' => [
|
|
19
19
|
'message too large', # https://service.mail.qq.com/detail/122/168
|
|
20
20
|
],
|
|
21
|
+
'ratelimited' => [
|
|
22
|
+
'mailbox unavailable or access denined', # https://service.mail.qq.com/detail/122/166
|
|
23
|
+
'ip frequency limited', # https://service.mail.qq.com/detail/122/172
|
|
24
|
+
'domain frequency limited', # https://service.mail.qq.com/detail/122/173
|
|
25
|
+
'sender frequency limited', # https://service.mail.qq.com/detail/122/174
|
|
26
|
+
'connection frequency limited', # https://service.mail.qq.com/detail/122/175
|
|
27
|
+
"frequency of receiving messages is limited", # https://service.mail.qq.com/detail/122/1011
|
|
28
|
+
],
|
|
21
29
|
'rejected' => [
|
|
22
30
|
'suspected spam', # https://service.mail.qq.com/detail/122/71
|
|
23
31
|
'mail is rejected by recipients', # https://service.mail.qq.com/detail/122/92
|
|
24
32
|
],
|
|
25
|
-
'
|
|
33
|
+
'spamdetected' => [
|
|
26
34
|
'spam is embedded in the email', # https://service.mail.qq.com/detail/122/59
|
|
27
35
|
'mail content denied', # https://service.mail.qq.com/detail/122/171
|
|
28
36
|
],
|
|
29
|
-
'speeding' => [
|
|
30
|
-
'mailbox unavailable or access denined', # https://service.mail.qq.com/detail/122/166
|
|
31
|
-
],
|
|
32
37
|
'suspend' => [
|
|
33
38
|
'is a deactivated mailbox', # http://service.mail.qq.com/cgi-bin/help?subtype=1&&id=20022&&no=1000742
|
|
34
39
|
],
|
|
35
40
|
'syntaxerror' => [
|
|
36
41
|
'bad address syntax', # https://service.mail.qq.com/detail/122/167
|
|
37
42
|
],
|
|
38
|
-
'toomanyconn' => [
|
|
39
|
-
'ip frequency limited', # https://service.mail.qq.com/detail/122/172
|
|
40
|
-
'domain frequency limited', # https://service.mail.qq.com/detail/122/173
|
|
41
|
-
'sender frequency limited', # https://service.mail.qq.com/detail/122/174
|
|
42
|
-
'connection frequency limited', # https://service.mail.qq.com/detail/122/175
|
|
43
|
-
],
|
|
44
43
|
'userunknown' => [
|
|
45
44
|
'mailbox not found', # https://service.mail.qq.com/detail/122/169
|
|
46
45
|
],
|
|
@@ -50,13 +49,13 @@ module Sisimai
|
|
|
50
49
|
# @param [Sisimai::Fact] argvs Decoded email object
|
|
51
50
|
# @return [String] The bounce reason at Tencent QQ
|
|
52
51
|
def find(argvs)
|
|
53
|
-
return argvs['reason']
|
|
52
|
+
return argvs['reason'] if argvs['reason'].empty? == false
|
|
54
53
|
issuedcode = argvs['diagnosticcode'].downcase
|
|
55
54
|
reasontext = ''
|
|
56
55
|
|
|
57
56
|
MessagesOf.each_key do |e|
|
|
58
57
|
MessagesOf[e].each do |f|
|
|
59
|
-
next
|
|
58
|
+
next if issuedcode.include?(f) == false
|
|
60
59
|
reasontext = e
|
|
61
60
|
break
|
|
62
61
|
end
|
|
@@ -31,6 +31,13 @@ module Sisimai
|
|
|
31
31
|
# See https://postmaster.yahooinc.com/error-codes
|
|
32
32
|
'not accepted for policy reasons',
|
|
33
33
|
],
|
|
34
|
+
'ratelimited' => [
|
|
35
|
+
# - 421 Max message per connection reached, closing transmission channel
|
|
36
|
+
'max message per connection reached',
|
|
37
|
+
|
|
38
|
+
# - 450 User is receiving mail too quickly
|
|
39
|
+
'user is receiving mail too quickly',
|
|
40
|
+
],
|
|
34
41
|
'rejected' => [
|
|
35
42
|
# Observed the following error message since around March 2024:
|
|
36
43
|
#
|
|
@@ -53,10 +60,6 @@ module Sisimai
|
|
|
53
60
|
# Retrying will NOT succeed. See https://postmaster.yahooinc.com/error-codes
|
|
54
61
|
' will be permanently deferred',
|
|
55
62
|
],
|
|
56
|
-
'speeding' => [
|
|
57
|
-
# - 450 User is receiving mail too quickly
|
|
58
|
-
'user is receiving mail too quickly',
|
|
59
|
-
],
|
|
60
63
|
'suspend' => [
|
|
61
64
|
# - 554 delivery error: dd ****@yahoo.com is no longer valid.
|
|
62
65
|
# - 554 30 Sorry, your message to *****@aol.jp cannot be delivered.
|
|
@@ -68,10 +71,6 @@ module Sisimai
|
|
|
68
71
|
# - 501 Syntax error in parameters or arguments
|
|
69
72
|
'syntax error in parameters or arguments',
|
|
70
73
|
],
|
|
71
|
-
'toomanyconn' => [
|
|
72
|
-
# - 421 Max message per connection reached, closing transmission channel
|
|
73
|
-
'max message per connection reached',
|
|
74
|
-
],
|
|
75
74
|
'userunknown' => [
|
|
76
75
|
# - 554 delivery error: dd This user doesn't have a yahoo.com account (***@yahoo.com)
|
|
77
76
|
# - 552 1 Requested mail action aborted, mailbox not found (in reply to end of DATA command)
|
|
@@ -88,13 +87,13 @@ module Sisimai
|
|
|
88
87
|
# https://www.postmastery.com/yahoo-postmaster/
|
|
89
88
|
# @since v5.1.0
|
|
90
89
|
def find(argvs)
|
|
91
|
-
return argvs['reason']
|
|
90
|
+
return argvs['reason'] if argvs['reason'].empty? == false
|
|
92
91
|
issuedcode = argvs['diagnosticcode'].downcase
|
|
93
92
|
reasontext = ''
|
|
94
93
|
|
|
95
94
|
MessagesOf.each_key do |e|
|
|
96
95
|
MessagesOf[e].each do |f|
|
|
97
|
-
next
|
|
96
|
+
next if issuedcode.include?(f) == false
|
|
98
97
|
reasontext = e
|
|
99
98
|
break
|
|
100
99
|
end
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
module Sisimai
|
|
2
|
+
module Rhost
|
|
3
|
+
# Sisimai::Rhost detects the bounce reason from the content of Sisimai::Fact object as an argument
|
|
4
|
+
# of find() method when the value of "destination" of the object is ".zoho.com" or ".zoho.eu".
|
|
5
|
+
# This class is called only Sisimai::Fact class.
|
|
6
|
+
module Zoho
|
|
7
|
+
class << self
|
|
8
|
+
MessagesOf = {
|
|
9
|
+
'authfailure' => [
|
|
10
|
+
# - <*******@zoho.com>: host smtpin.zoho.com[204.141.33.23] said: 550 5.7.1 Email
|
|
11
|
+
# rejected per DMARC policy for zoho.com
|
|
12
|
+
"Email rejected per DMARC policy",
|
|
13
|
+
],
|
|
14
|
+
'blocked' => [
|
|
15
|
+
# - mx.zoho.com[204.141.33.44]:25, delay=1202, delays=1200/0/0.91/0.30, dsn=4.7.1,
|
|
16
|
+
# status=deferred (host mx.zoho.com[204.141.33.44] said:
|
|
17
|
+
# 451 4.7.1 Greylisted, try again after some time (in reply to RCPT TO command))
|
|
18
|
+
"Greylisted, try again after some time",
|
|
19
|
+
],
|
|
20
|
+
'rejected' => [
|
|
21
|
+
# - <*******@zoho.com>: host smtpin.zoho.com[204.141.33.23] said: 554 5.7.1 Email
|
|
22
|
+
# cannot be delivered. Reason: Email flagged as Spam. (in reply to RCPT TO command)
|
|
23
|
+
# - <***@zoho.com>: host mx.zoho.com[136.143.183.44] said: 541 5.4.1 Mail rejected
|
|
24
|
+
# by destination domain (in reply to RCPT TO command)
|
|
25
|
+
"Email cannot be delivered. Reason: Email flagged as Spam",
|
|
26
|
+
"Mail rejected by destination domain",
|
|
27
|
+
],
|
|
28
|
+
'policyviolation' => [
|
|
29
|
+
# - <*******@zoho.com>: host smtpin.zoho.com[204.141.33.23] said: 554 5.7.7 Email
|
|
30
|
+
# policy violation detected (in reply to end of DATA command)
|
|
31
|
+
"Email policy violation detected",
|
|
32
|
+
"Mailbox delivery restricted by policy error",
|
|
33
|
+
],
|
|
34
|
+
'systemerror' => [
|
|
35
|
+
# - https://github.com/zoho/zohodesk-oas/blob/main/v1.0/EmailFailureAlert.json#L168
|
|
36
|
+
# 452 4.3.1 Temporary System Error
|
|
37
|
+
"Temporary System Error",
|
|
38
|
+
],
|
|
39
|
+
'userunknown' => [
|
|
40
|
+
# - <*******@zoho.com>: host smtpin.zoho.com[204.141.33.23] said:
|
|
41
|
+
# 550 5.1.1 User does not exist - <***@zoho.com> (in reply to RCPT TO command)
|
|
42
|
+
# - 552 5.1.1 <****@zoho.com> Mailbox delivery failure policy error
|
|
43
|
+
"User does not exist",
|
|
44
|
+
],
|
|
45
|
+
'virusdetected' => [
|
|
46
|
+
# - 552 5.7.1 virus **** detected by Zoho Mail
|
|
47
|
+
" detected by Zoho Mail",
|
|
48
|
+
],
|
|
49
|
+
}.freeze
|
|
50
|
+
|
|
51
|
+
# Detect bounce reason from Apple iCloud Mail
|
|
52
|
+
# @param [Sisimai::Fact] argvs Decoded email object
|
|
53
|
+
# @return [String] The bounce reason for Apple
|
|
54
|
+
# @see
|
|
55
|
+
# @since v5.5.0
|
|
56
|
+
# - Zoho Mail: https://www.zoho.com/mail/
|
|
57
|
+
# - Reasons an email is marked as Spam: https://www.zoho.com/mail/help/spam-reason.html
|
|
58
|
+
# - https://github.com/zoho/zohodesk-oas/blob/main/v1.0/EmailFailureAlert.json
|
|
59
|
+
# - Zoho SMTP Error Codes | SMTP Field Manual: https://smtpfieldmanual.com/provider/zoho
|
|
60
|
+
def find(argvs)
|
|
61
|
+
return '' if argvs.nil? || argvs['diagnosticcode'].size == 0
|
|
62
|
+
MessagesOf.each_key do |e|
|
|
63
|
+
return e if MessagesOf[e].any? { |a| argvs['diagnosticcode'].include?(a) }
|
|
64
|
+
end
|
|
65
|
+
return ''
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
data/lib/sisimai/rhost.rb
CHANGED
|
@@ -24,6 +24,7 @@ module Sisimai
|
|
|
24
24
|
"Spectrum" => ["charter.net"],
|
|
25
25
|
"Tencent" => [".qq.com"],
|
|
26
26
|
"YahooInc" => [".yahoodns.net"],
|
|
27
|
+
"Zoho" => [".zoho.com", ".zoho.eu"],
|
|
27
28
|
}.freeze
|
|
28
29
|
|
|
29
30
|
# Returns the rhost class name
|
|
@@ -44,14 +45,14 @@ module Sisimai
|
|
|
44
45
|
# 3. lhost: local MTA hostname
|
|
45
46
|
RhostClass.each_key do |e|
|
|
46
47
|
# Try to match the domain part of the recipient address with each value of RhostClass
|
|
47
|
-
next
|
|
48
|
+
next if RhostClass[e].none? { |a| a.end_with?(domainpart) }
|
|
48
49
|
rhostclass = e
|
|
49
50
|
throw :FINDRHOST
|
|
50
51
|
end
|
|
51
52
|
|
|
52
53
|
RhostClass.each_key do |e|
|
|
53
54
|
# Try to match the remote host with each value of RhostClass
|
|
54
|
-
next
|
|
55
|
+
next if RhostClass[e].none? { |a| remotehost.end_with?(a) }
|
|
55
56
|
rhostclass = e
|
|
56
57
|
throw :FINDRHOST
|
|
57
58
|
end
|
|
@@ -59,7 +60,7 @@ module Sisimai
|
|
|
59
60
|
# Neither the remote host nor the destination did not matched with any value of RhostClass
|
|
60
61
|
RhostClass.each_key do |e|
|
|
61
62
|
# Try to match the client host with each value of RhostClass
|
|
62
|
-
next
|
|
63
|
+
next if RhostClass[e].none? { |a| clienthost.end_with?(a) }
|
|
63
64
|
rhostclass = e
|
|
64
65
|
throw :FINDRHOST
|
|
65
66
|
end
|
data/lib/sisimai/smtp/command.rb
CHANGED
|
@@ -2,6 +2,8 @@ module Sisimai
|
|
|
2
2
|
module SMTP
|
|
3
3
|
# Sisimai::SMTP::Transcript is an SMTP Command related utilities
|
|
4
4
|
module Command
|
|
5
|
+
ExceptDATA = ["CONN", "EHLO", "HELO", "MAIL", "RCPT"].freeze
|
|
6
|
+
BeforeRCPT = ["CONN", "EHLO", "EHLO", "MAIL", "AUTH", "STARTTLS"].freeze
|
|
5
7
|
class << self
|
|
6
8
|
Availables = [
|
|
7
9
|
"HELO", "EHLO", "MAIL", "RCPT", "DATA", "QUIT", "RSET", "NOOP", "VRFY", "ETRN", "EXPN",
|
|
@@ -28,7 +30,7 @@ module Sisimai
|
|
|
28
30
|
# @return [String] An SMTP command
|
|
29
31
|
# @since v5.0.0
|
|
30
32
|
def find(argv0 = '')
|
|
31
|
-
return ""
|
|
33
|
+
return "" if Sisimai::SMTP::Command.test(argv0) == false
|
|
32
34
|
|
|
33
35
|
issuedcode = " " + argv0.downcase + " "
|
|
34
36
|
commandmap = {"STAR" => "STARTTLS", "XFOR" => "XFORWARD"}
|
|
@@ -36,7 +38,7 @@ module Sisimai
|
|
|
36
38
|
|
|
37
39
|
Detectable.each do |e|
|
|
38
40
|
# Find an SMTP command from the given string
|
|
39
|
-
p0 = argv0.index(e); next
|
|
41
|
+
p0 = argv0.index(e); next if p0.nil?
|
|
40
42
|
if e.include?(" ") == false
|
|
41
43
|
# For example, "RCPT T" does not appear in an email address or a domain name
|
|
42
44
|
cx = true; while true do
|
data/lib/sisimai/smtp/reply.rb
CHANGED
|
@@ -113,18 +113,25 @@ module Sisimai
|
|
|
113
113
|
Associated = {
|
|
114
114
|
"422" => ["AUTH", "4.7.12", "securityerror"], # RFC5238
|
|
115
115
|
"432" => ["AUTH", "4.7.12", "securityerror"], # RFC4954, RFC5321
|
|
116
|
+
"451" => ["", "", "systemerror"], # RFC2465, RFC5321
|
|
117
|
+
"452" => ["", "", "systemfull"], # RFC5321
|
|
118
|
+
"454" => ["AUTH", "4.7.0", "securityerror"], # RFC3027, RFC4954
|
|
119
|
+
"455" => ["", "", "syntaxerror"], # RFC5321
|
|
116
120
|
"500" => ["", "", "syntaxerror"], # RFC5321
|
|
117
121
|
"501" => ["", "", "syntaxerror"], # RFC5321
|
|
118
122
|
"502" => ["", "", "syntaxerror"], # RFC5321
|
|
119
123
|
"503" => ["", "", "syntaxerror"], # RFC5321
|
|
120
124
|
"504" => ["", "", "syntaxerror"], # RFC5321
|
|
121
125
|
"521" => ["CONN", "", "notaccept"], # RFC7504
|
|
122
|
-
"523" => ["AUTH", "",
|
|
123
|
-
"524" => ["AUTH", "",
|
|
124
|
-
"525" => ["AUTH", "",
|
|
126
|
+
"523" => ["AUTH", "5.7.10", "securityerror"], # RFC5248
|
|
127
|
+
"524" => ["AUTH", "5.7.11", "securityerror"], # RFC5248
|
|
128
|
+
"525" => ["AUTH", "5.7.13", "securityerror"], # RFC5248
|
|
125
129
|
"534" => ["AUTH", "5.7.9", "securityerror"], # RFC4954, RFC5248
|
|
126
130
|
"535" => ["AUTH", "5.7.8", "securityerror"], # RFC4954, RFC5248
|
|
127
131
|
"538" => ["AUTH", "5.7.11", "securityerror"], # RFC4954, RFC5248
|
|
132
|
+
"551" => ["", "", "hasmoved"], # RFC5321, RFC5336, RFC6531
|
|
133
|
+
"552" => ["", "", "mailboxfull"], # RFC5321
|
|
134
|
+
"555" => ["", "", "syntaxerror"], # RFC5321
|
|
128
135
|
"556" => ["RCPT", "", "notaccept"], # RFC7504
|
|
129
136
|
}.freeze
|
|
130
137
|
|
|
@@ -153,7 +160,7 @@ module Sisimai
|
|
|
153
160
|
|
|
154
161
|
if first == 3
|
|
155
162
|
# 3yz
|
|
156
|
-
return false
|
|
163
|
+
return false if reply != 334 && reply != 354
|
|
157
164
|
return true
|
|
158
165
|
end
|
|
159
166
|
|