summaryrefslogtreecommitdiff
path: root/src/leap/bitmask/services/eip
diff options
context:
space:
mode:
Diffstat (limited to 'src/leap/bitmask/services/eip')
-rw-r--r--src/leap/bitmask/services/eip/conductor.py6
-rw-r--r--src/leap/bitmask/services/eip/eipconfig.py43
-rw-r--r--src/leap/bitmask/services/eip/linuxvpnlauncher.py99
-rw-r--r--src/leap/bitmask/services/eip/vpnprocess.py20
4 files changed, 44 insertions, 124 deletions
diff --git a/src/leap/bitmask/services/eip/conductor.py b/src/leap/bitmask/services/eip/conductor.py
index 0ee56628..01dd7449 100644
--- a/src/leap/bitmask/services/eip/conductor.py
+++ b/src/leap/bitmask/services/eip/conductor.py
@@ -124,6 +124,12 @@ class EIPConductor(object):
"""
self._backend.tear_fw_down()
+ def terminate(self):
+ """
+ Turn off VPN
+ """
+ self.qtsigs.do_disconnect_signal.emit()
+
@QtCore.Slot()
def _start_eip(self):
"""
diff --git a/src/leap/bitmask/services/eip/eipconfig.py b/src/leap/bitmask/services/eip/eipconfig.py
index 37c0c8ae..5b51d12e 100644
--- a/src/leap/bitmask/services/eip/eipconfig.py
+++ b/src/leap/bitmask/services/eip/eipconfig.py
@@ -113,39 +113,38 @@ class VPNGatewaySelector(object):
"""
Return the existing gateways, sorted by timezone proximity.
- :rtype: list of tuples (location, ip)
- (str, IPv4Address or IPv6Address object)
+ :rtype: list of tuples (label, ip, country_code)
+ (str, IPv4Address or IPv6Address object, str)
"""
gateways_timezones = []
locations = self._eipconfig.get_locations()
gateways = self._eipconfig.get_gateways()
for idx, gateway in enumerate(gateways):
- gateway_location = gateway.get('location')
- gateway_distance = 99 # if hasn't location -> should go last
-
- if gateway_location is not None:
- timezone = locations[gateway['location']]['timezone']
- gateway_name = locations[gateway['location']].get('name', None)
- if gateway_name is not None:
- gateway_location = gateway_name
-
- gw_offset = int(timezone)
- if gw_offset in self.equivalent_timezones:
- gw_offset = self.equivalent_timezones[gw_offset]
-
- gateway_distance = self._get_timezone_distance(gw_offset)
+ distance = 99 # if hasn't location -> should go last
+ location = locations.get(gateway.get('location'))
+ label = gateway.get('location', 'Unknown')
+ country = 'XX'
+ if location is not None:
+ country = location.get('country_code', 'XX')
+ label = location.get('name', label)
+ timezone = location.get('timezone')
+ if timezone is not None:
+ offset = int(timezone)
+ if offset in self.equivalent_timezones:
+ offset = self.equivalent_timezones[offset]
+ distance = self._get_timezone_distance(offset)
ip = self._eipconfig.get_gateway_ip(idx)
- gateways_timezones.append((ip, gateway_distance, gateway_location))
+ gateways_timezones.append((ip, distance, label, country))
gateways_timezones = sorted(gateways_timezones, key=lambda gw: gw[1])
- gateways = []
- for ip, distance, location in gateways_timezones:
- gateways.append((location, ip))
+ result = []
+ for ip, distance, label, country in gateways_timezones:
+ result.append((label, ip, country))
- return gateways
+ return result
def get_gateways(self):
"""
@@ -153,7 +152,7 @@ class VPNGatewaySelector(object):
:rtype: list of IPv4Address or IPv6Address object.
"""
- gateways = [ip for location, ip in self.get_gateways_list()][:4]
+ gateways = [gateway[1] for gateway in self.get_gateways_list()][:4]
return gateways
def get_gateways_country_code(self):
diff --git a/src/leap/bitmask/services/eip/linuxvpnlauncher.py b/src/leap/bitmask/services/eip/linuxvpnlauncher.py
index b6e47f25..a3ab408b 100644
--- a/src/leap/bitmask/services/eip/linuxvpnlauncher.py
+++ b/src/leap/bitmask/services/eip/linuxvpnlauncher.py
@@ -20,17 +20,15 @@ Linux VPN launcher implementation.
import commands
import logging
import os
-import subprocess
import sys
-import time
from leap.bitmask.config import flags
from leap.bitmask.util.privilege_policies import LinuxPolicyChecker
-from leap.common.files import which
+from leap.bitmask.util.privilege_policies import NoPolkitAuthAgentAvailable
+from leap.bitmask.util.privilege_policies import NoPkexecAvailable
from leap.bitmask.services.eip.vpnlauncher import VPNLauncher
from leap.bitmask.services.eip.vpnlauncher import VPNLauncherException
from leap.bitmask.util import get_path_prefix, force_eval
-from leap.common.check import leap_assert
from leap.bitmask.util import first
logger = logging.getLogger(__name__)
@@ -46,66 +44,11 @@ class EIPNoPkexecAvailable(VPNLauncherException):
pass
-def _is_pkexec_in_system():
- """
- Checks the existence of the pkexec binary in system.
- """
- pkexec_path = which('pkexec')
- if len(pkexec_path) == 0:
- return False
- return True
-
-
-def _is_auth_agent_running():
- """
- Checks if a polkit daemon is running.
-
- :return: True if it's running, False if it's not.
- :rtype: boolean
- """
- # Note that gnome-shell does not uses a separate process for the
- # polkit-agent, it uses a polkit-agent within its own process so we can't
- # ps-grep a polkit process, we can ps-grep gnome-shell itself.
-
- # 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 "[g]nome-shell"',
- 'ps aux | grep "[f]ingerprint-polkit-agent"',
- ]
- is_running = [commands.getoutput(cmd) for cmd in polkit_options]
-
- return any(is_running)
-
-
-def _try_to_launch_agent():
- """
- Tries to launch a polkit daemon.
- """
- env = None
- if flags.STANDALONE:
- env = {"PYTHONPATH": os.path.abspath('../../../../lib/')}
- try:
- # We need to quote the command because subprocess call
- # 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'
# The following classes depend on force_eval to be called against
# the classes, to get the evaluation of the standalone flag on runtine.
@@ -130,36 +73,6 @@ class LinuxVPNLauncher(VPNLauncher):
OTHER_FILES = (POLKIT_PATH, BITMASK_ROOT, OPENVPN_BIN_PATH)
@classmethod
- def maybe_pkexec(kls):
- """
- Checks whether pkexec is available in the system, and
- returns the path if found.
-
- Might raise:
- EIPNoPkexecAvailable,
- EIPNoPolkitAuthAgentAvailable.
-
- :returns: a list of the paths where pkexec is to be found
- :rtype: list
- """
- if _is_pkexec_in_system():
- if not _is_auth_agent_running():
- _try_to_launch_agent()
- time.sleep(2)
- if _is_auth_agent_running():
- pkexec_possibilities = which(kls.PKEXEC_BIN)
- leap_assert(len(pkexec_possibilities) > 0,
- "We couldn't find pkexec")
- return pkexec_possibilities
- else:
- logger.warning("No polkit auth agent found. pkexec " +
- "will use its own auth agent.")
- raise EIPNoPolkitAuthAgentAvailable()
- else:
- logger.warning("System has no pkexec")
- raise EIPNoPkexecAvailable()
-
- @classmethod
def get_vpn_command(kls, eipconfig, providerconfig, socket_host,
socket_port="unix", openvpn_verb=1):
"""
@@ -194,7 +107,13 @@ class LinuxVPNLauncher(VPNLauncher):
command.insert(1, "openvpn")
command.insert(2, "start")
- pkexec = kls.maybe_pkexec()
+ policyChecker = LinuxPolicyChecker()
+ try:
+ pkexec = policyChecker.maybe_pkexec()
+ except NoPolkitAuthAgentAvailable:
+ raise EIPNoPolkitAuthAgentAvailable()
+ except NoPkexecAvailable:
+ raise EIPNoPkexecAvailable()
if pkexec:
command.insert(0, first(pkexec))
diff --git a/src/leap/bitmask/services/eip/vpnprocess.py b/src/leap/bitmask/services/eip/vpnprocess.py
index c7159a93..8dc6021f 100644
--- a/src/leap/bitmask/services/eip/vpnprocess.py
+++ b/src/leap/bitmask/services/eip/vpnprocess.py
@@ -50,8 +50,7 @@ from leap.common.check import leap_assert, leap_assert_type
logger = logging.getLogger(__name__)
vpnlog = logging.getLogger('leap.openvpn')
-from twisted.internet import protocol
-from twisted.internet import defer
+from twisted.internet import defer, protocol, reactor
from twisted.internet import error as internet_error
from twisted.internet.task import LoopingCall
@@ -157,10 +156,8 @@ class VPN(object):
of a QObject containing the QSignals that we will pass along
to the VPNManager.
"""
- from twisted.internet import reactor
self._vpnproc = None
self._pollers = []
- self._reactor = reactor
self._signaler = kwargs['signaler']
self._openvpn_verb = flags.OPENVPN_VERBOSITY
@@ -217,14 +214,15 @@ class VPN(object):
# and abstract us away from anything else.
try:
cmd = vpnproc.getCommand()
- except Exception:
- logger.error("Error while getting vpn command...")
+ except Exception as e:
+ logger.error("Error while getting vpn command... {0!r}".format(e))
raise
+
env = os.environ
for key, val in vpnproc.vpn_env.items():
env[key] = val
- self._reactor.spawnProcess(vpnproc, cmd[0], cmd, env)
+ reactor.spawnProcess(vpnproc, cmd[0], cmd, env)
self._vpnproc = vpnproc
# add pollers for status and state
@@ -300,7 +298,6 @@ class VPN(object):
:param tries: counter of tries, used in recursion
:type tries: int
"""
- from twisted.internet import reactor
while tries < self.TERMINATE_MAXTRIES:
if self._vpnproc.transport.pid is None:
logger.debug("Process has been happily terminated.")
@@ -351,7 +348,6 @@ class VPN(object):
:param restart: whether this stop is part of a hard restart.
:type restart: bool
"""
- from twisted.internet import reactor
self._stop_pollers()
# First we try to be polite and send a SIGTERM...
@@ -375,6 +371,8 @@ class VPN(object):
logger.debug("Firewall down")
else:
logger.warning("Could not tear firewall down")
+ else:
+ logger.debug("VPN is not running.")
def _start_pollers(self):
"""
@@ -424,8 +422,6 @@ class VPNManager(object):
backend
:type signaler: backend.Signaler
"""
- from twisted.internet import reactor
- self._reactor = reactor
self._tn = None
self._signaler = signaler
self._aborted = False
@@ -602,7 +598,7 @@ class VPNManager(object):
logger.debug('trying to connect to management')
if not self.aborted and not self.is_connected():
self.connect_to_management(self._socket_host, self._socket_port)
- self._reactor.callLater(
+ reactor.callLater(
self.CONNECTION_RETRY_TIME,
self.try_to_connect_to_management, retry + 1)