aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSchanzenbach, Martin <martin.schanzenbach@aisec.fraunhofer.de>2018-07-22 21:26:47 +0200
committerSchanzenbach, Martin <martin.schanzenbach@aisec.fraunhofer.de>2018-07-22 21:26:47 +0200
commit0e3d3b63bf18148828e722fa1a29fc196f6f441d (patch)
tree46333b3cbf4976714c0d8c0d7383b86a42fc3d4a /src
parent96fdc9cacc176d6269e51dbd490de568c2254bb4 (diff)
downloadgnunet-0e3d3b63bf18148828e722fa1a29fc196f6f441d.tar.gz
gnunet-0e3d3b63bf18148828e722fa1a29fc196f6f441d.zip
towards secure redirects
Diffstat (limited to 'src')
-rw-r--r--src/reclaim/plugin_rest_openid_connect.c124
1 files changed, 96 insertions, 28 deletions
diff --git a/src/reclaim/plugin_rest_openid_connect.c b/src/reclaim/plugin_rest_openid_connect.c
index 679d8f7d9..0f746f988 100644
--- a/src/reclaim/plugin_rest_openid_connect.c
+++ b/src/reclaim/plugin_rest_openid_connect.c
@@ -340,6 +340,16 @@ struct RequestHandle
340 struct GNUNET_REST_RequestHandle *rest_handle; 340 struct GNUNET_REST_RequestHandle *rest_handle;
341 341
342 /** 342 /**
343 * GNS handle
344 */
345 struct GNUNET_GNS_Handle *gns_handle;
346
347 /**
348 * GNS lookup op
349 */
350 struct GNUNET_GNS_LookupRequest *gns_op;
351
352 /**
343 * Handle to NAMESTORE 353 * Handle to NAMESTORE
344 */ 354 */
345 struct GNUNET_NAMESTORE_Handle *namestore_handle; 355 struct GNUNET_NAMESTORE_Handle *namestore_handle;
@@ -415,6 +425,16 @@ struct RequestHandle
415 char *tld; 425 char *tld;
416 426
417 /** 427 /**
428 * The redirect prefix
429 */
430 char *redirect_prefix;
431
432 /**
433 * The redirect suffix
434 */
435 char *redirect_suffix;
436
437 /**
418 * Error response message 438 * Error response message
419 */ 439 */
420 char *emsg; 440 char *emsg;
@@ -465,10 +485,19 @@ cleanup_handle (struct RequestHandle *handle)
465 GNUNET_free (handle->url); 485 GNUNET_free (handle->url);
466 if (NULL != handle->tld) 486 if (NULL != handle->tld)
467 GNUNET_free (handle->tld); 487 GNUNET_free (handle->tld);
488 if (NULL != handle->redirect_prefix)
489 GNUNET_free (handle->redirect_prefix);
490 if (NULL != handle->redirect_suffix)
491 GNUNET_free (handle->redirect_suffix);
468 if (NULL != handle->emsg) 492 if (NULL != handle->emsg)
469 GNUNET_free (handle->emsg); 493 GNUNET_free (handle->emsg);
470 if (NULL != handle->edesc) 494 if (NULL != handle->edesc)
471 GNUNET_free (handle->edesc); 495 GNUNET_free (handle->edesc);
496 if (NULL != handle->gns_op)
497 GNUNET_GNS_lookup_cancel (handle->gns_op);
498 if (NULL != handle->gns_handle)
499 GNUNET_GNS_disconnect (handle->gns_handle);
500
472 if (NULL != handle->namestore_handle) 501 if (NULL != handle->namestore_handle)
473 GNUNET_NAMESTORE_disconnect (handle->namestore_handle); 502 GNUNET_NAMESTORE_disconnect (handle->namestore_handle);
474 if (NULL != handle->oidc) 503 if (NULL != handle->oidc)
@@ -812,7 +841,7 @@ parse_authz_code (const struct GNUNET_CRYPTO_EcdsaPublicKey *audience,
812 struct GNUNET_CRYPTO_EccSignaturePurpose *purpose; 841 struct GNUNET_CRYPTO_EccSignaturePurpose *purpose;
813 struct GNUNET_CRYPTO_EcdsaSignature signature; 842 struct GNUNET_CRYPTO_EcdsaSignature signature;
814 size_t signature_payload_len; 843 size_t signature_payload_len;
815 844
816 code_output = NULL; 845 code_output = NULL;
817 GNUNET_STRINGS_base64_decode (code, 846 GNUNET_STRINGS_base64_decode (code,
818 strlen(code), 847 strlen(code),
@@ -978,10 +1007,7 @@ get_client_name_result (void *cls,
978 char *redirect_uri; 1007 char *redirect_uri;
979 char *code_json_string; 1008 char *code_json_string;
980 char *code_base64_final_string; 1009 char *code_base64_final_string;
981 char *redirect_path; 1010
982 char *tmp;
983 char *tmp_prefix;
984 char *prefix;
985 ticket_str = GNUNET_STRINGS_data_to_string_alloc (&handle->ticket, 1011 ticket_str = GNUNET_STRINGS_data_to_string_alloc (&handle->ticket,
986 sizeof (struct GNUNET_RECLAIM_Ticket)); 1012 sizeof (struct GNUNET_RECLAIM_Ticket));
987 //TODO change if more attributes are needed (see max_age) 1013 //TODO change if more attributes are needed (see max_age)
@@ -989,33 +1015,25 @@ get_client_name_result (void *cls,
989 &handle->ticket, 1015 &handle->ticket,
990 handle->oidc->nonce); 1016 handle->oidc->nonce);
991 code_base64_final_string = base_64_encode(code_json_string); 1017 code_base64_final_string = base_64_encode(code_json_string);
992 tmp = GNUNET_strdup (handle->oidc->redirect_uri);
993 redirect_path = strtok (tmp, "/");
994 redirect_path = strtok (NULL, "/");
995 redirect_path = strtok (NULL, "/");
996 tmp_prefix = GNUNET_strdup (handle->oidc->redirect_uri);
997 prefix = strrchr (tmp_prefix,
998 (unsigned char) '.');
999 *prefix = '\0';
1000 GNUNET_asprintf (&redirect_uri, "%s.%s/%s?%s=%s&state=%s", 1018 GNUNET_asprintf (&redirect_uri, "%s.%s/%s?%s=%s&state=%s",
1001 tmp_prefix, 1019 handle->redirect_prefix,
1002 handle->tld, 1020 handle->tld,
1003 redirect_path, 1021 handle->redirect_suffix,
1004 handle->oidc->response_type, 1022 handle->oidc->response_type,
1005 code_base64_final_string, handle->oidc->state); 1023 code_base64_final_string, handle->oidc->state);
1006 resp = GNUNET_REST_create_response (""); 1024 resp = GNUNET_REST_create_response ("");
1007 MHD_add_response_header (resp, "Location", redirect_uri); 1025 MHD_add_response_header (resp, "Location", redirect_uri);
1008 handle->proc (handle->proc_cls, resp, MHD_HTTP_FOUND); 1026 handle->proc (handle->proc_cls, resp, MHD_HTTP_FOUND);
1009 GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle); 1027 GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle);
1010 GNUNET_free (tmp);
1011 GNUNET_free (tmp_prefix);
1012 GNUNET_free (redirect_uri); 1028 GNUNET_free (redirect_uri);
1013 GNUNET_free (ticket_str); 1029 GNUNET_free (ticket_str);
1014 GNUNET_free (code_json_string); 1030 GNUNET_free (code_json_string);
1015 GNUNET_free (code_base64_final_string); 1031 GNUNET_free (code_base64_final_string);
1016 return; 1032 return;
1033
1017} 1034}
1018 1035
1036
1019static void 1037static void
1020get_client_name_error (void *cls) 1038get_client_name_error (void *cls)
1021{ 1039{
@@ -1026,6 +1044,52 @@ get_client_name_error (void *cls)
1026 GNUNET_SCHEDULER_add_now (&do_redirect_error, handle); 1044 GNUNET_SCHEDULER_add_now (&do_redirect_error, handle);
1027} 1045}
1028 1046
1047
1048static void
1049lookup_redirect_uri_result (void *cls,
1050 uint32_t rd_count,
1051 const struct GNUNET_GNSRECORD_Data *rd)
1052{
1053 struct RequestHandle *handle = cls;
1054 char *tmp;
1055 char *tmp_key_str;
1056 char *pos;
1057 struct GNUNET_CRYPTO_EcdsaPublicKey redirect_zone;
1058
1059 handle->gns_op = NULL;
1060 if (1 != rd_count)
1061 {
1062 handle->emsg = GNUNET_strdup("server_error");
1063 handle->edesc = GNUNET_strdup("Server cannot generate ticket, redirect uri not found.");
1064 GNUNET_SCHEDULER_add_now (&do_redirect_error, handle);
1065 return;
1066 }
1067 tmp = GNUNET_strdup (rd->data);
1068 pos = strrchr (tmp,
1069 (unsigned char) '.');
1070 *pos = '\0';
1071 handle->redirect_prefix = GNUNET_strdup (tmp);
1072 tmp_key_str = pos + 1;
1073 pos = strchr (tmp_key_str,
1074 (unsigned char) '/');
1075 *pos = '\0';
1076 handle->redirect_suffix = GNUNET_strdup (pos + 1);
1077 GNUNET_free (tmp);
1078
1079 GNUNET_STRINGS_string_to_data (tmp_key_str,
1080 strlen (tmp_key_str),
1081 &redirect_zone,
1082 sizeof (redirect_zone));
1083
1084 GNUNET_NAMESTORE_zone_to_name (handle->namestore_handle,
1085 &handle->priv_key,
1086 &redirect_zone,
1087 &get_client_name_error,
1088 handle,
1089 &get_client_name_result,
1090 handle);
1091}
1092
1029/** 1093/**
1030 * Issues ticket and redirects to relying party with the authorization code as 1094 * Issues ticket and redirects to relying party with the authorization code as
1031 * parameter. Otherwise redirects with error 1095 * parameter. Otherwise redirects with error
@@ -1035,21 +1099,24 @@ oidc_ticket_issue_cb (void* cls,
1035 const struct GNUNET_RECLAIM_Ticket *ticket) 1099 const struct GNUNET_RECLAIM_Ticket *ticket)
1036{ 1100{
1037 struct RequestHandle *handle = cls; 1101 struct RequestHandle *handle = cls;
1102
1038 handle->idp_op = NULL; 1103 handle->idp_op = NULL;
1039 handle->ticket = *ticket; 1104 handle->ticket = *ticket;
1040 if (NULL != ticket) { 1105 if (NULL == ticket)
1041 GNUNET_NAMESTORE_zone_to_name (handle->namestore_handle, 1106 {
1042 &handle->priv_key, 1107 handle->emsg = GNUNET_strdup("server_error");
1043 &handle->oidc->client_pkey, 1108 handle->edesc = GNUNET_strdup("Server cannot generate ticket.");
1044 &get_client_name_error, 1109 GNUNET_SCHEDULER_add_now (&do_redirect_error, handle);
1045 handle,
1046 &get_client_name_result,
1047 handle);
1048 return; 1110 return;
1049 } 1111 }
1050 handle->emsg = GNUNET_strdup("server_error"); 1112 handle->gns_op = GNUNET_GNS_lookup (handle->gns_handle,
1051 handle->edesc = GNUNET_strdup("Server cannot generate ticket."); 1113 handle->oidc->redirect_uri,
1052 GNUNET_SCHEDULER_add_now (&do_redirect_error, handle); 1114 &handle->oidc->client_pkey,
1115 GNUNET_DNSPARSER_TYPE_TXT,
1116 GNUNET_GNS_LO_DEFAULT,
1117 &lookup_redirect_uri_result,
1118 handle);
1119
1053} 1120}
1054 1121
1055static void 1122static void
@@ -2148,6 +2215,7 @@ rest_identity_process_request(struct GNUNET_REST_RequestHandle *rest_handle,
2148 handle->identity_handle = GNUNET_IDENTITY_connect (cfg, 2215 handle->identity_handle = GNUNET_IDENTITY_connect (cfg,
2149 &list_ego, 2216 &list_ego,
2150 handle); 2217 handle);
2218 handle->gns_handle = GNUNET_GNS_connect (cfg);
2151 handle->namestore_handle = GNUNET_NAMESTORE_connect (cfg); 2219 handle->namestore_handle = GNUNET_NAMESTORE_connect (cfg);
2152 handle->timeout_task = 2220 handle->timeout_task =
2153 GNUNET_SCHEDULER_add_delayed (handle->timeout, 2221 GNUNET_SCHEDULER_add_delayed (handle->timeout,