Skip to content
Snippets Groups Projects
Commit a885a2a8 authored by Antoine Millet's avatar Antoine Millet
Browse files

Added VpnProtocol.

parent 9659bfe9
No related branches found
No related tags found
No related merge requests found
......@@ -82,5 +82,6 @@ class Protocol(object):
from sjrpc.core.protocols.rpc import RpcProtocol
from sjrpc.core.protocols.tunnel import TunnelProtocol
from sjrpc.core.protocols.vpn import VpnProtocol
__all__ = ['Protocol', 'RpcProtocol', 'TunnelProtocol']
__all__ = ['Protocol', 'RpcProtocol', 'TunnelProtocol', 'VpnProtocol']
from __future__ import absolute_import
import os
import struct
import fcntl
from sjrpc.core.protocols import TunnelProtocol
__all__ = ['VpnProtocol']
class _FileSocket(object):
'''
A fake Socket interface for files.
'''
def __init__(self, file_):
self.file = file_
def recv(self, size):
self.file.read(size)
def send(self, data):
self.file.write(data)
return len(data)
def fileno(self):
return self.file.fileno()
def setblocking(self, blocking):
if not blocking:
# Disable blocking mode on devzero:
current_flags = fcntl.fcntl(self.fileno(), fcntl.F_GETFL)
fcntl.fcntl(self.fileno(), fcntl.F_SETFL, current_flags | os.O_NONBLOCK)
else:
raise NotImplementedError('Not implemented')
class VpnProtocol(TunnelProtocol):
'''
A VPN protocol which spawn a network interface and tunnel all its traffic
through the sjRpc tunnel.
:param inherited: All options (except endpoint) are inherited from
:class:`TunnelProtocol`.
:param tun_prefix: the prefix name of the spawned interface
:param tun_mode: which can be VpnProtocol.IFF_TUN or VpnProtocol.IFF_TAP
The user starting the sjRpc process must have the CAP_NET_ADMIN capability,
by default, only root have this capability.
.. warning::
This protocol is a proof of concept and should not be used in production
software.
'''
# Taken from linux/if_tun.h:
TUNSETIFF = 0x400454ca
IFF_TUN = 0x0001
IFF_TAP = 0x0002
# Default values:
DEFAULT_TUN_PREFIX = 'tun'
DEFAULT_TUN_MODE = IFF_TAP
def __init__(self, *args, **kwargs):
tun_prefix = kwargs.pop('tun_prefix', VpnProtocol.DEFAULT_TUN_PREFIX)
tun_mode = kwargs.pop('tun_mode', VpnProtocol.DEFAULT_TUN_MODE)
ftun = open('/dev/net/tun', 'r+b')
# Create the tunnel and get its final name:
create_tun_arg = struct.pack('16sH', tun_prefix + '%d', tun_mode)
tun = fcntl.ioctl(ftun, VpnProtocol.TUNSETIFF, create_tun_arg)
self.tun_name = tun[:16].rstrip('\0')
kwargs['endpoint'] = _FileSocket(ftun)
super(VpnProtocol, self).__init__(*args, **kwargs)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment