sisimai 4.22.2 → 4.22.3
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.
- checksums.yaml +4 -4
- data/ANALYTICAL-PRECISION +24 -23
- data/ChangeLog.md +39 -2
- data/README-JA.md +10 -10
- data/README.md +10 -10
- data/lib/sisimai.rb +0 -1
- data/lib/sisimai/bite/email.rb +1 -1
- data/lib/sisimai/bite/email/amazonses.rb +1 -2
- data/lib/sisimai/bite/email/exim.rb +46 -8
- data/lib/sisimai/bite/email/fml.rb +170 -0
- data/lib/sisimai/bite/email/imailserver.rb +1 -1
- data/lib/sisimai/bite/email/messagelabs.rb +6 -1
- data/lib/sisimai/bite/email/office365.rb +0 -1
- data/lib/sisimai/data.rb +34 -12
- data/lib/sisimai/datetime.rb +10 -4
- data/lib/sisimai/reason.rb +70 -55
- data/lib/sisimai/reason/blocked.rb +91 -21
- data/lib/sisimai/reason/expired.rb +7 -3
- data/lib/sisimai/reason/filtered.rb +1 -0
- data/lib/sisimai/reason/hostunknown.rb +9 -5
- data/lib/sisimai/reason/mailboxfull.rb +17 -9
- data/lib/sisimai/reason/mailererror.rb +5 -4
- data/lib/sisimai/reason/mesgtoobig.rb +2 -0
- data/lib/sisimai/reason/networkerror.rb +11 -3
- data/lib/sisimai/reason/norelaying.rb +5 -2
- data/lib/sisimai/reason/policyviolation.rb +9 -2
- data/lib/sisimai/reason/rejected.rb +41 -10
- data/lib/sisimai/reason/securityerror.rb +2 -0
- data/lib/sisimai/reason/spamdetected.rb +37 -20
- data/lib/sisimai/reason/suspend.rb +10 -4
- data/lib/sisimai/reason/systemerror.rb +1 -0
- data/lib/sisimai/reason/toomanyconn.rb +4 -0
- data/lib/sisimai/reason/userunknown.rb +40 -20
- data/lib/sisimai/reason/vacation.rb +20 -1
- data/lib/sisimai/reason/virusdetected.rb +3 -1
- data/lib/sisimai/rfc3464.rb +3 -4
- data/lib/sisimai/rfc3834.rb +37 -6
- data/lib/sisimai/rhost.rb +2 -1
- data/lib/sisimai/rhost/exchangeonline.rb +29 -0
- data/lib/sisimai/rhost/franceptt.rb +58 -0
- data/lib/sisimai/smtp/status.rb +1 -0
- data/lib/sisimai/version.rb +1 -1
- data/set-of-emails/jsonobj/json-amazonses-06.json +1 -0
- data/set-of-emails/maildir/bsd/email-exim-31.eml +39 -0
- data/set-of-emails/maildir/bsd/email-exim-32.eml +42 -0
- data/set-of-emails/maildir/bsd/email-exim-33.eml +42 -0
- data/set-of-emails/maildir/bsd/email-exim-34.eml +41 -0
- data/set-of-emails/maildir/bsd/email-exim-35.eml +41 -0
- data/set-of-emails/maildir/bsd/email-exim-36.eml +41 -0
- data/set-of-emails/maildir/bsd/email-exim-37.eml +41 -0
- data/set-of-emails/maildir/bsd/email-exim-38.eml +32 -0
- data/set-of-emails/maildir/bsd/email-exim-39.eml +47 -0
- data/set-of-emails/maildir/bsd/email-exim-40.eml +41 -0
- data/set-of-emails/maildir/bsd/email-exim-41.eml +32 -0
- data/set-of-emails/maildir/bsd/email-exim-42.eml +41 -0
- data/set-of-emails/maildir/bsd/email-exim-43.eml +60 -0
- data/set-of-emails/maildir/bsd/email-exim-44.eml +64 -0
- data/set-of-emails/maildir/bsd/email-exim-45.eml +43 -0
- data/set-of-emails/maildir/bsd/email-exim-46.eml +41 -0
- data/set-of-emails/maildir/bsd/email-exim-47.eml +42 -0
- data/set-of-emails/maildir/bsd/email-exim-48.eml +59 -0
- data/set-of-emails/maildir/bsd/email-exim-49.eml +59 -0
- data/set-of-emails/maildir/bsd/email-exim-50.eml +41 -0
- data/set-of-emails/maildir/bsd/email-exim-51.eml +41 -0
- data/set-of-emails/maildir/bsd/email-exim-52.eml +34 -0
- data/set-of-emails/maildir/bsd/email-exim-53.eml +48 -0
- data/set-of-emails/maildir/bsd/email-exim-54.eml +40 -0
- data/set-of-emails/maildir/bsd/email-exim-55.eml +38 -0
- data/set-of-emails/maildir/bsd/email-exim-56.eml +40 -0
- data/set-of-emails/maildir/bsd/email-exim-57.eml +39 -0
- data/set-of-emails/maildir/bsd/email-exim-58.eml +43 -0
- data/set-of-emails/maildir/bsd/email-fml-01.eml +70 -0
- data/set-of-emails/maildir/bsd/email-fml-02.eml +44 -0
- data/set-of-emails/maildir/bsd/email-office365-03.eml +117 -0
- data/set-of-emails/maildir/bsd/email-postfix-31.eml +94 -0
- data/set-of-emails/maildir/bsd/email-sendmail-45.eml +102 -0
- data/set-of-emails/maildir/bsd/email-sendmail-46.eml +103 -0
- data/set-of-emails/maildir/bsd/email-sendmail-47.eml +102 -0
- data/set-of-emails/maildir/bsd/email-sendmail-48.eml +101 -0
- data/set-of-emails/maildir/bsd/rfc3464-33.eml +38 -0
- data/set-of-emails/maildir/bsd/rfc3464-34.eml +53 -0
- data/set-of-emails/maildir/bsd/rhost-exchange-online-02.eml +89 -0
- data/set-of-emails/maildir/bsd/rhost-exchange-online-03.eml +205 -0
- data/set-of-emails/maildir/bsd/rhost-franceptt-01.eml +102 -0
- data/set-of-emails/maildir/bsd/rhost-franceptt-02.eml +103 -0
- metadata +47 -2
@@ -20,18 +20,24 @@ module Sisimai
|
|
20
20
|
def match(argv1)
|
21
21
|
return nil unless argv1
|
22
22
|
regex = %r{(?>
|
23
|
-
|
24
|
-
# http://service.mail.qq.com/cgi-bin/help?subtype=1&&id=20022&&no=1000742
|
23
|
+
Boite[ ]du[ ]destinataire[ ]archivee.+[A-Z]{3}.+420
|
25
24
|
|email[ ]account[ ]that[ ]you[ ]tried[ ]to[ ]reach[ ]is[ ]disabled
|
25
|
+
|invalid/inactive[ ]user
|
26
|
+
# http://service.mail.qq.com/cgi-bin/help?subtype=1&&id=20022&&no=1000742
|
26
27
|
|is[ ]a[ ]deactivated[ ]mailbox
|
27
28
|
|mailbox[ ](?:
|
28
29
|
currently[ ]suspended
|
29
30
|
|unavailable[ ]or[ ]access[ ]denied
|
30
31
|
)
|
31
|
-
|
|
32
|
-
|
32
|
+
|recipient[ ](?:
|
33
|
+
rejected:[ ]Temporarily[ ]inactive
|
34
|
+
|suspend[ ]the[ ]service
|
35
|
+
)
|
33
36
|
|sorry[ ]your[ ]message[ ]to[ ].+[ ]cannot[ ]be[ ]delivered[.][ ]this[ ]
|
34
37
|
account[ ]has[ ]been[ ]disabled[ ]or[ ]discontinued
|
38
|
+
|The[ ]domain[ ].+[ ]is[ ]currently[ ]suspended
|
39
|
+
|User[ ].+[ ]temporary[ ]locked
|
40
|
+
|user[ ]suspended # http://mail.163.com/help/help_spam_16.htm
|
35
41
|
|vdelivermail:[ ]account[ ]is[ ]locked[ ]email[ ]bounced
|
36
42
|
)
|
37
43
|
}ix
|
@@ -25,6 +25,7 @@ module Sisimai
|
|
25
25
|
return nil unless argv1
|
26
26
|
regex = %r{(?>
|
27
27
|
can[']t[ ]create[ ]user[ ]output[ ]file
|
28
|
+
|Could[ ]not[ ]load[ ]DRD[ ]for[ ]domain
|
28
29
|
|Internal[ ](?:
|
29
30
|
error[ ]reading[ ]data # Microsoft
|
30
31
|
|server[ ]error:[ ]Operation[ ]now[ ]in[ ]progress # Microsoft
|
@@ -26,6 +26,7 @@ module Sisimai
|
|
26
26
|
regex = %r{(?>
|
27
27
|
All[ ]available[ ]IPs[ ]are[ ]at[ ]maximum[ ]connection[ ]limit # SendGrid
|
28
28
|
|connection[ ]rate[ ]limit[ ]exceeded
|
29
|
+
|domain[ ].+[ ]has[ ]exceeded[ ]the[ ]max[ ]emails[ ]per[ ]hour[ ].+[ ]allowed
|
29
30
|
|no[ ]IPs[ ]available[ ][-][ ].+[ ]exceeds[ ]per[-]domain[ ]connection[ ]limit[ ]for
|
30
31
|
|Throttling[ ]failure:[ ](?:
|
31
32
|
Daily[ ]message[ ]quota[ ]exceeded
|
@@ -35,8 +36,11 @@ module Sisimai
|
|
35
36
|
connections
|
36
37
|
|connections[ ]from[ ]your[ ]host[.] # Microsoft
|
37
38
|
|concurrent[ ]SMTP[ ]connections # Microsoft
|
39
|
+
|errors[ ]from[ ]your[ ]IP # Free.fr
|
38
40
|
|SMTP[ ]sessions[ ]for[ ]this[ ]host # Sendmail(daemon.c)
|
39
41
|
)
|
42
|
+
|Trop[ ]de[ ]connexions,[ ].+[A-Z]{3}.+104
|
43
|
+
|We[ ]have[ ]already[ ]made[ ]numerous[ ]attempts[ ]to[ ]deliver[ ]this[ ]message
|
40
44
|
)
|
41
45
|
}ix
|
42
46
|
|
@@ -31,65 +31,83 @@ module Sisimai
|
|
31
31
|
.+[ ]user[ ]unknown
|
32
32
|
|[#]5[.]1[.]1[ ]bad[ ]address
|
33
33
|
|[<].+[>][ ]not[ ]found
|
34
|
-
|
|
35
|
-
|
|
34
|
+
|[<].+[@].+[>][.][.][.][ ]Blocked[ ]by[ ]
|
35
|
+
|5[.]0[.]0[.][ ]Mail[ ]rejected[.]
|
36
|
+
|5[.]1[.]0[ ]Address[ ]rejected[.]
|
37
|
+
|Adresse[ ]d[ ]au[ ]moins[ ]un[ ]destinataire[ ]invalide.+[A-Z]{3}.+(?:416|418)
|
38
|
+
|address[ ](?:does[ ]not[ ]exist|unknown)
|
36
39
|
|archived[ ]recipient
|
37
40
|
|BAD[-_ ]RECIPIENT
|
38
41
|
|can[']t[ ]accept[ ]user
|
39
|
-
|destination[ ]
|
40
|
-
|
41
|
-
|
42
|
+
|destination[ ](?:
|
43
|
+
addresses[ ]were[ ]unknown
|
44
|
+
|server[ ]rejected[ ]recipients
|
45
|
+
)
|
46
|
+
|email[ ]address[ ](?:does[ ]not[ ]exist|could[ ]not[ ]be[ ]found)
|
42
47
|
|invalid[ ](?:
|
43
48
|
address
|
49
|
+
|mailbox:
|
44
50
|
|mailbox[ ]path
|
45
|
-
|recipient
|
51
|
+
|recipient
|
46
52
|
)
|
47
53
|
|is[ ]not[ ](?:
|
48
54
|
a[ ]known[ ]user
|
55
|
+
|a[ ]valid[ ]mailbox
|
49
56
|
|an[ ]active[ ]address[ ]at[ ]this[ ]host
|
50
57
|
)
|
51
58
|
|mailbox[ ](?:
|
52
|
-
not[ ]
|
53
|
-
|
59
|
+
.+[ ]does[ ]not[ ]exist
|
60
|
+
|.+[@].+[ ]unavailable
|
61
|
+
|invalid
|
62
|
+
|is[ ](?:inactive|unavailable)
|
63
|
+
|not[ ](?:present|found)
|
54
64
|
|unavailable
|
55
65
|
)
|
56
66
|
|no[ ](?:
|
57
|
-
|
67
|
+
[ ].+[ ]in[ ]name[ ]directory
|
68
|
+
|account[ ]by[ ]that[ ]name[ ]here
|
69
|
+
|existe[ ](?:dicha[ ]persona|ese[ ]usuario[ ])
|
58
70
|
|mail[ ]box[ ]available[ ]for[ ]this[ ]user
|
59
|
-
|mailbox[ ]
|
71
|
+
|mailbox[ ](?:
|
72
|
+
by[ ]that[ ]name[ ]is[ ]currently[ ]available
|
73
|
+
|found
|
74
|
+
)
|
60
75
|
|matches[ ]to[ ]nameserver[ ]query
|
61
76
|
|such[ ](?:
|
62
|
-
|
77
|
+
address[ ]here
|
78
|
+
|mailbox
|
63
79
|
|person[ ]at[ ]this[ ]address
|
64
80
|
|recipient
|
65
81
|
|user(?:[ ]here)?
|
66
82
|
)
|
67
|
-
|[ ]
|
83
|
+
|thank[ ]you[ ]rejected:[ ]Account[ ]Unavailable:
|
68
84
|
|valid[ ]recipients[,][ ]bye # Microsoft
|
69
85
|
)
|
70
86
|
|non[- ]?existent[ ]user
|
71
87
|
|not[ ](?:
|
72
88
|
a[ ]valid[ ]user[ ]here
|
73
89
|
|a[ ]local[ ]address
|
90
|
+
|email[ ]addresses
|
74
91
|
)
|
75
92
|
|rcpt[ ][<].+[>][ ]does[ ]not[ ]exist
|
76
|
-
|
|
93
|
+
|rece?ipient[ ](?:
|
77
94
|
.+[ ]was[ ]not[ ]found[ ]in
|
78
95
|
|address[ ]rejected:[ ](?:
|
79
|
-
|
96
|
+
Access[ ]denied
|
97
|
+
|invalid[ ]user
|
80
98
|
|user[ ].+[ ]does[ ]not[ ]exist
|
81
99
|
|user[ ]unknown[ ]in[ ].+[ ]table
|
82
100
|
|unknown[ ]user
|
83
101
|
)
|
84
102
|
|does[ ]not[ ]exist(?:[ ]on[ ]this[ ]system)?
|
85
103
|
|is[ ]not[ ]local
|
86
|
-
|not[ ]found
|
87
|
-
|not[ ]OK
|
104
|
+
|not[ ](?:exist|found|OK)
|
88
105
|
|unknown
|
89
106
|
)
|
90
107
|
|requested[ ]action[ ]not[ ]taken:[ ]mailbox[ ]unavailable
|
91
|
-
|RESOLVER[.]ADR[.]
|
108
|
+
|RESOLVER[.]ADR[.]Recip(?:ient)NotFound
|
92
109
|
|said:[ ]550[-[ ]]5[.]1[.]1[ ].+[ ]user[ ]unknown[ ]
|
110
|
+
|SMTP[ ]error[ ]from[ ]remote[ ]mail[ ]server[ ]after[ ]end[ ]of[ ]data:[ ]553.+does[ ]not[ ]exist
|
93
111
|
|sorry,[ ](?:
|
94
112
|
user[ ]unknown
|
95
113
|
|badrcptto
|
@@ -100,9 +118,11 @@ module Sisimai
|
|
100
118
|
|following[ ]recipients[ ]was[ ]undeliverable
|
101
119
|
|user[']s[ ]email[ ]name[ ]is[ ]not[ ]found
|
102
120
|
)
|
121
|
+
|There[ ]is[ ]no[ ]one[ ]at[ ]this[ ]address
|
103
122
|
|this[ ](?:
|
104
123
|
address[ ]no[ ]longer[ ]accepts[ ]mail
|
105
124
|
|email[ ]address[ ]is[ ]wrong[ ]or[ ]no[ ]longer[ ]valid
|
125
|
+
|spectator[ ]does[ ]not[ ]exist
|
106
126
|
|user[ ]doesn[']?t[ ]have[ ]a[ ].+[ ]account
|
107
127
|
)
|
108
128
|
|unknown[ ](?:
|
@@ -117,11 +137,11 @@ module Sisimai
|
|
117
137
|
|.+[ ]does[ ]not[ ]exist
|
118
138
|
|does[ ]not[ ]exist
|
119
139
|
|missing[ ]home[ ]directory
|
120
|
-
|not[ ]found
|
121
|
-
|not[ ]known
|
140
|
+
|not[ ](?:active|found|known)
|
122
141
|
|unknown
|
123
142
|
)
|
124
143
|
|vdeliver:[ ]invalid[ ]or[ ]unknown[ ]virtual[ ]user
|
144
|
+
|your[ ]envelope[ ]recipient[ ]is[ ]in[ ]my[ ]badrcptto[ ]list
|
125
145
|
)
|
126
146
|
}ix
|
127
147
|
|
@@ -140,7 +160,7 @@ module Sisimai
|
|
140
160
|
return true if argvs.reason == Sisimai::Reason::UserUnknown.text
|
141
161
|
|
142
162
|
require 'sisimai/smtp/status'
|
143
|
-
prematches = %w|NoRelaying Blocked MailboxFull HasMoved|
|
163
|
+
prematches = %w|NoRelaying Blocked MailboxFull HasMoved Blocked Rejected|
|
144
164
|
matchother = false
|
145
165
|
statuscode = argvs.deliverystatus || ''
|
146
166
|
diagnostic = argvs.diagnosticcode || ''
|
@@ -9,7 +9,26 @@ module Sisimai
|
|
9
9
|
def description
|
10
10
|
return 'Email replied automatically due to a recipient is out of office'
|
11
11
|
end
|
12
|
-
|
12
|
+
|
13
|
+
# Try to match that the given text and regular expressions
|
14
|
+
# @param [String] argv1 String to be matched with regular expressions
|
15
|
+
# @return [True,False] false: Did not match
|
16
|
+
# true: Matched
|
17
|
+
def match(argv1)
|
18
|
+
return nil unless argv1
|
19
|
+
regex = %r{(?>
|
20
|
+
I[ ]am[ ](?:
|
21
|
+
away[ ](?:on[ ]vacation|until)
|
22
|
+
|out[ ]of[ ]the[ ]office
|
23
|
+
)
|
24
|
+
|I[ ]will[ ]be[ ]traveling[ ]for[ ]work[ ]on
|
25
|
+
)
|
26
|
+
}ix
|
27
|
+
|
28
|
+
return true if argv1 =~ regex
|
29
|
+
return false
|
30
|
+
end
|
31
|
+
|
13
32
|
def true(*); return nil; end
|
14
33
|
end
|
15
34
|
end
|
@@ -29,7 +29,9 @@ module Sisimai
|
|
29
29
|
def match(argv1)
|
30
30
|
return nil unless argv1
|
31
31
|
regex = %r{(?>
|
32
|
-
|
32
|
+
it[ ]has[ ]a[ ]potentially[ ]executable[ ]attachment
|
33
|
+
|the[ ]message[ ]was[ ]rejected[ ]because[ ]it[ ]contains[ ]prohibited[ ]virus[ ]or[ ]spam[ ]content
|
34
|
+
|This[ ]form[ ]of[ ]attachment[ ]has[ ]been[ ]used[ ]by[ ]recent[ ]viruses[ ]or[ ]other[ ]malware
|
33
35
|
|Your[ ]message[ ]was[ ]infected[ ]with[ ]a[ ]virus
|
34
36
|
)
|
35
37
|
}ix
|
data/lib/sisimai/rfc3464.rb
CHANGED
@@ -68,7 +68,7 @@ module Sisimai
|
|
68
68
|
require 'sisimai/address'
|
69
69
|
|
70
70
|
dscontents = [Sisimai::Bite.DELIVERYSTATUS]
|
71
|
-
hasdivided = mbody.split("\n")
|
71
|
+
hasdivided = mbody.scrub('?').split("\n")
|
72
72
|
havepassed = ['']
|
73
73
|
scannedset = Sisimai::MDA.scan(mhead, mbody)
|
74
74
|
rfc822list = [] # (Array) Each line in message/rfc822 part string
|
@@ -372,7 +372,6 @@ module Sisimai
|
|
372
372
|
|Error-for:[ ]+
|
373
373
|
|Failed[ ]Recipient:[ ]
|
374
374
|
|Failed[ ]to[ ]deliver[ ]to[ ]
|
375
|
-
|generated[ ]from[ ]
|
376
375
|
|Intended[ ]recipient:[ ]
|
377
376
|
|Mailbox[ ]is[ ]full:[ ]
|
378
377
|
|RCPT[ ]To:
|
@@ -414,7 +413,7 @@ module Sisimai
|
|
414
413
|
b['agent'] = self.smtpagent + '::Fallback'
|
415
414
|
recipients += 1
|
416
415
|
|
417
|
-
elsif cv = e.match(/[(]expanded[ ]from
|
416
|
+
elsif cv = e.match(/[(](?:expanded|generated)[ ]from:?[ ]([^@]+[@][^@]+)[)]/)
|
418
417
|
# (expanded from: neko@example.jp)
|
419
418
|
b['alias'] = Sisimai::Address.s3s4(cv[1])
|
420
419
|
end
|
@@ -430,7 +429,7 @@ module Sisimai
|
|
430
429
|
rfc822list.each do |e|
|
431
430
|
# Check To: header in the original message
|
432
431
|
next unless cv = e.match(/\ATo:\s*(.+)\z/)
|
433
|
-
r = Sisimai::Address.find(cv[1], true)
|
432
|
+
r = Sisimai::Address.find(cv[1], true) || []
|
434
433
|
next if r.empty?
|
435
434
|
|
436
435
|
if dscontents.size == recipients
|
data/lib/sisimai/rfc3834.rb
CHANGED
@@ -10,13 +10,18 @@ module Sisimai
|
|
10
10
|
# https://msdn.microsoft.com/en-us/library/ee219609(v=exchg.80).aspx
|
11
11
|
:'x-auto-response-suppress' => %r/(?:OOF|AutoReply)/i,
|
12
12
|
:'precedence' => %r/\Aauto_reply\z/,
|
13
|
-
:'subject' => %r/\A(
|
13
|
+
:'subject' => %r/\A(?>
|
14
14
|
Auto:
|
15
|
-
|
|
15
|
+
|Auto[ ]Response:
|
16
|
+
|Automatic[ ]reply:
|
17
|
+
|Out[ ]of[ ](?:the[ ])*Office:
|
16
18
|
)
|
17
19
|
/xi,
|
18
20
|
}.freeze
|
19
|
-
Re1 = {
|
21
|
+
Re1 = {
|
22
|
+
:boundary => %r/\A__SISIMAI_PSEUDO_BOUNDARY__\z/,
|
23
|
+
:endof => %r/\A__END_OF_EMAIL_MESSAGE__\z/
|
24
|
+
}
|
20
25
|
Re2 = {
|
21
26
|
:subject => %r/(?:
|
22
27
|
SECURITY[ ]information[ ]for # sudo
|
@@ -26,6 +31,14 @@ module Sisimai
|
|
26
31
|
:from => %r/(?:root|postmaster|mailer-daemon)[@]/i,
|
27
32
|
:to => %r/root[@]/,
|
28
33
|
}.freeze
|
34
|
+
ReV = %r{\A(?>
|
35
|
+
(?:.+?)?Re:
|
36
|
+
|Auto(?:[ ]Response):
|
37
|
+
|Automatic[ ]reply:
|
38
|
+
|Out[ ]of[ ]Office:
|
39
|
+
)
|
40
|
+
[ ]*(.+)\z
|
41
|
+
}xi
|
29
42
|
|
30
43
|
def description; 'Detector for auto replied message'; end
|
31
44
|
def smtpagent; 'RFC3834'; end
|
@@ -84,11 +97,13 @@ module Sisimai
|
|
84
97
|
require 'sisimai/address'
|
85
98
|
|
86
99
|
dscontents = [Sisimai::Bite.DELIVERYSTATUS]
|
87
|
-
hasdivided = mbody.split("\n")
|
100
|
+
hasdivided = mbody.scrub('?').split("\n")
|
101
|
+
rfc822part = '' # (String) message/rfc822-headers part
|
88
102
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
89
103
|
maxmsgline = 5 # (Integer) Max message length(lines)
|
90
104
|
haveloaded = 0 # (Integer) The number of lines loaded from message body
|
91
105
|
blanklines = 0 # (Integer) Counter for countinuous blank lines
|
106
|
+
countuntil = 1 # (Integer) Maximum value of blank lines in the body part
|
92
107
|
v = dscontents[-1]
|
93
108
|
|
94
109
|
# RECIPIENT_ADDRESS
|
@@ -107,16 +122,27 @@ module Sisimai
|
|
107
122
|
end
|
108
123
|
return nil unless recipients > 0
|
109
124
|
|
125
|
+
if mhead['content-type']
|
126
|
+
# Get the boundary string and set regular expression for matching with
|
127
|
+
# the boundary string.
|
128
|
+
require 'sisimai/mime'
|
129
|
+
b0 = Sisimai::MIME.boundary(mhead['content-type'], 0)
|
130
|
+
Re1[:boundary] = %r/\A\Q#{b0}\E\z/ unless b0.empty?
|
131
|
+
end
|
132
|
+
|
110
133
|
# BODY_PARSER: Get vacation message
|
111
134
|
hasdivided.each do |e|
|
112
135
|
# Read the first 5 lines except a blank line
|
136
|
+
countuntil += 1 if e =~ Re1[:boundary]
|
137
|
+
|
113
138
|
unless e.size > 0
|
114
139
|
# Check a blank line
|
115
140
|
blanklines += 1
|
116
|
-
break if blanklines >
|
141
|
+
break if blanklines > countuntil
|
117
142
|
next
|
118
143
|
end
|
119
144
|
next unless e =~ / /
|
145
|
+
next if e =~ /\AContent-(?:Type|Transfer)/
|
120
146
|
|
121
147
|
v['diagnosis'] ||= ''
|
122
148
|
v['diagnosis'] += e + ' '
|
@@ -133,7 +159,12 @@ module Sisimai
|
|
133
159
|
v['status'] = ''
|
134
160
|
|
135
161
|
v.each_key { |a| v[a] ||= '' }
|
136
|
-
|
162
|
+
|
163
|
+
if cv = mhead['subject'].match(ReV)
|
164
|
+
# Get the Subject header from the original message
|
165
|
+
rfc822part = sprintf("Subject: %s\n", cv[1])
|
166
|
+
end
|
167
|
+
return { 'ds' => dscontents, 'rfc822' => rfc822part }
|
137
168
|
end
|
138
169
|
|
139
170
|
end
|
data/lib/sisimai/rhost.rb
CHANGED
@@ -8,8 +8,9 @@ module Sisimai
|
|
8
8
|
# Imported from p5-Sisimail/lib/Sisimai/Rhost.pm
|
9
9
|
RhostClass = {
|
10
10
|
%r/\Aaspmx[.]l[.]google[.]com\z/ => 'GoogleApps',
|
11
|
-
%r/[.]protection[.]outlook[.]com\z/
|
11
|
+
%r/[.](?:prod|protection)[.]outlook[.]com\z/ => 'ExchangeOnline',
|
12
12
|
%r/\A(?:smtp|mailstore1)[.]secureserver[.]net\z/ => 'GoDaddy',
|
13
|
+
%r/\b(?:laposte[.]net|orange[.]fr)\z/ => 'FrancePTT',
|
13
14
|
}.freeze
|
14
15
|
|
15
16
|
# Retrun the list of remote hosts Sisimai support
|
@@ -128,6 +128,12 @@ module Sisimai
|
|
128
128
|
:regexp => %r/(?:Invalid[ ]arguments|Routing[ ]loop[ ]detected)/x,
|
129
129
|
},
|
130
130
|
],
|
131
|
+
%r/\A5[.]4[.]14\z/ => [
|
132
|
+
{
|
133
|
+
:reason => 'networkerror',
|
134
|
+
:regexp => %r/Hop[ ]count[ ]exceeded/x
|
135
|
+
},
|
136
|
+
],
|
131
137
|
%r/\A5[.]5[.]2\z/ => [
|
132
138
|
{
|
133
139
|
:reason => 'syntaxerror',
|
@@ -239,6 +245,18 @@ module Sisimai
|
|
239
245
|
},
|
240
246
|
],
|
241
247
|
}.freeze
|
248
|
+
MesgTable = {
|
249
|
+
# Copied and converted from Sisimai::Bite::Email::Exchange2007
|
250
|
+
:expired => %r/QUEUE[.]Expired/,
|
251
|
+
:hostunknown => %r/SMTPSEND[.]DNS[.]NonExistentDomain/,
|
252
|
+
:mesgtoobig => %r/RESOLVER[.]RST[.]Recip(?:ient)?SizeLimit/,
|
253
|
+
:networkerror => %r/SMTPSEND[.]DNS[.]MxLoopback/,
|
254
|
+
:rejected => %r/RESOLVER[.]RST[.]NotAuthorized/,
|
255
|
+
:securityerror => %r/RESOLVER[.]RST[.]AuthRequired/,
|
256
|
+
:systemerror => %r/RESOLVER[.]ADR[.](?:Ambiguous|BadPrimary|InvalidInSmtp)/,
|
257
|
+
:toomanyconn => %r/RESOLVER[.]ADR[.]Recip(?:ient)?Limit/,
|
258
|
+
:userunknown => %r/RESOLVER[.]ADR[.](?:Ex)?Recip(?:ient)?NotFound/,
|
259
|
+
}.freeze
|
242
260
|
|
243
261
|
# Detect bounce reason from Exchange Online
|
244
262
|
# @param [Sisimai::Data] argvs Parsed email object
|
@@ -263,6 +281,17 @@ module Sisimai
|
|
263
281
|
end
|
264
282
|
end
|
265
283
|
|
284
|
+
if reasontext.empty?
|
285
|
+
# D.S.N. included in the error message did not matched with any key
|
286
|
+
# in CodeTable
|
287
|
+
MesgTable.each_key do |e|
|
288
|
+
# Try to match with error messages defined in MesgTable
|
289
|
+
next unless statusmesg =~ MesgTable[e]
|
290
|
+
reasontext = e.to_s
|
291
|
+
break
|
292
|
+
end
|
293
|
+
end
|
294
|
+
|
266
295
|
return reasontext
|
267
296
|
end
|
268
297
|
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Sisimai
|
2
|
+
module Rhost
|
3
|
+
# Sisimai::Rhost detects the bounce reason from the content of Sisimai::Data
|
4
|
+
# object as an argument of get() method when the value of "rhost" of the object
|
5
|
+
# is "*.laposte.net" or "*.orange.fr".
|
6
|
+
# This class is called only Sisimai::Data class.
|
7
|
+
module FrancePTT
|
8
|
+
class << self
|
9
|
+
# Imported from p5-Sisimail/lib/Sisimai/Rhost/FrancePTT.pm
|
10
|
+
CodeTable = {
|
11
|
+
:'103' => 'blocked', # Service refuse. Veuillez essayer plus tard.
|
12
|
+
:'104' => 'toomanyconn', # Too many connections, slow down. LPN105_104
|
13
|
+
:'105' => nil, # Veuillez essayer plus tard.
|
14
|
+
:'109' => nil, # Veuillez essayer plus tard. LPN003_109
|
15
|
+
:'201' => nil, # Veuillez essayer plus tard. OFR004_201
|
16
|
+
:'305' => 'securityerror', # 550 5.7.0 Code d'authentification invalide OFR_305
|
17
|
+
:'401' => 'blocked', # 550 5.5.0 SPF: *** is not allowed to send mail. LPN004_401
|
18
|
+
:'402' => 'securityerror', # 550 5.5.0 Authentification requise. Authentication Required. LPN105_402
|
19
|
+
:'403' => 'rejected', # 5.0.1 Emetteur invalide. Invalid Sender.
|
20
|
+
:'405' => 'rejected', # 5.0.1 Emetteur invalide. Invalid Sender. LPN105_405
|
21
|
+
:'415' => 'rejected', # Emetteur invalide. Invalid Sender. OFR_415
|
22
|
+
:'416' => 'userunknown', # 550 5.1.1 Adresse d au moins un destinataire invalide. Invalid recipient. LPN416
|
23
|
+
:'417' => 'mailboxfull', # 552 5.1.1 Boite du destinataire pleine. Recipient overquota.
|
24
|
+
:'418' => 'userunknown', # Adresse d au moins un destinataire invalide
|
25
|
+
:'420' => 'suspend', # Boite du destinataire archivee. Archived recipient.
|
26
|
+
:'421' => 'rejected', # 5.5.3 Mail from not owned by user. LPN105_421.
|
27
|
+
:'423' => nil, # Service refused, please try later. LPN105_423
|
28
|
+
:'424' => nil, # Veuillez essayer plus tard. LPN105_424
|
29
|
+
:'506' => 'spamdetected', # Mail rejete. Mail rejected. OFR_506 [506]
|
30
|
+
:'510' => 'blocked', # Veuillez essayer plus tard. service refused, please try later. LPN004_510
|
31
|
+
:'513' => nil, # Mail rejete. Mail rejected. OUK_513
|
32
|
+
:'514' => 'mesgtoobig', # Taille limite du message atteinte
|
33
|
+
}.freeze
|
34
|
+
|
35
|
+
# Detect bounce reason from Oranage or La Poste
|
36
|
+
# @param [Sisimai::Data] argvs Parsed email object
|
37
|
+
# @return [String] The bounce reason for Orange or La Poste
|
38
|
+
def get(argvs)
|
39
|
+
return nil unless argvs
|
40
|
+
return nil unless argvs.is_a? Sisimai::Data
|
41
|
+
return argvs.reason if argvs.reason.size > 0
|
42
|
+
|
43
|
+
statusmesg = argvs.diagnosticcode
|
44
|
+
reasontext = ''
|
45
|
+
|
46
|
+
if cv = statusmesg.match(/\b(LPN|OFR|OUK)(_[0-9]{3}|[0-9]{3}[-_][0-9]{3})\b/)
|
47
|
+
# OUK_513, LPN105-104, OFR102-104
|
48
|
+
v = sprintf("%03d", (cv[1] + cv[2])[-3, 3])
|
49
|
+
reasontext = CodeTable[v.to_sym] || 'undefined'
|
50
|
+
end
|
51
|
+
return reasontext
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|