Author: brane Date: Thu Jun 26 06:06:32 2025 New Revision: 1926731 URL: http://svn.apache.org/viewvc?rev=1926731&view=rev Log: On the user-defined-authn branch: Parse parameters from the Authentication-Info and Proxy-Authentication-Info headers and pass them to the response-validation callback.
* serf.h (serf_authn_validate_response_func_t): Add the parameter dict argument and update the docstring. * auth/auth.h (SERF__INFO_HEADER_FROM_PEER): New macro. * auth/auth_user_defined.c (serf__authn_user__validate_response): Parse the response authn parameters if the appropriate header was part of the response. * test/test_auth.c (struct user_authn_baton, user_authn_make_baton): Add the test context to the struct. (user_authn_handle, user_authn_setup_request): Use test assertions where appropriate. (user_authn_validate_response): Handle the new parameter. (user_authentication): Return authentication info in the mock response. Modified: serf/branches/user-defined-authn/auth/auth.h serf/branches/user-defined-authn/auth/auth_user_defined.c serf/branches/user-defined-authn/serf.h serf/branches/user-defined-authn/test/test_auth.c serf/branches/user-defined-authn/test/test_serf.h Modified: serf/branches/user-defined-authn/auth/auth.h URL: http://svn.apache.org/viewvc/serf/branches/user-defined-authn/auth/auth.h?rev=1926731&r1=1926730&r2=1926731&view=diff ============================================================================== --- serf/branches/user-defined-authn/auth/auth.h (original) +++ serf/branches/user-defined-authn/auth/auth.h Thu Jun 26 06:06:32 2025 @@ -176,6 +176,9 @@ extern const serf__authn_scheme_t serf__ #define SERF__HEADER_FROM_PEER(peer) \ (((peer) == HOST) ? "Authorization" : "Proxy-Authorization") +#define SERF__INFO_HEADER_FROM_PEER(peer) \ + (((peer) == HOST) ? "Authentication-Info" : "Proxy-Authentication-Info") + /** User-defined authentication scheme handlers */ apr_status_t Modified: serf/branches/user-defined-authn/auth/auth_user_defined.c URL: http://svn.apache.org/viewvc/serf/branches/user-defined-authn/auth/auth_user_defined.c?rev=1926731&r1=1926730&r2=1926731&view=diff ============================================================================== --- serf/branches/user-defined-authn/auth/auth_user_defined.c (original) +++ serf/branches/user-defined-authn/auth/auth_user_defined.c Thu Jun 26 06:06:32 2025 @@ -291,9 +291,13 @@ serf__authn_user__validate_response(cons apr_pool_t *pool) { const int peer_id = SERF__CODE_FROM_PEER(peer); + const char *const info_header = SERF__INFO_HEADER_FROM_PEER(peer); serf__authn_info_t *const authn_info = get_authn_info(peer_id, conn); + serf_bucket_t *headers = serf_bucket_response_get_headers(response); + apr_hash_t *info_params = NULL; int reset_pipelining = 0; struct authn_baton_wrapper *authn_baton; + const char *auth_attr; apr_pool_t *scratch_pool; apr_status_t status; @@ -317,10 +321,17 @@ serf__authn_user__validate_response(cons authn_baton = authn_info->baton; apr_pool_create(&scratch_pool, conn->pool); + + auth_attr = serf_bucket_headers_get(headers, info_header); + if (auth_attr) { + info_params = serf__parse_authn_parameters(auth_attr, scratch_pool); + } + status = scheme->user_validate_response_func(&reset_pipelining, scheme->user_baton, authn_baton->user_authn_baton, - code, conn, request, response, + code, conn, info_params, + request, response, scratch_pool); /* Reset pipelining if the scheme requires it. */ Modified: serf/branches/user-defined-authn/serf.h URL: http://svn.apache.org/viewvc/serf/branches/user-defined-authn/serf.h?rev=1926731&r1=1926730&r2=1926731&view=diff ============================================================================== --- serf/branches/user-defined-authn/serf.h (original) +++ serf/branches/user-defined-authn/serf.h Thu Jun 26 06:06:32 2025 @@ -1128,6 +1128,12 @@ typedef apr_status_t * * @a baton and @a authn_baton are the same as in the setup-request function * + * @a authn_info_parameters is a dictionary with the same structure as the + * `authn_parameters` argument to `serf_authn_get_realm_func_t`; except that + * they're extracted from the Authentication-Info or Proxy-Authentication-Info + * response header. This argument will be NULL @a response does not contain + * one of those headers. + * * If the scheme flag @c SERF_AUTHN_FLAG_PIPE is *not* set, return a boolean * value in @a reset_pipelining to indicate whether pipelining on @a conn should * be restored to the value before the init-conn callback was invoked. @@ -1142,6 +1148,7 @@ typedef apr_status_t void *authn_baton, int code, serf_connection_t *conn, + apr_hash_t *authn_info_parameters, serf_request_t *request, serf_bucket_t *response, apr_pool_t *scratch_pool); Modified: serf/branches/user-defined-authn/test/test_auth.c URL: http://svn.apache.org/viewvc/serf/branches/user-defined-authn/test/test_auth.c?rev=1926731&r1=1926730&r2=1926731&view=diff ============================================================================== --- serf/branches/user-defined-authn/test/test_auth.c (original) +++ serf/branches/user-defined-authn/test/test_auth.c Thu Jun 26 06:06:32 2025 @@ -658,6 +658,7 @@ static void test_authn_registered_pool_c typedef struct user_authn_baton user_authn_t; struct user_authn_baton { + CuTest *tc; const char *name; int all_count; int init_conn_count; @@ -674,9 +675,11 @@ struct user_authn_baton { ++b->all_count; \ } while(0) -static user_authn_t *user_authn_make_baton(const char* name, apr_pool_t *pool) +static user_authn_t *user_authn_make_baton(CuTest *tc, const char* name, + apr_pool_t *pool) { user_authn_t *baton = apr_pcalloc(pool, sizeof(*baton)); + baton->tc = tc; baton->name = apr_pstrdup(pool, name); return baton; } @@ -746,9 +749,7 @@ static apr_status_t user_authn_handle(vo user_authn_baton_t *const ab = authn_baton; USER_AUTHN_COUNT(baton, handle); - if (username != NULL) - return SERF_ERROR_AUTHN_INITALIZATION_FAILED; - + CuAssertTrue(b->tc, username == NULL); ab->header = apr_pstrdup(result_pool, response_header); ab->value = apr_pstrcat(result_pool, b->name, " ", password, NULL); @@ -767,17 +768,16 @@ static apr_status_t user_authn_setup_req user_authn_baton_t *const ab = authn_baton; USER_AUTHN_COUNT(baton, setup_request); + CuAssertPtrNotNull(b->tc, authn_baton); + CuAssertPtrNotNull(b->tc, ab->header); + CuAssertPtrNotNull(b->tc, ab->value); - if (ab && ab->header && ab->value) { - test__log(TEST_VERBOSE, __FILE__, - "user_authn_setup_request, header %s: %s\n", - ab->header, ab->value); - - serf_bucket_headers_setn(headers, ab->header, ab->value); - return APR_SUCCESS; - } + test__log(TEST_VERBOSE, __FILE__, + "user_authn_setup_request, header %s: %s\n", + ab->header, ab->value); - return SERF_ERROR_AUTHN_FAILED; + serf_bucket_headers_setn(headers, ab->header, ab->value); + return APR_SUCCESS; } static apr_status_t user_authn_validate_response(int *reset_pipelining, @@ -785,11 +785,22 @@ static apr_status_t user_authn_validate_ void *authn_baton, int code, serf_connection_t *conn, + apr_hash_t *authn_params, serf_request_t *request, serf_bucket_t *response, apr_pool_t *scratch_pool) { + const char *knight; USER_AUTHN_COUNT(baton, validate_response); + + CuAssertPtrNotNull(b->tc, authn_params); + knight = apr_hash_get(authn_params, "white", 5); + CuAssertPtrNotNull(b->tc, knight); + test__log(TEST_VERBOSE, __FILE__, + "user_authn_validate_response, info white=%s\n", + knight); + CuAssertStrEquals(b->tc, "Knight", knight); + *reset_pipelining = 1; return APR_SUCCESS; } @@ -840,8 +851,8 @@ static void user_authentication(CuTest * apr_status_t status; int typedee, typedum; const char *hdr_value = "tweeDlEdee scope=Alice"; - user_authn_t *const tdee = user_authn_make_baton("TweedleDee", tb->pool); - user_authn_t *const tdum = user_authn_make_baton("TweedleDum", tb->pool); + user_authn_t *const tdee = user_authn_make_baton(tc, "TweedleDee", tb->pool); + user_authn_t *const tdum = user_authn_make_baton(tc, "TweedleDum", tb->pool); const int flags = (SERF_AUTHN_FLAG_CREDS | (use_pipelining ? SERF_AUTHN_FLAG_PIPE : 0)); @@ -897,7 +908,9 @@ static void user_authentication(CuTest * OnConditionThat(close_conn, WithConnectionCloseHeader)) GETRequest(URLEqualTo("/"), HeaderEqualTo("Authorization", "TweedleDee TweedleDee")) - Respond(WithCode(200),WithChunkedBody("")) + Respond(WithCode(200), + WithHeader("Authentication-Info", "White=Knight"), + WithChunkedBody("")) Expect AllRequestsReceivedInOrder EndGiven 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=1926731&r1=1926730&r2=1926731&view=diff ============================================================================== --- serf/branches/user-defined-authn/test/test_serf.h (original) +++ serf/branches/user-defined-authn/test/test_serf.h Thu Jun 26 06:06:32 2025 @@ -33,7 +33,7 @@ /* Test logging facilities, set flag to 1 to enable console logging for the test suite. */ -#define TEST_VERBOSE 01 +#define TEST_VERBOSE 0 /* Preferred proxy port */ #define PROXY_PORT 23456