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>
This commit is contained in:
Christian Heimes 2018-01-20 13:19:21 +01:00 committed by GitHub
parent d911e40e78
commit ff5be6e810
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 585 additions and 83 deletions

View File

@ -181,6 +181,11 @@ RUNSHARED= @RUNSHARED@
# ensurepip options # ensurepip options
ENSUREPIP= @ENSUREPIP@ ENSUREPIP= @ENSUREPIP@
# OpenSSL options for setup.py so sysconfig can pick up AC_SUBST() vars.
OPENSSL_INCLUDES=@OPENSSL_INCLUDES@
OPENSSL_LIBS=@OPENSSL_LIBS@
OPENSSL_LDFLAGS=@OPENSSL_LDFLAGS@
# Modes for directories, executables and data files created by the # Modes for directories, executables and data files created by the
# install process. Default to user-only-writable for all file types. # install process. Default to user-only-writable for all file types.
DIRMODE= 755 DIRMODE= 755

View File

@ -0,0 +1,3 @@
Use autoconf to detect OpenSSL libs, headers and supported features. The
ax_check_openssl M4 macro uses pkg-config to locate OpenSSL and falls back
to manual search.

View File

@ -64,6 +64,13 @@ static PySocketModule_APIObject PySocketModule;
#include "openssl/rand.h" #include "openssl/rand.h"
#include "openssl/bio.h" #include "openssl/bio.h"
/* Set HAVE_X509_VERIFY_PARAM_SET1_HOST for non-autoconf builds */
#ifndef HAVE_X509_VERIFY_PARAM_SET1_HOST
# if !defined(LIBRESSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER > 0x1000200fL
# define HAVE_X509_VERIFY_PARAM_SET1_HOST
# endif
#endif
/* SSL error object */ /* SSL error object */
static PyObject *PySSLErrorObject; static PyObject *PySSLErrorObject;
static PyObject *PySSLCertVerificationErrorObject; static PyObject *PySSLCertVerificationErrorObject;

77
aclocal.m4 vendored
View File

@ -12,9 +12,9 @@
# PARTICULAR PURPOSE. # PARTICULAR PURPOSE.
m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
dnl pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- # pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
dnl serial 11 (pkg-config-0.29) # serial 11 (pkg-config-0.29.1)
dnl
dnl Copyright © 2004 Scott James Remnant <scott@netsplit.com>. dnl Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
dnl Copyright © 2012-2015 Dan Nicholson <dbn.lists@gmail.com> dnl Copyright © 2012-2015 Dan Nicholson <dbn.lists@gmail.com>
dnl dnl
@ -55,7 +55,7 @@ dnl
dnl See the "Since" comment for each macro you use to see what version dnl See the "Since" comment for each macro you use to see what version
dnl of the macros you require. dnl of the macros you require.
m4_defun([PKG_PREREQ], m4_defun([PKG_PREREQ],
[m4_define([PKG_MACROS_VERSION], [0.29]) [m4_define([PKG_MACROS_VERSION], [0.29.1])
m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1, m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1,
[m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])]) [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])])
])dnl PKG_PREREQ ])dnl PKG_PREREQ
@ -288,3 +288,72 @@ AS_VAR_COPY([$1], [pkg_cv_][$1])
AS_VAR_IF([$1], [""], [$5], [$4])dnl AS_VAR_IF([$1], [""], [$5], [$4])dnl
])dnl PKG_CHECK_VAR ])dnl PKG_CHECK_VAR
dnl PKG_WITH_MODULES(VARIABLE-PREFIX, MODULES,
dnl [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND],
dnl [DESCRIPTION], [DEFAULT])
dnl ------------------------------------------
dnl
dnl Prepare a "--with-" configure option using the lowercase
dnl [VARIABLE-PREFIX] name, merging the behaviour of AC_ARG_WITH and
dnl PKG_CHECK_MODULES in a single macro.
AC_DEFUN([PKG_WITH_MODULES],
[
m4_pushdef([with_arg], m4_tolower([$1]))
m4_pushdef([description],
[m4_default([$5], [build with ]with_arg[ support])])
m4_pushdef([def_arg], [m4_default([$6], [auto])])
m4_pushdef([def_action_if_found], [AS_TR_SH([with_]with_arg)=yes])
m4_pushdef([def_action_if_not_found], [AS_TR_SH([with_]with_arg)=no])
m4_case(def_arg,
[yes],[m4_pushdef([with_without], [--without-]with_arg)],
[m4_pushdef([with_without],[--with-]with_arg)])
AC_ARG_WITH(with_arg,
AS_HELP_STRING(with_without, description[ @<:@default=]def_arg[@:>@]),,
[AS_TR_SH([with_]with_arg)=def_arg])
AS_CASE([$AS_TR_SH([with_]with_arg)],
[yes],[PKG_CHECK_MODULES([$1],[$2],$3,$4)],
[auto],[PKG_CHECK_MODULES([$1],[$2],
[m4_n([def_action_if_found]) $3],
[m4_n([def_action_if_not_found]) $4])])
m4_popdef([with_arg])
m4_popdef([description])
m4_popdef([def_arg])
])dnl PKG_WITH_MODULES
dnl PKG_HAVE_WITH_MODULES(VARIABLE-PREFIX, MODULES,
dnl [DESCRIPTION], [DEFAULT])
dnl -----------------------------------------------
dnl
dnl Convenience macro to trigger AM_CONDITIONAL after PKG_WITH_MODULES
dnl check._[VARIABLE-PREFIX] is exported as make variable.
AC_DEFUN([PKG_HAVE_WITH_MODULES],
[
PKG_WITH_MODULES([$1],[$2],,,[$3],[$4])
AM_CONDITIONAL([HAVE_][$1],
[test "$AS_TR_SH([with_]m4_tolower([$1]))" = "yes"])
])dnl PKG_HAVE_WITH_MODULES
dnl PKG_HAVE_DEFINE_WITH_MODULES(VARIABLE-PREFIX, MODULES,
dnl [DESCRIPTION], [DEFAULT])
dnl ------------------------------------------------------
dnl
dnl Convenience macro to run AM_CONDITIONAL and AC_DEFINE after
dnl PKG_WITH_MODULES check. HAVE_[VARIABLE-PREFIX] is exported as make
dnl and preprocessor variable.
AC_DEFUN([PKG_HAVE_DEFINE_WITH_MODULES],
[
PKG_HAVE_WITH_MODULES([$1],[$2],[$3],[$4])
AS_IF([test "$AS_TR_SH([with_]m4_tolower([$1]))" = "yes"],
[AC_DEFINE([HAVE_][$1], 1, [Enable ]m4_tolower([$1])[ support])])
])dnl PKG_HAVE_DEFINE_WITH_MODULES
m4_include([m4/ax_check_openssl.m4])

280
configure vendored
View File

@ -623,6 +623,9 @@ ac_includes_default="\
#endif" #endif"
ac_subst_vars='LTLIBOBJS ac_subst_vars='LTLIBOBJS
OPENSSL_LDFLAGS
OPENSSL_LIBS
OPENSSL_INCLUDES
ENSUREPIP ENSUREPIP
SRCDIRS SRCDIRS
THREADHEADERS THREADHEADERS
@ -778,7 +781,6 @@ infodir
docdir docdir
oldincludedir oldincludedir
includedir includedir
runstatedir
localstatedir localstatedir
sharedstatedir sharedstatedir
sysconfdir sysconfdir
@ -837,6 +839,7 @@ with_libc
enable_big_digits enable_big_digits
with_computed_gotos with_computed_gotos
with_ensurepip with_ensurepip
with_openssl
' '
ac_precious_vars='build_alias ac_precious_vars='build_alias
host_alias host_alias
@ -889,7 +892,6 @@ datadir='${datarootdir}'
sysconfdir='${prefix}/etc' sysconfdir='${prefix}/etc'
sharedstatedir='${prefix}/com' sharedstatedir='${prefix}/com'
localstatedir='${prefix}/var' localstatedir='${prefix}/var'
runstatedir='${localstatedir}/run'
includedir='${prefix}/include' includedir='${prefix}/include'
oldincludedir='/usr/include' oldincludedir='/usr/include'
docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
@ -1142,15 +1144,6 @@ do
| -silent | --silent | --silen | --sile | --sil) | -silent | --silent | --silen | --sile | --sil)
silent=yes ;; silent=yes ;;
-runstatedir | --runstatedir | --runstatedi | --runstated \
| --runstate | --runstat | --runsta | --runst | --runs \
| --run | --ru | --r)
ac_prev=runstatedir ;;
-runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
| --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
| --run=* | --ru=* | --r=*)
runstatedir=$ac_optarg ;;
-sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
ac_prev=sbindir ;; ac_prev=sbindir ;;
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
@ -1288,7 +1281,7 @@ fi
for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
datadir sysconfdir sharedstatedir localstatedir includedir \ datadir sysconfdir sharedstatedir localstatedir includedir \
oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
libdir localedir mandir runstatedir libdir localedir mandir
do do
eval ac_val=\$$ac_var eval ac_val=\$$ac_var
# Remove trailing slashes. # Remove trailing slashes.
@ -1441,7 +1434,6 @@ Fine tuning of the installation directories:
--sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
--localstatedir=DIR modifiable single-machine data [PREFIX/var] --localstatedir=DIR modifiable single-machine data [PREFIX/var]
--runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run]
--libdir=DIR object code libraries [EPREFIX/lib] --libdir=DIR object code libraries [EPREFIX/lib]
--includedir=DIR C header files [PREFIX/include] --includedir=DIR C header files [PREFIX/include]
--oldincludedir=DIR C header files for non-gcc [/usr/include] --oldincludedir=DIR C header files for non-gcc [/usr/include]
@ -1545,6 +1537,7 @@ Optional Packages:
default on supported compilers) default on supported compilers)
--with(out)-ensurepip=[=upgrade] --with(out)-ensurepip=[=upgrade]
"install" or "upgrade" using bundled pip "install" or "upgrade" using bundled pip
--with-openssl=DIR root of the OpenSSL directory
Some influential environment variables: Some influential environment variables:
MACHDEP name for machine-dependent library files MACHDEP name for machine-dependent library files
@ -2687,6 +2680,8 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
if test "$srcdir" != . -a "$srcdir" != "$(pwd)"; then if test "$srcdir" != . -a "$srcdir" != "$(pwd)"; then
# If we're building out-of-tree, we need to make sure the following # If we're building out-of-tree, we need to make sure the following
# resources get picked up before their $srcdir counterparts. # resources get picked up before their $srcdir counterparts.
@ -16681,6 +16676,265 @@ $as_echo "#define HAVE_GETRANDOM 1" >>confdefs.h
fi fi
# Check for usable OpenSSL
found=false
# Check whether --with-openssl was given.
if test "${with_openssl+set}" = set; then :
withval=$with_openssl;
case "$withval" in
"" | y | ye | yes | n | no)
as_fn_error $? "Invalid --with-openssl value" "$LINENO" 5
;;
*) ssldirs="$withval"
;;
esac
else
# if pkg-config is installed and openssl has installed a .pc file,
# then use that information and don't search ssldirs
if test -n "$ac_tool_prefix"; then
# Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args.
set dummy ${ac_tool_prefix}pkg-config; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_PKG_CONFIG+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$PKG_CONFIG"; then
ac_cv_prog_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_PKG_CONFIG="${ac_tool_prefix}pkg-config"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
IFS=$as_save_IFS
fi
fi
PKG_CONFIG=$ac_cv_prog_PKG_CONFIG
if test -n "$PKG_CONFIG"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5
$as_echo "$PKG_CONFIG" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
fi
if test -z "$ac_cv_prog_PKG_CONFIG"; then
ac_ct_PKG_CONFIG=$PKG_CONFIG
# Extract the first word of "pkg-config", so it can be a program name with args.
set dummy pkg-config; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_ac_ct_PKG_CONFIG+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$ac_ct_PKG_CONFIG"; then
ac_cv_prog_ac_ct_PKG_CONFIG="$ac_ct_PKG_CONFIG" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_PKG_CONFIG="pkg-config"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
IFS=$as_save_IFS
fi
fi
ac_ct_PKG_CONFIG=$ac_cv_prog_ac_ct_PKG_CONFIG
if test -n "$ac_ct_PKG_CONFIG"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_PKG_CONFIG" >&5
$as_echo "$ac_ct_PKG_CONFIG" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
if test "x$ac_ct_PKG_CONFIG" = x; then
PKG_CONFIG=""
else
case $cross_compiling:$ac_tool_warned in
yes:)
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
ac_tool_warned=yes ;;
esac
PKG_CONFIG=$ac_ct_PKG_CONFIG
fi
else
PKG_CONFIG="$ac_cv_prog_PKG_CONFIG"
fi
if test x"$PKG_CONFIG" != x""; then
OPENSSL_LDFLAGS=`$PKG_CONFIG openssl --libs-only-L 2>/dev/null`
if test $? = 0; then
OPENSSL_LIBS=`$PKG_CONFIG openssl --libs-only-l 2>/dev/null`
OPENSSL_INCLUDES=`$PKG_CONFIG openssl --cflags-only-I 2>/dev/null`
found=true
fi
fi
# no such luck; use some default ssldirs
if ! $found; then
ssldirs="/usr/local/ssl /usr/lib/ssl /usr/ssl /usr/pkg /usr/local /usr"
fi
fi
# note that we #include <openssl/foo.h>, so the OpenSSL headers have to be in
# an 'openssl' subdirectory
if ! $found; then
OPENSSL_INCLUDES=
for ssldir in $ssldirs; do
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for openssl/ssl.h in $ssldir" >&5
$as_echo_n "checking for openssl/ssl.h in $ssldir... " >&6; }
if test -f "$ssldir/include/openssl/ssl.h"; then
OPENSSL_INCLUDES="-I$ssldir/include"
OPENSSL_LDFLAGS="-L$ssldir/lib"
OPENSSL_LIBS="-lssl -lcrypto"
found=true
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
break
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
done
# if the file wasn't found, well, go ahead and try the link anyway -- maybe
# it will just work!
fi
# try the preprocessor and linker with our new flags,
# being careful not to pollute the global LIBS, LDFLAGS, and CPPFLAGS
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether compiling and linking against OpenSSL works" >&5
$as_echo_n "checking whether compiling and linking against OpenSSL works... " >&6; }
echo "Trying link with OPENSSL_LDFLAGS=$OPENSSL_LDFLAGS;" \
"OPENSSL_LIBS=$OPENSSL_LIBS; OPENSSL_INCLUDES=$OPENSSL_INCLUDES" >&5
save_LIBS="$LIBS"
save_LDFLAGS="$LDFLAGS"
save_CPPFLAGS="$CPPFLAGS"
LDFLAGS="$LDFLAGS $OPENSSL_LDFLAGS"
LIBS="$OPENSSL_LIBS $LIBS"
CPPFLAGS="$OPENSSL_INCLUDES $CPPFLAGS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <openssl/ssl.h>
int
main ()
{
SSL_new(NULL)
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
have_openssl=yes
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
have_openssl=no
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
CPPFLAGS="$save_CPPFLAGS"
LDFLAGS="$save_LDFLAGS"
LIBS="$save_LIBS"
if test "$have_openssl" = yes; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for X509_VERIFY_PARAM_set1_host in libssl" >&5
$as_echo_n "checking for X509_VERIFY_PARAM_set1_host in libssl... " >&6; }
save_LIBS="$LIBS"
save_LDFLAGS="$LDFLAGS"
save_CPPFLAGS="$CPPFLAGS"
LDFLAGS="$LDFLAGS $OPENSSL_LDFLAGS"
LIBS="$OPENSSL_LIBS $LIBS"
CPPFLAGS="$OPENSSL_INCLUDES $CPPFLAGS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <openssl/x509_vfy.h>
int
main ()
{
X509_VERIFY_PARAM *p = X509_VERIFY_PARAM_new();
X509_VERIFY_PARAM_set1_host(p, "localhost", 0);
X509_VERIFY_PARAM_set1_ip_asc(p, "127.0.0.1");
X509_VERIFY_PARAM_set_hostflags(p, 0);
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
ac_cv_has_x509_verify_param_set1_host=yes
else
ac_cv_has_x509_verify_param_set1_host=no
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_has_x509_verify_param_set1_host" >&5
$as_echo "$ac_cv_has_x509_verify_param_set1_host" >&6; }
if test "$ac_cv_has_x509_verify_param_set1_host" = "yes"; then
$as_echo "#define HAVE_X509_VERIFY_PARAM_SET1_HOST 1" >>confdefs.h
fi
CPPFLAGS="$save_CPPFLAGS"
LDFLAGS="$save_LDFLAGS"
LIBS="$save_LIBS"
fi
# generate output files # generate output files
ac_config_files="$ac_config_files Makefile.pre Misc/python.pc Misc/python-config.sh" ac_config_files="$ac_config_files Makefile.pre Misc/python.pc Misc/python-config.sh"

View File

@ -9,6 +9,8 @@ AC_PREREQ(2.65)
AC_INIT(python, PYTHON_VERSION, https://bugs.python.org/) AC_INIT(python, PYTHON_VERSION, https://bugs.python.org/)
AC_CONFIG_MACRO_DIR(m4)
AC_SUBST(BASECPPFLAGS) AC_SUBST(BASECPPFLAGS)
if test "$srcdir" != . -a "$srcdir" != "$(pwd)"; then if test "$srcdir" != . -a "$srcdir" != "$(pwd)"; then
# If we're building out-of-tree, we need to make sure the following # If we're building out-of-tree, we need to make sure the following
@ -5460,6 +5462,45 @@ if test "$have_getrandom" = yes; then
[Define to 1 if the getrandom() function is available]) [Define to 1 if the getrandom() function is available])
fi fi
# Check for usable OpenSSL
AX_CHECK_OPENSSL([have_openssl=yes],[have_openssl=no])
if test "$have_openssl" = yes; then
AC_MSG_CHECKING([for X509_VERIFY_PARAM_set1_host in libssl])
save_LIBS="$LIBS"
save_LDFLAGS="$LDFLAGS"
save_CPPFLAGS="$CPPFLAGS"
LDFLAGS="$LDFLAGS $OPENSSL_LDFLAGS"
LIBS="$OPENSSL_LIBS $LIBS"
CPPFLAGS="$OPENSSL_INCLUDES $CPPFLAGS"
AC_LINK_IFELSE([AC_LANG_PROGRAM([
[#include <openssl/x509_vfy.h>]
], [
[X509_VERIFY_PARAM *p = X509_VERIFY_PARAM_new();]
[X509_VERIFY_PARAM_set1_host(p, "localhost", 0);]
[X509_VERIFY_PARAM_set1_ip_asc(p, "127.0.0.1");]
[X509_VERIFY_PARAM_set_hostflags(p, 0);]
])
],
[
ac_cv_has_x509_verify_param_set1_host=yes
],
[
ac_cv_has_x509_verify_param_set1_host=no
])
AC_MSG_RESULT($ac_cv_has_x509_verify_param_set1_host)
if test "$ac_cv_has_x509_verify_param_set1_host" = "yes"; then
AC_DEFINE(HAVE_X509_VERIFY_PARAM_SET1_HOST, 1,
[Define if libssl has X509_VERIFY_PARAM_set1_host and related function])
fi
CPPFLAGS="$save_CPPFLAGS"
LDFLAGS="$save_LDFLAGS"
LIBS="$save_LIBS"
fi
# generate output files # generate output files
AC_CONFIG_FILES(Makefile.pre Misc/python.pc Misc/python-config.sh) AC_CONFIG_FILES(Makefile.pre Misc/python.pc Misc/python-config.sh)
AC_CONFIG_FILES([Modules/ld_so_aix], [chmod +x Modules/ld_so_aix]) AC_CONFIG_FILES([Modules/ld_so_aix], [chmod +x Modules/ld_so_aix])

124
m4/ax_check_openssl.m4 Normal file
View File

@ -0,0 +1,124 @@
# ===========================================================================
# https://www.gnu.org/software/autoconf-archive/ax_check_openssl.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_CHECK_OPENSSL([action-if-found[, action-if-not-found]])
#
# DESCRIPTION
#
# Look for OpenSSL in a number of default spots, or in a user-selected
# spot (via --with-openssl). Sets
#
# OPENSSL_INCLUDES to the include directives required
# OPENSSL_LIBS to the -l directives required
# OPENSSL_LDFLAGS to the -L or -R flags required
#
# and calls ACTION-IF-FOUND or ACTION-IF-NOT-FOUND appropriately
#
# This macro sets OPENSSL_INCLUDES such that source files should use the
# openssl/ directory in include directives:
#
# #include <openssl/hmac.h>
#
# LICENSE
#
# Copyright (c) 2009,2010 Zmanda Inc. <http://www.zmanda.com/>
# Copyright (c) 2009,2010 Dustin J. Mitchell <dustin@zmanda.com>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved. This file is offered as-is, without any
# warranty.
#serial 10
AU_ALIAS([CHECK_SSL], [AX_CHECK_OPENSSL])
AC_DEFUN([AX_CHECK_OPENSSL], [
found=false
AC_ARG_WITH([openssl],
[AS_HELP_STRING([--with-openssl=DIR],
[root of the OpenSSL directory])],
[
case "$withval" in
"" | y | ye | yes | n | no)
AC_MSG_ERROR([Invalid --with-openssl value])
;;
*) ssldirs="$withval"
;;
esac
], [
# if pkg-config is installed and openssl has installed a .pc file,
# then use that information and don't search ssldirs
AC_CHECK_TOOL([PKG_CONFIG], [pkg-config])
if test x"$PKG_CONFIG" != x""; then
OPENSSL_LDFLAGS=`$PKG_CONFIG openssl --libs-only-L 2>/dev/null`
if test $? = 0; then
OPENSSL_LIBS=`$PKG_CONFIG openssl --libs-only-l 2>/dev/null`
OPENSSL_INCLUDES=`$PKG_CONFIG openssl --cflags-only-I 2>/dev/null`
found=true
fi
fi
# no such luck; use some default ssldirs
if ! $found; then
ssldirs="/usr/local/ssl /usr/lib/ssl /usr/ssl /usr/pkg /usr/local /usr"
fi
]
)
# note that we #include <openssl/foo.h>, so the OpenSSL headers have to be in
# an 'openssl' subdirectory
if ! $found; then
OPENSSL_INCLUDES=
for ssldir in $ssldirs; do
AC_MSG_CHECKING([for openssl/ssl.h in $ssldir])
if test -f "$ssldir/include/openssl/ssl.h"; then
OPENSSL_INCLUDES="-I$ssldir/include"
OPENSSL_LDFLAGS="-L$ssldir/lib"
OPENSSL_LIBS="-lssl -lcrypto"
found=true
AC_MSG_RESULT([yes])
break
else
AC_MSG_RESULT([no])
fi
done
# if the file wasn't found, well, go ahead and try the link anyway -- maybe
# it will just work!
fi
# try the preprocessor and linker with our new flags,
# being careful not to pollute the global LIBS, LDFLAGS, and CPPFLAGS
AC_MSG_CHECKING([whether compiling and linking against OpenSSL works])
echo "Trying link with OPENSSL_LDFLAGS=$OPENSSL_LDFLAGS;" \
"OPENSSL_LIBS=$OPENSSL_LIBS; OPENSSL_INCLUDES=$OPENSSL_INCLUDES" >&AS_MESSAGE_LOG_FD
save_LIBS="$LIBS"
save_LDFLAGS="$LDFLAGS"
save_CPPFLAGS="$CPPFLAGS"
LDFLAGS="$LDFLAGS $OPENSSL_LDFLAGS"
LIBS="$OPENSSL_LIBS $LIBS"
CPPFLAGS="$OPENSSL_INCLUDES $CPPFLAGS"
AC_LINK_IFELSE(
[AC_LANG_PROGRAM([#include <openssl/ssl.h>], [SSL_new(NULL)])],
[
AC_MSG_RESULT([yes])
$1
], [
AC_MSG_RESULT([no])
$2
])
CPPFLAGS="$save_CPPFLAGS"
LDFLAGS="$save_LDFLAGS"
LIBS="$save_LIBS"
AC_SUBST([OPENSSL_INCLUDES])
AC_SUBST([OPENSSL_LIBS])
AC_SUBST([OPENSSL_LDFLAGS])
])

View File

@ -1237,6 +1237,9 @@
/* Define to 1 if you have the `writev' function. */ /* Define to 1 if you have the `writev' function. */
#undef HAVE_WRITEV #undef HAVE_WRITEV
/* Define if libssl has X509_VERIFY_PARAM_set1_host and related function */
#undef HAVE_X509_VERIFY_PARAM_SET1_HOST
/* Define if the zlib library has inflateCopy */ /* Define if the zlib library has inflateCopy */
#undef HAVE_ZLIB_COPY #undef HAVE_ZLIB_COPY

124
setup.py
View File

@ -860,73 +860,14 @@ class PyBuildExt(build_ext):
exts.append( Extension('_socket', ['socketmodule.c'], exts.append( Extension('_socket', ['socketmodule.c'],
depends = ['socketmodule.h']) ) depends = ['socketmodule.h']) )
# Detect SSL support for the socket module (via _ssl) # Detect SSL support for the socket module (via _ssl)
search_for_ssl_incs_in = [ ssl_ext, hashlib_ext = self._detect_openssl(inc_dirs, lib_dirs)
'/usr/local/ssl/include', if ssl_ext is not None:
'/usr/contrib/ssl/include/' exts.append(ssl_ext)
]
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']), )
else: else:
missing.append('_ssl') missing.append('_ssl')
if hashlib_ext is not None:
# find out which version of OpenSSL we have exts.append(hashlib_ext)
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: else:
print("warning: openssl 0x%08x is too old for _hashlib" %
openssl_ver)
missing.append('_hashlib') missing.append('_hashlib')
# We always compile these even when OpenSSL is available (issue #14693). # We always compile these even when OpenSSL is available (issue #14693).
@ -2183,6 +2124,61 @@ class PyBuildExt(build_ext):
) )
return 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): class PyBuildInstall(install):
# Suppress the warning about installation into the lib_dynload # Suppress the warning about installation into the lib_dynload
# directory, which is not in sys.path when running Python during # directory, which is not in sys.path when running Python during