summaryrefslogtreecommitdiff
path: root/src/leap/bitmask/vpn
diff options
context:
space:
mode:
authorKali Kaneko (leap communications) <kali@leap.se>2017-02-01 14:49:45 +0100
committerKali Kaneko (leap communications) <kali@leap.se>2017-02-23 00:40:31 +0100
commit1d4a3d68869dd9c416b104399097a6bb0c1bace3 (patch)
tree9afc38280e17a84e55184f064cf34f1a490ac539 /src/leap/bitmask/vpn
parent6d1d18faec5caa60c26b8245f0ab17c63d0b80d8 (diff)
[feature] new commands: get_cert
Diffstat (limited to 'src/leap/bitmask/vpn')
-rw-r--r--src/leap/bitmask/vpn/__init__.py10
-rw-r--r--src/leap/bitmask/vpn/_checks.py27
-rw-r--r--src/leap/bitmask/vpn/_control.py7
-rw-r--r--src/leap/bitmask/vpn/_management.py14
-rw-r--r--src/leap/bitmask/vpn/eip.py2
-rw-r--r--src/leap/bitmask/vpn/errors.py2
-rw-r--r--src/leap/bitmask/vpn/manager.py13
-rw-r--r--src/leap/bitmask/vpn/process.py7
-rw-r--r--src/leap/bitmask/vpn/service.py91
9 files changed, 109 insertions, 64 deletions
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 <http://www.gnu.org/licenses/>.
"""
-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"