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
@@ -67,6 +67,15 @@ module Sisimai
67
67
  # the associated IP address from the RBL.
68
68
  #[550, '< details of RBL >'], NEED AN ACTUAL ERROR MESSAGE STRING
69
69
  ],
70
+ 'expired' => [
71
+ # - Journal messages past the expiration
72
+ # - Attempts are being made to journal mail past the set expiry threshold.
73
+ # A retry response will replace the failure because the message is marked for retry
74
+ # if rejected, causing the journal queue to grow.
75
+ # - Check to confirm there are no significant time discrepancies on the mail server.
76
+ # Discontinue journaling old messages past the expiry threshold.
77
+ [550, 'Journal messages past the expiration'],
78
+ ],
70
79
  'mesgtoobig' => [
71
80
  # - The email size either exceeds an Email Size Limit policy or is larger than the
72
81
  # Mimecast service limit. The default is 100 MB for the Legacy MTA, and 200 MB for
@@ -96,6 +105,7 @@ module Sisimai
96
105
  # - Mimecast customers should contact Mimecast Support to add the Authorized Outbound
97
106
  # address, or to take other remedial action.
98
107
  [451, 'open relay not allowed'],
108
+ [451, 'open relay is not allowed'],
99
109
  ],
100
110
  'notaccept' => [
101
111
  # - The customer account Inbound emails are disabled in the Administration Console.
@@ -133,6 +143,7 @@ module Sisimai
133
143
  # - The message has triggered a Geographical Restriction policy.
134
144
  # - Delete or amend the policy.
135
145
  [554, 'host network not allowed'],
146
+ [554, 'host network, not allowed'],
136
147
  ],
137
148
  'rejected' => [
138
149
  # - The sender's email address or domain has triggered a Blocked Senders Policy or
@@ -160,6 +171,7 @@ module Sisimai
160
171
  # sage on SMTP port 25.
161
172
  [535, 'incorrect authentication data'],
162
173
  [550, 'submitter failed to disabled'],
174
+ [550, 'submitter failed to authenticate'],
163
175
 
164
176
  # - This email has been sent using SMTP, but TLS is required by policy.
165
177
  # - Delete or change the Secure Receipt or Secure Delivery policy enforcing TLS.
@@ -267,13 +279,12 @@ module Sisimai
267
279
  }.freeze
268
280
 
269
281
  # Detect bounce reason from Mimecast
270
- # @param [Sisimai::Fact] argvs Parsed email object
282
+ # @param [Sisimai::Fact] argvs Decoded email object
271
283
  # @return [String] The bounce reason for mimecast.com
272
284
  def get(argvs)
273
285
  return '' unless Sisimai::SMTP::Reply.test(argvs['replycode'])
274
- return '' unless argvs['diagnosticcode']
275
286
 
276
- esmtperror = argvs['diagnosticcode'].downcase || ''
287
+ issuedcode = argvs['diagnosticcode'].downcase || ''
277
288
  esmtpreply = argvs['replycode'].to_i
278
289
  reasontext = ''
279
290
 
@@ -282,7 +293,7 @@ module Sisimai
282
293
  MessagesOf[e].each do |f|
283
294
  # Find an error reason
284
295
  next unless esmtpreply == f[0]
285
- next unless esmtperror.include?(f[1])
296
+ next unless issuedcode.include?(f[1])
286
297
  reasontext = e
287
298
  break
288
299
  end
@@ -12,7 +12,7 @@ module Sisimai
12
12
  }.freeze
13
13
 
14
14
  # Detect bounce reason from NTT DOCOMO
15
- # @param [Sisimai::Fact] argvs Parsed email object
15
+ # @param [Sisimai::Fact] argvs Decoded email object
16
16
  # @return [String] The bounce reason for docomo.ne.jp
17
17
  def get(argvs)
18
18
  statuscode = argvs['deliverystatus'] || ''
@@ -1,66 +1,126 @@
1
1
  module Sisimai
2
2
  module Rhost
3
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 "charter.net". This class is
4
+ # of get() method when the value of "destination" of the object is "charter.net". This class is
5
5
  # called only Sisimai::Fact class.
6
6
  module Spectrum
7
7
  class << self
8
- ErrorCodes = {
8
+ ErrorCodes = [
9
9
  # https://www.spectrumbusiness.net/support/internet/understanding-email-error-codes
10
10
  # Error codes are placed in one of two categories: incoming or outgoing.
11
- # 1. If you are trying to send an email to a Charter email address from a non-Charter email
12
- # address (such as Gmail, Yahoo, Hotmail, etc.), you may receive an error that begins
13
- # with AUP#I, followed by four numbers.
11
+ # 1. If you're trying to send an email to a Charter email address from
12
+ # a non-Charter email address (such as Gmail, Yahoo, Hotmail, etc.),
13
+ # you may receive an error that begins with AUP#I, followed by four numbers.
14
14
  #
15
- # 2. If you are trying to send an email from a Charter email address to an outgoing recipient,
16
- # you may get an error code beginning with AUP#O, also followed by four numbers.
15
+ # 2. If you are trying to send an email from a Charter email address
16
+ # to an outgoing recipient, you may get an error code beginning with
17
+ # AUP#O, also followed by four numbers.
17
18
  #
18
- 1000 => 'blocked', # Your IP address has been blocked due to suspicious activity.
19
- 1010 => 'rejected', # This email account has been blocked from sending emails due to suspicious activity.
20
- 1090 => 'systemerror', # The email you're trying to send can't be processed. Try sending again at a later time.
21
- 1260 => 'networkerror', # Spectrum doesn't process IPV6 addresses. Connect with an IPv4 address and try again.
22
- 1500 => 'rejected', # Your email was rejected for attempting to send as a different email address than you signed in under.
23
- 1520 => 'rejected', # Your email was rejected for attempting to send as a different email address than a domain that we host.
24
- 1530 => 'mesgtoobig', # Your email was rejected because it's larger than the maximum size of 20MB.
25
- 1540 => 'toomanyconn', # Your emails were deferred for attempting to send too many in a single session.
26
- 1550 => 'toomanyconn', # Your email was rejected for having too many recipients in one message.
27
- 1560 => 'policyviolation', # Your email was rejected for having too many invalid recipients.
28
- }.freeze
29
- CodeRanges = [
30
- [1020, 1080, 'rejected'], # This email account has limited access to send emails based on suspicious activity.
31
- [1100, 1150, 'blocked'], # The IP address you're trying to connect from has an issue with the Domain Name System.
32
- [1160, 1190, 'policyviolation'], # The email you tried to send goes against your domain's security policies.
33
- [1200, 1210, 'blocked'], # The IP address you're trying to send from has been flagged by Cloudmark CSI as potential spam.
34
- [1220, 1250, 'blokced'], # Your IP address has been blacklisted by Spamhaus.
35
- [1300, 1340, 'toomanyconn'], # Spectrum limits the number of concurrent connections from a sender
36
- [1350, 1490, 'toomanyconn'], # Spectrum limits emails by the number of messages sent, amount of recipients,...
19
+ # 1000 Your IP address has been blocked due to suspicious activity. If you're a Spectrum
20
+ # customer using a Spectrum-issued IP, contact us. If you're using an IP address
21
+ # other than one provided by Spectrum, blocks will remain in place until they expire.
22
+ [1000, 0, 'blocked'],
23
+
24
+ # 1010 This email account has been blocked from sending emails due to suspicious activity.
25
+ # Blocks will expire based on the nature of the activity. If you're a Spectrum customer,
26
+ # change all of your Spectrum passwords to secure your account and then contact us.
27
+ [1010, 0, 'rejected'],
28
+
29
+ # 1020 This email account has limited access to send emails based on suspicious activity.
30
+ # 1080 Blocks will expire based on the nature of the activity.
31
+ # If you're a Spectrum customer, contact us to remove the block.
32
+ [1020, 1080, 'rejected'],
33
+
34
+ # 1090 The email you're trying to send can't be processed. Try sending again at a later time.
35
+ [1090, 0, 'systemerror'],
36
+
37
+ # 1100 The IP address you're trying to connect from has an issue with the Domain Name System.
38
+ # 1150 Spectrum requires a full circle DNS for emails to be allowed through. Verify the IP
39
+ # you're connecting from, and check the IP address to ensure a reverse DNS entry exists
40
+ # for the IP. If the IP address is a Spectrum-provided email address, contact us.
41
+ [1100, 1150, 'requireptr'],
42
+
43
+ # 1160 The email you tried to send goes against your domain's security policies.
44
+ # 1190 Please contact the email administrators of your domain.
45
+ [1160, 1190, 'policyviolation'],
46
+
47
+ # 1200 The IP address you're trying to send from has been flagged by Cloudmark CSI as
48
+ # 1210 potential spam. Have your IP administrator request a reset.
49
+ # Note: Cloudmark has sole discretion whether to remove the sending IP address from
50
+ # their lists.
51
+ [1200, 1210, 'blocked'],
52
+
53
+ # 1220 Your IP address has been blacklisted by Spamhaus. The owner of the IP address must
54
+ # 1250 contact Spamhaus to be removed from the list.
55
+ # Note: Spamhaus has sole discretion whether to remove the sending IP address from
56
+ # their lists.
57
+ [1220, 1250, 'blokced'],
58
+
59
+ # 1260 Spectrum doesn't process IPV6 addresses. Connect with an IPv4 address and try again.
60
+ [1260, 0, 'networkerror'],
61
+
62
+ # 1300 Spectrum limits the number of concurrent connections from a sender, as well as the
63
+ # 1340 total number of connections allowed. Limits vary based on the reputation of the IP
64
+ # address. Reduce your number of connections and try again later.
65
+ [1300, 1340, 'toomanyconn'],
66
+
67
+ # 1350 Spectrum limits emails by the number of messages sent, amount of recipients,
68
+ # 1490 potential for spam and invalid recipients.
69
+ [1350, 1490, 'speeding'],
70
+
71
+ # 1500 Your email was rejected for attempting to send as a different email address than you
72
+ # signed in under. Check that you're sending emails from the address you signed in with.
73
+ [1500, 0, 'rejected'],
74
+
75
+ # 1520 Your email was rejected for attempting to send as a different email address than a
76
+ # domain that we host. Check the outgoing email address and try again.
77
+ [1520, 0, 'rejected'],
78
+
79
+ # 1530 Your email was rejected because it's larger than the maximum size of 20MB.
80
+ [1530, 0, 'mesgtoobig'],
81
+
82
+ # 1540 Your emails were deferred for attempting to send too many in a single session.
83
+ # Reconnect and try reducing the number of emails you send at one time.
84
+ [1540, 0, 'speeding'],
85
+
86
+ # 1550 Your email was rejected for having too many recipients in one message. Reduce the
87
+ # number of recipients and try again later.
88
+ [1550, 0, 'speeding'],
89
+
90
+ # 1560 Your email was rejected for having too many invalid recipients. Check your outgoing
91
+ # email addresses and try again later.
92
+ [1560, 0, 'policyviolation'],
93
+
94
+ # 1580 You've tried to send messages to too many recipients in a short period of time.
95
+ # Wait a little while and try again later.
96
+ [1580, 0, 'speeding'],
37
97
  ].freeze
38
98
 
39
99
  # Detect bounce reason from https://www.spectrum.com/
40
- # @param [Sisimai::Fact] argvs Parsed email object
100
+ # @param [Sisimai::Fact] argvs Decoded email object
41
101
  # @return [String, Nil] The bounce reason at Spectrum
42
102
  # @since v4.25.8
43
103
  def get(argvs)
44
- statusmesg = argvs['diagnosticcode']
45
- codenumber = 0
104
+ issuedcode = argvs['diagnosticcode']
105
+ reasontext = ''
106
+ codenumber = if cv = issuedcode.match(/AUP#[-A-Za-z]*(\d{4})/) then cv[1].to_i else 0 end
46
107
 
47
- if cv = statusmesg.match(/AUP#[-A-Za-z]*(\d{4})/)
48
- # Capture the numeric part of the error code
49
- codenumber = cv[1].to_i
50
- end
51
- reasontext = ErrorCodes[codenumber] || ''
52
-
53
- if reasontext.empty?
54
- # The error code was not found in ErrorCodes
55
- CodeRanges.each do |e|
56
- # Check the code range
108
+ ErrorCodes.each do |e|
109
+ # Try to find an error code matches with the code in the value of $diagnosticcode
110
+ if codenumber == e[0]
111
+ # [1500, 0, 'reason'] or [1500, 1550, 'reason']
112
+ reasontext = e[2]
113
+ break
114
+ else
115
+ # Check the code number is inlcuded the range like [1500, 1550, 'reason']
116
+ next if e[1] == 0
57
117
  next if codenumber < e[0]
58
118
  next if codenumber > e[1]
119
+
59
120
  reasontext = e[2]
60
121
  break
61
122
  end
62
123
  end
63
-
64
124
  return reasontext
65
125
  end
66
126
 
@@ -6,39 +6,60 @@ module Sisimai
6
6
  module Tencent
7
7
  class << self
8
8
  MessagesOf = {
9
- # https://service.mail.qq.com/cgi-bin/help?id=20022
10
- 'dmarc check failed' => 'blocked',
11
- 'spf check failed' => 'blocked',
12
- 'suspected spam ip' => 'blocked',
13
- 'mail is rejected by recipients' => 'filtered',
14
- 'message too large' => 'mesgtoobig',
15
- 'mail content denied' => 'spamdetected',
16
- 'spam is embedded in the email' => 'spamdetected',
17
- 'suspected spam' => 'spamdetected',
18
- 'bad address syntax' => 'syntaxerror',
19
- 'connection denied' => 'toomanyconn',
20
- 'connection frequency limited' => 'toomanyconn',
21
- 'domain frequency limited' => 'toomanyconn',
22
- 'ip frequency limited' => 'toomanyconn',
23
- 'sender frequency limited' => 'toomanyconn',
24
- 'mailbox unavailable or access denied' => 'toomanyconn',
25
- 'mailbox not found' => 'userunknown',
9
+ 'authfailure' => [
10
+ 'spf check failed', # https://service.mail.qq.com/detail/122/72
11
+ 'dmarc check failed',
12
+ ],
13
+ 'blocked' => [
14
+ 'suspected bounce attacks', # https://service.mail.qq.com/detail/122/57
15
+ 'suspected spam ip', # https://service.mail.qq.com/detail/122/66
16
+ 'connection denied', # https://service.mail.qq.com/detail/122/170
17
+ ],
18
+ 'mesgtoobig' => [
19
+ 'message too large', # https://service.mail.qq.com/detail/122/168
20
+ ],
21
+ 'rejected' => [
22
+ 'suspected spam', # https://service.mail.qq.com/detail/122/71
23
+ 'mail is rejected by recipients', # https://service.mail.qq.com/detail/122/92
24
+ ],
25
+ 'spandetected' => [
26
+ 'spam is embedded in the email', # https://service.mail.qq.com/detail/122/59
27
+ 'mail content denied', # https://service.mail.qq.com/detail/122/171
28
+ ],
29
+ 'speeding' => [
30
+ 'mailbox unavailable or access denined', # https://service.mail.qq.com/detail/122/166
31
+ ],
32
+ 'suspend' => [
33
+ 'is a deactivated mailbox', # http://service.mail.qq.com/cgi-bin/help?subtype=1&&id=20022&&no=1000742
34
+ ],
35
+ 'syntaxerror' => [
36
+ 'bad address syntax', # https://service.mail.qq.com/detail/122/167
37
+ ],
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
+ 'userunknown' => [
45
+ 'mailbox not found', # https://service.mail.qq.com/detail/122/169
46
+ ],
26
47
  }.freeze
27
48
 
28
49
  # Detect bounce reason from Tencent QQ
29
- # @param [Sisimai::Fact] argvs Parsed email object
50
+ # @param [Sisimai::Fact] argvs Decoded email object
30
51
  # @return [String] The bounce reason at Tencent QQ
31
52
  def get(argvs)
32
- return argvs['reason'] unless argvs['reason'].empty?
33
-
34
- statusmesg = argvs['diagnosticcode'].downcase
53
+ issuedcode = argvs['diagnosticcode'].downcase
35
54
  reasontext = ''
36
55
 
37
56
  MessagesOf.each_key do |e|
38
- # Try to match the error message with message patterns defined in $MessagesOf
39
- next unless statusmesg.include?(e)
40
- reasontext = MessagesOf[e]
41
- break
57
+ MessagesOf[e].each do |f|
58
+ next unless issuedcode.include?(f)
59
+ reasontext = e
60
+ break
61
+ end
62
+ break if reasontext.size > 0
42
63
  end
43
64
  return reasontext
44
65
  end
@@ -0,0 +1,110 @@
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 "*.yahoodns.net".
5
+ # This class is called only Sisimai::Fact class.
6
+ module YahooInc
7
+ class << self
8
+ MessagesOf = {
9
+ 'authfailure' => [
10
+ # - 550 5.7.9 This mail has been blocked because the sender is unauthenticated. Yahoo
11
+ # requires all senders to authenticate with either SPF or DKIM.
12
+ 'yahoo requires all senders to authenticate with either spf or dkim',
13
+ ],
14
+ 'blocked' => [
15
+ # - 553 5.7.1 [BL21] Connections will not be accepted from 192.0.2.25,
16
+ # because the ip is in Spamhaus's list; see http://postmaster.yahoo.com/550-bl23.html
17
+ # - 553 5.7.1 [BL23] Connections not accepted from IP addresses on Spamhaus XBL;
18
+ # see http://postmaster.yahoo.com/errors/550-bl23.html [550]",
19
+ " because the ip is in spamhaus's list;",
20
+ 'not accepted from ip addresses on spamhaus xbl',
21
+ ],
22
+ 'norelaying' => [
23
+ # - 550 relaying denied for <***@yahoo.com>
24
+ 'relaying denied for ',
25
+ ],
26
+ 'notcomplaintrfc' => ['headers are not rfc compliant'],
27
+ 'policyviolation' => [
28
+ # - 554 Message not allowed - [PH01] Email not accepted for policy reasons.
29
+ # Please visit https://postmaster.yahooinc.com/error-codes
30
+ # - 554 5.7.9 Message not accepted for policy reasons.
31
+ # See https://postmaster.yahooinc.com/error-codes
32
+ 'not accepted for policy reasons',
33
+ ],
34
+ 'rejected' => [
35
+ # Observed the following error message since around March 2024:
36
+ #
37
+ # - 421 4.7.0 [TSS04] Messages from 192.0.2.25 temporarily deferred due to unexpected
38
+ # volume or user complaints - 4.16.55.1;
39
+ # see https://postmaster.yahooinc.com/error-codes (in reply to MAIL FROM command))
40
+ #
41
+ # However, the same error message is returned even for domains that are considered to
42
+ # have a poor reputation without SPF, DKIM, or DMARC settings, or for other reasons.
43
+ # It seems that the error message is not as granular as Google's.
44
+ 'temporarily deferred due to unexpected volume or user complaints',
45
+
46
+ # - 451 Message temporarily deferred due to unresolvable RFC.5321 from domain.
47
+ # See https://senders.yahooinc.com/error-codes#unresolvable-from-domain
48
+ 'due to unresolvable rfc.5321 domain',
49
+
50
+ # - 553 5.7.2 [TSS09] All messages from 192.0.2.25 will be permanently deferred;
51
+ # Retrying will NOT succeed. See https://postmaster.yahooinc.com/error-codes
52
+ # - 553 5.7.2 [TSS11] All messages from 192.0.2.25 will be permanently deferred;
53
+ # Retrying will NOT succeed. See https://postmaster.yahooinc.com/error-codes
54
+ ' will be permanently deferred',
55
+ ],
56
+ 'speeding' => [
57
+ # - 450 User is receiving mail too quickly
58
+ 'user is receiving mail too quickly',
59
+ ],
60
+ 'suspend' => [
61
+ # - 554 delivery error: dd ****@yahoo.com is no longer valid.
62
+ # - 554 30 Sorry, your message to *****@aol.jp cannot be delivered.
63
+ # This mailbox is disabled (554.30)
64
+ ' is no longer valid.',
65
+ 'this mailbox is disabled',
66
+ ],
67
+ 'syntaxerror' => [
68
+ # - 501 Syntax error in parameters or arguments
69
+ 'syntax error in parameters or arguments',
70
+ ],
71
+ 'toomanyconn' => [
72
+ # - 421 Max message per connection reached, closing transmission channel
73
+ 'max message per connection reached',
74
+ ],
75
+ 'userunknown' => [
76
+ # - 554 delivery error: dd This user doesn't have a yahoo.com account (***@yahoo.com)
77
+ # - 552 1 Requested mail action aborted, mailbox not found (in reply to end of DATA command)
78
+ "dd this user doesn't have a ",
79
+ 'mailbox not found',
80
+ ],
81
+ }.freeze
82
+
83
+ # Detect bounce reason from Yahoo Inc. (*.yahoodns.net)
84
+ # @param [Sisimai::Fact] argvs Decoded email object
85
+ # @return [String] The bounce reason for YahooInc
86
+ # @see https://senders.yahooinc.com/smtp-error-codes
87
+ # https://smtpfieldmanual.com/provider/yahoo
88
+ # https://www.postmastery.com/yahoo-postmaster/
89
+ # @since v5.1.0
90
+ def get(argvs)
91
+ issuedcode = argvs['diagnosticcode'].downcase
92
+ reasontext = ''
93
+
94
+ MessagesOf.each_key do |e|
95
+ MessagesOf[e].each do |f|
96
+ next unless issuedcode.include?(f)
97
+ reasontext = e
98
+ break
99
+ end
100
+ break if reasontext.size > 0
101
+ end
102
+
103
+ return reasontext
104
+ end
105
+
106
+ end
107
+ end
108
+ end
109
+ end
110
+
data/lib/sisimai/rhost.rb CHANGED
@@ -5,49 +5,41 @@ module Sisimai
5
5
  module Rhost
6
6
  class << self
7
7
  RhostClass = {
8
- 'Cox' => ['cox.net'],
9
- 'FrancePTT' => ['.laposte.net', '.orange.fr', '.wanadoo.fr'],
10
- 'GoDaddy' => ['smtp.secureserver.net', 'mailstore1.secureserver.net'],
11
- 'Google' => ['aspmx.l.google.com', 'gmail-smtp-in.l.google.com'],
12
- 'IUA' => ['.email.ua'],
13
- 'KDDI' => ['.ezweb.ne.jp', 'msmx.au.com'],
14
- 'Microsoft' => ['.prod.outlook.com', '.protection.outlook.com'],
15
- 'Mimecast' => ['.mimecast.com'],
16
- 'NTTDOCOMO' => ['mfsmax.docomo.ne.jp'],
17
- 'Spectrum' => ['charter.net'],
18
- 'Tencent' => ['.qq.com'],
8
+ 'Apple' => ['.mail.icloud.com', '.apple.com', '.me.com'],
9
+ 'Cox' => ['cox.net'],
10
+ 'FrancePTT' => ['.laposte.net', '.orange.fr', '.wanadoo.fr'],
11
+ 'GoDaddy' => ['smtp.secureserver.net', 'mailstore1.secureserver.net'],
12
+ 'Google' => ['aspmx.l.google.com', 'gmail-smtp-in.l.google.com'],
13
+ 'IUA' => ['.email.ua'],
14
+ 'KDDI' => ['.ezweb.ne.jp', 'msmx.au.com'],
15
+ 'Microsoft' => ['.prod.outlook.com', '.protection.outlook.com'],
16
+ 'Mimecast' => ['.mimecast.com'],
17
+ 'NTTDOCOMO' => ['mfsmax.docomo.ne.jp'],
18
+ 'Spectrum' => ['charter.net'],
19
+ 'Tencent' => ['.qq.com'],
20
+ 'YahooInc' => ['.yahoodns.net'],
19
21
  }.freeze
20
22
 
21
- # The value of "rhost" is listed in RhostClass or not
22
- # @param [String] argvs Remote host name
23
- # @return [True,False] True: matched
24
- # False: did not match
25
- def match(rhost)
26
- return false if rhost.empty?
27
-
28
- host0 = rhost.downcase
29
- match = false
30
- RhostClass.each_key do |e|
31
- # Try to match with each key of RhostClass
32
- next unless RhostClass[e].any? { |a| host0.end_with?(a) }
33
- match = true
34
- break
35
- end
36
- return match
37
- end
38
-
39
23
  # Detect the bounce reason from certain remote hosts
40
- # @param [Hash] argvs Parsed email data
41
- # @param [String] proxy The alternative of the "rhost"
24
+ # @param [Hash] argvs Decoded email data
42
25
  # @return [String] The value of bounce reason
43
- def get(argvs, proxy = nil)
44
- remotehost = proxy || argvs['rhost'].downcase
26
+ def get(argvs)
27
+ return nil if argvs['diagnosticcode'].empty?
28
+
29
+ remotehost = argvs['rhost'].downcase
30
+ domainpart = argvs['destination'].downcase
31
+ return nil if (remotehost + domainpart).empty?
32
+
33
+ rhostmatch = nil
45
34
  rhostclass = ''
46
35
  modulename = ''
47
36
 
48
37
  RhostClass.each_key do |e|
49
- # Try to match with each key of RhostClass
50
- next unless RhostClass[e].any? { |a| remotehost.end_with?(a) }
38
+ # Try to match with each value of RhostClass
39
+ rhostmatch = true if RhostClass[e].any? { |a| remotehost.end_with?(a) }
40
+ rhostmatch ||= true if RhostClass[e].any? { |a| domainpart.end_with?(a) }
41
+ next unless rhostmatch
42
+
51
43
  modulename = 'Sisimai::Rhost::' << e
52
44
  rhostclass = 'sisimai/rhost/' << e.downcase
53
45
  break
@@ -56,6 +48,7 @@ module Sisimai
56
48
 
57
49
  require rhostclass
58
50
  reasontext = Module.const_get(modulename).get(argvs)
51
+ return nil if reasontext.empty?
59
52
  return reasontext
60
53
  end
61
54
  end
@@ -125,9 +125,10 @@ module Sisimai
125
125
 
126
126
  if first == 2
127
127
  # 2yz
128
- return false if reply < 211
129
- return false if reply > 252
130
- return false if reply > 221 && reply < 250
128
+ return true if reply == 235
129
+ return false if reply < 211
130
+ return false if reply > 252
131
+ return false if reply > 221 && reply < 250
131
132
  return true
132
133
  end
133
134
 
@@ -1,17 +1,17 @@
1
1
  module Sisimai
2
2
  module SMTP
3
- # Sisimai::SMTP::Transcript is a parser for transcript logs of SMTP session
3
+ # Sisimai::SMTP::Transcript is a decoder for the transcript logs of the SMTP session
4
4
  module Transcript
5
5
  class << self
6
6
  require 'sisimai/smtp/reply'
7
7
  require 'sisimai/smtp/status'
8
8
 
9
- # Parse a transcript of an SMTP session and makes structured data
9
+ # @abstract decodes the transcript of the SMTP session and makes structured data
10
10
  # @param [String] argv0 A transcript text MTA returned
11
11
  # @param [String] argv1 A label string of a SMTP client
12
12
  # @apram [String] argv2 A label string of a SMTP server
13
13
  # @return [Array] Structured data
14
- # [Nil] Failed to parse or the 1st argument is missing
14
+ # [Nil] Failed to decode or the 1st argument is missing
15
15
  # @since v5.0.0
16
16
  def rise(argv0 = '', argv1 = '>>>', argv2 = '<<<')
17
17
  return nil if argv0.size == 0
@@ -1,4 +1,4 @@
1
1
  # Define the version number of Sisimai
2
2
  module Sisimai
3
- VERSION = '5.0.3'.freeze
3
+ VERSION = '5.1.0'.freeze
4
4
  end
data/lib/sisimai.rb CHANGED
@@ -7,12 +7,6 @@ module Sisimai
7
7
  def version(); return Sisimai::VERSION; end
8
8
  def libname(); return 'Sisimai'; end
9
9
 
10
- # Emulate "rise" method for the backward compatible
11
- def make(argv0, **argv1)
12
- warn ' ***warning: Sisimai.make will be removed at v5.1.0. Use Sisimai.rise instead';
13
- return Sisimai.rise(argv0, **argv1)
14
- end
15
-
16
10
  # Wrapper method for decoding mailbox/maidir
17
11
  # @param [String] argv0 Path to mbox or Maildir/
18
12
  # @param [Hash] argv0 or Hash (decoded JSON)
@@ -0,0 +1,36 @@
1
+ Received: from MAILER-DAEMON
2
+ id e0720
3
+ by df.example.jp (DragonFly Mail Agent v0.13);
4
+ Tue, 11 Jun 2024 18:02:02 +0900
5
+ X-Original-To: <pseudo-local-part@google.example.com>
6
+ From: MAILER-DAEMON <>
7
+ To: kijitora@df.example.jp
8
+ Subject: Mail delivery failed
9
+ Message-Id: <e0720@df.example.jp>
10
+ Date: Tue, 11 Jun 2024 18:02:02 +0900
11
+
12
+ This is the DragonFly Mail Agent v0.13 at df.example.jp.
13
+
14
+ There was an error delivering your mail to <pseudo-local-part@google.example.com>.
15
+
16
+ gmail-smtp-in.l.google.com [74.125.203.27] did not like our final DATA:
17
+ 550-5.7.26 Unauthenticated email from example.jp is not accepted due to domain's
18
+ 550-5.7.26 DMARC policy. Please contact the administrator of example.jp domain if
19
+ 550-5.7.26 this was a legitimate mail. To learn about the DMARC initiative, go
20
+ 550-5.7.26 to
21
+ 550 5.7.26 https://support.google.com/mail/?p=DmarcRejection 98e67ed59e1d1-2c2d0e28189si6418580a91.13 - gsmtp
22
+
23
+ Message headers follow.
24
+
25
+ Received: from root (uid 0)
26
+ (envelope-from kijitora@df.example.jp)
27
+ id e06d1
28
+ by df.example.jp (DragonFly Mail Agent v0.13);
29
+ Tue, 11 Jun 2024 18:02:00 +0900
30
+ Subject: Nyaan 01
31
+ To: <pseudo-local-part@google.example.com>
32
+ User-Agent: mail (GNU Mailutils 3.14)
33
+ Date: Tue, 11 Jun 2024 18:02:00 +0900
34
+ Message-Id: <66681288.e06d1.3824794@df.example.jp>
35
+ From: <kijitora@df.example.jp>
36
+