diff -up stunnel-5.56/src/ssl.c.verify-chain stunnel-5.56/src/ssl.c --- stunnel-5.56/src/ssl.c.verify-chain 2021-02-17 00:37:28.950981672 +0100 +++ stunnel-5.56/src/ssl.c 2021-02-17 00:37:36.047053139 +0100 @@ -1,6 +1,6 @@ /* * stunnel TLS offloading and load-balancing proxy - * Copyright (C) 1998-2019 Michal Trojnara + * Copyright (C) 1998-2020 Michal Trojnara * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -39,7 +39,12 @@ #include "prototypes.h" /* global OpenSSL initialization: compression, engine, entropy */ -#if OPENSSL_VERSION_NUMBER>=0x10100000L +NOEXPORT void cb_new_auth(void *parent, void *ptr, CRYPTO_EX_DATA *ad, + int idx, long argl, void *argp); +#if OPENSSL_VERSION_NUMBER>=0x30000000L +NOEXPORT int cb_dup_addr(CRYPTO_EX_DATA *to, const CRYPTO_EX_DATA *from, + void **from_d, int idx, long argl, void *argp); +#elif OPENSSL_VERSION_NUMBER>=0x10100000L NOEXPORT int cb_dup_addr(CRYPTO_EX_DATA *to, const CRYPTO_EX_DATA *from, void *from_d, int idx, long argl, void *argp); #else @@ -72,7 +77,7 @@ int ssl_init(void) { /* init TLS before index_ssl_ctx_opt=SSL_CTX_get_ex_new_index(0, "SERVICE_OPTIONS pointer", NULL, NULL, NULL); index_session_authenticated=SSL_SESSION_get_ex_new_index(0, - "session authenticated", NULL, NULL, NULL); + "session authenticated", cb_new_auth, NULL, NULL); index_session_connect_address=SSL_SESSION_get_ex_new_index(0, "session connect address", NULL, cb_dup_addr, cb_free_addr); if(index_ssl_cli<0 || index_ssl_ctx_opt<0 || @@ -104,17 +109,31 @@ int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNU BN_free(dh->p); BN_free(dh->q); BN_free(dh->g); - dh->p = p; - dh->q = q; - dh->g = g; + dh->p=p; + dh->q=q; + dh->g=g; if(q) - dh->length = BN_num_bits(q); + dh->length=BN_num_bits(q); return 1; } #endif #endif -#if OPENSSL_VERSION_NUMBER>=0x10100000L +NOEXPORT void cb_new_auth(void *parent, void *ptr, CRYPTO_EX_DATA *ad, + int idx, long argl, void *argp) { + (void)parent; /* squash the unused parameter warning */ + (void)ptr; /* squash the unused parameter warning */ + (void)argl; /* squash the unused parameter warning */ + s_log(LOG_DEBUG, "Initializing application specific data for %s", + (char *)argp); + if(!CRYPTO_set_ex_data(ad, idx, (void *)(-1))) + sslerror("CRYPTO_set_ex_data"); +} + +#if OPENSSL_VERSION_NUMBER>=0x30000000L +NOEXPORT int cb_dup_addr(CRYPTO_EX_DATA *to, const CRYPTO_EX_DATA *from, + void **from_d, int idx, long argl, void *argp) { +#elif OPENSSL_VERSION_NUMBER>=0x10100000L NOEXPORT int cb_dup_addr(CRYPTO_EX_DATA *to, const CRYPTO_EX_DATA *from, void *from_d, int idx, long argl, void *argp) { #else diff -up stunnel-5.56/src/verify.c.verify-chain stunnel-5.56/src/verify.c --- stunnel-5.56/src/verify.c.verify-chain 2021-02-17 00:37:11.577806692 +0100 +++ stunnel-5.56/src/verify.c 2021-02-17 00:37:42.542118546 +0100 @@ -1,6 +1,6 @@ /* * stunnel TLS offloading and load-balancing proxy - * Copyright (C) 1998-2019 Michal Trojnara + * Copyright (C) 1998-2020 Michal Trojnara * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -214,11 +214,15 @@ NOEXPORT int verify_callback(int preveri s_log(LOG_INFO, "Certificate verification disabled"); return 1; /* accept */ } - if(verify_checks(c, preverify_ok, callback_ctx)) { + if(verify_checks(c, preverify_ok, callback_ctx)) + return 1; /* accept */ + if(c->opt->option.client || c->opt->protocol) + return 0; /* reject */ + if(c->opt->redirect_addr.names) { SSL_SESSION *sess=SSL_get1_session(c->ssl); if(sess) { - int ok=SSL_SESSION_set_ex_data(sess, index_session_authenticated, - (void *)(-1)); + int ok=SSL_SESSION_set_ex_data(sess, + index_session_authenticated, NULL); SSL_SESSION_free(sess); if(!ok) { sslerror("SSL_SESSION_set_ex_data"); @@ -227,10 +231,6 @@ NOEXPORT int verify_callback(int preveri } return 1; /* accept */ } - if(c->opt->option.client || c->opt->protocol) - return 0; /* reject */ - if(c->opt->redirect_addr.names) - return 1; /* accept */ return 0; /* reject */ } diff -up stunnel-5.56/tests/recipes/028_redirect_chain.verify-chain stunnel-5.56/tests/recipes/028_redirect_chain --- stunnel-5.56/tests/recipes/028_redirect_chain.verify-chain 2021-02-17 00:38:44.823745781 +0100 +++ stunnel-5.56/tests/recipes/028_redirect_chain 2021-02-17 00:38:16.143456937 +0100 @@ -0,0 +1,50 @@ +#!/bin/sh + +# Redirect TLS client connections on certificate-based authentication failures. +# [client_1] -> [server_1] -> [client_2] -> [server_2] +# The success is expected because the client presents the *wrong* certificate +# and the client connection is redirected. +# Checking if the verifyChain option verifies the peer certificate starting from the root CA. + +. $(dirname $0)/../test_library + +start() { + ../../src/stunnel -fd 0 <> "stderr.log" +exit $? diff -up stunnel-5.56/tests/recipes/029_no_redirect_chain.verify-chain stunnel-5.56/tests/recipes/029_no_redirect_chain --- stunnel-5.56/tests/recipes/029_no_redirect_chain.verify-chain 2021-02-17 00:38:57.819876672 +0100 +++ stunnel-5.56/tests/recipes/029_no_redirect_chain 2021-02-17 00:38:24.895545080 +0100 @@ -0,0 +1,49 @@ +#!/bin/sh + +# Do not redirect TLS client connections on certificate-based authentication success. +# [client_1] -> [server_1] +# The success is expected because the client presents the *correct* certificate +# and the client connection isn't redirected. +# Checking if the verifyChain option verifies the peer certificate starting from the root CA. + +. $(dirname $0)/../test_library + +start() { + ../../src/stunnel -fd 0 <> "stderr.log" +exit $?