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
@@ -1,5 +1,6 @@
1
1
  module Sisimai::Lhost
2
- # Sisimai::Lhost::Exchange2007 parses a bounce email which created by Microsoft Exchange Server 2007.
2
+ # Sisimai::Lhost::Exchange2007 decodes a bounce email which created by Microsoft Exchange Server
3
+ # 2007 https://www.microsoft.com/microsoft-365/exchange/email.
3
4
  # Methods in the module are called from only Sisimai::Message.
4
5
  module Exchange2007
5
6
  class << self
@@ -7,156 +8,166 @@ module Sisimai::Lhost
7
8
 
8
9
  Indicators = Sisimai::Lhost.INDICATORS
9
10
  Boundaries = [
10
- 'Original message headers:', # en-US
11
+ "Original Message Headers",
12
+ "Original message headers:", # en-US
11
13
  "tes de message d'origine :", # fr-FR/En-têtes de message d'origine
12
- 'Intestazioni originali del messaggio:', # it-CH
14
+ "Intestazioni originali del messaggio:", # it-CH
15
+ "Ursprungshuvuden:", # sv-SE
13
16
  ].freeze
14
- MarkingsOf = {
17
+ StartingOf = {
18
+ error: [" RESOLVER.", " QUEUE."],
15
19
  message: [
16
- 'Diagnostic information for administrators:', # en-US
17
- 'Informations de diagnostic pour les administrateurs', # fr-FR
18
- 'Informazioni di diagnostica per gli amministratori', # it-CH
20
+ "Error Details",
21
+ "Diagnostic information for administrators:", # en-US
22
+ "Informations de diagnostic pour les administrateurs", # fr-FR
23
+ "Informazioni di diagnostica per gli amministratori", # it-CH
24
+ "Diagnostisk information f", # sv-SE
19
25
  ],
20
- error: [' RESOLVER.', ' QUEUE.'],
21
26
  rhost: [
22
- 'Generating server', # en-US
23
- 'Serveur de g', # fr-FR/Serveur de g�Hn�Hration
24
- 'Server di generazione', # it-CH
27
+ "DSN generated by:",
28
+ "Generating server", # en-US
29
+ "Serveur de g", # fr-FR/Serveur de g�Hn�Hration
30
+ "Server di generazione", # it-CH
31
+ "Genererande server", # sv-SE
25
32
  ]
26
33
  }.freeze
27
34
  NDRSubject = {
28
- 'SMTPSEND.DNS.NonExistentDomain' => 'hostunknown', # 554 5.4.4 SMTPSEND.DNS.NonExistentDomain
29
- 'SMTPSEND.DNS.MxLoopback' => 'networkerror', # 554 5.4.4 SMTPSEND.DNS.MxLoopback
30
- 'RESOLVER.ADR.BadPrimary' => 'systemerror', # 550 5.2.0 RESOLVER.ADR.BadPrimary
31
- 'RESOLVER.ADR.RecipNotFound' => 'userunknown', # 550 5.1.1 RESOLVER.ADR.RecipNotFound
32
- 'RESOLVER.ADR.ExRecipNotFound' => 'userunknown', # 550 5.1.1 RESOLVER.ADR.ExRecipNotFound
33
- 'RESOLVER.ADR.RecipLimit' => 'toomanyconn', # 550 5.5.3 RESOLVER.ADR.RecipLimit
34
- 'RESOLVER.ADR.InvalidInSmtp' => 'systemerror', # 550 5.1.0 RESOLVER.ADR.InvalidInSmtp
35
- 'RESOLVER.ADR.Ambiguous' => 'systemerror', # 550 5.1.4 RESOLVER.ADR.Ambiguous, 420 4.2.0 RESOLVER.ADR.Ambiguous
36
- 'RESOLVER.RST.AuthRequired' => 'securityerror', # 550 5.7.1 RESOLVER.RST.AuthRequired
37
- 'RESOLVER.RST.NotAuthorized' => 'rejected', # 550 5.7.1 RESOLVER.RST.NotAuthorized
38
- 'RESOLVER.RST.RecipSizeLimit' => 'mesgtoobig', # 550 5.2.3 RESOLVER.RST.RecipSizeLimit
39
- 'QUEUE.Expired' => 'expired', # 550 4.4.7 QUEUE.Expired
35
+ "SMTPSEND.DNS.NonExistentDomain" => "hostunknown", # 554 5.4.4 SMTPSEND.DNS.NonExistentDomain
36
+ "SMTPSEND.DNS.MxLoopback" => "networkerror", # 554 5.4.4 SMTPSEND.DNS.MxLoopback
37
+ "RESOLVER.ADR.BadPrimary" => "systemerror", # 550 5.2.0 RESOLVER.ADR.BadPrimary
38
+ "RESOLVER.ADR.RecipNotFound" => "userunknown", # 550 5.1.1 RESOLVER.ADR.RecipNotFound
39
+ "RESOLVER.ADR.RecipientNotFound" => "userunknown", # 550 5.1.1 RESOLVER.ADR.RecipientNotFound
40
+ "RESOLVER.ADR.ExRecipNotFound" => "userunknown", # 550 5.1.1 RESOLVER.ADR.ExRecipNotFound
41
+ "RESOLVER.ADR.RecipLimit" => "toomanyconn", # 550 5.5.3 RESOLVER.ADR.RecipLimit
42
+ "RESOLVER.ADR.InvalidInSmtp" => "systemerror", # 550 5.1.0 RESOLVER.ADR.InvalidInSmtp
43
+ "RESOLVER.ADR.Ambiguous" => "systemerror", # 550 5.1.4 RESOLVER.ADR.Ambiguous, 420 4.2.0 RESOLVER.ADR.Ambiguous
44
+ "RESOLVER.RST.AuthRequired" => "securityerror", # 550 5.7.1 RESOLVER.RST.AuthRequired
45
+ "RESOLVER.RST.NotAuthorized" => "rejected", # 550 5.7.1 RESOLVER.RST.NotAuthorized
46
+ "RESOLVER.RST.RecipSizeLimit" => "exceedlimit", # 550 5.2.3 RESOLVER.RST.RecipSizeLimit
47
+ "QUEUE.Expired" => "expired", # 550 4.4.7 QUEUE.Expired
40
48
  }.freeze
49
+ MailSender = ["postmaster@outlook.com", ".onmicrosoft.com"].freeze
50
+ EmailTitle = [
51
+ # Subject: Content-Language:
52
+ "Undeliverable", # en-US
53
+ "Non_remis_", # fr-FR
54
+ "Non remis ", # fr-FR
55
+ "Non recapitabile", # it-CH
56
+ "Olevererbart", # sv-SE
57
+ ].freeze
41
58
 
42
- # Parse bounce messages from Microsoft Exchange Server 2007
59
+ # @abstract Decodes the bounce message from Microsoft Exchange Server 2007
43
60
  # @param [Hash] mhead Message headers of a bounce email
44
61
  # @param [String] mbody Message body of a bounce email
45
62
  # @return [Hash] Bounce data list and message/rfc822 part
46
- # @return [Nil] it failed to parse or the arguments are missing
63
+ # @return [Nil] it failed to decode or the arguments are missing
47
64
  def inquire(mhead, mbody)
48
- # Content-Language: en-US, fr-FR
49
- match = nil
50
- match ||= 1 if mhead['subject'].start_with?('Undeliverable')
51
- match ||= 1 if mhead['subject'].start_with?('Non_remis_')
52
- match ||= 1 if mhead['subject'].start_with?('Non recapitabile')
53
- return nil unless match
54
- return nil unless mhead['content-language']
55
-
56
- match += 1 if mhead['content-language'].size == 2 # JP
57
- match += 1 if mhead['content-language'].size == 5 # ja-JP
58
- return nil unless match > 1
59
-
60
- # These headers exist only a bounce mail from Office365
61
- return nil if mhead['x-ms-exchange-crosstenant-originalarrivaltime']
62
- return nil if mhead['x-ms-exchange-crosstenant-fromentityheader']
65
+ proceedsto = 0
66
+ proceedsto += 1 if EmailTitle.any? { |a| mhead["subject"].include?(a) }
67
+ proceedsto += 1 if MailSender.any? { |a| mhead["from"].include?(a) }
68
+ proceedsto += 1 if mhead["content-language"]
69
+ return nil if proceedsto < 2
63
70
 
71
+ require "sisimai/rfc1123"
72
+ require "sisimai/smtp/reply"
73
+ require "sisimai/smtp/status"
64
74
  dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
65
75
  emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
66
76
  bodyslices = emailparts[0].split("\n")
67
77
  readcursor = 0 # (Integer) Points the current cursor position
68
78
  recipients = 0 # (Integer) The number of 'Final-Recipient' header
69
- connvalues = 0 # (Integer) Flag, 1 if all the value of connheader have been set
70
- connheader = {
71
- 'rhost' => '', # The value of Reporting-MTA header or "Generating Server:"
72
- }
73
- v = nil
74
79
 
75
80
  while e = bodyslices.shift do
76
81
  # Read error messages and delivery status lines from the head of the email to the previous
77
82
  # line of the beginning of the original message.
78
83
  if readcursor == 0
79
84
  # Beginning of the bounce message or delivery status part
80
- readcursor |= Indicators[:deliverystatus] if MarkingsOf[:message].any? { |a| e.start_with?(a) }
85
+ readcursor |= Indicators[:deliverystatus] if StartingOf[:message].any? { |a| e.start_with?(a) }
81
86
  next
82
87
  end
83
88
  next if (readcursor & Indicators[:deliverystatus]) == 0
89
+ next if e == ""
84
90
 
85
- if connvalues == connheader.keys.size
86
- # Diagnostic information for administrators:
87
- #
88
- # Generating server: mta2.neko.example.jp
89
- #
90
- # kijitora@example.jp
91
- # #550 5.1.1 RESOLVER.ADR.RecipNotFound; not found ##
92
- #
93
- # Original message headers:
94
- v = dscontents[-1]
91
+ # Diagnostic information for administrators:
92
+ #
93
+ # Generating server: mta2.neko.example.jp
94
+ #
95
+ # kijitora@example.jp
96
+ # #550 5.1.1 RESOLVER.ADR.RecipNotFound; not found ##
97
+ #
98
+ # Original message headers:
99
+ v = dscontents[-1]
95
100
 
96
- if e.include?('@') && e.include?(' ') == false
97
- # kijitora@example.jp
98
- if v['recipient']
99
- # There are multiple recipient addresses in the message body.
100
- dscontents << Sisimai::Lhost.DELIVERYSTATUS
101
- v = dscontents[-1]
102
- end
103
- v['recipient'] = Sisimai::Address.s3s4(e)
104
- v['diagnosis'] = ''
105
- recipients += 1
101
+ if e.include?('@') && e.include?(' ') == false
102
+ # kijitora@example.jp
103
+ if v["recipient"] != ""
104
+ # There are multiple recipient addresses in the message body.
105
+ dscontents << Sisimai::Lhost.DELIVERYSTATUS
106
+ v = dscontents[-1]
107
+ end
108
+ v["recipient"] = Sisimai::Address.s3s4(e)
109
+ v["diagnosis"] = ""
110
+ recipients += 1
106
111
 
112
+ else
113
+ # Try to pick the remote hostname and status code, reply code from the error message
114
+ if StartingOf[:rhost].any? { |a| e.start_with?(a) }
115
+ # Generating server: SG2APC01HT234.mail.protection.outlook.com
116
+ # DSN generated by: NEKONYAAN0022.apcprd01.prod.exchangelabs.com
117
+ cv = Sisimai::RFC1123.find(e)
118
+ v["rhost"] = cv if Sisimai::RFC1123.is_internethost(cv)
107
119
  else
108
- # Continued line of error messages
109
- cr = Sisimai::SMTP::Reply.find(e)
110
- cs = Sisimai::SMTP::Status.find(e)
111
- if cr || cs
112
- # #550 5.1.1 RESOLVER.ADR.RecipNotFound; not found ##
113
- # #550 5.2.3 RESOLVER.RST.RecipSizeLimit; message too large for this recipient ##
120
+ # #550 5.1.1 RESOLVER.ADR.RecipNotFound; not found ##
121
+ # #550 5.2.3 RESOLVER.RST.RecipSizeLimit; message too large for this recipient ##
122
+ cr = Sisimai::SMTP::Reply.find(e) || ""
123
+ cs = Sisimai::SMTP::Status.find(e) || ""
124
+ if cr != "" || cs != "" || e.include?("Remote Server ")
114
125
  # Remote Server returned '550 5.1.1 RESOLVER.ADR.RecipNotFound; not found'
115
126
  # 3/09/2016 8:05:56 PM - Remote Server at mydomain.com (10.1.1.3) returned '550 4.4.7 QUEUE.Expired; message expired'
116
- v['replycode'] = cr || ''
117
- v['status'] = cs || ''
118
- v['diagnosis'] = e
119
- else
120
- # Continued line of error messages
121
- next if v['diagnosis'].to_s.empty?
122
- next unless v['diagnosis'].end_with?('=')
123
- v['diagnosis'] = v['diagnosis'].chomp('=')
124
- v['diagnosis'] << e
127
+ v["replycode"] = cr
128
+ v["status"] = cs
129
+ v["diagnosis"] << e << " "
125
130
  end
126
131
  end
127
- else
128
- # Diagnostic information for administrators:
129
- #
130
- # Generating server: mta22.neko.example.org
131
- next unless MarkingsOf[:rhost].any? { |a| e.start_with?(a) }
132
- next unless connheader['rhost'].empty?
133
- connheader['rhost'] = e[e.index(':') + 1, e.size]
134
- connvalues += 1
135
132
  end
136
133
  end
134
+
135
+ while recipients == 0
136
+ # Try to pick the recipient address from the following formatted bounce message:
137
+ # Original Message Details
138
+ # Created Date: 4/29/2017 11:23:34 PM
139
+ # Sender Address: neko@example.com
140
+ # Recipient Address: kijitora-nyaan@neko.kyoto.example.jp
141
+ # Subject: Nyaan?
142
+ p1 = emailparts[0].index("Original Message Details"); break if p1.nil?
143
+ p2 = emailparts[0].index("\nRecipient Address: "); break if p2.nil?
144
+ p3 = emailparts[0].index("\n", p2 + 20); break if p3.nil?
145
+ cv = Sisimai::Address.s3s4(emailparts[0][p2 + 20, p3 - p2 - 20])
146
+
147
+ break unless Sisimai::Address.is_emailaddress(cv)
148
+ dscontents[0]["recipient"] = cv
149
+ recipients += 1
150
+ end
137
151
  return nil unless recipients > 0
138
152
 
139
153
  dscontents.each do |e|
140
- p = -1
141
- e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
142
- MarkingsOf[:error].each do |q|
143
- # Find an error message, get an error code.
144
- p = e['diagnosis'].index(q) || -1
145
- break if p > -1
154
+ # Tidy up the error message in $e->{'diagnosis'}, Try to detect the bounce reason.
155
+ e["diagnosis"] = Sisimai::String.sweep(e["diagnosis"])
156
+
157
+ p0 = -1; StartingOf[:error].each do |r|
158
+ # Try to find the NDR subject string such as "RESOLVER.ADR.RecipientNotFound" from the
159
+ # error message
160
+ p0 = e["diagnosis"].index(r); break if p0.nil? == false
146
161
  end
147
- next unless p > 0
162
+ next if p0.nil?
148
163
 
149
164
  # #550 5.1.1 RESOLVER.ADR.RecipNotFound; not found ##
150
- f = e['diagnosis'][p + 1, e['diagnosis'].index(';') - p - 1]
151
- NDRSubject.each_key do |r|
152
- # Try to match with error subject strings
153
- next unless f == r
154
- e['reason'] = NDRSubject[r]
155
- break
156
- end
165
+ cv = e["diagnosis"][p0 + 1, e["diagnosis"].index(";") - p0 - 1]
166
+ next if NDRSubject.has_key?(cv) == false
167
+ e["reason"] = NDRSubject[cv]
157
168
  end
158
169
 
159
- return { 'ds' => dscontents, 'rfc822' => emailparts[1] }
170
+ return { "ds" => dscontents, "rfc822" => emailparts[1] }
160
171
  end
161
172
  def description; return 'Microsoft Exchange Server 2007'; end
162
173
  end