Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4b1a24df60 |
+3
-17
@@ -310,7 +310,7 @@ class Base(object):
|
|||||||
## Called when the connection is closed.
|
## Called when the connection is closed.
|
||||||
def close(self): return CONTINUE
|
def close(self): return CONTINUE
|
||||||
|
|
||||||
## Return mask of SMFIP_N* protocol option bits to clear for this class
|
## Return mask of SMFIP_N.. protocol option bits to clear for this class
|
||||||
# The @@nocallback and @@noreply decorators set the
|
# The @@nocallback and @@noreply decorators set the
|
||||||
# <code>milter_protocol</code> function attribute to the protocol mask bit to
|
# <code>milter_protocol</code> function attribute to the protocol mask bit to
|
||||||
# pass to libmilter, causing that callback or its reply to be skipped.
|
# pass to libmilter, causing that callback or its reply to be skipped.
|
||||||
@@ -336,10 +336,7 @@ class Base(object):
|
|||||||
|
|
||||||
## Negotiate milter protocol options. Called by the
|
## Negotiate milter protocol options. Called by the
|
||||||
# <a href="https://www.milter.org/developers/api/xxfi_negotiate">
|
# <a href="https://www.milter.org/developers/api/xxfi_negotiate">
|
||||||
# xffi_negotiate</a> callback. This is an advanced callback,
|
# xffi_negotiate</a> callback.
|
||||||
# do not override unless you know what you are doing. Most
|
|
||||||
# negotiation can be done simply by using the supplied
|
|
||||||
# class and function decorators.
|
|
||||||
# Options are passed as
|
# Options are passed as
|
||||||
# a list of 4 32-bit ints which can be modified and are passed
|
# a list of 4 32-bit ints which can be modified and are passed
|
||||||
# back to libmilter on return.
|
# back to libmilter on return.
|
||||||
@@ -366,24 +363,14 @@ class Base(object):
|
|||||||
## Return the value of an MTA macro. Sendmail macro names
|
## Return the value of an MTA macro. Sendmail macro names
|
||||||
# are either single chars (e.g. "j") or multiple chars enclosed
|
# are either single chars (e.g. "j") or multiple chars enclosed
|
||||||
# in braces (e.g. "{auth_type}"). Macro names are MTA dependent.
|
# in braces (e.g. "{auth_type}"). Macro names are MTA dependent.
|
||||||
# See <a href="https://www.milter.org/developers/api/smfi_getsymval">
|
|
||||||
# smfi_getsymval</a> for default sendmail macros.
|
|
||||||
# @param sym the macro name
|
# @param sym the macro name
|
||||||
def getsymval(self,sym):
|
def getsymval(self,sym):
|
||||||
return self._ctx.getsymval(sym)
|
return self._ctx.getsymval(sym)
|
||||||
|
|
||||||
## Set the SMTP reply code and message.
|
## Set the SMTP reply code and message.
|
||||||
# If the MTA does not support setmlreply, then only the
|
# If the MTA does not support setmlreply, then only the
|
||||||
# first msg line is used. Any '%' in a message line
|
# first msg line is used.
|
||||||
# must be doubled, or libmilter will silently ignore the setreply.
|
|
||||||
# Beginning with 0.9.6, we test for that case and throw ValueError to avoid
|
|
||||||
# head scratching. What will <i>really</i> irritate you, however,
|
|
||||||
# is that if you carefully double any '%', your message will be
|
|
||||||
# sent - but with the '%' still doubled!
|
|
||||||
def setreply(self,rcode,xcode=None,msg=None,*ml):
|
def setreply(self,rcode,xcode=None,msg=None,*ml):
|
||||||
for m in (msg,)+ml:
|
|
||||||
if 1 in [len(s)&1 for s in R.findall(m)]:
|
|
||||||
raise ValueError("'%' must be doubled: "+m)
|
|
||||||
return self._ctx.setreply(rcode,xcode,msg,*ml)
|
return self._ctx.setreply(rcode,xcode,msg,*ml)
|
||||||
|
|
||||||
## Tell the MTA which macro names will be used.
|
## Tell the MTA which macro names will be used.
|
||||||
@@ -727,5 +714,4 @@ for priv in ('os','milter','thread','factory','_seq','_seq_lock','__version__'):
|
|||||||
__all__ = __all__.keys()
|
__all__ = __all__.keys()
|
||||||
|
|
||||||
## @example milter-template.py
|
## @example milter-template.py
|
||||||
## @example milter-nomix.py
|
|
||||||
#
|
#
|
||||||
|
|||||||
+1
-1
@@ -50,7 +50,7 @@ class Greylist(object):
|
|||||||
# expired
|
# expired
|
||||||
log.debug('Expired greylist: %s',key)
|
log.debug('Expired greylist: %s',key)
|
||||||
r = Record()
|
r = Record()
|
||||||
elif now < r.firstseen + self.greylist_time + 5:
|
elif now < r.firstseen + self.greylist_time:
|
||||||
# still greylisted
|
# still greylisted
|
||||||
log.debug('Early greylist: %s',key)
|
log.debug('Early greylist: %s',key)
|
||||||
#r = Record()
|
#r = Record()
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ web:
|
|||||||
doxygen
|
doxygen
|
||||||
rsync -ravK doc/html/ spidey2.bmsi.com:/Public/pymilter
|
rsync -ravK doc/html/ spidey2.bmsi.com:/Public/pymilter
|
||||||
|
|
||||||
VERSION=0.9.6
|
VERSION=0.9.5
|
||||||
CVSTAG=pymilter-0_9_6
|
CVSTAG=pymilter-0_9_5
|
||||||
PKG=pymilter-$(VERSION)
|
PKG=pymilter-$(VERSION)
|
||||||
SRCTAR=$(PKG).tar.gz
|
SRCTAR=$(PKG).tar.gz
|
||||||
|
|
||||||
|
|||||||
@@ -1,79 +0,0 @@
|
|||||||
## A very simple milter to prevent mixing of internal and external mail.
|
|
||||||
# Internal is defined as using one of a list of internal top level domains.
|
|
||||||
# This code is open-source on the same terms as Python.
|
|
||||||
|
|
||||||
import Milter
|
|
||||||
import time
|
|
||||||
import sys
|
|
||||||
from Milter.utils import parse_addr
|
|
||||||
|
|
||||||
internal_tlds = ["corp", "personal"]
|
|
||||||
|
|
||||||
## Determine if a hostname is internal or not.
|
|
||||||
# True if internal, False otherwise
|
|
||||||
def is_internal(hostname):
|
|
||||||
components = hostname.split(".")
|
|
||||||
return components.pop() in internal_tlds:
|
|
||||||
|
|
||||||
# Determine if internal and external hosts are mixed based on a list
|
|
||||||
# of hostnames
|
|
||||||
def are_mixed(hostnames):
|
|
||||||
hostnames_mapped = map(is_internal, hostnames)
|
|
||||||
|
|
||||||
# Num internals
|
|
||||||
num_internal_hosts = hostnames_mapped.count(True)
|
|
||||||
|
|
||||||
# Num externals
|
|
||||||
num_external_hosts = hostnames_mapped.count(False)
|
|
||||||
|
|
||||||
return num_external_hosts >= 1 and num_internal_hosts >= 1
|
|
||||||
|
|
||||||
class NoMixMilter(Milter.Base):
|
|
||||||
|
|
||||||
def __init__(self): # A new instance with each new connection.
|
|
||||||
self.id = Milter.uniqueID() # Integer incremented with each call.
|
|
||||||
|
|
||||||
|
|
||||||
## def envfrom(self,f,*str):
|
|
||||||
@Milter.noreply
|
|
||||||
def envfrom(self, mailfrom, *str):
|
|
||||||
self.mailfrom = mailfrom
|
|
||||||
self.domains = []
|
|
||||||
t = parse_addr(mailfrom)
|
|
||||||
if len(t) > 1:
|
|
||||||
self.domains.append(t[1])
|
|
||||||
else:
|
|
||||||
self.domains.append('local')
|
|
||||||
self.internal = False
|
|
||||||
return Milter.CONTINUE
|
|
||||||
|
|
||||||
## def envrcpt(self, to, *str):
|
|
||||||
def envrcpt(self, to, *str):
|
|
||||||
self.R.append(to)
|
|
||||||
t = parse_addr(to)
|
|
||||||
if len(t) > 1:
|
|
||||||
self.domains.append(t[1])
|
|
||||||
else:
|
|
||||||
self.domains.append('local')
|
|
||||||
|
|
||||||
if are_mixed(self.domains):
|
|
||||||
# FIXME: log recipients collected in self.mailfrom and self.R
|
|
||||||
self.setreply('550','5.7.1','Mixing internal and external TLDs')
|
|
||||||
return Milter.REJECT
|
|
||||||
|
|
||||||
return Milter.CONTINUE
|
|
||||||
|
|
||||||
def main():
|
|
||||||
socketname = "/var/run/nomixsock"
|
|
||||||
timeout = 600
|
|
||||||
# Register to have the Milter factory create instances of your class:
|
|
||||||
Milter.factory = NoMixMilter
|
|
||||||
print "%s milter startup" % time.strftime('%Y%b%d %H:%M:%S')
|
|
||||||
sys.stdout.flush()
|
|
||||||
Milter.runmilter("nomixfilter",socketname,timeout)
|
|
||||||
logq.put(None)
|
|
||||||
bt.join()
|
|
||||||
print "%s nomix milter shutdown" % time.strftime('%Y%b%d %H:%M:%S')
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
||||||
+2
-1
@@ -79,7 +79,7 @@ class myMilter(Milter.Base):
|
|||||||
|
|
||||||
## def envrcpt(self, to, *str):
|
## def envrcpt(self, to, *str):
|
||||||
@Milter.noreply
|
@Milter.noreply
|
||||||
def envrcpt(self, to, *str):
|
def envrcpt(self, recipient, *str):
|
||||||
rcptinfo = to,Milter.dictfromlist(str)
|
rcptinfo = to,Milter.dictfromlist(str)
|
||||||
self.R.append(rcptinfo)
|
self.R.append(rcptinfo)
|
||||||
|
|
||||||
@@ -110,6 +110,7 @@ class myMilter(Milter.Base):
|
|||||||
self.addrcpt('<%s>' % 'spy@example.com')
|
self.addrcpt('<%s>' % 'spy@example.com')
|
||||||
return Milter.ACCEPT
|
return Milter.ACCEPT
|
||||||
|
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
# always called, even when abort is called. Clean up
|
# always called, even when abort is called. Clean up
|
||||||
# any external resources here.
|
# any external resources here.
|
||||||
|
|||||||
@@ -1,7 +1,4 @@
|
|||||||
# $Log$
|
# $Log$
|
||||||
# Revision 1.7 2009/06/13 21:15:12 customdesigned
|
|
||||||
# Doxygen updates.
|
|
||||||
#
|
|
||||||
# Revision 1.6 2009/06/09 03:13:13 customdesigned
|
# Revision 1.6 2009/06/09 03:13:13 customdesigned
|
||||||
# More doxygen docs.
|
# More doxygen docs.
|
||||||
#
|
#
|
||||||
@@ -168,14 +165,15 @@ class MimeMessage(Message):
|
|||||||
"""
|
"""
|
||||||
def __init__(self,fp=None,seekable=1):
|
def __init__(self,fp=None,seekable=1):
|
||||||
Message.__init__(self)
|
Message.__init__(self)
|
||||||
|
self.headerchange = None
|
||||||
self.submsg = None
|
self.submsg = None
|
||||||
self.modified = False
|
self.modified = False
|
||||||
|
|
||||||
## @var headerchange
|
## @var headerchange
|
||||||
# Provide a headerchange event for integration with Milter.
|
# Provide a headerchange event for integration with Milter.
|
||||||
# The headerchange attribute can be assigned a function to be called when
|
# The headerchange attribute can be assigned a function to be called when
|
||||||
# changing headers. The signature is:
|
# changing headers. The signature is:
|
||||||
# headerchange(msg,name,value) -> None
|
# headerchange(msg,name,value) -> None
|
||||||
self.headerchange = None
|
|
||||||
|
|
||||||
def get_param(self, param, failobj=None, header='content-type', unquote=True):
|
def get_param(self, param, failobj=None, header='content-type', unquote=True):
|
||||||
val = Message.get_param(self,param,failobj,header,unquote)
|
val = Message.get_param(self,param,failobj,header,unquote)
|
||||||
|
|||||||
+2
-6
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
Summary: Python interface to sendmail milter API
|
Summary: Python interface to sendmail milter API
|
||||||
Name: %{pythonbase}-pymilter
|
Name: %{pythonbase}-pymilter
|
||||||
Version: 0.9.6
|
Version: 0.9.5
|
||||||
Release: 1%{dist}
|
Release: 1%{dist}
|
||||||
Source: http://downloads.sourceforge.net/pymilter/pymilter-%{version}.tar.gz
|
Source: http://downloads.sourceforge.net/pymilter/pymilter-%{version}.tar.gz
|
||||||
License: GPLv2+
|
License: GPLv2+
|
||||||
@@ -75,11 +75,7 @@ chmod a+x $RPM_BUILD_ROOT%{libdir}/start.sh
|
|||||||
rm -rf $RPM_BUILD_ROOT
|
rm -rf $RPM_BUILD_ROOT
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
* Sat Feb 25 2012 Stuart Gathman <stuart@bmsi.com> 0.9.6-1
|
* Wed Mar 02 2010 Stuart Gathman <stuart@bmsi.com> 0.9.5-1
|
||||||
- Raise ValueError on unescaped '%' passed to setreply
|
|
||||||
- Grace time at end of Greylist window
|
|
||||||
|
|
||||||
* Fri Aug 19 2011 Stuart Gathman <stuart@bmsi.com> 0.9.5-1
|
|
||||||
- Print milter.error for invalid callback return type.
|
- Print milter.error for invalid callback return type.
|
||||||
(Since stacktrace is empty, the TypeError exception is confusing.)
|
(Since stacktrace is empty, the TypeError exception is confusing.)
|
||||||
- Fix milter-template.py
|
- Fix milter-template.py
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ libs = ["milter"]
|
|||||||
libdirs = ["/usr/lib/libmilter"] # needed for Debian
|
libdirs = ["/usr/lib/libmilter"] # needed for Debian
|
||||||
|
|
||||||
# NOTE: importing Milter to obtain version fails when milter.so not built
|
# NOTE: importing Milter to obtain version fails when milter.so not built
|
||||||
setup(name = "pymilter", version = '0.9.6',
|
setup(name = "pymilter", version = '0.9.5',
|
||||||
description="Python interface to sendmail milter API",
|
description="Python interface to sendmail milter API",
|
||||||
long_description="""\
|
long_description="""\
|
||||||
This is a python extension module to enable python scripts to
|
This is a python extension module to enable python scripts to
|
||||||
|
|||||||
Reference in New Issue
Block a user