@@ -72,7 +72,6 @@ static int oidc_response_authorization_error(request_rec *r, oidc_cfg_t *c, oidc
7272 const char * prompt = oidc_proto_state_get_prompt (proto_state );
7373 if (prompt != NULL )
7474 prompt = apr_pstrdup (r -> pool , prompt );
75- oidc_proto_state_destroy (proto_state );
7675 if ((prompt != NULL ) && (_oidc_strcmp (prompt , OIDC_PROTO_PROMPT_NONE ) == 0 )) {
7776 return oidc_response_redirect_parent_window_to_logout (r , c );
7877 }
@@ -377,7 +376,6 @@ static apr_byte_t oidc_response_proto_state_restore(request_rec *r, oidc_cfg_t *
377376 r ,
378377 "calculated state from cookie does not match state parameter passed back in URL: \"%s\" != \"%s\"" ,
379378 state , calc );
380- oidc_proto_state_destroy (* proto_state );
381379 return FALSE;
382380 }
383381
@@ -396,7 +394,6 @@ static apr_byte_t oidc_response_proto_state_restore(request_rec *r, oidc_cfg_t *
396394 oidc_proto_state_get_original_url (* proto_state )),
397395 OK );
398396 }
399- oidc_proto_state_destroy (* proto_state );
400397 return FALSE;
401398 }
402399
@@ -433,13 +430,7 @@ static apr_byte_t oidc_response_match_state(request_rec *r, oidc_cfg_t *c, const
433430
434431 * provider = oidc_get_provider_for_issuer (r , c , oidc_proto_state_get_issuer (* proto_state ), FALSE);
435432
436- if (* provider == NULL ) {
437- oidc_proto_state_destroy (* proto_state );
438- * proto_state = NULL ;
439- return FALSE;
440- }
441-
442- return TRUE;
433+ return (* provider != NULL );
443434}
444435
445436/*
@@ -545,16 +536,25 @@ static char *_oidc_response_post_restore_template_contents = NULL;
545536 */
546537static int oidc_response_process (request_rec * r , oidc_cfg_t * c , oidc_session_t * session , apr_table_t * params ,
547538 const char * response_mode ) {
548-
549- oidc_debug (r , "enter, response_mode=%s" , response_mode );
550-
539+ int rc = -1 ;
551540 oidc_provider_t * provider = NULL ;
552541 oidc_proto_state_t * proto_state = NULL ;
553542 oidc_jwt_t * id_token = NULL ;
543+ json_t * userinfo_claims = NULL ;
544+ int expires_in = 0 ;
545+ char * userinfo_jwt = NULL ;
546+ const char * s_userinfo_claims = NULL ;
547+ const char * original_url = NULL ;
548+ const char * original_method = NULL ;
549+ const char * prompt = NULL ;
550+
551+ oidc_debug (r , "enter, response_mode=%s" , response_mode );
554552
555553 /* see if this response came from a browser-back event */
556- if (oidc_response_browser_back (r , apr_table_get (params , OIDC_PROTO_STATE ), session ) == TRUE)
557- return HTTP_MOVED_TEMPORARILY ;
554+ if (oidc_response_browser_back (r , apr_table_get (params , OIDC_PROTO_STATE ), session ) == TRUE) {
555+ rc = HTTP_MOVED_TEMPORARILY ;
556+ goto end ;
557+ }
558558
559559 /* match the returned state parameter against the state stored in the browser */
560560 if (oidc_response_match_state (r , c , apr_table_get (params , OIDC_PROTO_STATE ), & provider , & proto_state ) ==
@@ -566,115 +566,109 @@ static int oidc_response_process(request_rec *r, oidc_cfg_t *c, oidc_session_t *
566566 oidc_cfg_default_sso_url_get (c ));
567567 oidc_http_hdr_out_location_set (r , oidc_util_url_abs (r , c , oidc_cfg_default_sso_url_get (c )));
568568 OIDC_METRICS_COUNTER_INC (r , c , OM_AUTHN_RESPONSE_ERROR_STATE_MISMATCH );
569- return HTTP_MOVED_TEMPORARILY ;
569+ rc = HTTP_MOVED_TEMPORARILY ;
570+ goto end ;
570571 }
571572 oidc_error (r ,
572573 "invalid authorization response state and no default SSO URL is set, sending an error..." );
573574
574575 // if error text was already produced (e.g. state timeout) then just return with a 400
575576 if (apr_table_get (r -> subprocess_env , OIDC_ERROR_ENVVAR ) != NULL ) {
576577 OIDC_METRICS_COUNTER_INC (r , c , OM_AUTHN_RESPONSE_ERROR_STATE_EXPIRED );
577- return HTTP_BAD_REQUEST ;
578+ rc = HTTP_BAD_REQUEST ;
579+ goto end ;
578580 }
579581
580582 OIDC_METRICS_COUNTER_INC (r , c , OM_AUTHN_RESPONSE_ERROR_STATE_MISMATCH );
581583
582- return oidc_util_html_send_error (r , "Invalid Authorization Response" ,
583- "Could not match the authorization response to an earlier request via "
584- "the state parameter and corresponding state cookie" ,
585- HTTP_BAD_REQUEST );
584+ rc = oidc_util_html_send_error (r , "Invalid Authorization Response" ,
585+ "Could not match the authorization response to an earlier request via "
586+ "the state parameter and corresponding state cookie" ,
587+ HTTP_BAD_REQUEST );
588+ goto end ;
586589 }
587590
588591 /* see if the response is an error response */
589592 if (apr_table_get (params , OIDC_PROTO_ERROR ) != NULL ) {
590593 OIDC_METRICS_COUNTER_INC (r , c , OM_AUTHN_RESPONSE_ERROR_PROVIDER );
591- return oidc_response_authorization_error (r , c , proto_state , apr_table_get (params , OIDC_PROTO_ERROR ),
592- apr_table_get (params , OIDC_PROTO_ERROR_DESCRIPTION ));
594+ rc = oidc_response_authorization_error (r , c , proto_state , apr_table_get (params , OIDC_PROTO_ERROR ),
595+ apr_table_get (params , OIDC_PROTO_ERROR_DESCRIPTION ));
596+ goto end ;
593597 }
594598
595599 /* handle the code, implicit or hybrid flow */
596600 if (oidc_response_flows (r , c , proto_state , provider , params , response_mode , & id_token ) == FALSE) {
597601 OIDC_METRICS_COUNTER_INC (r , c , OM_AUTHN_RESPONSE_ERROR_PROTOCOL );
598- return oidc_response_authorization_error (r , c , proto_state , "Error in handling response type." , NULL );
602+ rc = oidc_response_authorization_error (r , c , proto_state , "Error in handling response type." , NULL );
603+ goto end ;
599604 }
600605
601606 if (id_token == NULL ) {
602607 oidc_error (r , "no id_token was provided" );
603- return oidc_response_authorization_error (r , c , proto_state , "No id_token was provided." , NULL );
608+ rc = oidc_response_authorization_error (r , c , proto_state , "No id_token was provided." , NULL );
609+ goto end ;
604610 }
605611
606- int expires_in = _oidc_str_to_int (apr_table_get (params , OIDC_PROTO_EXPIRES_IN ), -1 );
607- char * userinfo_jwt = NULL ;
612+ expires_in = _oidc_str_to_int (apr_table_get (params , OIDC_PROTO_EXPIRES_IN ), -1 );
608613
609614 /*
610615 * optionally resolve additional claims against the userinfo endpoint
611616 * parsed claims are not actually used here but need to be parsed anyway for error checking purposes
612617 */
613- json_t * userinfo_claims = NULL ;
614- const char * s_userinfo_claims = oidc_userinfo_retrieve_claims (
618+ s_userinfo_claims = oidc_userinfo_retrieve_claims (
615619 r , c , provider , apr_table_get (params , OIDC_PROTO_ACCESS_TOKEN ),
616620 apr_table_get (params , OIDC_PROTO_TOKEN_TYPE ), NULL , id_token -> payload .sub , & userinfo_claims , & userinfo_jwt );
617621
618622 /* restore the original protected URL that the user was trying to access */
619- const char * original_url = oidc_proto_state_get_original_url (proto_state );
623+ original_url = oidc_proto_state_get_original_url (proto_state );
620624 if (original_url != NULL )
621625 original_url = apr_pstrdup (r -> pool , original_url );
622- const char * original_method = oidc_proto_state_get_original_method (proto_state );
626+ original_method = oidc_proto_state_get_original_method (proto_state );
623627 if (original_method != NULL )
624628 original_method = apr_pstrdup (r -> pool , original_method );
625- const char * prompt = oidc_proto_state_get_prompt (proto_state );
629+ prompt = oidc_proto_state_get_prompt (proto_state );
626630
627631 /* set the user */
628- if (oidc_response_set_request_user (r , c , provider , id_token , userinfo_claims ) == TRUE) {
629-
630- /* session management: if the user in the new response is not equal to the old one, error out */
631- if ((prompt != NULL ) && (_oidc_strcmp (prompt , OIDC_PROTO_PROMPT_NONE ) == 0 )) {
632- // TOOD: actually need to compare sub? (need to store it in the session separately then
633- // const char *sub = NULL;
634- // oidc_session_get(r, session, "sub", &sub);
635- // if (_oidc_strcmp(sub, jwt->payload.sub) != 0) {
636- if (_oidc_strcmp (session -> remote_user , r -> user ) != 0 ) {
637- oidc_warn (r , "user set from new id_token is different from current one" );
638- oidc_jwt_destroy (id_token );
639- json_decref (userinfo_claims );
640- return oidc_response_authorization_error (r , c , proto_state , "User changed!" , NULL );
641- }
642- }
643-
644- /* store resolved information in the session */
645- if (oidc_response_save_in_session (
646- r , c , session , provider , r -> user , apr_table_get (params , OIDC_PROTO_ID_TOKEN ), id_token ,
647- s_userinfo_claims , userinfo_claims , apr_table_get (params , OIDC_PROTO_ACCESS_TOKEN ),
648- apr_table_get (params , OIDC_PROTO_TOKEN_TYPE ), expires_in ,
649- apr_table_get (params , OIDC_PROTO_REFRESH_TOKEN ), apr_table_get (params , OIDC_PROTO_SCOPE ),
650- apr_table_get (params , OIDC_PROTO_SESSION_STATE ), apr_table_get (params , OIDC_PROTO_STATE ),
651- original_url , userinfo_jwt ) == FALSE) {
652- oidc_proto_state_destroy (proto_state );
653- oidc_jwt_destroy (id_token );
654- json_decref (userinfo_claims );
655- return HTTP_INTERNAL_SERVER_ERROR ;
656- }
657-
658- oidc_debug (r , "set remote_user to \"%s\" in new session \"%s\"" , r -> user , session -> uuid );
659-
660- } else {
632+ if (oidc_response_set_request_user (r , c , provider , id_token , userinfo_claims ) == FALSE) {
661633 oidc_error (r , "remote user could not be set" );
662- oidc_jwt_destroy (id_token );
663- json_decref (userinfo_claims );
664634 OIDC_METRICS_COUNTER_INC (r , c , OM_AUTHN_RESPONSE_ERROR_REMOTE_USER );
665- return oidc_response_authorization_error (
635+ rc = oidc_response_authorization_error (
666636 r , c , proto_state , "Remote user could not be set: contact the website administrator" , NULL );
637+ goto end ;
638+ }
639+
640+ oidc_debug (r , "set remote_user to \"%s\" in new session \"%s\"" , r -> user , session -> uuid );
641+
642+ /* session management: if the user in the new response is not equal to the old one, error out */
643+ if ((prompt != NULL ) && (_oidc_strcmp (prompt , OIDC_PROTO_PROMPT_NONE ) == 0 )) {
644+ // TOOD: actually need to compare sub? (need to store it in the session separately then
645+ // const char *sub = NULL;
646+ // oidc_session_get(r, session, "sub", &sub);
647+ // if (_oidc_strcmp(sub, jwt->payload.sub) != 0) {
648+ if (_oidc_strcmp (session -> remote_user , r -> user ) != 0 ) {
649+ oidc_warn (r , "user set from new id_token is different from current one" );
650+ rc = oidc_response_authorization_error (r , c , proto_state , "User changed!" , NULL );
651+ goto end ;
652+ }
667653 }
668654
669- /* cleanup */
670- oidc_proto_state_destroy (proto_state );
671- oidc_jwt_destroy (id_token );
672- json_decref (userinfo_claims );
655+ /* store resolved information in the session */
656+ if (oidc_response_save_in_session (
657+ r , c , session , provider , r -> user , apr_table_get (params , OIDC_PROTO_ID_TOKEN ), id_token ,
658+ s_userinfo_claims , userinfo_claims , apr_table_get (params , OIDC_PROTO_ACCESS_TOKEN ),
659+ apr_table_get (params , OIDC_PROTO_TOKEN_TYPE ), expires_in ,
660+ apr_table_get (params , OIDC_PROTO_REFRESH_TOKEN ), apr_table_get (params , OIDC_PROTO_SCOPE ),
661+ apr_table_get (params , OIDC_PROTO_SESSION_STATE ), apr_table_get (params , OIDC_PROTO_STATE ), original_url ,
662+ userinfo_jwt ) == FALSE) {
663+ rc = HTTP_INTERNAL_SERVER_ERROR ;
664+ goto end ;
665+ }
673666
674667 /* check that we've actually authenticated a user; functions as error handling for oidc_get_remote_user */
675668 if (r -> user == NULL ) {
676669 OIDC_METRICS_COUNTER_INC (r , c , OM_AUTHN_RESPONSE_ERROR_REMOTE_USER );
677- return HTTP_UNAUTHORIZED ;
670+ rc = HTTP_UNAUTHORIZED ;
671+ goto end ;
678672 }
679673
680674 /* log the successful response */
@@ -683,18 +677,32 @@ static int oidc_response_process(request_rec *r, oidc_cfg_t *c, oidc_session_t *
683677
684678 /* check whether form post data was preserved; if so restore it */
685679 if (_oidc_strcmp (original_method , OIDC_METHOD_FORM_POST ) == 0 ) {
686- if (oidc_cfg_post_restore_template_get (c ) != NULL )
687- return oidc_util_html_send_in_template (
680+ if (oidc_cfg_post_restore_template_get (c ) != NULL ) {
681+ rc = oidc_util_html_send_in_template (
688682 r , oidc_cfg_post_restore_template_get (c ), & _oidc_response_post_restore_template_contents ,
689683 original_url , OIDC_POST_PRESERVE_ESCAPE_JAVASCRIPT , "" , OIDC_POST_PRESERVE_ESCAPE_NONE );
690- return oidc_response_post_preserved_restore (r , original_url );
684+ } else {
685+ rc = oidc_response_post_preserved_restore (r , original_url );
686+ }
687+ goto end ;
691688 }
692689
693690 /* now we've authenticated the user so go back to the URL that he originally tried to access */
694691 oidc_http_hdr_out_location_set (r , original_url );
695692
696693 /* do the actual redirect to the original URL */
697- return HTTP_MOVED_TEMPORARILY ;
694+ rc = HTTP_MOVED_TEMPORARILY ;
695+
696+ end :
697+
698+ if (proto_state )
699+ oidc_proto_state_destroy (proto_state );
700+ if (id_token )
701+ oidc_jwt_destroy (id_token );
702+ if (userinfo_claims )
703+ json_decref (userinfo_claims );
704+
705+ return rc ;
698706}
699707
700708/*
0 commit comments