From 4359515dafe572398262ce91bf88d4f122042981 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Touceda?= Date: Wed, 13 Mar 2013 13:39:00 -0300 Subject: Add vpn already running checks --- pkg/requirements.pip | 1 + src/leap/gui/mainwindow.py | 8 +++++ src/leap/services/eip/vpn.py | 76 ++++++++++++++++++++++++++++++++++++++++++++ src/leap/util/certs.py | 6 ++-- 4 files changed, 89 insertions(+), 2 deletions(-) diff --git a/pkg/requirements.pip b/pkg/requirements.pip index e47e0bff..b6a2083f 100644 --- a/pkg/requirements.pip +++ b/pkg/requirements.pip @@ -10,3 +10,4 @@ pyxdg argparse PySide python-dateutil +psutil diff --git a/src/leap/gui/mainwindow.py b/src/leap/gui/mainwindow.py index 6f7f646e..9b4a70a5 100644 --- a/src/leap/gui/mainwindow.py +++ b/src/leap/gui/mainwindow.py @@ -680,6 +680,14 @@ class MainWindow(QtGui.QMainWindow): self._set_eip_status(self.tr("VPN: Connected!")) elif status == "WAIT": self._set_eip_status(self.tr("VPN: Waiting to start...")) + elif status == "ALREADYRUNNING": + # Put the following calls in Qt's event queue, otherwise + # the UI won't update properly + QtCore.QTimer.singleShot(0, self._stop_eip) + QtCore.QTimer.singleShot(0, partial(self._set_eip_status, + self.tr("Unable to start VPN, " + "it's already " + "running."))) else: self._set_eip_status(status) diff --git a/src/leap/services/eip/vpn.py b/src/leap/services/eip/vpn.py index b9988117..dd42cd13 100644 --- a/src/leap/services/eip/vpn.py +++ b/src/leap/services/eip/vpn.py @@ -18,8 +18,10 @@ """ VPN launcher and watcher thread """ + import logging import sys +import psutil from PySide import QtCore, QtGui from functools import partial @@ -61,6 +63,8 @@ class VPN(QtCore.QThread): TCPUDP_WRITE_KEY = "tcp_udp_write" AUTH_READ_KEY = "auth_read" + ALREADY_RUNNING_STEP = "ALREADYRUNNING" + def __init__(self): QtCore.QThread.__init__(self) @@ -134,6 +138,20 @@ class VPN(QtCore.QThread): with QtCore.QMutexLocker(self._should_quit_lock): self._should_quit = False + if not self._stop_if_already_running(): + # We send a fake state + state_dict = { + self.TS_KEY: "", + self.STATUS_STEP_KEY: self.ALREADY_RUNNING_STEP, + self.OK_KEY: "", + self.IP_KEY: "", + self.REMOTE_KEY: "" + } + + self.state_changed.emit(state_dict) + # And just return, don't start the process + return + command = self._launcher.get_vpn_command(eipconfig=eipconfig, providerconfig=providerconfig, socket_host=socket_host, @@ -156,6 +174,64 @@ class VPN(QtCore.QThread): logger.warning("Something went wrong while starting OpenVPN: %r" % (e,)) + def _get_openvpn_process(self): + """ + Looks for openvpn instances running + + @rtype: process + """ + openvpn_process = None + for p in psutil.process_iter(): + try: + # XXX Not exact! + # Will give false positives. + # we should check that cmdline BEGINS + # with openvpn or with our wrapper + # (pkexec / osascript / whatever) + if self._launcher.OPENVPN_BIN in ' '.join(p.cmdline): + openvpn_process = p + break + except psutil.error.AccessDenied: + pass + return openvpn_process + + def _stop_if_already_running(self): + """ + Checks if VPN is already running and tries to stop it + + @return: True if stopped, False otherwise + """ + + process = self._get_openvpn_process() + if process: + logger.debug("OpenVPN is already running, trying to stop it") + cmdline = process.cmdline + + manag_flag = "--management" + if isinstance(cmdline, list) and manag_flag in cmdline: + try: + index = cmdline.index(manag_flag) + host = cmdline[index + 1] + port = cmdline[index + 2] + logger.debug("Trying to connect to %s:%s" + % (host, port)) + self._connect(host, port) + self._send_command("signal SIGTERM") + self._tn.close() + self._tn = None + except Exception as e: + logger.warning("Problem trying to terminate OpenVPN: %r" + % (e,)) + + process = self._get_openvpn_process() + if process is None: + logger.warning("Unabled to terminate OpenVPN") + return True + else: + return False + + return True + def _connect(self, socket_host, socket_port): """ Connects to the specified socket_host socket_port diff --git a/src/leap/util/certs.py b/src/leap/util/certs.py index a8bcd65e..63c60c3d 100644 --- a/src/leap/util/certs.py +++ b/src/leap/util/certs.py @@ -162,14 +162,16 @@ def should_redownload(certfile, now=time.gmtime): if not exists: return True + certdata = None try: with open(certfile, "r") as f: - if not is_valid_pemfile(f.read()): + certdata = f.read() + if not is_valid_pemfile(certdata): return True except: return True - valid_from, valid_to = get_cert_time_boundaries(certfile) + valid_from, valid_to = get_cert_time_boundaries(certdata) if not (valid_from < now() < valid_to): return True -- cgit v1.2.3