From ee8fbbdc2f3dbccea3a830b40e9eb0be5b392d7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Wed, 6 Mar 2013 15:38:05 -0300 Subject: Add EIP service --- src/leap/services/eip/vpnlaunchers.py | 270 ++++++++++++++++++++++++++++++++++ 1 file changed, 270 insertions(+) create mode 100644 src/leap/services/eip/vpnlaunchers.py (limited to 'src/leap/services/eip/vpnlaunchers.py') diff --git a/src/leap/services/eip/vpnlaunchers.py b/src/leap/services/eip/vpnlaunchers.py new file mode 100644 index 00000000..68978248 --- /dev/null +++ b/src/leap/services/eip/vpnlaunchers.py @@ -0,0 +1,270 @@ +# -*- 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 . + +""" +Platform dependant VPN launchers +""" +import os +import platform +import logging +import commands +import getpass +import grp + +from abc import ABCMeta, abstractmethod + +from leap.config.providerconfig import ProviderConfig +from leap.services.eip.eipconfig import EIPConfig + +logger = logging.getLogger(__name__) + + +class VPNLauncher: + """ + Abstract launcher class + """ + + __metaclass__ = ABCMeta + + # TODO: document parameters + @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 [] + + +def get_platform_launcher(): + launcher = globals()[platform.system() + "VPNLauncher"] + assert launcher, "Unimplemented platform launcher: %s" % \ + (platform.system(),) + return launcher() + + +# Twisted implementation of which +def which(name, flags=os.X_OK): + """ + Search PATH for executable files with the given name. + + On newer versions of MS-Windows, the PATHEXT environment variable will be + set to the list of file extensions for files considered executable. This + will normally include things like ".EXE". This fuction will also find files + with the given name ending with any of these extensions. + + On MS-Windows the only flag that has any meaning is os.F_OK. Any other + flags will be ignored. + + @type name: C{str} + @param name: The name for which to search. + + @type flags: C{int} + @param flags: Arguments to L{os.access}. + + @rtype: C{list} + @param: A list of the full paths to files found, in the + order in which they were found. + """ + + # TODO: make sure sbin is in path + + result = [] + exts = filter(None, os.environ.get('PATHEXT', '').split(os.pathsep)) + path = os.environ.get('PATH', None) + if path is None: + return [] + for p in os.environ.get('PATH', '').split(os.pathsep): + p = os.path.join(p, name) + if os.access(p, flags): + result.append(p) + for e in exts: + pext = p + e + if os.access(pext, flags): + result.append(pext) + return result + + +def _is_pkexec_in_system(): + pkexec_path = which('pkexec') + if len(pkexec_path) == 0: + return False + return True + + +def _has_updown_scripts(path): + """ + Checks the existence of the up/down scripts + """ + # XXX should check permissions too + is_file = os.path.isfile(path) + if not is_file: + logger.warning("Could not find up/down scripts. " + + "Might produce DNS leaks.") + return is_file + + +def _is_auth_agent_running(): + return bool( + commands.getoutput( + 'ps aux | grep polkit-[g]nome-authentication-agent-1')) + + +class LinuxVPNLauncher(VPNLauncher): + """ + VPN launcher for the Linux platform + """ + + PKEXEC_BIN = 'pkexec' + OPENVPN_BIN = 'openvpn' + UP_DOWN_SCRIPT = "/etc/leap/resolv-update" + OPENVPN_DOWN_ROOT = "/usr/lib/openvpn/openvpn-down-root.so" + + def get_vpn_command(self, eipconfig=None, providerconfig=None, + socket_host=None, socket_port="unix"): + """ + 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 + """ + assert eipconfig, "We need an eip config" + assert isinstance(eipconfig, EIPConfig), "Expected EIPConfig " + \ + "object instead of %s" % (type(eipconfig),) + assert providerconfig, "We need a provider config" + assert isinstance(providerconfig, ProviderConfig), "Expected " + \ + "ProviderConfig object instead of %s" % (type(providerconfig),) + assert socket_host, "We need a socket host!" + assert socket_port, "We need a socket port!" + + openvpn_possibilities = which(self.OPENVPN_BIN) + assert len(openvpn_possibilities) > 0, "We couldn't find openvpn" + + openvpn = openvpn_possibilities[0] + args = [] + + if _is_pkexec_in_system(): + if _is_auth_agent_running(): + pkexec_possibilities = which(self.PKEXEC_BIN) + assert len(pkexec_possibilities) > 0, "We couldn't find pkexec" + args.append(openvpn) + openvpn = pkexec_possibilities[0] + else: + logger.warning("No polkit auth agent found. pkexec " + + "will use its own auth agent.") + else: + logger.warning("System has no pkexec") + + # TODO: handle verbosity + + gateway_ip = str(eipconfig.get_gateway_ip(0)) + + logger.debug("Using gateway ip %s" % (gateway_ip,)) + + args += [ + '--client', + '--dev', 'tun', + '--persist-tun', + '--persist-key', + '--remote', gateway_ip, '1194', 'udp', + '--tls-client', + '--remote-cert-tls', + 'server' + ] + + openvpn_configuration = eipconfig.get_openvpn_configuration() + for key, value in openvpn_configuration.items(): + args += ['--%s' % (key,), value] + + args += [ + '--user', getpass.getuser(), + '--group', grp.getgrgid(os.getgroups()[-1]).gr_name, + '--management-client-user', getpass.getuser(), + '--management-signal', + '--management', socket_host, socket_port, + '--script-security', '2' + ] + + if _has_updown_scripts(self.UP_DOWN_SCRIPT): + args += [ + '--up', self.UP_DOWN_SCRIPT, + '--down', self.UP_DOWN_SCRIPT, + '--plugin', self.OPENVPN_DOWN_ROOT, + '\'script_type=down %s\'' % self.UP_DOWN_SCRIPT + ] + + 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 + + +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() + 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") -- cgit v1.2.3 From 751638b4eb8208e1eaa1beaaed284da6b412bca7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Thu, 7 Mar 2013 19:05:11 -0300 Subject: Change asserts for a custom leap_assert method Also: - Make SRPAuth and the Bootstrappers be a QObject instead of a QThread so we can use them inside another more generic thread - Add a generic CheckerThread that runs checks or whatever operation as long as it returns a boolean value - Closes the whole application if the wizard is rejected at the first run - Do not fail when the config directory doesn't exist - Set the wizard pixmap logo as LEAP's logo - Improve wizard checks - Make SRPRegister play nice with the CheckerThread --- src/leap/services/eip/vpnlaunchers.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'src/leap/services/eip/vpnlaunchers.py') diff --git a/src/leap/services/eip/vpnlaunchers.py b/src/leap/services/eip/vpnlaunchers.py index 68978248..00e9c966 100644 --- a/src/leap/services/eip/vpnlaunchers.py +++ b/src/leap/services/eip/vpnlaunchers.py @@ -29,6 +29,7 @@ from abc import ABCMeta, abstractmethod from leap.config.providerconfig import ProviderConfig from leap.services.eip.eipconfig import EIPConfig +from leap.util.check import leap_assert, leap_assert_type logger = logging.getLogger(__name__) @@ -65,8 +66,8 @@ class VPNLauncher: def get_platform_launcher(): launcher = globals()[platform.system() + "VPNLauncher"] - assert launcher, "Unimplemented platform launcher: %s" % \ - (platform.system(),) + leap_assert(launcher, "Unimplemented platform launcher: %s" % + (platform.system(),)) return launcher() @@ -165,17 +166,15 @@ class LinuxVPNLauncher(VPNLauncher): @return: A VPN command ready to be launched @rtype: list """ - assert eipconfig, "We need an eip config" - assert isinstance(eipconfig, EIPConfig), "Expected EIPConfig " + \ - "object instead of %s" % (type(eipconfig),) - assert providerconfig, "We need a provider config" - assert isinstance(providerconfig, ProviderConfig), "Expected " + \ - "ProviderConfig object instead of %s" % (type(providerconfig),) - assert socket_host, "We need a socket host!" - assert socket_port, "We need a socket port!" + 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!") openvpn_possibilities = which(self.OPENVPN_BIN) - assert len(openvpn_possibilities) > 0, "We couldn't find openvpn" + leap_assert(len(openvpn_possibilities) > 0, "We couldn't find openvpn") openvpn = openvpn_possibilities[0] args = [] @@ -183,7 +182,8 @@ class LinuxVPNLauncher(VPNLauncher): if _is_pkexec_in_system(): if _is_auth_agent_running(): pkexec_possibilities = which(self.PKEXEC_BIN) - assert len(pkexec_possibilities) > 0, "We couldn't find pkexec" + leap_assert(len(pkexec_possibilities) > 0, + "We couldn't find pkexec") args.append(openvpn) openvpn = pkexec_possibilities[0] else: -- cgit v1.2.3 From 926575bc811e8382100695a3396da7191fb43eb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Fri, 8 Mar 2013 13:15:38 -0300 Subject: Add translation support Also: - Make OpenVPN use a random port every time - Logout in parallel so the UI doesn't block - Add the WAIT status from OpenVPN to the mainwindow displays - Support non-unix sockets in the LinuxVPNLauncher --- src/leap/services/eip/vpnlaunchers.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'src/leap/services/eip/vpnlaunchers.py') diff --git a/src/leap/services/eip/vpnlaunchers.py b/src/leap/services/eip/vpnlaunchers.py index 00e9c966..cf817321 100644 --- a/src/leap/services/eip/vpnlaunchers.py +++ b/src/leap/services/eip/vpnlaunchers.py @@ -215,8 +215,15 @@ class LinuxVPNLauncher(VPNLauncher): args += [ '--user', getpass.getuser(), - '--group', grp.getgrgid(os.getgroups()[-1]).gr_name, - '--management-client-user', getpass.getuser(), + '--group', grp.getgrgid(os.getgroups()[-1]).gr_name + ] + + if socket_port == "unix": + args += [ + '--management-client-user', getpass.getuser() + ] + + args += [ '--management-signal', '--management', socket_host, socket_port, '--script-security', '2' -- cgit v1.2.3 From 060984df444dbf407e9078de638ef7486ef7b0a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Mon, 11 Mar 2013 16:42:23 -0300 Subject: Notify if openvpn is not found --- src/leap/services/eip/vpnlaunchers.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'src/leap/services/eip/vpnlaunchers.py') diff --git a/src/leap/services/eip/vpnlaunchers.py b/src/leap/services/eip/vpnlaunchers.py index cf817321..9f2967aa 100644 --- a/src/leap/services/eip/vpnlaunchers.py +++ b/src/leap/services/eip/vpnlaunchers.py @@ -34,6 +34,10 @@ from leap.util.check import leap_assert, leap_assert_type logger = logging.getLogger(__name__) +class VPNLauncherException(Exception): + pass + + class VPNLauncher: """ Abstract launcher class @@ -153,6 +157,8 @@ class LinuxVPNLauncher(VPNLauncher): """ Returns the platform dependant vpn launching command + Might raise VPNException. + @param eipconfig: eip configuration object @type eipconfig: EIPConfig @param providerconfig: provider specific configuration @@ -174,7 +180,8 @@ class LinuxVPNLauncher(VPNLauncher): leap_assert(socket_port, "We need a socket port!") openvpn_possibilities = which(self.OPENVPN_BIN) - leap_assert(len(openvpn_possibilities) > 0, "We couldn't find openvpn") + if len(openvpn_possibilities) == 0: + raise VPNLauncherException("We couldn't find openvpn") openvpn = openvpn_possibilities[0] args = [] -- cgit v1.2.3 From cf83b3ffe300058a4ed30d255481f0c781b0b942 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Tue, 12 Mar 2013 09:02:08 -0300 Subject: Extend path to sbin by default --- src/leap/services/eip/vpnlaunchers.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/leap/services/eip/vpnlaunchers.py') diff --git a/src/leap/services/eip/vpnlaunchers.py b/src/leap/services/eip/vpnlaunchers.py index 9f2967aa..6f277481 100644 --- a/src/leap/services/eip/vpnlaunchers.py +++ b/src/leap/services/eip/vpnlaunchers.py @@ -76,7 +76,7 @@ def get_platform_launcher(): # Twisted implementation of which -def which(name, flags=os.X_OK): +def which(name, flags=os.X_OK, path_extension="/usr/sbin:/sbin"): """ Search PATH for executable files with the given name. @@ -99,14 +99,14 @@ def which(name, flags=os.X_OK): order in which they were found. """ - # TODO: make sure sbin is in path - result = [] exts = filter(None, os.environ.get('PATHEXT', '').split(os.pathsep)) path = os.environ.get('PATH', None) + path += ":" + path_extension if path is None: return [] - for p in os.environ.get('PATH', '').split(os.pathsep): + parts = path.split(os.pathsep) + for p in parts: p = os.path.join(p, name) if os.access(p, flags): result.append(p) -- cgit v1.2.3 From ef43dff37c6db915757184ad51bc017d45e70c98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Wed, 13 Mar 2013 14:02:13 -0300 Subject: Notify the user of pkexec/polkit/openvpn checks --- src/leap/services/eip/vpnlaunchers.py | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) (limited to 'src/leap/services/eip/vpnlaunchers.py') diff --git a/src/leap/services/eip/vpnlaunchers.py b/src/leap/services/eip/vpnlaunchers.py index 6f277481..9345c0b3 100644 --- a/src/leap/services/eip/vpnlaunchers.py +++ b/src/leap/services/eip/vpnlaunchers.py @@ -38,6 +38,18 @@ class VPNLauncherException(Exception): pass +class OpenVPNNotFoundException(VPNLauncherException): + pass + + +class EIPNoPolkitAuthAgentAvailable(VPNLauncherException): + pass + + +class EIPNoPkexecAvailable(VPNLauncherException): + pass + + class VPNLauncher: """ Abstract launcher class @@ -45,7 +57,6 @@ class VPNLauncher: __metaclass__ = ABCMeta - # TODO: document parameters @abstractmethod def get_vpn_command(self, eipconfig=None, providerconfig=None, socket_host=None, socket_port=None): @@ -137,9 +148,9 @@ def _has_updown_scripts(path): def _is_auth_agent_running(): - return bool( + return len( commands.getoutput( - 'ps aux | grep polkit-[g]nome-authentication-agent-1')) + 'ps aux | grep polkit-[g]nome-authentication-agent-1')) > 0 class LinuxVPNLauncher(VPNLauncher): @@ -181,7 +192,7 @@ class LinuxVPNLauncher(VPNLauncher): openvpn_possibilities = which(self.OPENVPN_BIN) if len(openvpn_possibilities) == 0: - raise VPNLauncherException("We couldn't find openvpn") + raise OpenVPNNotFoundException() openvpn = openvpn_possibilities[0] args = [] @@ -196,8 +207,10 @@ class LinuxVPNLauncher(VPNLauncher): 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() # TODO: handle verbosity -- cgit v1.2.3 From 452d1b3a0ab64a6d1e742a74c369336dcdf91897 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Wed, 13 Mar 2013 15:37:04 -0300 Subject: Make the no up/down log an error instead of a warning --- src/leap/services/eip/vpnlaunchers.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/leap/services/eip/vpnlaunchers.py') diff --git a/src/leap/services/eip/vpnlaunchers.py b/src/leap/services/eip/vpnlaunchers.py index 9345c0b3..c646da7d 100644 --- a/src/leap/services/eip/vpnlaunchers.py +++ b/src/leap/services/eip/vpnlaunchers.py @@ -142,8 +142,8 @@ def _has_updown_scripts(path): # XXX should check permissions too is_file = os.path.isfile(path) if not is_file: - logger.warning("Could not find up/down scripts. " + - "Might produce DNS leaks.") + logger.error("Could not find up/down scripts. " + + "Might produce DNS leaks.") return is_file -- cgit v1.2.3 From d0dfad6ac2af360de6421ce74a6831b5b81ad019 Mon Sep 17 00:00:00 2001 From: kali Date: Thu, 14 Mar 2013 07:08:31 +0900 Subject: namespace leap + leap.common split leap is a namespace package from here on. common folder will be deleted and moved to leap_pycommon repository. --- src/leap/services/eip/vpnlaunchers.py | 51 ++++------------------------------- 1 file changed, 5 insertions(+), 46 deletions(-) (limited to 'src/leap/services/eip/vpnlaunchers.py') diff --git a/src/leap/services/eip/vpnlaunchers.py b/src/leap/services/eip/vpnlaunchers.py index c646da7d..f9e8e366 100644 --- a/src/leap/services/eip/vpnlaunchers.py +++ b/src/leap/services/eip/vpnlaunchers.py @@ -18,18 +18,19 @@ """ Platform dependant VPN launchers """ -import os -import platform -import logging import commands +import logging import getpass import grp +import os +import platform from abc import ABCMeta, abstractmethod +from leap.common.check import leap_assert, leap_assert_type +from leap.common.files import which from leap.config.providerconfig import ProviderConfig from leap.services.eip.eipconfig import EIPConfig -from leap.util.check import leap_assert, leap_assert_type logger = logging.getLogger(__name__) @@ -86,48 +87,6 @@ def get_platform_launcher(): return launcher() -# Twisted implementation of which -def which(name, flags=os.X_OK, path_extension="/usr/sbin:/sbin"): - """ - Search PATH for executable files with the given name. - - On newer versions of MS-Windows, the PATHEXT environment variable will be - set to the list of file extensions for files considered executable. This - will normally include things like ".EXE". This fuction will also find files - with the given name ending with any of these extensions. - - On MS-Windows the only flag that has any meaning is os.F_OK. Any other - flags will be ignored. - - @type name: C{str} - @param name: The name for which to search. - - @type flags: C{int} - @param flags: Arguments to L{os.access}. - - @rtype: C{list} - @param: A list of the full paths to files found, in the - order in which they were found. - """ - - result = [] - exts = filter(None, os.environ.get('PATHEXT', '').split(os.pathsep)) - path = os.environ.get('PATH', None) - path += ":" + path_extension - if path is None: - return [] - parts = path.split(os.pathsep) - for p in parts: - p = os.path.join(p, name) - if os.access(p, flags): - result.append(p) - for e in exts: - pext = p + e - if os.access(pext, flags): - result.append(pext) - return result - - def _is_pkexec_in_system(): pkexec_path = which('pkexec') if len(pkexec_path) == 0: -- cgit v1.2.3 From e33081871affdbca197ea77c461b1379b9039117 Mon Sep 17 00:00:00 2001 From: kali Date: Wed, 20 Mar 2013 19:31:24 +0900 Subject: add darwin prefixer and launcher --- src/leap/services/eip/vpnlaunchers.py | 110 ++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) (limited to 'src/leap/services/eip/vpnlaunchers.py') diff --git a/src/leap/services/eip/vpnlaunchers.py b/src/leap/services/eip/vpnlaunchers.py index f9e8e366..44dff4d0 100644 --- a/src/leap/services/eip/vpnlaunchers.py +++ b/src/leap/services/eip/vpnlaunchers.py @@ -188,6 +188,115 @@ class LinuxVPNLauncher(VPNLauncher): 'server' ] + openvpn_configuration = eipconfig.get_openvpn_configuration() + + # FIXME: sanitize this! -- + for key, value in openvpn_configuration.items(): + args += ['--%s' % (key,), value] + + args += [ + '--user', getpass.getuser(), + '--group', grp.getgrgid(os.getgroups()[-1]).gr_name + ] + + if socket_port == "unix": + args += [ + '--management-client-user', getpass.getuser() + ] + + args += [ + '--management-signal', + '--management', socket_host, socket_port, + '--script-security', '2' + ] + + if _has_updown_scripts(self.UP_DOWN_SCRIPT): + args += [ + '--up', self.UP_DOWN_SCRIPT, + '--down', self.UP_DOWN_SCRIPT, + '--plugin', self.OPENVPN_DOWN_ROOT, + '\'script_type=down %s\'' % self.UP_DOWN_SCRIPT + ] + + 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 + + +class DarwinVPNLauncher(VPNLauncher): + """ + VPN launcher for the Darwin Platform + """ + + OSASCRIPT_BIN = 'osascript' + OSX_ASADMIN = 'do shell script "%s" with administrator privileges' + OPENVPN_BIN = 'openvpn.leap' + INSTALL_PATH = "/Applications/LEAPClient.app/" + # OPENVPN_BIN = "/%s/Contents/Resources/openvpn.leap" % ( + # self.INSTALL_PATH,) + UP_DOWN_SCRIPT = "/etc/leap/resolv-update" + OPENVPN_DOWN_ROOT = "/usr/lib/openvpn/openvpn-down-root.so" + + def get_vpn_command(self, eipconfig=None, providerconfig=None, + socket_host=None, socket_port="unix"): + """ + 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 + + @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!") + + openvpn_possibilities = which(self.OPENVPN_BIN) + if len(openvpn_possibilities) == 0: + raise OpenVPNNotFoundException() + + openvpn = openvpn_possibilities[0] + args = [] + + # TODO: handle verbosity + + gateway_ip = str(eipconfig.get_gateway_ip(0)) + + logger.debug("Using gateway ip %s" % (gateway_ip,)) + + args += [ + '--client', + '--dev', 'tun', + '--persist-tun', + '--persist-key', + '--remote', gateway_ip, '1194', 'udp', + '--tls-client', + '--remote-cert-tls', + 'server' + ] + + # FIXME: sanitize this! -- + openvpn_configuration = eipconfig.get_openvpn_configuration() for key, value in openvpn_configuration.items(): args += ['--%s' % (key,), value] @@ -225,6 +334,7 @@ class LinuxVPNLauncher(VPNLauncher): logger.debug("Running VPN with command:") logger.debug("%s %s" % (openvpn, " ".join(args))) + # return [self.OSASCRIPT_BIN, ["-e", self.OSX_ASADMIN % ' '.join(args)]] return [openvpn] + args -- cgit v1.2.3 From 85166f4d12fbaafa5ab1cd5fca5ad37a4ba94774 Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Wed, 20 Mar 2013 23:48:07 +0900 Subject: fix osascript invocation --- src/leap/services/eip/vpnlaunchers.py | 36 +++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) (limited to 'src/leap/services/eip/vpnlaunchers.py') diff --git a/src/leap/services/eip/vpnlaunchers.py b/src/leap/services/eip/vpnlaunchers.py index 44dff4d0..773b1f92 100644 --- a/src/leap/services/eip/vpnlaunchers.py +++ b/src/leap/services/eip/vpnlaunchers.py @@ -235,14 +235,17 @@ class DarwinVPNLauncher(VPNLauncher): VPN launcher for the Darwin Platform """ - OSASCRIPT_BIN = 'osascript' - OSX_ASADMIN = 'do shell script "%s" with administrator privileges' + OSASCRIPT_BIN = '/usr/bin/osascript' + OSX_ASADMIN = "do shell script \"%s\" with administrator privileges" OPENVPN_BIN = 'openvpn.leap' INSTALL_PATH = "/Applications/LEAPClient.app/" # OPENVPN_BIN = "/%s/Contents/Resources/openvpn.leap" % ( # self.INSTALL_PATH,) - UP_DOWN_SCRIPT = "/etc/leap/resolv-update" - OPENVPN_DOWN_ROOT = "/usr/lib/openvpn/openvpn-down-root.so" + UP_SCRIPT = "/%s/client.up.sh" % (INSTALL_PATH,) + DOWN_SCRIPT = "/%s/client.down.sh" % (INSTALL_PATH,) + + # TODO: Add + # OPENVPN_DOWN_ROOT = "/usr/lib/openvpn/openvpn-down-root.so" def get_vpn_command(self, eipconfig=None, providerconfig=None, socket_host=None, socket_port="unix"): @@ -276,12 +279,11 @@ class DarwinVPNLauncher(VPNLauncher): raise OpenVPNNotFoundException() openvpn = openvpn_possibilities[0] - args = [] + args = [openvpn] # TODO: handle verbosity gateway_ip = str(eipconfig.get_gateway_ip(0)) - logger.debug("Using gateway ip %s" % (gateway_ip,)) args += [ @@ -317,12 +319,16 @@ class DarwinVPNLauncher(VPNLauncher): '--script-security', '2' ] - if _has_updown_scripts(self.UP_DOWN_SCRIPT): + if _has_updown_scripts(self.UP_SCRIPT): args += [ - '--up', self.UP_DOWN_SCRIPT, - '--down', self.UP_DOWN_SCRIPT, - '--plugin', self.OPENVPN_DOWN_ROOT, - '\'script_type=down %s\'' % self.UP_DOWN_SCRIPT + '--up', self.UP_SCRIPT, + ] + if _has_updown_scripts(self.DOWN_SCRIPT): + args += [ + '--down', self.DOWN_SCRIPT, + # FIXME add down-plugin + # '--plugin', self.OPENVPN_DOWN_ROOT, + # '\'script_type=down %s\'' % self.DOWN_SCRIPT ] args += [ @@ -331,11 +337,13 @@ class DarwinVPNLauncher(VPNLauncher): '--ca', providerconfig.get_ca_cert_path() ] + command = self.OSASCRIPT_BIN + cmd_args = ["-e", self.OSX_ASADMIN % (' '.join(args),)] + logger.debug("Running VPN with command:") - logger.debug("%s %s" % (openvpn, " ".join(args))) + logger.debug("%s %s" % (command, " ".join(cmd_args))) - # return [self.OSASCRIPT_BIN, ["-e", self.OSX_ASADMIN % ' '.join(args)]] - return [openvpn] + args + return [command] + cmd_args if __name__ == "__main__": -- cgit v1.2.3 From 8f54774f6c3f779527718a0158ebd0efc4aab588 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Fri, 15 Mar 2013 13:30:01 -0300 Subject: Handle configuration and paths in a standalone way Also, abstracts QSettings under LeapSettings and adds a way to define the VPN env in a platform dependant way. --- src/leap/services/eip/vpnlaunchers.py | 38 +++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) (limited to 'src/leap/services/eip/vpnlaunchers.py') diff --git a/src/leap/services/eip/vpnlaunchers.py b/src/leap/services/eip/vpnlaunchers.py index f9e8e366..c58649b9 100644 --- a/src/leap/services/eip/vpnlaunchers.py +++ b/src/leap/services/eip/vpnlaunchers.py @@ -79,6 +79,20 @@ class VPNLauncher: """ return [] + @abstractmethod + def get_vpn_env(self, providerconfig): + """ + 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 + + @param providerconfig: provider specific configuration + @type providerconfig: ProviderConfig + + @rtype: dict + """ + return {} + def get_platform_launcher(): launcher = globals()[platform.system() + "VPNLauncher"] @@ -125,7 +139,9 @@ class LinuxVPNLauncher(VPNLauncher): def get_vpn_command(self, eipconfig=None, providerconfig=None, socket_host=None, socket_port="unix"): """ - Returns the platform dependant vpn launching command + 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. @@ -149,7 +165,11 @@ class LinuxVPNLauncher(VPNLauncher): leap_assert(socket_host, "We need a socket host!") leap_assert(socket_port, "We need a socket port!") - openvpn_possibilities = which(self.OPENVPN_BIN) + openvpn_possibilities = which( + self.OPENVPN_BIN, + path_extension=os.path.join(providerconfig.get_path_prefix(), + "..", "apps", "eip")) + if len(openvpn_possibilities) == 0: raise OpenVPNNotFoundException() @@ -227,6 +247,20 @@ class LinuxVPNLauncher(VPNLauncher): return [openvpn] + args + def get_vpn_env(self, providerconfig): + """ + 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 + """ + leap_assert(providerconfig, "We need a provider config") + leap_assert_type(providerconfig, ProviderConfig) + + return {"LD_LIBRARY_PATH": os.path.join( + providerconfig.get_path_prefix(), + "..", "lib")} if __name__ == "__main__": logger = logging.getLogger(name='leap') -- cgit v1.2.3 From bdc3e1b840c383f0d9236ad8d4df66633e87baf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Thu, 21 Mar 2013 10:38:48 -0300 Subject: Fixes as per review --- src/leap/services/eip/vpnlaunchers.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'src/leap/services/eip/vpnlaunchers.py') diff --git a/src/leap/services/eip/vpnlaunchers.py b/src/leap/services/eip/vpnlaunchers.py index c58649b9..e6502813 100644 --- a/src/leap/services/eip/vpnlaunchers.py +++ b/src/leap/services/eip/vpnlaunchers.py @@ -165,10 +165,15 @@ class LinuxVPNLauncher(VPNLauncher): leap_assert(socket_host, "We need a socket host!") leap_assert(socket_port, "We need a socket port!") + kwargs = {} + if ProviderConfig.standalone: + kwargs['path_extension'] = os.path.join( + providerconfig.get_path_prefix(), + "..", "apps", "eip") + openvpn_possibilities = which( self.OPENVPN_BIN, - path_extension=os.path.join(providerconfig.get_path_prefix(), - "..", "apps", "eip")) + **kwargs) if len(openvpn_possibilities) == 0: raise OpenVPNNotFoundException() @@ -253,6 +258,9 @@ class LinuxVPNLauncher(VPNLauncher): This is mainly used for setting LD_LIBRARY_PATH to the correct path when distributing a standalone client + @param providerconfig: provider specific configuration + @type providerconfig: ProviderConfig + @rtype: dict """ leap_assert(providerconfig, "We need a provider config") -- cgit v1.2.3 From 5488aa1c4f01be567248c2a8ccd0d49d4161877b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Thu, 21 Mar 2013 13:39:35 -0300 Subject: Add Windows VPN Launcher --- src/leap/services/eip/vpnlaunchers.py | 107 ++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) (limited to 'src/leap/services/eip/vpnlaunchers.py') diff --git a/src/leap/services/eip/vpnlaunchers.py b/src/leap/services/eip/vpnlaunchers.py index 78db0176..1b7f11f5 100644 --- a/src/leap/services/eip/vpnlaunchers.py +++ b/src/leap/services/eip/vpnlaunchers.py @@ -272,6 +272,7 @@ class LinuxVPNLauncher(VPNLauncher): providerconfig.get_path_prefix(), "..", "lib")} + class DarwinVPNLauncher(VPNLauncher): """ VPN launcher for the Darwin Platform @@ -388,6 +389,112 @@ class DarwinVPNLauncher(VPNLauncher): return [command] + cmd_args +class WindowsVPNLauncher(VPNLauncher): + """ + VPN launcher for the Windows platform + """ + + OPENVPN_BIN = 'openvpn.exe' + + def get_vpn_command(self, eipconfig=None, providerconfig=None, + socket_host=None, socket_port="9876"): + """ + 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 + + @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(providerconfig.get_path_prefix(), + "..", "apps", "eip")) + + if len(openvpn_possibilities) == 0: + raise OpenVPNNotFoundException() + + openvpn = openvpn_possibilities[0] + args = [] + + # TODO: handle verbosity + + gateway_ip = str(eipconfig.get_gateway_ip(0)) + + logger.debug("Using gateway ip %s" % (gateway_ip,)) + + args += [ + '--client', + '--dev', 'tun', + '--persist-tun', + '--persist-key', + '--remote', gateway_ip, '1194', 'udp', + '--tls-client', + '--remote-cert-tls', + 'server' + ] + + openvpn_configuration = eipconfig.get_openvpn_configuration() + for key, value in openvpn_configuration.items(): + args += ['--%s' % (key,), value] + + 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, providerconfig): + """ + 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 + + @param providerconfig: provider specific configuration + @type providerconfig: ProviderConfig + + @rtype: dict + """ + return {} + + if __name__ == "__main__": logger = logging.getLogger(name='leap') logger.setLevel(logging.DEBUG) -- cgit v1.2.3 From 01ebc3a165de4f84313b298ab6da78c11f181e6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Mon, 25 Mar 2013 12:01:03 -0300 Subject: grp doesn't exist in windows --- src/leap/services/eip/vpnlaunchers.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/leap/services/eip/vpnlaunchers.py') diff --git a/src/leap/services/eip/vpnlaunchers.py b/src/leap/services/eip/vpnlaunchers.py index 78db0176..9761c225 100644 --- a/src/leap/services/eip/vpnlaunchers.py +++ b/src/leap/services/eip/vpnlaunchers.py @@ -21,9 +21,12 @@ Platform dependant VPN launchers import commands import logging import getpass -import grp import os import platform +try: + import grp +except ImportError: + pass # ignore, probably windows from abc import ABCMeta, abstractmethod -- cgit v1.2.3 From a72a8e0eca6d070b51673129fddb2192066ab1af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Mon, 25 Mar 2013 13:07:48 -0300 Subject: Rename the openvpn exe to something more specific --- src/leap/services/eip/vpnlaunchers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/leap/services/eip/vpnlaunchers.py') diff --git a/src/leap/services/eip/vpnlaunchers.py b/src/leap/services/eip/vpnlaunchers.py index 1b7f11f5..b5a6cc94 100644 --- a/src/leap/services/eip/vpnlaunchers.py +++ b/src/leap/services/eip/vpnlaunchers.py @@ -394,7 +394,7 @@ class WindowsVPNLauncher(VPNLauncher): VPN launcher for the Windows platform """ - OPENVPN_BIN = 'openvpn.exe' + OPENVPN_BIN = 'openvpn_leap.exe' def get_vpn_command(self, eipconfig=None, providerconfig=None, socket_host=None, socket_port="9876"): -- cgit v1.2.3 From bd883c86aec15673a56b954cc6046b43e759e562 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Mon, 25 Mar 2013 13:09:15 -0300 Subject: Mark sanitation point clearly for future reference --- src/leap/services/eip/vpnlaunchers.py | 1 + 1 file changed, 1 insertion(+) (limited to 'src/leap/services/eip/vpnlaunchers.py') diff --git a/src/leap/services/eip/vpnlaunchers.py b/src/leap/services/eip/vpnlaunchers.py index b5a6cc94..5267d918 100644 --- a/src/leap/services/eip/vpnlaunchers.py +++ b/src/leap/services/eip/vpnlaunchers.py @@ -456,6 +456,7 @@ class WindowsVPNLauncher(VPNLauncher): ] openvpn_configuration = eipconfig.get_openvpn_configuration() + # XXX sanitize this for key, value in openvpn_configuration.items(): args += ['--%s' % (key,), value] -- cgit v1.2.3 From 2c3593b803d88b67e8d98f6227a687a6737916ec Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Wed, 27 Mar 2013 03:56:57 +0900 Subject: fix osx prefixer and launcher --- src/leap/services/eip/vpnlaunchers.py | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) (limited to 'src/leap/services/eip/vpnlaunchers.py') diff --git a/src/leap/services/eip/vpnlaunchers.py b/src/leap/services/eip/vpnlaunchers.py index 57a8092e..37c6256e 100644 --- a/src/leap/services/eip/vpnlaunchers.py +++ b/src/leap/services/eip/vpnlaunchers.py @@ -320,7 +320,15 @@ class DarwinVPNLauncher(VPNLauncher): leap_assert(socket_host, "We need a socket host!") leap_assert(socket_port, "We need a socket port!") - openvpn_possibilities = which(self.OPENVPN_BIN) + kwargs = {} + if ProviderConfig.standalone: + kwargs['path_extension'] = os.path.join( + providerconfig.get_path_prefix(), + "..", "apps", "eip") + + openvpn_possibilities = which( + self.OPENVPN_BIN, + **kwargs) if len(openvpn_possibilities) == 0: raise OpenVPNNotFoundException() @@ -391,6 +399,21 @@ class DarwinVPNLauncher(VPNLauncher): return [command] + cmd_args + def get_vpn_env(self, providerconfig): + """ + 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 + + @param providerconfig: provider specific configuration + @type providerconfig: ProviderConfig + + @rtype: dict + """ + return {"LD_LIBRARY_PATH": os.path.join( + providerconfig.get_path_prefix(), + "..", "lib")} + class WindowsVPNLauncher(VPNLauncher): """ -- cgit v1.2.3 From 2c4cbe8f0e77e0b7cb08fd2dec3cd43bab6ac62e Mon Sep 17 00:00:00 2001 From: kali Date: Mon, 8 Apr 2013 23:54:42 +0900 Subject: fix dyld_library_path for osx --- src/leap/services/eip/vpnlaunchers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/leap/services/eip/vpnlaunchers.py') diff --git a/src/leap/services/eip/vpnlaunchers.py b/src/leap/services/eip/vpnlaunchers.py index 37c6256e..3d36736d 100644 --- a/src/leap/services/eip/vpnlaunchers.py +++ b/src/leap/services/eip/vpnlaunchers.py @@ -410,7 +410,7 @@ class DarwinVPNLauncher(VPNLauncher): @rtype: dict """ - return {"LD_LIBRARY_PATH": os.path.join( + return {"DYLD_LIBRARY_PATH": os.path.join( providerconfig.get_path_prefix(), "..", "lib")} -- cgit v1.2.3 From 2dae2703fb8c2ae7e721ce83020c0dd10ff9ca33 Mon Sep 17 00:00:00 2001 From: kali Date: Fri, 3 May 2013 02:59:22 +0900 Subject: updated documentation * documentation reviewed after rewrite, ready for 0.2.1 * updated docstrings format to fit sphinx autodoc --- src/leap/services/eip/vpnlaunchers.py | 114 ++++++++++++++++++---------------- 1 file changed, 60 insertions(+), 54 deletions(-) (limited to 'src/leap/services/eip/vpnlaunchers.py') diff --git a/src/leap/services/eip/vpnlaunchers.py b/src/leap/services/eip/vpnlaunchers.py index 3d36736d..540bc45e 100644 --- a/src/leap/services/eip/vpnlaunchers.py +++ b/src/leap/services/eip/vpnlaunchers.py @@ -67,18 +67,18 @@ class VPNLauncher: """ 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 + :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 + :type socket_port: str - @return: A VPN command ready to be launched - @rtype: list + :return: A VPN command ready to be launched + :rtype: list """ return [] @@ -89,10 +89,10 @@ class VPNLauncher: This is mainly used for setting LD_LIBRARY_PATH to the correct path when distributing a standalone client - @param providerconfig: provider specific configuration - @type providerconfig: ProviderConfig + :param providerconfig: provider specific configuration + :type providerconfig: ProviderConfig - @rtype: dict + :rtype: dict """ return {} @@ -148,18 +148,21 @@ class LinuxVPNLauncher(VPNLauncher): 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 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: A VPN command ready to be launched + :rtype: list """ leap_assert(eipconfig, "We need an eip config") leap_assert_type(eipconfig, EIPConfig) @@ -263,10 +266,10 @@ class LinuxVPNLauncher(VPNLauncher): This is mainly used for setting LD_LIBRARY_PATH to the correct path when distributing a standalone client - @param providerconfig: provider specific configuration - @type providerconfig: ProviderConfig + :param providerconfig: provider specific configuration + :type providerconfig: ProviderConfig - @rtype: dict + :rtype: dict """ leap_assert(providerconfig, "We need a provider config") leap_assert_type(providerconfig, ProviderConfig) @@ -300,18 +303,21 @@ class DarwinVPNLauncher(VPNLauncher): 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 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: A VPN command ready to be launched + :rtype: list """ leap_assert(eipconfig, "We need an eip config") leap_assert_type(eipconfig, EIPConfig) @@ -405,10 +411,10 @@ class DarwinVPNLauncher(VPNLauncher): This is mainly used for setting LD_LIBRARY_PATH to the correct path when distributing a standalone client - @param providerconfig: provider specific configuration - @type providerconfig: ProviderConfig + :param providerconfig: provider specific configuration + :type providerconfig: ProviderConfig - @rtype: dict + :rtype: dict """ return {"DYLD_LIBRARY_PATH": os.path.join( providerconfig.get_path_prefix(), @@ -431,18 +437,18 @@ class WindowsVPNLauncher(VPNLauncher): 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 + :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 + :type socket_port: str - @return: A VPN command ready to be launched - @rtype: list + :return: A VPN command ready to be launched + :rtype: list """ leap_assert(eipconfig, "We need an eip config") leap_assert_type(eipconfig, EIPConfig) @@ -514,10 +520,10 @@ class WindowsVPNLauncher(VPNLauncher): This is mainly used for setting LD_LIBRARY_PATH to the correct path when distributing a standalone client - @param providerconfig: provider specific configuration - @type providerconfig: ProviderConfig + :param providerconfig: provider specific configuration + :type providerconfig: ProviderConfig - @rtype: dict + :rtype: dict """ return {} -- cgit v1.2.3 From 372a9aad068e16c0ed957fac5c081ce409dbf7e7 Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Tue, 21 May 2013 10:20:43 -0300 Subject: Add support for kde polkit, closes #2630 Close issue #2630 Add changes file for #2630 Add documentation to '_is_auth_agent_running' method. --- src/leap/services/eip/vpnlaunchers.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'src/leap/services/eip/vpnlaunchers.py') diff --git a/src/leap/services/eip/vpnlaunchers.py b/src/leap/services/eip/vpnlaunchers.py index 540bc45e..addad959 100644 --- a/src/leap/services/eip/vpnlaunchers.py +++ b/src/leap/services/eip/vpnlaunchers.py @@ -124,9 +124,16 @@ def _has_updown_scripts(path): def _is_auth_agent_running(): - return len( - commands.getoutput( - 'ps aux | grep polkit-[g]nome-authentication-agent-1')) > 0 + """ + Checks if a polkit daemon is running. + + :return: True if it's running, False if it's not. + :rtype: boolean + """ + polkit_gnome = 'ps aux | grep polkit-[g]nome-authentication-agent-1' + polkit_kde = 'ps aux | grep polkit-[k]de-authentication-agent-1' + return (len(commands.getoutput(polkit_gnome) > 0) or + len(commands.getoutput(polkit_kde)) > 0) class LinuxVPNLauncher(VPNLauncher): -- cgit v1.2.3 From 4c726c1531abfe288604eaa4c1d347e85bed81eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Mon, 3 Jun 2013 15:02:41 -0300 Subject: Use Twisted's deferToThread and Deferreds to handle parallel tasks This removes CheckerThread --- src/leap/services/eip/vpnlaunchers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/leap/services/eip/vpnlaunchers.py') diff --git a/src/leap/services/eip/vpnlaunchers.py b/src/leap/services/eip/vpnlaunchers.py index addad959..0691e121 100644 --- a/src/leap/services/eip/vpnlaunchers.py +++ b/src/leap/services/eip/vpnlaunchers.py @@ -132,7 +132,7 @@ def _is_auth_agent_running(): """ polkit_gnome = 'ps aux | grep polkit-[g]nome-authentication-agent-1' polkit_kde = 'ps aux | grep polkit-[k]de-authentication-agent-1' - return (len(commands.getoutput(polkit_gnome) > 0) or + return (len(commands.getoutput(polkit_gnome)) > 0 or len(commands.getoutput(polkit_kde)) > 0) -- cgit v1.2.3 From dbb873016042b213dd9cd84a59aec0c0a2383691 Mon Sep 17 00:00:00 2001 From: kali Date: Wed, 5 Jun 2013 05:18:39 +0900 Subject: use twisted processProtocol instead of QProcess to drive openvpn --- src/leap/services/eip/vpnlaunchers.py | 1 + 1 file changed, 1 insertion(+) (limited to 'src/leap/services/eip/vpnlaunchers.py') diff --git a/src/leap/services/eip/vpnlaunchers.py b/src/leap/services/eip/vpnlaunchers.py index 0691e121..952d3618 100644 --- a/src/leap/services/eip/vpnlaunchers.py +++ b/src/leap/services/eip/vpnlaunchers.py @@ -132,6 +132,7 @@ def _is_auth_agent_running(): """ polkit_gnome = 'ps aux | grep polkit-[g]nome-authentication-agent-1' polkit_kde = 'ps aux | grep polkit-[k]de-authentication-agent-1' + return (len(commands.getoutput(polkit_gnome)) > 0 or len(commands.getoutput(polkit_kde)) > 0) -- cgit v1.2.3 From ba27c14ba84c6869c187bdd09138bfae4424445d Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Thu, 13 Jun 2013 01:19:49 +0900 Subject: copy missing updown scripts if missing --- src/leap/services/eip/vpnlaunchers.py | 96 ++++++++++++++++++++++++++--------- 1 file changed, 73 insertions(+), 23 deletions(-) (limited to 'src/leap/services/eip/vpnlaunchers.py') diff --git a/src/leap/services/eip/vpnlaunchers.py b/src/leap/services/eip/vpnlaunchers.py index 952d3618..d15aed82 100644 --- a/src/leap/services/eip/vpnlaunchers.py +++ b/src/leap/services/eip/vpnlaunchers.py @@ -29,6 +29,7 @@ except ImportError: pass # ignore, probably windows from abc import ABCMeta, abstractmethod +from functools import partial from leap.common.check import leap_assert, leap_assert_type from leap.common.files import which @@ -105,22 +106,37 @@ def get_platform_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): +def _has_updown_scripts(path, warn=True): """ - Checks the existence of the up/down scripts + Checks the existence of the up/down scripts. + + :param path: the path to be checked + :type path: str + + :param warn: whether we should log the absence + :type warn: bool + + :rtype: bool """ - # XXX should check permissions too is_file = os.path.isfile(path) - if not is_file: - logger.error("Could not find up/down scripts. " + - "Might produce DNS leaks.") - return is_file + if warn and not is_file: + logger.error("Could not find up/down script %s. " + "Might produce DNS leaks." % (path,)) + + is_exe = os.access(path, os.X_OK) + 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 _is_auth_agent_running(): @@ -229,7 +245,6 @@ class LinuxVPNLauncher(VPNLauncher): openvpn_configuration = eipconfig.get_openvpn_configuration() - # FIXME: sanitize this! -- for key, value in openvpn_configuration.items(): args += ['--%s' % (key,), value] @@ -294,15 +309,40 @@ class DarwinVPNLauncher(VPNLauncher): OSASCRIPT_BIN = '/usr/bin/osascript' OSX_ASADMIN = "do shell script \"%s\" with administrator privileges" - OPENVPN_BIN = 'openvpn.leap' - INSTALL_PATH = "/Applications/LEAPClient.app/" + + INSTALL_PATH = "/Applications/LEAP\ Client.app" # OPENVPN_BIN = "/%s/Contents/Resources/openvpn.leap" % ( # self.INSTALL_PATH,) - UP_SCRIPT = "/%s/client.up.sh" % (INSTALL_PATH,) - DOWN_SCRIPT = "/%s/client.down.sh" % (INSTALL_PATH,) + OPENVPN_BIN = 'openvpn.leap' + OPENVPN_PATH = "%s/Contents/Resources/openvpn" % (INSTALL_PATH,) + + 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) - # TODO: Add - # OPENVPN_DOWN_ROOT = "/usr/lib/openvpn/openvpn-down-root.so" + @classmethod + def missing_updown_scripts(kls): + """ + Returns what updown scripts are missing. + :rtype: list + """ + 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 cmd_for_missing_scripts(kls, frompath): + """ + Returns a command that can copy the missing scripts. + :rtype: str + """ + to = kls.OPENVPN_PATH + cmd = "#!/bin/sh\nmkdir -p %s\ncp \"%s/\"* %s" % (to, frompath, to) + #return kls.OSX_ASADMIN % cmd + return cmd def get_vpn_command(self, eipconfig=None, providerconfig=None, socket_host=None, socket_port="unix"): @@ -365,20 +405,19 @@ class DarwinVPNLauncher(VPNLauncher): 'server' ] - # FIXME: sanitize this! -- - openvpn_configuration = eipconfig.get_openvpn_configuration() for key, value in openvpn_configuration.items(): args += ['--%s' % (key,), value] + user = getpass.getuser() args += [ - '--user', getpass.getuser(), + '--user', user, '--group', grp.getgrgid(os.getgroups()[-1]).gr_name ] if socket_port == "unix": args += [ - '--management-client-user', getpass.getuser() + '--management-client-user', user ] args += [ @@ -391,13 +430,21 @@ class DarwinVPNLauncher(VPNLauncher): args += [ '--up', self.UP_SCRIPT, ] + if _has_updown_scripts(self.DOWN_SCRIPT): args += [ - '--down', self.DOWN_SCRIPT, - # FIXME add down-plugin - # '--plugin', self.OPENVPN_DOWN_ROOT, - # '\'script_type=down %s\'' % self.DOWN_SCRIPT - ] + '--down', self.DOWN_SCRIPT] + + # should have the down script too + if _has_updown_scripts(self.OPENVPN_DOWN_PLUGIN): + args += [ + '--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), @@ -405,6 +452,9 @@ class DarwinVPNLauncher(VPNLauncher): '--ca', providerconfig.get_ca_cert_path() ] + # We are using osascript until we can write a proper wrapper + # for privilege escalation. + command = self.OSASCRIPT_BIN cmd_args = ["-e", self.OSX_ASADMIN % (' '.join(args),)] -- cgit v1.2.3 From cd11784b8fdf0cb45783e8d6a8e9b5288f34820d Mon Sep 17 00:00:00 2001 From: kali Date: Thu, 13 Jun 2013 22:48:29 +0900 Subject: pep8 --- src/leap/services/eip/vpnlaunchers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/leap/services/eip/vpnlaunchers.py') diff --git a/src/leap/services/eip/vpnlaunchers.py b/src/leap/services/eip/vpnlaunchers.py index d15aed82..6c2ff006 100644 --- a/src/leap/services/eip/vpnlaunchers.py +++ b/src/leap/services/eip/vpnlaunchers.py @@ -319,7 +319,7 @@ class DarwinVPNLauncher(VPNLauncher): 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) @classmethod -- cgit v1.2.3 From 336c21f8f5691f30cdf43c025695c5476be7fcec Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Thu, 13 Jun 2013 18:04:38 -0300 Subject: Autoselect VPN gateway based on timezone. --- src/leap/services/eip/vpnlaunchers.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'src/leap/services/eip/vpnlaunchers.py') diff --git a/src/leap/services/eip/vpnlaunchers.py b/src/leap/services/eip/vpnlaunchers.py index 6c2ff006..fa2989bc 100644 --- a/src/leap/services/eip/vpnlaunchers.py +++ b/src/leap/services/eip/vpnlaunchers.py @@ -34,7 +34,7 @@ from functools import partial from leap.common.check import leap_assert, leap_assert_type from leap.common.files import which from leap.config.providerconfig import ProviderConfig -from leap.services.eip.eipconfig import EIPConfig +from leap.services.eip.eipconfig import EIPConfig, VPNGatewaySelector logger = logging.getLogger(__name__) @@ -228,7 +228,8 @@ class LinuxVPNLauncher(VPNLauncher): # TODO: handle verbosity - gateway_ip = str(eipconfig.get_gateway_ip(0)) + gateway_selector = VPNGatewaySelector(eipconfig) + gateway_ip = gateway_selector.get_best_gateway_ip() logger.debug("Using gateway ip %s" % (gateway_ip,)) @@ -391,7 +392,9 @@ class DarwinVPNLauncher(VPNLauncher): # TODO: handle verbosity - gateway_ip = str(eipconfig.get_gateway_ip(0)) + gateway_selector = VPNGatewaySelector(eipconfig) + gateway_ip = gateway_selector.get_best_gateway_ip() + logger.debug("Using gateway ip %s" % (gateway_ip,)) args += [ @@ -530,7 +533,8 @@ class WindowsVPNLauncher(VPNLauncher): # TODO: handle verbosity - gateway_ip = str(eipconfig.get_gateway_ip(0)) + gateway_selector = VPNGatewaySelector(eipconfig) + gateway_ip = gateway_selector.get_best_gateway_ip() logger.debug("Using gateway ip %s" % (gateway_ip,)) -- cgit v1.2.3 From 6c309232c6b669a3f715913f5e172dc6a5e24078 Mon Sep 17 00:00:00 2001 From: Ivan Alejandro Date: Tue, 18 Jun 2013 14:39:33 -0300 Subject: Improve timezone gateway selector. Closes #2894 It allows to use multiple gateways in openvpn for redundancy. --- src/leap/services/eip/vpnlaunchers.py | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) (limited to 'src/leap/services/eip/vpnlaunchers.py') diff --git a/src/leap/services/eip/vpnlaunchers.py b/src/leap/services/eip/vpnlaunchers.py index fa2989bc..fdc863c6 100644 --- a/src/leap/services/eip/vpnlaunchers.py +++ b/src/leap/services/eip/vpnlaunchers.py @@ -229,16 +229,18 @@ class LinuxVPNLauncher(VPNLauncher): # TODO: handle verbosity gateway_selector = VPNGatewaySelector(eipconfig) - gateway_ip = gateway_selector.get_best_gateway_ip() + gateways = gateway_selector.get_gateways() - logger.debug("Using gateway ip %s" % (gateway_ip,)) + logger.debug("Using gateways ips: {}".format(', '.join(gateways))) + + for gw in gateways: + args += ['--remote', gw, '1194', 'udp'] args += [ '--client', '--dev', 'tun', '--persist-tun', '--persist-key', - '--remote', gateway_ip, '1194', 'udp', '--tls-client', '--remote-cert-tls', 'server' @@ -393,16 +395,18 @@ class DarwinVPNLauncher(VPNLauncher): # TODO: handle verbosity gateway_selector = VPNGatewaySelector(eipconfig) - gateway_ip = gateway_selector.get_best_gateway_ip() + gateways = gateway_selector.get_gateways() + + logger.debug("Using gateways ips: {}".format(', '.join(gateways))) - logger.debug("Using gateway ip %s" % (gateway_ip,)) + for gw in gateways: + args += ['--remote', gw, '1194', 'udp'] args += [ '--client', '--dev', 'tun', '--persist-tun', '--persist-key', - '--remote', gateway_ip, '1194', 'udp', '--tls-client', '--remote-cert-tls', 'server' @@ -534,16 +538,18 @@ class WindowsVPNLauncher(VPNLauncher): # TODO: handle verbosity gateway_selector = VPNGatewaySelector(eipconfig) - gateway_ip = gateway_selector.get_best_gateway_ip() + gateways = gateway_selector.get_gateways() + + logger.debug("Using gateways ips: {}".format(', '.join(gateways))) - logger.debug("Using gateway ip %s" % (gateway_ip,)) + for gw in gateways: + args += ['--remote', gw, '1194', 'udp'] args += [ '--client', '--dev', 'tun', '--persist-tun', '--persist-key', - '--remote', gateway_ip, '1194', 'udp', '--tls-client', '--remote-cert-tls', 'server' -- cgit v1.2.3 From b36fe9cf87bc1917abc0667756f01e6d4609cc4c Mon Sep 17 00:00:00 2001 From: kali Date: Mon, 17 Jun 2013 04:46:06 +0900 Subject: install missing files during linux initialization Closes: #2247, #2761 --- src/leap/services/eip/vpnlaunchers.py | 164 +++++++++++++++++++++++++--------- 1 file changed, 122 insertions(+), 42 deletions(-) (limited to 'src/leap/services/eip/vpnlaunchers.py') diff --git a/src/leap/services/eip/vpnlaunchers.py b/src/leap/services/eip/vpnlaunchers.py index fa2989bc..436072d2 100644 --- a/src/leap/services/eip/vpnlaunchers.py +++ b/src/leap/services/eip/vpnlaunchers.py @@ -35,6 +35,7 @@ from leap.common.check import leap_assert, leap_assert_type from leap.common.files import which from leap.config.providerconfig import ProviderConfig from leap.services.eip.eipconfig import EIPConfig, VPNGatewaySelector +from leap.util import first logger = logging.getLogger(__name__) @@ -59,9 +60,11 @@ class VPNLauncher: """ 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): @@ -97,6 +100,35 @@ class VPNLauncher: """ 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.UPDOWN_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"] @@ -117,7 +149,8 @@ def _is_pkexec_in_system(): def _has_updown_scripts(path, warn=True): """ - Checks the existence of the up/down scripts. + Checks the existence of the up/down scripts and its + exec bit if applicable. :param path: the path to be checked :type path: str @@ -132,6 +165,7 @@ def _has_updown_scripts(path, warn=True): logger.error("Could not find up/down script %s. " "Might produce DNS leaks." % (path,)) + # XXX check if applies in win is_exe = os.access(path, os.X_OK) if warn and not is_exe: logger.error("Up/down script %s is not executable. " @@ -139,6 +173,25 @@ def _has_updown_scripts(path, warn=True): 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. @@ -160,8 +213,59 @@ class LinuxVPNLauncher(VPNLauncher): PKEXEC_BIN = 'pkexec' OPENVPN_BIN = 'openvpn' - UP_DOWN_SCRIPT = "/etc/leap/resolv-update" - OPENVPN_DOWN_ROOT = "/usr/lib/openvpn/openvpn-down-root.so" + 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 = "/usr/lib/openvpn/openvpn-plugin-down-root.so" + + POLKIT_BASE = "/usr/share/polkit-1/actions" + POLKIT_FILE = "net.openvpn.gui.leap.policy" + POLKIT_PATH = "%s/%s" % (POLKIT_BASE, POLKIT_FILE) + + UPDOWN_FILES = (UP_DOWN_PATH,) + OTHER_FILES = (POLKIT_PATH,) + + @classmethod + def cmd_for_missing_scripts(kls, frompath): + """ + Returns a command that can copy the missing scripts. + :rtype: str + """ + to = kls.SYSTEM_CONFIG + cmd = "#!/bin/sh\nset -e\nmkdir -p %s\ncp %s/%s %s\ncp %s/%s %s" % ( + to, + frompath, kls.UP_DOWN_FILE, to, + frompath, kls.POLKIT_FILE, 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 _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() def get_vpn_command(self, eipconfig=None, providerconfig=None, socket_host=None, socket_port="unix"): @@ -201,30 +305,18 @@ class LinuxVPNLauncher(VPNLauncher): providerconfig.get_path_prefix(), "..", "apps", "eip") - openvpn_possibilities = which( - self.OPENVPN_BIN, - **kwargs) + openvpn_possibilities = which(self.OPENVPN_BIN, **kwargs) if len(openvpn_possibilities) == 0: raise OpenVPNNotFoundException() - openvpn = openvpn_possibilities[0] + openvpn = first(openvpn_possibilities) args = [] - if _is_pkexec_in_system(): - if _is_auth_agent_running(): - pkexec_possibilities = which(self.PKEXEC_BIN) - leap_assert(len(pkexec_possibilities) > 0, - "We couldn't find pkexec") - args.append(openvpn) - openvpn = pkexec_possibilities[0] - 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() + pkexec = self.maybe_pkexec() + if pkexec: + args.append(openvpn) + openvpn = first(pkexec) # TODO: handle verbosity @@ -265,12 +357,12 @@ class LinuxVPNLauncher(VPNLauncher): '--script-security', '2' ] - if _has_updown_scripts(self.UP_DOWN_SCRIPT): + if _has_updown_scripts(self.UP_DOWN_PATH): args += [ - '--up', self.UP_DOWN_SCRIPT, - '--down', self.UP_DOWN_SCRIPT, + '--up', self.UP_DOWN_PATH, + '--down', self.UP_DOWN_PATH, '--plugin', self.OPENVPN_DOWN_ROOT, - '\'script_type=down %s\'' % self.UP_DOWN_SCRIPT + '\'script_type=down %s\'' % self.UP_DOWN_PATH ] args += [ @@ -323,17 +415,6 @@ class DarwinVPNLauncher(VPNLauncher): UPDOWN_FILES = (UP_SCRIPT, DOWN_SCRIPT, OPENVPN_DOWN_PLUGIN) - @classmethod - def missing_updown_scripts(kls): - """ - Returns what updown scripts are missing. - :rtype: list - """ - 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 cmd_for_missing_scripts(kls, frompath): """ @@ -387,7 +468,7 @@ class DarwinVPNLauncher(VPNLauncher): if len(openvpn_possibilities) == 0: raise OpenVPNNotFoundException() - openvpn = openvpn_possibilities[0] + openvpn = first(openvpn_possibilities) args = [openvpn] # TODO: handle verbosity @@ -489,6 +570,8 @@ class WindowsVPNLauncher(VPNLauncher): OPENVPN_BIN = 'openvpn_leap.exe' + # XXX UPDOWN_FILES ... we do not have updown files defined yet! + def get_vpn_command(self, eipconfig=None, providerconfig=None, socket_host=None, socket_port="9876"): """ @@ -528,7 +611,7 @@ class WindowsVPNLauncher(VPNLauncher): if len(openvpn_possibilities) == 0: raise OpenVPNNotFoundException() - openvpn = openvpn_possibilities[0] + openvpn = first(openvpn_possibilities) args = [] # TODO: handle verbosity @@ -550,7 +633,6 @@ class WindowsVPNLauncher(VPNLauncher): ] openvpn_configuration = eipconfig.get_openvpn_configuration() - # XXX sanitize this for key, value in openvpn_configuration.items(): args += ['--%s' % (key,), value] @@ -558,13 +640,11 @@ class WindowsVPNLauncher(VPNLauncher): '--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), -- cgit v1.2.3 From d43a6905bc255946c8ecb02dfdfed5d159a86b26 Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Thu, 20 Jun 2013 02:59:44 +0900 Subject: fix zero length field format in 2.6 --- src/leap/services/eip/vpnlaunchers.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/leap/services/eip/vpnlaunchers.py') diff --git a/src/leap/services/eip/vpnlaunchers.py b/src/leap/services/eip/vpnlaunchers.py index af77c146..ef73ed94 100644 --- a/src/leap/services/eip/vpnlaunchers.py +++ b/src/leap/services/eip/vpnlaunchers.py @@ -478,7 +478,8 @@ class DarwinVPNLauncher(VPNLauncher): gateway_selector = VPNGatewaySelector(eipconfig) gateways = gateway_selector.get_gateways() - logger.debug("Using gateways ips: {}".format(', '.join(gateways))) + logger.debug("Using gateways ips: {gw}".format( + gw=', '.join(gateways))) for gw in gateways: args += ['--remote', gw, '1194', 'udp'] -- cgit v1.2.3 From 8b690a0a84dcb19259e863e05d71423d1272b435 Mon Sep 17 00:00:00 2001 From: kali Date: Thu, 20 Jun 2013 05:57:38 +0900 Subject: look for down-root plugin in bundle and system --- src/leap/services/eip/vpnlaunchers.py | 42 +++++++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 4 deletions(-) (limited to 'src/leap/services/eip/vpnlaunchers.py') diff --git a/src/leap/services/eip/vpnlaunchers.py b/src/leap/services/eip/vpnlaunchers.py index ef73ed94..01ec42cf 100644 --- a/src/leap/services/eip/vpnlaunchers.py +++ b/src/leap/services/eip/vpnlaunchers.py @@ -220,7 +220,11 @@ class LinuxVPNLauncher(VPNLauncher): # 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 = "/usr/lib/openvpn/openvpn-plugin-down-root.so" + 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) POLKIT_BASE = "/usr/share/polkit-1/actions" POLKIT_FILE = "net.openvpn.gui.leap.policy" @@ -267,6 +271,30 @@ class LinuxVPNLauncher(VPNLauncher): 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_FILE + 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=None, providerconfig=None, socket_host=None, socket_port="unix"): """ @@ -348,7 +376,7 @@ class LinuxVPNLauncher(VPNLauncher): '--group', grp.getgrgid(os.getgroups()[-1]).gr_name ] - if socket_port == "unix": + if socket_port == "unix": # that's always the case for linux args += [ '--management-client-user', getpass.getuser() ] @@ -359,11 +387,17 @@ class LinuxVPNLauncher(VPNLauncher): '--script-security', '2' ] - if _has_updown_scripts(self.UP_DOWN_PATH): + plugin_path = self.maybe_down_plugin() + # If we do not have the down plugin neither in the bundle + # nor in the system, we do not do updown scripts. The alternative + # is leaving the user without the ability to restore dns and routes + # to its original state. + + if plugin_path and _has_updown_scripts(self.UP_DOWN_PATH): args += [ '--up', self.UP_DOWN_PATH, '--down', self.UP_DOWN_PATH, - '--plugin', self.OPENVPN_DOWN_ROOT, + '--plugin', plugin_path, '\'script_type=down %s\'' % self.UP_DOWN_PATH ] -- cgit v1.2.3 From d288330c6294a51cec6fd1dcc35b1b6f4f36932d Mon Sep 17 00:00:00 2001 From: kali Date: Thu, 20 Jun 2013 08:38:23 +0900 Subject: tries to launch polkit authentication agent Closes: #2884 --- src/leap/services/eip/vpnlaunchers.py | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) (limited to 'src/leap/services/eip/vpnlaunchers.py') diff --git a/src/leap/services/eip/vpnlaunchers.py b/src/leap/services/eip/vpnlaunchers.py index ef73ed94..813527bd 100644 --- a/src/leap/services/eip/vpnlaunchers.py +++ b/src/leap/services/eip/vpnlaunchers.py @@ -23,6 +23,7 @@ import logging import getpass import os import platform +import subprocess try: import grp except ImportError: @@ -199,11 +200,25 @@ def _is_auth_agent_running(): :return: True if it's running, False if it's not. :rtype: boolean """ - polkit_gnome = 'ps aux | grep polkit-[g]nome-authentication-agent-1' - polkit_kde = 'ps aux | grep polkit-[k]de-authentication-agent-1' + 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) - return (len(commands.getoutput(polkit_gnome)) > 0 or - len(commands.getoutput(polkit_kde)) > 0) + +def _try_to_launch_agent(): + """ + Tries to launch a polkit daemon. + """ + opts = [ + "/usr/lib/policykit-1-gnome/polkit-gnome-authentication-agent-1&", + # XXX add kde thing here + ] + for cmd in opts: + try: + subprocess.Popen([cmd], shell=True) + except: + pass class LinuxVPNLauncher(VPNLauncher): @@ -254,6 +269,8 @@ class LinuxVPNLauncher(VPNLauncher): :rtype: list """ if _is_pkexec_in_system(): + if not _is_auth_agent_running(): + _try_to_launch_agent() if _is_auth_agent_running(): pkexec_possibilities = which(kls.PKEXEC_BIN) leap_assert(len(pkexec_possibilities) > 0, -- cgit v1.2.3 From b265380ebedb1603933251a6e8fd0e7c850eba5a Mon Sep 17 00:00:00 2001 From: Tomas Touceda Date: Fri, 21 Jun 2013 14:17:09 -0300 Subject: Use an alternative method to check for file permission --- src/leap/services/eip/vpnlaunchers.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/leap/services/eip/vpnlaunchers.py') diff --git a/src/leap/services/eip/vpnlaunchers.py b/src/leap/services/eip/vpnlaunchers.py index 762b536d..c5b21eac 100644 --- a/src/leap/services/eip/vpnlaunchers.py +++ b/src/leap/services/eip/vpnlaunchers.py @@ -24,6 +24,7 @@ import getpass import os import platform import subprocess +import stat try: import grp except ImportError: @@ -167,7 +168,7 @@ def _has_updown_scripts(path, warn=True): "Might produce DNS leaks." % (path,)) # XXX check if applies in win - is_exe = os.access(path, os.X_OK) + is_exe = (stat.S_IXUSR & os.stat(path)[stat.ST_MODE] != 0) if warn and not is_exe: logger.error("Up/down script %s is not executable. " "Might produce DNS leaks." % (path,)) -- cgit v1.2.3 From 63bc283c90a80ddc030e24fcc38c533b1e7c551d Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Mon, 24 Jun 2013 02:21:34 +0900 Subject: let errors go in their own panel --- src/leap/services/eip/vpnlaunchers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/leap/services/eip/vpnlaunchers.py') diff --git a/src/leap/services/eip/vpnlaunchers.py b/src/leap/services/eip/vpnlaunchers.py index c5b21eac..939f51d7 100644 --- a/src/leap/services/eip/vpnlaunchers.py +++ b/src/leap/services/eip/vpnlaunchers.py @@ -212,7 +212,7 @@ def _try_to_launch_agent(): Tries to launch a polkit daemon. """ opts = [ - "/usr/lib/policykit-1-gnome/polkit-gnome-authentication-agent-1&", + "/usr/lib/policykit-1-gnome/polkit-gnome-authentication-agent-1", # XXX add kde thing here ] for cmd in opts: -- cgit v1.2.3 From f9257a1bf085736592a6a8daca4d4e11dfcc1748 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Mon, 24 Jun 2013 11:33:38 -0300 Subject: Catch OSError when checking for permissions --- src/leap/services/eip/vpnlaunchers.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/leap/services/eip/vpnlaunchers.py') diff --git a/src/leap/services/eip/vpnlaunchers.py b/src/leap/services/eip/vpnlaunchers.py index c5b21eac..7449acd0 100644 --- a/src/leap/services/eip/vpnlaunchers.py +++ b/src/leap/services/eip/vpnlaunchers.py @@ -168,7 +168,11 @@ def _has_updown_scripts(path, warn=True): "Might produce DNS leaks." % (path,)) # XXX check if applies in win - is_exe = (stat.S_IXUSR & os.stat(path)[stat.ST_MODE] != 0) + 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,)) -- cgit v1.2.3 From 6873b5b5ef4d1e4af44fe41a52f402d3d9a16d5c Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Thu, 20 Jun 2013 07:52:37 +0900 Subject: use cocoasudo instead of osascript Closes:#2925 --- src/leap/services/eip/vpnlaunchers.py | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) (limited to 'src/leap/services/eip/vpnlaunchers.py') diff --git a/src/leap/services/eip/vpnlaunchers.py b/src/leap/services/eip/vpnlaunchers.py index 56df0b1c..570a7893 100644 --- a/src/leap/services/eip/vpnlaunchers.py +++ b/src/leap/services/eip/vpnlaunchers.py @@ -458,12 +458,12 @@ class DarwinVPNLauncher(VPNLauncher): VPN launcher for the Darwin Platform """ - OSASCRIPT_BIN = '/usr/bin/osascript' - OSX_ASADMIN = "do shell script \"%s\" with administrator privileges" + COCOASUDO = "cocoasudo" + # XXX need magic translate for this string + SUDO_MSG = ("LEAP needs administrative privileges to run " + "Encrypted Internet.") INSTALL_PATH = "/Applications/LEAP\ Client.app" - # OPENVPN_BIN = "/%s/Contents/Resources/openvpn.leap" % ( - # self.INSTALL_PATH,) OPENVPN_BIN = 'openvpn.leap' OPENVPN_PATH = "%s/Contents/Resources/openvpn" % (INSTALL_PATH,) @@ -481,9 +481,25 @@ class DarwinVPNLauncher(VPNLauncher): """ to = kls.OPENVPN_PATH cmd = "#!/bin/sh\nmkdir -p %s\ncp \"%s/\"* %s" % (to, frompath, to) - #return kls.OSX_ASADMIN % cmd return cmd + def get_cocoasudo_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 = os.path.abspath(os.path.join( + os.getcwd(), + "../../../Resources/leap-client.tiff")) + 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_vpn_command(self, eipconfig=None, providerconfig=None, socket_host=None, socket_port="unix"): """ @@ -597,11 +613,8 @@ class DarwinVPNLauncher(VPNLauncher): '--ca', providerconfig.get_ca_cert_path() ] - # We are using osascript until we can write a proper wrapper - # for privilege escalation. - - command = self.OSASCRIPT_BIN - cmd_args = ["-e", self.OSX_ASADMIN % (' '.join(args),)] + command, cargs = self.get_cocoasudo_cmd() + cmd_args = cargs + args logger.debug("Running VPN with command:") logger.debug("%s %s" % (command, " ".join(cmd_args))) -- cgit v1.2.3