aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPhil <phil.buschmann@tum.de>2018-01-15 16:24:11 +0100
committerPhil <phil.buschmann@tum.de>2018-01-15 16:24:11 +0100
commita49f0792a13322b8445279dab6dafc6d13c83fbc (patch)
tree43702386f1c269c92dd0ddbecb109387e926abbf /src
parentcbe68f524b22246b1cf66a10c2ad6e28ccd7cdd5 (diff)
downloadgnunet-a49f0792a13322b8445279dab6dafc6d13c83fbc.tar.gz
gnunet-a49f0792a13322b8445279dab6dafc6d13c83fbc.zip
-fix GET login finished
Diffstat (limited to 'src')
-rw-r--r--src/identity-provider/plugin_rest_identity_provider.c415
1 files changed, 251 insertions, 164 deletions
diff --git a/src/identity-provider/plugin_rest_identity_provider.c b/src/identity-provider/plugin_rest_identity_provider.c
index 515020e1b..d341abb0d 100644
--- a/src/identity-provider/plugin_rest_identity_provider.c
+++ b/src/identity-provider/plugin_rest_identity_provider.c
@@ -188,6 +188,28 @@ struct Plugin
188 const struct GNUNET_CONFIGURATION_Handle *cfg; 188 const struct GNUNET_CONFIGURATION_Handle *cfg;
189}; 189};
190 190
191struct OIDC_Variables
192{
193
194 struct GNUNET_CRYPTO_EcdsaPublicKey client_pkey;
195
196 char *client_id;
197
198 int client_trusted;
199
200 char *redirect_uri;
201
202 char* scope;
203
204 char* state;
205
206 char* nonce;
207
208 char* response_type;
209
210 char* login_identity;
211};
212
191/** 213/**
192 * The ego list 214 * The ego list
193 */ 215 */
@@ -238,11 +260,16 @@ struct RequestHandle
238 struct EgoEntry *ego_entry; 260 struct EgoEntry *ego_entry;
239 261
240 /** 262 /**
241 * Ptr to current ego private key 263 * Pointer to ego private key
242 */ 264 */
243 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key; 265 const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv_key;
244 266
245 /** 267 /**
268 * OIDC variables
269 */
270 struct OIDC_Variables *oidc;
271
272 /**
246 * The processing state 273 * The processing state
247 */ 274 */
248 int state; 275 int state;
@@ -268,29 +295,9 @@ struct RequestHandle
268 struct GNUNET_NAMESTORE_ZoneIterator *namestore_handle_it; 295 struct GNUNET_NAMESTORE_ZoneIterator *namestore_handle_it;
269 296
270 /** 297 /**
271 * OIDC_client_id existence 298 * Attribute claim list
272 */
273 int client_exists;
274
275 /**
276 * Private key for the zone
277 */ 299 */
278 struct GNUNET_CRYPTO_EcdsaPrivateKey zone_pkey; 300 struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList *attr_list;
279
280 /**
281 * Private key for the zone
282 */
283 struct GNUNET_CRYPTO_EcdsaPublicKey client_pkey;
284
285 /**
286 * OIDC_client public key
287 */
288 char *client_pkey_string;
289
290 /**
291 * OIDC login identity
292 */
293 char *identity_cookie;
294 301
295 /** 302 /**
296 * IDENTITY Operation 303 * IDENTITY Operation
@@ -348,11 +355,6 @@ struct RequestHandle
348 char *emsg; 355 char *emsg;
349 356
350 /** 357 /**
351 * Error response uri
352 */
353 char *eredirect;
354
355 /**
356 * Error response description 358 * Error response description
357 */ 359 */
358 char *edesc; 360 char *edesc;
@@ -376,6 +378,8 @@ struct RequestHandle
376static void 378static void
377cleanup_handle (struct RequestHandle *handle) 379cleanup_handle (struct RequestHandle *handle)
378{ 380{
381 struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *claim_entry;
382 struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *claim_tmp;
379 struct EgoEntry *ego_entry; 383 struct EgoEntry *ego_entry;
380 struct EgoEntry *ego_tmp; 384 struct EgoEntry *ego_tmp;
381 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 385 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -398,12 +402,38 @@ cleanup_handle (struct RequestHandle *handle)
398 GNUNET_free (handle->emsg); 402 GNUNET_free (handle->emsg);
399 if (NULL != handle->edesc) 403 if (NULL != handle->edesc)
400 GNUNET_free (handle->edesc); 404 GNUNET_free (handle->edesc);
401 if (NULL != handle->eredirect)
402 GNUNET_free (handle->eredirect);
403 if (NULL != handle->namestore_handle) 405 if (NULL != handle->namestore_handle)
404 GNUNET_NAMESTORE_disconnect (handle->namestore_handle); 406 GNUNET_NAMESTORE_disconnect (handle->namestore_handle);
405 if (NULL != handle->client_pkey_string) 407 if (NULL != handle->oidc)
406 GNUNET_free (handle->client_pkey_string); 408 {
409 if (NULL != handle->oidc->client_id)
410 GNUNET_free(handle->oidc->client_id);
411 if (NULL != handle->oidc->login_identity)
412 GNUNET_free(handle->oidc->login_identity);
413 if (NULL != handle->oidc->nonce)
414 GNUNET_free(handle->oidc->nonce);
415 if (NULL != handle->oidc->redirect_uri)
416 GNUNET_free(handle->oidc->redirect_uri);
417 if (NULL != handle->oidc->response_type)
418 GNUNET_free(handle->oidc->response_type);
419 if (NULL != handle->oidc->scope)
420 GNUNET_free(handle->oidc->scope);
421 if (NULL != handle->oidc->state)
422 GNUNET_free(handle->oidc->state);
423 GNUNET_free(handle->oidc);
424 }
425 if ( NULL != handle->attr_list )
426 {
427 for (claim_entry = handle->attr_list->list_head;
428 NULL != claim_entry;)
429 {
430 claim_tmp = claim_entry;
431 claim_entry = claim_entry->next;
432 GNUNET_free(claim_tmp->claim);
433 GNUNET_free(claim_tmp);
434 }
435 GNUNET_free (handle->attr_list);
436 }
407 for (ego_entry = handle->ego_head; 437 for (ego_entry = handle->ego_head;
408 NULL != ego_entry;) 438 NULL != ego_entry;)
409 { 439 {
@@ -413,6 +443,10 @@ cleanup_handle (struct RequestHandle *handle)
413 GNUNET_free (ego_tmp->keystring); 443 GNUNET_free (ego_tmp->keystring);
414 GNUNET_free (ego_tmp); 444 GNUNET_free (ego_tmp);
415 } 445 }
446 if (NULL != handle->attr_it)
447 {
448 GNUNET_free(handle->attr_it);
449 }
416 GNUNET_free (handle); 450 GNUNET_free (handle);
417} 451}
418 452
@@ -461,7 +495,7 @@ do_redirect_error (void *cls)
461 //TODO handle->url is wrong 495 //TODO handle->url is wrong
462 GNUNET_asprintf (&redirect, 496 GNUNET_asprintf (&redirect,
463 "%s?error=%s&error_description=%s", 497 "%s?error=%s&error_description=%s",
464 handle->eredirect, handle->emsg, handle->edesc ); 498 handle->oidc->redirect_uri, handle->emsg, handle->edesc );
465 resp = GNUNET_REST_create_response (""); 499 resp = GNUNET_REST_create_response ("");
466 MHD_add_response_header (resp, "Location", redirect); 500 MHD_add_response_header (resp, "Location", redirect);
467 handle->proc (handle->proc_cls, resp, MHD_HTTP_FOUND); 501 handle->proc (handle->proc_cls, resp, MHD_HTTP_FOUND);
@@ -1169,7 +1203,7 @@ options_cont (struct GNUNET_REST_RequestHandle *con_handle,
1169 * Function called if we had an error in zone-to-name mapping. 1203 * Function called if we had an error in zone-to-name mapping.
1170 */ 1204 */
1171static void 1205static void
1172namestore_iteration_error (void *cls) 1206oidc_iteration_error (void *cls)
1173{ 1207{
1174 struct RequestHandle *handle = cls; 1208 struct RequestHandle *handle = cls;
1175 handle->emsg = GNUNET_strdup("unauthorized_client"); 1209 handle->emsg = GNUNET_strdup("unauthorized_client");
@@ -1177,13 +1211,86 @@ namestore_iteration_error (void *cls)
1177 GNUNET_SCHEDULER_add_now (&do_error, handle); 1211 GNUNET_SCHEDULER_add_now (&do_error, handle);
1178} 1212}
1179 1213
1214static void
1215oidc_ticket_issue_cb (void* cls,
1216 const struct GNUNET_IDENTITY_PROVIDER_Ticket *ticket)
1217{
1218 struct RequestHandle *handle = cls;
1219 struct MHD_Response *resp;
1220 char* ticket_str;
1221 char* redirect_uri;
1222 resp = GNUNET_REST_create_response ("");
1223 if (NULL != ticket) {
1224 ticket_str = GNUNET_STRINGS_data_to_string_alloc (ticket,
1225 sizeof (struct GNUNET_IDENTITY_PROVIDER_Ticket));
1226 //TODO redirect to address
1227 GNUNET_asprintf(&redirect_uri, "%s?code=%s&state=", handle->oidc->redirect_uri, ticket_str);
1228 MHD_add_response_header (resp, "Location", redirect_uri);
1229 handle->proc (handle->proc_cls, resp, MHD_HTTP_FOUND);
1230 GNUNET_free (redirect_uri);
1231 GNUNET_free (ticket_str);
1232 }
1233 //TODO add error
1234 GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle);
1235}
1236
1237static void
1238oidc_collect_finished_cb (void *cls)
1239{
1240 struct RequestHandle *handle = cls;
1241 //Done
1242 handle->attr_it = NULL;
1243 handle->ticket_it = NULL;
1244 handle->idp_op = GNUNET_IDENTITY_PROVIDER_ticket_issue (handle->idp,
1245 handle->priv_key,
1246 &handle->oidc->client_pkey,
1247 handle->attr_list,
1248 &oidc_ticket_issue_cb,
1249 handle);
1250}
1251
1252
1253/**
1254 * Collect all attributes for an ego
1255 *
1256 */
1257static void
1258oidc_attr_collect (void *cls,
1259 const struct GNUNET_CRYPTO_EcdsaPublicKey *identity,
1260 const struct GNUNET_IDENTITY_ATTRIBUTE_Claim *attr)
1261{
1262 struct RequestHandle *handle = cls;
1263 struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *le;
1264
1265 if ((NULL == attr->name) || (NULL == attr->data))
1266 {
1267 GNUNET_IDENTITY_PROVIDER_get_attributes_next (handle->attr_it);
1268 return;
1269 }
1270
1271 if ( NULL == strstr(handle->oidc->scope,attr->name))
1272 {
1273 GNUNET_IDENTITY_PROVIDER_get_attributes_next (handle->attr_it);
1274 return;
1275 }
1276
1277 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Adding attribute: %s\n",
1278 attr->name);
1279 le = GNUNET_new(struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry);
1280 le->claim = GNUNET_IDENTITY_ATTRIBUTE_claim_new (attr->name, attr->type,
1281 attr->data, attr->data_size);
1282 GNUNET_CONTAINER_DLL_insert(handle->attr_list->list_head, handle->attr_list->list_tail, le);
1283 GNUNET_IDENTITY_PROVIDER_get_attributes_next (handle->attr_it);
1284}
1285
1286
1180/** 1287/**
1181 * Create a response with requested records 1288 * Create a response with requested records
1182 * 1289 *
1183 * @param handle the RequestHandle 1290 * @param handle the RequestHandle
1184 */ 1291 */
1185static void 1292static void
1186namestore_iteration_callback ( 1293oidc_namestore_iteration_callback (
1187 void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key, 1294 void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key,
1188 const char *rname, unsigned int rd_len, 1295 const char *rname, unsigned int rd_len,
1189 const struct GNUNET_GNSRECORD_Data *rd) 1296 const struct GNUNET_GNSRECORD_Data *rd)
@@ -1198,31 +1305,33 @@ namestore_iteration_callback (
1198 if ( GNUNET_GNSRECORD_TYPE_PKEY != rd[i].record_type ) 1305 if ( GNUNET_GNSRECORD_TYPE_PKEY != rd[i].record_type )
1199 continue; 1306 continue;
1200 1307
1201 if( NULL != handle->identity_cookie) 1308 if ( NULL != handle->oidc->login_identity )
1202 { 1309 {
1203 GNUNET_CRYPTO_ecdsa_public_key_from_string ( 1310 GNUNET_CRYPTO_ecdsa_public_key_from_string (
1204 handle->identity_cookie, strlen (handle->identity_cookie), 1311 handle->oidc->login_identity, strlen (handle->oidc->login_identity),
1205 &login_identity_pkey); 1312 &login_identity_pkey);
1206 GNUNET_IDENTITY_ego_get_public_key (handle->ego_entry->ego, 1313 GNUNET_IDENTITY_ego_get_public_key (handle->ego_entry->ego,
1207 &current_zone_pkey); 1314 &current_zone_pkey);
1208 1315
1209 if ( 0 1316 if ( 0
1210 == memcmp (rd[i].data, &handle->client_pkey, 1317 == memcmp (rd[i].data, &handle->oidc->client_pkey,
1211 sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)) ) 1318 sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)) )
1212 { 1319 {
1213 if( 0 == memcmp (&login_identity_pkey, &current_zone_pkey, sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey))) 1320 if ( 0
1321 == memcmp (&login_identity_pkey, &current_zone_pkey,
1322 sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)) )
1214 { 1323 {
1215 handle->client_exists = GNUNET_YES; 1324 handle->oidc->client_trusted = GNUNET_YES;
1216 } 1325 }
1217 } 1326 }
1218 } 1327 }
1219 else 1328 else
1220 { 1329 {
1221 if ( 0 1330 if ( 0
1222 == memcmp (rd[i].data, &handle->client_pkey, 1331 == memcmp (rd[i].data, &handle->oidc->client_pkey,
1223 sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)) ) 1332 sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)) )
1224 { 1333 {
1225 handle->client_exists = GNUNET_YES; 1334 handle->oidc->client_trusted = GNUNET_YES;
1226 } 1335 }
1227 } 1336 }
1228 } 1337 }
@@ -1236,36 +1345,31 @@ namestore_iteration_callback (
1236 * 1345 *
1237 * @param cls the `struct RequestHandle` 1346 * @param cls the `struct RequestHandle`
1238 */ 1347 */
1239static void 1348static void oidc_namestore_iteration_finished (void *cls)
1240namestore_iteration_finished (void *cls)
1241{ 1349{
1242 struct RequestHandle *handle = cls; 1350 struct RequestHandle *handle = cls;
1243 struct MHD_Response *resp; 1351 struct MHD_Response *resp;
1352 struct GNUNET_HashCode cache_key;
1353 struct GNUNET_CRYPTO_EcdsaPublicKey pubkey, ego_pkey;
1354 struct GNUNET_TIME_Absolute current_time, *relog_time;
1244 1355
1245 char *response_type;
1246 char *scope;
1247 char *redirect_uri;
1248 char *expected_redirect_uri; 1356 char *expected_redirect_uri;
1249 char *state = NULL; 1357 char *identity_cookie;
1250 char *nonce = NULL; 1358 char *login_base_url;
1251 struct GNUNET_TIME_Absolute current_time, *relog_time; 1359 char *new_redirect;
1252 char *login_base_url, *new_redirect;
1253 struct GNUNET_HashCode cache_key;
1254 struct GNUNET_CRYPTO_EcdsaPublicKey pubkey;
1255 int number_of_ignored_parameter, iterator; 1360 int number_of_ignored_parameter, iterator;
1256 1361
1257 1362
1258 handle->ego_entry = handle->ego_entry->next; 1363 handle->ego_entry = handle->ego_entry->next;
1259 1364
1260 if(NULL != handle->ego_entry){ 1365 if(NULL != handle->ego_entry){
1261 handle->zone_pkey = *GNUNET_IDENTITY_ego_get_private_key ( 1366 handle->priv_key = GNUNET_IDENTITY_ego_get_private_key (handle->ego_entry->ego);
1262 handle->ego_entry->ego); 1367 handle->namestore_handle_it = GNUNET_NAMESTORE_zone_iteration_start (handle->namestore_handle, handle->priv_key,
1263 handle->namestore_handle_it = GNUNET_NAMESTORE_zone_iteration_start (handle->namestore_handle, &handle->zone_pkey, 1368 &oidc_iteration_error, handle, &oidc_namestore_iteration_callback, handle,
1264 &namestore_iteration_error, handle, &namestore_iteration_callback, handle, 1369 &oidc_namestore_iteration_finished, handle);
1265 &namestore_iteration_finished, handle);
1266 return; 1370 return;
1267 } 1371 }
1268 if (GNUNET_YES != handle->client_exists) 1372 if (GNUNET_YES != handle->oidc->client_trusted)
1269 { 1373 {
1270 handle->emsg = GNUNET_strdup("unauthorized_client"); 1374 handle->emsg = GNUNET_strdup("unauthorized_client");
1271 handle->edesc = GNUNET_strdup("Client is not trusted."); 1375 handle->edesc = GNUNET_strdup("Client is not trusted.");
@@ -1284,20 +1388,20 @@ namestore_iteration_finished (void *cls)
1284 GNUNET_SCHEDULER_add_now (&do_error, handle); 1388 GNUNET_SCHEDULER_add_now (&do_error, handle);
1285 return; 1389 return;
1286 } 1390 }
1287 redirect_uri = GNUNET_CONTAINER_multihashmap_get(handle->rest_handle->url_param_map, 1391 handle->oidc->redirect_uri = GNUNET_CONTAINER_multihashmap_get(handle->rest_handle->url_param_map,
1288 &cache_key); 1392 &cache_key);
1289 1393
1290 GNUNET_asprintf (&expected_redirect_uri, "https://%s.zkey", handle->client_pkey_string); 1394 GNUNET_asprintf (&expected_redirect_uri, "https://%s.zkey", handle->oidc->client_id);
1291 // verify the redirect uri matches https://<client_id>.zkey[/xyz] 1395 // verify the redirect uri matches https://<client_id>.zkey[/xyz]
1292 if( 0 != strncmp( expected_redirect_uri, redirect_uri, strlen(expected_redirect_uri)) ) 1396 if( 0 != strncmp( expected_redirect_uri, handle->oidc->redirect_uri, strlen(expected_redirect_uri)) )
1293 { 1397 {
1294 handle->emsg=GNUNET_strdup("invalid_request"); 1398 handle->emsg=GNUNET_strdup("invalid_request");
1295 handle->edesc=GNUNET_strdup("Invalid redirect_uri"); 1399 handle->edesc=GNUNET_strdup("Invalid redirect_uri");
1296 GNUNET_SCHEDULER_add_now (&do_error, handle); 1400 GNUNET_SCHEDULER_add_now (&do_error, handle);
1297// GNUNET_free(expected_redirect_uri); 1401 GNUNET_free(expected_redirect_uri);
1298 return; 1402 return;
1299 } 1403 }
1300 handle->eredirect = GNUNET_strdup(redirect_uri); 1404 handle->oidc->redirect_uri = GNUNET_strdup(handle->oidc->redirect_uri);
1301 1405
1302 GNUNET_free(expected_redirect_uri); 1406 GNUNET_free(expected_redirect_uri);
1303 // REQUIRED value: response_type 1407 // REQUIRED value: response_type
@@ -1311,8 +1415,9 @@ namestore_iteration_finished (void *cls)
1311 GNUNET_SCHEDULER_add_now (&do_redirect_error, handle); 1415 GNUNET_SCHEDULER_add_now (&do_redirect_error, handle);
1312 return; 1416 return;
1313 } 1417 }
1314 response_type = GNUNET_CONTAINER_multihashmap_get(handle->rest_handle->url_param_map, 1418 handle->oidc->response_type = GNUNET_CONTAINER_multihashmap_get(handle->rest_handle->url_param_map,
1315 &cache_key); 1419 &cache_key);
1420 handle->oidc->response_type = GNUNET_strdup (handle->oidc->response_type);
1316 1421
1317 // REQUIRED value: scope 1422 // REQUIRED value: scope
1318 GNUNET_CRYPTO_hash (OIDC_SCOPE_KEY, strlen (OIDC_SCOPE_KEY), &cache_key); 1423 GNUNET_CRYPTO_hash (OIDC_SCOPE_KEY, strlen (OIDC_SCOPE_KEY), &cache_key);
@@ -1324,16 +1429,18 @@ namestore_iteration_finished (void *cls)
1324 GNUNET_SCHEDULER_add_now (&do_redirect_error, handle); 1429 GNUNET_SCHEDULER_add_now (&do_redirect_error, handle);
1325 return; 1430 return;
1326 } 1431 }
1327 scope = GNUNET_CONTAINER_multihashmap_get(handle->rest_handle->url_param_map, 1432 handle->oidc->scope = GNUNET_CONTAINER_multihashmap_get(handle->rest_handle->url_param_map,
1328 &cache_key); 1433 &cache_key);
1434 handle->oidc->scope = GNUNET_strdup(handle->oidc->scope);
1329 1435
1330 //RECOMMENDED value: state 1436 //RECOMMENDED value: state
1331 GNUNET_CRYPTO_hash (OIDC_STATE_KEY, strlen (OIDC_STATE_KEY), &cache_key); 1437 GNUNET_CRYPTO_hash (OIDC_STATE_KEY, strlen (OIDC_STATE_KEY), &cache_key);
1332 if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle->url_param_map, 1438 if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle->url_param_map,
1333 &cache_key)) 1439 &cache_key))
1334 { 1440 {
1335 state = GNUNET_CONTAINER_multihashmap_get(handle->rest_handle->url_param_map, 1441 handle->oidc->state = GNUNET_CONTAINER_multihashmap_get(handle->rest_handle->url_param_map,
1336 &cache_key); 1442 &cache_key);
1443 handle->oidc->state = GNUNET_strdup (handle->oidc->state);
1337 } 1444 }
1338 1445
1339 //OPTIONAL value: nonce 1446 //OPTIONAL value: nonce
@@ -1341,8 +1448,10 @@ namestore_iteration_finished (void *cls)
1341 if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle->url_param_map, 1448 if (GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle->url_param_map,
1342 &cache_key)) 1449 &cache_key))
1343 { 1450 {
1344 nonce = GNUNET_CONTAINER_multihashmap_get(handle->rest_handle->url_param_map, 1451 handle->oidc->nonce = GNUNET_CONTAINER_multihashmap_get(handle->rest_handle->url_param_map,
1345 &cache_key); 1452 &cache_key);
1453 //ASK: what do we do with the nonce?
1454 handle->oidc->nonce = GNUNET_strdup (handle->oidc->nonce);
1346 } 1455 }
1347 1456
1348 //TODO check other values and use them accordingly 1457 //TODO check other values and use them accordingly
@@ -1364,7 +1473,7 @@ namestore_iteration_finished (void *cls)
1364 } 1473 }
1365 1474
1366 // Checks if response_type is 'code' 1475 // Checks if response_type is 'code'
1367 if( 0 != strcmp( response_type, OIDC_EXPECTED_AUTHORIZATION_RESPONSE_TYPE ) ) 1476 if( 0 != strcmp( handle->oidc->response_type, OIDC_EXPECTED_AUTHORIZATION_RESPONSE_TYPE ) )
1368 { 1477 {
1369 handle->emsg=GNUNET_strdup("unsupported_response_type"); 1478 handle->emsg=GNUNET_strdup("unsupported_response_type");
1370 handle->edesc=GNUNET_strdup("The authorization server does not support " 1479 handle->edesc=GNUNET_strdup("The authorization server does not support "
@@ -1373,7 +1482,7 @@ namestore_iteration_finished (void *cls)
1373 return; 1482 return;
1374 } 1483 }
1375 // Checks if scope contains 'openid' 1484 // Checks if scope contains 'openid'
1376 if( NULL == strstr( scope, OIDC_EXPECTED_AUTHORIZATION_SCOPE ) ) 1485 if( NULL == strstr( handle->oidc->scope, OIDC_EXPECTED_AUTHORIZATION_SCOPE ) )
1377 { 1486 {
1378 handle->emsg=GNUNET_strdup("invalid_scope"); 1487 handle->emsg=GNUNET_strdup("invalid_scope");
1379 handle->edesc=GNUNET_strdup("The requested scope is invalid, unknown, or " 1488 handle->edesc=GNUNET_strdup("The requested scope is invalid, unknown, or "
@@ -1382,12 +1491,11 @@ namestore_iteration_finished (void *cls)
1382 return; 1491 return;
1383 } 1492 }
1384 1493
1385 if( NULL != handle->identity_cookie ) 1494 if( NULL != handle->oidc->login_identity )
1386 { 1495 {
1387 char *identity_cookie; 1496 GNUNET_asprintf(&identity_cookie,"Identity=%s",handle->oidc->login_identity);
1388 GNUNET_asprintf(&identity_cookie,"Identity=%s",handle->identity_cookie);
1389 GNUNET_CRYPTO_hash (identity_cookie, strlen (identity_cookie), &cache_key); 1497 GNUNET_CRYPTO_hash (identity_cookie, strlen (identity_cookie), &cache_key);
1390 1498 GNUNET_free(identity_cookie);
1391 //No login time for identity -> redirect to login 1499 //No login time for identity -> redirect to login
1392 if ( GNUNET_YES 1500 if ( GNUNET_YES
1393 == GNUNET_CONTAINER_multihashmap_contains (OIDC_authorized_identities, 1501 == GNUNET_CONTAINER_multihashmap_contains (OIDC_authorized_identities,
@@ -1402,35 +1510,39 @@ namestore_iteration_finished (void *cls)
1402 // 30 min after old login -> redirect to login 1510 // 30 min after old login -> redirect to login
1403 if ( current_time.abs_value_us <= relog_time->abs_value_us ) 1511 if ( current_time.abs_value_us <= relog_time->abs_value_us )
1404 { 1512 {
1405 resp = GNUNET_REST_create_response (""); 1513 if ( GNUNET_OK != GNUNET_CRYPTO_ecdsa_public_key_from_string (handle->oidc->login_identity,
1406 1514 strlen (handle->oidc->login_identity),
1407 GNUNET_CRYPTO_ecdsa_public_key_from_string (identity_cookie, 1515 &pubkey))
1408 strlen (identity_cookie), 1516 {
1409 &pubkey); 1517 handle->emsg=GNUNET_strdup("invalid_cookie");
1410 1518 handle->edesc=GNUNET_strdup("Test");
1519 GNUNET_SCHEDULER_add_now (&do_redirect_error, handle);
1520 return;
1521 }
1522 handle->priv_key=NULL;
1411 // iterate over egos and compare their public key 1523 // iterate over egos and compare their public key
1412// GNUNET_IDENTITY_PROVIDER_get_attributes_start 1524 for (handle->ego_entry = handle->ego_head;
1413 // iterate over scope variables 1525 NULL != handle->ego_entry; handle->ego_entry = handle->ego_entry->next)
1414// char delimiter[] = " "; 1526 {
1415// char *scope_attribute; 1527 GNUNET_IDENTITY_ego_get_public_key( handle->ego_entry->ego, &ego_pkey );
1416// scope_attribute = strtok(scope, delimiter); 1528 if ( 0 == memcmp(&ego_pkey,&pubkey, sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)))
1417// 1529 {
1418// while ( NULL != scope_attribute ) 1530 handle->priv_key = GNUNET_IDENTITY_ego_get_private_key (handle->ego_entry->ego);
1419// { 1531 break;
1420// if ( NULL == strstr (scope_attribute, OIDC_EXPECTED_AUTHORIZATION_SCOPE) ) 1532 }
1421// { 1533 }
1422// // claim attribute from ego 1534 if ( NULL != handle->priv_key )
1423// scope_attribute = strtok (NULL, delimiter); 1535 {
1424// } 1536 handle->resp_object = GNUNET_JSONAPI_document_new ();
1425// } 1537 handle->idp = GNUNET_IDENTITY_PROVIDER_connect (cfg);
1426 // create an authorization code 1538 handle->attr_list = GNUNET_new (struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList);
1427 1539 handle->attr_it = GNUNET_IDENTITY_PROVIDER_get_attributes_start (
1428// GNUNET_IDENTITY_PROVIDER_t 1540 handle->idp, handle->priv_key, &oidc_iteration_error, handle, &oidc_attr_collect,
1429 1541 handle, &oidc_collect_finished_cb, handle);
1430 MHD_add_response_header (resp, "Location", redirect_uri); 1542 GNUNET_free(relog_time);
1431 handle->proc (handle->proc_cls, resp, MHD_HTTP_FOUND); 1543 return;
1432 GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle); 1544 }
1433 GNUNET_free(relog_time); 1545 //TODO add error
1434 return; 1546 return;
1435 } 1547 }
1436 GNUNET_free(relog_time); 1548 GNUNET_free(relog_time);
@@ -1446,20 +1558,20 @@ namestore_iteration_finished (void *cls)
1446 GNUNET_asprintf (&new_redirect, "%s?%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s", 1558 GNUNET_asprintf (&new_redirect, "%s?%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s",
1447 login_base_url, 1559 login_base_url,
1448 OIDC_RESPONSE_TYPE_KEY, 1560 OIDC_RESPONSE_TYPE_KEY,
1449 response_type, 1561 handle->oidc->response_type,
1450 OIDC_CLIENT_ID_KEY, 1562 OIDC_CLIENT_ID_KEY,
1451 handle->client_pkey_string, 1563 handle->oidc->client_id,
1452 OIDC_REDIRECT_URI_KEY, 1564 OIDC_REDIRECT_URI_KEY,
1453 redirect_uri, 1565 handle->oidc->redirect_uri,
1454 OIDC_SCOPE_KEY, 1566 OIDC_SCOPE_KEY,
1455 scope, 1567 handle->oidc->scope,
1456 OIDC_STATE_KEY, 1568 OIDC_STATE_KEY,
1457 (NULL != state) ? state : "", 1569 (NULL != handle->oidc->state) ? handle->oidc->state : "",
1458 OIDC_NONCE_KEY, 1570 OIDC_NONCE_KEY,
1459 (NULL != nonce) ? nonce : ""); 1571 (NULL != handle->oidc->nonce) ? handle->oidc->nonce : "");
1460 resp = GNUNET_REST_create_response (""); 1572 resp = GNUNET_REST_create_response ("");
1461 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "%s\n", new_redirect);
1462 MHD_add_response_header (resp, "Location", new_redirect); 1573 MHD_add_response_header (resp, "Location", new_redirect);
1574 GNUNET_free(login_base_url);
1463 } 1575 }
1464 else 1576 else
1465 { 1577 {
@@ -1471,7 +1583,6 @@ namestore_iteration_finished (void *cls)
1471 handle->proc (handle->proc_cls, resp, MHD_HTTP_FOUND); 1583 handle->proc (handle->proc_cls, resp, MHD_HTTP_FOUND);
1472 GNUNET_free(new_redirect); 1584 GNUNET_free(new_redirect);
1473 GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle); 1585 GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle);
1474 return;
1475} 1586}
1476 1587
1477/** 1588/**
@@ -1486,56 +1597,34 @@ authorize_get_cont (struct GNUNET_REST_RequestHandle *con_handle,
1486 const char* url, 1597 const char* url,
1487 void *cls) 1598 void *cls)
1488{ 1599{
1489 /** The Authorization Server MUST validate all the OAuth 2.0 parameters
1490 * according to the OAuth 2.0 specification.
1491 */
1492 /**
1493 * If the sub (subject) Claim is requested with a specific value for the
1494 * ID Token, the Authorization Server MUST only send a positive response
1495 * if the End-User identified by that sub value has an active session with
1496 * the Authorization Server or has been Authenticated as a result of the
1497 * request. The Authorization Server MUST NOT reply with an ID Token or
1498 * Access Token for a different user, even if they have an active session
1499 * with the Authorization Server. Such a request can be made either using
1500 * an id_token_hint parameter or by requesting a specific Claim Value as
1501 * described in Section 5.5.1, if the claims parameter is supported by
1502 * the implementation.
1503 */
1504
1505 struct RequestHandle *handle = cls; 1600 struct RequestHandle *handle = cls;
1506 struct GNUNET_HashCode cache_key; 1601 struct GNUNET_HashCode cache_key;
1507 char *client_id; 1602 char* cookies;
1508 char *identity_cookie; 1603 char delimiter[] = "; ";
1509 1604
1510 // identity cookie 1605 //gets identity of login try with cookie
1511 GNUNET_CRYPTO_hash (OIDC_COOKIE_HEADER_KEY, strlen (OIDC_COOKIE_HEADER_KEY), 1606 GNUNET_CRYPTO_hash (OIDC_COOKIE_HEADER_KEY, strlen (OIDC_COOKIE_HEADER_KEY),
1512 &cache_key); 1607 &cache_key);
1513 if ( GNUNET_YES 1608 if ( GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle->header_param_map,
1514 == GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle->header_param_map, 1609 &cache_key) )
1515 &cache_key) )
1516 { 1610 {
1517 //split cookies and find 'Identity' cookie 1611 //splits cookies and find 'Identity' cookie
1518 char* cookies = GNUNET_CONTAINER_multihashmap_get ( 1612 cookies = GNUNET_CONTAINER_multihashmap_get ( handle->rest_handle->header_param_map, &cache_key);
1519 handle->rest_handle->header_param_map, &cache_key); 1613 handle->oidc->login_identity = strtok(cookies, delimiter);
1520 char delimiter[] = "; ";
1521 identity_cookie = strtok(cookies, delimiter);
1522 1614
1523 while ( NULL != identity_cookie ) 1615 while ( NULL != handle->oidc->login_identity )
1524 { 1616 {
1525 if ( NULL != strstr (identity_cookie, OIDC_COOKIE_HEADER_INFORMATION_KEY) ) 1617 if ( NULL != strstr (handle->oidc->login_identity, OIDC_COOKIE_HEADER_INFORMATION_KEY) )
1526 { 1618 {
1527 break; 1619 break;
1528 } 1620 }
1529 identity_cookie = strtok (NULL, delimiter); 1621 handle->oidc->login_identity = strtok (NULL, delimiter);
1530 } 1622 }
1531 identity_cookie = strtok(cookies, OIDC_COOKIE_HEADER_INFORMATION_KEY); 1623 handle->oidc->login_identity = strtok(cookies, OIDC_COOKIE_HEADER_INFORMATION_KEY);
1532 handle->identity_cookie = GNUNET_strdup(identity_cookie); 1624 handle->oidc->login_identity = GNUNET_strdup(handle->oidc->login_identity);
1533 GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Cookie: %s\n", handle->identity_cookie);
1534 } 1625 }
1535 1626
1536 1627
1537 handle->response_code = 0;
1538
1539 // REQUIRED value: client_id 1628 // REQUIRED value: client_id
1540 GNUNET_CRYPTO_hash (OIDC_CLIENT_ID_KEY, strlen (OIDC_CLIENT_ID_KEY), 1629 GNUNET_CRYPTO_hash (OIDC_CLIENT_ID_KEY, strlen (OIDC_CLIENT_ID_KEY),
1541 &cache_key); 1630 &cache_key);
@@ -1548,14 +1637,16 @@ authorize_get_cont (struct GNUNET_REST_RequestHandle *con_handle,
1548 GNUNET_SCHEDULER_add_now (&do_error, handle); 1637 GNUNET_SCHEDULER_add_now (&do_error, handle);
1549 return; 1638 return;
1550 } 1639 }
1551 client_id = GNUNET_CONTAINER_multihashmap_get(handle->rest_handle->url_param_map, 1640 handle->oidc->client_id = GNUNET_CONTAINER_multihashmap_get(handle->rest_handle->url_param_map,
1552 &cache_key); 1641 &cache_key);
1642 handle->oidc->client_id = GNUNET_strdup (handle->oidc->client_id);
1553 1643
1554 if ( GNUNET_OK 1644 if ( GNUNET_OK
1555 != GNUNET_CRYPTO_ecdsa_public_key_from_string (client_id, 1645 != GNUNET_CRYPTO_ecdsa_public_key_from_string (handle->oidc->client_id,
1556 strlen (client_id), 1646 strlen (handle->oidc->client_id),
1557 &handle->client_pkey) ) 1647 &handle->oidc->client_pkey) )
1558 { 1648 {
1649 //ASK rewrite error?
1559 handle->emsg = GNUNET_strdup("unauthorized_client"); 1650 handle->emsg = GNUNET_strdup("unauthorized_client");
1560 handle->edesc = GNUNET_strdup("The client is not authorized to request an " 1651 handle->edesc = GNUNET_strdup("The client is not authorized to request an "
1561 "authorization code using this method."); 1652 "authorization code using this method.");
@@ -1564,29 +1655,25 @@ authorize_get_cont (struct GNUNET_REST_RequestHandle *con_handle,
1564 return; 1655 return;
1565 } 1656 }
1566 1657
1567 if ( NULL == handle->namestore_handle )
1568 handle->namestore_handle = GNUNET_NAMESTORE_connect (cfg);
1569 1658
1570 if ( NULL == handle->ego_head ) 1659 if ( NULL == handle->ego_head )
1571 { 1660 {
1661 //ASK throw error or ignore if egos are missing?
1572 handle->emsg = GNUNET_strdup("Missing egos."); 1662 handle->emsg = GNUNET_strdup("Missing egos.");
1573 handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR; 1663 handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR;
1574 GNUNET_SCHEDULER_add_now (&do_error, handle); 1664 GNUNET_SCHEDULER_add_now (&do_error, handle);
1575 return; 1665 return;
1576 } 1666 }
1577 1667
1578 handle->zone_pkey = *GNUNET_IDENTITY_ego_get_private_key (
1579 handle->ego_head->ego);
1580 handle->ego_entry = handle->ego_head; 1668 handle->ego_entry = handle->ego_head;
1581 handle->client_exists = GNUNET_NO; 1669 handle->priv_key = GNUNET_IDENTITY_ego_get_private_key (handle->ego_head->ego);
1582 handle->client_pkey_string = GNUNET_strdup(client_id); 1670 handle->oidc->client_trusted = GNUNET_NO;
1583 1671
1584 // Checks if client_id is valid: 1672 // Checks if client_id is valid:
1585 handle->namestore_handle_it = GNUNET_NAMESTORE_zone_iteration_start ( 1673 handle->namestore_handle_it = GNUNET_NAMESTORE_zone_iteration_start (
1586 handle->namestore_handle, &handle->zone_pkey, &namestore_iteration_error, 1674 handle->namestore_handle, handle->priv_key, &oidc_iteration_error,
1587 handle, &namestore_iteration_callback, handle, 1675 handle, &oidc_namestore_iteration_callback, handle,
1588 &namestore_iteration_finished, handle); 1676 &oidc_namestore_iteration_finished, handle);
1589 return;
1590} 1677}
1591 1678
1592/** 1679/**
@@ -1689,7 +1776,7 @@ authorize_post_cont (struct GNUNET_REST_RequestHandle *con_handle,
1689 GNUNET_SCHEDULER_add_now (&do_error, handle); 1776 GNUNET_SCHEDULER_add_now (&do_error, handle);
1690 return; 1777 return;
1691 } 1778 }
1692 handle->eredirect = GNUNET_strdup(redirect_uri); 1779 handle->oidc->redirect_uri = GNUNET_strdup(redirect_uri);
1693 1780
1694 // REQUIRED value: response_type 1781 // REQUIRED value: response_type
1695 cache_object = json_object_get (root, OIDC_RESPONSE_TYPE_KEY); 1782 cache_object = json_object_get (root, OIDC_RESPONSE_TYPE_KEY);
@@ -2021,11 +2108,10 @@ rest_identity_process_request(struct GNUNET_REST_RequestHandle *rest_handle,
2021 void *proc_cls) 2108 void *proc_cls)
2022{ 2109{
2023 struct RequestHandle *handle = GNUNET_new (struct RequestHandle); 2110 struct RequestHandle *handle = GNUNET_new (struct RequestHandle);
2111 handle->oidc = GNUNET_new (struct OIDC_Variables);
2024 if ( NULL == OIDC_authorized_identities ) 2112 if ( NULL == OIDC_authorized_identities )
2025 { 2113 OIDC_authorized_identities = GNUNET_CONTAINER_multihashmap_create (10, GNUNET_NO);
2026 OIDC_authorized_identities = GNUNET_CONTAINER_multihashmap_create (10, 2114 handle->response_code = 0;
2027 GNUNET_NO);
2028 }
2029 handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL; 2115 handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL;
2030 handle->proc_cls = proc_cls; 2116 handle->proc_cls = proc_cls;
2031 handle->proc = proc; 2117 handle->proc = proc;
@@ -2040,6 +2126,7 @@ rest_identity_process_request(struct GNUNET_REST_RequestHandle *rest_handle,
2040 handle->identity_handle = GNUNET_IDENTITY_connect (cfg, 2126 handle->identity_handle = GNUNET_IDENTITY_connect (cfg,
2041 &list_ego, 2127 &list_ego,
2042 handle); 2128 handle);
2129 handle->namestore_handle = GNUNET_NAMESTORE_connect (cfg);
2043 handle->timeout_task = 2130 handle->timeout_task =
2044 GNUNET_SCHEDULER_add_delayed (handle->timeout, 2131 GNUNET_SCHEDULER_add_delayed (handle->timeout,
2045 &do_timeout, 2132 &do_timeout,