sisimai 4.25.16 → 5.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (178) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +3 -3
  3. data/ANALYTICAL-PRECISION +2 -2
  4. data/Benchmarks.mk +3 -3
  5. data/CONTRIBUTING +1 -1
  6. data/ChangeLog.md +424 -393
  7. data/Developers.mk +5 -6
  8. data/Gemfile +1 -1
  9. data/Makefile +15 -15
  10. data/README-JA.md +323 -149
  11. data/README.md +319 -148
  12. data/Rakefile +9 -3
  13. data/Repository.mk +2 -3
  14. data/lib/sisimai/address.rb +118 -74
  15. data/lib/sisimai/arf.rb +84 -82
  16. data/lib/sisimai/datetime.rb +5 -52
  17. data/lib/sisimai/{data → fact}/json.rb +7 -9
  18. data/lib/sisimai/fact/yaml.rb +31 -0
  19. data/lib/sisimai/fact.rb +468 -0
  20. data/lib/sisimai/lhost/activehunter.rb +12 -14
  21. data/lib/sisimai/lhost/amavis.rb +11 -14
  22. data/lib/sisimai/lhost/amazonses.rb +37 -41
  23. data/lib/sisimai/lhost/amazonworkmail.rb +15 -18
  24. data/lib/sisimai/lhost/aol.rb +12 -14
  25. data/lib/sisimai/lhost/apachejames.rb +19 -21
  26. data/lib/sisimai/lhost/barracuda.rb +10 -12
  27. data/lib/sisimai/lhost/bigfoot.rb +21 -21
  28. data/lib/sisimai/lhost/biglobe.rb +15 -16
  29. data/lib/sisimai/lhost/courier.rb +20 -20
  30. data/lib/sisimai/lhost/domino.rb +23 -19
  31. data/lib/sisimai/lhost/einsundeins.rb +23 -18
  32. data/lib/sisimai/lhost/exchange2003.rb +30 -29
  33. data/lib/sisimai/lhost/exchange2007.rb +70 -58
  34. data/lib/sisimai/lhost/exim.rb +175 -161
  35. data/lib/sisimai/lhost/ezweb.rb +31 -56
  36. data/lib/sisimai/lhost/facebook.rb +21 -33
  37. data/lib/sisimai/lhost/fml.rb +43 -48
  38. data/lib/sisimai/lhost/gmail.rb +29 -29
  39. data/lib/sisimai/lhost/gmx.rb +18 -17
  40. data/lib/sisimai/lhost/googlegroups.rb +9 -10
  41. data/lib/sisimai/lhost/gsuite.rb +21 -27
  42. data/lib/sisimai/lhost/imailserver.rb +25 -39
  43. data/lib/sisimai/lhost/interscanmss.rb +28 -31
  44. data/lib/sisimai/lhost/kddi.rb +22 -28
  45. data/lib/sisimai/lhost/mailfoundry.rb +11 -12
  46. data/lib/sisimai/lhost/mailmarshalsmtp.rb +25 -29
  47. data/lib/sisimai/lhost/mailru.rb +33 -27
  48. data/lib/sisimai/lhost/mcafee.rb +21 -31
  49. data/lib/sisimai/lhost/messagelabs.rb +17 -20
  50. data/lib/sisimai/lhost/messagingserver.rb +40 -37
  51. data/lib/sisimai/lhost/mfilter.rb +15 -16
  52. data/lib/sisimai/lhost/mxlogic.rb +24 -23
  53. data/lib/sisimai/lhost/notes.rb +17 -17
  54. data/lib/sisimai/lhost/office365.rb +63 -27
  55. data/lib/sisimai/lhost/opensmtpd.rb +12 -13
  56. data/lib/sisimai/lhost/outlook.rb +12 -15
  57. data/lib/sisimai/lhost/postfix.rb +179 -129
  58. data/lib/sisimai/lhost/powermta.rb +12 -14
  59. data/lib/sisimai/lhost/qmail.rb +44 -47
  60. data/lib/sisimai/lhost/receivingses.rb +15 -20
  61. data/lib/sisimai/lhost/sendgrid.rb +34 -32
  62. data/lib/sisimai/lhost/sendmail.rb +66 -53
  63. data/lib/sisimai/lhost/surfcontrol.rb +19 -19
  64. data/lib/sisimai/lhost/v5sendmail.rb +45 -39
  65. data/lib/sisimai/lhost/verizon.rb +35 -39
  66. data/lib/sisimai/lhost/x1.rb +18 -17
  67. data/lib/sisimai/lhost/x2.rb +17 -14
  68. data/lib/sisimai/lhost/x3.rb +19 -19
  69. data/lib/sisimai/lhost/x4.rb +72 -57
  70. data/lib/sisimai/lhost/x5.rb +17 -19
  71. data/lib/sisimai/lhost/x6.rb +41 -17
  72. data/lib/sisimai/lhost/yahoo.rb +17 -16
  73. data/lib/sisimai/lhost/yandex.rb +16 -20
  74. data/lib/sisimai/lhost/zoho.rb +16 -15
  75. data/lib/sisimai/lhost.rb +8 -10
  76. data/lib/sisimai/mail/maildir.rb +1 -3
  77. data/lib/sisimai/mail/mbox.rb +3 -4
  78. data/lib/sisimai/mail/memory.rb +0 -1
  79. data/lib/sisimai/mail/stdin.rb +1 -3
  80. data/lib/sisimai/mail.rb +3 -7
  81. data/lib/sisimai/mda.rb +28 -42
  82. data/lib/sisimai/message.rb +435 -326
  83. data/lib/sisimai/order.rb +5 -5
  84. data/lib/sisimai/reason/authfailure.rb +64 -0
  85. data/lib/sisimai/reason/badreputation.rb +53 -0
  86. data/lib/sisimai/reason/blocked.rb +94 -160
  87. data/lib/sisimai/reason/contenterror.rb +8 -9
  88. data/lib/sisimai/reason/delivered.rb +4 -6
  89. data/lib/sisimai/reason/exceedlimit.rb +10 -12
  90. data/lib/sisimai/reason/expired.rb +6 -8
  91. data/lib/sisimai/reason/feedback.rb +2 -3
  92. data/lib/sisimai/reason/filtered.rb +17 -19
  93. data/lib/sisimai/reason/hasmoved.rb +9 -10
  94. data/lib/sisimai/reason/hostunknown.rb +15 -15
  95. data/lib/sisimai/reason/mailboxfull.rb +10 -12
  96. data/lib/sisimai/reason/mailererror.rb +18 -20
  97. data/lib/sisimai/reason/mesgtoobig.rb +9 -11
  98. data/lib/sisimai/reason/networkerror.rb +5 -8
  99. data/lib/sisimai/reason/norelaying.rb +8 -11
  100. data/lib/sisimai/reason/notaccept.rb +13 -14
  101. data/lib/sisimai/reason/notcompliantrfc.rb +43 -0
  102. data/lib/sisimai/reason/onhold.rb +6 -9
  103. data/lib/sisimai/reason/policyviolation.rb +14 -12
  104. data/lib/sisimai/reason/rejected.rb +26 -24
  105. data/lib/sisimai/reason/requireptr.rb +69 -0
  106. data/lib/sisimai/reason/securityerror.rb +33 -36
  107. data/lib/sisimai/reason/spamdetected.rb +114 -147
  108. data/lib/sisimai/reason/speeding.rb +49 -0
  109. data/lib/sisimai/reason/suspend.rb +11 -11
  110. data/lib/sisimai/reason/syntaxerror.rb +11 -10
  111. data/lib/sisimai/reason/systemerror.rb +7 -9
  112. data/lib/sisimai/reason/systemfull.rb +7 -8
  113. data/lib/sisimai/reason/toomanyconn.rb +9 -11
  114. data/lib/sisimai/reason/undefined.rb +2 -3
  115. data/lib/sisimai/reason/userunknown.rb +129 -146
  116. data/lib/sisimai/reason/vacation.rb +3 -4
  117. data/lib/sisimai/reason/virusdetected.rb +10 -11
  118. data/lib/sisimai/reason.rb +59 -64
  119. data/lib/sisimai/rfc1894.rb +55 -28
  120. data/lib/sisimai/rfc2045.rb +373 -0
  121. data/lib/sisimai/rfc3464.rb +250 -308
  122. data/lib/sisimai/rfc3834.rb +42 -45
  123. data/lib/sisimai/rfc5322.rb +75 -100
  124. data/lib/sisimai/rfc5965.rb +31 -0
  125. data/lib/sisimai/rhost/cox.rb +5 -6
  126. data/lib/sisimai/rhost/franceptt.rb +6 -8
  127. data/lib/sisimai/rhost/godaddy.rb +12 -12
  128. data/lib/sisimai/rhost/google.rb +530 -0
  129. data/lib/sisimai/rhost/iua.rb +9 -10
  130. data/lib/sisimai/rhost/kddi.rb +6 -8
  131. data/lib/sisimai/rhost/{exchangeonline.rb → microsoft.rb} +115 -114
  132. data/lib/sisimai/rhost/mimecast.rb +42 -40
  133. data/lib/sisimai/rhost/nttdocomo.rb +12 -12
  134. data/lib/sisimai/rhost/spectrum.rb +10 -12
  135. data/lib/sisimai/rhost/{tencentqq.rb → tencent.rb} +7 -8
  136. data/lib/sisimai/rhost.rb +23 -31
  137. data/lib/sisimai/smtp/command.rb +59 -0
  138. data/lib/sisimai/smtp/error.rb +4 -7
  139. data/lib/sisimai/smtp/reply.rb +161 -74
  140. data/lib/sisimai/smtp/status.rb +507 -393
  141. data/lib/sisimai/smtp/transcript.rb +124 -0
  142. data/lib/sisimai/smtp.rb +0 -1
  143. data/lib/sisimai/string.rb +74 -5
  144. data/lib/sisimai/time.rb +1 -2
  145. data/lib/sisimai/version.rb +1 -1
  146. data/lib/sisimai.rb +46 -31
  147. data/set-of-emails/maildir/bsd/lhost-domino-02.eml +6 -3
  148. data/set-of-emails/maildir/bsd/lhost-googlegroups-15.eml +174 -0
  149. data/set-of-emails/maildir/bsd/lhost-gsuite-15.eml +229 -0
  150. data/set-of-emails/maildir/bsd/lhost-postfix-75.eml +51 -0
  151. data/set-of-emails/maildir/bsd/lhost-postfix-76.eml +101 -0
  152. data/set-of-emails/maildir/bsd/lhost-postfix-77.eml +74 -0
  153. data/set-of-emails/maildir/bsd/lhost-postfix-78.eml +91 -0
  154. data/set-of-emails/maildir/bsd/lhost-receivingses-08.eml +88 -0
  155. data/set-of-emails/maildir/bsd/rfc3464-43.eml +88 -0
  156. data/set-of-emails/maildir/bsd/rhost-google-03.eml +101 -0
  157. data/set-of-emails/maildir/bsd/rhost-google-04.eml +102 -0
  158. data/set-of-emails/maildir/bsd/rhost-google-05.eml +82 -0
  159. data/set-of-emails/maildir/bsd/rhost-google-06.eml +102 -0
  160. data/set-of-emails/maildir/bsd/rhost-google-07.eml +69 -0
  161. data/set-of-emails/maildir/bsd/rhost-google-08.eml +99 -0
  162. data/sisimai-java.gemspec +1 -1
  163. data/sisimai.gemspec +1 -1
  164. metadata +41 -20
  165. data/.rspec +0 -2
  166. data/lib/sisimai/data/yaml.rb +0 -33
  167. data/lib/sisimai/data.rb +0 -411
  168. data/lib/sisimai/mime.rb +0 -456
  169. data/lib/sisimai/rhost/googleapps.rb +0 -261
  170. /data/set-of-emails/maildir/bsd/{rfc3464-41.eml → rfc3834-05.eml} +0 -0
  171. /data/set-of-emails/maildir/bsd/{rhost-googleapps-01.eml → rhost-google-01.eml} +0 -0
  172. /data/set-of-emails/maildir/bsd/{rhost-googleapps-02.eml → rhost-google-02.eml} +0 -0
  173. /data/set-of-emails/maildir/bsd/{rhost-exchangeonline-01.eml → rhost-microsoft-01.eml} +0 -0
  174. /data/set-of-emails/maildir/bsd/{rhost-exchangeonline-02.eml → rhost-microsoft-02.eml} +0 -0
  175. /data/set-of-emails/maildir/bsd/{rhost-exchangeonline-03.eml → rhost-microsoft-03.eml} +0 -0
  176. /data/set-of-emails/maildir/bsd/{rhost-tencentqq-01.eml → rhost-tencent-01.eml} +0 -0
  177. /data/set-of-emails/maildir/bsd/{rhost-tencentqq-02.eml → rhost-tencent-02.eml} +0 -0
  178. /data/set-of-emails/maildir/bsd/{rhost-tencentqq-03.eml → rhost-tencent-03.eml} +0 -0
@@ -1,15 +1,70 @@
1
1
  module Sisimai
2
2
  module Rhost
3
- # Sisimai::Rhost detects the bounce reason from the content of Sisimai::Data
4
- # object as an argument of get() method when the value of "rhost" of the object
5
- # is "*.protection.outlook.com". This class is called only Sisimai::Data class.
6
- #
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 "rhost" of the object is *.protection.outlook.com. This class
5
+ # is called only Sisimai::Fact class.
6
+ #
7
7
  # https://technet.microsoft.com/en-us/library/bb232118
8
8
  # https://learn.microsoft.com/en-us/Exchange/mail-flow-best-practices/non-delivery-reports-in-exchange-online/non-delivery-reports-in-exchange-online
9
9
  # https://learn.microsoft.com/en-us/Exchange/mail-flow/non-delivery-reports-and-bounce-messages/non-delivery-reports-and-bounce-messages
10
- module ExchangeOnline
10
+ module Microsoft
11
11
  class << self
12
12
  MessagesOf = {
13
+ 'authfailure' => [
14
+ # - Access denied, a message sent over IPv6 [2a01:111:f200:2004::240] must pass either
15
+ # SPF or DKIM validation, this message is not signed
16
+ # - The sending message sent over IPv6 must pass either SPF or DKIM.
17
+ ['4.7.26', 0, 0, 'must pass either spf or dkim validation, this message is not signed'],
18
+
19
+ # - Records are DNSSEC authentic, but one or multiple of these scenarios occurred:
20
+ # - The destination mail server's certificate doesn't match with what is expected per
21
+ # the authentic TLSA record.
22
+ # - Authentic TLSA record is misconfigured.
23
+ # - Destination domain is being attacked.
24
+ # - Any other DANE failure.
25
+ # - This message usually indicates an issue on the destination email server. Check the
26
+ # validity of recipient address and determine if the destination server is configured
27
+ # correctly to receive messages.
28
+ # - For more information about DANE, see: https://datatracker.ietf.org/doc/html/rfc7671
29
+ ['4.7.323', 0, 0, 'tlsa-invalid: The domain failed dane validation'],
30
+ ['5.7.323', 0, 0, 'tlsa-invalid: The domain failed dane validation'],
31
+
32
+ # - The destination domain indicated it was DNSSEC-authentic, but Exchange Online was
33
+ # not able to verify it as DNSSEC-authentic.
34
+ ['4.7.324', 0, 0, 'dnssec-invalid: destination domain returned invalid dnssec records'],
35
+ ['5.7.324', 0, 0, 'dnssec-invalid: destination domain returned invalid dnssec records'],
36
+
37
+ # - This happens when the presented certificate identities (CN and SAN) of a destina-
38
+ # tion SMTP target host don't match any of the domains or MX host.
39
+ # - This message usually indicates an issue on the destination email server. Check the
40
+ # validity of recipient address and determine if the destination server is configured
41
+ # correctly to receive messages. For more information, see How SMTP DNS-based Authen-
42
+ # tication of Named Entities (DANE) works to secure email communications.
43
+ ['4.7.325', 0, 0, 'certificate-host-mismatch: remote certificate must have a common name or subject alternative name matching the hostname (dane)'],
44
+ ['5.7.325', 0, 0, 'certificate-host-mismatch: remote certificate must have a common name or subject alternative name matching the hostname (dane)'],
45
+
46
+ # - The destination email system uses SPF to validate inbound mail, and there's a prob-
47
+ # lem with your SPF configuration.
48
+ ['5.7.23', 0, 0, 'the message was rejected because of sender policy framework violation'],
49
+
50
+ # - DNSSEC checks have passed, yet upon establishing the connection the destination
51
+ # mail server provides a certificate that is expired.
52
+ # - A valid X.509 certificate that isn't expired must be presented. X.509 certificates
53
+ # must be renewed after their expiration, commonly annually.
54
+ ['5.7.322', 0, 0, "certificate-expired: destination mail server's certificate is expired"],
55
+
56
+ # - Access denied, sending domain [$SenderDomain] does not pass DMARC verification
57
+ # - The sender's domain in the 5322.From address doesn't pass DMARC.
58
+ ['5.7.509', 0, 0, 'does not pass dmarc verification'],
59
+ ],
60
+ 'badreputation' => [
61
+ # Undocumented error messages ---------------------------------------------------------
62
+ # - status=deferred (host outlook-com.olc.protection.outlook.com[192.0.2.255] said:
63
+ # 451 4.7.650 The mail server [192.0.2.5] has been temporarily rate limited due to IP
64
+ # reputation. For e-mail delivery information, see https://postmaster.live.com (S775)
65
+ # [***.prod.protection.outlook.com] (in reply to MAIL FROM command))
66
+ ['4.7.650', 0, 0, 'has been temporarily rate limited due to ip reputation'],
67
+ ],
13
68
  'blocked' => [
14
69
  # Exchange Server 2019 ----------------------------------------------------------------
15
70
  # - Transient network issues or server problems that might eventually correct them-
@@ -87,58 +142,6 @@ module Sisimai
87
142
  # - 550 5.7.1 Unfortunately, messages from [10.0.2.5] weren't sent. Please contact your
88
143
  # Internet service provider since part of their network is on our block list (S3150).
89
144
  ['5.7.1', 0, 0, 'part of their network is on our block list (s3150)'],
90
-
91
- # - Access denied, a message sent over IPv6 [2a01:111:f200:2004::240] must pass either
92
- # SPF or DKIM validation, this message is not signed
93
- # - The sending message sent over IPv6 must pass either SPF or DKIM.
94
- ['4.7.26', 0, 0, 'must pass either spf or dkim validation, this message is not signed'],
95
-
96
- # - Records are DNSSEC authentic, but one or multiple of these scenarios occurred:
97
- # - The destination mail server's certificate doesn't match with what is expected per
98
- # the authentic TLSA record.
99
- # - Authentic TLSA record is misconfigured.
100
- # - Destination domain is being attacked.
101
- # - Any other DANE failure.
102
- # - This message usually indicates an issue on the destination email server. Check the
103
- # validity of recipient address and determine if the destination server is configured
104
- # correctly to receive messages.
105
- # - For more information about DANE, see: https://datatracker.ietf.org/doc/html/rfc7671
106
- ['4.7.323', 0, 0, 'tlsa-invalid: The domain failed dane validation'],
107
- ['5.7.323', 0, 0, 'tlsa-invalid: The domain failed dane validation'],
108
-
109
- # - The destination domain indicated it was DNSSEC-authentic, but Exchange Online was
110
- # not able to verify it as DNSSEC-authentic.
111
- ['4.7.324', 0, 0, 'dnssec-invalid: destination domain returned invalid dnssec records'],
112
- ['5.7.324', 0, 0, 'dnssec-invalid: destination domain returned invalid dnssec records'],
113
-
114
- # - This happens when the presented certificate identities (CN and SAN) of a destina-
115
- # tion SMTP target host don't match any of the domains or MX host.
116
- # - This message usually indicates an issue on the destination email server. Check the
117
- # validity of recipient address and determine if the destination server is configured
118
- # correctly to receive messages. For more information, see How SMTP DNS-based Authen-
119
- # tication of Named Entities (DANE) works to secure email communications.
120
- ['4.7.325', 0, 0, 'certificate-host-mismatch: remote certificate must have a common name or subject alternative name matching the hostname (dane)'],
121
- ['5.7.325', 0, 0, 'certificate-host-mismatch: remote certificate must have a common name or subject alternative name matching the hostname (dane)'],
122
-
123
- # - The destination email system uses SPF to validate inbound mail, and there's a prob-
124
- # lem with your SPF configuration.
125
- ['5.7.23', 0, 0, 'the message was rejected because of sender policy framework violation'],
126
-
127
- # - DNSSEC checks have passed, yet upon establishing the connection the destination
128
- # mail server provides a certificate that is expired.
129
- # - A valid X.509 certificate that isn't expired must be presented. X.509 certificates
130
- # must be renewed after their expiration, commonly annually.
131
- ['5.7.322', 0, 0, "certificate-expired: destination mail server's certificate is expired"],
132
-
133
- # - Access denied, sending domain [$SenderDomain] does not pass DMARC verification
134
- # - The sender's domain in the 5322.From address doesn't pass DMARC.
135
- ['5.7.509', 0, 0, 'does not pass dmarc verification'],
136
- # Undocumented error messages ---------------------------------------------------------
137
- # - status=deferred (host outlook-com.olc.protection.outlook.com[192.0.2.255] said:
138
- # 451 4.7.650 The mail server [192.0.2.5] has been temporarily rate limited due to IP
139
- # reputation. For e-mail delivery information, see https://postmaster.live.com (S775)
140
- # [***.prod.protection.outlook.com] (in reply to MAIL FROM command))
141
- ['4.7.650', 0, 0, 'has been temporarily rate limited due to ip reputation'],
142
145
  ],
143
146
  'contenterror' => [
144
147
  # Exchange Server 2019 ----------------------------------------------------------------
@@ -477,6 +480,53 @@ module Sisimai
477
480
  ['5.2.1', 0, 0, 'content filter agent quarantined this message'],
478
481
  ],
479
482
  'speeding' => [
483
+ # Exchange Online ---------------------------------------------------------------------
484
+ # - The recipient mailbox's ability to accept messages is being throttled because it's
485
+ # receiving too many messages too quickly. This is done so a single recipient's mail
486
+ # processing doesn't unfairly impact other recipients sharing the same mailbox data-
487
+ # base.
488
+ ['4.3.2', 0, 0, 'storedrv.deliver; recipient thread limit exceeded'],
489
+
490
+ # - The sender has exceeded the recipient rate limit as described in Sending limits.
491
+ # - This could indicate the account has been compromised and is being used to send
492
+ # spam.
493
+ ['5.1.90', 0, 0, "your message can't be sent because you've reached your daily limit for message recipients"],
494
+
495
+ # - The sender has exceeded the recipient rate limit or the message rate limit as de-
496
+ # scribed in Sending limits.
497
+ # - This could indicate the account has been compromised and is being used to send
498
+ # spam.
499
+ ['5.2.2', 0, 0, 'submission quota exceeded'],
500
+
501
+ # - The sender has exceeded the maximum number of messages they're allowed to send per
502
+ # hour to a specific recipient in Exchange Online.
503
+ # - The automated mailer or sender should try again later, and reduce the number of
504
+ # messages they send per hour to a specific recipient. This limit helps protect
505
+ # Microsoft 365 or Office 365 users from rapidly filling their inboxes with a large
506
+ # number of messages from errant automated notification systems or other single-send-
507
+ # er mail storms.
508
+ ['5.2.121', 0, 0, "recipient's per hour message receive limit from specific sender exceeded"],
509
+
510
+ # - The Microsoft 365 or Office 365 recipient has exceeded the number of messages they
511
+ # can receive per hour from all senders.
512
+ # - The automated mailer or sender should try again later, and reduce the number of
513
+ # messages they send per hour to a specific recipient. This limit helps protect
514
+ # Microsoft 365 and Office 365 users from rapidly filling their inboxes with a large
515
+ # number of messages from errant automated notification systems or other mail storms.
516
+ ['5.2.122', 0, 0, "recipient's per hour message receive limit exceeded"],
517
+
518
+ # - Access denied, [$SenderIPAddress] has exceeded permitted limits within $range range
519
+ # - The sender's IPv6 range has attempted to send too many messages in too short a time
520
+ # period.
521
+ ['5.7.508', 0, 0, 'has exceeded permitted limits within'],
522
+
523
+ # - The majority of traffic from this tenant has been detected as suspicious and has
524
+ # resulted in a ban on sending ability for the tenant.
525
+ # - Ensure that any compromises or open relays have been resolved, and then contact
526
+ # support through your regular channel. For more information, see Fix email delivery
527
+ # issues for error codes 5.7.700 through 5.7.750 in Exchange Online.
528
+ ['5.7.', 700, 749, 'access denied, tenant has exceeded threshold'],
529
+ ['5.7.', 700, 749, 'access denied, traffic not accepted from this ip'],
480
530
  ],
481
531
  'suspend' => [
482
532
  # Exchange Online ---------------------------------------------------------------------
@@ -588,54 +638,6 @@ module Sisimai
588
638
 
589
639
  # Previous versions of Exchange Server ------------------------------------------------
590
640
  ['5.2.122', 0, 0, 'the recipient has exceeded their limit for'],
591
-
592
- # Exchange Online ---------------------------------------------------------------------
593
- # - The recipient mailbox's ability to accept messages is being throttled because it's
594
- # receiving too many messages too quickly. This is done so a single recipient's mail
595
- # processing doesn't unfairly impact other recipients sharing the same mailbox data-
596
- # base.
597
- ['4.3.2', 0, 0, 'storedrv.deliver; recipient thread limit exceeded'],
598
-
599
- # - The sender has exceeded the recipient rate limit as described in Sending limits.
600
- # - This could indicate the account has been compromised and is being used to send
601
- # spam.
602
- ['5.1.90', 0, 0, "your message can't be sent because you've reached your daily limit for message recipients"],
603
-
604
- # - The sender has exceeded the recipient rate limit or the message rate limit as de-
605
- # scribed in Sending limits.
606
- # - This could indicate the account has been compromised and is being used to send
607
- # spam.
608
- ['5.2.2', 0, 0, 'submission quota exceeded'],
609
-
610
- # - The sender has exceeded the maximum number of messages they're allowed to send per
611
- # hour to a specific recipient in Exchange Online.
612
- # - The automated mailer or sender should try again later, and reduce the number of
613
- # messages they send per hour to a specific recipient. This limit helps protect
614
- # Microsoft 365 or Office 365 users from rapidly filling their inboxes with a large
615
- # number of messages from errant automated notification systems or other single-send-
616
- # er mail storms.
617
- ['5.2.121', 0, 0, "recipient's per hour message receive limit from specific sender exceeded"],
618
-
619
- # - The Microsoft 365 or Office 365 recipient has exceeded the number of messages they
620
- # can receive per hour from all senders.
621
- # - The automated mailer or sender should try again later, and reduce the number of
622
- # messages they send per hour to a specific recipient. This limit helps protect
623
- # Microsoft 365 and Office 365 users from rapidly filling their inboxes with a large
624
- # number of messages from errant automated notification systems or other mail storms.
625
- ['5.2.122', 0, 0, "recipient's per hour message receive limit exceeded"],
626
-
627
- # - Access denied, [$SenderIPAddress] has exceeded permitted limits within $range range
628
- # - The sender's IPv6 range has attempted to send too many messages in too short a time
629
- # period.
630
- ['5.7.508', 0, 0, 'has exceeded permitted limits within'],
631
-
632
- # - The majority of traffic from this tenant has been detected as suspicious and has
633
- # resulted in a ban on sending ability for the tenant.
634
- # - Ensure that any compromises or open relays have been resolved, and then contact
635
- # support through your regular channel. For more information, see Fix email delivery
636
- # issues for error codes 5.7.700 through 5.7.750 in Exchange Online.
637
- ['5.7.', 700, 749, 'access denied, tenant has exceeded threshold'],
638
- ['5.7.', 700, 749, 'access denied, traffic not accepted from this ip'],
639
641
  ],
640
642
  'userunknown' => [
641
643
  # Exchange Server 2019 ----------------------------------------------------------------
@@ -700,17 +702,17 @@ module Sisimai
700
702
  ],
701
703
  }.freeze
702
704
 
703
- # Detect bounce reason from Exchange Online
704
- # @param [Sisimai::Data] argvs Parsed email object
705
+ # Detect bounce reason from Exchange Server 2019 or older and Exchange Online
706
+ # @param [Sisimai::Fact] argvs Parsed email object
705
707
  # @return [String] The bounce reason for Exchange Online
706
708
  def get(argvs)
707
- return argvs.reason unless argvs.reason.empty?
708
- return '' if argvs.diagnosticcode.empty?
709
- return '' if argvs.deliverystatus.empty?
710
- return '' unless argvs.deliverystatus =~ /\A[245][.]\d[.]\d+\z/
709
+ return argvs['reason'] unless argvs['reason'].empty?
710
+ return '' if argvs['diagnosticcode'].empty?
711
+ return '' if argvs['deliverystatus'].empty?
712
+ return '' unless Sisimai::SMTP::Status.test(argvs['deliverystatus'])
711
713
 
712
- statuscode = argvs.deliverystatus
713
- esmtperror = argvs.diagnosticcode.downcase
714
+ statuscode = argvs['deliverystatus']
715
+ esmtperror = argvs['diagnosticcode'].downcase
714
716
  thirddigit = statuscode.split('.')[-1].to_i
715
717
  reasontext = ''
716
718
 
@@ -735,7 +737,6 @@ module Sisimai
735
737
  break unless reasontext.empty?
736
738
  end
737
739
 
738
-
739
740
  return reasontext
740
741
  end
741
742
 
@@ -1,28 +1,35 @@
1
1
  module Sisimai
2
2
  module Rhost
3
- # Sisimai::Rhost detects the bounce reason from the content of Sisimai::Data object as an argu-
3
+ # Sisimai::Rhost detects the bounce reason from the content of Sisimai::Fact object as an argu-
4
4
  # ment of get() method when the value of "rhost" of the object is "*.mimecast.com". This class
5
5
  # is called only Sisimai::Fact class.
6
6
  module Mimecast
7
7
  class << self
8
8
  MessagesOf = {
9
9
  # https://community.mimecast.com/s/article/Mimecast-SMTP-Error-Codes-842605754
10
- 'blocked' => [
11
- # - The sender's IP address has been blocked by a Blocked Senders Policy.
12
- # - Remove the entry from the policy.
13
- [421, 'sender address blocked'],
14
-
15
- # - The Sender's IP address has been placed on the block list due to too many invalid
16
- # connections.
17
- # - The sender's mail server must retry the connection. The mail server performing the
18
- # connection says the recipient address validation isn't responding.
19
- [451, 'recipient temporarily unavailable'],
10
+ 'authfailure' => [
11
+ # - The inbound message has been rejected because the originated IP address isn't list-
12
+ # ed in the published SPF records for the sending domain.
13
+ # - Ensure all the IP addresses for your mail servers are listed in your SPF records.
14
+ # Alternatively, create a DNS Authentication (Inbound / Outbound) policy with the
15
+ # "Inbound SPF" or "Reject on Hard Fail" option disabled. Messages that fail our SPF
16
+ # checks are subjected to spam and RBL checks, instead of being rejected.
17
+ [550, 'spf sender invalid - envelope rejected'],
20
18
 
21
- # - You've reached your mail server's limit.
22
- # - Wait and try again. The mail server won't accept any messages until you're under
23
- # the limit.
24
- [451, 'ip temporarily blacklisted'],
19
+ # - The DKIM key for the outbound message is broken and doesn't match the DNS record of
20
+ # the registered sender.
21
+ # - Check your organization's DNS record is populated with the right public key as part
22
+ # of the DNS Authentication Outbound Signing definition. The private key of the key-
23
+ # pair must be populated in the DNS Authentication policy, along with the domain and
24
+ # selector of that record.
25
+ [550, 'dkim sender invalid - envelope rejected'],
25
26
 
27
+ # - The inbound message has been rejected because the originated IP address isn't list-
28
+ # ed in the published SPF records for the sending domain.
29
+ # - Ensure all the IP addresses for your mail servers are listed in your SPF records.
30
+ [550, 'dmarc sender invalid - envelope rejected'],
31
+ ],
32
+ 'badreputation' => [
26
33
  # - The sending mail server is subjected to Greylisting. This requires the server to
27
34
  # retry the connection, between one minute and 12 hours. Alternatively, the sender's
28
35
  # IP address has a poor reputation.
@@ -36,33 +43,28 @@ module Sisimai
36
43
  # Note:
37
44
  # You can request a review of your source IP ranges by completing our online form.
38
45
  [550, 'local ct ip reputation - (reject)'],
46
+ ],
47
+ 'blocked' => [
48
+ # - The sender's IP address has been blocked by a Blocked Senders Policy.
49
+ # - Remove the entry from the policy.
50
+ [421, 'sender address blocked'],
51
+
52
+ # - The Sender's IP address has been placed on the block list due to too many invalid
53
+ # connections.
54
+ # - The sender's mail server must retry the connection. The mail server performing the
55
+ # connection says the recipient address validation isn't responding.
56
+ [451, 'recipient temporarily unavailable'],
57
+
58
+ # - You've reached your mail server's limit.
59
+ # - Wait and try again. The mail server won't accept any messages until you're under
60
+ # the limit.
61
+ [451, 'ip temporarily blacklisted'],
39
62
 
40
63
  # - The sender's IP address is listed in an RBL. The text displayed is specific to the
41
64
  # RBL which lists the sender's IP address.
42
65
  # - Bypass the RBL with an Auto Allow or Permitted Senders policy. Additionally request
43
66
  # the associated IP address from the RBL.
44
67
  #[550, '< details of RBL >'], NEED AN ACTUAL ERROR MESSAGE STRING
45
-
46
- # - The inbound message has been rejected because the originated IP address isn't list-
47
- # ed in the published SPF records for the sending domain.
48
- # - Ensure all the IP addresses for your mail servers are listed in your SPF records.
49
- # Alternatively, create a DNS Authentication (Inbound / Outbound) policy with the
50
- # "Inbound SPF" or "Reject on Hard Fail" option disabled. Messages that fail our SPF
51
- # checks are subjected to spam and RBL checks, instead of being rejected.
52
- [550, 'spf sender invalid - envelope rejected'],
53
-
54
- # - The DKIM key for the outbound message is broken and doesn't match the DNS record of
55
- # the registered sender.
56
- # - Check your organization's DNS record is populated with the right public key as part
57
- # of the DNS Authentication Outbound Signing definition. The private key of the key-
58
- # pair must be populated in the DNS Authentication policy, along with the domain and
59
- # selector of that record.
60
- [550, 'dkim sender invalid - envelope rejected'],
61
-
62
- # - The inbound message has been rejected because the originated IP address isn't list-
63
- # ed in the published SPF records for the sending domain.
64
- # - Ensure all the IP addresses for your mail servers are listed in your SPF records.
65
- [550, 'dmarc sender invalid - envelope rejected'],
66
68
  ],
67
69
  'mesgtoobig' => [
68
70
  # - The email size either exceeds an Email Size Limit policy or is larger than the
@@ -261,11 +263,11 @@ module Sisimai
261
263
  # @param [Sisimai::Fact] argvs Parsed email object
262
264
  # @return [String] The bounce reason for mimecast.com
263
265
  def get(argvs)
264
- return '' unless argvs.replycode =~ /\A[245]\d\d\z/
265
- return '' unless argvs.diagnosticcode
266
+ return '' unless Sisimai::SMTP::Reply.test(argvs['replycode'])
267
+ return '' unless argvs['diagnosticcode']
266
268
 
267
- esmtperror = argvs.diagnosticcode.downcase || ''
268
- esmtpreply = argvs.replycode.to_i
269
+ esmtperror = argvs['diagnosticcode'].downcase || ''
270
+ esmtpreply = argvs['replycode'].to_i
269
271
  reasontext = ''
270
272
 
271
273
  MessagesOf.each_key do |e|
@@ -1,23 +1,23 @@
1
1
  module Sisimai
2
2
  module Rhost
3
- # Sisimai::Rhost detects the bounce reason from the content of Sisimai::Data object as an argument
3
+ # Sisimai::Rhost detects the bounce reason from the content of Sisimai::Fact object as an argument
4
4
  # of get() method when the value of "rhost" of the object is "mfsmax.docomo.ne.jp". This class
5
- # is called only Sisimai::Data class.
5
+ # is called only Sisimai::Fact class.
6
6
  module NTTDOCOMO
7
7
  class << self
8
8
  MessagesOf = {
9
- 'mailboxfull' => %r/552 too much mail data/,
10
- 'toomanyconn' => %r/552 too many recipients/,
11
- 'syntaxerror' => %r/(?:503 bad sequence of commands|504 command parameter not implemented)/,
9
+ 'mailboxfull' => ['552 too much mail data'],
10
+ 'toomanyconn' => ['552 too many recipients'],
11
+ 'syntaxerror' => ['503 bad sequence of commands', '504 command parameter not implemented'],
12
12
  }.freeze
13
13
 
14
14
  # Detect bounce reason from NTT DOCOMO
15
- # @param [Sisimai::Data] argvs Parsed email object
15
+ # @param [Sisimai::Fact] argvs Parsed email object
16
16
  # @return [String] The bounce reason for docomo.ne.jp
17
17
  def get(argvs)
18
- statuscode = argvs.deliverystatus || ''
19
- commandtxt = argvs.smtpcommand || ''
20
- esmtperror = argvs.diagnosticcode.downcase || ''
18
+ statuscode = argvs['deliverystatus'] || ''
19
+ thecommand = argvs['smtpcommand'] || ''
20
+ esmtperror = argvs['diagnosticcode'].downcase || ''
21
21
  reasontext = ''
22
22
 
23
23
  # Check the value of Status: field, an SMTP Reply Code, and the SMTP Command
@@ -51,7 +51,7 @@ module Sisimai
51
51
  # The value of "Diagnostic-Code:" field is not empty
52
52
  MessagesOf.each_key do |e|
53
53
  # Try to match the error message with message patterns defined in "MessagesOf"
54
- next unless esmtperror =~ MessagesOf[e]
54
+ next unless MessagesOf[e].any? { |a| esmtperror.include?(a) }
55
55
  reasontext = e
56
56
  break
57
57
  end
@@ -61,7 +61,7 @@ module Sisimai
61
61
  # A bounce reason did not decide from a status code, an error message.
62
62
  if statuscode == '5.0.0'
63
63
  # Status: 5.0.0
64
- if commandtxt == 'RCPT'
64
+ if thecommand == 'RCPT'
65
65
  # Your message to the following recipients cannot be delivered:
66
66
  #
67
67
  # <***@docomo.ne.jp>:
@@ -77,7 +77,7 @@ module Sisimai
77
77
  # Diagnostic-Code: smtp; 550 Unknown user ***@docomo.ne.jp
78
78
  reasontext = 'userunknown'
79
79
 
80
- elsif commandtxt == 'DATA'
80
+ elsif thecommand == 'DATA'
81
81
  # <***@docomo.ne.jp>: host mfsmax.docomo.ne.jp[203.138.181.240] said:
82
82
  # 550 Unknown user ***@docomo.ne.jp (in reply to end of DATA
83
83
  # command)
@@ -1,21 +1,19 @@
1
1
  module Sisimai
2
2
  module Rhost
3
- # Sisimai::Rhost detects the bounce reason from the content of Sisimai::Data
4
- # object as an argument of get() method when the value of "destination" of
5
- # the object is "charter.net". This class is called only Sisimai::Data class.
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
5
+ # called only Sisimai::Fact class.
6
6
  module Spectrum
7
7
  class << self
8
- # Imported from p5-Sisimail/lib/Sisimai/Rhost/Spectrum.pm
9
8
  ErrorCodes = {
10
9
  # https://www.spectrumbusiness.net/support/internet/understanding-email-error-codes
11
10
  # Error codes are placed in one of two categories: incoming or outgoing.
12
- # 1. If you’re trying to send an email to a Charter email address from
13
- # a non-Charter email address (such as Gmail, Yahoo, Hotmail, etc.),
14
- # you may receive an error that begins with AUP#I, followed by four numbers.
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.
15
14
  #
16
- # 2. If you are trying to send an email from a Charter email address
17
- # to an outgoing recipient, you may get an error code beginning with
18
- # AUP#O, also followed by four numbers.
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.
19
17
  #
20
18
  1000 => 'blocked', # Your IP address has been blocked due to suspicious activity.
21
19
  1010 => 'rejected', # This email account has been blocked from sending emails due to suspicious activity.
@@ -39,11 +37,11 @@ module Sisimai
39
37
  ].freeze
40
38
 
41
39
  # Detect bounce reason from https://www.spectrum.com/
42
- # @param [Sisimai::Data] argvs Parsed email object
40
+ # @param [Sisimai::Fact] argvs Parsed email object
43
41
  # @return [String, Nil] The bounce reason at Spectrum
44
42
  # @since v4.25.8
45
43
  def get(argvs)
46
- statusmesg = argvs.diagnosticcode
44
+ statusmesg = argvs['diagnosticcode']
47
45
  codenumber = 0
48
46
 
49
47
  if cv = statusmesg.match(/AUP#[-A-Za-z]*(\d{4})/)
@@ -1,11 +1,10 @@
1
1
  module Sisimai
2
2
  module Rhost
3
- # Sisimai::Rhost detects the bounce reason from the content of Sisimai::Data
4
- # object as an argument of get() method when the value of "rhost" of the object
5
- # is "mx*.qq.com". This class is called only Sisimai::Data class.
6
- module TencentQQ
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 "rhost" of the object is "mx*.qq.com". This class is called
5
+ # only Sisimai::Fact class.
6
+ module Tencent
7
7
  class << self
8
- # Imported from p5-Sisimail/lib/Sisimai/Rhost/TencentQQ.pm
9
8
  MessagesOf = {
10
9
  # https://service.mail.qq.com/cgi-bin/help?id=20022
11
10
  'dmarc check failed' => 'blocked',
@@ -27,12 +26,12 @@ module Sisimai
27
26
  }.freeze
28
27
 
29
28
  # Detect bounce reason from Tencent QQ
30
- # @param [Sisimai::Data] argvs Parsed email object
29
+ # @param [Sisimai::Fact] argvs Parsed email object
31
30
  # @return [String] The bounce reason at Tencent QQ
32
31
  def get(argvs)
33
- return argvs.reason unless argvs.reason.empty?
32
+ return argvs['reason'] unless argvs['reason'].empty?
34
33
 
35
- statusmesg = argvs.diagnosticcode.downcase
34
+ statusmesg = argvs['diagnosticcode'].downcase
36
35
  reasontext = ''
37
36
 
38
37
  MessagesOf.each_key do |e|
data/lib/sisimai/rhost.rb CHANGED
@@ -1,29 +1,21 @@
1
1
  module Sisimai
2
- # Sisimai::Rhost detects the bounce reason from the content of Sisimai::Data
3
- # object as an argument of get() method when the value of rhost of the object
4
- # is listed in the results of Sisimai::Rhost->list method.
5
- # This class is called only Sisimai::Data class.
2
+ # Sisimai::Rhost detects the bounce reason from the content of Sisimai::Fact object as an argument
3
+ # of get() method when the value of rhost of the object is listed in the results of Sisimai::Rhost
4
+ # ->list method. This class is called only Sisimai::Fact class.
6
5
  module Rhost
7
6
  class << self
8
- # Imported from p5-Sisimail/lib/Sisimai/Rhost.pm
9
7
  RhostClass = {
10
- 'cox.net' => 'Cox',
11
- '.prod.outlook.com' => 'ExchangeOnline',
12
- '.protection.outlook.com' => 'ExchangeOnline',
13
- 'laposte.net' => 'FrancePTT',
14
- 'orange.fr' => 'FrancePTT',
15
- 'wanadoo.fr' => 'FrancePTT',
16
- 'smtp.secureserver.net' => 'GoDaddy',
17
- 'mailstore1.secureserver.net' => 'GoDaddy',
18
- 'aspmx.l.google.com' => 'GoogleApps',
19
- 'gmail-smtp-in.l.google.com' => 'GoogleApps',
20
- '.email.ua' => 'IUA',
21
- 'lsean.ezweb.ne.jp' => 'KDDI',
22
- 'msmx.au.com' => 'KDDI',
23
- '.mimecast.com' => 'Mimecast',
24
- 'mfsmax.docomo.ne.jp' => 'NTTDOCOMO',
25
- 'charter.net' => 'Spectrum',
26
- '.qq.com' => 'TencentQQ',
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'],
27
19
  }.freeze
28
20
 
29
21
  # The value of "rhost" is listed in RhostClass or not
@@ -35,10 +27,9 @@ module Sisimai
35
27
 
36
28
  host0 = rhost.downcase
37
29
  match = false
38
-
39
30
  RhostClass.each_key do |e|
40
31
  # Try to match with each key of RhostClass
41
- next unless host0.end_with?(e)
32
+ next unless RhostClass[e].any? { |a| host0.end_with?(a) }
42
33
  match = true
43
34
  break
44
35
  end
@@ -46,19 +37,19 @@ module Sisimai
46
37
  end
47
38
 
48
39
  # Detect the bounce reason from certain remote hosts
49
- # @param [Sisimai::Data] argvs Parsed email object
50
- # @param [String] proxy The alternative of the "rhost"
51
- # @return [String] The value of bounce reason
40
+ # @param [Hash] argvs Parsed email data
41
+ # @param [String] proxy The alternative of the "rhost"
42
+ # @return [String] The value of bounce reason
52
43
  def get(argvs, proxy = nil)
53
- remotehost = proxy || argvs.rhost.downcase
44
+ remotehost = proxy || argvs['rhost'].downcase
54
45
  rhostclass = ''
55
46
  modulename = ''
56
47
 
57
48
  RhostClass.each_key do |e|
58
49
  # Try to match with each key of RhostClass
59
- next unless remotehost.end_with?(e)
60
- modulename = 'Sisimai::Rhost::' << RhostClass[e]
61
- rhostclass = modulename.gsub('::', '/').downcase
50
+ next unless RhostClass[e].any? { |a| remotehost.end_with?(a) }
51
+ modulename = 'Sisimai::Rhost::' << e
52
+ rhostclass = 'sisimai/rhost/' << e.downcase
62
53
  break
63
54
  end
64
55
  return nil if rhostclass.empty?
@@ -70,3 +61,4 @@ module Sisimai
70
61
  end
71
62
  end
72
63
  end
64
+