def __init__ (self, msg, mode): global rules, rlock self.msg = msg self.mode = mode self.parm = {} if not self.msg.has_key (BAV.x_agn): if self.msg.has_key ('return-path'): rp = self.msg['return-path'].strip () if rp[0] == '<' and rp[-1] == '>': addr = rp[1:-1].lower () try: fd = open (BAV.configFile) for line in [l for l in fd if len (l) > 0 and l[0] != '#']: parts = line.split (None, 1) if parts[0].lower () == addr: data = agn.chop (parts[1]) if data[:7] == 'accept:': self.msg[BAV.x_agn] = data[7:] break fd.close () except IOError, e: agn.log (agn.LV_WARNING, 'bav', 'Cannot read file %s %s' % (BAV.configFile, `e.args`)) else: agn.log (agn.LV_WARNING, 'bav', 'No %s header, neither Return-Path: found' % BAV.x_agn)
def __init__(self, msg, mode): global rules, rlock self.msg = msg self.mode = mode self.parm = {} if not self.msg.has_key(BAV.x_agn): if self.msg.has_key('return-path'): rp = self.msg['return-path'].strip() if rp[0] == '<' and rp[-1] == '>': addr = rp[1:-1].lower() try: fd = open(BAV.configFile) for line in [ l for l in fd if len(l) > 0 and l[0] != '#' ]: parts = line.split(None, 1) if parts[0].lower() == addr: data = agn.chop(parts[1]) if data[:7] == 'accept:': self.msg[BAV.x_agn] = data[7:] break fd.close() except IOError, e: agn.log( agn.LV_WARNING, 'bav', 'Cannot read file %s %s' % (BAV.configFile, ` e.args `)) else: agn.log(agn.LV_WARNING, 'bav', 'No %s header, neither Return-Path: found' % BAV.x_agn)
class Rule: lifetime = 180 rulePattern = agn.base + os.sep + 'conf' + os.sep + 'bav' + os.sep + 'bav_%s.rule' ruleFile = agn.base + os.sep + 'conf' + os.sep + 'bav' + os.sep + 'bav.rule' DSNRE = (re.compile('[45][0-9][0-9] +([0-9]\\.[0-9]\\.[0-9]) +(.*)'), re.compile('\\(#([0-9]\\.[0-9]\\.[0-9])\\)'), re.compile('^([0-9]\\.[0-9]\\.[0-9])')) NMidRE = re.compile( '<([0-9]{14}-[0-9]+\\.[0-9a-z]+\\.[0-9a-z]+\\.[0-9a-z]+\\.[0-9a-z]+\\.[0-9a-z]+)@' ) def __init__(self, rid, now): self.rid = rid self.created = now self.sections = {} self.passwords = {} for fname in [Rule.rulePattern % rid, Rule.ruleFile]: try: fd = open(fname, 'r') agn.log(agn.LV_DEBUG, 'rule', 'Reading rules from %s' % fname) except IOError, e: agn.log(agn.LV_VERBOSE, 'rule', 'Unable to open %s %s' % (fname, ` e.args `)) fd = None if fd: break if fd: cur = None for line in [ agn.chop(l) for l in fd if len(l) > 0 and not l[0] in '\n#' ]: if line[0] == '[' and line[-1] == ']': name = line[1:-1] if self.sections.has_key(name): cur = self.sections[name] else: cur = Section(name) self.sections[name] = cur elif cur: cur.append(line)
def createMessage (self, orig, parm): global alock fname = Autoresponder.msgPattern % self.aid if not os.access (fname, os.R_OK): agn.log (agn.LV_WARNING, 'ar', 'No autoresponder mail %s for enabled autoresponder %s found' % (fname, self.aid)) return None mayReceive = False for arwlist in [Autoresponder.wlPattern % self.aid, Autoresponder.wlFile]: try: fd = open (arwlist) for line in [agn.chop (l) for l in fd.readlines () if not l[0] in '\n#']: if line == self.sender: mayReceive = True agn.log (agn.LV_VERBOSE, 'ar', 'Sender %s is on whitelist file %s' % (self.sender, arwlist)) break fd.close () except IOError: pass if mayReceive: break if gdbm is None: mayReceive = True if not mayReceive: hasLock = False retry = 5 while retry >= 0: if alock.testandset (): hasLock = True break time.sleep (1) retry -= 1 if hasLock: try: arlimit = Autoresponder.limitPattern % self.aid now = time.time () dbf = gdbm.open (arlimit, 'c') if not dbf.has_key (self.sender): agn.log (agn.LV_DEBUG, 'ar', 'Never sent mail to %s from this autoresponder %s' % (self.sender, self.aid)) mayReceive = True else: try: last = int (dbf[self.sender]) if last + 24 * 60 * 60 < now: agn.log (agn.LV_DEBUG, 'ar', 'Last mail to "%s" is older than 24 hours' % self.sender) mayReceive = True else: diff = (now - last) / 60 agn.log (agn.LV_INFO, 'ar', 'Reject mail to "%s", sent already mail in last 24 hours (%d:%02d)' % (self.sender, diff / 60, diff % 60)) except ValueError: pass if mayReceive: dbf[self.sender] = '%d' % now dbf.close () except gdbm.error, e: agn.log (agn.LV_ERROR, 'ar', 'Unable to acess %s %s' % (arlimit, `e.args`)) mayReceive = False alock.unlock () else: agn.log (agn.LV_WARNING, 'ar', 'Unable to get global lock for %s' % self.aid) if not mayReceive: return None
def fileReader(fname): fd = open(fname, 'r') rc = [agn.chop(line) for line in fd.readlines() if not line[0] in '\n#'] fd.close() return rc
tfname = self.renameToTemp() if tfname is None: return False try: fd = open(tfname, 'r') except IOError, e: agn.log(agn.LV_ERROR, 'update', 'Unable to open %s: %s' % (tfname, ` e.args `)) fd = None if fd is None: return False self.lineno = 0 removeTemp = True rc = self.updateStart(inst) for line in [agn.chop(l) for l in fd.readlines()]: self.lineno += 1 if self.lineno % 10000 == 0: agn.log(agn.LV_INFO, 'update', '%s: Now at line %d' % (self.name, self.lineno)) if not self.updateLine(inst, line): if not self.saveToFail(line): removeTemp = False rc = False else: if not self.saveToLog(line): removeTemp = False if not self.updateEnd(inst): rc = False fd.close() if removeTemp:
def do_GET(self): path = self.path agn.log(agn.LV_VERBOSE, 'get', 'Got path: ' + path) n = path.find('?') if n != -1: path = path[:n] self.out('HTTP/1.0 200 OK\r\n') self.out('Content-Type: text/plain\r\n') self.out('\r\n') if path == '/ping': self.ok('pong') elif path == '/reread': updateLog = agn.base + os.sep + 'var' + os.sep + 'run' + os.sep + 'bav-update.log' size = -1 try: st = os.stat(updateLog) size = st[stat.ST_SIZE] except OSError, e: agn.log(agn.LV_INFO, 'get', 'Failed to stat %s %s' % (updateLog, ` e.args `)) if e.args[0] == errno.ENOENT: self.err('Missing file %s, update daemon not running?' % updateLog) else: self.err('Unable to stat %s %s' % (updateLog, ` e.args `)) if size != -1: (rc, msg) = agn.signallock('bav-update', signal.SIGUSR1) if not rc: agn.log(agn.LV_INFO, 'get', 'Unable to signal bav-update: %s' % msg) self.err( 'Failed to signal update daemon, perhaps its not running?' ) else: n = 10 while n > 0: nsize = -1 try: st = os.stat(updateLog) nsize = st[stat.ST_SIZE] except OSError, e: agn.log( agn.LV_INFO, 'get', 'Unable to restat %s %s' % (updateLog, ` e.args `)) self.err('Unable to stat %s again %s' % (updateLog, ` e.args `)) if nsize > size or nsize == -1: break n -= 1 if n > 0: time.sleep(1) if nsize == size: agn.log(agn.LV_INFO, 'get', 'Update process did not wrote %s' % updateLog) self.err('Update process seems not to respond') else: try: fd = open(updateLog, 'r') fd.seek(size) inp = fd.readline() fd.close() if inp: inp = agn.chop(inp) parts = inp.split(None, 1) if len(parts) == 2: if parts[1] == 'success': agn.log(agn.LV_VERBOSE, 'get', 'Got %s' % inp) self.ok('Update completed') else: agn.log(agn.LV_INFO, 'get', 'Update failed: %s' % inp) self.err('Updated failed: ' + parts[1]) else: agn.log( agn.LV_INFO, 'get', 'Update failed with invalid entry: %s' % inp) self.err('Invalid entry in %s: %s' % (updateLog, inp)) else: agn.log(agn.LV_INFO, 'get', 'Update failed with missing entry') self.err('Missing entry in %s' % updateLog) except IOError, e: agn.log( agn.LV_INFO, 'get', 'Update failed due to unreadable file %s %s' % (updateLog, ` e.args `)) self.err('Unable to read %s %s' % (updateLog, ` e.args `))
def createMessage(self, orig, parm): global alock fname = Autoresponder.msgPattern % self.aid if not os.access(fname, os.R_OK): agn.log( agn.LV_WARNING, 'ar', 'No autoresponder mail %s for enabled autoresponder %s found' % (fname, self.aid)) return None mayReceive = False for arwlist in [ Autoresponder.wlPattern % self.aid, Autoresponder.wlFile ]: try: fd = open(arwlist) for line in [ agn.chop(l) for l in fd.readlines() if not l[0] in '\n#' ]: if line == self.sender: mayReceive = True agn.log( agn.LV_VERBOSE, 'ar', 'Sender %s is on whitelist file %s' % (self.sender, arwlist)) break fd.close() except IOError: pass if mayReceive: break if gdbm is None: mayReceive = True if not mayReceive: hasLock = False retry = 5 while retry >= 0: if alock.testandset(): hasLock = True break time.sleep(1) retry -= 1 if hasLock: try: arlimit = Autoresponder.limitPattern % self.aid now = time.time() dbf = gdbm.open(arlimit, 'c') if not dbf.has_key(self.sender): agn.log( agn.LV_DEBUG, 'ar', 'Never sent mail to %s from this autoresponder %s' % (self.sender, self.aid)) mayReceive = True else: try: last = int(dbf[self.sender]) if last + 24 * 60 * 60 < now: agn.log( agn.LV_DEBUG, 'ar', 'Last mail to "%s" is older than 24 hours' % self.sender) mayReceive = True else: diff = (now - last) / 60 agn.log( agn.LV_INFO, 'ar', 'Reject mail to "%s", sent already mail in last 24 hours (%d:%02d)' % (self.sender, diff / 60, diff % 60)) except ValueError: pass if mayReceive: dbf[self.sender] = '%d' % now dbf.close() except gdbm.error, e: agn.log(agn.LV_ERROR, 'ar', 'Unable to acess %s %s' % (arlimit, ` e.args `)) mayReceive = False alock.unlock() else: agn.log(agn.LV_WARNING, 'ar', 'Unable to get global lock for %s' % self.aid) if not mayReceive: return None
def update (self, inst): tfname = self.renameToTemp () if tfname is None: return False try: fd = open (tfname, 'r') except IOError, e: agn.log (agn.LV_ERROR, 'update', 'Unable to open %s: %s' % (tfname, `e.args`)) fd = None if fd is None: return False self.lineno = 0 removeTemp = True rc = self.updateStart (inst) for line in [agn.chop (l) for l in fd.readlines ()]: self.lineno += 1 if self.lineno % 10000 == 0: agn.log (agn.LV_INFO, 'update', '%s: Now at line %s' % (self.name, agn.numfmt (self.lineno))) if not self.updateLine (inst, line): if not self.saveToFail (line): removeTemp = False rc = False else: if not self.saveToLog (line): removeTemp = False if not self.updateEnd (inst): rc = False fd.close () if removeTemp: self.__removeFile (tfname)
def fileReader (fname): fd = open (fname, 'r') rc = [agn.chop (line) for line in fd.readlines () if not line[0] in '\n#'] fd.close () return rc
def do_GET (self): path = self.path agn.log (agn.LV_VERBOSE, 'get', 'Got path: ' + path) n = path.find ('?') if n != -1: query = path[n + 1:] path = path[:n] else: query = None self.out ('HTTP/1.0 200 OK\r\n') self.out ('Content-Type: text/plain\r\n') self.out ('\r\n') if path == '/ping': self.ok ('pong') elif path == '/reread': updateLog = agn.base + os.sep + 'var' + os.sep + 'run' + os.sep + 'bav-update.log' size = -1 try: st = os.stat (updateLog) size = st[stat.ST_SIZE] except OSError, e: agn.log (agn.LV_INFO, 'get', 'Failed to stat %s %s' % (updateLog, `e.args`)) if e.args[0] == errno.ENOENT: self.err ('Missing file %s, update daemon not running?' % updateLog) else: self.err ('Unable to stat %s %s' % (updateLog, `e.args`)) if size != -1: (rc, msg) = agn.signallock ('bav-update', signal.SIGUSR1) if not rc: agn.log (agn.LV_INFO, 'get', 'Unable to signal bav-update: %s' % msg) self.err ('Failed to signal update daemon, perhaps its not running?') else: n = 10 while n > 0: nsize = -1 try: st = os.stat (updateLog) nsize = st[stat.ST_SIZE] except OSError, e: agn.log (agn.LV_INFO, 'get', 'Unable to restat %s %s' % (updateLog, `e.args`)) self.err ('Unable to stat %s again %s' % (updateLog, `e.args`)) if nsize > size or nsize == -1: break n -= 1 if n > 0: time.sleep (1) if nsize == size: agn.log (agn.LV_INFO, 'get', 'Update process did not wrote %s' % updateLog) self.err ('Update process seems not to respond') else: try: fd = open (updateLog, 'r') fd.seek (size) inp = fd.readline () fd.close () if inp: inp = agn.chop (inp) parts = inp.split (None, 1) if len (parts) == 2: if parts[1] == 'success': agn.log (agn.LV_VERBOSE, 'get', 'Got %s' % inp) self.ok ('Update completed') else: agn.log (agn.LV_INFO, 'get', 'Update failed: %s' % inp) self.err ('Updated failed: ' + parts[1]) else: agn.log (agn.LV_INFO, 'get', 'Update failed with invalid entry: %s' % inp) self.err ('Invalid entry in %s: %s' % (updateLog, inp)) else: agn.log (agn.LV_INFO, 'get', 'Update failed with missing entry') self.err ('Missing entry in %s' % updateLog) except IOError, e: agn.log (agn.LV_INFO, 'get', 'Update failed due to unreadable file %s %s' % (updateLog, `e.args`)) self.err ('Unable to read %s %s' % (updateLog, `e.args`))