From 2c30ffe4ab8a12712735b7f8fef27cd7700eaaae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Mon, 25 Mar 2013 12:00:49 -0300 Subject: Add windows platform initializer --- src/leap/platform_init/initializers.py | 92 ++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 src/leap/platform_init/initializers.py (limited to 'src/leap/platform_init/initializers.py') diff --git a/src/leap/platform_init/initializers.py b/src/leap/platform_init/initializers.py new file mode 100644 index 00000000..60421d62 --- /dev/null +++ b/src/leap/platform_init/initializers.py @@ -0,0 +1,92 @@ +# -*- coding: utf-8 -*- +# initializers.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 initializing code +""" + +import logging +import os +import platform +import subprocess + +from PySide import QtGui + +logger = logging.getLogger(__name__) + + +def init_platform(): + initializer = globals()[platform.system() + "Initializer"] + if initializer: + logger.debug("Running initializer for %s" % (platform.system(),)) + initializer() + else: + logger.debug("Initializer not found for %s" % (platform.system(),)) + + +def _windows_has_tap_device(): + import _winreg as reg + + adapter_key = 'SYSTEM\CurrentControlSet\Control\Class' \ + '\{4D36E972-E325-11CE-BFC1-08002BE10318}' + with reg.OpenKey(reg.HKEY_LOCAL_MACHINE, adapter_key) as adapters: + try: + for i in xrange(10000): + key_name = reg.EnumKey(adapters, i) + with reg.OpenKey(adapters, key_name) as adapter: + try: + component_id = reg.QueryValueEx(adapter, + 'ComponentId')[0] + if component_id.startswith("tap0901"): + return True + except WindowsError: + pass + except WindowsError: + pass + return False + + +def WindowsInitializer(): + if not _windows_has_tap_device(): + msg = QtGui.QMessageBox() + msg.setWindowTitle(msg.tr("TAP Driver")) + msg.setText(msg.tr("LEAPClient needs to install the necessary drivers " + "for Encrypted Internet to work. Would you like to " + "proceed?")) + msg.setInformativeText(msg.tr("Encrypted Internet uses VPN, which " + "needs a TAP device installed and none " + "have been found")) + msg.setStandardButtons(QtGui.QMessageBox.Yes | QtGui.QMessageBox.No) + msg.setDefaultButton(QtGui.QMessageBox.Yes) + ret = msg.exec_() + + if ret == QtGui.QMessageBox.Yes: + driver_path = os.path.join(os.getcwd(), + "apps", + "eip", + "tap_driver") + dev_installer = os.path.join(driver_path, + "devcon.exe") + if os.path.isfile(dev_installer) and \ + os.access(dev_installer, os.X_OK): + inf_path = os.path.join(driver_path, + "OemWin2k.inf") + cmd = [dev_installer, "install", inf_path, "tap0901"] + ret = subprocess.call(cmd, stdout=subprocess.PIPE, shell=True) + else: + logger.error("Tried to install TAP driver, but the installer " + "is not found or not executable") -- cgit v1.2.3 From 310eff047bdc8f5c5cbd4890f91f9cf492c68922 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Mon, 25 Mar 2013 13:14:29 -0300 Subject: Fix grammar error --- src/leap/platform_init/initializers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/leap/platform_init/initializers.py') diff --git a/src/leap/platform_init/initializers.py b/src/leap/platform_init/initializers.py index 60421d62..427b3da4 100644 --- a/src/leap/platform_init/initializers.py +++ b/src/leap/platform_init/initializers.py @@ -69,7 +69,7 @@ def WindowsInitializer(): "proceed?")) msg.setInformativeText(msg.tr("Encrypted Internet uses VPN, which " "needs a TAP device installed and none " - "have been found")) + "has been found")) msg.setStandardButtons(QtGui.QMessageBox.Yes | QtGui.QMessageBox.No) msg.setDefaultButton(QtGui.QMessageBox.Yes) ret = msg.exec_() -- cgit v1.2.3 From ee2ea741883aa6fa3b168431d588f20a5e90f5f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Mon, 25 Mar 2013 13:31:53 -0300 Subject: Make it not fail in any other platform --- src/leap/platform_init/initializers.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/leap/platform_init/initializers.py') diff --git a/src/leap/platform_init/initializers.py b/src/leap/platform_init/initializers.py index 427b3da4..ac08e23f 100644 --- a/src/leap/platform_init/initializers.py +++ b/src/leap/platform_init/initializers.py @@ -30,7 +30,11 @@ logger = logging.getLogger(__name__) def init_platform(): - initializer = globals()[platform.system() + "Initializer"] + initializer = None + try: + initializer = globals()[platform.system() + "Initializer"] + except: + pass if initializer: logger.debug("Running initializer for %s" % (platform.system(),)) initializer() -- cgit v1.2.3 From 399b80dbc2a48806fe54fa4d84d513dc83269c3d Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Tue, 2 Apr 2013 23:58:34 +0900 Subject: add osx initializer --- src/leap/platform_init/initializers.py | 55 ++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) (limited to 'src/leap/platform_init/initializers.py') diff --git a/src/leap/platform_init/initializers.py b/src/leap/platform_init/initializers.py index ac08e23f..6392a3c5 100644 --- a/src/leap/platform_init/initializers.py +++ b/src/leap/platform_init/initializers.py @@ -30,6 +30,10 @@ logger = logging.getLogger(__name__) def init_platform(): + """ + Returns the right initializer for the platform we are running in, or + None if no proper initializer is found + """ initializer = None try: initializer = globals()[platform.system() + "Initializer"] @@ -43,6 +47,10 @@ def init_platform(): def _windows_has_tap_device(): + """ + Loops over the windows registry trying to find if the tap0901 tap driver + has been installed on this machine. + """ import _winreg as reg adapter_key = 'SYSTEM\CurrentControlSet\Control\Class' \ @@ -65,6 +73,10 @@ def _windows_has_tap_device(): def WindowsInitializer(): + """ + Raises a dialog in case that the windows tap driver has not been found + in the registry, asking the user for permission to install the driver + """ if not _windows_has_tap_device(): msg = QtGui.QMessageBox() msg.setWindowTitle(msg.tr("TAP Driver")) @@ -94,3 +106,46 @@ def WindowsInitializer(): else: logger.error("Tried to install TAP driver, but the installer " "is not found or not executable") + + +def _darwin_has_tun_kext(): + """ + Returns True only if we found a directory under the system kext folder + containing a kext named tun.kext, AND we found a startup item named 'tun' + """ + # XXX we should be smarter here and use kextstats output. + has_kext = lambda: os.path.isdir("/System/Library/Extensions/tun.kext") + has_startup = lambda: os.path.isdir("/System/Library/StartupItems/tun") + return has_kext() and has_startup() + +def DarwinInitializer(): + """ + Raises a dialog in case that the osx tuntap driver has not been found + in the registry, asking the user for permission to install the driver + """ + if not _darwin_has_tun_kext(): + msg = QtGui.QMessageBox() + msg.setWindowTitle(msg.tr("TUN Driver")) + msg.setText(msg.tr("LEAPClient needs to install the necessary drivers " + "for Encrypted Internet to work. Would you like to " + "proceed?")) + msg.setInformativeText(msg.tr("Encrypted Internet uses VPN, which " + "needs a kernel extension for a TUN " + "device installed and none " + "has been found")) + msg.setStandardButtons(QtGui.QMessageBox.Yes | QtGui.QMessageBox.No) + msg.setDefaultButton(QtGui.QMessageBox.Yes) + ret = msg.exec_() + + if ret == QtGui.QMessageBox.Yes: + installer_path = os.path.join(os.getcwd(), + "..", + "Resources", + "tuntap-installer.app") + if os.path.isfile(installer_path) and \ + os.access(installer_path, os.X_OK): + cmd = ["open", installer_path] + ret = subprocess.call(cmd, stdout=subprocess.PIPE, shell=True) + else: + logger.error("Tried to install tuntaposx kext, but the installer " + "is not found inside this bundle, or it is not executable") -- cgit v1.2.3 From 91a60870e89e565a6136bf6d21b155dc055f4827 Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Wed, 3 Apr 2013 00:42:29 +0900 Subject: fix tuntaposx invocation --- src/leap/platform_init/initializers.py | 35 ++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) (limited to 'src/leap/platform_init/initializers.py') diff --git a/src/leap/platform_init/initializers.py b/src/leap/platform_init/initializers.py index 6392a3c5..3cb19fc6 100644 --- a/src/leap/platform_init/initializers.py +++ b/src/leap/platform_init/initializers.py @@ -85,7 +85,8 @@ def WindowsInitializer(): "proceed?")) msg.setInformativeText(msg.tr("Encrypted Internet uses VPN, which " "needs a TAP device installed and none " - "has been found")) + "has been found. This will ask for " + "administrative privileges.")) msg.setStandardButtons(QtGui.QMessageBox.Yes | QtGui.QMessageBox.No) msg.setDefaultButton(QtGui.QMessageBox.Yes) ret = msg.exec_() @@ -102,6 +103,7 @@ def WindowsInitializer(): inf_path = os.path.join(driver_path, "OemWin2k.inf") cmd = [dev_installer, "install", inf_path, "tap0901"] + # XXX should avoid shell expansion. ret = subprocess.call(cmd, stdout=subprocess.PIPE, shell=True) else: logger.error("Tried to install TAP driver, but the installer " @@ -114,15 +116,23 @@ def _darwin_has_tun_kext(): containing a kext named tun.kext, AND we found a startup item named 'tun' """ # XXX we should be smarter here and use kextstats output. + has_kext = lambda: os.path.isdir("/System/Library/Extensions/tun.kext") has_startup = lambda: os.path.isdir("/System/Library/StartupItems/tun") - return has_kext() and has_startup() + has_tun_and_startup = has_kext() and has_startup() + logger.debug('platform initializer check: has tun_and_startup = %s' % + (has_tun_and_startup,)) + return has_tun_and_startup def DarwinInitializer(): """ Raises a dialog in case that the osx tuntap driver has not been found in the registry, asking the user for permission to install the driver """ + NOTFOUND_MSG = ("Tried to install tuntaposx kext, but the installer " + "is not found inside this bundle.") + BADEXEC_MSG = ("Tried to install tuntaposx kext, but the installer " + "failed to be launched.") if not _darwin_has_tun_kext(): msg = QtGui.QMessageBox() msg.setWindowTitle(msg.tr("TUN Driver")) @@ -131,8 +141,9 @@ def DarwinInitializer(): "proceed?")) msg.setInformativeText(msg.tr("Encrypted Internet uses VPN, which " "needs a kernel extension for a TUN " - "device installed and none " - "has been found")) + "device installed, and none " + "has been found. This will ask for " + "administrative privileges.")) msg.setStandardButtons(QtGui.QMessageBox.Yes | QtGui.QMessageBox.No) msg.setDefaultButton(QtGui.QMessageBox.Yes) ret = msg.exec_() @@ -142,10 +153,14 @@ def DarwinInitializer(): "..", "Resources", "tuntap-installer.app") - if os.path.isfile(installer_path) and \ - os.access(installer_path, os.X_OK): - cmd = ["open", installer_path] - ret = subprocess.call(cmd, stdout=subprocess.PIPE, shell=True) + if os.path.isdir(installer_path): + cmd = ["open %s" % (installer_path,)] + try: + # XXX should avoid shell expansion + ret = subprocess.call( + cmd, stdout=subprocess.PIPE, + shell=True) + except: + logger.error(BADEXEC_MSG) else: - logger.error("Tried to install tuntaposx kext, but the installer " - "is not found inside this bundle, or it is not executable") + logger.error(NOTFOUND_MSG) -- cgit v1.2.3 From 3b253461e79f286f29b890cd0e4adb94c2695393 Mon Sep 17 00:00:00 2001 From: kali Date: Tue, 9 Apr 2013 00:06:27 +0900 Subject: add TODO about refactor install dialog --- src/leap/platform_init/initializers.py | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/leap/platform_init/initializers.py') diff --git a/src/leap/platform_init/initializers.py b/src/leap/platform_init/initializers.py index 3cb19fc6..055c90a2 100644 --- a/src/leap/platform_init/initializers.py +++ b/src/leap/platform_init/initializers.py @@ -124,6 +124,7 @@ def _darwin_has_tun_kext(): (has_tun_and_startup,)) return has_tun_and_startup + def DarwinInitializer(): """ Raises a dialog in case that the osx tuntap driver has not been found @@ -133,6 +134,11 @@ def DarwinInitializer(): "is not found inside this bundle.") BADEXEC_MSG = ("Tried to install tuntaposx kext, but the installer " "failed to be launched.") + + # TODO DRY this with other cases, and + # factor out to _should_install() function. + # Leave the dialog as a more generic thing. + if not _darwin_has_tun_kext(): msg = QtGui.QMessageBox() msg.setWindowTitle(msg.tr("TUN Driver")) -- cgit v1.2.3 From a0497a6e1a4ef556e55299c967441e237a5e7bce Mon Sep 17 00:00:00 2001 From: kali Date: Tue, 9 Apr 2013 20:03:54 +0900 Subject: remove lambdas --- src/leap/platform_init/initializers.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/leap/platform_init/initializers.py') diff --git a/src/leap/platform_init/initializers.py b/src/leap/platform_init/initializers.py index 3cb19fc6..049d32a2 100644 --- a/src/leap/platform_init/initializers.py +++ b/src/leap/platform_init/initializers.py @@ -117,13 +117,14 @@ def _darwin_has_tun_kext(): """ # XXX we should be smarter here and use kextstats output. - has_kext = lambda: os.path.isdir("/System/Library/Extensions/tun.kext") - has_startup = lambda: os.path.isdir("/System/Library/StartupItems/tun") - has_tun_and_startup = has_kext() and has_startup() + has_kext = os.path.isdir("/System/Library/Extensions/tun.kext") + has_startup = os.path.isdir("/System/Library/StartupItems/tun") + has_tun_and_startup = has_kext and has_startup logger.debug('platform initializer check: has tun_and_startup = %s' % (has_tun_and_startup,)) return has_tun_and_startup + def DarwinInitializer(): """ Raises a dialog in case that the osx tuntap driver has not been found -- cgit v1.2.3 From f74849f4c926a83190169cae570e9ec826fd46da Mon Sep 17 00:00:00 2001 From: kali Date: Wed, 1 May 2013 04:14:15 +0900 Subject: pep8 --- src/leap/platform_init/initializers.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'src/leap/platform_init/initializers.py') diff --git a/src/leap/platform_init/initializers.py b/src/leap/platform_init/initializers.py index cf7e71b8..7e184d8a 100644 --- a/src/leap/platform_init/initializers.py +++ b/src/leap/platform_init/initializers.py @@ -120,8 +120,9 @@ def _darwin_has_tun_kext(): has_kext = os.path.isdir("/System/Library/Extensions/tun.kext") has_startup = os.path.isdir("/System/Library/StartupItems/tun") has_tun_and_startup = has_kext and has_startup - logger.debug('platform initializer check: has tun_and_startup = %s' % - (has_tun_and_startup,)) + logger.debug( + 'platform initializer check: has tun_and_startup = %s' % + (has_tun_and_startup,)) return has_tun_and_startup @@ -155,10 +156,11 @@ def DarwinInitializer(): ret = msg.exec_() if ret == QtGui.QMessageBox.Yes: - installer_path = os.path.join(os.getcwd(), - "..", - "Resources", - "tuntap-installer.app") + installer_path = os.path.join( + os.getcwd(), + "..", + "Resources", + "tuntap-installer.app") if os.path.isdir(installer_path): cmd = ["open %s" % (installer_path,)] try: -- cgit v1.2.3 From c85894efdbd6f65eb2b0c2edfc216827c192c1d1 Mon Sep 17 00:00:00 2001 From: kali Date: Wed, 1 May 2013 04:45:05 +0900 Subject: remove comment about shell expansion --- src/leap/platform_init/initializers.py | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/leap/platform_init/initializers.py') diff --git a/src/leap/platform_init/initializers.py b/src/leap/platform_init/initializers.py index 7e184d8a..91c7086b 100644 --- a/src/leap/platform_init/initializers.py +++ b/src/leap/platform_init/initializers.py @@ -103,7 +103,6 @@ def WindowsInitializer(): inf_path = os.path.join(driver_path, "OemWin2k.inf") cmd = [dev_installer, "install", inf_path, "tap0901"] - # XXX should avoid shell expansion. ret = subprocess.call(cmd, stdout=subprocess.PIPE, shell=True) else: logger.error("Tried to install TAP driver, but the installer " @@ -164,7 +163,6 @@ def DarwinInitializer(): if os.path.isdir(installer_path): cmd = ["open %s" % (installer_path,)] try: - # XXX should avoid shell expansion ret = subprocess.call( cmd, stdout=subprocess.PIPE, shell=True) -- cgit v1.2.3 From 1cb931e83522746da668f9a8bb5943aca1882086 Mon Sep 17 00:00:00 2001 From: kali Date: Thu, 16 May 2013 04:26:00 +0900 Subject: use qtreactor so twisted is driven by qt main loop aboutToQuit signal is not raised anymore with the qt4reactor. So we are calling all cleanup callbacks from the quit function. --- src/leap/platform_init/initializers.py | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/leap/platform_init/initializers.py') diff --git a/src/leap/platform_init/initializers.py b/src/leap/platform_init/initializers.py index 91c7086b..2e8cbe95 100644 --- a/src/leap/platform_init/initializers.py +++ b/src/leap/platform_init/initializers.py @@ -28,6 +28,9 @@ from PySide import QtGui logger = logging.getLogger(__name__) +# NOTE we could use a deferToThread here, but should +# be aware of this bug: http://www.themacaque.com/?p=1067 + def init_platform(): """ -- 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/platform_init/initializers.py | 119 +++++++++++++++++++++++++++++++-- 1 file changed, 113 insertions(+), 6 deletions(-) (limited to 'src/leap/platform_init/initializers.py') diff --git a/src/leap/platform_init/initializers.py b/src/leap/platform_init/initializers.py index 2e8cbe95..9dd31a18 100644 --- a/src/leap/platform_init/initializers.py +++ b/src/leap/platform_init/initializers.py @@ -22,10 +22,15 @@ Platform dependant initializing code import logging import os import platform +import stat import subprocess +import tempfile from PySide import QtGui +from leap.config.leapsettings import LeapSettings +from leap.services.eip import vpnlaunchers + logger = logging.getLogger(__name__) # NOTE we could use a deferToThread here, but should @@ -74,6 +79,28 @@ def _windows_has_tap_device(): pass return False +def _get_missing_updown_dialog(): + """ + Creates a dialog for notifying of missing updown scripts. + Returns that dialog. + + :rtype: QtGui.QMessageBox instance + """ + msg = QtGui.QMessageBox() + msg.setWindowTitle(msg.tr("Missing up/down scripts")) + msg.setText(msg.tr( + "LEAPClient needs to install up/down scripts " + "for Encrypted Internet to work properly. " + "Would you like to proceed?")) + msg.setInformativeText(msg.tr( + "It looks like either you have not installed " + "LEAP Client in a permanent location or you have an " + "incomplete installation. This will ask for " + "administrative privileges.")) + msg.setStandardButtons(QtGui.QMessageBox.Yes | QtGui.QMessageBox.No) + msg.addButton("No, don't ask again", QtGui.QMessageBox.RejectRole) + msg.setDefaultButton(QtGui.QMessageBox.Yes) + return msg def WindowsInitializer(): """ @@ -128,15 +155,73 @@ def _darwin_has_tun_kext(): return has_tun_and_startup +def _darwin_install_missing_scripts(badexec, notfound): + """ + Tries to install the missing up/down scripts. + + :param badexec: error for notifying execution error during command. + :type badexec: str + :param notfound: error for notifying missing path. + :type notfound: str + """ + # We expect to execute this from some way of bundle, since + # the up/down scripts should be put in place by the installer. + installer_path = os.path.join( + os.getcwd(), + "..", + "Resources", + "openvpn") + launcher = vpnlaunchers.DarwinVPNLauncher + if os.path.isdir(installer_path): + tempscript = tempfile.mktemp() + try: + cmd = launcher.OSASCRIPT_BIN + scriptlines = launcher.cmd_for_missing_scripts(installer_path) + with open(tempscript, 'w') as f: + f.write(scriptlines) + st = os.stat(tempscript) + os.chmod(tempscript, st.st_mode | stat.S_IEXEC | stat.S_IXUSR | + stat.S_IXGRP | stat.S_IXOTH) + + osascript = launcher.OSX_ASADMIN % ("/bin/sh %s" % (tempscript,),) + cmdline = ["%s -e '%s'" % (cmd, osascript)] + ret = subprocess.call( + cmdline, stdout=subprocess.PIPE, + shell=True) + assert(ret) + except Exception as exc: + logger.error(badexec) + logger.error("Error was: %r" % (exc,)) + f.close() + finally: + # XXX remove file + pass + else: + logger.error(notfound) + logger.debug('path searched: %s' % (installer_path,)) + + def DarwinInitializer(): """ Raises a dialog in case that the osx tuntap driver has not been found in the registry, asking the user for permission to install the driver """ - NOTFOUND_MSG = ("Tried to install tuntaposx kext, but the installer " - "is not found inside this bundle.") - BADEXEC_MSG = ("Tried to install tuntaposx kext, but the installer " - "failed to be launched.") + # XXX split this function into several + + NOTFOUND_MSG = ("Tried to install %s, but %s " + "not found inside this bundle.") + BADEXEC_MSG = ("Tried to install %s, but %s " + "failed to %s.") + + TUNTAP_NOTFOUND_MSG = NOTFOUND_MSG % ( + "tuntaposx kext", "the installer") + TUNTAP_BADEXEC_MSG = BADEXEC_MSG % ( + "tuntaposx kext", "the installer", "be launched") + + UPDOWN_NOTFOUND_MSG = NOTFOUND_MSG % ( + "updown scripts", "those were") + UPDOWN_BADEXEC_MSG = BADEXEC_MSG % ( + "updown scripts", "they", "be copied") # TODO DRY this with other cases, and # factor out to _should_install() function. @@ -170,6 +255,28 @@ def DarwinInitializer(): cmd, stdout=subprocess.PIPE, shell=True) except: - logger.error(BADEXEC_MSG) + logger.error(TUNTAP_BADEXEC_MSG) else: - logger.error(NOTFOUND_MSG) + logger.error(TUNTAP_NOTFOUND_MSG) + + config = LeapSettings() + alert_missing = config.get_alert_missing_scripts() + missing_scripts = vpnlaunchers.DarwinVPNLauncher.missing_updown_scripts + if alert_missing and missing_scripts(): + msg = _get_missing_updown_dialog() + ret = msg.exec_() + + if ret == QtGui.QMessageBox.Yes: + _darwin_install_missing_scripts( + UPDOWN_BADEXEC_MSG, + UPDOWN_NOTFOUND_MSG) + + elif ret == QtGui.QMessageBox.No: + logger.debug("Not installing missing scripts, " + "user decided to ignore our warning.") + + elif ret == QtGui.QMessageBox.Rejected: + logger.debug( + "Setting alert_missing_scripts to False, we will not " + "ask again") + config.set_alert_missing_scripts(False) -- 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/platform_init/initializers.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/leap/platform_init/initializers.py') diff --git a/src/leap/platform_init/initializers.py b/src/leap/platform_init/initializers.py index 9dd31a18..d72dc61f 100644 --- a/src/leap/platform_init/initializers.py +++ b/src/leap/platform_init/initializers.py @@ -79,6 +79,7 @@ def _windows_has_tap_device(): pass return False + def _get_missing_updown_dialog(): """ Creates a dialog for notifying of missing updown scripts. @@ -102,6 +103,7 @@ def _get_missing_updown_dialog(): msg.setDefaultButton(QtGui.QMessageBox.Yes) return msg + def WindowsInitializer(): """ Raises a dialog in case that the windows tap driver has not been found -- 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/platform_init/initializers.py | 217 ++++++++++++++++++++++++--------- 1 file changed, 158 insertions(+), 59 deletions(-) (limited to 'src/leap/platform_init/initializers.py') diff --git a/src/leap/platform_init/initializers.py b/src/leap/platform_init/initializers.py index d72dc61f..3374e32e 100644 --- a/src/leap/platform_init/initializers.py +++ b/src/leap/platform_init/initializers.py @@ -30,12 +30,17 @@ from PySide import QtGui from leap.config.leapsettings import LeapSettings from leap.services.eip import vpnlaunchers +from leap.util import first logger = logging.getLogger(__name__) # NOTE we could use a deferToThread here, but should # be aware of this bug: http://www.themacaque.com/?p=1067 +__all__ = ["init_platform"] + +_system = platform.system() + def init_platform(): """ @@ -44,7 +49,7 @@ def init_platform(): """ initializer = None try: - initializer = globals()[platform.system() + "Initializer"] + initializer = globals()[_system + "Initializer"] except: pass if initializer: @@ -54,6 +59,86 @@ def init_platform(): logger.debug("Initializer not found for %s" % (platform.system(),)) +# +# common utils +# + +NOTFOUND_MSG = ("Tried to install %s, but %s " + "not found inside this bundle.") +BADEXEC_MSG = ("Tried to install %s, but %s " + "failed to %s.") + +UPDOWN_NOTFOUND_MSG = NOTFOUND_MSG % ( + "updown scripts", "those were") +UPDOWN_BADEXEC_MSG = BADEXEC_MSG % ( + "updown scripts", "they", "be copied") + + +def get_missing_updown_dialog(): + """ + Creates a dialog for notifying of missing updown scripts. + Returns that dialog. + + :rtype: QtGui.QMessageBox instance + """ + WE_NEED_POWERS = ("To better protect your privacy, " + "LEAP needs administrative privileges " + "to install helper files. " + "Do you want to proceed?") + msg = QtGui.QMessageBox() + msg.setWindowTitle(msg.tr("Missing up/down scripts")) + msg.setText(msg.tr(WE_NEED_POWERS)) + # but maybe the user really deserve to know more + #msg.setInformativeText(msg.tr(BECAUSE)) + msg.setStandardButtons(QtGui.QMessageBox.Yes | QtGui.QMessageBox.No) + msg.addButton("No, don't ask again", QtGui.QMessageBox.RejectRole) + msg.setDefaultButton(QtGui.QMessageBox.Yes) + return msg + + +def check_missing(): + """ + Checks for the need of installing missing scripts, and + raises a dialog to ask user for permission to do it. + """ + config = LeapSettings() + alert_missing = config.get_alert_missing_scripts() + + launcher = vpnlaunchers.get_platform_launcher() + missing_scripts = launcher.missing_updown_scripts + missing_other = launcher.missing_other_files + + if alert_missing and (missing_scripts() or missing_other()): + msg = get_missing_updown_dialog() + ret = msg.exec_() + + if ret == QtGui.QMessageBox.Yes: + install_missing_fun = globals().get( + "_%s_install_missing_scripts" % (_system.lower(),), + None) + if not install_missing_fun: + logger.warning( + "Installer not found for platform %s." % (_system,)) + return + install_missing_fun( + # XXX maybe move constants to fun + UPDOWN_BADEXEC_MSG, + UPDOWN_NOTFOUND_MSG) + + elif ret == QtGui.QMessageBox.No: + logger.debug("Not installing missing scripts, " + "user decided to ignore our warning.") + + elif ret == QtGui.QMessageBox.Rejected: + logger.debug( + "Setting alert_missing_scripts to False, we will not " + "ask again") + config.set_alert_missing_scripts(False) +# +# windows initializers +# + + def _windows_has_tap_device(): """ Loops over the windows registry trying to find if the tap0901 tap driver @@ -80,30 +165,6 @@ def _windows_has_tap_device(): return False -def _get_missing_updown_dialog(): - """ - Creates a dialog for notifying of missing updown scripts. - Returns that dialog. - - :rtype: QtGui.QMessageBox instance - """ - msg = QtGui.QMessageBox() - msg.setWindowTitle(msg.tr("Missing up/down scripts")) - msg.setText(msg.tr( - "LEAPClient needs to install up/down scripts " - "for Encrypted Internet to work properly. " - "Would you like to proceed?")) - msg.setInformativeText(msg.tr( - "It looks like either you have not installed " - "LEAP Client in a permanent location or you have an " - "incomplete installation. This will ask for " - "administrative privileges.")) - msg.setStandardButtons(QtGui.QMessageBox.Yes | QtGui.QMessageBox.No) - msg.addButton("No, don't ask again", QtGui.QMessageBox.RejectRole) - msg.setDefaultButton(QtGui.QMessageBox.Yes) - return msg - - def WindowsInitializer(): """ Raises a dialog in case that the windows tap driver has not been found @@ -124,6 +185,9 @@ def WindowsInitializer(): ret = msg.exec_() if ret == QtGui.QMessageBox.Yes: + # XXX should do this only if executed inside bundle. + # Let's assume it's the only way it's gonna be executed under win + # by now. driver_path = os.path.join(os.getcwd(), "apps", "eip", @@ -140,6 +204,10 @@ def WindowsInitializer(): logger.error("Tried to install TAP driver, but the installer " "is not found or not executable") +# +# Darwin initializer functions +# + def _darwin_has_tun_kext(): """ @@ -174,12 +242,15 @@ def _darwin_install_missing_scripts(badexec, notfound): "Resources", "openvpn") launcher = vpnlaunchers.DarwinVPNLauncher + + # TODO should change osascript by use of the proper + # os authorization api. if os.path.isdir(installer_path): - tempscript = tempfile.mktemp() + fd, tempscript = tempfile.mkstemp(prefix="leap_installer-") try: cmd = launcher.OSASCRIPT_BIN scriptlines = launcher.cmd_for_missing_scripts(installer_path) - with open(tempscript, 'w') as f: + with os.fdopen(fd, 'w') as f: f.write(scriptlines) st = os.stat(tempscript) os.chmod(tempscript, st.st_mode | stat.S_IEXEC | stat.S_IXUSR | @@ -190,14 +261,15 @@ def _darwin_install_missing_scripts(badexec, notfound): ret = subprocess.call( cmdline, stdout=subprocess.PIPE, shell=True) - assert(ret) + assert([ret]) # happy flakes except Exception as exc: logger.error(badexec) logger.error("Error was: %r" % (exc,)) - f.close() finally: - # XXX remove file - pass + try: + os.remove(tempscript) + except OSError as exc: + logger.error("%r" % (exc,)) else: logger.error(notfound) logger.debug('path searched: %s' % (installer_path,)) @@ -210,21 +282,11 @@ def DarwinInitializer(): """ # XXX split this function into several - NOTFOUND_MSG = ("Tried to install %s, but %s " - "not found inside this bundle.") - BADEXEC_MSG = ("Tried to install %s, but %s " - "failed to %s.") - TUNTAP_NOTFOUND_MSG = NOTFOUND_MSG % ( "tuntaposx kext", "the installer") TUNTAP_BADEXEC_MSG = BADEXEC_MSG % ( "tuntaposx kext", "the installer", "be launched") - UPDOWN_NOTFOUND_MSG = NOTFOUND_MSG % ( - "updown scripts", "those were") - UPDOWN_BADEXEC_MSG = BADEXEC_MSG % ( - "updown scripts", "they", "be copied") - # TODO DRY this with other cases, and # factor out to _should_install() function. # Leave the dialog as a more generic thing. @@ -261,24 +323,61 @@ def DarwinInitializer(): else: logger.error(TUNTAP_NOTFOUND_MSG) - config = LeapSettings() - alert_missing = config.get_alert_missing_scripts() - missing_scripts = vpnlaunchers.DarwinVPNLauncher.missing_updown_scripts - if alert_missing and missing_scripts(): - msg = _get_missing_updown_dialog() - ret = msg.exec_() + # Second check, for missing scripts. + check_missing() - if ret == QtGui.QMessageBox.Yes: - _darwin_install_missing_scripts( - UPDOWN_BADEXEC_MSG, - UPDOWN_NOTFOUND_MSG) - elif ret == QtGui.QMessageBox.No: - logger.debug("Not installing missing scripts, " - "user decided to ignore our warning.") +# +# Linux initializers +# - elif ret == QtGui.QMessageBox.Rejected: - logger.debug( - "Setting alert_missing_scripts to False, we will not " - "ask again") - config.set_alert_missing_scripts(False) +def _linux_install_missing_scripts(badexec, notfound): + """ + Tries to install the missing up/down scripts. + + :param badexec: error for notifying execution error during command. + :type badexec: str + :param notfound: error for notifying missing path. + :type notfound: str + """ + installer_path = os.path.join( + os.getcwd(), + "apps", "eip", "files") + launcher = vpnlaunchers.LinuxVPNLauncher + + # XXX refactor with darwin, same block. + + if os.path.isdir(installer_path): + fd, tempscript = tempfile.mkstemp(prefix="leap_installer-") + try: + pkexec = first(launcher.maybe_pkexec()) + scriptlines = launcher.cmd_for_missing_scripts(installer_path) + with os.fdopen(fd, 'w') as f: + f.write(scriptlines) + st = os.stat(tempscript) + os.chmod(tempscript, st.st_mode | stat.S_IEXEC | stat.S_IXUSR | + stat.S_IXGRP | stat.S_IXOTH) + cmdline = ["%s %s" % (pkexec, tempscript)] + ret = subprocess.call( + cmdline, stdout=subprocess.PIPE, + shell=True) + assert([ret]) # happy flakes + except Exception as exc: + logger.error(badexec) + logger.error("Error was: %r" % (exc,)) + finally: + try: + os.remove(tempscript) + except OSError as exc: + logger.error("%r" % (exc,)) + else: + logger.error(notfound) + logger.debug('path searched: %s' % (installer_path,)) + + +def LinuxInitializer(): + """ + Raises a dialog in case that either updown scripts or policykit file + are missing or they have incorrect permissions. + """ + check_missing() -- 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/platform_init/initializers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/leap/platform_init/initializers.py') diff --git a/src/leap/platform_init/initializers.py b/src/leap/platform_init/initializers.py index 3374e32e..5345f11a 100644 --- a/src/leap/platform_init/initializers.py +++ b/src/leap/platform_init/initializers.py @@ -195,7 +195,7 @@ def WindowsInitializer(): dev_installer = os.path.join(driver_path, "devcon.exe") if os.path.isfile(dev_installer) and \ - os.access(dev_installer, os.X_OK): + stat.S_IXUSR & os.stat(dev_installer)[stat.ST_MODE] != 0: inf_path = os.path.join(driver_path, "OemWin2k.inf") cmd = [dev_installer, "install", inf_path, "tap0901"] -- cgit v1.2.3