summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKali Kaneko <kali@leap.se>2015-09-02 16:04:06 -0400
committerKali Kaneko <kali@leap.se>2015-09-21 16:59:36 -0400
commitce63b5a0277b3ff062d04a17af9e9a927b7d9b87 (patch)
tree35b30325c6e450d18e9a653fae4e83719df490e2
parent262a9a750a573ae6003ebf19d5a1867bc19d28c0 (diff)
[feature] retrieve specific smtp certificate. Closes: #4284
-rw-r--r--changes/feature_4284-download-smtp-certs1
-rw-r--r--src/leap/bitmask/crypto/certs.py38
-rw-r--r--src/leap/bitmask/services/mail/smtpbootstrapper.py6
-rw-r--r--src/leap/bitmask/services/mail/smtpconfig.py7
4 files changed, 35 insertions, 17 deletions
diff --git a/changes/feature_4284-download-smtp-certs b/changes/feature_4284-download-smtp-certs
new file mode 100644
index 00000000..929bd858
--- /dev/null
+++ b/changes/feature_4284-download-smtp-certs
@@ -0,0 +1 @@
+- Download specific smtp certificate from provider, instead of using the vpn one. Closes: #4284
diff --git a/src/leap/bitmask/crypto/certs.py b/src/leap/bitmask/crypto/certs.py
index 4b669376..017af144 100644
--- a/src/leap/bitmask/crypto/certs.py
+++ b/src/leap/bitmask/crypto/certs.py
@@ -30,7 +30,7 @@ from leap.common import certs as leap_certs
logger = get_logger()
-def download_client_cert(provider_config, path, session):
+def download_client_cert(provider_config, path, session, kind="vpn"):
"""
Downloads the client certificate for each service.
@@ -41,32 +41,45 @@ def download_client_cert(provider_config, path, session):
:param session: a fetcher.session instance. For the moment we only
support requests.sessions
:type session: requests.sessions.Session
+ :param kind: the kind of certificate being requested. Valid values are
+ "vpn" or "smtp".
+ :type kind: string
"""
- # TODO we should implement the @with_srp_auth decorator
- # again.
srp_auth = SRPAuth(provider_config)
session_id = srp_auth.get_session_id()
token = srp_auth.get_token()
cookies = None
if session_id is not None:
cookies = {"_session_id": session_id}
- cert_uri = "%s/%s/cert" % (
+
+ if kind == "vpn":
+ cert_uri_template = "%s/%s/cert"
+ method = 'get'
+ params = {}
+ elif kind == 'smtp':
+ cert_uri_template = "%s/%s/smtp_cert"
+ method = 'post'
+ params = {'address': srp_auth.get_username()}
+ else:
+ raise ValueError("Incorrect value passed to kind parameter")
+
+ cert_uri = cert_uri_template % (
provider_config.get_api_uri(),
provider_config.get_api_version())
- logger.debug('getting cert from uri: %s' % cert_uri)
+
+ logger.debug('getting %s cert from uri: %s' % (kind, cert_uri))
headers = {}
# API v2 will only support token auth, but in v1 we can send both
if token is not None:
- headers["Authorization"] = 'Token token="{0}"'.format(token)
+ headers["Authorization"] = 'Token token={0}'.format(token)
- res = session.get(cert_uri,
- verify=provider_config
- .get_ca_cert_path(),
- cookies=cookies,
- timeout=REQUEST_TIMEOUT,
- headers=headers)
+ call = getattr(session, method)
+ res = call(cert_uri, verify=provider_config.get_ca_cert_path(),
+ cookies=cookies, params=params,
+ timeout=REQUEST_TIMEOUT,
+ headers=headers, data=params)
res.raise_for_status()
client_cert = res.content
@@ -74,7 +87,6 @@ def download_client_cert(provider_config, path, session):
# XXX raise more specific exception.
raise Exception("The downloaded certificate is not a "
"valid PEM file")
-
mkdir_p(os.path.dirname(path))
try:
diff --git a/src/leap/bitmask/services/mail/smtpbootstrapper.py b/src/leap/bitmask/services/mail/smtpbootstrapper.py
index cd871803..a1b520ef 100644
--- a/src/leap/bitmask/services/mail/smtpbootstrapper.py
+++ b/src/leap/bitmask/services/mail/smtpbootstrapper.py
@@ -87,7 +87,7 @@ class SMTPBootstrapper(AbstractBootstrapper):
logger.debug("Using hostname %s for SMTP" % (hostname,))
client_cert_path = self._smtp_config.get_client_cert_path(
- self._provider_config, about_to_download=True)
+ self._userid, self._provider_config, about_to_download=True)
if not is_file(client_cert_path):
# For re-download if something is wrong with the cert
@@ -101,7 +101,7 @@ class SMTPBootstrapper(AbstractBootstrapper):
download_client_cert(self._provider_config,
client_cert_path,
- self._session)
+ self._session, kind="smtp")
def _start_smtp_service(self):
"""
@@ -117,7 +117,7 @@ class SMTPBootstrapper(AbstractBootstrapper):
host = hosts[hostname][self.IP_KEY].encode("utf-8")
port = hosts[hostname][self.PORT_KEY]
client_cert_path = self._smtp_config.get_client_cert_path(
- self._provider_config, about_to_download=True)
+ self._userid, self._provider_config, about_to_download=True)
from leap.mail.smtp import setup_smtp_gateway
diff --git a/src/leap/bitmask/services/mail/smtpconfig.py b/src/leap/bitmask/services/mail/smtpconfig.py
index 2d8de411..f78b3449 100644
--- a/src/leap/bitmask/services/mail/smtpconfig.py
+++ b/src/leap/bitmask/services/mail/smtpconfig.py
@@ -53,19 +53,24 @@ class SMTPConfig(ServiceConfig):
return self._safe_get_value("locations")
def get_client_cert_path(self,
+ userid,
providerconfig=None,
about_to_download=False):
"""
Returns the path to the certificate used by smtp
+ :param userid: the user id, in user@provider form
"""
+ leap_assert(userid, "Need an userid")
leap_assert(providerconfig, "We need a provider")
leap_assert_type(providerconfig, ProviderConfig)
+ username = userid.split("@")[0]
+
cert_path = os.path.join(get_path_prefix(),
"leap", "providers",
providerconfig.get_domain(),
- "keys", "client", "smtp.pem")
+ "keys", "client", "smtp_%s.pem" % username)
if not about_to_download:
leap_assert(os.path.exists(cert_path),