summaryrefslogtreecommitdiff
path: root/src/leap/mail/smtp
diff options
context:
space:
mode:
Diffstat (limited to 'src/leap/mail/smtp')
-rw-r--r--src/leap/mail/smtp/gateway.py38
-rw-r--r--src/leap/mail/smtp/tests/test_gateway.py25
2 files changed, 39 insertions, 24 deletions
diff --git a/src/leap/mail/smtp/gateway.py b/src/leap/mail/smtp/gateway.py
index b022091..d58c581 100644
--- a/src/leap/mail/smtp/gateway.py
+++ b/src/leap/mail/smtp/gateway.py
@@ -48,7 +48,6 @@ from leap.mail.smtp.rfc3156 import (
RFC3156CompliantGenerator,
)
-from leap.mail.service import OutgoingMail
# replace email generator with a RFC 3156 compliant one.
from email import generator
@@ -197,22 +196,31 @@ class SMTPDelivery(object):
accepted.
"""
# try to find recipient's public key
- try:
- address = validate_address(user.dest.addrstr)
- # verify if recipient key is available in keyring
- self._km.get_key(address, OpenPGPKey) # might raise KeyNotFound
+ address = validate_address(user.dest.addrstr)
+
+ # verify if recipient key is available in keyring
+ def found(_):
log.msg("Accepting mail for %s..." % user.dest.addrstr)
signal(proto.SMTP_RECIPIENT_ACCEPTED_ENCRYPTED, user.dest.addrstr)
- except KeyNotFound:
- # if key was not found, check config to see if will send anyway.
- if self._encrypted_only:
- signal(proto.SMTP_RECIPIENT_REJECTED, user.dest.addrstr)
- raise smtp.SMTPBadRcpt(user.dest.addrstr)
- log.msg("Warning: will send an unencrypted message (because "
- "encrypted_only' is set to False).")
- signal(
- proto.SMTP_RECIPIENT_ACCEPTED_UNENCRYPTED, user.dest.addrstr)
- return lambda: EncryptedMessage(user, self._outgoing_mail)
+
+ def not_found(failure):
+ if failure.check(KeyNotFound):
+ # if key was not found, check config to see if will send anyway
+ if self._encrypted_only:
+ signal(proto.SMTP_RECIPIENT_REJECTED, user.dest.addrstr)
+ raise smtp.SMTPBadRcpt(user.dest.addrstr)
+ log.msg("Warning: will send an unencrypted message (because "
+ "encrypted_only' is set to False).")
+ signal(
+ proto.SMTP_RECIPIENT_ACCEPTED_UNENCRYPTED,
+ user.dest.addrstr)
+ else:
+ return failure
+
+ d = self._km.get_key(address, OpenPGPKey) # might raise KeyNotFound
+ d.addCallbacks(found, not_found)
+ d.addCallbac(lambda _: EncryptedMessage(user, self._outgoing_mail))
+ return d
def validateFrom(self, helo, origin):
"""
diff --git a/src/leap/mail/smtp/tests/test_gateway.py b/src/leap/mail/smtp/tests/test_gateway.py
index aeace4a..8cbff8f 100644
--- a/src/leap/mail/smtp/tests/test_gateway.py
+++ b/src/leap/mail/smtp/tests/test_gateway.py
@@ -23,6 +23,7 @@ SMTP gateway tests.
import re
from datetime import datetime
+from twisted.internet.defer import inlineCallbacks, fail
from twisted.test import proto_helpers
from mock import Mock
@@ -34,7 +35,7 @@ from leap.mail.tests import (
ADDRESS,
ADDRESS_2,
)
-from leap.keymanager import openpgp
+from leap.keymanager import openpgp, errors
# some regexps
@@ -87,7 +88,8 @@ class TestSmtpGateway(TestCaseWithKeyManager):
proto = SMTPFactory(
u'anotheruser@leap.se',
self._km,
- self._config['encrypted_only'], outgoing_mail=Mock()).buildProtocol(('127.0.0.1', 0))
+ self._config['encrypted_only'],
+ outgoing_mail=Mock()).buildProtocol(('127.0.0.1', 0))
# snip...
transport = proto_helpers.StringTransport()
proto.makeConnection(transport)
@@ -98,23 +100,26 @@ class TestSmtpGateway(TestCaseWithKeyManager):
'Did not get expected answer from gateway.')
proto.setTimeout(None)
+ @inlineCallbacks
def test_missing_key_rejects_address(self):
"""
Test if server rejects to send unencrypted when 'encrypted_only' is
True.
"""
# remove key from key manager
- pubkey = self._km.get_key(ADDRESS, openpgp.OpenPGPKey)
+ pubkey = yield self._km.get_key(ADDRESS, openpgp.OpenPGPKey)
pgp = openpgp.OpenPGPScheme(
self._soledad, gpgbinary=self.GPG_BINARY_PATH)
- pgp.delete_key(pubkey)
+ yield pgp.delete_key(pubkey)
# mock the key fetching
- self._km.fetch_keys_from_server = Mock(return_value=[])
+ self._km._fetch_keys_from_server = Mock(
+ return_value=fail(errors.KeyNotFound()))
# prepare the SMTP factory
proto = SMTPFactory(
u'anotheruser@leap.se',
self._km,
- self._config['encrypted_only'], outgoing_mail=Mock()).buildProtocol(('127.0.0.1', 0))
+ self._config['encrypted_only'],
+ outgoing_mail=Mock()).buildProtocol(('127.0.0.1', 0))
transport = proto_helpers.StringTransport()
proto.makeConnection(transport)
proto.lineReceived(self.EMAIL_DATA[0] + '\r\n')
@@ -127,18 +132,20 @@ class TestSmtpGateway(TestCaseWithKeyManager):
lines[-1],
'Address should have been rejecetd with appropriate message.')
+ @inlineCallbacks
def test_missing_key_accepts_address(self):
"""
Test if server accepts to send unencrypted when 'encrypted_only' is
False.
"""
# remove key from key manager
- pubkey = self._km.get_key(ADDRESS, openpgp.OpenPGPKey)
+ pubkey = yield self._km.get_key(ADDRESS, openpgp.OpenPGPKey)
pgp = openpgp.OpenPGPScheme(
self._soledad, gpgbinary=self.GPG_BINARY_PATH)
- pgp.delete_key(pubkey)
+ yield pgp.delete_key(pubkey)
# mock the key fetching
- self._km.fetch_keys_from_server = Mock(return_value=[])
+ self._km._fetch_keys_from_server = Mock(
+ return_value=fail(errors.KeyNotFound()))
# prepare the SMTP factory with encrypted only equal to false
proto = SMTPFactory(
u'anotheruser@leap.se',