diff --git a/Makefile.pre.in b/Makefile.pre.in index 994e8611e13..d1512671735 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -181,6 +181,11 @@ RUNSHARED= @RUNSHARED@ # ensurepip options 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 # install process. Default to user-only-writable for all file types. DIRMODE= 755 diff --git a/Misc/NEWS.d/next/Build/2018-01-19-14-50-19.bpo-32598.hP7bMV.rst b/Misc/NEWS.d/next/Build/2018-01-19-14-50-19.bpo-32598.hP7bMV.rst new file mode 100644 index 00000000000..4b05e73feef --- /dev/null +++ b/Misc/NEWS.d/next/Build/2018-01-19-14-50-19.bpo-32598.hP7bMV.rst @@ -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. diff --git a/Modules/_ssl.c b/Modules/_ssl.c index 380dd1b72db..c5eec7eded6 100644 --- a/Modules/_ssl.c +++ b/Modules/_ssl.c @@ -64,6 +64,13 @@ static PySocketModule_APIObject PySocketModule; #include "openssl/rand.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 */ static PyObject *PySSLErrorObject; static PyObject *PySSLCertVerificationErrorObject; diff --git a/aclocal.m4 b/aclocal.m4 index 61b2539d2e9..09694962914 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -12,9 +12,9 @@ # PARTICULAR PURPOSE. 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 -*- -dnl serial 11 (pkg-config-0.29) -dnl +# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- +# serial 11 (pkg-config-0.29.1) + dnl Copyright © 2004 Scott James Remnant . dnl Copyright © 2012-2015 Dan Nicholson dnl @@ -55,7 +55,7 @@ dnl dnl See the "Since" comment for each macro you use to see what version dnl of the macros you require. 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_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])]) ])dnl PKG_PREREQ @@ -288,3 +288,72 @@ AS_VAR_COPY([$1], [pkg_cv_][$1]) AS_VAR_IF([$1], [""], [$5], [$4])dnl ])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]) diff --git a/configure b/configure index 9286443124a..420c07639b5 100755 --- a/configure +++ b/configure @@ -623,6 +623,9 @@ ac_includes_default="\ #endif" ac_subst_vars='LTLIBOBJS +OPENSSL_LDFLAGS +OPENSSL_LIBS +OPENSSL_INCLUDES ENSUREPIP SRCDIRS THREADHEADERS @@ -778,7 +781,6 @@ infodir docdir oldincludedir includedir -runstatedir localstatedir sharedstatedir sysconfdir @@ -837,6 +839,7 @@ with_libc enable_big_digits with_computed_gotos with_ensurepip +with_openssl ' ac_precious_vars='build_alias host_alias @@ -889,7 +892,6 @@ datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' -runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' @@ -1142,15 +1144,6 @@ do | -silent | --silent | --silen | --sile | --sil) 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) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ @@ -1288,7 +1281,7 @@ fi for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir runstatedir + libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. @@ -1441,7 +1434,6 @@ Fine tuning of the installation directories: --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] - --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] @@ -1545,6 +1537,7 @@ Optional Packages: default on supported compilers) --with(out)-ensurepip=[=upgrade] "install" or "upgrade" using bundled pip + --with-openssl=DIR root of the OpenSSL directory Some influential environment variables: 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 we're building out-of-tree, we need to make sure the following # resources get picked up before their $srcdir counterparts. @@ -16681,6 +16676,265 @@ $as_echo "#define HAVE_GETRANDOM 1" >>confdefs.h 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 , 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 +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 + +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 ac_config_files="$ac_config_files Makefile.pre Misc/python.pc Misc/python-config.sh" diff --git a/configure.ac b/configure.ac index 1894e21f304..39e2e8e769e 100644 --- a/configure.ac +++ b/configure.ac @@ -9,6 +9,8 @@ AC_PREREQ(2.65) AC_INIT(python, PYTHON_VERSION, https://bugs.python.org/) +AC_CONFIG_MACRO_DIR(m4) + AC_SUBST(BASECPPFLAGS) if test "$srcdir" != . -a "$srcdir" != "$(pwd)"; then # 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]) 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 ] + ], [ + [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 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]) diff --git a/m4/ax_check_openssl.m4 b/m4/ax_check_openssl.m4 new file mode 100644 index 00000000000..28e48cbefb6 --- /dev/null +++ b/m4/ax_check_openssl.m4 @@ -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 +# +# LICENSE +# +# Copyright (c) 2009,2010 Zmanda Inc. +# Copyright (c) 2009,2010 Dustin J. Mitchell +# +# 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 , 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 ], [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]) +]) diff --git a/pyconfig.h.in b/pyconfig.h.in index ff1083ae0b0..dd7c62bad1b 100644 --- a/pyconfig.h.in +++ b/pyconfig.h.in @@ -1237,6 +1237,9 @@ /* Define to 1 if you have the `writev' function. */ #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 */ #undef HAVE_ZLIB_COPY diff --git a/setup.py b/setup.py index 8e98fdcb7ef..c23628a2a94 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