sisimai 5.0.3-java → 5.1.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.
Files changed (157) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/codecovio.yml +3 -1
  3. data/.github/workflows/rake-test.yml +6 -2
  4. data/ChangeLog.md +34 -0
  5. data/README-JA.md +20 -17
  6. data/README.md +20 -17
  7. data/lib/sisimai/arf.rb +3 -3
  8. data/lib/sisimai/fact/json.rb +2 -2
  9. data/lib/sisimai/fact/yaml.rb +2 -2
  10. data/lib/sisimai/fact.rb +4 -19
  11. data/lib/sisimai/lhost/activehunter.rb +4 -3
  12. data/lib/sisimai/lhost/amavis.rb +4 -4
  13. data/lib/sisimai/lhost/amazonses.rb +6 -6
  14. data/lib/sisimai/lhost/amazonworkmail.rb +4 -4
  15. data/lib/sisimai/lhost/aol.rb +4 -4
  16. data/lib/sisimai/lhost/apachejames.rb +4 -4
  17. data/lib/sisimai/lhost/barracuda.rb +4 -4
  18. data/lib/sisimai/lhost/bigfoot.rb +4 -4
  19. data/lib/sisimai/lhost/biglobe.rb +4 -4
  20. data/lib/sisimai/lhost/courier.rb +4 -4
  21. data/lib/sisimai/lhost/domino.rb +4 -4
  22. data/lib/sisimai/lhost/dragonfly.rb +114 -0
  23. data/lib/sisimai/lhost/einsundeins.rb +4 -4
  24. data/lib/sisimai/lhost/exchange2003.rb +4 -3
  25. data/lib/sisimai/lhost/exchange2007.rb +4 -3
  26. data/lib/sisimai/lhost/exim.rb +4 -4
  27. data/lib/sisimai/lhost/ezweb.rb +4 -4
  28. data/lib/sisimai/lhost/facebook.rb +4 -4
  29. data/lib/sisimai/lhost/fml.rb +4 -4
  30. data/lib/sisimai/lhost/gmail.rb +4 -4
  31. data/lib/sisimai/lhost/gmx.rb +4 -4
  32. data/lib/sisimai/lhost/googlegroups.rb +4 -4
  33. data/lib/sisimai/lhost/gsuite.rb +4 -4
  34. data/lib/sisimai/lhost/imailserver.rb +4 -3
  35. data/lib/sisimai/lhost/interscanmss.rb +5 -4
  36. data/lib/sisimai/lhost/kddi.rb +4 -4
  37. data/lib/sisimai/lhost/mailfoundry.rb +4 -4
  38. data/lib/sisimai/lhost/mailmarshalsmtp.rb +5 -4
  39. data/lib/sisimai/lhost/mailru.rb +4 -4
  40. data/lib/sisimai/lhost/mcafee.rb +4 -4
  41. data/lib/sisimai/lhost/messagelabs.rb +4 -3
  42. data/lib/sisimai/lhost/messagingserver.rb +5 -4
  43. data/lib/sisimai/lhost/mfilter.rb +4 -4
  44. data/lib/sisimai/lhost/mxlogic.rb +3 -3
  45. data/lib/sisimai/lhost/notes.rb +4 -4
  46. data/lib/sisimai/lhost/office365.rb +4 -4
  47. data/lib/sisimai/lhost/opensmtpd.rb +9 -7
  48. data/lib/sisimai/lhost/outlook.rb +4 -4
  49. data/lib/sisimai/lhost/postfix.rb +4 -4
  50. data/lib/sisimai/lhost/powermta.rb +4 -4
  51. data/lib/sisimai/lhost/qmail.rb +10 -10
  52. data/lib/sisimai/lhost/receivingses.rb +4 -4
  53. data/lib/sisimai/lhost/sendgrid.rb +4 -4
  54. data/lib/sisimai/lhost/sendmail.rb +4 -4
  55. data/lib/sisimai/lhost/surfcontrol.rb +4 -4
  56. data/lib/sisimai/lhost/v5sendmail.rb +5 -4
  57. data/lib/sisimai/lhost/verizon.rb +4 -4
  58. data/lib/sisimai/lhost/x1.rb +3 -3
  59. data/lib/sisimai/lhost/x2.rb +3 -3
  60. data/lib/sisimai/lhost/x3.rb +3 -3
  61. data/lib/sisimai/lhost/x4.rb +3 -3
  62. data/lib/sisimai/lhost/x5.rb +3 -3
  63. data/lib/sisimai/lhost/x6.rb +3 -3
  64. data/lib/sisimai/lhost/yahoo.rb +4 -4
  65. data/lib/sisimai/lhost/yandex.rb +4 -4
  66. data/lib/sisimai/lhost/zoho.rb +4 -4
  67. data/lib/sisimai/lhost.rb +5 -5
  68. data/lib/sisimai/mail/maildir.rb +1 -1
  69. data/lib/sisimai/mail/stdin.rb +1 -1
  70. data/lib/sisimai/mda.rb +3 -3
  71. data/lib/sisimai/message.rb +8 -8
  72. data/lib/sisimai/order.rb +1 -0
  73. data/lib/sisimai/reason/badreputation.rb +1 -1
  74. data/lib/sisimai/reason/norelaying.rb +1 -0
  75. data/lib/sisimai/reason/rejected.rb +1 -0
  76. data/lib/sisimai/reason.rb +8 -8
  77. data/lib/sisimai/rfc3464.rb +3 -3
  78. data/lib/sisimai/rfc3834.rb +2 -2
  79. data/lib/sisimai/rhost/apple.rb +92 -0
  80. data/lib/sisimai/rhost/cox.rb +81 -32
  81. data/lib/sisimai/rhost/franceptt.rb +84 -81
  82. data/lib/sisimai/rhost/godaddy.rb +205 -43
  83. data/lib/sisimai/rhost/google.rb +3 -5
  84. data/lib/sisimai/rhost/iua.rb +2 -2
  85. data/lib/sisimai/rhost/kddi.rb +6 -5
  86. data/lib/sisimai/rhost/microsoft.rb +4 -5
  87. data/lib/sisimai/rhost/mimecast.rb +15 -4
  88. data/lib/sisimai/rhost/nttdocomo.rb +1 -1
  89. data/lib/sisimai/rhost/spectrum.rb +100 -40
  90. data/lib/sisimai/rhost/tencent.rb +46 -25
  91. data/lib/sisimai/rhost/yahooinc.rb +110 -0
  92. data/lib/sisimai/rhost.rb +28 -35
  93. data/lib/sisimai/smtp/reply.rb +4 -3
  94. data/lib/sisimai/smtp/transcript.rb +3 -3
  95. data/lib/sisimai/version.rb +1 -1
  96. data/lib/sisimai.rb +0 -6
  97. data/set-of-emails/maildir/bsd/lhost-dragonfly-01.eml +36 -0
  98. data/set-of-emails/maildir/bsd/lhost-dragonfly-02.eml +32 -0
  99. data/set-of-emails/maildir/bsd/lhost-dragonfly-03.eml +32 -0
  100. data/set-of-emails/maildir/bsd/lhost-dragonfly-04.eml +31 -0
  101. data/set-of-emails/maildir/bsd/lhost-dragonfly-05.eml +32 -0
  102. data/set-of-emails/maildir/bsd/lhost-dragonfly-06.eml +32 -0
  103. data/set-of-emails/maildir/bsd/lhost-dragonfly-07.eml +32 -0
  104. data/set-of-emails/maildir/bsd/lhost-dragonfly-08.eml +32 -0
  105. data/set-of-emails/maildir/bsd/lhost-dragonfly-09.eml +32 -0
  106. data/set-of-emails/maildir/bsd/lhost-dragonfly-10.eml +32 -0
  107. data/set-of-emails/maildir/bsd/lhost-dragonfly-11.eml +32 -0
  108. data/set-of-emails/maildir/bsd/lhost-dragonfly-12.eml +32 -0
  109. data/set-of-emails/maildir/bsd/lhost-dragonfly-13.eml +32 -0
  110. data/set-of-emails/maildir/bsd/lhost-dragonfly-14.eml +32 -0
  111. data/set-of-emails/maildir/bsd/lhost-dragonfly-15.eml +32 -0
  112. data/set-of-emails/maildir/bsd/lhost-dragonfly-16.eml +32 -0
  113. data/set-of-emails/maildir/bsd/lhost-dragonfly-17.eml +32 -0
  114. data/set-of-emails/maildir/bsd/lhost-dragonfly-18.eml +32 -0
  115. data/set-of-emails/maildir/bsd/lhost-dragonfly-19.eml +32 -0
  116. data/set-of-emails/maildir/bsd/lhost-dragonfly-20.eml +32 -0
  117. data/set-of-emails/maildir/bsd/lhost-dragonfly-21.eml +33 -0
  118. data/set-of-emails/maildir/bsd/lhost-dragonfly-22.eml +32 -0
  119. data/set-of-emails/maildir/bsd/lhost-dragonfly-23.eml +32 -0
  120. data/set-of-emails/maildir/bsd/lhost-dragonfly-24.eml +32 -0
  121. data/set-of-emails/maildir/bsd/lhost-dragonfly-25.eml +33 -0
  122. data/set-of-emails/maildir/bsd/lhost-dragonfly-26.eml +33 -0
  123. data/set-of-emails/maildir/bsd/lhost-dragonfly-27.eml +47 -0
  124. data/set-of-emails/maildir/bsd/lhost-dragonfly-28.eml +47 -0
  125. data/set-of-emails/maildir/bsd/lhost-dragonfly-29.eml +32 -0
  126. data/set-of-emails/maildir/bsd/lhost-dragonfly-30.eml +32 -0
  127. data/set-of-emails/maildir/bsd/lhost-opensmtpd-10.eml +58 -0
  128. data/set-of-emails/maildir/bsd/lhost-opensmtpd-11.eml +58 -0
  129. data/set-of-emails/maildir/bsd/lhost-opensmtpd-12.eml +62 -0
  130. data/set-of-emails/maildir/bsd/lhost-opensmtpd-13.eml +62 -0
  131. data/set-of-emails/maildir/bsd/lhost-opensmtpd-14.eml +58 -0
  132. data/set-of-emails/maildir/bsd/lhost-opensmtpd-15.eml +63 -0
  133. data/set-of-emails/maildir/bsd/lhost-opensmtpd-16.eml +62 -0
  134. data/set-of-emails/maildir/bsd/lhost-opensmtpd-17.eml +63 -0
  135. data/set-of-emails/maildir/bsd/lhost-qmail-11.eml +29 -0
  136. data/set-of-emails/maildir/bsd/lhost-qmail-12.eml +29 -0
  137. data/set-of-emails/maildir/bsd/lhost-qmail-13.eml +29 -0
  138. data/set-of-emails/maildir/bsd/lhost-qmail-14.eml +34 -0
  139. data/set-of-emails/maildir/bsd/lhost-qmail-15.eml +30 -0
  140. data/set-of-emails/maildir/bsd/lhost-qmail-16.eml +31 -0
  141. data/set-of-emails/maildir/bsd/lhost-qmail-17.eml +38 -0
  142. data/set-of-emails/maildir/bsd/lhost-qmail-18.eml +31 -0
  143. data/set-of-emails/maildir/bsd/lhost-qmail-19.eml +31 -0
  144. data/set-of-emails/maildir/bsd/lhost-qmail-20.eml +46 -0
  145. data/set-of-emails/maildir/bsd/lhost-qmail-21.eml +41 -0
  146. data/set-of-emails/maildir/bsd/lhost-qmail-22.eml +42 -0
  147. data/set-of-emails/maildir/bsd/lhost-qmail-23.eml +43 -0
  148. data/set-of-emails/maildir/bsd/lhost-qmail-24.eml +43 -0
  149. data/set-of-emails/maildir/bsd/lhost-qmail-25.eml +54 -0
  150. data/set-of-emails/maildir/bsd/rhost-apple-01.eml +79 -0
  151. data/set-of-emails/maildir/bsd/rhost-apple-02.eml +81 -0
  152. data/set-of-emails/maildir/bsd/rhost-apple-03.eml +75 -0
  153. data/set-of-emails/maildir/bsd/rhost-apple-04.eml +74 -0
  154. data/set-of-emails/maildir/bsd/rhost-yahooinc-01.eml +80 -0
  155. data/set-of-emails/maildir/bsd/rhost-yahooinc-02.eml +83 -0
  156. data/set-of-emails/maildir/bsd/rhost-yahooinc-03.eml +125 -0
  157. metadata +65 -2
@@ -351,11 +351,11 @@ module Sisimai
351
351
  # @param options mail [String] from From line of mbox
352
352
  # @param options mail [Hash] header Email header data
353
353
  # @param options mail [String] rfc822 Original message part
354
- # @param options mail [Array] ds Delivery status list(parsed data)
354
+ # @param options mail [Array] ds Delivery status list(decoded data)
355
355
  # @param options argvs [String] body Email message body
356
356
  # @param options argvs [Array] tryonfirst MTA module list to load on first
357
357
  # @param options argvs [Array] tobeloaded User defined MTA module list
358
- # @return [Hash] Parsed and structured bounce mails
358
+ # @return [Hash] Decoded and structured bounce mails
359
359
  def sift(argvs)
360
360
  return nil unless argvs['mail']
361
361
  return nil unless argvs['body']
@@ -414,7 +414,7 @@ module Sisimai
414
414
  end
415
415
  end
416
416
 
417
- catch :PARSER do
417
+ catch :DECODER do
418
418
  while true
419
419
  # 1. User-Defined Module
420
420
  # 2. MTA Module Candidates to be tried on first
@@ -428,7 +428,7 @@ module Sisimai
428
428
  havesifted = Module.const_get(r).inquire(mailheader, bodystring)
429
429
  haveloaded[r] = true
430
430
  modulename = r
431
- throw :PARSER if havesifted
431
+ throw :DECODER if havesifted
432
432
  end
433
433
 
434
434
  [argvs['tryonfirst'], DefaultSet].flatten.each do |r|
@@ -438,7 +438,7 @@ module Sisimai
438
438
  havesifted = Module.const_get(r).inquire(mailheader, bodystring)
439
439
  haveloaded[r] = true
440
440
  modulename = r
441
- throw :PARSER if havesifted
441
+ throw :DECODER if havesifted
442
442
  end
443
443
 
444
444
  unless haveloaded['Sisimai::RFC3464']
@@ -446,14 +446,14 @@ module Sisimai
446
446
  require 'sisimai/rfc3464'
447
447
  havesifted = Sisimai::RFC3464.inquire(mailheader, bodystring)
448
448
  modulename = 'RFC3464'
449
- throw :PARSER if havesifted
449
+ throw :DECODER if havesifted
450
450
  end
451
451
 
452
452
  unless haveloaded['Sisimai::ARF']
453
453
  # Feedback Loop message
454
454
  require 'sisimai/arf'
455
455
  havesifted = Sisimai::ARF.inquire(mailheader, bodystring)
456
- throw :PARSER if havesifted
456
+ throw :DECODER if havesifted
457
457
  end
458
458
 
459
459
  unless haveloaded['Sisimai::RFC3834']
@@ -461,7 +461,7 @@ module Sisimai
461
461
  require 'sisimai/rfc3834'
462
462
  havesifted = Sisimai::RFC3834.inquire(mailheader, bodystring)
463
463
  modulename = 'RFC3834'
464
- throw :PARSER if havesifted
464
+ throw :DECODER if havesifted
465
465
  end
466
466
 
467
467
  break # as of now, we have no sample email for coding this block
data/lib/sisimai/order.rb CHANGED
@@ -105,6 +105,7 @@ module Sisimai
105
105
  'loop-alert' => ['Sisimai::Lhost::FML'],
106
106
  'mail-delivery' => [
107
107
  'Sisimai::Lhost::Exim',
108
+ 'Sisimai::Lhost::DragonFly',
108
109
  'Sisimai::Lhost::MailRu',
109
110
  'Sisimai::Lhost::GMX',
110
111
  'Sisimai::Lhost::EinsUndEins',
@@ -19,6 +19,7 @@ module Sisimai
19
19
  'has been temporarily rate limited due to ip reputation',
20
20
  'ip/domain reputation problems',
21
21
  'likely suspicious due to the very low reputation',
22
+ 'temporarily deferred due to unexpected volume or user complaints', # Yahoo Inc.
22
23
  "the sending mta's poor reputation",
23
24
  ].freeze
24
25
  def text; return 'badreputation'; end
@@ -40,7 +41,6 @@ module Sisimai
40
41
  # false: is not BadReputation
41
42
  # @see http://www.ietf.org/rfc/rfc2822.txt
42
43
  def true(argvs)
43
- return nil if argvs['deliverystatus'].empty?
44
44
  return true if argvs['reason'] == 'badreputation'
45
45
  return true if match(argvs['diagnosticcode'].downcase)
46
46
  return false
@@ -15,6 +15,7 @@ module Sisimai
15
15
  'insecure mail relay',
16
16
  'is not permitted to relay through this server without authentication',
17
17
  'mail server requires authentication when attempting to send to a non-local e-mail address', # MailEnable
18
+ 'no relaying',
18
19
  'not a gateway',
19
20
  'not allowed to relay through this machine',
20
21
  'not an open relay, so get lost',
@@ -63,6 +63,7 @@ module Sisimai
63
63
  'sender rejected',
64
64
  'sender domain is empty',
65
65
  'sender verify failed', # Exim callout
66
+ 'sender was rejected', # qmail
66
67
  'spam reporting address', # SendGrid|a message to an address has previously been marked as Spam by the recipient.
67
68
  'syntax error: empty email address',
68
69
  'the message has been rejected by batv defense',
@@ -38,13 +38,13 @@ module Sisimai
38
38
  ClassOrder = [
39
39
  %w[
40
40
  MailboxFull MesgTooBig ExceedLimit Suspend HasMoved NoRelaying AuthFailure UserUnknown
41
- Filtered RequirePTR NotCompliantRFC Rejected HostUnknown SpamDetected Speeding TooManyConn
42
- Blocked
41
+ Filtered RequirePTR NotCompliantRFC BadReputation Rejected HostUnknown SpamDetected Speeding
42
+ TooManyConn Blocked
43
43
  ],
44
44
  %w[
45
- MailboxFull SpamDetected PolicyViolation VirusDetected NoRelaying AuthFailure
46
- BadReputation SecurityError SystemError NetworkError Speeding Suspend Expired ContentError
47
- SystemFull NotAccept MailerError
45
+ MailboxFull AuthFailure BadReputation Speeding SpamDetected VirusDetected PolicyViolation
46
+ NoRelaying SystemError NetworkError Suspend ContentError SystemFull NotAccept Expired
47
+ SecurityError MailerError
48
48
  ],
49
49
  %w[
50
50
  MailboxFull MesgTooBig ExceedLimit Suspend UserUnknown Filtered Rejected HostUnknown
@@ -55,7 +55,7 @@ module Sisimai
55
55
  ]
56
56
 
57
57
  # Detect the bounce reason
58
- # @param [Hash] argvs Parsed email object
58
+ # @param [Hash] argvs Decoded email object
59
59
  # @return [String, nil] Bounce reason or nil if the argument is missing or not Hash
60
60
  # @see anotherone
61
61
  def get(argvs)
@@ -112,7 +112,7 @@ module Sisimai
112
112
  end
113
113
 
114
114
  # Detect the other bounce reason, fall back method for get()
115
- # @param [Hash] argvs Parsed email object
115
+ # @param [Hash] argvs Decoded email object
116
116
  # @return [String, Nil] Bounce reason or nli if the argument is missing or not Hash
117
117
  # @see get
118
118
  def anotherone(argvs)
@@ -216,7 +216,7 @@ module Sisimai
216
216
  end
217
217
  return reasontext unless reasontext.empty?
218
218
 
219
- if issuedcode.upcase == 'X-UNIX'
219
+ if issuedcode.upcase.include?('X-UNIX; ')
220
220
  # X-Unix; ...
221
221
  reasontext = 'mailererror'
222
222
  else
@@ -1,5 +1,5 @@
1
1
  module Sisimai
2
- # Sisimai::RFC3464 - bounce mail parser class for Fallback.
2
+ # Sisimai::RFC3464 - bounce mail decoder class for Fallback.
3
3
  module RFC3464
4
4
  class << self
5
5
  require 'sisimai/lhost'
@@ -96,7 +96,7 @@ module Sisimai
96
96
  # @param [Hash] mhead Message headers of a bounce email
97
97
  # @param [String] mbody Message body of a bounce email
98
98
  # @return [Hash] Bounce data list and message/rfc822 part
99
- # @return [Nil] it failed to parse or the arguments are missing
99
+ # @return [Nil] it failed to decode or the arguments are missing
100
100
  def inquire(mhead, mbody)
101
101
  fieldtable = Sisimai::RFC1894.FIELDTABLE
102
102
  permessage = {} # (Hash) Store values of each Per-Message field
@@ -233,7 +233,7 @@ module Sisimai
233
233
 
234
234
  # -----------------------------------------------------------------------------------------
235
235
  while true
236
- # Fallback, parse entire message body
236
+ # Fallback, decode the entire message body
237
237
  break if recipients > 0
238
238
 
239
239
  # Failed to get a recipient address at code above
@@ -33,7 +33,7 @@ module Sisimai
33
33
  # @param [Hash] mhead Message headers of a bounce email
34
34
  # @param [String] mbody Message body of a bounce email
35
35
  # @return [Hash] Bounce data list and message/rfc822 part
36
- # @return [Nil] it failed to parse or the arguments are missing
36
+ # @return [Nil] it failed to decode or the arguments are missing
37
37
  def inquire(mhead, mbody)
38
38
  leave = 0
39
39
  match = 0
@@ -98,7 +98,7 @@ module Sisimai
98
98
  MarkingsOf[:boundary] = q unless q.empty?
99
99
  end
100
100
 
101
- # BODY_PARSER: Get vacation message
101
+ # MESSAGE_BODY: Get the vacation message
102
102
  while e = bodyslices.shift do
103
103
  # Read the first 5 lines except a blank line
104
104
  countuntil += 1 if e.include?(MarkingsOf[:boundary])
@@ -0,0 +1,92 @@
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 get() method when the value of "destination" of the object is "mail.icloud.com" or "apple.com".
5
+ # This class is called only Sisimai::Fact class.
6
+ module Apple
7
+ class << self
8
+ MessagesOf = {
9
+ 'authfailure' => [
10
+ # - 554 5.7.1 Your message was rejected due to example.jp's DMARC policy.
11
+ # See https://support.apple.com/en-us/HT204137 for
12
+ # - 554 5.7.1 [HME1] This message was blocked for failing both SPF and DKIM authentication
13
+ # checks. See https://support.apple.com/en-us/HT204137 for mailing best practices
14
+ 's dmarc policy',
15
+ 'blocked for failing both spf and dkim autentication checks',
16
+ ],
17
+ 'blocked' => [
18
+ # - 550 5.7.0 Blocked - see https://support.proofpoint.com/dnsbl-lookup.cgi?ip=192.0.1.2
19
+ # - 550 5.7.1 Your email was rejected due to having a domain present in the Spamhaus
20
+ # DBL -- see https://www.spamhaus.org/dbl/
21
+ # - 550 5.7.1 Mail from IP 192.0.2.1 was rejected due to listing in Spamhaus SBL.
22
+ # For details please see http://www.spamhaus.org/query/bl?ip=x.x.x.x
23
+ # - 554 ****-smtpin001.me.com ESMTP not accepting connections
24
+ 'rejected due to having a domain present in the spamhaus',
25
+ 'rejected due to listing in spamhaus',
26
+ 'blocked - see https://support.proofpoint.com/dnsbl-lookup',
27
+ 'not accepting connections',
28
+ ],
29
+ 'hasmoved' => [
30
+ # - 550 5.1.6 recipient no longer on server: *****@icloud.com
31
+ 'recipient no longer on server',
32
+ ],
33
+ 'mailboxfull' => [
34
+ # - 552 5.2.2 <****@icloud.com>: user is over quota (in reply to RCPT TO command)
35
+ 'user is over quota',
36
+ ],
37
+ 'norelaying' => [
38
+ # - 554 5.7.1 <*****@icloud.com>: Relay access denied
39
+ 'relay access denied',
40
+ ],
41
+ 'notaccept' => ['host/domain does not accept mail'],
42
+ 'policyviolation' => [
43
+ # - 550 5.7.1 [CS01] Message rejected due to local policy.
44
+ # Please visit https://support.apple.com/en-us/HT204137
45
+ 'due to local policy',
46
+ ],
47
+ 'rejected' => [
48
+ # - 450 4.1.8 <kijitora@example.jp>: Sender address rejected: Domain not found
49
+ 'sender address rejected',
50
+ ],
51
+ 'speeding' => [
52
+ # - 421 4.7.1 Messages to ****@icloud.com deferred due to excessive volume.
53
+ # Try again later - https://support.apple.com/en-us/HT204137
54
+ 'due to excessive volume',
55
+ ],
56
+ 'userunknown' => [
57
+ # - 550 5.1.1 <****@icloud.com>: inactive email address (in reply to RCPT TO command)
58
+ # - 550 5.1.1 unknown or illegal alias: ****@icloud.com
59
+ 'inactive email address',
60
+ 'user does not exist',
61
+ 'unknown or illegal alias',
62
+ ],
63
+ }.freeze
64
+
65
+ # Detect bounce reason from Apple iCloud Mail
66
+ # @param [Sisimai::Fact] argvs Decoded email object
67
+ # @return [String] The bounce reason for Apple
68
+ # @see https://support.apple.com/en-us/102322
69
+ # https://www.postmastery.com/icloud-postmastery-page/
70
+ # https://smtpfieldmanual.com/provider/apple
71
+ # @since v5.1.0
72
+ def get(argvs)
73
+ issuedcode = argvs['diagnosticcode'].downcase
74
+ reasontext = ''
75
+
76
+ MessagesOf.each_key do |e|
77
+ MessagesOf[e].each do |f|
78
+ next unless issuedcode.include?(f)
79
+ reasontext = e
80
+ break
81
+ end
82
+ break if reasontext.size > 0
83
+ end
84
+
85
+ return reasontext
86
+ end
87
+
88
+ end
89
+ end
90
+ end
91
+ end
92
+
@@ -6,16 +6,54 @@ module Sisimai
6
6
  module Cox
7
7
  class << self
8
8
  ErrorCodes = {
9
- # https://www.cox.com/residential/support/email-error-codes.html
10
- 'CXBL' => 'blocked', # The sending IP address has been blocked by Cox due to exhibiting spam-like behavior.
9
+ # CXBL
10
+ # - The sending IP address has been blocked by Cox due to exhibiting spam-like behavior.
11
+ # - Send an email request to Cox to ask for a sending IP address be unblocked.
12
+ # Note: Cox has sole discretion whether to unblock the sending IP address.
13
+ 'CXBL' => 'blocked',
14
+
15
+ # CXDNS
16
+ # - There was an issue with the connecting IP address Domain Name System (DNS).
17
+ # - The Reverse DNS (rDNS) lookup for your IP address is failing.
18
+ # - Confirm the IP address that sends your email.
19
+ # - Check the rDNS of that IP address. If it passes, then wait 24 hours and try resending
20
+ # your email.
21
+ 'CXDNS' => 'requireptr',
22
+
23
+ # CXSNDR
24
+ # - There was a problem with the sender's domain.
25
+ # - Your email failed authentication checks against your sending domain's SPF, DomainKeys,
26
+ # or DKIM policy.
27
+ 'CXSNDR' => 'authfailure',
28
+
29
+ # CXSMTP
30
+ # - There was a violation of SMTP protocol.
31
+ # - Your email wasn't delivered because Cox was unable to verify that it came from a
32
+ # legitimate email sender.
33
+ 'CXSMTP' => 'rejected',
34
+
35
+ # CXCNCT
36
+ # - There was a connection issue from the IP address.
37
+ # - There is a limit to the number of concurrent SMTP connections per IP address to
38
+ # protect the systems against attack. Ensure that the sending email server is not
39
+ # opening more than 10 concurrent connections to avoid reaching this limit.
40
+ 'CXCNCT' => 'toomanyconn',
41
+
42
+ # CXMXRT
43
+ # - The sender has sent email to too many recipients and needs to wait before sending
44
+ # more email.
45
+ # - The email sender has exceeded the maximum number of sent email allowed.
46
+ 'CXMXRT' => 'toomanyconn',
47
+
48
+ # CDRBL
49
+ # - The sending IP address has been temporarily blocked by Cox due to exhibiting spam-like
50
+ # behavior.
51
+ # - The block duration varies depending on reputation and other factors, but will not exceed
52
+ # 24 hours. Inspect email traffic for potential spam, and retry email delivery.
53
+ 'CDRBL' => 'blocked',
54
+
11
55
  'CXTHRT' => 'securityerror', # Email sending limited due to suspicious account activity.
12
56
  'CXMJ' => 'securityerror', # Email sending blocked due to suspicious account activity on primary Cox account.
13
- 'CXDNS' => 'blocked', # There was an issue with the connecting IP address Domain Name System (DNS).
14
- 'CXSNDR' => 'rejected', # There was a problem with the sender's domain.
15
- 'CXSMTP' => 'rejected', # Your email wasn't delivered because Cox was unable to verify that it came from a legitimate email sender.
16
- 'CXCNCT' => 'toomanyconn', # There is a limit to the number of concurrent SMTP connections per IP address
17
- 'CXMXRT' => 'toomanyconn', # The email sender has exceeded the maximum number of sent email allowed.
18
- 'CDRBL' => 'blocked', # The sending IP address has been temporarily blocked by Cox due to exhibiting spam-like behavior.
19
57
  'IPBL0001' => 'blocked', # The sending IP address is listed in the Spamhaus Zen DNSBL.
20
58
  'IPBL0010' => 'blocked', # The sending IP is listed in the Return Path DNSBL.
21
59
  'IPBL0100' => 'blocked', # The sending IP is listed in the Invaluement ivmSIP DNSBL.
@@ -32,6 +70,7 @@ module Sisimai
32
70
  'IPBL1110' => 'blocked', # The sending IP is in the Cloudmark CSI, Return Path and Invaluement ivmSIP DNSBLs.
33
71
  'IPBL1111' => 'blocked', # The sending IP is in the Cloudmark CSI, Spamhaus Zen, Return Path and Invaluement ivmSIP DNSBLs.
34
72
  'IPBL00001' => 'blocked', # The sending IP address is listed on a Spamhaus blacklist. Check your status at Spamhaus.
73
+
35
74
  'URLBL011' => 'spamdetected', # A URL within the body of the message was found on blocklists SURBL and Spamhaus DBL.
36
75
  'URLBL101' => 'spamdetected', # A URL within the body of the message was found on blocklists SURBL and ivmURI.
37
76
  'URLBL110' => 'spamdetected', # A URL within the body of the message was found on blocklists Spamhaus DBL and ivmURI.
@@ -39,63 +78,73 @@ module Sisimai
39
78
  }.freeze
40
79
  MessagesOf = {
41
80
  'blocked' => [
42
- # Cox requires that all connecting email servers contain valid reverse DNS PTR records.
43
- 'rejected - no rDNS',
44
- # An email client has repeatedly sent bad commands or invalid passwords resulting in a three-hour block of the client's IP address.
81
+ # - An email client has repeatedly sent bad commands or invalid passwords resulting in
82
+ # a three-hour block of the client's IP address.
83
+ # - The sending IP address has exceeded the threshold of invalid recipients and has
84
+ # been blocked.
45
85
  'cox too many bad commands from',
46
- # The reverse DNS check of the sending server IP address has failed.
47
- 'DNS check failure - try again later',
48
- # The sending IP address has exceeded the threshold of invalid recipients and has been blocked.
49
- 'Too many invalid recipients',
86
+ 'too many invalid recipients',
50
87
  ],
51
- 'notaccept' => [
52
- # Our systems are experiencing an issue which is causing a temporary inability to accept new email.
53
- 'ESMTP server temporarily not available',
88
+ 'requireptr' => [
89
+ # - The reverse DNS check of the sending server IP address has failed.
90
+ # - Cox requires that all connecting email servers contain valid reverse DNS PTR records.
91
+ 'dns check failure - try again later',
92
+ 'rejected - no rdns',
54
93
  ],
55
94
  'policyviolation' => [
56
- # The sending server has attempted to communicate too soon within the SMTP transaction
57
- 'ESMTP no data before greeting',
58
- # The message has been rejected because it contains an attachment with one of the following prohibited
59
- # file types, which commonly contain viruses: .shb, .shs, .vbe, .vbs, .wsc, .wsf, .wsh, .pif, .msc,
60
- # .msi, .msp, .reg, .sct, .bat, .chm, .isp, .cpl, .js, .jse, .scr, .exe.
95
+ # - The sending server has attempted to communicate too soon within the SMTP transaction
96
+ # - The message has been rejected because it contains an attachment with one of the
97
+ # following prohibited file types, which commonly contain viruses: .shb, .shs, .vbe,
98
+ # .vbs, .wsc, .wsf, .wsh, .pif, .msc, .msi, .msp, .reg, .sct, .bat, .chm, .isp, .cpl,
99
+ # .js, .jse, .scr, .exe.
100
+ 'esmtp no data before greeting',
61
101
  'attachment extension is forbidden',
62
102
  ],
63
103
  'rejected' => [
64
104
  # Cox requires that all sender domains resolve to a valid MX or A-record within DNS.
65
105
  'sender rejected',
66
106
  ],
107
+ 'systemerror' => [
108
+ # - Our systems are experiencing an issue which is causing a temporary inability to
109
+ # accept new email.
110
+ 'esmtp server temporarily not available',
111
+ ],
67
112
  'toomanyconn' => [
68
- # The sending IP address has exceeded the five maximum concurrent connection limit.
113
+ # - The sending IP address has exceeded the five maximum concurrent connection limit.
114
+ # - The SMTP connection has exceeded the 100 email message threshold and was disconnected.
115
+ # - The sending IP address has exceeded one of these rate limits and has been temporarily
116
+ # blocked.
69
117
  'too many sessions from',
70
- # The SMTP connection has exceeded the 100 email message threshold and was disconnected.
71
118
  'requested action aborted: try again later',
72
- # The sending IP address has exceeded one of these rate limits and has been temporarily blocked.
73
- 'Message threshold exceeded',
119
+ 'message threshold exceeded',
74
120
  ],
75
121
  'userunknown' => [
76
- 'recipient rejected', # The intended recipient is not a valid Cox Email account.
122
+ # - The intended recipient is not a valid Cox Email account.
123
+ 'recipient rejected',
77
124
  ],
78
125
  }.freeze
79
126
 
80
127
  # Detect bounce reason from https://cox.com/
81
- # @param [Sisimai::Fact] argvs Parsed email object
128
+ # @param [Sisimai::Fact] argvs Decoded email object
82
129
  # @return [String, Nil] The bounce reason at Cox
130
+ # @see https://www.cox.com/residential/support/email-error-codes.html
83
131
  # @since v4.25.8
84
132
  def get(argvs)
85
- statusmesg = argvs['diagnosticcode']
133
+ issuedcode = argvs['diagnosticcode']
86
134
  codenumber = 0
87
135
 
88
- if cv = statusmesg.match(/AUP#([0-9A-Z]+)/)
136
+ if cv = issuedcode.match(/AUP#([0-9A-Z]+)/)
89
137
  # Capture the numeric part of the error code
90
138
  codenumber = cv[1]
91
139
  end
92
140
  reasontext = ErrorCodes[codenumber] || ''
93
141
 
142
+ issuedcode = argvs['diagnosticcode'].downcase
94
143
  if reasontext.empty?
95
144
  # The error code was not found in ErrorCodes
96
145
  MessagesOf.each_key do |e|
97
146
  # Try to find with each error message defined in MessagesOf
98
- next unless MessagesOf[e].any? { |a| statusmesg.include?(a) }
147
+ next unless MessagesOf[e].any? { |a| issuedcode.include?(a) }
99
148
  reasontext = e
100
149
  break
101
150
  end