#!/usr/bin/python -t import asynchat, asyncore, socket import pwd, os, sys, logging, logging.handlers class HTTPChannel(asynchat.async_chat): def __init__(self, server, sock, addr): asynchat.async_chat.__init__(self, sock) self.server = server self.set_terminator("\r\n\r\n") self.request = None self.data = StringIO.StringIO() self.shutdown = 0 def collect_incoming_data(self, data): self.data.write(data) if self.data.tell() > 16384: self.shutdown = 1 def found_terminator(self): if not self.request: # parse http header self.data.seek(0) self.request = string.split(self.data.readline(), None, 2) if len(self.request) != 3: # badly formed request; just shut down self.shutdown = 1 else: self.server.handle_request(self, self.request[0], self.request[1]) self.close_when_done() else: pass # ignore body data, for now class HTTPProxyServer(asyncore.dispatcher): def __init__(self): asyncore.dispatcher.__init__(self) self.port = 8080 self.create_socket(socket.AF_INET, socket.SOCK_STREAM) self.set_reuse_addr() self.bind(("", 8080)) self.listen(5) def handle_accept(self): conn, addr = self.accept() HTTPChannel(self, conn, addr) def handle_request(self, channel, method, path): rss = self.es.to_rss() channel.push("HTTP/1.0 200 OK\r\nContent-type: text/xml\r\n\r\n") channel.push(rss) if __name__ == "__main__": proxy = HTTPProxyServer() asyncore.loop() sys.exit(0) class SMTPChannel(asynchat.async_chat): def __init__(self, server, sock, addr): asynchat.async_chat.__init__(self, sock) self.server = server self.set_terminator("\n") self.data = "" self.read_data = False self.push("220 Mailserver terrorist.at. Nutzung ohne vorige Erlaubnis verboten!\n") def collect_incoming_data(self, data): if len(self.data) > 0: self.data += "\n" self.data += data self.server.logger.debug("Read: " + data.strip()) if self.data.__len__() > 16384: self.server.logger.error("too much data, shutdown") self.close_when_done() def push(self,data): self.server.logger.debug("Write: " + data) asynchat.async_chat.push(self,data) def handle_close(self): asynchat.async_chat.handle_close(self) if self.read_data and len(self.data) > 10: #QUIT oder "." wurde nicht erkannt mail = email.message_from_string(self.data) key=self.server.maildir.add(mail) self.server.logger.info("New Mail: %s" % key) self.server.maildir.flush() def found_terminator(self): try: if self.read_data: if self.data.endswith("\n.") or self.data.endswith("\n.\r"): self.read_data = False self.push("250 Ok: queued as 12345\n") mail = email.message_from_string(self.data) key=self.server.maildir.add(mail) self.server.logger.info("New Mail: %s" % key) self.server.maildir.flush() self.data = "" else: pass elif self.data.startswith("EHLO") \ or self.data.startswith("HELO"): self.push("250 Mailserver terrorist.at. Nutzung ohne vorige Erlaubnis verboten!\n") self.data = "" elif self.data.startswith("DATA"): self.push("354 End data with .\n") self.read_data = True self.data="" elif self.data.startswith("QUIT"): self.data = "" self.push("221 Bye\n") self.close_when_done() else: self.push("250 OK\n") self.data = "" except Exception,e: self.server.logger.error(str(e)) class SMTPServer(asyncore.dispatcher): def __init__(self): asyncore.dispatcher.__init__(self) self.port = 25 self.create_socket(socket.AF_INET, socket.SOCK_STREAM) self.set_reuse_addr() self.bind(("", self.port)) self.listen(5) self.maildir = mailbox.Maildir("Maildir", create=True) self.logger = logging.getLogger('MyLogger') self.logger.setLevel(logging.DEBUG) handler = logging.handlers.TimedRotatingFileHandler("log/smtp.log", "D", 1) self.logger.addHandler(handler) def handle_accept(self): conn, addr = self.accept() self.logger.info("New Client %s:%s" % conn.getpeername()) try: SMTPChannel(self, conn, addr) except Exception,e: self.logger.error(str(e)) if __name__ == '__main__': s = SMTPServer() #user change pwinfo = pwd.getpwnam('nobody') os.setregid(pwinfo[3],pwinfo[3]) os.setreuid(pwinfo[2],pwinfo[2]) #"Robustly turn into a UNIX daemon, running in our_home_dir." # First fork try: if os.fork() > 0: sys.exit(0) # kill off parent except OSError, e: sys.stderr.write("fork #1 failed: (%d) %s\n" % (e.errno, e.strerror)) sys.exit(1) os.setsid() os.chdir('/') os.umask(0) # Second fork try: pid = os.fork() if pid > 0: os._exit(0) except OSError, e: sys.stderr.write("fork #2 failed: (%d) %s\n" % (e.errno, e.strerror)) os._exit(1) si = open('/dev/null', 'r') so = open('/dev/null', 'a+', 0) se = open('/dev/null', 'a+', 0) os.dup2(si.fileno(), sys.stdin.fileno()) os.dup2(so.fileno(), sys.stdout.fileno()) os.dup2(se.fileno(), sys.stderr.fileno()) # Set custom file descriptors so that they get proper buffering. sys.stdout, sys.stderr = so, se #""" s.logger.info("Startup; pid=%s" % os.getpid()) asyncore.loop()