Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
P
pymilter-suspicious-from
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Deploy
Releases
Container registry
Model registry
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
misc
pymilter-suspicious-from
Commits
d0274f80
Commit
d0274f80
authored
5 years ago
by
Jan Philipp Timme
Browse files
Options
Downloads
Patches
Plain Diff
Lots of restructuring and basic implementing
parent
b554efad
Branches
Branches containing commit
No related tags found
No related merge requests found
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
main.py
+38
-16
38 additions, 16 deletions
main.py
with
38 additions
and
16 deletions
main.py
+
38
−
16
View file @
d0274f80
...
...
@@ -3,7 +3,6 @@ import sys
import
logging
import
Milter
from
Milter.utils
import
parse_addr
import
re
...
...
@@ -14,61 +13,84 @@ logger.setLevel(logging.DEBUG)
handler
=
logging
.
StreamHandler
(
sys
.
stdout
)
handler
.
setLevel
(
logging
.
DEBUG
)
formatter
=
logging
.
Formatter
(
'
%(asctime)s -
%(name)s -
%(levelname)s - %(message)s
'
)
formatter
=
logging
.
Formatter
(
'
%(asctime)s - %(levelname)s - %(message)s
'
)
handler
.
setFormatter
(
formatter
)
logger
.
addHandler
(
handler
)
split_from_regex
=
re
.
compile
(
'
(?P<from_label>(
"
(.*)
"
)|(.*))(.*)<(?P<from_address>.*)>
'
)
address_domain_regex
=
re
.
compile
(
'
.*@(?P<domain>[\.\w-]+)
'
)
def
splitFromHeader
(
value
):
"""
Split
'
From:
'
header into label and address values.
"""
match
=
split_from_regex
.
match
(
value
)
re
sult
=
{
re
turn
{
'
label
'
:
match
.
group
(
'
from_label
'
).
strip
(),
'
address
'
:
match
.
group
(
'
from_address
'
).
strip
()
}
return
result
def
labelContainsAddress
(
label
):
"""
Check whether given
'
From:
'
header label contains something that looks like an email address.
"""
return
address_domain_regex
.
match
(
label
)
is
not
None
def
labelAndAddressDomainsMatch
(
split
):
label_domain
=
address_domain_regex
.
match
(
split
[
'
label
'
]).
group
(
'
domain
'
).
strip
()
address_domain
=
address_domain_regex
.
match
(
split
[
'
address
'
]).
group
(
'
domain
'
).
strip
()
return
label_domain
.
lower
()
==
address_domain
.
lower
()
class
SuspiciousFrom
(
Milter
.
Base
):
def
__init__
(
self
):
self
.
id
=
Milter
.
uniqueID
()
logger
.
info
(
f
"
{
self
.
id
}
got fired up.
"
)
self
.
milter_final_result
=
Milter
.
ACCEPT
self
.
final_result
=
Milter
.
ACCEPT
self
.
new_headers
=
[]
logger
.
info
(
f
"
{
self
.
id
}
got fired up.
"
)
def
header
(
self
,
field
,
value
):
"""
Header hook gets called for every header within the email processed.
"""
if
field
.
lower
()
==
'
from
'
:
logger
.
info
(
f
"
Got
\"
From:
\"
header with raw value:
'
{
value
}
'"
)
split
=
splitFromHeader
(
value
)
logger
.
info
(
f
"
Label:
{
split
[
'
label
'
]
}
, address:
{
split
[
'
address
'
]
}
"
)
if
'
@
'
in
split
[
'
label
'
]:
self
.
milter_final_result
=
Milter
.
REJECT
if
labelContainsAddress
(
split
[
'
label
'
]):
logger
.
info
()
if
labelAndAddressDomainsMatch
(
split
):
self
.
new_headers
.
append
({
'
name
'
:
'
X-From-Checked
'
,
'
value
'
:
'
Maybe multiple domains - no match - BAD!
'
})
self
.
final_result
=
Milter
.
ACCEPT
else
:
self
.
new_headers
.
append
({
'
name
'
:
'
X-From-Checked
'
,
'
value
'
:
'
Multiple domains - no match - BAD!
'
})
self
.
final_result
=
Milter
.
ACCEPT
else
:
self
.
new_headers
.
append
({
'
name
'
:
'
X-From-Checked
'
,
'
value
'
:
'
Yes, no address in label.
'
})
# Supposedly no additional address in the label, accept it for now
# TODO: Also decode utf-8 weirdness and check in there
self
.
milter_final_result
=
Milter
.
ACCEPT
return
Milter
.
CONTINUE
else
:
self
.
new_headers
.
append
({
'
name
'
:
'
X-From-Checked
'
,
'
value
'
:
'
Yes, no address in label.
'
})
self
.
final_result
=
Milter
.
ACCEPT
# Use continue here, so we can reach eom hook.
# TODO: Log and react if multiple From-headers are found?
return
Milter
.
CONTINUE
def
eom
(
self
):
"""
EOM hook gets called at the end of message processed. Headers and final verdict are applied only here.
"""
# Finish up message according to results collected on the way.
for
new_header
in
self
.
new_headers
:
self
.
addheader
(
new_header
[
'
name
'
],
new_header
[
'
value
'
])
return
self
.
milter_
final_result
return
self
.
final_result
def
main
():
# TODO: Move this into configuration of some sort.
milter_socket
=
"
inet:7777@127.0.0.1
"
milter_timeout
=
60
Milter
.
factory
=
SuspiciousFrom
logger
.
info
(
f
"
Starting Milter.
"
)
# This call blocks the main thread.
# TODO: Improve handling CTRL+C
Milter
.
runmilter
(
"
SuspiciousFromMilter
"
,
milter_socket
,
milter_timeout
,
rmsock
=
False
)
logger
.
info
(
f
"
Milter finished running.
"
)
if
__name__
==
"
__main__
"
:
logger
.
debug
(
f
"
Hello world!
"
)
main
()
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment