sisimai 4.25.8 → 4.25.12

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

Potentially problematic release.


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

Files changed (97) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +4 -3
  3. data/ANALYTICAL-PRECISION +1 -1
  4. data/ChangeLog.md +65 -0
  5. data/README-JA.md +3 -3
  6. data/README.md +4 -4
  7. data/lib/sisimai/address.rb +6 -3
  8. data/lib/sisimai/arf.rb +25 -21
  9. data/lib/sisimai/data.rb +7 -1
  10. data/lib/sisimai/datetime.rb +15 -14
  11. data/lib/sisimai/lhost/amazonses.rb +1 -1
  12. data/lib/sisimai/lhost/domino.rb +29 -4
  13. data/lib/sisimai/lhost/einsundeins.rb +1 -1
  14. data/lib/sisimai/lhost/exchange2007.rb +1 -1
  15. data/lib/sisimai/lhost/exim.rb +14 -10
  16. data/lib/sisimai/lhost/ezweb.rb +1 -1
  17. data/lib/sisimai/lhost/gsuite.rb +5 -0
  18. data/lib/sisimai/lhost/imailserver.rb +1 -1
  19. data/lib/sisimai/lhost/mailfoundry.rb +3 -4
  20. data/lib/sisimai/lhost/mailmarshalsmtp.rb +2 -2
  21. data/lib/sisimai/lhost/mxlogic.rb +1 -1
  22. data/lib/sisimai/lhost/notes.rb +1 -1
  23. data/lib/sisimai/lhost/office365.rb +1 -1
  24. data/lib/sisimai/lhost/postfix.rb +3 -10
  25. data/lib/sisimai/lhost/qmail.rb +7 -7
  26. data/lib/sisimai/lhost/sendgrid.rb +2 -2
  27. data/lib/sisimai/lhost/sendmail.rb +1 -1
  28. data/lib/sisimai/lhost/verizon.rb +4 -4
  29. data/lib/sisimai/lhost/x3.rb +4 -0
  30. data/lib/sisimai/lhost/x4.rb +8 -8
  31. data/lib/sisimai/mail.rb +2 -21
  32. data/lib/sisimai/mda.rb +2 -2
  33. data/lib/sisimai/mime.rb +1 -1
  34. data/lib/sisimai/reason/blocked.rb +40 -26
  35. data/lib/sisimai/reason/exceedlimit.rb +4 -1
  36. data/lib/sisimai/reason/expired.rb +2 -0
  37. data/lib/sisimai/reason/filtered.rb +10 -9
  38. data/lib/sisimai/reason/hostunknown.rb +3 -0
  39. data/lib/sisimai/reason/mailererror.rb +1 -1
  40. data/lib/sisimai/reason/norelaying.rb +8 -7
  41. data/lib/sisimai/reason/notaccept.rb +5 -3
  42. data/lib/sisimai/reason/policyviolation.rb +5 -1
  43. data/lib/sisimai/reason/rejected.rb +5 -1
  44. data/lib/sisimai/reason/securityerror.rb +5 -6
  45. data/lib/sisimai/reason/spamdetected.rb +23 -16
  46. data/lib/sisimai/reason/suspend.rb +1 -0
  47. data/lib/sisimai/reason/systemerror.rb +2 -0
  48. data/lib/sisimai/reason/userunknown.rb +25 -21
  49. data/lib/sisimai/reason/virusdetected.rb +9 -3
  50. data/lib/sisimai/rfc1894.rb +24 -22
  51. data/lib/sisimai/rfc3464.rb +1 -1
  52. data/lib/sisimai/rfc3834.rb +1 -1
  53. data/lib/sisimai/rfc5322.rb +8 -3
  54. data/lib/sisimai/rhost/exchangeonline.rb +8 -1
  55. data/lib/sisimai/rhost/franceptt.rb +4 -0
  56. data/lib/sisimai/rhost/googleapps.rb +4 -1
  57. data/lib/sisimai/rhost.rb +1 -0
  58. data/lib/sisimai/smtp/error.rb +8 -6
  59. data/lib/sisimai/smtp/reply.rb +1 -1
  60. data/lib/sisimai/smtp/status.rb +1 -1
  61. data/lib/sisimai/time.rb +1 -2
  62. data/lib/sisimai/version.rb +1 -1
  63. data/lib/sisimai.rb +3 -3
  64. data/set-of-emails/maildir/bsd/arf-25.eml +61 -0
  65. data/set-of-emails/maildir/bsd/lhost-aol-04.eml +23 -23
  66. data/set-of-emails/maildir/bsd/lhost-domino-02.eml +1 -2
  67. data/set-of-emails/maildir/bsd/lhost-exim-61.eml +40 -0
  68. data/set-of-emails/maildir/bsd/lhost-postfix-66.eml +80 -0
  69. data/set-of-emails/maildir/bsd/lhost-postfix-67.eml +80 -0
  70. data/set-of-emails/maildir/bsd/lhost-postfix-68.eml +82 -0
  71. data/set-of-emails/maildir/bsd/lhost-postfix-69.eml +80 -0
  72. data/set-of-emails/maildir/bsd/lhost-postfix-70.eml +87 -0
  73. data/set-of-emails/maildir/bsd/lhost-postfix-71.eml +81 -0
  74. data/set-of-emails/maildir/bsd/lhost-postfix-72.eml +81 -0
  75. data/set-of-emails/maildir/bsd/lhost-postfix-73.eml +79 -0
  76. data/set-of-emails/maildir/bsd/lhost-postfix-74.eml +83 -0
  77. data/set-of-emails/maildir/bsd/lhost-sendmail-08.eml +1 -1
  78. data/set-of-emails/maildir/bsd/lhost-sendmail-11.eml +1 -1
  79. data/set-of-emails/maildir/bsd/lhost-sendmail-57.eml +59 -0
  80. data/set-of-emails/maildir/bsd/lhost-sendmail-58.eml +70 -0
  81. data/set-of-emails/maildir/bsd/lhost-sendmail-59.eml +68 -0
  82. data/set-of-emails/maildir/bsd/lhost-x3-06.eml +53 -0
  83. data/set-of-emails/maildir/bsd/rfc3464-41.eml +19 -0
  84. data/set-of-emails/maildir/bsd/rfc3464-42.eml +34 -0
  85. data/set-of-emails/maildir/bsd/{rhost-exchange-online-01.eml → rhost-exchangeonline-01.eml} +0 -0
  86. data/set-of-emails/maildir/bsd/{rhost-exchange-online-02.eml → rhost-exchangeonline-02.eml} +0 -0
  87. data/set-of-emails/maildir/bsd/{rhost-exchange-online-03.eml → rhost-exchangeonline-03.eml} +0 -0
  88. data/set-of-emails/maildir/bsd/rhost-franceptt-12.eml +82 -0
  89. data/set-of-emails/maildir/bsd/{rhost-google-apps-01.eml → rhost-googleapps-01.eml} +0 -0
  90. data/set-of-emails/maildir/bsd/{rhost-google-apps-02.eml → rhost-googleapps-02.eml} +0 -0
  91. data/set-of-emails/maildir/dos/{rhost-exchange-online-01.eml → rhost-exchangeonline-01.eml} +0 -0
  92. data/set-of-emails/maildir/dos/{rhost-google-apps-01.eml → rhost-googleapps-01.eml} +0 -0
  93. data/set-of-emails/maildir/mac/{rhost-exchange-online-01.eml → rhost-exchangeonline-01.eml} +0 -0
  94. data/set-of-emails/maildir/mac/{rhost-google-apps-01.eml → rhost-googleapps-01.eml} +0 -0
  95. data/sisimai-java.gemspec +4 -4
  96. data/sisimai.gemspec +4 -4
  97. metadata +38 -20
@@ -21,8 +21,8 @@ module Sisimai
21
21
  'sender ip address rejected',
22
22
  ]
23
23
  Index = [
24
- '<> invalid sender',
25
24
  'access denied (in reply to mail from command)',
25
+ 'access denied (sender blacklisted)',
26
26
  'address rejected',
27
27
  'administrative prohibition',
28
28
  'batv failed to verify', # SoniWall
@@ -31,6 +31,7 @@ module Sisimai
31
31
  'bogus mail from', # IMail - block empty sender
32
32
  'connections not accepted from servers without a valid sender domain',
33
33
  'denied [bouncedeny]', # McAfee
34
+ 'denied by secumail valid-address-filter',
34
35
  'delivery not authorized, message refused',
35
36
  'does not exist e2110',
36
37
  'domain of sender address ',
@@ -41,6 +42,7 @@ module Sisimai
41
42
  'from: domain is invalid. please provide a valid from:',
42
43
  'fully qualified email address required', # McAfee
43
44
  'invalid domain, see <url:',
45
+ 'invalid sender',
44
46
  'is not a registered gateway user',
45
47
  'mail from not owned by user',
46
48
  'message rejected: email address is not verified',
@@ -51,6 +53,7 @@ module Sisimai
51
53
  'returned mail not accepted here',
52
54
  'rfc 1035 violation: recursive cname records for',
53
55
  'rule imposed mailbox access for', # MailMarshal
56
+ 'sender address has been blacklisted',
54
57
  'sender email address rejected',
55
58
  'sender is spammer',
56
59
  'sender not pre-approved',
@@ -59,6 +62,7 @@ module Sisimai
59
62
  'sender verify failed', # Exim callout
60
63
  'syntax error: empty email address',
61
64
  'the message has been rejected by batv defense',
65
+ 'this server does not accept mail from',
62
66
  'transaction failed unsigned dsn for',
63
67
  'unroutable sender address',
64
68
  'you are sending to/from an address that has been blacklisted',
@@ -21,27 +21,26 @@ module Sisimai
21
21
  class << self
22
22
  Regex = %r{(?>
23
23
  account[ ]not[ ]subscribed[ ]to[ ]ses
24
- |authentification[ ]requise.+[a-z]{3}.+402
25
24
  |authentication[ ](?:
26
25
  credentials invalid
27
26
  |failure
28
- |failed;[ ]server[ ].+[ ]said: # Postfix
27
+ |failed;[ ]server[ ][^ ]+[ ]said: # Postfix
29
28
  |required
30
29
  |turned[ ]on[ ]in[ ]your[ ]email[ ]client
31
30
  )
32
31
  |\d+[ ]denied[ ]\[[a-z]+\][ ].+[(]mode:[ ].+[)]
33
- |codes?[ ]d'?[ ]*authentification[ ]invalide.+[a-z]{3}.+305
34
- |domain[ ].+[ ]is[ ]a[ ]dead[ ]domain
32
+ |authentification[ ]requise.+[0-9a-z_]+402
33
+ |codes?[ ]d'?[ ]*authentification[ ]invalide.+[0-9a-z_]+305
34
+ |domain[ ][^ ]+[ ]is[ ]a[ ]dead[ ]domain
35
35
  |executable[ ]files[ ]are[ ]not[ ]allowed[ ]in[ ]compressed[ ]files
36
36
  |insecure[ ]mail[ ]relay
37
37
  |recipient[ ]address[ ]rejected:[ ]access[ ]denied
38
38
  |sorry,[ ]you[ ]don'?t[ ]authenticate[ ]or[ ]the[ ]domain[ ]isn'?t[ ]in[ ]
39
39
  my[ ]list[ ]of[ ]allowed[ ]rcpthosts
40
40
  |tls[ ]required[ ]but[ ]not[ ]supported # SendGrid:the recipient mailserver does not support TLS or have a valid certificate
41
- |user[ ].+[ ]is[ ]not[ ]authorized[ ]to[ ]perform[ ]ses:sendrawemail[ ]on[ ]resource
42
41
  |tls[ ]required[ ]but[ ]not[ ]supported # SendGrid:the recipient mailserver does not support TLS or have a valid certificate
43
42
  |unauthenticated[ ]senders[ ]not[ ]allowed
44
- |user[ ].+[ ]is[ ]not[ ]authorized[ ]to[ ]perform[ ]ses:sendrawemail[ ]on[ ]resource
43
+ |user[ ][^ ]+[ ]is[ ]not[ ]authorized[ ]to[ ]perform[ ]ses:sendrawemail[ ]on[ ]resource
45
44
  |you[ ]are[ ]not[ ]authorized[ ]to[ ]send[ ]mail,[ ]authentication[ ]is[ ]required
46
45
  |verification[ ]failure
47
46
  )
@@ -20,6 +20,7 @@ module Sisimai
20
20
  ["]the[ ]mail[ ]server[ ]detected[ ]your[ ]message[ ]as[ ]spam[ ]and[ ]
21
21
  has[ ]prevented[ ]delivery[.]["] # CPanel/Exim with SA rejections on
22
22
  |(?:\d[.]\d[.]\d|\d{3})[ ]spam\z
23
+ |554[ ]5[.]7[.]0[ ]reject,[ ]id=\d+
23
24
  |appears[ ]to[ ]be[ ]unsolicited
24
25
  |blacklisted[ ]url[ ]in[ ]message
25
26
  |block[ ]for[ ]spam
@@ -29,17 +30,18 @@ module Sisimai
29
30
  )
30
31
  |blocked[ ]for[ ]abuse[.][ ]see[ ]http://att[.]net/blocks # AT&T
31
32
  |bulk[ ]email
33
+ |considered[ ]unsolicited[ ]bulk[ ]e-mail[ ][(]spam[)][ ]by[ ]our[ ]mail[ ]filters
32
34
  |content[ ]filter[ ]rejection
33
35
  |cyberoam[ ]anti[ ]spam[ ]engine[ ]has[ ]identified[ ]this[ ]email[ ]as[ ]a[ ]bulk[ ]email
34
36
  |denied[ ]due[ ]to[ ]spam[ ]list
35
- |dt:spm[ ]mx.+[ ]http://mail[.]163[.]com/help/help_spam_16[.]htm
36
37
  |greylisted.?.[ ]please[ ]try[ ]again[ ]in
37
- |http://(?:www[.]spamhaus[.]org|dsbl[.]org)
38
+ |high[ ]probability[ ]of[ ]spam
39
+ |https?://(?:www[.]spamhaus[.]org|dsbl[.]org|mail[.]163[.]com/help/help_spam_16[.]htm)
38
40
  |listed[ ]in[ ]work[.]drbl[.]imedia[.]ru
39
41
  |mail[ ](?:
40
42
  appears[ ]to[ ]be[ ]unsolicited # rejected due to spam
41
43
  |content[ ]denied # http://service.mail.qq.com/cgi-bin/help?subtype=1&&id=20022&&no=1000726
42
- |rejete.+[a-z]{3}.+506
44
+ |rejete[.][ ]mail[ ]rejected[.][ ][0-9a-z_]+506
43
45
  )
44
46
  |may[ ]consider[ ]spam
45
47
  |message[ ](?:
@@ -51,8 +53,10 @@ module Sisimai
51
53
  |refer[ ]to[ ]the[ ]troubleshooting[ ]page[ ]at[ ]
52
54
  )
53
55
  |looks[ ]like[ ]spam
54
- |not[ ]accepted[ ]for[ ]policy[ ]reasons[.][ ]see[ ]http: # Yahoo!
55
- |refused[ ]by[ ]mailmarshal[ ]spamprofiler
56
+ |refused[ ]by[ ](?:
57
+ mailmarshal[ ]spamprofiler
58
+ |trustwave[ ]seg[ ]spamprofiler
59
+ )
56
60
  |rejected[ ](?:
57
61
  as[ ]spam
58
62
  |because[ ]of[ ]unacceptable[ ]content
@@ -62,25 +66,23 @@ module Sisimai
62
66
  )
63
67
  |our[ ](?:
64
68
  email[ ]server[ ]thinks[ ]this[ ]email[ ]is[ ]spam
65
- |filters[ ]rate[ ]at[ ]and[ ]above[ ].+[ ]percent[ ]probability[ ]of[ ]being[ ]spam
69
+ |filters[ ]rate[ ]at[ ]and[ ]above[ ]\d+[ ]percent[ ]probability[ ]of[ ]being[ ]spam
66
70
  |system[ ]has[ ]detected[ ]that[ ]this[ ]message[ ]is
67
71
  )
68
- |permanent[ ]failure[ ]for[ ]one[ ]or[ ]more[ ]recipients[ ][(].+:blocked[)]
69
72
  |probable[ ]spam
70
73
  |reject[ ]bulk[.]advertising
71
- |reject,.+[ ][-][ ]spam[.][ ]
72
74
  |rejected(?:
73
75
  :[ ]spamassassin[ ]score[ ]
74
- |[ ]by[ ].+[ ][(]spam[)]
75
- |[ ]due[ ]to[ ]spam[ ](?:classification|content)
76
+ |[ ]by[ ][^ ]+[ ][(]spam[)]
77
+ |[ ]due[ ]to[ ]spam[ ](?:url[ ]in[ ])?(?:classification|content)
76
78
  )
77
- |rejecting[ ]banned[ ]content
79
+ |rejecting[ ](?:banned|mail)[ ]content
78
80
  |related[ ]to[ ]content[ ]with[ ]spam[-]like[ ]characteristics
79
- |rule[ ]imposed[ ]as[ ].+is[ ]blacklisted[ ]on # Mailmarshal RBLs
80
- |sender[ ]domain[ ]listed[ ]at[ ].+
81
+ |rule[ ]imposed[ ]as[ ][^ ]+[ ]is[ ]blacklisted[ ]on
82
+ |sender[ ]domain[ ]listed[ ]at[ ][^ ]+
81
83
  |sending[ ]address[ ]not[ ]accepted[ ]due[ ]to[ ]spam[ ]filter
82
84
  |spam[ ](?:
83
- .+[ ]exceeded
85
+ [^ ]+[ ]exceeded
84
86
  |blocked
85
87
  |check
86
88
  |content[ ]matched
@@ -112,7 +114,7 @@ module Sisimai
112
114
  identified[ ]as[ ]spam
113
115
  |scored[ ]as[ ]spam[ ]with[ ]a[ ]probability
114
116
  )
115
- |scored[ ].+[ ]spam[ ]points
117
+ |scored[ ][^ ]+[ ]spam[ ]points
116
118
  |was[ ]classified[ ]as[ ]spam
117
119
  |was[ ]rejected[ ]by[ ]recurrent[ ]pattern[ ]detection[ ]system
118
120
  )
@@ -163,7 +165,12 @@ module Sisimai
163
165
  return nil if argvs.deliverystatus.empty?
164
166
  return true if argvs.reason == 'spamdetected'
165
167
  return true if Sisimai::SMTP::Status.name(argvs.deliverystatus).to_s == 'spamdetected'
166
- return true if match(argvs.diagnosticcode.downcase)
168
+
169
+ # The value of "reason" isn't "spamdetected" when the value of "smtpcommand" is an SMTP
170
+ # command to be sent before the SMTP DATA command because all the MTAs read the headers
171
+ # and the entire message body after the DATA command.
172
+ return false if %w[CONN EHLO HELO MAIL RCPT].include?(argvs.smtpcommand)
173
+ return true if match(argvs.diagnosticcode.downcase)
167
174
  return false
168
175
  end
169
176
 
@@ -13,6 +13,7 @@ module Sisimai
13
13
  ' temporary locked',
14
14
  'boite du destinataire archivee',
15
15
  'email account that you tried to reach is disabled',
16
+ 'has been suspended',
16
17
  'invalid/inactive user',
17
18
  'is a deactivated mailbox', # http://service.mail.qq.com/cgi-bin/help?subtype=1&&id=20022&&no=1000742
18
19
  'mailbox currently suspended',
@@ -13,6 +13,7 @@ module Sisimai
13
13
  # Imported from p5-Sisimail/lib/Sisimai/Reason/SystemError.pm
14
14
  class << self
15
15
  Index = [
16
+ 'aliasing/forwarding loop broken',
16
17
  "can't create user output file",
17
18
  'could not load drd for domain',
18
19
  'internal error reading data', # Microsoft
@@ -25,6 +26,7 @@ module Sisimai
25
26
  'loop was found in the mail exchanger',
26
27
  'loops back to myself',
27
28
  'mail system configuration error',
29
+ 'remote server is misconfigured',
28
30
  'server configuration error',
29
31
  'service currently unavailable',
30
32
  'system config error',
@@ -25,17 +25,20 @@ module Sisimai
25
25
  'Sisimai::Reason::Rejected' => 'sisimai/reason/rejected',
26
26
  }
27
27
  Regex = %r{(?>
28
- .+[ ]user[ ]unknown
29
- |[#]5[.]1[.]1[ ]bad[ ]address
30
- |[<].+[>][ ]not[ ]found
31
- |[<].+[@].+[>][.][.][.][ ]blocked[ ]by[ ]
28
+ [#]5[.]1[.]1[ ]bad[ ]address
29
+ |[<][^ ]+[>][ ]not[ ]found
30
+ |[<][^ ]+[@][^ ]+[>][.][.][.][ ]blocked[ ]by[ ]
31
+ |550[ ]address[ ]invalid
32
32
  |5[.]0[.]0[.][ ]mail[ ]rejected[.]
33
33
  |5[.]1[.]0[ ]address[ ]rejected[.]
34
- |adresse[ ]d[ ]au[ ]moins[ ]un[ ]destinataire[ ]invalide.+[a-z]{3}.+(?:416|418)
34
+ |account[ ][^ ]+[ ]does[ ]not[ ]exist[ ]at[ ]the[ ]organization
35
+ |adresse[ ]d[ ]au[ ]moins[ ]un[ ]destinataire[ ]invalide[.][ ]invalid[ ]recipient[.][0-9a-z_]+41[68]
35
36
  |address[ ](?:does[ ]not[ ]exist|unknown)
37
+ |address[ ](?:does[ ]not[ ]exist|not[ ]present[ ]in[ ]directory|unknown)
36
38
  |archived[ ]recipient
37
39
  |bad[-_ ]recipient
38
40
  |can[']t[ ]accept[ ]user
41
+ |does[ ]not[ ]exist[.]
39
42
  |destination[ ](?:
40
43
  addresses[ ]were[ ]unknown
41
44
  |server[ ]rejected[ ]recipients
@@ -43,7 +46,7 @@ module Sisimai
43
46
  |email[ ]address[ ](?:does[ ]not[ ]exist|could[ ]not[ ]be[ ]found)
44
47
  |invalid[ ](?:
45
48
  address
46
- |mailbox:
49
+ |mailbox:?
47
50
  |mailbox[ ]path
48
51
  |recipient
49
52
  )
@@ -53,16 +56,17 @@ module Sisimai
53
56
  |an[ ]active[ ]address[ ]at[ ]this[ ]host
54
57
  )
55
58
  |mailbox[ ](?:
56
- .+[ ]does[ ]not[ ]exist
57
- |.+[@].+[ ]unavailable
59
+ [^ ]+[ ]does[ ]not[ ]exist
60
+ |[^ ]+[@][^ ]+[ ]unavailable
58
61
  |does[ ]not[ ]exist
59
62
  |invalid
60
63
  |is[ ](?:inactive|unavailable)
61
64
  |not[ ](?:present|found)
62
65
  |unavailable
63
66
  )
67
+ |nessun[ ]utente[ ]simile[ ]in[ ]questo[ ]indirizzo
64
68
  |no[ ](?:
65
- [ ].+[ ]in[ ]name[ ]directory
69
+ [ ][^ ]+[ ]in[ ]name[ ]directory
66
70
  |account[ ]by[ ]that[ ]name[ ]here
67
71
  |existe[ ](?:dicha[ ]persona|ese[ ]usuario[ ])
68
72
  |mail[ ]box[ ]available[ ]for[ ]this[ ]user
@@ -79,7 +83,7 @@ module Sisimai
79
83
  |user(?:[ ]here)?
80
84
  )
81
85
  |thank[ ]you[ ]rejected:[ ]account[ ]unavailable:
82
- |valid[ ]recipients[,][ ]bye # Microsoft
86
+ |valid[ ]recipients,[ ]bye
83
87
  )
84
88
  |non[- ]?existent[ ]user
85
89
  |not[ ](?:
@@ -87,15 +91,15 @@ module Sisimai
87
91
  |a[ ]local[ ]address
88
92
  |email[ ]addresses
89
93
  )
90
- |rcpt[ ][<].+[>][ ]does[ ]not[ ]exist
94
+ |rcpt[ ][<][^ ]+[>][ ]does[ ]not[ ]exist
91
95
  |recipient[ ]address[ ]rejected[.][ ][(]in[ ]reply[ ]to[ ]rcpt[ ]to[ ]command[)]
92
- |rece?ipient[ ](?:
93
- .+[ ]was[ ]not[ ]found[ ]in
96
+ |recipient[ ](?:
97
+ [^ ]+[ ]was[ ]not[ ]found[ ]in
94
98
  |address[ ]rejected:[ ](?:
95
99
  access[ ]denied
96
100
  |invalid[ ]user
97
- |user[ ].+[ ]does[ ]not[ ]exist
98
- |user[ ]unknown[ ]in[ ].+[ ]table
101
+ |user[ ][^ ]+[ ]does[ ]not[ ]exist
102
+ |user[ ]unknown[ ]in[ ][^ ]+[ ]table
99
103
  |unknown[ ]user
100
104
  )
101
105
  |does[ ]not[ ]exist(?:[ ]on[ ]this[ ]system)?
@@ -104,9 +108,8 @@ module Sisimai
104
108
  |unknown
105
109
  )
106
110
  |requested[ ]action[ ]not[ ]taken:[ ]mailbox[ ]unavailable
107
- |resolver[.]adr[.]recip(?:ient)notfound
108
- |said:[ ]550[-[ ]]5[.]1[.]1[ ].+[ ]user[ ]unknown[ ]
109
- |smtp[ ]error[ ]from[ ]remote[ ]mail[ ]server[ ]after[ ]end[ ]of[ ]data:[ ]553.+does[ ]not[ ]exist
111
+ |resolver[.]adr[.]recipient notfound
112
+ |said:[ ]550[-[ ]]5[.]1[.]1[ ][^ ]+[ ]user[ ]unknown[ ]
110
113
  |sorry,[ ](?:
111
114
  user[ ]unknown
112
115
  |badrcptto
@@ -122,7 +125,7 @@ module Sisimai
122
125
  address[ ]no[ ]longer[ ]accepts[ ]mail
123
126
  |email[ ]address[ ]is[ ]wrong[ ]or[ ]no[ ]longer[ ]valid
124
127
  |spectator[ ]does[ ]not[ ]exist
125
- |user[ ]doesn[']?t[ ]have[ ]a[ ].+[ ]account
128
+ |user[ ]doesn[']?t[ ]have[ ]a[ ][^ ]+[ ]account
126
129
  )
127
130
  |unknown[ ](?:
128
131
  e[-]?mail[ ]address
@@ -132,13 +135,14 @@ module Sisimai
132
135
  |user
133
136
  )
134
137
  |user[ ](?:
135
- .+[ ]was[ ]not[ ]found
136
- |.+[ ]does[ ]not[ ]exist
138
+ [^ ]+[ ]was[ ]not[ ]found
139
+ |[^ ]+[ ]does[ ]not[ ]exist
137
140
  |does[ ]not[ ]exist
138
141
  |missing[ ]home[ ]directory
139
142
  |not[ ](?:active|exist|found|known)
140
143
  |unknown
141
144
  )
145
+ |utilisateur[ ]inconnu[ ]!
142
146
  |vdeliver:[ ]invalid[ ]or[ ]unknown[ ]virtual[ ]user
143
147
  |your[ ]envelope[ ]recipient[ ]is[ ]in[ ]my[ ]badrcptto[ ]list
144
148
  )
@@ -38,14 +38,20 @@ module Sisimai
38
38
  return false
39
39
  end
40
40
 
41
- # The bounce reason is security error or not
41
+ # The bounce reason is "virusdetected" or not
42
42
  # @param [Sisimai::Data] argvs Object to be detected the reason
43
43
  # @return [True,False] true: virus detected
44
44
  # false: virus was not detected
45
45
  # @since 4.22.0
46
46
  # @see http://www.ietf.org/rfc/rfc2822.txt
47
- def true(_argvs)
48
- return nil
47
+ def true(argvs)
48
+ # The value of "reason" isn't "visusdetected" when the value of "smtpcommand" is an SMTP
49
+ # command to be sent before the SMTP DATA command because all the MTAs read the headers
50
+ # and the entire message body after the DATA command.
51
+ return true if argvs.reason == 'virusdetected'
52
+ return false if %w[CONN EHLO HELO MAIL RCPT].include?(argvs.smtpcommand)
53
+ return true if match(argvs.diagnosticcode.downcase)
54
+ return false
49
55
  end
50
56
 
51
57
  end
@@ -38,14 +38,14 @@ module Sisimai
38
38
  'addr' => %r/\A((?:Original|Final|X-Actual)-Recipient):[ ]*(.+?);[ ]*(.+)/,
39
39
  'code' => %r/\A(Diagnostic-Code):[ ]*(.+?);[ ]*(.*)/,
40
40
  'date' => %r/\A((?:Arrival|Last-Attempt)-Date):[ ]*(.+)/,
41
- 'host' => %r/\A((?:Reporting|Received-From|Remote)-MTA):[ ]*(.+?);[ ]*(.+)/,
42
- 'list' => %r/\A(Action):[ ]*(failed|delayed|delivered|relayed|expanded|expired|failure)/i,
41
+ 'host' => %r/\A((?:Received-From|Remote|Reporting)-MTA):[ ]*(.+?);[ ]*(.+)/,
42
+ 'list' => %r/\A(Action):[ ]*(delayed|deliverable|delivered|expanded|expired|failed|failure|relayed)/i,
43
43
  'stat' => %r/\A(Status):[ ]*([245][.]\d+[.]\d+)/,
44
44
  'text' => %r/\A(X-Original-Message-ID):[ ]*(.+)/,
45
- #text: %r/\A(Original-Envelope-Id|Final-Log-ID):[ ]*(.+)/,
45
+ #'text' => %r/\A(Final-Log-ID|Original-Envelope-Id):[ ]*(.+)/,
46
46
  }.freeze
47
47
 
48
- Correction = { action: { 'failure' => 'failed', 'expired' => 'delayed' } }
48
+ Correction = { action: { 'deliverable' => 'delivered', 'expired' => 'delayed', 'failure' => 'failed' }}
49
49
  FieldGroup = {
50
50
  'original-recipient' => 'addr',
51
51
  'final-recipient' => 'addr',
@@ -86,8 +86,8 @@ module Sisimai
86
86
  # @since v4.25.0
87
87
  def match(argv0 = '')
88
88
  return nil if argv0.empty?
89
- return 1 if FieldNames[0].any? { |a| argv0.start_with?(a) }
90
- return 2 if FieldNames[1].any? { |a| argv0.start_with?(a) }
89
+ return 1 if FieldNames[0].any? { |a| argv0.start_with?(a) }
90
+ return 2 if FieldNames[1].any? { |a| argv0.start_with?(a) }
91
91
  return nil
92
92
  end
93
93
 
@@ -98,42 +98,44 @@ module Sisimai
98
98
  def field(argv0 = '')
99
99
  return nil if argv0.empty?
100
100
  group = FieldGroup[argv0.split(':',2).shift.downcase] || ''
101
- match = []
102
101
 
103
102
  return nil if group.empty?
104
103
  return nil unless CapturesOn[group]
105
104
 
105
+ table = ['', '', '', '']
106
+ match = false
106
107
  while cv = argv0.match(CapturesOn[group])
107
108
  # Try to match with each pattern of Per-Message field, Per-Recipient field
108
- # - 0: Field-Name
109
- # - 1: Sub Type: RFC822, DNS, X-Unix, and so on)
110
- # - 2: Value
111
- # - 3: Field Group(addr, code, date, host, stat, text)
112
- match[0] = cv[1].downcase
113
- match[3] = group
109
+ # - 0: Field-Name
110
+ # - 1: Sub Type: RFC822, DNS, X-Unix, and so on)
111
+ # - 2: Value
112
+ # - 3: Field Group(addr, code, date, host, stat, text)
113
+ match = true
114
+ table[0] = cv[1].downcase
115
+ table[3] = group
114
116
 
115
117
  if group == 'addr' || group == 'code' || group == 'host'
116
118
  # - Final-Recipient: RFC822; kijitora@nyaan.jp
117
119
  # - Diagnostic-Code: SMTP; 550 5.1.1 <kijitora@example.jp>... User Unknown
118
120
  # - Remote-MTA: DNS; mx.example.jp
119
- match[1] = cv[2].upcase
120
- match[2] = group == 'host' ? cv[3].downcase : cv[3]
121
- match[2] = '' if match[2] =~ /\A\s+\z/ # Remote-MTA: dns;
121
+ table[1] = cv[2].upcase
122
+ table[2] = group == 'host' ? cv[3].downcase : cv[3]
123
+ table[2] = '' if table[2] =~ /\A\s+\z/ # Remote-MTA: dns;
122
124
  else
123
125
  # - Action: failed
124
126
  # - Status: 5.2.2
125
- match[1] = ''
126
- match[2] = group == 'date' ? cv[2] : cv[2].downcase
127
+ table[1] = ''
128
+ table[2] = group == 'date' ? cv[2] : cv[2].downcase
127
129
 
128
130
  # Correct invalid value in Action field:
129
131
  break unless group == 'list'
130
- break unless Correction[:action][match[2]]
131
- match[2] = Correction[:action][match[2]]
132
+ break unless Correction[:action][table[2]]
133
+ table[2] = Correction[:action][table[2]]
132
134
  end
133
135
  break
134
136
  end
135
- return nil if match.empty?
136
- return match
137
+ return nil unless match
138
+ return table
137
139
  end
138
140
 
139
141
  end
@@ -174,7 +174,7 @@ module Sisimai
174
174
  maybealias = cv[2]
175
175
  else
176
176
  # Final-Recipient: ...
177
- x = v['recipienet'] || ''
177
+ x = v['recipient'] || ''
178
178
  y = Sisimai::Address.s3s4(cv[2])
179
179
  y = maybealias unless Sisimai::RFC5322.is_emailaddress(y)
180
180
 
@@ -99,7 +99,7 @@ module Sisimai
99
99
  if mhead['content-type']
100
100
  # Get the boundary string and set regular expression for matching with
101
101
  # the boundary string.
102
- b0 = Sisimai::MIME.boundary(mhead['content-type'], 0)
102
+ b0 = Sisimai::MIME.boundary(mhead['content-type'], 0) || ''
103
103
  MarkingsOf[:boundary] = %r/\A\Q#{b0}\E\z/ unless b0.empty?
104
104
  end
105
105
 
@@ -64,7 +64,7 @@ module Sisimai
64
64
  # Fields that might be long
65
65
  # @return [Hash] Long filed(email header) list
66
66
  def LONGFIELDS
67
- return { 'to' => 1, 'from' => 1, 'subject' => 1, 'message-id' => 1 }
67
+ return { 'to' => true, 'from' => true, 'subject' => true, 'message-id' => true }
68
68
  end
69
69
 
70
70
  # Check that the argument is an email address or not
@@ -191,8 +191,13 @@ module Sisimai
191
191
  v[1] ||= ''
192
192
 
193
193
  unless v[1].empty?
194
- v[1].sub(/\A[\r\n\s]+/, '')
195
- v[1].sub(/\n\n.+\z/m, '')
194
+ # Remove blank lines, the message body of the original message, and append "\n" at the end
195
+ # of the original message headers
196
+ # 1. Remove leading blank lines
197
+ # 2. Remove text after the first blank line: \n\n
198
+ # 3. Append "\n" at the end of test block when the last character is not "\n"
199
+ v[1].sub!(/\A[\r\n\s]+/, '')
200
+ v[1] = v[1][0, v[1].index("\n\n")] if v[1].include?("\n\n")
196
201
  v[1] << "\n" unless v[1].end_with?("\n")
197
202
  end
198
203
  return v
@@ -22,6 +22,7 @@ module Sisimai
22
22
  '5.2.2' => [{ reason: 'mailboxfull', string: 'Mailbox full' }],
23
23
  '5.2.3' => [{ reason: 'exceedlimit', string: 'Message too large' }],
24
24
  '5.2.4' => [{ reason: 'systemerror', string: 'Mailing list expansion problem' }],
25
+ '5.2.14' => [{ reason: 'systemerror', string: 'misconfigured forwarding address' }],
25
26
  '5.2.122' => [{ reason: 'toomanyconn' ,string: 'The recipient has exceeded their limit for' }],
26
27
  '5.3.3' => [{ reason: 'systemfull', string: 'Unrecognized command' }],
27
28
  '5.3.4' => [{ reason: 'mesgtoobig', string: 'Message too big for system' }],
@@ -29,6 +30,7 @@ module Sisimai
29
30
  '5.4.1' => [{ reason: 'rejected', string: 'Recipient address rejected: Access denied' }],
30
31
  '5.4.11' => [{ reason: 'contenterror',string: 'Agent generated message depth exceeded' }],
31
32
  '5.4.14' => [{ reason: 'networkerror',string: 'Hop count exceeded' }],
33
+ '5.4.310' => [{ reason: 'systemerror', string: 'does not exist' }], # DNS domain * does not exist
32
34
  '5.5.2' => [{ reason: 'syntaxerror', string: 'Send hello first' }],
33
35
  '5.5.3' => [{ reason: 'syntaxerror', string: 'Too many recipients' }],
34
36
  '5.5.4' => [{ reason: 'filtered', string: 'Invalid domain name' }],
@@ -100,7 +102,12 @@ module Sisimai
100
102
  'networkerror' => ['SMTPSEND.DNS.MxLoopback'],
101
103
  'rejected' => ['RESOLVER.RST.NotAuthorized'],
102
104
  'securityerror' => ['RESOLVER.RST.AuthRequired'],
103
- 'systemerror' => ['RESOLVER.ADR.Ambiguous', 'RESOLVER.ADR.BadPrimary', 'RESOLVER.ADR.InvalidInSmtp'],
105
+ 'systemerror' => [
106
+ 'RESOLVER.ADR.Ambiguous',
107
+ 'RESOLVER.ADR.BadPrimary',
108
+ 'RESOLVER.ADR.InvalidInSmtp',
109
+ 'RESOLVER.FWD.NotFound',
110
+ ],
104
111
  'toomanyconn' => ['RESOLVER.ADR.RecipLimit', 'RESOLVER.ADR.RecipientLimit'],
105
112
  'userunknown' => [
106
113
  'RESOLVER.ADR.RecipNotFound',
@@ -123,6 +123,10 @@ module Sisimai
123
123
  # Message refuse, verification DMARC en echec LPN007_517
124
124
  '517' => 'policyviolation',
125
125
 
126
+ # 554 5.7.1 Client host rejected
127
+ # LPN000_630
128
+ '630' => 'policyviolation',
129
+
126
130
  # 421 mwinf5c77 ME Service refuse. Veuillez essayer plus tard.
127
131
  # Service refused, please try later. OFR_999 [999]
128
132
  '999' => 'blocked',
@@ -92,7 +92,10 @@ module Sisimai
92
92
  'Messages with multiple addresses in From: header are not accepted.',
93
93
  'The user or domain that you are sending to (or from) has a policy',
94
94
  ]},
95
- { reason: 'rejected', string: ['Unauthenticated email is not accepted from this domain.'] },
95
+ { reason: 'rejected', string: [
96
+ 'This message does not have authentication information or fails to pass authentication checks',
97
+ 'Unauthenticated email is not accepted from this domain.',
98
+ ]},
96
99
  ],
97
100
  'X.7.4' => [{ reason: 'syntaxerror', string: ['Unrecognized Authentication Type.'] }],
98
101
  }.freeze
data/lib/sisimai/rhost.rb CHANGED
@@ -59,6 +59,7 @@ module Sisimai
59
59
  rhostclass = modulename.gsub('::', '/').downcase
60
60
  break
61
61
  end
62
+ return nil if rhostclass.empty?
62
63
 
63
64
  require rhostclass
64
65
  reasontext = Module.const_get(modulename).get(argvs)
@@ -24,27 +24,28 @@ module Sisimai
24
24
  # nil: is not an error
25
25
  # @since v4.17.3
26
26
  def is_permanent(argv1 = '')
27
- getchecked = nil
27
+ return nil unless argv1
28
+ permanent1 = nil
28
29
  statuscode = Sisimai::SMTP::Status.find(argv1) || Sisimai::SMTP::Reply.find(argv1) || '0'
29
30
 
30
31
  if (classvalue = statuscode[0, 1].to_i) > 0
31
32
  # 2, 4, or 5
32
33
  if classvalue == 5
33
34
  # Permanent error
34
- getchecked = true
35
+ permanent1 = true
35
36
 
36
37
  elsif classvalue == 4
37
38
  # Temporary error
38
- getchecked = false
39
+ permanent1 = false
39
40
 
40
41
  elsif classvalue == 2
41
42
  # Succeeded
42
- getchecked = nil
43
+ permanent1 = nil
43
44
  end
44
45
  else
45
46
  # Check with regular expression
46
47
  v = argv1.downcase
47
- getchecked = if v.include?('temporar') || v.include?('persistent')
48
+ permanent1 = if v.include?('temporar') || v.include?('persistent')
48
49
  # Temporary failure
49
50
  false
50
51
  elsif v.include?('permanent')
@@ -53,7 +54,7 @@ module Sisimai
53
54
  end
54
55
  end
55
56
 
56
- return getchecked
57
+ return permanent1
57
58
  end
58
59
 
59
60
  # Check softbounce or not
@@ -64,6 +65,7 @@ module Sisimai
64
65
  # '': May not be bounce ?
65
66
  # @since v4.17.3
66
67
  def soft_or_hard(argv1 = '', argv2 = '')
68
+ return nil unless argv1
67
69
  return nil if argv1.empty?
68
70
  value = nil
69
71
 
@@ -82,7 +82,7 @@ module Sisimai
82
82
  # reply code.
83
83
  argv1 = argv1.gsub(/#{IP4Re}/, '***.***.***.***') if argv1 =~ IP4Re
84
84
 
85
- if cv = argv1.match(/\b([45][0-5][0-9])\b/) || argv1.match(/\b(25[0-3])\b/)
85
+ if cv = argv1.match(/\b([45][0-7][0-9])\b/) || argv1.match(/\b(25[0-3])\b/)
86
86
  # 550, 447, or 250
87
87
  return cv[1]
88
88
  else
@@ -651,7 +651,7 @@ module Sisimai
651
651
  '5.7.24' => 'securityerror', # SPF validation error
652
652
  '5.7.25' => 'blocked', # Reverse DNS validation failed
653
653
  '5.7.26' => 'securityerror', # Multiple authentication checks failed
654
- '5.7.27' => 'rejected', # Sender address has null MX
654
+ '5.7.27' => 'notaccept', # MX resource record of a destination host is Null MX: RFC7505
655
655
  }.freeze
656
656
 
657
657
  InternalCode = {
data/lib/sisimai/time.rb CHANGED
@@ -1,8 +1,7 @@
1
1
  require 'date'
2
-
3
2
  module Sisimai
4
3
  # Sisimai::Time is a child class of Date for Sisimai::Data.
5
- class Time < DateTime
4
+ class Time < ::DateTime
6
5
  # Imported from p5-Sisimail/lib/Sisimai/Time.pm
7
6
  def to_json(*)
8
7
  return self.to_time.to_i
@@ -1,4 +1,4 @@
1
1
  # Define the version number of Sisimai
2
2
  module Sisimai
3
- VERSION = '4.25.8'.freeze
3
+ VERSION = '4.25.12'.freeze
4
4
  end