From 98384361a7c49ad4e0ff0127fd923a8b72cc910a Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Tue, 8 Dec 2015 21:04:11 -0400 Subject: [feat] adapt to use cred-based authentication for imap This includes getting the token for the imap authentication, and displaying it on the help window. - Resolves: #4469 - Releases: 0.10.0 --- src/leap/bitmask/backend/api.py | 2 ++ src/leap/bitmask/backend/components.py | 23 +++++++++++++++++++++++ src/leap/bitmask/backend/leapbackend.py | 7 +++++++ src/leap/bitmask/backend/leapsignaler.py | 1 + 4 files changed, 33 insertions(+) (limited to 'src/leap/bitmask/backend') diff --git a/src/leap/bitmask/backend/api.py b/src/leap/bitmask/backend/api.py index 48aa2090..134a2d56 100644 --- a/src/leap/bitmask/backend/api.py +++ b/src/leap/bitmask/backend/api.py @@ -57,6 +57,7 @@ API = ( "soledad_change_password", "soledad_close", "soledad_load_offline", + "soledad_get_service_token", "tear_fw_down", "bitmask_root_vpn_down", "user_cancel_login", @@ -135,6 +136,7 @@ SIGNALS = ( "soledad_offline_finished", "soledad_password_change_error", "soledad_password_change_ok", + "soledad_got_service_token", "srp_auth_bad_user_or_password", "srp_auth_connection_error", "srp_auth_error", diff --git a/src/leap/bitmask/backend/components.py b/src/leap/bitmask/backend/components.py index 5f34d290..a07d3bad 100644 --- a/src/leap/bitmask/backend/components.py +++ b/src/leap/bitmask/backend/components.py @@ -763,6 +763,7 @@ class Soledad(object): self._signaler = signaler self._soledad_bootstrapper = SoledadBootstrapper(signaler) self._soledad_defer = None + self._service_tokens = {} def bootstrap(self, username, domain, password): """ @@ -786,6 +787,7 @@ class Soledad(object): provider_config, username, password, download_if_needed=True) self._soledad_defer.addCallback(self._set_proxies_cb) + self._soledad_defer.addCallback(self._set_service_tokens_cb) else: if self._signaler is not None: self._signaler.signal(self._signaler.soledad_bootstrap_failed) @@ -793,6 +795,21 @@ class Soledad(object): return self._soledad_defer + def _set_service_tokens_cb(self, result): + + def register_imap_token(imap_token): + self._service_tokens['imap'] = imap_token + if self._signaler is not None: + self._signaler.signal( + self._signaler.soledad_got_service_token, + ('imap', imap_token)) + + sol = self._soledad_bootstrapper.soledad + d = sol.get_or_create_service_token('imap') + d.addCallback(register_imap_token) + d.addCallback(lambda _: result) + return d + def _set_proxies_cb(self, _): """ Update the soledad and keymanager proxies to reference the ones created @@ -803,6 +820,12 @@ class Soledad(object): zope.proxy.setProxiedObject(self._keymanager_proxy, self._soledad_bootstrapper.keymanager) + def get_service_token(self, service): + """ + Get an authentication token for a given service. + """ + return self._service_tokens.get(service, '') + def load_offline(self, username, password, uuid): """ Load the soledad database in offline mode. diff --git a/src/leap/bitmask/backend/leapbackend.py b/src/leap/bitmask/backend/leapbackend.py index cf45c4f8..d0668a1c 100644 --- a/src/leap/bitmask/backend/leapbackend.py +++ b/src/leap/bitmask/backend/leapbackend.py @@ -35,6 +35,7 @@ class LeapBackend(Backend): """ Backend server subclass, used to implement the API methods. """ + def __init__(self, bypass_checks=False, frontend_pid=None): """ Constructor for the backend. @@ -438,6 +439,12 @@ class LeapBackend(Backend): """ self._soledad.load_offline(username, password, uuid) + def soledad_get_service_token(self, service): + """ + Attempt to get an authentication token for a given service. + """ + self._soledad.get_service_token(service) + def soledad_cancel_bootstrap(self): """ Cancel the ongoing soledad bootstrapping process (if any). diff --git a/src/leap/bitmask/backend/leapsignaler.py b/src/leap/bitmask/backend/leapsignaler.py index 1ac51f5e..13a9fa5f 100644 --- a/src/leap/bitmask/backend/leapsignaler.py +++ b/src/leap/bitmask/backend/leapsignaler.py @@ -97,6 +97,7 @@ class LeapSignaler(SignalerQt): soledad_offline_finished = QtCore.Signal() soledad_password_change_error = QtCore.Signal() soledad_password_change_ok = QtCore.Signal() + soledad_got_service_token = QtCore.Signal(object) srp_auth_bad_user_or_password = QtCore.Signal() srp_auth_connection_error = QtCore.Signal() -- cgit v1.2.3 From 7b80dd1fca9828331f3327c418913539a3a303c0 Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Wed, 16 Dec 2015 15:33:25 -0400 Subject: [feat] adapt to use cred-based authentication for smtp --- src/leap/bitmask/backend/components.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'src/leap/bitmask/backend') diff --git a/src/leap/bitmask/backend/components.py b/src/leap/bitmask/backend/components.py index a07d3bad..e93ca19f 100644 --- a/src/leap/bitmask/backend/components.py +++ b/src/leap/bitmask/backend/components.py @@ -797,16 +797,19 @@ class Soledad(object): def _set_service_tokens_cb(self, result): - def register_imap_token(imap_token): - self._service_tokens['imap'] = imap_token + def register_service_token(token, service): + self._service_tokens[service] = token if self._signaler is not None: self._signaler.signal( self._signaler.soledad_got_service_token, - ('imap', imap_token)) + (service, token)) sol = self._soledad_bootstrapper.soledad d = sol.get_or_create_service_token('imap') - d.addCallback(register_imap_token) + d.addCallback(register_service_token, 'imap') + d.addCallback( + lambda _: sol.get_or_create_service_token('smtp')) + d.addCallback(register_service_token, 'smtp') d.addCallback(lambda _: result) return d @@ -1035,7 +1038,8 @@ class Mail(object): """ return threads.deferToThread( self._smtp_bootstrapper.start_smtp_service, - self._keymanager_proxy, full_user_id, download_if_needed) + self._soledad_proxy, self._keymanager_proxy, full_user_id, + download_if_needed) def start_imap_service(self, full_user_id, offline=False): """ -- cgit v1.2.3 From 8e17fb43b4cbda9ee7b386d084e01fc99345f060 Mon Sep 17 00:00:00 2001 From: Ruben Pollan Date: Mon, 21 Dec 2015 15:48:00 +0100 Subject: [feat] use fingerprint instead of key_id to address keys --- src/leap/bitmask/backend/components.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/leap/bitmask/backend') diff --git a/src/leap/bitmask/backend/components.py b/src/leap/bitmask/backend/components.py index e93ca19f..d8e4edbf 100644 --- a/src/leap/bitmask/backend/components.py +++ b/src/leap/bitmask/backend/components.py @@ -984,7 +984,8 @@ class Keymanager(object): List all the keys stored in the local DB. """ def signal_details(public_key): - details = (public_key.key_id, public_key.fingerprint) + # XXX: We should avoid the key-id + details = (public_key.fingerprint[-16:], public_key.fingerprint) self._signaler.signal(self._signaler.keymanager_key_details, details) -- cgit v1.2.3 From c866892b988912a5b9a88edfd6d1e71491617822 Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Wed, 23 Mar 2016 11:53:15 -0400 Subject: [feature] quick integration with legacy gui --- src/leap/bitmask/backend/api.py | 2 ++ src/leap/bitmask/backend/components.py | 13 ++++++++++++- src/leap/bitmask/backend/leapbackend.py | 6 ++++++ 3 files changed, 20 insertions(+), 1 deletion(-) (limited to 'src/leap/bitmask/backend') diff --git a/src/leap/bitmask/backend/api.py b/src/leap/bitmask/backend/api.py index 134a2d56..2fd983ae 100644 --- a/src/leap/bitmask/backend/api.py +++ b/src/leap/bitmask/backend/api.py @@ -42,6 +42,8 @@ API = ( "keymanager_export_keys", "keymanager_get_key_details", "keymanager_list_keys", + "pixelated_start_service", + "pixelated_stop_service", "provider_bootstrap", "provider_cancel_setup", "provider_get_all_services", diff --git a/src/leap/bitmask/backend/components.py b/src/leap/bitmask/backend/components.py index d8e4edbf..0f8864c3 100644 --- a/src/leap/bitmask/backend/components.py +++ b/src/leap/bitmask/backend/components.py @@ -26,7 +26,7 @@ import time from functools import partial -from twisted.internet import threads, defer +from twisted.internet import threads, defer, reactor from twisted.python import log import zope.interface @@ -38,6 +38,7 @@ from leap.bitmask.crypto.srpauth import SRPAuth from leap.bitmask.crypto.srpregister import SRPRegister from leap.bitmask.logs.utils import get_logger from leap.bitmask.platform_init import IS_LINUX +from leap.bitmask.pix import start_pixelated_user_agent from leap.bitmask.provider.pinned import PinnedProviders from leap.bitmask.provider.providerbootstrapper import ProviderBootstrapper from leap.bitmask.services import get_supported @@ -1086,6 +1087,16 @@ class Mail(object): """ return threads.deferToThread(self._stop_imap_service) + def start_pixelated_service(self, full_user_id): + reactor.callFromThread( + start_pixelated_user_agent, + full_user_id, + self._soledad_proxy, + self._keymanager_proxy) + + def stop_pixelated_service(self): + pass + class Authenticate(object): """ diff --git a/src/leap/bitmask/backend/leapbackend.py b/src/leap/bitmask/backend/leapbackend.py index d0668a1c..56b1597c 100644 --- a/src/leap/bitmask/backend/leapbackend.py +++ b/src/leap/bitmask/backend/leapbackend.py @@ -531,6 +531,12 @@ class LeapBackend(Backend): """ self._mail.stop_imap_service() + def pixelated_start_service(self, full_user_id): + self._mail.start_pixelated_service(full_user_id) + + def pixelated_stop_service(self): + self._mail.stop_pixelated_service() + def settings_set_selected_gateway(self, provider, gateway): """ Set the selected gateway for a given provider. -- cgit v1.2.3 From 0ce1c02dd59df3e4f23ba0b90e67644258412533 Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Mon, 4 Apr 2016 21:55:06 -0400 Subject: [bug] fail gracefully if no pixelated modules present currently, we're distributing the wheels for the pixelated modules under downloads.leap.se. bootstrap script tried to download the pixelated modules, but it fails on python versions < 2.7.9, apparently. as a workaround, I make the import of the pixelated modules a non-fatal error by setting a flag, and doing the launching of the pix UA conditional on a successful import. - Related: #8009 --- src/leap/bitmask/backend/components.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'src/leap/bitmask/backend') diff --git a/src/leap/bitmask/backend/components.py b/src/leap/bitmask/backend/components.py index 0f8864c3..0c2b3280 100644 --- a/src/leap/bitmask/backend/components.py +++ b/src/leap/bitmask/backend/components.py @@ -38,7 +38,7 @@ from leap.bitmask.crypto.srpauth import SRPAuth from leap.bitmask.crypto.srpregister import SRPRegister from leap.bitmask.logs.utils import get_logger from leap.bitmask.platform_init import IS_LINUX -from leap.bitmask.pix import start_pixelated_user_agent +from leap.bitmask import pix from leap.bitmask.provider.pinned import PinnedProviders from leap.bitmask.provider.providerbootstrapper import ProviderBootstrapper from leap.bitmask.services import get_supported @@ -1088,13 +1088,15 @@ class Mail(object): return threads.deferToThread(self._stop_imap_service) def start_pixelated_service(self, full_user_id): - reactor.callFromThread( - start_pixelated_user_agent, - full_user_id, - self._soledad_proxy, - self._keymanager_proxy) + if pix.HAS_PIXELATED: + reactor.callFromThread( + pix.start_pixelated_user_agent, + full_user_id, + self._soledad_proxy, + self._keymanager_proxy) def stop_pixelated_service(self): + # TODO stop it, somehow pass -- cgit v1.2.3 From 3340e1a898bacdd05fb6e6bf8d37596f7aff81a2 Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Thu, 7 Apr 2016 09:56:36 -0400 Subject: [feat] use same token for imap/smtp authentication This greatly simplifies the handling of the password in the thunderbird extension. - Related: #6041 --- src/leap/bitmask/backend/components.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'src/leap/bitmask/backend') diff --git a/src/leap/bitmask/backend/components.py b/src/leap/bitmask/backend/components.py index 0c2b3280..f9ad1480 100644 --- a/src/leap/bitmask/backend/components.py +++ b/src/leap/bitmask/backend/components.py @@ -806,11 +806,8 @@ class Soledad(object): (service, token)) sol = self._soledad_bootstrapper.soledad - d = sol.get_or_create_service_token('imap') - d.addCallback(register_service_token, 'imap') - d.addCallback( - lambda _: sol.get_or_create_service_token('smtp')) - d.addCallback(register_service_token, 'smtp') + d = sol.get_or_create_service_token('mail_auth') + d.addCallback(register_service_token, 'mail_auth') d.addCallback(lambda _: result) return d -- cgit v1.2.3 From 939fefc012213d3aa433caec47e2e0b19d64901e Mon Sep 17 00:00:00 2001 From: Ruben Pollan Date: Wed, 30 Mar 2016 13:51:01 +0200 Subject: [feat] Write service tokens to a file The thunderbird plugin will read the tokens from there. - Related: #6041 --- src/leap/bitmask/backend/components.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'src/leap/bitmask/backend') diff --git a/src/leap/bitmask/backend/components.py b/src/leap/bitmask/backend/components.py index f9ad1480..bc34c84c 100644 --- a/src/leap/bitmask/backend/components.py +++ b/src/leap/bitmask/backend/components.py @@ -20,8 +20,11 @@ Backend components # TODO [ ] Get rid of all this deferToThread mess, or at least contain # all of it into its own threadpool. +import json import os +import shutil import socket +import tempfile import time from functools import partial @@ -789,6 +792,8 @@ class Soledad(object): download_if_needed=True) self._soledad_defer.addCallback(self._set_proxies_cb) self._soledad_defer.addCallback(self._set_service_tokens_cb) + self._soledad_defer.addCallback(self._write_tokens_file, + username, domain) else: if self._signaler is not None: self._signaler.signal(self._signaler.soledad_bootstrap_failed) @@ -811,6 +816,23 @@ class Soledad(object): d.addCallback(lambda _: result) return d + def _write_tokens_file(self, result, username, domain): + tokens_folder = os.path.join(tempfile.gettempdir(), "bitmask_tokens") + if os.path.exists(tokens_folder): + try: + shutil.rmtree(tokens_folder) + except OSError as e: + logger.error("Can't remove tokens folder %s: %s" + % (tokens_folder, e)) + return + os.mkdir(tokens_folder, 0700) + + tokens_path = os.path.join(tokens_folder, + "%s@%s.json" % (username, domain)) + with open(tokens_path, 'w') as ftokens: + json.dump(self._service_tokens, ftokens) + return result + def _set_proxies_cb(self, _): """ Update the soledad and keymanager proxies to reference the ones created -- cgit v1.2.3 From 8361cfdf5f6f56da8e1f7297092d1458a72f9444 Mon Sep 17 00:00:00 2001 From: elijah Date: Thu, 14 Apr 2016 12:39:26 -0700 Subject: [bug] eip_can_start should return false if provider does not support eip otherwise, it tries to open eip config. - Resolves: #7538 - Releases: 0.9.2 --- src/leap/bitmask/backend/components.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/leap/bitmask/backend') diff --git a/src/leap/bitmask/backend/components.py b/src/leap/bitmask/backend/components.py index bc34c84c..03a92c88 100644 --- a/src/leap/bitmask/backend/components.py +++ b/src/leap/bitmask/backend/components.py @@ -44,7 +44,7 @@ from leap.bitmask.platform_init import IS_LINUX from leap.bitmask import pix from leap.bitmask.provider.pinned import PinnedProviders from leap.bitmask.provider.providerbootstrapper import ProviderBootstrapper -from leap.bitmask.services import get_supported +from leap.bitmask.services import get_supported, EIP_SERVICE from leap.bitmask.services.eip import eipconfig from leap.bitmask.services.eip import get_openvpn_management from leap.bitmask.services.eip.eipbootstrapper import EIPBootstrapper @@ -651,8 +651,10 @@ class EIP(object): logger.error("No polkit agent running.") return False - eip_config = eipconfig.EIPConfig() provider_config = ProviderConfig.get_provider_config(domain) + if EIP_SERVICE not in provider_config.get_services(): + return False + eip_config = eipconfig.EIPConfig() api_version = provider_config.get_api_version() eip_config.set_api_version(api_version) -- cgit v1.2.3 From e9e9abc4ec26be29b3a6b09e6a0b67786269183b Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Fri, 29 Jan 2016 13:18:36 -0800 Subject: [feature] privileged bitmask helper This is still quite untested, and a bit hacky, but the main idea behind let us have a daemonized bitmask helper, that should be installed by the Bitmask installer. Its responsibilities are to launch the vpn process as a privileged user, and start/stop the firewall. --- src/leap/bitmask/backend/components.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/leap/bitmask/backend') diff --git a/src/leap/bitmask/backend/components.py b/src/leap/bitmask/backend/components.py index 03a92c88..acb562c7 100644 --- a/src/leap/bitmask/backend/components.py +++ b/src/leap/bitmask/backend/components.py @@ -647,7 +647,7 @@ class EIP(object): :param domain: the domain for the provider to check :type domain: str """ - if not LinuxPolicyChecker.is_up(): + if IS_LINUX and not LinuxPolicyChecker.is_up(): logger.error("No polkit agent running.") return False -- cgit v1.2.3 From 229f803235ae9b9a71313d11071c7a0fbea0a681 Mon Sep 17 00:00:00 2001 From: elijah Date: Mon, 18 Apr 2016 23:44:12 -0700 Subject: [feature] add email panel to preferences --- src/leap/bitmask/backend/components.py | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) (limited to 'src/leap/bitmask/backend') diff --git a/src/leap/bitmask/backend/components.py b/src/leap/bitmask/backend/components.py index acb562c7..3192e1c4 100644 --- a/src/leap/bitmask/backend/components.py +++ b/src/leap/bitmask/backend/components.py @@ -576,8 +576,10 @@ class EIP(object): self._signaler.eip_uninitialized_provider) return - eip_config = eipconfig.EIPConfig() provider_config = ProviderConfig.get_provider_config(domain) + if EIP_SERVICE not in provider_config.get_services(): + return + eip_config = eipconfig.EIPConfig() api_version = provider_config.get_api_version() eip_config.set_api_version(api_version) @@ -1003,13 +1005,11 @@ class Keymanager(object): def get_key_details(self, username): """ - List all the keys stored in the local DB. + Get information on our primary key pair """ def signal_details(public_key): - # XXX: We should avoid the key-id - details = (public_key.fingerprint[-16:], public_key.fingerprint) self._signaler.signal(self._signaler.keymanager_key_details, - details) + public_key.get_dict()) d = self._keymanager_proxy.get_key(username, openpgp.OpenPGPKey) @@ -1215,15 +1215,13 @@ class Authenticate(object): def get_logged_in_status(self): """ - Signal if the user is currently logged in or not. + Signal if the user is currently logged in or not. If logged in, + authenticated username is passed as argument to the signal. """ if self._signaler is None: return - signal = None if self._is_logged_in(): - signal = self._signaler.srp_status_logged_in + self._signaler.signal(self._signaler.srp_status_logged_in) else: - signal = self._signaler.srp_status_not_logged_in - - self._signaler.signal(signal) + self._signaler.signal(self._signaler.srp_status_not_logged_in) -- cgit v1.2.3 From 5a1dd49debdcd9a1ce0568217e9411d1e45a3cad Mon Sep 17 00:00:00 2001 From: Ruben Pollan Date: Mon, 25 Apr 2016 20:24:04 -0300 Subject: [bug] represent keys correctly in preference window --- src/leap/bitmask/backend/components.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'src/leap/bitmask/backend') diff --git a/src/leap/bitmask/backend/components.py b/src/leap/bitmask/backend/components.py index 3192e1c4..ba64fd65 100644 --- a/src/leap/bitmask/backend/components.py +++ b/src/leap/bitmask/backend/components.py @@ -994,14 +994,14 @@ class Keymanager(object): d.addCallback(export) d.addErrback(log_error) + @defer.inlineCallbacks def list_keys(self): """ List all the keys stored in the local DB. """ - d = self._keymanager_proxy.get_all_keys() - d.addCallback( - lambda keys: - self._signaler.signal(self._signaler.keymanager_keys_list, keys)) + keys = yield self._keymanager_proxy.get_all_keys() + keydicts = [dict(key) for key in keys] + self._signaler.signal(self._signaler.keymanager_keys_list, keydicts) def get_key_details(self, username): """ @@ -1009,7 +1009,7 @@ class Keymanager(object): """ def signal_details(public_key): self._signaler.signal(self._signaler.keymanager_key_details, - public_key.get_dict()) + dict(public_key)) d = self._keymanager_proxy.get_key(username, openpgp.OpenPGPKey) -- cgit v1.2.3