summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/leap/baseapp/dialogs.py11
-rw-r--r--src/leap/baseapp/mainwindow.py14
-rw-r--r--src/leap/eip/conductor.py21
-rw-r--r--src/leap/eip/config.py56
-rw-r--r--src/leap/util/fileutil.py24
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