コード例 #1
0
ファイル: milterconnector.py プロジェクト: jahlives/fuglu
    def __init__(self, socket, config):
        PpyMilter.__init__(self)
        self.socket = socket
        self.config = config
        self.CanAddHeaders()
        self.CanChangeBody()
        self.CanChangeHeaders()

        self.logger = logging.getLogger('fuglu.miltersession')

        self.__milter_dispatcher = PpyMilterDispatcher(self)
        self.recipients = []
        self.from_address = None

        (handle, tempfilename) = tempfile.mkstemp(prefix='fuglu',
                                                  dir=self.config.get(
                                                      'main', 'tempdir'))
        self.tempfilename = tempfilename
        self.tempfile = os.fdopen(handle, 'w+b')

        self.currentmilterdata = None

        self.answer = self.Continue()

        self.helo = None
        self.ip = None
        self.rdns = None
コード例 #2
0
ファイル: milterconnector.py プロジェクト: jahlives/fuglu
class MilterSession(PpyMilter):
    def __init__(self, socket, config):
        PpyMilter.__init__(self)
        self.socket = socket
        self.config = config
        self.CanAddHeaders()
        self.CanChangeBody()
        self.CanChangeHeaders()

        self.logger = logging.getLogger('fuglu.miltersession')

        self.__milter_dispatcher = PpyMilterDispatcher(self)
        self.recipients = []
        self.from_address = None

        (handle, tempfilename) = tempfile.mkstemp(prefix='fuglu',
                                                  dir=self.config.get(
                                                      'main', 'tempdir'))
        self.tempfilename = tempfilename
        self.tempfile = os.fdopen(handle, 'w+b')

        self.currentmilterdata = None

        self.answer = self.Continue()

        self.helo = None
        self.ip = None
        self.rdns = None

    def OnConnect(self, cmd, hostname, family, port, address):
        if family not in ('4', '6'):  # we don't handle unix socket
            return self.Continue()
        if hostname is None or hostname == '[%s]' % address:
            hostname = 'unknown'

        self.rdns = hostname
        self.addr = address
        return self.Continue()

    def OnHelo(self, cmd, helo):
        self.helo = helo
        return self.Continue()

    def OnRcptTo(self, cmd, rcpt_to, esmtp_info):
        self.recipients.append(rcpt_to)
        return self.Continue()

    def OnMailFrom(self, cmd, mail_from, args):
        self.from_address = mail_from
        return self.Continue()

    def OnHeader(self, cmd, header, value):
        self.tempfile.write("%s: %s\n" % (header, value))
        return self.Continue()

    def OnEndHeaders(self, cmd):
        self.tempfile.write("\n")
        return self.Continue()

    def OnBody(self, cmd, data):
        self.tempfile.write(data)
        return self.Continue()

    def OnEndBody(self, cmd):
        return self.answer

    def OnResetState(self):
        self.recipients = None
        self.tempfile = None
        self.tempfilename = None

    def _read_milter_command(self):
        lenbuf = []
        lenread = 0
        while lenread < MILTER_LEN_BYTES:
            pdat = self.socket.recv(MILTER_LEN_BYTES - lenread)
            lenbuf.append(pdat)
            lenread += len(pdat)
        dat = b"".join(lenbuf)
        # self.logger.info(dat)
        # self.logger.info(len(dat))
        packetlen = int(struct.unpack('!I', dat)[0])
        inbuf = []
        read = 0
        while read < packetlen:
            partial_data = self.socket.recv(packetlen - read)
            inbuf.append(partial_data)
            read += len(partial_data)
        data = b"".join(inbuf)
        return data

    def finish(self):
        """we assume to be at SMFIC_BODYEOB"""
        try:
            while True:
                if self.currentmilterdata != None:
                    data = self.currentmilterdata
                    self.currentmilterdata = None
                else:
                    data = self._read_milter_command()
                try:
                    response = self.__milter_dispatcher.Dispatch(data)
                    if type(response) == list:
                        for r in response:
                            self.__send_response(r)
                    elif response:
                        self.__send_response(response)
                except PpyMilterCloseConnection as e:
                    #logging.info('Closing connection ("%s")', str(e))
                    break
        except Exception as e:
            # TODO: here we get broken pipe if we're not using self.Continue(), but the milter client seems happy
            # so, silently discarding this exception for now
            pass

    def getincomingmail(self):
        try:
            while True:
                data = self._read_milter_command()
                self.currentmilterdata = data
                (cmd, args) = (data[0], data[1:])
                if cmd == SMFIC_BODYEOB:
                    self.tempfile.close()
                    return True
                try:
                    response = self.__milter_dispatcher.Dispatch(data)
                    if type(response) == list:
                        for r in response:
                            self.__send_response(r)
                    elif response:
                        self.__send_response(response)
                except PpyMilterCloseConnection as e:
                    #logging.info('Closing connection ("%s")', str(e))
                    break
        except Exception as e:
            exc = traceback.format_exc()
            self.logger.error('Exception in MilterSession: %s %s' % (e, exc))
            return False
        return False

    def __send_response(self, response):
        """Send data down the milter socket.

        Args:
          response: the data to send
        """
        self.socket.send(struct.pack('!I', len(response)))
        self.socket.send(force_bString(response))