summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomás Touceda <chiiph@leap.se>2013-07-30 10:40:23 -0300
committerTomás Touceda <chiiph@leap.se>2013-07-30 10:40:23 -0300
commit93cd6851384de336a717b5bccc1c1be7a2bf950e (patch)
treedbdddd03aee4c3f7b3e779750edc5d3ec4755d17
parentb39584175fda25d812dbb90d3fa171f7a50e3914 (diff)
parentb655c0ab05bf55e62e2f27174b34ca63fe45431b (diff)
Merge remote-tracking branch 'ivan/feature/3209_check-outdated-polkit' into develop
-rw-r--r--changes/feature-3209_check-outdated-polkit-file1
-rw-r--r--src/leap/platform_init/initializers.py42
-rw-r--r--src/leap/services/eip/vpnlaunchers.py44
-rw-r--r--src/leap/util/privilege_policies.py87
4 files changed, 124 insertions, 50 deletions
diff --git a/changes/feature-3209_check-outdated-polkit-file b/changes/feature-3209_check-outdated-polkit-file
new file mode 100644
index 00000000..8cb7c35c
--- /dev/null
+++ b/changes/feature-3209_check-outdated-polkit-file
@@ -0,0 +1 @@
+ o Add check for outdated polkit file. Closes #3209.
diff --git a/src/leap/platform_init/initializers.py b/src/leap/platform_init/initializers.py
index d04daca6..3523c117 100644
--- a/src/leap/platform_init/initializers.py
+++ b/src/leap/platform_init/initializers.py
@@ -31,7 +31,7 @@ from PySide import QtGui
from leap.config.leapsettings import LeapSettings
from leap.services.eip import vpnlaunchers
from leap.util import first
-from leap.config.providerconfig import ProviderConfig
+from leap.util import privilege_policies
logger = logging.getLogger(__name__)
@@ -331,36 +331,6 @@ def DarwinInitializer():
#
# Linux initializers
#
-
-POLICY_TEMPLATE = """<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE policyconfig PUBLIC
- "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
- "http://www.freedesktop.org/standards/PolicyKit/1/policyconfig.dtd">
-<policyconfig>
-
- <vendor>LEAP Project</vendor>
- <vendor_url>http://leap.se/</vendor_url>
-
- <action id="net.openvpn.gui.leap.run-openvpn">
- <description>Runs the openvpn binary</description>
- <description xml:lang="es">Ejecuta el binario openvpn</description>
- <message>OpenVPN needs that you authenticate to start</message>
- <message xml:lang="es">
- OpenVPN necesita autorizacion para comenzar
- </message>
- <icon_name>package-x-generic</icon_name>
- <defaults>
- <allow_any>yes</allow_any>
- <allow_inactive>yes</allow_inactive>
- <allow_active>yes</allow_active>
- </defaults>
- <annotate key="org.freedesktop.policykit.exec.path">{path}</annotate>
- <annotate key="org.freedesktop.policykit.exec.allow_gui">true</annotate>
- </action>
-</policyconfig>
-"""
-
-
def _linux_install_missing_scripts(badexec, notfound):
"""
Tries to install the missing up/down scripts.
@@ -381,14 +351,8 @@ def _linux_install_missing_scripts(badexec, notfound):
fd, tempscript = tempfile.mkstemp(prefix="leap_installer-")
polfd, pol_tempfile = tempfile.mkstemp(prefix="leap_installer-")
try:
- # We need to do the config/../apps/openvpn otherwise the
- # policy file won't work
- openvpn_path = os.path.join(
- ProviderConfig().get_path_prefix(),
- "..", "apps", "eip",
- launcher.OPENVPN_BIN)
-
- policy_contents = POLICY_TEMPLATE.format(path=openvpn_path)
+ path = launcher.OPENVPN_BIN_PATH
+ policy_contents = privilege_policies.get_policy_contents(path)
with os.fdopen(polfd, 'w') as f:
f.write(policy_contents)
diff --git a/src/leap/services/eip/vpnlaunchers.py b/src/leap/services/eip/vpnlaunchers.py
index 8522d1df..b591b3ca 100644
--- a/src/leap/services/eip/vpnlaunchers.py
+++ b/src/leap/services/eip/vpnlaunchers.py
@@ -38,6 +38,8 @@ 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
+from leap.util.privilege_policies import LinuxPolicyChecker
+from leap.util import privilege_policies
logger = logging.getLogger(__name__)
@@ -62,7 +64,7 @@ class EIPNoTunKextLoaded(VPNLauncherException):
pass
-class VPNLauncher:
+class VPNLauncher(object):
"""
Abstract launcher class
"""
@@ -237,6 +239,10 @@ class LinuxVPNLauncher(VPNLauncher):
PKEXEC_BIN = 'pkexec'
OPENVPN_BIN = 'openvpn'
+ OPENVPN_BIN_PATH = os.path.join(
+ ProviderConfig().get_path_prefix(),
+ "..", "apps", "eip", OPENVPN_BIN)
+
SYSTEM_CONFIG = "/etc/leap"
UP_DOWN_FILE = "resolv-update"
UP_DOWN_PATH = "%s/%s" % (SYSTEM_CONFIG, UP_DOWN_FILE)
@@ -250,12 +256,26 @@ class LinuxVPNLauncher(VPNLauncher):
OPENVPN_DOWN_ROOT_BASE,
OPENVPN_DOWN_ROOT_FILE)
- 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,)
+ POLKIT_PATH = LinuxPolicyChecker.get_polkit_path()
+ OTHER_FILES = (POLKIT_PATH, )
+
+ def missing_other_files(self):
+ """
+ 'Extend' the VPNLauncher's missing_other_files to check if the polkit
+ files is outdated. If the polkit file that is in OTHER_FILES exists but
+ is not up to date, it is added to the missing list.
+
+ :returns: a list of missing files
+ :rtype: list of str
+ """
+ missing = VPNLauncher.missing_other_files.im_func(self)
+ polkit_file = LinuxPolicyChecker.get_polkit_path()
+ if polkit_file not in missing:
+ if privilege_policies.is_policy_outdated(self.OPENVPN_BIN_PATH):
+ missing.append(polkit_file)
+
+ return missing
@classmethod
def cmd_for_missing_scripts(kls, frompath, pol_file):
@@ -271,11 +291,13 @@ class LinuxVPNLauncher(VPNLauncher):
:rtype: str
"""
to = kls.SYSTEM_CONFIG
- cmd = "#!/bin/sh\nset -e\nmkdir -p %s\n"
- cmd = (cmd + "cp %s/%s %s\ncp \"%s\" \"%s\"") % (
- to,
- frompath, kls.UP_DOWN_FILE, to,
- pol_file, kls.POLKIT_PATH)
+
+ cmd = '#!/bin/sh\nset -e\n'
+ cmd += 'mkdir -p "%s"\n' % (to, )
+ cmd += 'cp "%s/%s" "%s"\n' % (frompath, kls.UP_DOWN_FILE, to)
+ cmd += 'cp "%s" "%s"\n' % (pol_file, kls.POLKIT_PATH)
+ cmd += 'chmod 644 "%s"\n' % (kls.POLKIT_PATH, )
+
return cmd
@classmethod
diff --git a/src/leap/util/privilege_policies.py b/src/leap/util/privilege_policies.py
index 10224bcd..72442553 100644
--- a/src/leap/util/privilege_policies.py
+++ b/src/leap/util/privilege_policies.py
@@ -27,6 +27,35 @@ from abc import ABCMeta, abstractmethod
logger = logging.getLogger(__name__)
+POLICY_TEMPLATE = """<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE policyconfig PUBLIC
+ "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
+ "http://www.freedesktop.org/standards/PolicyKit/1/policyconfig.dtd">
+<policyconfig>
+
+ <vendor>LEAP Project</vendor>
+ <vendor_url>https://leap.se/</vendor_url>
+
+ <action id="net.openvpn.gui.leap.run-openvpn">
+ <description>Runs the openvpn binary</description>
+ <description xml:lang="es">Ejecuta el binario openvpn</description>
+ <message>OpenVPN needs that you authenticate to start</message>
+ <message xml:lang="es">
+ OpenVPN necesita autorizacion para comenzar
+ </message>
+ <icon_name>package-x-generic</icon_name>
+ <defaults>
+ <allow_any>yes</allow_any>
+ <allow_inactive>yes</allow_inactive>
+ <allow_active>yes</allow_active>
+ </defaults>
+ <annotate key="org.freedesktop.policykit.exec.path">{path}</annotate>
+ <annotate key="org.freedesktop.policykit.exec.allow_gui">true</annotate>
+ </action>
+</policyconfig>
+"""
+
+
def is_missing_policy_permissions():
"""
Returns True if we do not have implemented a policy checker for this
@@ -47,6 +76,36 @@ def is_missing_policy_permissions():
return policy_checker().is_missing_policy_permissions()
+def get_policy_contents(openvpn_path):
+ """
+ Returns the contents that the policy file should have.
+
+ :param openvpn_path: the openvpn path to use in the polkit file
+ :type openvpn_path: str
+ :rtype: str
+ """
+ return POLICY_TEMPLATE.format(path=openvpn_path)
+
+
+def is_policy_outdated(path):
+ """
+ Returns if the existing polkit file is outdated, comparing if the path
+ is correct.
+
+ :param path: the path that should have the polkit file.
+ :type path: str.
+ :rtype: bool
+ """
+ _system = platform.system()
+ platform_checker = _system + "PolicyChecker"
+ policy_checker = globals().get(platform_checker, None)
+ if policy_checker is None:
+ logger.debug("we could not find a policy checker implementation "
+ "for %s" % (_system,))
+ return False
+ return policy_checker().is_outdated(path)
+
+
class PolicyChecker:
"""
Abstract PolicyChecker class
@@ -72,6 +131,15 @@ class LinuxPolicyChecker(PolicyChecker):
LINUX_POLKIT_FILE = ("/usr/share/polkit-1/actions/"
"net.openvpn.gui.leap.policy")
+ @classmethod
+ def get_polkit_path(self):
+ """
+ Returns the polkit file path.
+
+ :rtype: str
+ """
+ return self.LINUX_POLKIT_FILE
+
def is_missing_policy_permissions(self):
"""
Returns True if we could not find the appropriate policykit file
@@ -80,3 +148,22 @@ class LinuxPolicyChecker(PolicyChecker):
:rtype: bool
"""
return not os.path.isfile(self.LINUX_POLKIT_FILE)
+
+ def is_outdated(self, path):
+ """
+ Returns if the existing polkit file is outdated, comparing if the path
+ is correct.
+
+ :param path: the path that should have the polkit file.
+ :type path: str.
+ :rtype: bool
+ """
+ polkit = None
+ try:
+ with open(self.LINUX_POLKIT_FILE) as f:
+ polkit = f.read()
+ except IOError, e:
+ logger.error("Error reading polkit file(%s): %r" % (
+ self.LINUX_POLKIT_FILE, e))
+
+ return get_policy_contents(path) != polkit