Skip to content

Commit 2d79d1c

Browse files
committed
fix memory leaks when using provider specific client keys
in a multi-provider setup; bump to 2.4.17rc0 Signed-off-by: Hans Zandbelt <[email protected]>
1 parent f570de5 commit 2d79d1c

File tree

10 files changed

+57
-7
lines changed

10 files changed

+57
-7
lines changed

ChangeLog

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
04/15/2025
2+
- fix memory leaks when using provider specific client keys in a multi-provider setup
3+
- bump to 2.4.17rc0
4+
15
04/08/2025
26
- proto: pass the scope parameter as returned from the token endpoint in the OIDC_scope
37
header/environment variable and make it available for `Require claim scope:` purposes

configure.ac

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
AC_INIT([mod_auth_openidc],[2.4.17dev],[[email protected]])
1+
AC_INIT([mod_auth_openidc],[2.4.17rc0],[[email protected]])
22

33
AC_SUBST(NAMEVER, AC_PACKAGE_TARNAME()-AC_PACKAGE_VERSION())
44

src/cfg/provider.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -875,6 +875,8 @@ oidc_provider_t *oidc_cfg_provider_copy(apr_pool_t *pool, const oidc_provider_t
875875
}
876876

877877
void oidc_cfg_provider_destroy(oidc_provider_t *provider) {
878+
if (provider == NULL)
879+
return;
878880
oidc_jwk_list_destroy(provider->jwks_uri.jwk_list);
879881
oidc_jwk_list_destroy(provider->verify_public_keys);
880882
oidc_jwk_list_destroy(provider->client_keys);

src/handle/discovery.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,7 @@ int oidc_discovery_response(request_rec *r, oidc_cfg_t *c) {
367367
if (oidc_cfg_metadata_dir_get(c) == NULL) {
368368
if ((oidc_provider_static_config(r, c, &provider) == TRUE) && (issuer != NULL)) {
369369
if (_oidc_strcmp(oidc_cfg_provider_issuer_get(provider), issuer) != 0) {
370+
oidc_cfg_provider_destroy(provider);
370371
return oidc_util_html_send_error(
371372
r, "Invalid Request",
372373
apr_psprintf(
@@ -376,6 +377,7 @@ int oidc_discovery_response(request_rec *r, oidc_cfg_t *c) {
376377
HTTP_INTERNAL_SERVER_ERROR);
377378
}
378379
}
380+
oidc_cfg_provider_destroy(provider);
379381
return oidc_request_authenticate_user(r, c, NULL, target_link_uri, login_hint, NULL, NULL,
380382
auth_request_params, path_scopes);
381383
}
@@ -446,14 +448,19 @@ int oidc_discovery_response(request_rec *r, oidc_cfg_t *c) {
446448
oidc_cfg_provider_ssl_validate_server_get(provider), &j_jwks,
447449
&force_refresh);
448450
json_decref(j_jwks);
451+
oidc_cfg_provider_destroy(provider);
449452
return OK;
450453
} else {
451454
/* now we've got a selected OP, send the user there to authenticate */
452-
return oidc_request_authenticate_user(r, c, provider, target_link_uri, login_hint, NULL, NULL,
453-
auth_request_params, path_scopes);
455+
int rv = oidc_request_authenticate_user(r, c, provider, target_link_uri, login_hint, NULL, NULL,
456+
auth_request_params, path_scopes);
457+
oidc_cfg_provider_destroy(provider);
458+
return rv;
454459
}
455460
}
456461

462+
oidc_cfg_provider_destroy(provider);
463+
457464
/* something went wrong */
458465
return oidc_util_html_send_error(r, "Invalid Request",
459466
"Could not find valid provider metadata for the selected OpenID Connect "

src/handle/info.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,15 +106,19 @@ int oidc_info_request(request_rec *r, oidc_cfg_t *c, oidc_session_t *session, ap
106106

107107
/* get the current provider info */
108108
oidc_provider_t *provider = NULL;
109-
if (oidc_get_provider_from_session(r, c, session, &provider) == FALSE)
109+
if (oidc_get_provider_from_session(r, c, session, &provider) == FALSE) {
110+
oidc_cfg_provider_destroy(provider);
110111
return HTTP_INTERNAL_SERVER_ERROR;
112+
}
111113

112114
/* execute the actual refresh grant */
113115
if (oidc_refresh_token_grant(r, c, session, provider, NULL, NULL, NULL) == FALSE) {
114116
oidc_warn(r, "access_token could not be refreshed");
117+
oidc_cfg_provider_destroy(provider);
115118
return HTTP_INTERNAL_SERVER_ERROR;
116119
}
117120
needs_save = TRUE;
121+
oidc_cfg_provider_destroy(provider);
118122
}
119123
}
120124
}

src/handle/logout.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ static void oidc_logout_revoke_tokens(request_rec *r, oidc_cfg_t *c, oidc_sessio
119119

120120
out:
121121

122+
oidc_cfg_provider_destroy(provider);
122123
oidc_debug(r, "leave");
123124
}
124125

@@ -233,6 +234,7 @@ int oidc_logout_request(request_rec *r, oidc_cfg_t *c, oidc_session_t *session,
233234
}
234235
if (provider) {
235236
oidc_logout_cleanup_by_sid(r, sid, c, provider, revoke_tokens);
237+
oidc_cfg_provider_destroy(provider);
236238
} else {
237239
oidc_info(r, "No provider for front channel logout found");
238240
}
@@ -432,6 +434,10 @@ static int oidc_logout_backchannel(request_rec *r, oidc_cfg_t *cfg) {
432434
oidc_jwt_destroy(jwt);
433435
jwt = NULL;
434436
}
437+
if (provider != NULL) {
438+
oidc_cfg_provider_destroy(provider);
439+
provider = NULL;
440+
}
435441

436442
oidc_http_hdr_err_out_add(r, OIDC_HTTP_HDR_CACHE_CONTROL, "no-cache, no-store");
437443
oidc_http_hdr_err_out_add(r, OIDC_HTTP_HDR_PRAGMA, "no-cache");
@@ -518,5 +524,7 @@ int oidc_logout(request_rec *r, oidc_cfg_t *c, oidc_session_t *session) {
518524
url = s_logout_request;
519525
}
520526

527+
oidc_cfg_provider_destroy(provider);
528+
521529
return oidc_logout_request(r, c, session, url, TRUE);
522530
}

src/handle/refresh.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,7 @@ int oidc_refresh_token_request(request_rec *r, oidc_cfg_t *c, oidc_session_t *se
316316
char *error_str = NULL;
317317
char *error_description = NULL;
318318
apr_byte_t needs_save = TRUE;
319+
oidc_provider_t *provider = NULL;
319320

320321
/* get the command passed to the session management handler */
321322
oidc_util_request_parameter_get(r, OIDC_REDIRECT_URI_REQUEST_REFRESH, &return_to);
@@ -354,7 +355,6 @@ int oidc_refresh_token_request(request_rec *r, oidc_cfg_t *c, oidc_session_t *se
354355
}
355356

356357
/* get a handle to the provider configuration */
357-
oidc_provider_t *provider = NULL;
358358
if (oidc_get_provider_from_session(r, c, session, &provider) == FALSE) {
359359
error_code = "session_corruption";
360360
goto end;
@@ -389,6 +389,8 @@ int oidc_refresh_token_request(request_rec *r, oidc_cfg_t *c, oidc_session_t *se
389389
/* add the redirect location header */
390390
oidc_http_hdr_out_location_set(r, return_to);
391391

392+
oidc_cfg_provider_destroy(provider);
393+
392394
return HTTP_MOVED_TEMPORARILY;
393395
}
394396

@@ -425,16 +427,21 @@ apr_byte_t oidc_refresh_access_token_before_expiry(request_rec *r, oidc_cfg_t *c
425427
if (t_expires > apr_time_now())
426428
return TRUE;
427429

428-
if (oidc_get_provider_from_session(r, cfg, session, &provider) == FALSE)
430+
if (oidc_get_provider_from_session(r, cfg, session, &provider) == FALSE) {
431+
oidc_cfg_provider_destroy(provider);
429432
return FALSE;
433+
}
430434

431435
if (oidc_refresh_token_grant(r, cfg, session, provider, NULL, NULL, NULL) == FALSE) {
432436
oidc_warn(r, "access_token could not be refreshed");
437+
oidc_cfg_provider_destroy(provider);
433438
*needs_save = FALSE;
434439
return FALSE;
435440
}
436441

437442
*needs_save = TRUE;
438443

444+
oidc_cfg_provider_destroy(provider);
445+
439446
return TRUE;
440447
}

src/handle/response.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -565,6 +565,7 @@ static int oidc_response_process(request_rec *r, oidc_cfg_t *c, oidc_session_t *
565565
oidc_http_hdr_out_location_set(r,
566566
oidc_util_absolute_url(r, c, oidc_cfg_default_sso_url_get(c)));
567567
OIDC_METRICS_COUNTER_INC(r, c, OM_AUTHN_RESPONSE_ERROR_STATE_MISMATCH);
568+
oidc_cfg_provider_destroy(provider);
568569
return HTTP_MOVED_TEMPORARILY;
569570
}
570571
oidc_error(r,
@@ -577,7 +578,7 @@ static int oidc_response_process(request_rec *r, oidc_cfg_t *c, oidc_session_t *
577578
}
578579

579580
OIDC_METRICS_COUNTER_INC(r, c, OM_AUTHN_RESPONSE_ERROR_STATE_MISMATCH);
580-
581+
oidc_cfg_provider_destroy(provider);
581582
return oidc_util_html_send_error(r, "Invalid Authorization Response",
582583
"Could not match the authorization response to an earlier request via "
583584
"the state parameter and corresponding state cookie",
@@ -587,18 +588,21 @@ static int oidc_response_process(request_rec *r, oidc_cfg_t *c, oidc_session_t *
587588
/* see if the response is an error response */
588589
if (apr_table_get(params, OIDC_PROTO_ERROR) != NULL) {
589590
OIDC_METRICS_COUNTER_INC(r, c, OM_AUTHN_RESPONSE_ERROR_PROVIDER);
591+
oidc_cfg_provider_destroy(provider);
590592
return oidc_response_authorization_error(r, c, proto_state, apr_table_get(params, OIDC_PROTO_ERROR),
591593
apr_table_get(params, OIDC_PROTO_ERROR_DESCRIPTION));
592594
}
593595

594596
/* handle the code, implicit or hybrid flow */
595597
if (oidc_response_flows(r, c, proto_state, provider, params, response_mode, &jwt) == FALSE) {
596598
OIDC_METRICS_COUNTER_INC(r, c, OM_AUTHN_RESPONSE_ERROR_PROTOCOL);
599+
oidc_cfg_provider_destroy(provider);
597600
return oidc_response_authorization_error(r, c, proto_state, "Error in handling response type.", NULL);
598601
}
599602

600603
if (jwt == NULL) {
601604
oidc_error(r, "no id_token was provided");
605+
oidc_cfg_provider_destroy(provider);
602606
return oidc_response_authorization_error(r, c, proto_state, "No id_token was provided.", NULL);
603607
}
604608

@@ -634,6 +638,7 @@ static int oidc_response_process(request_rec *r, oidc_cfg_t *c, oidc_session_t *
634638
if (_oidc_strcmp(session->remote_user, r->user) != 0) {
635639
oidc_warn(r, "user set from new id_token is different from current one");
636640
oidc_jwt_destroy(jwt);
641+
oidc_cfg_provider_destroy(provider);
637642
return oidc_response_authorization_error(r, c, proto_state, "User changed!", NULL);
638643
}
639644
}
@@ -647,6 +652,7 @@ static int oidc_response_process(request_rec *r, oidc_cfg_t *c, oidc_session_t *
647652
apr_table_get(params, OIDC_PROTO_STATE), original_url, userinfo_jwt) == FALSE) {
648653
oidc_proto_state_destroy(proto_state);
649654
oidc_jwt_destroy(jwt);
655+
oidc_cfg_provider_destroy(provider);
650656
return HTTP_INTERNAL_SERVER_ERROR;
651657
}
652658

@@ -656,13 +662,15 @@ static int oidc_response_process(request_rec *r, oidc_cfg_t *c, oidc_session_t *
656662
oidc_error(r, "remote user could not be set");
657663
oidc_jwt_destroy(jwt);
658664
OIDC_METRICS_COUNTER_INC(r, c, OM_AUTHN_RESPONSE_ERROR_REMOTE_USER);
665+
oidc_cfg_provider_destroy(provider);
659666
return oidc_response_authorization_error(
660667
r, c, proto_state, "Remote user could not be set: contact the website administrator", NULL);
661668
}
662669

663670
/* cleanup */
664671
oidc_proto_state_destroy(proto_state);
665672
oidc_jwt_destroy(jwt);
673+
oidc_cfg_provider_destroy(provider);
666674

667675
/* check that we've actually authenticated a user; functions as error handling for oidc_get_remote_user */
668676
if (r->user == NULL) {

src/handle/session_management.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,23 +173,27 @@ int oidc_session_management(request_rec *r, oidc_cfg_t *c, oidc_session_t *sessi
173173
/* see if this is a request for the OP iframe */
174174
if (_oidc_strcmp("iframe_op", cmd) == 0) {
175175
if (oidc_cfg_provider_check_session_iframe_get(provider) != NULL) {
176+
oidc_cfg_provider_destroy(provider);
176177
return oidc_session_management_iframe_op(r, c, session,
177178
oidc_cfg_provider_check_session_iframe_get(provider));
178179
}
180+
oidc_cfg_provider_destroy(provider);
179181
return HTTP_NOT_FOUND;
180182
}
181183

182184
/* see if this is a request for the RP iframe */
183185
if (_oidc_strcmp("iframe_rp", cmd) == 0) {
184186
if ((oidc_cfg_provider_client_id_get(provider) != NULL) &&
185187
(oidc_cfg_provider_check_session_iframe_get(provider) != NULL)) {
188+
oidc_cfg_provider_destroy(provider);
186189
return oidc_session_management_iframe_rp(r, c, session,
187190
oidc_cfg_provider_client_id_get(provider),
188191
oidc_cfg_provider_check_session_iframe_get(provider));
189192
}
190193
oidc_debug(r, "iframe_rp command issued but no client (%s) and/or no check_session_iframe (%s) set",
191194
oidc_cfg_provider_client_id_get(provider),
192195
oidc_cfg_provider_check_session_iframe_get(provider));
196+
oidc_cfg_provider_destroy(provider);
193197
return HTTP_NOT_FOUND;
194198
}
195199

@@ -202,6 +206,7 @@ int oidc_session_management(request_rec *r, oidc_cfg_t *c, oidc_session_t *sessi
202206
* those for the redirect_uri itself; do we need to store those as part of the
203207
* session now?
204208
*/
209+
oidc_cfg_provider_destroy(provider);
205210
return oidc_request_authenticate_user(
206211
r, c, provider, apr_psprintf(r->pool, "%s?session=iframe_rp", oidc_util_redirect_uri(r, c)), NULL,
207212
id_token_hint, "none", oidc_cfg_dir_path_auth_request_params_get(r),
@@ -211,5 +216,7 @@ int oidc_session_management(request_rec *r, oidc_cfg_t *c, oidc_session_t *sessi
211216
/* handle failure in fallthrough */
212217
oidc_error(r, "unknown command: %s", cmd);
213218

219+
oidc_cfg_provider_destroy(provider);
220+
214221
return HTTP_INTERNAL_SERVER_ERROR;
215222
}

src/handle/userinfo.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ apr_byte_t oidc_userinfo_refresh_claims(request_rec *r, oidc_cfg_t *cfg, oidc_se
197197
/* get the current provider info */
198198
if (oidc_get_provider_from_session(r, cfg, session, &provider) == FALSE) {
199199
*needs_save = TRUE;
200+
oidc_cfg_provider_destroy(provider);
200201
return FALSE;
201202
}
202203

@@ -238,6 +239,8 @@ apr_byte_t oidc_userinfo_refresh_claims(request_rec *r, oidc_cfg_t *cfg, oidc_se
238239

239240
oidc_debug(r, "return: %d", rc);
240241

242+
oidc_cfg_provider_destroy(provider);
243+
241244
return rc;
242245
}
243246

0 commit comments

Comments
 (0)