summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuben Pollan <meskio@sindominio.net>2017-03-17 00:34:12 +0100
committerRuben Pollan <meskio@sindominio.net>2017-03-17 00:42:13 +0100
commit09bf881b4f457f731c5a49e88822bc731eda2c96 (patch)
tree1c164fd3381cfe68d05a5f09f7f52f3756615b5a
parent4fe2ad820ab46f522682bcaece55a400c7038378 (diff)
[feat] report the real status of the VPN
-rw-r--r--src/leap/bitmask/cli/command.py23
-rw-r--r--src/leap/bitmask/cli/mail.py20
-rw-r--r--src/leap/bitmask/cli/vpn.py6
-rw-r--r--src/leap/bitmask/core/mail_services.py27
-rw-r--r--src/leap/bitmask/util.py27
-rw-r--r--src/leap/bitmask/vpn/_control.py2
-rw-r--r--src/leap/bitmask/vpn/_status.py37
-rw-r--r--src/leap/bitmask/vpn/fw/firewall.py16
-rw-r--r--src/leap/bitmask/vpn/process.py4
-rw-r--r--src/leap/bitmask/vpn/service.py9
-rw-r--r--src/leap/bitmask/vpn/vpn.py17
11 files changed, 114 insertions, 74 deletions
diff --git a/src/leap/bitmask/cli/command.py b/src/leap/bitmask/cli/command.py
index 068f19b..4bee325 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 fd44383..1624606 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 6982515..e413e89 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 019a104..70e7b49 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 3a7bacd..05f1c5b 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 8dfe4c6..a490934 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 a0e3842..7c8ff6b 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 5eace20..8b71a9f 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 cb67eff..6096a47 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 b5d7e52..2c7c69c 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 e19f662..dc3062a 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)