Commit e24eb3f5 authored by Julien Muchembled's avatar Julien Muchembled

INCOMPATIBLE: change registry protocol

- authenticated communications with registered clients
- XML-RPC is dropped
- multi-threaded server
parent 4a8905ef
...@@ -283,8 +283,9 @@ if len(sys.argv) > 1: ...@@ -283,8 +283,9 @@ if len(sys.argv) > 1:
elif self.path == '/tunnel.html': elif self.path == '/tunnel.html':
other = 'route' other = 'route'
gv = registry.Popen(('python', '-c', r"""if 1: gv = registry.Popen(('python', '-c', r"""if 1:
import math, xmlrpclib import math
g = xmlrpclib.ServerProxy('http://localhost/').topology() from re6st.registry import RegistryClient
g = eval(RegistryClient('http://localhost/').topology())
print 'digraph {' print 'digraph {'
a = 2 * math.pi / len(g) a = 2 * math.pi / len(g)
z = 4 z = 4
...@@ -298,7 +299,7 @@ if len(sys.argv) > 1: ...@@ -298,7 +299,7 @@ if len(sys.argv) > 1:
for p in p or (): for p in p or ():
print '"%s" -> "%s";' % (n, title(p)) print '"%s" -> "%s";' % (n, title(p))
print '}' print '}'
"""), stdout=subprocess.PIPE).communicate()[0] """), stdout=subprocess.PIPE, cwd="..").communicate()[0]
if gv: if gv:
svg = subprocess.Popen(('neato', '-Tsvg'), svg = subprocess.Popen(('neato', '-Tsvg'),
stdin=subprocess.PIPE, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
......
#!/usr/bin/python #!/usr/bin/python
import argparse, atexit, errno, os, subprocess, sqlite3, sys, xmlrpclib import argparse, atexit, errno, os, subprocess, sqlite3, sys
from OpenSSL import crypto from OpenSSL import crypto
from re6st import utils from re6st import registry, utils
def create(path, text=None, mode=0666): def create(path, text=None, mode=0666):
fd = os.open(path, os.O_CREAT | os.O_WRONLY | os.O_TRUNC, mode) fd = os.open(path, os.O_CREAT | os.O_WRONLY | os.O_TRUNC, mode)
...@@ -10,6 +10,9 @@ def create(path, text=None, mode=0666): ...@@ -10,6 +10,9 @@ def create(path, text=None, mode=0666):
finally: finally:
os.close(fd) os.close(fd)
def loadCert(pem):
return crypto.load_certificate(crypto.FILETYPE_PEM, pem)
def main(): def main():
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
description="Setup script for re6stnet.", description="Setup script for re6stnet.",
...@@ -47,11 +50,11 @@ def main(): ...@@ -47,11 +50,11 @@ def main():
dh_path = 'dh2048.pem' dh_path = 'dh2048.pem'
# Establish connection with server # Establish connection with server
s = xmlrpclib.ServerProxy(config.registry, allow_none=True) s = registry.RegistryClient(config.registry)
# Get CA # Get CA
ca = s.getCa() ca = s.getCa()
network = utils.networkFromCa(ca) network = utils.networkFromCa(loadCert(ca))
if config.is_needed: if config.is_needed:
route, err = subprocess.Popen(('ip', '-6', '-o', 'route', 'get', route, err = subprocess.Popen(('ip', '-6', '-o', 'route', 'get',
utils.ipFromBin(network)), utils.ipFromBin(network)),
...@@ -72,7 +75,7 @@ def main(): ...@@ -72,7 +75,7 @@ def main():
req = crypto.X509Req() req = crypto.X509Req()
try: try:
with open(cert_path) as f: with open(cert_path) as f:
cert = crypto.load_certificate(crypto.FILETYPE_PEM, f.read()) cert = loadCert(f.read())
components = dict(cert.get_subject().get_components()) components = dict(cert.get_subject().get_components())
components.pop('CN', None) components.pop('CN', None)
except IOError, e: except IOError, e:
...@@ -157,7 +160,7 @@ dh %s ...@@ -157,7 +160,7 @@ dh %s
""" % (config.registry, ca_path, cert_path, key_path, dh_path)) """ % (config.registry, ca_path, cert_path, key_path, dh_path))
print "Sample configuration file created." print "Sample configuration file created."
cn = utils.subnetFromCert(cert) cn = utils.subnetFromCert(loadCert(cert))
subnet = network + utils.binFromSubnet(cn) subnet = network + utils.binFromSubnet(cn)
print "Your subnet: %s/%u (CN=%s)" \ print "Your subnet: %s/%u (CN=%s)" \
% (utils.ipFromBin(subnet), len(subnet), cn) % (utils.ipFromBin(subnet), len(subnet), cn)
......
This diff is collapsed.
import logging, sqlite3, socket, subprocess, xmlrpclib, time import logging, sqlite3, socket, subprocess, time
from urllib import splittype, splithost, splitport from . import utils
import utils
class PeerDB(object): class PeerDB(object):
...@@ -10,7 +9,7 @@ class PeerDB(object): ...@@ -10,7 +9,7 @@ class PeerDB(object):
self._prefix = prefix self._prefix = prefix
self._db_size = db_size self._db_size = db_size
self._key_path = key_path self._key_path = key_path
self._proxy = xmlrpclib.ServerProxy(registry) self._registry = registry
logging.info('Initialize cache ...') logging.info('Initialize cache ...')
self._db = sqlite3.connect(db_path, isolation_level=None) self._db = sqlite3.connect(db_path, isolation_level=None)
...@@ -37,7 +36,7 @@ class PeerDB(object): ...@@ -37,7 +36,7 @@ class PeerDB(object):
retry = 1 retry = 1
while True: while True:
try: try:
a = self._proxy.getPrivateAddress() a = self._registry.getPrivateAddress(self._prefix)
break break
except socket.error, e: except socket.error, e:
logging.warning(e) logging.warning(e)
...@@ -83,16 +82,9 @@ class PeerDB(object): ...@@ -83,16 +82,9 @@ class PeerDB(object):
def getBootstrapPeer(self): def getBootstrapPeer(self):
logging.info('Getting Boot peer...') logging.info('Getting Boot peer...')
try: try:
bootpeer = self._proxy.getBootstrapPeer(self._prefix).data bootpeer = self._registry.getBootstrapPeer(self._prefix)
p = subprocess.Popen( prefix, address = utils.decrypt(self._key_path, bootpeer).split()
('openssl', 'rsautl', '-decrypt', '-inkey', self._key_path), except (socket.error, subprocess.CalledProcessError, ValueError), e:
stdin=subprocess.PIPE, stdout=subprocess.PIPE)
out, err = p.communicate(bootpeer)
if p.returncode:
raise subprocess.CalledProcessError(p.returncode, err)
prefix, address = out.split()
except (socket.error, xmlrpclib.Fault, subprocess.CalledProcessError,
ValueError), e:
logging.warning('Failed to bootstrap (%s)', e) logging.warning('Failed to bootstrap (%s)', e)
else: else:
if prefix != self._prefix: if prefix != self._prefix:
......
This diff is collapsed.
import argparse, errno, logging, os, shlex, signal, socket import argparse, errno, logging, os, shlex, signal, socket
import struct, subprocess, textwrap, threading, time import struct, subprocess, textwrap, threading, time
from OpenSSL import crypto
logging_levels = logging.WARNING, logging.INFO, logging.DEBUG, 5 logging_levels = logging.WARNING, logging.INFO, logging.DEBUG, 5
...@@ -128,11 +127,9 @@ def ipFromBin(ip, suffix=''): ...@@ -128,11 +127,9 @@ def ipFromBin(ip, suffix=''):
struct.pack('>QQ', int(ip[:64], 2), int(ip[64:], 2))) struct.pack('>QQ', int(ip[:64], 2), int(ip[64:], 2)))
def networkFromCa(ca): def networkFromCa(ca):
ca = crypto.load_certificate(crypto.FILETYPE_PEM, ca)
return bin(ca.get_serial_number())[3:] return bin(ca.get_serial_number())[3:]
def subnetFromCert(cert): def subnetFromCert(cert):
cert = crypto.load_certificate(crypto.FILETYPE_PEM, cert)
return cert.get_subject().CN return cert.get_subject().CN
def dump_address(address): def dump_address(address):
...@@ -150,3 +147,27 @@ def parse_address(address_list): ...@@ -150,3 +147,27 @@ def parse_address(address_list):
def binFromSubnet(subnet): def binFromSubnet(subnet):
p, l = subnet.split('/') p, l = subnet.split('/')
return bin(int(p))[2:].rjust(int(l), '0') return bin(int(p))[2:].rjust(int(l), '0')
def decrypt(key_path, data):
p = subprocess.Popen(
('openssl', 'rsautl', '-decrypt', '-inkey', key_path),
stdin=subprocess.PIPE, stdout=subprocess.PIPE)
out, err = p.communicate(data)
if p.returncode:
raise subprocess.CalledProcessError(p.returncode, err)
return out
def encrypt(cert, data):
r, w = os.pipe()
try:
threading.Thread(target=os.write, args=(w, cert)).start()
p = subprocess.Popen(('openssl', 'rsautl', '-encrypt', '-certin',
'-inkey', '/proc/self/fd/%u' % r),
stdin=subprocess.PIPE, stdout=subprocess.PIPE)
out, err = p.communicate(data)
finally:
os.close(r)
os.close(w)
if p.returncode:
raise subprocess.CalledProcessError(p.returncode, err)
return out
...@@ -2,7 +2,9 @@ ...@@ -2,7 +2,9 @@
import atexit, errno, logging, os, select, signal import atexit, errno, logging, os, select, signal
import sqlite3, subprocess, sys, time, traceback import sqlite3, subprocess, sys, time, traceback
from collections import deque from collections import deque
from re6st import plib, utils, db, tunnel from OpenSSL import crypto
from re6st import db, plib, tunnel, utils
from re6st.registry import RegistryClient
def getConfig(): def getConfig():
...@@ -115,9 +117,11 @@ def main(): ...@@ -115,9 +117,11 @@ def main():
# Get arguments # Get arguments
config = getConfig() config = getConfig()
with open(config.ca) as f: with open(config.ca) as f:
network = utils.networkFromCa(f.read()) ca = crypto.load_certificate(crypto.FILETYPE_PEM, f.read())
with open(config.cert) as f: with open(config.cert) as f:
prefix = utils.binFromSubnet(utils.subnetFromCert(f.read())) cert = crypto.load_certificate(crypto.FILETYPE_PEM, f.read())
network = utils.networkFromCa(ca)
prefix = utils.binFromSubnet(utils.subnetFromCert(cert))
config.openvpn_args += ( config.openvpn_args += (
'--ca', config.ca, '--ca', config.ca,
'--cert', config.cert, '--cert', config.cert,
...@@ -228,7 +232,8 @@ def main(): ...@@ -228,7 +232,8 @@ def main():
# Create and open read_only pipe to get server events # Create and open read_only pipe to get server events
r_pipe, write_pipe = os.pipe() r_pipe, write_pipe = os.pipe()
read_pipe = os.fdopen(r_pipe) read_pipe = os.fdopen(r_pipe)
peer_db = db.PeerDB(db_path, config.registry, config.key, prefix) registry = RegistryClient(config.registry, config.key, ca)
peer_db = db.PeerDB(db_path, registry, config.key, prefix)
tunnel_manager = tunnel.TunnelManager(write_pipe, peer_db, tunnel_manager = tunnel.TunnelManager(write_pipe, peer_db,
config.openvpn_args, timeout, config.tunnel_refresh, config.openvpn_args, timeout, config.tunnel_refresh,
config.client_count, config.iface_list, network, prefix, config.client_count, config.iface_list, network, prefix,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment