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/vpnprocess.py | 30 ++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) (limited to 'src/leap/bitmask/services/eip/vpnprocess.py') 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/vpnprocess.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'src/leap/bitmask/services/eip/vpnprocess.py') 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/vpnprocess.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/leap/bitmask/services/eip/vpnprocess.py') 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/leap/bitmask/services/eip/vpnprocess.py') 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/services/eip/vpnprocess.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/leap/bitmask/services/eip/vpnprocess.py') 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 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/services/eip/vpnprocess.py | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'src/leap/bitmask/services/eip/vpnprocess.py') 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 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/vpnprocess.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/leap/bitmask/services/eip/vpnprocess.py') 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 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/leap/bitmask/services/eip/vpnprocess.py') 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