summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKali Kaneko <kali@leap.se>2017-06-08 15:36:37 -0700
committerKali Kaneko (leap communications) <kali@leap.se>2017-06-09 00:48:40 +0200
commita003e13cec2c44160b46047d0fee8d52dfc6253f (patch)
tree6322f118707e5ce5da435873744024eee9afb3d6
parent6f961fc09dd633d0bcf5397787139c0032e0661e (diff)
[bug] make openvpn and firewall able to launch
with these fixes, I'm able to finally launch openvpn and firewall on osx. :) all that's left for a minimum vpn release is packaging and installing all the helpers in the proper place.
-rw-r--r--src/leap/bitmask/vpn/_control.py10
-rw-r--r--src/leap/bitmask/vpn/fw/firewall.py47
-rwxr-xr-xsrc/leap/bitmask/vpn/fw/osx/bitmask-helper19
-rw-r--r--src/leap/bitmask/vpn/launcher.py27
-rw-r--r--src/leap/bitmask/vpn/launchers/darwin.py7
-rw-r--r--src/leap/bitmask/vpn/process.py20
6 files changed, 85 insertions, 45 deletions
diff --git a/src/leap/bitmask/vpn/_control.py b/src/leap/bitmask/vpn/_control.py
index 74182a9e..bf33b1bc 100644
--- a/src/leap/bitmask/vpn/_control.py
+++ b/src/leap/bitmask/vpn/_control.py
@@ -54,7 +54,7 @@ class VPNControl(object):
args = [self._vpnconfig, self._providerconfig, self._host,
self._port]
- kwargs = {'openvpn_verb': 7, 'remotes': self._remotes,
+ kwargs = {'openvpn_verb': 4, 'remotes': self._remotes,
'restartfun': self.restart}
vpnproc = VPNProcess(*args, **kwargs)
@@ -63,6 +63,11 @@ class VPNControl(object):
vpnproc.stop_if_already_running()
try:
+ vpnproc.preUp()
+ except Exception as e:
+ log.error('Error on vpn pre-up {0!r}'.format(e))
+ raise
+ try:
cmd = vpnproc.getCommand()
except Exception as e:
log.error('Error while getting vpn command... {0!r}'.format(e))
@@ -70,7 +75,8 @@ class VPNControl(object):
env = os.environ
- reactor.spawnProcess(vpnproc, cmd[0], cmd, env)
+ runningproc = reactor.spawnProcess(vpnproc, cmd[0], cmd, env)
+ vpnproc.pid = runningproc.pid
self._vpnproc = vpnproc
# add pollers for status and state
diff --git a/src/leap/bitmask/vpn/fw/firewall.py b/src/leap/bitmask/vpn/fw/firewall.py
index 23bdbd91..dcd956d4 100644
--- a/src/leap/bitmask/vpn/fw/firewall.py
+++ b/src/leap/bitmask/vpn/fw/firewall.py
@@ -25,14 +25,12 @@ import subprocess
from twisted.logger import Logger
-from leap.bitmask.vpn.constants import IS_MAC
+from leap.bitmask.vpn.constants import IS_MAC, IS_LINUX
from leap.common.events import catalog, emit_async
-log = Logger()
-
-
-# TODO -- subclass it for osx/windows, not only for linux.
+from leap.bitmask.vpn.launchers import darwin
+log = Logger()
# A regular user should not run bitmask as root, but we contemplate
# this case for tests inside docker.
@@ -46,7 +44,34 @@ def check_root(cmd):
return cmd
-class FirewallManager(object):
+class _OSXFirewallManager(object):
+ def __init__(self, remotes):
+ self._remotes = list(remotes)
+ self._helper = darwin.HelperCommand()
+
+ def start(self, restart=False):
+ gateways = [gateway for gateway, port in self._remotes]
+ cmd = 'firewall_start %s' % (' '.join(gateways),)
+ self._helper.send(cmd)
+ # TODO parse OK from result
+ return True
+
+ def stop(self):
+ cmd = 'firewall_stop'
+ self._helper.send(cmd)
+ return True
+
+ def is_up(self):
+ # TODO implement!!!
+ return True
+
+ @property
+ def status(self):
+ # TODO implement!!! -- factor out, too
+ return {'status': 'on', 'error': None}
+
+
+class _LinuxFirewallManager(object):
"""
Firewall manager that blocks/unblocks all the internet traffic with some
@@ -100,10 +125,6 @@ class FirewallManager(object):
"""
Tear the firewall down using the privileged wrapper.
"""
- # We don't support Mac so far
- if IS_MAC:
- return True
-
cmd = [self.BITMASK_ROOT, "firewall", "stop"]
cmd = check_root(cmd)
exitCode = subprocess.call(cmd)
@@ -133,3 +154,9 @@ class FirewallManager(object):
status = 'on'
return {'status': status, 'error': None}
+
+
+if IS_LINUX:
+ FirewallManager = _LinuxFirewallManager
+elif IS_MAC:
+ FirewallManager = _OSXFirewallManager
diff --git a/src/leap/bitmask/vpn/fw/osx/bitmask-helper b/src/leap/bitmask/vpn/fw/osx/bitmask-helper
index 68be7dbb..2990219f 100755
--- a/src/leap/bitmask/vpn/fw/osx/bitmask-helper
+++ b/src/leap/bitmask/vpn/fw/osx/bitmask-helper
@@ -2,7 +2,7 @@
# -*- coding: utf-8 -*-
#
# Author: Kali Kaneko
-# Copyright (C) 2015-2016 LEAP Encryption Access Project
+# Copyright (C) 2015-2017 LEAP Encryption Access Project
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -42,11 +42,10 @@ To see the loaded rules:
To test the commands, you can write directly to the unix socket. Remember to
terminate the command properly:
- echo 'firewall_stop/CMD' | socat - UNIX-CONNECT:/tmp/bitmask-helper.socket
+ echo 'firewall_stop/CMD' | socat - UNIX-CONNECT:/tmp/bitmask-helper.socket
"""
import os
-import re
import socket
import signal
import subprocess
@@ -75,7 +74,6 @@ FIXED_FLAGS = [
"--setenv", "LEAPOPENVPN", "1",
"--nobind",
"--client",
- "--dev", "tun",
"--tls-client",
"--remote-cert-tls", "server",
"--management-signal",
@@ -243,14 +241,19 @@ def openvpn_start(*args):
opts += ['--dhcp-option', 'DNS', '10.42.0.1',
'--up', RESOURCES_PATH + 'client.up.sh',
'--down', RESOURCES_PATH + 'client.down.sh']
+ opts += ["--dev", "tun"]
binary = [RESOURCES_PATH + 'openvpn.leap']
-
- syslog.syslog(syslog.LOG_WARNING, ' '.join(binary + opts))
+ cmd = binary + opts
+ #syslog.syslog(syslog.LOG_WARNING, 'LAUNCHING VPN: ' + ' '.join(cmd))
# TODO sanitize options
global openvpn_proc
- openvpn_proc = subprocess.Popen(binary + opts, shell=False)
- syslog.syslog(syslog.LOG_WARNING, "OpenVPN PID: %s" % str(openvpn_proc.pid))
+ openvpn_proc = subprocess.Popen(cmd, shell=False, bufsize=-1)
+ #try:
+ # result = subprocess.check_output(cmd, shell=False, stderr=subprocess.STDOUT)
+ #except Exception as exc:
+ # syslog.syslog(syslog.LOG_WARNING, exc.output)
+ #syslog.syslog(syslog.LOG_WARNING, "OpenVPN PID: %s" % str(openvpn_proc.pid))
def openvpn_stop(sig='TERM'):
diff --git a/src/leap/bitmask/vpn/launcher.py b/src/leap/bitmask/vpn/launcher.py
index f412acef..8ce2660f 100644
--- a/src/leap/bitmask/vpn/launcher.py
+++ b/src/leap/bitmask/vpn/launcher.py
@@ -29,7 +29,7 @@ from twisted.logger import Logger
from abc import ABCMeta, abstractmethod
from functools import partial
-from leap.bitmask.vpn.constants import IS_LINUX
+from leap.bitmask.vpn.constants import IS_LINUX, IS_MAC
from leap.bitmask.vpn.utils import force_eval
@@ -186,16 +186,6 @@ class VPNLauncher(object):
:return: A VPN command ready to be launched.
:rtype: list
"""
- # leap_assert_type(vpnconfig, VPNConfig)
- # leap_assert_type(providerconfig, ProviderConfig)
-
- # XXX this still has to be changed on osx and windows accordingly
- # kwargs = {}
- # openvpn_possibilities = which(kls.OPENVPN_BIN, **kwargs)
- # if not openvpn_possibilities:
- # raise OpenVPNNotFoundException()
- # openvpn = first(openvpn_possibilities)
- # -----------------------------------------
openvpn_path = force_eval(kls.OPENVPN_BIN_PATH)
if not os.path.isfile(openvpn_path):
@@ -215,7 +205,6 @@ class VPNLauncher(object):
if openvpn_verb is not None:
args += ['--verb', '%d' % (openvpn_verb,)]
- # gateways = kls.get_gateways(vpnconfig, providerconfig)
gateways = remotes
for ip, port in gateways:
@@ -224,7 +213,6 @@ class VPNLauncher(object):
args += [
'--client',
'--dev', ' tun',
- '--persist-key',
'--tls-client',
'--remote-cert-tls',
'server'
@@ -269,13 +257,12 @@ class VPNLauncher(object):
'--ca', providerconfig.get_ca_cert_path()
]
- args += [
- '--ping', '5',
- '--ping-restart', '10']
-
- args += [
- '--persist-key',
- '--persist-local-ip', '--persist-remote-ip']
+ if not IS_MAC:
+ args += [
+ '--ping', '5',
+ '--ping-restart', '10',
+ '--persist-key',
+ '--persist-local-ip', '--persist-remote-ip']
command_and_args = [openvpn_path] + args
return command_and_args
diff --git a/src/leap/bitmask/vpn/launchers/darwin.py b/src/leap/bitmask/vpn/launchers/darwin.py
index 3d64c857..80cacc4b 100644
--- a/src/leap/bitmask/vpn/launchers/darwin.py
+++ b/src/leap/bitmask/vpn/launchers/darwin.py
@@ -119,8 +119,8 @@ class DarwinVPNLauncher(VPNLauncher):
return os.path.join(resources_path, "bitmask.tiff")
@classmethod
- def get_vpn_command(kls, eipconfig, providerconfig, socket_host,
- socket_port="unix", openvpn_verb=1):
+ def get_vpn_command(kls, vpnconfig, providerconfig, socket_host,
+ remotes, socket_port="unix", openvpn_verb=1):
"""
Returns the OSX implementation for the vpn launching command.
@@ -149,7 +149,8 @@ class DarwinVPNLauncher(VPNLauncher):
# we use `super` in order to send the class to use
command = super(DarwinVPNLauncher, kls).get_vpn_command(
- eipconfig, providerconfig, socket_host, socket_port, openvpn_verb)
+ vpnconfig, providerconfig, socket_host, socket_port, remotes,
+ openvpn_verb)
command.extend(['--setenv', "LEAPUSER", getpass.getuser()])
return command
diff --git a/src/leap/bitmask/vpn/process.py b/src/leap/bitmask/vpn/process.py
index 895cd0a2..844cd0ff 100644
--- a/src/leap/bitmask/vpn/process.py
+++ b/src/leap/bitmask/vpn/process.py
@@ -50,6 +50,10 @@ class _VPNProcess(protocol.ProcessProtocol, _management.VPNManagement):
log = Logger()
+ # HACK - reactor is expected to set this up when the process is spawned.
+ # should try to get it from within this class.
+ pid = None
+
# TODO do we really need the vpnconfig/providerconfig objects in here???
def __init__(self, vpnconfig, providerconfig, socket_host, socket_port,
@@ -183,6 +187,9 @@ class _VPNProcess(protocol.ProcessProtocol, _management.VPNManagement):
# launcher
+ def preUp(self):
+ pass
+
def getCommand(self):
"""
Gets the vpn command from the aproppriate launcher.
@@ -252,11 +259,19 @@ elif IS_MAC:
This is a workaround to allow the state machine to be notified when
openvpn process is spawned by the privileged helper.
"""
+
def setupHelper(self):
+ # TODO use get_vpn_launcher instead
self.helper = darwin.HelperCommand()
+ def preUp(self):
+ self.setupHelper()
+ cmd = self.getVPNCommand()
+ self.helper.send('openvpn_start %s' % ' '.join(cmd))
+
def connectionMade(self):
- VPNProcess.connectionMade(self)
+ super(_VPNProcess, self).connectionMade()
+ self.setupHelper()
reactor.callLater(2, self.registerPID)
def registerPID(self):
@@ -268,7 +283,8 @@ elif IS_MAC:
self.helper.send(cmd)
def getVPNCommand(self):
- return VPNProcess.getCommand(self)
+ vpncmd = _VPNProcess.getCommand(self)
+ return vpncmd
def getCommand(self):
canary = '''import sys, signal, time