Commit eb0246c2 authored by Julien Muchembled's avatar Julien Muchembled

Add support for Python 3

parent 4dee0c16
...@@ -11,7 +11,7 @@ FILETYPE_PEM = 1 ...@@ -11,7 +11,7 @@ FILETYPE_PEM = 1
def load_privatekey(type, buffer): def load_privatekey(type, buffer):
r = _tmpfile() r = _tmpfile()
r.write(buffer) r.write(buffer.encode())
r.flush() r.flush()
return r return r
...@@ -20,7 +20,7 @@ def load_certificate(type, buffer): ...@@ -20,7 +20,7 @@ def load_certificate(type, buffer):
r = _tmpfile() r = _tmpfile()
p = Popen(("openssl", "x509", "-pubkey", "-noout"), p = Popen(("openssl", "x509", "-pubkey", "-noout"),
stdin=PIPE, stdout=r, stderr=PIPE) stdin=PIPE, stdout=r, stderr=PIPE)
err = p.communicate(buffer)[1] err = p.communicate(buffer.encode())[1]
if p.poll(): if p.poll():
raise Error(err) raise Error(err)
return r return r
......
...@@ -13,10 +13,7 @@ ...@@ -13,10 +13,7 @@
############################################################################## ##############################################################################
import argparse import argparse
import ConfigParser
import hashlib import hashlib
import httplib
import inspect
import json import json
import logging import logging
import os import os
...@@ -26,8 +23,19 @@ import sys ...@@ -26,8 +23,19 @@ import sys
import tarfile import tarfile
import tempfile import tempfile
import traceback import traceback
import urllib2 from base64 import b64encode, decodestring, encodestring
import urlparse try:
import configparser
from http.client import HTTPConnection, HTTPSConnection
from urllib.error import HTTPError
from urllib.parse import urlsplit
from urllib.request import urlopen
basestring = bytes, str
except ImportError:
import ConfigParser as configparser
from httplib import HTTPConnection, HTTPSConnection
from urllib2 import HTTPError, urlopen
from urlparse import urlsplit
try: try:
from OpenSSL import crypto from OpenSSL import crypto
except ImportError: except ImportError:
...@@ -52,17 +60,21 @@ class short_exc_info(tuple): ...@@ -52,17 +60,21 @@ class short_exc_info(tuple):
l += traceback.format_exception_only(t, v) l += traceback.format_exception_only(t, v)
return ''.join(l).rstrip() return ''.join(l).rstrip()
def byteify(input): def strify(input):
'''Transform every unicode string inside a list or dict into normal strings. ''' '''Transform every unicode string inside a list or dict into normal strings. '''
if isinstance(input, dict): if isinstance(input, dict):
return dict([(byteify(key), byteify(value)) for key, value in input.iteritems()]) return dict((strify(key), strify(value)) for key, value in input.items())
elif isinstance(input, list): elif isinstance(input, list):
return [byteify(element) for element in input] return map(strify, input)
elif isinstance(input, unicode): elif isinstance(input, unicode):
return input.encode('utf-8') return input.encode('utf-8')
else: else:
return input return input
try:
unicode
except NameError:
def strify(input):
return input
class NetworkcacheClient(object): class NetworkcacheClient(object):
''' '''
...@@ -100,7 +112,7 @@ class NetworkcacheClient(object): ...@@ -100,7 +112,7 @@ class NetworkcacheClient(object):
def __new_init(self, config, signature_certificate_list=None): def __new_init(self, config, signature_certificate_list=None):
if not hasattr(config, 'get'): if not hasattr(config, 'get'):
parser = ConfigParser.SafeConfigParser() parser = configparser.SafeConfigParser()
parser.readfp(config) parser.readfp(config)
config = dict(parser.items('networkcache')) config = dict(parser.items('networkcache'))
self.config = config self.config = config
...@@ -147,12 +159,12 @@ class NetworkcacheClient(object): ...@@ -147,12 +159,12 @@ class NetworkcacheClient(object):
method = 'PUT' if name else 'POST' method = 'PUT' if name else 'POST'
url = self.config['upload-%s-url' % where] url = self.config['upload-%s-url' % where]
timeout = UPLOAD_TIMEOUT timeout = UPLOAD_TIMEOUT
parsed_url = urlparse.urlsplit(url.rstrip('/') + ('/' + name if name else '')) parsed_url = urlsplit(url.rstrip('/') + ('/' + name if name else ''))
if not headers: if not headers:
headers = {} headers = {}
if parsed_url.username: if parsed_url.username:
headers['Authorization'] = 'Basic %s' % ('%s:%s' % ( headers['Authorization'] = 'Basic ' + b64encode('%s:%s' % (
parsed_url.username, parsed_url.password)).encode('base64').strip() parsed_url.username, parsed_url.password))
headers["Connection"] = "close" headers["Connection"] = "close"
connection_kw = { connection_kw = {
'host': parsed_url.hostname, 'host': parsed_url.hostname,
...@@ -162,23 +174,21 @@ class NetworkcacheClient(object): ...@@ -162,23 +174,21 @@ class NetworkcacheClient(object):
if parsed_url.scheme == 'https': if parsed_url.scheme == 'https':
connection_kw['cert_file'] = self.config['sha%s-cert-file' % where] connection_kw['cert_file'] = self.config['sha%s-cert-file' % where]
connection_kw['key_file'] = self.config['sha%s-key-file' % where] connection_kw['key_file'] = self.config['sha%s-key-file' % where]
if 'context' in inspect.getargspec( if hasattr(ssl, 'create_default_context'):
httplib.HTTPSConnection.__init__).args:
connection_kw['context'] = ssl.create_default_context( connection_kw['context'] = ssl.create_default_context(
cafile=self.config.get('sha%s-ca-file' % where) cafile=self.config.get('sha%s-ca-file' % where)
) )
connection = httplib.HTTPSConnection(**connection_kw) connection = HTTPSConnection(**connection_kw)
else: else:
connection = httplib.HTTPConnection(**connection_kw) connection = HTTPConnection(**connection_kw)
try: try:
connection.request(method, parsed_url.path, data, headers) connection.request(method, parsed_url.path, data, headers)
r = connection.getresponse() r = connection.getresponse()
if 200 <= r.status < 300: if 200 <= r.status < 300:
return r return r
except: finally:
connection.close() connection.close()
raise raise HTTPError(url, r.status, r.reason, r.msg, r.fp)
raise urllib2.HTTPError(url, r.status, r.reason, r.msg, r.fp)
@staticmethod @staticmethod
def archive(path): def archive(path):
...@@ -216,7 +226,7 @@ class NetworkcacheClient(object): ...@@ -216,7 +226,7 @@ class NetworkcacheClient(object):
try: try:
try: try:
file_descriptor.seek(0) file_descriptor.seek(0)
except StandardError: except Exception:
f = tempfile.TemporaryFile() f = tempfile.TemporaryFile()
while 1: while 1:
data = file_descriptor.read(65536) data = file_descriptor.read(65536)
...@@ -234,14 +244,14 @@ class NetworkcacheClient(object): ...@@ -234,14 +244,14 @@ class NetworkcacheClient(object):
sha512sum = sha512sum.hexdigest() sha512sum = sha512sum.hexdigest()
try: try:
self._request('cache', sha512sum).close() self._request('cache', sha512sum).close()
except urllib2.HTTPError: except HTTPError:
size = file_descriptor.tell() size = file_descriptor.tell()
file_descriptor.seek(0) file_descriptor.seek(0)
result = self._request('cache', data=file_descriptor, headers={ result = self._request('cache', data=file_descriptor, headers={
'Content-Length': str(size), 'Content-Length': str(size),
'Content-Type': 'application/octet-stream'}) 'Content-Type': 'application/octet-stream'})
data = result.read() data = result.read()
if result.status != 201 or data != sha512sum: if result.status != 201 or data != sha512sum.encode():
raise NetworkcacheException( raise NetworkcacheException(
'Failed to upload data to SHACACHE Server.' 'Failed to upload data to SHACACHE Server.'
' Response code: %s. Response data: %s' % (result.status, data)) ' Response code: %s. Response data: %s' % (result.status, data))
...@@ -266,7 +276,7 @@ class NetworkcacheClient(object): ...@@ -266,7 +276,7 @@ class NetworkcacheClient(object):
def index(self, key, **kw): def index(self, key, **kw):
data = json.dumps(kw) data = json.dumps(kw)
data = [data, self._getSignatureString(data)] data = [data, self._getSignatureString(data.encode())]
result = self._request('dir', key, json.dumps(data), { result = self._request('dir', key, json.dumps(data), {
'Content-Type': 'application/json'}) 'Content-Type': 'application/json'})
if result.status != 201: if result.status != 201:
...@@ -287,19 +297,19 @@ class NetworkcacheClient(object): ...@@ -287,19 +297,19 @@ class NetworkcacheClient(object):
data_list = self.select_generic(key, self.signature_certificate_list) data_list = self.select_generic(key, self.signature_certificate_list)
for information_json, signature in data_list: for information_json, signature in data_list:
try: try:
information_dict = byteify(json.loads(information_json)) information_dict = strify(json.loads(information_json))
except Exception: except Exception:
logger.info('Failed to parse json-in-json response (%r)', logger.info('Failed to parse json-in-json response (%r)',
information_json) information_json)
continue continue
try: try:
len(information_dict['sha512']) len(information_dict['sha512'])
except StandardError: except Exception:
logger.info('Bad or missing sha512 in directory response (%r)', logger.info('Bad or missing sha512 in directory response (%r)',
information_dict) information_dict)
continue continue
if required_key_test(information_dict): if required_key_test(information_dict):
for k, v in wanted_metadata_dict.iteritems(): for k, v in wanted_metadata_dict.items():
if information_dict.get(k) != v: if information_dict.get(k) != v:
break break
else: else:
...@@ -310,7 +320,7 @@ class NetworkcacheClient(object): ...@@ -310,7 +320,7 @@ class NetworkcacheClient(object):
''' '''
data = self._request('dir', key).read() data = self._request('dir', key).read()
try: try:
data_list = json.loads(data) data_list = json.loads(data.decode())
except Exception: except Exception:
raise NetworkcacheException('Failed to parse json response (%r)' % data) raise NetworkcacheException('Failed to parse json response (%r)' % data)
if filter: if filter:
...@@ -323,7 +333,9 @@ class NetworkcacheClient(object): ...@@ -323,7 +333,9 @@ class NetworkcacheClient(object):
Return the signature based on certification file. Return the signature based on certification file.
""" """
k = self.signature_private_key k = self.signature_private_key
return '' if k is None else crypto.sign(k, content, 'sha1').encode('base64') if k is None:
return ''
return encodestring(crypto.sign(k, content, 'sha1')).decode()
def _verifySignatureInCertificateList(self, content, signature_string): def _verifySignatureInCertificateList(self, content, signature_string):
""" """
...@@ -331,8 +343,8 @@ class NetworkcacheClient(object): ...@@ -331,8 +343,8 @@ class NetworkcacheClient(object):
find any. find any.
""" """
if signature_string: if signature_string:
signature = signature_string.decode('base64') signature = decodestring(signature_string.encode())
content = str(content) content = content.encode()
for certificate in self.signature_certificate_list: for certificate in self.signature_certificate_list:
try: try:
crypto.verify(certificate, signature, content, 'sha1') crypto.verify(certificate, signature, content, 'sha1')
...@@ -371,12 +383,12 @@ def cmd_upload(*args): ...@@ -371,12 +383,12 @@ def cmd_upload(*args):
f = None f = None
try: try:
if args.file: if args.file:
f = open(args.file) f = open(args.file, 'rb')
elif os.path.isdir(args.url): elif os.path.isdir(args.url):
f = nc.archive(args.url) f = nc.archive(args.url)
else: else:
f = urllib2.urlopen(args.url) f = urlopen(args.url)
urlmd5 = hashlib.md5(args.url).hexdigest() urlmd5 = str(hashlib.md5(args.url.encode()).hexdigest())
nc.upload(f, args.prefix_key + urlmd5 + args.suffix_key, urlmd5=urlmd5, nc.upload(f, args.prefix_key + urlmd5 + args.suffix_key, urlmd5=urlmd5,
file_name=os.path.basename(args.url) or "file", file_name=os.path.basename(args.url) or "file",
**dict(x.split('=', 1) for x in args.meta)) **dict(x.split('=', 1) for x in args.meta))
...@@ -387,5 +399,8 @@ def cmd_download(*args): ...@@ -387,5 +399,8 @@ def cmd_download(*args):
parser = _newArgumentParser("URL of data to download.") parser = _newArgumentParser("URL of data to download.")
args = parser.parse_args(args or sys.argv[1:]) args = parser.parse_args(args or sys.argv[1:])
nc = NetworkcacheClient(args.config) nc = NetworkcacheClient(args.config)
key = args.prefix_key + hashlib.md5(args.url).hexdigest() + args.suffix_key urlmd5 = str(hashlib.md5(args.url.encode()).hexdigest())
shutil.copyfileobj(nc.download(nc.select(key).next()['sha512']), sys.stdout) key = args.prefix_key + urlmd5 + args.suffix_key
f = sys.stdout
shutil.copyfileobj(nc.download(next(nc.select(key))['sha512']),
getattr(f, 'buffer', f))
import BaseHTTPServer
import datetime import datetime
import errno import errno
import hashlib import hashlib
import httplib
import json import json
import logging import logging
import logging.handlers import logging.handlers
import os import os
import urllib2
import random import random
import shutil import shutil
import ssl import ssl
...@@ -20,21 +17,29 @@ import unittest ...@@ -20,21 +17,29 @@ import unittest
import slapos.libnetworkcache import slapos.libnetworkcache
import slapos.signature import slapos.signature
import sys import sys
from cStringIO import StringIO from io import BytesIO
try:
from http.server import BaseHTTPRequestHandler, HTTPServer
from http.client import HTTPConnection, NOT_FOUND
from urllib.error import HTTPError
except ImportError:
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
from httplib import HTTPConnection, NOT_FOUND
from urllib2 import HTTPError
logging.basicConfig() logging.basicConfig()
class NCHandler(BaseHTTPServer.BaseHTTPRequestHandler): class NCHandler(BaseHTTPRequestHandler):
def __init__(self, request, address, server): def __init__(self, request, address, server):
self.__server = server self.__server = server
self.tree = server.tree self.tree = server.tree
BaseHTTPServer.BaseHTTPRequestHandler.__init__( BaseHTTPRequestHandler.__init__(
self, request, address, server) self, request, address, server)
def handle(self): def handle(self):
try: try:
BaseHTTPServer.BaseHTTPRequestHandler.handle(self) BaseHTTPRequestHandler.handle(self)
except Exception: except Exception:
traceback.print_exc() traceback.print_exc()
raise raise
...@@ -49,80 +54,79 @@ class NCHandler(BaseHTTPServer.BaseHTTPRequestHandler): ...@@ -49,80 +54,79 @@ class NCHandler(BaseHTTPServer.BaseHTTPRequestHandler):
and and
os.path.exists(path) os.path.exists(path)
): ):
self.send_response(404, 'Not Found') self.send_error(404)
return return
self.send_response(200) self.send_response(200)
out = open(path, 'rb').read() with open(path, 'rb') as f:
out = f.read()
self.send_header('Content-Length', len(out)) self.send_header('Content-Length', len(out))
self.end_headers() self.end_headers()
self.wfile.write(out) self.wfile.write(out)
def do_PUT(self): def do_PUT(self):
assert 'shadir' in self.path assert 'shadir' in self.path
assert self.headers.getheader('content-type') == 'application/json' assert self.headers.get('content-type') == 'application/json'
path = os.path.abspath(os.path.join(self.tree, *self.path.split('/'))) path = os.path.abspath(os.path.join(self.tree, *self.path.split('/')))
if not os.path.exists(os.path.dirname(path)): if not os.path.exists(os.path.dirname(path)):
os.makedirs(os.path.dirname(path)) os.makedirs(os.path.dirname(path))
data = self.rfile.read(int(self.headers.getheader('content-length'))) data = self.rfile.read(int(self.headers.get('content-length')))
cksum = hashlib.sha512(data).hexdigest() cksum = hashlib.sha512(data).hexdigest()
if os.path.exists(path): if os.path.exists(path):
with open(path, 'rb') as f: with open(path) as f:
json_data_list = json.loads(f.read().strip()) json_data_list = json.load(f)
else: else:
json_data_list = [] json_data_list = []
json_data_list.append(json.loads(data)) json_data_list.append(json.loads(data.decode()))
data = json.dumps(json_data_list)
open(path, 'wb').write(data) with open(path, 'w') as f:
json.dump(json_data_list, f)
self.send_response(201) self.send_response(201)
self.send_header('Content-Length', str(len(cksum))) self.send_header('Content-Length', str(len(cksum)))
self.send_header('Content-Type', 'text/html') self.send_header('Content-Type', 'text/html')
self.end_headers() self.end_headers()
self.wfile.write(cksum) self.wfile.write(cksum.encode())
return
def do_POST(self): def do_POST(self):
assert 'shacache' in self.path assert 'shacache' in self.path
assert self.headers.getheader('content-type') == 'application/octet-stream' assert self.headers.get('content-type') == 'application/octet-stream'
path = os.path.abspath(os.path.join(self.tree, *self.path.split('/'))) path = os.path.abspath(os.path.join(self.tree, *self.path.split('/')))
if not os.path.exists(path): if not os.path.exists(path):
os.makedirs(path) os.makedirs(path)
data = self.rfile.read(int(self.headers.getheader('content-length'))) data = self.rfile.read(int(self.headers.get('content-length')))
cksum = hashlib.sha512(data).hexdigest() cksum = hashlib.sha512(data).hexdigest()
path = os.path.join(path, cksum) path = os.path.join(path, cksum)
# Although real server would accept the request, # Although real server would accept the request,
# clients should avoid uploading same content twice. # clients should avoid uploading same content twice.
assert not os.path.exists(path) assert not os.path.exists(path)
open(path, 'wb').write(data) with open(path, 'wb') as f:
f.write(data)
self.send_response(201) self.send_response(201)
self.send_header('Content-Length', str(len(cksum))) self.send_header('Content-Length', str(len(cksum)))
self.send_header('Content-Type', 'text/html') self.send_header('Content-Type', 'text/html')
self.end_headers() self.end_headers()
self.wfile.write(cksum) self.wfile.write(cksum.encode())
return
class NCHandlerPOST200(NCHandler): class NCHandlerPOST200(NCHandler):
def do_POST(self): def do_POST(self):
self.send_response(200) self.send_response(200)
return self.end_headers()
class NCHandlerReturnWrong(NCHandler): class NCHandlerReturnWrong(NCHandler):
def do_POST(self): def do_POST(self):
cksum = 'incorrect' cksum = b'incorrect'
self.send_response(201) self.send_response(201)
self.send_header('Content-Length', str(len(cksum))) self.send_header('Content-Length', str(len(cksum)))
self.send_header('Content-Type', 'text/html') self.send_header('Content-Type', 'text/html')
self.end_headers() self.end_headers()
self.wfile.write(cksum) self.wfile.write(cksum)
return
class Server(BaseHTTPServer.HTTPServer): class Server(HTTPServer):
def __init__(self, tree, *args): def __init__(self, tree, *args):
BaseHTTPServer.HTTPServer.__init__(self, *args) HTTPServer.__init__(self, *args)
self.tree = os.path.abspath(tree) self.tree = os.path.abspath(tree)
__run = True __run = True
...@@ -158,7 +162,7 @@ class OfflineTest(unittest.TestCase): ...@@ -158,7 +162,7 @@ class OfflineTest(unittest.TestCase):
def test_upload_offline(self): def test_upload_offline(self):
nc = slapos.libnetworkcache.NetworkcacheClient(self.shacache_url, nc = slapos.libnetworkcache.NetworkcacheClient(self.shacache_url,
self.shadir_url) self.shadir_url)
self.assertRaises(IOError, nc.upload, StringIO()) self.assertRaises(IOError, nc.upload, BytesIO())
class OnlineMixin: class OnlineMixin:
...@@ -174,18 +178,21 @@ class OnlineMixin: ...@@ -174,18 +178,21 @@ class OnlineMixin:
if not 'TEST_SHA_CACHE' in os.environ and not 'TEST_SHA_DIR' in os.environ: if not 'TEST_SHA_CACHE' in os.environ and not 'TEST_SHA_DIR' in os.environ:
self.tree = tempfile.mkdtemp() self.tree = tempfile.mkdtemp()
self.thread = Server.run(self.tree, (self.host, self.port), self.handler) self.thread = Server.run(self.tree, (self.host, self.port), self.handler)
self.test_string = str(random.random()) self.test_string = str(random.random()).encode()
self.test_data = StringIO(self.test_string) self.test_data = BytesIO(self.test_string)
self.test_shasum = hashlib.sha512(self.test_string).hexdigest() self.test_shasum = hashlib.sha512(self.test_string).hexdigest()
self.handler = logging.handlers.BufferingHandler(float('inf')) self.handler = logging.handlers.BufferingHandler(float('inf'))
slapos.libnetworkcache.logger.addHandler(self.handler) slapos.libnetworkcache.logger.addHandler(self.handler)
def tearDown(self): def tearDown(self):
if not 'TEST_SHA_CACHE' in os.environ and not 'TEST_SHA_DIR' in os.environ: if not 'TEST_SHA_CACHE' in os.environ and not 'TEST_SHA_DIR' in os.environ:
conn = HTTPConnection(self.host, self.port)
try: try:
httplib.HTTPConnection(self.host, self.port).request('KILL', '/') conn.request('KILL', '/')
except Exception: except Exception:
pass pass
finally:
conn.close()
if self.thread is not None: if self.thread is not None:
self.thread.join() self.thread.join()
...@@ -204,7 +211,7 @@ class OnlineMixin: ...@@ -204,7 +211,7 @@ class OnlineMixin:
def select(self, nc, key, *args): def select(self, nc, key, *args):
try: try:
return nc.download(nc.select(key).next()['sha512']) return nc.download(next(nc.select(key))['sha512'])
except StopIteration: except StopIteration:
for msg in args: for msg in args:
self.assertLog(msg) self.assertLog(msg)
...@@ -369,8 +376,8 @@ class OnlineTest(OnlineMixin, unittest.TestCase): ...@@ -369,8 +376,8 @@ class OnlineTest(OnlineMixin, unittest.TestCase):
key = 'somekey' + str(random.random()) key = 'somekey' + str(random.random())
nc.upload(self.test_data, key, urlmd5=urlmd5, file_name='my file') nc.upload(self.test_data, key, urlmd5=urlmd5, file_name='my file')
with nc: with nc:
nc.select('key_another_key' + str(random.random())).next() next(nc.select('key_another_key' + str(random.random())))
self.assertRaised(urllib2.HTTPError) self.assertRaised(HTTPError)
def test_upload_shadir_no_filename(self): def test_upload_shadir_no_filename(self):
"""Check scenario with shadir used, but not filename passed""" """Check scenario with shadir used, but not filename passed"""
...@@ -403,14 +410,14 @@ class OnlineTest(OnlineMixin, unittest.TestCase): ...@@ -403,14 +410,14 @@ class OnlineTest(OnlineMixin, unittest.TestCase):
try: try:
nc.download(self.test_shasum) nc.download(self.test_shasum)
self.fail("HTTPError not raised") self.fail("HTTPError not raised")
except urllib2.HTTPError, error: except HTTPError as error:
self.assertEqual(error.code, httplib.NOT_FOUND) self.assertEqual(error.code, NOT_FOUND)
def test_select_signed_content(self): def test_select_signed_content(self):
key = 'somekey' + str(random.random()) key = 'somekey' + str(random.random())
urlmd5 = str(random.random()) urlmd5 = str(random.random())
file_name = 'my file' file_name = 'my file'
key_file = tempfile.NamedTemporaryFile() key_file = tempfile.NamedTemporaryFile('w+')
key_file.write(self.key) key_file.write(self.key)
key_file.flush() key_file.flush()
signed_nc = slapos.libnetworkcache.NetworkcacheClient( signed_nc = slapos.libnetworkcache.NetworkcacheClient(
...@@ -423,7 +430,7 @@ class OnlineTest(OnlineMixin, unittest.TestCase): ...@@ -423,7 +430,7 @@ class OnlineTest(OnlineMixin, unittest.TestCase):
key = 'somekey' + str(random.random()) key = 'somekey' + str(random.random())
urlmd5 = str(random.random()) urlmd5 = str(random.random())
file_name = 'my file' file_name = 'my file'
key_file = tempfile.NamedTemporaryFile() key_file = tempfile.NamedTemporaryFile('w+')
key_file.write(self.key) key_file.write(self.key)
key_file.flush() key_file.flush()
signed_nc = slapos.libnetworkcache.NetworkcacheClient( signed_nc = slapos.libnetworkcache.NetworkcacheClient(
...@@ -437,7 +444,7 @@ class OnlineTest(OnlineMixin, unittest.TestCase): ...@@ -437,7 +444,7 @@ class OnlineTest(OnlineMixin, unittest.TestCase):
key = 'somekey' + str(random.random()) key = 'somekey' + str(random.random())
urlmd5 = str(random.random()) urlmd5 = str(random.random())
file_name = 'my file' file_name = 'my file'
key_file = tempfile.NamedTemporaryFile() key_file = tempfile.NamedTemporaryFile('w+')
key_file.write(self.key) key_file.write(self.key)
key_file.flush() key_file.flush()
signed_nc = slapos.libnetworkcache.NetworkcacheClient( signed_nc = slapos.libnetworkcache.NetworkcacheClient(
...@@ -455,9 +462,10 @@ class OnlineTest(OnlineMixin, unittest.TestCase): ...@@ -455,9 +462,10 @@ class OnlineTest(OnlineMixin, unittest.TestCase):
self.shacache, self.shadir) self.shacache, self.shadir)
self.assertEqual(self.test_shasum, nc.upload(self.test_data, self.assertEqual(self.test_shasum, nc.upload(self.test_data,
key, urlmd5=urlmd5, file_name=file_name)) key, urlmd5=urlmd5, file_name=file_name))
f = os.path.join(self.tree, 'shadir', key) path = os.path.join(self.tree, 'shadir', key)
# now remove the entry from shacache # now remove the entry from shacache
open(f, 'w').write(json.dumps([])) with open(path, 'w') as f:
json.dump([], f)
self.assertEqual(self.select(nc, key), None) self.assertEqual(self.select(nc, key), None)
def test_select_no_json_response(self): def test_select_no_json_response(self):
...@@ -472,7 +480,7 @@ class OnlineTest(OnlineMixin, unittest.TestCase): ...@@ -472,7 +480,7 @@ class OnlineTest(OnlineMixin, unittest.TestCase):
# now remove the entry from shacache # now remove the entry from shacache
f.write('This is not a json.') f.write('This is not a json.')
with nc: with nc:
nc.select(key).next() next(nc.select(key))
self.assertLog('Failed to parse json response') self.assertLog('Failed to parse json response')
def test_select_json_no_in_json_response(self): def test_select_json_no_in_json_response(self):
...@@ -505,7 +513,7 @@ class OnlineTest(OnlineMixin, unittest.TestCase): ...@@ -505,7 +513,7 @@ class OnlineTest(OnlineMixin, unittest.TestCase):
key = 'somekey' + str(random.random()) key = 'somekey' + str(random.random())
urlmd5 = str(random.random()) urlmd5 = str(random.random())
file_name = 'my file' file_name = 'my file'
key_file = tempfile.NamedTemporaryFile() key_file = tempfile.NamedTemporaryFile('w+')
key_file.write(self.key) key_file.write(self.key)
key_file.flush() key_file.flush()
signed_nc = slapos.libnetworkcache.NetworkcacheClient( signed_nc = slapos.libnetworkcache.NetworkcacheClient(
...@@ -513,9 +521,9 @@ class OnlineTest(OnlineMixin, unittest.TestCase): ...@@ -513,9 +521,9 @@ class OnlineTest(OnlineMixin, unittest.TestCase):
signed_nc.upload(self.test_data, key, urlmd5=urlmd5, file_name=file_name) signed_nc.upload(self.test_data, key, urlmd5=urlmd5, file_name=file_name)
# Hacker entered the server... # Hacker entered the server...
f = os.path.join(self.tree, 'shadir', key) path = os.path.join(self.tree, 'shadir', key)
original_data = open(f).read() with open(path) as f:
original_json = json.loads(original_data) original_json = json.load(f)
hacked_entry_json = json.loads(original_json[0][0]) hacked_entry_json = json.loads(original_json[0][0])
# ...he modifies something... # ...he modifies something...
hacked_entry_json['file'] = 'hacked' hacked_entry_json['file'] = 'hacked'
...@@ -524,11 +532,12 @@ class OnlineTest(OnlineMixin, unittest.TestCase): ...@@ -524,11 +532,12 @@ class OnlineTest(OnlineMixin, unittest.TestCase):
hacked_json[0][0] = json.dumps(hacked_entry_json) hacked_json[0][0] = json.dumps(hacked_entry_json)
# ...but as he has no access to key, no way to sign data.. # ...but as he has no access to key, no way to sign data..
# hacked_json[0][1] is still a good key # hacked_json[0][1] is still a good key
open(f, 'w').write(json.dumps(hacked_json)) with open(path, 'w') as f:
json.dump(hacked_json, f)
self.assertEqual(self.select(signed_nc, key), None) self.assertEqual(self.select(signed_nc, key), None)
def test_DirectoryNotFound_non_trustable_entry(self): def test_DirectoryNotFound_non_trustable_entry(self):
key_file = tempfile.NamedTemporaryFile() key_file = tempfile.NamedTemporaryFile('w+')
key_file.write(self.key) key_file.write(self.key)
key_file.flush() key_file.flush()
...@@ -573,7 +582,7 @@ class OnlineTestSSLServer(OnlineMixin, unittest.TestCase): ...@@ -573,7 +582,7 @@ class OnlineTestSSLServer(OnlineMixin, unittest.TestCase):
nc = slapos.libnetworkcache.NetworkcacheClient(self.shacache, self.shadir) nc = slapos.libnetworkcache.NetworkcacheClient(self.shacache, self.shadir)
try: try:
nc.upload(self.test_data) nc.upload(self.test_data)
except ssl.SSLError, e: except ssl.SSLError as e:
self.assertTrue('alert handshake failure' in str(e)) self.assertTrue('alert handshake failure' in str(e))
def test_upload_to_ssl_auth(self): def test_upload_to_ssl_auth(self):
...@@ -589,7 +598,7 @@ class OnlineTestSSLServer(OnlineMixin, unittest.TestCase): ...@@ -589,7 +598,7 @@ class OnlineTestSSLServer(OnlineMixin, unittest.TestCase):
try: try:
nc.upload(self.test_data, key=str(random.random()), nc.upload(self.test_data, key=str(random.random()),
file_name=str(random.random()), urlmd5=str(random.random())) file_name=str(random.random()), urlmd5=str(random.random()))
except ssl.SSLError, e: except ssl.SSLError as e:
self.assertTrue('alert handshake failure' in str(e)) self.assertTrue('alert handshake failure' in str(e))
def test_upload_with_key_with_ssl_auth(self): def test_upload_with_key_with_ssl_auth(self):
...@@ -641,11 +650,11 @@ class GenerateSignatureScriptTest(unittest.TestCase): ...@@ -641,11 +650,11 @@ class GenerateSignatureScriptTest(unittest.TestCase):
self.common_name) self.common_name)
today = datetime.date.today() today = datetime.date.today()
result = subprocess.check_output(['openssl', 'x509', '-noout', '-subject', result = subprocess.check_output(['openssl', 'x509', '-noout', '-subject',
'-in', self.certificate]) '-in', self.certificate], universal_newlines=True)
self.assertEqual('subject= /CN=%s' % self.common_name, result.strip()) self.assertEqual('subject= /CN=%s' % self.common_name, result.strip())
result = subprocess.check_output(['openssl', 'x509', '-noout', '-enddate', result = subprocess.check_output(['openssl', 'x509', '-noout', '-enddate',
'-in', self.certificate]) '-in', self.certificate], universal_newlines=True)
self.assertTrue(' %s ' % (today.year + 100) in result) self.assertIn(' %s ' % (today.year + 100), result)
def test_generate_key_exists(self): def test_generate_key_exists(self):
with tempfile.NamedTemporaryFile() as key: with tempfile.NamedTemporaryFile() as key:
......
...@@ -51,9 +51,6 @@ def __upload_network_cached(dir_url, cache_url, ...@@ -51,9 +51,6 @@ def __upload_network_cached(dir_url, cache_url,
) as nc: ) as nc:
return nc.upload(file_descriptor, directory_key, **metadata_dict) return nc.upload(file_descriptor, directory_key, **metadata_dict)
# BBB: slapos.buildout (1.6.0-dev-SlapOS-011) imports it without using it
helper_upload_network_cached_from_file = None
def helper_upload_network_cached_from_directory(dir_url, cache_url, def helper_upload_network_cached_from_directory(dir_url, cache_url,
path, directory_key, metadata_dict, path, directory_key, metadata_dict,
signature_private_key_file, shacache_ca_file, shacache_cert_file, signature_private_key_file, shacache_ca_file, shacache_cert_file,
......
...@@ -12,11 +12,14 @@ ...@@ -12,11 +12,14 @@
# #
############################################################################## ##############################################################################
import ConfigParser
import argparse import argparse
import os import os
import subprocess import subprocess
import sys import sys
try:
import configparser
except ImportError:
import ConfigParser as configparser
def generateCertificate(certificate_file, key_file, common_name): def generateCertificate(certificate_file, key_file, common_name):
if os.path.lexists(certificate_file): if os.path.lexists(certificate_file):
...@@ -26,8 +29,8 @@ def generateCertificate(certificate_file, key_file, common_name): ...@@ -26,8 +29,8 @@ def generateCertificate(certificate_file, key_file, common_name):
raise ValueError("Key %r exists, will not overwrite." % raise ValueError("Key %r exists, will not overwrite." %
key_file) key_file)
print 'Generating certificate for %r (key: %r, certficate: %r)' % ( print('Generating certificate for %r (key: %r, certficate: %r)' % (
common_name, key_file, certificate_file) common_name, key_file, certificate_file))
subj = '/CN=%s' % common_name subj = '/CN=%s' % common_name
subprocess.check_call(["openssl", "req", "-x509", "-nodes", "-days", "36500", subprocess.check_call(["openssl", "req", "-x509", "-nodes", "-days", "36500",
"-subj", subj, "-newkey", "rsa:1024", "-keyout", key_file, "-out", "-subj", subj, "-newkey", "rsa:1024", "-keyout", key_file, "-out",
...@@ -39,7 +42,7 @@ def run(*args): ...@@ -39,7 +42,7 @@ def run(*args):
parser.add_argument('slapos_config', type=argparse.FileType('r'), parser.add_argument('slapos_config', type=argparse.FileType('r'),
help='SlapOS configuration file.') help='SlapOS configuration file.')
config = ConfigParser.SafeConfigParser() config = configparser.SafeConfigParser()
option = parser.parse_args(list(args) or sys.argv[1:]) option = parser.parse_args(list(args) or sys.argv[1:])
config.readfp(option.slapos_config) config.readfp(option.slapos_config)
generateCertificate(config.get('networkcache', 'signature-certificate-file'), generateCertificate(config.get('networkcache', 'signature-certificate-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