From ac55fee7ef10b5e760d72b0a98ef5dd6925fe72e Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Tue, 17 Dec 2013 15:57:30 -0400 Subject: take get_db_paths function out of class --- .../services/soledad/soledadbootstrapper.py | 54 +++++++++++----------- 1 file changed, 28 insertions(+), 26 deletions(-) (limited to 'src/leap/bitmask/services/soledad/soledadbootstrapper.py') diff --git a/src/leap/bitmask/services/soledad/soledadbootstrapper.py b/src/leap/bitmask/services/soledad/soledadbootstrapper.py index d078ae96..a92c24a0 100644 --- a/src/leap/bitmask/services/soledad/soledadbootstrapper.py +++ b/src/leap/bitmask/services/soledad/soledadbootstrapper.py @@ -59,6 +59,33 @@ class SoledadInitError(Exception): message = "Error while initializing Soledad" +def get_db_paths(uuid): + """ + Returns the secrets and local db paths needed for soledad + initialization + + :param uuid: uuid for user + :type uuid: str + + :return: a tuple with secrets, local_db paths + :rtype: tuple + """ + prefix = os.path.join(get_path_prefix(), "leap", "soledad") + secrets = "%s/%s.secret" % (prefix, uuid) + local_db = "%s/%s.db" % (prefix, uuid) + + # We remove an empty file if found to avoid complains + # about the db not being properly initialized + if is_file(local_db) and is_empty_file(local_db): + try: + os.remove(local_db) + except OSError: + logger.warning( + "Could not remove empty file %s" + % local_db) + return secrets, local_db + + class SoledadBootstrapper(AbstractBootstrapper): """ Soledad init procedure @@ -127,31 +154,6 @@ class SoledadBootstrapper(AbstractBootstrapper): """ self._soledad_retries += 1 - def _get_db_paths(self, uuid): - """ - Returns the secrets and local db paths needed for soledad - initialization - - :param uuid: uuid for user - :type uuid: str - - :return: a tuple with secrets, local_db paths - :rtype: tuple - """ - prefix = os.path.join(get_path_prefix(), "leap", "soledad") - secrets = "%s/%s.secret" % (prefix, uuid) - local_db = "%s/%s.db" % (prefix, uuid) - - # We remove an empty file if found to avoid complains - # about the db not being properly initialized - if is_file(local_db) and is_empty_file(local_db): - try: - os.remove(local_db) - except OSError: - logger.warning("Could not remove empty file %s" - % local_db) - return secrets, local_db - # initialization def load_and_sync_soledad(self): @@ -163,7 +165,7 @@ class SoledadBootstrapper(AbstractBootstrapper): uuid = self.srpauth.get_uid() token = self.srpauth.get_token() - secrets_path, local_db_path = self._get_db_paths(uuid) + secrets_path, local_db_path = get_db_paths(uuid) # TODO: Select server based on timezone (issue #3308) server_dict = self._soledad_config.get_hosts() -- cgit v1.2.3 From 8ba650488ea1f1a50b4c22758f647c9f2ee7839d Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Fri, 20 Dec 2013 13:44:53 -0400 Subject: mail logs --- src/leap/bitmask/services/soledad/soledadbootstrapper.py | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/leap/bitmask/services/soledad/soledadbootstrapper.py') diff --git a/src/leap/bitmask/services/soledad/soledadbootstrapper.py b/src/leap/bitmask/services/soledad/soledadbootstrapper.py index a92c24a0..3ab62b2e 100644 --- a/src/leap/bitmask/services/soledad/soledadbootstrapper.py +++ b/src/leap/bitmask/services/soledad/soledadbootstrapper.py @@ -302,6 +302,10 @@ class SoledadBootstrapper(AbstractBootstrapper): except SSLError as exc: logger.error("%r" % (exc,)) raise SoledadSyncError("Failed to sync soledad") + except u1db_errors.InvalidGeneration as exc: + logger.error("%r" % (exc,)) + raise SoledadSyncError("u1db: InvalidGeneration") + except Exception as exc: logger.exception("Unhandled error while syncing " "soledad: %r" % (exc,)) -- cgit v1.2.3 From a1db341a39ec336ab62e89280f9bfb315420bfb5 Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Sat, 11 Jan 2014 23:10:09 -0400 Subject: offline mode This will skip: * srp authentication with server * remote soledad configuration * keymanager sending key to server * imap fetches. Its main goal is to help us while debugging imap accounts, by cutting almost all communication with server. It will break havoc if you use it without having local keys configured. So, basically, use with care. --- .../services/soledad/soledadbootstrapper.py | 252 ++++++++++++++++----- 1 file changed, 195 insertions(+), 57 deletions(-) (limited to 'src/leap/bitmask/services/soledad/soledadbootstrapper.py') diff --git a/src/leap/bitmask/services/soledad/soledadbootstrapper.py b/src/leap/bitmask/services/soledad/soledadbootstrapper.py index 3ab62b2e..5351bcd2 100644 --- a/src/leap/bitmask/services/soledad/soledadbootstrapper.py +++ b/src/leap/bitmask/services/soledad/soledadbootstrapper.py @@ -28,15 +28,13 @@ from PySide import QtCore from u1db import errors as u1db_errors from zope.proxy import sameProxiedObjects -from twisted.internet.threads import deferToThread - from leap.bitmask.config import flags from leap.bitmask.config.providerconfig import ProviderConfig from leap.bitmask.crypto.srpauth import SRPAuth from leap.bitmask.services import download_service_config from leap.bitmask.services.abstractbootstrapper import AbstractBootstrapper from leap.bitmask.services.soledad.soledadconfig import SoledadConfig -from leap.bitmask.util import is_file, is_empty_file +from leap.bitmask.util import first, is_file, is_empty_file, make_address from leap.bitmask.util import get_path_prefix from leap.bitmask.platform_init import IS_WIN from leap.common.check import leap_assert, leap_assert_type, leap_check @@ -47,10 +45,44 @@ from leap.soledad.client import Soledad, BootstrapSequenceError logger = logging.getLogger(__name__) +""" +These mocks are replicated from imap tests and the repair utility. +They are needed for the moment to knock out the remote capabilities of soledad +during the use of the offline mode. + +They should not be needed after we allow a null remote initialization in the +soledad client, and a switch to remote sync-able mode during runtime. +""" + + +class Mock(object): + """ + A generic simple mock class + """ + def __init__(self, return_value=None): + self._return = return_value + + def __call__(self, *args, **kwargs): + return self._return + + +class MockSharedDB(object): + """ + Mocked SharedDB object to replace in soledad before + instantiating it in offline mode. + """ + get_doc = Mock() + put_doc = Mock() + lock = Mock(return_value=('atoken', 300)) + unlock = Mock(return_value=True) + + def __call__(self): + return self # TODO these exceptions could be moved to soledad itself # after settling this down. + class SoledadSyncError(Exception): message = "Error while syncing Soledad" @@ -61,7 +93,7 @@ class SoledadInitError(Exception): def get_db_paths(uuid): """ - Returns the secrets and local db paths needed for soledad + Return the secrets and local db paths needed for soledad initialization :param uuid: uuid for user @@ -88,7 +120,7 @@ def get_db_paths(uuid): class SoledadBootstrapper(AbstractBootstrapper): """ - Soledad init procedure + Soledad init procedure. """ SOLEDAD_KEY = "soledad" KEYMANAGER_KEY = "keymanager" @@ -102,6 +134,7 @@ class SoledadBootstrapper(AbstractBootstrapper): # {"passed": bool, "error": str} download_config = QtCore.Signal(dict) gen_key = QtCore.Signal(dict) + local_only_ready = QtCore.Signal(dict) soledad_timeout = QtCore.Signal() soledad_failed = QtCore.Signal() @@ -115,6 +148,9 @@ class SoledadBootstrapper(AbstractBootstrapper): self._user = "" self._password = "" + self._address = "" + self._uuid = "" + self._srpauth = None self._soledad = None @@ -130,6 +166,8 @@ class SoledadBootstrapper(AbstractBootstrapper): @property def srpauth(self): + if flags.OFFLINE is True: + return None leap_assert(self._provider_config is not None, "We need a provider config") return SRPAuth(self._provider_config) @@ -141,7 +179,7 @@ class SoledadBootstrapper(AbstractBootstrapper): def should_retry_initialization(self): """ - Returns True if we should retry the initialization. + Return True if we should retry the initialization. """ logger.debug("current retries: %s, max retries: %s" % ( self._soledad_retries, @@ -150,47 +188,94 @@ class SoledadBootstrapper(AbstractBootstrapper): def increment_retries_count(self): """ - Increments the count of initialization retries. + Increment the count of initialization retries. """ self._soledad_retries += 1 # initialization - def load_and_sync_soledad(self): + def load_offline_soledad(self, username, password, uuid): """ - Once everthing is in the right place, we instantiate and sync - Soledad + Instantiate Soledad for offline use. + + :param username: full user id (user@provider) + :type username: basestring + :param password: the soledad passphrase + :type password: unicode + :param uuid: the user uuid + :type uuid: basestring """ - # TODO this method is still too large - uuid = self.srpauth.get_uid() - token = self.srpauth.get_token() + print "UUID ", uuid + self._address = username + self._uuid = uuid + return self.load_and_sync_soledad(uuid, offline=True) + + def _get_soledad_local_params(self, uuid, offline=False): + """ + Return the locals parameters needed for the soledad initialization. + + :param uuid: the uuid of the user, used in offline mode. + :type uuid: unicode, or None. + :return: secrets_path, local_db_path, token + :rtype: tuple + """ + # in the future, when we want to be able to switch to + # online mode, this should be a proxy object too. + # Same for server_url below. + + if offline is False: + token = self.srpauth.get_token() + else: + token = "" secrets_path, local_db_path = get_db_paths(uuid) - # TODO: Select server based on timezone (issue #3308) - server_dict = self._soledad_config.get_hosts() + logger.debug('secrets_path:%s' % (secrets_path,)) + logger.debug('local_db:%s' % (local_db_path,)) + return (secrets_path, local_db_path, token) - if not server_dict.keys(): - # XXX raise more specific exception, and catch it properly! - raise Exception("No soledad server found") + def _get_soledad_server_params(self, uuid, offline): + """ + Return the remote parameters needed for the soledad initialization. - selected_server = server_dict[server_dict.keys()[0]] - server_url = "https://%s:%s/user-%s" % ( - selected_server["hostname"], - selected_server["port"], - uuid) - logger.debug("Using soledad server url: %s" % (server_url,)) + :param uuid: the uuid of the user, used in offline mode. + :type uuid: unicode, or None. + :return: server_url, cert_file + :rtype: tuple + """ + if uuid is None: + uuid = self.srpauth.get_uuid() + + if offline is True: + server_url = "http://localhost:9999/" + cert_file = "" + else: + server_url = self._pick_server(uuid) + cert_file = self._provider_config.get_ca_cert_path() - cert_file = self._provider_config.get_ca_cert_path() + return server_url, cert_file - logger.debug('local_db:%s' % (local_db_path,)) - logger.debug('secrets_path:%s' % (secrets_path,)) + def load_and_sync_soledad(self, uuid=None, offline=False): + """ + Once everthing is in the right place, we instantiate and sync + Soledad + + :param uuid: the uuid of the user, used in offline mode. + :type uuid: unicode, or None. + :param offline: whether to instantiate soledad for offline use. + :type offline: bool + """ + local_param = self._get_soledad_local_params(uuid, offline) + remote_param = self._get_soledad_server_params(uuid, offline) + + secrets_path, local_db_path, token = local_param + server_url, cert_file = remote_param try: self._try_soledad_init( uuid, secrets_path, local_db_path, server_url, cert_file, token) - except: + except Exception: # re-raise the exceptions from try_init, # we're currently handling the retries from the # soledad-launcher in the gui. @@ -198,11 +283,40 @@ class SoledadBootstrapper(AbstractBootstrapper): leap_assert(not sameProxiedObjects(self._soledad, None), "Null soledad, error while initializing") - self._do_soledad_sync() + + if flags.OFFLINE is True: + self._init_keymanager(self._address) + self.local_only_ready.emit({self.PASSED_KEY: True}) + else: + self._do_soledad_sync() + + def _pick_server(self, uuid): + """ + Choose a soledad server to sync against. + + :param uuid: the uuid for the user. + :type uuid: unicode + :returns: the server url + :rtype: unicode + """ + # TODO: Select server based on timezone (issue #3308) + server_dict = self._soledad_config.get_hosts() + + if not server_dict.keys(): + # XXX raise more specific exception, and catch it properly! + raise Exception("No soledad server found") + + selected_server = server_dict[first(server_dict.keys())] + server_url = "https://%s:%s/user-%s" % ( + selected_server["hostname"], + selected_server["port"], + uuid) + logger.debug("Using soledad server url: %s" % (server_url,)) + return server_url def _do_soledad_sync(self): """ - Does several retries to get an initial soledad sync. + Do several retries to get an initial soledad sync. """ # and now, let's sync sync_tries = self.MAX_SYNC_RETRIES @@ -231,7 +345,7 @@ class SoledadBootstrapper(AbstractBootstrapper): def _try_soledad_init(self, uuid, secrets_path, local_db_path, server_url, cert_file, auth_token): """ - Tries to initialize soledad. + Try to initialize soledad. :param uuid: user identifier :param secrets_path: path to secrets file @@ -247,6 +361,10 @@ class SoledadBootstrapper(AbstractBootstrapper): # TODO: If selected server fails, retry with another host # (issue #3309) encoding = sys.getfilesystemencoding() + + # XXX We should get a flag in soledad itself + if flags.OFFLINE is True: + Soledad._shared_db = MockSharedDB() try: self._soledad = Soledad( uuid, @@ -281,7 +399,7 @@ class SoledadBootstrapper(AbstractBootstrapper): self.soledad_failed.emit() raise except u1db_errors.HTTPError as exc: - logger.exception("Error whie initializing soledad " + logger.exception("Error while initializing soledad " "(HTTPError)") self.soledad_failed.emit() raise @@ -293,7 +411,7 @@ class SoledadBootstrapper(AbstractBootstrapper): def _try_soledad_sync(self): """ - Tries to sync soledad. + Try to sync soledad. Raises SoledadSyncError if not successful. """ try: @@ -313,7 +431,7 @@ class SoledadBootstrapper(AbstractBootstrapper): def _download_config(self): """ - Downloads the Soledad config for the given provider + Download the Soledad config for the given provider """ leap_assert(self._provider_config, @@ -332,11 +450,14 @@ class SoledadBootstrapper(AbstractBootstrapper): # XXX but honestly, this is a pretty strange entry point for that. # it feels like it should be the other way around: # load_and_sync, and from there, if needed, call download_config - self.load_and_sync_soledad() + + uuid = self.srpauth.get_uuid() + self.load_and_sync_soledad(uuid) def _get_gpg_bin_path(self): """ - Returns the path to gpg binary. + Return the path to gpg binary. + :returns: the gpg binary path :rtype: str """ @@ -364,38 +485,54 @@ class SoledadBootstrapper(AbstractBootstrapper): def _init_keymanager(self, address): """ - Initializes the keymanager. + Initialize the keymanager. + :param address: the address to initialize the keymanager with. :type address: str """ srp_auth = self.srpauth logger.debug('initializing keymanager...') - try: - self._keymanager = KeyManager( + + if flags.OFFLINE is True: + args = (address, "https://localhost", self._soledad) + kwargs = { + "session_id": "", + "ca_cert_path": "", + "api_uri": "", + "api_version": "", + "uid": self._uuid, + "gpgbinary": self._get_gpg_bin_path() + } + else: + args = ( address, "https://nicknym.%s:6425" % ( self._provider_config.get_domain(),), - self._soledad, - #token=srp_auth.get_token(), # TODO: enable token usage - session_id=srp_auth.get_session_id(), - ca_cert_path=self._provider_config.get_ca_cert_path(), - api_uri=self._provider_config.get_api_uri(), - api_version=self._provider_config.get_api_version(), - uid=srp_auth.get_uid(), - gpgbinary=self._get_gpg_bin_path()) + self._soledad + ) + kwargs = { + "session_id": srp_auth.get_session_id(), + "ca_cert_path": self._provider_config.get_ca_cert_path(), + "api_uri": self._provider_config.get_api_uri(), + "api_version": self._provider_config.get_api_version(), + "uid": srp_auth.get_uuid(), + "gpgbinary": self._get_gpg_bin_path() + } + try: + self._keymanager = KeyManager(*args, **kwargs) except Exception as exc: logger.exception(exc) raise - logger.debug('sending key to server...') - - # make sure key is in server - try: - self._keymanager.send_key(openpgp.OpenPGPKey) - except Exception as exc: - logger.error("Error sending key to server.") - logger.exception(exc) - # but we do not raise + if flags.OFFLINE is False: + # make sure key is in server + logger.debug('sending key to server...') + try: + self._keymanager.send_key(openpgp.OpenPGPKey) + except Exception as exc: + logger.error("Error sending key to server.") + logger.exception(exc) + # but we do not raise def _gen_key(self, _): """ @@ -407,7 +544,8 @@ class SoledadBootstrapper(AbstractBootstrapper): leap_assert(self._soledad is not None, "We need a non-null soledad to generate keys") - address = "%s@%s" % (self._user, self._provider_config.get_domain()) + address = make_address( + self._user, self._provider_config.get_domain()) self._init_keymanager(address) logger.debug("Retrieving key for %s" % (address,)) -- cgit v1.2.3 From 80a3983b5d3562906fcc81e8b196810d7d5a82cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Fri, 31 Jan 2014 12:30:53 -0300 Subject: Only sync soledad at account creation, otherwise defer to thread --- src/leap/bitmask/services/soledad/soledadbootstrapper.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'src/leap/bitmask/services/soledad/soledadbootstrapper.py') diff --git a/src/leap/bitmask/services/soledad/soledadbootstrapper.py b/src/leap/bitmask/services/soledad/soledadbootstrapper.py index 5351bcd2..f7217af6 100644 --- a/src/leap/bitmask/services/soledad/soledadbootstrapper.py +++ b/src/leap/bitmask/services/soledad/soledadbootstrapper.py @@ -26,6 +26,7 @@ from ssl import SSLError from PySide import QtCore from u1db import errors as u1db_errors +from twisted.internet import threads from zope.proxy import sameProxiedObjects from leap.bitmask.config import flags @@ -288,7 +289,18 @@ class SoledadBootstrapper(AbstractBootstrapper): self._init_keymanager(self._address) self.local_only_ready.emit({self.PASSED_KEY: True}) else: - self._do_soledad_sync() + try: + address = make_address( + self._user, self._provider_config.get_domain()) + self._init_keymanager(address) + self._keymanager.get_key( + address, openpgp.OpenPGPKey, + private=True, fetch_remote=False) + threads.deferToThread(self._do_soledad_sync) + except KeyNotFound: + logger.debug("Key not found. Generating key for %s" % + (address,)) + self._do_soledad_sync() def _pick_server(self, uuid): """ @@ -546,7 +558,6 @@ class SoledadBootstrapper(AbstractBootstrapper): address = make_address( self._user, self._provider_config.get_domain()) - self._init_keymanager(address) logger.debug("Retrieving key for %s" % (address,)) try: -- cgit v1.2.3 From 61420592e80d5446f8a5fba317316beeaff287e2 Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Fri, 7 Feb 2014 16:07:26 -0300 Subject: Pep8 fixes, remove commented ipdb, group imports. --- src/leap/bitmask/services/soledad/soledadbootstrapper.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/leap/bitmask/services/soledad/soledadbootstrapper.py') diff --git a/src/leap/bitmask/services/soledad/soledadbootstrapper.py b/src/leap/bitmask/services/soledad/soledadbootstrapper.py index f7217af6..9a292b18 100644 --- a/src/leap/bitmask/services/soledad/soledadbootstrapper.py +++ b/src/leap/bitmask/services/soledad/soledadbootstrapper.py @@ -508,10 +508,10 @@ class SoledadBootstrapper(AbstractBootstrapper): if flags.OFFLINE is True: args = (address, "https://localhost", self._soledad) kwargs = { - "session_id": "", - "ca_cert_path": "", - "api_uri": "", - "api_version": "", + "session_id": "", + "ca_cert_path": "", + "api_uri": "", + "api_version": "", "uid": self._uuid, "gpgbinary": self._get_gpg_bin_path() } -- cgit v1.2.3 From 29902330067f564185d7b57a864be2099f8ea2e8 Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Mon, 10 Feb 2014 14:29:09 -0300 Subject: Properly handle defer cancelling. - Fix issues related to "Cancel login does not work". - Move srpauth errback to mainwindow. - Add signal for provider setup cancel. - Add support to cancel the soledad defer. [Closes #4869] [Closes #4973] --- src/leap/bitmask/services/soledad/soledadbootstrapper.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/leap/bitmask/services/soledad/soledadbootstrapper.py') diff --git a/src/leap/bitmask/services/soledad/soledadbootstrapper.py b/src/leap/bitmask/services/soledad/soledadbootstrapper.py index 9a292b18..53846b31 100644 --- a/src/leap/bitmask/services/soledad/soledadbootstrapper.py +++ b/src/leap/bitmask/services/soledad/soledadbootstrapper.py @@ -617,4 +617,4 @@ class SoledadBootstrapper(AbstractBootstrapper): (self._gen_key, self.gen_key) ] - self.addCallbackChain(cb_chain) + return self.addCallbackChain(cb_chain) -- cgit v1.2.3 From d8ce7c3b9f8b0176f8ac617ee30072a86c52f695 Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Wed, 12 Feb 2014 09:50:57 -0300 Subject: Handle closed db exception during sync. [Closes #5130] --- src/leap/bitmask/services/soledad/soledadbootstrapper.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'src/leap/bitmask/services/soledad/soledadbootstrapper.py') diff --git a/src/leap/bitmask/services/soledad/soledadbootstrapper.py b/src/leap/bitmask/services/soledad/soledadbootstrapper.py index 9a292b18..9e797042 100644 --- a/src/leap/bitmask/services/soledad/soledadbootstrapper.py +++ b/src/leap/bitmask/services/soledad/soledadbootstrapper.py @@ -20,6 +20,7 @@ Soledad bootstrapping import logging import os import socket +import sqlite3 import sys from ssl import SSLError @@ -348,6 +349,10 @@ class SoledadBootstrapper(AbstractBootstrapper): # ubuntu folks. sync_tries -= 1 continue + except Exception as e: + logger.exception("Unhandled error while syncing " + "soledad: %r" % (e,)) + break # reached bottom, failed to sync # and there's nothing we can do... @@ -435,7 +440,9 @@ class SoledadBootstrapper(AbstractBootstrapper): except u1db_errors.InvalidGeneration as exc: logger.error("%r" % (exc,)) raise SoledadSyncError("u1db: InvalidGeneration") - + except sqlite3.ProgrammingError as e: + logger.exception("%r" % (e,)) + raise except Exception as exc: logger.exception("Unhandled error while syncing " "soledad: %r" % (exc,)) -- cgit v1.2.3 From f56c549e590d5f091690666cb3538a38700635ee Mon Sep 17 00:00:00 2001 From: drebs Date: Mon, 17 Feb 2014 16:57:45 -0300 Subject: Update keymanager auth to interact with webapp v2 (Closes #5120). --- .../bitmask/services/soledad/soledadbootstrapper.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'src/leap/bitmask/services/soledad/soledadbootstrapper.py') diff --git a/src/leap/bitmask/services/soledad/soledadbootstrapper.py b/src/leap/bitmask/services/soledad/soledadbootstrapper.py index b61d0d43..797508a7 100644 --- a/src/leap/bitmask/services/soledad/soledadbootstrapper.py +++ b/src/leap/bitmask/services/soledad/soledadbootstrapper.py @@ -287,13 +287,13 @@ class SoledadBootstrapper(AbstractBootstrapper): "Null soledad, error while initializing") if flags.OFFLINE is True: - self._init_keymanager(self._address) + self._init_keymanager(self._address, token) self.local_only_ready.emit({self.PASSED_KEY: True}) else: try: address = make_address( self._user, self._provider_config.get_domain()) - self._init_keymanager(address) + self._init_keymanager(address, token) self._keymanager.get_key( address, openpgp.OpenPGPKey, private=True, fetch_remote=False) @@ -502,12 +502,14 @@ class SoledadBootstrapper(AbstractBootstrapper): leap_check(gpgbin is not None, "Could not find gpg binary") return gpgbin - def _init_keymanager(self, address): + def _init_keymanager(self, address, token): """ Initialize the keymanager. :param address: the address to initialize the keymanager with. :type address: str + :param token: the auth token for accessing webapp. + :type token: str """ srp_auth = self.srpauth logger.debug('initializing keymanager...') @@ -515,7 +517,6 @@ class SoledadBootstrapper(AbstractBootstrapper): if flags.OFFLINE is True: args = (address, "https://localhost", self._soledad) kwargs = { - "session_id": "", "ca_cert_path": "", "api_uri": "", "api_version": "", @@ -530,7 +531,7 @@ class SoledadBootstrapper(AbstractBootstrapper): self._soledad ) kwargs = { - "session_id": srp_auth.get_session_id(), + "token": token, "ca_cert_path": self._provider_config.get_ca_cert_path(), "api_uri": self._provider_config.get_api_uri(), "api_version": self._provider_config.get_api_version(), @@ -539,15 +540,20 @@ class SoledadBootstrapper(AbstractBootstrapper): } try: self._keymanager = KeyManager(*args, **kwargs) + except KeyNotFound: + logger.debug('key for %s not found.' % address) except Exception as exc: logger.exception(exc) raise if flags.OFFLINE is False: # make sure key is in server - logger.debug('sending key to server...') + logger.debug('Trying to send key to server...') try: self._keymanager.send_key(openpgp.OpenPGPKey) + except KeyNotFound: + logger.debug('No key found for %s, will generate soon.' + % address) except Exception as exc: logger.error("Error sending key to server.") logger.exception(exc) -- cgit v1.2.3 From 388196b372f693b596cf96c6982d5b38ff0d8b56 Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Wed, 19 Feb 2014 14:44:27 -0300 Subject: Catch ProgrammingError from pysqlcipher too. Related to #5130. --- src/leap/bitmask/services/soledad/soledadbootstrapper.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/leap/bitmask/services/soledad/soledadbootstrapper.py') diff --git a/src/leap/bitmask/services/soledad/soledadbootstrapper.py b/src/leap/bitmask/services/soledad/soledadbootstrapper.py index 797508a7..7aa86a02 100644 --- a/src/leap/bitmask/services/soledad/soledadbootstrapper.py +++ b/src/leap/bitmask/services/soledad/soledadbootstrapper.py @@ -20,15 +20,16 @@ Soledad bootstrapping import logging import os import socket -import sqlite3 import sys from ssl import SSLError +from sqlite3 import ProgrammingError as sqlite_ProgrammingError from PySide import QtCore from u1db import errors as u1db_errors from twisted.internet import threads from zope.proxy import sameProxiedObjects +from pysqlcipher.dbapi2 import ProgrammingError as sqlcipher_ProgrammingError from leap.bitmask.config import flags from leap.bitmask.config.providerconfig import ProviderConfig @@ -440,7 +441,7 @@ class SoledadBootstrapper(AbstractBootstrapper): except u1db_errors.InvalidGeneration as exc: logger.error("%r" % (exc,)) raise SoledadSyncError("u1db: InvalidGeneration") - except sqlite3.ProgrammingError as e: + except (sqlite_ProgrammingError, sqlcipher_ProgrammingError) as e: logger.exception("%r" % (e,)) raise except Exception as exc: -- cgit v1.2.3 From 21e8d1a4539b0b0837ca0763de4974ac6f216bf7 Mon Sep 17 00:00:00 2001 From: drebs Date: Mon, 17 Mar 2014 13:21:51 -0300 Subject: Catch soledad invalid token error (#5191). --- .../bitmask/services/soledad/soledadbootstrapper.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'src/leap/bitmask/services/soledad/soledadbootstrapper.py') diff --git a/src/leap/bitmask/services/soledad/soledadbootstrapper.py b/src/leap/bitmask/services/soledad/soledadbootstrapper.py index 7aa86a02..ad5ee4d0 100644 --- a/src/leap/bitmask/services/soledad/soledadbootstrapper.py +++ b/src/leap/bitmask/services/soledad/soledadbootstrapper.py @@ -44,6 +44,7 @@ from leap.common.check import leap_assert, leap_assert_type, leap_check from leap.common.files import which from leap.keymanager import KeyManager, openpgp from leap.keymanager.errors import KeyNotFound +from leap.soledad.common.errors import InvalidAuthTokenError from leap.soledad.client import Soledad, BootstrapSequenceError logger = logging.getLogger(__name__) @@ -139,6 +140,7 @@ class SoledadBootstrapper(AbstractBootstrapper): gen_key = QtCore.Signal(dict) local_only_ready = QtCore.Signal(dict) soledad_timeout = QtCore.Signal() + soledad_invalid_auth_token = QtCore.Signal() soledad_failed = QtCore.Signal() def __init__(self): @@ -258,6 +260,12 @@ class SoledadBootstrapper(AbstractBootstrapper): return server_url, cert_file + def _soledad_sync_errback(self, failure): + failure.trap(InvalidAuthTokenError) + # in the case of an invalid token we have already turned off mail and + # warned the user in _do_soledad_sync() + + def load_and_sync_soledad(self, uuid=None, offline=False): """ Once everthing is in the right place, we instantiate and sync @@ -298,7 +306,8 @@ class SoledadBootstrapper(AbstractBootstrapper): self._keymanager.get_key( address, openpgp.OpenPGPKey, private=True, fetch_remote=False) - threads.deferToThread(self._do_soledad_sync) + d = threads.deferToThread(self._do_soledad_sync) + d.addErrback(self._soledad_sync_errback) except KeyNotFound: logger.debug("Key not found. Generating key for %s" % (address,)) @@ -350,6 +359,9 @@ class SoledadBootstrapper(AbstractBootstrapper): # ubuntu folks. sync_tries -= 1 continue + except InvalidAuthTokenError: + self.soledad_invalid_auth_token.emit() + raise except Exception as e: logger.exception("Unhandled error while syncing " "soledad: %r" % (e,)) @@ -444,6 +456,10 @@ class SoledadBootstrapper(AbstractBootstrapper): except (sqlite_ProgrammingError, sqlcipher_ProgrammingError) as e: logger.exception("%r" % (e,)) raise + except InvalidAuthTokenError: + # token is invalid, probably expired + logger.error('Invalid auth token while trying to sync Soledad') + raise except Exception as exc: logger.exception("Unhandled error while syncing " "soledad: %r" % (exc,)) -- cgit v1.2.3