Commit 3d7d1bcb authored by Joanne Hugé's avatar Joanne Hugé Committed by Tom Niget

python2 to python3: manual fixes

parent 76b72be3
...@@ -11,6 +11,6 @@ Architecture: all ...@@ -11,6 +11,6 @@ Architecture: all
Depends: ${misc:Depends}, ${python:Depends}, python-pkg-resources, python-openssl (>= 0.13), openvpn (>= 2.4), openpvn (<< 2.5~), babeld (= v1.12.1-nxd3), iproute2 | iproute, openssl Depends: ${misc:Depends}, ${python:Depends}, python-pkg-resources, python-openssl (>= 0.13), openvpn (>= 2.4), openpvn (<< 2.5~), babeld (= v1.12.1-nxd3), iproute2 | iproute, openssl
Recommends: ${python:Recommends}, logrotate Recommends: ${python:Recommends}, logrotate
Suggests: ${python:Suggests}, ndisc6 Suggests: ${python:Suggests}, ndisc6
Conflicts: re6st-node Conflicts: re6st-node-py3
Replaces: re6st-node Replaces: re6st-node-py3
Description: resilient, scalable, IPv6 network application Description: resilient, scalable, IPv6 network application
#!/usr/bin/python2 #!/usr/bin/python
import argparse, math, nemu, os, re, signal import argparse, math, nemu, os, re, signal
import socket, sqlite3, subprocess, sys, time, weakref import socket, sqlite3, subprocess, sys, time, weakref
from collections import defaultdict from collections import defaultdict
......
import json, logging, os, sqlite3, socket, subprocess, sys, time, zlib import base64, json, logging, os, sqlite3, socket, subprocess, sys, time, zlib
from itertools import chain from itertools import chain
from .registry import RegistryClient from .registry import RegistryClient
from . import utils, version, x509 from . import utils, version, x509
...@@ -65,7 +65,7 @@ class Cache(object): ...@@ -65,7 +65,7 @@ class Cache(object):
@staticmethod @staticmethod
def _selectConfig(execute): # BBB: blob def _selectConfig(execute): # BBB: blob
return ((k, str(v) if type(v) is buffer else v) return ((k, str(v) if type(v) is memoryview else v)
for k, v in execute("SELECT * FROM config")) for k, v in execute("SELECT * FROM config"))
def _loadConfig(self, config): def _loadConfig(self, config):
...@@ -91,15 +91,15 @@ class Cache(object): ...@@ -91,15 +91,15 @@ class Cache(object):
# TODO: When possible, the registry should be queried via the re6st. # TODO: When possible, the registry should be queried via the re6st.
x = json.loads(zlib.decompress( x = json.loads(zlib.decompress(
self._registry.getNetworkConfig(self._prefix))) self._registry.getNetworkConfig(self._prefix)))
base64 = x.pop('', ()) base64_list = x.pop('', ())
config = {} config = {}
for k, v in x.items(): for k, v in x.items():
k = str(k) k = str(k)
if k.startswith('babel_hmac'): if k.startswith('babel_hmac'):
if v: if v:
v = self._decrypt(v.decode('base64')) v = self._decrypt(base64.b64decode(v))
elif k in base64: elif k in base64_list:
v = v.decode('base64') v = base64.b64decode(v)
elif isinstance(v, (list, dict)): elif isinstance(v, (list, dict)):
k += ':json' k += ':json'
v = json.dumps(v) v = json.dumps(v)
...@@ -131,7 +131,7 @@ class Cache(object): ...@@ -131,7 +131,7 @@ class Cache(object):
# BBB: Use buffer because of http://bugs.python.org/issue13676 # BBB: Use buffer because of http://bugs.python.org/issue13676
# on Python 2.6 # on Python 2.6
db.executemany("INSERT OR REPLACE INTO config VALUES(?,?)", db.executemany("INSERT OR REPLACE INTO config VALUES(?,?)",
((k, buffer(v) if k in base64 or ((k, memoryview(v) if k in base64_list or
k.startswith('babel_hmac') else v) k.startswith('babel_hmac') else v)
for k, v in config.items())) for k, v in config.items()))
self._loadConfig(iter(config.items())) self._loadConfig(iter(config.items()))
...@@ -229,7 +229,9 @@ class Cache(object): ...@@ -229,7 +229,9 @@ class Cache(object):
" WHERE prefix=peer AND prefix!=? AND try=?" " WHERE prefix=peer AND prefix!=? AND try=?"
def getPeerList(self, failed=0, __sql=_get_peer_sql % "prefix, address" def getPeerList(self, failed=0, __sql=_get_peer_sql % "prefix, address"
+ " ORDER BY RANDOM()"): + " ORDER BY RANDOM()"):
return self._db.execute(__sql, (self._prefix, failed)) #return self._db.execute(__sql, (self._prefix, failed))
r = self._db.execute(__sql, (self._prefix, failed))
return r
def getPeerCount(self, failed=0, __sql=_get_peer_sql % "COUNT(*)"): def getPeerCount(self, failed=0, __sql=_get_peer_sql % "COUNT(*)"):
return self._db.execute(__sql, (self._prefix, failed)).next()[0] return self._db.execute(__sql, (self._prefix, failed)).next()[0]
...@@ -237,7 +239,7 @@ class Cache(object): ...@@ -237,7 +239,7 @@ class Cache(object):
logging.info('Getting Boot peer...') logging.info('Getting Boot peer...')
try: try:
bootpeer = self._registry.getBootstrapPeer(self._prefix) bootpeer = self._registry.getBootstrapPeer(self._prefix)
prefix, address = self._decrypt(bootpeer).split() prefix, address = self._decrypt(bootpeer).decode().split()
except (socket.error, subprocess.CalledProcessError, ValueError) as e: except (socket.error, subprocess.CalledProcessError, ValueError) as e:
logging.warning('Failed to bootstrap (%s)', logging.warning('Failed to bootstrap (%s)',
e if bootpeer else 'no peer returned') e if bootpeer else 'no peer returned')
...@@ -273,6 +275,6 @@ class Cache(object): ...@@ -273,6 +275,6 @@ class Cache(object):
def getCountry(self, ip): def getCountry(self, ip):
try: try:
return self._registry.getCountry(self._prefix, ip) return self._registry.getCountry(self._prefix, ip).decode()
except socket.error as e: except socket.error as e:
logging.warning('Failed to get country (%s)', ip) logging.warning('Failed to get country (%s)', ip)
...@@ -6,7 +6,7 @@ if 're6st' not in sys.modules: ...@@ -6,7 +6,7 @@ if 're6st' not in sys.modules:
sys.path[0] = os.path.dirname(os.path.dirname(sys.path[0])) sys.path[0] = os.path.dirname(os.path.dirname(sys.path[0]))
from re6st import registry, utils, x509 from re6st import registry, utils, x509
def create(path, text=None, mode=0666): def create(path, text=None, mode=0o666):
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)
try: try:
os.write(fd, text) os.write(fd, text)
...@@ -68,12 +68,12 @@ def main(): ...@@ -68,12 +68,12 @@ def main():
fingerprint = binascii.a2b_hex(fingerprint) fingerprint = binascii.a2b_hex(fingerprint)
if hashlib.new(alg).digest_size != len(fingerprint): if hashlib.new(alg).digest_size != len(fingerprint):
raise ValueError("wrong size") raise ValueError("wrong size")
except StandardError, e: except Exception as e:
parser.error("invalid fingerprint: %s" % e) parser.error("invalid fingerprint: %s" % e)
if x509.fingerprint(ca, alg).digest() != fingerprint: if x509.fingerprint(ca, alg).digest() != fingerprint:
sys.exit("CA fingerprint doesn't match") sys.exit("CA fingerprint doesn't match")
else: else:
print "WARNING: it is strongly recommended to use --fingerprint option." print("WARNING: it is strongly recommended to use --fingerprint option.")
network = x509.networkFromCa(ca) network = x509.networkFromCa(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',
...@@ -92,16 +92,17 @@ def main(): ...@@ -92,16 +92,17 @@ def main():
with open(cert_path) as f: with open(cert_path) as f:
cert = loadCert(f.read()) cert = loadCert(f.read())
components = dict(cert.get_subject().get_components()) components = dict(cert.get_subject().get_components())
components = {k.decode(): v for k, v in components.items()}
for k in reserved: for k in reserved:
components.pop(k, None) components.pop(k, None)
except IOError, e: except IOError as e:
if e.errno != errno.ENOENT: if e.errno != errno.ENOENT:
raise raise
components = {} components = {}
if config.req: if config.req:
components.update(config.req) components.update(config.req)
subj = req.get_subject() subj = req.get_subject()
for k, v in list(components.items()): for k, v in components.items():
if k in reserved: if k in reserved:
sys.exit(k + " field is reserved.") sys.exit(k + " field is reserved.")
if v: if v:
...@@ -116,26 +117,26 @@ def main(): ...@@ -116,26 +117,26 @@ def main():
token = '' token = ''
elif not token: elif not token:
if not config.email: if not config.email:
config.email = eval(input('Please enter your email address: ')) config.email = input('Please enter your email address: ')
s.requestToken(config.email) s.requestToken(config.email)
token_advice = "Use --token to retry without asking a new token\n" token_advice = "Use --token to retry without asking a new token\n"
while not token: while not token:
token = eval(input('Please enter your token: ')) token = input('Please enter your token: ')
try: try:
with open(key_path) as f: with open(key_path) as f:
pkey = crypto.load_privatekey(crypto.FILETYPE_PEM, f.read()) pkey = crypto.load_privatekey(crypto.FILETYPE_PEM, f.read())
key = None key = None
print "Reusing existing key." print("Reusing existing key.")
except IOError, e: except IOError as e:
if e.errno != errno.ENOENT: if e.errno != errno.ENOENT:
raise raise
bits = ca.get_pubkey().bits() bits = ca.get_pubkey().bits()
print(("Generating %s-bit key ..." % bits)) print("Generating %s-bit key ..." % bits)
pkey = crypto.PKey() pkey = crypto.PKey()
pkey.generate_key(crypto.TYPE_RSA, bits) pkey.generate_key(crypto.TYPE_RSA, bits)
key = crypto.dump_privatekey(crypto.FILETYPE_PEM, pkey) key = crypto.dump_privatekey(crypto.FILETYPE_PEM, pkey)
create(key_path, key, 0600) create(key_path, key, 0o600)
req.set_pubkey(pkey) req.set_pubkey(pkey)
req.sign(pkey, 'sha512') req.sign(pkey, 'sha512')
...@@ -143,8 +144,8 @@ def main(): ...@@ -143,8 +144,8 @@ def main():
# First make sure we can open certificate file for writing, # First make sure we can open certificate file for writing,
# to avoid using our token for nothing. # to avoid using our token for nothing.
cert_fd = os.open(cert_path, os.O_CREAT | os.O_WRONLY, 0666) cert_fd = os.open(cert_path, os.O_CREAT | os.O_WRONLY, 0o666)
print "Requesting certificate ..." print("Requesting certificate ...")
if config.location: if config.location:
cert = s.requestCertificate(token, req, location=config.location) cert = s.requestCertificate(token, req, location=config.location)
else: else:
...@@ -173,7 +174,7 @@ def main(): ...@@ -173,7 +174,7 @@ def main():
key_path))) key_path)))
if not os.path.lexists(conf_path): if not os.path.lexists(conf_path):
create(conf_path, """\ create(conf_path, ("""\
registry %s registry %s
ca %s ca %s
cert %s cert %s
...@@ -188,13 +189,13 @@ key %s ...@@ -188,13 +189,13 @@ key %s
#O3 #O3
""" % (config.registry, ca_path, cert_path, key_path, """ % (config.registry, ca_path, cert_path, key_path,
('country ' + config.location.split(',', 1)[0]) \ ('country ' + config.location.split(',', 1)[0]) \
if config.location else '')) if config.location else '')).encode())
print "Sample configuration file created." print("Sample configuration file created.")
cn = x509.subnetFromCert(cert) cn = x509.subnetFromCert(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))
if __name__ == "__main__": if __name__ == "__main__":
main() main()
...@@ -53,11 +53,11 @@ class String(object): ...@@ -53,11 +53,11 @@ class String(object):
@staticmethod @staticmethod
def encode(buffer, value): def encode(buffer, value):
buffer += value + "\0" buffer += value + b'\x00'
@staticmethod @staticmethod
def decode(buffer, offset=0): def decode(buffer, offset=0):
i = buffer.index("\0", offset) i = buffer.index(0, offset)
return i + 1, buffer[offset:i] return i + 1, buffer[offset:i]
...@@ -69,7 +69,7 @@ class Buffer(object): ...@@ -69,7 +69,7 @@ class Buffer(object):
def __iadd__(self, value): def __iadd__(self, value):
self._buf += value self._buf.extend(value)
return self return self
def __len__(self): def __len__(self):
...@@ -104,21 +104,6 @@ class Buffer(object): ...@@ -104,21 +104,6 @@ class Buffer(object):
self._seek(r) self._seek(r)
return value return value
try: # BBB: Python < 2.7.4 (http://bugs.python.org/issue10212)
uint16.unpack_from(bytearray(uint16.size))
except TypeError:
def unpack_from(self, struct):
r = self._r
x = r + struct.size
value = struct.unpack(buffer(self._buf)[r:x])
self._seek(x)
return value
def decode(self, decode):
r = self._r
size, value = decode(buffer(self._buf)[r:])
self._seek(r + size)
return value
# writing # writing
def send(self, socket, *args): def send(self, socket, *args):
...@@ -149,7 +134,7 @@ class Packet(object): ...@@ -149,7 +134,7 @@ class Packet(object):
logging.trace('send %s%r', self.__class__.__name__, logging.trace('send %s%r', self.__class__.__name__,
(self.id,) + self.args) (self.id,) + self.args)
offset = len(buffer) offset = len(buffer)
buffer += '\0' * header.size buffer += b'\x00' * header.size
r = self.request r = self.request
if isinstance(r, Struct): if isinstance(r, Struct):
r.encode(buffer, self.args) r.encode(buffer, self.args)
...@@ -209,7 +194,7 @@ class Babel(object): ...@@ -209,7 +194,7 @@ class Babel(object):
except socket.error as e: except socket.error as e:
logging.debug("Can't connect to %r (%r)", self.socket_path, e) logging.debug("Can't connect to %r (%r)", self.socket_path, e)
return e return e
s.send("\1") s.send(b'\x01')
s.setblocking(0) s.setblocking(0)
del self.select del self.select
self.socket = s self.socket = s
...@@ -269,7 +254,7 @@ class Babel(object): ...@@ -269,7 +254,7 @@ class Babel(object):
a = len(self.network) a = len(self.network)
for route in routes: for route in routes:
assert route.flags & 1, route # installed assert route.flags & 1, route # installed
if route.prefix.startswith('\0\0\0\0\0\0\0\0\0\0\xff\xff'): if route.prefix.startswith(b'\0\0\0\0\0\0\0\0\0\0\xff\xff'):
continue continue
assert route.neigh_address == route.nexthop, route assert route.neigh_address == route.nexthop, route
address = route.neigh_address, route.ifindex address = route.neigh_address, route.ifindex
......
#!/usr/bin/python2 -S #!/usr/bin/python -S
import os, sys import os, sys
script_type = os.environ['script_type'] script_type = os.environ['script_type']
...@@ -13,5 +13,7 @@ if script_type == 'up': ...@@ -13,5 +13,7 @@ if script_type == 'up':
if script_type == 'route-up': if script_type == 'route-up':
import time import time
with open('/opt/openvpn_route_up.log', 'w+') as f:
f.write(repr(sys.argv))
os.write(int(sys.argv[1]), repr((os.environ['common_name'], time.time(), os.write(int(sys.argv[1]), repr((os.environ['common_name'], time.time(),
int(os.environ['tls_serial_0']), os.environ['OPENVPN_external_ip']))) int(os.environ['tls_serial_0']), os.environ['OPENVPN_external_ip'])).encode())
#!/usr/bin/python2 -S #!/usr/bin/python -S
import os, sys import os, sys
script_type = os.environ['script_type'] script_type = os.environ['script_type']
...@@ -10,7 +10,7 @@ os.write(fd, repr((script_type, (os.environ['common_name'], os.environ['dev'], ...@@ -10,7 +10,7 @@ os.write(fd, repr((script_type, (os.environ['common_name'], os.environ['dev'],
int(os.environ['tls_serial_0']), external_ip)))) int(os.environ['tls_serial_0']), external_ip))))
if script_type == 'client-connect': if script_type == 'client-connect':
if os.read(fd, 1) == '\0': if os.read(fd, 1) == b'\x00':
sys.exit(1) sys.exit(1)
# Send client its external ip address # Send client its external ip address
with open(sys.argv[2], 'w') as f: with open(sys.argv[2], 'w') as f:
......
...@@ -43,7 +43,7 @@ def server(iface, max_clients, dh_path, fd, port, proto, encrypt, *args, **kw): ...@@ -43,7 +43,7 @@ def server(iface, max_clients, dh_path, fd, port, proto, encrypt, *args, **kw):
'--max-clients', str(max_clients), '--max-clients', str(max_clients),
'--port', str(port), '--port', str(port),
'--proto', proto, '--proto', proto,
*args, **kw) *args, pass_fds=[fd], **kw)
def client(iface, address_list, encrypt, *args, **kw): def client(iface, address_list, encrypt, *args, **kw):
......
...@@ -27,7 +27,7 @@ from http.server import HTTPServer, BaseHTTPRequestHandler ...@@ -27,7 +27,7 @@ from http.server import HTTPServer, BaseHTTPRequestHandler
from email.mime.text import MIMEText from email.mime.text import MIMEText
from operator import itemgetter from operator import itemgetter
from OpenSSL import crypto from OpenSSL import crypto
from urllib.parse import splittype, splithost, unquote, urlencode from urllib.parse import urlparse, unquote, urlencode
from . import ctl, tunnel, utils, version, x509 from . import ctl, tunnel, utils, version, x509
HMAC_HEADER = "Re6stHMAC" HMAC_HEADER = "Re6stHMAC"
...@@ -69,7 +69,7 @@ class RegistryServer(object): ...@@ -69,7 +69,7 @@ class RegistryServer(object):
# Parse community file # Parse community file
self.community_map = {} self.community_map = {}
if config.community: if config.community:
with open(config.community) as x: with open(config.community) as x:
for x in x: for x in x:
x = x.strip() x = x.strip()
...@@ -91,7 +91,7 @@ class RegistryServer(object): ...@@ -91,7 +91,7 @@ class RegistryServer(object):
"name TEXT PRIMARY KEY NOT NULL", "name TEXT PRIMARY KEY NOT NULL",
"value") "value")
self.prefix = self.getConfig("prefix", None) self.prefix = self.getConfig("prefix", None)
self.version = str(self.getConfig("version", "\0")) # BBB: blob self.version = str(self.getConfig("version", b'\x00')) # BBB: blob
utils.sqliteCreateTable(self.db, "token", utils.sqliteCreateTable(self.db, "token",
"token TEXT PRIMARY KEY NOT NULL", "token TEXT PRIMARY KEY NOT NULL",
"email TEXT NOT NULL", "email TEXT NOT NULL",
...@@ -184,18 +184,16 @@ class RegistryServer(object): ...@@ -184,18 +184,16 @@ class RegistryServer(object):
config = json.dumps(kw, sort_keys=True) config = json.dumps(kw, sort_keys=True)
if config != self.getConfig('last_config', None): if config != self.getConfig('last_config', None):
self.increaseVersion() self.increaseVersion()
# BBB: Use buffer because of http://bugs.python.org/issue13676 self.setConfig('version', self.version)
# on Python 2.6
self.setConfig('version', buffer(self.version))
self.setConfig('last_config', config) self.setConfig('last_config', config)
self.sendto(self.prefix, 0) self.sendto(self.prefix, 0)
# The following entry lists values that are base64-encoded. # The following entry lists values that are base64-encoded.
kw[''] = 'version', kw[''] = 'version',
kw['version'] = self.version.encode('base64') kw['version'] = base64.b64encode(self.version)
self.network_config = kw self.network_config = kw
def increaseVersion(self): def increaseVersion(self):
x = utils.packInteger(1 + utils.unpackInteger(self.version)[0]) x = utils.packInteger(1 + utils.unpackInteger(self.version)[0:1])
self.version = x + self.cert.sign(x) self.version = x + self.cert.sign(x)
def sendto(self, prefix, code): def sendto(self, prefix, code):
...@@ -203,12 +201,12 @@ class RegistryServer(object): ...@@ -203,12 +201,12 @@ class RegistryServer(object):
def recv(self, code): def recv(self, code):
try: try:
prefix, msg = self.sock.recv(1<<16).split('\0', 1) prefix, msg = self.sock.recv(1<<16).split(b'\x00', 1)
int(prefix, 2) int(prefix, 2)
except ValueError: except ValueError:
pass pass
else: else:
if msg and ord(msg[0]) == code: if msg and msg[0:1] == code:
return prefix, msg[1:] return prefix, msg[1:]
return None, None return None, None
...@@ -293,7 +291,7 @@ class RegistryServer(object): ...@@ -293,7 +291,7 @@ class RegistryServer(object):
with self.lock: with self.lock:
session = self.sessions[key] session = self.sessions[key]
for key, protocol in session: for key, protocol in session:
if h == hmac.HMAC(key, request.path, hashlib.sha1).digest(): if h == hmac.HMAC(key, request.path.encode(), hashlib.sha1).digest():
break break
else: else:
raise Exception("Wrong HMAC") raise Exception("Wrong HMAC")
...@@ -349,14 +347,14 @@ class RegistryServer(object): ...@@ -349,14 +347,14 @@ class RegistryServer(object):
assert self.lock.locked() assert self.lock.locked()
return self.db.execute("SELECT cert FROM cert" return self.db.execute("SELECT cert FROM cert"
" WHERE prefix=? AND cert IS NOT NULL", " WHERE prefix=? AND cert IS NOT NULL",
(client_prefix,)).next()[0] (client_prefix,)).fetchone()[0]
@rpc_private @rpc_private
def isToken(self, token): def isToken(self, token):
with self.lock: with self.lock:
if self.db.execute("SELECT 1 FROM token WHERE token = ?", if self.db.execute("SELECT 1 FROM token WHERE token = ?",
(token,)).fetchone(): (token,)).fetchone():
return "1" return b"1"
@rpc_private @rpc_private
def deleteToken(self, token): def deleteToken(self, token):
...@@ -595,7 +593,7 @@ class RegistryServer(object): ...@@ -595,7 +593,7 @@ class RegistryServer(object):
hmac = [self.getConfig(k, None) for k in BABEL_HMAC] hmac = [self.getConfig(k, None) for k in BABEL_HMAC]
for i, v in enumerate(v for v in hmac if v is not None): for i, v in enumerate(v for v in hmac if v is not None):
config[('babel_hmac_sign', 'babel_hmac_accept')[i]] = \ config[('babel_hmac_sign', 'babel_hmac_accept')[i]] = \
v and x509.encrypt(cert, v).encode('base64') v and base64.b64encode(x509.encrypt(cert, v))
return zlib.compress(json.dumps(config)) return zlib.compress(json.dumps(config))
def _queryAddress(self, peer): def _queryAddress(self, peer):
...@@ -615,7 +613,7 @@ class RegistryServer(object): ...@@ -615,7 +613,7 @@ class RegistryServer(object):
@rpc @rpc
def getCountry(self, cn, address): def getCountry(self, cn, address):
country = self._geoiplookup(address)[0] country = self._geoiplookup(address)[0]
return None if country == '*' else country return None if country == '*' else country.encode()
@rpc @rpc
def getBootstrapPeer(self, cn): def getBootstrapPeer(self, cn):
...@@ -673,7 +671,7 @@ class RegistryServer(object): ...@@ -673,7 +671,7 @@ class RegistryServer(object):
def newHMAC(self, i, key=None): def newHMAC(self, i, key=None):
if key is None: if key is None:
key = buffer(os.urandom(16)) key = os.urandom(16)
self.setConfig(BABEL_HMAC[i], key) self.setConfig(BABEL_HMAC[i], key)
def delHMAC(self, i): def delHMAC(self, i):
...@@ -696,10 +694,10 @@ class RegistryServer(object): ...@@ -696,10 +694,10 @@ class RegistryServer(object):
else: else:
# Initialization of HMAC on the network # Initialization of HMAC on the network
self.newHMAC(1) self.newHMAC(1)
self.newHMAC(2, '') self.newHMAC(2, b'')
self.increaseVersion() self.increaseVersion()
self.setConfig('version', buffer(self.version)) self.setConfig('version', self.version)
self.network_config['version'] = self.version.encode('base64') self.network_config['version'] = base64.b64encode(self.version)
self.sendto(self.prefix, 0) self.sendto(self.prefix, 0)
@rpc_private @rpc_private
...@@ -736,9 +734,9 @@ class RegistryServer(object): ...@@ -736,9 +734,9 @@ class RegistryServer(object):
return return
logging.info("%s %s", email, peer) logging.info("%s %s", email, peer)
with self.lock: with self.lock:
msg = self._queryAddress(peer) msg = self._queryAddress(peer).decode()
if msg: if msg:
return msg.split(',')[0] return msg.split(',')[0].encode()
@rpc_private @rpc_private
def versions(self): def versions(self):
...@@ -805,8 +803,8 @@ class RegistryClient(object): ...@@ -805,8 +803,8 @@ class RegistryClient(object):
def __init__(self, url, cert=None, auto_close=True): def __init__(self, url, cert=None, auto_close=True):
self.cert = cert self.cert = cert
self.auto_close = auto_close self.auto_close = auto_close
scheme, host = splittype(url) url_parsed = urlparse(url)
host, path = splithost(host) scheme, host, path = url_parsed.scheme, url_parsed.netloc, url_parsed.path
self._conn = dict(http=http.client.HTTPConnection, self._conn = dict(http=http.client.HTTPConnection,
https=http.client.HTTPSConnection, https=http.client.HTTPSConnection,
)[scheme](unquote(host), timeout=60) )[scheme](unquote(host), timeout=60)
...@@ -834,7 +832,7 @@ class RegistryClient(object): ...@@ -834,7 +832,7 @@ class RegistryClient(object):
n = len(h) // 2 n = len(h) // 2
self.cert.verify(h[n:], h[:n]) self.cert.verify(h[n:], h[:n])
key = self.cert.decrypt(h[:n]) key = self.cert.decrypt(h[:n])
h = hmac.HMAC(key, query, hashlib.sha1).digest() h = hmac.HMAC(key, query.encode(), hashlib.sha1).digest()
key = hashlib.sha1(key).digest() key = hashlib.sha1(key).digest()
self._hmac = hashlib.sha1(key).digest() self._hmac = hashlib.sha1(key).digest()
else: else:
......
...@@ -72,7 +72,7 @@ class TestConf(unittest.TestCase): ...@@ -72,7 +72,7 @@ class TestConf(unittest.TestCase):
# go back to original dir # go back to original dir
os.chdir(self.origin_dir) os.chdir(self.origin_dir)
@patch("__builtin__.raw_input") @patch("builtins.input")
def test_basic(self, mock_raw_input): def test_basic(self, mock_raw_input):
""" go through all the step """ go through all the step
getCa, requestToken, requestCertificate getCa, requestToken, requestCertificate
......
...@@ -146,13 +146,13 @@ class TestRegistryServer(unittest.TestCase): ...@@ -146,13 +146,13 @@ class TestRegistryServer(unittest.TestCase):
params = {"cn" : prefix, "a" : 1, "b" : 2} params = {"cn" : prefix, "a" : 1, "b" : 2}
func.getcallargs.return_value = params func.getcallargs.return_value = params
del func._private del func._private
func.return_value = result = "this_is_a_result" func.return_value = result = b"this_is_a_result"
key = "this_is_a_key" key = b"this_is_a_key"
self.server.sessions[prefix] = [(key, protocol)] self.server.sessions[prefix] = [(key, protocol)]
request = Mock() request = Mock()
request.path = "/func?a=1&b=2&cn=0000000011111111" request.path = "/func?a=1&b=2&cn=0000000011111111"
request.headers = {registry.HMAC_HEADER: base64.b64encode( request.headers = {registry.HMAC_HEADER: base64.b64encode(
hmac.HMAC(key, request.path, hashlib.sha1).digest())} hmac.HMAC(key, request.path.encode(), hashlib.sha1).digest())}
self.server.handle_request(request, method, params) self.server.handle_request(request, method, params)
...@@ -213,7 +213,7 @@ class TestRegistryServer(unittest.TestCase): ...@@ -213,7 +213,7 @@ class TestRegistryServer(unittest.TestCase):
res = self.server.hello(prefix, protocol=protocol) res = self.server.hello(prefix, protocol=protocol)
# decrypt # decrypt
length = len(res)/2 length = len(res) // 2
key, sign = res[:length], res[length:] key, sign = res[:length], res[length:]
key = decrypt(pkey, key) key = decrypt(pkey, key)
self.assertEqual(self.server.sessions[prefix][-1][0], key, self.assertEqual(self.server.sessions[prefix][-1][0], key,
......
...@@ -57,9 +57,9 @@ class TestRegistryClient(unittest.TestCase): ...@@ -57,9 +57,9 @@ class TestRegistryClient(unittest.TestCase):
h = hmac.HMAC(key, query, hashlib.sha1).digest() h = hmac.HMAC(key, query, hashlib.sha1).digest()
key = hashlib.sha1(key).digest() key = hashlib.sha1(key).digest()
# response part # response part
body = None body = b'this is a body'
response = fakeResponse(body, http.client.NO_CONTENT) response = fakeResponse(body, http.client.NO_CONTENT)
response.msg = dict(Re6stHMAC=hmac.HMAC(key, body, hashlib.sha1).digest()) response.msg = dict(Re6stHMAC=base64.b64encode(hmac.HMAC(key, body, hashlib.sha1).digest()))
self.client._conn.getresponse.return_value = response self.client._conn.getresponse.return_value = response
res = self.client.getNetworkConfig(cn) res = self.client.getNetworkConfig(cn)
......
...@@ -40,7 +40,7 @@ def generate_cert(ca, ca_key, csr, prefix, serial, not_after=None): ...@@ -40,7 +40,7 @@ def generate_cert(ca, ca_key, csr, prefix, serial, not_after=None):
cert.gmtime_adj_notBefore(0) cert.gmtime_adj_notBefore(0)
if not_after: if not_after:
cert.set_notAfter( cert.set_notAfter(
time.strftime("%Y%m%d%H%M%SZ", time.gmtime(not_after))) time.strftime("%Y%m%d%H%M%SZ", time.gmtime(not_after)).encode())
else: else:
cert.gmtime_adj_notAfter(registry.RegistryServer.cert_duration) cert.gmtime_adj_notAfter(registry.RegistryServer.cert_duration)
subject = req.get_subject() subject = req.get_subject()
...@@ -57,9 +57,9 @@ def create_cert_file(pkey_file, cert_file, ca, ca_key, prefix, serial): ...@@ -57,9 +57,9 @@ def create_cert_file(pkey_file, cert_file, ca, ca_key, prefix, serial):
pkey, csr = generate_csr() pkey, csr = generate_csr()
cert = generate_cert(ca, ca_key, csr, prefix, serial) cert = generate_cert(ca, ca_key, csr, prefix, serial)
with open(pkey_file, 'w') as f: with open(pkey_file, 'w') as f:
f.write(pkey) f.write(pkey.decode())
with open(cert_file, 'w') as f: with open(cert_file, 'w') as f:
f.write(cert) f.write(cert.decode())
return pkey, cert return pkey, cert
...@@ -101,7 +101,7 @@ def serial2prefix(serial): ...@@ -101,7 +101,7 @@ def serial2prefix(serial):
# pkey: private key # pkey: private key
def decrypt(pkey, incontent): def decrypt(pkey, incontent):
with open("node.key", 'w') as f: with open("node.key", 'w') as f:
f.write(pkey) f.write(pkey.decode())
args = "openssl rsautl -decrypt -inkey node.key".split() args = "openssl rsautl -decrypt -inkey node.key".split()
p = subprocess.Popen( p = subprocess.Popen(
args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
......
...@@ -94,7 +94,7 @@ class Connection(object): ...@@ -94,7 +94,7 @@ class Connection(object):
'--remap-usr1', 'SIGTERM', '--remap-usr1', 'SIGTERM',
'--ping-exit', str(tm.timeout), '--ping-exit', str(tm.timeout),
'--route-up', '%s %u' % (plib.ovpn_client, tm.write_sock.fileno()), '--route-up', '%s %u' % (plib.ovpn_client, tm.write_sock.fileno()),
*tm.ovpn_args) *tm.ovpn_args, pass_fds=[tm.write_sock.fileno()])
tm.resetTunnelRefresh() tm.resetTunnelRefresh()
self._retry += 1 self._retry += 1
...@@ -169,7 +169,7 @@ class TunnelKiller(object): ...@@ -169,7 +169,7 @@ class TunnelKiller(object):
if (self.address, self.ifindex) in tm.ctl.locked: if (self.address, self.ifindex) in tm.ctl.locked:
self.state = 'locked' self.state = 'locked'
self.timeout = time.time() + 2 * tm.timeout self.timeout = time.time() + 2 * tm.timeout
tm.sendto(self.peer, '\2' if self.client else '\3') tm.sendto(self.peer, b'\2' if self.client else b'\3')
else: else:
self.timeout = 0 self.timeout = 0
...@@ -359,13 +359,13 @@ class BaseTunnelManager(object): ...@@ -359,13 +359,13 @@ class BaseTunnelManager(object):
to = address[:2] to = address[:2]
if address[0] == '::1': if address[0] == '::1':
try: try:
prefix, msg = msg.split('\0', 1) prefix, msg = msg.split(b'\0', 1)
int(prefix, 2) int(prefix, 2)
except ValueError: except ValueError:
return return
if msg: if msg:
self._forward = to self._forward = to
code = ord(msg[0]) code = msg[0]
if prefix == self._prefix: if prefix == self._prefix:
msg = self._processPacket(msg) msg = self._processPacket(msg)
if msg: if msg:
...@@ -397,7 +397,7 @@ class BaseTunnelManager(object): ...@@ -397,7 +397,7 @@ class BaseTunnelManager(object):
address, exc_info=1) address, exc_info=1)
return return
peer.version = self._version \ peer.version = self._version \
if self._sendto(to, '\0' + self._version, peer) else '' if self._sendto(to, b'\0' + self._version, peer) else b''
return return
if seqno: if seqno:
h = x509.fingerprint(self.cert.cert).digest() h = x509.fingerprint(self.cert.cert).digest()
...@@ -444,10 +444,11 @@ class BaseTunnelManager(object): ...@@ -444,10 +444,11 @@ class BaseTunnelManager(object):
# We got a valid and non-empty message. Always reply # We got a valid and non-empty message. Always reply
# something so that the sender knows we're still connected. # something so that the sender knows we're still connected.
answer = self._processPacket(msg, peer.prefix) answer = self._processPacket(msg, peer.prefix)
self._sendto(to, msg[0] + answer if answer else "", peer) self._sendto(to, msg[0:1] + answer.encode() if answer else b'', peer)
def _processPacket(self, msg, peer=None): def _processPacket(self, msg, peer=None):
c = ord(msg[0]) c = msg[0]
msg = msg[1:] msg = msg[1:]
code = c & 0x7f code = c & 0x7f
if c > 0x7f and msg: if c > 0x7f and msg:
...@@ -456,6 +457,7 @@ class BaseTunnelManager(object): ...@@ -456,6 +457,7 @@ class BaseTunnelManager(object):
elif code == 1: # address elif code == 1: # address
if msg: if msg:
if peer: if peer:
msg = msg.decode()
self.cache.addPeer(peer, msg) self.cache.addPeer(peer, msg)
try: try:
self._connecting.remove(peer) self._connecting.remove(peer)
...@@ -526,7 +528,7 @@ class BaseTunnelManager(object): ...@@ -526,7 +528,7 @@ class BaseTunnelManager(object):
if peer.prefix != prefix: if peer.prefix != prefix:
self.sendto(prefix, None) self.sendto(prefix, None)
elif (peer.version < self._version and elif (peer.version < self._version and
self.sendto(prefix, '\0' + self._version)): self.sendto(prefix, b'\0' + self._version)):
peer.version = self._version peer.version = self._version
def broadcastNewVersion(self): def broadcastNewVersion(self):
...@@ -635,7 +637,7 @@ class BaseTunnelManager(object): ...@@ -635,7 +637,7 @@ class BaseTunnelManager(object):
logging.error("%s. Flushing...", msg) logging.error("%s. Flushing...", msg)
subprocess.call(("ip", "-6", "route", "flush", "cached")) subprocess.call(("ip", "-6", "route", "flush", "cached"))
self.sendto(self.cache.registry_prefix, self.sendto(self.cache.registry_prefix,
'\7%s (%s)' % (msg, os.uname()[2])) b'\7%s (%s)' % (msg, os.uname()[2]))
break break
def _updateCountry(self, address): def _updateCountry(self, address):
...@@ -957,7 +959,7 @@ class TunnelManager(BaseTunnelManager): ...@@ -957,7 +959,7 @@ class TunnelManager(BaseTunnelManager):
address = self.cache.getAddress(peer) address = self.cache.getAddress(peer)
if address: if address:
count -= self._makeTunnel(peer, address) count -= self._makeTunnel(peer, address)
elif self.sendto(peer, '\1'): elif self.sendto(peer, b'\1'):
self._connecting.add(peer) self._connecting.add(peer)
count -= 1 count -= 1
elif distant_peers is None: elif distant_peers is None:
......
...@@ -6,9 +6,9 @@ import sys, textwrap, threading, time, traceback ...@@ -6,9 +6,9 @@ import sys, textwrap, threading, time, traceback
# and then socket.SOCK_CLOEXEC will be useless. # and then socket.SOCK_CLOEXEC will be useless.
# (We already follow the good practice that consists in not # (We already follow the good practice that consists in not
# relying on the GC for the closing of file descriptors.) # relying on the GC for the closing of file descriptors.)
socket.SOCK_CLOEXEC = 0x80000 #socket.SOCK_CLOEXEC = 0x80000
HMAC_LEN = len(hashlib.sha1('').digest()) HMAC_LEN = len(hashlib.sha1(b'').digest())
class ReexecException(Exception): class ReexecException(Exception):
pass pass
...@@ -180,8 +180,10 @@ class Popen(subprocess.Popen): ...@@ -180,8 +180,10 @@ class Popen(subprocess.Popen):
t = threading.Timer(5, self.kill) t = threading.Timer(5, self.kill)
t.start() t.start()
# PY3: use waitid(WNOWAIT) and call self.poll() after t.cancel() # PY3: use waitid(WNOWAIT) and call self.poll() after t.cancel()
r = self.wait() #r = self.wait()
r = self.waitid(WNOWAIT) # PY3
t.cancel() t.cancel()
self.poll() # PY3
return r return r
...@@ -270,9 +272,9 @@ def packInteger(i): ...@@ -270,9 +272,9 @@ def packInteger(i):
raise OverflowError raise OverflowError
def unpackInteger(x): def unpackInteger(x):
n = ord(x[0]) >> 5 n = x[0] >> 5
try: try:
i, = struct.unpack("!Q", '\0' * (7 - n) + x[:n+1]) i, = struct.unpack("!Q", b'\0' * (7 - n) + x[:n+1])
except struct.error: except struct.error:
return return
return sum((32 << 8 * i for i in range(n)), return sum((32 << 8 * i for i in range(n)),
......
...@@ -40,4 +40,4 @@ protocol = 8 ...@@ -40,4 +40,4 @@ protocol = 8
min_protocol = 1 min_protocol = 1
if __name__ == "__main__": if __name__ == "__main__":
print version print(version)
...@@ -14,23 +14,23 @@ def subnetFromCert(cert): ...@@ -14,23 +14,23 @@ def subnetFromCert(cert):
return cert.get_subject().CN return cert.get_subject().CN
def notBefore(cert): def notBefore(cert):
return calendar.timegm(time.strptime(cert.get_notBefore(),'%Y%m%d%H%M%SZ')) return calendar.timegm(time.strptime(cert.get_notBefore().decode(),'%Y%m%d%H%M%SZ'))
def notAfter(cert): def notAfter(cert):
return calendar.timegm(time.strptime(cert.get_notAfter(),'%Y%m%d%H%M%SZ')) return calendar.timegm(time.strptime(cert.get_notAfter().decode(),'%Y%m%d%H%M%SZ'))
def openssl(*args): def openssl(*args, fds=[]):
return utils.Popen(('openssl',) + args, return utils.Popen(('openssl',) + args,
stdin=subprocess.PIPE, stdin=subprocess.PIPE,
stdout=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.PIPE) stderr=subprocess.PIPE, pass_fds=fds)
def encrypt(cert, data): def encrypt(cert, data):
r, w = os.pipe() r, w = os.pipe()
try: try:
threading.Thread(target=os.write, args=(w, cert)).start() threading.Thread(target=os.write, args=(w, cert)).start()
p = openssl('rsautl', '-encrypt', '-certin', p = openssl('rsautl', '-encrypt', '-certin',
'-inkey', '/proc/self/fd/%u' % r) '-inkey', '/proc/self/fd/%u' % r, fds=[r])
out, err = p.communicate(data) out, err = p.communicate(data)
finally: finally:
os.close(r) os.close(r)
...@@ -96,7 +96,7 @@ class Cert(object): ...@@ -96,7 +96,7 @@ class Cert(object):
self.key = crypto.load_privatekey(crypto.FILETYPE_PEM, f.read()) self.key = crypto.load_privatekey(crypto.FILETYPE_PEM, f.read())
if cert: if cert:
with open(cert) as f: with open(cert) as f:
self.cert = self.loadVerify(f.read()) self.cert = self.loadVerify(f.read().encode())
@property @property
def prefix(self): def prefix(self):
...@@ -143,6 +143,7 @@ class Cert(object): ...@@ -143,6 +143,7 @@ class Cert(object):
"error running openssl, assuming cert is invalid") "error running openssl, assuming cert is invalid")
# BBB: With old versions of openssl, detailed # BBB: With old versions of openssl, detailed
# error is printed to standard output. # error is printed to standard output.
out, err = out.decode(), err.decode()
for err in err, out: for err in err, out:
for x in err.splitlines(): for x in err.splitlines():
if x.startswith('error '): if x.startswith('error '):
...@@ -166,7 +167,7 @@ class Cert(object): ...@@ -166,7 +167,7 @@ class Cert(object):
def verifyVersion(self, version): def verifyVersion(self, version):
try: try:
n = 1 + (ord(version[0]) >> 5) n = 1 + (version[0] >> 5)
self.verify(version[n:], version[:n]) self.verify(version[n:], version[:n])
except (IndexError, crypto.Error): except (IndexError, crypto.Error):
raise VerifyError(None, None, 'invalid network version') raise VerifyError(None, None, 'invalid network version')
...@@ -206,7 +207,7 @@ class Peer(object): ...@@ -206,7 +207,7 @@ class Peer(object):
_key = newHmacSecret() _key = newHmacSecret()
serial = None serial = None
stop_date = float('inf') stop_date = float('inf')
version = '' version = b''
def __init__(self, prefix): def __init__(self, prefix):
self.prefix = prefix self.prefix = prefix
...@@ -229,11 +230,11 @@ class Peer(object): ...@@ -229,11 +230,11 @@ class Peer(object):
try: try:
# Always assume peer is not old, in case it has just upgraded, # Always assume peer is not old, in case it has just upgraded,
# else we would be stuck with the old protocol. # else we would be stuck with the old protocol.
msg = ('\0\0\0\1' msg = (b'\0\0\0\1'
+ PACKED_PROTOCOL + PACKED_PROTOCOL
+ fingerprint(self.cert).digest()) + fingerprint(self.cert).digest())
except AttributeError: except AttributeError:
msg = '\0\0\0\0' msg = b'\0\0\0\0'
return msg + crypto.dump_certificate(crypto.FILETYPE_ASN1, cert) return msg + crypto.dump_certificate(crypto.FILETYPE_ASN1, cert)
def hello0Sent(self): def hello0Sent(self):
...@@ -246,7 +247,7 @@ class Peer(object): ...@@ -246,7 +247,7 @@ class Peer(object):
self._i = self._j = 2 self._i = self._j = 2
self._last = 0 self._last = 0
self.protocol = protocol self.protocol = protocol
return ''.join(('\0\0\0\2', PACKED_PROTOCOL if protocol else '', return b''.join((b'\0\0\0\2', PACKED_PROTOCOL if protocol else b'',
h, cert.sign(h))) h, cert.sign(h)))
def _hmac(self, msg): def _hmac(self, msg):
......
...@@ -21,7 +21,7 @@ Requires: python-setuptools ...@@ -21,7 +21,7 @@ Requires: python-setuptools
BuildRequires: python3-devel BuildRequires: python3-devel
%endif %endif
Recommends: python-miniupnpc Recommends: python-miniupnpc
Conflicts: re6st-node Conflicts: re6st-node-py3
%description %description
......
...@@ -7,7 +7,9 @@ from setuptools.command import sdist as _sdist, build_py as _build_py ...@@ -7,7 +7,9 @@ from setuptools.command import sdist as _sdist, build_py as _build_py
from distutils import log from distutils import log
version = {"__file__": "re6st/version.py"} version = {"__file__": "re6st/version.py"}
execfile(version["__file__"], version) with open(version["__file__"]) as f:
code = compile(f.read(), version["__file__"], 'exec')
exec(code, version)
def copy_file(self, infile, outfile, *args, **kw): def copy_file(self, infile, outfile, *args, **kw):
if infile == version["__file__"]: if infile == version["__file__"]:
......
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