diff options
| -rw-r--r-- | src/leap/bitmask/cli/command.py | 23 | ||||
| -rw-r--r-- | src/leap/bitmask/cli/mail.py | 20 | ||||
| -rw-r--r-- | src/leap/bitmask/cli/vpn.py | 6 | ||||
| -rw-r--r-- | src/leap/bitmask/core/mail_services.py | 27 | ||||
| -rw-r--r-- | src/leap/bitmask/util.py | 27 | ||||
| -rw-r--r-- | src/leap/bitmask/vpn/_control.py | 2 | ||||
| -rw-r--r-- | src/leap/bitmask/vpn/_status.py | 37 | ||||
| -rw-r--r-- | src/leap/bitmask/vpn/fw/firewall.py | 16 | ||||
| -rw-r--r-- | src/leap/bitmask/vpn/process.py | 4 | ||||
| -rw-r--r-- | src/leap/bitmask/vpn/service.py | 9 | ||||
| -rw-r--r-- | src/leap/bitmask/vpn/vpn.py | 17 | 
11 files changed, 114 insertions, 74 deletions
| diff --git a/src/leap/bitmask/cli/command.py b/src/leap/bitmask/cli/command.py index 068f19b5..4bee325d 100644 --- a/src/leap/bitmask/cli/command.py +++ b/src/leap/bitmask/cli/command.py @@ -51,6 +51,29 @@ def default_dict_printer(result):          print(Fore.RESET + key.ljust(10) + color + value + Fore.RESET) +def print_status(status, depth=0): +    for name, v in [('  status', status)] + status['childrenStatus'].items(): +        line = Fore.RESET + name.ljust(12) +        if v['status'] in ('on', 'starting'): +            line += Fore.GREEN +        elif v['status'] == 'failure': +            line += Fore.RED +        line += v['status'] +        if v['error']: +            line += Fore.RED + " (" + v['error'] + ")" +        line += Fore.RESET +        print(line) + +    for k, v in status.items(): +        if k in ('status', 'childrenStatus', 'error'): +            continue +        if k == 'up': +            k = '↑↑↑         ' +        elif k == 'down': +            k = '↓↓↓         ' +        print(Fore.RESET + k.ljust(12) + Fore.CYAN + str(v) + Fore.RESET) + +  class Command(object):      """A generic command dispatcher.      Any command in the class attribute `commands` will be dispached and diff --git a/src/leap/bitmask/cli/mail.py b/src/leap/bitmask/cli/mail.py index fd44383b..1624606a 100644 --- a/src/leap/bitmask/cli/mail.py +++ b/src/leap/bitmask/cli/mail.py @@ -57,22 +57,4 @@ SUBCOMMANDS:              uid = self.cfg.get('bonafide', 'active', default=None)          self.data += ['status', uid] -        return self._send(self._print_status) - -    def _print_status(self, status, depth=0): -        for name, v in [('mail', status)] + status['childrenStatus'].items(): -            line = Fore.RESET + name.ljust(10) -            if v['status'] in ('on', 'starting'): -                line += Fore.GREEN -            elif v['status'] == 'failure': -                line += Fore.RED -            line += v['status'] -            if v['error']: -                line += Fore.RED + " (" + v['error'] + ")" -            line += Fore.RESET -            print(line) - -        for k, v in status.items(): -            if k in ('status', 'childrenStatus', 'error'): -                continue -            print(Fore.RESET + k.ljust(10) + Fore.CYAN + str(v) + Fore.RESET) +        return self._send(command.print_status) diff --git a/src/leap/bitmask/cli/vpn.py b/src/leap/bitmask/cli/vpn.py index 69825159..e413e89d 100644 --- a/src/leap/bitmask/cli/vpn.py +++ b/src/leap/bitmask/cli/vpn.py @@ -43,7 +43,7 @@ SUBCOMMANDS:  '''.format(name=command.appname) -    commands = ['stop', 'status', 'install', 'uninstall', +    commands = ['stop', 'install', 'uninstall',                  'enable', 'disable']      def start(self, raw_args): @@ -68,6 +68,10 @@ SUBCOMMANDS:          return self._send(command.default_dict_printer) +    def status(self, raw_args): +        self.data += ['status'] +        return self._send(command.print_status) +      def check(self, raw_args):          parser = argparse.ArgumentParser(              description='Bitmask VPN check', diff --git a/src/leap/bitmask/core/mail_services.py b/src/leap/bitmask/core/mail_services.py index 019a1048..70e7b490 100644 --- a/src/leap/bitmask/core/mail_services.py +++ b/src/leap/bitmask/core/mail_services.py @@ -47,7 +47,7 @@ from leap.bitmask.mail.imap import service as imap_service  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.util import get_gpg_bin_path +from leap.bitmask.util import get_gpg_bin_path, merge_status  from leap.soledad.client.api import Soledad  from leap.bitmask.core.uuid_map import UserMap @@ -599,30 +599,7 @@ class StandardMailService(service.MultiService, HookableService):              'keymanager': keymanager.status(userid),              'incoming': incoming_status          } - -        def key(service): -            status = childrenStatus[service] -            level = { -                "on": 0, -                "off": 1, -                "starting": 10, -                "stopping": 11, -                "failure": 100 -            } -            return level.get(status["status"], -1) - -        service = max(childrenStatus, key=key) - -        status = childrenStatus[service]["status"] -        error = childrenStatus[service]["error"] - -        res = {} -        for s in childrenStatus.values(): -            res.update(s) -        res['status'] = status -        res['error'] = error -        res['childrenStatus'] = childrenStatus -        defer.returnValue(res) +        defer.returnValue(merge_status(childrenStatus))      def get_token(self):          active_user = self._active_user diff --git a/src/leap/bitmask/util.py b/src/leap/bitmask/util.py index 3a7bacd2..05f1c5b3 100644 --- a/src/leap/bitmask/util.py +++ b/src/leap/bitmask/util.py @@ -45,6 +45,33 @@ def here(module=None):              return dirname(__file__) +def merge_status(children): + +    def key(service): +        status = children[service] +        level = { +            "on": 0, +            "off": 1, +            "starting": 10, +            "stopping": 11, +            "failure": 100 +        } +        return level.get(status["status"], -1) + +    service = max(children, key=key) + +    status = children[service]["status"] +    error = children[service]["error"] + +    res = {} +    for s in children.values(): +        res.update(s) +    res['status'] = status +    res['error'] = error +    res['childrenStatus'] = children +    return res + +  def get_gpg_bin_path():      """      Return the path to gpg binary. diff --git a/src/leap/bitmask/vpn/_control.py b/src/leap/bitmask/vpn/_control.py index 8dfe4c64..a4909346 100644 --- a/src/leap/bitmask/vpn/_control.py +++ b/src/leap/bitmask/vpn/_control.py @@ -145,7 +145,7 @@ class VPNControl(object):      @property      def status(self):          if not self._vpnproc: -            return 'OFFLINE' +            return {'status': 'off', 'error': None}          return self._vpnproc.status      @property diff --git a/src/leap/bitmask/vpn/_status.py b/src/leap/bitmask/vpn/_status.py index a0e38420..7c8ff6b0 100644 --- a/src/leap/bitmask/vpn/_status.py +++ b/src/leap/bitmask/vpn/_status.py @@ -2,6 +2,8 @@ from itertools import chain, repeat  from twisted.logger import Logger  from ._human import bytes2human +from leap.common.events import catalog, emit_async +  logger = Logger() @@ -24,7 +26,8 @@ class VPNStatus(object):      }      def __init__(self): -        self.status = 'OFFLINE' +        self._status = 'off' +        self.errcode = None          self._traffic_down = None          self._traffic_up = None @@ -49,8 +52,14 @@ class VPNStatus(object):          self.set_status(status, errcode)      def set_status(self, status, errcode): -        self.status = status +        if status in ("AUTH", "WAIT"): +            status = "starting" +        elif status == "CONNECTED": +            status = "on" + +        self._status = status          self.errcode = errcode +        emit_async(catalog.VPN_STATUS_CHANGED)      def set_traffic_status(self, status):          up, down = status @@ -58,16 +67,30 @@ class VPNStatus(object):          self._traffic_down = down      def get_traffic_status(self): -        return {'down': bytes2human(self._traffic_down), -                'up': bytes2human(self._traffic_up)} +        down = None +        up = None +        if self._traffic_down: +            down = bytes2human(self._traffic_down) +        if self._traffic_up: +            up = bytes2human(self._traffic_up) +        return {'down': down, 'up': up} + +    @property +    def status(self): +        status = self.get_traffic_status() +        status.update({ +            'status': self._status, +            'error': self.errcode +        }) +        return status      def _status_codes(self, event):          # TODO check good transitions          # TODO check valid states          _table = { -            "network_unreachable": ('OFFLINE', 'network unreachable'), -            "process_restart_tls": ('RESTARTING', 'restart tls'), -            "initialization_completed": ('ONLINE', None) +            "network_unreachable": ('off', 'network unreachable'), +            "process_restart_tls": ('starting', 'restart tls'), +            "initialization_completed": ('on', None)          }          return _table.get(event.lower()) diff --git a/src/leap/bitmask/vpn/fw/firewall.py b/src/leap/bitmask/vpn/fw/firewall.py index 5eace20a..8b71a9fd 100644 --- a/src/leap/bitmask/vpn/fw/firewall.py +++ b/src/leap/bitmask/vpn/fw/firewall.py @@ -23,6 +23,7 @@ import commands  import subprocess  from leap.bitmask.vpn.constants import IS_MAC +from leap.common.events import catalog, emit_async  class FirewallManager(object): @@ -44,7 +45,6 @@ class FirewallManager(object):          :param remotes: the gateway(s) that we will allow          :type remotes: list          """ -        self.status = 'OFF'          self._remotes = remotes      def start(self, restart=False): @@ -66,12 +66,11 @@ class FirewallManager(object):          # FIXME -- use a processprotocol          exitCode = subprocess.call(cmd + gateways) +        emit_async(catalog.VPN_STATUS_CHANGED)          if exitCode == 0: -            self.status = 'ON'              return True          else: -            self.status = 'OFF'              return False      # def tear_down_firewall(self): @@ -85,11 +84,10 @@ class FirewallManager(object):          exitCode = subprocess.call(["pkexec", self.BITMASK_ROOT,                                      "firewall", "stop"]) +        emit_async(catalog.VPN_STATUS_CHANGED)          if exitCode == 0: -            self.status = 'OFF'              return True          else: -            self.status = 'ON'              return False      def is_up(self): @@ -104,3 +102,11 @@ class FirewallManager(object):          output = commands.getstatusoutput(cmd)[0]          return output != 256 + +    @property +    def status(self): +        status = 'off' +        if self.is_up(): +            status = 'on' + +        return {'status': status, 'error': None} diff --git a/src/leap/bitmask/vpn/process.py b/src/leap/bitmask/vpn/process.py index cb67eff3..6096a473 100644 --- a/src/leap/bitmask/vpn/process.py +++ b/src/leap/bitmask/vpn/process.py @@ -136,9 +136,9 @@ class VPNProcess(protocol.ProcessProtocol, _management.VPNManagement):              internet_error.ProcessDone, internet_error.ProcessTerminated)          if err == internet_error.ProcessDone: -            status, errmsg = 'OFFLINE', None +            status, errmsg = 'off', None          elif err == internet_error.ProcessTerminated: -            status, errmsg = 'ABORTED', failure.value.exitCode +            status, errmsg = 'failure', failure.value.exitCode              if errmsg:                  logger.debug("processExited, status %d" % (errmsg,))              else: diff --git a/src/leap/bitmask/vpn/service.py b/src/leap/bitmask/vpn/service.py index b5d7e523..2c7c69ce 100644 --- a/src/leap/bitmask/vpn/service.py +++ b/src/leap/bitmask/vpn/service.py @@ -80,11 +80,14 @@ class VPNService(HookableService):              return {'result': 'stopped'}      def do_status(self): +        status = { +            'status': 'off', +            'error': None, +            'childrenStatus': {} +        }          if self._vpn:              status = self._vpn.get_status() -        else: -            status = {'VPN': 'OFF'} -        status['domain'] = self._domain +            status['domain'] = self._domain          return status      def do_check(self, domain): diff --git a/src/leap/bitmask/vpn/vpn.py b/src/leap/bitmask/vpn/vpn.py index e19f6629..dc3062af 100644 --- a/src/leap/bitmask/vpn/vpn.py +++ b/src/leap/bitmask/vpn/vpn.py @@ -18,6 +18,7 @@  from colorama import Fore +from leap.bitmask.util import merge_status  from leap.bitmask.vpn.manager import TunnelManager  from leap.bitmask.vpn.fw.firewall import FirewallManager @@ -68,14 +69,8 @@ class VPNManager(object):          return True      def get_status(self): -        vpn_status = self._vpn.status -        # TODO use firewall.is_up instead -        fw_status = self._firewall.status - -        result = {'VPN': vpn_status, -                  'firewall': fw_status} -        if vpn_status == 'CONNECTED': -            traffic = self._vpn.traffic_status -            result['↑↑↑'] = traffic['up'] -            result['↓↓↓'] = traffic['down'] -        return result +        childrenStatus = { +            "vpn": self._vpn.status, +            "firewall": self._firewall.status +        } +        return merge_status(childrenStatus) | 
