From a733e83ae0bcbcc9daa0cba0aa4704f499406394 Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Tue, 29 Apr 2014 10:40:48 -0500 Subject: add elijah's root-wrapper in python --- src/leap/bitmask/services/eip/linuxvpnlauncher.py | 48 +++++++++++++++++------ src/leap/bitmask/services/eip/vpnlauncher.py | 5 +++ 2 files changed, 40 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/leap/bitmask/services/eip/linuxvpnlauncher.py b/src/leap/bitmask/services/eip/linuxvpnlauncher.py index 8747daa6..988970a5 100644 --- a/src/leap/bitmask/services/eip/linuxvpnlauncher.py +++ b/src/leap/bitmask/services/eip/linuxvpnlauncher.py @@ -36,6 +36,8 @@ from leap.bitmask.util import first logger = logging.getLogger(__name__) +COM = commands + class EIPNoPolkitAuthAgentAvailable(VPNLauncherException): pass @@ -64,12 +66,13 @@ def _is_auth_agent_running(): """ # the [x] thing is to avoid grep match itself polkit_options = [ - 'ps aux | grep polkit-[g]nome-authentication-agent-1', - 'ps aux | grep polkit-[k]de-authentication-agent-1', - 'ps aux | grep polkit-[m]ate-authentication-agent-1', - 'ps aux | grep [l]xpolkit' + 'ps aux | grep "polkit-[g]nome-authentication-agent-1"', + 'ps aux | grep "polkit-[k]de-authentication-agent-1"', + 'ps aux | grep "polkit-[m]ate-authentication-agent-1"', + 'ps aux | grep "[l]xpolkit"' ] is_running = [commands.getoutput(cmd) for cmd in polkit_options] + print "IS RUNNING ->", is_running return any(is_running) @@ -85,22 +88,23 @@ def _try_to_launch_agent(): # will do "sh -c 'foo'", so if we do not quoute it we'll end # up with a invocation to the python interpreter. And that # is bad. + logger.debug("Trying to launch polkit agent") subprocess.call(["python -m leap.bitmask.util.polkit_agent"], shell=True, env=env) except Exception as exc: logger.exception(exc) +SYSTEM_CONFIG = "/etc/leap" +leapfile = lambda f: "%s/%s" % (SYSTEM_CONFIG, f) + + class LinuxVPNLauncher(VPNLauncher): PKEXEC_BIN = 'pkexec' OPENVPN_BIN = 'openvpn' OPENVPN_BIN_PATH = os.path.join( get_path_prefix(), "..", "apps", "eip", OPENVPN_BIN) - SYSTEM_CONFIG = "/etc/leap" - UP_DOWN_FILE = "resolv-update" - UP_DOWN_PATH = "%s/%s" % (SYSTEM_CONFIG, UP_DOWN_FILE) - # We assume this is there by our openvpn dependency, and # we will put it there on the bundle too. # TODO adapt to the bundle path. @@ -110,10 +114,23 @@ class LinuxVPNLauncher(VPNLauncher): OPENVPN_DOWN_ROOT_BASE, OPENVPN_DOWN_ROOT_FILE) - UP_SCRIPT = DOWN_SCRIPT = UP_DOWN_PATH - UPDOWN_FILES = (UP_DOWN_PATH,) + UPDOWN_FILE = "vpn-updown" + + # vpn-up and vpn-down are hard-links to vpn-updown + UP_FILE = "vpn-up" + DOWN_FILE = "vpn-down" + UP_SCRIPT = leapfile(UP_FILE) + DOWN_SCRIPT = leapfile(DOWN_FILE) + + RESOLV_UPDATE_FILE = "resolv-update" + RESOLV_UPDATE_SCRIPT = leapfile(RESOLV_UPDATE_FILE) + + RESOLVCONF_FILE = "update-resolv-conf" + RESOLVCONF_SCRIPT = leapfile(RESOLVCONF_FILE) + + UPDOWN_FILES = (UP_SCRIPT, DOWN_SCRIPT) POLKIT_PATH = LinuxPolicyChecker.get_polkit_path() - OTHER_FILES = (POLKIT_PATH, ) + OTHER_FILES = (POLKIT_PATH, RESOLV_UPDATE_SCRIPT, RESOLVCONF_SCRIPT) @classmethod def maybe_pkexec(kls): @@ -131,7 +148,7 @@ class LinuxVPNLauncher(VPNLauncher): if _is_pkexec_in_system(): if not _is_auth_agent_running(): _try_to_launch_agent() - time.sleep(0.5) + time.sleep(2) if _is_auth_agent_running(): pkexec_possibilities = which(kls.PKEXEC_BIN) leap_assert(len(pkexec_possibilities) > 0, @@ -158,6 +175,7 @@ class LinuxVPNLauncher(VPNLauncher): """ # we use `super` in order to send the class to use missing = super(LinuxVPNLauncher, kls).missing_other_files() + print "MISSING OTHER", missing if flags.STANDALONE: polkit_file = LinuxPolicyChecker.get_polkit_path() @@ -221,7 +239,11 @@ class LinuxVPNLauncher(VPNLauncher): cmd = '#!/bin/sh\n' cmd += 'mkdir -p "%s"\n' % (to, ) - cmd += 'cp "%s/%s" "%s"\n' % (frompath, kls.UP_DOWN_FILE, to) + cmd += 'cp "%s/%s" "%s"\n' % (frompath, kls.UPDOWN_FILE, to) + cmd += 'ln -f %s/%s %s/%s\n' % (to, kls.UPDOWN_FILE, to, kls.UP_FILE) + cmd += 'ln -f %s/%s %s/%s\n' % (to, kls.UPDOWN_FILE, to, kls.DOWN_FILE) + cmd += 'cp "%s/%s" "%s"\n' % (frompath, kls.RESOLVCONF_FILE, to) + cmd += 'cp "%s/%s" "%s"\n' % (frompath, kls.RESOLV_UDATE_FILE, to) cmd += 'cp "%s" "%s"\n' % (pol_file, kls.POLKIT_PATH) cmd += 'chmod 644 "%s"\n' % (kls.POLKIT_PATH, ) diff --git a/src/leap/bitmask/services/eip/vpnlauncher.py b/src/leap/bitmask/services/eip/vpnlauncher.py index 99cae7f9..ab423bcd 100644 --- a/src/leap/bitmask/services/eip/vpnlauncher.py +++ b/src/leap/bitmask/services/eip/vpnlauncher.py @@ -226,6 +226,11 @@ class VPNLauncher(object): '--down', '\"%s\"' % (kls.DOWN_SCRIPT,) ] + args += [ + '--up-restart', + '--persist-tun' + ] + ########################################################### # For the time being we are disabling the usage of the # down-root plugin, because it doesn't quite work as -- cgit v1.2.3 From 0c2f23bd8a76ec8e36639c965ccc15303bd66b10 Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Mon, 5 May 2014 12:18:09 -0500 Subject: use bitmask-root to bring up the firewall --- src/leap/bitmask/services/eip/linuxvpnlauncher.py | 23 ++++++++++------- src/leap/bitmask/services/eip/vpnprocess.py | 30 ++++++++++++++++++++++- 2 files changed, 43 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/leap/bitmask/services/eip/linuxvpnlauncher.py b/src/leap/bitmask/services/eip/linuxvpnlauncher.py index 988970a5..ef670303 100644 --- a/src/leap/bitmask/services/eip/linuxvpnlauncher.py +++ b/src/leap/bitmask/services/eip/linuxvpnlauncher.py @@ -101,7 +101,12 @@ leapfile = lambda f: "%s/%s" % (SYSTEM_CONFIG, f) class LinuxVPNLauncher(VPNLauncher): PKEXEC_BIN = 'pkexec' + + # FIXME should get the absolute path to openvpn. See #5592 OPENVPN_BIN = 'openvpn' + BITMASK_ROOT = "/usr/sbin/bitmask-root" + + # FIXME get ABSOLUTE PATH OPENVPN_BIN_PATH = os.path.join( get_path_prefix(), "..", "apps", "eip", OPENVPN_BIN) @@ -114,23 +119,23 @@ class LinuxVPNLauncher(VPNLauncher): OPENVPN_DOWN_ROOT_BASE, OPENVPN_DOWN_ROOT_FILE) - UPDOWN_FILE = "vpn-updown" - - # vpn-up and vpn-down are hard-links to vpn-updown - UP_FILE = "vpn-up" - DOWN_FILE = "vpn-down" - UP_SCRIPT = leapfile(UP_FILE) - DOWN_SCRIPT = leapfile(DOWN_FILE) - + # XXX Should be able to pick the right resolvconf script + # on the fly. RESOLV_UPDATE_FILE = "resolv-update" RESOLV_UPDATE_SCRIPT = leapfile(RESOLV_UPDATE_FILE) RESOLVCONF_FILE = "update-resolv-conf" RESOLVCONF_SCRIPT = leapfile(RESOLVCONF_FILE) + UP_SCRIPT = RESOLVCONF_SCRIPT + DOWN_SCRIPT = RESOLVCONF_SCRIPT + UPDOWN_FILES = (UP_SCRIPT, DOWN_SCRIPT) + + # XXX GET BOTH POLKIT FILES: the one for vpn and the other for the wrapper POLKIT_PATH = LinuxPolicyChecker.get_polkit_path() - OTHER_FILES = (POLKIT_PATH, RESOLV_UPDATE_SCRIPT, RESOLVCONF_SCRIPT) + OTHER_FILES = (POLKIT_PATH, RESOLV_UPDATE_SCRIPT, RESOLVCONF_SCRIPT, + BITMASK_ROOT) @classmethod def maybe_pkexec(kls): diff --git a/src/leap/bitmask/services/eip/vpnprocess.py b/src/leap/bitmask/services/eip/vpnprocess.py index c7b8071c..71a21cdb 100644 --- a/src/leap/bitmask/services/eip/vpnprocess.py +++ b/src/leap/bitmask/services/eip/vpnprocess.py @@ -21,6 +21,7 @@ import logging import os import shutil import socket +import subprocess import sys from itertools import chain, repeat @@ -36,10 +37,11 @@ except ImportError: from leap.bitmask.config import flags from leap.bitmask.config.providerconfig import ProviderConfig from leap.bitmask.services.eip import get_vpn_launcher +from leap.bitmask.services.eip import linuxvpnlauncher from leap.bitmask.services.eip.eipconfig import EIPConfig from leap.bitmask.services.eip.udstelnet import UDSTelnet from leap.bitmask.util import first -from leap.bitmask.platform_init import IS_MAC +from leap.bitmask.platform_init import IS_MAC, IS_LINUX from leap.common.check import leap_assert, leap_assert_type logger = logging.getLogger(__name__) @@ -181,6 +183,14 @@ class VPN(object): logger.info("Another vpn process is running. Will try to stop it.") vpnproc.stop_if_already_running() + # XXX we try to bring the firewall up + if IS_LINUX: + firewall_up = self._launch_firewall() + if not firewall_up: + logger.error("Could not bring firewall up, " + "aborting openvpn launch.") + return + cmd = vpnproc.getCommand() env = os.environ for key, val in vpnproc.vpn_env.items(): @@ -198,6 +208,24 @@ class VPN(object): self._pollers.extend(poll_list) self._start_pollers() + def _launch_firewall(self): + """ + Launch the firewall using the privileged wrapper. + + :returns: True if the exitcode of calling the root helper in a + subprocess is 0. + :rtype: bool + """ + # XXX this is a temporary solution for being able to use the root + # helper while we still control the openvpn process. + + # XXX could check for wrapper existence, check it's root owned etc. + # XXX could check that the iptables rules are in place. + + BM_ROOT = linuxvpnlauncher.LinuxVPNLauncher.BITMASK_ROOT + exitCode = subprocess.call([BM_ROOT, "firewall", "start"]) + return True if exitCode is 0 else False + def _kill_if_left_alive(self, tries=0): """ Check if the process is still alive, and sends a -- cgit v1.2.3 From 120fd991719897c9a62a797842036a030246ff7c Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Tue, 6 May 2014 20:14:39 -0500 Subject: pass gateways to firewall up --- src/leap/bitmask/services/eip/linuxvpnlauncher.py | 1 + src/leap/bitmask/services/eip/vpnlauncher.py | 52 +++++++++++++++-------- src/leap/bitmask/services/eip/vpnprocess.py | 16 +++++-- 3 files changed, 49 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/leap/bitmask/services/eip/linuxvpnlauncher.py b/src/leap/bitmask/services/eip/linuxvpnlauncher.py index ef670303..e1c8e680 100644 --- a/src/leap/bitmask/services/eip/linuxvpnlauncher.py +++ b/src/leap/bitmask/services/eip/linuxvpnlauncher.py @@ -220,6 +220,7 @@ class LinuxVPNLauncher(VPNLauncher): # we use `super` in order to send the class to use command = super(LinuxVPNLauncher, kls).get_vpn_command( eipconfig, providerconfig, socket_host, socket_port, openvpn_verb) + command.insert(0, kls.BITMASK_ROOT + "openvpn start") pkexec = kls.maybe_pkexec() if pkexec: diff --git a/src/leap/bitmask/services/eip/vpnlauncher.py b/src/leap/bitmask/services/eip/vpnlauncher.py index ab423bcd..c95545a2 100644 --- a/src/leap/bitmask/services/eip/vpnlauncher.py +++ b/src/leap/bitmask/services/eip/vpnlauncher.py @@ -105,12 +105,45 @@ class VPNLauncher(object): UP_SCRIPT = None DOWN_SCRIPT = None + @classmethod + @abstractmethod + def get_gateways(kls, eipconfig, providerconfig): + """ + Return the selected gateways for a given provider, looking at the EIP + config file. + + :param eipconfig: eip configuration object + :type eipconfig: EIPConfig + + :param providerconfig: provider specific configuration + :type providerconfig: ProviderConfig + + :rtype: list + """ + gateways = [] + leap_settings = LeapSettings() + domain = providerconfig.get_domain() + gateway_conf = leap_settings.get_selected_gateway(domain) + + if gateway_conf == leap_settings.GATEWAY_AUTOMATIC: + gateway_selector = VPNGatewaySelector(eipconfig) + gateways = gateway_selector.get_gateways() + else: + gateways = [gateway_conf] + + if not gateways: + logger.error('No gateway was found!') + raise VPNLauncherException('No gateway was found!') + + logger.debug("Using gateways ips: {0}".format(', '.join(gateways))) + return gateways + @classmethod @abstractmethod def get_vpn_command(kls, eipconfig, providerconfig, socket_host, socket_port, openvpn_verb=1): """ - Returns the platform dependant vpn launching command + Return the platform-dependant vpn command for launching openvpn. Might raise: OpenVPNNotFoundException, @@ -154,22 +187,7 @@ class VPNLauncher(object): if openvpn_verb is not None: args += ['--verb', '%d' % (openvpn_verb,)] - gateways = [] - leap_settings = LeapSettings() - domain = providerconfig.get_domain() - gateway_conf = leap_settings.get_selected_gateway(domain) - - if gateway_conf == leap_settings.GATEWAY_AUTOMATIC: - gateway_selector = VPNGatewaySelector(eipconfig) - gateways = gateway_selector.get_gateways() - else: - gateways = [gateway_conf] - - if not gateways: - logger.error('No gateway was found!') - raise VPNLauncherException('No gateway was found!') - - logger.debug("Using gateways ips: {0}".format(', '.join(gateways))) + gateways = kls.get_gateways(providerconfig) for gw in gateways: args += ['--remote', gw, '1194', 'udp'] diff --git a/src/leap/bitmask/services/eip/vpnprocess.py b/src/leap/bitmask/services/eip/vpnprocess.py index 71a21cdb..cbcdd5c6 100644 --- a/src/leap/bitmask/services/eip/vpnprocess.py +++ b/src/leap/bitmask/services/eip/vpnprocess.py @@ -185,7 +185,8 @@ class VPN(object): # XXX we try to bring the firewall up if IS_LINUX: - firewall_up = self._launch_firewall() + gateways = vpnproc.getGateways() + firewall_up = self._launch_firewall(gateways) if not firewall_up: logger.error("Could not bring firewall up, " "aborting openvpn launch.") @@ -208,10 +209,13 @@ class VPN(object): self._pollers.extend(poll_list) self._start_pollers() - def _launch_firewall(self): + def _launch_firewall(self, gateways): """ Launch the firewall using the privileged wrapper. + :param gateways: + :type gateways: list + :returns: True if the exitcode of calling the root helper in a subprocess is 0. :rtype: bool @@ -223,7 +227,7 @@ class VPN(object): # XXX could check that the iptables rules are in place. BM_ROOT = linuxvpnlauncher.LinuxVPNLauncher.BITMASK_ROOT - exitCode = subprocess.call([BM_ROOT, "firewall", "start"]) + exitCode = subprocess.call([BM_ROOT, "firewall", "start"] + gateways) return True if exitCode is 0 else False def _kill_if_left_alive(self, tries=0): @@ -861,6 +865,12 @@ class VPNProcess(protocol.ProcessProtocol, VPNManager): logger.debug("Running VPN with command: {0}".format(command)) return command + def getGateways(self): + gateways = self._launcher.get_gateways( + self._eipconfig, self._providerconfig) + print "getGateways --> ", gateways + return gateways + # shutdown def killProcess(self): -- cgit v1.2.3 From 6d18c78b384dc6624cde25cb41a998587661ffa5 Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Tue, 6 May 2014 21:16:18 -0500 Subject: use bitmask-root with pkexec --- src/leap/bitmask/services/eip/linuxvpnlauncher.py | 7 ++++--- src/leap/bitmask/services/eip/vpnlauncher.py | 5 ++++- src/leap/bitmask/services/eip/vpnprocess.py | 8 ++++++-- 3 files changed, 14 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/leap/bitmask/services/eip/linuxvpnlauncher.py b/src/leap/bitmask/services/eip/linuxvpnlauncher.py index e1c8e680..791c318c 100644 --- a/src/leap/bitmask/services/eip/linuxvpnlauncher.py +++ b/src/leap/bitmask/services/eip/linuxvpnlauncher.py @@ -72,7 +72,6 @@ def _is_auth_agent_running(): 'ps aux | grep "[l]xpolkit"' ] is_running = [commands.getoutput(cmd) for cmd in polkit_options] - print "IS RUNNING ->", is_running return any(is_running) @@ -180,7 +179,6 @@ class LinuxVPNLauncher(VPNLauncher): """ # we use `super` in order to send the class to use missing = super(LinuxVPNLauncher, kls).missing_other_files() - print "MISSING OTHER", missing if flags.STANDALONE: polkit_file = LinuxPolicyChecker.get_polkit_path() @@ -220,7 +218,10 @@ class LinuxVPNLauncher(VPNLauncher): # we use `super` in order to send the class to use command = super(LinuxVPNLauncher, kls).get_vpn_command( eipconfig, providerconfig, socket_host, socket_port, openvpn_verb) - command.insert(0, kls.BITMASK_ROOT + "openvpn start") + + command.insert(0, kls.BITMASK_ROOT) + command.insert(1, "openvpn") + command.insert(2, "start") pkexec = kls.maybe_pkexec() if pkexec: diff --git a/src/leap/bitmask/services/eip/vpnlauncher.py b/src/leap/bitmask/services/eip/vpnlauncher.py index c95545a2..20b4d87d 100644 --- a/src/leap/bitmask/services/eip/vpnlauncher.py +++ b/src/leap/bitmask/services/eip/vpnlauncher.py @@ -125,8 +125,11 @@ class VPNLauncher(object): domain = providerconfig.get_domain() gateway_conf = leap_settings.get_selected_gateway(domain) + print "GETTING GATEWAYS -----" + if gateway_conf == leap_settings.GATEWAY_AUTOMATIC: gateway_selector = VPNGatewaySelector(eipconfig) + print "auto: getting from selector" gateways = gateway_selector.get_gateways() else: gateways = [gateway_conf] @@ -187,7 +190,7 @@ class VPNLauncher(object): if openvpn_verb is not None: args += ['--verb', '%d' % (openvpn_verb,)] - gateways = kls.get_gateways(providerconfig) + gateways = kls.get_gateways(eipconfig, providerconfig) for gw in gateways: args += ['--remote', gw, '1194', 'udp'] diff --git a/src/leap/bitmask/services/eip/vpnprocess.py b/src/leap/bitmask/services/eip/vpnprocess.py index cbcdd5c6..beb33db8 100644 --- a/src/leap/bitmask/services/eip/vpnprocess.py +++ b/src/leap/bitmask/services/eip/vpnprocess.py @@ -226,8 +226,11 @@ class VPN(object): # XXX could check for wrapper existence, check it's root owned etc. # XXX could check that the iptables rules are in place. + print "LAUNCHING FIREWALL --", gateways + BM_ROOT = linuxvpnlauncher.LinuxVPNLauncher.BITMASK_ROOT - exitCode = subprocess.call([BM_ROOT, "firewall", "start"] + gateways) + exitCode = subprocess.call(["pkexec", + BM_ROOT, "firewall", "start"] + gateways) return True if exitCode is 0 else False def _kill_if_left_alive(self, tries=0): @@ -862,7 +865,8 @@ class VPNProcess(protocol.ProcessProtocol, VPNManager): if not isinstance(c, str): command[i] = c.encode(encoding) - logger.debug("Running VPN with command: {0}".format(command)) + logger.debug("Running VPN with command: ") + logger.debug("{0}".format(" ".join(command))) return command def getGateways(self): -- cgit v1.2.3 From d8d7d2b781aea558d7e39d397a85c15ac9839abb Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Wed, 7 May 2014 08:14:01 -0500 Subject: tear the firewall down when openvpn is finished --- src/leap/bitmask/services/eip/vpnprocess.py | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/leap/bitmask/services/eip/vpnprocess.py b/src/leap/bitmask/services/eip/vpnprocess.py index beb33db8..c09daf78 100644 --- a/src/leap/bitmask/services/eip/vpnprocess.py +++ b/src/leap/bitmask/services/eip/vpnprocess.py @@ -183,7 +183,7 @@ class VPN(object): logger.info("Another vpn process is running. Will try to stop it.") vpnproc.stop_if_already_running() - # XXX we try to bring the firewall up + # we try to bring the firewall up if IS_LINUX: gateways = vpnproc.getGateways() firewall_up = self._launch_firewall(gateways) @@ -226,13 +226,20 @@ class VPN(object): # XXX could check for wrapper existence, check it's root owned etc. # XXX could check that the iptables rules are in place. - print "LAUNCHING FIREWALL --", gateways - BM_ROOT = linuxvpnlauncher.LinuxVPNLauncher.BITMASK_ROOT exitCode = subprocess.call(["pkexec", BM_ROOT, "firewall", "start"] + gateways) return True if exitCode is 0 else False + def _tear_down_firewall(self): + """ + Tear the firewall down using the privileged wrapper. + """ + BM_ROOT = linuxvpnlauncher.LinuxVPNLauncher.BITMASK_ROOT + exitCode = subprocess.call(["pkexec", + BM_ROOT, "firewall", "stop"]) + return True if exitCode is 0 else False + def _kill_if_left_alive(self, tries=0): """ Check if the process is still alive, and sends a @@ -245,6 +252,17 @@ class VPN(object): while tries < self.TERMINATE_MAXTRIES: if self._vpnproc.transport.pid is None: logger.debug("Process has been happily terminated.") + + # we try to bring the firewall up + # XXX We could keep some state to be sure it was the + # user who did turn EIP off. + if IS_LINUX: + firewall_down = self._tear_down_firewall() + if firewall_down: + logger.debug("Firewall down") + else: + logger.warning("Could not tear firewall down") + return else: logger.debug("Process did not die, waiting...") -- cgit v1.2.3 From 2f47053b631df231e4fcceafef227cf905b660cc Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Wed, 7 May 2014 09:18:23 -0500 Subject: only switch the fw down if user asked for eip down --- src/leap/bitmask/backend.py | 3 +++ src/leap/bitmask/services/eip/vpnlauncher.py | 2 -- src/leap/bitmask/services/eip/vpnprocess.py | 8 ++++++-- 3 files changed, 9 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/leap/bitmask/backend.py b/src/leap/bitmask/backend.py index 2bfcbfa0..bd26bb1c 100644 --- a/src/leap/bitmask/backend.py +++ b/src/leap/bitmask/backend.py @@ -1048,6 +1048,9 @@ class Backend(object): def stop_eip(self, shutdown=False): """ Stop the EIP service. + + :param shutdown: + :type shutdown: bool """ self._call_queue.put(("eip", "stop", None, shutdown)) diff --git a/src/leap/bitmask/services/eip/vpnlauncher.py b/src/leap/bitmask/services/eip/vpnlauncher.py index 20b4d87d..af3116f2 100644 --- a/src/leap/bitmask/services/eip/vpnlauncher.py +++ b/src/leap/bitmask/services/eip/vpnlauncher.py @@ -125,8 +125,6 @@ class VPNLauncher(object): domain = providerconfig.get_domain() gateway_conf = leap_settings.get_selected_gateway(domain) - print "GETTING GATEWAYS -----" - if gateway_conf == leap_settings.GATEWAY_AUTOMATIC: gateway_selector = VPNGatewaySelector(eipconfig) print "auto: getting from selector" diff --git a/src/leap/bitmask/services/eip/vpnprocess.py b/src/leap/bitmask/services/eip/vpnprocess.py index c09daf78..a8b833d0 100644 --- a/src/leap/bitmask/services/eip/vpnprocess.py +++ b/src/leap/bitmask/services/eip/vpnprocess.py @@ -161,6 +161,8 @@ class VPN(object): self._signaler = kwargs['signaler'] self._openvpn_verb = flags.OPENVPN_VERBOSITY + self._user_stopped = False + def start(self, *args, **kwargs): """ Starts the openvpn subprocess. @@ -172,6 +174,7 @@ class VPN(object): :type kwargs: dict """ logger.debug('VPN: start') + self._user_stopped = False self._stop_pollers() kwargs['openvpn_verb'] = self._openvpn_verb kwargs['signaler'] = self._signaler @@ -242,7 +245,7 @@ class VPN(object): def _kill_if_left_alive(self, tries=0): """ - Check if the process is still alive, and sends a + Check if the process is still alive, and send a SIGKILL after a timeout period. :param tries: counter of tries, used in recursion @@ -256,7 +259,7 @@ class VPN(object): # we try to bring the firewall up # XXX We could keep some state to be sure it was the # user who did turn EIP off. - if IS_LINUX: + if IS_LINUX and self._user_stopped: firewall_down = self._tear_down_firewall() if firewall_down: logger.debug("Firewall down") @@ -298,6 +301,7 @@ class VPN(object): """ from twisted.internet import reactor self._stop_pollers() + self._user_stopped = True # First we try to be polite and send a SIGTERM... if self._vpnproc: -- cgit v1.2.3 From 14b208105a6417aefd351f5b38f33bb89358ddcd Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Wed, 7 May 2014 11:24:53 -0500 Subject: hardcode openvpn binary for bundle --- src/leap/bitmask/services/eip/linuxvpnlauncher.py | 36 +++++------------------ src/leap/bitmask/services/eip/vpnlauncher.py | 35 ++++++++++++---------- 2 files changed, 27 insertions(+), 44 deletions(-) (limited to 'src') diff --git a/src/leap/bitmask/services/eip/linuxvpnlauncher.py b/src/leap/bitmask/services/eip/linuxvpnlauncher.py index 791c318c..6d54c27b 100644 --- a/src/leap/bitmask/services/eip/linuxvpnlauncher.py +++ b/src/leap/bitmask/services/eip/linuxvpnlauncher.py @@ -100,41 +100,19 @@ leapfile = lambda f: "%s/%s" % (SYSTEM_CONFIG, f) class LinuxVPNLauncher(VPNLauncher): PKEXEC_BIN = 'pkexec' - - # FIXME should get the absolute path to openvpn. See #5592 - OPENVPN_BIN = 'openvpn' BITMASK_ROOT = "/usr/sbin/bitmask-root" - # FIXME get ABSOLUTE PATH - OPENVPN_BIN_PATH = os.path.join( - get_path_prefix(), "..", "apps", "eip", OPENVPN_BIN) - # We assume this is there by our openvpn dependency, and # we will put it there on the bundle too. - # TODO adapt to the bundle path. - OPENVPN_DOWN_ROOT_BASE = "/usr/lib/openvpn/" - OPENVPN_DOWN_ROOT_FILE = "openvpn-plugin-down-root.so" - OPENVPN_DOWN_ROOT_PATH = "%s/%s" % ( - OPENVPN_DOWN_ROOT_BASE, - OPENVPN_DOWN_ROOT_FILE) - - # XXX Should be able to pick the right resolvconf script - # on the fly. - RESOLV_UPDATE_FILE = "resolv-update" - RESOLV_UPDATE_SCRIPT = leapfile(RESOLV_UPDATE_FILE) - - RESOLVCONF_FILE = "update-resolv-conf" - RESOLVCONF_SCRIPT = leapfile(RESOLVCONF_FILE) - - UP_SCRIPT = RESOLVCONF_SCRIPT - DOWN_SCRIPT = RESOLVCONF_SCRIPT - - UPDOWN_FILES = (UP_SCRIPT, DOWN_SCRIPT) + if flags.STANDALONE: + OPENVPN_BIN_PATH = "/usr/sbin/leap-openvpn" + else: + OPENVPN_BIN_PATH = "/usr/sbin/openvpn" - # XXX GET BOTH POLKIT FILES: the one for vpn and the other for the wrapper POLKIT_PATH = LinuxPolicyChecker.get_polkit_path() - OTHER_FILES = (POLKIT_PATH, RESOLV_UPDATE_SCRIPT, RESOLVCONF_SCRIPT, - BITMASK_ROOT) + + # XXX openvpn binary TOO + OTHER_FILES = (POLKIT_PATH, BITMASK_ROOT) @classmethod def maybe_pkexec(kls): diff --git a/src/leap/bitmask/services/eip/vpnlauncher.py b/src/leap/bitmask/services/eip/vpnlauncher.py index af3116f2..ed49ba59 100644 --- a/src/leap/bitmask/services/eip/vpnlauncher.py +++ b/src/leap/bitmask/services/eip/vpnlauncher.py @@ -168,16 +168,19 @@ class VPNLauncher(object): leap_assert_type(eipconfig, EIPConfig) leap_assert_type(providerconfig, ProviderConfig) - kwargs = {} - if flags.STANDALONE: - kwargs['path_extension'] = os.path.join( - get_path_prefix(), "..", "apps", "eip") - - openvpn_possibilities = which(kls.OPENVPN_BIN, **kwargs) - if len(openvpn_possibilities) == 0: + # XXX this still has to be changed on osx and windows accordingly + #kwargs = {} + #openvpn_possibilities = which(kls.OPENVPN_BIN, **kwargs) + #if not openvpn_possibilities: + #raise OpenVPNNotFoundException() + #openvpn = first(openvpn_possibilities) + # ----------------------------------------- + if not os.path.isfile(kls.OPENVPN_BIN_PATH): + logger.warning("Could not find openvpn bin in path %s" % ( + kls.OPENVPN_BIN_PATH)) raise OpenVPNNotFoundException() - openvpn = first(openvpn_possibilities) + openvpn = kls.OPENVPN_BIN_PATH args = [] args += [ @@ -295,13 +298,15 @@ class VPNLauncher(object): :rtype: list """ - leap_assert(kls.UPDOWN_FILES is not None, - "Need to define UPDOWN_FILES for this particular " - "launcher before calling this method") - file_exist = partial(_has_updown_scripts, warn=False) - zipped = zip(kls.UPDOWN_FILES, map(file_exist, kls.UPDOWN_FILES)) - missing = filter(lambda (path, exists): exists is False, zipped) - return [path for path, exists in missing] + # XXX remove when we ditch UPDOWN in osx and win too + #leap_assert(kls.UPDOWN_FILES is not None, + #"Need to define UPDOWN_FILES for this particular " + #"launcher before calling this method") + #file_exist = partial(_has_updown_scripts, warn=False) + #zipped = zip(kls.UPDOWN_FILES, map(file_exist, kls.UPDOWN_FILES)) + #missing = filter(lambda (path, exists): exists is False, zipped) + #return [path for path, exists in missing] + return [] @classmethod def missing_other_files(kls): -- cgit v1.2.3 From ca0e9b85a831f716a0959c5fdb9dbb571515de97 Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Wed, 7 May 2014 15:42:56 -0500 Subject: tear down fw on quit-action too --- src/leap/bitmask/gui/mainwindow.py | 5 +++++ src/leap/bitmask/gui/twisted_main.py | 1 - src/leap/bitmask/services/eip/vpnprocess.py | 22 +++++++++++++--------- 3 files changed, 18 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/leap/bitmask/gui/mainwindow.py b/src/leap/bitmask/gui/mainwindow.py index a5c81983..70fad204 100644 --- a/src/leap/bitmask/gui/mainwindow.py +++ b/src/leap/bitmask/gui/mainwindow.py @@ -19,6 +19,7 @@ Main window for Bitmask. """ import logging import socket +import time from threading import Condition from datetime import datetime @@ -2067,6 +2068,10 @@ class MainWindow(QtGui.QMainWindow): logger.debug('Terminating vpn') self._backend.stop_eip(shutdown=True) + # XXX this *has* to block, since we have some delay in vpn.terminate + # it should receive a signal from backend that everything is clear to + # proceed, or timeout happened. + self._cancel_ongoing_defers() # TODO missing any more cancels? diff --git a/src/leap/bitmask/gui/twisted_main.py b/src/leap/bitmask/gui/twisted_main.py index f39d0bbe..dfd69033 100644 --- a/src/leap/bitmask/gui/twisted_main.py +++ b/src/leap/bitmask/gui/twisted_main.py @@ -26,7 +26,6 @@ logger = logging.getLogger(__name__) def stop(): - logger.debug("Really stoping all the things...") QtCore.QCoreApplication.sendPostedEvents() QtCore.QCoreApplication.flush() try: diff --git a/src/leap/bitmask/services/eip/vpnprocess.py b/src/leap/bitmask/services/eip/vpnprocess.py index a8b833d0..420db971 100644 --- a/src/leap/bitmask/services/eip/vpnprocess.py +++ b/src/leap/bitmask/services/eip/vpnprocess.py @@ -223,9 +223,6 @@ class VPN(object): subprocess is 0. :rtype: bool """ - # XXX this is a temporary solution for being able to use the root - # helper while we still control the openvpn process. - # XXX could check for wrapper existence, check it's root owned etc. # XXX could check that the iptables rules are in place. @@ -257,8 +254,6 @@ class VPN(object): logger.debug("Process has been happily terminated.") # we try to bring the firewall up - # XXX We could keep some state to be sure it was the - # user who did turn EIP off. if IS_LINUX and self._user_stopped: firewall_down = self._tear_down_firewall() if firewall_down: @@ -310,12 +305,17 @@ class VPN(object): # ...but we also trigger a countdown to be unpolite # if strictly needed. - - # XXX Watch out! This will fail NOW since we are running - # openvpn as root as a workaround for some connection issues. reactor.callLater( self.TERMINATE_WAIT, self._kill_if_left_alive) + if shutdown: + if IS_LINUX and self._user_stopped: + firewall_down = self._tear_down_firewall() + if firewall_down: + logger.debug("Firewall down") + else: + logger.warning("Could not tear firewall down") + def _start_pollers(self): """ Iterate through the registered observers @@ -892,9 +892,13 @@ class VPNProcess(protocol.ProcessProtocol, VPNManager): return command def getGateways(self): + """ + Get the gateways from the appropiate launcher. + + :rtype: list + """ gateways = self._launcher.get_gateways( self._eipconfig, self._providerconfig) - print "getGateways --> ", gateways return gateways # shutdown -- cgit v1.2.3 From d68e35c611638a57bbda99665f9685e5ae6fcd23 Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Wed, 7 May 2014 17:24:12 -0500 Subject: introduce delay on shutdown after resolvconf was daemonized --- src/leap/bitmask/gui/mainwindow.py | 9 ++++++--- src/leap/bitmask/services/eip/vpnlauncher.py | 1 - 2 files changed, 6 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/leap/bitmask/gui/mainwindow.py b/src/leap/bitmask/gui/mainwindow.py index 70fad204..681432b3 100644 --- a/src/leap/bitmask/gui/mainwindow.py +++ b/src/leap/bitmask/gui/mainwindow.py @@ -2068,9 +2068,12 @@ class MainWindow(QtGui.QMainWindow): logger.debug('Terminating vpn') self._backend.stop_eip(shutdown=True) - # XXX this *has* to block, since we have some delay in vpn.terminate - # it should receive a signal from backend that everything is clear to - # proceed, or timeout happened. + # XXX this *has* to wait for a reasonable lapse, since we have some + # delay in vpn.terminate. + # For a better solution it should receive be + # signaled from backend that + # everything is clear to proceed, or timeout happened. + time.sleep(1.5) self._cancel_ongoing_defers() diff --git a/src/leap/bitmask/services/eip/vpnlauncher.py b/src/leap/bitmask/services/eip/vpnlauncher.py index ed49ba59..dc72f276 100644 --- a/src/leap/bitmask/services/eip/vpnlauncher.py +++ b/src/leap/bitmask/services/eip/vpnlauncher.py @@ -127,7 +127,6 @@ class VPNLauncher(object): if gateway_conf == leap_settings.GATEWAY_AUTOMATIC: gateway_selector = VPNGatewaySelector(eipconfig) - print "auto: getting from selector" gateways = gateway_selector.get_gateways() else: gateways = [gateway_conf] -- cgit v1.2.3 From 745ae7f55836ff331d9176b52cc98df451a3c2ef Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Thu, 8 May 2014 10:41:55 -0500 Subject: change paths for installing the latest helpers --- src/leap/bitmask/platform_init/initializers.py | 9 +-- src/leap/bitmask/services/eip/linuxvpnlauncher.py | 83 +++++++++++++---------- src/leap/bitmask/util/privilege_policies.py | 82 +--------------------- 3 files changed, 52 insertions(+), 122 deletions(-) (limited to 'src') diff --git a/src/leap/bitmask/platform_init/initializers.py b/src/leap/bitmask/platform_init/initializers.py index d93efbc6..f2710c58 100644 --- a/src/leap/bitmask/platform_init/initializers.py +++ b/src/leap/bitmask/platform_init/initializers.py @@ -366,15 +366,8 @@ def _linux_install_missing_scripts(badexec, notfound): fd, tempscript = tempfile.mkstemp(prefix="leap_installer-") polfd, pol_tempfile = tempfile.mkstemp(prefix="leap_installer-") try: - path = launcher.OPENVPN_BIN_PATH - policy_contents = privilege_policies.get_policy_contents(path) - - with os.fdopen(polfd, 'w') as f: - f.write(policy_contents) - pkexec = first(launcher.maybe_pkexec()) - scriptlines = launcher.cmd_for_missing_scripts(installer_path, - pol_tempfile) + scriptlines = launcher.cmd_for_missing_scripts(installer_path) with os.fdopen(fd, 'w') as f: f.write(scriptlines) diff --git a/src/leap/bitmask/services/eip/linuxvpnlauncher.py b/src/leap/bitmask/services/eip/linuxvpnlauncher.py index 6d54c27b..9e6176cb 100644 --- a/src/leap/bitmask/services/eip/linuxvpnlauncher.py +++ b/src/leap/bitmask/services/eip/linuxvpnlauncher.py @@ -25,7 +25,6 @@ import sys import time from leap.bitmask.config import flags -from leap.bitmask.util import privilege_policies from leap.bitmask.util.privilege_policies import LinuxPolicyChecker from leap.common.files import which from leap.bitmask.services.eip.vpnlauncher import VPNLauncher @@ -111,8 +110,15 @@ class LinuxVPNLauncher(VPNLauncher): POLKIT_PATH = LinuxPolicyChecker.get_polkit_path() + if flags.STANDALONE: + RESOLVCONF_BIN_PATH = "/usr/local/sbin/leap-resolvconf" + else: + # this only will work with debian/ubuntu distros. + RESOLVCONF_BIN_PATH = "/sbin/resolvconf" + # XXX openvpn binary TOO - OTHER_FILES = (POLKIT_PATH, BITMASK_ROOT) + OTHER_FILES = (POLKIT_PATH, BITMASK_ROOT, OPENVPN_BIN_PATH, + RESOLVCONF_BIN_PATH) @classmethod def maybe_pkexec(kls): @@ -144,27 +150,20 @@ class LinuxVPNLauncher(VPNLauncher): logger.warning("System has no pkexec") raise EIPNoPkexecAvailable() - @classmethod - def missing_other_files(kls): - """ - 'Extend' the VPNLauncher's missing_other_files to check if the polkit - files is outdated, in the case of an standalone bundle. - If the polkit file that is in OTHER_FILES exists but is not up to date, - it is added to the missing list. - - :returns: a list of missing files - :rtype: list of str - """ + #@classmethod + #def missing_other_files(kls): + #""" + #'Extend' the VPNLauncher's missing_other_files to check if the polkit + #files is outdated, in the case of an standalone bundle. + #If the polkit file that is in OTHER_FILES exists but is not up to date, + #it is added to the missing list. +# + #:returns: a list of missing files + #:rtype: list of str + #""" # we use `super` in order to send the class to use - missing = super(LinuxVPNLauncher, kls).missing_other_files() - - if flags.STANDALONE: - polkit_file = LinuxPolicyChecker.get_polkit_path() - if polkit_file not in missing: - if privilege_policies.is_policy_outdated(kls.OPENVPN_BIN_PATH): - missing.append(polkit_file) - - return missing + #missing = super(LinuxVPNLauncher, kls).missing_other_files() + #return missing @classmethod def get_vpn_command(kls, eipconfig, providerconfig, socket_host, @@ -208,30 +207,44 @@ class LinuxVPNLauncher(VPNLauncher): return command @classmethod - def cmd_for_missing_scripts(kls, frompath, pol_file): + def cmd_for_missing_scripts(kls, frompath): """ Returns a sh script that can copy the missing files. - :param frompath: The path where the up/down scripts live + :param frompath: The path where the helper files live :type frompath: str - :param pol_file: The path where the dynamically generated - policy file lives - :type pol_file: str :rtype: str """ - to = kls.SYSTEM_CONFIG + # no system config for now + # sys_config = kls.SYSTEM_CONFIG + (polkit_file, openvpn_bin_file, + bitmask_root_file, resolvconf_bin_file) = map( + lambda p: os.path.split(p)[-1], + (kls.POLKIT_PATH, kls.OPENVPN_BIN_PATH, + kls.BITMASK_ROOT, kls.RESOLVCONF_BIN_PATH)) cmd = '#!/bin/sh\n' - cmd += 'mkdir -p "%s"\n' % (to, ) - cmd += 'cp "%s/%s" "%s"\n' % (frompath, kls.UPDOWN_FILE, to) - cmd += 'ln -f %s/%s %s/%s\n' % (to, kls.UPDOWN_FILE, to, kls.UP_FILE) - cmd += 'ln -f %s/%s %s/%s\n' % (to, kls.UPDOWN_FILE, to, kls.DOWN_FILE) - cmd += 'cp "%s/%s" "%s"\n' % (frompath, kls.RESOLVCONF_FILE, to) - cmd += 'cp "%s/%s" "%s"\n' % (frompath, kls.RESOLV_UDATE_FILE, to) - cmd += 'cp "%s" "%s"\n' % (pol_file, kls.POLKIT_PATH) + cmd += 'mkdir -p /usr/local/sbin\n' + + cmd += 'cp "%s" "%s"\n' % (os.path.join(frompath, polkit_file), + kls.POLKIT_PATH) cmd += 'chmod 644 "%s"\n' % (kls.POLKIT_PATH, ) + cmd += 'cp "%s" "%s"\n' % (os.path.join(frompath, bitmask_root_file), + kls.BITMASK_ROOT) + cmd += 'chmod 744 "%s"\n' % (kls.BITMASK_ROOT, ) + + if flags.STANDALONE: + cmd += 'cp "%s" "%s"\n' % ( + os.path.join(frompath, openvpn_bin_file), + kls.OPENVPN_BIN_PATH) + cmd += 'chmod 744 "%s"\n' % (kls.POLKIT_PATH, ) + + cmd += 'cp "%s" "%s"\n' % ( + os.path.join(frompath, resolvconf_bin_file), + kls.RESOLVCONF_BIN_PATH) + cmd += 'chmod 744 "%s"\n' % (kls.POLKIT_PATH, ) return cmd @classmethod diff --git a/src/leap/bitmask/util/privilege_policies.py b/src/leap/bitmask/util/privilege_policies.py index 72442553..9d1e2c9a 100644 --- a/src/leap/bitmask/util/privilege_policies.py +++ b/src/leap/bitmask/util/privilege_policies.py @@ -27,35 +27,6 @@ from abc import ABCMeta, abstractmethod logger = logging.getLogger(__name__) -POLICY_TEMPLATE = """ - - - - LEAP Project - https://leap.se/ - - - Runs the openvpn binary - Ejecuta el binario openvpn - OpenVPN needs that you authenticate to start - - OpenVPN necesita autorizacion para comenzar - - package-x-generic - - yes - yes - yes - - {path} - true - - -""" - - def is_missing_policy_permissions(): """ Returns True if we do not have implemented a policy checker for this @@ -76,36 +47,6 @@ def is_missing_policy_permissions(): return policy_checker().is_missing_policy_permissions() -def get_policy_contents(openvpn_path): - """ - Returns the contents that the policy file should have. - - :param openvpn_path: the openvpn path to use in the polkit file - :type openvpn_path: str - :rtype: str - """ - return POLICY_TEMPLATE.format(path=openvpn_path) - - -def is_policy_outdated(path): - """ - Returns if the existing polkit file is outdated, comparing if the path - is correct. - - :param path: the path that should have the polkit file. - :type path: str. - :rtype: bool - """ - _system = platform.system() - platform_checker = _system + "PolicyChecker" - policy_checker = globals().get(platform_checker, None) - if policy_checker is None: - logger.debug("we could not find a policy checker implementation " - "for %s" % (_system,)) - return False - return policy_checker().is_outdated(path) - - class PolicyChecker: """ Abstract PolicyChecker class @@ -129,7 +70,7 @@ class LinuxPolicyChecker(PolicyChecker): PolicyChecker for Linux """ LINUX_POLKIT_FILE = ("/usr/share/polkit-1/actions/" - "net.openvpn.gui.leap.policy") + "se.leap.bitmask.policy") @classmethod def get_polkit_path(self): @@ -141,6 +82,8 @@ class LinuxPolicyChecker(PolicyChecker): return self.LINUX_POLKIT_FILE def is_missing_policy_permissions(self): + # FIXME this name is quite confusing, it does not have anything to do with + # file permissions. """ Returns True if we could not find the appropriate policykit file in place @@ -148,22 +91,3 @@ class LinuxPolicyChecker(PolicyChecker): :rtype: bool """ return not os.path.isfile(self.LINUX_POLKIT_FILE) - - def is_outdated(self, path): - """ - Returns if the existing polkit file is outdated, comparing if the path - is correct. - - :param path: the path that should have the polkit file. - :type path: str. - :rtype: bool - """ - polkit = None - try: - with open(self.LINUX_POLKIT_FILE) as f: - polkit = f.read() - except IOError, e: - logger.error("Error reading polkit file(%s): %r" % ( - self.LINUX_POLKIT_FILE, e)) - - return get_policy_contents(path) != polkit -- cgit v1.2.3 From 66c94c7533a81cf9512b41090ccab4ee8360e611 Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Thu, 8 May 2014 17:19:01 -0500 Subject: wait on shutdown until firewall is down --- src/leap/bitmask/backend.py | 31 +++++++++++++++++++++++++++++++ src/leap/bitmask/gui/mainwindow.py | 7 ------- 2 files changed, 31 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/leap/bitmask/backend.py b/src/leap/bitmask/backend.py index bd26bb1c..41fdc06e 100644 --- a/src/leap/bitmask/backend.py +++ b/src/leap/bitmask/backend.py @@ -17,8 +17,10 @@ """ Backend for everything """ +import commands import logging import os +import time from functools import partial from Queue import Queue, Empty @@ -32,6 +34,7 @@ import zope.interface from leap.bitmask.config.providerconfig import ProviderConfig from leap.bitmask.crypto.srpauth import SRPAuth from leap.bitmask.crypto.srpregister import SRPRegister +from leap.bitmask.platform_init import IS_LINUX from leap.bitmask.provider import get_provider_path from leap.bitmask.provider.providerbootstrapper import ProviderBootstrapper from leap.bitmask.services.eip import eipconfig @@ -366,6 +369,34 @@ class EIP(object): Stop the service. """ self._vpn.terminate(shutdown) + if IS_LINUX: + self._wait_for_firewall_down() + + def _wait_for_firewall_down(self): + """ + Wait for the firewall to come down. + """ + # Due to how we delay the resolvconf action in linux. + # XXX this *has* to wait for a reasonable lapse, since we have some + # delay in vpn.terminate. + # For a better solution it should be signaled from backend that + # everything is clear to proceed, or a timeout happened. + MAX_FW_WAIT_RETRIES = 25 + FW_WAIT_STEP = 0.5 + + retry = 0 + + fw_up_cmd = "pkexec /usr/sbin/bitmask-root firewall isup" + fw_is_down = lambda: commands.getstatusoutput(fw_up_cmd)[0] == 256 + + while retry < MAX_FW_WAIT_RETRIES: + if fw_is_down(): + return + else: + time.sleep(FW_WAIT_STEP) + retry += 1 + logger.warning("After waiting, firewall is not down... " + "You might experience lack of connectivity") def terminate(self): """ diff --git a/src/leap/bitmask/gui/mainwindow.py b/src/leap/bitmask/gui/mainwindow.py index 681432b3..c55dbb82 100644 --- a/src/leap/bitmask/gui/mainwindow.py +++ b/src/leap/bitmask/gui/mainwindow.py @@ -2068,13 +2068,6 @@ class MainWindow(QtGui.QMainWindow): logger.debug('Terminating vpn') self._backend.stop_eip(shutdown=True) - # XXX this *has* to wait for a reasonable lapse, since we have some - # delay in vpn.terminate. - # For a better solution it should receive be - # signaled from backend that - # everything is clear to proceed, or timeout happened. - time.sleep(1.5) - self._cancel_ongoing_defers() # TODO missing any more cancels? -- cgit v1.2.3 From 02b7b4a35d45671542f1e665767e9227c81207af Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Tue, 13 May 2014 01:55:28 -0500 Subject: give some time for eip to shudown on bundle. Closes: #5663 --- src/leap/bitmask/backend.py | 9 +++++++++ src/leap/bitmask/gui/mainwindow.py | 18 +++++++++++++----- 2 files changed, 22 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/leap/bitmask/backend.py b/src/leap/bitmask/backend.py index 41fdc06e..a351a477 100644 --- a/src/leap/bitmask/backend.py +++ b/src/leap/bitmask/backend.py @@ -25,6 +25,7 @@ import time from functools import partial from Queue import Queue, Empty +from twisted.internet import reactor from twisted.internet import threads, defer from twisted.internet.task import LoopingCall from twisted.python import log @@ -899,9 +900,17 @@ class Backend(object): """ Stops the looping call and tries to cancel all the defers. """ + reactor.callLater(2, self._stop) + + def _stop(self): + """ + Delayed stopping of worker. Called from `stop`. + """ log.msg("Stopping worker...") if self._lc.running: self._lc.stop() + else: + logger.warning("Looping call is not running, cannot stop") while len(self._ongoing_defers) > 0: d = self._ongoing_defers.pop() d.cancel() diff --git a/src/leap/bitmask/gui/mainwindow.py b/src/leap/bitmask/gui/mainwindow.py index c55dbb82..8b60ad8e 100644 --- a/src/leap/bitmask/gui/mainwindow.py +++ b/src/leap/bitmask/gui/mainwindow.py @@ -2068,12 +2068,25 @@ class MainWindow(QtGui.QMainWindow): logger.debug('Terminating vpn') self._backend.stop_eip(shutdown=True) + # We need to give some time to the ongoing signals for shutdown + # to come into action. This needs to be solved using + # back-communication from backend. + QtCore.QTimer.singleShot(3000, self._shutdown) + + def _shutdown(self): + """ + Actually shutdown. + """ self._cancel_ongoing_defers() # TODO missing any more cancels? logger.debug('Cleaning pidfiles') self._cleanup_pidfiles() + if self._quit_callback: + self._quit_callback() + + logger.debug('Bye.') def quit(self): """ @@ -2109,8 +2122,3 @@ class MainWindow(QtGui.QMainWindow): self._logger_window.close() self.close() - - if self._quit_callback: - self._quit_callback() - - logger.debug('Bye.') -- cgit v1.2.3 From 8a4b9c176a5ca9c9236283b1d6191872c0d3582b Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Thu, 15 May 2014 08:43:53 -0500 Subject: remove commented block, fix typo --- src/leap/bitmask/services/eip/linuxvpnlauncher.py | 15 --------------- src/leap/bitmask/services/eip/vpnprocess.py | 2 +- 2 files changed, 1 insertion(+), 16 deletions(-) (limited to 'src') diff --git a/src/leap/bitmask/services/eip/linuxvpnlauncher.py b/src/leap/bitmask/services/eip/linuxvpnlauncher.py index 9e6176cb..1f0813e0 100644 --- a/src/leap/bitmask/services/eip/linuxvpnlauncher.py +++ b/src/leap/bitmask/services/eip/linuxvpnlauncher.py @@ -150,21 +150,6 @@ class LinuxVPNLauncher(VPNLauncher): logger.warning("System has no pkexec") raise EIPNoPkexecAvailable() - #@classmethod - #def missing_other_files(kls): - #""" - #'Extend' the VPNLauncher's missing_other_files to check if the polkit - #files is outdated, in the case of an standalone bundle. - #If the polkit file that is in OTHER_FILES exists but is not up to date, - #it is added to the missing list. -# - #:returns: a list of missing files - #:rtype: list of str - #""" - # we use `super` in order to send the class to use - #missing = super(LinuxVPNLauncher, kls).missing_other_files() - #return missing - @classmethod def get_vpn_command(kls, eipconfig, providerconfig, socket_host, socket_port="unix", openvpn_verb=1): diff --git a/src/leap/bitmask/services/eip/vpnprocess.py b/src/leap/bitmask/services/eip/vpnprocess.py index 420db971..d57eafe2 100644 --- a/src/leap/bitmask/services/eip/vpnprocess.py +++ b/src/leap/bitmask/services/eip/vpnprocess.py @@ -253,7 +253,7 @@ class VPN(object): if self._vpnproc.transport.pid is None: logger.debug("Process has been happily terminated.") - # we try to bring the firewall up + # we try to tear the firewall down if IS_LINUX and self._user_stopped: firewall_down = self._tear_down_firewall() if firewall_down: -- cgit v1.2.3 From 825ac1fcb8bf5a0ac3ae44442e287d207374ca14 Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Thu, 15 May 2014 08:46:49 -0500 Subject: remove up-restart option. Related: #5669 --- src/leap/bitmask/services/eip/vpnlauncher.py | 33 ---------------------------- 1 file changed, 33 deletions(-) (limited to 'src') diff --git a/src/leap/bitmask/services/eip/vpnlauncher.py b/src/leap/bitmask/services/eip/vpnlauncher.py index dc72f276..1498632a 100644 --- a/src/leap/bitmask/services/eip/vpnlauncher.py +++ b/src/leap/bitmask/services/eip/vpnlauncher.py @@ -198,11 +198,6 @@ class VPNLauncher(object): args += [ '--client', '--dev', 'tun', - ############################################################## - # persist-tun makes ping-restart fail because it leaves a - # broken routing table - ############################################################## - # '--persist-tun', '--persist-key', '--tls-client', '--remote-cert-tls', @@ -215,15 +210,6 @@ class VPNLauncher(object): user = getpass.getuser() - ############################################################## - # The down-root plugin fails in some situations, so we don't - # drop privs for the time being - ############################################################## - # args += [ - # '--user', user, - # '--group', grp.getgrgid(os.getgroups()[-1]).gr_name - # ] - if socket_port == "unix": # that's always the case for linux args += [ '--management-client-user', user @@ -247,25 +233,6 @@ class VPNLauncher(object): '--down', '\"%s\"' % (kls.DOWN_SCRIPT,) ] - args += [ - '--up-restart', - '--persist-tun' - ] - - ########################################################### - # For the time being we are disabling the usage of the - # down-root plugin, because it doesn't quite work as - # expected (i.e. it doesn't run route -del as root - # when finishing, so it fails to properly - # restart/quit) - ########################################################### - # if _has_updown_scripts(kls.OPENVPN_DOWN_PLUGIN): - # args += [ - # '--plugin', kls.OPENVPN_DOWN_ROOT, - # '\'%s\'' % kls.DOWN_SCRIPT # for OSX - # '\'script_type=down %s\'' % kls.DOWN_SCRIPT # for Linux - # ] - args += [ '--cert', eipconfig.get_client_cert_path(providerconfig), '--key', eipconfig.get_client_cert_path(providerconfig), -- cgit v1.2.3 From 19391a9eb7ac4b09dd86c4d722291dbda140dde0 Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Thu, 15 May 2014 08:50:07 -0500 Subject: allow osx and win to continue with updown scripts for the time being --- src/leap/bitmask/services/eip/vpnlauncher.py | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/leap/bitmask/services/eip/vpnlauncher.py b/src/leap/bitmask/services/eip/vpnlauncher.py index 1498632a..dcb48e8a 100644 --- a/src/leap/bitmask/services/eip/vpnlauncher.py +++ b/src/leap/bitmask/services/eip/vpnlauncher.py @@ -25,14 +25,12 @@ import stat from abc import ABCMeta, abstractmethod from functools import partial -from leap.bitmask.config import flags from leap.bitmask.config.leapsettings import LeapSettings from leap.bitmask.config.providerconfig import ProviderConfig +from leap.bitmask.platform_init import IS_LINUX from leap.bitmask.services.eip.eipconfig import EIPConfig, VPNGatewaySelector -from leap.bitmask.util import first -from leap.bitmask.util import get_path_prefix from leap.common.check import leap_assert, leap_assert_type -from leap.common.files import which + logger = logging.getLogger(__name__) @@ -264,15 +262,18 @@ class VPNLauncher(object): :rtype: list """ - # XXX remove when we ditch UPDOWN in osx and win too - #leap_assert(kls.UPDOWN_FILES is not None, - #"Need to define UPDOWN_FILES for this particular " - #"launcher before calling this method") - #file_exist = partial(_has_updown_scripts, warn=False) - #zipped = zip(kls.UPDOWN_FILES, map(file_exist, kls.UPDOWN_FILES)) - #missing = filter(lambda (path, exists): exists is False, zipped) - #return [path for path, exists in missing] - return [] + # FIXME + # XXX remove method when we ditch UPDOWN in osx and win too + if IS_LINUX: + return [] + else: + leap_assert(kls.UPDOWN_FILES is not None, + "Need to define UPDOWN_FILES for this particular " + "launcher before calling this method") + file_exist = partial(_has_updown_scripts, warn=False) + zipped = zip(kls.UPDOWN_FILES, map(file_exist, kls.UPDOWN_FILES)) + missing = filter(lambda (path, exists): exists is False, zipped) + return [path for path, exists in missing] @classmethod def missing_other_files(kls): -- cgit v1.2.3 From dfbe8c4f0158366e91ea5118e5aa68c07d28ddbf Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Thu, 15 May 2014 09:25:25 -0500 Subject: avoid openvp soft-restart. Closes: #5669 --- src/leap/bitmask/services/eip/vpnprocess.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/leap/bitmask/services/eip/vpnprocess.py b/src/leap/bitmask/services/eip/vpnprocess.py index d57eafe2..1559ea8b 100644 --- a/src/leap/bitmask/services/eip/vpnprocess.py +++ b/src/leap/bitmask/services/eip/vpnprocess.py @@ -68,9 +68,8 @@ class VPNObserver(object): 'Network is unreachable (code=101)',), 'PROCESS_RESTART_TLS': ( "SIGUSR1[soft,tls-error]",), - # Let ping-restart work as it should - # 'PROCESS_RESTART_PING': ( - # "SIGUSR1[soft,ping-restart]",), + 'PROCESS_RESTART_PING': ( + "SIGTERM[soft,ping-restart]",), 'INITIALIZATION_COMPLETED': ( "Initialization Sequence Completed",), } @@ -296,7 +295,10 @@ class VPN(object): """ from twisted.internet import reactor self._stop_pollers() - self._user_stopped = True + + # We assume that the only valid shutodowns are initiated + # by an user action. + self._user_stopped = shutdown # First we try to be polite and send a SIGTERM... if self._vpnproc: -- cgit v1.2.3