aboutsummaryrefslogtreecommitdiff
path: root/src/reclaim/plugin_rest_openid_connect.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/reclaim/plugin_rest_openid_connect.c')
-rw-r--r--src/reclaim/plugin_rest_openid_connect.c2084
1 files changed, 1044 insertions, 1040 deletions
diff --git a/src/reclaim/plugin_rest_openid_connect.c b/src/reclaim/plugin_rest_openid_connect.c
index bf1e950da..3f1dba254 100644
--- a/src/reclaim/plugin_rest_openid_connect.c
+++ b/src/reclaim/plugin_rest_openid_connect.c
@@ -16,7 +16,7 @@
16 along with this program. If not, see <http://www.gnu.org/licenses/>. 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 17
18 SPDX-License-Identifier: AGPL3.0-or-later 18 SPDX-License-Identifier: AGPL3.0-or-later
19 */ 19 */
20/** 20/**
21 * @author Martin Schanzenbach 21 * @author Martin Schanzenbach
22 * @author Philippe Buschmann 22 * @author Philippe Buschmann
@@ -218,13 +218,13 @@
218/** 218/**
219 * OIDC ignored parameter array 219 * OIDC ignored parameter array
220 */ 220 */
221static char *OIDC_ignored_parameter_array[] = {"display", 221static char *OIDC_ignored_parameter_array[] = { "display",
222 "prompt", 222 "prompt",
223 "ui_locales", 223 "ui_locales",
224 "response_mode", 224 "response_mode",
225 "id_token_hint", 225 "id_token_hint",
226 "login_hint", 226 "login_hint",
227 "acr_values"}; 227 "acr_values" };
228 228
229/** 229/**
230 * OIDC Hash map that keeps track of issued cookies 230 * OIDC Hash map that keeps track of issued cookies
@@ -250,16 +250,14 @@ static char *allow_methods;
250/** 250/**
251 * @brief struct returned by the initialization function of the plugin 251 * @brief struct returned by the initialization function of the plugin
252 */ 252 */
253struct Plugin 253struct Plugin {
254{
255 const struct GNUNET_CONFIGURATION_Handle *cfg; 254 const struct GNUNET_CONFIGURATION_Handle *cfg;
256}; 255};
257 256
258/** 257/**
259 * OIDC needed variables 258 * OIDC needed variables
260 */ 259 */
261struct OIDC_Variables 260struct OIDC_Variables {
262{
263 /** 261 /**
264 * The RP client public key 262 * The RP client public key
265 */ 263 */
@@ -324,8 +322,7 @@ struct OIDC_Variables
324/** 322/**
325 * The ego list 323 * The ego list
326 */ 324 */
327struct EgoEntry 325struct EgoEntry {
328{
329 /** 326 /**
330 * DLL 327 * DLL
331 */ 328 */
@@ -353,8 +350,7 @@ struct EgoEntry
353}; 350};
354 351
355 352
356struct RequestHandle 353struct RequestHandle {
357{
358 /** 354 /**
359 * Ego list 355 * Ego list
360 */ 356 */
@@ -511,74 +507,75 @@ struct RequestHandle
511 * @param handle Handle to clean up 507 * @param handle Handle to clean up
512 */ 508 */
513static void 509static void
514cleanup_handle (struct RequestHandle *handle) 510cleanup_handle(struct RequestHandle *handle)
515{ 511{
516 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *claim_entry; 512 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *claim_entry;
517 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *claim_tmp; 513 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *claim_tmp;
518 struct EgoEntry *ego_entry; 514 struct EgoEntry *ego_entry;
519 struct EgoEntry *ego_tmp; 515 struct EgoEntry *ego_tmp;
520 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n"); 516
517 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n");
521 if (NULL != handle->timeout_task) 518 if (NULL != handle->timeout_task)
522 GNUNET_SCHEDULER_cancel (handle->timeout_task); 519 GNUNET_SCHEDULER_cancel(handle->timeout_task);
523 if (NULL != handle->identity_handle) 520 if (NULL != handle->identity_handle)
524 GNUNET_IDENTITY_disconnect (handle->identity_handle); 521 GNUNET_IDENTITY_disconnect(handle->identity_handle);
525 if (NULL != handle->attr_it) 522 if (NULL != handle->attr_it)
526 GNUNET_RECLAIM_get_attributes_stop (handle->attr_it); 523 GNUNET_RECLAIM_get_attributes_stop(handle->attr_it);
527 if (NULL != handle->ticket_it) 524 if (NULL != handle->ticket_it)
528 GNUNET_RECLAIM_ticket_iteration_stop (handle->ticket_it); 525 GNUNET_RECLAIM_ticket_iteration_stop(handle->ticket_it);
529 if (NULL != handle->idp) 526 if (NULL != handle->idp)
530 GNUNET_RECLAIM_disconnect (handle->idp); 527 GNUNET_RECLAIM_disconnect(handle->idp);
531 GNUNET_free_non_null (handle->url); 528 GNUNET_free_non_null(handle->url);
532 GNUNET_free_non_null (handle->tld); 529 GNUNET_free_non_null(handle->tld);
533 GNUNET_free_non_null (handle->redirect_prefix); 530 GNUNET_free_non_null(handle->redirect_prefix);
534 GNUNET_free_non_null (handle->redirect_suffix); 531 GNUNET_free_non_null(handle->redirect_suffix);
535 GNUNET_free_non_null (handle->emsg); 532 GNUNET_free_non_null(handle->emsg);
536 GNUNET_free_non_null (handle->edesc); 533 GNUNET_free_non_null(handle->edesc);
537 if (NULL != handle->gns_op) 534 if (NULL != handle->gns_op)
538 GNUNET_GNS_lookup_cancel (handle->gns_op); 535 GNUNET_GNS_lookup_cancel(handle->gns_op);
539 if (NULL != handle->gns_handle) 536 if (NULL != handle->gns_handle)
540 GNUNET_GNS_disconnect (handle->gns_handle); 537 GNUNET_GNS_disconnect(handle->gns_handle);
541 538
542 if (NULL != handle->namestore_handle) 539 if (NULL != handle->namestore_handle)
543 GNUNET_NAMESTORE_disconnect (handle->namestore_handle); 540 GNUNET_NAMESTORE_disconnect(handle->namestore_handle);
544 if (NULL != handle->oidc) 541 if (NULL != handle->oidc)
545 { 542 {
546 GNUNET_free_non_null (handle->oidc->client_id); 543 GNUNET_free_non_null(handle->oidc->client_id);
547 GNUNET_free_non_null (handle->oidc->login_identity); 544 GNUNET_free_non_null(handle->oidc->login_identity);
548 GNUNET_free_non_null (handle->oidc->nonce); 545 GNUNET_free_non_null(handle->oidc->nonce);
549 GNUNET_free_non_null (handle->oidc->redirect_uri); 546 GNUNET_free_non_null(handle->oidc->redirect_uri);
550 GNUNET_free_non_null (handle->oidc->response_type); 547 GNUNET_free_non_null(handle->oidc->response_type);
551 GNUNET_free_non_null (handle->oidc->scope); 548 GNUNET_free_non_null(handle->oidc->scope);
552 GNUNET_free_non_null (handle->oidc->state); 549 GNUNET_free_non_null(handle->oidc->state);
553 json_decref (handle->oidc->response); 550 json_decref(handle->oidc->response);
554 GNUNET_free (handle->oidc); 551 GNUNET_free(handle->oidc);
555 } 552 }
556 if (NULL != handle->attr_list) 553 if (NULL != handle->attr_list)
557 {
558 for (claim_entry = handle->attr_list->list_head; NULL != claim_entry;)
559 { 554 {
560 claim_tmp = claim_entry; 555 for (claim_entry = handle->attr_list->list_head; NULL != claim_entry;)
561 claim_entry = claim_entry->next; 556 {
562 GNUNET_free (claim_tmp->claim); 557 claim_tmp = claim_entry;
563 GNUNET_free (claim_tmp); 558 claim_entry = claim_entry->next;
559 GNUNET_free(claim_tmp->claim);
560 GNUNET_free(claim_tmp);
561 }
562 GNUNET_free(handle->attr_list);
564 } 563 }
565 GNUNET_free (handle->attr_list);
566 }
567 for (ego_entry = handle->ego_head; NULL != ego_entry;) 564 for (ego_entry = handle->ego_head; NULL != ego_entry;)
568 { 565 {
569 ego_tmp = ego_entry; 566 ego_tmp = ego_entry;
570 ego_entry = ego_entry->next; 567 ego_entry = ego_entry->next;
571 GNUNET_free (ego_tmp->identifier); 568 GNUNET_free(ego_tmp->identifier);
572 GNUNET_free (ego_tmp->keystring); 569 GNUNET_free(ego_tmp->keystring);
573 GNUNET_free (ego_tmp); 570 GNUNET_free(ego_tmp);
574 } 571 }
575 GNUNET_free (handle); 572 GNUNET_free(handle);
576} 573}
577 574
578static void 575static void
579cleanup_handle_delayed (void *cls) 576cleanup_handle_delayed(void *cls)
580{ 577{
581 cleanup_handle (cls); 578 cleanup_handle(cls);
582} 579}
583 580
584 581
@@ -588,30 +585,30 @@ cleanup_handle_delayed (void *cls)
588 * @param cls the `struct RequestHandle` 585 * @param cls the `struct RequestHandle`
589 */ 586 */
590static void 587static void
591do_error (void *cls) 588do_error(void *cls)
592{ 589{
593 struct RequestHandle *handle = cls; 590 struct RequestHandle *handle = cls;
594 struct MHD_Response *resp; 591 struct MHD_Response *resp;
595 char *json_error; 592 char *json_error;
596 593
597 GNUNET_asprintf (&json_error, 594 GNUNET_asprintf(&json_error,
598 "{ \"error\" : \"%s\", \"error_description\" : \"%s\"%s%s%s}", 595 "{ \"error\" : \"%s\", \"error_description\" : \"%s\"%s%s%s}",
599 handle->emsg, 596 handle->emsg,
600 (NULL != handle->edesc) ? handle->edesc : "", 597 (NULL != handle->edesc) ? handle->edesc : "",
601 (NULL != handle->oidc->state) ? ", \"state\":\"" : "", 598 (NULL != handle->oidc->state) ? ", \"state\":\"" : "",
602 (NULL != handle->oidc->state) ? handle->oidc->state : "", 599 (NULL != handle->oidc->state) ? handle->oidc->state : "",
603 (NULL != handle->oidc->state) ? "\"" : ""); 600 (NULL != handle->oidc->state) ? "\"" : "");
604 if (0 == handle->response_code) 601 if (0 == handle->response_code)
605 handle->response_code = MHD_HTTP_BAD_REQUEST; 602 handle->response_code = MHD_HTTP_BAD_REQUEST;
606 resp = GNUNET_REST_create_response (json_error); 603 resp = GNUNET_REST_create_response(json_error);
607 if (MHD_HTTP_UNAUTHORIZED == handle->response_code) 604 if (MHD_HTTP_UNAUTHORIZED == handle->response_code)
608 MHD_add_response_header (resp, MHD_HTTP_HEADER_WWW_AUTHENTICATE, "Basic"); 605 MHD_add_response_header(resp, MHD_HTTP_HEADER_WWW_AUTHENTICATE, "Basic");
609 MHD_add_response_header (resp, 606 MHD_add_response_header(resp,
610 MHD_HTTP_HEADER_CONTENT_TYPE, 607 MHD_HTTP_HEADER_CONTENT_TYPE,
611 "application/json"); 608 "application/json");
612 handle->proc (handle->proc_cls, resp, handle->response_code); 609 handle->proc(handle->proc_cls, resp, handle->response_code);
613 GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle); 610 GNUNET_SCHEDULER_add_now(&cleanup_handle_delayed, handle);
614 GNUNET_free (json_error); 611 GNUNET_free(json_error);
615} 612}
616 613
617 614
@@ -622,21 +619,21 @@ do_error (void *cls)
622 * @param cls the `struct RequestHandle` 619 * @param cls the `struct RequestHandle`
623 */ 620 */
624static void 621static void
625do_userinfo_error (void *cls) 622do_userinfo_error(void *cls)
626{ 623{
627 struct RequestHandle *handle = cls; 624 struct RequestHandle *handle = cls;
628 struct MHD_Response *resp; 625 struct MHD_Response *resp;
629 char *error; 626 char *error;
630 627
631 GNUNET_asprintf (&error, 628 GNUNET_asprintf(&error,
632 "error=\"%s\", error_description=\"%s\"", 629 "error=\"%s\", error_description=\"%s\"",
633 handle->emsg, 630 handle->emsg,
634 (NULL != handle->edesc) ? handle->edesc : ""); 631 (NULL != handle->edesc) ? handle->edesc : "");
635 resp = GNUNET_REST_create_response (""); 632 resp = GNUNET_REST_create_response("");
636 MHD_add_response_header (resp, MHD_HTTP_HEADER_WWW_AUTHENTICATE, "Bearer"); 633 MHD_add_response_header(resp, MHD_HTTP_HEADER_WWW_AUTHENTICATE, "Bearer");
637 handle->proc (handle->proc_cls, resp, handle->response_code); 634 handle->proc(handle->proc_cls, resp, handle->response_code);
638 GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle); 635 GNUNET_SCHEDULER_add_now(&cleanup_handle_delayed, handle);
639 GNUNET_free (error); 636 GNUNET_free(error);
640} 637}
641 638
642 639
@@ -646,23 +643,24 @@ do_userinfo_error (void *cls)
646 * @param cls the `struct RequestHandle` 643 * @param cls the `struct RequestHandle`
647 */ 644 */
648static void 645static void
649do_redirect_error (void *cls) 646do_redirect_error(void *cls)
650{ 647{
651 struct RequestHandle *handle = cls; 648 struct RequestHandle *handle = cls;
652 struct MHD_Response *resp; 649 struct MHD_Response *resp;
653 char *redirect; 650 char *redirect;
654 GNUNET_asprintf (&redirect, 651
655 "%s?error=%s&error_description=%s%s%s", 652 GNUNET_asprintf(&redirect,
656 handle->oidc->redirect_uri, 653 "%s?error=%s&error_description=%s%s%s",
657 handle->emsg, 654 handle->oidc->redirect_uri,
658 handle->edesc, 655 handle->emsg,
659 (NULL != handle->oidc->state) ? "&state=" : "", 656 handle->edesc,
660 (NULL != handle->oidc->state) ? handle->oidc->state : ""); 657 (NULL != handle->oidc->state) ? "&state=" : "",
661 resp = GNUNET_REST_create_response (""); 658 (NULL != handle->oidc->state) ? handle->oidc->state : "");
662 MHD_add_response_header (resp, "Location", redirect); 659 resp = GNUNET_REST_create_response("");
663 handle->proc (handle->proc_cls, resp, MHD_HTTP_FOUND); 660 MHD_add_response_header(resp, "Location", redirect);
664 GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle); 661 handle->proc(handle->proc_cls, resp, MHD_HTTP_FOUND);
665 GNUNET_free (redirect); 662 GNUNET_SCHEDULER_add_now(&cleanup_handle_delayed, handle);
663 GNUNET_free(redirect);
666} 664}
667 665
668/** 666/**
@@ -671,12 +669,12 @@ do_redirect_error (void *cls)
671 * @param cls the `struct RequestHandle` 669 * @param cls the `struct RequestHandle`
672 */ 670 */
673static void 671static void
674do_timeout (void *cls) 672do_timeout(void *cls)
675{ 673{
676 struct RequestHandle *handle = cls; 674 struct RequestHandle *handle = cls;
677 675
678 handle->timeout_task = NULL; 676 handle->timeout_task = NULL;
679 do_error (handle); 677 do_error(handle);
680} 678}
681 679
682/** 680/**
@@ -685,18 +683,18 @@ do_timeout (void *cls)
685 * @param cls the request handle 683 * @param cls the request handle
686 */ 684 */
687static void 685static void
688return_userinfo_response (void *cls) 686return_userinfo_response(void *cls)
689{ 687{
690 char *result_str; 688 char *result_str;
691 struct RequestHandle *handle = cls; 689 struct RequestHandle *handle = cls;
692 struct MHD_Response *resp; 690 struct MHD_Response *resp;
693 691
694 result_str = json_dumps (handle->oidc->response, 0); 692 result_str = json_dumps(handle->oidc->response, 0);
695 693
696 resp = GNUNET_REST_create_response (result_str); 694 resp = GNUNET_REST_create_response(result_str);
697 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); 695 handle->proc(handle->proc_cls, resp, MHD_HTTP_OK);
698 GNUNET_free (result_str); 696 GNUNET_free(result_str);
699 cleanup_handle (handle); 697 cleanup_handle(handle);
700} 698}
701 699
702 700
@@ -708,18 +706,18 @@ return_userinfo_response (void *cls)
708 * @param cls the RequestHandle 706 * @param cls the RequestHandle
709 */ 707 */
710static void 708static void
711options_cont (struct GNUNET_REST_RequestHandle *con_handle, 709options_cont(struct GNUNET_REST_RequestHandle *con_handle,
712 const char *url, 710 const char *url,
713 void *cls) 711 void *cls)
714{ 712{
715 struct MHD_Response *resp; 713 struct MHD_Response *resp;
716 struct RequestHandle *handle = cls; 714 struct RequestHandle *handle = cls;
717 715
718 // For now, independent of path return all options 716 // For now, independent of path return all options
719 resp = GNUNET_REST_create_response (NULL); 717 resp = GNUNET_REST_create_response(NULL);
720 MHD_add_response_header (resp, "Access-Control-Allow-Methods", allow_methods); 718 MHD_add_response_header(resp, "Access-Control-Allow-Methods", allow_methods);
721 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); 719 handle->proc(handle->proc_cls, resp, MHD_HTTP_OK);
722 cleanup_handle (handle); 720 cleanup_handle(handle);
723 return; 721 return;
724} 722}
725 723
@@ -728,7 +726,7 @@ options_cont (struct GNUNET_REST_RequestHandle *con_handle,
728 * Interprets cookie header and pass its identity keystring to handle 726 * Interprets cookie header and pass its identity keystring to handle
729 */ 727 */
730static void 728static void
731cookie_identity_interpretation (struct RequestHandle *handle) 729cookie_identity_interpretation(struct RequestHandle *handle)
732{ 730{
733 struct GNUNET_HashCode cache_key; 731 struct GNUNET_HashCode cache_key;
734 char *cookies; 732 char *cookies;
@@ -739,142 +737,143 @@ cookie_identity_interpretation (struct RequestHandle *handle)
739 char *value; 737 char *value;
740 738
741 // gets identity of login try with cookie 739 // gets identity of login try with cookie
742 GNUNET_CRYPTO_hash (OIDC_COOKIE_HEADER_KEY, 740 GNUNET_CRYPTO_hash(OIDC_COOKIE_HEADER_KEY,
743 strlen (OIDC_COOKIE_HEADER_KEY), 741 strlen(OIDC_COOKIE_HEADER_KEY),
744 &cache_key); 742 &cache_key);
745 if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle 743 if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains(handle->rest_handle
746 ->header_param_map, 744 ->header_param_map,
747 &cache_key)) 745 &cache_key))
748 { 746 {
749 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "No cookie found\n"); 747 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "No cookie found\n");
750 return; 748 return;
751 } 749 }
752 // splits cookies and find 'Identity' cookie 750 // splits cookies and find 'Identity' cookie
753 tmp_cookies = 751 tmp_cookies =
754 GNUNET_CONTAINER_multihashmap_get (handle->rest_handle->header_param_map, 752 GNUNET_CONTAINER_multihashmap_get(handle->rest_handle->header_param_map,
755 &cache_key); 753 &cache_key);
756 cookies = GNUNET_strdup (tmp_cookies); 754 cookies = GNUNET_strdup(tmp_cookies);
757 token = strtok (cookies, delimiter); 755 token = strtok(cookies, delimiter);
758 handle->oidc->user_cancelled = GNUNET_NO; 756 handle->oidc->user_cancelled = GNUNET_NO;
759 handle->oidc->login_identity = NULL; 757 handle->oidc->login_identity = NULL;
760 if (NULL == token) 758 if (NULL == token)
761 { 759 {
762 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 760 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
763 "Unable to parse cookie: %s\n", 761 "Unable to parse cookie: %s\n",
764 cookies); 762 cookies);
765 GNUNET_free (cookies); 763 GNUNET_free(cookies);
766 return; 764 return;
767 } 765 }
768 766
769 while (NULL != token) 767 while (NULL != token)
770 {
771 if (0 == strcmp (token, OIDC_COOKIE_HEADER_ACCESS_DENIED))
772 { 768 {
773 handle->oidc->user_cancelled = GNUNET_YES; 769 if (0 == strcmp(token, OIDC_COOKIE_HEADER_ACCESS_DENIED))
774 GNUNET_free (cookies); 770 {
775 return; 771 handle->oidc->user_cancelled = GNUNET_YES;
772 GNUNET_free(cookies);
773 return;
774 }
775 if (NULL != strstr(token, OIDC_COOKIE_HEADER_INFORMATION_KEY))
776 break;
777 token = strtok(NULL, delimiter);
776 } 778 }
777 if (NULL != strstr (token, OIDC_COOKIE_HEADER_INFORMATION_KEY))
778 break;
779 token = strtok (NULL, delimiter);
780 }
781 if (NULL == token) 779 if (NULL == token)
782 { 780 {
783 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 781 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
784 "No cookie value to process: %s\n", 782 "No cookie value to process: %s\n",
785 cookies); 783 cookies);
786 GNUNET_free (cookies); 784 GNUNET_free(cookies);
787 return; 785 return;
788 } 786 }
789 GNUNET_CRYPTO_hash (token, strlen (token), &cache_key); 787 GNUNET_CRYPTO_hash(token, strlen(token), &cache_key);
790 if (GNUNET_NO == 788 if (GNUNET_NO ==
791 GNUNET_CONTAINER_multihashmap_contains (OIDC_cookie_jar_map, &cache_key)) 789 GNUNET_CONTAINER_multihashmap_contains(OIDC_cookie_jar_map, &cache_key))
792 { 790 {
793 GNUNET_log ( 791 GNUNET_log(
794 GNUNET_ERROR_TYPE_WARNING, 792 GNUNET_ERROR_TYPE_WARNING,
795 "Found cookie `%s', but no corresponding expiration entry present...\n", 793 "Found cookie `%s', but no corresponding expiration entry present...\n",
796 token); 794 token);
797 GNUNET_free (cookies); 795 GNUNET_free(cookies);
798 return; 796 return;
799 } 797 }
800 relog_time = 798 relog_time =
801 GNUNET_CONTAINER_multihashmap_get (OIDC_cookie_jar_map, &cache_key); 799 GNUNET_CONTAINER_multihashmap_get(OIDC_cookie_jar_map, &cache_key);
802 current_time = GNUNET_TIME_absolute_get (); 800 current_time = GNUNET_TIME_absolute_get();
803 // 30 min after old login -> redirect to login 801 // 30 min after old login -> redirect to login
804 if (current_time.abs_value_us > relog_time->abs_value_us) 802 if (current_time.abs_value_us > relog_time->abs_value_us)
805 { 803 {
806 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 804 GNUNET_log(GNUNET_ERROR_TYPE_WARNING,
807 "Found cookie `%s', but it is expired.\n", 805 "Found cookie `%s', but it is expired.\n",
808 token); 806 token);
809 GNUNET_free (cookies); 807 GNUNET_free(cookies);
810 return; 808 return;
811 } 809 }
812 value = strtok (token, OIDC_COOKIE_HEADER_INFORMATION_KEY); 810 value = strtok(token, OIDC_COOKIE_HEADER_INFORMATION_KEY);
813 GNUNET_assert (NULL != value); 811 GNUNET_assert(NULL != value);
814 handle->oidc->login_identity = GNUNET_strdup (value); 812 handle->oidc->login_identity = GNUNET_strdup(value);
815 GNUNET_free (cookies); 813 GNUNET_free(cookies);
816} 814}
817 815
818/** 816/**
819 * Redirects to login page stored in configuration file 817 * Redirects to login page stored in configuration file
820 */ 818 */
821static void 819static void
822login_redirect (void *cls) 820login_redirect(void *cls)
823{ 821{
824 char *login_base_url; 822 char *login_base_url;
825 char *new_redirect; 823 char *new_redirect;
826 struct MHD_Response *resp; 824 struct MHD_Response *resp;
827 struct RequestHandle *handle = cls; 825 struct RequestHandle *handle = cls;
828 826
829 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (cfg, 827 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string(cfg,
830 "reclaim-rest-plugin", 828 "reclaim-rest-plugin",
831 "address", 829 "address",
832 &login_base_url)) 830 &login_base_url))
833 { 831 {
834 GNUNET_asprintf (&new_redirect, 832 GNUNET_asprintf(&new_redirect,
835 "%s?%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s", 833 "%s?%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s",
836 login_base_url, 834 login_base_url,
837 OIDC_RESPONSE_TYPE_KEY, 835 OIDC_RESPONSE_TYPE_KEY,
838 handle->oidc->response_type, 836 handle->oidc->response_type,
839 OIDC_CLIENT_ID_KEY, 837 OIDC_CLIENT_ID_KEY,
840 handle->oidc->client_id, 838 handle->oidc->client_id,
841 OIDC_REDIRECT_URI_KEY, 839 OIDC_REDIRECT_URI_KEY,
842 handle->oidc->redirect_uri, 840 handle->oidc->redirect_uri,
843 OIDC_SCOPE_KEY, 841 OIDC_SCOPE_KEY,
844 handle->oidc->scope, 842 handle->oidc->scope,
845 OIDC_STATE_KEY, 843 OIDC_STATE_KEY,
846 (NULL != handle->oidc->state) ? handle->oidc->state : "", 844 (NULL != handle->oidc->state) ? handle->oidc->state : "",
847 OIDC_CODE_CHALLENGE_KEY, 845 OIDC_CODE_CHALLENGE_KEY,
848 (NULL != handle->oidc->code_challenge) ? handle->oidc->code_challenge : "", 846 (NULL != handle->oidc->code_challenge) ? handle->oidc->code_challenge : "",
849 OIDC_NONCE_KEY, 847 OIDC_NONCE_KEY,
850 (NULL != handle->oidc->nonce) ? handle->oidc->nonce : ""); 848 (NULL != handle->oidc->nonce) ? handle->oidc->nonce : "");
851 resp = GNUNET_REST_create_response (""); 849 resp = GNUNET_REST_create_response("");
852 MHD_add_response_header (resp, "Location", new_redirect); 850 MHD_add_response_header(resp, "Location", new_redirect);
853 GNUNET_free (login_base_url); 851 GNUNET_free(login_base_url);
854 } 852 }
855 else 853 else
856 { 854 {
857 handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_SERVER_ERROR); 855 handle->emsg = GNUNET_strdup(OIDC_ERROR_KEY_SERVER_ERROR);
858 handle->edesc = GNUNET_strdup ("gnunet configuration failed"); 856 handle->edesc = GNUNET_strdup("gnunet configuration failed");
859 handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR; 857 handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
860 GNUNET_SCHEDULER_add_now (&do_error, handle); 858 GNUNET_SCHEDULER_add_now(&do_error, handle);
861 return; 859 return;
862 } 860 }
863 handle->proc (handle->proc_cls, resp, MHD_HTTP_FOUND); 861 handle->proc(handle->proc_cls, resp, MHD_HTTP_FOUND);
864 GNUNET_free (new_redirect); 862 GNUNET_free(new_redirect);
865 GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle); 863 GNUNET_SCHEDULER_add_now(&cleanup_handle_delayed, handle);
866} 864}
867 865
868/** 866/**
869 * Does internal server error when iteration failed. 867 * Does internal server error when iteration failed.
870 */ 868 */
871static void 869static void
872oidc_iteration_error (void *cls) 870oidc_iteration_error(void *cls)
873{ 871{
874 struct RequestHandle *handle = cls; 872 struct RequestHandle *handle = cls;
875 handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_SERVER_ERROR); 873
874 handle->emsg = GNUNET_strdup(OIDC_ERROR_KEY_SERVER_ERROR);
876 handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR; 875 handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
877 GNUNET_SCHEDULER_add_now (&do_error, handle); 876 GNUNET_SCHEDULER_add_now(&do_error, handle);
878} 877}
879 878
880 879
@@ -883,7 +882,7 @@ oidc_iteration_error (void *cls)
883 * parameter. Otherwise redirects with error 882 * parameter. Otherwise redirects with error
884 */ 883 */
885static void 884static void
886oidc_ticket_issue_cb (void *cls, const struct GNUNET_RECLAIM_Ticket *ticket) 885oidc_ticket_issue_cb(void *cls, const struct GNUNET_RECLAIM_Ticket *ticket)
887{ 886{
888 struct RequestHandle *handle = cls; 887 struct RequestHandle *handle = cls;
889 struct MHD_Response *resp; 888 struct MHD_Response *resp;
@@ -893,72 +892,72 @@ oidc_ticket_issue_cb (void *cls, const struct GNUNET_RECLAIM_Ticket *ticket)
893 892
894 handle->idp_op = NULL; 893 handle->idp_op = NULL;
895 if (NULL == ticket) 894 if (NULL == ticket)
896 { 895 {
897 handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_SERVER_ERROR); 896 handle->emsg = GNUNET_strdup(OIDC_ERROR_KEY_SERVER_ERROR);
898 handle->edesc = GNUNET_strdup ("Server cannot generate ticket."); 897 handle->edesc = GNUNET_strdup("Server cannot generate ticket.");
899 GNUNET_SCHEDULER_add_now (&do_redirect_error, handle); 898 GNUNET_SCHEDULER_add_now(&do_redirect_error, handle);
900 return; 899 return;
901 } 900 }
902 handle->ticket = *ticket; 901 handle->ticket = *ticket;
903 ticket_str = 902 ticket_str =
904 GNUNET_STRINGS_data_to_string_alloc (&handle->ticket, 903 GNUNET_STRINGS_data_to_string_alloc(&handle->ticket,
905 sizeof (struct GNUNET_RECLAIM_Ticket)); 904 sizeof(struct GNUNET_RECLAIM_Ticket));
906 // TODO change if more attributes are needed (see max_age) 905 // TODO change if more attributes are needed (see max_age)
907 code_string = OIDC_build_authz_code (&handle->priv_key, 906 code_string = OIDC_build_authz_code(&handle->priv_key,
908 &handle->ticket, 907 &handle->ticket,
909 handle->attr_list, 908 handle->attr_list,
910 handle->oidc->nonce, 909 handle->oidc->nonce,
911 handle->oidc->code_challenge); 910 handle->oidc->code_challenge);
912 if ((NULL != handle->redirect_prefix) && (NULL != handle->redirect_suffix) && 911 if ((NULL != handle->redirect_prefix) && (NULL != handle->redirect_suffix) &&
913 (NULL != handle->tld)) 912 (NULL != handle->tld))
914 { 913 {
915 914 GNUNET_asprintf(&redirect_uri,
916 GNUNET_asprintf (&redirect_uri, 915 "%s.%s/%s?%s=%s&state=%s",
917 "%s.%s/%s?%s=%s&state=%s", 916 handle->redirect_prefix,
918 handle->redirect_prefix, 917 handle->tld,
919 handle->tld, 918 handle->redirect_suffix,
920 handle->redirect_suffix, 919 handle->oidc->response_type,
921 handle->oidc->response_type, 920 code_string,
922 code_string, 921 handle->oidc->state);
923 handle->oidc->state); 922 }
924 }
925 else 923 else
926 { 924 {
927 GNUNET_asprintf (&redirect_uri, 925 GNUNET_asprintf(&redirect_uri,
928 "%s?%s=%s&state=%s", 926 "%s?%s=%s&state=%s",
929 handle->oidc->redirect_uri, 927 handle->oidc->redirect_uri,
930 handle->oidc->response_type, 928 handle->oidc->response_type,
931 code_string, 929 code_string,
932 handle->oidc->state); 930 handle->oidc->state);
933 } 931 }
934 resp = GNUNET_REST_create_response (""); 932 resp = GNUNET_REST_create_response("");
935 MHD_add_response_header (resp, "Location", redirect_uri); 933 MHD_add_response_header(resp, "Location", redirect_uri);
936 handle->proc (handle->proc_cls, resp, MHD_HTTP_FOUND); 934 handle->proc(handle->proc_cls, resp, MHD_HTTP_FOUND);
937 GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle); 935 GNUNET_SCHEDULER_add_now(&cleanup_handle_delayed, handle);
938 GNUNET_free (redirect_uri); 936 GNUNET_free(redirect_uri);
939 GNUNET_free (ticket_str); 937 GNUNET_free(ticket_str);
940 GNUNET_free (code_string); 938 GNUNET_free(code_string);
941} 939}
942 940
943static void 941static void
944oidc_collect_finished_cb (void *cls) 942oidc_collect_finished_cb(void *cls)
945{ 943{
946 struct RequestHandle *handle = cls; 944 struct RequestHandle *handle = cls;
945
947 handle->attr_it = NULL; 946 handle->attr_it = NULL;
948 handle->ticket_it = NULL; 947 handle->ticket_it = NULL;
949 if (NULL == handle->attr_list->list_head) 948 if (NULL == handle->attr_list->list_head)
950 { 949 {
951 handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_SCOPE); 950 handle->emsg = GNUNET_strdup(OIDC_ERROR_KEY_INVALID_SCOPE);
952 handle->edesc = GNUNET_strdup ("The requested scope is not available."); 951 handle->edesc = GNUNET_strdup("The requested scope is not available.");
953 GNUNET_SCHEDULER_add_now (&do_redirect_error, handle); 952 GNUNET_SCHEDULER_add_now(&do_redirect_error, handle);
954 return; 953 return;
955 } 954 }
956 handle->idp_op = GNUNET_RECLAIM_ticket_issue (handle->idp, 955 handle->idp_op = GNUNET_RECLAIM_ticket_issue(handle->idp,
957 &handle->priv_key, 956 &handle->priv_key,
958 &handle->oidc->client_pkey, 957 &handle->oidc->client_pkey,
959 handle->attr_list, 958 handle->attr_list,
960 &oidc_ticket_issue_cb, 959 &oidc_ticket_issue_cb,
961 handle); 960 handle);
962} 961}
963 962
964 963
@@ -966,9 +965,9 @@ oidc_collect_finished_cb (void *cls)
966 * Collects all attributes for an ego if in scope parameter 965 * Collects all attributes for an ego if in scope parameter
967 */ 966 */
968static void 967static void
969oidc_attr_collect (void *cls, 968oidc_attr_collect(void *cls,
970 const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, 969 const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
971 const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr) 970 const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr)
972{ 971{
973 struct RequestHandle *handle = cls; 972 struct RequestHandle *handle = cls;
974 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le; 973 struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry *le;
@@ -977,38 +976,38 @@ oidc_attr_collect (void *cls,
977 char delimiter[] = " "; 976 char delimiter[] = " ";
978 977
979 if ((NULL == attr->name) || (NULL == attr->data)) 978 if ((NULL == attr->name) || (NULL == attr->data))
980 { 979 {
981 GNUNET_RECLAIM_get_attributes_next (handle->attr_it); 980 GNUNET_RECLAIM_get_attributes_next(handle->attr_it);
982 return; 981 return;
983 } 982 }
984 983
985 scope_variables = GNUNET_strdup (handle->oidc->scope); 984 scope_variables = GNUNET_strdup(handle->oidc->scope);
986 scope_variable = strtok (scope_variables, delimiter); 985 scope_variable = strtok(scope_variables, delimiter);
987 while (NULL != scope_variable) 986 while (NULL != scope_variable)
988 { 987 {
989 if (0 == strcmp (attr->name, scope_variable)) 988 if (0 == strcmp(attr->name, scope_variable))
990 break; 989 break;
991 scope_variable = strtok (NULL, delimiter); 990 scope_variable = strtok(NULL, delimiter);
992 } 991 }
993 if (NULL == scope_variable) 992 if (NULL == scope_variable)
994 { 993 {
995 GNUNET_RECLAIM_get_attributes_next (handle->attr_it); 994 GNUNET_RECLAIM_get_attributes_next(handle->attr_it);
996 GNUNET_free (scope_variables); 995 GNUNET_free(scope_variables);
997 return; 996 return;
998 } 997 }
999 GNUNET_free (scope_variables); 998 GNUNET_free(scope_variables);
1000 999
1001 le = GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry); 1000 le = GNUNET_new(struct GNUNET_RECLAIM_ATTRIBUTE_ClaimListEntry);
1002 le->claim = GNUNET_RECLAIM_ATTRIBUTE_claim_new (attr->name, 1001 le->claim = GNUNET_RECLAIM_ATTRIBUTE_claim_new(attr->name,
1003 attr->type, 1002 attr->type,
1004 attr->data, 1003 attr->data,
1005 attr->data_size); 1004 attr->data_size);
1006 le->claim->id = attr->id; 1005 le->claim->id = attr->id;
1007 le->claim->version = attr->version; 1006 le->claim->version = attr->version;
1008 GNUNET_CONTAINER_DLL_insert (handle->attr_list->list_head, 1007 GNUNET_CONTAINER_DLL_insert(handle->attr_list->list_head,
1009 handle->attr_list->list_tail, 1008 handle->attr_list->list_tail,
1010 le); 1009 le);
1011 GNUNET_RECLAIM_get_attributes_next (handle->attr_it); 1010 GNUNET_RECLAIM_get_attributes_next(handle->attr_it);
1012} 1011}
1013 1012
1014 1013
@@ -1016,7 +1015,7 @@ oidc_attr_collect (void *cls,
1016 * Checks time and cookie and redirects accordingly 1015 * Checks time and cookie and redirects accordingly
1017 */ 1016 */
1018static void 1017static void
1019code_redirect (void *cls) 1018code_redirect(void *cls)
1020{ 1019{
1021 struct RequestHandle *handle = cls; 1020 struct RequestHandle *handle = cls;
1022 struct GNUNET_TIME_Absolute current_time; 1021 struct GNUNET_TIME_Absolute current_time;
@@ -1026,111 +1025,111 @@ code_redirect (void *cls)
1026 struct GNUNET_HashCode cache_key; 1025 struct GNUNET_HashCode cache_key;
1027 char *identity_cookie; 1026 char *identity_cookie;
1028 1027
1029 GNUNET_asprintf (&identity_cookie, 1028 GNUNET_asprintf(&identity_cookie,
1030 "Identity=%s", 1029 "Identity=%s",
1031 handle->oidc->login_identity); 1030 handle->oidc->login_identity);
1032 GNUNET_CRYPTO_hash (identity_cookie, strlen (identity_cookie), &cache_key); 1031 GNUNET_CRYPTO_hash(identity_cookie, strlen(identity_cookie), &cache_key);
1033 GNUNET_free (identity_cookie); 1032 GNUNET_free(identity_cookie);
1034 // No login time for identity -> redirect to login 1033 // No login time for identity -> redirect to login
1035 if (GNUNET_YES == 1034 if (GNUNET_YES ==
1036 GNUNET_CONTAINER_multihashmap_contains (OIDC_cookie_jar_map, &cache_key)) 1035 GNUNET_CONTAINER_multihashmap_contains(OIDC_cookie_jar_map, &cache_key))
1037 { 1036 {
1038 relog_time = 1037 relog_time =
1039 GNUNET_CONTAINER_multihashmap_get (OIDC_cookie_jar_map, &cache_key); 1038 GNUNET_CONTAINER_multihashmap_get(OIDC_cookie_jar_map, &cache_key);
1040 current_time = GNUNET_TIME_absolute_get (); 1039 current_time = GNUNET_TIME_absolute_get();
1041 // 30 min after old login -> redirect to login 1040 // 30 min after old login -> redirect to login
1042 if (current_time.abs_value_us <= relog_time->abs_value_us) 1041 if (current_time.abs_value_us <= relog_time->abs_value_us)
1043 {
1044 if (GNUNET_OK !=
1045 GNUNET_CRYPTO_ecdsa_public_key_from_string (handle->oidc
1046 ->login_identity,
1047 strlen (
1048 handle->oidc
1049 ->login_identity),
1050 &pubkey))
1051 {
1052 handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_COOKIE);
1053 handle->edesc =
1054 GNUNET_strdup ("The cookie of a login identity is not valid");
1055 GNUNET_SCHEDULER_add_now (&do_redirect_error, handle);
1056 return;
1057 }
1058 // iterate over egos and compare their public key
1059 for (handle->ego_entry = handle->ego_head; NULL != handle->ego_entry;
1060 handle->ego_entry = handle->ego_entry->next)
1061 {
1062 GNUNET_IDENTITY_ego_get_public_key (handle->ego_entry->ego, &ego_pkey);
1063 if (0 == GNUNET_memcmp (&ego_pkey, &pubkey))
1064 { 1042 {
1065 handle->priv_key = 1043 if (GNUNET_OK !=
1066 *GNUNET_IDENTITY_ego_get_private_key (handle->ego_entry->ego); 1044 GNUNET_CRYPTO_ecdsa_public_key_from_string(handle->oidc
1067 handle->idp = GNUNET_RECLAIM_connect (cfg); 1045 ->login_identity,
1068 handle->attr_list = 1046 strlen(
1069 GNUNET_new (struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList); 1047 handle->oidc
1070 handle->attr_it = 1048 ->login_identity),
1071 GNUNET_RECLAIM_get_attributes_start (handle->idp, 1049 &pubkey))
1072 &handle->priv_key, 1050 {
1073 &oidc_iteration_error, 1051 handle->emsg = GNUNET_strdup(OIDC_ERROR_KEY_INVALID_COOKIE);
1074 handle, 1052 handle->edesc =
1075 &oidc_attr_collect, 1053 GNUNET_strdup("The cookie of a login identity is not valid");
1076 handle, 1054 GNUNET_SCHEDULER_add_now(&do_redirect_error, handle);
1077 &oidc_collect_finished_cb, 1055 return;
1078 handle); 1056 }
1057 // iterate over egos and compare their public key
1058 for (handle->ego_entry = handle->ego_head; NULL != handle->ego_entry;
1059 handle->ego_entry = handle->ego_entry->next)
1060 {
1061 GNUNET_IDENTITY_ego_get_public_key(handle->ego_entry->ego, &ego_pkey);
1062 if (0 == GNUNET_memcmp(&ego_pkey, &pubkey))
1063 {
1064 handle->priv_key =
1065 *GNUNET_IDENTITY_ego_get_private_key(handle->ego_entry->ego);
1066 handle->idp = GNUNET_RECLAIM_connect(cfg);
1067 handle->attr_list =
1068 GNUNET_new(struct GNUNET_RECLAIM_ATTRIBUTE_ClaimList);
1069 handle->attr_it =
1070 GNUNET_RECLAIM_get_attributes_start(handle->idp,
1071 &handle->priv_key,
1072 &oidc_iteration_error,
1073 handle,
1074 &oidc_attr_collect,
1075 handle,
1076 &oidc_collect_finished_cb,
1077 handle);
1078 return;
1079 }
1080 }
1081 GNUNET_SCHEDULER_add_now(&login_redirect, handle);
1079 return; 1082 return;
1080 } 1083 }
1081 }
1082 GNUNET_SCHEDULER_add_now (&login_redirect, handle);
1083 return;
1084 } 1084 }
1085 }
1086} 1085}
1087 1086
1088 1087
1089static void 1088static void
1090build_redirect (void *cls) 1089build_redirect(void *cls)
1091{ 1090{
1092 struct RequestHandle *handle = cls; 1091 struct RequestHandle *handle = cls;
1093 struct MHD_Response *resp; 1092 struct MHD_Response *resp;
1094 char *redirect_uri; 1093 char *redirect_uri;
1095 1094
1096 if (GNUNET_YES == handle->oidc->user_cancelled) 1095 if (GNUNET_YES == handle->oidc->user_cancelled)
1097 { 1096 {
1098 if ((NULL != handle->redirect_prefix) && 1097 if ((NULL != handle->redirect_prefix) &&
1099 (NULL != handle->redirect_suffix) && (NULL != handle->tld)) 1098 (NULL != handle->redirect_suffix) && (NULL != handle->tld))
1100 { 1099 {
1101 GNUNET_asprintf (&redirect_uri, 1100 GNUNET_asprintf(&redirect_uri,
1102 "%s.%s/%s?error=%s&error_description=%s&state=%s", 1101 "%s.%s/%s?error=%s&error_description=%s&state=%s",
1103 handle->redirect_prefix, 1102 handle->redirect_prefix,
1104 handle->tld, 1103 handle->tld,
1105 handle->redirect_suffix, 1104 handle->redirect_suffix,
1106 "access_denied", 1105 "access_denied",
1107 "User denied access", 1106 "User denied access",
1108 handle->oidc->state); 1107 handle->oidc->state);
1109 } 1108 }
1110 else 1109 else
1111 { 1110 {
1112 GNUNET_asprintf (&redirect_uri, 1111 GNUNET_asprintf(&redirect_uri,
1113 "%s?error=%s&error_description=%s&state=%s", 1112 "%s?error=%s&error_description=%s&state=%s",
1114 handle->oidc->redirect_uri, 1113 handle->oidc->redirect_uri,
1115 "access_denied", 1114 "access_denied",
1116 "User denied access", 1115 "User denied access",
1117 handle->oidc->state); 1116 handle->oidc->state);
1118 } 1117 }
1119 resp = GNUNET_REST_create_response (""); 1118 resp = GNUNET_REST_create_response("");
1120 MHD_add_response_header (resp, "Location", redirect_uri); 1119 MHD_add_response_header(resp, "Location", redirect_uri);
1121 handle->proc (handle->proc_cls, resp, MHD_HTTP_FOUND); 1120 handle->proc(handle->proc_cls, resp, MHD_HTTP_FOUND);
1122 GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle); 1121 GNUNET_SCHEDULER_add_now(&cleanup_handle_delayed, handle);
1123 GNUNET_free (redirect_uri); 1122 GNUNET_free(redirect_uri);
1124 return; 1123 return;
1125 } 1124 }
1126 GNUNET_SCHEDULER_add_now (&code_redirect, handle); 1125 GNUNET_SCHEDULER_add_now(&code_redirect, handle);
1127} 1126}
1128 1127
1129 1128
1130static void 1129static void
1131lookup_redirect_uri_result (void *cls, 1130lookup_redirect_uri_result(void *cls,
1132 uint32_t rd_count, 1131 uint32_t rd_count,
1133 const struct GNUNET_GNSRECORD_Data *rd) 1132 const struct GNUNET_GNSRECORD_Data *rd)
1134{ 1133{
1135 struct RequestHandle *handle = cls; 1134 struct RequestHandle *handle = cls;
1136 char *tmp; 1135 char *tmp;
@@ -1140,66 +1139,66 @@ lookup_redirect_uri_result (void *cls,
1140 1139
1141 handle->gns_op = NULL; 1140 handle->gns_op = NULL;
1142 if (0 == rd_count) 1141 if (0 == rd_count)
1143 { 1142 {
1144 handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_SERVER_ERROR); 1143 handle->emsg = GNUNET_strdup(OIDC_ERROR_KEY_SERVER_ERROR);
1145 handle->edesc = 1144 handle->edesc =
1146 GNUNET_strdup ("Server cannot generate ticket, redirect uri not found."); 1145 GNUNET_strdup("Server cannot generate ticket, redirect uri not found.");
1147 GNUNET_SCHEDULER_add_now (&do_redirect_error, handle); 1146 GNUNET_SCHEDULER_add_now(&do_redirect_error, handle);
1148 return; 1147 return;
1149 } 1148 }
1150 for (int i = 0; i < rd_count; i++) 1149 for (int i = 0; i < rd_count; i++)
1151 { 1150 {
1152 if (GNUNET_GNSRECORD_TYPE_RECLAIM_OIDC_REDIRECT != rd[i].record_type) 1151 if (GNUNET_GNSRECORD_TYPE_RECLAIM_OIDC_REDIRECT != rd[i].record_type)
1153 continue;
1154 if (0 != strncmp (rd[i].data, handle->oidc->redirect_uri, rd[i].data_size))
1155 continue;
1156 tmp = GNUNET_strndup (rd[i].data, rd[i].data_size);
1157 if (NULL == strstr (tmp, handle->oidc->client_id))
1158 {
1159 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1160 "Redirect uri %s does not contain client_id %s\n",
1161 tmp,
1162 handle->oidc->client_id);
1163 }
1164 else
1165 {
1166 pos = strrchr (tmp, (unsigned char) '.');
1167 if (NULL == pos)
1168 {
1169 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1170 "Redirect uri %s contains client_id but is malformed\n",
1171 tmp);
1172 GNUNET_free (tmp);
1173 continue; 1152 continue;
1174 } 1153 if (0 != strncmp(rd[i].data, handle->oidc->redirect_uri, rd[i].data_size))
1175 *pos = '\0';
1176 handle->redirect_prefix = GNUNET_strdup (tmp);
1177 tmp_key_str = pos + 1;
1178 pos = strchr (tmp_key_str, (unsigned char) '/');
1179 if (NULL == pos)
1180 {
1181 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1182 "Redirect uri %s contains client_id but is malformed\n",
1183 tmp);
1184 GNUNET_free (tmp);
1185 continue; 1154 continue;
1186 } 1155 tmp = GNUNET_strndup(rd[i].data, rd[i].data_size);
1187 *pos = '\0'; 1156 if (NULL == strstr(tmp, handle->oidc->client_id))
1188 handle->redirect_suffix = GNUNET_strdup (pos + 1); 1157 {
1189 1158 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
1190 GNUNET_STRINGS_string_to_data (tmp_key_str, 1159 "Redirect uri %s does not contain client_id %s\n",
1191 strlen (tmp_key_str), 1160 tmp,
1192 &redirect_zone, 1161 handle->oidc->client_id);
1193 sizeof (redirect_zone)); 1162 }
1194 } 1163 else
1195 GNUNET_SCHEDULER_add_now (&build_redirect, handle); 1164 {
1196 GNUNET_free (tmp); 1165 pos = strrchr(tmp, (unsigned char)'.');
1197 return; 1166 if (NULL == pos)
1198 } 1167 {
1199 handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_SERVER_ERROR); 1168 GNUNET_log(GNUNET_ERROR_TYPE_WARNING,
1169 "Redirect uri %s contains client_id but is malformed\n",
1170 tmp);
1171 GNUNET_free(tmp);
1172 continue;
1173 }
1174 *pos = '\0';
1175 handle->redirect_prefix = GNUNET_strdup(tmp);
1176 tmp_key_str = pos + 1;
1177 pos = strchr(tmp_key_str, (unsigned char)'/');
1178 if (NULL == pos)
1179 {
1180 GNUNET_log(GNUNET_ERROR_TYPE_WARNING,
1181 "Redirect uri %s contains client_id but is malformed\n",
1182 tmp);
1183 GNUNET_free(tmp);
1184 continue;
1185 }
1186 *pos = '\0';
1187 handle->redirect_suffix = GNUNET_strdup(pos + 1);
1188
1189 GNUNET_STRINGS_string_to_data(tmp_key_str,
1190 strlen(tmp_key_str),
1191 &redirect_zone,
1192 sizeof(redirect_zone));
1193 }
1194 GNUNET_SCHEDULER_add_now(&build_redirect, handle);
1195 GNUNET_free(tmp);
1196 return;
1197 }
1198 handle->emsg = GNUNET_strdup(OIDC_ERROR_KEY_SERVER_ERROR);
1200 handle->edesc = 1199 handle->edesc =
1201 GNUNET_strdup ("Server cannot generate ticket, redirect uri not found."); 1200 GNUNET_strdup("Server cannot generate ticket, redirect uri not found.");
1202 GNUNET_SCHEDULER_add_now (&do_redirect_error, handle); 1201 GNUNET_SCHEDULER_add_now(&do_redirect_error, handle);
1203} 1202}
1204 1203
1205 1204
@@ -1207,36 +1206,37 @@ lookup_redirect_uri_result (void *cls,
1207 * Initiate redirect back to client. 1206 * Initiate redirect back to client.
1208 */ 1207 */
1209static void 1208static void
1210client_redirect (void *cls) 1209client_redirect(void *cls)
1211{ 1210{
1212 struct RequestHandle *handle = cls; 1211 struct RequestHandle *handle = cls;
1213 1212
1214 /* Lookup client redirect uri to verify request */ 1213 /* Lookup client redirect uri to verify request */
1215 handle->gns_op = 1214 handle->gns_op =
1216 GNUNET_GNS_lookup (handle->gns_handle, 1215 GNUNET_GNS_lookup(handle->gns_handle,
1217 GNUNET_GNS_EMPTY_LABEL_AT, 1216 GNUNET_GNS_EMPTY_LABEL_AT,
1218 &handle->oidc->client_pkey, 1217 &handle->oidc->client_pkey,
1219 GNUNET_GNSRECORD_TYPE_RECLAIM_OIDC_REDIRECT, 1218 GNUNET_GNSRECORD_TYPE_RECLAIM_OIDC_REDIRECT,
1220 GNUNET_GNS_LO_DEFAULT, 1219 GNUNET_GNS_LO_DEFAULT,
1221 &lookup_redirect_uri_result, 1220 &lookup_redirect_uri_result,
1222 handle); 1221 handle);
1223} 1222}
1224 1223
1225static char * 1224static char *
1226get_url_parameter_copy (const struct RequestHandle *handle, const char *key) 1225get_url_parameter_copy(const struct RequestHandle *handle, const char *key)
1227{ 1226{
1228 struct GNUNET_HashCode hc; 1227 struct GNUNET_HashCode hc;
1229 char *value; 1228 char *value;
1230 GNUNET_CRYPTO_hash (key, strlen (key), &hc); 1229
1231 if (GNUNET_YES != GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle 1230 GNUNET_CRYPTO_hash(key, strlen(key), &hc);
1232 ->url_param_map, 1231 if (GNUNET_YES != GNUNET_CONTAINER_multihashmap_contains(handle->rest_handle
1233 &hc)) 1232 ->url_param_map,
1233 &hc))
1234 return NULL; 1234 return NULL;
1235 value = 1235 value =
1236 GNUNET_CONTAINER_multihashmap_get (handle->rest_handle->url_param_map, &hc); 1236 GNUNET_CONTAINER_multihashmap_get(handle->rest_handle->url_param_map, &hc);
1237 if (NULL == value) 1237 if (NULL == value)
1238 return NULL; 1238 return NULL;
1239 return GNUNET_strdup (value); 1239 return GNUNET_strdup(value);
1240} 1240}
1241 1241
1242 1242
@@ -1247,7 +1247,7 @@ get_url_parameter_copy (const struct RequestHandle *handle, const char *key)
1247 * @param cls the `struct RequestHandle` 1247 * @param cls the `struct RequestHandle`
1248 */ 1248 */
1249static void 1249static void
1250build_authz_response (void *cls) 1250build_authz_response(void *cls)
1251{ 1251{
1252 struct RequestHandle *handle = cls; 1252 struct RequestHandle *handle = cls;
1253 struct GNUNET_HashCode cache_key; 1253 struct GNUNET_HashCode cache_key;
@@ -1259,117 +1259,117 @@ build_authz_response (void *cls)
1259 1259
1260 // REQUIRED value: redirect_uri 1260 // REQUIRED value: redirect_uri
1261 handle->oidc->redirect_uri = 1261 handle->oidc->redirect_uri =
1262 get_url_parameter_copy (handle, OIDC_REDIRECT_URI_KEY); 1262 get_url_parameter_copy(handle, OIDC_REDIRECT_URI_KEY);
1263 if (NULL == handle->oidc->redirect_uri) 1263 if (NULL == handle->oidc->redirect_uri)
1264 { 1264 {
1265 handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_REQUEST); 1265 handle->emsg = GNUNET_strdup(OIDC_ERROR_KEY_INVALID_REQUEST);
1266 handle->edesc = GNUNET_strdup ("missing parameter redirect_uri"); 1266 handle->edesc = GNUNET_strdup("missing parameter redirect_uri");
1267 GNUNET_SCHEDULER_add_now (&do_error, handle); 1267 GNUNET_SCHEDULER_add_now(&do_error, handle);
1268 return; 1268 return;
1269 } 1269 }
1270 1270
1271 // REQUIRED value: response_type 1271 // REQUIRED value: response_type
1272 handle->oidc->response_type = 1272 handle->oidc->response_type =
1273 get_url_parameter_copy (handle, OIDC_RESPONSE_TYPE_KEY); 1273 get_url_parameter_copy(handle, OIDC_RESPONSE_TYPE_KEY);
1274 if (NULL == handle->oidc->response_type) 1274 if (NULL == handle->oidc->response_type)
1275 { 1275 {
1276 handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_REQUEST); 1276 handle->emsg = GNUNET_strdup(OIDC_ERROR_KEY_INVALID_REQUEST);
1277 handle->edesc = GNUNET_strdup ("missing parameter response_type"); 1277 handle->edesc = GNUNET_strdup("missing parameter response_type");
1278 GNUNET_SCHEDULER_add_now (&do_redirect_error, handle); 1278 GNUNET_SCHEDULER_add_now(&do_redirect_error, handle);
1279 return; 1279 return;
1280 } 1280 }
1281 1281
1282 // REQUIRED value: scope 1282 // REQUIRED value: scope
1283 handle->oidc->scope = get_url_parameter_copy (handle, OIDC_SCOPE_KEY); 1283 handle->oidc->scope = get_url_parameter_copy(handle, OIDC_SCOPE_KEY);
1284 if (NULL == handle->oidc->scope) 1284 if (NULL == handle->oidc->scope)
1285 { 1285 {
1286 handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_SCOPE); 1286 handle->emsg = GNUNET_strdup(OIDC_ERROR_KEY_INVALID_SCOPE);
1287 handle->edesc = GNUNET_strdup ("missing parameter scope"); 1287 handle->edesc = GNUNET_strdup("missing parameter scope");
1288 GNUNET_SCHEDULER_add_now (&do_redirect_error, handle); 1288 GNUNET_SCHEDULER_add_now(&do_redirect_error, handle);
1289 return; 1289 return;
1290 } 1290 }
1291 1291
1292 // OPTIONAL value: nonce 1292 // OPTIONAL value: nonce
1293 handle->oidc->nonce = get_url_parameter_copy (handle, OIDC_NONCE_KEY); 1293 handle->oidc->nonce = get_url_parameter_copy(handle, OIDC_NONCE_KEY);
1294 1294
1295 // TODO check other values if needed 1295 // TODO check other values if needed
1296 number_of_ignored_parameter = 1296 number_of_ignored_parameter =
1297 sizeof (OIDC_ignored_parameter_array) / sizeof (char *); 1297 sizeof(OIDC_ignored_parameter_array) / sizeof(char *);
1298 for (iterator = 0; iterator < number_of_ignored_parameter; iterator++) 1298 for (iterator = 0; iterator < number_of_ignored_parameter; iterator++)
1299 { 1299 {
1300 GNUNET_CRYPTO_hash (OIDC_ignored_parameter_array[iterator], 1300 GNUNET_CRYPTO_hash(OIDC_ignored_parameter_array[iterator],
1301 strlen (OIDC_ignored_parameter_array[iterator]), 1301 strlen(OIDC_ignored_parameter_array[iterator]),
1302 &cache_key); 1302 &cache_key);
1303 if (GNUNET_YES == 1303 if (GNUNET_YES ==
1304 GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle 1304 GNUNET_CONTAINER_multihashmap_contains(handle->rest_handle
1305 ->url_param_map, 1305 ->url_param_map,
1306 &cache_key)) 1306 &cache_key))
1307 { 1307 {
1308 handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_ACCESS_DENIED); 1308 handle->emsg = GNUNET_strdup(OIDC_ERROR_KEY_ACCESS_DENIED);
1309 GNUNET_asprintf (&handle->edesc, 1309 GNUNET_asprintf(&handle->edesc,
1310 "Server will not handle parameter: %s", 1310 "Server will not handle parameter: %s",
1311 OIDC_ignored_parameter_array[iterator]); 1311 OIDC_ignored_parameter_array[iterator]);
1312 GNUNET_SCHEDULER_add_now (&do_redirect_error, handle); 1312 GNUNET_SCHEDULER_add_now(&do_redirect_error, handle);
1313 return; 1313 return;
1314 }
1314 } 1315 }
1315 }
1316 1316
1317 // We only support authorization code flows. 1317 // We only support authorization code flows.
1318 if (0 != strcmp (handle->oidc->response_type, 1318 if (0 != strcmp(handle->oidc->response_type,
1319 OIDC_EXPECTED_AUTHORIZATION_RESPONSE_TYPE)) 1319 OIDC_EXPECTED_AUTHORIZATION_RESPONSE_TYPE))
1320 { 1320 {
1321 handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_UNSUPPORTED_RESPONSE_TYPE); 1321 handle->emsg = GNUNET_strdup(OIDC_ERROR_KEY_UNSUPPORTED_RESPONSE_TYPE);
1322 handle->edesc = GNUNET_strdup ("The authorization server does not support " 1322 handle->edesc = GNUNET_strdup("The authorization server does not support "
1323 "obtaining this authorization code."); 1323 "obtaining this authorization code.");
1324 GNUNET_SCHEDULER_add_now (&do_redirect_error, handle); 1324 GNUNET_SCHEDULER_add_now(&do_redirect_error, handle);
1325 return; 1325 return;
1326 } 1326 }
1327 1327
1328 // Checks if scope contains 'openid' 1328 // Checks if scope contains 'openid'
1329 expected_scope = GNUNET_strdup (handle->oidc->scope); 1329 expected_scope = GNUNET_strdup(handle->oidc->scope);
1330 char *test; 1330 char *test;
1331 test = strtok (expected_scope, delimiter); 1331 test = strtok(expected_scope, delimiter);
1332 while (NULL != test) 1332 while (NULL != test)
1333 { 1333 {
1334 if (0 == strcmp (OIDC_EXPECTED_AUTHORIZATION_SCOPE, expected_scope)) 1334 if (0 == strcmp(OIDC_EXPECTED_AUTHORIZATION_SCOPE, expected_scope))
1335 break; 1335 break;
1336 test = strtok (NULL, delimiter); 1336 test = strtok(NULL, delimiter);
1337 } 1337 }
1338 if (NULL == test) 1338 if (NULL == test)
1339 { 1339 {
1340 handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_SCOPE); 1340 handle->emsg = GNUNET_strdup(OIDC_ERROR_KEY_INVALID_SCOPE);
1341 handle->edesc = 1341 handle->edesc =
1342 GNUNET_strdup ("The requested scope is invalid, unknown, or malformed."); 1342 GNUNET_strdup("The requested scope is invalid, unknown, or malformed.");
1343 GNUNET_SCHEDULER_add_now (&do_redirect_error, handle); 1343 GNUNET_SCHEDULER_add_now(&do_redirect_error, handle);
1344 GNUNET_free (expected_scope); 1344 GNUNET_free(expected_scope);
1345 return; 1345 return;
1346 } 1346 }
1347 1347
1348 GNUNET_free (expected_scope); 1348 GNUNET_free(expected_scope);
1349 if ((NULL == handle->oidc->login_identity) && 1349 if ((NULL == handle->oidc->login_identity) &&
1350 (GNUNET_NO == handle->oidc->user_cancelled)) 1350 (GNUNET_NO == handle->oidc->user_cancelled))
1351 GNUNET_SCHEDULER_add_now (&login_redirect, handle); 1351 GNUNET_SCHEDULER_add_now(&login_redirect, handle);
1352 else 1352 else
1353 GNUNET_SCHEDULER_add_now (&client_redirect, handle); 1353 GNUNET_SCHEDULER_add_now(&client_redirect, handle);
1354} 1354}
1355 1355
1356/** 1356/**
1357 * Iterate over tlds in config 1357 * Iterate over tlds in config
1358 */ 1358 */
1359static void 1359static void
1360tld_iter (void *cls, const char *section, const char *option, const char *value) 1360tld_iter(void *cls, const char *section, const char *option, const char *value)
1361{ 1361{
1362 struct RequestHandle *handle = cls; 1362 struct RequestHandle *handle = cls;
1363 struct GNUNET_CRYPTO_EcdsaPublicKey pkey; 1363 struct GNUNET_CRYPTO_EcdsaPublicKey pkey;
1364 1364
1365 if (GNUNET_OK != 1365 if (GNUNET_OK !=
1366 GNUNET_CRYPTO_ecdsa_public_key_from_string (value, strlen (value), &pkey)) 1366 GNUNET_CRYPTO_ecdsa_public_key_from_string(value, strlen(value), &pkey))
1367 { 1367 {
1368 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Skipping non key %s\n", value); 1368 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Skipping non key %s\n", value);
1369 return; 1369 return;
1370 } 1370 }
1371 if (0 == GNUNET_memcmp (&pkey, &handle->oidc->client_pkey)) 1371 if (0 == GNUNET_memcmp(&pkey, &handle->oidc->client_pkey))
1372 handle->tld = GNUNET_strdup (option + 1); 1372 handle->tld = GNUNET_strdup(option + 1);
1373} 1373}
1374 1374
1375/** 1375/**
@@ -1380,70 +1380,70 @@ tld_iter (void *cls, const char *section, const char *option, const char *value)
1380 * @param cls the RequestHandle 1380 * @param cls the RequestHandle
1381 */ 1381 */
1382static void 1382static void
1383authorize_endpoint (struct GNUNET_REST_RequestHandle *con_handle, 1383authorize_endpoint(struct GNUNET_REST_RequestHandle *con_handle,
1384 const char *url, 1384 const char *url,
1385 void *cls) 1385 void *cls)
1386{ 1386{
1387 struct RequestHandle *handle = cls; 1387 struct RequestHandle *handle = cls;
1388 struct EgoEntry *tmp_ego; 1388 struct EgoEntry *tmp_ego;
1389 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key; 1389 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key;
1390 struct GNUNET_CRYPTO_EcdsaPublicKey pkey; 1390 struct GNUNET_CRYPTO_EcdsaPublicKey pkey;
1391 1391
1392 cookie_identity_interpretation (handle); 1392 cookie_identity_interpretation(handle);
1393 1393
1394 // RECOMMENDED value: state - REQUIRED for answers 1394 // RECOMMENDED value: state - REQUIRED for answers
1395 handle->oidc->state = get_url_parameter_copy (handle, OIDC_STATE_KEY); 1395 handle->oidc->state = get_url_parameter_copy(handle, OIDC_STATE_KEY);
1396 1396
1397 // REQUIRED value: client_id 1397 // REQUIRED value: client_id
1398 handle->oidc->client_id = get_url_parameter_copy (handle, OIDC_CLIENT_ID_KEY); 1398 handle->oidc->client_id = get_url_parameter_copy(handle, OIDC_CLIENT_ID_KEY);
1399 if (NULL == handle->oidc->client_id) 1399 if (NULL == handle->oidc->client_id)
1400 { 1400 {
1401 handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_REQUEST); 1401 handle->emsg = GNUNET_strdup(OIDC_ERROR_KEY_INVALID_REQUEST);
1402 handle->edesc = GNUNET_strdup ("missing parameter client_id"); 1402 handle->edesc = GNUNET_strdup("missing parameter client_id");
1403 handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR; 1403 handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
1404 GNUNET_SCHEDULER_add_now (&do_error, handle); 1404 GNUNET_SCHEDULER_add_now(&do_error, handle);
1405 return; 1405 return;
1406 } 1406 }
1407 1407
1408 // OPTIONAL value: code_challenge 1408 // OPTIONAL value: code_challenge
1409 handle->oidc->code_challenge = get_url_parameter_copy (handle, OIDC_CODE_CHALLENGE_KEY); 1409 handle->oidc->code_challenge = get_url_parameter_copy(handle, OIDC_CODE_CHALLENGE_KEY);
1410 if (NULL == handle->oidc->code_challenge) 1410 if (NULL == handle->oidc->code_challenge)
1411 { 1411 {
1412 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 1412 GNUNET_log(GNUNET_ERROR_TYPE_WARNING,
1413 "OAuth authorization request does not contain PKCE parameters!\n"); 1413 "OAuth authorization request does not contain PKCE parameters!\n");
1414 } 1414 }
1415 1415
1416 if (GNUNET_OK != 1416 if (GNUNET_OK !=
1417 GNUNET_CRYPTO_ecdsa_public_key_from_string (handle->oidc->client_id, 1417 GNUNET_CRYPTO_ecdsa_public_key_from_string(handle->oidc->client_id,
1418 strlen ( 1418 strlen(
1419 handle->oidc->client_id), 1419 handle->oidc->client_id),
1420 &handle->oidc->client_pkey)) 1420 &handle->oidc->client_pkey))
1421 { 1421 {
1422 handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_UNAUTHORIZED_CLIENT); 1422 handle->emsg = GNUNET_strdup(OIDC_ERROR_KEY_UNAUTHORIZED_CLIENT);
1423 handle->edesc = GNUNET_strdup ("The client is not authorized to request an " 1423 handle->edesc = GNUNET_strdup("The client is not authorized to request an "
1424 "authorization code using this method."); 1424 "authorization code using this method.");
1425 handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR; 1425 handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
1426 GNUNET_SCHEDULER_add_now (&do_error, handle); 1426 GNUNET_SCHEDULER_add_now(&do_error, handle);
1427 return; 1427 return;
1428 } 1428 }
1429 1429
1430 // If we know this identity, translated the corresponding TLD 1430 // If we know this identity, translated the corresponding TLD
1431 // TODO: We might want to have a reverse lookup functionality for TLDs? 1431 // TODO: We might want to have a reverse lookup functionality for TLDs?
1432 for (tmp_ego = handle->ego_head; NULL != tmp_ego; tmp_ego = tmp_ego->next) 1432 for (tmp_ego = handle->ego_head; NULL != tmp_ego; tmp_ego = tmp_ego->next)
1433 {
1434 priv_key = GNUNET_IDENTITY_ego_get_private_key (tmp_ego->ego);
1435 GNUNET_CRYPTO_ecdsa_key_get_public (priv_key, &pkey);
1436 if (0 == GNUNET_memcmp (&pkey, &handle->oidc->client_pkey))
1437 { 1433 {
1438 handle->tld = GNUNET_strdup (tmp_ego->identifier); 1434 priv_key = GNUNET_IDENTITY_ego_get_private_key(tmp_ego->ego);
1439 handle->ego_entry = handle->ego_tail; 1435 GNUNET_CRYPTO_ecdsa_key_get_public(priv_key, &pkey);
1436 if (0 == GNUNET_memcmp(&pkey, &handle->oidc->client_pkey))
1437 {
1438 handle->tld = GNUNET_strdup(tmp_ego->identifier);
1439 handle->ego_entry = handle->ego_tail;
1440 }
1440 } 1441 }
1441 }
1442 if (NULL == handle->tld) 1442 if (NULL == handle->tld)
1443 GNUNET_CONFIGURATION_iterate_section_values (cfg, "gns", tld_iter, handle); 1443 GNUNET_CONFIGURATION_iterate_section_values(cfg, "gns", tld_iter, handle);
1444 if (NULL == handle->tld) 1444 if (NULL == handle->tld)
1445 handle->tld = GNUNET_strdup (handle->oidc->client_id); 1445 handle->tld = GNUNET_strdup(handle->oidc->client_id);
1446 GNUNET_SCHEDULER_add_now (&build_authz_response, handle); 1446 GNUNET_SCHEDULER_add_now(&build_authz_response, handle);
1447} 1447}
1448 1448
1449/** 1449/**
@@ -1454,11 +1454,11 @@ authorize_endpoint (struct GNUNET_REST_RequestHandle *con_handle,
1454 * @param cls the RequestHandle 1454 * @param cls the RequestHandle
1455 */ 1455 */
1456static void 1456static void
1457login_cont (struct GNUNET_REST_RequestHandle *con_handle, 1457login_cont(struct GNUNET_REST_RequestHandle *con_handle,
1458 const char *url, 1458 const char *url,
1459 void *cls) 1459 void *cls)
1460{ 1460{
1461 struct MHD_Response *resp = GNUNET_REST_create_response (""); 1461 struct MHD_Response *resp = GNUNET_REST_create_response("");
1462 struct RequestHandle *handle = cls; 1462 struct RequestHandle *handle = cls;
1463 struct GNUNET_HashCode cache_key; 1463 struct GNUNET_HashCode cache_key;
1464 struct GNUNET_TIME_Absolute *current_time; 1464 struct GNUNET_TIME_Absolute *current_time;
@@ -1469,55 +1469,56 @@ login_cont (struct GNUNET_REST_RequestHandle *con_handle,
1469 json_error_t error; 1469 json_error_t error;
1470 json_t *identity; 1470 json_t *identity;
1471 char term_data[handle->rest_handle->data_size + 1]; 1471 char term_data[handle->rest_handle->data_size + 1];
1472
1472 term_data[handle->rest_handle->data_size] = '\0'; 1473 term_data[handle->rest_handle->data_size] = '\0';
1473 GNUNET_memcpy (term_data, 1474 GNUNET_memcpy(term_data,
1474 handle->rest_handle->data, 1475 handle->rest_handle->data,
1475 handle->rest_handle->data_size); 1476 handle->rest_handle->data_size);
1476 root = json_loads (term_data, JSON_DECODE_ANY, &error); 1477 root = json_loads(term_data, JSON_DECODE_ANY, &error);
1477 identity = json_object_get (root, "identity"); 1478 identity = json_object_get(root, "identity");
1478 if (! json_is_string (identity)) 1479 if (!json_is_string(identity))
1479 { 1480 {
1480 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1481 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
1481 "Error parsing json string from %s\n", 1482 "Error parsing json string from %s\n",
1482 term_data); 1483 term_data);
1483 handle->proc (handle->proc_cls, resp, MHD_HTTP_BAD_REQUEST); 1484 handle->proc(handle->proc_cls, resp, MHD_HTTP_BAD_REQUEST);
1484 json_decref (root); 1485 json_decref(root);
1485 GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle); 1486 GNUNET_SCHEDULER_add_now(&cleanup_handle_delayed, handle);
1486 return; 1487 return;
1487 } 1488 }
1488 GNUNET_asprintf (&cookie, "Identity=%s", json_string_value (identity)); 1489 GNUNET_asprintf(&cookie, "Identity=%s", json_string_value(identity));
1489 GNUNET_asprintf (&header_val, 1490 GNUNET_asprintf(&header_val,
1490 "%s;Max-Age=%d", 1491 "%s;Max-Age=%d",
1491 cookie, 1492 cookie,
1492 OIDC_COOKIE_EXPIRATION); 1493 OIDC_COOKIE_EXPIRATION);
1493 MHD_add_response_header (resp, "Set-Cookie", header_val); 1494 MHD_add_response_header(resp, "Set-Cookie", header_val);
1494 MHD_add_response_header (resp, "Access-Control-Allow-Methods", "POST"); 1495 MHD_add_response_header(resp, "Access-Control-Allow-Methods", "POST");
1495 GNUNET_CRYPTO_hash (cookie, strlen (cookie), &cache_key); 1496 GNUNET_CRYPTO_hash(cookie, strlen(cookie), &cache_key);
1496 1497
1497 if (0 != strcmp (json_string_value (identity), "Denied")) 1498 if (0 != strcmp(json_string_value(identity), "Denied"))
1498 { 1499 {
1499 current_time = GNUNET_new (struct GNUNET_TIME_Absolute); 1500 current_time = GNUNET_new(struct GNUNET_TIME_Absolute);
1500 *current_time = GNUNET_TIME_relative_to_absolute ( 1501 *current_time = GNUNET_TIME_relative_to_absolute(
1501 GNUNET_TIME_relative_multiply (GNUNET_TIME_relative_get_second_ (), 1502 GNUNET_TIME_relative_multiply(GNUNET_TIME_relative_get_second_(),
1502 OIDC_COOKIE_EXPIRATION)); 1503 OIDC_COOKIE_EXPIRATION));
1503 last_time = 1504 last_time =
1504 GNUNET_CONTAINER_multihashmap_get (OIDC_cookie_jar_map, &cache_key); 1505 GNUNET_CONTAINER_multihashmap_get(OIDC_cookie_jar_map, &cache_key);
1505 GNUNET_free_non_null (last_time); 1506 GNUNET_free_non_null(last_time);
1506 GNUNET_CONTAINER_multihashmap_put (OIDC_cookie_jar_map, 1507 GNUNET_CONTAINER_multihashmap_put(OIDC_cookie_jar_map,
1507 &cache_key, 1508 &cache_key,
1508 current_time, 1509 current_time,
1509 GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE); 1510 GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE);
1510 } 1511 }
1511 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); 1512 handle->proc(handle->proc_cls, resp, MHD_HTTP_OK);
1512 GNUNET_free (cookie); 1513 GNUNET_free(cookie);
1513 GNUNET_free (header_val); 1514 GNUNET_free(header_val);
1514 json_decref (root); 1515 json_decref(root);
1515 GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle); 1516 GNUNET_SCHEDULER_add_now(&cleanup_handle_delayed, handle);
1516} 1517}
1517 1518
1518static int 1519static int
1519check_authorization (struct RequestHandle *handle, 1520check_authorization(struct RequestHandle *handle,
1520 struct GNUNET_CRYPTO_EcdsaPublicKey *cid) 1521 struct GNUNET_CRYPTO_EcdsaPublicKey *cid)
1521{ 1522{
1522 struct GNUNET_HashCode cache_key; 1523 struct GNUNET_HashCode cache_key;
1523 char *authorization; 1524 char *authorization;
@@ -1527,146 +1528,146 @@ check_authorization (struct RequestHandle *handle,
1527 char *pass; 1528 char *pass;
1528 char *expected_pass; 1529 char *expected_pass;
1529 1530
1530 GNUNET_CRYPTO_hash (OIDC_AUTHORIZATION_HEADER_KEY, 1531 GNUNET_CRYPTO_hash(OIDC_AUTHORIZATION_HEADER_KEY,
1531 strlen (OIDC_AUTHORIZATION_HEADER_KEY), 1532 strlen(OIDC_AUTHORIZATION_HEADER_KEY),
1532 &cache_key); 1533 &cache_key);
1533 if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle 1534 if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains(handle->rest_handle
1534 ->header_param_map, 1535 ->header_param_map,
1535 &cache_key)) 1536 &cache_key))
1536 { 1537 {
1537 handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_CLIENT); 1538 handle->emsg = GNUNET_strdup(OIDC_ERROR_KEY_INVALID_CLIENT);
1538 handle->edesc = GNUNET_strdup ("missing authorization"); 1539 handle->edesc = GNUNET_strdup("missing authorization");
1539 handle->response_code = MHD_HTTP_UNAUTHORIZED; 1540 handle->response_code = MHD_HTTP_UNAUTHORIZED;
1540 return GNUNET_SYSERR; 1541 return GNUNET_SYSERR;
1541 } 1542 }
1542 authorization = 1543 authorization =
1543 GNUNET_CONTAINER_multihashmap_get (handle->rest_handle->header_param_map, 1544 GNUNET_CONTAINER_multihashmap_get(handle->rest_handle->header_param_map,
1544 &cache_key); 1545 &cache_key);
1545 1546
1546 // split header in "Basic" and [content] 1547 // split header in "Basic" and [content]
1547 credentials = strtok (authorization, " "); 1548 credentials = strtok(authorization, " ");
1548 if ((NULL == credentials) || (0 != strcmp ("Basic", credentials))) 1549 if ((NULL == credentials) || (0 != strcmp("Basic", credentials)))
1549 { 1550 {
1550 handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_CLIENT); 1551 handle->emsg = GNUNET_strdup(OIDC_ERROR_KEY_INVALID_CLIENT);
1551 handle->response_code = MHD_HTTP_UNAUTHORIZED; 1552 handle->response_code = MHD_HTTP_UNAUTHORIZED;
1552 return GNUNET_SYSERR; 1553 return GNUNET_SYSERR;
1553 } 1554 }
1554 credentials = strtok (NULL, " "); 1555 credentials = strtok(NULL, " ");
1555 if (NULL == credentials) 1556 if (NULL == credentials)
1556 { 1557 {
1557 handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_CLIENT); 1558 handle->emsg = GNUNET_strdup(OIDC_ERROR_KEY_INVALID_CLIENT);
1558 handle->response_code = MHD_HTTP_UNAUTHORIZED; 1559 handle->response_code = MHD_HTTP_UNAUTHORIZED;
1559 return GNUNET_SYSERR; 1560 return GNUNET_SYSERR;
1560 } 1561 }
1561 GNUNET_STRINGS_base64_decode (credentials, 1562 GNUNET_STRINGS_base64_decode(credentials,
1562 strlen (credentials), 1563 strlen(credentials),
1563 (void **) &basic_authorization); 1564 (void **)&basic_authorization);
1564 1565
1565 if (NULL == basic_authorization) 1566 if (NULL == basic_authorization)
1566 { 1567 {
1567 handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_CLIENT); 1568 handle->emsg = GNUNET_strdup(OIDC_ERROR_KEY_INVALID_CLIENT);
1568 handle->response_code = MHD_HTTP_UNAUTHORIZED; 1569 handle->response_code = MHD_HTTP_UNAUTHORIZED;
1569 return GNUNET_SYSERR; 1570 return GNUNET_SYSERR;
1570 } 1571 }
1571 client_id = strtok (basic_authorization, ":"); 1572 client_id = strtok(basic_authorization, ":");
1572 if (NULL == client_id) 1573 if (NULL == client_id)
1573 { 1574 {
1574 GNUNET_free_non_null (basic_authorization); 1575 GNUNET_free_non_null(basic_authorization);
1575 handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_CLIENT); 1576 handle->emsg = GNUNET_strdup(OIDC_ERROR_KEY_INVALID_CLIENT);
1576 handle->response_code = MHD_HTTP_UNAUTHORIZED; 1577 handle->response_code = MHD_HTTP_UNAUTHORIZED;
1577 return GNUNET_SYSERR; 1578 return GNUNET_SYSERR;
1578 } 1579 }
1579 pass = strtok (NULL, ":"); 1580 pass = strtok(NULL, ":");
1580 if (NULL == pass) 1581 if (NULL == pass)
1581 { 1582 {
1582 GNUNET_free_non_null (basic_authorization); 1583 GNUNET_free_non_null(basic_authorization);
1583 handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_CLIENT); 1584 handle->emsg = GNUNET_strdup(OIDC_ERROR_KEY_INVALID_CLIENT);
1584 handle->response_code = MHD_HTTP_UNAUTHORIZED;
1585 return GNUNET_SYSERR;
1586 }
1587
1588 // check client password
1589 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (cfg,
1590 "reclaim-rest-plugin",
1591 "OIDC_CLIENT_SECRET",
1592 &expected_pass))
1593 {
1594 if (0 != strcmp (expected_pass, pass))
1595 {
1596 GNUNET_free_non_null (basic_authorization);
1597 GNUNET_free (expected_pass);
1598 handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_CLIENT);
1599 handle->response_code = MHD_HTTP_UNAUTHORIZED; 1585 handle->response_code = MHD_HTTP_UNAUTHORIZED;
1600 return GNUNET_SYSERR; 1586 return GNUNET_SYSERR;
1601 } 1587 }
1602 GNUNET_free (expected_pass); 1588
1603 } 1589 // check client password
1590 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string(cfg,
1591 "reclaim-rest-plugin",
1592 "OIDC_CLIENT_SECRET",
1593 &expected_pass))
1594 {
1595 if (0 != strcmp(expected_pass, pass))
1596 {
1597 GNUNET_free_non_null(basic_authorization);
1598 GNUNET_free(expected_pass);
1599 handle->emsg = GNUNET_strdup(OIDC_ERROR_KEY_INVALID_CLIENT);
1600 handle->response_code = MHD_HTTP_UNAUTHORIZED;
1601 return GNUNET_SYSERR;
1602 }
1603 GNUNET_free(expected_pass);
1604 }
1604 else 1605 else
1605 { 1606 {
1606 GNUNET_free_non_null (basic_authorization); 1607 GNUNET_free_non_null(basic_authorization);
1607 handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_SERVER_ERROR); 1608 handle->emsg = GNUNET_strdup(OIDC_ERROR_KEY_SERVER_ERROR);
1608 handle->edesc = GNUNET_strdup ("gnunet configuration failed"); 1609 handle->edesc = GNUNET_strdup("gnunet configuration failed");
1609 handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR; 1610 handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
1610 return GNUNET_SYSERR; 1611 return GNUNET_SYSERR;
1611 } 1612 }
1612 1613
1613 // check client_id 1614 // check client_id
1614 for (handle->ego_entry = handle->ego_head; NULL != handle->ego_entry; 1615 for (handle->ego_entry = handle->ego_head; NULL != handle->ego_entry;
1615 handle->ego_entry = handle->ego_entry->next) 1616 handle->ego_entry = handle->ego_entry->next)
1616 { 1617 {
1617 if (0 == strcmp (handle->ego_entry->keystring, client_id)) 1618 if (0 == strcmp(handle->ego_entry->keystring, client_id))
1618 break; 1619 break;
1619 } 1620 }
1620 if (NULL == handle->ego_entry) 1621 if (NULL == handle->ego_entry)
1621 { 1622 {
1622 GNUNET_free_non_null (basic_authorization); 1623 GNUNET_free_non_null(basic_authorization);
1623 handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_CLIENT); 1624 handle->emsg = GNUNET_strdup(OIDC_ERROR_KEY_INVALID_CLIENT);
1624 handle->response_code = MHD_HTTP_UNAUTHORIZED; 1625 handle->response_code = MHD_HTTP_UNAUTHORIZED;
1625 return GNUNET_SYSERR; 1626 return GNUNET_SYSERR;
1626 } 1627 }
1627 GNUNET_STRINGS_string_to_data (client_id, 1628 GNUNET_STRINGS_string_to_data(client_id,
1628 strlen (client_id), 1629 strlen(client_id),
1629 cid, 1630 cid,
1630 sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)); 1631 sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey));
1631 1632
1632 GNUNET_free (basic_authorization); 1633 GNUNET_free(basic_authorization);
1633 return GNUNET_OK; 1634 return GNUNET_OK;
1634} 1635}
1635 1636
1636const struct EgoEntry * 1637const struct EgoEntry *
1637find_ego (struct RequestHandle *handle, 1638find_ego(struct RequestHandle *handle,
1638 struct GNUNET_CRYPTO_EcdsaPublicKey *test_key) 1639 struct GNUNET_CRYPTO_EcdsaPublicKey *test_key)
1639{ 1640{
1640 struct EgoEntry *ego_entry; 1641 struct EgoEntry *ego_entry;
1641 struct GNUNET_CRYPTO_EcdsaPublicKey pub_key; 1642 struct GNUNET_CRYPTO_EcdsaPublicKey pub_key;
1642 1643
1643 for (ego_entry = handle->ego_head; NULL != ego_entry; 1644 for (ego_entry = handle->ego_head; NULL != ego_entry;
1644 ego_entry = ego_entry->next) 1645 ego_entry = ego_entry->next)
1645 { 1646 {
1646 GNUNET_IDENTITY_ego_get_public_key (ego_entry->ego, &pub_key); 1647 GNUNET_IDENTITY_ego_get_public_key(ego_entry->ego, &pub_key);
1647 if (0 == GNUNET_memcmp (&pub_key, test_key)) 1648 if (0 == GNUNET_memcmp(&pub_key, test_key))
1648 return ego_entry; 1649 return ego_entry;
1649 } 1650 }
1650 return NULL; 1651 return NULL;
1651} 1652}
1652 1653
1653static void 1654static void
1654persist_access_token (const struct RequestHandle *handle, 1655persist_access_token(const struct RequestHandle *handle,
1655 const char *access_token, 1656 const char *access_token,
1656 const struct GNUNET_RECLAIM_Ticket *ticket) 1657 const struct GNUNET_RECLAIM_Ticket *ticket)
1657{ 1658{
1658 struct GNUNET_HashCode hc; 1659 struct GNUNET_HashCode hc;
1659 struct GNUNET_RECLAIM_Ticket *ticketbuf; 1660 struct GNUNET_RECLAIM_Ticket *ticketbuf;
1660 1661
1661 GNUNET_CRYPTO_hash (access_token, strlen (access_token), &hc); 1662 GNUNET_CRYPTO_hash(access_token, strlen(access_token), &hc);
1662 ticketbuf = GNUNET_new (struct GNUNET_RECLAIM_Ticket); 1663 ticketbuf = GNUNET_new(struct GNUNET_RECLAIM_Ticket);
1663 *ticketbuf = *ticket; 1664 *ticketbuf = *ticket;
1664 GNUNET_assert (GNUNET_SYSERR != 1665 GNUNET_assert(GNUNET_SYSERR !=
1665 GNUNET_CONTAINER_multihashmap_put ( 1666 GNUNET_CONTAINER_multihashmap_put(
1666 OIDC_access_token_map, 1667 OIDC_access_token_map,
1667 &hc, 1668 &hc,
1668 ticketbuf, 1669 ticketbuf,
1669 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); 1670 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
1670} 1671}
1671 1672
1672/** 1673/**
@@ -1677,9 +1678,9 @@ persist_access_token (const struct RequestHandle *handle,
1677 * @param cls the RequestHandle 1678 * @param cls the RequestHandle
1678 */ 1679 */
1679static void 1680static void
1680token_endpoint (struct GNUNET_REST_RequestHandle *con_handle, 1681token_endpoint(struct GNUNET_REST_RequestHandle *con_handle,
1681 const char *url, 1682 const char *url,
1682 void *cls) 1683 void *cls)
1683{ 1684{
1684 struct RequestHandle *handle = cls; 1685 struct RequestHandle *handle = cls;
1685 const struct EgoEntry *ego_entry; 1686 const struct EgoEntry *ego_entry;
@@ -1698,16 +1699,17 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle,
1698 char *jwt_secret; 1699 char *jwt_secret;
1699 char *nonce; 1700 char *nonce;
1700 char *code_verifier; 1701 char *code_verifier;
1702
1701 /* 1703 /*
1702 * Check Authorization 1704 * Check Authorization
1703 */ 1705 */
1704 if (GNUNET_SYSERR == check_authorization (handle, &cid)) 1706 if (GNUNET_SYSERR == check_authorization(handle, &cid))
1705 { 1707 {
1706 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1708 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
1707 "OIDC authorization for token endpoint failed\n"); 1709 "OIDC authorization for token endpoint failed\n");
1708 GNUNET_SCHEDULER_add_now (&do_error, handle); 1710 GNUNET_SCHEDULER_add_now(&do_error, handle);
1709 return; 1711 return;
1710 } 1712 }
1711 1713
1712 /* 1714 /*
1713 * Check parameter 1715 * Check parameter
@@ -1715,148 +1717,148 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle,
1715 1717
1716 // TODO Do not allow multiple equal parameter names 1718 // TODO Do not allow multiple equal parameter names
1717 // REQUIRED grant_type 1719 // REQUIRED grant_type
1718 GNUNET_CRYPTO_hash (OIDC_GRANT_TYPE_KEY, 1720 GNUNET_CRYPTO_hash(OIDC_GRANT_TYPE_KEY,
1719 strlen (OIDC_GRANT_TYPE_KEY), 1721 strlen(OIDC_GRANT_TYPE_KEY),
1720 &cache_key); 1722 &cache_key);
1721 grant_type = get_url_parameter_copy (handle, OIDC_GRANT_TYPE_KEY); 1723 grant_type = get_url_parameter_copy(handle, OIDC_GRANT_TYPE_KEY);
1722 if (NULL == grant_type) 1724 if (NULL == grant_type)
1723 { 1725 {
1724 handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_REQUEST); 1726 handle->emsg = GNUNET_strdup(OIDC_ERROR_KEY_INVALID_REQUEST);
1725 handle->edesc = GNUNET_strdup ("missing parameter grant_type"); 1727 handle->edesc = GNUNET_strdup("missing parameter grant_type");
1726 handle->response_code = MHD_HTTP_BAD_REQUEST; 1728 handle->response_code = MHD_HTTP_BAD_REQUEST;
1727 GNUNET_SCHEDULER_add_now (&do_error, handle); 1729 GNUNET_SCHEDULER_add_now(&do_error, handle);
1728 return; 1730 return;
1729 } 1731 }
1730 1732
1731 // Check parameter grant_type == "authorization_code" 1733 // Check parameter grant_type == "authorization_code"
1732 if (0 != strcmp (OIDC_GRANT_TYPE_VALUE, grant_type)) 1734 if (0 != strcmp(OIDC_GRANT_TYPE_VALUE, grant_type))
1733 { 1735 {
1734 handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_UNSUPPORTED_GRANT_TYPE); 1736 handle->emsg = GNUNET_strdup(OIDC_ERROR_KEY_UNSUPPORTED_GRANT_TYPE);
1735 handle->response_code = MHD_HTTP_BAD_REQUEST; 1737 handle->response_code = MHD_HTTP_BAD_REQUEST;
1736 GNUNET_free (grant_type); 1738 GNUNET_free(grant_type);
1737 GNUNET_SCHEDULER_add_now (&do_error, handle); 1739 GNUNET_SCHEDULER_add_now(&do_error, handle);
1738 return; 1740 return;
1739 } 1741 }
1740 GNUNET_free (grant_type); 1742 GNUNET_free(grant_type);
1741 // REQUIRED code 1743 // REQUIRED code
1742 code = get_url_parameter_copy (handle, OIDC_CODE_KEY); 1744 code = get_url_parameter_copy(handle, OIDC_CODE_KEY);
1743 if (NULL == code) 1745 if (NULL == code)
1744 { 1746 {
1745 handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_REQUEST); 1747 handle->emsg = GNUNET_strdup(OIDC_ERROR_KEY_INVALID_REQUEST);
1746 handle->edesc = GNUNET_strdup ("missing parameter code"); 1748 handle->edesc = GNUNET_strdup("missing parameter code");
1747 handle->response_code = MHD_HTTP_BAD_REQUEST; 1749 handle->response_code = MHD_HTTP_BAD_REQUEST;
1748 GNUNET_SCHEDULER_add_now (&do_error, handle); 1750 GNUNET_SCHEDULER_add_now(&do_error, handle);
1749 return; 1751 return;
1750 } 1752 }
1751 ego_entry = find_ego (handle, &cid); 1753 ego_entry = find_ego(handle, &cid);
1752 if (NULL == ego_entry) 1754 if (NULL == ego_entry)
1753 { 1755 {
1754 handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_REQUEST); 1756 handle->emsg = GNUNET_strdup(OIDC_ERROR_KEY_INVALID_REQUEST);
1755 handle->edesc = GNUNET_strdup ("Unknown client"); 1757 handle->edesc = GNUNET_strdup("Unknown client");
1756 handle->response_code = MHD_HTTP_BAD_REQUEST; 1758 handle->response_code = MHD_HTTP_BAD_REQUEST;
1757 GNUNET_free (code); 1759 GNUNET_free(code);
1758 GNUNET_SCHEDULER_add_now (&do_error, handle); 1760 GNUNET_SCHEDULER_add_now(&do_error, handle);
1759 return; 1761 return;
1760 } 1762 }
1761 privkey = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); 1763 privkey = GNUNET_IDENTITY_ego_get_private_key(ego_entry->ego);
1762 1764
1763 // REQUIRED code verifier 1765 // REQUIRED code verifier
1764 code_verifier = get_url_parameter_copy (handle, OIDC_CODE_VERIFIER_KEY); 1766 code_verifier = get_url_parameter_copy(handle, OIDC_CODE_VERIFIER_KEY);
1765 if (NULL == code_verifier) 1767 if (NULL == code_verifier)
1766 { 1768 {
1767 handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_REQUEST); 1769 handle->emsg = GNUNET_strdup(OIDC_ERROR_KEY_INVALID_REQUEST);
1768 handle->edesc = GNUNET_strdup ("missing parameter code_verifier"); 1770 handle->edesc = GNUNET_strdup("missing parameter code_verifier");
1769 handle->response_code = MHD_HTTP_BAD_REQUEST; 1771 handle->response_code = MHD_HTTP_BAD_REQUEST;
1770 GNUNET_SCHEDULER_add_now (&do_error, handle); 1772 GNUNET_SCHEDULER_add_now(&do_error, handle);
1771 return; 1773 return;
1772 } 1774 }
1773 1775
1774 // decode code 1776 // decode code
1775 if (GNUNET_OK != OIDC_parse_authz_code (privkey, code, code_verifier, &ticket, &cl, &nonce)) 1777 if (GNUNET_OK != OIDC_parse_authz_code(privkey, code, code_verifier, &ticket, &cl, &nonce))
1776 { 1778 {
1777 handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_REQUEST); 1779 handle->emsg = GNUNET_strdup(OIDC_ERROR_KEY_INVALID_REQUEST);
1778 handle->edesc = GNUNET_strdup ("invalid code"); 1780 handle->edesc = GNUNET_strdup("invalid code");
1779 handle->response_code = MHD_HTTP_BAD_REQUEST; 1781 handle->response_code = MHD_HTTP_BAD_REQUEST;
1780 GNUNET_free (code); 1782 GNUNET_free(code);
1781 GNUNET_SCHEDULER_add_now (&do_error, handle); 1783 GNUNET_SCHEDULER_add_now(&do_error, handle);
1782 return; 1784 return;
1783 } 1785 }
1784 GNUNET_free (code); 1786 GNUNET_free(code);
1785 1787
1786 // create jwt 1788 // create jwt
1787 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_time (cfg, 1789 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_time(cfg,
1788 "reclaim-rest-plugin", 1790 "reclaim-rest-plugin",
1789 "expiration_time", 1791 "expiration_time",
1790 &expiration_time)) 1792 &expiration_time))
1791 { 1793 {
1792 handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_SERVER_ERROR); 1794 handle->emsg = GNUNET_strdup(OIDC_ERROR_KEY_SERVER_ERROR);
1793 handle->edesc = GNUNET_strdup ("gnunet configuration failed"); 1795 handle->edesc = GNUNET_strdup("gnunet configuration failed");
1794 handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR; 1796 handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
1795 GNUNET_SCHEDULER_add_now (&do_error, handle); 1797 GNUNET_SCHEDULER_add_now(&do_error, handle);
1796 return; 1798 return;
1797 } 1799 }
1798 1800
1799 1801
1800 // TODO OPTIONAL acr,amr,azp 1802 // TODO OPTIONAL acr,amr,azp
1801 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string (cfg, 1803 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string(cfg,
1802 "reclaim-rest-plugin", 1804 "reclaim-rest-plugin",
1803 "jwt_secret", 1805 "jwt_secret",
1804 &jwt_secret)) 1806 &jwt_secret))
1805 { 1807 {
1806 handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_REQUEST); 1808 handle->emsg = GNUNET_strdup(OIDC_ERROR_KEY_INVALID_REQUEST);
1807 handle->edesc = GNUNET_strdup ("No signing secret configured!"); 1809 handle->edesc = GNUNET_strdup("No signing secret configured!");
1808 handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR; 1810 handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
1809 GNUNET_SCHEDULER_add_now (&do_error, handle); 1811 GNUNET_SCHEDULER_add_now(&do_error, handle);
1810 return; 1812 return;
1811 } 1813 }
1812 id_token = OIDC_id_token_new (&ticket.audience, 1814 id_token = OIDC_id_token_new(&ticket.audience,
1813 &ticket.identity, 1815 &ticket.identity,
1814 cl, 1816 cl,
1815 &expiration_time, 1817 &expiration_time,
1816 (NULL != nonce) ? nonce : NULL, 1818 (NULL != nonce) ? nonce : NULL,
1817 jwt_secret); 1819 jwt_secret);
1818 access_token = OIDC_access_token_new (); 1820 access_token = OIDC_access_token_new();
1819 OIDC_build_token_response (access_token, 1821 OIDC_build_token_response(access_token,
1820 id_token, 1822 id_token,
1821 &expiration_time, 1823 &expiration_time,
1822 &json_response); 1824 &json_response);
1823 1825
1824 persist_access_token (handle, access_token, &ticket); 1826 persist_access_token(handle, access_token, &ticket);
1825 resp = GNUNET_REST_create_response (json_response); 1827 resp = GNUNET_REST_create_response(json_response);
1826 MHD_add_response_header (resp, "Cache-Control", "no-store"); 1828 MHD_add_response_header(resp, "Cache-Control", "no-store");
1827 MHD_add_response_header (resp, "Pragma", "no-cache"); 1829 MHD_add_response_header(resp, "Pragma", "no-cache");
1828 MHD_add_response_header (resp, "Content-Type", "application/json"); 1830 MHD_add_response_header(resp, "Content-Type", "application/json");
1829 handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); 1831 handle->proc(handle->proc_cls, resp, MHD_HTTP_OK);
1830 GNUNET_RECLAIM_ATTRIBUTE_list_destroy (cl); 1832 GNUNET_RECLAIM_ATTRIBUTE_list_destroy(cl);
1831 GNUNET_free (access_token); 1833 GNUNET_free(access_token);
1832 GNUNET_free (json_response); 1834 GNUNET_free(json_response);
1833 GNUNET_free (id_token); 1835 GNUNET_free(id_token);
1834 GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle); 1836 GNUNET_SCHEDULER_add_now(&cleanup_handle_delayed, handle);
1835} 1837}
1836 1838
1837/** 1839/**
1838 * Collects claims and stores them in handle 1840 * Collects claims and stores them in handle
1839 */ 1841 */
1840static void 1842static void
1841consume_ticket (void *cls, 1843consume_ticket(void *cls,
1842 const struct GNUNET_CRYPTO_EcdsaPublicKey *identity, 1844 const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
1843 const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr) 1845 const struct GNUNET_RECLAIM_ATTRIBUTE_Claim *attr)
1844{ 1846{
1845 struct RequestHandle *handle = cls; 1847 struct RequestHandle *handle = cls;
1846 char *tmp_value; 1848 char *tmp_value;
1847 json_t *value; 1849 json_t *value;
1848 1850
1849 if (NULL == identity) 1851 if (NULL == identity)
1850 { 1852 {
1851 GNUNET_SCHEDULER_add_now (&return_userinfo_response, handle); 1853 GNUNET_SCHEDULER_add_now(&return_userinfo_response, handle);
1852 return; 1854 return;
1853 } 1855 }
1854 tmp_value = GNUNET_RECLAIM_ATTRIBUTE_value_to_string (attr->type, 1856 tmp_value = GNUNET_RECLAIM_ATTRIBUTE_value_to_string(attr->type,
1855 attr->data, 1857 attr->data,
1856 attr->data_size); 1858 attr->data_size);
1857 value = json_string (tmp_value); 1859 value = json_string(tmp_value);
1858 json_object_set_new (handle->oidc->response, attr->name, value); 1860 json_object_set_new(handle->oidc->response, attr->name, value);
1859 GNUNET_free (tmp_value); 1861 GNUNET_free(tmp_value);
1860} 1862}
1861 1863
1862/** 1864/**
@@ -1867,9 +1869,9 @@ consume_ticket (void *cls,
1867 * @param cls the RequestHandle 1869 * @param cls the RequestHandle
1868 */ 1870 */
1869static void 1871static void
1870userinfo_endpoint (struct GNUNET_REST_RequestHandle *con_handle, 1872userinfo_endpoint(struct GNUNET_REST_RequestHandle *con_handle,
1871 const char *url, 1873 const char *url,
1872 void *cls) 1874 void *cls)
1873{ 1875{
1874 // TODO expiration time 1876 // TODO expiration time
1875 struct RequestHandle *handle = cls; 1877 struct RequestHandle *handle = cls;
@@ -1882,87 +1884,87 @@ userinfo_endpoint (struct GNUNET_REST_RequestHandle *con_handle,
1882 const struct EgoEntry *ego_entry; 1884 const struct EgoEntry *ego_entry;
1883 const struct GNUNET_CRYPTO_EcdsaPrivateKey *privkey; 1885 const struct GNUNET_CRYPTO_EcdsaPrivateKey *privkey;
1884 1886
1885 GNUNET_CRYPTO_hash (OIDC_AUTHORIZATION_HEADER_KEY, 1887 GNUNET_CRYPTO_hash(OIDC_AUTHORIZATION_HEADER_KEY,
1886 strlen (OIDC_AUTHORIZATION_HEADER_KEY), 1888 strlen(OIDC_AUTHORIZATION_HEADER_KEY),
1887 &cache_key); 1889 &cache_key);
1888 if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle 1890 if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains(handle->rest_handle
1889 ->header_param_map, 1891 ->header_param_map,
1890 &cache_key)) 1892 &cache_key))
1891 { 1893 {
1892 handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_TOKEN); 1894 handle->emsg = GNUNET_strdup(OIDC_ERROR_KEY_INVALID_TOKEN);
1893 handle->edesc = GNUNET_strdup ("No Access Token"); 1895 handle->edesc = GNUNET_strdup("No Access Token");
1894 handle->response_code = MHD_HTTP_UNAUTHORIZED; 1896 handle->response_code = MHD_HTTP_UNAUTHORIZED;
1895 GNUNET_SCHEDULER_add_now (&do_userinfo_error, handle); 1897 GNUNET_SCHEDULER_add_now(&do_userinfo_error, handle);
1896 return; 1898 return;
1897 } 1899 }
1898 authorization = 1900 authorization =
1899 GNUNET_CONTAINER_multihashmap_get (handle->rest_handle->header_param_map, 1901 GNUNET_CONTAINER_multihashmap_get(handle->rest_handle->header_param_map,
1900 &cache_key); 1902 &cache_key);
1901 1903
1902 // split header in "Bearer" and access_token 1904 // split header in "Bearer" and access_token
1903 authorization = GNUNET_strdup (authorization); 1905 authorization = GNUNET_strdup(authorization);
1904 authorization_type = strtok (authorization, delimiter); 1906 authorization_type = strtok(authorization, delimiter);
1905 if ((NULL == authorization_type) || 1907 if ((NULL == authorization_type) ||
1906 (0 != strcmp ("Bearer", authorization_type))) 1908 (0 != strcmp("Bearer", authorization_type)))
1907 { 1909 {
1908 handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_TOKEN); 1910 handle->emsg = GNUNET_strdup(OIDC_ERROR_KEY_INVALID_TOKEN);
1909 handle->edesc = GNUNET_strdup ("No Access Token"); 1911 handle->edesc = GNUNET_strdup("No Access Token");
1910 handle->response_code = MHD_HTTP_UNAUTHORIZED; 1912 handle->response_code = MHD_HTTP_UNAUTHORIZED;
1911 GNUNET_SCHEDULER_add_now (&do_userinfo_error, handle); 1913 GNUNET_SCHEDULER_add_now(&do_userinfo_error, handle);
1912 GNUNET_free (authorization); 1914 GNUNET_free(authorization);
1913 return; 1915 return;
1914 } 1916 }
1915 authorization_access_token = strtok (NULL, delimiter); 1917 authorization_access_token = strtok(NULL, delimiter);
1916 if (NULL == authorization_access_token) 1918 if (NULL == authorization_access_token)
1917 { 1919 {
1918 handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_TOKEN); 1920 handle->emsg = GNUNET_strdup(OIDC_ERROR_KEY_INVALID_TOKEN);
1919 handle->edesc = GNUNET_strdup ("Access token missing"); 1921 handle->edesc = GNUNET_strdup("Access token missing");
1920 handle->response_code = MHD_HTTP_UNAUTHORIZED; 1922 handle->response_code = MHD_HTTP_UNAUTHORIZED;
1921 GNUNET_SCHEDULER_add_now (&do_userinfo_error, handle); 1923 GNUNET_SCHEDULER_add_now(&do_userinfo_error, handle);
1922 GNUNET_free (authorization); 1924 GNUNET_free(authorization);
1923 return; 1925 return;
1924 } 1926 }
1925 1927
1926 GNUNET_CRYPTO_hash (authorization_access_token, 1928 GNUNET_CRYPTO_hash(authorization_access_token,
1927 strlen (authorization_access_token), 1929 strlen(authorization_access_token),
1928 &cache_key); 1930 &cache_key);
1929 if (GNUNET_NO == 1931 if (GNUNET_NO ==
1930 GNUNET_CONTAINER_multihashmap_contains (OIDC_access_token_map, 1932 GNUNET_CONTAINER_multihashmap_contains(OIDC_access_token_map,
1931 &cache_key)) 1933 &cache_key))
1932 { 1934 {
1933 handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_TOKEN); 1935 handle->emsg = GNUNET_strdup(OIDC_ERROR_KEY_INVALID_TOKEN);
1934 handle->edesc = GNUNET_strdup ("The access token expired"); 1936 handle->edesc = GNUNET_strdup("The access token expired");
1935 handle->response_code = MHD_HTTP_UNAUTHORIZED; 1937 handle->response_code = MHD_HTTP_UNAUTHORIZED;
1936 GNUNET_SCHEDULER_add_now (&do_userinfo_error, handle); 1938 GNUNET_SCHEDULER_add_now(&do_userinfo_error, handle);
1937 GNUNET_free (authorization); 1939 GNUNET_free(authorization);
1938 return; 1940 return;
1939 } 1941 }
1940 ticket = 1942 ticket =
1941 GNUNET_CONTAINER_multihashmap_get (OIDC_access_token_map, &cache_key); 1943 GNUNET_CONTAINER_multihashmap_get(OIDC_access_token_map, &cache_key);
1942 GNUNET_assert (NULL != ticket); 1944 GNUNET_assert(NULL != ticket);
1943 ego_entry = find_ego (handle, &ticket->audience); 1945 ego_entry = find_ego(handle, &ticket->audience);
1944 if (NULL == ego_entry) 1946 if (NULL == ego_entry)
1945 { 1947 {
1946 handle->emsg = GNUNET_strdup (OIDC_ERROR_KEY_INVALID_TOKEN); 1948 handle->emsg = GNUNET_strdup(OIDC_ERROR_KEY_INVALID_TOKEN);
1947 handle->edesc = GNUNET_strdup ("The access token expired"); 1949 handle->edesc = GNUNET_strdup("The access token expired");
1948 handle->response_code = MHD_HTTP_UNAUTHORIZED; 1950 handle->response_code = MHD_HTTP_UNAUTHORIZED;
1949 GNUNET_SCHEDULER_add_now (&do_userinfo_error, handle); 1951 GNUNET_SCHEDULER_add_now(&do_userinfo_error, handle);
1950 GNUNET_free (authorization); 1952 GNUNET_free(authorization);
1951 return; 1953 return;
1952 } 1954 }
1953 1955
1954 handle->idp = GNUNET_RECLAIM_connect (cfg); 1956 handle->idp = GNUNET_RECLAIM_connect(cfg);
1955 handle->oidc->response = json_object (); 1957 handle->oidc->response = json_object();
1956 json_object_set_new (handle->oidc->response, 1958 json_object_set_new(handle->oidc->response,
1957 "sub", 1959 "sub",
1958 json_string (ego_entry->keystring)); 1960 json_string(ego_entry->keystring));
1959 privkey = GNUNET_IDENTITY_ego_get_private_key (ego_entry->ego); 1961 privkey = GNUNET_IDENTITY_ego_get_private_key(ego_entry->ego);
1960 handle->idp_op = GNUNET_RECLAIM_ticket_consume (handle->idp, 1962 handle->idp_op = GNUNET_RECLAIM_ticket_consume(handle->idp,
1961 privkey, 1963 privkey,
1962 ticket, 1964 ticket,
1963 consume_ticket, 1965 consume_ticket,
1964 handle); 1966 handle);
1965 GNUNET_free (authorization); 1967 GNUNET_free(authorization);
1966} 1968}
1967 1969
1968 1970
@@ -1972,27 +1974,27 @@ userinfo_endpoint (struct GNUNET_REST_RequestHandle *con_handle,
1972 * @param handle the request handle 1974 * @param handle the request handle
1973 */ 1975 */
1974static void 1976static void
1975init_cont (struct RequestHandle *handle) 1977init_cont(struct RequestHandle *handle)
1976{ 1978{
1977 struct GNUNET_REST_RequestHandlerError err; 1979 struct GNUNET_REST_RequestHandlerError err;
1978 static const struct GNUNET_REST_RequestHandler handlers[] = 1980 static const struct GNUNET_REST_RequestHandler handlers[] =
1979 {{MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_AUTHORIZE, &authorize_endpoint}, 1981 { { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_AUTHORIZE, &authorize_endpoint },
1980 {MHD_HTTP_METHOD_POST, 1982 { MHD_HTTP_METHOD_POST,
1981 GNUNET_REST_API_NS_AUTHORIZE, 1983 GNUNET_REST_API_NS_AUTHORIZE,
1982 &authorize_endpoint}, // url-encoded 1984 &authorize_endpoint }, // url-encoded
1983 {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_LOGIN, &login_cont}, 1985 { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_LOGIN, &login_cont },
1984 {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_TOKEN, &token_endpoint}, 1986 { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_TOKEN, &token_endpoint },
1985 {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_USERINFO, &userinfo_endpoint}, 1987 { MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_USERINFO, &userinfo_endpoint },
1986 {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_USERINFO, &userinfo_endpoint}, 1988 { MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_USERINFO, &userinfo_endpoint },
1987 {MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_OIDC, &options_cont}, 1989 { MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_OIDC, &options_cont },
1988 GNUNET_REST_HANDLER_END}; 1990 GNUNET_REST_HANDLER_END };
1989 1991
1990 if (GNUNET_NO == 1992 if (GNUNET_NO ==
1991 GNUNET_REST_handle_request (handle->rest_handle, handlers, &err, handle)) 1993 GNUNET_REST_handle_request(handle->rest_handle, handlers, &err, handle))
1992 { 1994 {
1993 handle->response_code = err.error_code; 1995 handle->response_code = err.error_code;
1994 GNUNET_SCHEDULER_add_now (&do_error, handle); 1996 GNUNET_SCHEDULER_add_now(&do_error, handle);
1995 } 1997 }
1996} 1998}
1997 1999
1998/** 2000/**
@@ -2029,90 +2031,91 @@ init_cont (struct RequestHandle *handle)
2029 * must thus no longer be used 2031 * must thus no longer be used
2030 */ 2032 */
2031static void 2033static void
2032list_ego (void *cls, 2034list_ego(void *cls,
2033 struct GNUNET_IDENTITY_Ego *ego, 2035 struct GNUNET_IDENTITY_Ego *ego,
2034 void **ctx, 2036 void **ctx,
2035 const char *identifier) 2037 const char *identifier)
2036{ 2038{
2037 struct RequestHandle *handle = cls; 2039 struct RequestHandle *handle = cls;
2038 struct EgoEntry *ego_entry; 2040 struct EgoEntry *ego_entry;
2039 struct GNUNET_CRYPTO_EcdsaPublicKey pk; 2041 struct GNUNET_CRYPTO_EcdsaPublicKey pk;
2040 2042
2041 if ((NULL == ego) && (ID_REST_STATE_INIT == handle->state)) 2043 if ((NULL == ego) && (ID_REST_STATE_INIT == handle->state))
2042 { 2044 {
2043 handle->state = ID_REST_STATE_POST_INIT; 2045 handle->state = ID_REST_STATE_POST_INIT;
2044 init_cont (handle); 2046 init_cont(handle);
2045 return; 2047 return;
2046 } 2048 }
2047 GNUNET_assert (NULL != ego); 2049 GNUNET_assert(NULL != ego);
2048 if (ID_REST_STATE_INIT == handle->state) 2050 if (ID_REST_STATE_INIT == handle->state)
2049 2051
2050 { 2052 {
2051 ego_entry = GNUNET_new (struct EgoEntry); 2053 ego_entry = GNUNET_new(struct EgoEntry);
2052 GNUNET_IDENTITY_ego_get_public_key (ego, &pk); 2054 GNUNET_IDENTITY_ego_get_public_key(ego, &pk);
2053 ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk); 2055 ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string(&pk);
2054 ego_entry->ego = ego; 2056 ego_entry->ego = ego;
2055 ego_entry->identifier = GNUNET_strdup (identifier); 2057 ego_entry->identifier = GNUNET_strdup(identifier);
2056 GNUNET_CONTAINER_DLL_insert_tail (handle->ego_head, 2058 GNUNET_CONTAINER_DLL_insert_tail(handle->ego_head,
2057 handle->ego_tail, 2059 handle->ego_tail,
2058 ego_entry); 2060 ego_entry);
2059 return; 2061 return;
2060 } 2062 }
2061 /* Ego renamed or added */ 2063 /* Ego renamed or added */
2062 if (identifier != NULL) 2064 if (identifier != NULL)
2063 {
2064 for (ego_entry = handle->ego_head; NULL != ego_entry;
2065 ego_entry = ego_entry->next)
2066 {
2067 if (ego_entry->ego == ego)
2068 {
2069 /* Rename */
2070 GNUNET_free (ego_entry->identifier);
2071 ego_entry->identifier = GNUNET_strdup (identifier);
2072 break;
2073 }
2074 }
2075 if (NULL == ego_entry)
2076 { 2065 {
2077 /* Add */ 2066 for (ego_entry = handle->ego_head; NULL != ego_entry;
2078 ego_entry = GNUNET_new (struct EgoEntry); 2067 ego_entry = ego_entry->next)
2079 GNUNET_IDENTITY_ego_get_public_key (ego, &pk); 2068 {
2080 ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk); 2069 if (ego_entry->ego == ego)
2081 ego_entry->ego = ego; 2070 {
2082 ego_entry->identifier = GNUNET_strdup (identifier); 2071 /* Rename */
2083 GNUNET_CONTAINER_DLL_insert_tail (handle->ego_head, 2072 GNUNET_free(ego_entry->identifier);
2084 handle->ego_tail, 2073 ego_entry->identifier = GNUNET_strdup(identifier);
2085 ego_entry); 2074 break;
2075 }
2076 }
2077 if (NULL == ego_entry)
2078 {
2079 /* Add */
2080 ego_entry = GNUNET_new(struct EgoEntry);
2081 GNUNET_IDENTITY_ego_get_public_key(ego, &pk);
2082 ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string(&pk);
2083 ego_entry->ego = ego;
2084 ego_entry->identifier = GNUNET_strdup(identifier);
2085 GNUNET_CONTAINER_DLL_insert_tail(handle->ego_head,
2086 handle->ego_tail,
2087 ego_entry);
2088 }
2086 } 2089 }
2087 }
2088 else 2090 else
2089 {
2090 /* Delete */
2091 for (ego_entry = handle->ego_head; NULL != ego_entry;
2092 ego_entry = ego_entry->next)
2093 { 2091 {
2094 if (ego_entry->ego == ego) 2092 /* Delete */
2095 break; 2093 for (ego_entry = handle->ego_head; NULL != ego_entry;
2094 ego_entry = ego_entry->next)
2095 {
2096 if (ego_entry->ego == ego)
2097 break;
2098 }
2099 if (NULL != ego_entry)
2100 GNUNET_CONTAINER_DLL_remove(handle->ego_head,
2101 handle->ego_tail,
2102 ego_entry);
2096 } 2103 }
2097 if (NULL != ego_entry)
2098 GNUNET_CONTAINER_DLL_remove (handle->ego_head,
2099 handle->ego_tail,
2100 ego_entry);
2101 }
2102} 2104}
2103 2105
2104static void 2106static void
2105rest_identity_process_request (struct GNUNET_REST_RequestHandle *rest_handle, 2107rest_identity_process_request(struct GNUNET_REST_RequestHandle *rest_handle,
2106 GNUNET_REST_ResultProcessor proc, 2108 GNUNET_REST_ResultProcessor proc,
2107 void *proc_cls) 2109 void *proc_cls)
2108{ 2110{
2109 struct RequestHandle *handle = GNUNET_new (struct RequestHandle); 2111 struct RequestHandle *handle = GNUNET_new(struct RequestHandle);
2110 handle->oidc = GNUNET_new (struct OIDC_Variables); 2112
2113 handle->oidc = GNUNET_new(struct OIDC_Variables);
2111 if (NULL == OIDC_cookie_jar_map) 2114 if (NULL == OIDC_cookie_jar_map)
2112 OIDC_cookie_jar_map = GNUNET_CONTAINER_multihashmap_create (10, GNUNET_NO); 2115 OIDC_cookie_jar_map = GNUNET_CONTAINER_multihashmap_create(10, GNUNET_NO);
2113 if (NULL == OIDC_access_token_map) 2116 if (NULL == OIDC_access_token_map)
2114 OIDC_access_token_map = 2117 OIDC_access_token_map =
2115 GNUNET_CONTAINER_multihashmap_create (10, GNUNET_NO); 2118 GNUNET_CONTAINER_multihashmap_create(10, GNUNET_NO);
2116 handle->response_code = 0; 2119 handle->response_code = 0;
2117 handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL; 2120 handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL;
2118 handle->proc_cls = proc_cls; 2121 handle->proc_cls = proc_cls;
@@ -2120,16 +2123,16 @@ rest_identity_process_request (struct GNUNET_REST_RequestHandle *rest_handle,
2120 handle->state = ID_REST_STATE_INIT; 2123 handle->state = ID_REST_STATE_INIT;
2121 handle->rest_handle = rest_handle; 2124 handle->rest_handle = rest_handle;
2122 2125
2123 handle->url = GNUNET_strdup (rest_handle->url); 2126 handle->url = GNUNET_strdup(rest_handle->url);
2124 if (handle->url[strlen (handle->url) - 1] == '/') 2127 if (handle->url[strlen(handle->url) - 1] == '/')
2125 handle->url[strlen (handle->url) - 1] = '\0'; 2128 handle->url[strlen(handle->url) - 1] = '\0';
2126 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting...\n"); 2129 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Connecting...\n");
2127 handle->identity_handle = GNUNET_IDENTITY_connect (cfg, &list_ego, handle); 2130 handle->identity_handle = GNUNET_IDENTITY_connect(cfg, &list_ego, handle);
2128 handle->gns_handle = GNUNET_GNS_connect (cfg); 2131 handle->gns_handle = GNUNET_GNS_connect(cfg);
2129 handle->namestore_handle = GNUNET_NAMESTORE_connect (cfg); 2132 handle->namestore_handle = GNUNET_NAMESTORE_connect(cfg);
2130 handle->timeout_task = 2133 handle->timeout_task =
2131 GNUNET_SCHEDULER_add_delayed (handle->timeout, &do_timeout, handle); 2134 GNUNET_SCHEDULER_add_delayed(handle->timeout, &do_timeout, handle);
2132 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connected\n"); 2135 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Connected\n");
2133} 2136}
2134 2137
2135/** 2138/**
@@ -2139,7 +2142,7 @@ rest_identity_process_request (struct GNUNET_REST_RequestHandle *rest_handle,
2139 * @return NULL on error, otherwise the plugin context 2142 * @return NULL on error, otherwise the plugin context
2140 */ 2143 */
2141void * 2144void *
2142libgnunet_plugin_rest_openid_connect_init (void *cls) 2145libgnunet_plugin_rest_openid_connect_init(void *cls)
2143{ 2146{
2144 static struct Plugin plugin; 2147 static struct Plugin plugin;
2145 struct GNUNET_REST_Plugin *api; 2148 struct GNUNET_REST_Plugin *api;
@@ -2147,22 +2150,22 @@ libgnunet_plugin_rest_openid_connect_init (void *cls)
2147 cfg = cls; 2150 cfg = cls;
2148 if (NULL != plugin.cfg) 2151 if (NULL != plugin.cfg)
2149 return NULL; /* can only initialize once! */ 2152 return NULL; /* can only initialize once! */
2150 memset (&plugin, 0, sizeof (struct Plugin)); 2153 memset(&plugin, 0, sizeof(struct Plugin));
2151 plugin.cfg = cfg; 2154 plugin.cfg = cfg;
2152 api = GNUNET_new (struct GNUNET_REST_Plugin); 2155 api = GNUNET_new(struct GNUNET_REST_Plugin);
2153 api->cls = &plugin; 2156 api->cls = &plugin;
2154 api->name = GNUNET_REST_API_NS_OIDC; 2157 api->name = GNUNET_REST_API_NS_OIDC;
2155 api->process_request = &rest_identity_process_request; 2158 api->process_request = &rest_identity_process_request;
2156 GNUNET_asprintf (&allow_methods, 2159 GNUNET_asprintf(&allow_methods,
2157 "%s, %s, %s, %s, %s", 2160 "%s, %s, %s, %s, %s",
2158 MHD_HTTP_METHOD_GET, 2161 MHD_HTTP_METHOD_GET,
2159 MHD_HTTP_METHOD_POST, 2162 MHD_HTTP_METHOD_POST,
2160 MHD_HTTP_METHOD_PUT, 2163 MHD_HTTP_METHOD_PUT,
2161 MHD_HTTP_METHOD_DELETE, 2164 MHD_HTTP_METHOD_DELETE,
2162 MHD_HTTP_METHOD_OPTIONS); 2165 MHD_HTTP_METHOD_OPTIONS);
2163 2166
2164 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2167 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2165 _ ("OpenID Connect REST API initialized\n")); 2168 _("OpenID Connect REST API initialized\n"));
2166 return api; 2169 return api;
2167} 2170}
2168 2171
@@ -2174,33 +2177,34 @@ libgnunet_plugin_rest_openid_connect_init (void *cls)
2174 * @return always NULL 2177 * @return always NULL
2175 */ 2178 */
2176void * 2179void *
2177libgnunet_plugin_rest_openid_connect_done (void *cls) 2180libgnunet_plugin_rest_openid_connect_done(void *cls)
2178{ 2181{
2179 struct GNUNET_REST_Plugin *api = cls; 2182 struct GNUNET_REST_Plugin *api = cls;
2180 struct Plugin *plugin = api->cls; 2183 struct Plugin *plugin = api->cls;
2184
2181 plugin->cfg = NULL; 2185 plugin->cfg = NULL;
2182 2186
2183 struct GNUNET_CONTAINER_MultiHashMapIterator *hashmap_it; 2187 struct GNUNET_CONTAINER_MultiHashMapIterator *hashmap_it;
2184 void *value = NULL; 2188 void *value = NULL;
2185 hashmap_it = 2189 hashmap_it =
2186 GNUNET_CONTAINER_multihashmap_iterator_create (OIDC_cookie_jar_map); 2190 GNUNET_CONTAINER_multihashmap_iterator_create(OIDC_cookie_jar_map);
2187 while (GNUNET_YES == 2191 while (GNUNET_YES ==
2188 GNUNET_CONTAINER_multihashmap_iterator_next (hashmap_it, NULL, value)) 2192 GNUNET_CONTAINER_multihashmap_iterator_next(hashmap_it, NULL, value))
2189 GNUNET_free_non_null (value); 2193 GNUNET_free_non_null(value);
2190 GNUNET_CONTAINER_multihashmap_iterator_destroy (hashmap_it); 2194 GNUNET_CONTAINER_multihashmap_iterator_destroy(hashmap_it);
2191 GNUNET_CONTAINER_multihashmap_destroy (OIDC_cookie_jar_map); 2195 GNUNET_CONTAINER_multihashmap_destroy(OIDC_cookie_jar_map);
2192 2196
2193 hashmap_it = 2197 hashmap_it =
2194 GNUNET_CONTAINER_multihashmap_iterator_create (OIDC_access_token_map); 2198 GNUNET_CONTAINER_multihashmap_iterator_create(OIDC_access_token_map);
2195 while (GNUNET_YES == 2199 while (GNUNET_YES ==
2196 GNUNET_CONTAINER_multihashmap_iterator_next (hashmap_it, NULL, value)) 2200 GNUNET_CONTAINER_multihashmap_iterator_next(hashmap_it, NULL, value))
2197 GNUNET_free_non_null (value); 2201 GNUNET_free_non_null(value);
2198 GNUNET_CONTAINER_multihashmap_destroy (OIDC_access_token_map); 2202 GNUNET_CONTAINER_multihashmap_destroy(OIDC_access_token_map);
2199 GNUNET_CONTAINER_multihashmap_iterator_destroy (hashmap_it); 2203 GNUNET_CONTAINER_multihashmap_iterator_destroy(hashmap_it);
2200 GNUNET_free_non_null (allow_methods); 2204 GNUNET_free_non_null(allow_methods);
2201 GNUNET_free (api); 2205 GNUNET_free(api);
2202 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2206 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2203 "OpenID Connect REST plugin is finished\n"); 2207 "OpenID Connect REST plugin is finished\n");
2204 return NULL; 2208 return NULL;
2205} 2209}
2206 2210