diff options
author | Phil <phil.buschmann@tum.de> | 2017-12-07 13:03:56 +0000 |
---|---|---|
committer | Phil <phil.buschmann@tum.de> | 2017-12-07 13:23:16 +0000 |
commit | 68978a08e0d16b5b0e5a7e6f2ca1e625b3fd4e0f (patch) | |
tree | ce289b21cb54dd9740e39c2087f92c612a8098d0 /src | |
parent | cd0ff18525770f9f3578c90a2dc6938911c910df (diff) | |
download | gnunet-68978a08e0d16b5b0e5a7e6f2ca1e625b3fd4e0f.tar.gz gnunet-68978a08e0d16b5b0e5a7e6f2ca1e625b3fd4e0f.zip |
Refactored file
Diffstat (limited to 'src')
-rw-r--r-- | src/identity-provider/plugin_rest_identity_provider.c | 270 |
1 files changed, 156 insertions, 114 deletions
diff --git a/src/identity-provider/plugin_rest_identity_provider.c b/src/identity-provider/plugin_rest_identity_provider.c index 1bef87ace..d5309f9dd 100644 --- a/src/identity-provider/plugin_rest_identity_provider.c +++ b/src/identity-provider/plugin_rest_identity_provider.c | |||
@@ -70,7 +70,6 @@ | |||
70 | */ | 70 | */ |
71 | #define GNUNET_REST_API_NS_AUTHORIZE "/idp/authorize" | 71 | #define GNUNET_REST_API_NS_AUTHORIZE "/idp/authorize" |
72 | 72 | ||
73 | |||
74 | /** | 73 | /** |
75 | * Attribute key | 74 | * Attribute key |
76 | */ | 75 | */ |
@@ -97,6 +96,55 @@ | |||
97 | */ | 96 | */ |
98 | #define ID_REST_STATE_POST_INIT 1 | 97 | #define ID_REST_STATE_POST_INIT 1 |
99 | 98 | ||
99 | /** | ||
100 | * OIDC response_type key | ||
101 | */ | ||
102 | #define OIDC_RESPONSE_TYPE_KEY "response_type" | ||
103 | |||
104 | /** | ||
105 | * OIDC client_id key | ||
106 | */ | ||
107 | #define OIDC_CLIENT_ID_KEY "client_id" | ||
108 | |||
109 | /** | ||
110 | * OIDC scope key | ||
111 | */ | ||
112 | #define OIDC_SCOPE_KEY "scope" | ||
113 | |||
114 | /** | ||
115 | * OIDC redirect_uri key | ||
116 | */ | ||
117 | #define OIDC_REDIRECT_URI_KEY "redirect_uri" | ||
118 | |||
119 | /** | ||
120 | * OIDC state key | ||
121 | */ | ||
122 | #define OIDC_STATE_KEY "state" | ||
123 | |||
124 | /** | ||
125 | * OIDC nonce key | ||
126 | */ | ||
127 | #define OIDC_NONCE_KEY "nonce" | ||
128 | |||
129 | /** | ||
130 | * OIDC expected response_type while authorizing | ||
131 | */ | ||
132 | #define OIDC_EXPECTED_AUTHORIZATION_RESPONSE_TYPE "code" | ||
133 | |||
134 | /** | ||
135 | * OIDC expected scope part while authorizing | ||
136 | */ | ||
137 | #define OIDC_EXPECTED_AUTHORIZATION_SCOPE "openid" | ||
138 | |||
139 | |||
140 | /** | ||
141 | * OIDC ignored parameter array | ||
142 | */ | ||
143 | char* OIDC_ignored_parameter_array [] = | ||
144 | { | ||
145 | "display", "prompt", "max_age", "ui_locales", "response_mode", | ||
146 | "id_token_hint", "login_hint", "acr_values" | ||
147 | }; | ||
100 | 148 | ||
101 | /** | 149 | /** |
102 | * The configuration handle | 150 | * The configuration handle |
@@ -1030,88 +1078,120 @@ authorize_cont (struct GNUNET_REST_RequestHandle *con_handle, | |||
1030 | const char* url, | 1078 | const char* url, |
1031 | void *cls) | 1079 | void *cls) |
1032 | { | 1080 | { |
1081 | struct MHD_Response *resp; | ||
1082 | struct RequestHandle *handle = cls; | ||
1083 | char *response_type, *client_id, *scope, *redirect_uri, *state, *nonce; | ||
1033 | 1084 | ||
1034 | //TODO clean up method | 1085 | //TODO clean up method |
1035 | 1086 | ||
1087 | /** The Authorization Server MUST validate all the OAuth 2.0 parameters | ||
1088 | * according to the OAuth 2.0 specification. | ||
1089 | */ | ||
1090 | /** The Authorization Server MUST verify that all the REQUIRED parameters | ||
1091 | * are present and their usage conforms to this specification. | ||
1092 | */ | ||
1093 | /** | ||
1094 | * If the sub (subject) Claim is requested with a specific value for the | ||
1095 | * ID Token, the Authorization Server MUST only send a positive response | ||
1096 | * if the End-User identified by that sub value has an active session with | ||
1097 | * the Authorization Server or has been Authenticated as a result of the | ||
1098 | * request. The Authorization Server MUST NOT reply with an ID Token or | ||
1099 | * Access Token for a different user, even if they have an active session | ||
1100 | * with the Authorization Server. Such a request can be made either using | ||
1101 | * an id_token_hint parameter or by requesting a specific Claim Value as | ||
1102 | * described in Section 5.5.1, if the claims parameter is supported by | ||
1103 | * the implementation. | ||
1104 | */ | ||
1036 | 1105 | ||
1037 | // The Authorization Server MUST validate all the OAuth 2.0 parameters according to the OAuth 2.0 specification. | ||
1038 | // The Authorization Server MUST verify that all the REQUIRED parameters are present and their usage conforms to this specification. | ||
1039 | // If the sub (subject) Claim is requested with a specific value for the ID Token, the Authorization Server MUST only send a positive response if the End-User identified by that sub value has an active session with the Authorization Server or has been Authenticated as a result of the request. The Authorization Server MUST NOT reply with an ID Token or Access Token for a different user, even if they have an active session with the Authorization Server. Such a request can be made either using an id_token_hint parameter or by requesting a specific Claim Value as described in Section 5.5.1, if the claims parameter is supported by the implementation. | ||
1040 | 1106 | ||
1107 | int size=sizeof(OIDC_ignored_parameter_array)/sizeof(char *); | ||
1041 | 1108 | ||
1109 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Size %i = 8\n", size); | ||
1042 | 1110 | ||
1043 | struct MHD_Response *resp; | 1111 | struct GNUNET_HashCode cache_key; |
1044 | struct RequestHandle *handle = cls; | ||
1045 | 1112 | ||
1046 | /* | 1113 | GNUNET_CRYPTO_hash (OIDC_RESPONSE_TYPE_KEY, strlen (OIDC_RESPONSE_TYPE_KEY), |
1047 | * response_type 0 | 1114 | &cache_key); |
1048 | * client_id 1 | 1115 | if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle->url_param_map, |
1049 | * scope 2 | 1116 | &cache_key)) |
1050 | * redirect_uri 3 | 1117 | { |
1051 | * state 4 | 1118 | //TODO error |
1052 | * nonce 5 | ||
1053 | * display 6 | ||
1054 | * prompt 7 | ||
1055 | * max_age 8 | ||
1056 | * ui_locales 9 | ||
1057 | * response_mode 10 | ||
1058 | * id_token_hint 11 | ||
1059 | * login_hint 12 | ||
1060 | * acr_values 13 | ||
1061 | */ | ||
1062 | char* array[] = { "response_type", "client_id", "scope", "redirect_uri", | ||
1063 | "state", "nonce", "display", "prompt", "max_age", "ui_locales", | ||
1064 | "response_mode", "id_token_hint","login_hint", "acr_values" }; | ||
1065 | int array_size=14; | ||
1066 | int bool_array[array_size]; | ||
1067 | 1119 | ||
1068 | struct GNUNET_HashCode cache_key; | 1120 | } |
1121 | response_type = GNUNET_CONTAINER_multihashmap_get(handle->rest_handle->url_param_map, | ||
1122 | &cache_key); | ||
1069 | 1123 | ||
1070 | //iterates over each parameter and store used values in array array[] | 1124 | |
1071 | int iterator; | 1125 | GNUNET_CRYPTO_hash (OIDC_CLIENT_ID_KEY, strlen (OIDC_CLIENT_ID_KEY), |
1072 | for( iterator = 0; iterator<array_size; iterator++){ | 1126 | &cache_key); |
1073 | GNUNET_CRYPTO_hash (array[iterator], strlen (array[iterator]), &cache_key); | 1127 | if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle->url_param_map, |
1074 | char* cache=GNUNET_CONTAINER_multihashmap_get(handle->rest_handle->url_param_map, &cache_key); | 1128 | &cache_key)) |
1075 | bool_array[iterator]=0; | 1129 | { |
1076 | if(cache!=0){ | 1130 | //TODO error |
1077 | size_t size=strlen(cache)+1; | ||
1078 | array[iterator]=(char*)malloc(size*sizeof(char)); | ||
1079 | strncpy(array[iterator],cache,size); | ||
1080 | bool_array[iterator]=1; | ||
1081 | } | ||
1082 | } | 1131 | } |
1132 | client_id = GNUNET_CONTAINER_multihashmap_get(handle->rest_handle->url_param_map, | ||
1133 | &cache_key); | ||
1083 | 1134 | ||
1084 | /* MUST validate all the OAuth 2.0 parameters & that all the | 1135 | |
1085 | * REQUIRED parameters are present and their usage conforms to this specification | 1136 | GNUNET_CRYPTO_hash (OIDC_SCOPE_KEY, strlen (OIDC_SCOPE_KEY), &cache_key); |
1086 | */ | ||
1087 | GNUNET_CRYPTO_hash (OIDC_RESPONSE_TYPE_KEY, strlen (array[iterator]), &cache_key); | ||
1088 | if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle->url_param_map, | 1137 | if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle->url_param_map, |
1089 | &key)) | 1138 | &cache_key)) |
1090 | { | 1139 | { |
1091 | handle->emsg=GNUNET_strdup("invalid_request"); | 1140 | //TODO error |
1092 | handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR; | ||
1093 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
1094 | return; | ||
1095 | } | 1141 | } |
1096 | response_type = GNUNET_CONTAINER_multihashmap_get(handle->rest_handle->url_param_map, | 1142 | scope = GNUNET_CONTAINER_multihashmap_get(handle->rest_handle->url_param_map, |
1097 | &key); | 1143 | &cache_key); |
1098 | 1144 | ||
1099 | //required values: response_type, client_id, scope, redirect_uri | 1145 | GNUNET_CRYPTO_hash (OIDC_REDIRECT_URI_KEY, strlen (OIDC_REDIRECT_URI_KEY), |
1100 | if(!bool_array[0] || !bool_array[1] || !bool_array[2] || !bool_array[3]){ | 1146 | &cache_key); |
1101 | handle->emsg=GNUNET_strdup("invalid_request"); | 1147 | if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle->url_param_map, |
1102 | handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR; | 1148 | &cache_key)) |
1103 | GNUNET_SCHEDULER_add_now (&do_error, handle); | 1149 | { |
1104 | return; | 1150 | //TODO error |
1151 | } | ||
1152 | redirect_uri = GNUNET_CONTAINER_multihashmap_get(handle->rest_handle->url_param_map, | ||
1153 | &cache_key); | ||
1154 | |||
1155 | GNUNET_CRYPTO_hash (OIDC_STATE_KEY, strlen (OIDC_STATE_KEY), &cache_key); | ||
1156 | if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle->url_param_map, | ||
1157 | &cache_key)) | ||
1158 | { | ||
1159 | //TODO error | ||
1160 | } | ||
1161 | state = GNUNET_CONTAINER_multihashmap_get(handle->rest_handle->url_param_map, | ||
1162 | &cache_key); | ||
1163 | |||
1164 | GNUNET_CRYPTO_hash (OIDC_NONCE_KEY, strlen (OIDC_NONCE_KEY), &cache_key); | ||
1165 | if (GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle->url_param_map, | ||
1166 | &cache_key)) | ||
1167 | { | ||
1168 | //TODO error | ||
1105 | } | 1169 | } |
1170 | nonce = GNUNET_CONTAINER_multihashmap_get(handle->rest_handle->url_param_map, | ||
1171 | &cache_key); | ||
1172 | |||
1173 | int iterator; | ||
1174 | for( iterator = 0; iterator < size; iterator++ ) | ||
1175 | { | ||
1176 | GNUNET_CRYPTO_hash (OIDC_ignored_parameter_array[iterator], | ||
1177 | strlen(OIDC_ignored_parameter_array[iterator]), | ||
1178 | &cache_key); | ||
1179 | if(GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains(handle->rest_handle->url_param_map, | ||
1180 | &cache_key)) | ||
1181 | { | ||
1182 | //TODO error | ||
1183 | } | ||
1184 | } | ||
1185 | |||
1186 | |||
1106 | //response_type = code | 1187 | //response_type = code |
1107 | if(strcmp(array[0],"code")!=0){ | 1188 | if( strcmp( response_type, OIDC_EXPECTED_AUTHORIZATION_RESPONSE_TYPE ) != 0 ) |
1108 | handle->emsg=GNUNET_strdup("invalid_response_type"); | 1189 | { |
1109 | handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR; | 1190 | //TODO error |
1110 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
1111 | return; | ||
1112 | } | 1191 | } |
1113 | //scope contains openid | 1192 | //scope contains openid |
1114 | if(strstr(array[2],"openid")==NULL){ | 1193 | if( strstr( scope, OIDC_EXPECTED_AUTHORIZATION_SCOPE ) == NULL ) |
1194 | { | ||
1115 | handle->emsg=GNUNET_strdup("invalid_scope"); | 1195 | handle->emsg=GNUNET_strdup("invalid_scope"); |
1116 | handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR; | 1196 | handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR; |
1117 | GNUNET_SCHEDULER_add_now (&do_error, handle); | 1197 | GNUNET_SCHEDULER_add_now (&do_error, handle); |
@@ -1121,7 +1201,7 @@ authorize_cont (struct GNUNET_REST_RequestHandle *con_handle, | |||
1121 | //TODO check other values and use them accordingly | 1201 | //TODO check other values and use them accordingly |
1122 | 1202 | ||
1123 | 1203 | ||
1124 | char* redirect_url_to_login; | 1204 | char* login_base_url; |
1125 | 1205 | ||
1126 | // if(){ | 1206 | // if(){ |
1127 | // | 1207 | // |
@@ -1131,67 +1211,29 @@ authorize_cont (struct GNUNET_REST_RequestHandle *con_handle, | |||
1131 | if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (cfg, | 1211 | if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string (cfg, |
1132 | "identity-rest-plugin", | 1212 | "identity-rest-plugin", |
1133 | "address", | 1213 | "address", |
1134 | &redirect_url_to_login)){ | 1214 | &login_base_url)) |
1135 | 1215 | { | |
1136 | char* build_array[] = { "response_type", "client_id", "scope", "redirect_uri", | 1216 | char* new_redirect; |
1137 | "state", "nonce", "display", "prompt", "max_age", "ui_locales", | 1217 | GNUNET_asprintf (&new_redirect, "%s?%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s", |
1138 | "response_mode", "id_token_hint","login_hint", "acr_values" }; | 1218 | login_base_url, |
1139 | GNUNET_asprintf (new_redirect, "%s=%s&...", | 1219 | OIDC_RESPONSE_TYPE_KEY, response_type, |
1220 | OIDC_CLIENT_ID_KEY, client_id, | ||
1140 | OIDC_REDIRECT_URI_KEY, redirect_uri, | 1221 | OIDC_REDIRECT_URI_KEY, redirect_uri, |
1141 | OIDC_CLIENT_ID_KEY, client_id, | 1222 | OIDC_SCOPE_KEY, scope, |
1142 | ...); | 1223 | OIDC_STATE_KEY, state, |
1143 | size_t redirect_parameter_size= strlen("?"); | 1224 | OIDC_NONCE_KEY, nonce |
1144 | for(iterator=0;iterator<array_size;iterator++){ | 1225 | ); |
1145 | if(bool_array[iterator]){ | ||
1146 | redirect_parameter_size += strlen(array[iterator]); | ||
1147 | redirect_parameter_size += strlen(build_array[iterator]); | ||
1148 | if(iterator==array_size-1) | ||
1149 | { | ||
1150 | redirect_parameter_size += strlen("="); | ||
1151 | }else{ | ||
1152 | redirect_parameter_size += strlen("=&"); | ||
1153 | } | ||
1154 | } | ||
1155 | } | ||
1156 | |||
1157 | char redirect_parameter[redirect_parameter_size+1]; | ||
1158 | redirect_parameter_size = 0; | ||
1159 | redirect_parameter[redirect_parameter_size]='?'; | ||
1160 | for(iterator=0;iterator<array_size;iterator++){ | ||
1161 | if(bool_array[iterator]){ | ||
1162 | //If not last parameter | ||
1163 | if(iterator!=array_size-1) | ||
1164 | { | ||
1165 | char cache[strlen(array[iterator])+strlen(build_array[iterator])+2+1]; | ||
1166 | snprintf(cache,sizeof(cache),"%s=%s&", build_array[iterator], array[iterator]); | ||
1167 | strncat(redirect_parameter, cache, strlen(array[iterator])+strlen(build_array[iterator])+2 ); | ||
1168 | }else{ | ||
1169 | char cache[strlen(array[iterator])+strlen(build_array[iterator])+1+1]; | ||
1170 | snprintf(cache,sizeof(cache),"%s=%s", build_array[iterator], array[iterator]); | ||
1171 | strncat(redirect_parameter, cache, strlen(array[iterator])+strlen(build_array[iterator])+1 ); | ||
1172 | } | ||
1173 | } | ||
1174 | } | ||
1175 | char redirect_component[strlen(redirect_url_to_login)+strlen(redirect_parameter)+1]; | ||
1176 | snprintf(redirect_component, sizeof(redirect_component), "%s%s", redirect_url_to_login, redirect_parameter); | ||
1177 | resp = GNUNET_REST_create_response (""); | 1226 | resp = GNUNET_REST_create_response (""); |
1178 | MHD_add_response_header (resp, "Location", redirect_component); | 1227 | MHD_add_response_header (resp, "Location", new_redirect); |
1179 | }else{ | 1228 | }else{ |
1180 | handle->emsg=GNUNET_strdup("No server on localhost:8000"); | 1229 | handle->emsg=GNUNET_strdup("No server on localhost:8000"); |
1181 | handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR; | 1230 | handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR; |
1182 | GNUNET_SCHEDULER_add_now (&do_error, handle); | 1231 | GNUNET_SCHEDULER_add_now (&do_error, handle); |
1183 | return; | 1232 | return; |
1184 | // resp = GNUNET_REST_create_response (""); | ||
1185 | // MHD_add_response_header (resp, "Location", array[3]); | ||
1186 | } | 1233 | } |
1187 | 1234 | ||
1188 | handle->proc (handle->proc_cls, resp, MHD_HTTP_FOUND); | 1235 | handle->proc (handle->proc_cls, resp, MHD_HTTP_FOUND); |
1189 | cleanup_handle (handle); | 1236 | cleanup_handle (handle); |
1190 | for(iterator=0; iterator<array_size; iterator++){ | ||
1191 | if(bool_array[iterator]){ | ||
1192 | free(array[iterator]); | ||
1193 | } | ||
1194 | } | ||
1195 | return; | 1237 | return; |
1196 | } | 1238 | } |
1197 | 1239 | ||