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. */