sisimai 4.14.2

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 (562) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +12 -0
  3. data/.rspec +2 -0
  4. data/.rubocop.yml +165 -0
  5. data/.travis.yml +21 -0
  6. data/ANALYTICAL-PRECISION +54 -0
  7. data/Changes +5 -0
  8. data/Developers.mk +129 -0
  9. data/Gemfile +9 -0
  10. data/LICENSE +26 -0
  11. data/Makefile +56 -0
  12. data/README.md +300 -0
  13. data/Rakefile +7 -0
  14. data/Repository.mk +69 -0
  15. data/bin/console +14 -0
  16. data/bin/setup +7 -0
  17. data/lib/sisimai.rb +60 -0
  18. data/lib/sisimai/address.rb +218 -0
  19. data/lib/sisimai/arf.rb +343 -0
  20. data/lib/sisimai/data.rb +413 -0
  21. data/lib/sisimai/data/json.rb +36 -0
  22. data/lib/sisimai/data/yaml.rb +32 -0
  23. data/lib/sisimai/datetime.rb +518 -0
  24. data/lib/sisimai/mail.rb +82 -0
  25. data/lib/sisimai/mail/maildir.rb +85 -0
  26. data/lib/sisimai/mail/mbox.rb +69 -0
  27. data/lib/sisimai/mail/stdin.rb +52 -0
  28. data/lib/sisimai/mda.rb +152 -0
  29. data/lib/sisimai/message.rb +510 -0
  30. data/lib/sisimai/mime.rb +127 -0
  31. data/lib/sisimai/msp.rb +54 -0
  32. data/lib/sisimai/msp/de/einsundeins.rb +174 -0
  33. data/lib/sisimai/msp/de/gmx.rb +197 -0
  34. data/lib/sisimai/msp/jp/biglobe.rb +179 -0
  35. data/lib/sisimai/msp/jp/ezweb.rb +292 -0
  36. data/lib/sisimai/msp/jp/kddi.rb +195 -0
  37. data/lib/sisimai/msp/ru/mailru.rb +306 -0
  38. data/lib/sisimai/msp/ru/yandex.rb +241 -0
  39. data/lib/sisimai/msp/uk/messagelabs.rb +250 -0
  40. data/lib/sisimai/msp/us/amazonses.rb +248 -0
  41. data/lib/sisimai/msp/us/aol.rb +234 -0
  42. data/lib/sisimai/msp/us/bigfoot.rb +243 -0
  43. data/lib/sisimai/msp/us/facebook.rb +306 -0
  44. data/lib/sisimai/msp/us/google.rb +357 -0
  45. data/lib/sisimai/msp/us/outlook.rb +243 -0
  46. data/lib/sisimai/msp/us/receivingses.rb +247 -0
  47. data/lib/sisimai/msp/us/sendgrid.rb +257 -0
  48. data/lib/sisimai/msp/us/verizon.rb +311 -0
  49. data/lib/sisimai/msp/us/yahoo.rb +178 -0
  50. data/lib/sisimai/msp/us/zoho.rb +198 -0
  51. data/lib/sisimai/mta.rb +55 -0
  52. data/lib/sisimai/mta/activehunter.rb +155 -0
  53. data/lib/sisimai/mta/apachejames.rb +194 -0
  54. data/lib/sisimai/mta/courier.rb +307 -0
  55. data/lib/sisimai/mta/domino.rb +209 -0
  56. data/lib/sisimai/mta/exchange.rb +314 -0
  57. data/lib/sisimai/mta/exim.rb +549 -0
  58. data/lib/sisimai/mta/imailserver.rb +227 -0
  59. data/lib/sisimai/mta/interscanmss.rb +167 -0
  60. data/lib/sisimai/mta/mailfoundry.rb +173 -0
  61. data/lib/sisimai/mta/mailmarshalsmtp.rb +206 -0
  62. data/lib/sisimai/mta/mcafee.rb +201 -0
  63. data/lib/sisimai/mta/messagingserver.rb +241 -0
  64. data/lib/sisimai/mta/mfilter.rb +190 -0
  65. data/lib/sisimai/mta/mxlogic.rb +283 -0
  66. data/lib/sisimai/mta/notes.rb +206 -0
  67. data/lib/sisimai/mta/opensmtpd.rb +225 -0
  68. data/lib/sisimai/mta/postfix.rb +306 -0
  69. data/lib/sisimai/mta/qmail.rb +335 -0
  70. data/lib/sisimai/mta/sendmail.rb +317 -0
  71. data/lib/sisimai/mta/surfcontrol.rb +193 -0
  72. data/lib/sisimai/mta/userdefined.rb +148 -0
  73. data/lib/sisimai/mta/v5sendmail.rb +232 -0
  74. data/lib/sisimai/mta/x1.rb +156 -0
  75. data/lib/sisimai/mta/x2.rb +157 -0
  76. data/lib/sisimai/mta/x3.rb +171 -0
  77. data/lib/sisimai/mta/x4.rb +365 -0
  78. data/lib/sisimai/mta/x5.rb +208 -0
  79. data/lib/sisimai/order.rb +217 -0
  80. data/lib/sisimai/reason.rb +235 -0
  81. data/lib/sisimai/reason/blocked.rb +105 -0
  82. data/lib/sisimai/reason/contenterror.rb +53 -0
  83. data/lib/sisimai/reason/exceedlimit.rb +60 -0
  84. data/lib/sisimai/reason/expired.rb +53 -0
  85. data/lib/sisimai/reason/filtered.rb +98 -0
  86. data/lib/sisimai/reason/hasmoved.rb +45 -0
  87. data/lib/sisimai/reason/hostunknown.rb +74 -0
  88. data/lib/sisimai/reason/mailboxfull.rb +118 -0
  89. data/lib/sisimai/reason/mailererror.rb +55 -0
  90. data/lib/sisimai/reason/mesgtoobig.rb +77 -0
  91. data/lib/sisimai/reason/networkerror.rb +57 -0
  92. data/lib/sisimai/reason/norelaying.rb +71 -0
  93. data/lib/sisimai/reason/notaccept.rb +63 -0
  94. data/lib/sisimai/reason/onhold.rb +45 -0
  95. data/lib/sisimai/reason/rejected.rb +101 -0
  96. data/lib/sisimai/reason/securityerror.rb +72 -0
  97. data/lib/sisimai/reason/spamdetected.rb +172 -0
  98. data/lib/sisimai/reason/suspend.rb +58 -0
  99. data/lib/sisimai/reason/systemerror.rb +69 -0
  100. data/lib/sisimai/reason/systemfull.rb +45 -0
  101. data/lib/sisimai/reason/toomanyconn.rb +73 -0
  102. data/lib/sisimai/reason/userunknown.rb +194 -0
  103. data/lib/sisimai/rfc2606.rb +24 -0
  104. data/lib/sisimai/rfc3464.rb +497 -0
  105. data/lib/sisimai/rfc3834.rb +150 -0
  106. data/lib/sisimai/rfc5322.rb +204 -0
  107. data/lib/sisimai/rhost.rb +47 -0
  108. data/lib/sisimai/rhost/googleapps.rb +237 -0
  109. data/lib/sisimai/smtp.rb +58 -0
  110. data/lib/sisimai/smtp/reply.rb +81 -0
  111. data/lib/sisimai/smtp/status.rb +755 -0
  112. data/lib/sisimai/string.rb +65 -0
  113. data/lib/sisimai/time.rb +11 -0
  114. data/lib/sisimai/version.rb +4 -0
  115. data/set-of-emails/README.md +35 -0
  116. data/set-of-emails/mailbox/mbox-0 +2467 -0
  117. data/set-of-emails/mailbox/mbox-1 +71 -0
  118. data/set-of-emails/maildir/bsd/README.md +261 -0
  119. data/set-of-emails/maildir/bsd/activehunter-01.eml +54 -0
  120. data/set-of-emails/maildir/bsd/activehunter-02.eml +53 -0
  121. data/set-of-emails/maildir/bsd/apachejames-01.eml +46 -0
  122. data/set-of-emails/maildir/bsd/arf-01.eml +66 -0
  123. data/set-of-emails/maildir/bsd/arf-02.eml +68 -0
  124. data/set-of-emails/maildir/bsd/arf-03.eml +56 -0
  125. data/set-of-emails/maildir/bsd/arf-04.eml +89 -0
  126. data/set-of-emails/maildir/bsd/arf-05.eml +82 -0
  127. data/set-of-emails/maildir/bsd/arf-06.eml +166 -0
  128. data/set-of-emails/maildir/bsd/arf-07.eml +59 -0
  129. data/set-of-emails/maildir/bsd/arf-08.eml +103 -0
  130. data/set-of-emails/maildir/bsd/arf-09.eml +104 -0
  131. data/set-of-emails/maildir/bsd/arf-10.eml +56 -0
  132. data/set-of-emails/maildir/bsd/arf-11.eml +37 -0
  133. data/set-of-emails/maildir/bsd/arf-12.eml +40 -0
  134. data/set-of-emails/maildir/bsd/arf-13.eml +76 -0
  135. data/set-of-emails/maildir/bsd/arf-14.eml +333 -0
  136. data/set-of-emails/maildir/bsd/arf-15.eml +66 -0
  137. data/set-of-emails/maildir/bsd/courier-01.eml +79 -0
  138. data/set-of-emails/maildir/bsd/courier-02.eml +83 -0
  139. data/set-of-emails/maildir/bsd/courier-03.eml +85 -0
  140. data/set-of-emails/maildir/bsd/courier-04.eml +87 -0
  141. data/set-of-emails/maildir/bsd/de-einsundeins-01.eml +38 -0
  142. data/set-of-emails/maildir/bsd/de-gmx-01.eml +52 -0
  143. data/set-of-emails/maildir/bsd/de-gmx-02.eml +51 -0
  144. data/set-of-emails/maildir/bsd/de-gmx-03.eml +56 -0
  145. data/set-of-emails/maildir/bsd/de-gmx-04.eml +51 -0
  146. data/set-of-emails/maildir/bsd/domino-01.eml +33 -0
  147. data/set-of-emails/maildir/bsd/domino-02.eml +83 -0
  148. data/set-of-emails/maildir/bsd/exchange-01.eml +31 -0
  149. data/set-of-emails/maildir/bsd/exchange-02.eml +67 -0
  150. data/set-of-emails/maildir/bsd/exchange-03.eml +52 -0
  151. data/set-of-emails/maildir/bsd/exchange-04.eml +28 -0
  152. data/set-of-emails/maildir/bsd/exchange-05.eml +56 -0
  153. data/set-of-emails/maildir/bsd/exchange-06.eml +151 -0
  154. data/set-of-emails/maildir/bsd/exim-01.eml +46 -0
  155. data/set-of-emails/maildir/bsd/exim-02.eml +41 -0
  156. data/set-of-emails/maildir/bsd/exim-03.eml +42 -0
  157. data/set-of-emails/maildir/bsd/exim-04.eml +46 -0
  158. data/set-of-emails/maildir/bsd/exim-05.eml +49 -0
  159. data/set-of-emails/maildir/bsd/exim-06.eml +44 -0
  160. data/set-of-emails/maildir/bsd/exim-07.eml +28 -0
  161. data/set-of-emails/maildir/bsd/exim-08.eml +42 -0
  162. data/set-of-emails/maildir/bsd/exim-09.eml +169 -0
  163. data/set-of-emails/maildir/bsd/exim-10.eml +718 -0
  164. data/set-of-emails/maildir/bsd/exim-11.eml +718 -0
  165. data/set-of-emails/maildir/bsd/exim-12.eml +75 -0
  166. data/set-of-emails/maildir/bsd/exim-13.eml +145 -0
  167. data/set-of-emails/maildir/bsd/exim-14.eml +32 -0
  168. data/set-of-emails/maildir/bsd/exim-15.eml +49 -0
  169. data/set-of-emails/maildir/bsd/exim-16.eml +98 -0
  170. data/set-of-emails/maildir/bsd/exim-17.eml +50 -0
  171. data/set-of-emails/maildir/bsd/exim-18.eml +96 -0
  172. data/set-of-emails/maildir/bsd/exim-19.eml +52 -0
  173. data/set-of-emails/maildir/bsd/exim-20.eml +159 -0
  174. data/set-of-emails/maildir/bsd/exim-21.eml +150 -0
  175. data/set-of-emails/maildir/bsd/exim-22.eml +50 -0
  176. data/set-of-emails/maildir/bsd/exim-23.eml +57 -0
  177. data/set-of-emails/maildir/bsd/exim-24.eml +107 -0
  178. data/set-of-emails/maildir/bsd/exim-25.eml +18 -0
  179. data/set-of-emails/maildir/bsd/exim-26.eml +111 -0
  180. data/set-of-emails/maildir/bsd/exim-27.eml +120 -0
  181. data/set-of-emails/maildir/bsd/exim-28.eml +148 -0
  182. data/set-of-emails/maildir/bsd/google-apps-01.eml +66 -0
  183. data/set-of-emails/maildir/bsd/imailserver-01.eml +27 -0
  184. data/set-of-emails/maildir/bsd/imailserver-02.eml +36 -0
  185. data/set-of-emails/maildir/bsd/imailserver-03.eml +28 -0
  186. data/set-of-emails/maildir/bsd/imailserver-04.eml +15 -0
  187. data/set-of-emails/maildir/bsd/imailserver-05.eml +92 -0
  188. data/set-of-emails/maildir/bsd/imailserver-06.eml +29 -0
  189. data/set-of-emails/maildir/bsd/interscanmss-01.eml +49 -0
  190. data/set-of-emails/maildir/bsd/interscanmss-02.eml +259 -0
  191. data/set-of-emails/maildir/bsd/jp-biglobe-01.eml +43 -0
  192. data/set-of-emails/maildir/bsd/jp-ezweb-01.eml +36 -0
  193. data/set-of-emails/maildir/bsd/jp-ezweb-02.eml +65 -0
  194. data/set-of-emails/maildir/bsd/jp-ezweb-03.eml +35 -0
  195. data/set-of-emails/maildir/bsd/jp-ezweb-04.eml +38 -0
  196. data/set-of-emails/maildir/bsd/jp-ezweb-05.eml +38 -0
  197. data/set-of-emails/maildir/bsd/jp-ezweb-06.eml +33 -0
  198. data/set-of-emails/maildir/bsd/jp-kddi-01.eml +49 -0
  199. data/set-of-emails/maildir/bsd/jp-kddi-02.eml +54 -0
  200. data/set-of-emails/maildir/bsd/jp-kddi-03.eml +54 -0
  201. data/set-of-emails/maildir/bsd/mailfoundry-01.eml +50 -0
  202. data/set-of-emails/maildir/bsd/mailfoundry-02.eml +49 -0
  203. data/set-of-emails/maildir/bsd/mailmarshalsmtp-01.eml +43 -0
  204. data/set-of-emails/maildir/bsd/mcafee-01.eml +63 -0
  205. data/set-of-emails/maildir/bsd/mcafee-02.eml +65 -0
  206. data/set-of-emails/maildir/bsd/mcafee-03.eml +59 -0
  207. data/set-of-emails/maildir/bsd/messagingserver-01.eml +102 -0
  208. data/set-of-emails/maildir/bsd/messagingserver-02.eml +72 -0
  209. data/set-of-emails/maildir/bsd/messagingserver-03.eml +70 -0
  210. data/set-of-emails/maildir/bsd/messagingserver-04.eml +102 -0
  211. data/set-of-emails/maildir/bsd/messagingserver-05.eml +98 -0
  212. data/set-of-emails/maildir/bsd/messagingserver-06.eml +101 -0
  213. data/set-of-emails/maildir/bsd/messagingserver-07.eml +129 -0
  214. data/set-of-emails/maildir/bsd/mfilter-01.eml +49 -0
  215. data/set-of-emails/maildir/bsd/mfilter-02.eml +48 -0
  216. data/set-of-emails/maildir/bsd/mfilter-03.eml +43 -0
  217. data/set-of-emails/maildir/bsd/mxlogic-01.eml +47 -0
  218. data/set-of-emails/maildir/bsd/mxlogic-02.eml +44 -0
  219. data/set-of-emails/maildir/bsd/mxlogic-03.eml +46 -0
  220. data/set-of-emails/maildir/bsd/notes-01.eml +42 -0
  221. data/set-of-emails/maildir/bsd/notes-02.eml +42 -0
  222. data/set-of-emails/maildir/bsd/notes-03.eml +38 -0
  223. data/set-of-emails/maildir/bsd/notes-04.eml +181 -0
  224. data/set-of-emails/maildir/bsd/opensmtpd-01.eml +33 -0
  225. data/set-of-emails/maildir/bsd/opensmtpd-02.eml +33 -0
  226. data/set-of-emails/maildir/bsd/opensmtpd-03.eml +36 -0
  227. data/set-of-emails/maildir/bsd/opensmtpd-04.eml +40 -0
  228. data/set-of-emails/maildir/bsd/opensmtpd-05.eml +36 -0
  229. data/set-of-emails/maildir/bsd/postfix-01.eml +60 -0
  230. data/set-of-emails/maildir/bsd/postfix-02.eml +78 -0
  231. data/set-of-emails/maildir/bsd/postfix-03.eml +71 -0
  232. data/set-of-emails/maildir/bsd/postfix-04.eml +89 -0
  233. data/set-of-emails/maildir/bsd/postfix-05.eml +78 -0
  234. data/set-of-emails/maildir/bsd/postfix-06.eml +72 -0
  235. data/set-of-emails/maildir/bsd/postfix-07.eml +74 -0
  236. data/set-of-emails/maildir/bsd/postfix-08.eml +78 -0
  237. data/set-of-emails/maildir/bsd/postfix-09.eml +76 -0
  238. data/set-of-emails/maildir/bsd/postfix-10.eml +73 -0
  239. data/set-of-emails/maildir/bsd/postfix-11.eml +86 -0
  240. data/set-of-emails/maildir/bsd/postfix-12.eml +71 -0
  241. data/set-of-emails/maildir/bsd/postfix-13.eml +81 -0
  242. data/set-of-emails/maildir/bsd/postfix-14.eml +68 -0
  243. data/set-of-emails/maildir/bsd/postfix-15.eml +69 -0
  244. data/set-of-emails/maildir/bsd/postfix-16.eml +73 -0
  245. data/set-of-emails/maildir/bsd/postfix-17.eml +68 -0
  246. data/set-of-emails/maildir/bsd/postfix-18.eml +121 -0
  247. data/set-of-emails/maildir/bsd/postfix-19.eml +105 -0
  248. data/set-of-emails/maildir/bsd/postfix-20.eml +231 -0
  249. data/set-of-emails/maildir/bsd/postfix-21.eml +60 -0
  250. data/set-of-emails/maildir/bsd/qmail-01.eml +40 -0
  251. data/set-of-emails/maildir/bsd/qmail-02.eml +35 -0
  252. data/set-of-emails/maildir/bsd/qmail-03.eml +22 -0
  253. data/set-of-emails/maildir/bsd/qmail-04.eml +31 -0
  254. data/set-of-emails/maildir/bsd/qmail-05.eml +31 -0
  255. data/set-of-emails/maildir/bsd/qmail-06.eml +39 -0
  256. data/set-of-emails/maildir/bsd/qmail-07.eml +22 -0
  257. data/set-of-emails/maildir/bsd/qmail-08.eml +23 -0
  258. data/set-of-emails/maildir/bsd/qmail-09.eml +103 -0
  259. data/set-of-emails/maildir/bsd/rfc3464-01.eml +60 -0
  260. data/set-of-emails/maildir/bsd/rfc3464-02.eml +43 -0
  261. data/set-of-emails/maildir/bsd/rfc3464-03.eml +40 -0
  262. data/set-of-emails/maildir/bsd/rfc3464-04.eml +50 -0
  263. data/set-of-emails/maildir/bsd/rfc3464-05.eml +63 -0
  264. data/set-of-emails/maildir/bsd/rfc3464-06.eml +48 -0
  265. data/set-of-emails/maildir/bsd/rfc3464-07.eml +88 -0
  266. data/set-of-emails/maildir/bsd/rfc3464-08.eml +70 -0
  267. data/set-of-emails/maildir/bsd/rfc3464-09.eml +93 -0
  268. data/set-of-emails/maildir/bsd/rfc3464-10.eml +467 -0
  269. data/set-of-emails/maildir/bsd/rfc3464-11.eml +1171 -0
  270. data/set-of-emails/maildir/bsd/rfc3464-12.eml +101 -0
  271. data/set-of-emails/maildir/bsd/rfc3464-13.eml +131 -0
  272. data/set-of-emails/maildir/bsd/rfc3464-14.eml +121 -0
  273. data/set-of-emails/maildir/bsd/rfc3464-15.eml +144 -0
  274. data/set-of-emails/maildir/bsd/rfc3464-16.eml +36 -0
  275. data/set-of-emails/maildir/bsd/rfc3464-17.eml +109 -0
  276. data/set-of-emails/maildir/bsd/rfc3464-18.eml +149 -0
  277. data/set-of-emails/maildir/bsd/rfc3464-19.eml +65 -0
  278. data/set-of-emails/maildir/bsd/rfc3464-20.eml +145 -0
  279. data/set-of-emails/maildir/bsd/rfc3464-21.eml +146 -0
  280. data/set-of-emails/maildir/bsd/rfc3464-22.eml +105 -0
  281. data/set-of-emails/maildir/bsd/rfc3464-23.eml +21 -0
  282. data/set-of-emails/maildir/bsd/rfc3464-24.eml +27 -0
  283. data/set-of-emails/maildir/bsd/rfc3464-25.eml +33 -0
  284. data/set-of-emails/maildir/bsd/rfc3464-26.eml +98 -0
  285. data/set-of-emails/maildir/bsd/rfc3464-27.eml +180 -0
  286. data/set-of-emails/maildir/bsd/rfc3834-01.eml +37 -0
  287. data/set-of-emails/maildir/bsd/rfc3834-02.eml +51 -0
  288. data/set-of-emails/maildir/bsd/rfc3834-03.eml +33 -0
  289. data/set-of-emails/maildir/bsd/ru-mailru-01.eml +54 -0
  290. data/set-of-emails/maildir/bsd/ru-mailru-02.eml +54 -0
  291. data/set-of-emails/maildir/bsd/ru-mailru-03.eml +62 -0
  292. data/set-of-emails/maildir/bsd/ru-mailru-04.eml +54 -0
  293. data/set-of-emails/maildir/bsd/ru-yandex-01.eml +102 -0
  294. data/set-of-emails/maildir/bsd/ru-yandex-02.eml +113 -0
  295. data/set-of-emails/maildir/bsd/ru-yandex-03.eml +101 -0
  296. data/set-of-emails/maildir/bsd/sendmail-01.eml +70 -0
  297. data/set-of-emails/maildir/bsd/sendmail-02.eml +82 -0
  298. data/set-of-emails/maildir/bsd/sendmail-03.eml +76 -0
  299. data/set-of-emails/maildir/bsd/sendmail-04.eml +63 -0
  300. data/set-of-emails/maildir/bsd/sendmail-05.eml +64 -0
  301. data/set-of-emails/maildir/bsd/sendmail-06.eml +67 -0
  302. data/set-of-emails/maildir/bsd/sendmail-07.eml +65 -0
  303. data/set-of-emails/maildir/bsd/sendmail-08.eml +62 -0
  304. data/set-of-emails/maildir/bsd/sendmail-09.eml +60 -0
  305. data/set-of-emails/maildir/bsd/sendmail-10.eml +82 -0
  306. data/set-of-emails/maildir/bsd/sendmail-11.eml +60 -0
  307. data/set-of-emails/maildir/bsd/sendmail-12.eml +62 -0
  308. data/set-of-emails/maildir/bsd/sendmail-13.eml +66 -0
  309. data/set-of-emails/maildir/bsd/sendmail-14.eml +64 -0
  310. data/set-of-emails/maildir/bsd/sendmail-15.eml +60 -0
  311. data/set-of-emails/maildir/bsd/sendmail-16.eml +69 -0
  312. data/set-of-emails/maildir/bsd/sendmail-17.eml +68 -0
  313. data/set-of-emails/maildir/bsd/sendmail-18.eml +64 -0
  314. data/set-of-emails/maildir/bsd/sendmail-19.eml +71 -0
  315. data/set-of-emails/maildir/bsd/sendmail-20.eml +120 -0
  316. data/set-of-emails/maildir/bsd/sendmail-21.eml +69 -0
  317. data/set-of-emails/maildir/bsd/sendmail-22.eml +73 -0
  318. data/set-of-emails/maildir/bsd/sendmail-23.eml +137 -0
  319. data/set-of-emails/maildir/bsd/sendmail-24.eml +66 -0
  320. data/set-of-emails/maildir/bsd/sendmail-25.eml +70 -0
  321. data/set-of-emails/maildir/bsd/sendmail-26.eml +71 -0
  322. data/set-of-emails/maildir/bsd/sendmail-27.eml +69 -0
  323. data/set-of-emails/maildir/bsd/sendmail-28.eml +69 -0
  324. data/set-of-emails/maildir/bsd/sendmail-29.eml +70 -0
  325. data/set-of-emails/maildir/bsd/sendmail-30.eml +68 -0
  326. data/set-of-emails/maildir/bsd/sendmail-31.eml +80 -0
  327. data/set-of-emails/maildir/bsd/sendmail-32.eml +71 -0
  328. data/set-of-emails/maildir/bsd/sendmail-33.eml +71 -0
  329. data/set-of-emails/maildir/bsd/sendmail-34.eml +75 -0
  330. data/set-of-emails/maildir/bsd/sendmail-35.eml +70 -0
  331. data/set-of-emails/maildir/bsd/sendmail-36.eml +71 -0
  332. data/set-of-emails/maildir/bsd/sendmail-37.eml +71 -0
  333. data/set-of-emails/maildir/bsd/surfcontrol-01.eml +79 -0
  334. data/set-of-emails/maildir/bsd/surfcontrol-02.eml +70 -0
  335. data/set-of-emails/maildir/bsd/surfcontrol-03.eml +70 -0
  336. data/set-of-emails/maildir/bsd/uk-messagelabs-01.eml +76 -0
  337. data/set-of-emails/maildir/bsd/us-amazonses-01.eml +59 -0
  338. data/set-of-emails/maildir/bsd/us-amazonses-02.eml +177 -0
  339. data/set-of-emails/maildir/bsd/us-amazonses-03.eml +55 -0
  340. data/set-of-emails/maildir/bsd/us-amazonses-04.eml +55 -0
  341. data/set-of-emails/maildir/bsd/us-aol-01.eml +1258 -0
  342. data/set-of-emails/maildir/bsd/us-aol-02.eml +1257 -0
  343. data/set-of-emails/maildir/bsd/us-aol-03.eml +1264 -0
  344. data/set-of-emails/maildir/bsd/us-aol-04.eml +1260 -0
  345. data/set-of-emails/maildir/bsd/us-bigfoot-01.eml +64 -0
  346. data/set-of-emails/maildir/bsd/us-facebook-01.eml +40 -0
  347. data/set-of-emails/maildir/bsd/us-facebook-02.eml +42 -0
  348. data/set-of-emails/maildir/bsd/us-google-01.eml +70 -0
  349. data/set-of-emails/maildir/bsd/us-google-02.eml +50 -0
  350. data/set-of-emails/maildir/bsd/us-google-03.eml +51 -0
  351. data/set-of-emails/maildir/bsd/us-google-04.eml +82 -0
  352. data/set-of-emails/maildir/bsd/us-google-05.eml +50 -0
  353. data/set-of-emails/maildir/bsd/us-google-06.eml +56 -0
  354. data/set-of-emails/maildir/bsd/us-google-07.eml +42 -0
  355. data/set-of-emails/maildir/bsd/us-google-08.eml +59 -0
  356. data/set-of-emails/maildir/bsd/us-google-09.eml +76 -0
  357. data/set-of-emails/maildir/bsd/us-google-10.eml +69 -0
  358. data/set-of-emails/maildir/bsd/us-google-11.eml +68 -0
  359. data/set-of-emails/maildir/bsd/us-google-12.eml +76 -0
  360. data/set-of-emails/maildir/bsd/us-google-13.eml +79 -0
  361. data/set-of-emails/maildir/bsd/us-google-14.eml +304 -0
  362. data/set-of-emails/maildir/bsd/us-outlook-01.eml +72 -0
  363. data/set-of-emails/maildir/bsd/us-outlook-02.eml +72 -0
  364. data/set-of-emails/maildir/bsd/us-outlook-03.eml +72 -0
  365. data/set-of-emails/maildir/bsd/us-outlook-04.eml +79 -0
  366. data/set-of-emails/maildir/bsd/us-outlook-05.eml +85 -0
  367. data/set-of-emails/maildir/bsd/us-outlook-06.eml +75 -0
  368. data/set-of-emails/maildir/bsd/us-outlook-07.eml +70 -0
  369. data/set-of-emails/maildir/bsd/us-receivingses-01.eml +74 -0
  370. data/set-of-emails/maildir/bsd/us-receivingses-02.eml +74 -0
  371. data/set-of-emails/maildir/bsd/us-receivingses-03.eml +74 -0
  372. data/set-of-emails/maildir/bsd/us-receivingses-04.eml +74 -0
  373. data/set-of-emails/maildir/bsd/us-receivingses-05.eml +74 -0
  374. data/set-of-emails/maildir/bsd/us-receivingses-06.eml +74 -0
  375. data/set-of-emails/maildir/bsd/us-receivingses-07.eml +74 -0
  376. data/set-of-emails/maildir/bsd/us-sendgrid-01.eml +95 -0
  377. data/set-of-emails/maildir/bsd/us-sendgrid-02.eml +98 -0
  378. data/set-of-emails/maildir/bsd/us-sendgrid-03.eml +100 -0
  379. data/set-of-emails/maildir/bsd/us-verizon-01.eml +31 -0
  380. data/set-of-emails/maildir/bsd/us-yahoo-01.eml +78 -0
  381. data/set-of-emails/maildir/bsd/us-yahoo-02.eml +79 -0
  382. data/set-of-emails/maildir/bsd/us-yahoo-03.eml +93 -0
  383. data/set-of-emails/maildir/bsd/us-yahoo-04.eml +94 -0
  384. data/set-of-emails/maildir/bsd/us-yahoo-05.eml +94 -0
  385. data/set-of-emails/maildir/bsd/us-zoho-01.eml +40 -0
  386. data/set-of-emails/maildir/bsd/us-zoho-02.eml +38 -0
  387. data/set-of-emails/maildir/bsd/us-zoho-03.eml +37 -0
  388. data/set-of-emails/maildir/bsd/us-zoho-04.eml +47 -0
  389. data/set-of-emails/maildir/bsd/us-zoho-05.eml +37 -0
  390. data/set-of-emails/maildir/bsd/v5sendmail-01.eml +24 -0
  391. data/set-of-emails/maildir/bsd/v5sendmail-02.eml +26 -0
  392. data/set-of-emails/maildir/bsd/v5sendmail-03.eml +29 -0
  393. data/set-of-emails/maildir/bsd/v5sendmail-04.eml +29 -0
  394. data/set-of-emails/maildir/bsd/v5sendmail-05.eml +42 -0
  395. data/set-of-emails/maildir/bsd/v5sendmail-06.eml +28 -0
  396. data/set-of-emails/maildir/bsd/v5sendmail-07.eml +35 -0
  397. data/set-of-emails/maildir/bsd/x1-01.eml +61 -0
  398. data/set-of-emails/maildir/bsd/x1-02.eml +62 -0
  399. data/set-of-emails/maildir/bsd/x2-01.eml +41 -0
  400. data/set-of-emails/maildir/bsd/x2-02.eml +46 -0
  401. data/set-of-emails/maildir/bsd/x2-03.eml +34 -0
  402. data/set-of-emails/maildir/bsd/x2-04.eml +0 -0
  403. data/set-of-emails/maildir/bsd/x2-05.eml +98 -0
  404. data/set-of-emails/maildir/bsd/x3-01.eml +61 -0
  405. data/set-of-emails/maildir/bsd/x3-02.eml +64 -0
  406. data/set-of-emails/maildir/bsd/x3-03.eml +59 -0
  407. data/set-of-emails/maildir/bsd/x3-04.eml +106 -0
  408. data/set-of-emails/maildir/bsd/x4-01.eml +92 -0
  409. data/set-of-emails/maildir/bsd/x4-02.eml +112 -0
  410. data/set-of-emails/maildir/bsd/x4-03.eml +245 -0
  411. data/set-of-emails/maildir/bsd/x4-04.eml +81 -0
  412. data/set-of-emails/maildir/bsd/x4-05.eml +121 -0
  413. data/set-of-emails/maildir/bsd/x4-06.eml +32 -0
  414. data/set-of-emails/maildir/bsd/x4-07.eml +153 -0
  415. data/set-of-emails/maildir/bsd/x5-01.eml +155 -0
  416. data/set-of-emails/maildir/dos/activehunter-01.eml +54 -0
  417. data/set-of-emails/maildir/dos/apachejames-01.eml +46 -0
  418. data/set-of-emails/maildir/dos/arf-01.eml +66 -0
  419. data/set-of-emails/maildir/dos/courier-01.eml +79 -0
  420. data/set-of-emails/maildir/dos/de-einsundeins-01.eml +38 -0
  421. data/set-of-emails/maildir/dos/de-gmx-01.eml +52 -0
  422. data/set-of-emails/maildir/dos/domino-01.eml +33 -0
  423. data/set-of-emails/maildir/dos/exchange-01.eml +31 -0
  424. data/set-of-emails/maildir/dos/exim-01.eml +46 -0
  425. data/set-of-emails/maildir/dos/google-apps-01.eml +66 -0
  426. data/set-of-emails/maildir/dos/imailserver-01.eml +27 -0
  427. data/set-of-emails/maildir/dos/interscanmss-01.eml +49 -0
  428. data/set-of-emails/maildir/dos/jp-biglobe-01.eml +43 -0
  429. data/set-of-emails/maildir/dos/jp-ezweb-01.eml +36 -0
  430. data/set-of-emails/maildir/dos/jp-kddi-01.eml +49 -0
  431. data/set-of-emails/maildir/dos/mailfoundry-01.eml +50 -0
  432. data/set-of-emails/maildir/dos/mailmarshalsmtp-01.eml +43 -0
  433. data/set-of-emails/maildir/dos/mcafee-01.eml +63 -0
  434. data/set-of-emails/maildir/dos/messagingserver-01.eml +102 -0
  435. data/set-of-emails/maildir/dos/mfilter-01.eml +49 -0
  436. data/set-of-emails/maildir/dos/mxlogic-01.eml +47 -0
  437. data/set-of-emails/maildir/dos/notes-01.eml +42 -0
  438. data/set-of-emails/maildir/dos/opensmtpd-01.eml +33 -0
  439. data/set-of-emails/maildir/dos/postfix-01.eml +60 -0
  440. data/set-of-emails/maildir/dos/qmail-01.eml +40 -0
  441. data/set-of-emails/maildir/dos/rfc3464-01.eml +59 -0
  442. data/set-of-emails/maildir/dos/rfc3834-01.eml +37 -0
  443. data/set-of-emails/maildir/dos/ru-mailru-01.eml +54 -0
  444. data/set-of-emails/maildir/dos/ru-yandex-01.eml +102 -0
  445. data/set-of-emails/maildir/dos/sendmail-01.eml +69 -0
  446. data/set-of-emails/maildir/dos/surfcontrol-01.eml +79 -0
  447. data/set-of-emails/maildir/dos/uk-messagelabs-01.eml +76 -0
  448. data/set-of-emails/maildir/dos/us-amazonses-01.eml +59 -0
  449. data/set-of-emails/maildir/dos/us-aol-01.eml +1258 -0
  450. data/set-of-emails/maildir/dos/us-bigfoot-01.eml +64 -0
  451. data/set-of-emails/maildir/dos/us-facebook-01.eml +40 -0
  452. data/set-of-emails/maildir/dos/us-google-01.eml +70 -0
  453. data/set-of-emails/maildir/dos/us-outlook-01.eml +72 -0
  454. data/set-of-emails/maildir/dos/us-receivingses-01.eml +74 -0
  455. data/set-of-emails/maildir/dos/us-sendgrid-01.eml +95 -0
  456. data/set-of-emails/maildir/dos/us-verizon-01.eml +31 -0
  457. data/set-of-emails/maildir/dos/us-yahoo-01.eml +78 -0
  458. data/set-of-emails/maildir/dos/us-zoho-01.eml +40 -0
  459. data/set-of-emails/maildir/dos/v5sendmail-01.eml +24 -0
  460. data/set-of-emails/maildir/dos/x1-01.eml +61 -0
  461. data/set-of-emails/maildir/dos/x2-01.eml +41 -0
  462. data/set-of-emails/maildir/dos/x3-01.eml +61 -0
  463. data/set-of-emails/maildir/dos/x4-01.eml +90 -0
  464. data/set-of-emails/maildir/dos/x5-01.eml +155 -0
  465. data/set-of-emails/maildir/err/make-test-01.eml +70 -0
  466. data/set-of-emails/maildir/err/make-test-02.eml +70 -0
  467. data/set-of-emails/maildir/err/make-test-03.eml +64 -0
  468. data/set-of-emails/maildir/err/make-test-04.eml +64 -0
  469. data/set-of-emails/maildir/err/make-test-05.eml +66 -0
  470. data/set-of-emails/maildir/err/make-test-06.eml +118 -0
  471. data/set-of-emails/maildir/err/make-test-07.eml +26 -0
  472. data/set-of-emails/maildir/err/make-test-08.eml +67 -0
  473. data/set-of-emails/maildir/err/make-test-09.eml +55 -0
  474. data/set-of-emails/maildir/err/make-test-10.eml +69 -0
  475. data/set-of-emails/maildir/err/make-test-11.eml +64 -0
  476. data/set-of-emails/maildir/err/make-test-12.eml +66 -0
  477. data/set-of-emails/maildir/err/make-test-13.eml +67 -0
  478. data/set-of-emails/maildir/err/make-test-14.eml +66 -0
  479. data/set-of-emails/maildir/err/make-test-15.eml +70 -0
  480. data/set-of-emails/maildir/err/make-test-16.eml +68 -0
  481. data/set-of-emails/maildir/err/make-test-17.eml +68 -0
  482. data/set-of-emails/maildir/err/make-test-18.eml +68 -0
  483. data/set-of-emails/maildir/err/make-test-19.eml +69 -0
  484. data/set-of-emails/maildir/err/make-test-20.eml +67 -0
  485. data/set-of-emails/maildir/err/make-test-21.eml +69 -0
  486. data/set-of-emails/maildir/err/make-test-22.eml +66 -0
  487. data/set-of-emails/maildir/err/make-test-23.eml +70 -0
  488. data/set-of-emails/maildir/err/make-test-24.eml +69 -0
  489. data/set-of-emails/maildir/err/make-test-25.eml +67 -0
  490. data/set-of-emails/maildir/err/make-test-26.eml +69 -0
  491. data/set-of-emails/maildir/err/make-test-27.eml +69 -0
  492. data/set-of-emails/maildir/err/make-test-28.eml +66 -0
  493. data/set-of-emails/maildir/err/make-test-29.eml +68 -0
  494. data/set-of-emails/maildir/err/make-test-30.eml +68 -0
  495. data/set-of-emails/maildir/err/make-test-31.eml +80 -0
  496. data/set-of-emails/maildir/err/make-test-32.eml +66 -0
  497. data/set-of-emails/maildir/err/make-test-33.eml +68 -0
  498. data/set-of-emails/maildir/err/make-test-34.eml +56 -0
  499. data/set-of-emails/maildir/err/make-test-35.eml +59 -0
  500. data/set-of-emails/maildir/err/make-test-36.eml +53 -0
  501. data/set-of-emails/maildir/err/make-test-37.eml +62 -0
  502. data/set-of-emails/maildir/mac/activehunter-01.eml +1 -2
  503. data/set-of-emails/maildir/mac/apachejames-01.eml +1 -4
  504. data/set-of-emails/maildir/mac/arf-01.eml +1 -3
  505. data/set-of-emails/maildir/mac/courier-01.eml +1 -6
  506. data/set-of-emails/maildir/mac/de-einsundeins-01.eml +1 -1
  507. data/set-of-emails/maildir/mac/de-gmx-01.eml +1 -1
  508. data/set-of-emails/maildir/mac/domino-01.eml +1 -0
  509. data/set-of-emails/maildir/mac/exchange-01.eml +1 -0
  510. data/set-of-emails/maildir/mac/exim-01.eml +1 -1
  511. data/set-of-emails/maildir/mac/google-apps-01.eml +1 -4
  512. data/set-of-emails/maildir/mac/imailserver-01.eml +1 -0
  513. data/set-of-emails/maildir/mac/interscanmss-01.eml +1 -2
  514. data/set-of-emails/maildir/mac/jp-biglobe-01.eml +1 -2
  515. data/set-of-emails/maildir/mac/jp-ezweb-01.eml +1 -1
  516. data/set-of-emails/maildir/mac/jp-kddi-01.eml +1 -2
  517. data/set-of-emails/maildir/mac/mailfoundry-01.eml +1 -2
  518. data/set-of-emails/maildir/mac/mailmarshalsmtp-01.eml +1 -2
  519. data/set-of-emails/maildir/mac/mcafee-01.eml +1 -4
  520. data/set-of-emails/maildir/mac/messagingserver-01.eml +1 -4
  521. data/set-of-emails/maildir/mac/mfilter-01.eml +1 -3
  522. data/set-of-emails/maildir/mac/mxlogic-01.eml +1 -1
  523. data/set-of-emails/maildir/mac/notes-01.eml +1 -2
  524. data/set-of-emails/maildir/mac/opensmtpd-01.eml +1 -0
  525. data/set-of-emails/maildir/mac/postfix-01.eml +1 -3
  526. data/set-of-emails/maildir/mac/qmail-01.eml +1 -1
  527. data/set-of-emails/maildir/mac/rfc3464-01.eml +1 -4
  528. data/set-of-emails/maildir/mac/rfc3834-01.eml +1 -0
  529. data/set-of-emails/maildir/mac/ru-mailru-01.eml +1 -1
  530. data/set-of-emails/maildir/mac/ru-yandex-01.eml +1 -4
  531. data/set-of-emails/maildir/mac/sendmail-01.eml +1 -4
  532. data/set-of-emails/maildir/mac/surfcontrol-01.eml +1 -5
  533. data/set-of-emails/maildir/mac/uk-messagelabs-01.eml +1 -4
  534. data/set-of-emails/maildir/mac/us-amazonses-01.eml +1 -4
  535. data/set-of-emails/maildir/mac/us-aol-01.eml +1 -15
  536. data/set-of-emails/maildir/mac/us-bigfoot-01.eml +1 -4
  537. data/set-of-emails/maildir/mac/us-facebook-01.eml +1 -4
  538. data/set-of-emails/maildir/mac/us-google-01.eml +1 -1
  539. data/set-of-emails/maildir/mac/us-outlook-01.eml +1 -4
  540. data/set-of-emails/maildir/mac/us-receivingses-01.eml +1 -4
  541. data/set-of-emails/maildir/mac/us-sendgrid-01.eml +1 -3
  542. data/set-of-emails/maildir/mac/us-verizon-01.eml +1 -2
  543. data/set-of-emails/maildir/mac/us-yahoo-01.eml +1 -1
  544. data/set-of-emails/maildir/mac/us-zoho-01.eml +1 -2
  545. data/set-of-emails/maildir/mac/v5sendmail-01.eml +1 -0
  546. data/set-of-emails/maildir/mac/x1-01.eml +1 -4
  547. data/set-of-emails/maildir/mac/x2-01.eml +1 -1
  548. data/set-of-emails/maildir/mac/x3-01.eml +1 -3
  549. data/set-of-emails/maildir/mac/x4-01.eml +1 -2
  550. data/set-of-emails/maildir/mac/x5-01.eml +1 -8
  551. data/set-of-emails/maildir/not/is-not-bounce-01.eml +25 -0
  552. data/set-of-emails/to-be-debugged-because/reason-is-onhold/onhold-0001.eml +85 -0
  553. data/set-of-emails/to-be-debugged-because/reason-is-undefined/undefined-0002.eml +27 -0
  554. data/set-of-emails/to-be-debugged-because/reason-is-undefined/undefined-0003.eml +78 -0
  555. data/set-of-emails/to-be-debugged-because/sisimai-cannot-parse-yet/cannot-parse-this-email-0002.eml +25 -0
  556. data/set-of-emails/to-be-debugged-because/something-is-wrong/issue-106-01.eml +79 -0
  557. data/set-of-emails/to-be-debugged-because/something-is-wrong/issue-106-02.eml +72 -0
  558. data/set-of-emails/to-be-debugged-because/something-is-wrong/issue-106-03.eml +68 -0
  559. data/set-of-emails/to-be-debugged-because/something-is-wrong/no-message-id-from-pr-150.eml +75 -0
  560. data/set-of-emails/to-be-parsed-for-test/README.md +20 -0
  561. data/sisimai.gemspec +25 -0
  562. metadata +647 -0
data/bin/setup ADDED
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
data/lib/sisimai.rb ADDED
@@ -0,0 +1,60 @@
1
+ require 'sisimai/version'
2
+
3
+ # Sisimai is the system formerly known as bounceHammer 4, is a Ruby module for
4
+ # analyzing bounce mails and generate structured data in a JSON format (YAML is
5
+ # also available if "YAML" module is installed on your system) from parsed bounce
6
+ # messages. Sisimai is a coined word: Sisi (the number 4 is pronounced "Si" in
7
+ # Japanese) and MAI (acronym of "Mail Analyzing Interface").
8
+ module Sisimai
9
+ # Imported from p5-Sisimail/lib/Sisimai.pm
10
+ class << self
11
+ def version(); return Sisimai::VERSION; end
12
+ def sysname(); return 'bouncehammer'; end
13
+ def libname(); return 'Sisimai'; end
14
+
15
+ # Wrapper method for parsing mailbox/maidir
16
+ # @param [String] path Path to mbox or Maildir/
17
+ # @return [Array] Parsed objects
18
+ # @return [nil] nil if the argument was wrong or an empty array
19
+ def make(path)
20
+ return nil unless path
21
+
22
+ require 'sisimai/mail'
23
+ mail = Sisimai::Mail.new(path)
24
+ list = []
25
+
26
+ return nil unless mail
27
+ require 'sisimai/data'
28
+ require 'sisimai/message'
29
+
30
+ while r = mail.read do
31
+ # Read and parse each mail file
32
+ mesg = Sisimai::Message.new(data: r)
33
+ next if mesg.void
34
+ data = Sisimai::Data.make(data: mesg)
35
+ next unless data
36
+ list.concat(data) if data.size > 0
37
+ end
38
+
39
+ return nil if list.size == 0
40
+ return list
41
+ end
42
+
43
+ # Wrapper method to parse mailbox/Maildir and dump as JSON
44
+ # @param [String] path Path to mbox or Maildir/
45
+ # @return [String] Parsed data as JSON text
46
+ def dump(path)
47
+ return nil unless path
48
+
49
+ require 'json'
50
+ parseddata = Sisimai.make(path) || []
51
+ jsonoption = JSON::state.new
52
+
53
+ jsonoption.space = ' '
54
+ jsonoption.object_nl = ' '
55
+
56
+ return JSON.generate(parseddata, jsonoption)
57
+ end
58
+ end
59
+
60
+ end
@@ -0,0 +1,218 @@
1
+ module Sisimai
2
+ # Sisimai::Address provide methods for dealing email address.
3
+ class Address
4
+ # Imported from p5-Sisimail/lib/Sisimai/Address.pm
5
+ require 'sisimai/rfc5322'
6
+
7
+ # Return pseudo recipient or sender address
8
+ # @param [String] argv1 Address type: 'r' or 's'
9
+ # @return [String, Nil] Pseudo recipient address or sender address or
10
+ # Undef when the $argv1 is neither 'r' nor 's'
11
+ def self.undisclosed(argv1)
12
+ return nil unless argv1
13
+ return nil unless ['r', 's'].index(argv1)
14
+
15
+ local = argv1 == 'r' ? 'recipient' : 'sender'
16
+ return sprintf('undisclosed-%s-in-headers@dummy-domain.invalid', local)
17
+ end
18
+
19
+
20
+ # Email address parser
21
+ # @param [Array] argvs List of strings including email address
22
+ # @return [Array, Nil] Email address list or Undef when there is no
23
+ # email address in the argument
24
+ # @example Parse email address
25
+ # parse( [ 'Neko <neko@example.cat>' ] ) #=> [ 'neko@example.cat' ]
26
+ def self.parse(argvs)
27
+ addrs = []
28
+ argvs.each do |e|
29
+ # Parse each element in the array
30
+ # 1. The element must include '@'.
31
+ # 2. The element must not include character except from 0x20 to 0x7e.
32
+ next unless e
33
+ next unless e =~ /[@]/
34
+ next if e =~ /[^\x20-\x7e]/
35
+
36
+ v = Sisimai::Address.s3s4(e)
37
+ if v.size > 0
38
+ # The element includes a valid email address
39
+ addrs << v
40
+ end
41
+ end
42
+
43
+ return nil unless addrs.size > 0
44
+ return addrs
45
+ end
46
+
47
+ # Runs like ruleset 3,4 of sendmail.cf
48
+ # @param [String] email Text including an email address
49
+ # @return [String] Email address without comment, brackets
50
+ # @example Parse email address
51
+ # s3s4( '<neko@example.cat>' ) #=> 'neko@example.cat'
52
+ def self.s3s4(input)
53
+ unless input =~ /[ ]/
54
+ # no space character between " and < .
55
+ # no space character between " and < .
56
+ input = input.sub(/\A(.+)"<(.+)\z/, '\1" <\2') # "=?ISO-2022-JP?B?....?="<user@example.jp>,
57
+ input = input.sub(/\A(.+)[?]=<(.+)\z/, '\1?= <\2') # =?ISO-2022-JP?B?....?=<user@example.jp>
58
+
59
+ # comment-part<localpart@domainpart>
60
+ input = input.sub(/[<]/, ' <') unless input =~ /\A[<]/
61
+ input = input.sub(/[>]/, '> ') unless input =~ /[>]\z/
62
+ end
63
+
64
+ canon = ''
65
+ addrs = []
66
+ token = input.split(' ')
67
+
68
+ token.map! do |e|
69
+ # Convert character entity; "&lt;" -> ">", "&gt;" -> "<".
70
+ e = e.gsub(/&lt;/, '<')
71
+ e = e.gsub(/&gt;/, '>')
72
+ e = e.gsub(/,\z/, '')
73
+ end
74
+
75
+ if token.size == 1
76
+ addrs << token[0]
77
+
78
+ else
79
+ token.each do |e|
80
+ e.chomp
81
+ next unless e =~ /\A[<]?.+[@][-.0-9A-Za-z]+[.]?[A-Za-z]{2,}[>]?\z/
82
+ addrs << e
83
+ end
84
+ end
85
+
86
+ if addrs.size > 1
87
+ # Get the first element which is <...> format string from @addrs array.
88
+ canon = addrs.detect { |e| e =~ /\A[<].+[>]\z/ } || ''
89
+ canon = addrs[0] if canon.size < 1
90
+
91
+ else
92
+ canon = addrs.shift
93
+ end
94
+
95
+ return '' if !canon || canon == ''
96
+ canon = canon.delete('<>[]():;') # Remove brackets, colons
97
+
98
+ if canon =~ /\A["].+["][@].+\z/
99
+ canon = canon.delete(%q|{}'`|) # "localpart..."@example.jp
100
+ else
101
+ canon = canon.delete(%q|{}'"`|) # Remove brackets, quotations
102
+ end
103
+
104
+ return canon
105
+ end
106
+
107
+ # Expand VERP: Get the original recipient address from VERP
108
+ # @param [String] email VERP Address
109
+ # @return [String] Email address
110
+ # @example Expand VERP address
111
+ # expand_verp('bounce+neko=example.jp@example.org') #=> 'neko@example.jp'
112
+ def self.expand_verp(email)
113
+ local = email.split('@', 2).first
114
+ verp0 = ''
115
+
116
+ if cv = local.match(/\A[-_\w]+?[+](\w[-._\w]+\w)[=](\w[-.\w]+\w)\z/)
117
+ verp0 = cv[1] + '@' + cv[2]
118
+ return verp0 if Sisimai::RFC5322.is_emailaddress(verp0)
119
+
120
+ else
121
+ return ''
122
+ end
123
+ end
124
+
125
+ # Expand alias: remove from '+' to '@'
126
+ # @param [String] email Email alias string
127
+ # @return [String] Expanded email address
128
+ # @example Expand alias
129
+ # expand_alias('neko+straycat@example.jp') #=> 'neko@example.jp'
130
+ def self.expand_alias(email)
131
+ return '' unless Sisimai::RFC5322.is_emailaddress(email)
132
+
133
+ local = email.split('@')
134
+ value = ''
135
+ if cv = local[0].match(/\A([-_\w]+?)[+].+\z/)
136
+ value = sprintf('%s@%s', cv[1], local[1])
137
+ end
138
+ return value
139
+ end
140
+
141
+ @@roaccessors = [
142
+ :address, # [String] Email address
143
+ :user, # [String] local part of the email address
144
+ :host, # [String] domain part of the email address
145
+ :verp, # [String] VERP
146
+ :alias, # [String] alias of the email address
147
+ ]
148
+ @@roaccessors.each { |e| attr_reader e }
149
+
150
+ # Constructor of Sisimai::Address
151
+ # @param <str> [String] email Email address
152
+ # @return [Sisimai::Address, Nil] Object or Undef when the email
153
+ # address was not valid
154
+ def initialize(email)
155
+ return nil unless email
156
+
157
+ if cv = email.match(/\A([^@]+)[@]([^@]+)\z/)
158
+ # Get the local part and the domain part from the email address
159
+ lpart = cv[1]
160
+ dpart = cv[2]
161
+
162
+ # Remove MIME-Encoded comment part
163
+ lpart = lpart.sub(/\A=[?].+[?]b[?].+[?]=/, '')
164
+ lpart = lpart.delete(%q|`'"<>|) unless lpart =~ /\A["].+["]\z/
165
+
166
+ aflag = false
167
+ addr0 = sprintf('%s@%s', lpart, dpart)
168
+ addr1 = Sisimai::Address.expand_verp(addr0)
169
+
170
+ if addr1.size < 1
171
+ addr1 = Sisimai::Address.expand_alias(addr0)
172
+ aflag = true if addr1.size > 0
173
+ end
174
+
175
+ if addr1.size > 0
176
+ # The email address is VERP or alias
177
+ addrs = addr1.split('@')
178
+ if aflag
179
+ # The email address is an alias
180
+ @alias = addr0
181
+
182
+ else
183
+ # The email address is a VERP
184
+ @verp = addr0
185
+ end
186
+ @user = addrs[0]
187
+ @host = addrs[1]
188
+
189
+ else
190
+ # The email address is neither VERP nor alias.
191
+ @user = lpart
192
+ @host = dpart
193
+
194
+ end
195
+ @address = sprintf('%s@%s', @user, @host)
196
+ @alias ||= ''
197
+ @verp ||= ''
198
+
199
+ else
200
+ return nil
201
+ end
202
+ end
203
+
204
+ # Check whether the object has valid content or not
205
+ # @return [True,False] returns true if the object is void
206
+ def void
207
+ return true unless @address
208
+ return false
209
+ end
210
+
211
+ # Returns the value of address as String
212
+ # @return [String] Email address
213
+ def to_json
214
+ return self.address.to_s
215
+ end
216
+
217
+ end
218
+ end
@@ -0,0 +1,343 @@
1
+ module Sisimai
2
+ # Sisimai::ARF is a parser for email returned as a FeedBack Loop report message.
3
+ module ARF
4
+ # Imported from p5-Sisimail/lib/Sisimai/Message.pm
5
+ class << self
6
+ require 'sisimai/mta'
7
+ require 'sisimai/rfc5322'
8
+
9
+ Re0 = {
10
+ :'content-type' => %r|multipart/mixed|,
11
+ :'report-type' => %r/report-type=["]?feedback-report["]?/,
12
+ :'from' => %r{(?:
13
+ staff[@]hotmail[.]com\z
14
+ |complaints[@]email-abuse[.]amazonses[.]com\z
15
+ )
16
+ }x,
17
+ :'subject' => %r/complaint[ ]about[ ]message[ ]from[ ]/,
18
+ }
19
+ # http://tools.ietf.org/html/rfc5965
20
+ # http://en.wikipedia.org/wiki/Feedback_loop_(email)
21
+ # http://en.wikipedia.org/wiki/Abuse_Reporting_Format
22
+ #
23
+ # Netease DMARC uses: This is a spf/dkim authentication-failure report for an email message received from IP
24
+ # OpenDMARC 1.3.0 uses: This is an authentication failure report for an email message received from IP
25
+ # Abusix ARF uses this is an autogenerated email abuse complaint regarding your network.
26
+ Re1 = {
27
+ :begin => %r{\A(?>
28
+ [Tt]his[ ]is[ ].+[ ]email[ ]abuse[ ]report
29
+ |[Tt]his[ ]is[ ](?:
30
+ an[ ]autogenerated[ ]email[ ]abuse[ ]complaint
31
+ |an?[ ].+[ ]report[ ]for
32
+ |a[ ].+[ ]authentication[ -]failure[ ]report[ ]for
33
+ )
34
+ )
35
+ }x,
36
+ :rfc822 => %r[\AContent-Type: (:?message/rfc822|text/rfc822-headers)],
37
+ :endof => %r/\A__END_OF_EMAIL_MESSAGE__\z/,
38
+ }
39
+ Indicators = Sisimai::MTA.INDICATORS
40
+ LongFields = Sisimai::RFC5322.LONGFIELDS
41
+ RFC822Head = Sisimai::RFC5322.HEADERFIELDS
42
+
43
+ def description; return 'Abuse Feedback Reporting Format'; end
44
+ def smtpagent; return 'FeedBack-Loop'; end
45
+ def headerlist; return []; end
46
+ def pattern; return Re0; end
47
+
48
+ # Email is a Feedback-Loop message or not
49
+ # @param [Hash] heads Email header including "Content-Type", "From",
50
+ # and "Subject" field
51
+ # @return [True,False] true: Feedback Loop
52
+ # false: is not Feedback loop
53
+ def is_arf(heads)
54
+ return false unless heads
55
+ match = false
56
+
57
+ if heads['content-type'] =~ Re0[:'report-type']
58
+ # Content-Type: multipart/report; report-type=feedback-report; ...
59
+ match = true
60
+
61
+ elsif heads['content-type'] =~ Re0[:'content-type']
62
+ # Microsoft (Hotmail, MSN, Live, Outlook) uses its own report format.
63
+ # Amazon SES Complaints bounces
64
+ if heads['from'] =~ Re0[:'from'] && heads['subject'] =~ Re0[:'subject']
65
+ # From: staff@hotmail.com
66
+ # From: complaints@email-abuse.amazonses.com
67
+ # Subject: complaint about message from 192.0.2.1
68
+ match = true
69
+ end
70
+ end
71
+ return match
72
+ end
73
+
74
+ # Detect an error for Feedback Loop
75
+ # @param [Hash] mhead Message header of a bounce email
76
+ # @options mhead [String] from From header
77
+ # @options mhead [String] date Date header
78
+ # @options mhead [String] subject Subject header
79
+ # @options mhead [Array] received Received headers
80
+ # @options mhead [String] others Other required headers
81
+ # @param [String] mbody Message body of a bounce email
82
+ # @return [Hash, Nil] Bounce data list and message/rfc822 part
83
+ # or Undef if it failed to parse or the
84
+ # arguments are missing
85
+ def scan(mhead, mbody)
86
+ return nil unless self.is_arf(mhead)
87
+
88
+ require 'sisimai/address'
89
+ dscontents = []; dscontents << Sisimai::MTA.DELIVERYSTATUS
90
+ hasdivided = mbody.split("\n")
91
+ havepassed = ['']
92
+ rfc822next = { 'from' => false, 'to' => false, 'subject' => false }
93
+ rfc822part = '' # (String) message/rfc822-headers part
94
+ previousfn = '' # (String) Previous field name
95
+ readcursor = 0 # (Integer) Points the current cursor position
96
+ recipients = 0 # (Integer) The number of 'Final-Recipient' header
97
+ rcptintext = '' # (String) Recipient address in the message body
98
+ commondata = {
99
+ 'diagnosis' => '', # Error message
100
+ 'from' => '', # Original-Mail-From:
101
+ 'rhost' => '', # Reporting-MTA:
102
+ }
103
+ arfheaders = {
104
+ 'feedbacktype' => nil, # FeedBack-Type:
105
+ 'rhost' => nil, # Source-IP:
106
+ 'agent' => nil, # User-Agent:
107
+ 'date' => nil, # Arrival-Date:
108
+ 'authres' => nil, # Authentication-Results:
109
+ }
110
+ v = nil
111
+
112
+ # 3.1. Required Fields
113
+ #
114
+ # The following report header fields MUST appear exactly once:
115
+ #
116
+ # o "Feedback-Type" contains the type of feedback report (as defined
117
+ # in the corresponding IANA registry and later in this memo). This
118
+ # is intended to let report parsers distinguish among different
119
+ # types of reports.
120
+ #
121
+ # o "User-Agent" indicates the name and version of the software
122
+ # program that generated the report. The format of this field MUST
123
+ # follow section 14.43 of [HTTP]. This field is for documentation
124
+ # only; there is no registry of user agent names or versions, and
125
+ # report receivers SHOULD NOT expect user agent names to belong to a
126
+ # known set.
127
+ #
128
+ # o "Version" indicates the version of specification that the report
129
+ # generator is using to generate the report. The version number in
130
+ # this specification is set to "1".
131
+ #
132
+ hasdivided.each do |e|
133
+ # Save the current line for the next loop
134
+ havepassed << e; p = havepassed[-2]
135
+
136
+ if readcursor == 0
137
+ # Beginning of the bounce message or delivery status part
138
+ if e =~ Re1[:begin]
139
+ readcursor |= Indicators[:'deliverystatus']
140
+ next
141
+ end
142
+ end
143
+
144
+ if readcursor & Indicators[:'message-rfc822'] == 0
145
+ # Beginning of the original message part
146
+ if e =~ Re1[:rfc822]
147
+ readcursor |= Indicators[:'message-rfc822']
148
+ next
149
+ end
150
+ end
151
+
152
+ if readcursor & Indicators[:'message-rfc822'] > 0
153
+ # After "message/rfc822"
154
+ if cv = e.match(/X-HmXmrOriginalRecipient:[ ]*(.+)\z/)
155
+ # Microsoft ARF: original recipient.
156
+ dscontents[-1]['recipient'] = Sisimai::Address.s3s4(cv[1])
157
+ recipients += 1
158
+
159
+ # The "X-HmXmrOriginalRecipient" header appears only once so
160
+ # we take this opportunity to hard-code ARF headers missing in
161
+ # Microsoft's implementation.
162
+ arfheaders['feedbacktype'] = 'abuse'
163
+ arfheaders['agent'] = 'Microsoft Junk Mail Reporting Program'
164
+
165
+ elsif cv = e.match(/\AFrom:[ ]*(.+)\z/)
166
+ # Microsoft ARF: original sender.
167
+ if commondata['from'].empty?
168
+ commondata['from'] = Sisimai::Address.s3s4(cv[1])
169
+ end
170
+
171
+ elsif cv = e.match(/\A([-0-9A-Za-z]+?)[:][ ]*(.+)\z/)
172
+ # Get required headers only
173
+ lhs = cv[1].downcase
174
+ rhs = cv[2]
175
+
176
+ previousfn = ''
177
+ next unless RFC822Head.key?(lhs)
178
+
179
+ previousfn = lhs
180
+ rfc822part += e + "\n"
181
+ rcptintext = rhs if lhs == 'to'
182
+
183
+ elsif e =~ /\A[ \t]+/
184
+ # Continued line from the previous line
185
+ rfc822part += e + "\n" if LongFields.key?(previousfn)
186
+ next if e.size > 0
187
+ rcptintext += e if previousfn == 'to'
188
+ end
189
+
190
+ else
191
+ # Before "message/rfc822"
192
+ next unless readcursor & Indicators[:'deliverystatus'] > 0
193
+ next unless e.size > 0
194
+
195
+ # Feedback-Type: abuse
196
+ # User-Agent: SomeGenerator/1.0
197
+ # Version: 0.1
198
+ # Original-Mail-From: <somespammer@example.net>
199
+ # Original-Rcpt-To: <kijitora@example.jp>
200
+ # Received-Date: Thu, 29 Apr 2009 00:00:00 JST
201
+ # Source-IP: 192.0.2.1
202
+ v = dscontents[-1]
203
+
204
+ if cv = e.match(/\AOriginal-Rcpt-To:[ ]+[<]?(.+)[>]?\z/) ||
205
+ cv = e.match(/\ARedacted-Address:[ ]([^ ].+[@])\z/)
206
+ # Original-Rcpt-To header field is optional and may appear any
207
+ # number of times as appropriate:
208
+ # Original-Rcpt-To: <user@example.com>
209
+ # Redacted-Address: localpart@
210
+ if v['recipient']
211
+ # There are multiple recipient addresses in the message body.
212
+ dscontents << Sisimai::MTA.DELIVERYSTATUS
213
+ v = dscontents[-1]
214
+ end
215
+ v['recipient'] = Sisimai::Address.s3s4(cv[1])
216
+ recipients += 1
217
+
218
+ elsif cv = e.match(/\AFeedback-Type:[ ]*([^ ]+)\z/)
219
+ # The header field MUST appear exactly once.
220
+ # Feedback-Type: abuse
221
+ arfheaders['feedbacktype'] = cv[1]
222
+
223
+ elsif cv = e.match(/\AAuthentication-Results:[ ]*(.+)\z/)
224
+ # "Authentication-Results" indicates the result of one or more
225
+ # authentication checks run by the report generator.
226
+ #
227
+ # Authentication-Results: mail.example.com;
228
+ # spf=fail smtp.mail=somespammer@example.com
229
+ arfheaders['authres'] = cv[1]
230
+
231
+ elsif cv = e.match(/\AUser-Agent:[ ]*(.+)\z/)
232
+ # The header field MUST appear exactly once.
233
+ # User-Agent: SomeGenerator/1.0
234
+ arfheaders['agent'] = cv[1]
235
+
236
+ elsif cv = e.match(/\A(?:Received|Arrival)-Date:[ ]*(.+)\z/)
237
+ # Arrival-Date header is optional and MUST NOT appear more than
238
+ # once.
239
+ # Received-Date: Thu, 29 Apr 2010 00:00:00 JST
240
+ # Arrival-Date: Thu, 29 Apr 2010 00:00:00 +0000
241
+ arfheaders['date'] = cv[1]
242
+
243
+ elsif cv = e.match(/\AReporting-MTA:[ ]*dns;[ ]*(.+)\z/)
244
+ # The header is optional and MUST NOT appear more than once.
245
+ # Reporting-MTA: dns; mx.example.jp
246
+ commondata['rhost'] = cv[1]
247
+
248
+ elsif cv = e.match(/\ASource-IP:[ ]*(.+)\z/)
249
+ # The header is optional and MUST NOT appear more than once.
250
+ # Source-IP: 192.0.2.45
251
+ arfheaders['rhost'] = cv[1]
252
+
253
+ elsif cv = e.match(/\AOriginal-Mail-From:[ ]*(.+)\z/)
254
+ # the header is optional and MUST NOT appear more than once.
255
+ # Original-Mail-From: <somespammer@example.net>
256
+ if commondata['from'].empty?
257
+ commondata['from'] = Sisimai::Address.s3s4(cv[1])
258
+ end
259
+
260
+ elsif e =~ Re1[:begin]
261
+ # This is an email abuse report for an email message with the
262
+ # message-id of 0000-000000000000000000000000000000000@mx
263
+ # received from IP address 192.0.2.1 on
264
+ # Thu, 29 Apr 2010 00:00:00 +0900 (JST)
265
+ commondata['diagnosis'] = e
266
+ end
267
+ end
268
+ end
269
+
270
+ if arfheaders['feedbacktype'] == 'auth-failure' && arfheaders['authres']
271
+ # Append the value of Authentication-Results header
272
+ commondata['diagnosis'] += ' ' + arfheaders['authres']
273
+ end
274
+
275
+ if recipients == 0
276
+ # Insert pseudo recipient address when there is no valid recipient
277
+ # address in the message.
278
+ dscontents[-1]['recipient'] = Sisimai::Address.undisclosed('r')
279
+ recipients = 1
280
+ end
281
+
282
+ unless rfc822part =~ /\bFrom: [^ ]+[@][^ ]+\b/
283
+ # There is no "From:" header in the original message
284
+ if commondata['from'].size > 0
285
+ # Append the value of "Original-Mail-From" value as a sender address.
286
+ rfc822part += sprintf("From: %s\n", commondata['from'])
287
+ end
288
+ end
289
+
290
+ if cv = mhead['subject'].match(/complaint about message from (\d{1,3}[.]\d{1,3}[.]\d{1,3}[.]\d{1,3})/)
291
+ # Microsoft ARF: remote host address.
292
+ arfheaders['rhost'] = cv[1]
293
+ commondata['diagnosis'] = sprintf(
294
+ 'This is a Microsoft email abuse report for an email message received from IP %s on %s',
295
+ arfheaders['rhost'], mhead['date'])
296
+ end
297
+
298
+ dscontents.map do |e|
299
+ if e['recipient'] =~ /\A[^ ]+[@]\z/
300
+ # AOL = http://forums.cpanel.net/f43/aol-brutal-work-71473.html
301
+ e['recipient'] = Sisimai::Address.s3s4(rcptintext)
302
+ end
303
+ arfheaders.each_key { |a| e[a] ||= arfheaders[a] || '' }
304
+ e.delete('authres')
305
+
306
+ e['softbounce'] = -1
307
+ e['diagnosis'] = commondata['diagnosis'] unless e['diagnosis']
308
+ e['date'] = mhead['date'] if e['date'].empty?
309
+
310
+ if e['rhost'].empty?
311
+ # Get the remote IP address from the message body
312
+ if commondata['rhost'].size > 0
313
+ # The value of "Reporting-MTA" header
314
+ e['rhost'] = commondata['rhost']
315
+
316
+ elsif cv = e['diagnosis'].match(/\breceived from IP address ([^ ]+)/)
317
+ # This is an email abuse report for an email message received
318
+ # from IP address 24.64.1.1 on Thu, 29 Apr 2010 00:00:00 +0000
319
+ e['rhost'] = cv[1]
320
+ end
321
+ end
322
+
323
+ if mhead['received'].size > 0
324
+ # Get localhost and remote host name from Received header.
325
+ r0 = mhead['received']
326
+ ['lhost', 'rhost'].each { |a| e[a] ||= '' }
327
+ e['lhost'] = Sisimai::RFC5322.received(r0[0]).shift if e['lhost'].empty?
328
+ e['rhost'] = Sisimai::RFC5322.received(r0[-1]).pop if e['rhost'].empty?
329
+ end
330
+
331
+ e['spec'] = 'SMTP'
332
+ e['action'] = 'failed'
333
+ e['reason'] = 'feedback'
334
+ e['command'] = ''
335
+ e['status'] = ''
336
+ e['alias'] = ''
337
+ e['agent'] = self.smtpagent if e['agent'].empty?
338
+ end
339
+ return { 'ds' => dscontents, 'rfc822' => rfc822part }
340
+ end
341
+ end
342
+ end
343
+ end