diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/leap/bitmask/gui/mainwindow.py | 10 | ||||
| -rw-r--r-- | src/leap/bitmask/platform_init/initializers.py | 10 | ||||
| -rw-r--r-- | src/leap/bitmask/services/eip/__init__.py | 27 | ||||
| -rw-r--r-- | src/leap/bitmask/services/eip/vpnlaunchers.py | 965 | ||||
| -rw-r--r-- | src/leap/bitmask/services/eip/vpnprocess.py | 4 | 
5 files changed, 39 insertions, 977 deletions
diff --git a/src/leap/bitmask/gui/mainwindow.py b/src/leap/bitmask/gui/mainwindow.py index 200d68aa..6022210c 100644 --- a/src/leap/bitmask/gui/mainwindow.py +++ b/src/leap/bitmask/gui/mainwindow.py @@ -53,12 +53,12 @@ from leap.bitmask.services.eip.vpnprocess import VPN  from leap.bitmask.services.eip.vpnprocess import OpenVPNAlreadyRunning  from leap.bitmask.services.eip.vpnprocess import AlienOpenVPNAlreadyRunning -from leap.bitmask.services.eip.vpnlaunchers import VPNLauncherException -from leap.bitmask.services.eip.vpnlaunchers import OpenVPNNotFoundException -from leap.bitmask.services.eip.vpnlaunchers import EIPNoPkexecAvailable -from leap.bitmask.services.eip.vpnlaunchers import \ +from leap.bitmask.services.eip.vpnlauncher import VPNLauncherException +from leap.bitmask.services.eip.vpnlauncher import OpenVPNNotFoundException +from leap.bitmask.services.eip.linuxvpnlauncher import EIPNoPkexecAvailable +from leap.bitmask.services.eip.linuxvpnlauncher import \      EIPNoPolkitAuthAgentAvailable -from leap.bitmask.services.eip.vpnlaunchers import EIPNoTunKextLoaded +from leap.bitmask.services.eip.darwinvpnlauncher import EIPNoTunKextLoaded  from leap.bitmask.util.keyring_helpers import has_keyring  from leap.bitmask.util.leap_log_handler import LeapLogHandler diff --git a/src/leap/bitmask/platform_init/initializers.py b/src/leap/bitmask/platform_init/initializers.py index 831c6a1c..d93efbc6 100644 --- a/src/leap/bitmask/platform_init/initializers.py +++ b/src/leap/bitmask/platform_init/initializers.py @@ -29,7 +29,9 @@ import tempfile  from PySide import QtGui  from leap.bitmask.config.leapsettings import LeapSettings -from leap.bitmask.services.eip import vpnlaunchers +from leap.bitmask.services.eip import get_vpn_launcher +from leap.bitmask.services.eip.linuxvpnlauncher import LinuxVPNLauncher +from leap.bitmask.services.eip.darwinvpnlauncher import DarwinVPNLauncher  from leap.bitmask.util import first  from leap.bitmask.util import privilege_policies @@ -106,7 +108,7 @@ def check_missing():      config = LeapSettings()      alert_missing = config.get_alert_missing_scripts() -    launcher = vpnlaunchers.get_platform_launcher() +    launcher = get_vpn_launcher()      missing_scripts = launcher.missing_updown_scripts      missing_other = launcher.missing_other_files @@ -251,7 +253,7 @@ def _darwin_install_missing_scripts(badexec, notfound):          "..",          "Resources",          "openvpn") -    launcher = vpnlaunchers.DarwinVPNLauncher +    launcher = DarwinVPNLauncher      if os.path.isdir(installer_path):          fd, tempscript = tempfile.mkstemp(prefix="leap_installer-") @@ -356,7 +358,7 @@ def _linux_install_missing_scripts(badexec, notfound):      """      success = False      installer_path = os.path.join(os.getcwd(), "apps", "eip", "files") -    launcher = vpnlaunchers.LinuxVPNLauncher +    launcher = LinuxVPNLauncher      # XXX refactor with darwin, same block. diff --git a/src/leap/bitmask/services/eip/__init__.py b/src/leap/bitmask/services/eip/__init__.py index dd010027..6030cac3 100644 --- a/src/leap/bitmask/services/eip/__init__.py +++ b/src/leap/bitmask/services/eip/__init__.py @@ -20,7 +20,11 @@ leap.bitmask.services.eip module initialization  import os  import tempfile -from leap.bitmask.platform_init import IS_WIN +from leap.bitmask.services.eip.darwinvpnlauncher import DarwinVPNLauncher +from leap.bitmask.services.eip.linuxvpnlauncher import LinuxVPNLauncher +from leap.bitmask.services.eip.windowsvpnlauncher import WindowsVPNLauncher +from leap.bitmask.platform_init import IS_LINUX, IS_MAC, IS_WIN +from leap.common.check import leap_assert  def get_openvpn_management(): @@ -40,3 +44,24 @@ def get_openvpn_management():          port = "unix"      return host, port + + +def get_vpn_launcher(): +    """ +    Return the VPN launcher for the current platform. +    """ +    if not (IS_LINUX or IS_MAC or IS_WIN): +        error_msg = "VPN Launcher not implemented for this platform." +        raise NotImplementedError(error_msg) + +    launcher = None +    if IS_LINUX: +        launcher = LinuxVPNLauncher +    elif IS_MAC: +        launcher = DarwinVPNLauncher +    elif IS_WIN: +        launcher = WindowsVPNLauncher + +    leap_assert(launcher is not None) + +    return launcher() diff --git a/src/leap/bitmask/services/eip/vpnlaunchers.py b/src/leap/bitmask/services/eip/vpnlaunchers.py deleted file mode 100644 index e27a48d9..00000000 --- a/src/leap/bitmask/services/eip/vpnlaunchers.py +++ /dev/null @@ -1,965 +0,0 @@ -# -*- coding: utf-8 -*- -# vpnlaunchers.py -# Copyright (C) 2013 LEAP -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program.  If not, see <http://www.gnu.org/licenses/>. - -""" -Platform dependant VPN launchers -""" -import commands -import logging -import getpass -import os -import platform -import stat -import subprocess -try: -    import grp -except ImportError: -    pass  # ignore, probably windows - -from abc import ABCMeta, abstractmethod -from functools import partial -from time import sleep - -from leap.bitmask.config import flags -from leap.bitmask.config.leapsettings import LeapSettings - -from leap.bitmask.config.providerconfig import ProviderConfig -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.bitmask.util.privilege_policies import LinuxPolicyChecker -from leap.bitmask.util import privilege_policies -from leap.common.check import leap_assert, leap_assert_type -from leap.common.files import which - - -logger = logging.getLogger(__name__) - - -class VPNLauncherException(Exception): -    pass - - -class OpenVPNNotFoundException(VPNLauncherException): -    pass - - -class EIPNoPolkitAuthAgentAvailable(VPNLauncherException): -    pass - - -class EIPNoPkexecAvailable(VPNLauncherException): -    pass - - -class EIPNoTunKextLoaded(VPNLauncherException): -    pass - - -class VPNLauncher(object): -    """ -    Abstract launcher class -    """ -    __metaclass__ = ABCMeta - -    UPDOWN_FILES = None -    OTHER_FILES = None - -    @abstractmethod -    def get_vpn_command(self, eipconfig=None, providerconfig=None, -                        socket_host=None, socket_port=None): -        """ -        Returns the platform dependant vpn launching command - -        :param eipconfig: eip configuration object -        :type eipconfig: EIPConfig -        :param providerconfig: provider specific configuration -        :type providerconfig: ProviderConfig -        :param socket_host: either socket path (unix) or socket IP -        :type socket_host: str -        :param socket_port: either string "unix" if it's a unix -        socket, or port otherwise -        :type socket_port: str - -        :return: A VPN command ready to be launched -        :rtype: list -        """ -        return [] - -    @abstractmethod -    def get_vpn_env(self): -        """ -        Returns a dictionary with the custom env for the platform. -        This is mainly used for setting LD_LIBRARY_PATH to the correct -        path when distributing a standalone client - -        :rtype: dict -        """ -        return {} - -    @classmethod -    def missing_updown_scripts(kls): -        """ -        Returns what updown scripts are missing. -        :rtype: list -        """ -        leap_assert(kls.UPDOWN_FILES is not None, -                    "Need to define UPDOWN_FILES for this particular " -                    "auncher 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): -        """ -        Returns what other important files are missing during startup. -        Same as missing_updown_scripts but does not check for exec bit. -        :rtype: list -        """ -        leap_assert(kls.OTHER_FILES is not None, -                    "Need to define OTHER_FILES for this particular " -                    "auncher before calling this method") -        file_exist = partial(_has_other_files, warn=False) -        zipped = zip(kls.OTHER_FILES, map(file_exist, kls.OTHER_FILES)) -        missing = filter(lambda (path, exists): exists is False, zipped) -        return [path for path, exists in missing] - - -def get_platform_launcher(): -    launcher = globals()[platform.system() + "VPNLauncher"] -    leap_assert(launcher, "Unimplemented platform launcher: %s" % -                (platform.system(),)) -    return launcher() - - -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 _has_updown_scripts(path, warn=True): -    """ -    Checks the existence of the up/down scripts and its -    exec bit if applicable. - -    :param path: the path to be checked -    :type path: str - -    :param warn: whether we should log the absence -    :type warn: bool - -    :rtype: bool -    """ -    is_file = os.path.isfile(path) -    if warn and not is_file: -        logger.error("Could not find up/down script %s. " -                     "Might produce DNS leaks." % (path,)) - -    # XXX check if applies in win -    is_exe = False -    try: -        is_exe = (stat.S_IXUSR & os.stat(path)[stat.ST_MODE] != 0) -    except OSError as e: -        logger.warn("%s" % (e,)) -    if warn and not is_exe: -        logger.error("Up/down script %s is not executable. " -                     "Might produce DNS leaks." % (path,)) -    return is_file and is_exe - - -def _has_other_files(path, warn=True): -    """ -    Checks the existence of other important files. - -    :param path: the path to be checked -    :type path: str - -    :param warn: whether we should log the absence -    :type warn: bool - -    :rtype: bool -    """ -    is_file = os.path.isfile(path) -    if warn and not is_file: -        logger.warning("Could not find file during checks: %s. " % ( -            path,)) -    return is_file - - -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 -    """ -    ps = 'ps aux | grep polkit-%s-authentication-agent-1' -    opts = (ps % case for case in ['[g]nome', '[k]de']) -    is_running = map(lambda l: commands.getoutput(l), opts) -    return any(is_running) - - -def _try_to_launch_agent(): -    """ -    Tries to launch a polkit daemon. -    """ -    env = None -    if flags.STANDALONE is True: -        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. -        subprocess.call(["python -m leap.bitmask.util.polkit_agent"], -                        shell=True, env=env) -    except Exception as exc: -        logger.exception(exc) - - -class LinuxVPNLauncher(VPNLauncher): -    """ -    VPN launcher for the Linux platform -    """ - -    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. -    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) - -    UP_SCRIPT = DOWN_SCRIPT = UP_DOWN_PATH -    UPDOWN_FILES = (UP_DOWN_PATH,) -    POLKIT_PATH = LinuxPolicyChecker.get_polkit_path() -    OTHER_FILES = (POLKIT_PATH, ) - -    def missing_other_files(self): -        """ -        'Extend' the VPNLauncher's missing_other_files to check if the polkit -        files is outdated. 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 -        """ -        missing = VPNLauncher.missing_other_files.im_func(self) -        polkit_file = LinuxPolicyChecker.get_polkit_path() -        if polkit_file not in missing: -            if privilege_policies.is_policy_outdated(self.OPENVPN_BIN_PATH): -                missing.append(polkit_file) - -        return missing - -    @classmethod -    def cmd_for_missing_scripts(kls, frompath, pol_file): -        """ -        Returns a sh script that can copy the missing files. - -        :param frompath: The path where the up/down scripts 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 - -        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"\n' % (pol_file, kls.POLKIT_PATH) -        cmd += 'chmod 644 "%s"\n' % (kls.POLKIT_PATH, ) - -        return cmd - -    @classmethod -    def maybe_pkexec(kls): -        """ -        Checks whether pkexec is available in the system, and -        returns the path if found. - -        Might raise EIPNoPkexecAvailable or 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() -                sleep(0.5) -            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 maybe_down_plugin(kls): -        """ -        Returns the path of the openvpn down-root-plugin, searching first -        in the relative path for the standalone bundle, and then in the system -        path where the debian package puts it. - -        :returns: the path where the plugin was found, or None -        :rtype: str or None -        """ -        cwd = os.getcwd() -        rel_path_in_bundle = os.path.join( -            'apps', 'eip', 'files', kls.OPENVPN_DOWN_ROOT_FILE) -        abs_path_in_bundle = os.path.join(cwd, rel_path_in_bundle) -        if os.path.isfile(abs_path_in_bundle): -            return abs_path_in_bundle -        abs_path_in_system = kls.OPENVPN_DOWN_ROOT_PATH -        if os.path.isfile(abs_path_in_system): -            return abs_path_in_system - -        logger.warning("We could not find the down-root-plugin, so no updown " -                       "scripts will be run. DNS leaks are likely!") -        return None - -    def get_vpn_command(self, eipconfig, providerconfig, socket_host, -                        socket_port="unix", openvpn_verb=1): -        """ -        Returns the platform dependant vpn launching command. It will -        look for openvpn in the regular paths and algo in -        path_prefix/apps/eip/ (in case that standalone is set) - -        Might raise: -            EIPNoTunKextLoaded, -            OpenVPNNotFoundException, -            VPNLauncherException. - -        :param eipconfig: eip configuration object -        :type eipconfig: EIPConfig - -        :param providerconfig: provider specific configuration -        :type providerconfig: ProviderConfig - -        :param socket_host: either socket path (unix) or socket IP -        :type socket_host: str - -        :param socket_port: either string "unix" if it's a unix -                            socket, or port otherwise -        :type socket_port: str - -        :param openvpn_verb: openvpn verbosity wanted -        :type openvpn_verb: int - -        :return: A VPN command ready to be launched -        :rtype: list -        """ -        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(self.OPENVPN_BIN, **kwargs) -        if len(openvpn_possibilities) == 0: -            raise OpenVPNNotFoundException() - -        openvpn = first(openvpn_possibilities) -        args = [] - -        args += [ -            '--setenv', "LEAPOPENVPN", "1" -        ] - -        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(self.tr('No gateway was found!')) - -        logger.debug("Using gateways ips: {0}".format(', '.join(gateways))) - -        for gw in gateways: -            args += ['--remote', gw, '1194', 'udp'] - -        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', -            'server' -        ] - -        openvpn_configuration = eipconfig.get_openvpn_configuration() -        for key, value in openvpn_configuration.items(): -            args += ['--%s' % (key,), value] - -        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 -            ] - -        args += [ -            '--management-signal', -            '--management', socket_host, socket_port, -            '--script-security', '2' -        ] - -        if _has_updown_scripts(self.UP_SCRIPT): -            args += [ -                '--up', '\"%s\"' % (self.UP_SCRIPT,), -            ] - -        if _has_updown_scripts(self.DOWN_SCRIPT): -            args += [ -                '--down', '\"%s\"' % (self.DOWN_SCRIPT,) -            ] - -        ########################################################### -        # 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(self.OPENVPN_DOWN_PLUGIN): -        #     args += [ -        #         '--plugin', self.OPENVPN_DOWN_ROOT, -        #         '\'%s\'' % self.DOWN_SCRIPT  # for OSX -        #         '\'script_type=down %s\'' % self.DOWN_SCRIPT  # for Linux -        #     ] - -        args += [ -            '--cert', eipconfig.get_client_cert_path(providerconfig), -            '--key', eipconfig.get_client_cert_path(providerconfig), -            '--ca', providerconfig.get_ca_cert_path() -        ] - -        command = [openvpn] -        pkexec = self.maybe_pkexec() -        if pkexec: -            command.insert(0, first(pkexec)) - -        command_and_args = command + args -        logger.debug("Running VPN with command:") -        logger.debug(" ".join(command_and_args)) - -        return command_and_args - -    def get_vpn_env(self): -        """ -        Returns a dictionary with the custom env for the platform. -        This is mainly used for setting LD_LIBRARY_PATH to the correct -        path when distributing a standalone client - -        :rtype: dict -        """ -        return { -            "LD_LIBRARY_PATH": os.path.join(get_path_prefix(), "..", "lib") -        } - - -class DarwinVPNLauncher(VPNLauncher): -    """ -    VPN launcher for the Darwin Platform -    """ - -    COCOASUDO = "cocoasudo" -    # XXX need the good old magic translate for these strings -    # (look for magic in 0.2.0 release) -    SUDO_MSG = ("Bitmask needs administrative privileges to run " -                "Encrypted Internet.") -    INSTALL_MSG = ("\"Bitmask needs administrative privileges to install " -                   "missing scripts and fix permissions.\"") - -    INSTALL_PATH = os.path.realpath(os.getcwd() + "/../../") -    INSTALL_PATH_ESCAPED = os.path.realpath(os.getcwd() + "/../../") -    OPENVPN_BIN = 'openvpn.leap' -    OPENVPN_PATH = "%s/Contents/Resources/openvpn" % (INSTALL_PATH,) -    OPENVPN_PATH_ESCAPED = "%s/Contents/Resources/openvpn" % ( -        INSTALL_PATH_ESCAPED,) - -    UP_SCRIPT = "%s/client.up.sh" % (OPENVPN_PATH,) -    DOWN_SCRIPT = "%s/client.down.sh" % (OPENVPN_PATH,) -    OPENVPN_DOWN_PLUGIN = '%s/openvpn-down-root.so' % (OPENVPN_PATH,) - -    UPDOWN_FILES = (UP_SCRIPT, DOWN_SCRIPT, OPENVPN_DOWN_PLUGIN) -    OTHER_FILES = [] - -    @classmethod -    def cmd_for_missing_scripts(kls, frompath): -        """ -        Returns a command that can copy the missing scripts. -        :rtype: str -        """ -        to = kls.OPENVPN_PATH_ESCAPED -        cmd = "#!/bin/sh\nmkdir -p %s\ncp \"%s/\"* %s\nchmod 744 %s/*" % ( -            to, frompath, to, to) -        return cmd - -    @classmethod -    def maybe_kextloaded(kls): -        """ -        Checks if the needed kext is loaded before launching openvpn. -        """ -        return bool(commands.getoutput('kextstat | grep "leap.tun"')) - -    def _get_resource_path(self): -        """ -        Returns the absolute path to the app resources directory - -        :rtype: str -        """ -        return os.path.abspath( -            os.path.join( -                os.getcwd(), -                "../../Contents/Resources")) - -    def _get_icon_path(self): -        """ -        Returns the absolute path to the app icon - -        :rtype: str -        """ -        return os.path.join(self._get_resource_path(), -                            "leap-client.tiff") - -    def get_cocoasudo_ovpn_cmd(self): -        """ -        Returns a string with the cocoasudo command needed to run openvpn -        as admin with a nice password prompt. The actual command needs to be -        appended. - -        :rtype: (str, list) -        """ -        iconpath = self._get_icon_path() -        has_icon = os.path.isfile(iconpath) -        args = ["--icon=%s" % iconpath] if has_icon else [] -        args.append("--prompt=%s" % (self.SUDO_MSG,)) - -        return self.COCOASUDO, args - -    def get_cocoasudo_installmissing_cmd(self): -        """ -        Returns a string with the cocoasudo command needed to install missing -        files as admin with a nice password prompt. The actual command needs to -        be appended. - -        :rtype: (str, list) -        """ -        iconpath = self._get_icon_path() -        has_icon = os.path.isfile(iconpath) -        args = ["--icon=%s" % iconpath] if has_icon else [] -        args.append("--prompt=%s" % (self.INSTALL_MSG,)) - -        return self.COCOASUDO, args - -    def get_vpn_command(self, eipconfig=None, providerconfig=None, -                        socket_host=None, socket_port="unix", openvpn_verb=1): -        """ -        Returns the platform dependant vpn launching command - -        Might raise VPNException. - -        :param eipconfig: eip configuration object -        :type eipconfig: EIPConfig - -        :param providerconfig: provider specific configuration -        :type providerconfig: ProviderConfig - -        :param socket_host: either socket path (unix) or socket IP -        :type socket_host: str - -        :param socket_port: either string "unix" if it's a unix -                            socket, or port otherwise -        :type socket_port: str - -        :param openvpn_verb: openvpn verbosity wanted -        :type openvpn_verb: int - -        :return: A VPN command ready to be launched -        :rtype: list -        """ -        leap_assert(eipconfig, "We need an eip config") -        leap_assert_type(eipconfig, EIPConfig) -        leap_assert(providerconfig, "We need a provider config") -        leap_assert_type(providerconfig, ProviderConfig) -        leap_assert(socket_host, "We need a socket host!") -        leap_assert(socket_port, "We need a socket port!") - -        if not self.maybe_kextloaded(): -            raise EIPNoTunKextLoaded - -        kwargs = {} -        if flags.STANDALONE: -            kwargs['path_extension'] = os.path.join( -                get_path_prefix(), "..", "apps", "eip") - -        openvpn_possibilities = which( -            self.OPENVPN_BIN, -            **kwargs) -        if len(openvpn_possibilities) == 0: -            raise OpenVPNNotFoundException() - -        openvpn = first(openvpn_possibilities) -        args = [openvpn] - -        args += [ -            '--setenv', "LEAPOPENVPN", "1" -        ] - -        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(self.tr('No gateway was found!')) - -        logger.debug("Using gateways ips: {0}".format(', '.join(gateways))) - -        for gw in gateways: -            args += ['--remote', gw, '1194', 'udp'] - -        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', -            'server' -        ] - -        openvpn_configuration = eipconfig.get_openvpn_configuration() -        for key, value in openvpn_configuration.items(): -            args += ['--%s' % (key,), value] - -        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": -            args += [ -                '--management-client-user', user -            ] - -        args += [ -            '--management-signal', -            '--management', socket_host, socket_port, -            '--script-security', '2' -        ] - -        if _has_updown_scripts(self.UP_SCRIPT): -            args += [ -                '--up', '\"%s\"' % (self.UP_SCRIPT,), -            ] - -        if _has_updown_scripts(self.DOWN_SCRIPT): -            args += [ -                '--down', '\"%s\"' % (self.DOWN_SCRIPT,) -            ] - -            # should have the down script too -            if _has_updown_scripts(self.OPENVPN_DOWN_PLUGIN): -                args += [ -                    ########################################################### -                    # 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) -                    ########################################################### -                    # '--plugin', self.OPENVPN_DOWN_PLUGIN, -                    # '\'%s\'' % self.DOWN_SCRIPT -                ] - -        # we set user to be passed to the up/down scripts -        args += [ -            '--setenv', "LEAPUSER", "%s" % (user,)] - -        args += [ -            '--cert', eipconfig.get_client_cert_path(providerconfig), -            '--key', eipconfig.get_client_cert_path(providerconfig), -            '--ca', providerconfig.get_ca_cert_path() -        ] - -        command, cargs = self.get_cocoasudo_ovpn_cmd() -        cmd_args = cargs + args - -        logger.debug("Running VPN with command:") -        logger.debug("%s %s" % (command, " ".join(cmd_args))) - -        return [command] + cmd_args - -    def get_vpn_env(self): -        """ -        Returns a dictionary with the custom env for the platform. -        This is mainly used for setting LD_LIBRARY_PATH to the correct -        path when distributing a standalone client - -        :rtype: dict -        """ -        return { -            "DYLD_LIBRARY_PATH": os.path.join(get_path_prefix(), "..", "lib") -        } - - -class WindowsVPNLauncher(VPNLauncher): -    """ -    VPN launcher for the Windows platform -    """ - -    OPENVPN_BIN = 'openvpn_leap.exe' - -    # XXX UPDOWN_FILES ... we do not have updown files defined yet! -    # (and maybe we won't) - -    def get_vpn_command(self, eipconfig=None, providerconfig=None, -                        socket_host=None, socket_port="9876", openvpn_verb=1): -        """ -        Returns the platform dependant vpn launching command. It will -        look for openvpn in the regular paths and algo in -        path_prefix/apps/eip/ (in case standalone is set) - -        Might raise VPNException. - -        :param eipconfig: eip configuration object -        :type eipconfig: EIPConfig - -        :param providerconfig: provider specific configuration -        :type providerconfig: ProviderConfig - -        :param socket_host: either socket path (unix) or socket IP -        :type socket_host: str - -        :param socket_port: either string "unix" if it's a unix -        socket, or port otherwise -        :type socket_port: str - -        :param openvpn_verb: the openvpn verbosity wanted -        :type openvpn_verb: int - -        :return: A VPN command ready to be launched -        :rtype: list -        """ -        leap_assert(eipconfig, "We need an eip config") -        leap_assert_type(eipconfig, EIPConfig) -        leap_assert(providerconfig, "We need a provider config") -        leap_assert_type(providerconfig, ProviderConfig) -        leap_assert(socket_host, "We need a socket host!") -        leap_assert(socket_port, "We need a socket port!") -        leap_assert(socket_port != "unix", -                    "We cannot use unix sockets in windows!") - -        openvpn_possibilities = which( -            self.OPENVPN_BIN, -            path_extension=os.path.join(get_path_prefix(), -                                        "..", "apps", "eip")) - -        if len(openvpn_possibilities) == 0: -            raise OpenVPNNotFoundException() - -        openvpn = first(openvpn_possibilities) -        args = [] - -        args += [ -            '--setenv', "LEAPOPENVPN", "1" -        ] - -        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(self.tr('No gateway was found!')) - -        logger.debug("Using gateways ips: {0}".format(', '.join(gateways))) - -        for gw in gateways: -            args += ['--remote', gw, '1194', 'udp'] - -        args += [ -            '--client', -            '--dev', 'tun', -            ############################################################## -            # persist-tun makes ping-restart fail because it leaves a -            # broken routing table -            ############################################################## -            # '--persist-tun', -            '--persist-key', -            '--tls-client', -            # We make it log to a file because we cannot attach to the -            # openvpn process' stdout since it's a process with more -            # privileges than we are -            '--log-append', 'eip.log', -            '--remote-cert-tls', -            'server' -        ] - -        openvpn_configuration = eipconfig.get_openvpn_configuration() -        for key, value in openvpn_configuration.items(): -            args += ['--%s' % (key,), value] - -        ############################################################## -        # The down-root plugin fails in some situations, so we don't -        # drop privs for the time being -        ############################################################## -        # args += [ -        #     '--user', getpass.getuser(), -        #     #'--group', grp.getgrgid(os.getgroups()[-1]).gr_name -        # ] - -        args += [ -            '--management-signal', -            '--management', socket_host, socket_port, -            '--script-security', '2' -        ] - -        args += [ -            '--cert', eipconfig.get_client_cert_path(providerconfig), -            '--key', eipconfig.get_client_cert_path(providerconfig), -            '--ca', providerconfig.get_ca_cert_path() -        ] - -        logger.debug("Running VPN with command:") -        logger.debug("%s %s" % (openvpn, " ".join(args))) - -        return [openvpn] + args - -    def get_vpn_env(self): -        """ -        Returns a dictionary with the custom env for the platform. -        This is mainly used for setting LD_LIBRARY_PATH to the correct -        path when distributing a standalone client - -        :rtype: dict -        """ -        return {} - - -if __name__ == "__main__": -    logger = logging.getLogger(name='leap') -    logger.setLevel(logging.DEBUG) -    console = logging.StreamHandler() -    console.setLevel(logging.DEBUG) -    formatter = logging.Formatter( -        '%(asctime)s ' -        '- %(name)s - %(levelname)s - %(message)s') -    console.setFormatter(formatter) -    logger.addHandler(console) - -    try: -        abs_launcher = VPNLauncher() -    except Exception as e: -        assert isinstance(e, TypeError), "Something went wrong" -        print "Abstract Prefixer class is working as expected" - -    vpnlauncher = get_platform_launcher() - -    eipconfig = EIPConfig() -    eipconfig.set_api_version('1') -    if eipconfig.load("leap/providers/bitmask.net/eip-service.json"): -        provider = ProviderConfig() -        if provider.load("leap/providers/bitmask.net/provider.json"): -            vpnlauncher.get_vpn_command(eipconfig=eipconfig, -                                        providerconfig=provider, -                                        socket_host="/blah") diff --git a/src/leap/bitmask/services/eip/vpnprocess.py b/src/leap/bitmask/services/eip/vpnprocess.py index 15ac812b..707967e0 100644 --- a/src/leap/bitmask/services/eip/vpnprocess.py +++ b/src/leap/bitmask/services/eip/vpnprocess.py @@ -27,7 +27,7 @@ import socket  from PySide import QtCore  from leap.bitmask.config.providerconfig import ProviderConfig -from leap.bitmask.services.eip.vpnlaunchers import get_platform_launcher +from leap.bitmask.services.eip import get_vpn_launcher  from leap.bitmask.services.eip.eipconfig import EIPConfig  from leap.bitmask.services.eip.udstelnet import UDSTelnet  from leap.bitmask.util import first @@ -697,7 +697,7 @@ class VPNProcess(protocol.ProcessProtocol, VPNManager):          self._socket_host = socket_host          self._socket_port = socket_port -        self._launcher = get_platform_launcher() +        self._launcher = get_vpn_launcher()          self._last_state = None          self._last_status = None  | 
