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))
This diff is collapsed.
...@@ -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