コード例 #1
0
ファイル: emailfirewall.py プロジェクト: EvyW/bitmask_client
    def _run(self, cmd):
        """
        Run an email firewall command with bitmask-root

        Might raise:
            NoPkexecAvailable,
            NoPolkitAuthAgentAvailable,

        :param cmd: command to send to bitmask-root fw-email
        :type cmd: [str]
        :returns: exit code of bitmask-root
        :rtype: int
        """
        command = []

        policyChecker = LinuxPolicyChecker()
        pkexec = policyChecker.maybe_pkexec()
        if pkexec:
            command.append(first(pkexec))

        command.append(force_eval(self.BITMASK_ROOT))
        command.append("fw-email")
        command += cmd

        # XXX: will be nice to use twisted ProcessProtocol instead of
        #      subprocess to avoid blocking until it finish
        return subprocess.call(command)
コード例 #2
0
    def _run(self, cmd):
        """
        Run an email firewall command with bitmask-root

        Might raise:
            NoPkexecAvailable,
            NoPolkitAuthAgentAvailable,

        :param cmd: command to send to bitmask-root fw-email
        :type cmd: [str]
        :returns: exit code of bitmask-root
        :rtype: int
        """
        command = []

        policyChecker = LinuxPolicyChecker()
        pkexec = policyChecker.maybe_pkexec()
        if pkexec:
            command.append(first(pkexec))

        command.append(force_eval(self.BITMASK_ROOT))
        command.append("fw-email")
        command += cmd

        # XXX: will be nice to use twisted ProcessProtocol instead of
        #      subprocess to avoid blocking until it finish
        return subprocess.call(command)
コード例 #3
0
    def cmd_for_missing_scripts(kls, frompath):
        """
        Returns a sh script that can copy the missing files.

        :param frompath: The path where the helper files live
        :type frompath: str

        :rtype: str
        """
        bin_paths = force_eval(
            (LinuxVPNLauncher.POLKIT_PATH, LinuxVPNLauncher.OPENVPN_BIN_PATH, LinuxVPNLauncher.BITMASK_ROOT)
        )

        polkit_path, openvpn_bin_path, bitmask_root = bin_paths

        # no system config for now
        # sys_config = kls.SYSTEM_CONFIG
        (polkit_file, openvpn_bin_file, bitmask_root_file) = map(lambda p: os.path.split(p)[-1], bin_paths)

        cmd = "#!/bin/sh\n"
        cmd += "mkdir -p /usr/local/sbin\n"

        cmd += 'cp "%s" "%s"\n' % (os.path.join(frompath, polkit_file), polkit_path)
        cmd += 'chmod 644 "%s"\n' % (polkit_path,)

        cmd += 'cp "%s" "%s"\n' % (os.path.join(frompath, bitmask_root_file), bitmask_root)
        cmd += 'chmod 744 "%s"\n' % (bitmask_root,)

        if flags.STANDALONE:
            cmd += 'cp "%s" "%s"\n' % (os.path.join(frompath, openvpn_bin_file), openvpn_bin_path)
            cmd += 'chmod 744 "%s"\n' % (openvpn_bin_path,)

        return cmd
コード例 #4
0
ファイル: vpnprocess.py プロジェクト: meskio/bitmask_client
 def tear_down_firewall(self):
     """
     Tear the firewall down using the privileged wrapper.
     """
     BM_ROOT = force_eval(linuxvpnlauncher.LinuxVPNLauncher.BITMASK_ROOT)
     exitCode = subprocess.call(["pkexec",
                                 BM_ROOT, "firewall", "stop"])
     return True if exitCode is 0 else False
コード例 #5
0
    def is_fw_down(self):
        """
        Return whether the firewall is down or not.

        :rtype: bool
        """
        BM_ROOT = force_eval(linuxvpnlauncher.LinuxVPNLauncher.BITMASK_ROOT)
        fw_up_cmd = "pkexec {0} firewall isup".format(BM_ROOT)
        fw_is_down = lambda: commands.getstatusoutput(fw_up_cmd)[0] == 256
        return fw_is_down()
コード例 #6
0
 def tear_down_firewall(self):
     """
     Tear the firewall down using the privileged wrapper.
     """
     if IS_MAC:
         # We don't support Mac so far
         return True
     BM_ROOT = force_eval(linuxvpnlauncher.LinuxVPNLauncher.BITMASK_ROOT)
     exitCode = subprocess.call(["pkexec", BM_ROOT, "firewall", "stop"])
     return True if exitCode is 0 else False
コード例 #7
0
 def bitmask_root_vpn_down(self):
     """
     Bring openvpn down using the privileged wrapper.
     """
     if IS_MAC:
         # We don't support Mac so far
         return True
     BM_ROOT = force_eval(linuxvpnlauncher.LinuxVPNLauncher.BITMASK_ROOT)
     exitCode = subprocess.call(["pkexec", BM_ROOT, "openvpn", "stop"])
     return True if exitCode is 0 else False
コード例 #8
0
    def is_fw_down(self):
        """
        Return whether the firewall is down or not.

        :rtype: bool
        """
        BM_ROOT = force_eval(linuxvpnlauncher.LinuxVPNLauncher.BITMASK_ROOT)
        fw_up_cmd = "pkexec {0} firewall isup".format(BM_ROOT)
        fw_is_down = lambda: commands.getstatusoutput(fw_up_cmd)[0] == 256
        return fw_is_down()
コード例 #9
0
 def bitmask_root_vpn_down(self):
     """
     Bring openvpn down using the privileged wrapper.
     """
     if IS_MAC:
         # We don't support Mac so far
         return True
     BM_ROOT = force_eval(linuxvpnlauncher.LinuxVPNLauncher.BITMASK_ROOT)
     exitCode = subprocess.call(["pkexec",
                                 BM_ROOT, "openvpn", "stop"])
     return True if exitCode is 0 else False
コード例 #10
0
    def get_vpn_command(kls,
                        eipconfig,
                        providerconfig,
                        socket_host,
                        socket_port="unix",
                        openvpn_verb=1):
        """
        Returns the Linux implementation for the vpn launching command.

        Might raise:
            EIPNoPkexecAvailable,
            EIPNoPolkitAuthAgentAvailable,
            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: the openvpn verbosity wanted
        :type openvpn_verb: int

        :return: A VPN command ready to be launched.
        :rtype: list
        """
        # 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, force_eval(kls.BITMASK_ROOT))
        command.insert(1, "openvpn")
        command.insert(2, "start")

        policyChecker = LinuxPolicyChecker()
        try:
            pkexec = policyChecker.maybe_pkexec()
        except NoPolkitAuthAgentAvailable:
            raise EIPNoPolkitAuthAgentAvailable()
        except NoPkexecAvailable:
            raise EIPNoPkexecAvailable()
        if pkexec:
            command.insert(0, first(pkexec))

        return command
コード例 #11
0
ファイル: vpnprocess.py プロジェクト: simonft/bitmask_client
    def bitmask_root_vpn_down(self):
        """
        Bring openvpn down using the privileged wrapper.
        """
        if IS_MAC:
            cmd = 'openvpn_stop'
            helper = darwinvpnlauncher.DarwinHelperCommand()
            result = helper.send(cmd)
            return True

        if IS_LINUX:
            BM_ROOT = force_eval(
                linuxvpnlauncher.LinuxVPNLauncher.BITMASK_ROOT)
            exitCode = subprocess.call(["pkexec", BM_ROOT, "openvpn", "stop"])
            return True if exitCode is 0 else False
コード例 #12
0
ファイル: vpnprocess.py プロジェクト: simonft/bitmask_client
    def tear_down_firewall(self):
        """
        Tear the firewall down using the privileged wrapper.
        """
        if IS_MAC:
            cmd = 'firewall_stop'
            helper = darwinvpnlauncher.DarwinHelperCommand()
            result = helper.send(cmd)
            return True

        if IS_LINUX:
            BM_ROOT = force_eval(
                linuxvpnlauncher.LinuxVPNLauncher.BITMASK_ROOT)
            exitCode = subprocess.call(["pkexec", BM_ROOT, "firewall", "stop"])
            return True if exitCode is 0 else False
コード例 #13
0
    def tear_down_firewall(self):
        """
        Tear the firewall down using the privileged wrapper.
        """
        if IS_MAC:
            cmd = 'firewall_stop'
            helper = darwinvpnlauncher.DarwinHelperCommand()
            result = helper.send(cmd)
            return True

        if IS_LINUX:
            BM_ROOT = force_eval(
                linuxvpnlauncher.LinuxVPNLauncher.BITMASK_ROOT)
            exitCode = subprocess.call(["pkexec",
                                        BM_ROOT, "firewall", "stop"])
            return True if exitCode is 0 else False
コード例 #14
0
    def bitmask_root_vpn_down(self):
        """
        Bring openvpn down using the privileged wrapper.
        """
        if IS_MAC:
            cmd = 'openvpn_stop'
            helper = darwinvpnlauncher.DarwinHelperCommand()
            result = helper.send(cmd)
            return True

        if IS_LINUX:
            BM_ROOT = force_eval(
                linuxvpnlauncher.LinuxVPNLauncher.BITMASK_ROOT)
            exitCode = subprocess.call(["pkexec",
                                        BM_ROOT, "openvpn", "stop"])
            return True if exitCode is 0 else False
コード例 #15
0
    def _can_start(self, domain):
        """
        Returns True if it has everything that is needed to run EIP,
        False otherwise

        :param domain: the domain for the provider to check
        :type domain: str
        """
        if IS_LINUX and not LinuxPolicyChecker.is_up():
            logger.error("No polkit agent running.")
            return False

        provider_config = ProviderConfig.get_provider_config(domain)
        if EIP_SERVICE not in provider_config.get_services():
            return False
        eip_config = eipconfig.EIPConfig()

        api_version = provider_config.get_api_version()
        eip_config.set_api_version(api_version)
        eip_loaded = eip_config.load(eipconfig.get_eipconfig_path(domain))

        launcher = get_vpn_launcher()
        ovpn_path = force_eval(launcher.OPENVPN_BIN_PATH)
        if not os.path.isfile(ovpn_path):
            logger.error("Cannot start OpenVPN, binary not found: %s" %
                         (ovpn_path,))
            return False

        # check for other problems
        if not eip_loaded or provider_config is None:
            logger.error("Cannot load provider and eip config, cannot "
                         "autostart")
            return False

        client_cert_path = eip_config.\
            get_client_cert_path(provider_config, about_to_download=True)

        if leap_certs.should_redownload(client_cert_path):
            logger.error("The client should redownload the certificate,"
                         " cannot autostart")
            return False

        if not os.path.isfile(client_cert_path):
            logger.error("Can't find the certificate, cannot autostart")
            return False

        return True
コード例 #16
0
    def _can_start(self, domain):
        """
        Returns True if it has everything that is needed to run EIP,
        False otherwise

        :param domain: the domain for the provider to check
        :type domain: str
        """
        if not LinuxPolicyChecker.is_up():
            logger.error("No polkit agent running.")
            return False

        eip_config = eipconfig.EIPConfig()
        provider_config = ProviderConfig.get_provider_config(domain)

        api_version = provider_config.get_api_version()
        eip_config.set_api_version(api_version)
        eip_loaded = eip_config.load(eipconfig.get_eipconfig_path(domain))

        launcher = get_vpn_launcher()
        ovpn_path = force_eval(launcher.OPENVPN_BIN_PATH)
        if not os.path.isfile(ovpn_path):
            logger.error("Cannot start OpenVPN, binary not found: %s" %
                         (ovpn_path, ))
            return False

        # check for other problems
        if not eip_loaded or provider_config is None:
            logger.error("Cannot load provider and eip config, cannot "
                         "autostart")
            return False

        client_cert_path = eip_config.\
            get_client_cert_path(provider_config, about_to_download=True)

        if leap_certs.should_redownload(client_cert_path):
            logger.error("The client should redownload the certificate,"
                         " cannot autostart")
            return False

        if not os.path.isfile(client_cert_path):
            logger.error("Can't find the certificate, cannot autostart")
            return False

        return True
コード例 #17
0
    def get_vpn_command(kls, eipconfig, providerconfig, socket_host, socket_port="unix", openvpn_verb=1):
        """
        Returns the Linux implementation for the vpn launching command.

        Might raise:
            EIPNoPkexecAvailable,
            EIPNoPolkitAuthAgentAvailable,
            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: the openvpn verbosity wanted
        :type openvpn_verb: int

        :return: A VPN command ready to be launched.
        :rtype: list
        """
        # 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, force_eval(kls.BITMASK_ROOT))
        command.insert(1, "openvpn")
        command.insert(2, "start")

        policyChecker = LinuxPolicyChecker()
        try:
            pkexec = policyChecker.maybe_pkexec()
        except NoPolkitAuthAgentAvailable:
            raise EIPNoPolkitAuthAgentAvailable()
        except NoPkexecAvailable:
            raise EIPNoPkexecAvailable()
        if pkexec:
            command.insert(0, first(pkexec))

        return command
コード例 #18
0
    def is_fw_down(self):
        """
        Return whether the firewall is down or not.

        :rtype: bool
        """
        if IS_LINUX:
            BM_ROOT = force_eval(
                linuxvpnlauncher.LinuxVPNLauncher.BITMASK_ROOT)
            fw_up_cmd = "pkexec {0} firewall isup".format(BM_ROOT)
            fw_is_down = lambda: commands.getstatusoutput(fw_up_cmd)[0] == 256
            return fw_is_down()

        if IS_MAC:
            cmd = 'firewall_isup'
            helper = darwinvpnlauncher.DarwinHelperCommand()
            result = helper.send(cmd)
            return True
コード例 #19
0
ファイル: vpnprocess.py プロジェクト: simonft/bitmask_client
    def is_fw_down(self):
        """
        Return whether the firewall is down or not.

        :rtype: bool
        """
        if IS_LINUX:
            BM_ROOT = force_eval(
                linuxvpnlauncher.LinuxVPNLauncher.BITMASK_ROOT)
            fw_up_cmd = "pkexec {0} firewall isup".format(BM_ROOT)
            fw_is_down = lambda: commands.getstatusoutput(fw_up_cmd)[0] == 256
            return fw_is_down()

        if IS_MAC:
            cmd = 'firewall_isup'
            helper = darwinvpnlauncher.DarwinHelperCommand()
            result = helper.send(cmd)
            return True
コード例 #20
0
ファイル: vpnprocess.py プロジェクト: simonft/bitmask_client
    def _launch_firewall_linux(self, gateways, restart=False):
        """
        Launch the firewall using the privileged wrapper (linux).

        :param gateways:
        :type gateways: list

        :returns: True if the exitcode of calling the root helper in a
                  subprocess is 0.
        :rtype: bool
        """
        # XXX could check for wrapper existence, check it's root owned etc.
        # XXX could check that the iptables rules are in place.

        BM_ROOT = force_eval(linuxvpnlauncher.LinuxVPNLauncher.BITMASK_ROOT)
        cmd = ["pkexec", BM_ROOT, "firewall", "start"]
        if restart:
            cmd.append("restart")
        exitCode = subprocess.call(cmd + gateways)
        return True if exitCode is 0 else False
コード例 #21
0
    def _launch_firewall(self, gateways, restart=False):
        """
        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
        """
        # XXX could check for wrapper existence, check it's root owned etc.
        # XXX could check that the iptables rules are in place.

        BM_ROOT = force_eval(linuxvpnlauncher.LinuxVPNLauncher.BITMASK_ROOT)
        cmd = ["pkexec", BM_ROOT, "firewall", "start"]
        if restart:
            cmd.append("restart")
        exitCode = subprocess.call(cmd + gateways)
        return True if exitCode is 0 else False
コード例 #22
0
    def missing_other_files(kls):
        """
        Return 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")
        other = force_eval(kls.OTHER_FILES)
        file_exist = partial(_has_other_files, warn=False)

        if flags.STANDALONE:
            try:
                from leap.bitmask import _binaries
            except ImportError:
                raise RuntimeError(
                    "Could not find binary hash info in this bundle!")

            _, bitmask_root_path, openvpn_bin_path = other

            check_hash = _has_expected_binary_hash
            openvpn_hash = _binaries.OPENVPN_BIN
            bitmask_root_hash = _binaries.BITMASK_ROOT

            correct_hash = (
                True,  # we do not check the polkit file
                check_hash(bitmask_root_path, bitmask_root_hash),
                check_hash(openvpn_bin_path, openvpn_hash))

            zipped = zip(other, map(file_exist, other), correct_hash)
            missing = filter(
                lambda (path, exists, hash_ok):
                (exists is False or hash_ok is False), zipped)
            return [path for path, exists, hash_ok in missing]
        else:
            zipped = zip(other, map(file_exist, other))
            missing = filter(lambda (path, exists): exists is False, zipped)
            return [path for path, exists in missing]
コード例 #23
0
    def missing_other_files(kls):
        """
        Return 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")
        other = force_eval(kls.OTHER_FILES)
        file_exist = partial(_has_other_files, warn=False)

        if flags.STANDALONE:
            try:
                from leap.bitmask import _binaries
            except ImportError:
                raise RuntimeError(
                    "Could not find binary hash info in this bundle!")

            _, bitmask_root_path, openvpn_bin_path = other

            check_hash = _has_expected_binary_hash
            openvpn_hash = _binaries.OPENVPN_BIN
            bitmask_root_hash = _binaries.BITMASK_ROOT

            correct_hash = (
                True,  # we do not check the polkit file
                check_hash(bitmask_root_path, bitmask_root_hash),
                check_hash(openvpn_bin_path, openvpn_hash))

            zipped = zip(other, map(file_exist, other), correct_hash)
            missing = filter(
                lambda (path, exists, hash_ok): (
                    exists is False or hash_ok is False),
                zipped)
            return [path for path, exists, hash_ok in missing]
        else:
            zipped = zip(other, map(file_exist, other))
            missing = filter(lambda (path, exists): exists is False, zipped)
            return [path for path, exists in missing]
コード例 #24
0
    def cmd_for_missing_scripts(kls, frompath):
        """
        Returns a sh script that can copy the missing files.

        :param frompath: The path where the helper files live
        :type frompath: str

        :rtype: str
        """
        bin_paths = force_eval(
            (LinuxVPNLauncher.POLKIT_PATH,
             LinuxVPNLauncher.OPENVPN_BIN_PATH,
             LinuxVPNLauncher.BITMASK_ROOT))

        polkit_path, openvpn_bin_path, bitmask_root = bin_paths

        # no system config for now
        # sys_config = kls.SYSTEM_CONFIG
        (polkit_file, openvpn_bin_file,
         bitmask_root_file) = map(
            lambda p: os.path.split(p)[-1],
            bin_paths)

        cmd = '#!/bin/sh\n'
        cmd += 'mkdir -p /usr/local/sbin\n'

        cmd += 'cp "%s" "%s"\n' % (os.path.join(frompath, polkit_file),
                                   polkit_path)
        cmd += 'chmod 644 "%s"\n' % (polkit_path, )

        cmd += 'cp "%s" "%s"\n' % (os.path.join(frompath, bitmask_root_file),
                                   bitmask_root)
        cmd += 'chmod 744 "%s"\n' % (bitmask_root, )

        if flags.STANDALONE:
            cmd += 'cp "%s" "%s"\n' % (
                os.path.join(frompath, openvpn_bin_file),
                openvpn_bin_path)
            cmd += 'chmod 744 "%s"\n' % (openvpn_bin_path, )

        return cmd
コード例 #25
0
    def get_vpn_command(kls,
                        eipconfig,
                        providerconfig,
                        socket_host,
                        socket_port,
                        openvpn_verb=1):
        """
        Return the platform-dependant vpn command for launching openvpn.

        Might raise:
            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: the 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)

        # 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)
        # -----------------------------------------
        openvpn_path = force_eval(kls.OPENVPN_BIN_PATH)

        if not os.path.isfile(openvpn_path):
            logger.warning("Could not find openvpn bin in path %s" %
                           (openvpn_path))
            raise OpenVPNNotFoundException()

        args = []

        args += ['--setenv', "LEAPOPENVPN", "1", '--nobind']

        if openvpn_verb is not None:
            args += ['--verb', '%d' % (openvpn_verb, )]

        gateways = kls.get_gateways(eipconfig, providerconfig)

        for gw in gateways:
            args += ['--remote', gw, '1194', 'udp']

        args += [
            '--client', '--dev', '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()

        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 kls.UP_SCRIPT is not None:
            if _has_updown_scripts(kls.UP_SCRIPT):
                args += [
                    '--up',
                    '\"%s\"' % (kls.UP_SCRIPT, ),
                ]

        if kls.DOWN_SCRIPT is not None:
            if _has_updown_scripts(kls.DOWN_SCRIPT):
                args += ['--down', '\"%s\"' % (kls.DOWN_SCRIPT, )]

        args += [
            '--cert',
            eipconfig.get_client_cert_path(providerconfig), '--key',
            eipconfig.get_client_cert_path(providerconfig), '--ca',
            providerconfig.get_ca_cert_path()
        ]

        args += ['--ping', '10', '--ping-restart', '30']

        command_and_args = [openvpn_path] + args
        return command_and_args
コード例 #26
0
    def get_vpn_command(kls, eipconfig, providerconfig,
                        socket_host, socket_port, openvpn_verb=1):
        """
        Return the platform-dependant vpn command for launching openvpn.

        Might raise:
            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: the 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)

        # 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)
        # -----------------------------------------
        openvpn_path = force_eval(kls.OPENVPN_BIN_PATH)

        if not os.path.isfile(openvpn_path):
            logger.warning("Could not find openvpn bin in path %s" % (
                openvpn_path))
            raise OpenVPNNotFoundException()

        args = []

        args += [
            '--setenv', "LEAPOPENVPN", "1",
            '--nobind'
        ]

        if openvpn_verb is not None:
            args += ['--verb', '%d' % (openvpn_verb,)]

        gateways = kls.get_gateways(eipconfig, providerconfig)

        for ip, port in gateways:
            args += ['--remote', ip, port, 'udp']

        args += [
            '--client',
            '--dev', '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()

        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 kls.UP_SCRIPT is not None:
            if _has_updown_scripts(kls.UP_SCRIPT):
                args += [
                    '--up', '\"%s\"' % (kls.UP_SCRIPT,),
                ]

        if kls.DOWN_SCRIPT is not None:
            if _has_updown_scripts(kls.DOWN_SCRIPT):
                args += [
                    '--down', '\"%s\"' % (kls.DOWN_SCRIPT,)
                ]

        args += [
            '--cert', eipconfig.get_client_cert_path(providerconfig),
            '--key', eipconfig.get_client_cert_path(providerconfig),
            '--ca', providerconfig.get_ca_cert_path()
        ]

        args += [
            '--ping', '10',
            '--ping-restart', '30']

        command_and_args = [openvpn_path] + args
        return command_and_args