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
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
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
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