From 3fae5a6fdaad3e06770797e6cf8c21d1804ddc22 Mon Sep 17 00:00:00 2001 From: Ruben Pollan Date: Wed, 29 Nov 2017 11:42:42 +0100 Subject: [feat] update bitmask-root if needed Chech the hash of the installed bitmask root and sign as not installed if doesn't match the one we have in the bundle. Also for running bitmask-root, if there is more than one (in /usr/local/sbin and /usr/sbin) run the one with higher version number. - Resolves: #9020 --- src/leap/bitmask/vpn/helpers/__init__.py | 45 +++++++++++++++++++++++--------- src/leap/bitmask/vpn/launchers/linux.py | 25 +++++++++++++++--- 2 files changed, 55 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/leap/bitmask/vpn/helpers/__init__.py b/src/leap/bitmask/vpn/helpers/__init__.py index 0378448d..8f8c1227 100644 --- a/src/leap/bitmask/vpn/helpers/__init__.py +++ b/src/leap/bitmask/vpn/helpers/__init__.py @@ -1,5 +1,6 @@ -from os import remove, chmod +from os import remove, chmod, access, R_OK from shutil import copyfile +from hashlib import sha512 import os.path import sys @@ -32,32 +33,52 @@ if IS_LINUX: if STANDALONE: copyfile(openvpn_from, OPENVPN_LOCAL) - chmod(OPENVPN_LOCAL, 0700) + chmod(OPENVPN_LOCAL, 0744) def uninstall(): remove(BITMASK_ROOT_LOCAL) remove(POLKIT_LOCAL) + remove(OPENVPN_LOCAL) def check(): - helper = ( - os.path.exists(BITMASK_ROOT_LOCAL) or - os.path.isfile(BITMASK_ROOT_SYSTEM)) - polkit = ( - os.path.exists(POLKIT_LOCAL) or - os.path.exists(POLKIT_SYSTEM)) - openvpn = ( - os.path.exists(OPENVPN_LOCAL) or - os.path.exists(OPENVPN_SYSTEM)) + helper = _is_up_to_date(_config.get_bitmask_helper_path(), + BITMASK_ROOT_LOCAL, + BITMASK_ROOT_SYSTEM) + polkit = _is_up_to_date(_config.get_bitmask_polkit_policy_path(), + POLKIT_LOCAL, + POLKIT_SYSTEM) + openvpn = (os.path.exists(OPENVPN_SYSTEM) or + _is_up_to_date(_config.get_bitmask_openvpn_path(), + OPENVPN_LOCAL, "")) return is_pkexec_in_system() and helper and polkit and openvpn -if IS_MAC: + def _is_up_to_date(src, local, system): + if src is None or not access(src, R_OK): + return True + + src_digest = digest(src) + if access(system, R_OK) and src_digest == digest(system): + return True + if access(local, R_OK) and src_digest == digest(local): + return True + + return False + + +elif IS_MAC: def check(): # XXX check if bitmask-helper is running return True +def digest(path): + with open(path, 'r') as f: + s = f.read() + return sha512(s).digest() + + def main(): if sys.argv[-1] == 'install': install() diff --git a/src/leap/bitmask/vpn/launchers/linux.py b/src/leap/bitmask/vpn/launchers/linux.py index bff2d8cb..b6bf278e 100644 --- a/src/leap/bitmask/vpn/launchers/linux.py +++ b/src/leap/bitmask/vpn/launchers/linux.py @@ -22,14 +22,15 @@ Linux VPN launcher implementation. import os import psutil +import subprocess from twisted.internet import defer, reactor from twisted.internet.endpoints import clientFromString, connectProtocol from twisted.logger import Logger -from leap.bitmask.util import STANDALONE from leap.bitmask.vpn.utils import first, force_eval from leap.bitmask.vpn import constants +from leap.bitmask.vpn import _config from leap.bitmask.vpn.privilege import LinuxPolicyChecker from leap.bitmask.vpn.management import ManagementProtocol from leap.bitmask.vpn.launcher import VPNLauncher @@ -85,15 +86,33 @@ class LinuxVPNLauncher(VPNLauncher): class BITMASK_ROOT(object): def __call__(self): + current_version = self._version(_config.get_bitmask_helper_path()) + _sys = constants.BITMASK_ROOT_SYSTEM - _local = constants.BITMASK_ROOT_LOCAL + _sys_version = 0 if os.path.isfile(_sys): + _sys_version = self._version(_sys) + + _local = constants.BITMASK_ROOT_LOCAL + _local_version = 0 + if os.path.isfile(_local): + _local_version = self._version(_local) + + if _sys_version == current_version: + return _sys + elif _local_version == current_version: + return _local + elif _sys_version != 0 and _sys_version >= _local_version: return _sys - elif os.path.isfile(_local): + elif _local_version != 0: return _local else: return 'bitmask-root' + def _version(self, bitmask_root): + out = subprocess.check_output(['python', bitmask_root, "version"]) + return int(out) + class OPENVPN_BIN_PATH(object): def __call__(self): _sys = constants.OPENVPN_SYSTEM -- cgit v1.2.3