sisimai 4.25.16-java → 5.0.2-java
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.
- checksums.yaml +5 -5
- data/.github/workflows/rake-test.yml +55 -0
- data/.travis.yml +3 -3
- data/ANALYTICAL-PRECISION +2 -2
- data/Benchmarks.mk +3 -3
- data/CONTRIBUTING +1 -1
- data/ChangeLog.md +451 -393
- data/Developers.mk +5 -6
- data/Gemfile +1 -1
- data/Makefile +15 -15
- data/README-JA.md +323 -149
- data/README.md +319 -149
- data/Rakefile +9 -3
- data/Repository.mk +2 -3
- data/lib/sisimai/address.rb +118 -74
- data/lib/sisimai/arf.rb +84 -82
- data/lib/sisimai/datetime.rb +5 -52
- data/lib/sisimai/{data → fact}/json.rb +7 -9
- data/lib/sisimai/fact/yaml.rb +31 -0
- data/lib/sisimai/fact.rb +506 -0
- data/lib/sisimai/lhost/activehunter.rb +12 -14
- data/lib/sisimai/lhost/amavis.rb +11 -14
- data/lib/sisimai/lhost/amazonses.rb +37 -42
- data/lib/sisimai/lhost/amazonworkmail.rb +15 -19
- data/lib/sisimai/lhost/aol.rb +12 -15
- data/lib/sisimai/lhost/apachejames.rb +19 -21
- data/lib/sisimai/lhost/barracuda.rb +10 -12
- data/lib/sisimai/lhost/bigfoot.rb +21 -22
- data/lib/sisimai/lhost/biglobe.rb +15 -16
- data/lib/sisimai/lhost/courier.rb +20 -20
- data/lib/sisimai/lhost/domino.rb +23 -20
- data/lib/sisimai/lhost/einsundeins.rb +23 -18
- data/lib/sisimai/lhost/exchange2003.rb +30 -29
- data/lib/sisimai/lhost/exchange2007.rb +70 -58
- data/lib/sisimai/lhost/exim.rb +179 -174
- data/lib/sisimai/lhost/ezweb.rb +31 -56
- data/lib/sisimai/lhost/facebook.rb +21 -34
- data/lib/sisimai/lhost/fml.rb +43 -48
- data/lib/sisimai/lhost/gmail.rb +29 -29
- data/lib/sisimai/lhost/gmx.rb +18 -17
- data/lib/sisimai/lhost/googlegroups.rb +11 -11
- data/lib/sisimai/lhost/gsuite.rb +21 -28
- data/lib/sisimai/lhost/imailserver.rb +25 -39
- data/lib/sisimai/lhost/interscanmss.rb +28 -31
- data/lib/sisimai/lhost/kddi.rb +22 -28
- data/lib/sisimai/lhost/mailfoundry.rb +11 -12
- data/lib/sisimai/lhost/mailmarshalsmtp.rb +25 -29
- data/lib/sisimai/lhost/mailru.rb +37 -40
- data/lib/sisimai/lhost/mcafee.rb +21 -31
- data/lib/sisimai/lhost/messagelabs.rb +17 -21
- data/lib/sisimai/lhost/messagingserver.rb +40 -37
- data/lib/sisimai/lhost/mfilter.rb +16 -17
- data/lib/sisimai/lhost/mxlogic.rb +24 -33
- data/lib/sisimai/lhost/notes.rb +17 -17
- data/lib/sisimai/lhost/office365.rb +64 -28
- data/lib/sisimai/lhost/opensmtpd.rb +12 -13
- data/lib/sisimai/lhost/outlook.rb +12 -16
- data/lib/sisimai/lhost/postfix.rb +179 -130
- data/lib/sisimai/lhost/powermta.rb +12 -14
- data/lib/sisimai/lhost/qmail.rb +44 -47
- data/lib/sisimai/lhost/receivingses.rb +15 -21
- data/lib/sisimai/lhost/sendgrid.rb +34 -34
- data/lib/sisimai/lhost/sendmail.rb +65 -53
- data/lib/sisimai/lhost/surfcontrol.rb +19 -19
- data/lib/sisimai/lhost/v5sendmail.rb +45 -39
- data/lib/sisimai/lhost/verizon.rb +35 -39
- data/lib/sisimai/lhost/x1.rb +18 -17
- data/lib/sisimai/lhost/x2.rb +17 -14
- data/lib/sisimai/lhost/x3.rb +19 -19
- data/lib/sisimai/lhost/x4.rb +72 -57
- data/lib/sisimai/lhost/x5.rb +17 -19
- data/lib/sisimai/lhost/x6.rb +41 -17
- data/lib/sisimai/lhost/yahoo.rb +17 -16
- data/lib/sisimai/lhost/yandex.rb +16 -21
- data/lib/sisimai/lhost/zoho.rb +16 -15
- data/lib/sisimai/lhost.rb +8 -10
- data/lib/sisimai/mail/maildir.rb +1 -3
- data/lib/sisimai/mail/mbox.rb +3 -4
- data/lib/sisimai/mail/memory.rb +0 -1
- data/lib/sisimai/mail/stdin.rb +1 -3
- data/lib/sisimai/mail.rb +3 -7
- data/lib/sisimai/mda.rb +28 -42
- data/lib/sisimai/message.rb +444 -326
- data/lib/sisimai/order.rb +5 -5
- data/lib/sisimai/reason/authfailure.rb +65 -0
- data/lib/sisimai/reason/badreputation.rb +53 -0
- data/lib/sisimai/reason/blocked.rb +96 -160
- data/lib/sisimai/reason/contenterror.rb +8 -9
- data/lib/sisimai/reason/delivered.rb +4 -6
- data/lib/sisimai/reason/exceedlimit.rb +10 -12
- data/lib/sisimai/reason/expired.rb +7 -8
- data/lib/sisimai/reason/feedback.rb +2 -3
- data/lib/sisimai/reason/filtered.rb +17 -19
- data/lib/sisimai/reason/hasmoved.rb +9 -10
- data/lib/sisimai/reason/hostunknown.rb +15 -15
- data/lib/sisimai/reason/mailboxfull.rb +11 -12
- data/lib/sisimai/reason/mailererror.rb +18 -20
- data/lib/sisimai/reason/mesgtoobig.rb +9 -11
- data/lib/sisimai/reason/networkerror.rb +5 -8
- data/lib/sisimai/reason/norelaying.rb +8 -11
- data/lib/sisimai/reason/notaccept.rb +13 -14
- data/lib/sisimai/reason/notcompliantrfc.rb +43 -0
- data/lib/sisimai/reason/onhold.rb +6 -9
- data/lib/sisimai/reason/policyviolation.rb +14 -12
- data/lib/sisimai/reason/rejected.rb +26 -24
- data/lib/sisimai/reason/requireptr.rb +69 -0
- data/lib/sisimai/reason/securityerror.rb +34 -36
- data/lib/sisimai/reason/spamdetected.rb +115 -147
- data/lib/sisimai/reason/speeding.rb +49 -0
- data/lib/sisimai/reason/suspend.rb +12 -11
- data/lib/sisimai/reason/syntaxerror.rb +11 -10
- data/lib/sisimai/reason/systemerror.rb +7 -9
- data/lib/sisimai/reason/systemfull.rb +7 -8
- data/lib/sisimai/reason/toomanyconn.rb +9 -11
- data/lib/sisimai/reason/undefined.rb +2 -3
- data/lib/sisimai/reason/userunknown.rb +129 -146
- data/lib/sisimai/reason/vacation.rb +3 -4
- data/lib/sisimai/reason/virusdetected.rb +10 -11
- data/lib/sisimai/reason.rb +59 -64
- data/lib/sisimai/rfc1894.rb +55 -28
- data/lib/sisimai/rfc2045.rb +373 -0
- data/lib/sisimai/rfc3464.rb +250 -308
- data/lib/sisimai/rfc3834.rb +42 -45
- data/lib/sisimai/rfc5322.rb +177 -146
- data/lib/sisimai/rfc5965.rb +31 -0
- data/lib/sisimai/rhost/cox.rb +5 -6
- data/lib/sisimai/rhost/franceptt.rb +6 -8
- data/lib/sisimai/rhost/godaddy.rb +12 -12
- data/lib/sisimai/rhost/google.rb +530 -0
- data/lib/sisimai/rhost/iua.rb +9 -10
- data/lib/sisimai/rhost/kddi.rb +6 -8
- data/lib/sisimai/rhost/{exchangeonline.rb → microsoft.rb} +115 -114
- data/lib/sisimai/rhost/mimecast.rb +51 -42
- data/lib/sisimai/rhost/nttdocomo.rb +12 -12
- data/lib/sisimai/rhost/spectrum.rb +10 -12
- data/lib/sisimai/rhost/{tencentqq.rb → tencent.rb} +7 -8
- data/lib/sisimai/rhost.rb +23 -31
- data/lib/sisimai/smtp/command.rb +59 -0
- data/lib/sisimai/smtp/error.rb +4 -7
- data/lib/sisimai/smtp/reply.rb +161 -74
- data/lib/sisimai/smtp/status.rb +507 -393
- data/lib/sisimai/smtp/transcript.rb +124 -0
- data/lib/sisimai/smtp.rb +0 -1
- data/lib/sisimai/string.rb +74 -5
- data/lib/sisimai/time.rb +1 -2
- data/lib/sisimai/version.rb +1 -1
- data/lib/sisimai.rb +46 -31
- data/set-of-emails/maildir/bsd/lhost-domino-02.eml +6 -3
- data/set-of-emails/maildir/bsd/lhost-googlegroups-15.eml +174 -0
- data/set-of-emails/maildir/bsd/lhost-gsuite-15.eml +229 -0
- data/set-of-emails/maildir/bsd/lhost-postfix-75.eml +51 -0
- data/set-of-emails/maildir/bsd/lhost-postfix-76.eml +101 -0
- data/set-of-emails/maildir/bsd/lhost-postfix-77.eml +74 -0
- data/set-of-emails/maildir/bsd/lhost-postfix-78.eml +91 -0
- data/set-of-emails/maildir/bsd/lhost-receivingses-08.eml +88 -0
- data/set-of-emails/maildir/bsd/lhost-sendmail-60.eml +85 -0
- data/set-of-emails/maildir/bsd/rfc3464-43.eml +88 -0
- data/set-of-emails/maildir/bsd/rhost-google-03.eml +101 -0
- data/set-of-emails/maildir/bsd/rhost-google-04.eml +102 -0
- data/set-of-emails/maildir/bsd/rhost-google-05.eml +82 -0
- data/set-of-emails/maildir/bsd/rhost-google-06.eml +102 -0
- data/set-of-emails/maildir/bsd/rhost-google-07.eml +69 -0
- data/set-of-emails/maildir/bsd/rhost-google-08.eml +99 -0
- data/sisimai-java.gemspec +1 -1
- data/sisimai.gemspec +1 -1
- metadata +48 -26
- data/.rspec +0 -2
- data/lib/sisimai/data/yaml.rb +0 -33
- data/lib/sisimai/data.rb +0 -411
- data/lib/sisimai/mime.rb +0 -456
- data/lib/sisimai/rhost/googleapps.rb +0 -261
- /data/set-of-emails/maildir/bsd/{rfc3464-41.eml → rfc3834-05.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{rhost-googleapps-01.eml → rhost-google-01.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{rhost-googleapps-02.eml → rhost-google-02.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{rhost-exchangeonline-01.eml → rhost-microsoft-01.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{rhost-exchangeonline-02.eml → rhost-microsoft-02.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{rhost-exchangeonline-03.eml → rhost-microsoft-03.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{rhost-tencentqq-01.eml → rhost-tencent-01.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{rhost-tencentqq-02.eml → rhost-tencent-02.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{rhost-tencentqq-03.eml → rhost-tencent-03.eml} +0 -0
|
@@ -1,18 +1,16 @@
|
|
|
1
1
|
module Sisimai::Lhost
|
|
2
|
-
# Sisimai::Lhost::MessageLabs parses a bounce email which created by
|
|
3
|
-
#
|
|
4
|
-
# from only Sisimai::Message.
|
|
2
|
+
# Sisimai::Lhost::MessageLabs parses a bounce email which created by Symantec.cloud: formerly MessageLabs.
|
|
3
|
+
# Methods in the module are called from only Sisimai::Message.
|
|
5
4
|
module MessageLabs
|
|
6
5
|
class << self
|
|
7
|
-
# Imported from p5-Sisimail/lib/Sisimai/Lhost/MessageLabs.pm
|
|
8
6
|
require 'sisimai/lhost'
|
|
9
7
|
|
|
10
8
|
Indicators = Sisimai::Lhost.INDICATORS
|
|
11
|
-
|
|
9
|
+
Boundaries = ['Content-Type: text/rfc822-headers'].freeze
|
|
12
10
|
StartingOf = { message: ['Content-Type: message/delivery-status'] }.freeze
|
|
13
|
-
|
|
14
|
-
'userunknown' =>
|
|
15
|
-
'securityerror' =>
|
|
11
|
+
MessagesOf = {
|
|
12
|
+
'userunknown' => ['542 ', ' Rejected', 'No such user'],
|
|
13
|
+
'securityerror' => ['Please turn on SMTP Authentication in your mail client'],
|
|
16
14
|
}.freeze
|
|
17
15
|
|
|
18
16
|
# Parse bounce messages from Symantec.cloud(MessageLabs)
|
|
@@ -20,7 +18,7 @@ module Sisimai::Lhost
|
|
|
20
18
|
# @param [String] mbody Message body of a bounce email
|
|
21
19
|
# @return [Hash] Bounce data list and message/rfc822 part
|
|
22
20
|
# @return [Nil] it failed to parse or the arguments are missing
|
|
23
|
-
def
|
|
21
|
+
def inquire(mhead, mbody)
|
|
24
22
|
# X-Msg-Ref: server-11.tower-143.messagelabs.com!1419367175!36473369!1
|
|
25
23
|
# X-Originating-IP: [10.245.230.38]
|
|
26
24
|
# X-StarScan-Received:
|
|
@@ -30,13 +28,12 @@ module Sisimai::Lhost
|
|
|
30
28
|
return nil unless mhead['from'].include?('MAILER-DAEMON@messagelabs.com')
|
|
31
29
|
return nil unless mhead['subject'].start_with?('Mail Delivery Failure')
|
|
32
30
|
|
|
33
|
-
require 'sisimai/rfc1894'
|
|
34
31
|
fieldtable = Sisimai::RFC1894.FIELDTABLE
|
|
35
32
|
permessage = {} # (Hash) Store values of each Per-Message field
|
|
36
33
|
|
|
37
34
|
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
|
|
38
|
-
|
|
39
|
-
bodyslices =
|
|
35
|
+
emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
|
|
36
|
+
bodyslices = emailparts[0].split("\n")
|
|
40
37
|
readslices = ['']
|
|
41
38
|
readcursor = 0 # (Integer) Points the current cursor position
|
|
42
39
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
|
@@ -44,8 +41,8 @@ module Sisimai::Lhost
|
|
|
44
41
|
v = nil
|
|
45
42
|
|
|
46
43
|
while e = bodyslices.shift do
|
|
47
|
-
# Read error messages and delivery status lines from the head of the email
|
|
48
|
-
#
|
|
44
|
+
# Read error messages and delivery status lines from the head of the email to the previous
|
|
45
|
+
# line of the beginning of the original message.
|
|
49
46
|
readslices << e # Save the current line for the next loop
|
|
50
47
|
|
|
51
48
|
if readcursor == 0
|
|
@@ -86,14 +83,14 @@ module Sisimai::Lhost
|
|
|
86
83
|
next unless fieldtable[o[0]]
|
|
87
84
|
v[fieldtable[o[0]]] = o[2]
|
|
88
85
|
|
|
89
|
-
next unless f
|
|
86
|
+
next unless f
|
|
90
87
|
permessage[fieldtable[o[0]]] = o[2]
|
|
91
88
|
end
|
|
92
89
|
else
|
|
93
90
|
# Continued line of the value of Diagnostic-Code field
|
|
94
91
|
next unless readslices[-2].start_with?('Diagnostic-Code:')
|
|
95
|
-
next unless
|
|
96
|
-
v['diagnosis'] << ' ' <<
|
|
92
|
+
next unless e.start_with?(' ')
|
|
93
|
+
v['diagnosis'] << ' ' << Sisimai::String.sweep(e)
|
|
97
94
|
readslices[-1] = 'Diagnostic-Code: ' << e
|
|
98
95
|
end
|
|
99
96
|
end
|
|
@@ -101,20 +98,19 @@ module Sisimai::Lhost
|
|
|
101
98
|
|
|
102
99
|
dscontents.each do |e|
|
|
103
100
|
# Set default values if each value is empty.
|
|
104
|
-
e['lhost'] ||= permessage['rhost']
|
|
105
101
|
permessage.each_key { |a| e[a] ||= permessage[a] || '' }
|
|
106
102
|
e['command'] = commandset.shift || ''
|
|
107
103
|
e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'])
|
|
108
104
|
|
|
109
|
-
|
|
105
|
+
MessagesOf.each_key do |r|
|
|
110
106
|
# Verify each regular expression of session errors
|
|
111
|
-
next unless e['diagnosis']
|
|
107
|
+
next unless MessagesOf[r].any? { |a| e['diagnosis'].include?(a) }
|
|
112
108
|
e['reason'] = r
|
|
113
109
|
break
|
|
114
110
|
end
|
|
115
111
|
end
|
|
116
112
|
|
|
117
|
-
return { 'ds' => dscontents, 'rfc822' =>
|
|
113
|
+
return { 'ds' => dscontents, 'rfc822' => emailparts[1] }
|
|
118
114
|
end
|
|
119
115
|
def description; return 'Symantec.cloud http://www.messagelabs.com'; end
|
|
120
116
|
end
|
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
module Sisimai::Lhost
|
|
2
|
-
# Sisimai::Lhost::MessagingServer parses a bounce email which created
|
|
3
|
-
#
|
|
4
|
-
# Server. Methods in the module are called from only Sisimai::Message.
|
|
2
|
+
# Sisimai::Lhost::MessagingServer parses a bounce email which created by Oracle Communications Messaging
|
|
3
|
+
# Server and Sun Java System Messaging Server. Methods in the module are called from only Sisimai::Message.
|
|
5
4
|
module MessagingServer
|
|
6
5
|
class << self
|
|
7
|
-
# Imported from p5-Sisimail/lib/Sisimai/Lhost/MessagingServer.pm
|
|
8
6
|
require 'sisimai/lhost'
|
|
9
7
|
|
|
10
8
|
Indicators = Sisimai::Lhost.INDICATORS
|
|
11
|
-
|
|
9
|
+
Boundaries = ['Content-Type: message/rfc822', 'Return-path: '].freeze
|
|
12
10
|
StartingOf = { message: ['This report relates to a message you sent with the following header fields:'] }.freeze
|
|
13
11
|
MessagesOf = { 'hostunknown' => ['Illegal host/domain name found'] }.freeze
|
|
14
12
|
|
|
@@ -17,23 +15,22 @@ module Sisimai::Lhost
|
|
|
17
15
|
# @param [String] mbody Message body of a bounce email
|
|
18
16
|
# @return [Hash] Bounce data list and message/rfc822 part
|
|
19
17
|
# @return [Nil] it failed to parse or the arguments are missing
|
|
20
|
-
def
|
|
21
|
-
# :received => %r/[ ][(]MessagingServer[)][ ]with[ ]/,
|
|
18
|
+
def inquire(mhead, mbody)
|
|
22
19
|
match = 0
|
|
23
20
|
match += 1 if mhead['content-type'].include?('Boundary_(ID_')
|
|
24
21
|
match += 1 if mhead['subject'].start_with?('Delivery Notification: ')
|
|
25
22
|
return nil unless match > 0
|
|
26
23
|
|
|
27
24
|
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
|
|
28
|
-
|
|
29
|
-
bodyslices =
|
|
25
|
+
emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
|
|
26
|
+
bodyslices = emailparts[0].split("\n")
|
|
30
27
|
readcursor = 0 # (Integer) Points the current cursor position
|
|
31
28
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
|
32
29
|
v = nil
|
|
33
30
|
|
|
34
31
|
while e = bodyslices.shift do
|
|
35
|
-
# Read error messages and delivery status lines from the head of the email
|
|
36
|
-
#
|
|
32
|
+
# Read error messages and delivery status lines from the head of the email to the previous
|
|
33
|
+
# line of the beginning of the original message.
|
|
37
34
|
if readcursor == 0
|
|
38
35
|
# Beginning of the bounce message or delivery status part
|
|
39
36
|
readcursor |= Indicators[:deliverystatus] if e.start_with?(StartingOf[:message][0])
|
|
@@ -62,45 +59,49 @@ module Sisimai::Lhost
|
|
|
62
59
|
# Remote system: dns;mx.example.jp (TCP|17.111.174.67|47323|192.0.2.225|25) (6jo.example.jp ESMTP SENDMAIL-VM)
|
|
63
60
|
v = dscontents[-1]
|
|
64
61
|
|
|
65
|
-
if
|
|
62
|
+
if e.start_with?(' Recipient address: ') && e.index('@') > 1
|
|
66
63
|
# Recipient address: kijitora@example.jp
|
|
67
64
|
if v['recipient']
|
|
68
65
|
# There are multiple recipient addresses in the message body.
|
|
69
66
|
dscontents << Sisimai::Lhost.DELIVERYSTATUS
|
|
70
67
|
v = dscontents[-1]
|
|
71
68
|
end
|
|
72
|
-
v['recipient'] = Sisimai::Address.s3s4(
|
|
69
|
+
v['recipient'] = Sisimai::Address.s3s4(e[e.rindex(' ') + 1, e.size])
|
|
73
70
|
recipients += 1
|
|
74
71
|
|
|
75
|
-
elsif
|
|
72
|
+
elsif e.start_with?(' Original address: ') && e.index('@') > 1
|
|
76
73
|
# Original address: kijitora@example.jp
|
|
77
|
-
v['recipient'] = Sisimai::Address.s3s4(
|
|
74
|
+
v['recipient'] = Sisimai::Address.s3s4(e[e.rindex(' ') + 1, e.size])
|
|
78
75
|
|
|
79
|
-
elsif
|
|
76
|
+
elsif e.start_with?(' Date: ')
|
|
80
77
|
# Date: Fri, 21 Nov 2014 23:34:45 +0900
|
|
81
|
-
v['date'] =
|
|
78
|
+
v['date'] = e[e.index(':') + 2, e.size]
|
|
82
79
|
|
|
83
|
-
elsif
|
|
80
|
+
elsif e.start_with?(' Reason: ')
|
|
84
81
|
# Reason: Remote SMTP server has rejected address
|
|
85
|
-
v['diagnosis'] =
|
|
82
|
+
v['diagnosis'] = e[e.index(':') + 2, e.size]
|
|
86
83
|
|
|
87
|
-
elsif
|
|
84
|
+
elsif e.start_with?(' Diagnostic code: ')
|
|
88
85
|
# Diagnostic code: smtp;550 5.1.1 <kijitora@example.jp>... User Unknown
|
|
89
|
-
|
|
90
|
-
|
|
86
|
+
p1 = e.index(':')
|
|
87
|
+
p2 = e.index(';')
|
|
88
|
+
v['spec'] = e[p1 + 2, p2 - p1 - 2].upcase
|
|
89
|
+
v['diagnosis'] = e[p2 + 1, e.size]
|
|
91
90
|
|
|
92
|
-
elsif
|
|
91
|
+
elsif e.start_with?(' Remote system: ')
|
|
93
92
|
# Remote system: dns;mx.example.jp (TCP|17.111.174.67|47323|192.0.2.225|25)
|
|
94
93
|
# (6jo.example.jp ESMTP SENDMAIL-VM)
|
|
95
|
-
|
|
96
|
-
|
|
94
|
+
p1 = e.index(';')
|
|
95
|
+
p2 = e.index('(')
|
|
96
|
+
remotehost = e[p1 + 1, p2 - p1 - 2]
|
|
97
|
+
sessionlog = e[p2, e.size].split('|')
|
|
97
98
|
v['rhost'] = remotehost
|
|
98
99
|
|
|
99
100
|
# The value does not include ".", use IP address instead.
|
|
100
101
|
# (TCP|17.111.174.67|47323|192.0.2.225|25)
|
|
101
|
-
next unless
|
|
102
|
-
v['lhost'] =
|
|
103
|
-
v['rhost'] =
|
|
102
|
+
next unless sessionlog[0] == '(TCP'
|
|
103
|
+
v['lhost'] = sessionlog[1]
|
|
104
|
+
v['rhost'] = sessionlog[3] unless remotehost.index('.') > 1
|
|
104
105
|
else
|
|
105
106
|
# Original-envelope-id: 0NFC009FLKOUVMA0@mr21p30im-asmtp004.me.com
|
|
106
107
|
# Reporting-MTA: dns;mr21p30im-asmtp004.me.com (tcp-daemon)
|
|
@@ -114,20 +115,22 @@ module Sisimai::Lhost
|
|
|
114
115
|
# (6jo.example.jp ESMTP SENDMAIL-VM)
|
|
115
116
|
# Diagnostic-code: smtp;550 5.1.1 <kijitora@example.jp>... User Unknown
|
|
116
117
|
#
|
|
117
|
-
if
|
|
118
|
+
if e.start_with?('Status: ')
|
|
118
119
|
# Status: 5.1.1 (Remote SMTP server has rejected address)
|
|
119
|
-
|
|
120
|
-
|
|
120
|
+
p1 = e.index(':')
|
|
121
|
+
p2 = e.index('(')
|
|
122
|
+
v['status'] = e[p1 + 2, p2 - p1 - 3]
|
|
123
|
+
v['diagnosis'] ||= e[p2 + 1, e[e.index(')') - p2 - 1]]
|
|
121
124
|
|
|
122
|
-
elsif
|
|
125
|
+
elsif e.start_with?('Arrival-Date: ')
|
|
123
126
|
# Arrival-date: Thu, 29 Apr 2014 23:34:45 +0000 (GMT)
|
|
124
|
-
v['date'] ||=
|
|
127
|
+
v['date'] ||= e[e.index(':') + 2, e.size]
|
|
125
128
|
|
|
126
|
-
elsif
|
|
129
|
+
elsif e.start_with?('Reporting-MTA: ')
|
|
127
130
|
# Reporting-MTA: dns;mr21p30im-asmtp004.me.com (tcp-daemon)
|
|
128
|
-
localhost =
|
|
131
|
+
localhost = e[e.index(';') + 1, e.size]
|
|
129
132
|
v['lhost'] ||= localhost
|
|
130
|
-
v['lhost'] = localhost unless v['lhost']
|
|
133
|
+
v['lhost'] = localhost unless v['lhost'].index('.') > 0
|
|
131
134
|
end
|
|
132
135
|
end
|
|
133
136
|
end
|
|
@@ -143,7 +146,7 @@ module Sisimai::Lhost
|
|
|
143
146
|
end
|
|
144
147
|
end
|
|
145
148
|
|
|
146
|
-
return { 'ds' => dscontents, 'rfc822' =>
|
|
149
|
+
return { 'ds' => dscontents, 'rfc822' => emailparts[1] }
|
|
147
150
|
end
|
|
148
151
|
def description; return 'Oracle Communications Messaging Server'; end
|
|
149
152
|
end
|
|
@@ -1,44 +1,43 @@
|
|
|
1
1
|
module Sisimai::Lhost
|
|
2
|
-
# Sisimai::Lhost::mFILTER parses a bounce email which created by
|
|
3
|
-
#
|
|
4
|
-
# Methods in the module are called from only Sisimai::Message.
|
|
2
|
+
# Sisimai::Lhost::mFILTER parses a bounce email which created by Digital Arts m-FILTER. Methods in
|
|
3
|
+
# the module are called from only Sisimai::Message.
|
|
5
4
|
module MFILTER
|
|
6
5
|
class << self
|
|
7
|
-
# Imported from p5-Sisimail/lib/Sisimai/Lhost/mFILTER.pm
|
|
8
6
|
require 'sisimai/lhost'
|
|
9
7
|
|
|
10
8
|
Indicators = Sisimai::Lhost.INDICATORS
|
|
11
|
-
|
|
9
|
+
Boundaries = ['-------original message', '-------original mail info'].freeze
|
|
12
10
|
StartingOf = {
|
|
13
11
|
error: ['-------server message'],
|
|
14
12
|
command: ['-------SMTP command'],
|
|
15
13
|
}.freeze
|
|
16
|
-
MarkingsOf = { message: %r/\A[^ ]+[@][^ ]+[.][a-zA-Z]+\z/ }.freeze
|
|
17
14
|
|
|
18
15
|
# Parse bounce messages from Digital Arts m-FILTER
|
|
19
16
|
# @param [Hash] mhead Message headers of a bounce email
|
|
20
17
|
# @param [String] mbody Message body of a bounce email
|
|
21
18
|
# @return [Hash] Bounce data list and message/rfc822 part
|
|
22
19
|
# @return [Nil] it failed to parse or the arguments are missing
|
|
23
|
-
def
|
|
20
|
+
def inquire(mhead, mbody)
|
|
24
21
|
# X-Mailer: m-FILTER
|
|
25
22
|
return nil unless mhead['x-mailer'].to_s == 'm-FILTER'
|
|
26
23
|
return nil unless mhead['subject'] == 'failure notice'
|
|
27
24
|
|
|
28
25
|
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
|
|
29
|
-
|
|
30
|
-
bodyslices =
|
|
26
|
+
emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
|
|
27
|
+
bodyslices = emailparts[0].split("\n")
|
|
31
28
|
readcursor = 0 # (Integer) Points the current cursor position
|
|
32
29
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
|
33
30
|
markingset = { 'diagnosis' => false, 'command' => false }
|
|
34
31
|
v = nil
|
|
35
32
|
|
|
36
33
|
while e = bodyslices.shift do
|
|
37
|
-
# Read error messages and delivery status lines from the head of the email
|
|
38
|
-
#
|
|
34
|
+
# Read error messages and delivery status lines from the head of the email to the previous
|
|
35
|
+
# line of the beginning of the original message.
|
|
39
36
|
if readcursor == 0
|
|
40
37
|
# Beginning of the bounce message or delivery status part
|
|
41
|
-
|
|
38
|
+
if e.include?('@') && e.include?(' ') == false && Sisimai::Address.is_emailaddress(e)
|
|
39
|
+
readcursor |= Indicators[:deliverystatus]
|
|
40
|
+
end
|
|
42
41
|
end
|
|
43
42
|
next if (readcursor & Indicators[:deliverystatus]) == 0
|
|
44
43
|
next if e.empty?
|
|
@@ -60,7 +59,7 @@ module Sisimai::Lhost
|
|
|
60
59
|
# -------original message
|
|
61
60
|
v = dscontents[-1]
|
|
62
61
|
|
|
63
|
-
if
|
|
62
|
+
if e.include?('@') && e.include?(' ') == false
|
|
64
63
|
# 以下のメールアドレスへの送信に失敗しました。
|
|
65
64
|
# kijitora@example.jp
|
|
66
65
|
if v['recipient']
|
|
@@ -68,10 +67,10 @@ module Sisimai::Lhost
|
|
|
68
67
|
dscontents << Sisimai::Lhost.DELIVERYSTATUS
|
|
69
68
|
v = dscontents[-1]
|
|
70
69
|
end
|
|
71
|
-
v['recipient'] =
|
|
70
|
+
v['recipient'] = e
|
|
72
71
|
recipients += 1
|
|
73
72
|
|
|
74
|
-
elsif e
|
|
73
|
+
elsif e.size == 4 && e.index(' ').nil?
|
|
75
74
|
# -------SMTP command
|
|
76
75
|
# DATA
|
|
77
76
|
next if v['command']
|
|
@@ -105,13 +104,13 @@ module Sisimai::Lhost
|
|
|
105
104
|
rhosts = Sisimai::RFC5322.received(rheads[-1])
|
|
106
105
|
|
|
107
106
|
e['lhost'] ||= Sisimai::RFC5322.received(rheads[0]).shift
|
|
108
|
-
|
|
107
|
+
[rhosts[0], rhosts[1]].each do |ee|
|
|
109
108
|
# Avoid "... by m-FILTER"
|
|
110
109
|
next unless ee.include?('.')
|
|
111
110
|
e['rhost'] = ee
|
|
112
111
|
end
|
|
113
112
|
end
|
|
114
|
-
return { 'ds' => dscontents, 'rfc822' =>
|
|
113
|
+
return { 'ds' => dscontents, 'rfc822' => emailparts[1] }
|
|
115
114
|
end
|
|
116
115
|
def description; return 'Digital Arts m-FILTER'; end
|
|
117
116
|
end
|
|
@@ -1,22 +1,20 @@
|
|
|
1
1
|
module Sisimai::Lhost
|
|
2
|
-
# Sisimai::Lhost::MXLogic parses a bounce email which created by
|
|
3
|
-
# McAfee SaaS (formerly MX Logic).
|
|
2
|
+
# Sisimai::Lhost::MXLogic parses a bounce email which created by McAfee SaaS (formerly MX Logic).
|
|
4
3
|
# Methods in the module are called from only Sisimai::Message.
|
|
5
4
|
module MXLogic
|
|
6
5
|
class << self
|
|
7
|
-
# Imported from p5-Sisimail/lib/Sisimai/Lhost/MXLogic.pm
|
|
8
6
|
# Based on Sisimai::Lhost::Exim
|
|
9
7
|
require 'sisimai/lhost'
|
|
10
8
|
|
|
11
9
|
Indicators = Sisimai::Lhost.INDICATORS
|
|
12
|
-
|
|
10
|
+
Boundaries = ['Included is a copy of the message header:'].freeze
|
|
13
11
|
StartingOf = { message: ['This message was created automatically by mail delivery software.'] }.freeze
|
|
14
12
|
ReCommands = [
|
|
15
13
|
%r/SMTP error from remote (?:mail server|mailer) after ([A-Za-z]{4})/,
|
|
16
14
|
%r/SMTP error from remote (?:mail server|mailer) after end of ([A-Za-z]{4})/,
|
|
17
15
|
].freeze
|
|
18
16
|
MessagesOf = {
|
|
19
|
-
# find exim/ -type f -exec grep 'message = US' {} /dev/null \;
|
|
17
|
+
# % find exim/ -type f -exec grep 'message = US' {} /dev/null \;
|
|
20
18
|
# route.c:1158| DEBUG(D_uid) debug_printf("getpwnam() returned NULL (user not found)\n");
|
|
21
19
|
'userunknown' => ['user not found'],
|
|
22
20
|
# transports/smtp.c:3524| addr->message = US"all host address lookups failed permanently";
|
|
@@ -74,7 +72,7 @@ module Sisimai::Lhost
|
|
|
74
72
|
# @param [String] mbody Message body of a bounce email
|
|
75
73
|
# @return [Hash] Bounce data list and message/rfc822 part
|
|
76
74
|
# @return [Nil] it failed to parse or the arguments are missing
|
|
77
|
-
def
|
|
75
|
+
def inquire(mhead, mbody)
|
|
78
76
|
# X-MX-Bounce: mta/src/queue/bounce
|
|
79
77
|
# X-MXL-NoteHash: ffffffffffffffff-0000000000000000000000000000000000000000
|
|
80
78
|
# X-MXL-Hash: 4c9d4d411993da17-bbd4212b6c887f6c23bab7db4bd87ef5edc00758
|
|
@@ -83,25 +81,19 @@ module Sisimai::Lhost
|
|
|
83
81
|
match += 1 if mhead['x-mxl-hash']
|
|
84
82
|
match += 1 if mhead['x-mxl-notehash']
|
|
85
83
|
match += 1 if mhead['from'].start_with?('Mail Delivery System')
|
|
86
|
-
match += 1 if mhead['subject']
|
|
87
|
-
Mail[ ]delivery[ ]failed(:[ ]returning[ ]message[ ]to[ ]sender)?
|
|
88
|
-
|Warning:[ ]message[ ][^ ]+[ ]delayed[ ]+
|
|
89
|
-
|Delivery[ ]Status[ ]Notification
|
|
90
|
-
)
|
|
91
|
-
}x
|
|
84
|
+
match += 1 if ['Delivery Status Notification', 'Mail delivery failed', 'Warning: message '].any? { |a| mhead['subject'].include?(a) }
|
|
92
85
|
return nil unless match > 0
|
|
93
86
|
|
|
94
87
|
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
|
|
95
|
-
|
|
96
|
-
bodyslices =
|
|
88
|
+
emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
|
|
89
|
+
bodyslices = emailparts[0].split("\n")
|
|
97
90
|
readcursor = 0 # (Integer) Points the current cursor position
|
|
98
91
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
|
99
|
-
localhost0 = '' # (String) Local MTA
|
|
100
92
|
v = nil
|
|
101
93
|
|
|
102
94
|
while e = bodyslices.shift do
|
|
103
|
-
# Read error messages and delivery status lines from the head of the email
|
|
104
|
-
#
|
|
95
|
+
# Read error messages and delivery status lines from the head of the email to the previous
|
|
96
|
+
# line of the beginning of the original message.
|
|
105
97
|
if readcursor == 0
|
|
106
98
|
# Beginning of the bounce message or delivery status part
|
|
107
99
|
readcursor |= Indicators[:deliverystatus] if e == StartingOf[:message][0]
|
|
@@ -120,7 +112,7 @@ module Sisimai::Lhost
|
|
|
120
112
|
# host neko.example.jp [192.0.2.222]: 550 5.1.1 <kijitora@example.jp>... User Unknown
|
|
121
113
|
v = dscontents[-1]
|
|
122
114
|
|
|
123
|
-
if
|
|
115
|
+
if e.start_with?(' <') && e.include?('@') && e.include?('>:')
|
|
124
116
|
# A message that you have sent could not be delivered to one or more
|
|
125
117
|
# recipients. This is a permanent error. The following address failed:
|
|
126
118
|
#
|
|
@@ -130,8 +122,8 @@ module Sisimai::Lhost
|
|
|
130
122
|
dscontents << Sisimai::Lhost.DELIVERYSTATUS
|
|
131
123
|
v = dscontents[-1]
|
|
132
124
|
end
|
|
133
|
-
v['recipient'] =
|
|
134
|
-
v['diagnosis'] =
|
|
125
|
+
v['recipient'] = e[3, e.index('>:') - 3]
|
|
126
|
+
v['diagnosis'] = e[e.index('>:') + 3, e.size]
|
|
135
127
|
recipients += 1
|
|
136
128
|
|
|
137
129
|
elsif dscontents.size == recipients
|
|
@@ -142,25 +134,24 @@ module Sisimai::Lhost
|
|
|
142
134
|
end
|
|
143
135
|
return nil unless recipients > 0
|
|
144
136
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
end
|
|
137
|
+
# Get the name of the local MTA
|
|
138
|
+
# Received: from marutamachi.example.org (c192128.example.net [192.0.2.128])
|
|
139
|
+
receivedby = mhead['received'] || []
|
|
140
|
+
recvdtoken = Sisimai::RFC5322.received(receivedby[-1])
|
|
150
141
|
|
|
151
142
|
dscontents.each do |e|
|
|
152
|
-
|
|
143
|
+
# Check the error message, the rhost, the lhost, and the smtp command.
|
|
144
|
+
e['lhost'] = recvdtoken[0]
|
|
153
145
|
e['diagnosis'] = Sisimai::String.sweep(e['diagnosis'].gsub(/[-]{2}.*\z/, ''))
|
|
154
146
|
|
|
155
147
|
unless e['rhost']
|
|
156
148
|
# Get the remote host name
|
|
157
|
-
|
|
158
|
-
|
|
149
|
+
p1 = e['diagnosis'].index('host ') || -1
|
|
150
|
+
p2 = e['diagnosis'].index(' ', p1 + 5)
|
|
159
151
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
end
|
|
152
|
+
# host neko.example.jp [192.0.2.222]: 550 5.1.1 <kijitora@example.jp>... User Unknown
|
|
153
|
+
e['rhost'] = e['diagnosis'][p1 + 5, p2 - p1 - 5] if p1 > -1
|
|
154
|
+
e['rhost'] ||= recvdtoken[1]
|
|
164
155
|
end
|
|
165
156
|
|
|
166
157
|
unless e['command']
|
|
@@ -198,7 +189,7 @@ module Sisimai::Lhost
|
|
|
198
189
|
end
|
|
199
190
|
end
|
|
200
191
|
|
|
201
|
-
return { 'ds' => dscontents, 'rfc822' =>
|
|
192
|
+
return { 'ds' => dscontents, 'rfc822' => emailparts[1] }
|
|
202
193
|
end
|
|
203
194
|
def description; return 'McAfee SaaS'; end
|
|
204
195
|
end
|
data/lib/sisimai/lhost/notes.rb
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
module Sisimai::Lhost
|
|
2
|
-
# Sisimai::Lhost::Notes parses a bounce email which created by Lotus
|
|
3
|
-
#
|
|
2
|
+
# Sisimai::Lhost::Notes parses a bounce email which created by Lotus Notes Server. Methods in the
|
|
3
|
+
# module are called from only Sisimai::Message.
|
|
4
4
|
module Notes
|
|
5
5
|
class << self
|
|
6
|
-
# Imported from p5-Sisimail/lib/Sisimai/Lhost/Notes.pm
|
|
7
6
|
require 'sisimai/lhost'
|
|
8
7
|
|
|
9
8
|
Indicators = Sisimai::Lhost.INDICATORS
|
|
10
|
-
|
|
9
|
+
Boundaries = ['------- Returned Message --------'].freeze
|
|
11
10
|
StartingOf = { message: ['------- Failure Reasons '] }.freeze
|
|
12
11
|
MessagesOf = {
|
|
13
12
|
'userunknown' => [
|
|
@@ -22,12 +21,12 @@ module Sisimai::Lhost
|
|
|
22
21
|
# @param [String] mbody Message body of a bounce email
|
|
23
22
|
# @return [Hash] Bounce data list and message/rfc822 part
|
|
24
23
|
# @return [Nil] it failed to parse or the arguments are missing
|
|
25
|
-
def
|
|
24
|
+
def inquire(mhead, mbody)
|
|
26
25
|
return nil unless mhead['subject'].start_with?('Undeliverable message')
|
|
27
26
|
|
|
28
27
|
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
|
|
29
|
-
|
|
30
|
-
bodyslices =
|
|
28
|
+
emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
|
|
29
|
+
bodyslices = emailparts[0].split("\n")
|
|
31
30
|
readcursor = 0 # (Integer) Points the current cursor position
|
|
32
31
|
recipients = 0 # (Integer) The number of 'Final-Recipient' header
|
|
33
32
|
characters = '' # (String) Character set name of the bounce mail
|
|
@@ -35,15 +34,14 @@ module Sisimai::Lhost
|
|
|
35
34
|
encodedmsg = ''
|
|
36
35
|
v = nil
|
|
37
36
|
|
|
38
|
-
if
|
|
39
|
-
# Get character set name
|
|
40
|
-
|
|
41
|
-
characters = cv[1].downcase
|
|
37
|
+
if mhead['content-type'].include?('charset=')
|
|
38
|
+
# Get character set name, Content-Type: text/plain; charset=ISO-2022-JP
|
|
39
|
+
characters = mhead['content-type'][mhead['content-type'].index('charset=') + 8, mhead['content-type'].size].downcase
|
|
42
40
|
end
|
|
43
41
|
|
|
44
42
|
while e = bodyslices.shift do
|
|
45
|
-
# Read error messages and delivery status lines from the head of the email
|
|
46
|
-
#
|
|
43
|
+
# Read error messages and delivery status lines from the head of the email to the previous
|
|
44
|
+
# line of the beginning of the original message.
|
|
47
45
|
if readcursor == 0
|
|
48
46
|
# Beginning of the bounce message or delivery status part
|
|
49
47
|
readcursor |= Indicators[:deliverystatus] if e.start_with?(StartingOf[:message][0])
|
|
@@ -58,7 +56,7 @@ module Sisimai::Lhost
|
|
|
58
56
|
#
|
|
59
57
|
# ------- Returned Message --------
|
|
60
58
|
v = dscontents[-1]
|
|
61
|
-
if e
|
|
59
|
+
if e.include?('@') && e.index(' ').nil?
|
|
62
60
|
# kijitora@notes.example.jp
|
|
63
61
|
if v['recipient']
|
|
64
62
|
# There are multiple recipient addresses in the message body.
|
|
@@ -97,8 +95,10 @@ module Sisimai::Lhost
|
|
|
97
95
|
|
|
98
96
|
unless recipients > 0
|
|
99
97
|
# Fallback: Get the recpient address from RFC822 part
|
|
100
|
-
|
|
101
|
-
|
|
98
|
+
p1 = emailparts[1].index("\nTo: ") || -1
|
|
99
|
+
p2 = emailparts[1].index("\n", p1 + 6) || -1
|
|
100
|
+
if p1 > 0
|
|
101
|
+
v['recipient'] = Sisimai::Address.s3s4(emailparts[1][p1 + 5, p2 - p1 - 5]) || ''
|
|
102
102
|
recipients += 1 unless v['recipient'].empty?
|
|
103
103
|
end
|
|
104
104
|
end
|
|
@@ -117,7 +117,7 @@ module Sisimai::Lhost
|
|
|
117
117
|
end
|
|
118
118
|
end
|
|
119
119
|
|
|
120
|
-
return { 'ds' => dscontents, 'rfc822' =>
|
|
120
|
+
return { 'ds' => dscontents, 'rfc822' => emailparts[1] }
|
|
121
121
|
end
|
|
122
122
|
def description; return 'Lotus Notes'; end
|
|
123
123
|
end
|