Author: brane
Date: Sun Jul  6 14:00:09 2025
New Revision: 1927005

URL: http://svn.apache.org/viewvc?rev=1927005&view=rev
Log:
On the user-defined-authn branch: sync with trunk r1927004.

Modified:
    serf/branches/user-defined-authn/   (props changed)
    serf/branches/user-defined-authn/CMakeLists.txt
    serf/branches/user-defined-authn/SConstruct
    serf/branches/user-defined-authn/buckets/deflate_buckets.c
    serf/branches/user-defined-authn/buckets/headers_buckets.c
    serf/branches/user-defined-authn/buckets/ssl_buckets.c
    serf/branches/user-defined-authn/build/SerfChecks.cmake
    serf/branches/user-defined-authn/build/SerfGenClangd.cmake
    serf/branches/user-defined-authn/build/scons_extras.py
    serf/branches/user-defined-authn/serf_bucket_types.h
    serf/branches/user-defined-authn/test/CuTest.c
    serf/branches/user-defined-authn/test/MockHTTPinC/CMakeLists.txt
    serf/branches/user-defined-authn/test/mock_buckets.c
    serf/branches/user-defined-authn/test/serf_get.c
    serf/branches/user-defined-authn/test/serf_httpd.c
    serf/branches/user-defined-authn/test/test_context.c
    serf/branches/user-defined-authn/test/test_serf.h

Propchange: serf/branches/user-defined-authn/
------------------------------------------------------------------------------
  Merged /serf/trunk:r1926970-1927004

Modified: serf/branches/user-defined-authn/CMakeLists.txt
URL: 
http://svn.apache.org/viewvc/serf/branches/user-defined-authn/CMakeLists.txt?rev=1927005&r1=1927004&r2=1927005&view=diff
==============================================================================
--- serf/branches/user-defined-authn/CMakeLists.txt (original)
+++ serf/branches/user-defined-authn/CMakeLists.txt Sun Jul  6 14:00:09 2025
@@ -367,18 +367,21 @@ if(NOT MSVC)
     list(APPEND SERF_C_WARNINGS "-Wall")
     list(APPEND SERF_C_WARNINGS "-Wdeclaration-after-statement")
     list(APPEND SERF_C_WARNINGS "-Wmissing-prototypes")
+    list(APPEND SERF_C_WARNINGS "-Wshadow")
 
     string(APPEND CMAKE_C_FLAGS_DEBUG " -O0")
 
     if(SERF_MAINTAINER_MODE)
+      # This is for clang, which happily accepts unknow warning options.
+      CheckCFlag(SERF_C_WARNINGS "-Werror=unknown-warning-option")
       # Additional warning flags for more pedantic checks
-      list(APPEND SERF_C_WARNINGS "-Wimplicit-function-declaration")
-      list(APPEND SERF_C_WARNINGS "-Wmissing-variable-declarations")
-      list(APPEND SERF_C_WARNINGS "-Wunreachable-code")
-      list(APPEND SERF_C_WARNINGS "-Wshorten-64-to-32")
-      list(APPEND SERF_C_WARNINGS "-Wno-system-headers")
-      list(APPEND SERF_C_WARNINGS "-Wextra-tokens")
-      list(APPEND SERF_C_WARNINGS "-Wnewline-eof")
+      CheckCFlag(SERF_C_WARNINGS "-Wimplicit-function-declaration")
+      CheckCFlag(SERF_C_WARNINGS "-Wmissing-variable-declarations")
+      CheckCFlag(SERF_C_WARNINGS "-Wunreachable-code")
+      CheckCFlag(SERF_C_WARNINGS "-Wshorten-64-to-32")
+      CheckCFlag(SERF_C_WARNINGS "-Wno-system-headers")
+      CheckCFlag(SERF_C_WARNINGS "-Wextra-tokens")
+      CheckCFlag(SERF_C_WARNINGS "-Wnewline-eof")
     endif()
   endif()
 else()

Modified: serf/branches/user-defined-authn/SConstruct
URL: 
http://svn.apache.org/viewvc/serf/branches/user-defined-authn/SConstruct?rev=1927005&r1=1927004&r2=1927005&view=diff
==============================================================================
--- serf/branches/user-defined-authn/SConstruct (original)
+++ serf/branches/user-defined-authn/SConstruct Sun Jul  6 14:00:09 2025
@@ -361,19 +361,23 @@ if sys.platform != 'win32':
     env.SerfAppendIf(['CFLAGS'], r'-(ansi|std=c\d+)', CFLAGS=['-std=c89'])
     env.Append(CCFLAGS=['-Wdeclaration-after-statement',
                         '-Wmissing-prototypes',
+                        '-Wshadow',
                         '-Wall'])
 
   if debug:
     # env.Append(CCFLAGS=['-g'])
     env.SerfAppendIf(['CFLAGS', 'CCFLAGS'], r'-g\S*', CCFLAGS=['-g'])
     env.Append(CPPDEFINES=['DEBUG', '_DEBUG'])
-    env.Append(CCFLAGS=['-Wimplicit-function-declaration',
-                        '-Wmissing-variable-declarations',
-                        '-Wunreachable-code',
-                        '-Wshorten-64-to-32',
-                        '-Wno-system-headers',
-                        '-Wextra-tokens',
-                        '-Wnewline-eof'])
+    for flag in ['-Werror=unknown-warning-option',
+                 '-Wimplicit-function-declaration',
+                 '-Wmissing-variable-declarations',
+                 '-Wunreachable-code',
+                 '-Wshorten-64-to-32',
+                 '-Wno-system-headers',
+                 '-Wextra-tokens',
+                 '-Wnewline-eof']:
+        if env.SerfCheckCFlag(flag):
+          env.Append(CCFLAGS=[flag])
   else:
     # env.Append(CCFLAGS=['-O2'])
     env.SerfAppendIf(['CFLAGS', 'CCFLAGS'], r'-O\S*', CCFLAGS=['-O2'])

Modified: serf/branches/user-defined-authn/buckets/deflate_buckets.c
URL: 
http://svn.apache.org/viewvc/serf/branches/user-defined-authn/buckets/deflate_buckets.c?rev=1927005&r1=1927004&r2=1927005&view=diff
==============================================================================
--- serf/branches/user-defined-authn/buckets/deflate_buckets.c (original)
+++ serf/branches/user-defined-authn/buckets/deflate_buckets.c Sun Jul  6 
14:00:09 2025
@@ -264,11 +264,12 @@ static apr_status_t serf_deflate_refill(
         /* Make valgrind happy and explicitly initialize next_in to specific
           * value for empty buffer. */
         if (private_len) {
-            ctx->zstream.next_in = (unsigned char*)private_data;
-            ctx->zstream.avail_in = private_len;
+            ctx->zstream.next_in = (Bytef *)private_data;
+            SERF__POSITIVE_TO_INT(ctx->zstream.avail_in, apr_size_t, 
private_len);
             if (ctx->memLevel >= 0)
-                ctx->crc = crc32(ctx->crc, (const Bytef *)private_data,
-                                 private_len);
+                ctx->crc = crc32(ctx->crc,
+                                 ctx->zstream.next_in,
+                                 ctx->zstream.avail_in);
         } else {
             ctx->zstream.next_in = Z_NULL;
             ctx->zstream.avail_in = 0;
@@ -295,7 +296,7 @@ static apr_status_t serf_deflate_refill(
         if (zRC == Z_BUF_ERROR || ctx->zstream.avail_out == 0) {
             /* We're full or zlib requires more space. Either case, clear
                out our buffer, reset, and return. */
-            apr_size_t private_len;
+            uInt private_len;
             serf_bucket_t *tmp;
 
             ctx->zstream.next_out = ctx->buffer;
@@ -317,7 +318,7 @@ static apr_status_t serf_deflate_refill(
         }
 
         if (zRC == Z_STREAM_END) {
-            apr_size_t private_len;
+            uInt private_len;
             serf_bucket_t *tmp;
 
             private_len = ctx->bufferSize - ctx->zstream.avail_out;

Modified: serf/branches/user-defined-authn/buckets/headers_buckets.c
URL: 
http://svn.apache.org/viewvc/serf/branches/user-defined-authn/buckets/headers_buckets.c?rev=1927005&r1=1927004&r2=1927005&view=diff
==============================================================================
--- serf/branches/user-defined-authn/buckets/headers_buckets.c (original)
+++ serf/branches/user-defined-authn/buckets/headers_buckets.c Sun Jul  6 
14:00:09 2025
@@ -160,7 +160,7 @@ const char *serf_bucket_headers_get(
     headers_context_t *ctx = headers_bucket->data;
     header_list_t *found = ctx->list;
     const char *val = NULL;
-    int value_size = 0;
+    apr_size_t value_size = 0;
     int val_alloc = 0;
 
     while (found) {
@@ -308,10 +308,10 @@ static void select_value(
         l = 2;
         break;
     case READ_DONE:
-        *len = 0;
-        return;
+        /* ctx->state can have no other value here, but fall through to the
+           default anyway, so that *len is initialized before we return. */
     default:
-        /* Not reachable */
+        *len = 0;
         return;
     }
 

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=1927005&r1=1927004&r2=1927005&view=diff
==============================================================================
--- serf/branches/user-defined-authn/buckets/ssl_buckets.c (original)
+++ serf/branches/user-defined-authn/buckets/ssl_buckets.c Sun Jul  6 14:00:09 
2025
@@ -206,6 +206,10 @@ struct serf_ssl_context_t {
     X509 *cached_cert;
     EVP_PKEY *cached_cert_pw;
 
+    /* Error callback */
+    serf_ssl_error_cb_t error_callback;
+    void *error_baton;
+
     apr_status_t pending_err;
 
     /* Status of a fatal error, returned on subsequent encrypt or decrypt
@@ -353,10 +357,17 @@ detect_renegotiate(const SSL *s, int whe
 
 static void log_ssl_error(serf_ssl_context_t *ctx)
 {
-    unsigned long e = ERR_get_error();
-    serf__log(LOGLVL_ERROR, LOGCOMP_SSL, __FILE__, ctx->config,
-              "SSL Error: %s\n", ERR_error_string(e, NULL));
+    unsigned long err;
+
+    while ((err = ERR_get_error())) {
+
+        if (err && ctx->error_callback) {
+            char ebuf[256];
+            ERR_error_string_n(err, ebuf, sizeof(ebuf));
+            ctx->error_callback(ctx->error_baton, ctx->fatal_err, ebuf);
+        }
 
+    }
 }
 
 static void bio_set_data(BIO *bio, void *data)
@@ -419,7 +430,9 @@ static int bio_bucket_read(BIO *bio, cha
               "bio_bucket_read received %"APR_SIZE_T_FMT" bytes (%d)\n", len, 
status);
 
     memcpy(in, data, len);
-    return len;
+
+    /* Safe cast: len <= inlen */
+    return (int)len;
 }
 
 /* Returns the amount written. */
@@ -465,7 +478,8 @@ static int bio_file_read(BIO *bio, char
         if (APR_STATUS_IS_EOF(status)) {
             return -1;
         } else {
-            return len;
+            /* Safe cast: len <= inlen */
+            return (int)len;
         }
     }
 
@@ -483,7 +497,8 @@ static int bio_file_write(BIO *bio, cons
     nbytes = inl;
     apr_file_write(file, in, &nbytes);
 
-    return nbytes;
+    /* Safe cast: nbytes <= inlen */
+    return (int)nbytes;
 }
 
 static int bio_file_gets(BIO *bio, char *in, int inlen)
@@ -683,7 +698,7 @@ static int ocsp_callback(SSL *ssl, void
     serf_ssl_context_t *ctx = (serf_ssl_context_t*)baton;
     OCSP_RESPONSE *response;
     const unsigned char *resp_der;
-    int len;
+    long len;
     int failures = 0;
     int cert_valid = 0;
 
@@ -1075,15 +1090,6 @@ static apr_status_t status_from_ssl_erro
                 status = ctx->pending_err;
                 ctx->pending_err = APR_SUCCESS;
             } else {
-                /*unsigned long l = ERR_peek_error();
-                int lib = ERR_GET_LIB(l);
-                int reason = ERR_GET_REASON(l);*/
-
-                /* ### Detect more specific errors?
-                  When lib is ERR_LIB_SSL, then reason is one of the
-                  many SSL_R_XXXX reasons in ssl.h
-                */
-
                 if (SSL_in_init(ctx->ssl))
                     ctx->fatal_err = SERF_ERROR_SSL_SETUP_FAILED;
                 else
@@ -1093,6 +1099,15 @@ static apr_status_t status_from_ssl_erro
                 log_ssl_error(ctx);
             }
             break;
+
+        case SSL_ERROR_WANT_X509_LOOKUP:
+            /* The ssl_need_client_cert() function returned -1 because an
+             * error occurred inside that function. The error has already
+             * been handled, just return the fatal error.
+             */
+            status = ctx->fatal_err = SERF_ERROR_SSL_CERT_FAILED;
+            break;
+
         default:
             status = ctx->fatal_err = SERF_ERROR_SSL_COMM_FAILED;
             log_ssl_error(ctx);
@@ -1143,7 +1158,7 @@ static apr_status_t ssl_decrypt(void *ba
 {
     serf_ssl_context_t *ctx = baton;
     apr_status_t status;
-    int ssl_len;
+    int ssl_len, ssl_bufsize;
 
     if (ctx->fatal_err)
         return ctx->fatal_err;
@@ -1160,8 +1175,9 @@ static apr_status_t ssl_decrypt(void *ba
         }
     }
 
+    SERF__POSITIVE_TO_INT(ssl_bufsize, apr_size_t, bufsize);
     serf__log(LOGLVL_DEBUG, LOGCOMP_SSL, __FILE__, ctx->config,
-              "ssl_decrypt: begin %" APR_SIZE_T_FMT "\n", bufsize);
+              "ssl_decrypt: begin %d\n", ssl_bufsize);
 
     ctx->want_read = FALSE; /* Reading now */
     ctx->crypt_status = APR_SUCCESS; /* Clear before calling SSL */
@@ -1173,7 +1189,7 @@ static apr_status_t ssl_decrypt(void *ba
        Luckily we can assume that we are called from the databuffer
        implementation */
     /* Is there some data waiting to be read? */
-    ssl_len = SSL_read(ctx->ssl, buf, bufsize);
+    ssl_len = SSL_read(ctx->ssl, buf, ssl_bufsize);
     if (ssl_len < 0) {
 
         *len = 0;
@@ -1207,7 +1223,7 @@ static apr_status_t ssl_decrypt(void *ba
         *len = ssl_len;
         status = ctx->crypt_status;
         serf__log(LOGLVL_DEBUG, LOGCOMP_SSLMSG, __FILE__, ctx->config,
-                  "---\n%.*s\n-(%"APR_SIZE_T_FMT")-\n", (int)*len, buf, *len);
+                  "---\n%.*s\n-(%"APR_SIZE_T_FMT")-\n", ssl_len, buf, *len);
     }
 
 
@@ -1304,7 +1320,7 @@ static apr_status_t ssl_encrypt(void *ba
     /* Oh well, read from our stream now. */
     interim_bufsize = bufsize;
     do {
-        apr_size_t interim_len;
+        int interim_len;
 
         if (!ctx->want_read) {
             struct iovec vecs[SERF__STD_IOV_COUNT];
@@ -1340,7 +1356,7 @@ static apr_status_t ssl_encrypt(void *ba
                 interim_len = vecs_data_len;
 
                 serf__log(LOGLVL_DEBUG, LOGCOMP_SSL, __FILE__, ctx->config,
-                          "ssl_encrypt: bucket read %"APR_SIZE_T_FMT" bytes; "\
+                          "ssl_encrypt: bucket read %d bytes; "\
                           "status %d\n", interim_len, status);
 
                 /* When an SSL_write() operation has to be repeated because of
@@ -1375,8 +1391,8 @@ static apr_status_t ssl_encrypt(void *ba
                     serf_bucket_mem_free(ctx->allocator, vecs_data);
 
                     serf__log(LOGLVL_DEBUG, LOGCOMP_SSL, __FILE__, ctx->config,
-                              "---\n%.*s\n-(%"APR_SIZE_T_FMT")-\n",
-                              (int)interim_len, vecs_data, interim_len);
+                              "---\n%.*s\n-(%d)-\n",
+                              interim_len, vecs_data, interim_len);
 
                 }
             }
@@ -1592,6 +1608,7 @@ static int ssl_pass_cb(UI *ui, UI_STRING
 static int ssl_need_client_cert(SSL *ssl, X509 **cert, EVP_PKEY **pkey)
 {
     serf_ssl_context_t *ctx = SSL_get_app_data(ssl);
+    unsigned long err = 0;
 #if defined(SERF_HAVE_OSSL_STORE_OPEN_EX)
     STACK_OF(X509) *leaves;
     STACK_OF(X509) *intermediates;
@@ -1629,7 +1646,7 @@ static int ssl_need_client_cert(SSL *ssl
         const char *cert_uri = NULL;
         OSSL_STORE_CTX *store = NULL;
         OSSL_STORE_INFO *info;
-        X509 *c;
+        X509 *x509;
         STACK_OF(X509_NAME) *requested;
         int type;
 
@@ -1656,10 +1673,14 @@ static int ssl_need_client_cert(SSL *ssl
         store = OSSL_STORE_open_ex(cert_uri, NULL, NULL, ui_method, ctx, NULL,
                                    NULL, NULL);
         if (!store) {
-            int err = ERR_get_error();
-            serf__log(LOGLVL_ERROR, LOGCOMP_SSL, __FILE__, ctx->config,
-                      "OpenSSL store error (%s): %d %d\n", cert_uri,
-                      ERR_GET_LIB(err), ERR_GET_REASON(err));
+
+            if (ctx->error_callback) {
+                char ebuf[1024];
+                ctx->fatal_err = SERF_ERROR_SSL_CERT_FAILED;
+                apr_snprintf(ebuf, sizeof(ebuf), "could not open URI: %s", 
cert_uri);
+                ctx->error_callback(ctx->error_baton, ctx->fatal_err, ebuf);
+            }
+
             break;
         }
 
@@ -1669,6 +1690,14 @@ static int ssl_need_client_cert(SSL *ssl
             info = OSSL_STORE_load(store);
 
             if (!info) {
+
+                if (ctx->error_callback) {
+                    char ebuf[1024];
+                    ctx->fatal_err = SERF_ERROR_SSL_CERT_FAILED;
+                    apr_snprintf(ebuf, sizeof(ebuf), "could not read URI: %s", 
cert_uri);
+                    ctx->error_callback(ctx->error_baton, ctx->fatal_err, 
ebuf);
+                }
+
                 break;
             }
 
@@ -1715,13 +1744,15 @@ static int ssl_need_client_cert(SSL *ssl
             OSSL_STORE_INFO_free(info);
         }
 
-        /* FIXME: openssl error checking goes here */
-
         OSSL_STORE_close(store);
 
+        if (ERR_peek_error()) {
+            break;
+        }
+
         /* walk the leaf certificates, choose the best one */
 
-        while ((c = sk_X509_pop(leaves))) {
+        while ((x509 = sk_X509_pop(leaves))) {
 
             EVP_PKEY *k = NULL;
             int i, n, found = 0;
@@ -1730,7 +1761,7 @@ static int ssl_need_client_cert(SSL *ssl
             n = sk_EVP_PKEY_num(keys);
             for (i = 0; i < n; ++i) {
                 k = sk_EVP_PKEY_value(keys, i);
-                if (X509_check_private_key(c, k)) {
+                if (X509_check_private_key(x509, k)) {
                     found = 1;
                     break;
                 }
@@ -1741,10 +1772,10 @@ static int ssl_need_client_cert(SSL *ssl
 
             /* CAs requested? if so, skip non matches, if not, accept all */
             if (sk_X509_NAME_num(requested) &&
-                    !X509_get_ex_data(c, ssl_x509_ex_data_idx)) {
+                    !X509_get_ex_data(x509, ssl_x509_ex_data_idx)) {
                 STACK_OF(X509) *chain;
 
-                chain = X509_build_chain(c, intermediates, requests, 0, NULL,
+                chain = X509_build_chain(x509, intermediates, requests, 0, 
NULL,
                                          NULL);
 
                 if (!chain) {
@@ -1757,23 +1788,23 @@ static int ssl_need_client_cert(SSL *ssl
             /* no best candidate yet? we're in first place */
             if (!*cert) {
                 EVP_PKEY_up_ref(k);
-                *cert = c; /* don't dup, we're returning this */
+                *cert = x509; /* don't dup, we're returning this */
                 *pkey = k;
                 continue;
             }
 
             /* were we issued after the previous best? */
             if (ASN1_TIME_compare(X509_get0_notBefore(*cert),
-                    X509_get0_notBefore(c)) < 0) {
+                    X509_get0_notBefore(x509)) < 0) {
                 X509_free(*cert);
                 EVP_PKEY_free(*pkey);
                 EVP_PKEY_up_ref(k);
-                *cert = c; /* don't dup, we're returning this */
+                *cert = x509; /* don't dup, we're returning this */
                 *pkey = k;
                 continue;
             }
 
-            X509_free(c);
+            X509_free(x509);
         }
 
         break;
@@ -1785,6 +1816,12 @@ static int ssl_need_client_cert(SSL *ssl
     X509_STORE_free(requests);
     UI_destroy_method(ui_method);
 
+    if (ERR_peek_error()) {
+        log_ssl_error(ctx);
+
+        return -1;
+    }
+
     /* we settled on a cert and key, cache it for later */
 
     if (*cert && *pkey) {
@@ -1843,9 +1880,15 @@ static int ssl_need_client_cert(SSL *ssl
         status = apr_file_open(&cert_file, cert_path, APR_READ, APR_OS_DEFAULT,
                                ctx->pool);
 
-        /* TODO: this will hang indefintely when the file can't be found. */
         if (status) {
-            continue;
+            if (ctx->error_callback) {
+                char ebuf[1024];
+                apr_snprintf(ebuf, sizeof(ebuf), "could not open PKCS12: %s", 
cert_path);
+                ctx->error_callback(ctx->error_baton, ctx->fatal_err, ebuf);
+                apr_strerror(status, ebuf, sizeof(ebuf));
+                ctx->error_callback(ctx->error_baton, ctx->fatal_err, ebuf);
+            }
+            return -1;
         }
 
         biom = bio_meth_file_new();
@@ -1876,7 +1919,7 @@ static int ssl_need_client_cert(SSL *ssl
             return 1;
         }
         else {
-            int err = ERR_get_error();
+            err = ERR_get_error();
             ERR_clear_error();
             if (ERR_GET_LIB(err) == ERR_LIB_PKCS12 &&
                 ERR_GET_REASON(err) == PKCS12_R_MAC_VERIFY_FAILURE) {
@@ -1922,18 +1965,46 @@ static int ssl_need_client_cert(SSL *ssl
                             }
                             return 1;
                         }
+                        else {
+
+                            if (ctx->error_callback) {
+                                char ebuf[1024];
+                                ctx->fatal_err = SERF_ERROR_SSL_CERT_FAILED;
+                                apr_snprintf(ebuf, sizeof(ebuf), "could not 
parse PKCS12: %s", cert_path);
+                                ctx->error_callback(ctx->error_baton, 
ctx->fatal_err, ebuf);
+                            }
+
+                            log_ssl_error(ctx);
+                            return -1;
+                        }
                     }
                 }
                 PKCS12_free(p12);
                 bio_meth_free(biom);
-                return 0;
+
+                if (ctx->error_callback) {
+                    char ebuf[1024];
+                    ctx->fatal_err = SERF_ERROR_SSL_CERT_FAILED;
+                    apr_snprintf(ebuf, sizeof(ebuf), "PKCS12 needs a password: 
%s", cert_path);
+                    ctx->error_callback(ctx->error_baton, ctx->fatal_err, 
ebuf);
+                }
+
+                log_ssl_error(ctx);
+                return -1;
             }
             else {
-                serf__log(LOGLVL_ERROR, LOGCOMP_SSL, __FILE__, ctx->config,
-                          "OpenSSL cert error: %d %d\n", ERR_GET_LIB(err),
-                          ERR_GET_REASON(err));
                 PKCS12_free(p12);
                 bio_meth_free(biom);
+
+                if (ctx->error_callback) {
+                    char ebuf[1024];
+                    ctx->fatal_err = SERF_ERROR_SSL_CERT_FAILED;
+                    apr_snprintf(ebuf, sizeof(ebuf), "could not parse PKCS12: 
%s", cert_path);
+                    ctx->error_callback(ctx->error_baton, ctx->fatal_err, 
ebuf);
+                }
+
+                log_ssl_error(ctx);
+                return -1;
             }
         }
     }
@@ -2010,6 +2081,15 @@ void serf_ssl_server_cert_chain_callback
     context->server_cert_userdata = data;
 }
 
+void serf_ssl_error_cb_set(
+    serf_ssl_context_t *context,
+    serf_ssl_error_cb_t callback,
+    void *baton)
+{
+    context->error_callback = callback;
+    context->error_baton = baton;
+}
+
 static int ssl_new_session(SSL *ssl, SSL_SESSION *session)
 {
     serf_ssl_context_t *ctx = SSL_get_app_data(ssl);
@@ -2075,6 +2155,9 @@ static serf_ssl_context_t *ssl_init_cont
     ssl_ctx->protocol_callback = NULL;
     ssl_ctx->protocol_userdata = NULL;
 
+    ssl_ctx->error_callback = NULL;
+    ssl_ctx->error_baton = NULL;
+
     SSL_CTX_set_verify(ssl_ctx->ctx, SSL_VERIFY_PEER,
                        validate_server_certificate);
     SSL_CTX_set_options(ssl_ctx->ctx, SSL_OP_ALL);
@@ -2165,8 +2248,9 @@ apr_status_t serf_ssl_set_hostname(serf_
         ERR_clear_error();
     }
     return APR_SUCCESS;
-#endif
+#else
     return APR_ENOTIMPL;
+#endif
 }
 
 apr_status_t serf_ssl_negotiate_protocol(serf_ssl_context_t *context,
@@ -2219,7 +2303,8 @@ apr_status_t serf_ssl_negotiate_protocol
     at += len;
 
 #ifdef SERF_HAVE_OPENSSL_ALPN
-    if (SSL_set_alpn_protos(context->ssl, raw_header, raw_len)) {
+    /* Safe cast: raw_len < 65536 therefore raw_len <= INT_MAX */
+    if (SSL_set_alpn_protos(context->ssl, raw_header, (int)raw_len)) {
         ERR_clear_error();
     }
     apr_pool_destroy(subpool);
@@ -2386,8 +2471,9 @@ apr_status_t serf_ssl_add_crl_from_file(
 
     result = X509_STORE_add_crl(store, crl);
     if (!result) {
+        ssl_ctx->fatal_err = status = SERF_ERROR_SSL_CERT_FAILED;
         log_ssl_error(ssl_ctx);
-        return SERF_ERROR_SSL_CERT_FAILED;
+        return status;
     }
 
     /* TODO: free crl when closing ssl session */
@@ -2403,8 +2489,9 @@ serf_ssl_check_cert_status_request(serf_
     SSL_CTX_set_tlsext_status_arg(ssl_ctx->ctx, ssl_ctx);
     SSL_set_tlsext_status_type(ssl_ctx->ssl, TLSEXT_STATUSTYPE_ocsp);
     return APR_SUCCESS;
-#endif
+#else
     return APR_ENOTIMPL;
+#endif
 }
 
 serf_bucket_t *serf_bucket_ssl_decrypt_create(
@@ -2769,19 +2856,17 @@ static void disable_compression(serf_ssl
 
 apr_status_t serf_ssl_use_compression(serf_ssl_context_t *ssl_ctx, int enabled)
 {
-    if (enabled) {
 #ifdef SSL_OP_NO_COMPRESSION
+    if (enabled) {
         SSL_clear_options(ssl_ctx->ssl, SSL_OP_NO_COMPRESSION);
         return APR_SUCCESS;
-#endif
     } else {
-#ifdef SSL_OP_NO_COMPRESSION
         SSL_set_options(ssl_ctx->ssl, SSL_OP_NO_COMPRESSION);
         return APR_SUCCESS;
-#endif
     }
-
-    return APR_EGENERAL;
+#else
+    return APR_ENOTIMPL;
+#endif
 }
 
 static void serf_ssl_destroy_and_data(serf_bucket_t *bucket)
@@ -2954,7 +3039,7 @@ struct serf_ssl_ocsp_request_t {
 
     /* DER-encoded request and size. */
     const void *der_request;
-    apr_size_t der_request_size;
+    int der_request_size;
 };
 
 static apr_status_t free_ocsp_request(void *data)
@@ -3137,8 +3222,8 @@ serf_ssl_ocsp_request_t *serf_ssl_ocsp_r
         const char *base64_request = apr_pstrmemdup(
             scratch_pool, encoded_ocsp_request,
             end_request - encoded_ocsp_request);
-        long der_request_size = apr_base64_decode_len(base64_request);
-        long der_id_size = apr_base64_decode_len(base64_id);
+        int der_request_size = apr_base64_decode_len(base64_request);
+        int der_id_size = apr_base64_decode_len(base64_id);
 
         OCSP_REQUEST *ocsp_req;
         OCSP_CERTID *cert_id;

Modified: serf/branches/user-defined-authn/build/SerfChecks.cmake
URL: 
http://svn.apache.org/viewvc/serf/branches/user-defined-authn/build/SerfChecks.cmake?rev=1927005&r1=1927004&r2=1927005&view=diff
==============================================================================
--- serf/branches/user-defined-authn/build/SerfChecks.cmake (original)
+++ serf/branches/user-defined-authn/build/SerfChecks.cmake Sun Jul  6 14:00:09 
2025
@@ -18,6 +18,7 @@
 # ===================================================================
 
 include(CheckCSourceCompiles)
+include(CheckCCompilerFlag)
 include(CheckIncludeFile)
 include(CheckTypeSize)
 
@@ -141,3 +142,13 @@ macro(CheckType name_ header_ symbol_)
     list(APPEND SERF_C_DEFINES "${symbol_}")
   endif()
 endmacro(CheckType)
+
+
+macro(CheckCFlag list_ flag_)
+  string(REGEX REPLACE "[/=-]" "__" __c__ "serf_feature_CheckCFlag_${flag_}")
+  check_c_compiler_flag(${flag_} ${__c__})
+  if(${__c__})
+    list(APPEND ${list_} ${flag_})
+  endif()
+  unset(__c__)
+endmacro(CheckCFlag)

Modified: serf/branches/user-defined-authn/build/SerfGenClangd.cmake
URL: 
http://svn.apache.org/viewvc/serf/branches/user-defined-authn/build/SerfGenClangd.cmake?rev=1927005&r1=1927004&r2=1927005&view=diff
==============================================================================
--- serf/branches/user-defined-authn/build/SerfGenClangd.cmake (original)
+++ serf/branches/user-defined-authn/build/SerfGenClangd.cmake Sun Jul  6 
14:00:09 2025
@@ -54,24 +54,24 @@ function(SerfGenClangd)
     "  Add:\n")
   write_flags("--language=c")
   write_includes("${CMAKE_SOURCE_DIR}")
-  write_includes("${APR_INCLUDES}")
+
+  list(APPEND includes ${APR_INCLUDES})
   if(NOT APR_CONTAINS_APRUTIL)
-    write_includes("${APRUTIL_INCLUDES}")
+    list(APPEND includes ${APRUTIL_INCLUDES})
   endif()
-  write_includes("${OPENSSL_INCLUDE_DIR}")
-  write_includes("${ZLIB_INCLUDE_DIR}")
+  list(APPEND includes ${OPENSSL_INCLUDE_DIR})
+  list(APPEND includes ${ZLIB_INCLUDE_DIR})
   if(BROTLI_FOUND)
-    write_includes("${BROTLI_INCLUDES}")
+    list(APPEND includes ${BROTLI_INCLUDES})
   endif()
   if(GSSAPI_FOUND)
-    write_includes("${GSSAPI_INCLUDES}")
+    list(APPEND includes ${GSSAPI_INCLUDES})
   endif()
+  list(REMOVE_DUPLICATES includes)
+  write_includes(${includes})
 
-  get_directory_property(cdef COMPILE_DEFINITIONS)
-  write_defines(${cdef})
-
-  set(flags ${CMAKE_C_FLAGS})
-  separate_arguments(flags)
-  write_flags(${flags})
+  write_defines(${SERF_C_DEFINES})
+  write_flags(${SERF_C_WARNINGS})
+  write_flags(${APR_CFLAGS})
 endfunction(SerfGenClangd)
 SerfGenClangd()

Modified: serf/branches/user-defined-authn/build/scons_extras.py
URL: 
http://svn.apache.org/viewvc/serf/branches/user-defined-authn/build/scons_extras.py?rev=1927005&r1=1927004&r2=1927005&view=diff
==============================================================================
--- serf/branches/user-defined-authn/build/scons_extras.py (original)
+++ serf/branches/user-defined-authn/build/scons_extras.py Sun Jul  6 14:00:09 
2025
@@ -22,6 +22,7 @@
 import re
 
 import SCons.Environment
+import SCons.SConf
 import SCons.Util
 
 
@@ -54,6 +55,20 @@ def __env_munge_if(env, method, variable
   getattr(env, method)(**kwargs)
 
 
+def __env_check_c_flag(env, flag):
+  '''Check if the C compiler accepts the `flag`'''
+
+  xenv = env.Clone()
+  xenv.Append(CCFLAGS=[flag])
+  xonf = SCons.SConf.SConf(xenv)
+  xmsg = SCons.SConf.CheckContext(xonf)
+  xmsg.Display('Checking if the C compiler accepts %s... ' % (flag,))
+  result = xonf.TryCompile('int main(void) { return 0; }', '.c')
+  xmsg.Result(result)
+  xonf.Finish()
+  return result
+
+
 def AddEnvironmentMethods():
   SCons.Util.AddMethod(
     SCons.Environment.Environment,
@@ -65,6 +80,9 @@ def AddEnvironmentMethods():
     lambda env, variables, pattern, **kwargs:
     __env_munge_if(env, 'Prepend', variables, pattern, **kwargs),
     'SerfPrependIf')
+  SCons.Util.AddMethod(
+    SCons.Environment.Environment,
+    __env_check_c_flag, 'SerfCheckCFlag')
 
 
 #

Modified: serf/branches/user-defined-authn/serf_bucket_types.h
URL: 
http://svn.apache.org/viewvc/serf/branches/user-defined-authn/serf_bucket_types.h?rev=1927005&r1=1927004&r2=1927005&view=diff
==============================================================================
--- serf/branches/user-defined-authn/serf_bucket_types.h (original)
+++ serf/branches/user-defined-authn/serf_bucket_types.h Sun Jul  6 14:00:09 
2025
@@ -687,6 +687,33 @@ void serf_ssl_server_cert_chain_callback
     void *data);
 
 /**
+ * Callback type for detailed TLS error strings. This callback will be fired
+ * every time the underlying crypto library encounters an error. The message
+ * lasts only as long as the callback, if the caller wants to set aside the
+ * message for later use, a copy must be made.
+ *
+ * It is possible that for a given error multiple strings will be returned
+ * in multiple callbacks. The caller may choose to handle all strings, or
+ * may choose to ignore all strings but the last most detailed one.
+ */
+typedef apr_status_t (*serf_ssl_error_cb_t)(
+    void *baton,
+    apr_status_t status,
+    const char *message);
+
+/**
+ * Set a callback to return any detailed certificate error from the underlying
+ * cryptographic library.
+ *
+ * The callback is associated with the context, however the choice of baton
+ * will depend on the needs of the caller.
+ */
+void serf_ssl_error_cb_set(
+    serf_ssl_context_t *context,
+    serf_ssl_error_cb_t callback,
+    void *baton);
+
+/**
  * Use the default root CA certificates as included with the OpenSSL library.
  */
 apr_status_t serf_ssl_use_default_certificates(

Modified: serf/branches/user-defined-authn/test/CuTest.c
URL: 
http://svn.apache.org/viewvc/serf/branches/user-defined-authn/test/CuTest.c?rev=1927005&r1=1927004&r2=1927005&view=diff
==============================================================================
--- serf/branches/user-defined-authn/test/CuTest.c (original)
+++ serf/branches/user-defined-authn/test/CuTest.c Sun Jul  6 14:00:09 2025
@@ -46,8 +46,7 @@ char* CuStrAlloc(int size)
 
 char* CuStrCopy(const char* old)
 {
-    int len = strlen(old);
-    char* newStr = CuStrAlloc(len + 1);
+    char* newStr = CuStrAlloc(1 + (int)strlen(old));
     strcpy(newStr, old);
     return newStr;
 }
@@ -94,7 +93,7 @@ void CuStringAppend(CuString* str, const
         text = "NULL";
     }
 
-    length = strlen(text);
+    length = (int)strlen(text);
     if (str->length + length + 1 >= str->size)
         CuStringResize(str, str->length + length + 1 + STRING_INC);
     str->length += length;
@@ -121,7 +120,7 @@ void CuStringAppendFormat(CuString* str,
 
 void CuStringInsert(CuString* str, const char* text, int pos)
 {
-    int length = strlen(text);
+    int length = (int)strlen(text);
     if (pos > str->length)
         pos = str->length;
     if (str->length + length + 1 >= str->size)

Modified: serf/branches/user-defined-authn/test/MockHTTPinC/CMakeLists.txt
URL: 
http://svn.apache.org/viewvc/serf/branches/user-defined-authn/test/MockHTTPinC/CMakeLists.txt?rev=1927005&r1=1927004&r2=1927005&view=diff
==============================================================================
--- serf/branches/user-defined-authn/test/MockHTTPinC/CMakeLists.txt (original)
+++ serf/branches/user-defined-authn/test/MockHTTPinC/CMakeLists.txt Sun Jul  6 
14:00:09 2025
@@ -49,7 +49,10 @@ set(MockHTTPinC_DEFINES ${SERF_C_DEFINES
 list(REMOVE_ITEM MockHTTPinC_DEFINES "OPENSSL_NO_DEPRECATED")
 
 add_library(mockhttpinc STATIC ${MockHTTPinC_SOURCES})
-target_compile_options(mockhttpinc PRIVATE ${MockHTTPinC_WARNINGS})
+target_compile_options(mockhttpinc
+                       PRIVATE
+                       ${MockHTTPinC_WARNINGS}
+                       ${APR_CFLAGS})
 target_compile_definitions(mockhttpinc
                            PUBLIC "MOCKHTTP_OPENSSL"
                            PRIVATE ${MockHTTPinC_DEFINES})

Modified: serf/branches/user-defined-authn/test/mock_buckets.c
URL: 
http://svn.apache.org/viewvc/serf/branches/user-defined-authn/test/mock_buckets.c?rev=1927005&r1=1927004&r2=1927005&view=diff
==============================================================================
--- serf/branches/user-defined-authn/test/mock_buckets.c (original)
+++ serf/branches/user-defined-authn/test/mock_buckets.c Sun Jul  6 14:00:09 
2025
@@ -73,7 +73,7 @@ static apr_status_t next_action(mockbkt_
         if (ctx->remaining_data <= 0) {
             ctx->current_data = action->data;
             ctx->remaining_times = action->times;
-            ctx->remaining_data = strlen(action->data);
+            ctx->remaining_data = (int)strlen(action->data);
         }
 
         return APR_SUCCESS;
@@ -331,7 +331,7 @@ static void test_basic_mock_bucket(CuTes
         for (i = 0; i < 5; i++) {
             status = serf_bucket_peek(mock_bkt, &data, &len);
             CuAssertIntEquals(tc, APR_SUCCESS, status);
-            CuAssertIntEquals(tc, 0, len);
+            CuAssertUIntEquals(tc, 0, len);
             CuAssertIntEquals(tc, '\0', *data);
         }
 
@@ -339,7 +339,7 @@ static void test_basic_mock_bucket(CuTes
 
         status = serf_bucket_peek(mock_bkt, &data, &len);
         CuAssertIntEquals(tc, APR_EOF, status);
-        CuAssertIntEquals(tc, 6, len);
+        CuAssertUIntEquals(tc, 6, len);
         CuAssert(tc, "Read data is not equal to expected.",
                  strncmp("blabla", data, len) == 0);
         serf_bucket_destroy(mock_bkt);

Modified: serf/branches/user-defined-authn/test/serf_get.c
URL: 
http://svn.apache.org/viewvc/serf/branches/user-defined-authn/test/serf_get.c?rev=1927005&r1=1927004&r2=1927005&view=diff
==============================================================================
--- serf/branches/user-defined-authn/test/serf_get.c (original)
+++ serf/branches/user-defined-authn/test/serf_get.c Sun Jul  6 14:00:09 2025
@@ -231,8 +231,8 @@ static apr_status_t conn_setup(apr_socke
         if (!conn_ctx->ssl_ctx) {
             conn_ctx->ssl_ctx = serf_bucket_ssl_decrypt_context_get(c);
         }
-        serf_ssl_server_cert_chain_callback_set(conn_ctx->ssl_ctx, 
-                                                ignore_all_cert_errors, 
+        serf_ssl_server_cert_chain_callback_set(conn_ctx->ssl_ctx,
+                                                ignore_all_cert_errors,
                                                 print_certs, NULL);
         serf_ssl_set_hostname(conn_ctx->ssl_ctx, ctx->hostname);
 
@@ -407,7 +407,7 @@ static apr_status_t setup_request(serf_r
     *acceptor_baton = ctx->acceptor_baton;
     *handler = ctx->handler;
     *handler_baton = ctx;
-    
+
     return APR_SUCCESS;
 }
 
@@ -816,7 +816,6 @@ int main(int argc, const char **argv)
     if (debug)
     {
         serf_log_output_t *output;
-        apr_status_t status;
 
         status = serf_logging_create_stream_output(&output,
                                                    context,

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=1927005&r1=1927004&r2=1927005&view=diff
==============================================================================
--- serf/branches/user-defined-authn/test/serf_httpd.c (original)
+++ serf/branches/user-defined-authn/test/serf_httpd.c Sun Jul  6 14:00:09 2025
@@ -461,7 +461,6 @@ int main(int argc, const char **argv)
     /* Setup debug logging */
     if (verbose) {
         serf_log_output_t *output;
-        apr_status_t status;
         apr_uint32_t level;
 
         level = SERF_LOG_WARNING;

Modified: serf/branches/user-defined-authn/test/test_context.c
URL: 
http://svn.apache.org/viewvc/serf/branches/user-defined-authn/test/test_context.c?rev=1927005&r1=1927004&r2=1927005&view=diff
==============================================================================
--- serf/branches/user-defined-authn/test/test_context.c (original)
+++ serf/branches/user-defined-authn/test/test_context.c Sun Jul  6 14:00:09 
2025
@@ -183,7 +183,7 @@ static apr_status_t http_conn_setup_mock
                                                                skt,
                                                                tb->bkt_alloc);
     *input_bkt = serf_bucket_mock_sock_create(skt_bkt,
-                                              tb->user_baton_l,
+                                              tb->user_baton_s,
                                               tb->bkt_alloc);
 
     return APR_SUCCESS;
@@ -286,7 +286,7 @@ static void test_aborted_connection(CuTe
     /* Set up a test context with a server. Use the mock socket to return
        APR_ECONNABORTED instead of APR_EOF. */
     setup_test_mock_server(tb);
-    tb->user_baton_l = APR_ECONNABORTED;
+    tb->user_baton_s = APR_ECONNABORTED;
     status = setup_test_client_context(tb, http_conn_setup_mock_socket,
                                        tb->pool);
     CuAssertIntEquals(tc, APR_SUCCESS, status);
@@ -304,7 +304,7 @@ static void test_aborted_connection_with
     /* Set up a test context with a server. Use the mock socket to return
      APR_ECONNABORTED instead of APR_EOF. */
     setup_test_mock_server(tb);
-    tb->user_baton_l = APR_ECONNABORTED;
+    tb->user_baton_s = APR_ECONNABORTED;
     status = setup_test_client_context(tb, http_conn_setup_mock_socket,
                                        tb->pool);
     CuAssertIntEquals(tc, APR_SUCCESS, status);
@@ -323,7 +323,7 @@ static void test_reset_connection(CuTest
     /* Set up a test context with a server. Use the mock socket to return
        APR_ECONNRESET instead of APR_EOF. */
     setup_test_mock_server(tb);
-    tb->user_baton_l = APR_ECONNRESET;
+    tb->user_baton_s = APR_ECONNRESET;
     status = setup_test_client_context(tb, http_conn_setup_mock_socket,
                                        tb->pool);
     CuAssertIntEquals(tc, APR_SUCCESS, status);
@@ -341,7 +341,7 @@ static void test_reset_connection_with_a
     /* Set up a test context with a server. Use the mock socket to return
        APR_ECONNRESET instead of APR_EOF. */
     setup_test_mock_server(tb);
-    tb->user_baton_l = APR_ECONNRESET;
+    tb->user_baton_s = APR_ECONNRESET;
     status = setup_test_client_context(tb, http_conn_setup_mock_socket,
                                        tb->pool);
     CuAssertIntEquals(tc, APR_SUCCESS, status);

Modified: serf/branches/user-defined-authn/test/test_serf.h
URL: 
http://svn.apache.org/viewvc/serf/branches/user-defined-authn/test/test_serf.h?rev=1927005&r1=1927004&r2=1927005&view=diff
==============================================================================
--- serf/branches/user-defined-authn/test/test_serf.h (original)
+++ serf/branches/user-defined-authn/test/test_serf.h Sun Jul  6 14:00:09 2025
@@ -90,6 +90,7 @@ typedef struct test_baton_t {
     /* Extra batons which can be freely used by tests. */
     void *user_baton;
     long user_baton_l;
+    apr_status_t user_baton_s;
 
     /* Flags that can be used to report situations, e.g. that a callback was
        called. */



Reply via email to