Skip to content
Snippets Groups Projects
Commit 6221f8b7 authored by Stuart Gathman's avatar Stuart Gathman
Browse files

Validate methods passed to @noreply, @nocallback

parent 344ecc7c
No related branches found
No related tags found
No related merge requests found
...@@ -24,10 +24,18 @@ def uniqueID(): ...@@ -24,10 +24,18 @@ def uniqueID():
_seq_lock.release() _seq_lock.release()
return seqno return seqno
OPTIONAL_CALLBACKS = frozenset((
'connect','hello','envfrom','envrcpt','data','header','eoh','body','unknown'))
def nocallback(func): def nocallback(func):
if not func.__name__ in OPTIONAL_CALLBACKS:
raise ValueError(
'@nocallback applied to non-optional method: '+func.__name__)
func.milter_protocol = 'NO' func.milter_protocol = 'NO'
return func return func
def noreply(func): def noreply(func):
if not func.__name__ in OPTIONAL_CALLBACKS:
raise ValueError(
'@noreply applied to non-optional method: '+func.__name__)
func.milter_protocol = 'NR' func.milter_protocol = 'NR'
return func return func
...@@ -40,12 +48,12 @@ class DisabledAction(RuntimeError): ...@@ -40,12 +48,12 @@ class DisabledAction(RuntimeError):
class Base(object): class Base(object):
"The core class interface to the milter module." "The core class interface to the milter module."
def __init__(self):
self.__actions = CURR_ACTS # all actions enabled
def _setctx(self,ctx): def _setctx(self,ctx):
self.__ctx = ctx self.__ctx = ctx
self.__actions = CURR_ACTS # all actions enabled by default
if ctx: if ctx:
ctx.setpriv(self) ctx.setpriv(self)
def log(self,*msg): pass
@nocallback @nocallback
def connect(self,hostname,family,hostaddr): return CONTINUE def connect(self,hostname,family,hostaddr): return CONTINUE
@nocallback @nocallback
...@@ -63,13 +71,13 @@ class Base(object): ...@@ -63,13 +71,13 @@ class Base(object):
@nocallback @nocallback
def body(self,unused): return CONTINUE def body(self,unused): return CONTINUE
@nocallback @nocallback
def unknown(self,cmd): return CONTINUE
def eom(self): return CONTINUE def eom(self): return CONTINUE
@nocallback
def abort(self): return CONTINUE def abort(self): return CONTINUE
@nocallback
def unknown(self,cmd): return CONTINUE
@nocallback
def close(self): return CONTINUE def close(self): return CONTINUE
# Default negotiation sets P_NO* and P_NR* for callbacks
# 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
...@@ -85,13 +93,18 @@ class Base(object): ...@@ -85,13 +93,18 @@ class Base(object):
(self.header,P_NR_HDR,P_NOHDRS) (self.header,P_NR_HDR,P_NOHDRS)
): ):
ca = getattr(func,'milter_protocol',None) ca = getattr(func,'milter_protocol',None)
if ca != 'NR': p &= ~nr if ca != 'NR':
elif p & nr: print func.__name__,'NOREPLY' p &= ~nr
if ca != 'NO': p &= ~nc #elif p & nr:
elif p & nc: print func.__name__,'NOCALLBACK' # 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[1] = p & ~P_RCPT_REJ & ~P_HDR_LEADSPC
opts[2] = 0 opts[2] = 0
opts[3] = 0 opts[3] = 0
self.log("Negotiated:",opts)
except: except:
# don't change anything if something went wrong # don't change anything if something went wrong
return ALL_OPTS return ALL_OPTS
...@@ -197,7 +210,6 @@ class Milter(Base): ...@@ -197,7 +210,6 @@ class Milter(Base):
self.log("eoh") self.log("eoh")
return CONTINUE return CONTINUE
@noreply
def eom(self): def eom(self):
"Called at the end of message." "Called at the end of message."
self.log("eom") self.log("eom")
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment