def test_levenshteinDistance_feidanchaoren0043_feidanchaoren0011(self): """The Levenshtein Distance between the usernames in '*****@*****.**' and '*****@*****.**' should be less than an EMAIL_FUZZY_MATCH parameter. """ email1 = Address('*****@*****.**') email2 = Address('*****@*****.**') # Fuzzy match if the Levenshtein Distance is less than or equal to: fuzzyMatch = 4 distance = util.levenshteinDistance(email1.local, email2.local) self.assertLessEqual(distance, fuzzyMatch)
def test_message_sign(self): """ Test if message is signed with sender key. """ # mock the key fetching self._km.fetch_keys_from_server = Mock(return_value=[]) proto = SMTPFactory( self._km, self._config).buildProtocol(('127.0.0.1', 0)) user = User('*****@*****.**', 'relay.leap.se', proto, ADDRESS) fromAddr = Address(ADDRESS_2) m = EncryptedMessage(fromAddr, user, self._km, self._config) for line in self.EMAIL_DATA[4:12]: m.lineReceived(line) # trigger signing m.eomReceived() # assert content of message self.assertTrue( m._message.get_payload().startswith( '-----BEGIN PGP SIGNED MESSAGE-----\n' + 'Hash: SHA1\n\n' + ('\r\n'.join(self.EMAIL_DATA[9:12]) + '\r\n' + '-----BEGIN PGP SIGNATURE-----\n')), 'Message does not start with signature header.') self.assertTrue( m._message.get_payload().endswith( '-----END PGP SIGNATURE-----\n'), 'Message does not end with signature footer.') # assert signature is valid pubkey = self._km.get_key(ADDRESS_2, openpgp.OpenPGPKey) self.assertTrue( openpgp.verify(m._message.get_payload(), pubkey), 'Signature could not be verified.')
def _recordEmailRequest(self, smtpAutoresp, success): emailAddrs = smtpAutoresp.getMailTo() if len(emailAddrs) == 0: # This is just for unit tests. emailAddr = Address("*****@*****.**") else: emailAddr = emailAddrs[0] # Get the requested transport protocol. br = request.determineBridgeRequestOptions( smtpAutoresp.incoming.lines) bridgeType = "vanilla" if not len(br.transports) else br.transports[0] # Over email, transports are requested by typing them. Typos happen # and users can request anything, really. if not isBridgeTypeSupported(bridgeType): logging.warning("User requested unsupported transport type %s " "over email." % bridgeType) return logging.debug("Recording %svalid email request for %s from %s." % ("" if success else "in", bridgeType, emailAddr)) sld = emailAddr.domain.split(b".")[0] # Now update our metrics. key = self.createKey(self.keyPrefix, bridgeType, sld, success, self.findAnomaly(request)) self.inc(key)
def setUp(self): self.t = NullTranslations(StringIO(unicode('test'))) self.client = Address('*****@*****.**') self.answer = 'obfs3 1.1.1.1:1111\nobfs3 2.2.2.2:2222' # This is the fingerprint of BridgeDB's offline, certification-only # GnuPG key. It should be present in any responses to requests for our # public keys. self.offlineFingerprint = '7B78437015E63DF47BB1270ACBD97AA24E8E472E'
def test_message_sign(self): """ Test if message is signed with sender key. """ # mock the key fetching self._km.fetch_keys_from_server = Mock(return_value=[]) proto = SMTPFactory(u'*****@*****.**', self._km, self._config['host'], self._config['port'], self._config['cert'], self._config['key'], self._config['encrypted_only']).buildProtocol( ('127.0.0.1', 0)) user = User('*****@*****.**', 'gateway.leap.se', proto, ADDRESS) fromAddr = Address(ADDRESS_2) m = EncryptedMessage(fromAddr, user, self._km, self._config['host'], self._config['port'], self._config['cert'], self._config['key']) for line in self.EMAIL_DATA[4:12]: m.lineReceived(line) # trigger signing #m.eomReceived() # this includes a defer, so we avoid calling it here m.lines.append('') # add a trailing newline # we need to call the following explicitelly because it was deferred # inside the previous method m._maybe_encrypt_and_sign() # assert structure of signed message self.assertTrue('Content-Type' in m._msg) self.assertEqual('multipart/signed', m._msg.get_content_type()) self.assertEqual('application/pgp-signature', m._msg.get_param('protocol')) self.assertEqual('pgp-sha512', m._msg.get_param('micalg')) # assert content of message self.assertEqual( '\r\n'.join(self.EMAIL_DATA[9:13]) + '\r\n--\r\n' + 'I prefer encrypted email - https://leap.se/key/anotheruser\r\n', m._msg.get_payload(0).get_payload(decode=True)) # assert content of signature self.assertTrue( m._msg.get_payload(1).get_payload().startswith( '-----BEGIN PGP SIGNATURE-----\n'), 'Message does not start with signature header.') self.assertTrue( m._msg.get_payload(1).get_payload().endswith( '-----END PGP SIGNATURE-----\n'), 'Message does not end with signature footer.') # assert signature is valid pubkey = self._km.get_key(ADDRESS_2, openpgp.OpenPGPKey) # replace EOL before verifying (according to rfc3156) signed_text = re.sub('\r?\n', '\r\n', m._msg.get_payload(0).as_string()) self.assertTrue( self._km.verify(signed_text, pubkey, detached_sig=m._msg.get_payload(1).get_payload()), 'Signature could not be verified.')
def test_SMTPAutoresponder_runChecks_RCPTTO_From_mismatched_domain(self): """runChecks() should catch emails where the SMTP 'MAIL FROM:' command reported being from an email address at one supported domain and the email's 'From:' header reported another domain. """ smtpFrom = '*****@*****.**' emailFrom = Address('*****@*****.**') self._getIncomingLines(str(emailFrom)) self._setUpResponder() self.responder.incoming.canonicalFromSMTP = smtpFrom self.assertFalse(self.responder.runChecks(emailFrom))
def _getIncomingLines(self, clientAddress="*****@*****.**"): """Generate the lines of an incoming email from **clientAddress**.""" self.toAddress = Address(clientAddress) lines = [ "From: %s" % clientAddress, "To: bridges@localhost", "Subject: testing", "", "get bridges", ] return lines
def test_SMTPAutoresponder_runChecks_DKIM_bad(self): """runChecks() should catch emails with bad DKIM headers (``"X-DKIM-Authentication-Results: dunno"``) for canonical domains which we're configured to check DKIM verification results for. """ emailFrom = Address('*****@*****.**') header = "X-DKIM-Authentication-Results: wowie zowie there's a sig here" self._getIncomingLines(str(emailFrom)) self.message.lines.insert(3, header) self._setUpResponder() self.assertFalse(self.responder.runChecks(emailFrom))
def test_SMTPAutoresponder_getMailFrom_plus_address(self): """SMTPAutoresponder.getMailFrom() for an incoming email sent with a valid plus address should respond. """ self._getIncomingLines() ours = Address(self.context.fromAddr) plus = '@'.join([ours.local + '+zh_cn', ours.domain]) self.message.lines[1] = 'To: {0}'.format(plus) self._setUpResponder() recipient = str(self.responder.getMailFrom()) self.assertEqual(recipient, plus)
def test_SMTPAutoresponder_getMailFrom_getbridges_at_localhost(self): """SMTPAutoresponder.getMailFrom() for an incoming email sent with 'getbridges+zh_cn@localhost' should be responded to from the default address. """ self._getIncomingLines() ours = Address(self.context.fromAddr) plus = '@'.join(['get' + ours.local + '+zh_cn', ours.domain]) self.message.lines[1] = 'To: {0}'.format(plus) self._setUpResponder() recipient = str(self.responder.getMailFrom()) self.assertEqual(recipient, self.context.fromAddr)
def test_SMTPAutoresponder_runChecks_RCPTTO_From_mismatched_username(self): """runChecks() should catch emails where the SMTP 'MAIL FROM:' command reported being from an email address and the email's 'From:' header reported another email address, even if the only the username part is mismatched. """ smtpFrom = '*****@*****.**' emailFrom = Address('*****@*****.**') self._getIncomingLines(str(emailFrom)) self._setUpResponder() self.responder.incoming.canonicalFromSMTP = smtpFrom self.assertFalse(self.responder.runChecks(emailFrom))
def _createUser(self, username, domain, ipaddress): """Create a ``twisted.mail.smtp.User`` for testing. :param str username: The local part of the client's email address. :param str domain: The host part of the client's email address. :param str ipaddress: The IP address of the client's mail server. """ self.helo = (domain, ipaddress) self._createProtocolWithHost(domain) self.origin = Address(b'@'.join(( username, domain, ))) self.user = User(username, self.helo, self.proto, self.origin)
def test_message_encrypt_sign(self): """ Test if message gets encrypted to destination email and signed with sender key. """ proto = SMTPFactory(u'*****@*****.**', self._km, self._config['host'], self._config['port'], self._config['cert'], self._config['key'], self._config['encrypted_only']).buildProtocol( ('127.0.0.1', 0)) user = User(ADDRESS, 'gateway.leap.se', proto, ADDRESS) fromAddr = Address(ADDRESS_2) m = EncryptedMessage(fromAddr, user, self._km, self._config['host'], self._config['port'], self._config['cert'], self._config['key']) for line in self.EMAIL_DATA[4:12]: m.lineReceived(line) # trigger encryption and signing #m.eomReceived() # this includes a defer, so we avoid calling it here m.lines.append('') # add a trailing newline # we need to call the following explicitelly because it was deferred # inside the previous method m._maybe_encrypt_and_sign() # assert structure of encrypted message self.assertTrue('Content-Type' in m._msg) self.assertEqual('multipart/encrypted', m._msg.get_content_type()) self.assertEqual('application/pgp-encrypted', m._msg.get_param('protocol')) self.assertEqual(2, len(m._msg.get_payload())) self.assertEqual('application/pgp-encrypted', m._msg.get_payload(0).get_content_type()) self.assertEqual('application/octet-stream', m._msg.get_payload(1).get_content_type()) # decrypt and verify privkey = self._km.get_key(ADDRESS, openpgp.OpenPGPKey, private=True) pubkey = self._km.get_key(ADDRESS_2, openpgp.OpenPGPKey) decrypted = self._km.decrypt(m._msg.get_payload(1).get_payload(), privkey, verify=pubkey) self.assertEqual( '\n' + '\r\n'.join(self.EMAIL_DATA[9:12]) + '\r\n\r\n--\r\n' + 'I prefer encrypted email - https://leap.se/key/anotheruser\r\n', decrypted, 'Decrypted text differs from plaintext.')
def test_message_encrypt(self): """ Test if message gets encrypted to destination email. """ proto = SMTPFactory( self._km, self._config).buildProtocol(('127.0.0.1', 0)) fromAddr = Address(ADDRESS_2) dest = User(ADDRESS, 'relay.leap.se', proto, ADDRESS) m = EncryptedMessage(fromAddr, dest, self._km, self._config) for line in self.EMAIL_DATA[4:12]: m.lineReceived(line) m.eomReceived() privkey = self._km.get_key( ADDRESS, openpgp.OpenPGPKey, private=True) decrypted = openpgp.decrypt_asym(m._message.get_payload(), privkey) self.assertEqual( '\r\n'.join(self.EMAIL_DATA[9:12]) + '\r\n', decrypted, 'Decrypted text differs from plaintext.')
def send_email(self, fromEmail, toEmails, fileName): """ @param fromEmail: The RFC 2821 address from which to send this message. @param toEmails: A sequence of RFC 2821 addresses to which to send this message. @param fileName: A full path to the file containing the message to send. @param deferred: A Deferred to callback or errback when sending of this message completes. """ deferred = defer.Deferred() self.log.debug("Add %s into factory (%s)", ', '.join(toEmails), self.targetDomain) self.mails.insert( 0, (Address(fromEmail), map(Address, toEmails), fileName, deferred)) return deferred
def test_message_encrypt_sign(self): """ Test if message gets encrypted to destination email and signed with sender key. """ proto = SMTPFactory( self._km, self._config).buildProtocol(('127.0.0.1', 0)) user = User(ADDRESS, 'relay.leap.se', proto, ADDRESS) fromAddr = Address(ADDRESS_2) m = EncryptedMessage(fromAddr, user, self._km, self._config) for line in self.EMAIL_DATA[4:12]: m.lineReceived(line) # trigger encryption and signing m.eomReceived() # decrypt and verify privkey = self._km.get_key( ADDRESS, openpgp.OpenPGPKey, private=True) pubkey = self._km.get_key(ADDRESS_2, openpgp.OpenPGPKey) decrypted = openpgp.decrypt_asym( m._message.get_payload(), privkey, verify=pubkey) self.assertEqual( '\r\n'.join(self.EMAIL_DATA[9:12]) + '\r\n', decrypted, 'Decrypted text differs from plaintext.')
def __init__(self, addr, code, resp): from twisted.mail.smtp import Address SMTPServerError.__init__(self, code, resp) self.addr = Address(addr)
def setUp(self): self.t = NullTranslations(StringIO('test')) self.client = Address('*****@*****.**') self.answer = 'obfs3 1.1.1.1:1111\nobfs3 2.2.2.2:2222'
def test_SMTPAutoresponder_runChecks_blacklisted(self): """runChecks() on an blacklisted email address should return False.""" emailFrom = Address('*****@*****.**') self._getIncomingLines(str(emailFrom)) self._setUpResponder() self.assertFalse(self.responder.runChecks(emailFrom))