summaryrefslogtreecommitdiff
path: root/setup.py
diff options
context:
space:
mode:
authorChristian Heimes <christian@python.org>2018-01-20 13:19:21 +0100
committerGitHub <noreply@github.com>2018-01-20 13:19:21 +0100
commitff5be6e8100276647e0077e80869fc022d1bb53f (patch)
tree70c1b01fa7040254bf81026e177a53862e7192b4 /setup.py
parentd911e40e788fb679723d78b6ea11cabf46caed5a (diff)
downloadcpython-git-ff5be6e8100276647e0077e80869fc022d1bb53f.tar.gz
bpo-32598: Use autoconf to detect usable OpenSSL (#5242)
Add https://www.gnu.org/software/autoconf-archive/ax_check_openssl.html to auto-detect compiler flags, linker flags and libraries to compile OpenSSL extensions. The M4 macro uses pkg-config and falls back to manual detection. Add autoconf magic to detect usable X509_VERIFY_PARAM_set1_host() and related functions. Refactor setup.py to use new config vars to compile _ssl and _hashlib modules. Signed-off-by: Christian Heimes <christian@python.org>
Diffstat (limited to 'setup.py')
-rw-r--r--setup.py128
1 files changed, 62 insertions, 66 deletions
diff --git a/setup.py b/setup.py
index 8e98fdcb7e..c23628a2a9 100644
--- a/setup.py
+++ b/setup.py
@@ -860,74 +860,15 @@ class PyBuildExt(build_ext):
exts.append( Extension('_socket', ['socketmodule.c'],
depends = ['socketmodule.h']) )
# Detect SSL support for the socket module (via _ssl)
- search_for_ssl_incs_in = [
- '/usr/local/ssl/include',
- '/usr/contrib/ssl/include/'
- ]
- ssl_incs = find_file('openssl/ssl.h', inc_dirs,
- search_for_ssl_incs_in
- )
- if ssl_incs is not None:
- krb5_h = find_file('krb5.h', inc_dirs,
- ['/usr/kerberos/include'])
- if krb5_h:
- ssl_incs += krb5_h
- ssl_libs = find_library_file(self.compiler, 'ssl',lib_dirs,
- ['/usr/local/ssl/lib',
- '/usr/contrib/ssl/lib/'
- ] )
-
- if (ssl_incs is not None and
- ssl_libs is not None):
- exts.append( Extension('_ssl', ['_ssl.c'],
- include_dirs = ssl_incs,
- library_dirs = ssl_libs,
- libraries = ['ssl', 'crypto'],
- depends = ['socketmodule.h']), )
+ ssl_ext, hashlib_ext = self._detect_openssl(inc_dirs, lib_dirs)
+ if ssl_ext is not None:
+ exts.append(ssl_ext)
else:
missing.append('_ssl')
-
- # find out which version of OpenSSL we have
- openssl_ver = 0
- openssl_ver_re = re.compile(
- r'^\s*#\s*define\s+OPENSSL_VERSION_NUMBER\s+(0x[0-9a-fA-F]+)' )
-
- # look for the openssl version header on the compiler search path.
- opensslv_h = find_file('openssl/opensslv.h', [],
- inc_dirs + search_for_ssl_incs_in)
- if opensslv_h:
- name = os.path.join(opensslv_h[0], 'openssl/opensslv.h')
- if host_platform == 'darwin' and is_macosx_sdk_path(name):
- name = os.path.join(macosx_sdk_root(), name[1:])
- try:
- with open(name, 'r') as incfile:
- for line in incfile:
- m = openssl_ver_re.match(line)
- if m:
- openssl_ver = int(m.group(1), 16)
- break
- except IOError as msg:
- print("IOError while reading opensshv.h:", msg)
-
- #print('openssl_ver = 0x%08x' % openssl_ver)
- min_openssl_ver = 0x00907000
- have_any_openssl = ssl_incs is not None and ssl_libs is not None
- have_usable_openssl = (have_any_openssl and
- openssl_ver >= min_openssl_ver)
-
- if have_any_openssl:
- if have_usable_openssl:
- # The _hashlib module wraps optimized implementations
- # of hash functions from the OpenSSL library.
- exts.append( Extension('_hashlib', ['_hashopenssl.c'],
- depends = ['hashlib.h'],
- include_dirs = ssl_incs,
- library_dirs = ssl_libs,
- libraries = ['ssl', 'crypto']) )
- else:
- print("warning: openssl 0x%08x is too old for _hashlib" %
- openssl_ver)
- missing.append('_hashlib')
+ if hashlib_ext is not None:
+ exts.append(hashlib_ext)
+ else:
+ missing.append('_hashlib')
# We always compile these even when OpenSSL is available (issue #14693).
# It's harmless and the object code is tiny (40-50 KiB per module,
@@ -2183,6 +2124,61 @@ class PyBuildExt(build_ext):
)
return ext
+ def _detect_openssl(self, inc_dirs, lib_dirs):
+ config_vars = sysconfig.get_config_vars()
+
+ def split_var(name, sep):
+ # poor man's shlex, the re module is not available yet.
+ value = config_vars.get(name)
+ if not value:
+ return ()
+ # This trick works because ax_check_openssl uses --libs-only-L,
+ # --libs-only-l, and --cflags-only-I.
+ value = ' ' + value
+ sep = ' ' + sep
+ return [v.strip() for v in value.split(sep) if v.strip()]
+
+ openssl_includes = split_var('OPENSSL_INCLUDES', '-I')
+ openssl_libdirs = split_var('OPENSSL_LDFLAGS', '-L')
+ openssl_libs = split_var('OPENSSL_LIBS', '-l')
+ if not openssl_libs:
+ # libssl and libcrypto not found
+ return None, None
+
+ # Find OpenSSL includes
+ ssl_incs = find_file(
+ 'openssl/ssl.h', inc_dirs, openssl_includes
+ )
+ if ssl_incs is None:
+ return None, None
+
+ # OpenSSL 1.0.2 uses Kerberos for KRB5 ciphers
+ krb5_h = find_file(
+ 'krb5.h', inc_dirs,
+ ['/usr/kerberos/include']
+ )
+ if krb5_h:
+ ssl_incs.extend(krb5_h)
+
+ ssl_ext = Extension(
+ '_ssl', ['_ssl.c'],
+ include_dirs=openssl_includes,
+ library_dirs=openssl_libdirs,
+ libraries=openssl_libs,
+ depends=['socketmodule.h']
+ )
+
+ hashlib_ext = Extension(
+ '_hashlib', ['_hashopenssl.c'],
+ depends=['hashlib.h'],
+ include_dirs=openssl_includes,
+ library_dirs=openssl_libdirs,
+ libraries=openssl_libs,
+ )
+
+ return ssl_ext, hashlib_ext
+
+
class PyBuildInstall(install):
# Suppress the warning about installation into the lib_dynload
# directory, which is not in sys.path when running Python during