Source

iredapd / src / iredapd.py

Zhang Huangbin 6143b46 


Zhang Huangbin 9408495 
Zhang Huangbin 6143b46 
Zhang Huangbin d70b0aa 

Zhang Huangbin 6143b46 
Zhang Huangbin 13031d7 
Zhang Huangbin 6143b46 

Zhang Huangbin d70b0aa 

Zhang Huangbin 6143b46 


Zhang Huangbin 1a31033 

Zhang Huangbin 1d3fcf1 
Zhang Huangbin 6143b46 












Zhang Huangbin f0e8ba4 









Zhang Huangbin 6143b46 
Zhang Huangbin d70b0aa 
Zhang Huangbin 1a31033 
Zhang Huangbin 6143b46 













Zhang Huangbin 1a31033 
Zhang Huangbin 6143b46 
Zhang Huangbin 92ad620 
Zhang Huangbin 6143b46 

Zhang Huangbin 13a9ea5 
Zhang Huangbin 6143b46 


Zhang Huangbin f0e8ba4 
Zhang Huangbin 8b3f08b 
Zhang Huangbin 6143b46 



Zhang Huangbin f0e8ba4 
Zhang Huangbin 1d3fcf1 
Zhang Huangbin 6143b46 
Zhang Huangbin f0e8ba4 
Zhang Huangbin d70b0aa 

Zhang Huangbin 4332627 
Zhang Huangbin d70b0aa 

Zhang Huangbin 4adf1a5 
Zhang Huangbin 6143b46 

Zhang Huangbin 4332627 
Zhang Huangbin 6143b46 
Zhang Huangbin f0e8ba4 
Zhang Huangbin 6143b46 





Zhang Huangbin d70b0aa 
Zhang Huangbin 1a31033 
Zhang Huangbin 6143b46 






Zhang Huangbin d70b0aa 

Zhang Huangbin 6143b46 


Zhang Huangbin 1a31033 
Zhang Huangbin 6143b46 
Zhang Huangbin d70b0aa 
Zhang Huangbin 6143b46 
Zhang Huangbin 35ed63e 


Zhang Huangbin 6143b46 

























Zhang Huangbin 1a31033 
Zhang Huangbin 6143b46 




Zhang Huangbin 13031d7 



Zhang Huangbin 6143b46 





Zhang Huangbin 13031d7 


Zhang Huangbin 6143b46 





#!/usr/bin/env python
# encoding: utf-8

# Author: Zhang Huangbin <zhb (at) iredmail.org>

import os
import os.path
import sys
import pwd
import ConfigParser
import socket
import asyncore
import asynchat
import logging
import daemon

# Append plugin directory.
sys.path.append(os.path.abspath(os.path.dirname(__file__)) + '/plugins')

# Get config file.
if len(sys.argv) != 2:
    sys.exit('Usage: %s /path/to/iredapd.ini')
else:
    config_file = sys.argv[1]

    # Check file exists.
    if not os.path.exists(config_file):
        sys.exit('File not exist: %s.' % config_file)

# Read configurations.
cfg = ConfigParser.SafeConfigParser()
cfg.read(config_file)
backend = cfg.get('general', 'backend', 'ldap')

if backend == 'ldap':
    from libs.ldaplib import LDAPModeler as Modeler
elif backend in ['mysql', 'pgsql']:
    from libs.sqllib import SQLModeler as Modeler
else:
    sys.exit('Invalid backend. It should be ldap or sql.')

from libs import __version__, SMTP_ACTIONS


class apd_channel(asynchat.async_chat):
    def __init__(self, conn, remoteaddr):
        asynchat.async_chat.__init__(self, conn)
        self.buffer = []
        self.map = {}
        self.set_terminator('\n')
        logging.debug("Connect from " + remoteaddr[0])

    def push(self, msg):
        asynchat.async_chat.push(self, msg + '\n')

    def collect_incoming_data(self, data):
        self.buffer.append(data)

    def found_terminator(self):
        if self.buffer:
            line = self.buffer.pop()
            logging.debug("smtp session: " + line)
            if line.find('=') != -1:
                key = line.split('=')[0]
                value = line.split('=', 1)[1]
                self.map[key] = value
        elif len(self.map) != 0:
            try:
                modeler = Modeler(cfg=cfg, logger=logging)

                result = modeler.handle_data(self.map)
                if result != None:
                    action = result
                else:
                    action = SMTP_ACTIONS['accept']
                logging.debug("Final action: %s." % str(result))
            except Exception, e:
                action = SMTP_ACTIONS['default']
                logging.debug('Error: %s. Use default action instead: %s' %
                        (str(e), str(action)))

            logging.info('%s -> %s, %s' %
                    (self.map['sender'], self.map['recipient'], action))
            self.push('action=' + action)
            self.push('')
            asynchat.async_chat.handle_close(self)
            logging.debug("Connection closed")
        else:
            action = SMTP_ACTIONS['defer']
            logging.debug("replying: " + action)
            self.push(action)
            self.push('')
            asynchat.async_chat.handle_close(self)
            logging.debug("Connection closed")


class apd_socket(asyncore.dispatcher):
    def __init__(self, localaddr):
        asyncore.dispatcher.__init__(self)
        self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
        self.set_reuse_addr()
        self.bind(localaddr)
        self.listen(5)
        ip, port = localaddr
        logging.info("Starting iredapd (v%s, pid: %d), listening on %s:%s." %
                (__version__, os.getpid(), ip, str(port)))

    def handle_accept(self):
        conn, remoteaddr = self.accept()
        channel = apd_channel(conn, remoteaddr)


def main():
    # Set umask.
    os.umask(0077)

    # Get listen address/port.
    listen_addr = cfg.get('general', 'listen_addr', '127.0.0.1')
    listen_port = int(cfg.get('general', 'listen_port', '7777'))

    run_as_daemon = cfg.get('general', 'run_as_daemon', 'yes')

    # Get log level.
    log_level = getattr(logging, cfg.get('general', 'log_level', 'info').upper())

    # Initialize file based logger.
    if cfg.get('general', 'log_type', 'file') == 'file':
        if run_as_daemon == 'yes':
            logging.basicConfig(
                    level=log_level,
                    format='%(asctime)s %(levelname)s %(message)s',
                    datefmt='%Y-%m-%d %H:%M:%S',
                    filename=cfg.get('general', 'log_file', '/var/log/iredapd.log'),
                    )
        else:
            logging.basicConfig(
                    level=log_level,
                    format='%(asctime)s %(levelname)s %(message)s',
                    datefmt='%Y-%m-%d %H:%M:%S',
                    )

    # Initialize policy daemon.
    socket_daemon = apd_socket((listen_addr, listen_port))

    # Run this program as daemon.
    if run_as_daemon == 'yes':
        daemon.daemonize()

    # Run as a low privileged user.
    run_as_user = cfg.get('general', 'run_as_user', 'nobody')
    uid = pwd.getpwnam(run_as_user)[2]

    try:
        # Write pid number into pid file.
        f = open(cfg.get('general', 'pid_file', '/var/run/iredapd.pid'), 'w')
        f.write(str(os.getpid()))
        f.close()

        # Set uid.
        os.setuid(uid)

        # Starting loop.
        asyncore.loop()
    except KeyboardInterrupt:
        pass

if __name__ == '__main__':
    main()
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.