diff options
Diffstat (limited to 'src/leap')
-rw-r--r-- | src/leap/config/providerconfig.py | 18 | ||||
-rw-r--r-- | src/leap/gui/mainwindow.py | 2 | ||||
-rw-r--r-- | src/leap/gui/ui/wizard.ui | 269 | ||||
-rw-r--r-- | src/leap/gui/wizard.py | 56 | ||||
-rw-r--r-- | src/leap/util/privilege_policies.py | 82 |
5 files changed, 357 insertions, 70 deletions
diff --git a/src/leap/config/providerconfig.py b/src/leap/config/providerconfig.py index 71b2856f..7651863b 100644 --- a/src/leap/config/providerconfig.py +++ b/src/leap/config/providerconfig.py @@ -65,6 +65,11 @@ class ProviderConfig(BaseConfig): return self._safe_get_value("domain") def get_enrollment_policy(self): + """ + Returns the enrollment policy + + @rtype: string + """ return self._safe_get_value("enrollment_policy") def get_languages(self): @@ -75,8 +80,21 @@ class ProviderConfig(BaseConfig): return self._safe_get_value("name") def get_services(self): + """ + Returns a list with the services supported by the + current provider + + @rtype: list + """ return self._safe_get_value("services") + def get_services_string(self): + """ + Returns a string with the services supported by the current provider, + ready to be shown to the user + """ + return ", ".join(self.get_services()) + def get_ca_cert_path(self, about_to_download=False): """ Returns the path to the certificate for the current provider diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index 3fa3aad3..f359d7c1 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -202,7 +202,7 @@ class MainWindow(QtGui.QMainWindow): self._wizard_firstrun = False if self._first_run(): self._wizard_firstrun = True - self._wizard = Wizard(self._checker_thread) + self._wizard = Wizard(self._checker_thread, standalone=standalone) # Give this window time to finish init and then show the wizard QtCore.QTimer.singleShot(1, self._launch_wizard) self._wizard.accepted.connect(self._finish_init) diff --git a/src/leap/gui/ui/wizard.ui b/src/leap/gui/ui/wizard.ui index b8fed183..ed7fe37c 100644 --- a/src/leap/gui/ui/wizard.ui +++ b/src/leap/gui/ui/wizard.ui @@ -100,7 +100,7 @@ <string>Provider selection</string> </property> <property name="subTitle"> - <string>Please enter the domain of the provider you want to user for your connection</string> + <string>Please enter the domain of the provider you want to use for your connection</string> </property> <attribute name="pageId"> <string notr="true">1</string> @@ -158,20 +158,20 @@ <item row="4" column="0" colspan="3"> <widget class="QGroupBox" name="grpCheckProvider"> <property name="title"> - <string>Checking provider</string> + <string>Checking for a valid provider</string> </property> <layout class="QGridLayout" name="gridLayout_3"> <item row="3" column="0"> <widget class="QLabel" name="label_5"> <property name="text"> - <string>Download provider information</string> + <string>Getting provider information</string> </property> </widget> </item> <item row="2" column="0"> <widget class="QLabel" name="label_4"> <property name="text"> - <string>HTTPS Connection</string> + <string>Can we stablish a secure connection?</string> </property> </widget> </item> @@ -244,7 +244,7 @@ <item row="1" column="0"> <widget class="QLabel" name="label_2"> <property name="text"> - <string>Name resolution</string> + <string>Can we reach this provider?</string> </property> </widget> </item> @@ -278,47 +278,118 @@ <string>Provider Information</string> </property> <property name="subTitle"> - <string>Services offered by this provider</string> + <string>Description of services offered by this provider</string> </property> <attribute name="pageId"> <string notr="true">2</string> </attribute> <layout class="QGridLayout" name="gridLayout_4"> - <item row="0" column="1" colspan="2"> - <spacer name="horizontalSpacer_6"> + <item row="0" column="0"> + <spacer name="verticalSpacer_5"> <property name="orientation"> - <enum>Qt::Horizontal</enum> + <enum>Qt::Vertical</enum> </property> <property name="sizeHint" stdset="0"> <size> - <width>40</width> - <height>0</height> + <width>20</width> + <height>40</height> </size> </property> </spacer> </item> - <item row="5" column="0" colspan="2"> - <widget class="QLabel" name="label_12"> + <item row="0" column="1"> + <spacer name="verticalSpacer_13"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + <item row="0" column="2"> + <spacer name="verticalSpacer_17"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + <item row="0" column="3"> + <spacer name="verticalSpacer_18"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + <item row="0" column="4"> + <spacer name="verticalSpacer_19"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + <item row="0" column="5"> + <spacer name="verticalSpacer_20"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="lblProviderName"> <property name="text"> - <string><b>Enrollment policy:</b></string> + <string>Name</string> </property> </widget> </item> - <item row="2" column="1" colspan="2"> + <item row="1" column="1"> <widget class="QLabel" name="lblProviderURL"> <property name="text"> <string>URL</string> </property> </widget> </item> - <item row="2" column="0"> - <widget class="QLabel" name="lblProviderName"> - <property name="text"> - <string>Name</string> + <item row="1" column="6"> + <spacer name="horizontalSpacer_3"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> </property> - </widget> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> </item> - <item row="4" column="2"> + <item row="2" column="0"> <spacer name="horizontalSpacer_7"> <property name="orientation"> <enum>Qt::Horizontal</enum> @@ -326,42 +397,75 @@ <property name="sizeHint" stdset="0"> <size> <width>40</width> - <height>0</height> + <height>20</height> </size> </property> </spacer> </item> - <item row="1" column="1"> - <spacer name="verticalSpacer_13"> + <item row="2" column="1" colspan="6"> + <widget class="QLabel" name="lblProviderDesc"> + <property name="minimumSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="baseSize"> + <size> + <width>200</width> + <height>0</height> + </size> + </property> + <property name="text"> + <string>Desc</string> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="3" column="0"> + <widget class="QLabel" name="lblServ"> + <property name="text"> + <string><b>Services offered:</b></string> + </property> + </widget> + </item> + <item row="3" column="1"> + <widget class="QLabel" name="lblServicesOffered"> + <property name="text"> + <string>services</string> + </property> + </widget> + </item> + <item row="3" column="6"> + <spacer name="horizontalSpacer_6"> <property name="orientation"> - <enum>Qt::Vertical</enum> + <enum>Qt::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> - <width>20</width> - <height>40</height> + <width>40</width> + <height>20</height> </size> </property> </spacer> </item> - <item row="5" column="2"> - <widget class="QLabel" name="lblProviderPolicy"> + <item row="4" column="0"> + <widget class="QLabel" name="label_12"> <property name="text"> - <string>policy</string> + <string><b>Enrollment policy:</b></string> </property> </widget> </item> - <item row="3" column="0" colspan="3"> - <widget class="QLabel" name="lblProviderDesc"> + <item row="4" column="1"> + <widget class="QLabel" name="lblProviderPolicy"> <property name="text"> - <string>Desc</string> - </property> - <property name="wordWrap"> - <bool>true</bool> + <string>policy</string> </property> </widget> </item> - <item row="6" column="0"> + <item row="5" column="0"> <spacer name="verticalSpacer_14"> <property name="orientation"> <enum>Qt::Vertical</enum> @@ -374,6 +478,32 @@ </property> </spacer> </item> + <item row="5" column="1"> + <spacer name="verticalSpacer_15"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + <item row="5" column="6"> + <spacer name="verticalSpacer_16"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> </layout> </widget> <widget class="WizardPage" name="setup_provider_page"> @@ -386,11 +516,47 @@ <attribute name="pageId"> <string notr="true">3</string> </attribute> - <layout class="QGridLayout" name="gridLayout_5"> - <item row="1" column="0"> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <spacer name="verticalSpacer_3"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>60</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLabel" name="lblSetupProviderExpl"> + <property name="text"> + <string>We are downloading some bits that we need to establish a secure connection with the provider for the first time.</string> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <spacer name="verticalSpacer_6"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + <item> <widget class="QGroupBox" name="groupBox_2"> <property name="title"> - <string>Checking provider</string> + <string>Setting up provider</string> </property> <layout class="QGridLayout" name="gridLayout_6"> <item row="2" column="1"> @@ -440,21 +606,21 @@ <item row="1" column="0"> <widget class="QLabel" name="label_9"> <property name="text"> - <string>Download CA Certificate</string> + <string>Getting info from the Certificate Authority</string> </property> </widget> </item> <item row="2" column="0"> <widget class="QLabel" name="label_10"> <property name="text"> - <string>Check CA Certificate Fingerprint</string> + <string>Do we trust this Certificate Authority?</string> </property> </widget> </item> <item row="3" column="0"> <widget class="QLabel" name="label_11"> <property name="text"> - <string>Check API Certificate</string> + <string>Establishing a trust relationship with this provider</string> </property> </widget> </item> @@ -496,20 +662,7 @@ </layout> </widget> </item> - <item row="0" column="0"> - <spacer name="verticalSpacer_3"> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>20</width> - <height>60</height> - </size> - </property> - </spacer> - </item> - <item row="2" column="0"> + <item> <spacer name="verticalSpacer_8"> <property name="orientation"> <enum>Qt::Vertical</enum> @@ -662,7 +815,7 @@ <string>Congratulations!</string> </property> <property name="subTitle"> - <string>You have successfully configured the LEAP client.</string> + <string>You have successfully configured the LEAP Client.</string> </property> <attribute name="pageId"> <string notr="true">6</string> diff --git a/src/leap/gui/wizard.py b/src/leap/gui/wizard.py index dee3b230..7759b98d 100644 --- a/src/leap/gui/wizard.py +++ b/src/leap/gui/wizard.py @@ -27,6 +27,7 @@ from functools import partial from ui_wizard import Ui_Wizard from leap.config.providerconfig import ProviderConfig from leap.crypto.srpregister import SRPRegister +from leap.util.privilege_policies import is_missing_policy_permissions from leap.services.eip.providerbootstrapper import ProviderBootstrapper logger = logging.getLogger(__name__) @@ -50,9 +51,20 @@ class Wizard(QtGui.QWizard): BARE_USERNAME_REGEX = r"^[A-Za-z\d_]+$" - def __init__(self, checker): + def __init__(self, checker, standalone=False): + """ + Constructor for the main Wizard. + + @param checker: Checker thread that the wizard should use. + @type checker: CheckerThread + @param standalone: If True, the application is running as standalone + and the wizard should display some messages according to this. + @type standalone: bool + """ QtGui.QWizard.__init__(self) + self.standalone = standalone + self.ui = Ui_Wizard() self.ui.setupUi(self) @@ -64,14 +76,21 @@ class Wizard(QtGui.QWizard): self.OK_ICON = QtGui.QPixmap(":/images/Dialog-accept.png") # Correspondence for services and their name to display + EIP_LABEL = self.tr("Encrypted Internet") + + if self._is_need_eip_password_warning(): + EIP_LABEL += " " + self.tr( + "(<b>will need admin password to start</b>)") + self.SERVICE_DISPLAY = [ - self.tr("Encrypted Internet") + EIP_LABEL ] self.SERVICE_CONFIG = [ "openvpn" ] self._selected_services = set() + self._shown_services = set() self._show_register = False @@ -235,7 +254,7 @@ class Wizard(QtGui.QWizard): error_msg = req.json().get("errors").get("login")[0] if not error_msg.istitle(): error_msg = "%s %s" % (old_username, error_msg) - self._set_register_status(error_msg) + self._set_register_status(error_msg, error=True) except: logger.error("Unknown error: %r" % (req.content,)) self.ui.btnRegister.setEnabled(True) @@ -451,13 +470,15 @@ class Wizard(QtGui.QWizard): for service in self._provider_config.get_services(): try: - checkbox = QtGui.QCheckBox(self) - service_index = self.SERVICE_CONFIG.index(service) - checkbox.setText(self.SERVICE_DISPLAY[service_index]) - self.ui.serviceListLayout.addWidget(checkbox) - checkbox.stateChanged.connect( - partial(self._service_selection_changed, service)) - checkbox.setChecked(True) + if service not in self._shown_services: + checkbox = QtGui.QCheckBox(self) + service_index = self.SERVICE_CONFIG.index(service) + checkbox.setText(self.SERVICE_DISPLAY[service_index]) + self.ui.serviceListLayout.addWidget(checkbox) + checkbox.stateChanged.connect( + partial(self._service_selection_changed, service)) + checkbox.setChecked(True) + self._shown_services.add(service) except ValueError: logger.error( self.tr("Something went wrong while trying to " @@ -486,7 +507,8 @@ class Wizard(QtGui.QWizard): self._provider_config) if pageId == self.PRESENT_PROVIDER_PAGE: - self.page(pageId).setSubTitle(self.tr("Services offered by %s") % + self.page(pageId).setSubTitle(self.tr("Description of services " + "offered by %s") % (self._provider_config .get_name(),)) @@ -499,6 +521,9 @@ class Wizard(QtGui.QWizard): self.ui.lblProviderDesc.setText( "<i>%s</i>" % (self._provider_config.get_description(lang=lang),)) + + self.ui.lblServicesOffered.setText(self._provider_config + .get_services_string()) self.ui.lblProviderPolicy.setText(self._provider_config .get_enrollment_policy()) @@ -511,6 +536,15 @@ class Wizard(QtGui.QWizard): if pageId == self.SERVICES_PAGE: self._populate_services() + def _is_need_eip_password_warning(self): + """ + Returns True if we need to add a warning about eip needing + administrative permissions to start. That can be either + because we are running in standalone mode, or because we could + not find the needed privilege escalation mechanisms being operative. + """ + return self.standalone or is_missing_policy_permissions() + def nextId(self): """ Sets the next page id for the wizard based on wether the user diff --git a/src/leap/util/privilege_policies.py b/src/leap/util/privilege_policies.py new file mode 100644 index 00000000..e74c4d33 --- /dev/null +++ b/src/leap/util/privilege_policies.py @@ -0,0 +1,82 @@ +# -*- coding: utf-8 -*- +# privilege_policies.py +# Copyright (C) 2013 LEAP +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +""" +Helpers to determine if the needed policies for privilege escalation +are operative under this client run. +""" +import logging +import os +import platform + +from abc import ABCMeta, abstractmethod + +logger = logging.getLogger(__name__) + + +def is_missing_policy_permissions(): + """ + Returns True if we do not have implemented a policy checker for this + platform, or if the policy checker exists but it cannot find the + appropriate policy mechanisms in place. + + @rtype: bool + """ + _system = platform.system() + platform_checker = _system + "PolicyChecker" + policy_checker = globals().get(platform_checker, None) + if not policy_checker: + # it is true that we miss permission to escalate + # privileges without asking for password each time. + logger.debug("we could not find a policy checker implementation " + "for %s" % (_system,)) + return True + return policy_checker().is_missing_policy_permissions() + + +class PolicyChecker: + """ + Abstract PolicyChecker class + """ + + __metaclass__ = ABCMeta + + @abstractmethod + def is_missing_policy_permissions(self): + """ + Returns True if we could not find any policy mechanisms that + are defined to be in used for this particular platform. + + @rtype: bool + """ + return True + + +class LinuxPolicyChecker(PolicyChecker): + """ + PolicyChecker for Linux + """ + LINUX_POLKIT_FILE = ("/usr/share/polkit-1/actions/" + "net.openvpn.gui.leap.policy") + + def is_missing_policy_permissions(self): + """ + Returns True if we could not find the appropriate policykit file + in place + + @rtype: bool + """ + return not os.path.isfile(self.LINUX_POLKIT_FILE) |