def __init__(self, clientSocket, serverName, serverPort): Dibbler.BrighterAsyncChat.__init__(self, clientSocket) self.request = '' self.set_terminator('\r\n') self.command = '' # The SMTP command being processed... self.args = '' # ...and its arguments self.isClosing = False # Has the server closed the socket? self.inData = False self.data = [] self.blockData = False if not self.onIncomingConnection(clientSocket): # We must refuse this connection, so pass an error back # to the mail client. self.push("421 Connection not allowed\r\n") self.close_when_done() return self.serverSocket = ServerLineReader(serverName, serverPort, self.onServerLine)
def __init__(self, clientSocket, serverName, serverPort): Dibbler.BrighterAsyncChat.__init__(self, clientSocket) self.request = '' self.set_terminator('\r\n') self.command = '' # The SMTP command being processed... self.args = '' # ...and its arguments self.isClosing = False # Has the server closed the socket? self.inData = False self.data = "" self.blockData = False self.serverSocket = ServerLineReader(serverName, serverPort, self.onServerLine)
def __init__(self, clientSocket, serverName, serverPort): Dibbler.BrighterAsyncChat.__init__(self, clientSocket) self.request = "" self.set_terminator("\r\n") self.command = "" # The SMTP command being processed... self.args = "" # ...and its arguments self.isClosing = False # Has the server closed the socket? self.inData = False self.data = [] self.blockData = False if not self.onIncomingConnection(clientSocket): self.push("421 Connection not allowed\r\n") self.close_when_done() return self.serverSocket = ServerLineReader(serverName, serverPort, self.onServerLine)
def __init__(self, clientSocket, serverName, serverPort): Dibbler.BrighterAsyncChat.__init__(self, clientSocket) self.request = '' self.set_terminator('\r\n') self.command = '' # The SMTP command being processed... self.args = '' # ...and its arguments self.isClosing = False # Has the server closed the socket? self.inData = False self.data = "" self.blockData = False if not self.onIncomingConnection(clientSocket): # We must refuse this connection, so pass an error back # to the mail client. self.push("421 Connection not allowed\r\n") self.close_when_done() return self.serverSocket = ServerLineReader(serverName, serverPort, self.onServerLine)
class SMTPProxyBase(Dibbler.BrighterAsyncChat): """An async dispatcher that understands SMTP and proxies to a SMTP server, calling `self.onTransaction(command, args)` for each transaction. self.onTransaction() should return the command to pass to the proxied server - the command can be the verbatim command or a processed version of it. The special command 'KILL' kills it (passing a 'QUIT' command to the server). """ def __init__(self, clientSocket, serverName, serverPort): Dibbler.BrighterAsyncChat.__init__(self, clientSocket) self.request = "" self.set_terminator("\r\n") self.command = "" # The SMTP command being processed... self.args = "" # ...and its arguments self.isClosing = False # Has the server closed the socket? self.inData = False self.data = [] self.blockData = False if not self.onIncomingConnection(clientSocket): # We must refuse this connection, so pass an error back # to the mail client. self.push("421 Connection not allowed\r\n") self.close_when_done() return self.serverSocket = ServerLineReader(serverName, serverPort, self.onServerLine) def onIncomingConnection(self, clientSocket): """Checks the security settings.""" # Stolen from UserInterface.py remoteIP = clientSocket.getpeername()[0] trustedIPs = options["smtpproxy", "allow_remote_connections"] if trustedIPs == "*" or remoteIP == clientSocket.getsockname()[0]: return True trustedIPs = trustedIPs.replace(".", "\.").replace("*", "([01]?\d\d?|2[04]\d|25[0-5])") for trusted in trustedIPs.split(","): if re.search("^" + trusted + "$", remoteIP): return True return False def onTransaction(self, command, args): """Overide this. Takes the raw command and returns the (possibly processed) command to pass to the email client.""" raise NotImplementedError def onProcessData(self, data): """Overide this. Takes the raw data and returns the (possibly processed) data to pass back to the email client.""" raise NotImplementedError def onServerLine(self, line): """A line of response has been received from the SMTP server.""" # Has the server closed its end of the socket? if not line: self.isClosing = True # We don't process the return, just echo the response. self.push(line) self.onResponse() def collect_incoming_data(self, data): """Asynchat override.""" self.request = self.request + data def found_terminator(self): """Asynchat override.""" verb = self.request.strip().upper() if verb == "KILL": self.socket.shutdown(2) self.close() raise SystemExit if self.request.strip() == "": # Someone just hit the Enter key. self.command = self.args = "" else: # A proper command. if self.request[:10].upper() == "MAIL FROM:": splitCommand = self.request.split(":", 1) elif self.request[:8].upper() == "RCPT TO:": splitCommand = self.request.split(":", 1) else: splitCommand = self.request.strip().split(None, 1) self.command = splitCommand[0] self.args = splitCommand[1:] if self.inData == True: self.data.append(self.request + "\r\n") if self.request == ".": self.inData = False cooked = self.onProcessData("".join(self.data)) self.data = [] if self.blockData == False: self.serverSocket.push(cooked) else: self.push("250 OK\r\n") else: cooked = self.onTransaction(self.command, self.args) if cooked is not None: self.serverSocket.push(cooked + "\r\n") self.command = self.args = self.request = "" def onResponse(self): # If onServerLine() decided that the server has closed its # socket, close this one when the response has been sent. if self.isClosing: self.close_when_done() # Reset. self.command = "" self.args = "" self.isClosing = False
class SMTPProxyBase(Dibbler.BrighterAsyncChat): """An async dispatcher that understands SMTP and proxies to a SMTP server, calling `self.onTransaction(command, args)` for each transaction. self.onTransaction() should return the command to pass to the proxied server - the command can be the verbatim command or a processed version of it. The special command 'KILL' kills it (passing a 'QUIT' command to the server). """ def __init__(self, clientSocket, serverName, serverPort): Dibbler.BrighterAsyncChat.__init__(self, clientSocket) self.request = '' self.set_terminator('\r\n') self.command = '' # The SMTP command being processed... self.args = '' # ...and its arguments self.isClosing = False # Has the server closed the socket? self.inData = False self.data = [] self.blockData = False if not self.onIncomingConnection(clientSocket): # We must refuse this connection, so pass an error back # to the mail client. self.push("421 Connection not allowed\r\n") self.close_when_done() return self.serverSocket = ServerLineReader(serverName, serverPort, self.onServerLine) def onIncomingConnection(self, clientSocket): """Checks the security settings.""" # Stolen from UserInterface.py remoteIP = clientSocket.getpeername()[0] trustedIPs = options["smtpproxy", "allow_remote_connections"] if trustedIPs == "*" or remoteIP == clientSocket.getsockname()[0]: return True trustedIPs = trustedIPs.replace('.', '\.').replace( '*', '([01]?\d\d?|2[04]\d|25[0-5])') for trusted in trustedIPs.split(','): if re.search("^" + trusted + "$", remoteIP): return True return False def onTransaction(self, command, args): """Overide this. Takes the raw command and returns the (possibly processed) command to pass to the email client.""" raise NotImplementedError def onProcessData(self, data): """Overide this. Takes the raw data and returns the (possibly processed) data to pass back to the email client.""" raise NotImplementedError def onServerLine(self, line): """A line of response has been received from the SMTP server.""" # Has the server closed its end of the socket? if not line: self.isClosing = True # We don't process the return, just echo the response. self.push(line) self.onResponse() def collect_incoming_data(self, data): """Asynchat override.""" self.request = self.request + data def found_terminator(self): """Asynchat override.""" verb = self.request.strip().upper() if verb == 'KILL': self.socket.shutdown(2) self.close() raise SystemExit if self.request.strip() == '': # Someone just hit the Enter key. self.command = self.args = '' else: # A proper command. if self.request[:10].upper() == "MAIL FROM:": splitCommand = self.request.split(":", 1) elif self.request[:8].upper() == "RCPT TO:": splitCommand = self.request.split(":", 1) else: splitCommand = self.request.strip().split(None, 1) self.command = splitCommand[0] self.args = splitCommand[1:] if self.inData == True: self.data.append(self.request + '\r\n') if self.request == ".": self.inData = False cooked = self.onProcessData("".join(self.data)) self.data = [] if self.blockData == False: self.serverSocket.push(cooked) else: self.push("250 OK\r\n") else: cooked = self.onTransaction(self.command, self.args) if cooked is not None: self.serverSocket.push(cooked + '\r\n') self.command = self.args = self.request = '' def onResponse(self): # If onServerLine() decided that the server has closed its # socket, close this one when the response has been sent. if self.isClosing: self.close_when_done() # Reset. self.command = '' self.args = '' self.isClosing = False
class SMTPProxyBase(Dibbler.BrighterAsyncChat): """An async dispatcher that understands SMTP and proxies to a SMTP server, calling `self.onTransaction(command, args)` for each transaction. self.onTransaction() should return the command to pass to the proxied server - the command can be the verbatim command or a processed version of it. The special command 'KILL' kills it (passing a 'QUIT' command to the server). """ def __init__(self, clientSocket, serverName, serverPort): Dibbler.BrighterAsyncChat.__init__(self, clientSocket) self.request = '' self.set_terminator('\r\n') self.command = '' # The SMTP command being processed... self.args = '' # ...and its arguments self.isClosing = False # Has the server closed the socket? self.inData = False self.data = "" self.blockData = False self.serverSocket = ServerLineReader(serverName, serverPort, self.onServerLine) def onTransaction(self, command, args): """Overide this. Takes the raw command and returns the (possibly processed) command to pass to the email client.""" raise NotImplementedError def onProcessData(self, data): """Overide this. Takes the raw data and returns the (possibly processed) data to pass back to the email client.""" raise NotImplementedError def onServerLine(self, line): """A line of response has been received from the SMTP server.""" # Has the server closed its end of the socket? if not line: self.isClosing = True # We don't process the return, just echo the response. self.push(line) self.onResponse() def collect_incoming_data(self, data): """Asynchat override.""" self.request = self.request + data def found_terminator(self): """Asynchat override.""" verb = self.request.strip().upper() if verb == 'KILL': self.socket.shutdown(2) self.close() raise SystemExit if self.request.strip() == '': # Someone just hit the Enter key. self.command = self.args = '' else: # A proper command. if self.request[:10].upper() == "MAIL FROM:": splitCommand = self.request.split(":", 1) elif self.request[:8].upper() == "RCPT TO:": splitCommand = self.request.split(":", 1) else: splitCommand = self.request.strip().split(None, 1) self.command = splitCommand[0] self.args = splitCommand[1:] if self.inData == True: self.data += self.request + '\r\n' if self.request == ".": self.inData = False cooked = self.onProcessData(self.data) self.data = "" if self.blockData == False: self.serverSocket.push(cooked) else: self.push("250 OK\r\n") else: cooked = self.onTransaction(self.command, self.args) if cooked is not None: self.serverSocket.push(cooked + '\r\n') self.command = self.args = self.request = '' def onResponse(self): # If onServerLine() decided that the server has closed its # socket, close this one when the response has been sent. if self.isClosing: self.close_when_done() # Reset. self.command = '' self.args = '' self.isClosing = False