Author: brane
Date: Mon Jun 23 10:09:30 2025
New Revision: 1926661
URL: http://svn.apache.org/viewvc?rev=1926661&view=rev
Log:
On the user-defined-authn branch: sync with trunk r1926660.
Added:
serf/branches/user-defined-authn/.github/workflows/linux-old-scons.yml
- copied unchanged from r1926660,
serf/trunk/.github/workflows/linux-old-scons.yml
serf/branches/user-defined-authn/src/init_once.c
- copied unchanged from r1926660, serf/trunk/src/init_once.c
Modified:
serf/branches/user-defined-authn/ (props changed)
serf/branches/user-defined-authn/CMakeLists.txt
serf/branches/user-defined-authn/auth/auth_spnego.c
serf/branches/user-defined-authn/buckets/ssl_buckets.c
serf/branches/user-defined-authn/serf_private.h
serf/branches/user-defined-authn/test/certs/create_certs.py
serf/branches/user-defined-authn/test/serf_httpd.c
Propchange: serf/branches/user-defined-authn/
------------------------------------------------------------------------------
Merged /serf/trunk:r1926567-1926660
Modified: serf/branches/user-defined-authn/CMakeLists.txt
URL:
http://svn.apache.org/viewvc/serf/branches/user-defined-authn/CMakeLists.txt?rev=1926661&r1=1926660&r2=1926661&view=diff
==============================================================================
--- serf/branches/user-defined-authn/CMakeLists.txt (original)
+++ serf/branches/user-defined-authn/CMakeLists.txt Mon Jun 23 10:09:30 2025
@@ -131,6 +131,7 @@ list(APPEND SOURCES
"src/context.c"
"src/deprecated.c"
"src/incoming.c"
+ "src/init_once.c"
"src/logging.c"
"src/outgoing.c"
"src/outgoing_request.c"
Modified: serf/branches/user-defined-authn/auth/auth_spnego.c
URL:
http://svn.apache.org/viewvc/serf/branches/user-defined-authn/auth/auth_spnego.c?rev=1926661&r1=1926660&r2=1926661&view=diff
==============================================================================
--- serf/branches/user-defined-authn/auth/auth_spnego.c (original)
+++ serf/branches/user-defined-authn/auth/auth_spnego.c Mon Jun 23 10:09:30 2025
@@ -261,20 +261,11 @@ do_auth(const serf__authn_scheme_t *sche
const char *auth_hdr,
apr_pool_t *pool)
{
- serf_context_t *ctx = conn->ctx;
- serf__authn_info_t *authn_info;
const char *tmp = NULL;
char *token = NULL;
apr_size_t tmp_len = 0, token_len = 0;
apr_status_t status;
- if (peer == HOST) {
- authn_info = serf__get_authn_info_for_server(conn);
- } else {
- authn_info = &ctx->proxy_authn_info;
- }
- /* FIXME: authn_info's value is never used. */
-
/* Is this a response from a host/proxy? auth_hdr should always be set. */
if (code && auth_hdr) {
const char *space = NULL;
Modified: serf/branches/user-defined-authn/buckets/ssl_buckets.c
URL:
http://svn.apache.org/viewvc/serf/branches/user-defined-authn/buckets/ssl_buckets.c?rev=1926661&r1=1926660&r2=1926661&view=diff
==============================================================================
--- serf/branches/user-defined-authn/buckets/ssl_buckets.c (original)
+++ serf/branches/user-defined-authn/buckets/ssl_buckets.c Mon Jun 23 10:09:30
2025
@@ -1467,90 +1467,66 @@ static apr_status_t cleanup_ssl(void *da
#endif
-#if !APR_VERSION_AT_LEAST(1,0,0)
-#define apr_atomic_cas32(mem, with, cmp) apr_atomic_cas(mem, with, cmp)
-#endif
-enum ssl_init_e
+static apr_status_t do_init_libraries(void* baton)
{
- INIT_UNINITIALIZED = 0,
- INIT_BUSY = 1,
- INIT_DONE = 2
-};
-
-static volatile apr_uint32_t have_init_ssl = INIT_UNINITIALIZED;
-
-static void init_ssl_libraries(void)
-{
- apr_uint32_t val;
-
- val = apr_atomic_cas32(&have_init_ssl, INIT_BUSY, INIT_UNINITIALIZED);
-
- if (!val) {
#if APR_HAS_THREADS && defined(SERF_HAVE_SSL_LOCKING_CALLBACKS)
- int i, numlocks;
+ int i, numlocks;
#endif
#ifdef SERF_LOGGING_ENABLED
- /* Warn when compile-time and run-time version of OpenSSL differ in
- major/minor version number. */
+ /* Warn when compile-time and run-time version of OpenSSL differ in
+ major/minor version number. */
#ifdef SERF_HAVE_OPENSSL_VERSION_NUM
- unsigned long libver = OpenSSL_version_num();
+ unsigned long libver = OpenSSL_version_num();
#else
- long libver = SSLeay();
+ long libver = SSLeay();
#endif
- if ((libver ^ OPENSSL_VERSION_NUMBER) & 0xFFF00000) {
- serf__log(LOGLVL_WARNING, LOGCOMP_SSL, __FILE__, NULL,
- "Warning: OpenSSL library version mismatch, compile-"
- "time was %lx, runtime is %lx.\n",
- OPENSSL_VERSION_NUMBER, libver);
- }
+ if ((libver ^ OPENSSL_VERSION_NUMBER) & 0xFFF00000) {
+ serf__log(LOGLVL_WARNING, LOGCOMP_SSL, __FILE__, NULL,
+ "Warning: OpenSSL library version mismatch, compile-"
+ "time was %lx, runtime is %lx.\n",
+ OPENSSL_VERSION_NUMBER, libver);
+ }
#endif
#ifdef SERF_HAVE_OPENSSL_SSL_LIBRARY_INIT
- ERR_load_crypto_strings();
- SSL_load_error_strings();
- SSL_library_init();
- OpenSSL_add_all_algorithms();
+ ERR_load_crypto_strings();
+ SSL_load_error_strings();
+ SSL_library_init();
+ OpenSSL_add_all_algorithms();
#endif
#if APR_HAS_THREADS && defined(SERF_HAVE_SSL_LOCKING_CALLBACKS)
- numlocks = CRYPTO_num_locks();
- apr_pool_create(&ssl_pool, NULL);
- ssl_locks = apr_palloc(ssl_pool, sizeof(apr_thread_mutex_t*)*numlocks);
- for (i = 0; i < numlocks; i++) {
- apr_status_t rv;
+ numlocks = CRYPTO_num_locks();
+ apr_pool_create(&ssl_pool, NULL);
+ ssl_locks = apr_palloc(ssl_pool, sizeof(apr_thread_mutex_t*)*numlocks);
+ for (i = 0; i < numlocks; i++) {
+ apr_status_t status;
- /* Intraprocess locks don't /need/ a filename... */
- rv = apr_thread_mutex_create(&ssl_locks[i],
+ /* Intraprocess locks don't /need/ a filename... */
+ status = apr_thread_mutex_create(&ssl_locks[i],
APR_THREAD_MUTEX_DEFAULT, ssl_pool);
- if (rv != APR_SUCCESS) {
- /* FIXME: error out here */
- }
- }
- CRYPTO_set_locking_callback(ssl_lock);
- CRYPTO_set_id_callback(ssl_id);
- CRYPTO_set_dynlock_create_callback(ssl_dyn_create);
- CRYPTO_set_dynlock_lock_callback(ssl_dyn_lock);
- CRYPTO_set_dynlock_destroy_callback(ssl_dyn_destroy);
+ if (status != APR_SUCCESS)
+ return status;
+ }
+ CRYPTO_set_locking_callback(ssl_lock);
+ CRYPTO_set_id_callback(ssl_id);
+ CRYPTO_set_dynlock_create_callback(ssl_dyn_create);
+ CRYPTO_set_dynlock_lock_callback(ssl_dyn_lock);
+ CRYPTO_set_dynlock_destroy_callback(ssl_dyn_destroy);
- apr_pool_cleanup_register(ssl_pool, NULL, cleanup_ssl, cleanup_ssl);
+ apr_pool_cleanup_register(ssl_pool, NULL, cleanup_ssl, cleanup_ssl);
#endif
- apr_atomic_cas32(&have_init_ssl, INIT_DONE, INIT_BUSY);
- }
- else
- {
- /* Make sure we don't continue before the initialization in another
- thread has completed */
- while (val != INIT_DONE) {
- apr_sleep(APR_USEC_PER_SEC / 1000);
-
- val = apr_atomic_cas32(&have_init_ssl,
- INIT_UNINITIALIZED,
- INIT_UNINITIALIZED);
- }
- }
+
+ return APR_SUCCESS;
+}
+
+static apr_status_t init_ssl_libraries(void)
+{
+ SERF__DECLARE_STATIC_INIT_ONCE_CONTEXT(init_ctx);
+ return serf__init_once(&init_ctx, do_init_libraries, NULL);
}
static int ssl_need_client_cert(SSL *ssl, X509 **cert, EVP_PKEY **pkey)
@@ -1774,7 +1750,8 @@ static serf_ssl_context_t *ssl_init_cont
{
serf_ssl_context_t *ssl_ctx;
- init_ssl_libraries();
+ if (init_ssl_libraries())
+ return NULL;
ssl_ctx = serf_bucket_mem_alloc(allocator, sizeof(*ssl_ctx));
@@ -2023,11 +2000,13 @@ apr_status_t serf_ssl_load_cert_file(
status = apr_file_open(&cert_file, file_path, APR_READ, APR_OS_DEFAULT,
pool);
+ if (!status) {
+ status = init_ssl_libraries();
+ }
if (status) {
return status;
}
- init_ssl_libraries();
biom = bio_meth_file_new();
bio = BIO_new(biom);
Modified: serf/branches/user-defined-authn/serf_private.h
URL:
http://svn.apache.org/viewvc/serf/branches/user-defined-authn/serf_private.h?rev=1926661&r1=1926660&r2=1926661&view=diff
==============================================================================
--- serf/branches/user-defined-authn/serf_private.h (original)
+++ serf/branches/user-defined-authn/serf_private.h Mon Jun 23 10:09:30 2025
@@ -167,6 +167,32 @@ typedef int serf__bool_t; /* Not _Bool *
#endif
#endif
+/*** One-time initialization. ***/
+
+/* Init-once context. */
+struct serf__init_once_context
+{
+ volatile apr_uint32_t state;
+ apr_status_t status;
+};
+
+#define SERF__INIT_ONCE_NONE 0
+#define SERF__DECLARE_STATIC_INIT_ONCE_CONTEXT(name) \
+ static struct serf__init_once_context name = { \
+ SERF__INIT_ONCE_NONE, APR_SUCCESS \
+ }
+
+/* The init-once callback function. */
+typedef apr_status_t (*serf__init_once_func_t)(void *baton);
+
+/* The function that performs on-time initialization.
+ If APR_HAS_THREADS, will use a spinlock to serialize the call to
+ the initialization function. */
+apr_status_t serf__init_once(struct serf__init_once_context *init_ctx,
+ serf__init_once_func_t init_func,
+ void *init_baton);
+
+
typedef struct serf__authn_scheme_t serf__authn_scheme_t;
typedef struct serf_io_baton_t {
Modified: serf/branches/user-defined-authn/test/certs/create_certs.py
URL:
http://svn.apache.org/viewvc/serf/branches/user-defined-authn/test/certs/create_certs.py?rev=1926661&r1=1926660&r2=1926661&view=diff
==============================================================================
--- serf/branches/user-defined-authn/test/certs/create_certs.py (original)
+++ serf/branches/user-defined-authn/test/certs/create_certs.py Mon Jun 23
10:09:30 2025
@@ -9,9 +9,9 @@
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@@ -21,9 +21,9 @@
# ===================================================================
#
-# This script creates the private keys and certificates required for
+# This script creates the private keys and certificates required for
# running the serf test suite.
-#
+#
# It should be run from the test/certs folder without arguments.
# Certificates will be created in the test/certs folder, private keys in the
# test/certs/private folder.
@@ -47,12 +47,12 @@ def create_key(keyfile='', passphrase=No
key = crypto.PKey()
key.generate_key(KEY_ALGO, KEY_SIZE)
if passphrase:
- open(keyfile, "wt").write(crypto.dump_privatekey(crypto.FILETYPE_PEM,
- key, KEY_CIPHER,
- passphrase))
+ open(keyfile, "wt").write(crypto.dump_privatekey(crypto.FILETYPE_PEM,
+ key, KEY_CIPHER,
+
passphrase).decode('utf-8'))
else:
- open(keyfile, "wt").write(crypto.dump_privatekey(crypto.FILETYPE_PEM,
- key))
+ open(keyfile, "wt").write(crypto.dump_privatekey(crypto.FILETYPE_PEM,
+ key).decode('utf-8'))
return key
@@ -62,7 +62,7 @@ def create_pkcs12(clientkey, clientcert,
pkcs12.set_certificate(clientcert)
pkcs12.set_privatekey(clientkey)
pkcs12.set_ca_certificates([issuer])
- open(pkcs12file, "wt").write(pkcs12.export(passphrase=passphrase,
+ open(pkcs12file, "wb").write(pkcs12.export(passphrase=passphrase,
iter=2048, maciter=2048))
def create_crl(revokedcert, cakey, cacert, crlfile, next_crl_days=VALID_DAYS):
@@ -73,9 +73,9 @@ def create_crl(revokedcert, cakey, cacer
now = datetime.utcnow()
now_str = now.strftime('%Y%m%d%H%M%SZ')
- revoked.set_serial(serial_number)
- revoked.set_reason('unspecified')
- revoked.set_rev_date(now_str) # revoked as of now
+ revoked.set_serial(serial_number.encode('ascii'))
+ revoked.set_reason(b'unspecified')
+ revoked.set_rev_date(now_str.encode('ascii')) # revoked as of now
crl.add_revoked(revoked)
try:
@@ -84,16 +84,16 @@ def create_crl(revokedcert, cakey, cacer
# Some very old versions of pyopenssl (such as the one on macOS)
# do not support the 'digest' keyword argument.
exported = crl.export(cacert, cakey, days=next_crl_days)
- open(crlfile, "wt").write(exported)
+ open(crlfile, "wb").write(exported)
# subjectAltName
-def create_cert(subjectkey, certfile, issuer=None, issuerkey=None, country='',
- state='', city='', org='', ou='', cn='', email='', ca=False,
+def create_cert(subjectkey, certfile, issuer=None, issuerkey=None, country='',
+ state='', city='', org='', ou='', cn='', email='', ca=False,
valid_before=0, days_valid=VALID_DAYS, subjectAltName=None,
ocsp_responder_url=None, ocsp_signer=False):
'''
Create a X509 signed certificate.
-
+
subjectAltName
Array of fully qualified subject alternative names (use OpenSSL
syntax):
For a DNS entry, use: ['DNS:localhost']. Other options are 'email',
'URI', 'IP'.
@@ -103,15 +103,15 @@ def create_cert(subjectkey, certfile, is
cert.set_version(3-1) # version 3, starts at 0
cert.get_subject().C = country
cert.get_subject().ST = state
- cert.get_subject().L = city
- cert.get_subject().O = org
+ cert.get_subject().L = city
+ cert.get_subject().O = org
cert.get_subject().OU = ou
if cn:
cert.get_subject().CN = cn
cert.get_subject().emailAddress = email
cert.set_serial_number(SERIAL_NUMBER)
cert.set_pubkey(subjectkey)
-
+
cert.gmtime_adj_notBefore(valid_before * 24 * 3600)
cert.gmtime_adj_notAfter(days_valid * 24 * 3600)
@@ -119,92 +119,92 @@ def create_cert(subjectkey, certfile, is
issuer = cert # self signed
issuerkey = subjectkey
cert.set_issuer(issuer.get_subject())
-
+
if ca:
cert.add_extensions([
- crypto.X509Extension("basicConstraints", False,
- "CA:TRUE"),
- crypto.X509Extension("subjectKeyIdentifier", False, "hash",
+ crypto.X509Extension(b"basicConstraints", False,
+ b"CA:TRUE"),
+ crypto.X509Extension(b"subjectKeyIdentifier", False, b"hash",
subject=cert)
])
cert.add_extensions([
- crypto.X509Extension("authorityKeyIdentifier", False,
- "keyid:always", issuer=issuer)
+ crypto.X509Extension(b"authorityKeyIdentifier", False,
+ b"keyid:always", issuer=issuer)
])
if subjectAltName:
critical = True if not cn else False
cert.add_extensions([
- crypto.X509Extension('subjectAltName', critical, ",
".join(subjectAltName))])
+ crypto.X509Extension(b'subjectAltName', critical, ",
".join(subjectAltName).encode('ascii'))])
if ocsp_responder_url:
cert.add_extensions([
- crypto.X509Extension('authorityInfoAccess', False,
- 'OCSP;URI:' + ocsp_responder_url)])
+ crypto.X509Extension(b'authorityInfoAccess', False,
+ ('OCSP;URI:' +
ocsp_responder_url).encode('ascii'))])
if ocsp_signer:
cert.add_extensions([
- crypto.X509Extension('extendedKeyUsage', True, 'OCSPSigning')
+ crypto.X509Extension(b'extendedKeyUsage', True, b'OCSPSigning')
])
cert.sign(issuerkey, SIGN_ALGO)
- open(certfile, "wt").write(crypto.dump_certificate(crypto.FILETYPE_PEM,
- cert))
+ open(certfile, "wt").write(crypto.dump_certificate(crypto.FILETYPE_PEM,
+ cert).decode('utf-8'))
return cert
if __name__ == '__main__':
# root CA key pair and certificate.
# This key will be used to sign the intermediate CA certificate
- rootcakey = create_key('private/serfrootcakey.pem', 'serftest')
+ rootcakey = create_key('private/serfrootcakey.pem', b'serftest')
- rootcacert = create_cert(subjectkey=rootcakey,
+ rootcacert = create_cert(subjectkey=rootcakey,
certfile='serfrootcacert.pem',
- country='BE', state='Antwerp', city='Mechelen',
- org='In Serf we trust, Inc.',
- ou='Test Suite Root CA', cn='Serf Root CA',
+ country='BE', state='Antwerp', city='Mechelen',
+ org='In Serf we trust, Inc.',
+ ou='Test Suite Root CA', cn='Serf Root CA',
email='[email protected]', ca=True)
# intermediate CA key pair and certificate
# This key will be used to sign all server certificates
- cakey = create_key('private/serfcakey.pem', 'serftest')
+ cakey = create_key('private/serfcakey.pem', b'serftest')
cacert = create_cert(subjectkey=cakey, certfile='serfcacert.pem',
issuer=rootcacert, issuerkey=rootcakey,
- country='BE', state='Antwerp', city='Mechelen',
- org='In Serf we trust, Inc.',
- ou='Test Suite CA', cn='Serf CA',
+ country='BE', state='Antwerp', city='Mechelen',
+ org='In Serf we trust, Inc.',
+ ou='Test Suite CA', cn='Serf CA',
email='[email protected]', ca=True)
# server key pair
# server certificate, no errors
- serverkey = create_key('private/serfserverkey.pem', 'serftest')
+ serverkey = create_key('private/serfserverkey.pem', b'serftest')
- servercert = create_cert(subjectkey=serverkey,
+ servercert = create_cert(subjectkey=serverkey,
certfile='serfservercert.pem',
issuer=cacert, issuerkey=cakey,
- country='BE', state='Antwerp', city='Mechelen',
- org='In Serf we trust, Inc.',
- ou='Test Suite Server', cn='localhost',
+ country='BE', state='Antwerp', city='Mechelen',
+ org='In Serf we trust, Inc.',
+ ou='Test Suite Server', cn='localhost',
email='[email protected]')
# server certificate that expired a year ago
- expiredcert = create_cert(subjectkey=serverkey,
+ expiredcert = create_cert(subjectkey=serverkey,
certfile='serfserver_expired_cert.pem',
issuer=cacert, issuerkey=cakey,
- country='BE', state='Antwerp', city='Mechelen',
- org='In Serf we trust, Inc.',
- ou='Test Suite Server', cn='localhost',
+ country='BE', state='Antwerp', city='Mechelen',
+ org='In Serf we trust, Inc.',
+ ou='Test Suite Server', cn='localhost',
email='[email protected]',
days_valid=-365)
# server certificate that will be valid in 10 years
- expiredcert = create_cert(subjectkey=serverkey,
+ expiredcert = create_cert(subjectkey=serverkey,
certfile='serfserver_future_cert.pem',
issuer=cacert, issuerkey=cakey,
country='BE', state='Antwerp', city='Mechelen',
- org='In Serf we trust, Inc.',
- ou='Test Suite Server', cn='localhost',
+ org='In Serf we trust, Inc.',
+ ou='Test Suite Server', cn='localhost',
email='[email protected]',
valid_before=10*365)
@@ -243,21 +243,21 @@ if __name__ == '__main__':
ocsp_signer=True)
# client key pair and certificate
- clientkey = create_key('private/serfclientkey.pem', 'serftest')
+ clientkey = create_key('private/serfclientkey.pem', b'serftest')
- clientcert = create_cert(subjectkey=clientkey,
+ clientcert = create_cert(subjectkey=clientkey,
certfile='serfclientcert.pem',
issuer=cacert, issuerkey=cakey,
- country='BE', state='Antwerp', city='Mechelen',
- org='In Serf we trust, Inc.',
- ou='Test Suite Client', cn='Serf Client',
+ country='BE', state='Antwerp', city='Mechelen',
+ org='In Serf we trust, Inc.',
+ ou='Test Suite Client', cn='Serf Client',
email='[email protected]')
- clientpkcs12 = create_pkcs12(clientkey, clientcert, cacert,
- 'serfclientcert.p12', 'serftest')
+ clientpkcs12 = create_pkcs12(clientkey, clientcert, cacert,
+ 'serfclientcert.p12', b'serftest')
- # Note that this creates a v1 CRL file without extensions set, and with
+ # Note that this creates a v1 CRL file without extensions set, and with
# MD5 hash. Not ideal, but pyOpenSSL doesn't support more than this.
- #
+ #
# crl
crl = create_crl(servercert, cakey, cacert, 'serfservercrl.pem')
Modified: serf/branches/user-defined-authn/test/serf_httpd.c
URL:
http://svn.apache.org/viewvc/serf/branches/user-defined-authn/test/serf_httpd.c?rev=1926661&r1=1926660&r2=1926661&view=diff
==============================================================================
--- serf/branches/user-defined-authn/test/serf_httpd.c (original)
+++ serf/branches/user-defined-authn/test/serf_httpd.c Mon Jun 23 10:09:30 2025
@@ -383,6 +383,7 @@ int main(int argc, const char **argv)
int verbose = 0;
const char *opt_arg;
const char *root_dir;
+ apr_finfo_t root_info;
apr_initialize();
atexit(apr_terminate);
@@ -448,8 +449,14 @@ int main(int argc, const char **argv)
exit(-1);
}
+ /* FIXME: root_dir is never used. */
root_dir = argv[opt->ind];
- /* FIXME: root_dir's value is never used. */
+ status = apr_stat(&root_info, root_dir, APR_FINFO_TYPE, scratch_pool);
+ printf("Ignoring root directory %s%s", root_dir,
+ (status == APR_SUCCESS
+ ? (root_info.filetype == APR_DIR ? "\n"
+ : " (which isn't a directory)\n")
+ : " (which doesn't even exist)\n"));
/* Setup debug logging */
if (verbose) {