Beispiel #1
0
def find_certificate(addr, local_domain, algo):
    #algorithms:
    # 0 = hybrid
    # 1 = address bound DNS CERT
    # 2 = domain bound DNS CERT
    # 3 = address bound LDAP
    # 4 = domain bound LDAP
    # 5 = stored in database
    logging.debug('Try finding certificate for address: %s', addr)
    parts = addr.partition('@')
    user = parts[0]
    domain = parts[2]

    if algo == 1 or algo == 0:
        logging.debug('Trying address bound DNS CERT')
        certs = certdisco.dns_cert(user + '.' + domain)
        if certs != []:
            for cert in certs:
                if certvld.validate(cert,
                                    local_domain,
                                    addr,
                                    domain,
                                    addressBound=True):
                    logging.debug('A valid address bound DNS CERT was found')
                    return cert
            logging.debug('No valid address bound DNS CERT found')
            return None
        logging.debug('No address bound DNS CERT found')

    if algo == 2 or algo == 0:
        logging.debug('Trying domain bound DNS CERT')
        certs = certdisco.dns_cert(domain)
        if certs != []:
            for cert in certs:
                if certvld.validate(cert,
                                    local_domain,
                                    addr,
                                    domain,
                                    addressBound=False):
                    logging.debug('A valid domain bound DNS CERT was found')
                    return cert
            logging.debug('No valid domain bound DNS CERT found')
            return None
        logging.debug('No domain bound DNS CERT found')

    if algo == 3 or algo == 0:
        logging.debug('Trying address bound LDAP')
        uris = certdisco.dns_srv(domain)
        for uri in uris:
            certs = certdisco.ldap_qry(uri, addr)
            if certs != []:
                for cert in certs:
                    if certvld.validate(cert,
                                        local_domain,
                                        addr,
                                        domain,
                                        addressBound=True):
                        logging.debug(
                            'A valid address bound LDAP was found using uri: '
                            + uri)
                        return cert
                logging.debug('No valid address bound LDAP found using uri: ' +
                              uri)
                return None
            logging.debug('No address bound LDAP found using uri: ' + uri)
        logging.debug('No address bound LDAP found')

    if algo == 4 or algo == 0:
        logging.debug('Trying domain bound LDAP')
        uris = certdisco.dns_srv(domain)
        for uri in uris:
            certs = certdisco.ldap_qry(uri, domain)
            if certs != []:
                for cert in certs:
                    if certvld.validate(cert,
                                        local_domain,
                                        addr,
                                        domain,
                                        addressBound=False):
                        logging.debug(
                            'A valid domain bound LDAP was found using uri: ' +
                            uri)
                        return cert
                logging.debug('No valid domain bound LDAP found using uri: ' +
                              uri)
                return None
            logging.debug('No domain bound LDAP found using uri: ' + uri)
        logging.debug('No domain bound LDAP found')

    return None
Beispiel #2
0
def send_message(sender, recipient, message_id, message):
    from M2Crypto import EVP, util, X509
    import certdisco, certvld, crypto, subprocess, os

    logging.debug('Start sending message to: %s', recipient)
    domain = recipient.partition('@')[2]
    sender_domain = sender.partition('@')[2]

    try:
        logging.debug('Connecting to "maildb" database')
        conn = psycopg2.connect(database='maildb', user='******')
    except psycopg2.OperationalError as dberr:
        logging.error('Database connection failed: %s', dberr)
        return 1

    cur = conn.cursor();
    logging.debug('Searching database record for domain: %s', domain)
    cur.execute("SELECT anchor_path, crl_path, crypt_cert, cert_disco_algo FROM domains WHERE name = %s;", (domain,))
    dom = cur.fetchone()
    cur.close()
    conn.close()

    from_key = os.path.join(CADIR, 'key', sender_domain, 'direct.key') #EVP.load_key('direct.key', util.passphrase_callback)
    from_cert = os.path.join(CADIR, 'cert', sender_domain, 'direct.pem') #X509.load_cert('direct.pem')
    
    algo = 0 if dom == None else dom[3]

    logging.debug('Certificate discovery algorithm: %s', algo)
    if (dom != None) and (dom[3] == 5): #cert_disco_algo = local (cert saved to database)
        logging.debug('Trying local CERT stored in database')
        to_cert = None
        if certvld.validate(dom[2], sender_domain, recipient, domain, addressBound = False):
            logging.debug('A valid local CERT stored in database was found')
            to_cert = dom[2]
        logging.debug('No local CERT found')
    else:
        to_cert = find_certificate(recipient, sender_domain, algo)

    if to_cert == None:
        logging.warning('Recipient certificate not found: %s', recipient)
        return 1

    logging.debug('Securing message')
    cms = crypto.to_smime(message, from_key, from_cert, to_cert)
    logging.debug('Message secured')

    logging.debug('Queueing encrypted mail message for: %s', recipient)
    command = ('/usr/sbin/sendmail', '-f', sender, '--', recipient)
    proc = subprocess.Popen(command, stdin=subprocess.PIPE)

    #proc.stdin.write('From: <%s>\r\n' % sender)
    proc.stdin.write('To: <%s>\r\n' % recipient)
    proc.stdin.write('Message-ID: %s\r\n' % message_id)
    proc.stdin.write(cms)
    proc.communicate()
    status = proc.returncode
    if status == 0:
        logging.debug('Message queued: %s: %s', message_id, recipient)
    else:
        logging.warning('Send message failed: %s: %s', message_id, recipient)
    return status
Beispiel #3
0
def send_message(sender, recipient, message_id, message):
    from M2Crypto import EVP, util, X509
    import certdisco, certvld, crypto, subprocess, os

    logging.debug('Start sending message to: %s', recipient)
    recipient = recipient.lower()
    domain = recipient.partition('@')[2]
    sender_domain = sender.partition('@')[2]

    msg = Parser().parsestr(message)
    is_mdn = False
    for mpart in msg.walk():
        ct = mpart.get_content_type()
        if ct == 'message/disposition-notification':
            is_mdn = True
    try:
        logging.debug('Connecting to "maildb" database')
        conn = psycopg2.connect(database='maildb', user='******')
    except psycopg2.OperationalError as dberr:
        logging.error('Database connection failed: %s', dberr)
        logging.error(
            format_log_message(sender, recipient, message_id,
                               'failed (Database connection failed)', is_mdn))
        return 1

    cur = conn.cursor()
    logging.debug('Searching database record for domain: %s', domain)
    cur.execute(
        "SELECT anchor_path, crl_path, crypt_cert, cert_disco_algo FROM domains WHERE name = %s;",
        (domain, ))
    dom = cur.fetchone()
    cur.close()
    conn.close()

    from_key = os.path.join(
        CADIR, 'key', sender_domain,
        'direct.key')  #EVP.load_key('direct.key', util.passphrase_callback)
    from_cert = os.path.join(CADIR, 'cert', sender_domain,
                             'direct.pem')  #X509.load_cert('direct.pem')

    algo = 0 if dom == None else dom[3]

    logging.debug('Certificate discovery algorithm: %s', algo)
    if (dom != None) and (
            dom[3] == 5):  #cert_disco_algo = local (cert saved to database)
        logging.debug('Trying local CERT stored in database')
        to_cert = None
        if certvld.validate(dom[2],
                            sender_domain,
                            recipient,
                            domain,
                            addressBound=False):
            logging.debug('A valid local CERT stored in database was found')
            to_cert = dom[2]
        logging.debug('No local CERT found')
    else:
        to_cert = find_certificate(recipient, sender_domain, algo)

    if to_cert == None:
        logging.warning(
            format_log_message(sender, recipient, message_id,
                               'failed (Recipient certificate not found)',
                               is_mdn))
        return 1

    logging.debug('Securing message')
    cms = crypto.to_smime(message, from_key, from_cert, to_cert)
    logging.debug('Message secured')

    logging.debug('Queueing encrypted mail message for: %s', recipient)
    command = ('/usr/sbin/sendmail', '-f', sender, '--', recipient)
    proc = subprocess.Popen(command, stdin=subprocess.PIPE)

    #proc.stdin.write('From: <%s>\r\n' % sender)
    proc.stdin.write('To: <%s>\r\n' % recipient)
    proc.stdin.write('Message-ID: %s\r\n' % message_id)
    proc.stdin.write(cms)
    proc.communicate()
    status = proc.returncode
    if status == 0:
        logging.info(
            format_log_message(sender, recipient, message_id,
                               'sent (successful processing)', is_mdn))
    else:
        logging.warning(
            format_log_message(sender, recipient, message_id,
                               'failed (sendmail error code: %s)' % status,
                               is_mdn))
    return status
Beispiel #4
0
def find_certificate(addr, local_domain, algo):
    #algorithms:
    # 0 = hybrid
    # 1 = address bound DNS CERT
    # 2 = domain bound DNS CERT
    # 3 = address bound LDAP
    # 4 = domain bound LDAP
    # 5 = stored in database
    logging.debug('Try finding certificate for address: %s', addr)
    parts = addr.partition('@')
    user = parts[0]
    domain = parts[2]
      
    if algo == 1 or algo == 0:
        logging.debug('Trying address bound DNS CERT')
        certs = certdisco.dns_cert(user + '.' + domain)
        if certs != []:
            for cert in certs:
                if certvld.validate(cert, local_domain, addr, domain, addressBound = True):
                    logging.debug('A valid address bound DNS CERT was found')
                    return cert
            logging.debug('No valid address bound DNS CERT found')
            return None
        logging.debug('No address bound DNS CERT found')

    if algo == 2 or algo == 0:
        logging.debug('Trying domain bound DNS CERT')
        certs = certdisco.dns_cert(domain)
        if certs != []:
            for cert in certs:
                if certvld.validate(cert, local_domain, addr, domain, addressBound = False):
                    logging.debug('A valid domain bound DNS CERT was found')
                    return cert
            logging.debug('No valid domain bound DNS CERT found')
            return None
        logging.debug('No domain bound DNS CERT found')

    if algo == 3 or algo == 0:
        logging.debug('Trying address bound LDAP')
        uris = certdisco.dns_srv(domain)
        for uri in uris:
            certs = certdisco.ldap_qry(uri, addr)
            if certs != []:
                for cert in certs:
                    if certvld.validate(cert, local_domain, addr, domain, addressBound = True):
                        logging.debug('A valid address bound LDAP was found using uri: ' + uri)
                        return cert
                logging.debug('No valid address bound LDAP found using uri: ' + uri)
                return None
            logging.debug('No address bound LDAP found using uri: ' + uri)
        logging.debug('No address bound LDAP found')

    if algo == 4 or algo == 0:
        logging.debug('Trying domain bound LDAP')
        uris = certdisco.dns_srv(domain)
        for uri in uris:
            certs = certdisco.ldap_qry(uri, domain)
            if certs != []:
                for cert in certs:
                    if certvld.validate(cert, local_domain, addr, domain, addressBound = False):
                        logging.debug('A valid domain bound LDAP was found using uri: ' + uri)
                        return cert
                logging.debug('No valid domain bound LDAP found using uri: ' + uri)
                return None
            logging.debug('No domain bound LDAP found using uri: ' + uri)
        logging.debug('No domain bound LDAP found')

    return None