sisimai 5.1.0-java → 5.2.0-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 +4 -4
- data/.github/workflows/rake-test.yml +1 -1
- data/ChangeLog.md +102 -0
- data/Makefile +4 -2
- data/README-JA.md +23 -16
- data/README.md +22 -15
- data/lib/sisimai/arf.rb +121 -210
- data/lib/sisimai/fact.rb +208 -158
- data/lib/sisimai/lda.rb +98 -0
- data/lib/sisimai/lhost/activehunter.rb +1 -1
- data/lib/sisimai/lhost/amazonses.rb +185 -301
- data/lib/sisimai/lhost/apachejames.rb +48 -51
- data/lib/sisimai/lhost/biglobe.rb +1 -2
- data/lib/sisimai/lhost/courier.rb +10 -8
- data/lib/sisimai/lhost/domino.rb +25 -25
- data/lib/sisimai/lhost/dragonfly.rb +3 -4
- data/lib/sisimai/lhost/einsundeins.rb +3 -4
- data/lib/sisimai/lhost/exchange2003.rb +6 -8
- data/lib/sisimai/lhost/exchange2007.rb +111 -101
- data/lib/sisimai/lhost/exim.rb +232 -242
- data/lib/sisimai/lhost/ezweb.rb +43 -51
- data/lib/sisimai/lhost/fml.rb +2 -3
- data/lib/sisimai/lhost/gmail.rb +32 -28
- data/lib/sisimai/lhost/gmx.rb +4 -16
- data/lib/sisimai/lhost/googlegroups.rb +9 -8
- data/lib/sisimai/lhost/googleworkspace.rb +94 -0
- data/lib/sisimai/lhost/imailserver.rb +7 -16
- data/lib/sisimai/lhost/interscanmss.rb +1 -1
- data/lib/sisimai/lhost/kddi.rb +3 -4
- data/lib/sisimai/lhost/mailfoundry.rb +2 -5
- data/lib/sisimai/lhost/mailmarshalsmtp.rb +1 -2
- data/lib/sisimai/lhost/messagingserver.rb +14 -13
- data/lib/sisimai/lhost/mfilter.rb +4 -3
- data/lib/sisimai/lhost/notes.rb +2 -4
- data/lib/sisimai/lhost/opensmtpd.rb +2 -2
- data/lib/sisimai/lhost/postfix.rb +25 -27
- data/lib/sisimai/lhost/qmail.rb +130 -106
- data/lib/sisimai/lhost/sendmail.rb +19 -18
- data/lib/sisimai/lhost/v5sendmail.rb +88 -60
- data/lib/sisimai/lhost/verizon.rb +2 -2
- data/lib/sisimai/lhost/x1.rb +1 -1
- data/lib/sisimai/lhost/x2.rb +1 -2
- data/lib/sisimai/lhost/x3.rb +2 -2
- data/lib/sisimai/lhost/x6.rb +1 -1
- data/lib/sisimai/lhost/zoho.rb +2 -2
- data/lib/sisimai/lhost.rb +18 -21
- data/lib/sisimai/message.rb +93 -146
- data/lib/sisimai/order.rb +21 -77
- data/lib/sisimai/reason/authfailure.rb +1 -4
- data/lib/sisimai/reason/badreputation.rb +2 -2
- data/lib/sisimai/reason/blocked.rb +7 -10
- data/lib/sisimai/reason/contenterror.rb +7 -1
- data/lib/sisimai/reason/exceedlimit.rb +1 -4
- data/lib/sisimai/reason/failedstarttls.rb +42 -0
- data/lib/sisimai/reason/filtered.rb +5 -4
- data/lib/sisimai/reason/hasmoved.rb +1 -2
- data/lib/sisimai/reason/hostunknown.rb +3 -3
- data/lib/sisimai/reason/mailboxfull.rb +2 -4
- data/lib/sisimai/reason/mailererror.rb +1 -2
- data/lib/sisimai/reason/mesgtoobig.rb +2 -4
- data/lib/sisimai/reason/norelaying.rb +2 -3
- data/lib/sisimai/reason/notaccept.rb +2 -3
- data/lib/sisimai/reason/notcompliantrfc.rb +10 -4
- data/lib/sisimai/reason/rejected.rb +1 -1
- data/lib/sisimai/reason/requireptr.rb +2 -2
- data/lib/sisimai/reason/securityerror.rb +1 -3
- data/lib/sisimai/reason/spamdetected.rb +6 -8
- data/lib/sisimai/reason/speeding.rb +1 -2
- data/lib/sisimai/reason/suppressed.rb +36 -0
- data/lib/sisimai/reason/suspend.rb +1 -3
- data/lib/sisimai/reason/systemerror.rb +5 -0
- data/lib/sisimai/reason/toomanyconn.rb +1 -2
- data/lib/sisimai/reason/userunknown.rb +1 -1
- data/lib/sisimai/reason/virusdetected.rb +5 -6
- data/lib/sisimai/reason.rb +77 -73
- data/lib/sisimai/rfc1123.rb +152 -0
- data/lib/sisimai/rfc1894.rb +102 -62
- data/lib/sisimai/rfc2045.rb +2 -1
- data/lib/sisimai/rfc3464/thirdparty.rb +102 -0
- data/lib/sisimai/rfc3464.rb +222 -343
- data/lib/sisimai/rfc3834.rb +1 -1
- data/lib/sisimai/rfc5322.rb +7 -17
- data/lib/sisimai/rfc791.rb +69 -0
- data/lib/sisimai/rhost/aol.rb +36 -0
- data/lib/sisimai/rhost/apple.rb +5 -2
- data/lib/sisimai/rhost/cox.rb +3 -2
- data/lib/sisimai/rhost/facebook.rb +100 -0
- data/lib/sisimai/rhost/franceptt.rb +3 -2
- data/lib/sisimai/rhost/godaddy.rb +3 -2
- data/lib/sisimai/rhost/google.rb +19 -17
- data/lib/sisimai/rhost/gsuite.rb +42 -0
- data/lib/sisimai/rhost/iua.rb +3 -3
- data/lib/sisimai/rhost/kddi.rb +3 -2
- data/lib/sisimai/rhost/messagelabs.rb +37 -0
- data/lib/sisimai/rhost/microsoft.rb +56 -49
- data/lib/sisimai/rhost/mimecast.rb +29 -27
- data/lib/sisimai/rhost/nttdocomo.rb +4 -3
- data/lib/sisimai/rhost/outlook.rb +36 -0
- data/lib/sisimai/rhost/spectrum.rb +3 -2
- data/lib/sisimai/rhost/tencent.rb +3 -2
- data/lib/sisimai/rhost/yahooinc.rb +4 -3
- data/lib/sisimai/rhost.rb +69 -39
- data/lib/sisimai/smtp/command.rb +31 -21
- data/lib/sisimai/smtp/failure.rb +103 -0
- data/lib/sisimai/smtp/reply.rb +29 -25
- data/lib/sisimai/smtp/status.rb +36 -19
- data/lib/sisimai/smtp/transcript.rb +15 -15
- data/lib/sisimai/string.rb +0 -46
- data/lib/sisimai/version.rb +1 -1
- data/set-of-emails/maildir/bsd/lhost-postfix-30.eml +81 -81
- data/set-of-emails/maildir/bsd/{lhost-aol-03.eml → rhost-aol-03.eml} +1264 -1264
- data/set-of-emails/maildir/bsd/{lhost-aol-04.eml → rhost-aol-04.eml} +1260 -1260
- data/set-of-emails/maildir/bsd/{lhost-aol-05.eml → rhost-aol-05.eml} +105 -105
- data/set-of-emails/maildir/bsd/{lhost-aol-06.eml → rhost-aol-06.eml} +105 -105
- data/set-of-emails/maildir/bsd/rhost-gsuite-01.eml +189 -0
- data/set-of-emails/maildir/bsd/rhost-gsuite-02.eml +180 -0
- data/set-of-emails/maildir/bsd/rhost-gsuite-03.eml +251 -0
- data/set-of-emails/maildir/bsd/rhost-gsuite-04.eml +211 -0
- data/set-of-emails/maildir/bsd/rhost-gsuite-05.eml +226 -0
- data/set-of-emails/maildir/bsd/rhost-gsuite-06.eml +257 -0
- data/set-of-emails/maildir/bsd/rhost-gsuite-07.eml +289 -0
- data/set-of-emails/maildir/bsd/rhost-gsuite-08.eml +231 -0
- data/set-of-emails/maildir/bsd/rhost-gsuite-09.eml +231 -0
- data/set-of-emails/maildir/bsd/rhost-gsuite-10.eml +254 -0
- data/set-of-emails/maildir/bsd/rhost-gsuite-11.eml +228 -0
- data/set-of-emails/maildir/bsd/rhost-gsuite-12.eml +271 -0
- data/set-of-emails/maildir/bsd/rhost-gsuite-13.eml +261 -0
- data/set-of-emails/maildir/bsd/rhost-gsuite-14.eml +273 -0
- data/set-of-emails/maildir/bsd/rhost-gsuite-15.eml +229 -0
- data/set-of-emails/maildir/bsd/{lhost-messagelabs-01.eml → rhost-messagelabs-01.eml} +93 -93
- data/set-of-emails/maildir/bsd/rhost-outlook-01.eml +72 -0
- data/set-of-emails/maildir/bsd/rhost-outlook-02.eml +72 -0
- data/set-of-emails/maildir/bsd/rhost-outlook-03.eml +72 -0
- data/set-of-emails/maildir/bsd/rhost-outlook-04.eml +79 -0
- data/set-of-emails/maildir/bsd/rhost-outlook-06.eml +75 -0
- data/set-of-emails/maildir/bsd/rhost-outlook-07.eml +70 -0
- data/set-of-emails/maildir/bsd/rhost-outlook-08.eml +70 -0
- data/set-of-emails/maildir/bsd/rhost-outlook-09.eml +56 -0
- data/set-of-emails/maildir/tmp/arf-22.eml +49 -0
- data/set-of-emails/maildir/tmp/arf-23.eml +49 -0
- data/set-of-emails/maildir/tmp/arf-24.eml +50 -0
- data/set-of-emails/maildir/tmp/lhost-exim-07.eml +28 -0
- metadata +73 -56
- data/lib/sisimai/lhost/amavis.rb +0 -163
- data/lib/sisimai/lhost/amazonworkmail.rb +0 -127
- data/lib/sisimai/lhost/aol.rb +0 -125
- data/lib/sisimai/lhost/barracuda.rb +0 -92
- data/lib/sisimai/lhost/bigfoot.rb +0 -125
- data/lib/sisimai/lhost/facebook.rb +0 -188
- data/lib/sisimai/lhost/gsuite.rb +0 -194
- data/lib/sisimai/lhost/mailru.rb +0 -214
- data/lib/sisimai/lhost/mcafee.rb +0 -109
- data/lib/sisimai/lhost/messagelabs.rb +0 -120
- data/lib/sisimai/lhost/mxlogic.rb +0 -198
- data/lib/sisimai/lhost/office365.rb +0 -252
- data/lib/sisimai/lhost/outlook.rb +0 -129
- data/lib/sisimai/lhost/powermta.rb +0 -118
- data/lib/sisimai/lhost/receivingses.rb +0 -126
- data/lib/sisimai/lhost/sendgrid.rb +0 -150
- data/lib/sisimai/lhost/surfcontrol.rb +0 -105
- data/lib/sisimai/lhost/x4.rb +0 -269
- data/lib/sisimai/lhost/x5.rb +0 -112
- data/lib/sisimai/lhost/yahoo.rb +0 -102
- data/lib/sisimai/lhost/yandex.rb +0 -118
- data/lib/sisimai/mda.rb +0 -121
- data/lib/sisimai/smtp/error.rb +0 -119
- /data/set-of-emails/maildir/bsd/{lhost-googlegroups-15.eml → lhost-googleworkspace-01.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-x4-08.eml → lhost-x2-06.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-gsuite-01.eml → rfc3464-51.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-gsuite-03.eml → rfc3464-52.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-gsuite-04.eml → rfc3464-53.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-gsuite-05.eml → rfc3464-54.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-gsuite-06.eml → rfc3464-55.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-gsuite-07.eml → rfc3464-56.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-gsuite-08.eml → rfc3464-57.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-gsuite-09.eml → rfc3464-58.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-gsuite-10.eml → rfc3464-59.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-gsuite-11.eml → rfc3464-60.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-gsuite-12.eml → rfc3464-61.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-gsuite-13.eml → rfc3464-62.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-gsuite-14.eml → rfc3464-63.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-gsuite-15.eml → rfc3464-64.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-gsuite-02.eml → rfc3464-65.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-aol-01.eml → rhost-aol-01.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-aol-02.eml → rhost-aol-02.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-facebook-03.eml → rhost-facebook-03.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-facebook-04.eml → rhost-facebook-04.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-messagelabs-02.eml → rhost-messagelabs-02.eml} +0 -0
- /data/set-of-emails/maildir/bsd/{lhost-messagelabs-03.eml → rhost-messagelabs-03.eml} +0 -0
- /data/set-of-emails/maildir/{bsd → tmp}/rfc3464-37.eml +0 -0
- /data/set-of-emails/maildir/{bsd → tmp}/rfc3464-38.eml +0 -0
- /data/set-of-emails/maildir/{bsd → tmp}/rfc3464-39.eml +0 -0
data/lib/sisimai/arf.rb
CHANGED
@@ -13,21 +13,21 @@ module Sisimai
|
|
13
13
|
# OpenDMARC 1.3.0 uses: This is an authentication failure report for an email message received from IP
|
14
14
|
# Abusix ARF uses this is an autogenerated email abuse complaint regarding your network.
|
15
15
|
Indicators = Sisimai::Lhost.INDICATORS
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
],
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
16
|
+
AbuseAddrs = ['staff@hotmail.com', 'complaints@email-abuse.amazonses.com'].freeze
|
17
|
+
ReportFrom = "Content-Type: message/feedback-report".freeze
|
18
|
+
Boundaries = [
|
19
|
+
"Content-Type: message/rfc822",
|
20
|
+
"Content-Type: text/rfc822-headers",
|
21
|
+
"Content-Type: text/rfc822-header", # ??
|
22
|
+
].freeze
|
23
|
+
ARFPreface = [
|
24
|
+
["this is a", "abuse report"],
|
25
|
+
["this is a", "authentication", "failure report"],
|
26
|
+
["this is a", " report for"],
|
27
|
+
["this is an authentication", "failure report"],
|
28
|
+
["this is an autogenerated email abuse complaint"],
|
29
|
+
["this is an email abuse report"],
|
30
|
+
].freeze
|
31
31
|
|
32
32
|
def description; return 'Abuse Feedback Reporting Format'; end
|
33
33
|
|
@@ -39,23 +39,27 @@ module Sisimai
|
|
39
39
|
return false unless heads
|
40
40
|
|
41
41
|
# Content-Type: multipart/report; report-type=feedback-report; ...
|
42
|
-
return true if Sisimai::String.aligned(heads[
|
42
|
+
return true if Sisimai::String.aligned(heads["content-type"], ["report-type=", "feedback-report"])
|
43
43
|
|
44
|
-
|
45
|
-
if heads['content-type'].include?('multipart/mixed')
|
44
|
+
if heads["content-type"].include?("multipart/mixed")
|
46
45
|
# Microsoft (Hotmail, MSN, Live, Outlook) uses its own report format.
|
47
46
|
# Amazon SES Complaints bounces
|
48
47
|
cv = Sisimai::Address.s3s4(heads['from'])
|
49
|
-
if heads[
|
48
|
+
if heads["subject"].include?("complaint about message from ")
|
50
49
|
# From: staff@hotmail.com
|
51
50
|
# From: complaints@email-abuse.amazonses.com
|
52
51
|
# Subject: complaint about message from 192.0.2.1
|
53
|
-
|
52
|
+
return true if AbuseAddrs.any? { |a| cv.include?(a) }
|
54
53
|
end
|
55
54
|
end
|
56
|
-
match = true if heads['x-apple-unsubscribe'] == 'true'
|
57
55
|
|
58
|
-
|
56
|
+
while true
|
57
|
+
# X-Apple-Unsubscribe: true
|
58
|
+
break unless heads.has_key?("x-apple-unsubscribe")
|
59
|
+
return true if heads["x-apple-unsubscribe"] == "true"
|
60
|
+
break
|
61
|
+
end
|
62
|
+
return false
|
59
63
|
end
|
60
64
|
|
61
65
|
# @abstract Detect an error for Feedback Loop
|
@@ -67,25 +71,16 @@ module Sisimai
|
|
67
71
|
return nil unless self.is_arf(mhead)
|
68
72
|
|
69
73
|
dscontents = [Sisimai::Lhost.DELIVERYSTATUS]
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
readcursor = 0 #
|
74
|
-
recipients = 0 #
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
}
|
81
|
-
arfheaders = {
|
82
|
-
'feedbacktype' => nil, # FeedBack-Type:
|
83
|
-
'rhost' => nil, # Source-IP:
|
84
|
-
'agent' => nil, # User-Agent:
|
85
|
-
'date' => nil, # Arrival-Date:
|
86
|
-
'authres' => nil, # Authentication-Results:
|
87
|
-
}
|
88
|
-
v = nil
|
74
|
+
emailparts = Sisimai::RFC5322.part(mbody, Boundaries)
|
75
|
+
bodyslices = emailparts[0].split("\n")
|
76
|
+
reportpart = false
|
77
|
+
readcursor = 0 # Points the current cursor position
|
78
|
+
recipients = 0 # The number of 'Final-Recipient' header
|
79
|
+
timestamp0 = "" # The value of "Arrival-Date" or "Received-Date"
|
80
|
+
remotehost = "" # The value of "Source-IP" field
|
81
|
+
reportedby = "" # The value of "Reporting-MTA" field
|
82
|
+
anotherone = "" # Other fields(append to Diagnosis)
|
83
|
+
v = dscontents[-1]
|
89
84
|
|
90
85
|
# 3.1. Required Fields
|
91
86
|
#
|
@@ -112,71 +107,24 @@ module Sisimai
|
|
112
107
|
# message-id of 0000-000000000000000000000000000000000@mx
|
113
108
|
# received from IP address 192.0.2.1 on
|
114
109
|
# Thu, 29 Apr 2010 00:00:00 +0900 (JST)
|
115
|
-
p = e.downcase
|
116
|
-
if commondata['diagnosis'].empty?
|
117
|
-
commondata['diagnosis'] = e if StartingOf[:message].any? { |a| Sisimai::String.aligned(p, a) }
|
118
|
-
end
|
119
|
-
|
120
110
|
if readcursor == 0
|
121
111
|
# Beginning of the bounce message or message/delivery-status part
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
112
|
+
r = e.downcase
|
113
|
+
ARFPreface.each do |f|
|
114
|
+
# Hello,
|
115
|
+
# this is an autogenerated email abuse complaint regarding your network.
|
116
|
+
next unless Sisimai::String.aligned(r, f)
|
117
|
+
readcursor |= Indicators[:deliverystatus]
|
118
|
+
v["diagnosis"] << " " + e
|
119
|
+
break
|
130
120
|
end
|
121
|
+
next
|
131
122
|
end
|
123
|
+
next unless readcursor & Indicators[:deliverystatus] > 0
|
124
|
+
next if e.empty?
|
125
|
+
if e == ReportFrom then reportpart = true; next; end
|
132
126
|
|
133
|
-
if
|
134
|
-
# message/rfc822 OR text/rfc822-headers part
|
135
|
-
if e.start_with?('X-HmXmrOriginalRecipient:')
|
136
|
-
# Microsoft ARF: original recipient.
|
137
|
-
dscontents[-1]['recipient'] = Sisimai::Address.s3s4(e[e.index(':') + 1, e.size])
|
138
|
-
recipients += 1
|
139
|
-
|
140
|
-
# The "X-HmXmrOriginalRecipient" header appears only once so we take this opportunity
|
141
|
-
# to hard-code ARF headers missing in Microsoft's implementation.
|
142
|
-
arfheaders['feedbacktype'] = 'abuse'
|
143
|
-
arfheaders['agent'] = 'Microsoft Junk Mail Reporting Program'
|
144
|
-
|
145
|
-
elsif e.start_with?('From: ')
|
146
|
-
# Microsoft ARF: original sender.
|
147
|
-
commondata['from'] = Sisimai::Address.s3s4(e[6, e.size]) if commondata['from'].empty?
|
148
|
-
previousfn = 'from'
|
149
|
-
|
150
|
-
elsif e.start_with?(' ')
|
151
|
-
# Continued line from the previous line
|
152
|
-
if previousfn == 'from'
|
153
|
-
# Multiple lines at "From:" field
|
154
|
-
commondata['from'] << e
|
155
|
-
next
|
156
|
-
else
|
157
|
-
rfc822part << e + "\n" if LongFields[previousfn]
|
158
|
-
next unless e.empty?
|
159
|
-
end
|
160
|
-
rcptintext << e if previousfn == 'to'
|
161
|
-
|
162
|
-
else
|
163
|
-
# Get required headers only
|
164
|
-
(lhs, rhs) = e.split(/:[ ]/, 2)
|
165
|
-
next unless lhs
|
166
|
-
lhs.downcase!
|
167
|
-
|
168
|
-
previousfn = ''
|
169
|
-
next unless RFC822Head[lhs]
|
170
|
-
|
171
|
-
previousfn = lhs
|
172
|
-
rfc822part << e + "\n"
|
173
|
-
rcptintext = rhs if lhs == 'to'
|
174
|
-
end
|
175
|
-
else
|
176
|
-
# message/feedback-report part
|
177
|
-
next unless readcursor & Indicators[:deliverystatus] > 0
|
178
|
-
next if e.empty?
|
179
|
-
|
127
|
+
if reportpart
|
180
128
|
# Feedback-Type: abuse
|
181
129
|
# User-Agent: SomeGenerator/1.0
|
182
130
|
# Version: 0.1
|
@@ -184,151 +132,114 @@ module Sisimai
|
|
184
132
|
# Original-Rcpt-To: <kijitora@example.jp>
|
185
133
|
# Received-Date: Thu, 29 Apr 2009 00:00:00 JST
|
186
134
|
# Source-IP: 192.0.2.1
|
187
|
-
|
188
|
-
|
189
|
-
if e.start_with?('Original-Rcpt-To: ', 'Redacted-Address: ')
|
135
|
+
if e.start_with?("Original-Rcpt-To: ") || e.start_with?("Removal-Recipient: ")
|
190
136
|
# Original-Rcpt-To header field is optional and may appear any number of times as appropriate:
|
191
|
-
# Original-Rcpt-To: <
|
192
|
-
#
|
193
|
-
|
137
|
+
# Original-Rcpt-To: <kijitora@example.jp>
|
138
|
+
# Removal-Recipient: user@example.com
|
139
|
+
cv = Sisimai::Address.s3s4(e[e.index(" ") + 1, e.size]); next unless Sisimai::Address.is_emailaddress(cv)
|
140
|
+
cw = dscontents.size; next if cw > 0 && cv == dscontents[cw - 1]["recipient"]
|
141
|
+
|
142
|
+
if v["recipient"] != ""
|
194
143
|
# There are multiple recipient addresses in the message body.
|
195
144
|
dscontents << Sisimai::Lhost.DELIVERYSTATUS
|
196
145
|
v = dscontents[-1]
|
197
146
|
end
|
198
|
-
v[
|
147
|
+
v["recipient"] = cv
|
199
148
|
recipients += 1
|
200
149
|
|
201
|
-
elsif e.start_with?(
|
150
|
+
elsif e.start_with?("Feedback-Type: ")
|
202
151
|
# The header field MUST appear exactly once.
|
203
152
|
# Feedback-Type: abuse
|
204
|
-
|
153
|
+
v["feedbacktype"] = e[e.index(" ") + 1, e.size]
|
205
154
|
|
206
|
-
elsif e.start_with?(
|
155
|
+
elsif e.start_with?("Authentication-Results: ")
|
207
156
|
# "Authentication-Results" indicates the result of one or more authentication checks
|
208
157
|
# run by the report generator.
|
209
|
-
#
|
210
|
-
|
158
|
+
#
|
159
|
+
# Authentication-Results: mail.example.com;
|
160
|
+
# spf=fail smtp.mail=somespammer@example.com
|
161
|
+
anotherone << e + ", "
|
211
162
|
|
212
|
-
elsif e.start_with?(
|
163
|
+
elsif e.start_with?("User-Agent: ")
|
213
164
|
# The header field MUST appear exactly once.
|
214
165
|
# User-Agent: SomeGenerator/1.0
|
215
|
-
|
166
|
+
anotherone << e + ", "
|
216
167
|
|
217
|
-
elsif e.start_with?(
|
168
|
+
elsif e.start_with?("Received-Date: ") || e.start_with?("Arrival-Date: ")
|
218
169
|
# Arrival-Date header is optional and MUST NOT appear more than once.
|
219
170
|
# Received-Date: Thu, 29 Apr 2010 00:00:00 JST
|
220
171
|
# Arrival-Date: Thu, 29 Apr 2010 00:00:00 +0000
|
221
|
-
|
172
|
+
timestamp0 = e[e.index(" ") + 1, e.size]
|
222
173
|
|
223
|
-
elsif e.start_with?(
|
174
|
+
elsif e.start_with?("Reporting-MTA: ")
|
224
175
|
# The header is optional and MUST NOT appear more than once.
|
225
176
|
# Reporting-MTA: dns; mx.example.jp
|
226
|
-
|
177
|
+
cv = Sisimai::RFC1894.field(e); next if cv.size == 0
|
178
|
+
reportedby = cv[2]
|
227
179
|
|
228
|
-
elsif e.start_with?(
|
180
|
+
elsif e.start_with?("Source-IP: ")
|
229
181
|
# The header is optional and MUST NOT appear more than once.
|
230
182
|
# Source-IP: 192.0.2.45
|
231
|
-
|
183
|
+
remotehost = e[e.index(" ") + 1, e.size]
|
232
184
|
|
233
|
-
elsif e.start_with?(
|
185
|
+
elsif e.start_with?("Original-Mail-From: ")
|
234
186
|
# the header is optional and MUST NOT appear more than once.
|
235
187
|
# Original-Mail-From: <somespammer@example.net>
|
236
|
-
|
237
|
-
|
188
|
+
anotherone << e + ", "
|
238
189
|
end
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
if arfheaders['feedbacktype'] == 'auth-failure' && arfheaders['authres']
|
243
|
-
# Append the value of Authentication-Results header
|
244
|
-
commondata['diagnosis'] << ' ' << arfheaders['authres']
|
245
|
-
end
|
246
|
-
|
247
|
-
if recipients == 0
|
248
|
-
# The original recipient address was not found
|
249
|
-
if Sisimai::String.aligned(rfc822part, ["\nTo: ", '@'])
|
250
|
-
# pick the address from To: header in message/rfc822 part.
|
251
|
-
p1 = rfc822part.index("\nTo: ") + 5
|
252
|
-
p2 = rfc822part.index("\n", p1 + 1)
|
253
|
-
cm = p2 > 0 ? p2 - p1 : 255
|
254
|
-
dscontents[-1]['recipient'] = Sisimai::Address.s3s4(rfc822part[p1, cm])
|
255
|
-
recipients = 1
|
190
|
+
else
|
191
|
+
# Messages before "Content-Type: message/feedback-report" part
|
192
|
+
v["diagnosis"] << " " + e
|
256
193
|
end
|
257
194
|
|
258
|
-
while
|
259
|
-
#
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
dscontents[-1]['recipient'] = Sisimai::Address.undisclosed(true)
|
268
|
-
recipients = 1
|
269
|
-
break
|
270
|
-
end
|
271
|
-
end
|
272
|
-
|
273
|
-
unless Sisimai::String.aligned(rfc822part, ['From: ', '@'])
|
274
|
-
# There is no "From:" header in the original message. Append the value of "Original-Mail-From"
|
275
|
-
# value as a sender address.
|
276
|
-
rfc822part << 'From: ' << commondata['from'] + "\n" unless commondata['from'].empty?
|
277
|
-
end
|
195
|
+
while recipients == 0
|
196
|
+
# There is no recipient address in the message
|
197
|
+
if mhead.has_key?("x-apple-unsubscribe")
|
198
|
+
# X-Apple-Unsubscribe: true
|
199
|
+
last unless mhead["x-apple-unsubscribe"] == "true"
|
200
|
+
last unless mhead["from"].include?('@')
|
201
|
+
dscontents[0]["recipient"] = mhead["from"]
|
202
|
+
dscontents[0]["diagnosis"] = Sisimai::String.sweep(emailparts[0])
|
203
|
+
dscontents[0]["feedbacktype"] = "opt-out"
|
278
204
|
|
279
|
-
|
280
|
-
|
281
|
-
arfheaders['rhost'] = mhead['subject'][mhead['subject'].rindex(' ') + 1, mhead['subject'].size]
|
282
|
-
commondata['diagnosis'] =
|
283
|
-
'This is a Microsoft email abuse report for an email message received from IP' << arfheaders['rhost'] + ' on ' << mhead['date']
|
205
|
+
# Addpend To: field as a pseudo header
|
206
|
+
emailparts[1] = sprintf("To: <%s>\n", mhead["from"]) if emailparts[1].empty?
|
284
207
|
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
dscontents[-1]['recipient'] = Sisimai::Address.s3s4(mhead['from'])
|
299
|
-
dscontents[-1]['feedbacktype'] = 'opt-out'
|
300
|
-
break
|
208
|
+
else
|
209
|
+
# Pick it from the original message part
|
210
|
+
p1 = emailparts[1].index("\nTo:"); break if p1.nil?
|
211
|
+
p2 = emailparts[1].index("\n", p1 + 4); break if p2.nil?
|
212
|
+
cv = Sisimai::Address.s3s4(emailparts[1][p1 + 4, p2 - p1])
|
213
|
+
|
214
|
+
# There is no valid email address in the To: header of the original message such as
|
215
|
+
# To: <Undisclosed Recipients>
|
216
|
+
cv = Sisimai::Address.undisclosed("r") unless Sisimai::Address.is_emailaddress(cv)
|
217
|
+
dscontents[0]["recipient"] = cv
|
218
|
+
end
|
219
|
+
recipients += 1
|
301
220
|
end
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
e
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
e['rhost'] = commondata['rhost']
|
322
|
-
|
323
|
-
else
|
324
|
-
# Try to get an IP address from the error message
|
325
|
-
# This is an email abuse report for an email message received from IP address 24.64.1.1
|
326
|
-
# on Thu, 29 Apr 2010 00:00:00 +0000
|
327
|
-
ip = Sisimai::String.ipv4(e['diagnosis']) || []
|
328
|
-
e['rhost'] = ip[0] if ip.size > 0
|
221
|
+
return nil if recipients == 0
|
222
|
+
|
223
|
+
anotherone = ": " + Sisimai::String.sweep(anotherone) if anotherone != ""
|
224
|
+
anotherone = anotherone.chop if anotherone[-1, 1] == ","
|
225
|
+
|
226
|
+
j = -1
|
227
|
+
dscontents.each do |e|
|
228
|
+
# Tidy up the error message in e.Diagnosis, Try to detect the bounce reason.
|
229
|
+
j += 1
|
230
|
+
e["diagnosis"] = Sisimai::String.sweep(e["diagnosis"] + anotherone)
|
231
|
+
e["reason"] = "feedback"
|
232
|
+
e["rhost"] = remotehost
|
233
|
+
e["lhost"] = reportedby
|
234
|
+
e["date"] = timestamp0
|
235
|
+
|
236
|
+
# Copy some values from the previous element when the report have 2 or more email address
|
237
|
+
next if j == 0 || dscontents.size == 1
|
238
|
+
e["diagnosis"] = dscontents[j - 1]["diagnosis"]
|
239
|
+
e["feedbacktype"] = dscontents[j - 1]["feedbacktype"]
|
329
240
|
end
|
330
241
|
end
|
331
|
-
return {
|
242
|
+
return { "ds" => dscontents, "rfc822" => emailparts[1] }
|
332
243
|
end
|
333
244
|
end
|
334
245
|
end
|