diff options
Diffstat (limited to 'src/leap/bitmask/backend')
-rw-r--r-- | src/leap/bitmask/backend/backend.py | 2 | ||||
-rw-r--r-- | src/leap/bitmask/backend/backend_proxy.py | 33 | ||||
-rw-r--r-- | src/leap/bitmask/backend/components.py | 9 | ||||
-rw-r--r-- | src/leap/bitmask/backend/signaler.py | 1 | ||||
-rw-r--r-- | src/leap/bitmask/backend/utils.py | 26 |
5 files changed, 66 insertions, 5 deletions
diff --git a/src/leap/bitmask/backend/backend.py b/src/leap/bitmask/backend/backend.py index 37535f37..75eff8a9 100644 --- a/src/leap/bitmask/backend/backend.py +++ b/src/leap/bitmask/backend/backend.py @@ -135,7 +135,7 @@ class Backend(object): i.e.: use threads.deferToThread(this_method) instead of this_method() """ - wait_max = 5 # seconds + wait_max = 3 # seconds wait_step = 0.5 wait = 0 while self._ongoing_defers and wait < wait_max: diff --git a/src/leap/bitmask/backend/backend_proxy.py b/src/leap/bitmask/backend/backend_proxy.py index e2611251..3e79289f 100644 --- a/src/leap/bitmask/backend/backend_proxy.py +++ b/src/leap/bitmask/backend/backend_proxy.py @@ -28,6 +28,7 @@ import time import zmq from leap.bitmask.backend.api import API, STOP_REQUEST, PING_REQUEST +from leap.bitmask.backend.utils import generate_zmq_certificates_if_needed from leap.bitmask.backend.utils import get_backend_certificates import logging @@ -49,6 +50,8 @@ class BackendProxy(object): PING_INTERVAL = 2 # secs def __init__(self): + generate_zmq_certificates_if_needed() + self._socket = None # initialize ZMQ stuff: @@ -67,6 +70,7 @@ class BackendProxy(object): socket.curve_serverkey = public socket.setsockopt(zmq.RCVTIMEO, 1000) + socket.setsockopt(zmq.LINGER, 0) # Terminate early socket.connect(self.SERVER) self._socket = socket @@ -75,8 +79,23 @@ class BackendProxy(object): self._call_queue = Queue.Queue() self._worker_caller = threading.Thread(target=self._worker) + + def start(self): self._worker_caller.start() + def check_online(self): + """ + Return whether the backend is accessible or not. + You don't need to do `run` in order to use this. + + :rtype: bool + """ + # we use a small timeout in order to response quickly if the backend is + # offline + self._send_request(PING_REQUEST, retry=False, timeout=500) + self._socket.close() + return self.online + def _worker(self): """ Worker loop that processes the Queue of pending requests to do. @@ -150,7 +169,7 @@ class BackendProxy(object): if api_method == STOP_REQUEST: self._call_queue.put(STOP_REQUEST) - def _send_request(self, request): + def _send_request(self, request, retry=True, timeout=None): """ Send the given request to the server. This is used from a thread safe loop in order to avoid sending a @@ -158,6 +177,10 @@ class BackendProxy(object): :param request: the request to send. :type request: str + :param retry: whether we should retry or not in case of timeout. + :type retry: bool + :param timeout: a custom timeout (milliseconds) to wait for a response. + :type timeout: int """ # logger.debug("Sending request to backend: {0}".format(request)) self._socket.send(request) @@ -166,10 +189,16 @@ class BackendProxy(object): poll.register(self._socket, zmq.POLLIN) reply = None + tries = 0 + if not retry: + tries = self.POLL_TRIES + 1 # this means: no retries left + + if timeout is None: + timeout = self.POLL_TIMEOUT while True: - socks = dict(poll.poll(self.POLL_TIMEOUT)) + socks = dict(poll.poll(timeout)) if socks.get(self._socket) == zmq.POLLIN: reply = self._socket.recv() break diff --git a/src/leap/bitmask/backend/components.py b/src/leap/bitmask/backend/components.py index 5ef6befd..4b63af84 100644 --- a/src/leap/bitmask/backend/components.py +++ b/src/leap/bitmask/backend/components.py @@ -54,6 +54,7 @@ from leap.bitmask.services.mail.smtpconfig import SMTPConfig from leap.bitmask.services.soledad.soledadbootstrapper import \ SoledadBootstrapper from leap.bitmask.util import force_eval +from leap.bitmask.util.privilege_policies import LinuxPolicyChecker from leap.common import certs as leap_certs @@ -638,6 +639,10 @@ class EIP(object): :param domain: the domain for the provider to check :type domain: str """ + if not LinuxPolicyChecker.is_up(): + logger.error("No polkit agent running.") + return False + eip_config = eipconfig.EIPConfig() provider_config = ProviderConfig.get_provider_config(domain) @@ -914,6 +919,8 @@ class Keymanager(object): keymanager = self._keymanager_proxy try: + # NOTE: parse_openpgp_ascii_key is not in keymanager anymore + # the API for that will need some thinking public_key, private_key = keymanager.parse_openpgp_ascii_key( new_key) except (KeyAddressMismatch, KeyFingerprintMismatch) as e: @@ -974,7 +981,7 @@ class Keymanager(object): """ List all the keys stored in the local DB. """ - keys = self._keymanager_proxy.get_all_keys_in_local_db() + keys = self._keymanager_proxy.get_all_keys() self._signaler.signal(self._signaler.keymanager_keys_list, keys) def get_key_details(self, username): diff --git a/src/leap/bitmask/backend/signaler.py b/src/leap/bitmask/backend/signaler.py index 574bfa71..43cba994 100644 --- a/src/leap/bitmask/backend/signaler.py +++ b/src/leap/bitmask/backend/signaler.py @@ -60,6 +60,7 @@ class Signaler(object): socket.curve_serverkey = public socket.setsockopt(zmq.RCVTIMEO, 1000) + socket.setsockopt(zmq.LINGER, 0) # Terminate early socket.connect(self.SERVER) self._socket = socket diff --git a/src/leap/bitmask/backend/utils.py b/src/leap/bitmask/backend/utils.py index 65bf6753..18e70743 100644 --- a/src/leap/bitmask/backend/utils.py +++ b/src/leap/bitmask/backend/utils.py @@ -17,6 +17,7 @@ """ Backend utilities to handle ZMQ certificates. """ +import logging import os import shutil import stat @@ -26,10 +27,12 @@ import zmq.auth from leap.bitmask.util import get_path_prefix from leap.common.files import mkdir_p +logger = logging.getLogger(__name__) + KEYS_DIR = os.path.join(get_path_prefix(), 'leap', 'zmq_certificates') -def generate_certificates(): +def generate_zmq_certificates(): """ Generate client and server CURVE certificate files. """ @@ -62,3 +65,24 @@ def get_backend_certificates(base_dir='.'): backend_secret_file = os.path.join(KEYS_DIR, "backend.key_secret") public, secret = zmq.auth.load_certificate(backend_secret_file) return public, secret + + +def _certificates_exist(): + """ + Return whether there are certificates in place or not. + + :rtype: bool + """ + frontend_secret_file = os.path.join(KEYS_DIR, "frontend.key_secret") + backend_secret_file = os.path.join(KEYS_DIR, "backend.key_secret") + return os.path.isfile(frontend_secret_file) and \ + os.path.isfile(backend_secret_file) + + +def generate_zmq_certificates_if_needed(): + """ + Generate the needed ZMQ certificates for backend/frontend communication if + needed. + """ + if not _certificates_exist(): + generate_zmq_certificates() |