Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
P
pymilter
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
GitLab community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
misc
pymilter
Commits
60963b3c
Commit
60963b3c
authored
16 years ago
by
Stuart Gathman
Browse files
Options
Downloads
Patches
Plain Diff
Streamline negotiate
parent
6221f8b7
No related branches found
No related tags found
No related merge requests found
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
Milter/__init__.py
+59
-51
59 additions, 51 deletions
Milter/__init__.py
pymilter.spec
+2
-1
2 additions, 1 deletion
pymilter.spec
with
61 additions
and
52 deletions
Milter/__init__.py
+
59
−
51
View file @
60963b3c
...
@@ -4,14 +4,14 @@
...
@@ -4,14 +4,14 @@
# A thin OO wrapper for the milter module
# A thin OO wrapper for the milter module
__version__
=
'
0.9.2
'
import
os
import
os
import
milter
import
milter
import
thread
import
thread
from
milter
import
*
from
milter
import
*
__version__
=
'
0.9.2
'
_seq_lock
=
thread
.
allocate_lock
()
_seq_lock
=
thread
.
allocate_lock
()
_seq
=
0
_seq
=
0
...
@@ -24,19 +24,32 @@ def uniqueID():
...
@@ -24,19 +24,32 @@ def uniqueID():
_seq_lock
.
release
()
_seq_lock
.
release
()
return
seqno
return
seqno
OPTIONAL_CALLBACKS
=
frozenset
((
OPTIONAL_CALLBACKS
=
{
'
connect
'
,
'
hello
'
,
'
envfrom
'
,
'
envrcpt
'
,
'
data
'
,
'
header
'
,
'
eoh
'
,
'
body
'
,
'
unknown
'
))
'
connect
'
:(
P_NR_CONN
,
P_NOCONNECT
),
'
hello
'
:(
P_NR_HELO
,
P_NOHELO
),
'
envfrom
'
:(
P_NR_MAIL
,
P_NOMAIL
),
'
envrcpt
'
:(
P_NR_RCPT
,
P_NORCPT
),
'
data
'
:(
P_NR_DATA
,
P_NODATA
),
'
unknown
'
:(
P_NR_UNKN
,
P_NOUNKNOWN
),
'
eoh
'
:(
P_NR_EOH
,
P_NOEOH
),
'
body
'
:(
P_NR_BODY
,
P_NOBODY
),
'
header
'
:(
P_NR_HDR
,
P_NOHDRS
)
}
def
nocallback
(
func
):
def
nocallback
(
func
):
if
not
func
.
__name__
in
OPTIONAL_CALLBACKS
:
try
:
func
.
milter_protocol
=
OPTIONAL_CALLBACKS
[
func
.
__name__
][
1
]
except
KeyError
:
raise
ValueError
(
raise
ValueError
(
'
@nocallback applied to non-optional method:
'
+
func
.
__name__
)
'
@nocallback applied to non-optional method:
'
+
func
.
__name__
)
func
.
milter_protocol
=
'
NO
'
return
func
return
func
def
noreply
(
func
):
def
noreply
(
func
):
if
not
func
.
__name__
in
OPTIONAL_CALLBACKS
:
try
:
func
.
milter_protocol
=
OPTIONAL_CALLBACKS
[
func
.
__name__
][
0
]
except
KeyErro
:
raise
ValueError
(
raise
ValueError
(
'
@noreply applied to non-optional method:
'
+
func
.
__name__
)
'
@noreply applied to non-optional method:
'
+
func
.
__name__
)
func
.
milter_protocol
=
'
NR
'
return
func
return
func
class
DisabledAction
(
RuntimeError
):
class
DisabledAction
(
RuntimeError
):
...
@@ -49,8 +62,8 @@ class Base(object):
...
@@ -49,8 +62,8 @@ class Base(object):
"
The core class interface to the milter module.
"
"
The core class interface to the milter module.
"
def
_setctx
(
self
,
ctx
):
def
_setctx
(
self
,
ctx
):
self
.
_
_
ctx
=
ctx
self
.
_ctx
=
ctx
self
.
_
_
actions
=
CURR_ACTS
# all actions enabled by default
self
.
_actions
=
CURR_ACTS
# all actions enabled by default
if
ctx
:
if
ctx
:
ctx
.
setpriv
(
self
)
ctx
.
setpriv
(
self
)
def
log
(
self
,
*
msg
):
pass
def
log
(
self
,
*
msg
):
pass
...
@@ -76,32 +89,27 @@ class Base(object):
...
@@ -76,32 +89,27 @@ class Base(object):
def
abort
(
self
):
return
CONTINUE
def
abort
(
self
):
return
CONTINUE
def
close
(
self
):
return
CONTINUE
def
close
(
self
):
return
CONTINUE
# Return mask of SMFIP_N.. protocol bits to clear for this class
@classmethod
def
protocol_mask
(
klass
):
try
:
return
klass
.
_protocol_mask
except
AttributeError
:
p
=
0
for
func
,(
nr
,
nc
)
in
OPTIONAL_CALLBACKS
.
items
():
func
=
getattr
(
klass
,
func
)
ca
=
getattr
(
func
,
'
milter_protocol
'
,
0
)
#print func,hex(nr),hex(nc),hex(ca)
p
|=
(
nr
|
nc
)
&
~
ca
klass
.
_protocol_mask
=
p
return
p
# Default negotiation sets P_NO* and P_NR* for callbacks
# Default negotiation sets P_NO* and P_NR* for callbacks
# marked @nocallback and @noreply respectively
# marked @nocallback and @noreply respectively
def
negotiate
(
self
,
opts
):
def
negotiate
(
self
,
opts
):
try
:
try
:
self
.
__actions
,
p
,
f1
,
f2
=
opts
self
.
_actions
,
p
,
f1
,
f2
=
opts
for
func
,
nr
,
nc
in
(
opts
[
1
]
=
p
&
~
self
.
protocol_mask
()
&
~
P_RCPT_REJ
&
~
P_HDR_LEADSPC
(
self
.
connect
,
P_NR_CONN
,
P_NOCONNECT
),
(
self
.
hello
,
P_NR_HELO
,
P_NOHELO
),
(
self
.
envfrom
,
P_NR_MAIL
,
P_NOMAIL
),
(
self
.
envrcpt
,
P_NR_RCPT
,
P_NORCPT
),
(
self
.
data
,
P_NR_DATA
,
P_NODATA
),
(
self
.
unknown
,
P_NR_UNKN
,
P_NOUNKNOWN
),
(
self
.
eoh
,
P_NR_EOH
,
P_NOEOH
),
(
self
.
body
,
P_NR_BODY
,
P_NOBODY
),
(
self
.
header
,
P_NR_HDR
,
P_NOHDRS
)
):
ca
=
getattr
(
func
,
'
milter_protocol
'
,
None
)
if
ca
!=
'
NR
'
:
p
&=
~
nr
#elif p & nr:
# self.log(func.__name__,'NOREPLY')
if
ca
!=
'
NO
'
:
p
&=
~
nc
#elif p & nc:
# self.log(func.__name__,'NOCALLBACK')
opts
[
1
]
=
p
&
~
P_RCPT_REJ
&
~
P_HDR_LEADSPC
opts
[
2
]
=
0
opts
[
2
]
=
0
opts
[
3
]
=
0
opts
[
3
]
=
0
self
.
log
(
"
Negotiated:
"
,
opts
)
self
.
log
(
"
Negotiated:
"
,
opts
)
...
@@ -112,53 +120,53 @@ class Base(object):
...
@@ -112,53 +120,53 @@ class Base(object):
# Milter methods which can be invoked from most callbacks
# Milter methods which can be invoked from most callbacks
def
getsymval
(
self
,
sym
):
def
getsymval
(
self
,
sym
):
return
self
.
_
_
ctx
.
getsymval
(
sym
)
return
self
.
_ctx
.
getsymval
(
sym
)
# If sendmail does not support setmlreply, then only the
# If sendmail does not support setmlreply, then only the
# first msg line is used.
# first msg line is used.
def
setreply
(
self
,
rcode
,
xcode
=
None
,
msg
=
None
,
*
ml
):
def
setreply
(
self
,
rcode
,
xcode
=
None
,
msg
=
None
,
*
ml
):
return
self
.
_
_
ctx
.
setreply
(
rcode
,
xcode
,
msg
,
*
ml
)
return
self
.
_ctx
.
setreply
(
rcode
,
xcode
,
msg
,
*
ml
)
# may only be called from negotiate callback
# may only be called from negotiate callback
def
setsmlist
(
self
,
stage
,
macros
):
def
setsmlist
(
self
,
stage
,
macros
):
if
not
self
.
_
_
actions
&
SETSMLIST
:
raise
DisabledAction
(
"
SETSMLIST
"
)
if
not
self
.
_actions
&
SETSMLIST
:
raise
DisabledAction
(
"
SETSMLIST
"
)
if
type
(
macros
)
in
(
list
,
tuple
):
if
type
(
macros
)
in
(
list
,
tuple
):
macros
=
'
'
.
join
(
macros
)
macros
=
'
'
.
join
(
macros
)
return
self
.
_
_
ctx
.
setsmlist
(
stage
,
macros
)
return
self
.
_ctx
.
setsmlist
(
stage
,
macros
)
# Milter methods which can only be called from eom callback.
# Milter methods which can only be called from eom callback.
def
addheader
(
self
,
field
,
value
,
idx
=-
1
):
def
addheader
(
self
,
field
,
value
,
idx
=-
1
):
if
not
self
.
_
_
actions
&
ADDHDRS
:
raise
DisabledAction
(
"
ADDHDRS
"
)
if
not
self
.
_actions
&
ADDHDRS
:
raise
DisabledAction
(
"
ADDHDRS
"
)
return
self
.
_
_
ctx
.
addheader
(
field
,
value
,
idx
)
return
self
.
_ctx
.
addheader
(
field
,
value
,
idx
)
def
chgheader
(
self
,
field
,
idx
,
value
):
def
chgheader
(
self
,
field
,
idx
,
value
):
if
not
self
.
_
_
actions
&
CHGHDRS
:
raise
DisabledAction
(
"
CHGHDRS
"
)
if
not
self
.
_actions
&
CHGHDRS
:
raise
DisabledAction
(
"
CHGHDRS
"
)
return
self
.
_
_
ctx
.
chgheader
(
field
,
idx
,
value
)
return
self
.
_ctx
.
chgheader
(
field
,
idx
,
value
)
def
addrcpt
(
self
,
rcpt
,
params
=
None
):
def
addrcpt
(
self
,
rcpt
,
params
=
None
):
if
not
self
.
_
_
actions
&
ADDRCPT
:
raise
DisabledAction
(
"
ADDRCPT
"
)
if
not
self
.
_actions
&
ADDRCPT
:
raise
DisabledAction
(
"
ADDRCPT
"
)
return
self
.
_
_
ctx
.
addrcpt
(
rcpt
,
params
)
return
self
.
_ctx
.
addrcpt
(
rcpt
,
params
)
def
delrcpt
(
self
,
rcpt
):
def
delrcpt
(
self
,
rcpt
):
if
not
self
.
_
_
actions
&
DELRCPT
:
raise
DisabledAction
(
"
DELRCPT
"
)
if
not
self
.
_actions
&
DELRCPT
:
raise
DisabledAction
(
"
DELRCPT
"
)
return
self
.
_
_
ctx
.
delrcpt
(
rcpt
)
return
self
.
_ctx
.
delrcpt
(
rcpt
)
def
replacebody
(
self
,
body
):
def
replacebody
(
self
,
body
):
if
not
self
.
_
_
actions
&
MODBODY
:
raise
DisabledAction
(
"
MODBODY
"
)
if
not
self
.
_actions
&
MODBODY
:
raise
DisabledAction
(
"
MODBODY
"
)
return
self
.
_
_
ctx
.
replacebody
(
body
)
return
self
.
_ctx
.
replacebody
(
body
)
def
chgfrom
(
self
,
sender
,
params
=
None
):
def
chgfrom
(
self
,
sender
,
params
=
None
):
if
not
self
.
_
_
actions
&
CHGFROM
:
raise
DisabledAction
(
"
CHGFROM
"
)
if
not
self
.
_actions
&
CHGFROM
:
raise
DisabledAction
(
"
CHGFROM
"
)
return
self
.
_
_
ctx
.
chgfrom
(
sender
,
params
)
return
self
.
_ctx
.
chgfrom
(
sender
,
params
)
# When quarantined, a message goes into the mailq as if to be delivered,
# When quarantined, a message goes into the mailq as if to be delivered,
# but delivery is deferred until the message is unquarantined.
# but delivery is deferred until the message is unquarantined.
def
quarantine
(
self
,
reason
):
def
quarantine
(
self
,
reason
):
if
not
self
.
_
_
actions
&
QUARANTINE
:
raise
DisabledAction
(
"
QUARANTINE
"
)
if
not
self
.
_actions
&
QUARANTINE
:
raise
DisabledAction
(
"
QUARANTINE
"
)
return
self
.
_
_
ctx
.
quarantine
(
reason
)
return
self
.
_ctx
.
quarantine
(
reason
)
def
progress
(
self
):
def
progress
(
self
):
return
self
.
_
_
ctx
.
progress
()
return
self
.
_ctx
.
progress
()
# A logging but otherwise do nothing Milter base class included
# A logging but otherwise do nothing Milter base class included
# for compatibility with previous versions of pymilter.
# for compatibility with previous versions of pymilter.
...
...
This diff is collapsed.
Click to expand it.
pymilter.spec
+
2
−
1
View file @
60963b3c
...
@@ -12,7 +12,7 @@
...
@@ -12,7 +12,7 @@
Summary: Python interface to sendmail milter API
Summary: Python interface to sendmail milter API
Name: pymilter
Name: pymilter
Version: 0.9.2
Version: 0.9.2
Release:
1
%{dist}
Release:
2
%{dist}
Source: http://downloads.sourceforge.net/pymilter/%{name}-%{version}.tar.gz
Source: http://downloads.sourceforge.net/pymilter/%{name}-%{version}.tar.gz
License: GPLv2+
License: GPLv2+
Group: Development/Libraries
Group: Development/Libraries
...
@@ -85,6 +85,7 @@ rm -rf $RPM_BUILD_ROOT
...
@@ -85,6 +85,7 @@ rm -rf $RPM_BUILD_ROOT
%changelog
%changelog
* Thu May 28 2009 Stuart Gathman <stuart@bmsi.com> 0.9.2-1
* Thu May 28 2009 Stuart Gathman <stuart@bmsi.com> 0.9.2-1
- Add new callback support: data,negotiate,unknown
- Add new callback support: data,negotiate,unknown
- Auto-negotiate protocol steps
* Thu Feb 05 2009 Stuart Gathman <stuart@bmsi.com> 0.9.1-1
* Thu Feb 05 2009 Stuart Gathman <stuart@bmsi.com> 0.9.1-1
- Fix missing address of optional param to addrcpt
- Fix missing address of optional param to addrcpt
...
...
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