On Sun, Dec 29, 2019 at 12:03:55AM +0100, Branko Čibej wrote:
> On 28.12.2019 17:49, James McCoy wrote:
> > On Wed, Dec 04, 2019 at 10:34:00PM -0500, James McCoy wrote:
> >> I use create_certs.py at build time in the Debian packaging to avoid
> >> dealing with expired certs. Since Debian is in the process of trying to
> >> remove Python 2, I've updated the script to work with Python 3.
> >>
> >> It would also be useful if 1.4 were released, so I could switch to the
> >> CMake build.
> > These are both becoming more important issues. As an alternative, is
> > current trunk in decent enough shape to be used, even without an
> > official release?
> >
> > I can also look into more of the Python3 issues (like SyntaxErrors in
> > SConstruct) if there's a desire to release another 1.3.x version (or to
> > carry the patches locally until a new release happens).
>
> Sorry for not getting back to you sooner.
No worries. I ended up with two patches. One that I've applied to the
packaging of 1.3.9, since that was the immediate need.
The other is for trunk and only covers a couple of the helper scripts.
I got distracted by other priorities and didn't get around to finishing
the work, but it should at least be a starting point.
Cheers,
--
James
GPG Key: 4096R/91BF BF4D 6956 BD5D F7B7 2D23 DFE6 91AE 331B A3DB
diff --git i/SConstruct w/SConstruct
index 4358a23..7f3cc94 100644
--- i/SConstruct
+++ w/SConstruct
@@ -20,6 +20,8 @@
# ====================================================================
#
+from __future__ import print_function
+
import sys
import os
import re
@@ -163,9 +165,9 @@ env.Append(BUILDERS = {
suffix='.def', src_suffix='.h')
})
-match = re.search('SERF_MAJOR_VERSION ([0-9]+).*'
- 'SERF_MINOR_VERSION ([0-9]+).*'
- 'SERF_PATCH_VERSION ([0-9]+)',
+match = re.search(b'SERF_MAJOR_VERSION ([0-9]+).*'
+ b'SERF_MINOR_VERSION ([0-9]+).*'
+ b'SERF_PATCH_VERSION ([0-9]+)',
env.File('serf.h').get_contents(),
re.DOTALL)
MAJOR, MINOR, PATCH = [int(x) for x in match.groups()]
@@ -183,7 +185,7 @@ CALLOUT_OKAY = not (env.GetOption('clean') or env.GetOption('help'))
unknown = opts.UnknownVariables()
if unknown:
- print 'Warning: Used unknown variables:', ', '.join(unknown.keys())
+ print('Warning: Used unknown variables:', ', '.join(unknown.keys()))
apr = str(env['APR'])
apu = str(env['APU'])
diff --git i/build/check.py w/build/check.py
index 2dacb4c..76945af 100755
--- i/build/check.py
+++ w/build/check.py
@@ -22,6 +22,8 @@
# ===================================================================
#
+from __future__ import print_function
+
import sys
import glob
import subprocess
@@ -52,16 +54,16 @@ if __name__ == '__main__':
# Find test responses and run them one by one
for case in glob.glob(testdir + "/testcases/*.response"):
- print "== Testing %s ==" % (case)
+ print("== Testing %s ==" % (case))
try:
subprocess.check_call([SERF_RESPONSE_EXE, case])
except subprocess.CalledProcessError:
- print "ERROR: test case %s failed" % (case)
+ print("ERROR: test case %s failed" % (case))
sys.exit(1)
- print "== Running the unit tests =="
+ print("== Running the unit tests ==")
try:
subprocess.check_call(TEST_ALL_EXE)
except subprocess.CalledProcessError:
- print "ERROR: test(s) failed in test_all"
+ print("ERROR: test(s) failed in test_all")
sys.exit(1)
diff --git i/build/gen_def.py w/build/gen_def.py
index a2222d0..1e006ee 100755
--- i/build/gen_def.py
+++ w/build/gen_def.py
@@ -52,12 +52,13 @@ _types = re.compile(r'^extern const serf_bucket_type_t (serf_[a-z_]*);',
def extract_exports(fname):
- content = open(fname).read()
exports = [ ]
- for name in _funcs.findall(content):
- exports.append(name)
- for name in _types.findall(content):
- exports.append(name)
+ with open(fname) as fd:
+ content = fd.read()
+ for name in _funcs.findall(content):
+ exports.append(name)
+ for name in _types.findall(content):
+ exports.append(name)
return exports
# Blacklist the serf v2 API for now
Index: buckets/hpack_huffman.py
===================================================================
--- buckets/hpack_huffman.py (revision 1875679)
+++ buckets/hpack_huffman.py (working copy)
@@ -29,6 +29,8 @@
# The following script parses the table to a C struct to be used
# by the hpack huffman decoder and encoder in serf.
+from __future__ import print_function
+
import re
rfc_text = """
@@ -391,13 +393,13 @@
bits = int(m.group(4))
if len(bitvals) != bits:
- print '%d vs %d (%s)' %(len(bitvals), bits, bitvals)
+ print('{d} vs {d} ({})'.format(len(bitvals), bits, bitvals))
continue
shift = hex << (32 - bits)
if '{0:032b}'.format(shift)[0:bits] != bitvals:
- print '%s vs %s' % ('{0:032b}'.format(shift)[0:bits], bitvals)
+ print('{} vs {}'.format('{0:032b}'.format(shift)[0:bits], bitvals))
continue
mask = 0
@@ -411,19 +413,19 @@
if len(items) != 257:
raise Exception('There should be exactly 257 items')
-print '/*****************************************************'
-print ' * Generated code *'
-print ' *****************************************************'
-print ' * Please edit hpack_huffman.py instead of this file *'
-print ' * to recreate this file *'
-print ' *****************************************************/'
-print ''
-print 'static const struct serf_hpack_huffman_item_t {'
-print ' apr_uint32_t hval; /* Huffman code shifted to most left bit */'
-print ' apr_uint32_t hmask; /* Mask of bits used in this code */'
-print ' apr_int16_t bits; /* Nr of bits used */'
-print ' apr_int16_t cval; /* The character value of this code */'
-print '} serf_hpack_hm_map[] = {'
+print('/*****************************************************')
+print(' * Generated code *')
+print(' *****************************************************')
+print(' * Please edit hpack_huffman.py instead of this file *')
+print(' * to recreate this file *')
+print(' *****************************************************/')
+print()
+print('static const struct serf_hpack_huffman_item_t {')
+print(' apr_uint32_t hval; /* Huffman code shifted to most left bit */')
+print(' apr_uint32_t hmask; /* Mask of bits used in this code */')
+print(' apr_int16_t bits; /* Nr of bits used */')
+print(' apr_int16_t cval; /* The character value of this code */')
+print('} serf_hpack_hm_map[] = {')
n = 1
map = {}
for i in items:
@@ -431,16 +433,16 @@
comma = ','
else:
comma = ' '
- print ' { 0x%08x, 0x%08x, %2d, %3d }%s /* %s */' % \
- (i[0], i[1], i[2], i[3], comma, i[4])
+ print(' {{ 0x{0:08x}, 0x{1:08x}, {2:2d}, {3:3d} }}{4:s} /* {5:s} */'
+ .format(i[0], i[1], i[2], i[3], comma, i[4]))
map[i[3]] = n-1
n += 1
-print '};'
-print ''
+print('};')
+print()
-print '/* Maps chars to records in serf_hpack_hm_map. */'
-print 'static const apr_int16_t serf_hpack_hm_rmap[] = {'
+print('/* Maps chars to records in serf_hpack_hm_map. */')
+print('static const apr_int16_t serf_hpack_hm_rmap[] = {')
for i in range(0,257):
if i < 256:
comma = ','
@@ -447,9 +449,9 @@
else:
comma = ''
if i % 8 != 7:
- print ' %3d%s' % (map[i], comma),
+ print(' {0:3d}{1:s}'.format(map[i], comma), end='')
else:
- print ' %3d%s' % (map[i], comma)
-print ''
-print '};'
-print ''
+ print(' {0:3d}{1:s}'.format(map[i], comma))
+print()
+print('};')
+print()
Index: test/certs/create_certs.py
===================================================================
--- test/certs/create_certs.py (revision 1875679)
+++ test/certs/create_certs.py (working copy)
@@ -47,11 +47,11 @@
key = crypto.PKey()
key.generate_key(KEY_ALGO, KEY_SIZE)
if passphrase:
- open(keyfile, "wt").write(crypto.dump_privatekey(crypto.FILETYPE_PEM,
+ open(keyfile, "wb").write(crypto.dump_privatekey(crypto.FILETYPE_PEM,
key, KEY_CIPHER,
passphrase))
else:
- open(keyfile, "wt").write(crypto.dump_privatekey(crypto.FILETYPE_PEM,
+ open(keyfile, "wb").write(crypto.dump_privatekey(crypto.FILETYPE_PEM,
key))
return key
@@ -62,7 +62,7 @@
pkcs12.set_certificate(clientcert)
pkcs12.set_privatekey(clientkey)
pkcs12.set_ca_certificates([issuer])
- open(pkcs12file, "wt").write(pkcs12.export(passphrase=passphrase,
+ open(pkcs12file, "wb").write(pkcs12.export(passphrase=passphrase,
iter=2048, maciter=2048))
def create_crl(revokedcert, cakey, cacert, crlfile, next_crl_days=VALID_DAYS):
@@ -69,12 +69,12 @@
crl = crypto.CRL()
revoked = crypto.Revoked()
- serial_number = "%x" % revokedcert.get_serial_number()
+ serial_number = b"%x" % revokedcert.get_serial_number()
now = datetime.utcnow()
- now_str = now.strftime('%Y%m%d%H%M%SZ')
+ now_str = now.strftime('%Y%m%d%H%M%SZ').encode('utf-8')
revoked.set_serial(serial_number)
- revoked.set_reason('unspecified')
+ revoked.set_reason(b'unspecified')
revoked.set_rev_date(now_str) # revoked as of now
crl.add_revoked(revoked)
@@ -84,7 +84,7 @@
# Some very old versions of pyopenssl (such as the one on macOS)
# do not support the 'digest' keyword argument.
exported = crl.export(cacert, cakey, days=next_crl_days)
- open(crlfile, "wt").write(exported)
+ open(crlfile, "wb").write(exported)
# subjectAltName
def create_cert(subjectkey, certfile, issuer=None, issuerkey=None, country='',
@@ -96,7 +96,7 @@
subjectAltName
Array of fully qualified subject alternative names (use OpenSSL syntax):
- For a DNS entry, use: ['DNS:localhost']. Other options are 'email', 'URI', 'IP'.
+ For a DNS entry, use: [b'DNS:localhost']. Other options are b'email', b'URI', b'IP'.
'''
cert = crypto.X509()
@@ -122,34 +122,34 @@
if ca:
cert.add_extensions([
- crypto.X509Extension("basicConstraints", False,
- "CA:TRUE"),
- crypto.X509Extension("subjectKeyIdentifier", False, "hash",
+ crypto.X509Extension(b"basicConstraints", False,
+ b"CA:TRUE"),
+ crypto.X509Extension(b"subjectKeyIdentifier", False, b"hash",
subject=cert)
])
cert.add_extensions([
- crypto.X509Extension("authorityKeyIdentifier", False,
- "keyid:always", issuer=issuer)
+ crypto.X509Extension(b"authorityKeyIdentifier", False,
+ b"keyid:always", issuer=issuer)
])
- if subjectAltName:
+ if subjectAltName is not None:
critical = True if not cn else False
cert.add_extensions([
- crypto.X509Extension('subjectAltName', critical, ", ".join(subjectAltName))])
+ crypto.X509Extension(b'subjectAltName', critical, ", ".join(subjectAltName).encode('utf-8'))])
- if ocsp_responder_url:
+ if ocsp_responder_url is not None:
cert.add_extensions([
- crypto.X509Extension('authorityInfoAccess', False,
- 'OCSP;URI:' + ocsp_responder_url)])
+ crypto.X509Extension(b'authorityInfoAccess', False,
+ 'OCSP;URI:{}'.format(ocsp_responder_url).encode('utf-8'))])
if ocsp_signer:
cert.add_extensions([
- crypto.X509Extension('extendedKeyUsage', True, 'OCSPSigning')
+ crypto.X509Extension(b'extendedKeyUsage', True, b'OCSPSigning')
])
cert.sign(issuerkey, SIGN_ALGO)
- open(certfile, "wt").write(crypto.dump_certificate(crypto.FILETYPE_PEM,
+ open(certfile, "wb").write(crypto.dump_certificate(crypto.FILETYPE_PEM,
cert))
return cert
@@ -156,7 +156,7 @@
if __name__ == '__main__':
# root CA key pair and certificate.
# This key will be used to sign the intermediate CA certificate
- rootcakey = create_key('private/serfrootcakey.pem', 'serftest')
+ rootcakey = create_key('private/serfrootcakey.pem', b'serftest')
rootcacert = create_cert(subjectkey=rootcakey,
certfile='serfrootcacert.pem',
@@ -167,7 +167,7 @@
# intermediate CA key pair and certificate
# This key will be used to sign all server certificates
- cakey = create_key('private/serfcakey.pem', 'serftest')
+ cakey = create_key('private/serfcakey.pem', b'serftest')
cacert = create_cert(subjectkey=cakey, certfile='serfcacert.pem',
issuer=rootcacert, issuerkey=rootcakey,
@@ -178,7 +178,7 @@
# server key pair
# server certificate, no errors
- serverkey = create_key('private/serfserverkey.pem', 'serftest')
+ serverkey = create_key('private/serfserverkey.pem', b'serftest')
servercert = create_cert(subjectkey=serverkey,
certfile='serfservercert.pem',
@@ -247,7 +247,7 @@
ocsp_signer=True)
# client key pair and certificate
- clientkey = create_key('private/serfclientkey.pem', 'serftest')
+ clientkey = create_key('private/serfclientkey.pem', b'serftest')
clientcert = create_cert(subjectkey=clientkey,
certfile='serfclientcert.pem',
@@ -258,10 +258,10 @@
email='[email protected]')
clientpkcs12 = create_pkcs12(clientkey, clientcert, cacert,
- 'serfclientcert.p12', 'serftest')
+ 'serfclientcert.p12', b'serftest')
# Note that this creates a v1 CRL file without extensions set, and with
# MD5 hash. Not ideal, but pyOpenSSL doesn't support more than this.
#
# crl
- crl = create_crl(servercert, cakey, cacert, 'serfservercrl.pem')
+ crl = create_crl(servercert, cakey, cacert, b'serfservercrl.pem')