sisimai 5.7.0-java → 5.7.2-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.
Files changed (102) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/codecovio.yml +1 -1
  3. data/.github/workflows/rake-test.yml +1 -1
  4. data/ChangeLog.md +25 -0
  5. data/README-JA.md +14 -13
  6. data/README.md +12 -12
  7. data/lib/sisimai/arf.rb +2 -1
  8. data/lib/sisimai/eb.rb +116 -0
  9. data/lib/sisimai/fact.rb +24 -17
  10. data/lib/sisimai/lda.rb +20 -18
  11. data/lib/sisimai/lhost/amazonses.rb +11 -10
  12. data/lib/sisimai/lhost/courier.rb +4 -3
  13. data/lib/sisimai/lhost/domino.rb +2 -1
  14. data/lib/sisimai/lhost/einsundeins.rb +3 -2
  15. data/lib/sisimai/lhost/exchange2003.rb +8 -7
  16. data/lib/sisimai/lhost/exchange2007.rb +14 -13
  17. data/lib/sisimai/lhost/exim.rb +7 -6
  18. data/lib/sisimai/lhost/ezweb.rb +4 -3
  19. data/lib/sisimai/lhost/fml.rb +4 -3
  20. data/lib/sisimai/lhost/gmail.rb +10 -9
  21. data/lib/sisimai/lhost/googlegroups.rb +3 -2
  22. data/lib/sisimai/lhost/googleworkspace.rb +2 -1
  23. data/lib/sisimai/lhost/imailserver.rb +3 -2
  24. data/lib/sisimai/lhost/kddi.rb +4 -3
  25. data/lib/sisimai/lhost/notes.rb +2 -1
  26. data/lib/sisimai/lhost/postfix.rb +7 -6
  27. data/lib/sisimai/lhost/qmail.rb +10 -9
  28. data/lib/sisimai/lhost/sendmail.rb +4 -3
  29. data/lib/sisimai/lhost/trendmicro.rb +2 -1
  30. data/lib/sisimai/lhost/v5sendmail.rb +2 -1
  31. data/lib/sisimai/lhost/verizon.rb +3 -2
  32. data/lib/sisimai/message.rb +5 -6
  33. data/lib/sisimai/reason/authfailure.rb +6 -5
  34. data/lib/sisimai/reason/badreputation.rb +5 -4
  35. data/lib/sisimai/reason/blocked.rb +6 -5
  36. data/lib/sisimai/reason/contenterror.rb +6 -5
  37. data/lib/sisimai/reason/delivered.rb +3 -2
  38. data/lib/sisimai/reason/emailtoolarge.rb +6 -5
  39. data/lib/sisimai/reason/expired.rb +3 -2
  40. data/lib/sisimai/reason/failedstarttls.rb +5 -3
  41. data/lib/sisimai/reason/feedback.rb +2 -1
  42. data/lib/sisimai/reason/filtered.rb +9 -8
  43. data/lib/sisimai/reason/hasmoved.rb +5 -4
  44. data/lib/sisimai/reason/hostunknown.rb +5 -4
  45. data/lib/sisimai/reason/mailboxfull.rb +7 -6
  46. data/lib/sisimai/reason/mailererror.rb +3 -2
  47. data/lib/sisimai/reason/networkerror.rb +3 -2
  48. data/lib/sisimai/reason/norelaying.rb +4 -3
  49. data/lib/sisimai/reason/notaccept.rb +5 -4
  50. data/lib/sisimai/reason/notcompliantrfc.rb +4 -3
  51. data/lib/sisimai/reason/onhold.rb +8 -7
  52. data/lib/sisimai/reason/policyviolation.rb +7 -6
  53. data/lib/sisimai/reason/ratelimited.rb +5 -4
  54. data/lib/sisimai/reason/rejected.rb +18 -14
  55. data/lib/sisimai/reason/requireptr.rb +5 -4
  56. data/lib/sisimai/reason/securityerror.rb +4 -3
  57. data/lib/sisimai/reason/spamdetected.rb +6 -5
  58. data/lib/sisimai/reason/suppressed.rb +4 -3
  59. data/lib/sisimai/reason/suspend.rb +4 -3
  60. data/lib/sisimai/reason/syntaxerror.rb +4 -3
  61. data/lib/sisimai/reason/systemerror.rb +3 -2
  62. data/lib/sisimai/reason/systemfull.rb +4 -3
  63. data/lib/sisimai/reason/undefined.rb +2 -1
  64. data/lib/sisimai/reason/userunknown.rb +13 -9
  65. data/lib/sisimai/reason/vacation.rb +2 -1
  66. data/lib/sisimai/reason/virusdetected.rb +6 -5
  67. data/lib/sisimai/reason.rb +45 -40
  68. data/lib/sisimai/rfc1894.rb +8 -2
  69. data/lib/sisimai/rfc2045.rb +6 -3
  70. data/lib/sisimai/rfc3464/thirdparty.rb +10 -9
  71. data/lib/sisimai/rfc3834.rb +4 -2
  72. data/lib/sisimai/rhost/aol.rb +3 -2
  73. data/lib/sisimai/rhost/apple.rb +12 -11
  74. data/lib/sisimai/rhost/cloudflare.rb +3 -2
  75. data/lib/sisimai/rhost/cox.rb +38 -37
  76. data/lib/sisimai/rhost/facebook.rb +17 -16
  77. data/lib/sisimai/rhost/franceptt.rb +39 -38
  78. data/lib/sisimai/rhost/godaddy.rb +35 -34
  79. data/lib/sisimai/rhost/google.rb +22 -21
  80. data/lib/sisimai/rhost/gsuite.rb +8 -7
  81. data/lib/sisimai/rhost/iua.rb +11 -10
  82. data/lib/sisimai/rhost/kddi.rb +3 -2
  83. data/lib/sisimai/rhost/messagelabs.rb +13 -12
  84. data/lib/sisimai/rhost/microsoft.rb +33 -32
  85. data/lib/sisimai/rhost/mimecast.rb +18 -17
  86. data/lib/sisimai/rhost/nttdocomo.rb +10 -9
  87. data/lib/sisimai/rhost/outlook.rb +3 -2
  88. data/lib/sisimai/rhost/spectrum.rb +19 -18
  89. data/lib/sisimai/rhost/tencent.rb +10 -9
  90. data/lib/sisimai/rhost/yahooinc.rb +11 -10
  91. data/lib/sisimai/rhost/zoho.rb +8 -7
  92. data/lib/sisimai/smtp/command.rb +13 -8
  93. data/lib/sisimai/smtp/failure.rb +9 -8
  94. data/lib/sisimai/smtp/reply.rb +23 -22
  95. data/lib/sisimai/smtp/status.rb +141 -140
  96. data/lib/sisimai/smtp/transcript.rb +3 -2
  97. data/lib/sisimai/string.rb +4 -3
  98. data/lib/sisimai/version.rb +1 -1
  99. data/lib/sisimai.rb +2 -1
  100. data/set-of-emails/maildir/bsd/lhost-postfix-81.eml +130 -0
  101. data/set-of-emails/should-not-crash/go-423-deeply-nested-mime-parts.eml +20050 -0
  102. metadata +5 -2
@@ -3,24 +3,28 @@ module Sisimai
3
3
  # Sisimai::Fact object as an argument of find() method. This class is called only Sisimai::Fact.
4
4
  module Reason
5
5
  class << self
6
+ require 'sisimai/eb'
7
+
6
8
  # All the error reason list Sisimai support
7
9
  # @return [Array] Reason list
8
10
  def index
9
- return %w[
10
- AuthFailure BadReputation Blocked ContentError EmailTooLarge Expired FailedSTARTTLS Filtered
11
- HasMoved HostUnknown MailboxFull MailerError NetworkError NotAccept NotCompliantRFC RateLimited
12
- OnHold Rejected NoRelaying SpamDetected VirusDetected PolicyViolation SecurityError Suspend
13
- RequirePTR SystemError SystemFull Suppressed UserUnknown SyntaxError
11
+ return [
12
+ Sisimai::Eb::ReAUTH, Sisimai::Eb::ReFAMA, Sisimai::Eb::ReBLOC, Sisimai::Eb::ReBODY, Sisimai::Eb::ReSIZE,
13
+ Sisimai::Eb::ReTIME, Sisimai::Eb::ReTTLS, Sisimai::Eb::ReFILT, Sisimai::Eb::ReMOVE, Sisimai::Eb::ReHOST,
14
+ Sisimai::Eb::ReFULL, Sisimai::Eb::ReUNIX, Sisimai::Eb::ReINET, Sisimai::Eb::Re00MX, Sisimai::Eb::ReNRFC,
15
+ Sisimai::Eb::ReRATE, Sisimai::Eb::Re___1, Sisimai::Eb::ReFROM, Sisimai::Eb::RePASS, Sisimai::Eb::ReSPAM,
16
+ Sisimai::Eb::ReEXEC, Sisimai::Eb::ReWONT, Sisimai::Eb::ReSAFE, Sisimai::Eb::ReQUIT, Sisimai::Eb::ReQPTR,
17
+ Sisimai::Eb::RePROC, Sisimai::Eb::ReDISK, Sisimai::Eb::ReSTOP, Sisimai::Eb::ReUSER, Sisimai::Eb::ReCOMM,
14
18
  ]
15
19
  end
16
20
 
17
- # @abstract is_explicit() returns 0 when the argument is empty or is "undefined" or is "onhold"
21
+ # @abstract is_explicit() returns 0 when the argument is empty or is "Undefined" or is "OnHold"
18
22
  # @param string argv1 Reason name
19
23
  # @return bool false: The reaosn is not explicit
20
24
  def is_explicit(argv1 = '')
21
25
  return false if argv1.nil?
22
26
  return false if argv1.empty?
23
- return false if argv1 == "undefined" || argv1 == "onhold" || argv1.empty?
27
+ return false if argv1 == Sisimai::Eb::Re___0 || argv1 == Sisimai::Eb::Re___1 || argv1.empty?
24
28
  return true
25
29
  end
26
30
 
@@ -38,29 +42,30 @@ module Sisimai
38
42
  # @return [Hash] Reason list
39
43
  def retry
40
44
  return {
41
- 'undefined' => true, 'onhold' => true, 'systemerror' => true, 'securityerror' => true,
42
- 'expired' => true, 'networkerror' => true, 'hostunknown' => true, 'userunknown' => true
45
+ Sisimai::Eb::Re___0 => true, Sisimai::Eb::Re___1 => true, Sisimai::Eb::RePROC => true,
46
+ Sisimai::Eb::ReSAFE => true, Sisimai::Eb::ReTIME => true, Sisimai::Eb::ReINET => true,
47
+ Sisimai::Eb::ReHOST => true, Sisimai::Eb::ReUSER => true,
43
48
  }.freeze
44
49
  end
45
50
  ModulePath = Sisimai::Reason.path
46
51
  GetRetried = Sisimai::Reason.retry
47
52
  ClassOrder = [
48
53
  # 0. true() meethod in the following reasons are called from Reason->find()
49
- %w[MailboxFull EmailTooLarge Suspend HasMoved NoRelaying AuthFailure UserUnknown Filtered RequirePTR
50
- NotCompliantRFC BadReputation ContentError Rejected HostUnknown SpamDetected RateLimited Blocked
51
- FailedSTARTTLS NotAccept VirusDetected PolicyViolation
52
- ],
54
+ [Sisimai::Eb::ReFULL, Sisimai::Eb::ReSIZE, Sisimai::Eb::ReQUIT, Sisimai::Eb::ReMOVE, Sisimai::Eb::RePASS,
55
+ Sisimai::Eb::ReAUTH, Sisimai::Eb::ReUSER, Sisimai::Eb::ReFILT, Sisimai::Eb::ReQPTR, Sisimai::Eb::ReNRFC,
56
+ Sisimai::Eb::ReFAMA, Sisimai::Eb::ReBODY, Sisimai::Eb::ReFROM, Sisimai::Eb::ReHOST, Sisimai::Eb::ReSPAM,
57
+ Sisimai::Eb::ReRATE, Sisimai::Eb::ReBLOC, Sisimai::Eb::ReTTLS, Sisimai::Eb::Re00MX, Sisimai::Eb::ReEXEC,
58
+ Sisimai::Eb::ReWONT],
59
+
53
60
  # 1. match() method in the following reasons are called from Reason->find()
54
- %w[
55
- MailboxFull SpamDetected VirusDetected NoRelaying SystemError NetworkError Suspend SystemFull
56
- Suppressed MailerError SecurityError PolicyViolation SyntaxError Expired
57
- ],
58
- %w[
59
- MailboxFull EmailTooLarge Suspend UserUnknown Filtered Rejected HostUnknown SpamDetected
60
- RateLimited Blocked SpamDetected AuthFailure FailedSTARTTLS SecurityError SystemError
61
- NetworkError Suspend Expired ContentError HasMoved SystemFull NotAccept MailerError
62
- NoRelaying Suppressed SyntaxError OnHold
63
- ]
61
+ [Sisimai::Eb::ReFULL, Sisimai::Eb::ReSPAM, Sisimai::Eb::ReEXEC, Sisimai::Eb::RePASS, Sisimai::Eb::RePROC,
62
+ Sisimai::Eb::ReINET, Sisimai::Eb::ReQUIT, Sisimai::Eb::ReDISK, Sisimai::Eb::ReSTOP, Sisimai::Eb::ReUNIX,
63
+ Sisimai::Eb::ReSAFE, Sisimai::Eb::ReWONT, Sisimai::Eb::ReCOMM, Sisimai::Eb::ReTIME],
64
+ [Sisimai::Eb::ReFULL, Sisimai::Eb::ReSIZE, Sisimai::Eb::ReQUIT, Sisimai::Eb::ReUSER, Sisimai::Eb::ReFILT,
65
+ Sisimai::Eb::ReFROM, Sisimai::Eb::ReHOST, Sisimai::Eb::ReSPAM, Sisimai::Eb::ReRATE, Sisimai::Eb::ReBLOC,
66
+ Sisimai::Eb::ReAUTH, Sisimai::Eb::ReTTLS, Sisimai::Eb::ReSAFE, Sisimai::Eb::RePROC, Sisimai::Eb::ReINET,
67
+ Sisimai::Eb::ReTIME, Sisimai::Eb::ReBODY, Sisimai::Eb::ReMOVE, Sisimai::Eb::ReDISK, Sisimai::Eb::Re00MX,
68
+ Sisimai::Eb::ReUNIX, Sisimai::Eb::RePASS, Sisimai::Eb::ReSTOP, Sisimai::Eb::ReCOMM, Sisimai::Eb::Re___1],
64
69
  ]
65
70
 
66
71
  # Detect the bounce reason
@@ -74,7 +79,7 @@ module Sisimai
74
79
  # retry() method.
75
80
  return argvs['reason'] if argvs['reason'].empty? == false
76
81
  end
77
- return 'delivered' if argvs['deliverystatus'].start_with?('2.')
82
+ return Sisimai::Eb::ReSENT if argvs['deliverystatus'].start_with?('2.')
78
83
 
79
84
  reasontext = ''
80
85
  issuedcode = argvs['diagnosticcode'] || ''
@@ -100,21 +105,21 @@ module Sisimai
100
105
  end
101
106
  end
102
107
 
103
- if reasontext.empty? || reasontext == 'undefined'
108
+ if reasontext.empty? || reasontext == Sisimai::Eb::Re___0
104
109
  # Bounce reason is not detected yet.
105
110
  reasontext = self.anotherone(argvs)
106
111
 
107
- if reasontext == 'undefined' || reasontext.empty?
112
+ if reasontext == Sisimai::Eb::Re___0 || reasontext.empty?
108
113
  # Action: delayed => "expired"
109
114
  reasontext = nil
110
- reasontext ||= 'expired' if argvs['action'] == 'delayed'
115
+ reasontext ||= Sisimai::Eb::ReTIME if argvs['action'] == Sisimai::Eb::AeSTAY
111
116
  return reasontext if reasontext
112
117
 
113
118
  # Try to match with message patterns in Sisimai::Reason::Vacation
114
119
  require 'sisimai/reason/vacation'
115
- reasontext = 'vacation' if Sisimai::Reason::Vacation.match(issuedcode.downcase)
116
- reasontext ||= 'onhold' if issuedcode.empty? == false
117
- reasontext ||= 'undefined'
120
+ reasontext = Sisimai::Eb::ReAWAY if Sisimai::Reason::Vacation.match(issuedcode.downcase)
121
+ reasontext ||= Sisimai::Eb::Re___1 if issuedcode.empty? == false
122
+ reasontext ||= Sisimai::Eb::Re___0
118
123
  end
119
124
  end
120
125
  return reasontext
@@ -151,7 +156,7 @@ module Sisimai
151
156
  end
152
157
 
153
158
  next if r.match(issuedcode) == false
154
- reasontext = e.downcase
159
+ reasontext = e
155
160
  break
156
161
  end
157
162
  break if reasontext.empty? == false
@@ -160,31 +165,31 @@ module Sisimai
160
165
  code2digit = statuscode[0, 3] || ''
161
166
  if code2digit == '5.6' || code2digit == '4.6'
162
167
  # X.6.0 Other or undefined media error
163
- reasontext = 'contenterror'
168
+ reasontext = Sisimai::Eb::ReBODY
164
169
 
165
170
  elsif code2digit == '5.7' || code2digit == '4.7'
166
171
  # X.7.0 Other or undefined security status
167
- reasontext = 'securityerror'
172
+ reasontext = Sisimai::Eb::ReSAFE
168
173
 
169
174
  elsif codeformat.start_with?('X-UNIX')
170
175
  # Diagnostic-Code: X-UNIX; ...
171
- reasontext = 'mailererror'
176
+ reasontext = Sisimai::Eb::ReUNIX
172
177
 
173
178
  else
174
179
  # 50X Syntax Error?
175
180
  require 'sisimai/reason/syntaxerror'
176
- reasontext = 'syntaxerror' if Sisimai::Reason::SyntaxError.true(argvs)
181
+ reasontext = Sisimai::Eb::ReCOMM if Sisimai::Reason::SyntaxError.true(argvs)
177
182
  end
178
183
  break if reasontext.empty? == false
179
184
 
180
185
  # Check the value of Action: field, first
181
- if actiontext.start_with?('delayed', 'expired')
186
+ if actiontext.start_with?(Sisimai::Eb::AeSTAY, 'expired')
182
187
  # Action: delayed, expired
183
- reasontext = 'expired'
188
+ reasontext = Sisimai::Eb::ReTIME
184
189
  else
185
190
  # Rejected at connection or after EHLO|HELO
186
191
  thecommand = argvs['command'] || ''
187
- reasontext = 'blocked' if %w[HELO EHLO].index(thecommand)
192
+ reasontext = Sisimai::Eb::ReBLOC if %w[HELO EHLO].index(thecommand)
188
193
  end
189
194
  break
190
195
  end
@@ -222,12 +227,12 @@ module Sisimai
222
227
 
223
228
  if issuedcode.upcase.include?('X-UNIX; ')
224
229
  # X-Unix; ...
225
- reasontext = 'mailererror'
230
+ reasontext = Sisimai::Eb::ReUNIX
226
231
  else
227
232
  # Detect the bounce reason from "Status:" code
228
233
  require 'sisimai/smtp/status'
229
234
  reasontext = Sisimai::SMTP::Status.name(Sisimai::SMTP::Status.find(argv1))
230
- reasontext = "undefined" if reasontext.empty?
235
+ reasontext = Sisimai::Eb::Re___0 if reasontext.empty?
231
236
  end
232
237
  return reasontext
233
238
  end
@@ -2,6 +2,7 @@ module Sisimai
2
2
  # Sisimai::RFC1894 DSN field defined in RFC3464 (obsoletes RFC1894)
3
3
  module RFC1894
4
4
  class << self
5
+ require 'sisimai/eb'
5
6
  require 'sisimai/string'
6
7
  FieldNames = [
7
8
  # https://tools.ietf.org/html/rfc3464#section-2.2
@@ -58,8 +59,13 @@ module Sisimai
58
59
  }.freeze
59
60
 
60
61
  SubtypeSet = {"addr" => "RFC822", "cdoe" => "SMTP", "host" => "DNS"}.freeze
61
- ActionList = ["failed", "delayed", "delivered", "relayed", "expanded"].freeze
62
- Correction = {'deliverable' => 'delivered', 'expired' => 'failed', 'failure' => 'failed'}
62
+ ActionList = [Sisimai::Eb::AeFAIL, Sisimai::Eb::AeSTAY, Sisimai::Eb::AeSENT,
63
+ Sisimai::Eb::AePASS, Sisimai::Eb::AeEXPN].freeze
64
+ Correction = {
65
+ 'deliverable' => Sisimai::Eb::AeSENT,
66
+ 'expired' => Sisimai::Eb::AeFAIL,
67
+ 'failure' => Sisimai::Eb::AeFAIL,
68
+ }
63
69
  FieldGroup = {
64
70
  'original-recipient' => 'addr',
65
71
  'final-recipient' => 'addr',
@@ -213,14 +213,17 @@ module Sisimai
213
213
  # Split argv1: multipart/* blocks by a boundary string in argv0
214
214
  # @param [String] argv0 The value of Content-Type header
215
215
  # @param [String] argv1 A pointer to multipart/* message blocks
216
+ # @param [String] depth Depth of MIME parts
216
217
  # @return [Array] List of each part of multipart/*
217
218
  # @since v5.0.0
218
- def levelout(argv0 = '', argv1 = '')
219
+ def levelout(argv0 = '', argv1 = '', depth = 0)
219
220
  return [] if argv0.empty?
220
221
  return [] if argv1.empty?
222
+ return [] if depth > 100
221
223
 
222
224
  boundary01 = boundary(argv0, 0); return [] if boundary01.empty?
223
225
  multiparts = argv1.split(Regexp.new(Regexp.escape(boundary01) + "\n"))
226
+ partsdepth = depth + 1
224
227
  partstable = []
225
228
 
226
229
  # Remove empty or useless preamble and epilogue of multipart/* block
@@ -237,7 +240,7 @@ module Sisimai
237
240
  bodyinside = f[-1].split("\n\n", 2)[-1]
238
241
  next if bodyinside.size < 9 || bodyinside.index(boundary02).nil?
239
242
 
240
- v = levelout(f[0], bodyinside)
243
+ v = levelout(f[0], bodyinside, partsdepth)
241
244
  partstable += v if v.size > 0
242
245
  else
243
246
  # The part is not a multipart/* block
@@ -271,7 +274,7 @@ module Sisimai
271
274
  # - CHARSET=, BOUNDARY= => charset-, boundary=
272
275
  # - message/xdelivery-status => message/delivery-status
273
276
  iso2022set = %r/charset=["']?(iso-2022-[-a-z0-9]+)['"]?\b/
274
- multiparts = levelout(argv0, argv1)
277
+ multiparts = levelout(argv0, argv1, 0)
275
278
  flattenout = ''
276
279
  delimiters = ["/delivery-status", "/rfc822", "/feedback-report", "/partial"]
277
280
 
@@ -2,6 +2,7 @@ module Sisimai
2
2
  module RFC3464
3
3
  module ThirdParty
4
4
  class << self
5
+ require 'sisimai/eb'
5
6
  ThirdParty = {
6
7
  #"Aol" => ["X-Outbound-Mail-Relay-"], # X-Outbound-Mail-Relay-(Queue-ID|Sender)
7
8
  "PowerMTA" => ["X-PowerMTA-"], # X-PowerMTA-(VirtualMTA|BounceCategory)
@@ -50,15 +51,15 @@ module Sisimai
50
51
  "x-powermta-bouncecategory" => "text", # X-PowerMTA-BounceCategory: bad-mailbox
51
52
  }.freeze
52
53
  MessagesOf = {
53
- "bad-domain" => "hostunknown",
54
- "bad-mailbox" => "userunknown",
55
- "inactive-mailbox" => "suspend",
56
- "message-expired" => "expired",
57
- "no-answer-from-host" => "networkerror",
58
- "policy-related" => "policyviolation",
59
- "quota-issues" => "mailboxfull",
60
- "routing-errors" => "systemerror",
61
- "spam-related" => "spamdetected",
54
+ "bad-domain" => Sisimai::Eb::ReHOST,
55
+ "bad-mailbox" => Sisimai::Eb::ReUSER,
56
+ "inactive-mailbox" => Sisimai::Eb::ReQUIT,
57
+ "message-expired" => Sisimai::Eb::ReTIME,
58
+ "no-answer-from-host" => Sisimai::Eb::ReINET,
59
+ "policy-related" => Sisimai::Eb::ReWONT,
60
+ "quota-issues" => Sisimai::Eb::ReFULL,
61
+ "routing-errors" => Sisimai::Eb::RePROC,
62
+ "spam-related" => Sisimai::Eb::ReSPAM,
62
63
  }.freeze
63
64
 
64
65
  # Returns an array which is compatible with the value returned from Sisimai::RFC1894->field()
@@ -3,6 +3,8 @@ module Sisimai
3
3
  module RFC3834
4
4
  class << self
5
5
  # http://tools.ietf.org/html/rfc3834
6
+ require 'sisimai/eb'
7
+
6
8
  MarkingsOf = {:boundary => '__SISIMAI_PSEUDO_BOUNDARY__'}
7
9
  LowerLabel = %w[from to subject auto-submitted precedence x-apple-action].freeze
8
10
  DoNotParse = {
@@ -116,13 +118,13 @@ module Sisimai
116
118
  break if haveloaded >= maxmsgline
117
119
  end
118
120
  v['diagnosis'] ||= mhead['subject']
119
- v['reason'] = 'vacation'
121
+ v['reason'] = Sisimai::Eb::ReAWAY
120
122
 
121
123
  cv = v['diagnosis'].downcase
122
124
  Suspending.each do |e|
123
125
  # Check that the auto-replied message indicates the "Suspend" reason or not.
124
126
  next unless Sisimai::String.aligned(cv, e)
125
- v['reason'] = 'suspend'
127
+ v['reason'] = Sisimai::Eb::ReQUIT
126
128
  break
127
129
  end
128
130
 
@@ -5,9 +5,10 @@ module Sisimai
5
5
  # only from Sisimai::Fact class.
6
6
  module Aol
7
7
  class << self
8
+ require 'sisimai/eb'
8
9
  MessagesOf = {
9
- "hostunknown" => ["Host or domain name not found"],
10
- "notaccept" => ["type=MX: Malformed or unexpected name server reply"],
10
+ Sisimai::Eb::ReHOST => ["Host or domain name not found"],
11
+ Sisimai::Eb::Re00MX => ["type=MX: Malformed or unexpected name server reply"],
11
12
  }.freeze
12
13
 
13
14
  # Detect bounce reason from Aol Mail: https://www.aol.com
@@ -5,8 +5,9 @@ module Sisimai
5
5
  # This class is called only Sisimai::Fact class.
6
6
  module Apple
7
7
  class << self
8
+ require 'sisimai/eb'
8
9
  MessagesOf = {
9
- 'authfailure' => [
10
+ Sisimai::Eb::ReAUTH => [
10
11
  # - 554 5.7.1 Your message was rejected due to example.jp's DMARC policy.
11
12
  # See https://support.apple.com/en-us/HT204137 for
12
13
  # - 554 5.7.1 [HME1] This message was blocked for failing both SPF and DKIM authentication
@@ -14,7 +15,7 @@ module Sisimai
14
15
  's dmarc policy',
15
16
  'blocked for failing both spf and dkim autentication checks',
16
17
  ],
17
- 'blocked' => [
18
+ Sisimai::Eb::ReBLOC => [
18
19
  # - 550 5.7.0 Blocked - see https://support.proofpoint.com/dnsbl-lookup.cgi?ip=192.0.1.2
19
20
  # - 550 5.7.1 Your email was rejected due to having a domain present in the Spamhaus
20
21
  # DBL -- see https://www.spamhaus.org/dbl/
@@ -26,39 +27,39 @@ module Sisimai
26
27
  'blocked - see https://support.proofpoint.com/dnsbl-lookup',
27
28
  'not accepting connections',
28
29
  ],
29
- 'hasmoved' => [
30
+ Sisimai::Eb::ReMOVE => [
30
31
  # - 550 5.1.6 recipient no longer on server: *****@icloud.com
31
32
  'recipient no longer on server',
32
33
  ],
33
- 'mailboxfull' => [
34
+ Sisimai::Eb::ReFULL => [
34
35
  # - 552 5.2.2 <****@icloud.com>: user is over quota (in reply to RCPT TO command)
35
36
  'user is over quota',
36
37
  ],
37
- 'norelaying' => [
38
+ Sisimai::Eb::RePASS => [
38
39
  # - 554 5.7.1 <*****@icloud.com>: Relay access denied
39
40
  'relay access denied',
40
41
  ],
41
- 'notaccept' => ['host/domain does not accept mail'],
42
- 'policyviolation' => [
42
+ Sisimai::Eb::Re00MX => ['host/domain does not accept mail'],
43
+ Sisimai::Eb::ReWONT => [
43
44
  # - 550 5.7.1 [CS01] Message rejected due to local policy.
44
45
  # Please visit https://support.apple.com/en-us/HT204137
45
46
  'due to local policy',
46
47
  ],
47
- 'ratelimited' => [
48
+ Sisimai::Eb::ReRATE => [
48
49
  # - 421 4.7.1 Messages to ****@icloud.com deferred due to excessive volume.
49
50
  # Try again later - https://support.apple.com/en-us/HT204137
50
51
  'due to excessive volume',
51
52
  ],
52
- 'rejected' => [
53
+ Sisimai::Eb::ReFROM => [
53
54
  # - 450 4.1.8 <kijitora@example.jp>: Sender address rejected: Domain not found
54
55
  'sender address rejected',
55
56
  ],
56
- 'suspend' => [
57
+ Sisimai::Eb::ReQUIT => [
57
58
  # - https://support.apple.com/guide/icloud/stop-using-or-reactivate-addresses-mm3adb030cbf/icloud
58
59
  # - 550 5.1.1 <****@icloud.com>: inactive email address (in reply to RCPT TO command)
59
60
  "inactive email address",
60
61
  ],
61
- 'userunknown' => [
62
+ Sisimai::Eb::ReUSER => [
62
63
  # - 550 5.1.1 <****@icloud.com>: inactive email address (in reply to RCPT TO command)
63
64
  # - 550 5.1.1 unknown or illegal alias: ****@icloud.com
64
65
  'user does not exist',
@@ -5,11 +5,12 @@ module Sisimai
5
5
  # This class is called only from Sisimai::Fact class.
6
6
  module Cloudflare
7
7
  class << self
8
+ require 'sisimai/eb'
8
9
  MessagesOf = {
9
10
  # - 554 <YOUR_IP_ADDRESS> found on one or more RBLs (abusixip). Refer to
10
11
  # https://developers.cloudflare.com/email-routing/postmaster/#spam-and-abusive-traffic/
11
- "blocked" => ["found on one or more DNSBLs"],
12
- "systemerror" => ["Upstream error"],
12
+ Sisimai::Eb::ReBLOC => ["found on one or more DNSBLs"],
13
+ Sisimai::Eb::RePROC => ["Upstream error"],
13
14
  }.freeze
14
15
 
15
16
  # Detect bounce reason from Cloudflare Email Routing
@@ -5,12 +5,13 @@ module Sisimai
5
5
  # called only Sisimai::Fact class.
6
6
  module Cox
7
7
  class << self
8
+ require 'sisimai/eb'
8
9
  ErrorCodes = {
9
10
  # CXBL
10
11
  # - The sending IP address has been blocked by Cox due to exhibiting spam-like behavior.
11
12
  # - Send an email request to Cox to ask for a sending IP address be unblocked.
12
13
  # Note: Cox has sole discretion whether to unblock the sending IP address.
13
- 'CXBL' => 'blocked',
14
+ 'CXBL' => Sisimai::Eb::ReBLOC,
14
15
 
15
16
  # CXDNS
16
17
  # - There was an issue with the connecting IP address Domain Name System (DNS).
@@ -18,66 +19,66 @@ module Sisimai
18
19
  # - Confirm the IP address that sends your email.
19
20
  # - Check the rDNS of that IP address. If it passes, then wait 24 hours and try resending
20
21
  # your email.
21
- 'CXDNS' => 'requireptr',
22
+ 'CXDNS' => Sisimai::Eb::ReQPTR,
22
23
 
23
24
  # CXSNDR
24
25
  # - There was a problem with the sender's domain.
25
26
  # - Your email failed authentication checks against your sending domain's SPF, DomainKeys,
26
27
  # or DKIM policy.
27
- 'CXSNDR' => 'authfailure',
28
+ 'CXSNDR' => Sisimai::Eb::ReAUTH,
28
29
 
29
30
  # CXSMTP
30
31
  # - There was a violation of SMTP protocol.
31
32
  # - Your email wasn't delivered because Cox was unable to verify that it came from a
32
33
  # legitimate email sender.
33
- 'CXSMTP' => 'rejected',
34
+ 'CXSMTP' => Sisimai::Eb::ReFROM,
34
35
 
35
36
  # CXCNCT
36
37
  # - There was a connection issue from the IP address.
37
38
  # - There is a limit to the number of concurrent SMTP connections per IP address to
38
39
  # protect the systems against attack. Ensure that the sending email server is not
39
40
  # opening more than 10 concurrent connections to avoid reaching this limit.
40
- 'CXCNCT' => 'ratelimited',
41
+ 'CXCNCT' => Sisimai::Eb::ReRATE,
41
42
 
42
43
  # CXMXRT
43
44
  # - The sender has sent email to too many recipients and needs to wait before sending
44
45
  # more email.
45
46
  # - The email sender has exceeded the maximum number of sent email allowed.
46
- 'CXMXRT' => 'ratelimited',
47
+ 'CXMXRT' => Sisimai::Eb::ReRATE,
47
48
 
48
49
  # CDRBL
49
50
  # - The sending IP address has been temporarily blocked by Cox due to exhibiting spam-like
50
51
  # behavior.
51
52
  # - The block duration varies depending on reputation and other factors, but will not exceed
52
53
  # 24 hours. Inspect email traffic for potential spam, and retry email delivery.
53
- 'CDRBL' => 'blocked',
54
+ 'CDRBL' => Sisimai::Eb::ReBLOC,
54
55
 
55
- 'CXTHRT' => 'securityerror', # Email sending limited due to suspicious account activity.
56
- 'CXMJ' => 'securityerror', # Email sending blocked due to suspicious account activity on primary Cox account.
57
- 'IPBL0001' => 'blocked', # The sending IP address is listed in the Spamhaus Zen DNSBL.
58
- 'IPBL0010' => 'blocked', # The sending IP is listed in the Return Path DNSBL.
59
- 'IPBL0100' => 'blocked', # The sending IP is listed in the Invaluement ivmSIP DNSBL.
60
- 'IPBL0011' => 'blocked', # The sending IP is in the Spamhaus Zen and Return Path DNSBLs.
61
- 'IPBL0101' => 'blocked', # The sending IP is in the Spamhaus Zen and Invaluement ivmSIP DNSBLs.
62
- 'IPBL0110' => 'blocked', # The sending IP is in the Return Path and Invaluement ivmSIP DNSBLs.
63
- 'IPBL0111' => 'blocked', # The sending IP is in the Spamhaus Zen, Return Path and Invaluement ivmSIP DNSBLs.
64
- 'IPBL1000' => 'blocked', # The sending IP address is listed on a CSI blacklist.
65
- 'IPBL1001' => 'blocked', # The sending IP is listed in the Cloudmark CSI and Spamhaus Zen DNSBLs.
66
- 'IPBL1010' => 'blocked', # The sending IP is listed in the Cloudmark CSI and Return Path DNSBLs.
67
- 'IPBL1011' => 'blocked', # The sending IP is in the Cloudmark CSI, Spamhaus Zen and Return Path DNSBLs.
68
- 'IPBL1100' => 'blocked', # The sending IP is listed in the Cloudmark CSI and Invaluement ivmSIP DNSBLs.
69
- 'IPBL1101' => 'blocked', # The sending IP is in the Cloudmark CSI, Spamhaus Zen and Invaluement IVMsip DNSBLs.
70
- 'IPBL1110' => 'blocked', # The sending IP is in the Cloudmark CSI, Return Path and Invaluement ivmSIP DNSBLs.
71
- 'IPBL1111' => 'blocked', # The sending IP is in the Cloudmark CSI, Spamhaus Zen, Return Path and Invaluement ivmSIP DNSBLs.
72
- 'IPBL00001' => 'blocked', # The sending IP address is listed on a Spamhaus blacklist.
56
+ 'CXTHRT' => Sisimai::Eb::ReSAFE, # Email sending limited due to suspicious account activity.
57
+ 'CXMJ' => Sisimai::Eb::ReSAFE, # Email sending blocked due to suspicious account activity on primary Cox account.
58
+ 'IPBL0001' => Sisimai::Eb::ReBLOC, # The sending IP address is listed in the Spamhaus Zen DNSBL.
59
+ 'IPBL0010' => Sisimai::Eb::ReBLOC, # The sending IP is listed in the Return Path DNSBL.
60
+ 'IPBL0100' => Sisimai::Eb::ReBLOC, # The sending IP is listed in the Invaluement ivmSIP DNSBL.
61
+ 'IPBL0011' => Sisimai::Eb::ReBLOC, # The sending IP is in the Spamhaus Zen and Return Path DNSBLs.
62
+ 'IPBL0101' => Sisimai::Eb::ReBLOC, # The sending IP is in the Spamhaus Zen and Invaluement ivmSIP DNSBLs.
63
+ 'IPBL0110' => Sisimai::Eb::ReBLOC, # The sending IP is in the Return Path and Invaluement ivmSIP DNSBLs.
64
+ 'IPBL0111' => Sisimai::Eb::ReBLOC, # The sending IP is in the Spamhaus Zen, Return Path and Invaluement ivmSIP DNSBLs.
65
+ 'IPBL1000' => Sisimai::Eb::ReBLOC, # The sending IP address is listed on a CSI blacklist.
66
+ 'IPBL1001' => Sisimai::Eb::ReBLOC, # The sending IP is listed in the Cloudmark CSI and Spamhaus Zen DNSBLs.
67
+ 'IPBL1010' => Sisimai::Eb::ReBLOC, # The sending IP is listed in the Cloudmark CSI and Return Path DNSBLs.
68
+ 'IPBL1011' => Sisimai::Eb::ReBLOC, # The sending IP is in the Cloudmark CSI, Spamhaus Zen and Return Path DNSBLs.
69
+ 'IPBL1100' => Sisimai::Eb::ReBLOC, # The sending IP is listed in the Cloudmark CSI and Invaluement ivmSIP DNSBLs.
70
+ 'IPBL1101' => Sisimai::Eb::ReBLOC, # The sending IP is in the Cloudmark CSI, Spamhaus Zen and Invaluement IVMsip DNSBLs.
71
+ 'IPBL1110' => Sisimai::Eb::ReBLOC, # The sending IP is in the Cloudmark CSI, Return Path and Invaluement ivmSIP DNSBLs.
72
+ 'IPBL1111' => Sisimai::Eb::ReBLOC, # The sending IP is in the Cloudmark CSI, Spamhaus Zen, Return Path and Invaluement ivmSIP DNSBLs.
73
+ 'IPBL00001' => Sisimai::Eb::ReBLOC, # The sending IP address is listed on a Spamhaus blacklist.
73
74
 
74
- 'URLBL011' => 'spamdetected', # A URL within the body of the message was found on blocklists SURBL and Spamhaus DBL.
75
- 'URLBL101' => 'spamdetected', # A URL within the body of the message was found on blocklists SURBL and ivmURI.
76
- 'URLBL110' => 'spamdetected', # A URL within the body of the message was found on blocklists Spamhaus DBL and ivmURI.
77
- 'URLBL1001' => 'spamdetected', # The URL is listed on a Spamhaus blacklist.
75
+ 'URLBL011' => Sisimai::Eb::ReSPAM, # A URL within the body of the message was found on blocklists SURBL and Spamhaus DBL.
76
+ 'URLBL101' => Sisimai::Eb::ReSPAM, # A URL within the body of the message was found on blocklists SURBL and ivmURI.
77
+ 'URLBL110' => Sisimai::Eb::ReSPAM, # A URL within the body of the message was found on blocklists Spamhaus DBL and ivmURI.
78
+ 'URLBL1001' => Sisimai::Eb::ReSPAM, # The URL is listed on a Spamhaus blacklist.
78
79
  }.freeze
79
80
  MessagesOf = {
80
- 'blocked' => [
81
+ Sisimai::Eb::ReBLOC => [
81
82
  # - An email client has repeatedly sent bad commands or invalid passwords resulting in
82
83
  # a three-hour block of the client's IP address.
83
84
  # - The sending IP address has exceeded the threshold of invalid recipients and has
@@ -87,18 +88,18 @@ module Sisimai
87
88
  'cox too many bad commands from',
88
89
  'too many invalid recipients',
89
90
  ],
90
- 'contenterror' => [
91
+ Sisimai::Eb::ReBODY => [
91
92
  # - The message has been rejected because it contains an attachment with one of the
92
93
  # following prohibited file types, which commonly contain viruses: .shb, .shs, .vbe,
93
94
  # .vbs, .wsc, .wsf, .wsh, .pif, .msc, .msi, .msp, .reg, .sct, .bat, .chm, .isp, .cpl,
94
95
  # .js, .jse, .scr, .exe.
95
96
  'attachment extension is forbidden',
96
97
  ],
97
- 'policyviolation' => [
98
+ Sisimai::Eb::ReWONT => [
98
99
  # - The sending server has attempted to communicate too soon within the SMTP transaction
99
100
  'esmtp no data before greeting',
100
101
  ],
101
- 'ratelimited' => [
102
+ Sisimai::Eb::ReWONT => [
102
103
  # - The sending IP address has exceeded the five maximum concurrent connection limit.
103
104
  # - The SMTP connection has exceeded the 100 email message threshold and was disconnected.
104
105
  # - The sending IP address has exceeded one of these rate limits and has been temporarily
@@ -107,22 +108,22 @@ module Sisimai
107
108
  'requested action aborted: try again later',
108
109
  'message threshold exceeded',
109
110
  ],
110
- 'rejected' => [
111
+ Sisimai::Eb::ReFROM => [
111
112
  # Cox requires that all sender domains resolve to a valid MX or A-record within DNS.
112
113
  'sender rejected',
113
114
  ],
114
- 'requireptr' => [
115
+ Sisimai::Eb::ReQPTR => [
115
116
  # - The reverse DNS check of the sending server IP address has failed.
116
117
  # - Cox requires that all connecting email servers contain valid reverse DNS PTR records.
117
118
  'dns check failure - try again later',
118
119
  'rejected - no rdns',
119
120
  ],
120
- 'systemerror' => [
121
+ Sisimai::Eb::RePROC => [
121
122
  # - Our systems are experiencing an issue which is causing a temporary inability to
122
123
  # accept new email.
123
124
  'esmtp server temporarily not available',
124
125
  ],
125
- 'userunknown' => [
126
+ Sisimai::Eb::ReUSER => [
126
127
  # - The intended recipient is not a valid Cox Email account.
127
128
  'recipient rejected',
128
129
  ],