diff --git a/CVSROOT/checkoutlist b/CVSROOT/checkoutlist deleted file mode 100644 index 2921bff..0000000 --- a/CVSROOT/checkoutlist +++ /dev/null @@ -1,13 +0,0 @@ -# The "checkoutlist" file is used to support additional version controlled -# administrative files in $CVSROOT/CVSROOT, such as template files. -# -# The first entry on a line is a filename which will be checked out from -# the corresponding RCS file in the $CVSROOT/CVSROOT directory. -# The remainder of the line is an error message to use if the file cannot -# be checked out. -# -# File format: -# -# [][] -# -# comment lines begin with '#' diff --git a/CVSROOT/commitinfo b/CVSROOT/commitinfo deleted file mode 100644 index b19e7b7..0000000 --- a/CVSROOT/commitinfo +++ /dev/null @@ -1,15 +0,0 @@ -# The "commitinfo" file is used to control pre-commit checks. -# The filter on the right is invoked with the repository and a list -# of files to check. A non-zero exit of the filter program will -# cause the commit to be aborted. -# -# The first entry on a line is a regular expression which is tested -# against the directory that the change is being committed to, relative -# to the $CVSROOT. For the first match that is found, then the remainder -# of the line is the name of the filter to run. -# -# If the repository name does not match any of the regular expressions in this -# file, the "DEFAULT" line is used, if it is specified. -# -# If the name "ALL" appears as a regular expression it is always used -# in addition to the first matching regex or "DEFAULT". diff --git a/CVSROOT/config b/CVSROOT/config deleted file mode 100644 index 92c150b..0000000 --- a/CVSROOT/config +++ /dev/null @@ -1,21 +0,0 @@ -# Set this to "no" if pserver shouldn't check system users/passwords -#SystemAuth=no - -# Put CVS lock files in this directory rather than directly in the repository. -#LockDir=/var/lock/cvs - -# Set `TopLevelAdmin' to `yes' to create a CVS directory at the top -# level of the new working directory when using the `cvs checkout' -# command. -#TopLevelAdmin=no - -# Set `LogHistory' to `all' or `TOEFWUPCGMAR' to log all transactions to the -# history file, or a subset as needed (ie `TMAR' logs all write operations) -#LogHistory=TOEFWUPCGMAR - -# Set `RereadLogAfterVerify' to `always' (the default) to allow the verifymsg -# script to change the log message. Set it to `stat' to force CVS to verify# that the file has changed before reading it (this can take up to an extra -# second per directory being committed, so it is not recommended for large -# repositories. Set it to `never' (the previous CVS behavior) to prevent -# verifymsg scripts from changing the log message. -#RereadLogAfterVerify=always diff --git a/CVSROOT/cvswrappers b/CVSROOT/cvswrappers deleted file mode 100644 index e989b75..0000000 --- a/CVSROOT/cvswrappers +++ /dev/null @@ -1,19 +0,0 @@ -# This file affects handling of files based on their names. -# -# The -m option specifies whether CVS attempts to merge files. -# -# The -k option specifies keyword expansion (e.g. -kb for binary). -# -# Format of wrapper file ($CVSROOT/CVSROOT/cvswrappers or .cvswrappers) -# -# wildcard [option value][option value]... -# -# where option is one of -# -f from cvs filter value: path to filter -# -t to cvs filter value: path to filter -# -m update methodology value: MERGE or COPY -# -k expansion mode value: b, o, kkv, &c -# -# and value is a single-quote delimited value. -# For example: -#*.gif -k 'b' diff --git a/CVSROOT/editinfo b/CVSROOT/editinfo deleted file mode 100644 index d78886c..0000000 --- a/CVSROOT/editinfo +++ /dev/null @@ -1,21 +0,0 @@ -# The "editinfo" file is used to allow verification of logging -# information. It works best when a template (as specified in the -# rcsinfo file) is provided for the logging procedure. Given a -# template with locations for, a bug-id number, a list of people who -# reviewed the code before it can be checked in, and an external -# process to catalog the differences that were code reviewed, the -# following test can be applied to the code: -# -# Making sure that the entered bug-id number is correct. -# Validating that the code that was reviewed is indeed the code being -# checked in (using the bug-id number or a seperate review -# number to identify this particular code set.). -# -# If any of the above test failed, then the commit would be aborted. -# -# Actions such as mailing a copy of the report to each reviewer are -# better handled by an entry in the loginfo file. -# -# One thing that should be noted is the the ALL keyword is not -# supported. There can be only one entry that matches a given -# repository. diff --git a/CVSROOT/loginfo b/CVSROOT/loginfo deleted file mode 100644 index 537607d..0000000 --- a/CVSROOT/loginfo +++ /dev/null @@ -1,27 +0,0 @@ -# The "loginfo" file controls where "cvs commit" log information -# is sent. The first entry on a line is a regular expression which must match -# the directory that the change is being made to, relative to the -# $CVSROOT. If a match is found, then the remainder of the line is a filter -# program that should expect log information on its standard input. -# -# If the repository name does not match any of the regular expressions in this -# file, the "DEFAULT" line is used, if it is specified. -# -# If the name ALL appears as a regular expression it is always used -# in addition to the first matching regex or DEFAULT. -# -# You may specify a format string as part of the -# filter. The string is composed of a `%' followed -# by a single format character, or followed by a set of format -# characters surrounded by `{' and `}' as separators. The format -# characters are: -# -# s = file name -# V = old version number (pre-checkin) -# v = new version number (post-checkin) -# t = tag or branch name -# -# For example: -#DEFAULT (echo ""; id; echo %s; date; cat) >> $CVSROOT/CVSROOT/commitlog -# or -#DEFAULT (echo ""; id; echo %{sVv}; date; cat) >> $CVSROOT/CVSROOT/commitlog diff --git a/CVSROOT/modules b/CVSROOT/modules deleted file mode 100644 index cb9e9ef..0000000 --- a/CVSROOT/modules +++ /dev/null @@ -1,26 +0,0 @@ -# Three different line formats are valid: -# key -a aliases... -# key [options] directory -# key [options] directory files... -# -# Where "options" are composed of: -# -i prog Run "prog" on "cvs commit" from top-level of module. -# -o prog Run "prog" on "cvs checkout" of module. -# -e prog Run "prog" on "cvs export" of module. -# -t prog Run "prog" on "cvs rtag" of module. -# -u prog Run "prog" on "cvs update" of module. -# -d dir Place module in directory "dir" instead of module name. -# -l Top-level directory only -- do not recurse. -# -# NOTE: If you change any of the "Run" options above, you'll have to -# release and re-checkout any working directories of these modules. -# -# And "directory" is a path to a directory relative to $CVSROOT. -# -# The "-a" option specifies an alias. An alias is interpreted as if -# everything on the right of the "-a" had been typed on the command line. -# -# You can encode a module within a module by using the special '&' -# character to interpose another module into the current module. This -# can be useful for creating a module that consists of many directories -# spread out over the entire source repository. diff --git a/CVSROOT/notify b/CVSROOT/notify deleted file mode 100644 index 74ae6f9..0000000 --- a/CVSROOT/notify +++ /dev/null @@ -1,12 +0,0 @@ -# The "notify" file controls where notifications from watches set by -# "cvs watch add" or "cvs edit" are sent. The first entry on a line is -# a regular expression which is tested against the directory that the -# change is being made to, relative to the $CVSROOT. If it matches, -# then the remainder of the line is a filter program that should contain -# one occurrence of %s for the user to notify, and information on its -# standard input. -# -# "ALL" or "DEFAULT" can be used in place of the regular expression. -# -# For example: -#ALL mail -s "CVS notification" %s diff --git a/CVSROOT/rcsinfo b/CVSROOT/rcsinfo deleted file mode 100644 index 49e59f4..0000000 --- a/CVSROOT/rcsinfo +++ /dev/null @@ -1,13 +0,0 @@ -# The "rcsinfo" file is used to control templates with which the editor -# is invoked on commit and import. -# -# The first entry on a line is a regular expression which is tested -# against the directory that the change is being made to, relative to the -# $CVSROOT. For the first match that is found, then the remainder of the -# line is the name of the file that contains the template. -# -# If the repository name does not match any of the regular expressions in this -# file, the "DEFAULT" line is used, if it is specified. -# -# If the name "ALL" appears as a regular expression it is always used -# in addition to the first matching regex or "DEFAULT". diff --git a/CVSROOT/taginfo b/CVSROOT/taginfo deleted file mode 100644 index 274a46d..0000000 --- a/CVSROOT/taginfo +++ /dev/null @@ -1,20 +0,0 @@ -# The "taginfo" file is used to control pre-tag checks. -# The filter on the right is invoked with the following arguments: -# -# $1 -- tagname -# $2 -- operation "add" for tag, "mov" for tag -F, and "del" for tag -d -# $3 -- repository -# $4-> file revision [file revision ...] -# -# A non-zero exit of the filter program will cause the tag to be aborted. -# -# The first entry on a line is a regular expression which is tested -# against the directory that the change is being committed to, relative -# to the $CVSROOT. For the first match that is found, then the remainder -# of the line is the name of the filter to run. -# -# If the repository name does not match any of the regular expressions in this -# file, the "DEFAULT" line is used, if it is specified. -# -# If the name "ALL" appears as a regular expression it is always used -# in addition to the first matching regex or "DEFAULT". diff --git a/CVSROOT/verifymsg b/CVSROOT/verifymsg deleted file mode 100644 index 86f747c..0000000 --- a/CVSROOT/verifymsg +++ /dev/null @@ -1,21 +0,0 @@ -# The "verifymsg" file is used to allow verification of logging -# information. It works best when a template (as specified in the -# rcsinfo file) is provided for the logging procedure. Given a -# template with locations for, a bug-id number, a list of people who -# reviewed the code before it can be checked in, and an external -# process to catalog the differences that were code reviewed, the -# following test can be applied to the code: -# -# Making sure that the entered bug-id number is correct. -# Validating that the code that was reviewed is indeed the code being -# checked in (using the bug-id number or a seperate review -# number to identify this particular code set.). -# -# If any of the above test failed, then the commit would be aborted. -# -# Actions such as mailing a copy of the report to each reviewer are -# better handled by an entry in the loginfo file. -# -# One thing that should be noted is the the ALL keyword is not -# supported. There can be only one entry that matches a given -# repository. diff --git a/smmapd_prototype/Cache.py b/smmapd_prototype/Cache.py deleted file mode 100644 index 8bbfcc9..0000000 --- a/smmapd_prototype/Cache.py +++ /dev/null @@ -1,37 +0,0 @@ -import threading -import time - -from Logging import * - - - -class Cache(object): - def __init__(self, expiration): - self.lock = threading.Lock() - self.expiration = expiration - self.cache = {} - - def put(self, key, value): - self.lock.acquire() - self.cache[key] = (time.time(), value) - debug("cache.put(%s, %s)" % (str(key), str(value))) - self.lock.release() - - def get(self, key): - try: - self.lock.acquire() - debug("cache.get(%s)" % str(key)) - try: - timestamp, value = self.cache[key] - debug("cache.get found: %s" % value) - if (timestamp + self.expiration) < time.time(): - debug("cache.get: expired") - del self.cache[key] - raise KeyError - return value - except KeyError: - debug("cache.get: found nothing") - return None - finally: - self.lock.release() - diff --git a/smmapd_prototype/CyrusChecker.py b/smmapd_prototype/CyrusChecker.py deleted file mode 100644 index c98733e..0000000 --- a/smmapd_prototype/CyrusChecker.py +++ /dev/null @@ -1,27 +0,0 @@ -from Logging import * - -from SendmailSocketMapHandler import smmapBaseHandlerWorker -from SendmailSocketMapHandler import smmapBaseHandlerContainer -from SendmailSocketMapHandler import MyPermanentVerifierException -from SendmailSocketMapHandler import MyTemporaryVerifierException - -from VerifierHandler import MySMTP - -class MyLMTP(MySMTP): - def lhlo(self, param): - return self.docmd("lhlo " + param) - -class CyrusCheckerWorker(smmapBaseHandlerWorker): - OK = "OK" - NOK = "NOK" - TEMPNOK = "TEMPNOK" - - def execute(self, data): - debug("data " + data) - - host, address = data.split('|') - - debug("host: (%s), address: (%s)" % (host, address)) - - return "" - diff --git a/smmapd_prototype/Logging.py b/smmapd_prototype/Logging.py deleted file mode 100644 index 6bd9438..0000000 --- a/smmapd_prototype/Logging.py +++ /dev/null @@ -1,14 +0,0 @@ -import syslog - - -config = None - -def log(data): - syslog.syslog(syslog.LOG_INFO, data) - -def debug(data): - syslog.syslog(syslog.LOG_DEBUG, data) - -def openlog(c): - config = c - syslog.openlog(config.get('Logging', 'ApplID'), syslog.LOG_PID, syslog.LOG_MAIL) diff --git a/smmapd_prototype/MANIFEST b/smmapd_prototype/MANIFEST deleted file mode 100644 index da3adf6..0000000 --- a/smmapd_prototype/MANIFEST +++ /dev/null @@ -1,8 +0,0 @@ -Cache.py -Logging.py -SendmailSocketMapHandler.py -VerifierHandler.py -setup.py -smmapd -smmapd.ini -verifysender.m4 diff --git a/smmapd_prototype/SendmailSocketMapHandler.py b/smmapd_prototype/SendmailSocketMapHandler.py deleted file mode 100644 index f5277e4..0000000 --- a/smmapd_prototype/SendmailSocketMapHandler.py +++ /dev/null @@ -1,190 +0,0 @@ -import SocketServer -import time - -from Logging import * - - -class NetStringError(ValueError): pass - -def NetStringDecode(s): - try: - length, data = s.split(':') - except ValueError: - raise NetStringError, "Separator not found" - try: - length = int(length) - except ValueError: - raise NetStringError, "Can not read length" - if len(data) != length+1: - raise NetStringError, "Data has unexpected length" - if data[-1] != ',': - raise NetStringError, "End-delimiter not found" - return data[:-1] - -def NetStringEncode(s): - return str(len(s)) + ":" + s + "," - - -class MyPermanentVerifierException(ValueError): pass - -class MyTemporaryVerifierException(ValueError): pass - -class MyBaseRequestHandler(SocketServer.BaseRequestHandler): - def handle(self): - debug("Connected from " + str(self.client_address)) - self.localSetup() - while 1: - receivedData = self.request.recv(8192) - if (receivedData == None) or (len(receivedData) == 0): break - debug("Data: (%s)" % receivedData) - self.request.sendall(self.process(receivedData)) - self.request.close(); - self.localFinish() - debug("Disconnected") - - def process(self, data): - debug("MyBaseRequestHandler.process") - return data - - def localSetup(self): pass - - def localfinish(self): pass - - -class SendmailAdaptor: - PERM = "PERM " - OK = "OK " - NOTFOUND = "NOTFOUND " - TEMP = "TEMP " - - def preProcess(self, data): - try: - data = NetStringDecode(data) - klass, data = data.split(' ') - return klass, data - except NetStringError, arg: - raise MyPermanentVerifierException, arg - except ValueError: - raise MyPermanentVerifierException, " expected, only one found" - - def postProcess(self, data): - return NetStringEncode(data) - - def process(self, data): - startTime = time.time() - try: - klass, data2 = self.preProcess(data) - arg = self.execute(klass, data2) - code = SendmailAdaptor.OK - except MyPermanentVerifierException, arg: - code, arg = SendmailAdaptor.PERM, str(arg) - except MyTemporaryVerifierException, arg: - code, arg = SendmailAdaptor.TEMP, str(arg) - endTime = time.time() - log("Class: %s, Data: %s, Code: %s, Arg: %s, Delay: %f" % (klass, data2, code, arg, endTime-startTime)) - return self.postProcess(code + arg) - - def execute(self, data): - return data - -class NullAdaptor(SendmailAdaptor): - def preProcess(self, data): - return re.compile(r'^(.*?)[\r\n]{1,2}$').match(data).group(1) - - def postProcess(self, data): - return data + "\n" - - -class SendmailDispatcher(SendmailAdaptor, MyBaseRequestHandler): - pluginContainerObjects = {} - - - def registerAll(config): - for section in config.get('Daemon', 'Plugins').split(','): - SendmailDispatcher.register(section, config) - - registerAll = staticmethod(registerAll) - - - def register(section, config): - cfg = Config(section, config) - className = cfg.get('ContainerClass') - moduleName = cfg.get('ContainerModule') - if className == None: - className = 'smmapBaseHandlerContainer' - else: - if moduleName == None: - moduleName == className - m = __import__(moduleName) - log("Registering %s, %s" % (section, className)) - klass = eval("m.%s" % className) - containerObject = klass(cfg) - containerObject.setup() - SendmailDispatcher.pluginContainerObjects[section] = containerObject - - register = staticmethod(register) - - - def localSetup(self): - self.pluginWorkerObjects = {} - - def localFinish(self): - for o in self.pluginWorkerObjects.values(): - o.finish() - - def execute(self, klass, data): - if not self.pluginContainerObjects.has_key(klass): - raise MyPermanentVerifierException, "Class %s not implemented" % klass - elif not self.pluginWorkerObjects.has_key(klass): - debug("Instantiate worker %s" % klass) - self.pluginWorkerObjects[klass] = self.pluginContainerObjects[klass].getWorker() - - return self.pluginWorkerObjects[klass].execute(data) - - -class Config(object): - def __init__(self, section, config): - self.section = section - self.config = config - - def getSection(self): - return self.section - - def get(self, item): - return self.config.get(self.section, item) - - -class smmapBaseHandlerWorker(object): - def __init__(self, container): - self.container = container - - def setup(self): pass - - def finish(self): pass - - def execute(self, data): - raise NotImplementedError - -class smmapBaseHandlerContainer(object): - def __init__(self, cfg): - self.config = cfg - workerClassName = cfg.get('WorkerClass') - workerModuleName = cfg.get('WorkerModule') - if workerModuleName == None: - workerModuleName = workerClassName - m = __import__(workerModuleName) - self.workerClass = eval("m.%s" % workerClassName) - - def setup(self): pass - - def finish(self): pass - - def getWorker(self): - worker = self.workerClass(self) - worker.setup() - return worker - - - - - diff --git a/smmapd_prototype/VerifierHandler.py b/smmapd_prototype/VerifierHandler.py deleted file mode 100644 index 34412e0..0000000 --- a/smmapd_prototype/VerifierHandler.py +++ /dev/null @@ -1,240 +0,0 @@ -import threading -import socket -import Queue -import re -import time - -#import timeoutsocket -import DNS - -from Logging import * - -from Cache import Cache - -from SendmailSocketMapHandler import smmapBaseHandlerWorker -from SendmailSocketMapHandler import smmapBaseHandlerContainer -from SendmailSocketMapHandler import MyPermanentVerifierException -from SendmailSocketMapHandler import MyTemporaryVerifierException - - - -class VerifierHandlerContainer(smmapBaseHandlerContainer): - def setup(self): - DNS.ParseResolvConf() - if self.config.get('EnableCaching').lower() in ('true', 'yes', '1'): - debug("enabling cache") - self.cache = Cache(int(self.config.get('CacheExpiration'))) - else: - debug("disabling cache") - self.cache = None - - -class VerifierHandlerWorker(smmapBaseHandlerWorker): - OK = "OK" - NOK = "NOK" - TEMPNOK = "TEMPNOK" - - def setup(self): - self.zombies = [] - - class checker(threading.Thread): - def __init__(self, ready, config, host, address): - threading.Thread.__init__(self) - self.ready = ready - self.config = config - self.host = host - self.address = address - - def checkAddressAvailability(self): - try: - debug("Trying " + self.host) - s = MySMTP(self.host, float(self.config.get('SMTPTimeOut'))) - s.helo(self.config.get('SMTPHeloParam')) - s.mail(self.config.get('SMTPCheckSender')) - s.rcpt(self.address.getAddress()) - s.quit() - result = VerifierHandlerWorker.OK - except MySMTPTemporaryException: - result = VerifierHandlerWorker.TEMPNOK - except MySMTPPermanentException: - result = VerifierHandlerWorker.NOK - except socket.timeout: - result = VerifierHandlerWorker.TEMPNOK - except socket.error: - result = VerifierHandlerWorker.TEMPNOK - return result - - def run(self): - self.result = self.checkAddressAvailability() - self.ready.put(self.getName()) - debug("NOTIFIED Host %s, Result %s" % (self.host, self.result)) - - def getResult(self): - return self.result - - def getHost(self): - return self.host - - def getAddress(self): - return self.address - - def checkAvailability(self, mxes, address): - ready = Queue.Queue() - checkerThreads = {} - for m in mxes: - checkerThread = VerifierHandlerWorker.checker(ready, self.container.config, m, address) - checkerThread.start() - checkerThreads[checkerThread.getName()] = checkerThread - - result = VerifierHandlerWorker.TEMPNOK - while 1: - debug("%i threads left" % len(checkerThreads)) - if len(checkerThreads) == 0: - debug("no threads left ...") - break - if result != VerifierHandlerWorker.TEMPNOK: - debug("got a permanent result ...") - break - debug("Waiting for results ...") - name = ready.get() - checkerThread = checkerThreads[name] - checkerThread.join() - tempResult = checkerThread.getResult() - debug("success, result is " + str(tempResult)) - if [VerifierHandlerWorker.OK, VerifierHandlerWorker.NOK].count(tempResult) != 0: - result = tempResult - del checkerThreads[name] - self.zombies.extend(checkerThreads.values()) - return result - - def finish(self): - while 1: - debug("finish: %i zombies left" % len(self.zombies)) - for z in self.zombies: - if not z.isAlive(): - debug("finish: thread %s for %s, %s terminated" % (z.getName(), z.getHost(), z.getAddress().getAddress())) - self.zombies.remove(z) - for z in self.zombies: - debug("finish: left over %s for %s, %s" % (z.getName(), z.getHost(), z.getAddress().getAddress())) - if len(self.zombies) == 0: - debug("finish: no zombie left ...") - break - debug("finish: WAITING") - time.sleep(5) - debug("finish: CONTINUE") - debug("finish: all threads terminated") - - - def execute(self, address): - debug("address " + address) - - address = EMailAddress(address) - - bestmxes = address.getBestMX() - if not bestmxes: - return " " - - if self.container.cache == None: - debug("no caching") - result = self.checkAvailability(bestmxes, address) - else: - result = self.container.cache.get(address.getAddress()) - if result == None: - debug("not found in cache") - result = self.checkAvailability(bestmxes, address) - if result != VerifierHandlerWorker.TEMPNOK: - self.container.cache.put(address.getAddress(), result) - else: - debug("found in cache") - - if result == VerifierHandlerWorker.OK: - return "" - elif result == VerifierHandlerWorker.NOK: - return " " - else: - raise MyTemporaryVerifierException, "no mx reachable" - - -class MySMTPPermanentException(ValueError): pass - -class MySMTPTemporaryException(ValueError): pass - -class MySMTP(object): - def __init__(self, host, timeout, port=25): - self.host = host - self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - self.socket.settimeout(timeout) - self.socket.connect((host, port)) - self.socket.recv(8192) - self.resPattern = re.compile(r'[\w\W]*?^(\d{3,3}) (.*?)[\r\n]{1,2}$', re.MULTILINE) - - def checkResult(self, r): - code, text = r - code = code / 100 - - if code == 2: - return; - elif code == 4: - raise MySMTPTemporaryException, text - elif code == 5: - raise MySMTPPermanentException, text - else: - raise MySMTPPermanentException, "unknown code: " + str(code) + ", text: " + str(text) - - def docmd(self, cmd): - debug("docmd: %s, cmd: %s " % (self.host, cmd)) - self.socket.sendall(cmd + "\r\n") - res = self.socket.recv(8192) - debug("docmd: result: (%s)" % res) - m = self.resPattern.match(res) - return self.checkResult((int(m.group(1)), m.group(2))) - - def helo(self, param): - return self.docmd("helo " + param) - - def mail(self, sender): - if sender[0] != '<' and sender[-1] != '>': sender = '<' + sender + '>' - return self.docmd("mail from:" + sender) - - def rcpt(self, recipient): - return self.docmd("rcpt to:<%s>" % recipient) - - def quit(self): - self.docmd("quit") - self.socket.close() - - -class EMailAddress(object): - def __init__(self, address): - self.address = address - if self.address[0] == '<' and self.address[-1] == '>': self.address = self.address[1:-1] - try: - self.userpart, self.domain = self.address.split('@') - except ValueError: - raise MyPermanentVerifierException, "excepted email address, found not at-sign" - - def getUserPart(self): - return self.userpart - - def getDomain(self): - return self.domain - - def getAddress(self): - return self.address - - def getBestMX(self): - if self.domain[0] == '[' and self.domain[-1] == ']': - bestmx2 = [self.domain[1:-1]] - else: - bestmx = DNS.mxlookup(self.domain) - pref = None - bestmx2 = [] - for mx in bestmx: - if pref == None: pref = mx[0] - if pref == mx[0]: - bestmx2.append(mx[1]) - else: - break - debug("bestmx " + str(bestmx2)) - return bestmx2 - diff --git a/smmapd_prototype/index.html b/smmapd_prototype/index.html deleted file mode 100644 index 4805fe1..0000000 --- a/smmapd_prototype/index.html +++ /dev/null @@ -1,327 +0,0 @@ - - - - Sender Address Verifier for Sendmail - - - - - - -

Sender Address Verifier for Sendmail

- -

-Author: Wolfgang Hottgenroth <woho@hottis.de>, 2004-05-17 - -

- -

-This is the prototype of a sender address verifier for sendmail-8.13. - -

- -

-It consists of a m4 file containing a FEATURE to be included in your -sendmail.mc and a verifier daemon in a bit of python code. - -

- -

-By including the FEATURE in your sendmail.mc file and running the -verifier daemon, sendmail file verify either - -

- -
    -
  • all sender addresses (with certain exceptions) or -
  • -
  • only certain sender addresses -
  • -
- -

-This will be done by connecting to the best MX servers of the -particular domain, trying to send a mail to the particular address and -collect the replies. - -

- -

-Actually only the HELO, MAIL and RCPT commands are issued. - -

- -

-If a positive reply was found, the mail is considered as valid. - -

- -

-If a permanent negative reply was found, the mail is considered as -invalid. - -

- -

-If no MX entry was found, the mail is considered as invalid. - -

- -

-If a temporary negative reply was found, the mail is considered as -temporary invalid. - -

- -

-If there is more than one best MX server all of these servers are -connected in parallel and the first permanent reply (either positive -or negative) is returned. - -

- -

Download

- -

-The complete sources: download - -

- -

-Have a look into the sources: sources - -

- -

Requirements

- -

sendmail

- -

-sendmail-8.13 is required, since this thing uses the fresh introduced -socket map. - -

- -

-Find it here on the sendmail homepage. - -

- -

-Your need to build sendmail with support for the socket map. Include - -

- -
-APPENDDEF(`confMAPDEF',`-DSOCKETMAP')
-
- -

-in your site.config.m4. - -

- -

Python

- -

-Python 2.2 or 2.3 is required. If you have Python 2.3 you must delete -the import timeoutsocket line from verifier.py. - -

- -

-Additionally the python package python-dns is required. Find it -http://pydns.sourceforge.net. - -

- -

Configuration of sendmail

- -

-Include the FEATURE in your sendmail.mc file. You need to give two -parameters: - -

- -
-FEATURE(`verifysender', `mode', `return')
-
- -

-For mode you must give either white or black. - -

- -
-
white
-
-All sender addresses but those mentioned in the whitelist -file are verified. Complete addresses or just domains can be listed in -the file. The default location of the whitelist is -/etc/mail/verify-white-list. If you need a different location, -define it to confVERIFIER_WHITELIST. -
-
black
-
-only addresses or addresses within domains listed in the -blacklist file are verified. It is obviously only useful to mention -domains in the blacklist. The default location of the blacklist is -/etc/mail/verify-black-list. If you need a different location, -define it to confVERIFIER_BLACKLIST. -
-
- -

-Both the blacklist and the whitelist file are maps, they must be -created with makemap. Therefore the entries need a LHS (the address -or domain) and a RHS. The actual content of the RHS has NO meaning at -all. - -

- -

-The FEATURE defines a socket map. The default target of the map is -inet:8884@127.0.0.1, according to the default setting in -Config.py. If you need something different, define it to -confVERIFIER_MAP, but don't forget to also adjust Config.py. - -

- -

Configuration of the verification daemon

- -

-The configuration of the daemon is done in the file Config.py. - -

- -

-This is the default of this file: - -

- -
-[Daemon]
-Address: 127.0.0.1
-Port: 8884
-PidFile: smmapd.pid
-Plugins: Verifier,Verifier2
-
-[Logging]
-ApplId: smmapd
-
-[Verifier]
-ContainerModule: VerifierHandler
-ContainerClass: VerifierHandlerContainer
-WorkerModule: VerifierHandler
-WorkerClass: VerifierHandlerWorker
-EnableCaching: 1
-CacheExpiration: 20
-SMTPTimeOut: 20
-SMTPHeloParam: local
-SMTPCheckSender: <>
-
-[Verifier2]
-ContainerModule: VerifierHandler
-ContainerClass: VerifierHandlerContainer
-WorkerModule: VerifierHandler
-WorkerClass: VerifierHandlerWorker
-EnableCaching: 1
-CacheExpiration: 20
-SMTPTimeOut: 20
-SMTPHeloParam: hottis.de
-SMTPCheckSender: <postmaster@hottis.de>
- -

-Port and Address are specifying the socket the daemon should -listen to for communication with sendmail. These settings must be -reflected in the confVERIFIER_MAP if you change it. - -

- -

-SMTPTimeOut is the timeout for the communication with the MX servers -when verifying addresses. - -

- -

-SMTPHeloParam is the parameter the verifier will use with the HELO -command when verifying. - -

- -

-SMTPCheckSender is the sender address used during -verifications. You should not change it unless you know what you do to -avoid verification loops. - -

- -

-Since the verification is a time and resource consuming process, -results can be cached, which is enabled by default. Set -EnableCaching to 0 to disable it. - -

- -

-CacheExpiration is the time in seconds an entry in the cache is -considered as valid. It should be much higher. - -

- -

Operation

- -

-Configure sendmail and the daemon according to your needs. Start the -daemon: - -

- -
-./verifier.py
-
- -

Changes

- -
    -
  • According to a comment in comp.mail.sendmail I've introduced a class - verifier_fix_white in the FEATURE file, currently containing only - the string postmaster. Addresses with userpart in this class will - never ever be verified to avoid infinite verifying loops. -
  • -
- -

2004-05-17

- -
    -
  • support plugins -
  • -
  • separate container and worker object, thereby enable multiple - instances of the same plugins -
  • -
- - - - - - diff --git a/smmapd_prototype/index.wiki b/smmapd_prototype/index.wiki deleted file mode 100644 index af833d2..0000000 --- a/smmapd_prototype/index.wiki +++ /dev/null @@ -1,195 +0,0 @@ -#title Sender Address Verifier for Sendmail -#style /web/default.css - - -Author: Wolfgang Hottgenroth , 2004-05-17 - - - - -This is the prototype of a sender address verifier for sendmail-8.13. - -It consists of a m4 file containing a FEATURE to be included in your -=sendmail.mc= and a verifier daemon in a bit of python code. - - -By including the FEATURE in your sendmail.mc file and running the -verifier daemon, sendmail file verify either - -- all sender addresses (with certain exceptions) or -- only certain sender addresses - -This will be done by connecting to the best MX servers of the -particular domain, trying to send a mail to the particular address and -collect the replies. - -Actually only the =HELO=, =MAIL= and =RCPT= commands are issued. - -If a positive reply was found, the mail is considered as valid. - -If a permanent negative reply was found, the mail is considered as -invalid. - -If no MX entry was found, the mail is considered as invalid. - -If a temporary negative reply was found, the mail is considered as -temporary invalid. - -If there is more than one best MX server all of these servers are -connected in parallel and the first permanent reply (either positive -or negative) is returned. - - -** Download - -The complete sources: [[./download/][download]] - -Have a look into the sources: [[http://www.hottis.de/cgi-bin/cvsweb.cgi/sender_verifier/][sources]] - - - - -** Requirements - -*** sendmail - -sendmail-8.13 is required, since this thing uses the fresh introduced -socket map. - -Find it [[http://www.sendmail.org][here]] on the sendmail homepage. - -Your need to build sendmail with support for the socket map. Include - - -APPENDDEF(`confMAPDEF',`-DSOCKETMAP') - - -in your =site.config.m4=. - - -*** Python - -Python 2.2 or 2.3 is required. If you have Python 2.3 you must delete -the =import timeoutsocket= line from =verifier.py=. - -Additionally the python package =python-dns= is required. Find it -[[http://pydns.sourceforge.net/][http://pydns.sourceforge.net]]. - - - -** Configuration of sendmail - -Include the FEATURE in your =sendmail.mc= file. You need to give two -parameters: - - -FEATURE(`verifysender', `mode', `return') - - -For =mode= you must give either =white= or =black=. - -=white= :: All sender addresses but those mentioned in the whitelist -file are verified. Complete addresses or just domains can be listed in -the file. The default location of the whitelist is -=/etc/mail/verify-white-list=. If you need a different location, -define it to =confVERIFIER_WHITELIST=. - -=black= :: only addresses or addresses within domains listed in the -blacklist file are verified. It is obviously only useful to mention -domains in the blacklist. The default location of the blacklist is -=/etc/mail/verify-black-list=. If you need a different location, -define it to =confVERIFIER_BLACKLIST=. - -Both the blacklist and the whitelist file are maps, they must be -created with =makemap=. Therefore the entries need a LHS (the address -or domain) and a RHS. The actual content of the RHS has NO meaning at -all. - -The FEATURE defines a socket map. The default target of the map is -=inet:8884@127.0.0.1=, according to the default setting in -=Config.py=. If you need something different, define it to -=confVERIFIER_MAP=, but don't forget to also adjust =Config.py=. - - -** Configuration of the verification daemon - -The configuration of the daemon is done in the file =Config.py=. - -This is the default of this file: - - -[Daemon] -Address: 127.0.0.1 -Port: 8884 -PidFile: smmapd.pid -Plugins: Verifier,Verifier2 - -[Logging] -ApplId: smmapd - -[Verifier] -ContainerModule: VerifierHandler -ContainerClass: VerifierHandlerContainer -WorkerModule: VerifierHandler -WorkerClass: VerifierHandlerWorker -EnableCaching: 1 -CacheExpiration: 20 -SMTPTimeOut: 20 -SMTPHeloParam: local -SMTPCheckSender: <> - -[Verifier2] -ContainerModule: VerifierHandler -ContainerClass: VerifierHandlerContainer -WorkerModule: VerifierHandler -WorkerClass: VerifierHandlerWorker -EnableCaching: 1 -CacheExpiration: 20 -SMTPTimeOut: 20 -SMTPHeloParam: hottis.de -SMTPCheckSender: - -=Port= and =Address= are specifying the socket the daemon should -listen to for communication with sendmail. These settings must be -reflected in the =confVERIFIER_MAP= if you change it. - -=SMTPTimeOut= is the timeout for the communication with the MX servers -when verifying addresses. - -=SMTPHeloParam= is the parameter the verifier will use with the =HELO= -command when verifying. - -=SMTPCheckSender= is the sender address used during -verifications. You should not change it unless you know what you do to -avoid verification loops. - -Since the verification is a time and resource consuming process, -results can be cached, which is enabled by default. Set -=EnableCaching= to 0 to disable it. - -=CacheExpiration= is the time in seconds an entry in the cache is -considered as valid. It should be much higher. - - -** Operation - -Configure sendmail and the daemon according to your needs. Start the -daemon: - - -./verifier.py - - - -** Changes - -- According to a comment in comp.mail.sendmail I've introduced a class - =verifier_fix_white= in the FEATURE file, currently containing only - the string =postmaster=. Addresses with userpart in this class will - never ever be verified to avoid infinite verifying loops. - -*** 2004-05-17 -- support plugins -- separate container and worker object, thereby enable multiple - instances of the same plugins - diff --git a/smmapd_prototype/setup.py b/smmapd_prototype/setup.py deleted file mode 100644 index 67934a4..0000000 --- a/smmapd_prototype/setup.py +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/env python - -from distutils.core import setup - -setup(name="smmapd", - version="0.1", - description="Framework for sendmail SocketMap handlers", - long_description = """ -A framework to build handlers for the sendmail 8.13 SocketMap, -together with an implementation of a sender-address verifier, -together we a sendmail m4 feature file""", - author="Wolfgang Hottgenroth", - author_email="woho@hottis.de", - url="http://www.hottis.de/web/verifier/index.html", - py_modules = [ 'SendmailSocketMapHandler', 'Cache', 'Logging', 'VerifierHandler' ], - scripts = [ 'smmapd' ], - data_files = [('config', ['smmapd.ini']), - ('cf/feature', ['verifysender.m4'])] - ) diff --git a/smmapd_prototype/smmapd b/smmapd_prototype/smmapd deleted file mode 100755 index 0f6764d..0000000 --- a/smmapd_prototype/smmapd +++ /dev/null @@ -1,65 +0,0 @@ -#!/usr/bin/python - -import SocketServer -import socket -import os -import ConfigParser -import getopt -import sys - -from Logging import * -from SendmailSocketMapHandler import SendmailDispatcher - - -def usage(): - print "Usage" - - -try: - opts, args = getopt.getopt(sys.argv[1:], "hC:F", ["help", "ConfigFile=", "ForeGround"]) -except getopt.GetoptError: - usage() - sys.exit(2) - -configFile = '/etc/smmapd.ini' -foreGround = None -for o, a in opts: - if o in ("-h", "--help"): - usage() - sys.exit() - if o in ("-C", "--ConfigFile"): - configFile = a - if o in ("-F", "--ForeGround"): - foreGround = 1 - - - -config = ConfigParser.ConfigParser() -config.read(configFile) - -openlog(config) - -if foreGround: - pid = 0 -else: - pid = os.fork() - -if pid: - pidFile = file(config.get('Daemon', 'PidFile'), mode='w') - pidFile.write("%i\n" % pid) - pidFile.close() - print "daemon started with pid ", pid -else: - log("daemon started") - - SendmailDispatcher.registerAll(config) - - try: - address = config.get('Daemon', 'Address') - port = int(config.get('Daemon', 'Port')) - srv = SocketServer.ThreadingTCPServer((address, port), SendmailDispatcher) - srv.serve_forever() - except socket.error, arg: - log("got a socket error: %s" % str(arg)) - log("daemon died") - diff --git a/smmapd_prototype/smmapd.ini b/smmapd_prototype/smmapd.ini deleted file mode 100644 index 10af9d1..0000000 --- a/smmapd_prototype/smmapd.ini +++ /dev/null @@ -1,37 +0,0 @@ -[Daemon] -Address: 127.0.0.1 -Port: 8884 -PidFile: smmapd.pid -Plugins: verifier,verifier2,cyrusChecker - -[Logging] -ApplId: smmapd - -[verifier] -ContainerModule: VerifierHandler -ContainerClass: VerifierHandlerContainer -WorkerModule: VerifierHandler -WorkerClass: VerifierHandlerWorker -EnableCaching: yes -CacheExpiration: 20 -SMTPTimeOut: 20 -SMTPHeloParam: local -SMTPCheckSender: <> - -[verifier2] -ContainerModule: VerifierHandler -ContainerClass: VerifierHandlerContainer -WorkerModule: VerifierHandler -WorkerClass: VerifierHandlerWorker -EnableCaching: yes -CacheExpiration: 20 -SMTPTimeOut: 20 -SMTPHeloParam: hottis.de -SMTPCheckSender: - -[cyrusChecker] -ContainerModule: SendmailSocketMapHandler -ContainerClass: smmapBaseHandlerContainer -WorkerModule: CyrusChecker -WorkerClass: CyrusCheckerWorker - diff --git a/smmapd_prototype/timeoutsocket.py b/smmapd_prototype/timeoutsocket.py deleted file mode 100644 index eaaee50..0000000 --- a/smmapd_prototype/timeoutsocket.py +++ /dev/null @@ -1,424 +0,0 @@ - -#### -# Copyright 2000,2001 by Timothy O'Malley -# -# All Rights Reserved -# -# Permission to use, copy, modify, and distribute this software -# and its documentation for any purpose and without fee is hereby -# granted, provided that the above copyright notice appear in all -# copies and that both that copyright notice and this permission -# notice appear in supporting documentation, and that the name of -# Timothy O'Malley not be used in advertising or publicity -# pertaining to distribution of the software without specific, written -# prior permission. -# -# Timothy O'Malley DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS -# SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -# AND FITNESS, IN NO EVENT SHALL Timothy O'Malley BE LIABLE FOR -# ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS -# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -# PERFORMANCE OF THIS SOFTWARE. -# -#### - -"""Timeout Socket - -This module enables a timeout mechanism on all TCP connections. It -does this by inserting a shim into the socket module. After this module -has been imported, all socket creation goes through this shim. As a -result, every TCP connection will support a timeout. - -The beauty of this method is that it immediately and transparently -enables the entire python library to support timeouts on TCP sockets. -As an example, if you wanted to SMTP connections to have a 20 second -timeout: - - import timeoutsocket - import smtplib - timeoutsocket.setDefaultSocketTimeout(20) - - -The timeout applies to the socket functions that normally block on -execution: read, write, connect, and accept. If any of these -operations exceeds the specified timeout, the exception Timeout -will be raised. - -The default timeout value is set to None. As a result, importing -this module does not change the default behavior of a socket. The -timeout mechanism only activates when the timeout has been set to -a numeric value. (This behavior mimics the behavior of the -select.select() function.) - -This module implements two classes: TimeoutSocket and TimeoutFile. - -The TimeoutSocket class defines a socket-like object that attempts to -avoid the condition where a socket may block indefinitely. The -TimeoutSocket class raises a Timeout exception whenever the -current operation delays too long. - -The TimeoutFile class defines a file-like object that uses the TimeoutSocket -class. When the makefile() method of TimeoutSocket is called, it returns -an instance of a TimeoutFile. - -Each of these objects adds two methods to manage the timeout value: - - get_timeout() --> returns the timeout of the socket or file - set_timeout() --> sets the timeout of the socket or file - - -As an example, one might use the timeout feature to create httplib -connections that will timeout after 30 seconds: - - import timeoutsocket - import httplib - H = httplib.HTTP("www.python.org") - H.sock.set_timeout(30) - -Note: When used in this manner, the connect() routine may still -block because it happens before the timeout is set. To avoid -this, use the 'timeoutsocket.setDefaultSocketTimeout()' function. - -Good Luck! - -""" - -__version__ = "$Revision$" -__author__ = "Timothy O'Malley " - -# -# Imports -# -import select, string -import socket -if not hasattr(socket, "_no_timeoutsocket"): - _socket = socket.socket -else: - _socket = socket._no_timeoutsocket - - -# -# Set up constants to test for Connected and Blocking operations. -# We delete 'os' and 'errno' to keep our namespace clean(er). -# Thanks to Alex Martelli and G. Li for the Windows error codes. -# -import os -if os.name == "nt": - _IsConnected = ( 10022, 10056 ) - _ConnectBusy = ( 10035, ) - _AcceptBusy = ( 10035, ) -else: - import errno - _IsConnected = ( errno.EISCONN, ) - _ConnectBusy = ( errno.EINPROGRESS, errno.EALREADY, errno.EWOULDBLOCK ) - _AcceptBusy = ( errno.EAGAIN, errno.EWOULDBLOCK ) - del errno -del os - - -# -# Default timeout value for ALL TimeoutSockets -# -_DefaultTimeout = None -def setDefaultSocketTimeout(timeout): - global _DefaultTimeout - _DefaultTimeout = timeout -def getDefaultSocketTimeout(): - return _DefaultTimeout - -# -# Exceptions for socket errors and timeouts -# -Error = socket.error -class Timeout(Exception): - pass - - -# -# Factory function -# -from socket import AF_INET, SOCK_STREAM -def timeoutsocket(family=AF_INET, type=SOCK_STREAM, proto=None): - if family != AF_INET or type != SOCK_STREAM: - if proto: - return _socket(family, type, proto) - else: - return _socket(family, type) - return TimeoutSocket( _socket(family, type), _DefaultTimeout ) -# end timeoutsocket - -# -# The TimeoutSocket class definition -# -class TimeoutSocket: - """TimeoutSocket object - Implements a socket-like object that raises Timeout whenever - an operation takes too long. - The definition of 'too long' can be changed using the - set_timeout() method. - """ - - _copies = 0 - _blocking = 1 - - def __init__(self, sock, timeout): - self._sock = sock - self._timeout = timeout - # end __init__ - - def __getattr__(self, key): - return getattr(self._sock, key) - # end __getattr__ - - def get_timeout(self): - return self._timeout - # end set_timeout - - def set_timeout(self, timeout=None): - self._timeout = timeout - # end set_timeout - - def setblocking(self, blocking): - self._blocking = blocking - return self._sock.setblocking(blocking) - # end set_timeout - - def connect_ex(self, addr): - errcode = 0 - try: - self.connect(addr) - except Error, why: - errcode = why[0] - return errcode - # end connect_ex - - def connect(self, addr, port=None, dumbhack=None): - # In case we were called as connect(host, port) - if port != None: addr = (addr, port) - - # Shortcuts - sock = self._sock - timeout = self._timeout - blocking = self._blocking - - # First, make a non-blocking call to connect - try: - sock.setblocking(0) - sock.connect(addr) - sock.setblocking(blocking) - return - except Error, why: - # Set the socket's blocking mode back - sock.setblocking(blocking) - - # If we are not blocking, re-raise - if not blocking: - raise - - # If we are already connected, then return success. - # If we got a genuine error, re-raise it. - errcode = why[0] - if dumbhack and errcode in _IsConnected: - return - elif errcode not in _ConnectBusy: - raise - - # Now, wait for the connect to happen - # ONLY if dumbhack indicates this is pass number one. - # If select raises an error, we pass it on. - # Is this the right behavior? - if not dumbhack: - r,w,e = select.select([], [sock], [], timeout) - if w: - return self.connect(addr, dumbhack=1) - - # If we get here, then we should raise Timeout - raise Timeout("Attempted connect to %s timed out." % str(addr) ) - # end connect - - def accept(self, dumbhack=None): - # Shortcuts - sock = self._sock - timeout = self._timeout - blocking = self._blocking - - # First, make a non-blocking call to accept - # If we get a valid result, then convert the - # accept'ed socket into a TimeoutSocket. - # Be carefult about the blocking mode of ourselves. - try: - sock.setblocking(0) - newsock, addr = sock.accept() - sock.setblocking(blocking) - timeoutnewsock = self.__class__(newsock, timeout) - timeoutnewsock.setblocking(blocking) - return (timeoutnewsock, addr) - except Error, why: - # Set the socket's blocking mode back - sock.setblocking(blocking) - - # If we are not supposed to block, then re-raise - if not blocking: - raise - - # If we got a genuine error, re-raise it. - errcode = why[0] - if errcode not in _AcceptBusy: - raise - - # Now, wait for the accept to happen - # ONLY if dumbhack indicates this is pass number one. - # If select raises an error, we pass it on. - # Is this the right behavior? - if not dumbhack: - r,w,e = select.select([sock], [], [], timeout) - if r: - return self.accept(dumbhack=1) - - # If we get here, then we should raise Timeout - raise Timeout("Attempted accept timed out.") - # end accept - - def send(self, data, flags=0): - sock = self._sock - if self._blocking: - r,w,e = select.select([],[sock],[], self._timeout) - if not w: - raise Timeout("Send timed out") - return sock.send(data, flags) - # end send - - def recv(self, bufsize, flags=0): - sock = self._sock - if self._blocking: - r,w,e = select.select([sock], [], [], self._timeout) - if not r: - raise Timeout("Recv timed out") - return sock.recv(bufsize, flags) - # end recv - - def makefile(self, flags="r", bufsize=-1): - self._copies = self._copies +1 - return TimeoutFile(self, flags, bufsize) - # end makefile - - def close(self): - if self._copies <= 0: - self._sock.close() - else: - self._copies = self._copies -1 - # end close - -# end TimeoutSocket - - -class TimeoutFile: - """TimeoutFile object - Implements a file-like object on top of TimeoutSocket. - """ - - def __init__(self, sock, mode="r", bufsize=4096): - self._sock = sock - self._bufsize = 4096 - if bufsize > 0: self._bufsize = bufsize - if not hasattr(sock, "_inqueue"): self._sock._inqueue = "" - - # end __init__ - - def __getattr__(self, key): - return getattr(self._sock, key) - # end __getattr__ - - def close(self): - self._sock.close() - self._sock = None - # end close - - def write(self, data): - self.send(data) - # end write - - def read(self, size=-1): - _sock = self._sock - _bufsize = self._bufsize - while 1: - datalen = len(_sock._inqueue) - if datalen >= size >= 0: - break - bufsize = _bufsize - if size > 0: - bufsize = min(bufsize, size - datalen ) - buf = self.recv(bufsize) - if not buf: - break - _sock._inqueue = _sock._inqueue + buf - data = _sock._inqueue - _sock._inqueue = "" - if size > 0 and datalen > size: - _sock._inqueue = data[size:] - data = data[:size] - return data - # end read - - def readline(self, size=-1): - _sock = self._sock - _bufsize = self._bufsize - while 1: - idx = string.find(_sock._inqueue, "\n") - if idx >= 0: - break - datalen = len(_sock._inqueue) - if datalen >= size >= 0: - break - bufsize = _bufsize - if size > 0: - bufsize = min(bufsize, size - datalen ) - buf = self.recv(bufsize) - if not buf: - break - _sock._inqueue = _sock._inqueue + buf - - data = _sock._inqueue - _sock._inqueue = "" - if idx >= 0: - idx = idx + 1 - _sock._inqueue = data[idx:] - data = data[:idx] - elif size > 0 and datalen > size: - _sock._inqueue = data[size:] - data = data[:size] - return data - # end readline - - def readlines(self, sizehint=-1): - result = [] - data = self.read() - while data: - idx = string.find(data, "\n") - if idx >= 0: - idx = idx + 1 - result.append( data[:idx] ) - data = data[idx:] - else: - result.append( data ) - data = "" - return result - # end readlines - - def flush(self): pass - -# end TimeoutFile - - -# -# Silently replace the socket() builtin function with -# our timeoutsocket() definition. -# -if not hasattr(socket, "_no_timeoutsocket"): - socket._no_timeoutsocket = socket.socket - socket.socket = timeoutsocket -del socket -socket = timeoutsocket -# Finis diff --git a/smmapd_prototype/verifysender.m4 b/smmapd_prototype/verifysender.m4 deleted file mode 100644 index 47ad0c6..0000000 --- a/smmapd_prototype/verifysender.m4 +++ /dev/null @@ -1,110 +0,0 @@ -VERSIONID(`$Id$') - - - -divert(-1) - -define(`_USAGE_', `dnl -errprint(`*** ERROR: missing argument for FEATURE(verifysender): -Usage: FEATURE(`verifysender', `_mode_', `_return_') - _mode_: black or white - _return_: temp or perm - found: $1 -')') - -ifelse(_ARG_, `black', `', ` -ifelse(_ARG_, `white', `', ` -_USAGE_(`_mode_: ('_ARG_`) -') -')') - -ifelse(_ARG2_, `temp', `', ` -ifelse(_ARG2_, `perm', `', ` -_USAGE_(`_return_: ('_ARG2_`) -') -')') - -define(`_mode_', _ARG_) -define(`_return_', _ARG2_) - -errprint(`*** _mode_: '_mode_` -') -errprint(`*** _return_: '_return_` -') - - -define(`_T_DSN_', `4.1.0') -define(`_T_REPLY', `451') -ifelse(_return_, `temp', ` -define(`_DSN_', _T_DSN_) -define(`_REPLY_', _T_REPLY)', `dnl -define(`_DSN_', `5.1.0') -define(`_REPLY_', `550')') - -ifelse(defn(`confVERIFIER_MAP'), `', ` -define(`_VERIFIER_MAP_', `inet:8884@127.0.0.1')', ` -define(`_VERIFIER_MAP_', confVERIFIER_MAP)') - -ifelse(defn(`confVERIFIER_BLACKLIST'), `', ` -define(`_VERIFIER_BLACKLIST_', `/etc/mail/verifier-black-list')', ` -define(`_VERIFIER_BLACKLIST_', confVERIFIER_BLACKLIST)') - -ifelse(defn(`confVERIFIER_WHITELIST'), `', ` -define(`_VERIFIER_WHITELIST_', `/etc/mail/verifier-white-list')', ` -define(`_VERIFIER_WHITELIST_', confVERIFIER_WHITELIST)') - -divert(0) - -LOCAL_CONFIG -# Adjust the port -Kverifier socket -T _VERIFIER_MAP_ -ifelse(_mode_, `white', `dnl -Kverifier_helper hash -o _VERIFIER_WHITELIST_', `dnl -Kverifier_helper hash _VERIFIER_BLACKLIST_') -C{verifier_fix_white} postmaster - -LOCAL_RULESETS -# This ruleset can be used to test the verifier in -bt mode -Svt -R$+ $: < $(verifier $1 $:none $) > - -Sverifier0 -R< $={verifier_fix_white} @ $+ > $@ < ok > -R< $+ @ $+ > $: < $2 > < $(verifier_helper $1 @ $2 $: $) > -R< $+ > < > $: < $(verifier_helper $1 $: $) > -ifelse(_mode_, `white', `dnl -dnl if we found nothing in the whitelist, we continue with checking -R< > $@ < cont > -dnl if we found something in the whitelist, we skip further verifications -R< $+ > $@ < ok >', `dnl -dnl if we found nothing in the blacklist, we skip further verifications -R< > $@ < ok > -dnl if we found something in the blacklist, we continue with checking -R< $+ > $@ < cont >') - -Sverifier1 -R< $+ > $: < $(verifier $1 $:none $) > -R< $* < temp > > $#error $@ _T_DSN_ $: "_T_REPLY_ Sender Address could currently not be verified (1)" -R< none > $#error $@ _T_DSN_ $: "_T_REPLY_ Sender Address could currently not be verified (2)" -R< $* > $@ < ok > -R< < $* > > $#error $@ _DSN_ $: "_REPLY_ Sender Address was verified as bad: " $1 -R< < $* > > $#error $@ _T_DSN_ $: "_T_REPLY_ Sender Address could currently not be verified (3): " $1 -dnl if we get here, some is wrong with our code -R$* $#error $@ 4.7.1 $: "451 Local configuration error " - - -SLocal_check_mail -dnl MAILER-DAEMON address must not be verified -R<> $@ <> -dnl try to focus -R$+ $: <> $>3 $1 -R<> $+ < @ $+ . > $: < $1 @ $2 > -R<> $+ < @ $+ > $: < $1 @ $2 > -dnl if unable to focus, rest of check_mail should take care (may be we should reject) -R<> $* $@ OK -R< $+ @ $+ > $: < $1 @ $2 > $>verifier0 < $1 @ $2 > -R< $+ @ $+ > < cont > $: < $1 @ $2 > $>verifier1 < $1 @ $2 > -R< $+ @ $+ > $# $* $# $3 -R< $+ @ $+ > < ok > $@ OK -dnl if we get here, some is wrong with our code -R$* $#error $@ 4.7.1 $: "451 Local configuration error "