From d2e5f8406b6101971c196f40e39322e36d6bdb33 Mon Sep 17 00:00:00 2001 From: Ruben Pollan Date: Fri, 8 Dec 2017 18:10:13 +0100 Subject: [feat] Add msg_status call to the mail API To get the status of a single message providing it's mailbox and message-id. For now it only returns encryption/signature status. - Resolves: #6914 --- src/leap/bitmask/core/dispatcher.py | 12 ++++++++++++ src/leap/bitmask/core/mail_services.py | 32 ++++++++++++++++++++++++++++---- 2 files changed, 40 insertions(+), 4 deletions(-) (limited to 'src/leap/bitmask/core') diff --git a/src/leap/bitmask/core/dispatcher.py b/src/leap/bitmask/core/dispatcher.py index e97e6c0b..20c0615b 100644 --- a/src/leap/bitmask/core/dispatcher.py +++ b/src/leap/bitmask/core/dispatcher.py @@ -285,6 +285,18 @@ class MailCmd(SubCommand): 'wrong number of arguments: expected 1, got none') return mail.get_token(userid) + @register_method('dict') + def do_MSG_STATUS(self, mail, *parts, **kw): + try: + userid = parts[2] + mbox = parts[3] + message_id = parts[4] + except IndexError: + raise DispatchError( + 'wrong number of arguments: expected 3') + d = mail.do_msg_status(userid, mbox, message_id) + return d + @register_method('dict') def do_MIXNET_STATUS(self, mail, *parts, **kw): try: diff --git a/src/leap/bitmask/core/mail_services.py b/src/leap/bitmask/core/mail_services.py index ac5000fa..24bc48fa 100644 --- a/src/leap/bitmask/core/mail_services.py +++ b/src/leap/bitmask/core/mail_services.py @@ -22,6 +22,7 @@ This should be moved to the different submodules when it stabilizes. """ import json import os +import re import shutil import tempfile from collections import defaultdict @@ -48,6 +49,7 @@ try: from leap.bitmask.mail.smtp import service as smtp_service from leap.bitmask.mail.incoming.service import IncomingMail from leap.bitmask.mail.incoming.service import INCOMING_CHECK_PERIOD + from leap.bitmask.mail.utils import first from leap.soledad.client.api import Soledad HAS_MAIL = True except ImportError: @@ -625,6 +627,32 @@ class StandardMailService(service.MultiService, HookableService): token = self._service_tokens.get(userid) return {'user': userid, 'token': token} + @defer.inlineCallbacks + def do_msg_status(self, userid, mbox, msgid): + account = self._get_account(userid) + msg = yield account.get_message_by_msgid(mbox, msgid) + if msg is None: + raise Exception("Not found message id: " + msgid) + + headers = msg.get_headers() + encryption = headers.get(IncomingMail.LEAP_ENCRYPTION_HEADER, '') + signature = headers.get(IncomingMail.LEAP_SIGNATURE_HEADER, '') + + status = {} + pubkey_re = re.compile(' pubkey="([0-9A-F]*)"') + fingerprint = first(pubkey_re.findall(signature)) + status['signature'] = signature.split(';')[0] + status['sign_fp'] = fingerprint + status['encryption'] = encryption + + if ((IncomingMail.LEAP_ENCRYPTION_DECRYPTED == encryption) and + (IncomingMail.LEAP_SIGNATURE_VALID == status['signature'])): + status['secured'] = True + else: + status['secured'] = False + + defer.returnValue(status) + def do_msg_add(self, userid, raw_msg, mailbox=None): if not mailbox: mailbox = INBOX_NAME @@ -898,10 +926,6 @@ def _get_config_for_service(service, basedir, provider): return config -def first(xs): - return xs[0] - - def _pick_server(config, strategy=first): """ Picks a server from a list of possible choices. -- cgit v1.2.3