diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/leap/baseapp/dialogs.py | 11 | ||||
| -rw-r--r-- | src/leap/baseapp/mainwindow.py | 14 | ||||
| -rw-r--r-- | src/leap/eip/conductor.py | 21 | ||||
| -rw-r--r-- | src/leap/eip/config.py | 56 | ||||
| -rw-r--r-- | src/leap/util/fileutil.py | 24 | 
5 files changed, 119 insertions, 7 deletions
diff --git a/src/leap/baseapp/dialogs.py b/src/leap/baseapp/dialogs.py index d4e51a39..4b1b5b62 100644 --- a/src/leap/baseapp/dialogs.py +++ b/src/leap/baseapp/dialogs.py @@ -20,3 +20,14 @@ class ErrorDialog(QDialog):              self.warningLabel.setText("Save Again")          else:              self.warningLabel.setText("Continue") + +    def criticalMessage(self, msg, label): +        msgBox = QMessageBox(QMessageBox.Critical, +                             "QMessageBox.critical()", msg, +                             QMessageBox.NoButton, self) +        msgBox.addButton("&Ok", QMessageBox.AcceptRole) +        msgBox.addButton("&Cancel", QMessageBox.RejectRole) +        if msgBox.exec_() == QMessageBox.AcceptRole: +            self.warningLabel.setText("Save Again") +        else: +            self.warningLabel.setText("Continue") diff --git a/src/leap/baseapp/mainwindow.py b/src/leap/baseapp/mainwindow.py index d5251a5c..cbdd2d07 100644 --- a/src/leap/baseapp/mainwindow.py +++ b/src/leap/baseapp/mainwindow.py @@ -12,7 +12,12 @@ from PyQt4.QtGui import (QMainWindow, QWidget, QVBoxLayout, QMessageBox,  from PyQt4.QtCore import (pyqtSlot, pyqtSignal, QTimer)  from leap.baseapp.dialogs import ErrorDialog -from leap.eip.conductor import EIPConductor, EIPNoCommandError +from leap.eip.conductor import (EIPConductor, +                                EIPNoCommandError) + +from leap.eip.config import (EIPInitBadKeyFilePermError) +# from leap.eip import exceptions as eip_exceptions +  from leap.gui import mainwindow_rc @@ -68,14 +73,17 @@ class LeapWindow(QMainWindow):          # we pass a tuple of signals that will be          # triggered when status changes.          # -          self.conductor = EIPConductor(              watcher_cb=self.newLogLine.emit,              config_file=config_file,              status_signals=(self.statusChange.emit, ),              debug=self.debugmode) -        #print('debugmode:%s' % self.debugmode) +        if self.conductor.bad_keyfile_perms is True: +            dialog = ErrorDialog() +            dialog.criticalMessage( +                'The vpn keys file has bad permissions', +                'error')          if self.conductor.missing_auth_agent is True:              dialog = ErrorDialog() diff --git a/src/leap/eip/conductor.py b/src/leap/eip/conductor.py index 243f1fde..3f40f068 100644 --- a/src/leap/eip/conductor.py +++ b/src/leap/eip/conductor.py @@ -5,15 +5,16 @@ from __future__ import (division, unicode_literals, print_function)  #import threading  from functools import partial  import logging -import os  from leap.util.coroutines import spawn_and_watch_process - +# XXX import eip.config as eipconfig  from leap.eip.config import (get_config, build_ovpn_command,                               check_or_create_default_vpnconf, +                             check_vpn_keys,                               EIPNoPkexecAvailable, -                             EIPNoPolkitAuthAgentAvailable) +                             EIPNoPolkitAuthAgentAvailable, +                             EIPInitBadKeyFilePermError)  from leap.eip.vpnwatcher import EIPConnectionStatus, status_watcher  from leap.eip.vpnmanager import OpenVPNManager, ConnectionRefusedError @@ -21,6 +22,7 @@ logger = logging.getLogger(name=__name__)  # TODO Move exceptions to their own module +# eip.exceptions  class EIPNoCommandError(Exception):      pass @@ -98,11 +100,14 @@ to be triggered for each one of them.          self.missing_pkexec = False          self.missing_auth_agent = False +        self.bad_keyfile_perms = False +          self.command = None          self.args = None          self.autostart = True          self._get_or_create_config() +        self._check_vpn_keys()      def _set_autostart(self):          config = self.config @@ -170,6 +175,16 @@ to be triggered for each one of them.          self._set_ovpn_command()          self._check_ovpn_config() +    def _check_vpn_keys(self): +        """ +        checks for correct permissions on vpn keys +        """ +        try: +            check_vpn_keys(self.config) +        except EIPInitBadKeyFilePermError: +            logger.error('error while checking vpn keys') +            self.bad_keyfile_perms = True +      def _launch_openvpn(self):          """          invocation of openvpn binaries in a subprocess. diff --git a/src/leap/eip/config.py b/src/leap/eip/config.py index 9af6f57a..91c3953b 100644 --- a/src/leap/eip/config.py +++ b/src/leap/eip/config.py @@ -4,13 +4,17 @@ import logging  import os  import platform -from leap.util.fileutil import which, mkdir_p +from leap.util.fileutil import (which, mkdir_p, +                                check_and_fix_urw_only)  from leap.baseapp.permcheck import (is_pkexec_in_system,                                      is_auth_agent_running)  logger = logging.getLogger(name=__name__)  logger.setLevel('DEBUG') +# XXX move exceptions to +# from leap.eip import exceptions as eip_exceptions +  class EIPNoPkexecAvailable(Exception):      pass @@ -20,6 +24,14 @@ class EIPNoPolkitAuthAgentAvailable(Exception):      pass +class EIPInitNoKeyFileError(Exception): +    pass + + +class EIPInitBadKeyFilePermError(Exception): +    pass + +  OPENVPN_CONFIG_TEMPLATE = """#Autogenerated by eip-client wizard  remote {VPN_REMOTE_HOST} {VPN_REMOTE_PORT} @@ -345,3 +357,45 @@ def get_config(config_file=None):      config.readfp(config_file)      return config + + +def check_vpn_keys(config): +    """ +    performs an existance and permission check +    over the openvpn keys file. +    Currently we're expecting a single file +    per provider, containing the CA cert, +    the provider key, and our client certificate +    """ + +    keyopt = ('provider', 'keyfile') + +    # XXX at some point, +    # should separate between CA, provider cert +    # and our certificate. +    # make changes in the default provider template +    # accordingly. + +    # get vpn keys +    if config.has_option(*keyopt): +        keyfile = config.get(*keyopt) +    else: +        keyfile = get_config_file( +            'openvpn.keys', +            folder=get_default_provider_path()) +        logger.debug('keyfile = %s', keyfile) + +    # if no keys, raise error. +    # should be catched by the ui and signal user. + +    if not os.path.isfile(keyfile): +        logger.error('key file %s not found. aborting.', +                     keyfile) +        raise EIPInitNoKeyFileError + +    # check proper permission on keys +    # bad perms? try to fix them +    try: +        check_and_fix_urw_only(keyfile) +    except OSError: +        raise EIPInitBadKeyFilePermError diff --git a/src/leap/util/fileutil.py b/src/leap/util/fileutil.py index bb2c243b..cc3bf34b 100644 --- a/src/leap/util/fileutil.py +++ b/src/leap/util/fileutil.py @@ -1,10 +1,14 @@  import errno  from itertools import chain +import logging  import os  import platform  import stat +logger = logging.getLogger() + +  def is_user_executable(fpath):      st = os.stat(fpath)      return bool(st.st_mode & stat.S_IXUSR) @@ -85,3 +89,23 @@ def mkdir_p(path):              pass          else:              raise + + +def check_and_fix_urw_only(_file): +    """ +    test for 600 mode and try +    to set it if anything different found +    """ +    mode = os.stat(_file).st_mode +    if mode != int('600', 8): +        try: +            logger.warning( +                'bad permission on %s ' +                'attempting to set 600', +                _file) +            os.chmod(_file, stat.S_IRUSR | stat.S_IWUSR) +        except OSError: +            logger.error( +                'error while trying to chmod 600 %s', +                _file) +            raise  | 
