sisimai 5.0.3 → 5.2.0

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 (258) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/codecovio.yml +3 -1
  3. data/.github/workflows/rake-test.yml +7 -3
  4. data/ChangeLog.md +136 -0
  5. data/Makefile +4 -2
  6. data/README-JA.md +32 -22
  7. data/README.md +31 -21
  8. data/lib/sisimai/arf.rb +124 -213
  9. data/lib/sisimai/fact/json.rb +2 -2
  10. data/lib/sisimai/fact/yaml.rb +2 -2
  11. data/lib/sisimai/fact.rb +208 -173
  12. data/lib/sisimai/lda.rb +98 -0
  13. data/lib/sisimai/lhost/activehunter.rb +5 -4
  14. data/lib/sisimai/lhost/amazonses.rb +189 -305
  15. data/lib/sisimai/lhost/apachejames.rb +52 -55
  16. data/lib/sisimai/lhost/biglobe.rb +5 -6
  17. data/lib/sisimai/lhost/courier.rb +14 -12
  18. data/lib/sisimai/lhost/domino.rb +29 -29
  19. data/lib/sisimai/lhost/dragonfly.rb +113 -0
  20. data/lib/sisimai/lhost/einsundeins.rb +7 -8
  21. data/lib/sisimai/lhost/exchange2003.rb +10 -11
  22. data/lib/sisimai/lhost/exchange2007.rb +115 -104
  23. data/lib/sisimai/lhost/exim.rb +236 -246
  24. data/lib/sisimai/lhost/ezweb.rb +47 -55
  25. data/lib/sisimai/lhost/fml.rb +6 -7
  26. data/lib/sisimai/lhost/gmail.rb +36 -32
  27. data/lib/sisimai/lhost/gmx.rb +8 -20
  28. data/lib/sisimai/lhost/googlegroups.rb +13 -12
  29. data/lib/sisimai/lhost/googleworkspace.rb +94 -0
  30. data/lib/sisimai/lhost/imailserver.rb +11 -19
  31. data/lib/sisimai/lhost/interscanmss.rb +6 -5
  32. data/lib/sisimai/lhost/kddi.rb +7 -8
  33. data/lib/sisimai/lhost/mailfoundry.rb +6 -9
  34. data/lib/sisimai/lhost/mailmarshalsmtp.rb +6 -6
  35. data/lib/sisimai/lhost/messagingserver.rb +19 -17
  36. data/lib/sisimai/lhost/mfilter.rb +8 -7
  37. data/lib/sisimai/lhost/notes.rb +6 -8
  38. data/lib/sisimai/lhost/opensmtpd.rb +11 -9
  39. data/lib/sisimai/lhost/postfix.rb +29 -31
  40. data/lib/sisimai/lhost/qmail.rb +136 -112
  41. data/lib/sisimai/lhost/sendmail.rb +23 -22
  42. data/lib/sisimai/lhost/v5sendmail.rb +93 -64
  43. data/lib/sisimai/lhost/verizon.rb +6 -6
  44. data/lib/sisimai/lhost/x1.rb +4 -4
  45. data/lib/sisimai/lhost/x2.rb +4 -5
  46. data/lib/sisimai/lhost/x3.rb +5 -5
  47. data/lib/sisimai/lhost/x6.rb +4 -4
  48. data/lib/sisimai/lhost/zoho.rb +6 -6
  49. data/lib/sisimai/lhost.rb +21 -24
  50. data/lib/sisimai/mail/maildir.rb +1 -1
  51. data/lib/sisimai/mail/stdin.rb +1 -1
  52. data/lib/sisimai/message.rb +100 -153
  53. data/lib/sisimai/order.rb +22 -77
  54. data/lib/sisimai/reason/authfailure.rb +1 -4
  55. data/lib/sisimai/reason/badreputation.rb +3 -3
  56. data/lib/sisimai/reason/blocked.rb +7 -10
  57. data/lib/sisimai/reason/contenterror.rb +7 -1
  58. data/lib/sisimai/reason/exceedlimit.rb +1 -4
  59. data/lib/sisimai/reason/failedstarttls.rb +42 -0
  60. data/lib/sisimai/reason/filtered.rb +5 -4
  61. data/lib/sisimai/reason/hasmoved.rb +1 -2
  62. data/lib/sisimai/reason/hostunknown.rb +3 -3
  63. data/lib/sisimai/reason/mailboxfull.rb +2 -4
  64. data/lib/sisimai/reason/mailererror.rb +1 -2
  65. data/lib/sisimai/reason/mesgtoobig.rb +2 -4
  66. data/lib/sisimai/reason/norelaying.rb +3 -3
  67. data/lib/sisimai/reason/notaccept.rb +2 -3
  68. data/lib/sisimai/reason/notcompliantrfc.rb +10 -4
  69. data/lib/sisimai/reason/rejected.rb +2 -1
  70. data/lib/sisimai/reason/requireptr.rb +2 -2
  71. data/lib/sisimai/reason/securityerror.rb +1 -3
  72. data/lib/sisimai/reason/spamdetected.rb +6 -8
  73. data/lib/sisimai/reason/speeding.rb +1 -2
  74. data/lib/sisimai/reason/suppressed.rb +36 -0
  75. data/lib/sisimai/reason/suspend.rb +1 -3
  76. data/lib/sisimai/reason/systemerror.rb +5 -0
  77. data/lib/sisimai/reason/toomanyconn.rb +1 -2
  78. data/lib/sisimai/reason/userunknown.rb +1 -1
  79. data/lib/sisimai/reason/virusdetected.rb +5 -6
  80. data/lib/sisimai/reason.rb +82 -78
  81. data/lib/sisimai/rfc1123.rb +152 -0
  82. data/lib/sisimai/rfc1894.rb +102 -62
  83. data/lib/sisimai/rfc2045.rb +2 -1
  84. data/lib/sisimai/rfc3464/thirdparty.rb +102 -0
  85. data/lib/sisimai/rfc3464.rb +224 -345
  86. data/lib/sisimai/rfc3834.rb +3 -3
  87. data/lib/sisimai/rfc5322.rb +7 -17
  88. data/lib/sisimai/rfc791.rb +69 -0
  89. data/lib/sisimai/rhost/aol.rb +36 -0
  90. data/lib/sisimai/rhost/apple.rb +95 -0
  91. data/lib/sisimai/rhost/cox.rb +84 -34
  92. data/lib/sisimai/rhost/facebook.rb +100 -0
  93. data/lib/sisimai/rhost/franceptt.rb +87 -83
  94. data/lib/sisimai/rhost/godaddy.rb +208 -45
  95. data/lib/sisimai/rhost/google.rb +22 -22
  96. data/lib/sisimai/rhost/gsuite.rb +42 -0
  97. data/lib/sisimai/rhost/iua.rb +5 -5
  98. data/lib/sisimai/rhost/kddi.rb +9 -7
  99. data/lib/sisimai/rhost/messagelabs.rb +37 -0
  100. data/lib/sisimai/rhost/microsoft.rb +60 -54
  101. data/lib/sisimai/rhost/mimecast.rb +44 -31
  102. data/lib/sisimai/rhost/nttdocomo.rb +5 -4
  103. data/lib/sisimai/rhost/outlook.rb +36 -0
  104. data/lib/sisimai/rhost/spectrum.rb +102 -41
  105. data/lib/sisimai/rhost/tencent.rb +48 -26
  106. data/lib/sisimai/rhost/yahooinc.rb +111 -0
  107. data/lib/sisimai/rhost.rb +65 -42
  108. data/lib/sisimai/smtp/command.rb +31 -21
  109. data/lib/sisimai/smtp/failure.rb +103 -0
  110. data/lib/sisimai/smtp/reply.rb +29 -24
  111. data/lib/sisimai/smtp/status.rb +36 -19
  112. data/lib/sisimai/smtp/transcript.rb +18 -18
  113. data/lib/sisimai/string.rb +0 -46
  114. data/lib/sisimai/version.rb +1 -1
  115. data/lib/sisimai.rb +0 -6
  116. data/set-of-emails/maildir/bsd/lhost-dragonfly-01.eml +36 -0
  117. data/set-of-emails/maildir/bsd/lhost-dragonfly-02.eml +32 -0
  118. data/set-of-emails/maildir/bsd/lhost-dragonfly-03.eml +32 -0
  119. data/set-of-emails/maildir/bsd/lhost-dragonfly-04.eml +31 -0
  120. data/set-of-emails/maildir/bsd/lhost-dragonfly-05.eml +32 -0
  121. data/set-of-emails/maildir/bsd/lhost-dragonfly-06.eml +32 -0
  122. data/set-of-emails/maildir/bsd/lhost-dragonfly-07.eml +32 -0
  123. data/set-of-emails/maildir/bsd/lhost-dragonfly-08.eml +32 -0
  124. data/set-of-emails/maildir/bsd/lhost-dragonfly-09.eml +32 -0
  125. data/set-of-emails/maildir/bsd/lhost-dragonfly-10.eml +32 -0
  126. data/set-of-emails/maildir/bsd/lhost-dragonfly-11.eml +32 -0
  127. data/set-of-emails/maildir/bsd/lhost-dragonfly-12.eml +32 -0
  128. data/set-of-emails/maildir/bsd/lhost-dragonfly-13.eml +32 -0
  129. data/set-of-emails/maildir/bsd/lhost-dragonfly-14.eml +32 -0
  130. data/set-of-emails/maildir/bsd/lhost-dragonfly-15.eml +32 -0
  131. data/set-of-emails/maildir/bsd/lhost-dragonfly-16.eml +32 -0
  132. data/set-of-emails/maildir/bsd/lhost-dragonfly-17.eml +32 -0
  133. data/set-of-emails/maildir/bsd/lhost-dragonfly-18.eml +32 -0
  134. data/set-of-emails/maildir/bsd/lhost-dragonfly-19.eml +32 -0
  135. data/set-of-emails/maildir/bsd/lhost-dragonfly-20.eml +32 -0
  136. data/set-of-emails/maildir/bsd/lhost-dragonfly-21.eml +33 -0
  137. data/set-of-emails/maildir/bsd/lhost-dragonfly-22.eml +32 -0
  138. data/set-of-emails/maildir/bsd/lhost-dragonfly-23.eml +32 -0
  139. data/set-of-emails/maildir/bsd/lhost-dragonfly-24.eml +32 -0
  140. data/set-of-emails/maildir/bsd/lhost-dragonfly-25.eml +33 -0
  141. data/set-of-emails/maildir/bsd/lhost-dragonfly-26.eml +33 -0
  142. data/set-of-emails/maildir/bsd/lhost-dragonfly-27.eml +47 -0
  143. data/set-of-emails/maildir/bsd/lhost-dragonfly-28.eml +47 -0
  144. data/set-of-emails/maildir/bsd/lhost-dragonfly-29.eml +32 -0
  145. data/set-of-emails/maildir/bsd/lhost-dragonfly-30.eml +32 -0
  146. data/set-of-emails/maildir/bsd/lhost-opensmtpd-10.eml +58 -0
  147. data/set-of-emails/maildir/bsd/lhost-opensmtpd-11.eml +58 -0
  148. data/set-of-emails/maildir/bsd/lhost-opensmtpd-12.eml +62 -0
  149. data/set-of-emails/maildir/bsd/lhost-opensmtpd-13.eml +62 -0
  150. data/set-of-emails/maildir/bsd/lhost-opensmtpd-14.eml +58 -0
  151. data/set-of-emails/maildir/bsd/lhost-opensmtpd-15.eml +63 -0
  152. data/set-of-emails/maildir/bsd/lhost-opensmtpd-16.eml +62 -0
  153. data/set-of-emails/maildir/bsd/lhost-opensmtpd-17.eml +63 -0
  154. data/set-of-emails/maildir/bsd/lhost-postfix-30.eml +81 -81
  155. data/set-of-emails/maildir/bsd/lhost-qmail-11.eml +29 -0
  156. data/set-of-emails/maildir/bsd/lhost-qmail-12.eml +29 -0
  157. data/set-of-emails/maildir/bsd/lhost-qmail-13.eml +29 -0
  158. data/set-of-emails/maildir/bsd/lhost-qmail-14.eml +34 -0
  159. data/set-of-emails/maildir/bsd/lhost-qmail-15.eml +30 -0
  160. data/set-of-emails/maildir/bsd/lhost-qmail-16.eml +31 -0
  161. data/set-of-emails/maildir/bsd/lhost-qmail-17.eml +38 -0
  162. data/set-of-emails/maildir/bsd/lhost-qmail-18.eml +31 -0
  163. data/set-of-emails/maildir/bsd/lhost-qmail-19.eml +31 -0
  164. data/set-of-emails/maildir/bsd/lhost-qmail-20.eml +46 -0
  165. data/set-of-emails/maildir/bsd/lhost-qmail-21.eml +41 -0
  166. data/set-of-emails/maildir/bsd/lhost-qmail-22.eml +42 -0
  167. data/set-of-emails/maildir/bsd/lhost-qmail-23.eml +43 -0
  168. data/set-of-emails/maildir/bsd/lhost-qmail-24.eml +43 -0
  169. data/set-of-emails/maildir/bsd/lhost-qmail-25.eml +54 -0
  170. data/set-of-emails/maildir/bsd/{lhost-aol-03.eml → rhost-aol-03.eml} +1264 -1264
  171. data/set-of-emails/maildir/bsd/{lhost-aol-04.eml → rhost-aol-04.eml} +1260 -1260
  172. data/set-of-emails/maildir/bsd/{lhost-aol-05.eml → rhost-aol-05.eml} +105 -105
  173. data/set-of-emails/maildir/bsd/{lhost-aol-06.eml → rhost-aol-06.eml} +105 -105
  174. data/set-of-emails/maildir/bsd/rhost-apple-01.eml +79 -0
  175. data/set-of-emails/maildir/bsd/rhost-apple-02.eml +81 -0
  176. data/set-of-emails/maildir/bsd/rhost-apple-03.eml +75 -0
  177. data/set-of-emails/maildir/bsd/rhost-apple-04.eml +74 -0
  178. data/set-of-emails/maildir/bsd/rhost-gsuite-01.eml +189 -0
  179. data/set-of-emails/maildir/bsd/rhost-gsuite-02.eml +180 -0
  180. data/set-of-emails/maildir/bsd/rhost-gsuite-03.eml +251 -0
  181. data/set-of-emails/maildir/bsd/rhost-gsuite-04.eml +211 -0
  182. data/set-of-emails/maildir/bsd/rhost-gsuite-05.eml +226 -0
  183. data/set-of-emails/maildir/bsd/rhost-gsuite-06.eml +257 -0
  184. data/set-of-emails/maildir/bsd/rhost-gsuite-07.eml +289 -0
  185. data/set-of-emails/maildir/bsd/rhost-gsuite-08.eml +231 -0
  186. data/set-of-emails/maildir/bsd/rhost-gsuite-09.eml +231 -0
  187. data/set-of-emails/maildir/bsd/rhost-gsuite-10.eml +254 -0
  188. data/set-of-emails/maildir/bsd/rhost-gsuite-11.eml +228 -0
  189. data/set-of-emails/maildir/bsd/rhost-gsuite-12.eml +271 -0
  190. data/set-of-emails/maildir/bsd/rhost-gsuite-13.eml +261 -0
  191. data/set-of-emails/maildir/bsd/rhost-gsuite-14.eml +273 -0
  192. data/set-of-emails/maildir/bsd/rhost-gsuite-15.eml +229 -0
  193. data/set-of-emails/maildir/bsd/{lhost-messagelabs-01.eml → rhost-messagelabs-01.eml} +93 -93
  194. data/set-of-emails/maildir/bsd/rhost-outlook-01.eml +72 -0
  195. data/set-of-emails/maildir/bsd/rhost-outlook-02.eml +72 -0
  196. data/set-of-emails/maildir/bsd/rhost-outlook-03.eml +72 -0
  197. data/set-of-emails/maildir/bsd/rhost-outlook-04.eml +79 -0
  198. data/set-of-emails/maildir/bsd/rhost-outlook-06.eml +75 -0
  199. data/set-of-emails/maildir/bsd/rhost-outlook-07.eml +70 -0
  200. data/set-of-emails/maildir/bsd/rhost-outlook-08.eml +70 -0
  201. data/set-of-emails/maildir/bsd/rhost-outlook-09.eml +56 -0
  202. data/set-of-emails/maildir/bsd/rhost-yahooinc-01.eml +80 -0
  203. data/set-of-emails/maildir/bsd/rhost-yahooinc-02.eml +83 -0
  204. data/set-of-emails/maildir/bsd/rhost-yahooinc-03.eml +125 -0
  205. data/set-of-emails/maildir/tmp/arf-22.eml +49 -0
  206. data/set-of-emails/maildir/tmp/arf-23.eml +49 -0
  207. data/set-of-emails/maildir/tmp/arf-24.eml +50 -0
  208. data/set-of-emails/maildir/tmp/lhost-exim-07.eml +28 -0
  209. metadata +136 -56
  210. data/lib/sisimai/lhost/amavis.rb +0 -163
  211. data/lib/sisimai/lhost/amazonworkmail.rb +0 -127
  212. data/lib/sisimai/lhost/aol.rb +0 -125
  213. data/lib/sisimai/lhost/barracuda.rb +0 -92
  214. data/lib/sisimai/lhost/bigfoot.rb +0 -125
  215. data/lib/sisimai/lhost/facebook.rb +0 -188
  216. data/lib/sisimai/lhost/gsuite.rb +0 -194
  217. data/lib/sisimai/lhost/mailru.rb +0 -214
  218. data/lib/sisimai/lhost/mcafee.rb +0 -109
  219. data/lib/sisimai/lhost/messagelabs.rb +0 -119
  220. data/lib/sisimai/lhost/mxlogic.rb +0 -198
  221. data/lib/sisimai/lhost/office365.rb +0 -252
  222. data/lib/sisimai/lhost/outlook.rb +0 -129
  223. data/lib/sisimai/lhost/powermta.rb +0 -118
  224. data/lib/sisimai/lhost/receivingses.rb +0 -126
  225. data/lib/sisimai/lhost/sendgrid.rb +0 -150
  226. data/lib/sisimai/lhost/surfcontrol.rb +0 -105
  227. data/lib/sisimai/lhost/x4.rb +0 -269
  228. data/lib/sisimai/lhost/x5.rb +0 -112
  229. data/lib/sisimai/lhost/yahoo.rb +0 -102
  230. data/lib/sisimai/lhost/yandex.rb +0 -118
  231. data/lib/sisimai/mda.rb +0 -121
  232. data/lib/sisimai/smtp/error.rb +0 -119
  233. /data/set-of-emails/maildir/bsd/{lhost-googlegroups-15.eml → lhost-googleworkspace-01.eml} +0 -0
  234. /data/set-of-emails/maildir/bsd/{lhost-x4-08.eml → lhost-x2-06.eml} +0 -0
  235. /data/set-of-emails/maildir/bsd/{lhost-gsuite-01.eml → rfc3464-51.eml} +0 -0
  236. /data/set-of-emails/maildir/bsd/{lhost-gsuite-03.eml → rfc3464-52.eml} +0 -0
  237. /data/set-of-emails/maildir/bsd/{lhost-gsuite-04.eml → rfc3464-53.eml} +0 -0
  238. /data/set-of-emails/maildir/bsd/{lhost-gsuite-05.eml → rfc3464-54.eml} +0 -0
  239. /data/set-of-emails/maildir/bsd/{lhost-gsuite-06.eml → rfc3464-55.eml} +0 -0
  240. /data/set-of-emails/maildir/bsd/{lhost-gsuite-07.eml → rfc3464-56.eml} +0 -0
  241. /data/set-of-emails/maildir/bsd/{lhost-gsuite-08.eml → rfc3464-57.eml} +0 -0
  242. /data/set-of-emails/maildir/bsd/{lhost-gsuite-09.eml → rfc3464-58.eml} +0 -0
  243. /data/set-of-emails/maildir/bsd/{lhost-gsuite-10.eml → rfc3464-59.eml} +0 -0
  244. /data/set-of-emails/maildir/bsd/{lhost-gsuite-11.eml → rfc3464-60.eml} +0 -0
  245. /data/set-of-emails/maildir/bsd/{lhost-gsuite-12.eml → rfc3464-61.eml} +0 -0
  246. /data/set-of-emails/maildir/bsd/{lhost-gsuite-13.eml → rfc3464-62.eml} +0 -0
  247. /data/set-of-emails/maildir/bsd/{lhost-gsuite-14.eml → rfc3464-63.eml} +0 -0
  248. /data/set-of-emails/maildir/bsd/{lhost-gsuite-15.eml → rfc3464-64.eml} +0 -0
  249. /data/set-of-emails/maildir/bsd/{lhost-gsuite-02.eml → rfc3464-65.eml} +0 -0
  250. /data/set-of-emails/maildir/bsd/{lhost-aol-01.eml → rhost-aol-01.eml} +0 -0
  251. /data/set-of-emails/maildir/bsd/{lhost-aol-02.eml → rhost-aol-02.eml} +0 -0
  252. /data/set-of-emails/maildir/bsd/{lhost-facebook-03.eml → rhost-facebook-03.eml} +0 -0
  253. /data/set-of-emails/maildir/bsd/{lhost-facebook-04.eml → rhost-facebook-04.eml} +0 -0
  254. /data/set-of-emails/maildir/bsd/{lhost-messagelabs-02.eml → rhost-messagelabs-02.eml} +0 -0
  255. /data/set-of-emails/maildir/bsd/{lhost-messagelabs-03.eml → rhost-messagelabs-03.eml} +0 -0
  256. /data/set-of-emails/maildir/{bsd → tmp}/rfc3464-37.eml +0 -0
  257. /data/set-of-emails/maildir/{bsd → tmp}/rfc3464-38.eml +0 -0
  258. /data/set-of-emails/maildir/{bsd → tmp}/rfc3464-39.eml +0 -0
@@ -39,6 +39,7 @@ module Sisimai
39
39
  'host network not allowed',
40
40
  'hosts with dynamic ip',
41
41
  'invalid ip for sending mail of domain',
42
+ 'is in a black list',
42
43
  'is not allowed to send mail from',
43
44
  'no access from mail server',
44
45
  'no matches to nameserver query',
@@ -59,6 +60,7 @@ module Sisimai
59
60
  'to submit messages to this e-mail system has been rejected',
60
61
  'too many spams from your ip', # free.fr
61
62
  'too many unwanted messages have been sent from the following ip address above',
63
+ 'was blocked by ',
62
64
  'we do not accept mail from dynamic ips', # @mail.ru
63
65
  'you are not allowed to connect',
64
66
  'you are sending spam',
@@ -67,16 +69,19 @@ module Sisimai
67
69
  'your server requires confirmation',
68
70
  ].freeze
69
71
  Pairs = [
72
+ ['(', '@', ':blocked)'],
70
73
  ['access from ip address ', ' blocked'],
71
74
  ['client host ', ' blocked using'],
72
75
  ['connections will not be accepted from ', " because the ip is in spamhaus's list"],
73
76
  ['dnsbl:rbl ', '>_is_blocked'],
74
77
  ['email blocked by ', '.barracudacentral.org'],
75
78
  ['email blocked by ', 'spamhaus'],
79
+ ['host ', ' refused to talk to me: ', ' blocked'],
76
80
  ['ip ', ' is blocked by earthlink'], # Earthlink
77
81
  ['is in an ', 'rbl on '],
78
82
  ['mail server at ', ' is blocked'],
79
83
  ['mail from ',' refused:'],
84
+ ["mail from "," refused, see ", "orbs"],
80
85
  ['message from ', ' rejected based on blacklist'],
81
86
  ['messages from ', ' temporarily deferred due to user complaints'], # Yahoo!
82
87
  ['server ip ', ' listed as abusive'],
@@ -86,15 +91,9 @@ module Sisimai
86
91
  ['the ip', ' is blacklisted'],
87
92
  ['veuillez essayer plus tard. service refused, please try later. ', '103'],
88
93
  ['veuillez essayer plus tard. service refused, please try later. ', '510'],
94
+ ["your access ip", " has been rejected"],
89
95
  ["your sender's ip address is listed at ", '.abuseat.org'],
90
96
  ].freeze
91
- Regex = %r{(?>
92
- [(][^ ]+[@][^ ]+:blocked[)]
93
- |host[ ][^ ]+[ ]refused[ ]to[ ]talk[ ]to[ ]me:[ ]\d+[ ]blocked
94
- |is[ ]in[ ]a[ ]black[ ]list(?:[ ]at[ ][^ ]+[.])?
95
- |was[ ]blocked[ ]by[ ][^ ]+
96
- )
97
- }x.freeze
98
97
 
99
98
  def text; return 'blocked'; end
100
99
  def description; return 'Email rejected due to client IP address or a hostname'; end
@@ -107,7 +106,6 @@ module Sisimai
107
106
  return nil unless argv1
108
107
  return true if Index.any? { |a| argv1.include?(a) }
109
108
  return true if Pairs.any? { |a| Sisimai::String.aligned(argv1, a) }
110
- return true if argv1 =~ Regex
111
109
  return false
112
110
  end
113
111
 
@@ -119,8 +117,7 @@ module Sisimai
119
117
  def true(argvs)
120
118
  return true if argvs['reason'] == 'blocked'
121
119
  return true if Sisimai::SMTP::Status.name(argvs['deliverystatus']).to_s == 'blocked'
122
- return true if match(argvs['diagnosticcode'].downcase)
123
- return false
120
+ return match(argvs['diagnosticcode'].downcase)
124
121
  end
125
122
 
126
123
  end
@@ -38,7 +38,13 @@ module Sisimai
38
38
  # @return [True,False] true: rejected due to content error
39
39
  # false: is not content error
40
40
  # @see http://www.ietf.org/rfc/rfc2822.txt
41
- def true(_argvs); return nil; end
41
+ def true(argvs)
42
+ require 'sisimai/reason/spamdetected'
43
+ return true if argvs["reason"] == "blocked"
44
+ return false if Sisimai::Reason::SpamDetected.true(argvs)
45
+ return true if Sisimai::SMTP::Status.name(argvs["deliverystatus"]).to_s == "contenterror"
46
+ return match(argvs["diagnosticcode"].downcase)
47
+ end
42
48
 
43
49
  end
44
50
  end
@@ -38,10 +38,7 @@ module Sisimai
38
38
  # Status: 5.2.3
39
39
  # Diagnostic-Code: SMTP; 552 5.2.3 Message size exceeds fixed maximum message size
40
40
  return true if Sisimai::SMTP::Status.name(argvs['deliverystatus']).to_s == 'exceedlimit'
41
-
42
- # Check the value of Diagnosic-Code: header with patterns
43
- return true if match(argvs['diagnosticcode'].downcase)
44
- return false
41
+ return match(argvs['diagnosticcode'].downcase)
45
42
  end
46
43
 
47
44
  end
@@ -0,0 +1,42 @@
1
+ module Sisimai
2
+ module Reason
3
+ # Sisimai::Reason::FailedSTARTTLS checks the bounce reason is "failedstarttls" or not.
4
+ # This class is called only Sisimai::Reason class.
5
+ module FailedSTARTTLS
6
+ class << self
7
+ # Email delivery failed due to STARTTLS related problem
8
+ Index = [
9
+ 'starttls is required to send mail',
10
+ 'tls required but not supported', # SendGrid:the recipient mailserver does not support TLS or have a valid certificate
11
+ ].freeze
12
+
13
+ def text; return 'failedstarttls'; end
14
+ def description; return "Email delivery failed due to STARTTLS related problem"; end
15
+
16
+ # Try to match that the given text and regular expressions
17
+ # @param [String] argv1 String to be matched with regular expressions
18
+ # @return [True,False] false: Did not match
19
+ # true: Matched
20
+ def match(argv1)
21
+ return nil unless argv1
22
+ return true if Index.any? { |a| argv1.include?(a) }
23
+ return false
24
+ end
25
+
26
+ # Email delivery failed due to STARTTLS related problem
27
+ # @param [Sisimai::Fact] argvs Object to be detected the reason
28
+ # @return [True,False] true: FailedSTARTTLS
29
+ # false: Not FailedSTARTTLS
30
+ # @see http://www.ietf.org/rfc/rfc2822.txt
31
+ def true(argvs)
32
+ return true if argvs["reason"] == "failedstarttls"
33
+ return true if argvs["command"] == "STARTTLS"
34
+ return true if [523, 524, 538].index(argvs["replycode"].to_i)
35
+ return match(argvs["diagnosticcode"].downcase)
36
+ end
37
+
38
+ end
39
+ end
40
+ end
41
+ end
42
+
@@ -15,6 +15,7 @@ module Sisimai
15
15
  'due to extended inactivity new mail is not currently being accepted for this mailbox',
16
16
  'has restricted sms e-mail', # AT&T
17
17
  'is not accepting any mail',
18
+ "message filtered",
18
19
  'message rejected due to user rules',
19
20
  'not found recipient account',
20
21
  'refused due to recipient preferences', # Facebook
@@ -53,15 +54,15 @@ module Sisimai
53
54
  return false if tempreason == 'suspend'
54
55
 
55
56
  issuedcode = argvs['diagnosticcode'].downcase || ''
56
- thecommand = argvs['smtpcommand'] || ''
57
+ thecommand = argvs['command'] || ''
57
58
  if tempreason == 'filtered'
58
59
  # Delivery status code points "filtered".
59
60
  return true if Sisimai::Reason::UserUnknown.match(issuedcode)
60
61
  return true if match(issuedcode)
61
62
  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.
63
+ # The value of "reason" isn't "filtered" when the value of "command" is an SMTP command
64
+ # to be sent before the SMTP DATA command because all the MTAs read the headers and the
65
+ # entire message body after the DATA command.
65
66
  return false if %w[CONN EHLO HELO MAIL RCPT].include?(thecommand)
66
67
  return true if match(issuedcode)
67
68
  return true if Sisimai::Reason::UserUnknown.match(issuedcode)
@@ -30,8 +30,7 @@ module Sisimai
30
30
  # @see http://www.ietf.org/rfc/rfc2822.txt
31
31
  def true(argvs)
32
32
  return true if argvs['reason'] == 'hasmoved'
33
- return true if match(argvs['diagnosticcode'].downcase)
34
- return false
33
+ return match(argvs['diagnosticcode'].downcase)
35
34
  end
36
35
 
37
36
  end
@@ -54,12 +54,12 @@ module Sisimai
54
54
  statuscode = argvs['deliverystatus'] || ''
55
55
 
56
56
  if Sisimai::SMTP::Status.name(statuscode).to_s == 'hostunknown'
57
- # Status: 5.1.2
58
- # Diagnostic-Code: SMTP; 550 Host unknown
57
+ # To prevent classifying DNS errors as "HostUnknown"
59
58
  require 'sisimai/reason/networkerror'
60
59
  return true unless Sisimai::Reason::NetworkError.match(issuedcode)
61
60
  else
62
- # Check the value of Diagnosic-Code: header with patterns
61
+ # Status: 5.1.2
62
+ # Diagnostic-Code: SMTP; 550 Host unknown
63
63
  return true if match(issuedcode)
64
64
  end
65
65
 
@@ -37,6 +37,7 @@ module Sisimai
37
37
  'maildir delivery failed: domaindisk quota ',
38
38
  'mailfolder is full',
39
39
  'no space left on device',
40
+ 'not enough disk space',
40
41
  'not enough storage space in',
41
42
  'not sufficient disk space',
42
43
  'over the allowed quota',
@@ -84,10 +85,7 @@ module Sisimai
84
85
  # Status: 4.2.2
85
86
  # Diagnostic-Code: SMTP; 450 4.2.2 <***@example.jp>... Mailbox Full
86
87
  return true if Sisimai::SMTP::Status.name(argvs['deliverystatus']).to_s == 'mailboxfull'
87
-
88
- # Check the value of Diagnosic-Code: header with patterns
89
- return true if match(argvs['diagnosticcode'].downcase)
90
- return false
88
+ return match(argvs['diagnosticcode'].downcase)
91
89
  end
92
90
 
93
91
  end
@@ -11,6 +11,7 @@ module Sisimai
11
11
  module MailerError
12
12
  class << self
13
13
  Index = [
14
+ ' || exit ',
14
15
  'procmail: ',
15
16
  'bin/procmail',
16
17
  'bin/maidrop',
@@ -21,7 +22,6 @@ module Sisimai
21
22
  'pipe to |/',
22
23
  'x-unix; ',
23
24
  ].freeze
24
- Regex = %r/exit[ ]\d+/.freeze
25
25
 
26
26
  def text; return 'mailererror'; end
27
27
  def description; return 'Email returned due to a mailer program has not exited successfully'; end
@@ -33,7 +33,6 @@ module Sisimai
33
33
  def match(argv1)
34
34
  return nil unless argv1
35
35
  return true if Index.any? { |a| argv1.include?(a) }
36
- return true if argv1 =~ Regex
37
36
  return false
38
37
  end
39
38
 
@@ -8,6 +8,7 @@ module Sisimai
8
8
  class << self
9
9
  Index = [
10
10
  'exceeded maximum inbound message size',
11
+ 'exceeded the maximum incoming message size',
11
12
  'line limit exceeded',
12
13
  'max message size exceeded',
13
14
  'message file too big',
@@ -52,10 +53,7 @@ module Sisimai
52
53
 
53
54
  # 5.2.3 Message length exceeds administrative limit
54
55
  return false if( tempreason == 'exceedlimit' || statuscode == '5.2.3' )
55
-
56
- # Check the value of Diagnosic-Code: header with patterns
57
- return true if match(argvs['diagnosticcode'].downcase)
58
- return false
56
+ return match(argvs['diagnosticcode'].downcase)
59
57
  end
60
58
 
61
59
  end
@@ -15,6 +15,7 @@ module Sisimai
15
15
  'insecure mail relay',
16
16
  'is not permitted to relay through this server without authentication',
17
17
  'mail server requires authentication when attempting to send to a non-local e-mail address', # MailEnable
18
+ 'no relaying',
18
19
  'not a gateway',
19
20
  'not allowed to relay through this machine',
20
21
  'not an open relay, so get lost',
@@ -52,9 +53,8 @@ module Sisimai
52
53
  def true(argvs)
53
54
  r = argvs['reason'] || ''
54
55
  return false if r.start_with?('securityerror', 'systemerror', 'undefined')
55
- return false if %w[CONN EHLO HELO].include?(argvs['smtpcommand'])
56
- return true if match(argvs['diagnosticcode'].downcase)
57
- return false
56
+ return false if %w[CONN EHLO HELO].include?(argvs['command'])
57
+ return match(argvs['diagnosticcode'].downcase)
58
58
  end
59
59
 
60
60
  end
@@ -44,9 +44,8 @@ module Sisimai
44
44
 
45
45
  # SMTP Reply Code is 554 or 556
46
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)
49
- return false
47
+ return false if argvs['command'] != 'MAIL'
48
+ return match(argvs['diagnosticcode'].downcase)
50
49
  end
51
50
 
52
51
  end
@@ -7,10 +7,16 @@ module Sisimai
7
7
  # example, there are multiple "Subject" headers in the email.
8
8
  module NotCompliantRFC
9
9
  class << self
10
+ require 'sisimai/string'
10
11
  Index = [
11
- 'this message is not rfc 5322 compliant',
12
- 'https://support.google.com/mail/?p=rfcmessagenoncompliant',
12
+ 'duplicate header',
13
+ 'this message is not rfc 5322 compliant',
14
+ 'https://support.google.com/mail/?p=rfcmessagenoncompliant',
13
15
  ].freeze
16
+ Pairs = [
17
+ [' multiple ', ' header'],
18
+ ].freeze
19
+
14
20
 
15
21
  def text; return 'notcompliantrfc'; end
16
22
  def description; return 'Email rejected due to non-compliance with RFC'; end
@@ -22,6 +28,7 @@ module Sisimai
22
28
  def match(argv1)
23
29
  return nil unless argv1
24
30
  return true if Index.any? { |a| argv1.include?(a) }
31
+ return true if Pairs.any? { |a| Sisimai::String.aligned(argv1, a) }
25
32
  return false
26
33
  end
27
34
 
@@ -32,8 +39,7 @@ module Sisimai
32
39
  # @see http://www.ietf.org/rfc/rfc5322.txt
33
40
  def true(argvs)
34
41
  return true if argvs['reason'] == 'notcompliantrfc'
35
- return true if match(argvs['diagnosticcode'].downcase)
36
- return false
42
+ return match(argvs['diagnosticcode'].downcase)
37
43
  end
38
44
 
39
45
  end
@@ -63,6 +63,7 @@ module Sisimai
63
63
  'sender rejected',
64
64
  'sender domain is empty',
65
65
  'sender verify failed', # Exim callout
66
+ 'sender was rejected', # qmail
66
67
  'spam reporting address', # SendGrid|a message to an address has previously been marked as Spam by the recipient.
67
68
  'syntax error: empty email address',
68
69
  'the message has been rejected by batv defense',
@@ -101,7 +102,7 @@ module Sisimai
101
102
 
102
103
  # Check the value of Diagnosic-Code: header with patterns
103
104
  issuedcode = argvs['diagnosticcode'].downcase
104
- thecommand = argvs['smtpcommand'] || ''
105
+ thecommand = argvs['command'] || ''
105
106
  if thecommand == 'MAIL'
106
107
  # The session was rejected at 'MAIL FROM' command
107
108
  return true if match(issuedcode)
@@ -13,6 +13,7 @@ module Sisimai
13
13
  'all mail servers must have a ptr record with a valid reverse dns entry',
14
14
  'bad dns ptr resource record',
15
15
  'cannot find your hostname',
16
+ "cannot resolve your address.",
16
17
  'client host rejected: cannot find your hostname', # Yahoo!
17
18
  'fix reverse dns for ',
18
19
  'ips with missing ptr records',
@@ -58,8 +59,7 @@ module Sisimai
58
59
  def true(argvs)
59
60
  return true if argvs['reason'] == 'requireptr'
60
61
  return true if Sisimai::SMTP::Status.name(argvs['deliverystatus']).to_s == 'requireptr'
61
- return true if match(argvs['diagnosticcode'].downcase)
62
- return false
62
+ return match(argvs['diagnosticcode'].downcase)
63
63
  end
64
64
 
65
65
  end
@@ -29,8 +29,6 @@ module Sisimai
29
29
  'insecure mail relay',
30
30
  'recipient address rejected: access denied',
31
31
  "sorry, you don't authenticate or the domain isn't in my list of allowed rcpthosts",
32
- 'starttls is required to send mail',
33
- 'tls required but not supported', # SendGrid:the recipient mailserver does not support TLS or have a valid certificate
34
32
  'unauthenticated senders not allowed',
35
33
  'verification failure',
36
34
  'you are not authorized to send mail, authentication is required',
@@ -57,7 +55,7 @@ module Sisimai
57
55
  return false
58
56
  end
59
57
 
60
- # The bounce reason is security error or not
58
+ # The bounce reason is SecurityError or not
61
59
  # @param [Sisimai::Fact] argvs Object to be detected the reason
62
60
  # @return [True,False] true: is security error
63
61
  # false: is not security error
@@ -104,6 +104,7 @@ module Sisimai
104
104
  ].freeze
105
105
  Pairs = [
106
106
  ['greylisted', ' please try again in'],
107
+ ['mail score (', ' over '],
107
108
  ['mail rejete. mail rejected. ', '506'],
108
109
  ['our filters rate at and above ', ' percent probability of being spam'],
109
110
  ['rejected by ', ' (spam)'],
@@ -113,7 +114,6 @@ module Sisimai
113
114
  ['spam ', ' exceeded'],
114
115
  ['this message scored ', ' spam points'],
115
116
  ].freeze
116
- Regex = %r/(?:\d[.]\d[.]\d|\d{3})[ ]spam\z/.freeze
117
117
 
118
118
  def text; return 'spamdetected'; end
119
119
  def description; return 'Email rejected by spam filter running on the remote host'; end
@@ -126,7 +126,6 @@ module Sisimai
126
126
  return nil unless argv1
127
127
  return true if Index.any? { |a| argv1.include?(a) }
128
128
  return true if Pairs.any? { |a| Sisimai::String.aligned(argv1, a) }
129
- return true if argv1 =~ Regex
130
129
  return false
131
130
  end
132
131
 
@@ -140,12 +139,11 @@ module Sisimai
140
139
  return true if argvs['reason'] == 'spamdetected'
141
140
  return true if Sisimai::SMTP::Status.name(argvs['deliverystatus']).to_s == 'spamdetected'
142
141
 
143
- # The value of "reason" isn't "spamdetected" when the value of "smtpcommand" is an SMTP
144
- # command to be sent before the SMTP DATA command because all the MTAs read the headers
145
- # and the entire message body after the DATA command.
146
- return false if %w[CONN EHLO HELO MAIL RCPT].include?(argvs['smtpcommand'])
147
- return true if match(argvs['diagnosticcode'].downcase)
148
- return false
142
+ # The value of "reason" isn't "spamdetected" when the value of "command" is an SMTP command
143
+ # to be sent before the SMTP DATA command because all the MTAs read the headers and the
144
+ # entire message body after the DATA command.
145
+ return false if %w[CONN EHLO HELO MAIL RCPT].include?(argvs['command'])
146
+ return match(argvs['diagnosticcode'].downcase)
149
147
  end
150
148
 
151
149
  end
@@ -38,8 +38,7 @@ module Sisimai
38
38
  # Remote-MTA: dns; smtp.example.jp
39
39
  # Diagnostic-Code: smtp; 451 4.7.1 <mx.example.org[192.0.2.2]>: Client host rejected:
40
40
  # Please try again slower
41
- return true if match(argvs['diagnosticcode'].downcase)
42
- return false
41
+ return match(argvs['diagnosticcode'].downcase)
43
42
  end
44
43
 
45
44
  end
@@ -0,0 +1,36 @@
1
+ module Sisimai
2
+ module Reason
3
+ # Sisimai::Reason::Suppressed checks the bounce reason is "suppressed" or not. This class is called
4
+ # only Sisimai::Reason class.
5
+ #
6
+ # This is the error that the recipient adddress is listed in the suppression list of the relay
7
+ # server, and was not delivered.
8
+ module Suppressed
9
+ class << self
10
+ def text; return 'suppressed'; end
11
+ def description; return "Email was not delivered due to being listed in the suppression list of MTA"; end
12
+
13
+ # Try to match that the given text and regular expressions
14
+ # @param [String] argv1 String to be matched with regular expressions
15
+ # @return [True,False] false: Did not match
16
+ # true: Matched
17
+ def match(argv1)
18
+ return nil unless argv1
19
+ return false
20
+ end
21
+
22
+ # Whether the address is listed in the suppression list
23
+ # @param [Sisimai::Fact] argvs Object to be detected the reason
24
+ # @return [True,False] true: The address is listed in the suppression list
25
+ # false: is not listed in the suppression list
26
+ # @see http://www.ietf.org/rfc/rfc2822.txt
27
+ def true(argvs)
28
+ return true if argvs['reason'] == 'suppressed'
29
+ return match(argvs['diagnosticcode'].downcase)
30
+ end
31
+
32
+ end
33
+ end
34
+ end
35
+ end
36
+
@@ -50,11 +50,9 @@ module Sisimai
50
50
  # false: is not suspended
51
51
  # @see http://www.ietf.org/rfc/rfc2822.txt
52
52
  def true(argvs)
53
- return nil if argvs['deliverystatus'].empty?
54
53
  return true if argvs['reason'] == 'suspend'
55
54
  return true if argvs['replycode'].to_i == 525
56
- return true if match(argvs['diagnosticcode'].downcase)
57
- return false
55
+ return match(argvs['diagnosticcode'].downcase)
58
56
  end
59
57
 
60
58
  end
@@ -9,6 +9,7 @@ module Sisimai
9
9
  # message has been in the queue too long.
10
10
  module SystemError
11
11
  class << self
12
+ require 'sisimai/string'
12
13
  Index = [
13
14
  'aliasing/forwarding loop broken',
14
15
  "can't create user output file",
@@ -33,6 +34,9 @@ module Sisimai
33
34
  'timeout waiting for input',
34
35
  'transaction failed ',
35
36
  ].freeze
37
+ Pairs = [
38
+ ['unable to connect ', 'daemon'],
39
+ ].freeze
36
40
 
37
41
  def text; return 'systemerror'; end
38
42
  def description; return 'Email returned due to system error on the remote host'; end
@@ -44,6 +48,7 @@ module Sisimai
44
48
  def match(argv1)
45
49
  return nil unless argv1
46
50
  return true if Index.any? { |a| argv1.include?(a) }
51
+ return true if Pairs.any? { |a| Sisimai::String.aligned(argv1, a) }
47
52
  return false
48
53
  end
49
54
 
@@ -48,8 +48,7 @@ module Sisimai
48
48
  def true(argvs)
49
49
  return true if argvs['reason'] == 'toomanyconn'
50
50
  return true if Sisimai::SMTP::Status.name(argvs['deliverystatus']).to_s == 'toomanyconn'
51
- return true if match(argvs['diagnosticcode'].downcase)
52
- return false
51
+ return match(argvs['diagnosticcode'].downcase)
53
52
  end
54
53
 
55
54
  end
@@ -191,7 +191,7 @@ module Sisimai
191
191
  end
192
192
  return true unless matchother # Did not match with other message patterns
193
193
 
194
- elsif argvs['smtpcommand'] == 'RCPT'
194
+ elsif argvs['command'] == 'RCPT'
195
195
  # When the SMTP command is not "RCPT", the session rejected by other
196
196
  # reason, maybe.
197
197
  return true if match(issuedcode)
@@ -44,13 +44,12 @@ module Sisimai
44
44
  # @since 4.22.0
45
45
  # @see http://www.ietf.org/rfc/rfc2822.txt
46
46
  def true(argvs)
47
- # The value of "reason" isn't "visusdetected" when the value of "smtpcommand" is an SMTP
48
- # command to be sent before the SMTP DATA command because all the MTAs read the headers
49
- # and the entire message body after the DATA command.
47
+ # The value of "reason" isn't "visusdetected" when the value of "command" is an SMTP command
48
+ # to be sent before the SMTP DATA command because all the MTAs read the headers and the
49
+ # entire message body after the DATA command.
50
50
  return true if argvs['reason'] == 'virusdetected'
51
- return false if %w[CONN EHLO HELO MAIL RCPT].include?(argvs['smtpcommand'])
52
- return true if match(argvs['diagnosticcode'].downcase)
53
- return false
51
+ return false if %w[CONN EHLO HELO MAIL RCPT].include?(argvs['command'])
52
+ return match(argvs['diagnosticcode'].downcase)
54
53
  end
55
54
 
56
55
  end