sisimai 5.6.0 → 5.7.1

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 (130) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/rake-test.yml +0 -4
  3. data/ChangeLog.md +47 -0
  4. data/README-JA.md +19 -16
  5. data/README.md +23 -21
  6. data/lib/sisimai/address.rb +8 -31
  7. data/lib/sisimai/arf.rb +5 -6
  8. data/lib/sisimai/eb.rb +116 -0
  9. data/lib/sisimai/fact.rb +33 -51
  10. data/lib/sisimai/lda.rb +20 -18
  11. data/lib/sisimai/lhost/activehunter.rb +0 -2
  12. data/lib/sisimai/lhost/amazonses.rb +17 -18
  13. data/lib/sisimai/lhost/apachejames.rb +0 -1
  14. data/lib/sisimai/lhost/biglobe.rb +0 -16
  15. data/lib/sisimai/lhost/courier.rb +9 -7
  16. data/lib/sisimai/lhost/deutschetelekom.rb +120 -0
  17. data/lib/sisimai/lhost/domino.rb +2 -4
  18. data/lib/sisimai/lhost/dragonfly.rb +0 -27
  19. data/lib/sisimai/lhost/einsundeins.rb +4 -12
  20. data/lib/sisimai/lhost/exchange2003.rb +12 -11
  21. data/lib/sisimai/lhost/exchange2007.rb +17 -17
  22. data/lib/sisimai/lhost/exim.rb +34 -81
  23. data/lib/sisimai/lhost/ezweb.rb +15 -51
  24. data/lib/sisimai/lhost/fml.rb +8 -32
  25. data/lib/sisimai/lhost/gmail.rb +10 -32
  26. data/lib/sisimai/lhost/gmx.rb +7 -24
  27. data/lib/sisimai/lhost/googlegroups.rb +6 -5
  28. data/lib/sisimai/lhost/googleworkspace.rb +2 -5
  29. data/lib/sisimai/lhost/imailserver.rb +4 -9
  30. data/lib/sisimai/lhost/kddi.rb +8 -21
  31. data/lib/sisimai/lhost/mailfoundry.rb +0 -2
  32. data/lib/sisimai/lhost/mailmarshal.rb +1 -3
  33. data/lib/sisimai/lhost/messagingserver.rb +4 -15
  34. data/lib/sisimai/lhost/mfilter.rb +0 -1
  35. data/lib/sisimai/lhost/mimecast.rb +0 -1
  36. data/lib/sisimai/lhost/notes.rb +3 -3
  37. data/lib/sisimai/lhost/opensmtpd.rb +0 -40
  38. data/lib/sisimai/lhost/postfix.rb +14 -14
  39. data/lib/sisimai/lhost/qmail.rb +23 -89
  40. data/lib/sisimai/lhost/sendmail.rb +8 -7
  41. data/lib/sisimai/lhost/trendmicro.rb +5 -4
  42. data/lib/sisimai/lhost/v5sendmail.rb +2 -2
  43. data/lib/sisimai/lhost/verizon.rb +4 -4
  44. data/lib/sisimai/lhost/x1.rb +1 -2
  45. data/lib/sisimai/lhost/x2.rb +0 -2
  46. data/lib/sisimai/lhost/x3.rb +4 -9
  47. data/lib/sisimai/lhost/x6.rb +0 -1
  48. data/lib/sisimai/lhost/zoho.rb +0 -12
  49. data/lib/sisimai/lhost.rb +38 -19
  50. data/lib/sisimai/message.rb +1 -1
  51. data/lib/sisimai/order.rb +4 -1
  52. data/lib/sisimai/reason/authfailure.rb +8 -7
  53. data/lib/sisimai/reason/badreputation.rb +5 -4
  54. data/lib/sisimai/reason/blocked.rb +6 -5
  55. data/lib/sisimai/reason/contenterror.rb +8 -5
  56. data/lib/sisimai/reason/delivered.rb +3 -2
  57. data/lib/sisimai/reason/emailtoolarge.rb +7 -6
  58. data/lib/sisimai/reason/expired.rb +16 -4
  59. data/lib/sisimai/reason/failedstarttls.rb +5 -3
  60. data/lib/sisimai/reason/feedback.rb +2 -1
  61. data/lib/sisimai/reason/filtered.rb +9 -8
  62. data/lib/sisimai/reason/hasmoved.rb +5 -4
  63. data/lib/sisimai/reason/hostunknown.rb +14 -4
  64. data/lib/sisimai/reason/mailboxfull.rb +10 -8
  65. data/lib/sisimai/reason/mailererror.rb +3 -2
  66. data/lib/sisimai/reason/networkerror.rb +16 -3
  67. data/lib/sisimai/reason/norelaying.rb +8 -6
  68. data/lib/sisimai/reason/notaccept.rb +15 -7
  69. data/lib/sisimai/reason/notcompliantrfc.rb +5 -3
  70. data/lib/sisimai/reason/onhold.rb +8 -7
  71. data/lib/sisimai/reason/policyviolation.rb +11 -5
  72. data/lib/sisimai/reason/ratelimited.rb +5 -4
  73. data/lib/sisimai/reason/rejected.rb +24 -14
  74. data/lib/sisimai/reason/requireptr.rb +5 -4
  75. data/lib/sisimai/reason/securityerror.rb +5 -3
  76. data/lib/sisimai/reason/spamdetected.rb +6 -5
  77. data/lib/sisimai/reason/suppressed.rb +4 -3
  78. data/lib/sisimai/reason/suspend.rb +8 -3
  79. data/lib/sisimai/reason/syntaxerror.rb +5 -11
  80. data/lib/sisimai/reason/systemerror.rb +21 -2
  81. data/lib/sisimai/reason/systemfull.rb +4 -3
  82. data/lib/sisimai/reason/undefined.rb +2 -1
  83. data/lib/sisimai/reason/userunknown.rb +15 -9
  84. data/lib/sisimai/reason/vacation.rb +2 -1
  85. data/lib/sisimai/reason/virusdetected.rb +6 -5
  86. data/lib/sisimai/reason.rb +47 -42
  87. data/lib/sisimai/rfc1123.rb +1 -1
  88. data/lib/sisimai/rfc1894.rb +15 -8
  89. data/lib/sisimai/rfc2045.rb +8 -5
  90. data/lib/sisimai/rfc3464/thirdparty.rb +11 -10
  91. data/lib/sisimai/rfc3464.rb +10 -14
  92. data/lib/sisimai/rfc3834.rb +6 -5
  93. data/lib/sisimai/rfc791.rb +3 -38
  94. data/lib/sisimai/rhost/aol.rb +3 -2
  95. data/lib/sisimai/rhost/apple.rb +12 -11
  96. data/lib/sisimai/rhost/cloudflare.rb +3 -2
  97. data/lib/sisimai/rhost/cox.rb +38 -37
  98. data/lib/sisimai/rhost/facebook.rb +17 -16
  99. data/lib/sisimai/rhost/franceptt.rb +39 -38
  100. data/lib/sisimai/rhost/godaddy.rb +35 -34
  101. data/lib/sisimai/rhost/google.rb +22 -21
  102. data/lib/sisimai/rhost/gsuite.rb +8 -7
  103. data/lib/sisimai/rhost/iua.rb +11 -10
  104. data/lib/sisimai/rhost/kddi.rb +3 -2
  105. data/lib/sisimai/rhost/messagelabs.rb +13 -12
  106. data/lib/sisimai/rhost/microsoft.rb +37 -32
  107. data/lib/sisimai/rhost/mimecast.rb +18 -17
  108. data/lib/sisimai/rhost/nttdocomo.rb +10 -9
  109. data/lib/sisimai/rhost/outlook.rb +3 -2
  110. data/lib/sisimai/rhost/spectrum.rb +19 -18
  111. data/lib/sisimai/rhost/tencent.rb +10 -9
  112. data/lib/sisimai/rhost/yahooinc.rb +11 -10
  113. data/lib/sisimai/rhost/zoho.rb +8 -7
  114. data/lib/sisimai/rhost.rb +1 -1
  115. data/lib/sisimai/smtp/command.rb +13 -8
  116. data/lib/sisimai/smtp/failure.rb +9 -8
  117. data/lib/sisimai/smtp/reply.rb +23 -22
  118. data/lib/sisimai/smtp/status.rb +164 -159
  119. data/lib/sisimai/smtp/transcript.rb +3 -2
  120. data/lib/sisimai/string.rb +0 -12
  121. data/lib/sisimai/version.rb +1 -1
  122. data/lib/sisimai.rb +2 -1
  123. data/set-of-emails/maildir/bsd/lhost-deutschetelekom-01.eml +66 -0
  124. data/set-of-emails/maildir/bsd/lhost-deutschetelekom-02.eml +68 -0
  125. data/set-of-emails/maildir/bsd/lhost-deutschetelekom-03.eml +50 -0
  126. data/set-of-emails/maildir/bsd/lhost-postfix-81.eml +130 -0
  127. data/set-of-emails/should-not-crash/go-423-deeply-nested-mime-parts.eml +20050 -0
  128. data/set-of-emails/should-not-crash/p5-664-iomart-mail-filter.eml +258 -0
  129. data/set-of-emails/to-be-debugged-because/sisimai-cannot-parse-yet/.gitkeep +0 -0
  130. metadata +11 -2
@@ -1,11 +1,12 @@
1
1
  module Sisimai
2
2
  module Reason
3
- # Sisimai::Reason::OnHold checks the bounce reason is "onhold" or not. This class is called only
4
- # Sisimai::Reason class. Sisimai will set "onhold" to the reason of email bounce if there is no
3
+ # Sisimai::Reason::OnHold checks the bounce reason is "OnHold" or not. This class is called only
4
+ # Sisimai::Reason class. Sisimai will set "OnHold" to the reason of email bounce if there is no
5
5
  # (or less) detailed information about email bounce for judging the reason.
6
6
  module OnHold
7
7
  class << self
8
- def text; return 'onhold'; end
8
+ require 'sisimai/eb'
9
+ def text; return Sisimai::Eb::Re___1; end
9
10
  def description; return 'Sisimai could not decided the reason due to there is no (or less) detailed information for judging the reason'; end
10
11
 
11
12
  # Try to match that the given text and regular expressions
@@ -15,13 +16,13 @@ module Sisimai
15
16
 
16
17
  # On hold, Could not decide the bounce reason...
17
18
  # @param [Sisimai::Fact] argvs Object to be detected the reason
18
- # @return [Boolean] true: Status code is "onhold"
19
- # false: is not "onhold"
19
+ # @return [Boolean] true: Status code is "OnHold"
20
+ # false: is not "OnHold"
20
21
  # @see http://www.ietf.org/rfc/rfc2822.txt
21
22
  def true(argvs)
22
23
  return false if argvs['deliverystatus'].empty?
23
- return true if argvs['reason'] == 'onhold'
24
- return true if Sisimai::SMTP::Status.name(argvs['deliverystatus']) == 'onhold'
24
+ return true if argvs['reason'] == Sisimai::Eb::Re___1
25
+ return true if Sisimai::SMTP::Status.name(argvs['deliverystatus']) == Sisimai::Eb::Re___1
25
26
  return false
26
27
  end
27
28
  end
@@ -1,11 +1,11 @@
1
1
  module Sisimai
2
2
  module Reason
3
- # Sisimai::Reason::PolicyViolation checks the bounce reason is "policyviolation" or not. This class
3
+ # Sisimai::Reason::PolicyViolation checks the bounce reason is "PolicyViolation" or not. This class
4
4
  # is called only Sisimai::Reason class.
5
5
  #
6
6
  # This is the error that a policy violation was detected on a destination mail host. When a header
7
7
  # content or a format of the original message violates security policies, or multiple addresses
8
- # exist in the From: header, Sisimai will set "policyviolation".
8
+ # exist in the From: header, Sisimai will set "PolicyViolation".
9
9
  #
10
10
  # Status: 5.7.0
11
11
  # Remote-MTA: DNS; gmail-smtp-in.l.google.com
@@ -14,6 +14,7 @@ module Sisimai
14
14
  #
15
15
  module PolicyViolation
16
16
  class << self
17
+ require 'sisimai/eb'
17
18
  Index = [
18
19
  "because the recipient is not accepting mail with ", # AOL Phoenix
19
20
  "closed mailing list",
@@ -27,10 +28,11 @@ module Sisimai
27
28
  "message given low priority",
28
29
  "message was rejected by organization policy",
29
30
  "protocol violation",
31
+ "support.google.com/a/answer/172179",
30
32
  "you're using a mass mailer",
31
33
  ].freeze
32
34
 
33
- def text; return 'policyviolation'; end
35
+ def text; return Sisimai::Eb::ReWONT; end
34
36
  def description; return 'Email rejected due to policy violation on a destination host'; end
35
37
 
36
38
  # Try to match that the given text and regular expressions
@@ -43,13 +45,17 @@ module Sisimai
43
45
  return false
44
46
  end
45
47
 
46
- # The bounce reason is "policyviolation" or not
48
+ # The bounce reason is "PolicyViolation" or not
47
49
  # @param [Sisimai::Fact] argvs Object to be detected the reason
48
50
  # @return [Boolean] true: is policy violation
49
51
  # false: is not policy violation
50
52
  # @since 4.22.0
51
53
  # @see http://www.ietf.org/rfc/rfc2822.txt
52
- def true(_argvs); return false; end
54
+ def true(argvs)
55
+ return true if argvs['reason'] == Sisimai::Eb::ReWONT
56
+ return false if argvs['command'] != '' && argvs['command'] != Sisimai::Eb::CeDATA
57
+ return match(argvs['diagnosticcode'].downcase)
58
+ end
53
59
 
54
60
  end
55
61
  end
@@ -1,6 +1,6 @@
1
1
  module Sisimai
2
2
  module Reason
3
- # Sisimai::Reason::RateLimited checks the bounce reason is "ratelimited" or not. This class is
3
+ # Sisimai::Reason::RateLimited checks the bounce reason is "RateLimited" or not. This class is
4
4
  # called only Sisimai::Reason class.
5
5
  #
6
6
  # This is the error that SMTP connection was rejected temporarily due to too many recipients or
@@ -10,6 +10,7 @@ module Sisimai
10
10
  # 452 4.3.2 Connection rate limit exceeded. (in reply to MAIL FROM command)
11
11
  module RateLimited
12
12
  class << self
13
+ require 'sisimai/eb'
13
14
  Index = [
14
15
  "has exceeded the max emails per hour ",
15
16
  "please try again slower",
@@ -29,7 +30,7 @@ module Sisimai
29
30
  ["too many con", "s"],
30
31
  ].freeze
31
32
 
32
- def text; return 'ratelimited'; end
33
+ def text; return Sisimai::Eb::ReRATE; end
33
34
  def description; return 'SMTP connection rejected temporarily due to too many concurrency connections to the remote host'; end
34
35
 
35
36
  # Try to match that the given text and regular expressions
@@ -48,8 +49,8 @@ module Sisimai
48
49
  # false: is not rate limited
49
50
  # @see http://www.ietf.org/rfc/rfc2822.txt
50
51
  def true(argvs)
51
- return true if argvs['reason'] == 'ratelimited'
52
- return true if Sisimai::SMTP::Status.name(argvs['deliverystatus']) == 'ratelimited'
52
+ return true if argvs['reason'] == Sisimai::Eb::ReRATE
53
+ return true if Sisimai::SMTP::Status.name(argvs['deliverystatus']) == Sisimai::Eb::ReRATE
53
54
  return match(argvs['diagnosticcode'].downcase)
54
55
  end
55
56
 
@@ -1,10 +1,10 @@
1
1
  module Sisimai
2
2
  module Reason
3
- # Sisimai::Reason::Rejected checks the bounce reason is "rejected" or not. This class is called
3
+ # Sisimai::Reason::Rejected checks the bounce reason is "Rejected" or not. This class is called
4
4
  # only Sisimai::Reason class.
5
5
  #
6
6
  # This is the error that a connection to destination server was rejected by a sender's email
7
- # address (envelope from). Sisimai set "rejected" to the reason of email bounce if the value of
7
+ # address (envelope from). Sisimai set "Rejected" to the reason of email bounce if the value of
8
8
  # Status: field in a bounce email is "5.1.8" or the connection has been rejected due to the
9
9
  # argument of SMTP MAIL command.
10
10
  #
@@ -13,6 +13,7 @@ module Sisimai
13
13
  # Remote host said: 550 5.7.1 <root@nijo.example.jp>... Access denied
14
14
  module Rejected
15
15
  class << self
16
+ require 'sisimai/eb'
16
17
  IsNot = [
17
18
  "5.1.0 address rejected",
18
19
  "ip address ",
@@ -22,6 +23,7 @@ module Sisimai
22
23
  "access denied (in reply to mail from command)",
23
24
  "administrative prohibition",
24
25
  "all recipient addresses rejected : access denied",
26
+ "badsendermx", # BadSenderMX
25
27
  "backscatter protection detected an invalid or expired email address", # MDaemon
26
28
  "by non-member to a members-only list",
27
29
  "can't determine purported responsible address",
@@ -34,10 +36,12 @@ module Sisimai
34
36
  "empty envelope senders not allowed",
35
37
  "from: domain is invalid. please provide a valid from:",
36
38
  "fully qualified email address required", # McAfee
39
+ "has an outgoing mail suspension",
37
40
  "invalid sender",
38
41
  "is not a registered gateway user",
39
42
  "mail from not owned by user",
40
43
  "mailfrom domain is listed in spamhaus",
44
+ "not member article from ", # FML
41
45
  "null sender is not allowed",
42
46
  "returned mail not accepted here",
43
47
  "sending this from a different address or alias using the ",
@@ -46,8 +50,10 @@ module Sisimai
46
50
  "sender domain is empty",
47
51
  "sender domain listed at ",
48
52
  "sender verify failed", # Exim callout
53
+ "sendernoa", # SenderNoA
49
54
  "server does not accept mail from",
50
55
  "spam reporting address", # SendGrid|a message to an address has previously been marked as Spam by the recipient.
56
+ "too many spam complaints",
51
57
  "unroutable sender address",
52
58
  "you are not allowed to post to this mailing list",
53
59
  "your access to submit messages to this e-mail system has been rejected",
@@ -58,12 +64,13 @@ module Sisimai
58
64
  ["after mail from:", ".", " does not exist"],
59
65
  ["domain ", " is a dead domain"],
60
66
  ["email address ", "is not "],
67
+ ["reject mail from ", "@"], # FML
61
68
  ["send", "blacklisted"],
62
69
  ["sender", " rejected"],
63
70
  ["sender is", " list"],
64
71
  ].freeze
65
72
 
66
- def text; return 'rejected'; end
73
+ def text; return Sisimai::Eb::ReFROM; end
67
74
  def description; return "Email rejected due to a sender's email address (envelope from)"; end
68
75
 
69
76
  # Try to match that the given text and regular expressions
@@ -83,28 +90,31 @@ module Sisimai
83
90
  # false: is not rejected by the sender
84
91
  # @see http://www.ietf.org/rfc/rfc2822.txt
85
92
  def true(argvs)
86
- return true if argvs['reason'] == 'rejected'
93
+ return true if argvs['reason'] == Sisimai::Eb::ReFROM
87
94
  tempreason = Sisimai::SMTP::Status.name(argvs['deliverystatus'])
88
- return true if tempreason == 'rejected' # Delivery status code points "rejected".
95
+ return true if tempreason == Sisimai::Eb::ReFROM # Delivery status code points "Rejected".
89
96
 
90
97
  # Check the value of Diagnosic-Code: header with patterns
91
98
  issuedcode = argvs['diagnosticcode'].downcase
92
99
  thecommand = argvs['command'] || ''
93
- if thecommand == 'MAIL'
100
+ if thecommand == Sisimai::Eb::CeMAIL
94
101
  # The session was rejected at 'MAIL FROM' command
95
102
  return true if match(issuedcode)
96
103
 
97
- elsif thecommand == 'DATA'
104
+ elsif thecommand == Sisimai::Eb::CeDATA
98
105
  # The session was rejected at 'DATA' command
99
- if tempreason != 'userunknown'
100
- # Except "userunknown"
106
+ if tempreason != Sisimai::Eb::ReUSER
107
+ # Except "UserUnknown"
101
108
  return true if match(issuedcode)
102
109
  end
103
- elsif %w[onhold undefined securityerror systemerror].include?(tempreason) || tempreason == ""
104
- # Try to match with message patterns when the temporary reason is "onhold", "undefined",
105
- # "securityerror", or "systemerror"
106
- return true if match(issuedcode)
107
- end
110
+ else
111
+ tryto = [Sisimai::Eb::Re___1, Sisimai::Eb::Re___0, Sisimai::Eb::ReSAFE, Sisimai::Eb::RePROC]
112
+ if tryto.include?(tempreason) || tempreason == ""
113
+ # Try to match with message patterns when the temporary reason is "OnHold", "Undefined",
114
+ # "SecurityError", or "SystemError"
115
+ return true if match(issuedcode)
116
+ end
117
+ end
108
118
  return false
109
119
  end
110
120
 
@@ -1,11 +1,12 @@
1
1
  module Sisimai
2
2
  module Reason
3
- # Sisimai::Reason::RequirePTR checks the bounce reason is "requireptr" or not. This class is
3
+ # Sisimai::Reason::RequirePTR checks the bounce reason is "RequirePTR" or not. This class is
4
4
  # called only from Sisimai::Reason class. This is the error that SMTP connection was rejected
5
5
  # due to missing PTR record or having invalid PTR record at the source IP address used for the
6
6
  # SMTP connection.
7
7
  module RequirePTR
8
8
  class << self
9
+ require 'sisimai/eb'
9
10
  Index = [
10
11
  "cannot find your hostname",
11
12
  "cannot resolve your address.",
@@ -25,7 +26,7 @@ module Sisimai
25
26
  ["service permits ", " unverifyable sending ips"],
26
27
  ].freeze
27
28
 
28
- def text; return 'requireptr'; end
29
+ def text; return Sisimai::Eb::ReQPTR; end
29
30
  def description; return 'Email rejected due to missing PTR record or having invalid PTR record'; end
30
31
 
31
32
  # Try to match that the given text and regular expressions
@@ -44,8 +45,8 @@ module Sisimai
44
45
  # false: is not blocked due to missing PTR record
45
46
  # @see http://www.ietf.org/rfc/rfc5322.txt
46
47
  def true(argvs)
47
- return true if argvs['reason'] == 'requireptr'
48
- return true if Sisimai::SMTP::Status.name(argvs['deliverystatus']) == 'requireptr'
48
+ return true if argvs['reason'] == Sisimai::Eb::ReQPTR
49
+ return true if Sisimai::SMTP::Status.name(argvs['deliverystatus']) == Sisimai::Eb::ReQPTR
49
50
  return match(argvs['diagnosticcode'].downcase)
50
51
  end
51
52
 
@@ -1,12 +1,12 @@
1
1
  module Sisimai
2
2
  module Reason
3
- # Sisimai::Reason::SecurityError checks the bounce reason is "securityerror" or not. This class
3
+ # Sisimai::Reason::SecurityError checks the bounce reason is "SecurityError" or not. This class
4
4
  # is called only Sisimai::Reason class.
5
5
  #
6
6
  # This is the error that a security violation was detected on a destination mail server. Depends
7
7
  # on the security policy on the server, a sender's email address is camouflaged address.
8
8
  #
9
- # Sisimai will set "securityerror" to the reason of email bounce if the value of Status: field
9
+ # Sisimai will set "SecurityError" to the reason of email bounce if the value of Status: field
10
10
  # in a bounce email is "5.7.*".
11
11
  #
12
12
  # Action: failed
@@ -17,12 +17,14 @@ module Sisimai
17
17
  #
18
18
  module SecurityError
19
19
  class << self
20
+ require 'sisimai/eb'
20
21
  Index = [
21
22
  "account not subscribed to ses",
22
23
  "authentication credentials invalid",
23
24
  "authentication failure",
24
25
  "authentication required",
25
26
  "authentication turned on in your email client",
27
+ "could not retrieve credentials", # OpenSMTPD/smtpd/mta.c
26
28
  "unauthenticated senders not allowed",
27
29
  "verification failure",
28
30
  "you are not authorized to send mail, authentication is required",
@@ -35,7 +37,7 @@ module Sisimai
35
37
  ["user ", " is not authorized to perform ses:sendrawemail on resource"],
36
38
  ].freeze
37
39
 
38
- def text; return 'securityerror'; end
40
+ def text; return Sisimai::Eb::ReSAFE; end
39
41
  def description; return 'Email rejected due to security violation was detected on a destination host'; end
40
42
 
41
43
  # Try to match that the given text and regular expressions
@@ -1,6 +1,6 @@
1
1
  module Sisimai
2
2
  module Reason
3
- # Sisimai::Reason::SpamDetected checks the bounce reason is "spamdetected" due to Spam content
3
+ # Sisimai::Reason::SpamDetected checks the bounce reason is "SpamDetected" due to Spam content
4
4
  # in the message or not. This class is called only Sisimai::Reason class. This is the error that
5
5
  # the message you sent was rejected by "spam filter" which is running on the remote host.
6
6
  #
@@ -10,6 +10,7 @@ module Sisimai
10
10
  # Last-Attempt-Date: Thu, 9 Apr 2008 23:34:45 +0900 (JST)
11
11
  module SpamDetected
12
12
  class << self
13
+ require 'sisimai/eb'
13
14
  Index = [
14
15
  "blacklisted url in message",
15
16
  "block for spam",
@@ -65,7 +66,7 @@ module Sisimai
65
66
  ["spam ", "score"],
66
67
  ].freeze
67
68
 
68
- def text; return 'spamdetected'; end
69
+ def text; return Sisimai::Eb::ReSPAM; end
69
70
  def description; return 'Email rejected by spam filter running on the remote host'; end
70
71
 
71
72
  # Try to match that the given text and regular expressions
@@ -85,10 +86,10 @@ module Sisimai
85
86
  # @see http://www.ietf.org/rfc/rfc2822.txt
86
87
  def true(argvs)
87
88
  return false if argvs['deliverystatus'].empty?
88
- return true if argvs['reason'] == 'spamdetected'
89
- return true if Sisimai::SMTP::Status.name(argvs['deliverystatus']) == 'spamdetected'
89
+ return true if argvs['reason'] == Sisimai::Eb::ReSPAM
90
+ return true if Sisimai::SMTP::Status.name(argvs['deliverystatus']) == Sisimai::Eb::ReSPAM
90
91
 
91
- # The value of "reason" isn't "spamdetected" when the value of "command" is an SMTP command
92
+ # The value of "reason" isn't "SpamDetected" when the value of "command" is an SMTP command
92
93
  # to be sent before the SMTP DATA command because all the MTAs read the headers and the
93
94
  # entire message body after the DATA command.
94
95
  return false if Sisimai::SMTP::Command::ExceptDATA.include?(argvs['command'])
@@ -1,13 +1,14 @@
1
1
  module Sisimai
2
2
  module Reason
3
- # Sisimai::Reason::Suppressed checks the bounce reason is "suppressed" or not. This class is called
3
+ # Sisimai::Reason::Suppressed checks the bounce reason is "Suppressed" or not. This class is called
4
4
  # only Sisimai::Reason class.
5
5
  #
6
6
  # This is the error that the recipient adddress is listed in the suppression list of the relay
7
7
  # server, and was not delivered.
8
8
  module Suppressed
9
9
  class << self
10
- def text; return 'suppressed'; end
10
+ require 'sisimai/eb'
11
+ def text; return Sisimai::Eb::ReSTOP; end
11
12
  def description; return "Email was not delivered due to being listed in the suppression list of MTA"; end
12
13
 
13
14
  # Try to match that the given text and regular expressions
@@ -21,7 +22,7 @@ module Sisimai
21
22
  # false: is not listed in the suppression list
22
23
  # @see http://www.ietf.org/rfc/rfc2822.txt
23
24
  def true(argvs)
24
- return true if argvs['reason'] == 'suppressed'
25
+ return true if argvs['reason'] == Sisimai::Eb::ReSTOP
25
26
  return match(argvs['diagnosticcode'].downcase)
26
27
  end
27
28
 
@@ -1,10 +1,11 @@
1
1
  module Sisimai
2
2
  module Reason
3
- # Sisimai::Reason::Suspend checks the bounce reason is "suspend" or not. This class is called
3
+ # Sisimai::Reason::Suspend checks the bounce reason is "Suspend" or not. This class is called
4
4
  # only Sisimai::Reason class. This is the error that a recipient account is being suspended
5
5
  # due to unpaid or other reasons.
6
6
  module Suspend
7
7
  class << self
8
+ require 'sisimai/eb'
8
9
  Index = [
9
10
  " currently suspended",
10
11
  " temporary locked",
@@ -22,18 +23,22 @@ module Sisimai
22
23
  "mailbox unavailable or access denied",
23
24
  "recipient rejected: temporarily inactive",
24
25
  "recipient suspend the service",
26
+ "temporarily unavailable user",
27
+ "user is no longer with ",
25
28
  "user or domain is disabled",
26
29
  "user suspended", # http://mail.163.com/help/help_spam_16.htm
27
30
  "vdelivermail: account is locked email bounced",
28
31
  ].freeze
29
32
  Pairs = [
30
33
  ["account ", "disabled"],
34
+ ["account ", "limited"],
31
35
  ["has been ", "suspended"],
36
+ ["mailaddress ", "disabled"],
32
37
  ["mailbox ", "disabled"],
33
38
  ["not ", "active"],
34
39
  ].freeze
35
40
 
36
- def text; return 'suspend'; end
41
+ def text; return Sisimai::Eb::ReQUIT; end
37
42
  def description; return 'Email rejected due to a recipient account is being suspended'; end
38
43
 
39
44
  # Try to match that the given text and regular expressions
@@ -52,7 +57,7 @@ module Sisimai
52
57
  # false: is not suspended
53
58
  # @see http://www.ietf.org/rfc/rfc2822.txt
54
59
  def true(argvs)
55
- return true if argvs['reason'] == 'suspend' || argvs['replycode'].to_i == 525
60
+ return true if argvs['reason'] == Sisimai::Eb::ReQUIT || argvs['replycode'].to_i == 525
56
61
  return match(argvs['diagnosticcode'].downcase)
57
62
  end
58
63
 
@@ -1,10 +1,10 @@
1
1
  module Sisimai
2
2
  module Reason
3
- # Sisimai::Reason::SyntaxError checks the bounce reason is "syntaxerror" or not. This class is
3
+ # Sisimai::Reason::SyntaxError checks the bounce reason is "SyntaxError" or not. This class is
4
4
  # called only Sisimai::Reason class.
5
5
  #
6
6
  # This is the error that a destination mail server could not recognize SMTP command which is
7
- # sent from a sender's MTA. Sisimai will set "syntaxerror" to the reason if the value of
7
+ # sent from a sender's MTA. Sisimai will set "SyntaxError" to the reason if the value of
8
8
  # "replycode" begins with "50" such as 502, or 503.
9
9
  # Action: failed
10
10
  # Status: 5.5.0
@@ -12,7 +12,8 @@ module Sisimai
12
12
  #
13
13
  module SyntaxError
14
14
  class << self
15
- def text; return 'syntaxerror'; end
15
+ require 'sisimai/eb'
16
+ def text; return Sisimai::Eb::ReCOMM; end
16
17
  def description; return 'Email rejected due to syntax error at sent commands in SMTP session'; end
17
18
  def match(*); return false; end
18
19
 
@@ -22,14 +23,7 @@ module Sisimai
22
23
  # false: is not syntax error
23
24
  # @since 4.1.25
24
25
  # @see http://www.ietf.org/rfc/rfc2822.txt
25
- def true(argvs)
26
- return true if argvs['reason'] == 'syntaxerror'
27
-
28
- reply = argvs['replycode'].to_i
29
- return true if reply > 400 && reply < 408 || reply > 500 && reply < 508
30
- return false
31
- end
32
-
26
+ def true(argvs); return false; end
33
27
  end
34
28
  end
35
29
  end
@@ -1,6 +1,6 @@
1
1
  module Sisimai
2
2
  module Reason
3
- # Sisimai::Reason::SystemError checks the bounce reason is "systemerror" or not. This class is
3
+ # Sisimai::Reason::SystemError checks the bounce reason is "SystemError" or not. This class is
4
4
  # called only Sisimai::Reason class. This is the error that an email has bounced due to system
5
5
  # error on the remote host such as LDAP connection failure or other internal system error.
6
6
  #
@@ -9,32 +9,51 @@ module Sisimai
9
9
  # message has been in the queue too long.
10
10
  module SystemError
11
11
  class << self
12
+ require 'sisimai/eb'
12
13
  Index = [
13
14
  "aliasing/forwarding loop broken",
15
+ "automatic homedir creator crashed", # qmail-ldap-1.03-20040101.patch:19817 - 19866
14
16
  "can't create user output file",
15
17
  "cannot send e-mail to yourself",
16
18
  "could not load ",
19
+ "delivery to file forbidden", # Exim/deliver.c:5614
20
+ "delivery to pipe forbidden", # Exim/deliver.c:5624
21
+ "input/output error",
17
22
  "interrupted system call",
18
23
  "it encountered an error while being processed",
19
24
  "it would create a mail loop",
25
+ "ldap attribute", # qmail-ldap-1.03-20040101.patch:19817 - 19866
26
+ "ldap lookup", # qmail-ldap-1.03-20040101.patch:19817 - 19866
27
+ "ldap server", # qmail-ldap-1.03-20040101.patch:19817 - 19866
28
+ "lmtp error after ", # Exim/transports/lmtp.c:186
29
+ "local delivery failed", # Exim/transports/pipe.c:1156
30
+ "loop back warning:", # FML
20
31
  "loop was found in the mail exchanger",
21
32
  "loops back to myself",
33
+ "mail transport unavailable",
34
+ "may cause mail loop", # FML
35
+ "no such file or directory",
36
+ "error while executing qmail-forward", # qmail-ldap-1.03-20040101.patch:19817 - 19866
22
37
  "queue file write error",
23
38
  "recipient deferred because there is no mdb",
24
39
  "remote server is misconfigured",
25
40
  "service currently unavailable",
41
+ "several matches found in domino directory", # Donimo
26
42
  "temporary local problem",
27
43
  "timeout waiting for input",
44
+ "too many results returned but needs to be unique", # qmail-ldap-1.03-20040101.patch:19817 - 19866
28
45
  "transaction failed ",
29
46
  ].freeze
30
47
  Pairs = [
31
48
  ["config", " error"],
49
+ ["fml ", "has detected a loop condition so that"], # FML
32
50
  ["internal ", "error"],
33
51
  ["local ", "error"],
52
+ ["proxy", "broken pipe"],
34
53
  ["unable to connect ", "daemon"],
35
54
  ].freeze
36
55
 
37
- def text; return 'systemerror'; end
56
+ def text; return Sisimai::Eb::RePROC; end
38
57
  def description; return 'Email returned due to system error on the remote host'; end
39
58
 
40
59
  # Try to match that the given text and regular expressions
@@ -1,19 +1,20 @@
1
1
  module Sisimai
2
2
  module Reason
3
- # Sisimai::Reason::SystemFull checks the bounce reason is "systemfull" or not. This class is called
3
+ # Sisimai::Reason::SystemFull checks the bounce reason is "SystemFull" or not. This class is called
4
4
  # only Sisimai::Reason class.
5
5
  #
6
6
  # This is the error that a destination mail server's disk (or spool) is full. Sisimai will set
7
- # systemfull to the reason of email bounce if the value of Status: field in a bounce email is
7
+ # "SystemFull" to the reason of email bounce if the value of Status: field in a bounce email is
8
8
  # "4.3.1" or "5.3.1".
9
9
  module SystemFull
10
10
  class << self
11
+ require 'sisimai/eb'
11
12
  Index = [
12
13
  'exceeded storage allocation', # MS Exchange
13
14
  'mail system full',
14
15
  ].freeze
15
16
 
16
- def text; return 'systemfull'; end
17
+ def text; return Sisimai::Eb::ReDISK; end
17
18
  def description; return "Email rejected due to a destination mail server's disk is full"; end
18
19
 
19
20
  # Try to match that the given text and regular expressions
@@ -3,8 +3,9 @@ module Sisimai
3
3
  # Sisimai::Reason::Undefined is for only returning text and description. This class is called only
4
4
  # from Sisimai.reason method.
5
5
  module Undefined
6
+ require 'sisimai/eb'
6
7
  class << self
7
- def text; return 'undefined'; end
8
+ def text; return Sisimai::Eb::Re___0; end
8
9
  def description; return 'Sisimai could not detect an error reason'; end
9
10
  def match; return false; end
10
11
  def true(*); return false; end
@@ -1,11 +1,11 @@
1
1
  module Sisimai
2
2
  module Reason
3
- # Sisimai::Reason::UserUnknown checks the bounce reason is "userunknown" or not. This class is
3
+ # Sisimai::Reason::UserUnknown checks the bounce reason is "UserUnknown" or not. This class is
4
4
  # called only Sisimai::Reason class.
5
5
  #
6
6
  # This is the error that a local part (Left hand side of @ sign) of a recipient's email address
7
7
  # does not exist. In many case, a user has changed internet service provider, or has quit company,
8
- # or the local part is misspelled. Sisimai will set "userunknown" to the reason of email bounce
8
+ # or the local part is misspelled. Sisimai will set "UserUnknown" to the reason of email bounce
9
9
  # if the value of Status: field in a bounce email is "5.1.1", or connection was refused at SMTP
10
10
  # RCPT command, or the contents of Diagnostic-Code: field represents that it is unknown user.
11
11
  #
@@ -14,7 +14,11 @@ module Sisimai
14
14
  # RCPT TO command)
15
15
  module UserUnknown
16
16
  class << self
17
- PreMatches = %w[NoRelaying Blocked MailboxFull HasMoved Rejected NotAccept]
17
+ require 'sisimai/eb'
18
+ PreMatches = [
19
+ Sisimai::Eb::RePASS, Sisimai::Eb::ReBLOC, Sisimai::Eb::ReFULL,
20
+ Sisimai::Eb::ReMOVE, Sisimai::Eb::ReFROM, Sisimai::Eb::Re00MX,
21
+ ]
18
22
  ModulePath = {
19
23
  'Sisimai::Reason::NoRelaying' => 'sisimai/reason/norelaying',
20
24
  'Sisimai::Reason::Blocked' => 'sisimai/reason/blocked',
@@ -103,11 +107,13 @@ module Sisimai
103
107
  ["unknown e", "mail address"],
104
108
  ["unknown local", "part"],
105
109
  ["user ", " not exist"],
110
+ ["user ", "doesn't exist"],
106
111
  ["user ", "not found"],
107
112
  ["user (", ") unknown"],
113
+ ["user <", "> unknown"],
108
114
  ].freeze
109
115
 
110
- def text; return 'userunknown'; end
116
+ def text; return Sisimai::Eb::ReUSER; end
111
117
  def description; return "Email rejected due to a local part of a recipient's email address does not exist"; end
112
118
 
113
119
  # Try to match that the given text and regular expressions
@@ -120,20 +126,20 @@ module Sisimai
120
126
  return false
121
127
  end
122
128
 
123
- # Whether the address is "userunknown" or not
129
+ # Whether the address is "UserUnknown" or not
124
130
  # @param [Sisimai::Fact] argvs Object to be detected the reason
125
131
  # @return [Boolean] true: is unknown user
126
132
  # false: is not unknown user.
127
133
  # @see http://www.ietf.org/rfc/rfc2822.txt
128
134
  def true(argvs)
129
- return true if argvs['reason'] == 'userunknown'
135
+ return true if argvs['reason'] == Sisimai::Eb::ReUSER
130
136
  return false if Sisimai::SMTP::Command::BeforeRCPT.include?(argvs['command'])
131
137
 
132
138
  tempreason = Sisimai::SMTP::Status.name(argvs['deliverystatus'])
133
- return false if tempreason == 'suspend'
139
+ return false if tempreason == Sisimai::Eb::ReQUIT
134
140
 
135
141
  issuedcode = argvs['diagnosticcode'].downcase
136
- if tempreason == 'userunknown'
142
+ if tempreason == Sisimai::Eb::ReUSER
137
143
  # *.1.1 = 'Bad destination mailbox address'
138
144
  # Status: 5.1.1
139
145
  # Diagnostic-Code: SMTP; 550 5.1.1 <***@example.jp>:
@@ -158,7 +164,7 @@ module Sisimai
158
164
  end
159
165
  return true if matchother == false # Did not match with other message patterns
160
166
 
161
- elsif argvs['command'] == 'RCPT'
167
+ elsif argvs['command'] == Sisimai::Eb::CeRCPT
162
168
  # When the SMTP command is not "RCPT", the session rejected by other
163
169
  # reason, maybe.
164
170
  return true if match(issuedcode)
@@ -4,6 +4,7 @@ module Sisimai
4
4
  # from Sisimai.reason method.
5
5
  module Vacation
6
6
  class << self
7
+ require 'sisimai/eb'
7
8
  Index = [
8
9
  'i am away on vacation',
9
10
  'i am away until',
@@ -11,7 +12,7 @@ module Sisimai
11
12
  'i will be traveling for work on',
12
13
  ].freeze
13
14
 
14
- def text; return 'vacation'; end
15
+ def text; return Sisimai::Eb::ReAWAY; end
15
16
  def description; return 'Email replied automatically due to a recipient is out of office'; end
16
17
 
17
18
  # Try to match that the given text and regular expressions