sisimai 4.25.8-java → 4.25.12-java

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of sisimai might be problematic. Click here for more details.

Files changed (97) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +4 -3
  3. data/ANALYTICAL-PRECISION +1 -1
  4. data/ChangeLog.md +65 -0
  5. data/README-JA.md +3 -3
  6. data/README.md +4 -4
  7. data/lib/sisimai/address.rb +6 -3
  8. data/lib/sisimai/arf.rb +25 -21
  9. data/lib/sisimai/data.rb +7 -1
  10. data/lib/sisimai/datetime.rb +15 -14
  11. data/lib/sisimai/lhost/amazonses.rb +1 -1
  12. data/lib/sisimai/lhost/domino.rb +29 -4
  13. data/lib/sisimai/lhost/einsundeins.rb +1 -1
  14. data/lib/sisimai/lhost/exchange2007.rb +1 -1
  15. data/lib/sisimai/lhost/exim.rb +14 -10
  16. data/lib/sisimai/lhost/ezweb.rb +1 -1
  17. data/lib/sisimai/lhost/gsuite.rb +5 -0
  18. data/lib/sisimai/lhost/imailserver.rb +1 -1
  19. data/lib/sisimai/lhost/mailfoundry.rb +3 -4
  20. data/lib/sisimai/lhost/mailmarshalsmtp.rb +2 -2
  21. data/lib/sisimai/lhost/mxlogic.rb +1 -1
  22. data/lib/sisimai/lhost/notes.rb +1 -1
  23. data/lib/sisimai/lhost/office365.rb +1 -1
  24. data/lib/sisimai/lhost/postfix.rb +3 -10
  25. data/lib/sisimai/lhost/qmail.rb +7 -7
  26. data/lib/sisimai/lhost/sendgrid.rb +2 -2
  27. data/lib/sisimai/lhost/sendmail.rb +1 -1
  28. data/lib/sisimai/lhost/verizon.rb +4 -4
  29. data/lib/sisimai/lhost/x3.rb +4 -0
  30. data/lib/sisimai/lhost/x4.rb +8 -8
  31. data/lib/sisimai/mail.rb +2 -21
  32. data/lib/sisimai/mda.rb +2 -2
  33. data/lib/sisimai/mime.rb +1 -1
  34. data/lib/sisimai/reason/blocked.rb +40 -26
  35. data/lib/sisimai/reason/exceedlimit.rb +4 -1
  36. data/lib/sisimai/reason/expired.rb +2 -0
  37. data/lib/sisimai/reason/filtered.rb +10 -9
  38. data/lib/sisimai/reason/hostunknown.rb +3 -0
  39. data/lib/sisimai/reason/mailererror.rb +1 -1
  40. data/lib/sisimai/reason/norelaying.rb +8 -7
  41. data/lib/sisimai/reason/notaccept.rb +5 -3
  42. data/lib/sisimai/reason/policyviolation.rb +5 -1
  43. data/lib/sisimai/reason/rejected.rb +5 -1
  44. data/lib/sisimai/reason/securityerror.rb +5 -6
  45. data/lib/sisimai/reason/spamdetected.rb +23 -16
  46. data/lib/sisimai/reason/suspend.rb +1 -0
  47. data/lib/sisimai/reason/systemerror.rb +2 -0
  48. data/lib/sisimai/reason/userunknown.rb +25 -21
  49. data/lib/sisimai/reason/virusdetected.rb +9 -3
  50. data/lib/sisimai/rfc1894.rb +24 -22
  51. data/lib/sisimai/rfc3464.rb +1 -1
  52. data/lib/sisimai/rfc3834.rb +1 -1
  53. data/lib/sisimai/rfc5322.rb +8 -3
  54. data/lib/sisimai/rhost/exchangeonline.rb +8 -1
  55. data/lib/sisimai/rhost/franceptt.rb +4 -0
  56. data/lib/sisimai/rhost/googleapps.rb +4 -1
  57. data/lib/sisimai/rhost.rb +1 -0
  58. data/lib/sisimai/smtp/error.rb +8 -6
  59. data/lib/sisimai/smtp/reply.rb +1 -1
  60. data/lib/sisimai/smtp/status.rb +1 -1
  61. data/lib/sisimai/time.rb +1 -2
  62. data/lib/sisimai/version.rb +1 -1
  63. data/lib/sisimai.rb +3 -3
  64. data/set-of-emails/maildir/bsd/arf-25.eml +61 -0
  65. data/set-of-emails/maildir/bsd/lhost-aol-04.eml +23 -23
  66. data/set-of-emails/maildir/bsd/lhost-domino-02.eml +1 -2
  67. data/set-of-emails/maildir/bsd/lhost-exim-61.eml +40 -0
  68. data/set-of-emails/maildir/bsd/lhost-postfix-66.eml +80 -0
  69. data/set-of-emails/maildir/bsd/lhost-postfix-67.eml +80 -0
  70. data/set-of-emails/maildir/bsd/lhost-postfix-68.eml +82 -0
  71. data/set-of-emails/maildir/bsd/lhost-postfix-69.eml +80 -0
  72. data/set-of-emails/maildir/bsd/lhost-postfix-70.eml +87 -0
  73. data/set-of-emails/maildir/bsd/lhost-postfix-71.eml +81 -0
  74. data/set-of-emails/maildir/bsd/lhost-postfix-72.eml +81 -0
  75. data/set-of-emails/maildir/bsd/lhost-postfix-73.eml +79 -0
  76. data/set-of-emails/maildir/bsd/lhost-postfix-74.eml +83 -0
  77. data/set-of-emails/maildir/bsd/lhost-sendmail-08.eml +1 -1
  78. data/set-of-emails/maildir/bsd/lhost-sendmail-11.eml +1 -1
  79. data/set-of-emails/maildir/bsd/lhost-sendmail-57.eml +59 -0
  80. data/set-of-emails/maildir/bsd/lhost-sendmail-58.eml +70 -0
  81. data/set-of-emails/maildir/bsd/lhost-sendmail-59.eml +68 -0
  82. data/set-of-emails/maildir/bsd/lhost-x3-06.eml +53 -0
  83. data/set-of-emails/maildir/bsd/rfc3464-41.eml +19 -0
  84. data/set-of-emails/maildir/bsd/rfc3464-42.eml +34 -0
  85. data/set-of-emails/maildir/bsd/{rhost-exchange-online-01.eml → rhost-exchangeonline-01.eml} +0 -0
  86. data/set-of-emails/maildir/bsd/{rhost-exchange-online-02.eml → rhost-exchangeonline-02.eml} +0 -0
  87. data/set-of-emails/maildir/bsd/{rhost-exchange-online-03.eml → rhost-exchangeonline-03.eml} +0 -0
  88. data/set-of-emails/maildir/bsd/rhost-franceptt-12.eml +82 -0
  89. data/set-of-emails/maildir/bsd/{rhost-google-apps-01.eml → rhost-googleapps-01.eml} +0 -0
  90. data/set-of-emails/maildir/bsd/{rhost-google-apps-02.eml → rhost-googleapps-02.eml} +0 -0
  91. data/set-of-emails/maildir/dos/{rhost-exchange-online-01.eml → rhost-exchangeonline-01.eml} +0 -0
  92. data/set-of-emails/maildir/dos/{rhost-google-apps-01.eml → rhost-googleapps-01.eml} +0 -0
  93. data/set-of-emails/maildir/mac/{rhost-exchange-online-01.eml → rhost-exchangeonline-01.eml} +0 -0
  94. data/set-of-emails/maildir/mac/{rhost-google-apps-01.eml → rhost-googleapps-01.eml} +0 -0
  95. data/sisimai-java.gemspec +4 -4
  96. data/sisimai.gemspec +4 -4
  97. metadata +38 -20
@@ -188,7 +188,7 @@ module Sisimai::Lhost
188
188
  e['diagnosis'] = Sisimai::String.sweep(e['diagnosis']) || ''
189
189
  if e['status'].empty? || e['status'].end_with?('.0.0')
190
190
  # There is no value of Status header or the value is 5.0.0, 4.0.0
191
- e['status'] = Sisimai::SMTP::Status.find(e['diagnosis']) || ''
191
+ e['status'] = Sisimai::SMTP::Status.find(e['diagnosis']) || e['status']
192
192
  end
193
193
 
194
194
  ReCommands.each_key do |p|
@@ -110,8 +110,7 @@ module Sisimai::Lhost
110
110
  # The mail system
111
111
  #
112
112
  # <userunknown@example.co.jp>: host mx.example.co.jp[192.0.2.153] said: 550
113
- # 5.1.1 <userunknown@example.co.jp>... User Unknown (in reply to RCPT TO
114
- # command)
113
+ # 5.1.1 <userunknown@example.co.jp>... User Unknown (in reply to RCPT TO command)
115
114
  if readslices[-2].start_with?('Diagnostic-Code:') && cv = e.match(/\A[ \t]+(.+)\z/)
116
115
  # Continued line of the value of Diagnostic-Code header
117
116
  v['diagnosis'] << ' ' << cv[1]
@@ -122,18 +121,12 @@ module Sisimai::Lhost
122
121
  emailsteak[1] << cv[1] << ': ' << cv[2] << "\n"
123
122
 
124
123
  else
125
- if cv = e.match(/[ \t][(]in reply to ([A-Z]{4}).*/)
124
+ if cv = e.match(/[ \t][(]in reply to (?:end of )?([A-Z]{4}).*/) ||
125
+ cv = e.match(/([A-Z]{4})[ \t]*.*command[)]\z/)
126
126
  # 5.1.1 <userunknown@example.co.jp>... User Unknown (in reply to RCPT TO
127
127
  commandset << cv[1]
128
128
  anotherset['diagnosis'] ||= ''
129
129
  anotherset['diagnosis'] << ' ' << e
130
-
131
- elsif cv = e.match(/([A-Z]{4})[ \t]*.*command[)]\z/)
132
- # to MAIL command)
133
- commandset << cv[1]
134
- anotherset['diagnosis'] ||= ''
135
- anotherset['diagnosis'] << ' ' << e
136
-
137
130
  else
138
131
  # Alternative error message and recipient
139
132
  if cv = e.match(/\A[<]([^ ]+[@][^ ]+)[>] [(]expanded from [<](.+)[>][)]:[ \t]*(.+)\z/)
@@ -23,29 +23,29 @@ module Sisimai::Lhost
23
23
  ReSMTP = {
24
24
  # Error text regular expressions which defined in qmail-remote.c
25
25
  # qmail-remote.c:225| if (smtpcode() != 220) quit("ZConnected to "," but greeting failed");
26
- 'conn' => %r/(?:Error:)?Connected to .+ but greeting failed[.]/,
26
+ 'conn' => %r/(?:Error:)?Connected to [^ ]+ but greeting failed[.]/,
27
27
  # qmail-remote.c:231| if (smtpcode() != 250) quit("ZConnected to "," but my name was rejected");
28
- 'ehlo' => %r/(?:Error:)?Connected to .+ but my name was rejected[.]/,
28
+ 'ehlo' => %r/(?:Error:)?Connected to [^ ]+ but my name was rejected[.]/,
29
29
  # qmail-remote.c:238| if (code >= 500) quit("DConnected to "," but sender was rejected");
30
30
  # reason = rejected
31
- 'mail' => %r/(?:Error:)?Connected to .+ but sender was rejected[.]/,
31
+ 'mail' => %r/(?:Error:)?Connected to [^ ]+ but sender was rejected[.]/,
32
32
  # qmail-remote.c:249| out("h"); outhost(); out(" does not like recipient.\n");
33
33
  # qmail-remote.c:253| out("s"); outhost(); out(" does not like recipient.\n");
34
34
  # reason = userunknown
35
- 'rcpt' => %r/(?:Error:)?.+ does not like recipient[.]/,
35
+ 'rcpt' => %r/(?:Error:)?[^ ]+ does not like recipient[.]/,
36
36
  # qmail-remote.c:265| if (code >= 500) quit("D"," failed on DATA command");
37
37
  # qmail-remote.c:266| if (code >= 400) quit("Z"," failed on DATA command");
38
38
  # qmail-remote.c:271| if (code >= 500) quit("D"," failed after I sent the message");
39
39
  # qmail-remote.c:272| if (code >= 400) quit("Z"," failed after I sent the message");
40
40
  'data' => %r{(?:
41
- (?:Error:)?.+[ ]failed[ ]on[ ]DATA[ ]command[.]
42
- |(?:Error:)?.+[ ]failed[ ]after[ ]I[ ]sent[ ]the[ ]message[.]
41
+ (?:Error:)?[^ ]+[ ]failed[ ]on[ ]DATA[ ]command[.]
42
+ |(?:Error:)?[^ ]+[ ]failed[ ]after[ ]I[ ]sent[ ]the[ ]message[.]
43
43
  )
44
44
  }x,
45
45
  }.freeze
46
46
  # qmail-remote.c:261| if (!flagbother) quit("DGiving up on ","");
47
47
  ReHost = %r{(?:
48
- Giving[ ]up[ ]on[ ](.+[0-9a-zA-Z])[.]?\z
48
+ Giving[ ]up[ ]on[ ]([^ ]+[0-9a-zA-Z])[.]?\z
49
49
  |Connected[ ]to[ ]([-0-9a-zA-Z.]+[0-9a-zA-Z])[ ]
50
50
  |remote[ ]host[ ]([-0-9a-zA-Z.]+[0-9a-zA-Z])[ ]said:
51
51
  )
@@ -86,7 +86,7 @@ module Sisimai::Lhost
86
86
  # Arrival-Date: 2012-12-31 23-59-59
87
87
  next unless cv = e.match(/\AArrival-Date: (\d{4})[-](\d{2})[-](\d{2}) (\d{2})[-](\d{2})[-](\d{2})\z/)
88
88
  o[1] << 'Thu, ' << cv[3] + ' '
89
- o[1] << Sisimai::DateTime.monthname(0)[cv[2].to_i - 1]
89
+ o[1] << Sisimai::DateTime.monthname(false)[cv[2].to_i - 1]
90
90
  o[1] << ' ' << cv[1] + ' ' << [cv[4], cv[5], cv[6]].join(':')
91
91
  o[1] << ' ' << Sisimai::DateTime.abbr2tz('CDT')
92
92
  else
@@ -124,7 +124,7 @@ module Sisimai::Lhost
124
124
  if e['status'] == '5.0.0' || e['status'] == '4.0.0'
125
125
  # Get the value of D.S.N. from the error message or the value of
126
126
  # Diagnostic-Code header.
127
- e['status'] = Sisimai::SMTP::Status.find(e['diagnosis']) || ''
127
+ e['status'] = Sisimai::SMTP::Status.find(e['diagnosis']) || e['status']
128
128
  end
129
129
 
130
130
  if e['action'] == 'expired'
@@ -184,7 +184,7 @@ module Sisimai::Lhost
184
184
 
185
185
  if anotherset['status']
186
186
  # Check alternative status code
187
- if e['status'].empty? || e['status'] !~ /\A[45][.]\d[.]\d\z/
187
+ if e['status'].empty? || e['status'] !~ /\A[45][.]\d[.]\d{1,3}\z/
188
188
  # Override alternative status code
189
189
  e['status'] = anotherset['status']
190
190
  end
@@ -44,8 +44,8 @@ module Sisimai::Lhost
44
44
  # The attempted recipient address does not exist.
45
45
  'userunknown' => ['550 - Requested action not taken: no such user here'],
46
46
  }
47
- boundary00 = Sisimai::MIME.boundary(mhead['content-type']) || ''
48
- rebackbone = Regexp.new('^' << Regexp.escape('--' << boundary00 << '--')) unless boundary00.empty?
47
+ boundary00 = Sisimai::MIME.boundary(mhead['content-type'], 1) || ''
48
+ rebackbone = Regexp.new('^' << Regexp.escape(boundary00)) unless boundary00.empty?
49
49
  emailsteak = Sisimai::RFC5322.fillet(mbody, rebackbone)
50
50
  bodyslices = emailsteak[0].split("\n")
51
51
 
@@ -93,8 +93,8 @@ module Sisimai::Lhost
93
93
  # vzwpix.com
94
94
  startingof = { message: ['Message could not be delivered to mobile'] }
95
95
  messagesof = { 'userunknown' => ['No valid recipients for this MM'] }
96
- boundary00 = Sisimai::MIME.boundary(mhead['content-type'])
97
- rebackbone = Regexp.new('^' << Regexp.escape('--' << boundary00 << '--')) unless boundary00.empty?
96
+ boundary00 = Sisimai::MIME.boundary(mhead['content-type'], 1)
97
+ rebackbone = Regexp.new('^' << Regexp.escape(boundary00)) unless boundary00.empty?
98
98
  emailsteak = Sisimai::RFC5322.fillet(mbody, rebackbone)
99
99
  bodyslices = emailsteak[0].split("\n")
100
100
 
@@ -73,6 +73,10 @@ module Sisimai::Lhost
73
73
  elsif cv = e.match(/\ARouting: (.+)/)
74
74
  # Routing: Could not find a gateway for kijitora@example.co.jp
75
75
  v['diagnosis'] = cv[1]
76
+
77
+ elsif cv = e.match(/\ADiagnostic-Code: smtp; (.+)/)
78
+ # Diagnostic-Code: smtp; 552 5.2.2 Over quota
79
+ v['diagnosis'] = cv[1]
76
80
  end
77
81
  end
78
82
  end
@@ -19,7 +19,7 @@ module Sisimai::Lhost
19
19
  # Characters: K,Z,D in qmail-qmqpc.c, qmail-send.c, qmail-rspawn.c
20
20
  # K = success, Z = temporary error, D = permanent error
21
21
  message: %r{\A(?>
22
- He/Her[ ]is[ ]not.+[ ]user
22
+ He/Her[ ]is[ ]not[ ].+[ ]user
23
23
  |Hi[.][ ].+[ ]unable[ ]to[ ]deliver[ ]your[ ]message[ ]to[ ]
24
24
  the[ ]following[ ]addresses
25
25
  |Su[ ]mensaje[ ]no[ ]pudo[ ]ser[ ]entregado
@@ -41,29 +41,29 @@ module Sisimai::Lhost
41
41
  ReSMTP = {
42
42
  # Error text regular expressions which defined in qmail-remote.c
43
43
  # qmail-remote.c:225| if (smtpcode() != 220) quit("ZConnected to "," but greeting failed");
44
- 'conn' => %r/(?:Error:)?Connected to .+ but greeting failed[.]/,
44
+ 'conn' => %r/(?:Error:)?Connected to [^ ]+ but greeting failed[.]/,
45
45
  # qmail-remote.c:231| if (smtpcode() != 250) quit("ZConnected to "," but my name was rejected");
46
- 'ehlo' => %r/(?:Error:)?Connected to .+ but my name was rejected[.]/,
46
+ 'ehlo' => %r/(?:Error:)?Connected to [^ ]+ but my name was rejected[.]/,
47
47
  # qmail-remote.c:238| if (code >= 500) quit("DConnected to "," but sender was rejected");
48
48
  # reason = rejected
49
- 'mail' => %r/(?:Error:)?Connected to .+ but sender was rejected[.]/,
49
+ 'mail' => %r/(?:Error:)?Connected to [^ ]+ but sender was rejected[.]/,
50
50
  # qmail-remote.c:249| out("h"); outhost(); out(" does not like recipient.\n");
51
51
  # qmail-remote.c:253| out("s"); outhost(); out(" does not like recipient.\n");
52
52
  # reason = userunknown
53
- 'rcpt' => %r/(?:Error:)?.+ does not like recipient[.]/,
53
+ 'rcpt' => %r/(?:Error:)?[^ ]+ does not like recipient[.]/,
54
54
  # qmail-remote.c:265| if (code >= 500) quit("D"," failed on DATA command");
55
55
  # qmail-remote.c:266| if (code >= 400) quit("Z"," failed on DATA command");
56
56
  # qmail-remote.c:271| if (code >= 500) quit("D"," failed after I sent the message");
57
57
  # qmail-remote.c:272| if (code >= 400) quit("Z"," failed after I sent the message");
58
58
  'data' => %r{(?:
59
- (?:Error:)?.+[ ]failed[ ]on[ ]DATA[ ]command[.]
60
- |(?:Error:)?.+[ ]failed[ ]after[ ]I[ ]sent[ ]the[ ]message[.]
59
+ (?:Error:)?[^ ]+[ ]failed[ ]on[ ]DATA[ ]command[.]
60
+ |(?:Error:)?[^ ]+[ ]failed[ ]after[ ]I[ ]sent[ ]the[ ]message[.]
61
61
  )
62
62
  }x,
63
63
  }.freeze
64
64
  # qmail-remote.c:261| if (!flagbother) quit("DGiving up on ","");
65
65
  ReHost = %r{(?:
66
- Giving[ ]up[ ]on[ ](.+[0-9a-zA-Z])[.]?\z
66
+ Giving[ ]up[ ]on[ ]([^ ]+[0-9a-zA-Z])[.]?\z
67
67
  |Connected[ ]to[ ]([-0-9a-zA-Z.]+[0-9a-zA-Z])[ ]
68
68
  |remote[ ]host[ ]([-0-9a-zA-Z.]+[0-9a-zA-Z])[ ]said:
69
69
  )
data/lib/sisimai/mail.rb CHANGED
@@ -4,7 +4,6 @@ module Sisimai
4
4
  # Sisimai::Mail::Memory classes.
5
5
  class Mail
6
6
  # Imported from p5-Sisimail/lib/Sisimai/Mail.pm
7
- Until = 'v4.25.10'
8
7
 
9
8
  # :path [String] path to mbox or Maildir/
10
9
  # :kind [String] Data type: mailbox, maildir, or stdin
@@ -25,7 +24,7 @@ module Sisimai
25
24
  # Sisimai::Mail.new('<STDIN>')
26
25
  classname = self.class.to_s << '::STDIN'
27
26
  parameter['kind'] = 'stdin'
28
- parameter['path'] = $stdin
27
+ parameter['path'] = '<STDIN>'
29
28
  else
30
29
  # The argumenet is a mailbox or a Maildir/.
31
30
  mediatype = argv1.include?("\n") ? 'memory' : File.ftype(argv1)
@@ -52,6 +51,7 @@ module Sisimai
52
51
  # The argument neither a mailbox nor a Maildir/.
53
52
  classname = self.class.to_s << '::STDIN'
54
53
  parameter['kind'] = 'stdin'
54
+ parameter['path'] = '<STDIN>'
55
55
  end
56
56
  return nil unless classname
57
57
 
@@ -64,16 +64,6 @@ module Sisimai
64
64
  @data = parameter['data']
65
65
  end
66
66
 
67
- def mail
68
- warn " ***warning: Sisimai::Mail.mail will be removed at #{Until}. Use Sisimai::Mail.data instead"
69
- return data
70
- end
71
-
72
- def type
73
- warn " ***warning: Sisimai::Mail.type will be removed at #{Until}. Use Sisimai::Mail.kind instead"
74
- return kind
75
- end
76
-
77
67
  # Alias method of Sisimai::Mail.data.read()
78
68
  # @return [String] Contents of mbox/Maildir
79
69
  def read
@@ -81,15 +71,6 @@ module Sisimai
81
71
  return data.read
82
72
  end
83
73
 
84
- # Close the handle
85
- # @return [True,False] true: Successfully closed the handle
86
- # false: Mail handle is not defined
87
- def close
88
- warn " ***warning: Sisimai::Mail.close will be removed at #{Until}. The handle automatically closes at the EOF"
89
- return false unless data.handle
90
- data.handle = nil
91
- return true
92
- end
93
74
  end
94
75
  end
95
76
 
data/lib/sisimai/mda.rb CHANGED
@@ -7,7 +7,7 @@ module Sisimai
7
7
  # dovecot/src/deliver/deliver.c
8
8
  # 11: #define DEFAULT_MAIL_REJECTION_HUMAN_REASON \
9
9
  # 12: "Your message to <%t> was automatically rejected:%n%r"
10
- 'dovecot' => %r/\AYour message to .+ was automatically rejected:\z/,
10
+ 'dovecot' => %r/\AYour message to [^ ]+ was automatically rejected:\z/,
11
11
  'mail.local' => %r/\Amail[.]local: /,
12
12
  'procmail' => %r/\Aprocmail: /,
13
13
  'maildrop' => %r/\Amaildrop: /,
@@ -16,7 +16,7 @@ module Sisimai
16
16
  }.freeze
17
17
  MarkingsOf = {
18
18
  message: %r{\A(?>
19
- Your[ ]message[ ]to[ ].+[ ]was[ ]automatically[ ]rejected:\z
19
+ Your[ ]message[ ]to[ ][^ ]+[ ]was[ ]automatically[ ]rejected:\z
20
20
  |(?:mail[.]local|procmail|maildrop|vdelivermail|vdeliver):[ ]
21
21
  )
22
22
  }x
data/lib/sisimai/mime.rb CHANGED
@@ -225,7 +225,7 @@ module Sisimai
225
225
 
226
226
  plain = nil
227
227
  if cv = argv1.match(%r|([+/\=0-9A-Za-z\r\n]+)|) then plain = Base64.decode64(cv[1]) end
228
- return plain.force_encoding('UTF-8')
228
+ return plain.scrub('?')
229
229
  end
230
230
 
231
231
  # Get boundary string
@@ -10,8 +10,10 @@ module Sisimai
10
10
  # Imported from p5-Sisimail/lib/Sisimai/Reason/Blocked.pm
11
11
  class << self
12
12
  Regex = %r{(?>
13
- access[ ]denied[.][ ]ip[ ]name[ ]lookup[ ]failed
14
- |access[ ]from[ ]ip[ ]address[ ].+[ ]blocked
13
+ [ ]said:[ ]550[ ]blocked
14
+ |[(][^ ]+[@][^ ]+:blocked[)]
15
+ |access[ ]denied[.][ ]ip[ ]name[ ]lookup[ ]failed
16
+ |access[ ]from[ ]ip[ ]address[ ][^ ]+[ ]blocked
15
17
  |all[ ]mail[ ]servers[ ]must[ ]have[ ]a[ ]ptr[ ]record[ ]with[ ]a[ ]valid[ ]reverse[ ]dns[ ]entry
16
18
  |bad[ ](:?dns[ ]ptr[ ]resource[ ]record|sender[ ]ip[ ]address)
17
19
  |banned[ ]sending[ ]ip # Office365
@@ -24,7 +26,7 @@ module Sisimai
24
26
  |resolve[ ]your[ ]address
25
27
  )
26
28
  |client[ ]host[ ](?:
27
- .+[ ]blocked[ ]using
29
+ [^ ]+[ ]blocked[ ]using
28
30
  |rejected:[ ](?:
29
31
  abus[ ]detecte[ ]gu_eib_0[24] # SFR
30
32
  |cannot[ ]find[ ]your[ ]hostname # Yahoo!
@@ -41,22 +43,24 @@ module Sisimai
41
43
  )
42
44
  |connections[ ](?:
43
45
  not[ ]accepted[ ]from[ ]ip[ ]addresses[ ]on[ ]spamhaus[ ]xbl
44
- |will[ ]not[ ]be[ ]accepted[ ]from[ ].+because[ ]the[ ]ip[ ]is[ ]in[ ]spamhaus's[ ]list
46
+ |will[ ]not[ ]be[ ]accepted[ ]from[ ][^ ]+,[ ]because[ ]the[ ]ip[ ]is[ ]in[ ]spamhaus's[ ]list
45
47
  )
46
48
  |currently[ ]sending[ ]spam[ ]see:[ ]
47
49
  |domain[ ](?:
48
- .+[ ]mismatches[ ]client[ ]ip
50
+ [^ ]+[ ]mismatches[ ]client[ ]ip
49
51
  |does[ ]not[ ]exist:
50
52
  )
51
- |dns[ ]lookup[ ]failure:[ ].+[ ]try[ ]again[ ]later
53
+ |dns[ ]lookup[ ]failure:[ ][^ ]+[ ]try[ ]again[ ]later
52
54
  |dnsbl:attrbl
53
55
  |dynamic/zombied/spam[ ]ips[ ]blocked
54
- |email[ ]blocked[ ]by[ ](?:.+[.]barracudacentral[.]org|spamhaus)
56
+ |email[ ]blocked[ ]by[ ](?:[^ ]+[.]barracudacentral[.]org|spamhaus)
57
+ |error:[ ]no[ ]valid[ ]recipients[ ]from[ ]
55
58
  |esmtp[ ]not[ ]accepting[ ]connections # icloud.com
56
- |fix[ ]reverse[ ]dns[ ]for[ ].+
59
+ |fix[ ]reverse[ ]dns[ ]for[ ][^ ]+
57
60
  |go[ ]away
58
61
  |helo[ ]command[ ]rejected:
59
- |host[ ].+[ ]refused[ ]to[ ]talk[ ]to[ ]me:[ ]\d+[ ]blocked
62
+ |host[ ]+[^ ]refused[ ]to[ ]talk[ ]to[ ]me:[ ]\d+[ ]blocked
63
+ |host[ ]network[ ]not[ ]allowed
60
64
  |hosts[ ]with[ ]dynamic[ ]ip
61
65
  |http://(?:
62
66
  spf[.]pobox[.]com/why[.]html
@@ -66,17 +70,18 @@ module Sisimai
66
70
  |ip[ ]\d{1,3}[.]\d{1,3}[.]\d{1,3}[.]\d{1,3}[ ]is[ ]blocked[ ]by[ ]EarthLink # Earthlink
67
71
  |ip[/]domain[ ]reputation[ ]problems
68
72
  |is[ ](?:
69
- in[ ]a[ ]black[ ]list[ ]at[ ].+[.]
70
- |in[ ]an[ ].*rbl[ ]on[ ].+
73
+ in[ ]a[ ]black[ ]list(?:[ ]at[ ][^ ]+[.])?
74
+ |in[ ]an[ ][^ ]+rbl[ ]on[ ][^ ]+
71
75
  |not[ ]allowed[ ]to[ ]send[ ](?:
72
76
  mail[ ]from
73
- |from[ ].+[ ]per[ ]it's[ ]spf[ ]record
77
+ |from[ ][<][^ ]+[>][ ]per[ ]it's[ ]spf[ ]record
74
78
  )
75
79
  )
76
- |mail[ ]server[ ]at[ ].+[ ]is[ ]blocked
80
+ |mail[ ]server[ ]at[ ][^ ]+[ ]is[ ]blocked
77
81
  |mail[ ]from[ ]\d+[.]\d+[.]\d+[.]\d[ ]refused:
78
- |message[ ]from[ ].+[ ]rejected[ ]based[ ]on[ ]blacklist
79
- |messages[ ]from[ ].+[ ]temporarily[ ]deferred[ ]due[ ]to[ ]user[ ]complaints # Yahoo!
82
+ |message[ ]from[ ][^ ]+[ ]rejected[ ]based[ ]on[ ]blacklist
83
+ |message[ ]was[ ]rejected[ ]for[ ]possible[ ]spam/virus[ ]content
84
+ |messages[ ]from[ ][^ ]+[ ]temporarily[ ]deferred[ ]due[ ]to[ ]user[ ]complaints # Yahoo!
80
85
  |no[ ](?:
81
86
  access[ ]from[ ]mail[ ]server
82
87
  |ptr[ ]record[ ]found[.]
@@ -89,21 +94,26 @@ module Sisimai
89
94
  |use[ ]the[ ]smtp[ ]server[ ]of[ ]your[ ]isp
90
95
  )
91
96
  |ptr[ ]record[ ]setup
97
+ |rejected[ ]because[ ]the[ ]sending[ ]mta[ ]or[ ]the[ ]sender[ ]has[ ]not[ ]passed[ ]validation
98
+ |rejected[ ]due[ ]to[ ](?:
99
+ a[ ]poor[ ]email[ ]reputation[ ]score
100
+ |the[ ]sending[ ]mta's[ ]poor[ ]reputation
101
+ )
92
102
  |rejecting[ ]open[ ]proxy # Sendmail(srvrsmtp.c)
93
103
  |reverse[ ]dns[ ](?:
94
104
  failed
95
105
  |required
96
- |lookup[ ]for[ ]host[ ].+[ ]failed[ ]permanently
106
+ |lookup[ ]for[ ]host[ ][^ ]+[ ]failed[ ]permanently
97
107
  )
98
108
  |sender[ ]ip[ ](?:
99
109
  address[ ]rejected
100
110
  |reverse[ ]lookup[ ]rejected
101
111
  )
102
112
  |server[ ]access[ ](?:
103
- .+[ ]forbidden[ ]by[ ]invalid[ ]rdns[ ]record[ ]of[ ]your[ ]mail[ ]server
113
+ [^ ]+[ ]forbidden[ ]by[ ]invalid[ ]rdns[ ]record[ ]of[ ]your[ ]mail[ ]server
104
114
  |forbidden[ ]by[ ]your[ ]ip[ ]
105
115
  )
106
- |server[ ]ip[ ].+[ ]listed[ ]as[ ]abusive
116
+ |server[ ]ip[ ][^ ]+[ ]listed[ ]as[ ]abusive
107
117
  |service[ ]not[ ]available,[ ]closing[ ]transmission[ ]channel
108
118
  |service[ ]permits[ ]\d+[ ]unverifyable[ ]sending[ ]ips
109
119
  |smtp[ ]error[ ]from[ ]remote[ ]mail[ ]server[ ]after[ ]initial[ ]connection: # Exim
@@ -112,25 +122,27 @@ module Sisimai
112
122
  |your[ ]remotehost[ ]looks[ ]suspiciously[ ]like[ ]spammer
113
123
  )
114
124
  |spf[ ](?:
115
- .+[ ]domain[ ]authentication[ ]fail
125
+ [(]sender[ ]policy[ ]framework[)][ ]domain[ ]authentication[ ]fail
116
126
  |record
117
127
  |check:[ ]fail
118
128
  )
119
- |spf:[ ].+[ ]is[ ]not[ ]allowed[ ]to[ ]send[ ]mail.+[a-z]{3}.+401
120
- |the[ ](?:email|domain|ip).+[ ]is[ ]blacklisted
129
+ |spf:[ ][^ ]+[ ]is[ ]not[ ]allowed[ ]to[ ]send[ ]mail[.][ ][a-z0-9]_401
130
+ |temporarily[ ]deferred[ ]due[ ]to[ ]unexpected[ ]volume[ ]or[ ]user[ ]complaints
131
+ |the[ ](?:email|domain|ip)[ ][^ ]+[ ]is[ ]blacklisted
121
132
  |this[ ]system[ ]will[ ]not[ ]accept[ ]messages[ ]from[ ]servers[/]devices[ ]with[ ]no[ ]reverse[ ]dns
133
+ |to[ ]submit[ ]messages[ ]to[ ]this[ ]e-mail[ ]system[ ]has[ ]been[ ]rejected
122
134
  |too[ ]many[ ](?:
123
135
  spams[ ]from[ ]your[ ]ip # free.fr
124
136
  |unwanted[ ]messages[ ]have[ ]been[ ]sent[ ]from[ ]the[ ]following[ ]ip[ ]address[ ]above
125
137
  )
126
138
  |unresolvable[ ]relay[ ]host[ ]name
127
- |veuillez[ ]essayer[ ]plus[ ]tard.+[a-z]{3}.+(?:103|510)
139
+ |veuillez[ ]essayer[ ]plus[ ]tard[.][ ]service[ ]refused,[ ]please[ ]try[ ]later[.][ ][0-9a-z_]+(?:103|510)
128
140
  |your[ ](?:
129
141
  network[ ]is[ ]temporary[ ]blacklisted
130
- |sender's[ ]ip[ ]address[ ]is[ ]listed[ ]at[ ].+[.]abuseat[.]org
142
+ |sender's[ ]ip[ ]address[ ]is[ ]listed[ ]at[ ][^ ]+[.]abuseat[.]org
131
143
  |server[ ]requires[ ]confirmation
132
144
  )
133
- |was[ ]blocked[ ]by[ ].+
145
+ |was[ ]blocked[ ]by[ ][^ ]+
134
146
  |we[ ]do[ ]not[ ]accept[ ]mail[ ]from[ ](?: # @mail.ru
135
147
  dynamic[ ]ips
136
148
  |hosts[ ]with[ ]dynamic[ ]ip[ ]or[ ]generic[ ]dns[ ]ptr-records
@@ -140,8 +152,10 @@ module Sisimai
140
152
  |sending[ ]spam
141
153
  )
142
154
  |your[ ](?:
143
- access[ ]to[ ]submit[ ]messages[ ]to[ ]this[ ]e-mail[ ]system[ ]has[ ]been[ ]rejected
144
- |message[ ]was[ ]rejected[ ]for[ ]possible[ ]spam/virus[ ]content
155
+ email[ ]address[ ]has[ ]been[ ]blacklisted
156
+ |network[ ]is[ ]temporary[ ]blacklisted
157
+ |sender's[ ]ip[ ]address[ ]is[ ]listed[ ]at[ ][^ ]+[.]abuseat[.]org
158
+ |server[ ]requires[ ]confirmation
145
159
  )
146
160
  )
147
161
  }x
@@ -9,7 +9,10 @@ module Sisimai
9
9
  module ExceedLimit
10
10
  # Imported from p5-Sisimail/lib/Sisimai/Reason/ExceedLimit.pm
11
11
  class << self
12
- Index = ['message too large']
12
+ Index = [
13
+ 'message header size exceeds limit',
14
+ 'message too large',
15
+ ]
13
16
 
14
17
  def text; return 'exceedlimit'; end
15
18
  def description; return 'Email rejected due to an email exceeded the limit'; end
@@ -12,9 +12,11 @@ module Sisimai
12
12
  Index = [
13
13
  'connection timed out',
14
14
  'could not find a gateway for',
15
+ 'delivery attempts will continue to be',
15
16
  'delivery time expired',
16
17
  'failed to deliver to domain ',
17
18
  'giving up on',
19
+ 'have been failing for a long time',
18
20
  'has been delayed',
19
21
  'it has not been collected after',
20
22
  'message expired after sitting in queue for',
@@ -18,6 +18,7 @@ module Sisimai
18
18
  'due to extended inactivity new mail is not currently being accepted for this mailbox',
19
19
  'has restricted sms e-mail', # AT&T
20
20
  'is not accepting any mail',
21
+ 'message rejected due to user rules',
21
22
  'refused due to recipient preferences', # Facebook
22
23
  'resolver.rst.notauthorized', # Microsoft Exchange
23
24
  'this account is protected by',
@@ -40,7 +41,7 @@ module Sisimai
40
41
  return false
41
42
  end
42
43
 
43
- # Rejected by domain or address filter ?
44
+ # Rejected by a sender domain or a sender address by a filter ?
44
45
  # @param [Sisimai::Data] argvs Object to be detected the reason
45
46
  # @return [True,False] true: is filtered
46
47
  # false: is not filtered
@@ -52,18 +53,18 @@ module Sisimai
52
53
  tempreason = Sisimai::SMTP::Status.name(argvs.deliverystatus) || ''
53
54
  return false if tempreason == 'suspend'
54
55
 
55
- commandtxt = argvs.smtpcommand || ''
56
56
  diagnostic = argvs.diagnosticcode.downcase || ''
57
- alterclass = Sisimai::Reason::UserUnknown
58
-
59
57
  if tempreason == 'filtered'
60
58
  # Delivery status code points "filtered".
61
- return true if alterclass.match(diagnostic) || match(diagnostic)
62
-
63
- elsif commandtxt != 'RCPT' && commandtxt != 'MAIL'
64
- # Check the value of Diagnostic-Code and the last SMTP command
59
+ return true if Sisimai::Reason::UserUnknown.match(diagnostic)
65
60
  return true if match(diagnostic)
66
- return true if alterclass.match(diagnostic)
61
+ else
62
+ # The value of "reason" isn't "filtered" when the value of "smtpcommand" is an SMTP
63
+ # command to be sent before the SMTP DATA command because all the MTAs read the headers
64
+ # and the entire message body after the DATA command.
65
+ return false if %w[CONN EHLO HELO MAIL RCPT].include?(argvs.smtpcommand)
66
+ return true if match(diagnostic)
67
+ return true if Sisimai::Reason::UserUnknown.match(diagnostic)
67
68
  end
68
69
  return false
69
70
  end
@@ -22,8 +22,10 @@ module Sisimai
22
22
  'recipient domain must exist',
23
23
  'the account or domain may not exist',
24
24
  'unknown host',
25
+ 'unroutable address',
25
26
  'unrouteable address',
26
27
  ]
28
+ Regex = %r/553[ ][^ ]+[ ]does[ ]not[ ]exist/
27
29
 
28
30
  def text; return 'hostunknown'; end
29
31
  def description; return "Delivery failed due to a domain part of a recipient's email address does not exist"; end
@@ -36,6 +38,7 @@ module Sisimai
36
38
  def match(argv1)
37
39
  return nil unless argv1
38
40
  return true if Index.any? { |a| argv1.include?(a) }
41
+ return true if argv1 =~ Regex
39
42
  return false
40
43
  end
41
44
 
@@ -21,7 +21,7 @@ module Sisimai
21
21
  )
22
22
  |exit[ ]\d+
23
23
  |mailer[ ]error
24
- |pipe[ ]to[ ][|][/].+
24
+ |pipe[ ]to[ ][|][/][^ ]+
25
25
  |x[-]unix[;][ ]\d+ # X-UNIX; 127
26
26
  )
27
27
  }x
@@ -16,16 +16,21 @@ module Sisimai
16
16
  Index = [
17
17
  'as a relay',
18
18
  'insecure mail relay',
19
+ 'is not permitted to relay through this server without authentication',
19
20
  'mail server requires authentication when attempting to send to a non-local e-mail address', # MailEnable
21
+ 'not a gateway',
20
22
  'not allowed to relay through this machine',
21
23
  'not an open relay, so get lost',
24
+ 'not local host',
22
25
  'relay access denied',
23
26
  'relay denied',
24
27
  'relay not permitted',
25
28
  'relaying denied', # Sendmail
29
+ 'relaying mail to ',
26
30
  "that domain isn't in my list of allowed rcpthost",
27
31
  'this system is not configured to relay mail',
28
32
  'unable to relay for',
33
+ "we don't handle mail for",
29
34
  ]
30
35
 
31
36
  def text; return 'norelaying'; end
@@ -48,13 +53,9 @@ module Sisimai
48
53
  # @see http://www.ietf.org/rfc/rfc2822.txt
49
54
  def true(argvs)
50
55
  r = argvs.reason || ''
51
- if r.size > 0
52
- # Do not overwrite the reason
53
- return false if r.start_with?('securityerror', 'systemerror', 'undefined')
54
- else
55
- # Check the value of Diagnosic-Code: header with patterns
56
- return true if match(argvs.diagnosticcode.downcase)
57
- end
56
+ return false if r.start_with?('securityerror', 'systemerror', 'undefined')
57
+ return false if %w[CONN EHLO HELO].include?(argvs.smtpcommand)
58
+ return true if match(argvs.diagnosticcode.downcase)
58
59
  return false
59
60
  end
60
61
 
@@ -14,8 +14,10 @@ module Sisimai
14
14
  # Destination mail server does not accept any message
15
15
  Index = [
16
16
  'host/domain does not accept mail', # iCloud
17
+ 'host does not accept mail', # Sendmail
17
18
  'name server: .: host not found', # Sendmail
18
19
  'no mx record found for domain=', # Oath(Yahoo!)
20
+ 'no route for current request',
19
21
  'smtp protocol returned a permanent error',
20
22
  ]
21
23
 
@@ -41,9 +43,9 @@ module Sisimai
41
43
  return true if argvs.reason == 'notaccept'
42
44
 
43
45
  # SMTP Reply Code is 554 or 556
44
- return true if [521, 554, 556].index(argvs.replycode.to_i)
45
- return false if argvs.smtpcommand == 'MAIL'
46
- return true if match(argvs.diagnosticcode.downcase)
46
+ return true if [521, 554, 556].index(argvs.replycode.to_i)
47
+ return false if argvs.smtpcommand != 'MAIL'
48
+ return true if match(argvs.diagnosticcode.downcase)
47
49
  return false
48
50
  end
49
51
 
@@ -19,14 +19,17 @@ module Sisimai
19
19
  Index = [
20
20
  'an illegal attachment on your message',
21
21
  'because the recipient is not accepting mail with ', # AOL Phoenix
22
+ 'by non-member to a members-only list',
22
23
  'closed mailing list',
23
24
  'denied by policy',
25
+ 'dmarc policy',
24
26
  'email not accepted for policy reasons',
25
27
  # http://kb.mimecast.com/Mimecast_Knowledge_Base/Administration_Console/Monitoring/Mimecast_SMTP_Error_Codes#554
26
28
  'email rejected due to security policies',
27
29
  'header are not accepted',
28
30
  'header error',
29
31
  'local policy violation',
32
+ 'message bounced due to organizational settings',
30
33
  'message given low priority',
31
34
  'message not accepted for policy reasons',
32
35
  'messages with multiple addresses',
@@ -34,6 +37,7 @@ module Sisimai
34
37
  'protocol violation',
35
38
  'the email address used to send your message is not subscribed to this group',
36
39
  'this message was blocked because its content presents a potential',
40
+ 'we do not accept messages containing images or other attachments',
37
41
  'you have exceeded the allowable number of posts without solving a captcha',
38
42
  'you have exceeded the the allowable number of posts without solving a captcha',
39
43
  ]
@@ -52,7 +56,7 @@ module Sisimai
52
56
  return false
53
57
  end
54
58
 
55
- # The bounce reason is security error or not
59
+ # The bounce reason is "policyviolation" or not
56
60
  # @param [Sisimai::Data] argvs Object to be detected the reason
57
61
  # @return [True,False] true: is policy violation
58
62
  # false: is not policy violation