Make finding openssl program a configure or meson option

Various test suites use the "openssl" program as part of their setup.
There isn't a way to override which openssl program is to be used,
other than by fiddling with the path, perhaps.  This has gotten
increasingly problematic because different versions of openssl have
different capabilities and do different things by default.

This patch checks for an openssl binary in configure and meson setup,
with appropriate ways to override it.  This is similar to how "lz4"
and "zstd" are handled, for example.  The meson build system actually
already did this, but the result was only used in some places.  This
is now applied more uniformly.

Reviewed-by: Michael Paquier <michael@paquier.xyz>
Discussion: https://www.postgresql.org/message-id/flat/dc638b75-a16a-007d-9e1c-d16ed6cf0ad2%40enterprisedb.com
This commit is contained in:
Peter Eisentraut 2022-10-20 21:01:05 +02:00
parent 40c7fcbbed
commit c8e4030d1b
16 changed files with 107 additions and 29 deletions

55
configure vendored
View File

@ -648,6 +648,7 @@ PG_CRC32C_OBJS
CFLAGS_ARMV8_CRC32C CFLAGS_ARMV8_CRC32C
CFLAGS_SSE42 CFLAGS_SSE42
LIBOBJS LIBOBJS
OPENSSL
ZSTD ZSTD
LZ4 LZ4
UUID_LIBS UUID_LIBS
@ -14112,6 +14113,60 @@ done
fi fi
if test -z "$OPENSSL"; then
for ac_prog in openssl
do
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; 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_path_OPENSSL+:} false; then :
$as_echo_n "(cached) " >&6
else
case $OPENSSL in
[\\/]* | ?:[\\/]*)
ac_cv_path_OPENSSL="$OPENSSL" # Let the user override the test with a path.
;;
*)
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_path_OPENSSL="$as_dir/$ac_word$ac_exec_ext"
$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
;;
esac
fi
OPENSSL=$ac_cv_path_OPENSSL
if test -n "$OPENSSL"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $OPENSSL" >&5
$as_echo "$OPENSSL" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
test -n "$OPENSSL" && break
done
else
# Report the value of OPENSSL in configure's output in all cases.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for OPENSSL" >&5
$as_echo_n "checking for OPENSSL... " >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $OPENSSL" >&5
$as_echo "$OPENSSL" >&6; }
fi
if test "$with_ssl" = openssl ; then if test "$with_ssl" = openssl ; then
ac_fn_c_check_header_mongrel "$LINENO" "openssl/ssl.h" "ac_cv_header_openssl_ssl_h" "$ac_includes_default" ac_fn_c_check_header_mongrel "$LINENO" "openssl/ssl.h" "ac_cv_header_openssl_ssl_h" "$ac_includes_default"
if test "x$ac_cv_header_openssl_ssl_h" = xyes; then : if test "x$ac_cv_header_openssl_ssl_h" = xyes; then :

View File

@ -1542,6 +1542,7 @@ if test "$with_gssapi" = yes ; then
[AC_CHECK_HEADERS(gssapi.h, [], [AC_MSG_ERROR([gssapi.h header file is required for GSSAPI])])]) [AC_CHECK_HEADERS(gssapi.h, [], [AC_MSG_ERROR([gssapi.h header file is required for GSSAPI])])])
fi fi
PGAC_PATH_PROGS(OPENSSL, openssl)
if test "$with_ssl" = openssl ; then if test "$with_ssl" = openssl ; then
AC_CHECK_HEADER(openssl/ssl.h, [], [AC_MSG_ERROR([header file <openssl/ssl.h> is required for OpenSSL])]) AC_CHECK_HEADER(openssl/ssl.h, [], [AC_MSG_ERROR([header file <openssl/ssl.h> is required for OpenSSL])])
AC_CHECK_HEADER(openssl/err.h, [], [AC_MSG_ERROR([header file <openssl/err.h> is required for OpenSSL])]) AC_CHECK_HEADER(openssl/err.h, [], [AC_MSG_ERROR([header file <openssl/err.h> is required for OpenSSL])])

View File

@ -541,6 +541,15 @@ $ENV{PROVE_TESTS}='t/020*.pl t/010*.pl'
</para></listitem> </para></listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><varname>OPENSSL</varname></term>
<listitem><para>
Path to a <application>openssl</application> command. The default is
<literal>openssl</literal>, which will search for a command by that
name in the configured <envar>PATH</envar>.
</para></listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term><varname>TAR</varname></term> <term><varname>TAR</varname></term>
<listitem><para> <listitem><para>

View File

@ -328,6 +328,7 @@ tar = find_program(get_option('TAR'), native: true)
gzip = find_program(get_option('GZIP'), native: true) gzip = find_program(get_option('GZIP'), native: true)
program_lz4 = find_program(get_option('LZ4'), native: true, required: false) program_lz4 = find_program(get_option('LZ4'), native: true, required: false)
touch = find_program('touch', native: true) touch = find_program('touch', native: true)
openssl = find_program(get_option('OPENSSL'), native: true, required: false)
program_zstd = find_program(get_option('ZSTD'), native: true, required: false) program_zstd = find_program(get_option('ZSTD'), native: true, required: false)
dtrace = find_program(get_option('DTRACE'), native: true, required: get_option('dtrace')) dtrace = find_program(get_option('DTRACE'), native: true, required: get_option('dtrace'))
missing = find_program('config/missing', native: true) missing = find_program('config/missing', native: true)

View File

@ -157,6 +157,9 @@ option('GZIP', type : 'string', value: 'gzip',
option('LZ4', type : 'string', value: 'lz4', option('LZ4', type : 'string', value: 'lz4',
description: 'path to lz4 binary') description: 'path to lz4 binary')
option('OPENSSL', type : 'string', value: 'openssl',
description: 'path to openssl binary')
option('PERL', type : 'string', value: 'perl', option('PERL', type : 'string', value: 'perl',
description: 'path to perl binary') description: 'path to perl binary')

View File

@ -343,6 +343,7 @@ LN_S = @LN_S@
MSGFMT = @MSGFMT@ MSGFMT = @MSGFMT@
MSGFMT_FLAGS = @MSGFMT_FLAGS@ MSGFMT_FLAGS = @MSGFMT_FLAGS@
MSGMERGE = @MSGMERGE@ MSGMERGE = @MSGMERGE@
OPENSSL = @OPENSSL@
PYTHON = @PYTHON@ PYTHON = @PYTHON@
TAR = @TAR@ TAR = @TAR@
XGETTEXT = @XGETTEXT@ XGETTEXT = @XGETTEXT@

View File

@ -14,6 +14,7 @@ top_builddir = ../../..
include $(top_builddir)/src/Makefile.global include $(top_builddir)/src/Makefile.global
export with_ldap export with_ldap
export OPENSSL
check: check:
$(prove_check) $(prove_check)

View File

@ -6,6 +6,9 @@ tests += {
'tests': [ 'tests': [
't/001_auth.pl', 't/001_auth.pl',
], ],
'env': {'with_ldap': ldap.found() ? 'yes' : 'no'}, 'env': {
'with_ldap': ldap.found() ? 'yes' : 'no',
'OPENSSL': openssl.path(),
},
}, },
} }

View File

@ -113,13 +113,15 @@ append_to_file(
mkdir $ldap_datadir or die; mkdir $ldap_datadir or die;
mkdir $slapd_certs or die; mkdir $slapd_certs or die;
system_or_bail "openssl", "req", "-new", "-nodes", "-keyout", my $openssl = $ENV{OPENSSL};
system_or_bail $openssl, "req", "-new", "-nodes", "-keyout",
"$slapd_certs/ca.key", "-x509", "-out", "$slapd_certs/ca.crt", "-subj", "$slapd_certs/ca.key", "-x509", "-out", "$slapd_certs/ca.crt", "-subj",
"/CN=CA"; "/CN=CA";
system_or_bail "openssl", "req", "-new", "-nodes", "-keyout", system_or_bail $openssl, "req", "-new", "-nodes", "-keyout",
"$slapd_certs/server.key", "-out", "$slapd_certs/server.csr", "-subj", "$slapd_certs/server.key", "-out", "$slapd_certs/server.csr", "-subj",
"/CN=server"; "/CN=server";
system_or_bail "openssl", "x509", "-req", "-in", "$slapd_certs/server.csr", system_or_bail $openssl, "x509", "-req", "-in", "$slapd_certs/server.csr",
"-CA", "$slapd_certs/ca.crt", "-CAkey", "$slapd_certs/ca.key", "-CA", "$slapd_certs/ca.crt", "-CAkey", "$slapd_certs/ca.key",
"-CAcreateserial", "-out", "$slapd_certs/server.crt"; "-CAcreateserial", "-out", "$slapd_certs/server.crt";

View File

@ -31,9 +31,9 @@ PASS = FooBaR1
.PHONY: ssl-files ssl-files-clean .PHONY: ssl-files ssl-files-clean
ssl-files: ssl-files:
openssl req -new -x509 -days 10000 -nodes -out server.crt \ $(OPENSSL) req -new -x509 -days 10000 -nodes -out server.crt \
-keyout server.ckey -subj "/CN=localhost" -keyout server.ckey -subj "/CN=localhost"
openssl rsa -aes256 -in server.ckey -out server.key -passout pass:$(PASS) $(OPENSSL) rsa -aes256 -in server.ckey -out server.key -passout pass:$(PASS)
rm server.ckey rm server.ckey
ssl-files-clean: ssl-files-clean:

View File

@ -25,8 +25,6 @@ testprep_targets += ssl_passphrase_callback
# Targets to generate or remove the ssl certificate and key. Need to be copied # Targets to generate or remove the ssl certificate and key. Need to be copied
# to the source afterwards. Normally not needed. # to the source afterwards. Normally not needed.
openssl = find_program('openssl', native: true, required: false)
if openssl.found() if openssl.found()
cert = custom_target('server.crt', cert = custom_target('server.crt',
output: ['server.crt', 'server.ckey'], output: ['server.crt', 'server.ckey'],

View File

@ -15,7 +15,7 @@ subdir = src/test/ssl
top_builddir = ../../.. top_builddir = ../../..
include $(top_builddir)/src/Makefile.global include $(top_builddir)/src/Makefile.global
export with_ssl export OPENSSL with_ssl
# The sslfiles targets are separated into their own file due to interactions # The sslfiles targets are separated into their own file due to interactions
# with settings in Makefile.global. # with settings in Makefile.global.

View File

@ -3,7 +3,10 @@ tests += {
'sd': meson.current_source_dir(), 'sd': meson.current_source_dir(),
'bd': meson.current_build_dir(), 'bd': meson.current_build_dir(),
'tap': { 'tap': {
'env': {'with_ssl': get_option('ssl')}, 'env': {
'with_ssl': get_option('ssl'),
'OPENSSL': openssl.path(),
},
'tests': [ 'tests': [
't/001_ssltests.pl', 't/001_ssltests.pl',
't/002_scram.pl', 't/002_scram.pl',

View File

@ -84,7 +84,7 @@ sslfiles: $(SSLFILES) $(SSLDIRS)
# Root CA is self-signed. # Root CA is self-signed.
ssl/root_ca.crt: ssl/root_ca.key conf/root_ca.config ssl/root_ca.crt: ssl/root_ca.key conf/root_ca.config
openssl req -new -x509 -config conf/root_ca.config -days 10000 -key $< -out $@ $(OPENSSL) req -new -x509 -config conf/root_ca.config -days 10000 -key $< -out $@
# #
# Special-case keys # Special-case keys
@ -94,20 +94,20 @@ ssl/root_ca.crt: ssl/root_ca.key conf/root_ca.config
# Password-protected version of server-cn-only.key # Password-protected version of server-cn-only.key
ssl/server-password.key: ssl/server-cn-only.key ssl/server-password.key: ssl/server-cn-only.key
openssl rsa -aes256 -in $< -out $@ -passout 'pass:secret1' $(OPENSSL) rsa -aes256 -in $< -out $@ -passout 'pass:secret1'
# DER-encoded version of client.key # DER-encoded version of client.key
ssl/client-der.key: ssl/client.key ssl/client-der.key: ssl/client.key
openssl rsa -in $< -outform DER -out $@ $(OPENSSL) rsa -in $< -outform DER -out $@
# Convert client.key to encrypted PEM (X.509 text) and DER (X.509 ASN.1) # Convert client.key to encrypted PEM (X.509 text) and DER (X.509 ASN.1)
# formats to test libpq's support for the sslpassword= option. # formats to test libpq's support for the sslpassword= option.
ssl/client-encrypted-pem.key: ssl/client.key ssl/client-encrypted-pem.key: ssl/client.key
openssl rsa -in $< -outform PEM -aes128 -passout 'pass:dUmmyP^#+' -out $@ $(OPENSSL) rsa -in $< -outform PEM -aes128 -passout 'pass:dUmmyP^#+' -out $@
# TODO Explicitly choosing -aes128 generates a key unusable to PostgreSQL with # TODO Explicitly choosing -aes128 generates a key unusable to PostgreSQL with
# OpenSSL 3.0.0, so fall back on the default for now. # OpenSSL 3.0.0, so fall back on the default for now.
ssl/client-encrypted-der.key: ssl/client.key ssl/client-encrypted-der.key: ssl/client.key
openssl rsa -in $< -outform DER -passout 'pass:dUmmyP^#+' -out $@ $(OPENSSL) rsa -in $< -outform DER -passout 'pass:dUmmyP^#+' -out $@
# #
# Combined files # Combined files
@ -145,7 +145,7 @@ $(COMBINATIONS):
# #
$(STANDARD_KEYS): $(STANDARD_KEYS):
openssl genrsa -out $@ 2048 $(OPENSSL) genrsa -out $@ 2048
chmod 0600 $@ chmod 0600 $@
# #
@ -165,18 +165,18 @@ client_ca_state_files := ssl/client_ca-certindex ssl/client_ca-certindex.attr ss
# parallel processes, so we must mark the entire Makefile .NOTPARALLEL. # parallel processes, so we must mark the entire Makefile .NOTPARALLEL.
.NOTPARALLEL: .NOTPARALLEL:
$(CA_CERTS): ssl/%.crt: ssl/%.csr conf/%.config conf/cas.config ssl/root_ca.crt | ssl/new_certs_dir $(root_ca_state_files) $(CA_CERTS): ssl/%.crt: ssl/%.csr conf/%.config conf/cas.config ssl/root_ca.crt | ssl/new_certs_dir $(root_ca_state_files)
openssl ca -batch -config conf/cas.config -name root_ca -notext -in $< -out $@ $(OPENSSL) ca -batch -config conf/cas.config -name root_ca -notext -in $< -out $@
$(SERVER_CERTS): ssl/%.crt: ssl/%.csr conf/%.config conf/cas.config ssl/server_ca.crt | ssl/new_certs_dir $(server_ca_state_files) $(SERVER_CERTS): ssl/%.crt: ssl/%.csr conf/%.config conf/cas.config ssl/server_ca.crt | ssl/new_certs_dir $(server_ca_state_files)
openssl ca -batch -config conf/cas.config -name server_ca -notext -in $< -out $@ $(OPENSSL) ca -batch -config conf/cas.config -name server_ca -notext -in $< -out $@
$(CLIENT_CERTS): ssl/%.crt: ssl/%.csr conf/%.config conf/cas.config ssl/client_ca.crt | ssl/new_certs_dir $(client_ca_state_files) $(CLIENT_CERTS): ssl/%.crt: ssl/%.csr conf/%.config conf/cas.config ssl/client_ca.crt | ssl/new_certs_dir $(client_ca_state_files)
openssl ca -batch -config conf/cas.config -name client_ca -notext -in $< -out $@ $(OPENSSL) ca -batch -config conf/cas.config -name client_ca -notext -in $< -out $@
# The CSRs don't need to persist after a build. # The CSRs don't need to persist after a build.
.INTERMEDIATE: $(CERTIFICATES:%=ssl/%.csr) .INTERMEDIATE: $(CERTIFICATES:%=ssl/%.csr)
ssl/%.csr: ssl/%.key conf/%.config ssl/%.csr: ssl/%.key conf/%.config
openssl req -new -utf8 -key $< -out $@ -config conf/$*.config $(OPENSSL) req -new -utf8 -key $< -out $@ -config conf/$*.config
# #
# CA State # CA State
@ -210,16 +210,16 @@ ssl/%.srl:
# #
ssl/root.crl: ssl/root_ca.crt | $(root_ca_state_files) ssl/root.crl: ssl/root_ca.crt | $(root_ca_state_files)
openssl ca -config conf/cas.config -name root_ca -gencrl -out $@ $(OPENSSL) ca -config conf/cas.config -name root_ca -gencrl -out $@
ssl/server.crl: ssl/server-revoked.crt ssl/server_ca.crt | $(server_ca_state_files) ssl/server.crl: ssl/server-revoked.crt ssl/server_ca.crt | $(server_ca_state_files)
openssl ca -config conf/cas.config -name server_ca -revoke $< $(OPENSSL) ca -config conf/cas.config -name server_ca -revoke $<
openssl ca -config conf/cas.config -name server_ca -gencrl -out $@ $(OPENSSL) ca -config conf/cas.config -name server_ca -gencrl -out $@
ssl/client.crl: ssl/client-revoked.crt ssl/client-revoked-utf8.crt ssl/client_ca.crt | $(client_ca_state_files) ssl/client.crl: ssl/client-revoked.crt ssl/client-revoked-utf8.crt ssl/client_ca.crt | $(client_ca_state_files)
openssl ca -config conf/cas.config -name client_ca -revoke ssl/client-revoked.crt $(OPENSSL) ca -config conf/cas.config -name client_ca -revoke ssl/client-revoked.crt
openssl ca -config conf/cas.config -name client_ca -revoke ssl/client-revoked-utf8.crt $(OPENSSL) ca -config conf/cas.config -name client_ca -revoke ssl/client-revoked-utf8.crt
openssl ca -config conf/cas.config -name client_ca -gencrl -out $@ $(OPENSSL) ca -config conf/cas.config -name client_ca -gencrl -out $@
# #
# CRL hash directories # CRL hash directories
@ -230,7 +230,7 @@ ssl/root+client-crldir: ssl/client.crl ssl/root.crl
ssl/server-crldir: ssl/server.crl ssl/server-crldir: ssl/server.crl
ssl/client-crldir: ssl/client.crl ssl/client-crldir: ssl/client.crl
crlhashfile = $(shell openssl crl -hash -noout -in $(1)).r0 crlhashfile = $(shell $(OPENSSL) crl -hash -noout -in $(1)).r0
ssl/%-crldir: ssl/%-crldir:
mkdir -p $@ mkdir -p $@

View File

@ -611,7 +611,7 @@ TODO:
# pg_stat_ssl # pg_stat_ssl
my $serialno = `openssl x509 -serial -noout -in ssl/client.crt`; my $serialno = `$ENV{OPENSSL} x509 -serial -noout -in ssl/client.crt`;
if ($? == 0) if ($? == 0)
{ {
# OpenSSL prints serial numbers in hexadecimal and converting the serial # OpenSSL prints serial numbers in hexadecimal and converting the serial
@ -633,7 +633,7 @@ else
{ {
# OpenSSL isn't functioning on the user's PATH. This probably isn't worth # OpenSSL isn't functioning on the user's PATH. This probably isn't worth
# skipping the test over, so just fall back to a generic integer match. # skipping the test over, so just fall back to a generic integer match.
warn 'couldn\'t run `openssl x509` to get client cert serialno'; warn "couldn't run \"$ENV{OPENSSL} x509\" to get client cert serialno";
$serialno = '\d+'; $serialno = '\d+';
} }

View File

@ -146,6 +146,7 @@ sub set_command_env
{ {
set_single_env('GZIP_PROGRAM', 'gzip'); set_single_env('GZIP_PROGRAM', 'gzip');
set_single_env('LZ4', 'lz4'); set_single_env('LZ4', 'lz4');
set_single_env('OPENSSL', 'openssl');
set_single_env('ZSTD', 'zstd'); set_single_env('ZSTD', 'zstd');
} }