From 0a0bdc9abbca1d07c1af781567e3a51c529c0447 Mon Sep 17 00:00:00 2001 From: Ruben Pollan Date: Tue, 27 Sep 2016 15:48:29 -0500 Subject: [feat] Fetch smtp cert automatically if missing It's missing dealing with expired certs. I remove get_smtp_certificate core command. - Closes: #8486 --- docs/next-changelog.rst | 1 + src/leap/bitmask/cli/mail.py | 4 +--- src/leap/bitmask/core/dispatcher.py | 25 ------------------------- src/leap/bitmask/core/mail_services.py | 25 +++++++++++++++++++++---- src/leap/bitmask/core/service.py | 1 + 5 files changed, 24 insertions(+), 32 deletions(-) diff --git a/docs/next-changelog.rst b/docs/next-changelog.rst index bac463b..e9df07f 100644 --- a/docs/next-changelog.rst +++ b/docs/next-changelog.rst @@ -14,6 +14,7 @@ Features - `#8265 `_: Add a REST API and bitmask.js library for it. - `#8400 `_: Add manual provider registration. - `#8435 `_: Write service tokens to a file for email clients to read. +- `#8486 `_: Fetch smtp cert automatically if missing. - Use mail_auth token in the core instead of imap/smtp tokens. - `#1234 `_: Description of the new feature corresponding with issue #1234. diff --git a/src/leap/bitmask/cli/mail.py b/src/leap/bitmask/cli/mail.py index f0fa972..4625131 100644 --- a/src/leap/bitmask/cli/mail.py +++ b/src/leap/bitmask/cli/mail.py @@ -32,9 +32,7 @@ SUBCOMMANDS: disable Stop service status Display status about service get_token Returns token for the mail service - get_smtp_certificate Downloads a new smtp certificate '''.format(name=command.appname) - commands = ['enable', 'disable', 'status', 'get_token', - 'get_smtp_certificate'] + commands = ['enable', 'disable', 'status', 'get_token'] diff --git a/src/leap/bitmask/core/dispatcher.py b/src/leap/bitmask/core/dispatcher.py index 2950896..4c885ce 100644 --- a/src/leap/bitmask/core/dispatcher.py +++ b/src/leap/bitmask/core/dispatcher.py @@ -182,31 +182,6 @@ class MailCmd(SubCommand): d = mail.get_token() return d - @register_method('dict') - def do_GET_SMTP_CERTIFICATE(self, mail, *parts, **kw): - # TODO move to mail service - # TODO should ask for confirmation? like --force or something, - # if we already have a valid one. or better just refuse if cert - # exists. - # TODO how should we pass the userid?? - # - Keep an 'active' user in bonafide (last authenticated) - # (doing it now) - # - Get active user from Mail Service (maybe preferred?) - # - Have a command/method to set 'active' user. - - @defer.inlineCallbacks - def save_cert(cert_data): - userid, cert_str = cert_data - cert_path = yield mail.do_get_smtp_cert_path(userid) - with open(cert_path, 'w') as outf: - outf.write(cert_str) - defer.returnValue('certificate saved to %s' % cert_path) - - bonafide = kw['bonafide'] - d = bonafide.do_get_smtp_cert() - d.addCallback(save_cert) - return d - class WebUICmd(SubCommand): diff --git a/src/leap/bitmask/core/mail_services.py b/src/leap/bitmask/core/mail_services.py index a3cf692..91d8fca 100644 --- a/src/leap/bitmask/core/mail_services.py +++ b/src/leap/bitmask/core/mail_services.py @@ -35,6 +35,7 @@ from twisted.python import log # TODO move to bitmask.common from leap.common.service_hooks import HookableService +from leap.common.files import check_and_fix_urw_only from leap.bitmask.bonafide import config from leap.bitmask.keymanager import KeyManager from leap.bitmask.keymanager.errors import KeyNotFound @@ -488,6 +489,26 @@ class StandardMailService(service.MultiService, HookableService): # TODO --- only start instance if "autostart" is True. self.startInstance(userid, soledad, keymanager) + @defer.inlineCallbacks + def hook_on_bonafide_auth(self, **kw): + # TODO: if it's expired we should renew it + userid = kw['username'] + username, provider = userid.split('@') + cert_path = _get_smtp_client_cert_path(self._basedir, provider, + username) + if os.path.exists(cert_path): + return + + bonafide = self.parent.getServiceNamed("bonafide") + _, cert_str = yield bonafide.do_get_smtp_cert(userid) + + cert_dir = os.path.dirname(cert_path) + if not os.path.exists(cert_dir): + os.makedirs(cert_dir, mode=0700) + with open(cert_path, 'w') as outf: + outf.write(cert_str) + check_and_fix_urw_only(cert_path) + # commands def do_status(self): @@ -501,10 +522,6 @@ class StandardMailService(service.MultiService, HookableService): token = self._service_tokens.get(active_user) return defer.succeed({'user': active_user, 'token': token}) - def do_get_smtp_cert_path(self, userid): - username, provider = userid.split('@') - return _get_smtp_client_cert_path(self._basedir, provider, username) - # access to containers def get_soledad_session(self, userid): diff --git a/src/leap/bitmask/core/service.py b/src/leap/bitmask/core/service.py index bfcf0f2..27853c0 100644 --- a/src/leap/bitmask/core/service.py +++ b/src/leap/bitmask/core/service.py @@ -90,6 +90,7 @@ class BitmaskBackend(configurable.ConfigurableService): bf.register_hook('on_passphrase_entry', listener='soledad') bf.register_hook('on_bonafide_auth', listener='soledad') bf.register_hook('on_bonafide_auth', listener='keymanager') + bf.register_hook('on_bonafide_auth', listener='mail') def init_soledad(self): service = mail_services.SoledadService -- cgit v1.2.3