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