From 1d4a3d68869dd9c416b104399097a6bb0c1bace3 Mon Sep 17 00:00:00 2001 From: "Kali Kaneko (leap communications)" Date: Wed, 1 Feb 2017 14:49:45 +0100 Subject: [feature] new commands: get_cert --- src/leap/bitmask/vpn/__init__.py | 10 ---- src/leap/bitmask/vpn/_checks.py | 27 +++++++++++ src/leap/bitmask/vpn/_control.py | 7 +-- src/leap/bitmask/vpn/_management.py | 14 ++---- src/leap/bitmask/vpn/eip.py | 2 +- src/leap/bitmask/vpn/errors.py | 2 +- src/leap/bitmask/vpn/manager.py | 13 ++++-- src/leap/bitmask/vpn/process.py | 7 ++- src/leap/bitmask/vpn/service.py | 91 ++++++++++++++++++++++++------------- 9 files changed, 109 insertions(+), 64 deletions(-) create mode 100644 src/leap/bitmask/vpn/_checks.py (limited to 'src/leap/bitmask/vpn') diff --git a/src/leap/bitmask/vpn/__init__.py b/src/leap/bitmask/vpn/__init__.py index 6c3cf064..e69de29b 100644 --- a/src/leap/bitmask/vpn/__init__.py +++ b/src/leap/bitmask/vpn/__init__.py @@ -1,10 +0,0 @@ -# -*- coding: utf-8 -*- -from .manager import VPNManager -from .eip import EIPManager -from .service import EIPService -from .fw.firewall import FirewallManager - -import errors - -__all__ = ['VPNManager', 'FirewallManager', 'EIPManager', 'EIPService', - 'errors'] diff --git a/src/leap/bitmask/vpn/_checks.py b/src/leap/bitmask/vpn/_checks.py new file mode 100644 index 00000000..3a1914f1 --- /dev/null +++ b/src/leap/bitmask/vpn/_checks.py @@ -0,0 +1,27 @@ +import os + +from leap.common.config import get_path_prefix + + +class ImproperlyConfigured(Exception): + pass + + +def is_service_ready(provider): + valid_cert = _has_valid_cert(provider) + return True + + +def get_eip_cert_path(provider): + return os.path.join(get_path_prefix(), + 'leap', 'providers', provider, + 'keys', 'client', 'openvpn.pem') + + +def _has_valid_cert(provider): + cert_path = get_eip_cert_path(provider) + has_file = os.path.isfile(cert_path) + if not has_file: + raise ImproperlyConfigured('Missing EIP certificate') + + diff --git a/src/leap/bitmask/vpn/_control.py b/src/leap/bitmask/vpn/_control.py index 991dc0ff..82dd90bc 100644 --- a/src/leap/bitmask/vpn/_control.py +++ b/src/leap/bitmask/vpn/_control.py @@ -14,11 +14,8 @@ class VPNControl(object): OPENVPN_VERB = "openvpn_verb" def __init__(self, **kwargs): - """ - Instantiate empty attributes and get a copy - of a QObject containing the QSignals that we will pass along - to the VPNManager. - """ + # TODO what the fuck this is doing that is different from + # the manager? self._vpnproc = None self._pollers = [] diff --git a/src/leap/bitmask/vpn/_management.py b/src/leap/bitmask/vpn/_management.py index 0eb37b7b..51120a34 100644 --- a/src/leap/bitmask/vpn/_management.py +++ b/src/leap/bitmask/vpn/_management.py @@ -1,3 +1,6 @@ +from leap.bitmask.vpn.constants import IS_MAC + + class OpenVPNAlreadyRunning(Exception): message = ("Another openvpn instance is already running, and could " "not be stopped.") @@ -36,15 +39,7 @@ class VPNManagement(object): """ self._tn = None self._signaler = signaler - self._aborted = False - - @property - def aborted(self): - return self._aborted - - @aborted.setter - def aborted(self, value): - self._aborted = value + self.aborted = False def _seek_to_eof(self): """ @@ -419,4 +414,3 @@ class VPNManagement(object): else: logger.warning("Unable to terminate OpenVPN") raise OpenVPNAlreadyRunning - diff --git a/src/leap/bitmask/vpn/eip.py b/src/leap/bitmask/vpn/eip.py index 853fabda..d6736629 100644 --- a/src/leap/bitmask/vpn/eip.py +++ b/src/leap/bitmask/vpn/eip.py @@ -18,7 +18,7 @@ from colorama import Fore -from leap.bitmask.vpn import VPNManager +from leap.bitmask.vpn.manager import VPNManager from leap.bitmask.vpn.fw.firewall import FirewallManager from leap.bitmask.vpn.status import StatusQueue from leap.bitmask.vpn.zmq_pub import ZMQPublisher diff --git a/src/leap/bitmask/vpn/errors.py b/src/leap/bitmask/vpn/errors.py index 77cf1dcb..239ea352 100644 --- a/src/leap/bitmask/vpn/errors.py +++ b/src/leap/bitmask/vpn/errors.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -from .process import OpenVPNAlreadyRunning, AlienOpenVPNAlreadyRunning +from ._management import OpenVPNAlreadyRunning, AlienOpenVPNAlreadyRunning from .launcher import OpenVPNNotFoundException, VPNLauncherException from leap.bitmask.vpn.launchers.linux import ( EIPNoPolkitAuthAgentAvailable, EIPNoPkexecAvailable) diff --git a/src/leap/bitmask/vpn/manager.py b/src/leap/bitmask/vpn/manager.py index 541da9e0..68025852 100644 --- a/src/leap/bitmask/vpn/manager.py +++ b/src/leap/bitmask/vpn/manager.py @@ -22,11 +22,15 @@ VPN Manager import os import tempfile -from leap.bitmask.vpn import process, _config -from leap.bitmask.vpn.constants import IS_WIN +from .process import VPNProcess +from ._config import _TempEIPConfig +from .constants import IS_WIN +# TODO this is very badly named. There is another class that is called +# manager!!! + class VPNManager(object): def __init__(self, remotes, cert_path, key_path, ca_path, extra_flags, @@ -45,11 +49,12 @@ class VPNManager(object): domain = "demo.bitmask.net" self._remotes = remotes - self._eipconfig = _config._TempEIPConfig(extra_flags, cert_path, ports) + self._eipconfig = _TempEIPConfig(extra_flags, cert_path, ports) self._providerconfig = _config._TempProviderConfig(domain, ca_path) # signaler = None # XXX handle signaling somehow... signaler = mock_signaler - self._vpn = process.VPN(remotes=remotes, signaler=signaler) + self._vpn = VPNProcess(remotes=remotes, signaler=signaler) + def start(self): """ diff --git a/src/leap/bitmask/vpn/process.py b/src/leap/bitmask/vpn/process.py index 4aae26b5..47c29423 100644 --- a/src/leap/bitmask/vpn/process.py +++ b/src/leap/bitmask/vpn/process.py @@ -16,7 +16,9 @@ # along with this program. If not, see . """ -VPN Manager, spawned in a custom processProtocol. +VPN Process management. +A custom processProtocol launches the VPNProcess and connects to its management +interface. """ import os @@ -48,6 +50,7 @@ from leap.bitmask.vpn.utils import get_vpn_launcher from leap.bitmask.vpn.launchers import linux from leap.bitmask.vpn.udstelnet import UDSTelnet from leap.bitmask.vpn import _observer +from leap.bitmask.vpn import _management logger = Logger() @@ -56,7 +59,7 @@ logger = Logger() OPENVPN_VERBOSITY = 1 -class VPNProcess(protocol.ProcessProtocol, VPNManager): +class VPNProcess(protocol.ProcessProtocol, _management.VPNManagement): """ A ProcessProtocol class that can be used to spawn a process that will launch openvpn and connect to its management interface to control it diff --git a/src/leap/bitmask/vpn/service.py b/src/leap/bitmask/vpn/service.py index d83a9ef8..59e251da 100644 --- a/src/leap/bitmask/vpn/service.py +++ b/src/leap/bitmask/vpn/service.py @@ -22,16 +22,19 @@ EIP service declaration. import os -from twisted.application import service -from twisted.python import log +from twisted.internet import defer from leap.bitmask.hooks import HookableService -from leap.bitmask.vpn import EIPManager +from leap.bitmask.vpn.eip import EIPManager +from leap.bitmask.vpn._checks import is_service_ready, get_eip_cert_path from leap.common.config import get_path_prefix +from leap.common.files import check_and_fix_urw_only class EIPService(HookableService): + name = 'eip' + def __init__(self, basepath=None): """ Initialize EIP service @@ -45,18 +48,66 @@ class EIPService(HookableService): else: self._basepath = basepath + def startService(self): + print "Starting EIP Service..." + # TODO this could trigger a check for validity of the certificates, + # etc. + super(EIPService, self).startService() + + def stopService(self): + print "Stopping EIP Service..." + super(EIPService, self).stopService() + + def start_vpn(self, domain): + self._setup(domain) + self._eip.start() + self._started = True + return "Starting" + + def stop_vpn(self): + if self._started: + self._eip.stop() + self._started = False + return "Stopping" + else: + return "Not started" + + def do_status(self): + # TODO -- get status from a dedicated STATUS CLASS + return {'result': 'running'} + + def do_check(self): + """Check whether the EIP Service is properly configured, + and can be started""" + # TODO either pass a provider, or set a given provider + _ready = is_service_ready('demo.bitmask.net') + return {'eip_ready': 'ok'} + + @defer.inlineCallbacks + def do_get_cert(self, provider): + # fetch vpn cert and store + bonafide = self.parent.getServiceNamed("bonafide") + _, cert_str = yield bonafide.do_get_vpn_cert() + + cert_path = get_eip_cert_path(provider) + cert_dir = os.path.dirname(cert_path) + if not os.path.exists(cert_dir): + os.makedirs(cert_dir, mode=0700) + with open(cert_path, 'w') as outf: + outf.write(cert_str) + check_and_fix_urw_only(cert_path) + defer.returnValue({'get_cert': 'ok'}) + def _setup(self, provider): - """ - Set up EIPManager for a specified provider. + """Set up EIPManager for a specified provider. :param provider: the provider to use, e.g. 'demo.bitmask.net' - :type provider: str - """ + :type provider: str""" # FIXME # XXX picked manually from eip-service.json remotes = ( - ("198.252.153.84", "1194"), - ("46.165.242.169", "1194"), + ("198.252.153.84", "1194 "), + ("46.165.242.169", "1194 "), ) prefix = os.path.join(self._basepath, @@ -76,25 +127,3 @@ class EIPService(HookableService): self._eip = EIPManager(remotes, cert_path, key_path, ca_path, extra_flags) - - def startService(self): - print "Starting EIP Service..." - super(EIPService, self).startService() - - def stopService(self): - print "Stopping EIP Service..." - super(EIPService, self).stopService() - - def do_start(self, domain): - self._setup(domain) - self._eip.start() - self._started = True - return "Starting" - - def do_stop(self): - if self._started: - self._eip.stop() - self._started = False - return "Stopping" - else: - return "Not started" -- cgit v1.2.3