diff options
author | Phil <phil.buschmann@tum.de> | 2018-01-18 16:57:24 +0100 |
---|---|---|
committer | Phil <phil.buschmann@tum.de> | 2018-01-18 16:57:24 +0100 |
commit | ca115cc3605b2ecc88ce21a4758aa38149dc2342 (patch) | |
tree | 651cd8597c15664cfe07d5e907ec1a9ebe1ae10f /src | |
parent | c2077b1c8dd826192e8dc4be0567b2e6a61aa536 (diff) | |
download | gnunet-ca115cc3605b2ecc88ce21a4758aa38149dc2342.tar.gz gnunet-ca115cc3605b2ecc88ce21a4758aa38149dc2342.zip |
-fix get and post authorization request
Diffstat (limited to 'src')
-rw-r--r-- | src/identity-provider/plugin_rest_identity_provider.c | 871 | ||||
-rw-r--r-- | src/identity-provider/vgcore.2692 | bin | 72450048 -> 0 bytes |
2 files changed, 432 insertions, 439 deletions
diff --git a/src/identity-provider/plugin_rest_identity_provider.c b/src/identity-provider/plugin_rest_identity_provider.c index 1c7313aa1..0498f5c23 100644 --- a/src/identity-provider/plugin_rest_identity_provider.c +++ b/src/identity-provider/plugin_rest_identity_provider.c | |||
@@ -196,19 +196,21 @@ struct OIDC_Variables | |||
196 | 196 | ||
197 | char *client_id; | 197 | char *client_id; |
198 | 198 | ||
199 | int client_trusted; | 199 | int is_client_trusted; |
200 | 200 | ||
201 | char *redirect_uri; | 201 | char *redirect_uri; |
202 | 202 | ||
203 | char* scope; | 203 | char *scope; |
204 | 204 | ||
205 | char* state; | 205 | char *state; |
206 | 206 | ||
207 | char* nonce; | 207 | char *nonce; |
208 | 208 | ||
209 | char* response_type; | 209 | char *response_type; |
210 | 210 | ||
211 | char* login_identity; | 211 | char *login_identity; |
212 | |||
213 | json_t *post_object; | ||
212 | }; | 214 | }; |
213 | 215 | ||
214 | /** | 216 | /** |
@@ -421,6 +423,8 @@ cleanup_handle (struct RequestHandle *handle) | |||
421 | GNUNET_free(handle->oidc->scope); | 423 | GNUNET_free(handle->oidc->scope); |
422 | if (NULL != handle->oidc->state) | 424 | if (NULL != handle->oidc->state) |
423 | GNUNET_free(handle->oidc->state); | 425 | GNUNET_free(handle->oidc->state); |
426 | if (NULL != handle->oidc->post_object) | ||
427 | json_decref(handle->oidc->post_object); | ||
424 | GNUNET_free(handle->oidc); | 428 | GNUNET_free(handle->oidc); |
425 | } | 429 | } |
426 | if ( NULL != handle->attr_list ) | 430 | if ( NULL != handle->attr_list ) |
@@ -1206,6 +1210,101 @@ options_cont (struct GNUNET_REST_RequestHandle *con_handle, | |||
1206 | } | 1210 | } |
1207 | 1211 | ||
1208 | /** | 1212 | /** |
1213 | * Cookie interpretation | ||
1214 | */ | ||
1215 | static void | ||
1216 | cookie_identity_interpretation (struct RequestHandle *handle) | ||
1217 | { | ||
1218 | struct GNUNET_HashCode cache_key; | ||
1219 | char* cookies; | ||
1220 | char delimiter[] = "; "; | ||
1221 | |||
1222 | //gets identity of login try with cookie | ||
1223 | GNUNET_CRYPTO_hash (OIDC_COOKIE_HEADER_KEY, strlen (OIDC_COOKIE_HEADER_KEY), | ||
1224 | &cache_key); | ||
1225 | if ( GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle->header_param_map, | ||
1226 | &cache_key) ) | ||
1227 | { | ||
1228 | //splits cookies and find 'Identity' cookie | ||
1229 | cookies = GNUNET_CONTAINER_multihashmap_get ( handle->rest_handle->header_param_map, &cache_key); | ||
1230 | handle->oidc->login_identity = strtok(cookies, delimiter); | ||
1231 | |||
1232 | while ( NULL != handle->oidc->login_identity ) | ||
1233 | { | ||
1234 | if ( NULL != strstr (handle->oidc->login_identity, OIDC_COOKIE_HEADER_INFORMATION_KEY) ) | ||
1235 | { | ||
1236 | break; | ||
1237 | } | ||
1238 | handle->oidc->login_identity = strtok (NULL, delimiter); | ||
1239 | } | ||
1240 | GNUNET_CRYPTO_hash (handle->oidc->login_identity, strlen (handle->oidc->login_identity), | ||
1241 | &cache_key); | ||
1242 | if ( GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (OIDC_authorized_identities, &cache_key) ) | ||
1243 | { | ||
1244 | relog_time = GNUNET_CONTAINER_multihashmap_get (OIDC_authorized_identities, | ||
1245 | &cache_key); | ||
1246 | current_time = GNUNET_TIME_absolute_get (); | ||
1247 | // 30 min after old login -> redirect to login | ||
1248 | if ( current_time.abs_value_us <= relog_time->abs_value_us ) | ||
1249 | { | ||
1250 | handle->oidc->login_identity = strtok(handle->oidc->login_identity, OIDC_COOKIE_HEADER_INFORMATION_KEY); | ||
1251 | handle->oidc->login_identity = GNUNET_strdup(handle->oidc->login_identity); | ||
1252 | } | ||
1253 | } | ||
1254 | else | ||
1255 | { | ||
1256 | handle->oidc->login_identity = NULL; | ||
1257 | } | ||
1258 | } | ||
1259 | } | ||
1260 | |||
1261 | /** | ||
1262 | * Login redirection | ||
1263 | */ | ||
1264 | static void | ||
1265 | login_redirection(void *cls) | ||
1266 | { | ||
1267 | char *login_base_url; | ||
1268 | char *new_redirect; | ||
1269 | struct MHD_Response *resp; | ||
1270 | struct RequestHandle *handle = cls; | ||
1271 | |||
1272 | if ( GNUNET_OK | ||
1273 | == GNUNET_CONFIGURATION_get_value_string (cfg, "identity-rest-plugin", | ||
1274 | "address", &login_base_url) ) | ||
1275 | { | ||
1276 | GNUNET_asprintf (&new_redirect, "%s?%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s", | ||
1277 | login_base_url, | ||
1278 | OIDC_RESPONSE_TYPE_KEY, | ||
1279 | handle->oidc->response_type, | ||
1280 | OIDC_CLIENT_ID_KEY, | ||
1281 | handle->oidc->client_id, | ||
1282 | OIDC_REDIRECT_URI_KEY, | ||
1283 | handle->oidc->redirect_uri, | ||
1284 | OIDC_SCOPE_KEY, | ||
1285 | handle->oidc->scope, | ||
1286 | OIDC_STATE_KEY, | ||
1287 | (NULL != handle->oidc->state) ? handle->oidc->state : "", | ||
1288 | OIDC_NONCE_KEY, | ||
1289 | (NULL != handle->oidc->nonce) ? handle->oidc->nonce : ""); | ||
1290 | resp = GNUNET_REST_create_response (""); | ||
1291 | MHD_add_response_header (resp, "Location", new_redirect); | ||
1292 | GNUNET_free(login_base_url); | ||
1293 | } | ||
1294 | else | ||
1295 | { | ||
1296 | handle->emsg = GNUNET_strdup("server_error"); | ||
1297 | handle->edesc = GNUNET_strdup ("gnunet configuration failed"); | ||
1298 | handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR; | ||
1299 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
1300 | return; | ||
1301 | } | ||
1302 | handle->proc (handle->proc_cls, resp, MHD_HTTP_FOUND); | ||
1303 | GNUNET_free(new_redirect); | ||
1304 | GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle); | ||
1305 | } | ||
1306 | |||
1307 | /** | ||
1209 | * Function called if we had an error in zone-to-name mapping. | 1308 | * Function called if we had an error in zone-to-name mapping. |
1210 | */ | 1309 | */ |
1211 | static void | 1310 | static void |
@@ -1229,18 +1328,20 @@ oidc_ticket_issue_cb (void* cls, | |||
1229 | if (NULL != ticket) { | 1328 | if (NULL != ticket) { |
1230 | ticket_str = GNUNET_STRINGS_data_to_string_alloc (ticket, | 1329 | ticket_str = GNUNET_STRINGS_data_to_string_alloc (ticket, |
1231 | sizeof (struct GNUNET_IDENTITY_PROVIDER_Ticket)); | 1330 | sizeof (struct GNUNET_IDENTITY_PROVIDER_Ticket)); |
1232 | //TODO redirect to address | ||
1233 | GNUNET_asprintf (&redirect_uri, "%s?%s=%s&state=%s", | 1331 | GNUNET_asprintf (&redirect_uri, "%s?%s=%s&state=%s", |
1234 | handle->oidc->redirect_uri, | 1332 | handle->oidc->redirect_uri, |
1235 | handle->oidc->response_type, | 1333 | handle->oidc->response_type, |
1236 | ticket_str, handle->oidc->state); | 1334 | ticket_str, handle->oidc->state); |
1237 | MHD_add_response_header (resp, "Location", redirect_uri); | 1335 | MHD_add_response_header (resp, "Location", redirect_uri); |
1238 | handle->proc (handle->proc_cls, resp, MHD_HTTP_FOUND); | 1336 | handle->proc (handle->proc_cls, resp, MHD_HTTP_FOUND); |
1337 | GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle); | ||
1239 | GNUNET_free (redirect_uri); | 1338 | GNUNET_free (redirect_uri); |
1240 | GNUNET_free (ticket_str); | 1339 | GNUNET_free (ticket_str); |
1340 | return; | ||
1241 | } | 1341 | } |
1242 | //TODO add error | 1342 | handle->emsg = GNUNET_strdup("server_error"); |
1243 | GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle); | 1343 | handle->edesc = GNUNET_strdup("Server cannot generate ticket."); |
1344 | GNUNET_SCHEDULER_add_now (&do_redirect_error, handle); | ||
1244 | } | 1345 | } |
1245 | 1346 | ||
1246 | static void | 1347 | static void |
@@ -1253,7 +1354,6 @@ oidc_collect_finished_cb (void *cls) | |||
1253 | { | 1354 | { |
1254 | handle->emsg = GNUNET_strdup("invalid_scope"); | 1355 | handle->emsg = GNUNET_strdup("invalid_scope"); |
1255 | handle->edesc = GNUNET_strdup("The requested scope is not available."); | 1356 | handle->edesc = GNUNET_strdup("The requested scope is not available."); |
1256 | handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR; | ||
1257 | GNUNET_SCHEDULER_add_now (&do_redirect_error, handle); | 1357 | GNUNET_SCHEDULER_add_now (&do_redirect_error, handle); |
1258 | return; | 1358 | return; |
1259 | } | 1359 | } |
@@ -1268,7 +1368,6 @@ oidc_collect_finished_cb (void *cls) | |||
1268 | 1368 | ||
1269 | /** | 1369 | /** |
1270 | * Collect all attributes for an ego | 1370 | * Collect all attributes for an ego |
1271 | * | ||
1272 | */ | 1371 | */ |
1273 | static void | 1372 | static void |
1274 | oidc_attr_collect (void *cls, | 1373 | oidc_attr_collect (void *cls, |
@@ -1278,6 +1377,7 @@ oidc_attr_collect (void *cls, | |||
1278 | struct RequestHandle *handle = cls; | 1377 | struct RequestHandle *handle = cls; |
1279 | struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *le; | 1378 | struct GNUNET_IDENTITY_ATTRIBUTE_ClaimListEntry *le; |
1280 | char* scope_variables; | 1379 | char* scope_variables; |
1380 | char* scope_variable; | ||
1281 | char delimiter[]=" "; | 1381 | char delimiter[]=" "; |
1282 | 1382 | ||
1283 | if ( (NULL == attr->name) || (NULL == attr->data) ) | 1383 | if ( (NULL == attr->name) || (NULL == attr->data) ) |
@@ -1287,16 +1387,16 @@ oidc_attr_collect (void *cls, | |||
1287 | } | 1387 | } |
1288 | 1388 | ||
1289 | scope_variables = GNUNET_strdup(handle->oidc->scope); | 1389 | scope_variables = GNUNET_strdup(handle->oidc->scope); |
1290 | scope_variables = strtok (scope_variables, delimiter); | 1390 | scope_variable = strtok (scope_variables, delimiter); |
1291 | while (NULL != scope_variables) | 1391 | while (NULL != scope_variable) |
1292 | { | 1392 | { |
1293 | if ( 0 == strcmp (attr->name, scope_variables) ) | 1393 | if ( 0 == strcmp (attr->name, scope_variable) ) |
1294 | { | 1394 | { |
1295 | break; | 1395 | break; |
1296 | } | 1396 | } |
1297 | scope_variables = strtok (NULL, delimiter); | 1397 | scope_variable = strtok (NULL, delimiter); |
1298 | } | 1398 | } |
1299 | if ( NULL == scope_variables ) | 1399 | if ( NULL == scope_variable ) |
1300 | { | 1400 | { |
1301 | GNUNET_IDENTITY_PROVIDER_get_attributes_next (handle->attr_it); | 1401 | GNUNET_IDENTITY_PROVIDER_get_attributes_next (handle->attr_it); |
1302 | return; | 1402 | return; |
@@ -1313,12 +1413,80 @@ oidc_attr_collect (void *cls, | |||
1313 | 1413 | ||
1314 | 1414 | ||
1315 | /** | 1415 | /** |
1416 | * Cookie and Time check | ||
1417 | */ | ||
1418 | static void | ||
1419 | login_check (void *cls) | ||
1420 | { | ||
1421 | struct RequestHandle *handle = cls; | ||
1422 | struct GNUNET_TIME_Absolute current_time, *relog_time; | ||
1423 | struct GNUNET_CRYPTO_EcdsaPublicKey pubkey, ego_pkey; | ||
1424 | struct GNUNET_HashCode cache_key; | ||
1425 | char *identity_cookie; | ||
1426 | |||
1427 | GNUNET_asprintf (&identity_cookie, "Identity=%s", handle->oidc->login_identity); | ||
1428 | GNUNET_CRYPTO_hash (identity_cookie, strlen (identity_cookie), &cache_key); | ||
1429 | GNUNET_free(identity_cookie); | ||
1430 | //No login time for identity -> redirect to login | ||
1431 | if ( GNUNET_YES | ||
1432 | == GNUNET_CONTAINER_multihashmap_contains (OIDC_authorized_identities, | ||
1433 | &cache_key) ) | ||
1434 | { | ||
1435 | relog_time = GNUNET_CONTAINER_multihashmap_get (OIDC_authorized_identities, | ||
1436 | &cache_key); | ||
1437 | current_time = GNUNET_TIME_absolute_get (); | ||
1438 | // 30 min after old login -> redirect to login | ||
1439 | if ( current_time.abs_value_us <= relog_time->abs_value_us ) | ||
1440 | { | ||
1441 | if ( GNUNET_OK | ||
1442 | != GNUNET_CRYPTO_ecdsa_public_key_from_string ( | ||
1443 | handle->oidc->login_identity, | ||
1444 | strlen (handle->oidc->login_identity), &pubkey) ) | ||
1445 | { | ||
1446 | handle->emsg = GNUNET_strdup("invalid_cookie"); | ||
1447 | handle->edesc = GNUNET_strdup( | ||
1448 | "The cookie of a login identity is not valid"); | ||
1449 | GNUNET_SCHEDULER_add_now (&do_redirect_error, handle); | ||
1450 | return; | ||
1451 | } | ||
1452 | // iterate over egos and compare their public key | ||
1453 | for (handle->ego_entry = handle->ego_head; | ||
1454 | NULL != handle->ego_entry; handle->ego_entry = handle->ego_entry->next) | ||
1455 | { | ||
1456 | GNUNET_IDENTITY_ego_get_public_key (handle->ego_entry->ego, &ego_pkey); | ||
1457 | if ( 0 | ||
1458 | == memcmp (&ego_pkey, &pubkey, | ||
1459 | sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)) ) | ||
1460 | { | ||
1461 | handle->priv_key = *GNUNET_IDENTITY_ego_get_private_key ( | ||
1462 | handle->ego_entry->ego); | ||
1463 | handle->resp_object = GNUNET_JSONAPI_document_new (); | ||
1464 | handle->idp = GNUNET_IDENTITY_PROVIDER_connect (cfg); | ||
1465 | handle->attr_list = GNUNET_new( | ||
1466 | struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList); | ||
1467 | handle->attr_it = GNUNET_IDENTITY_PROVIDER_get_attributes_start ( | ||
1468 | handle->idp, &handle->priv_key, &oidc_iteration_error, handle, | ||
1469 | &oidc_attr_collect, handle, &oidc_collect_finished_cb, handle); | ||
1470 | return; | ||
1471 | } | ||
1472 | } | ||
1473 | handle->emsg = GNUNET_strdup("invalid_cookie"); | ||
1474 | handle->edesc = GNUNET_strdup( | ||
1475 | "The cookie of the login identity is not valid"); | ||
1476 | GNUNET_SCHEDULER_add_now (&do_redirect_error, handle); | ||
1477 | return; | ||
1478 | } | ||
1479 | //GNUNET_free(relog_time); | ||
1480 | } | ||
1481 | } | ||
1482 | |||
1483 | /** | ||
1316 | * Create a response with requested records | 1484 | * Create a response with requested records |
1317 | * | 1485 | * |
1318 | * @param handle the RequestHandle | 1486 | * @param handle the RequestHandle |
1319 | */ | 1487 | */ |
1320 | static void | 1488 | static void |
1321 | oidc_namestore_iteration_callback ( | 1489 | namestore_iteration_callback ( |
1322 | void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key, | 1490 | void *cls, const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_key, |
1323 | const char *rname, unsigned int rd_len, | 1491 | const char *rname, unsigned int rd_len, |
1324 | const struct GNUNET_GNSRECORD_Data *rd) | 1492 | const struct GNUNET_GNSRECORD_Data *rd) |
@@ -1348,7 +1516,7 @@ oidc_namestore_iteration_callback ( | |||
1348 | if ( 0 == memcmp (&login_identity_pkey, ¤t_zone_pkey, | 1516 | if ( 0 == memcmp (&login_identity_pkey, ¤t_zone_pkey, |
1349 | sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)) ) | 1517 | sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)) ) |
1350 | { | 1518 | { |
1351 | handle->oidc->client_trusted = GNUNET_YES; | 1519 | handle->oidc->is_client_trusted = GNUNET_YES; |
1352 | } | 1520 | } |
1353 | } | 1521 | } |
1354 | } | 1522 | } |
@@ -1357,7 +1525,7 @@ oidc_namestore_iteration_callback ( | |||
1357 | if ( 0 == memcmp (rd[i].data, &handle->oidc->client_pkey, | 1525 | if ( 0 == memcmp (rd[i].data, &handle->oidc->client_pkey, |
1358 | sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)) ) | 1526 | sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)) ) |
1359 | { | 1527 | { |
1360 | handle->oidc->client_trusted = GNUNET_YES; | 1528 | handle->oidc->is_client_trusted = GNUNET_YES; |
1361 | } | 1529 | } |
1362 | } | 1530 | } |
1363 | } | 1531 | } |
@@ -1371,20 +1539,14 @@ oidc_namestore_iteration_callback ( | |||
1371 | * | 1539 | * |
1372 | * @param cls the `struct RequestHandle` | 1540 | * @param cls the `struct RequestHandle` |
1373 | */ | 1541 | */ |
1374 | static void oidc_namestore_iteration_finished (void *cls) | 1542 | static void namestore_iteration_finished_GET (void *cls) |
1375 | { | 1543 | { |
1376 | struct RequestHandle *handle = cls; | 1544 | struct RequestHandle *handle = cls; |
1377 | struct MHD_Response *resp; | ||
1378 | struct GNUNET_HashCode cache_key; | 1545 | struct GNUNET_HashCode cache_key; |
1379 | struct GNUNET_CRYPTO_EcdsaPublicKey pubkey, ego_pkey; | ||
1380 | struct GNUNET_TIME_Absolute current_time, *relog_time; | ||
1381 | 1546 | ||
1382 | char *expected_redirect_uri; | 1547 | char *expected_redirect_uri; |
1383 | char *expected_scope; | 1548 | char *expected_scope; |
1384 | char delimiter[]=" "; | 1549 | char delimiter[]=" "; |
1385 | char *identity_cookie; | ||
1386 | char *login_base_url; | ||
1387 | char *new_redirect; | ||
1388 | int number_of_ignored_parameter, iterator; | 1550 | int number_of_ignored_parameter, iterator; |
1389 | 1551 | ||
1390 | 1552 | ||
@@ -1393,15 +1555,15 @@ static void oidc_namestore_iteration_finished (void *cls) | |||
1393 | if(NULL != handle->ego_entry){ | 1555 | if(NULL != handle->ego_entry){ |
1394 | handle->priv_key = *GNUNET_IDENTITY_ego_get_private_key (handle->ego_entry->ego); | 1556 | handle->priv_key = *GNUNET_IDENTITY_ego_get_private_key (handle->ego_entry->ego); |
1395 | handle->namestore_handle_it = GNUNET_NAMESTORE_zone_iteration_start (handle->namestore_handle, &handle->priv_key, | 1557 | handle->namestore_handle_it = GNUNET_NAMESTORE_zone_iteration_start (handle->namestore_handle, &handle->priv_key, |
1396 | &oidc_iteration_error, handle, &oidc_namestore_iteration_callback, handle, | 1558 | &oidc_iteration_error, handle, &namestore_iteration_callback, handle, |
1397 | &oidc_namestore_iteration_finished, handle); | 1559 | &namestore_iteration_finished_GET, handle); |
1398 | return; | 1560 | return; |
1399 | } | 1561 | } |
1400 | if (GNUNET_YES != handle->oidc->client_trusted) | 1562 | if (GNUNET_NO == handle->oidc->is_client_trusted) |
1401 | { | 1563 | { |
1402 | handle->emsg = GNUNET_strdup("unauthorized_client"); | 1564 | handle->emsg = GNUNET_strdup("unauthorized_client"); |
1403 | //TODO rewrite error | 1565 | handle->edesc = GNUNET_strdup("The client is not authorized to request an " |
1404 | handle->edesc = GNUNET_strdup("Client is not trusted."); | 1566 | "authorization code using this method."); |
1405 | GNUNET_SCHEDULER_add_now (&do_error, handle); | 1567 | GNUNET_SCHEDULER_add_now (&do_error, handle); |
1406 | return; | 1568 | return; |
1407 | } | 1569 | } |
@@ -1525,144 +1687,29 @@ static void oidc_namestore_iteration_finished (void *cls) | |||
1525 | 1687 | ||
1526 | if( NULL != handle->oidc->login_identity ) | 1688 | if( NULL != handle->oidc->login_identity ) |
1527 | { | 1689 | { |
1528 | GNUNET_asprintf(&identity_cookie,"Identity=%s",handle->oidc->login_identity); | 1690 | GNUNET_SCHEDULER_add_now(&login_check,handle); |
1529 | GNUNET_CRYPTO_hash (identity_cookie, strlen (identity_cookie), &cache_key); | ||
1530 | GNUNET_free(identity_cookie); | ||
1531 | //No login time for identity -> redirect to login | ||
1532 | if ( GNUNET_YES | ||
1533 | == GNUNET_CONTAINER_multihashmap_contains (OIDC_authorized_identities, | ||
1534 | &cache_key) ) | ||
1535 | { | ||
1536 | relog_time = GNUNET_CONTAINER_multihashmap_get ( | ||
1537 | OIDC_authorized_identities, &cache_key); | ||
1538 | |||
1539 | current_time = GNUNET_TIME_absolute_get(); | ||
1540 | |||
1541 | //GNUNET_CONTAINER_multihashmap_remove_all(OIDC_authorized_identities, &cache_key); | ||
1542 | // 30 min after old login -> redirect to login | ||
1543 | if ( current_time.abs_value_us <= relog_time->abs_value_us ) | ||
1544 | { | ||
1545 | if ( GNUNET_OK != GNUNET_CRYPTO_ecdsa_public_key_from_string ( | ||
1546 | handle->oidc->login_identity, | ||
1547 | strlen (handle->oidc->login_identity), &pubkey) ) | ||
1548 | { | ||
1549 | handle->emsg=GNUNET_strdup("invalid_cookie"); | ||
1550 | handle->edesc=GNUNET_strdup("The cookie of a login identity is not valid"); | ||
1551 | GNUNET_SCHEDULER_add_now (&do_redirect_error, handle); | ||
1552 | return; | ||
1553 | } | ||
1554 | // iterate over egos and compare their public key | ||
1555 | for (handle->ego_entry = handle->ego_head; | ||
1556 | NULL != handle->ego_entry; handle->ego_entry = handle->ego_entry->next) | ||
1557 | { | ||
1558 | GNUNET_IDENTITY_ego_get_public_key( handle->ego_entry->ego, &ego_pkey ); | ||
1559 | if ( 0 == memcmp(&ego_pkey,&pubkey, sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey))) | ||
1560 | { | ||
1561 | handle->priv_key = *GNUNET_IDENTITY_ego_get_private_key ( | ||
1562 | handle->ego_entry->ego); | ||
1563 | handle->resp_object = GNUNET_JSONAPI_document_new (); | ||
1564 | handle->idp = GNUNET_IDENTITY_PROVIDER_connect (cfg); | ||
1565 | handle->attr_list = GNUNET_new( | ||
1566 | struct GNUNET_IDENTITY_ATTRIBUTE_ClaimList); | ||
1567 | handle->attr_it = GNUNET_IDENTITY_PROVIDER_get_attributes_start ( | ||
1568 | handle->idp, &handle->priv_key, &oidc_iteration_error, handle, | ||
1569 | &oidc_attr_collect, handle, &oidc_collect_finished_cb, handle); | ||
1570 | return; | ||
1571 | } | ||
1572 | } | ||
1573 | handle->emsg=GNUNET_strdup("invalid_cookie"); | ||
1574 | handle->edesc = GNUNET_strdup( | ||
1575 | "The cookie of a login identity is not valid"); | ||
1576 | GNUNET_SCHEDULER_add_now (&do_redirect_error, handle); | ||
1577 | return; | ||
1578 | } | ||
1579 | //GNUNET_free(relog_time); | ||
1580 | } | ||
1581 | } | ||
1582 | |||
1583 | |||
1584 | // login redirection | ||
1585 | if ( GNUNET_OK | ||
1586 | == GNUNET_CONFIGURATION_get_value_string (cfg, "identity-rest-plugin", | ||
1587 | "address", &login_base_url) ) | ||
1588 | { | ||
1589 | GNUNET_asprintf (&new_redirect, "%s?%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s", | ||
1590 | login_base_url, | ||
1591 | OIDC_RESPONSE_TYPE_KEY, | ||
1592 | handle->oidc->response_type, | ||
1593 | OIDC_CLIENT_ID_KEY, | ||
1594 | handle->oidc->client_id, | ||
1595 | OIDC_REDIRECT_URI_KEY, | ||
1596 | handle->oidc->redirect_uri, | ||
1597 | OIDC_SCOPE_KEY, | ||
1598 | handle->oidc->scope, | ||
1599 | OIDC_STATE_KEY, | ||
1600 | (NULL != handle->oidc->state) ? handle->oidc->state : "", | ||
1601 | OIDC_NONCE_KEY, | ||
1602 | (NULL != handle->oidc->nonce) ? handle->oidc->nonce : ""); | ||
1603 | resp = GNUNET_REST_create_response (""); | ||
1604 | MHD_add_response_header (resp, "Location", new_redirect); | ||
1605 | GNUNET_free(login_base_url); | ||
1606 | } | ||
1607 | else | ||
1608 | { | ||
1609 | handle->emsg = GNUNET_strdup("No server configuration"); | ||
1610 | handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR; | ||
1611 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
1612 | return; | 1691 | return; |
1613 | } | 1692 | } |
1614 | handle->proc (handle->proc_cls, resp, MHD_HTTP_FOUND); | 1693 | |
1615 | GNUNET_free(new_redirect); | 1694 | GNUNET_SCHEDULER_add_now(&login_redirection,handle); |
1616 | GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle); | ||
1617 | } | 1695 | } |
1618 | 1696 | ||
1619 | /** | 1697 | /** |
1620 | * Respond to authorization GET request | 1698 | * Responds to authorization GET request |
1621 | * | 1699 | * |
1622 | * @param con_handle the connection handle | 1700 | * @param con_handle the connection handle |
1623 | * @param url the url | 1701 | * @param url the url |
1624 | * @param cls the RequestHandle | 1702 | * @param cls the RequestHandle |
1625 | */ | 1703 | */ |
1626 | static void | 1704 | static void |
1627 | authorize_get_cont (struct GNUNET_REST_RequestHandle *con_handle, | 1705 | authorize_GET_cont (struct GNUNET_REST_RequestHandle *con_handle, |
1628 | const char* url, | 1706 | const char* url, |
1629 | void *cls) | 1707 | void *cls) |
1630 | { | 1708 | { |
1631 | struct RequestHandle *handle = cls; | 1709 | struct RequestHandle *handle = cls; |
1632 | struct GNUNET_HashCode cache_key; | 1710 | struct GNUNET_HashCode cache_key; |
1633 | char* cookies; | ||
1634 | char delimiter[] = "; "; | ||
1635 | 1711 | ||
1636 | //gets identity of login try with cookie | 1712 | cookie_identity_interpretation(handle); |
1637 | GNUNET_CRYPTO_hash (OIDC_COOKIE_HEADER_KEY, strlen (OIDC_COOKIE_HEADER_KEY), | ||
1638 | &cache_key); | ||
1639 | if ( GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (handle->rest_handle->header_param_map, | ||
1640 | &cache_key) ) | ||
1641 | { | ||
1642 | //splits cookies and find 'Identity' cookie | ||
1643 | cookies = GNUNET_CONTAINER_multihashmap_get ( handle->rest_handle->header_param_map, &cache_key); | ||
1644 | handle->oidc->login_identity = strtok(cookies, delimiter); | ||
1645 | |||
1646 | while ( NULL != handle->oidc->login_identity ) | ||
1647 | { | ||
1648 | if ( NULL != strstr (handle->oidc->login_identity, OIDC_COOKIE_HEADER_INFORMATION_KEY) ) | ||
1649 | { | ||
1650 | break; | ||
1651 | } | ||
1652 | handle->oidc->login_identity = strtok (NULL, delimiter); | ||
1653 | } | ||
1654 | GNUNET_CRYPTO_hash (handle->oidc->login_identity, strlen (handle->oidc->login_identity), | ||
1655 | &cache_key); | ||
1656 | if ( GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains (OIDC_authorized_identities, &cache_key) ) | ||
1657 | { | ||
1658 | handle->oidc->login_identity = strtok(handle->oidc->login_identity, OIDC_COOKIE_HEADER_INFORMATION_KEY); | ||
1659 | handle->oidc->login_identity = GNUNET_strdup(handle->oidc->login_identity); | ||
1660 | } | ||
1661 | else | ||
1662 | { | ||
1663 | handle->oidc->login_identity = NULL; | ||
1664 | } | ||
1665 | } | ||
1666 | 1713 | ||
1667 | //RECOMMENDED value: state - REQUIRED for answers | 1714 | //RECOMMENDED value: state - REQUIRED for answers |
1668 | GNUNET_CRYPTO_hash (OIDC_STATE_KEY, strlen (OIDC_STATE_KEY), &cache_key); | 1715 | GNUNET_CRYPTO_hash (OIDC_STATE_KEY, strlen (OIDC_STATE_KEY), &cache_key); |
@@ -1695,7 +1742,6 @@ authorize_get_cont (struct GNUNET_REST_RequestHandle *con_handle, | |||
1695 | strlen (handle->oidc->client_id), | 1742 | strlen (handle->oidc->client_id), |
1696 | &handle->oidc->client_pkey) ) | 1743 | &handle->oidc->client_pkey) ) |
1697 | { | 1744 | { |
1698 | //TODO rewrite error? | ||
1699 | handle->emsg = GNUNET_strdup("unauthorized_client"); | 1745 | handle->emsg = GNUNET_strdup("unauthorized_client"); |
1700 | handle->edesc = GNUNET_strdup("The client is not authorized to request an " | 1746 | handle->edesc = GNUNET_strdup("The client is not authorized to request an " |
1701 | "authorization code using this method."); | 1747 | "authorization code using this method."); |
@@ -1717,297 +1763,238 @@ authorize_get_cont (struct GNUNET_REST_RequestHandle *con_handle, | |||
1717 | 1763 | ||
1718 | handle->ego_entry = handle->ego_head; | 1764 | handle->ego_entry = handle->ego_head; |
1719 | handle->priv_key = *GNUNET_IDENTITY_ego_get_private_key (handle->ego_head->ego); | 1765 | handle->priv_key = *GNUNET_IDENTITY_ego_get_private_key (handle->ego_head->ego); |
1720 | handle->oidc->client_trusted = GNUNET_NO; | 1766 | handle->oidc->is_client_trusted = GNUNET_NO; |
1721 | 1767 | ||
1722 | // Checks if client_id is valid: | 1768 | // Checks if client_id is valid: |
1723 | handle->namestore_handle_it = GNUNET_NAMESTORE_zone_iteration_start ( | 1769 | handle->namestore_handle_it = GNUNET_NAMESTORE_zone_iteration_start ( |
1724 | handle->namestore_handle, &handle->priv_key, &oidc_iteration_error, | 1770 | handle->namestore_handle, &handle->priv_key, &oidc_iteration_error, |
1725 | handle, &oidc_namestore_iteration_callback, handle, | 1771 | handle, &namestore_iteration_callback, handle, |
1726 | &oidc_namestore_iteration_finished, handle); | 1772 | &namestore_iteration_finished_GET, handle); |
1773 | } | ||
1774 | |||
1775 | /** | ||
1776 | * Iteration over all results finished, build final | ||
1777 | * response. | ||
1778 | * | ||
1779 | * @param cls the `struct RequestHandle` | ||
1780 | */ | ||
1781 | static void namestore_iteration_finished_POST (void *cls) | ||
1782 | { | ||
1783 | struct RequestHandle *handle = cls; | ||
1784 | json_t *cache_object; | ||
1785 | char *expected_redirect_uri; | ||
1786 | char *expected_scope; | ||
1787 | char delimiter[]=" "; | ||
1788 | int number_of_ignored_parameter, iterator; | ||
1789 | |||
1790 | |||
1791 | handle->ego_entry = handle->ego_entry->next; | ||
1792 | |||
1793 | if(NULL != handle->ego_entry){ | ||
1794 | handle->priv_key = *GNUNET_IDENTITY_ego_get_private_key (handle->ego_entry->ego); | ||
1795 | handle->namestore_handle_it = GNUNET_NAMESTORE_zone_iteration_start (handle->namestore_handle, &handle->priv_key, | ||
1796 | &oidc_iteration_error, handle, &namestore_iteration_callback, handle, | ||
1797 | &namestore_iteration_finished_POST, handle); | ||
1798 | return; | ||
1799 | } | ||
1800 | if (GNUNET_YES != handle->oidc->is_client_trusted) | ||
1801 | { | ||
1802 | handle->emsg = GNUNET_strdup("unauthorized_client"); | ||
1803 | handle->edesc = GNUNET_strdup("The client is not authorized to request an " | ||
1804 | "authorization code using this method."); | ||
1805 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
1806 | return; | ||
1807 | } | ||
1808 | |||
1809 | // REQUIRED value: redirect_uri | ||
1810 | cache_object = json_object_get (handle->oidc->post_object, OIDC_REDIRECT_URI_KEY); | ||
1811 | if ( NULL == cache_object || !json_is_string(cache_object) ) | ||
1812 | { | ||
1813 | handle->emsg=GNUNET_strdup("invalid_request"); | ||
1814 | handle->edesc=GNUNET_strdup("Missing parameter: redirect_uri"); | ||
1815 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
1816 | return; | ||
1817 | } | ||
1818 | handle->oidc->redirect_uri = json_string_value (cache_object); | ||
1819 | |||
1820 | GNUNET_asprintf (&expected_redirect_uri, "https://%s.zkey", handle->oidc->client_id); | ||
1821 | // verify the redirect uri matches https://<client_id>.zkey[/xyz] | ||
1822 | if( 0 != strncmp( expected_redirect_uri, handle->oidc->redirect_uri, strlen(expected_redirect_uri)) ) | ||
1823 | { | ||
1824 | handle->emsg=GNUNET_strdup("invalid_request"); | ||
1825 | handle->edesc=GNUNET_strdup("Invalid redirect_uri"); | ||
1826 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
1827 | GNUNET_free(expected_redirect_uri); | ||
1828 | return; | ||
1829 | } | ||
1830 | handle->oidc->redirect_uri = GNUNET_strdup(handle->oidc->redirect_uri); | ||
1831 | GNUNET_free(expected_redirect_uri); | ||
1832 | |||
1833 | // REQUIRED value: response_type | ||
1834 | cache_object = json_object_get (handle->oidc->post_object, OIDC_RESPONSE_TYPE_KEY); | ||
1835 | if ( NULL == cache_object || !json_is_string(cache_object) ) | ||
1836 | { | ||
1837 | handle->emsg=GNUNET_strdup("invalid_request"); | ||
1838 | handle->edesc=GNUNET_strdup("Missing parameter: response_type"); | ||
1839 | GNUNET_SCHEDULER_add_now (&do_redirect_error, handle); | ||
1840 | return; | ||
1841 | } | ||
1842 | handle->oidc->response_type = json_string_value (cache_object); | ||
1843 | handle->oidc->response_type = GNUNET_strdup (handle->oidc->response_type); | ||
1844 | |||
1845 | // REQUIRED value: scope | ||
1846 | cache_object = json_object_get (handle->oidc->post_object, OIDC_SCOPE_KEY); | ||
1847 | if ( NULL == cache_object || !json_is_string(cache_object) ) | ||
1848 | { | ||
1849 | handle->emsg=GNUNET_strdup("invalid_request"); | ||
1850 | handle->edesc=GNUNET_strdup("Missing parameter: scope"); | ||
1851 | GNUNET_SCHEDULER_add_now (&do_redirect_error, handle); | ||
1852 | return; | ||
1853 | } | ||
1854 | handle->oidc->scope = json_string_value (cache_object); | ||
1855 | handle->oidc->scope = GNUNET_strdup(handle->oidc->scope); | ||
1856 | |||
1857 | //OPTIONAL value: nonce | ||
1858 | cache_object = json_object_get (handle->oidc->post_object, OIDC_NONCE_KEY); | ||
1859 | if ( NULL != cache_object && json_is_string(cache_object) ) | ||
1860 | { | ||
1861 | handle->oidc->nonce = json_string_value (cache_object); | ||
1862 | //TODO: what do we do with the nonce? | ||
1863 | handle->oidc->nonce = GNUNET_strdup (handle->oidc->nonce); | ||
1864 | } | ||
1865 | |||
1866 | //TODO check other values and use them accordingly | ||
1867 | number_of_ignored_parameter = sizeof(OIDC_ignored_parameter_array) / sizeof(char *); | ||
1868 | for( iterator = 0; iterator < number_of_ignored_parameter; iterator++ ) | ||
1869 | { | ||
1870 | cache_object = json_object_get (handle->oidc->post_object, OIDC_ignored_parameter_array[iterator]); | ||
1871 | if( NULL != cache_object && json_is_string(cache_object) ) | ||
1872 | { | ||
1873 | handle->emsg=GNUNET_strdup("access_denied"); | ||
1874 | GNUNET_asprintf (&handle->edesc, "Server will not handle parameter: %s", | ||
1875 | OIDC_ignored_parameter_array[iterator]); | ||
1876 | GNUNET_SCHEDULER_add_now (&do_redirect_error, handle); | ||
1877 | return; | ||
1878 | } | ||
1879 | } | ||
1880 | |||
1881 | // Checks if response_type is 'code' | ||
1882 | if( 0 != strcmp( handle->oidc->response_type, OIDC_EXPECTED_AUTHORIZATION_RESPONSE_TYPE ) ) | ||
1883 | { | ||
1884 | handle->emsg=GNUNET_strdup("unsupported_response_type"); | ||
1885 | handle->edesc=GNUNET_strdup("The authorization server does not support " | ||
1886 | "obtaining this authorization code."); | ||
1887 | GNUNET_SCHEDULER_add_now (&do_redirect_error, handle); | ||
1888 | return; | ||
1889 | } | ||
1890 | |||
1891 | // Checks if scope contains 'openid' | ||
1892 | expected_scope = GNUNET_strdup(handle->oidc->scope); | ||
1893 | expected_scope = strtok (expected_scope, delimiter); | ||
1894 | while (NULL != expected_scope) | ||
1895 | { | ||
1896 | if ( 0 == strcmp (OIDC_EXPECTED_AUTHORIZATION_SCOPE, expected_scope) ) | ||
1897 | { | ||
1898 | break; | ||
1899 | } | ||
1900 | expected_scope = strtok (NULL, delimiter); | ||
1901 | } | ||
1902 | if (NULL == expected_scope) | ||
1903 | { | ||
1904 | handle->emsg = GNUNET_strdup("invalid_scope"); | ||
1905 | handle->edesc=GNUNET_strdup("The requested scope is invalid, unknown, or " | ||
1906 | "malformed."); | ||
1907 | GNUNET_SCHEDULER_add_now (&do_redirect_error, handle); | ||
1908 | return; | ||
1909 | } | ||
1910 | |||
1911 | GNUNET_free(expected_scope); | ||
1912 | |||
1913 | if( NULL != handle->oidc->login_identity ) | ||
1914 | { | ||
1915 | GNUNET_SCHEDULER_add_now(&login_check,handle); | ||
1916 | return; | ||
1917 | } | ||
1918 | |||
1919 | GNUNET_SCHEDULER_add_now(&login_redirection,handle); | ||
1727 | } | 1920 | } |
1728 | 1921 | ||
1729 | ///** | ||
1730 | // * Respond to authorization POST request | ||
1731 | // * | ||
1732 | // * @param con_handle the connection handle | ||
1733 | // * @param url the url | ||
1734 | // * @param cls the RequestHandle | ||
1735 | // */ | ||
1736 | //static void | ||
1737 | //authorize_post_cont (struct GNUNET_REST_RequestHandle *con_handle, | ||
1738 | // const char* url, | ||
1739 | // void *cls) | ||
1740 | //{ | ||
1741 | // /** The Authorization Server MUST validate all the OAuth 2.0 parameters | ||
1742 | // * according to the OAuth 2.0 specification. | ||
1743 | // */ | ||
1744 | // /** | ||
1745 | // * If the sub (subject) Claim is requested with a specific value for the | ||
1746 | // * ID Token, the Authorization Server MUST only send a positive response | ||
1747 | // * if the End-User identified by that sub value has an active session with | ||
1748 | // * the Authorization Server or has been Authenticated as a result of the | ||
1749 | // * request. The Authorization Server MUST NOT reply with an ID Token or | ||
1750 | // * Access Token for a different user, even if they have an active session | ||
1751 | // * with the Authorization Server. Such a request can be made either using | ||
1752 | // * an id_token_hint parameter or by requesting a specific Claim Value as | ||
1753 | // * described in Section 5.5.1, if the claims parameter is supported by | ||
1754 | // * the implementation. | ||
1755 | // */ | ||
1756 | // | ||
1757 | // struct MHD_Response *resp; | ||
1758 | // struct RequestHandle *handle = cls; | ||
1759 | // const char *response_type; | ||
1760 | // const char *client_id; | ||
1761 | // char *scope; | ||
1762 | // const char *redirect_uri; | ||
1763 | // const char *state = NULL; | ||
1764 | // const char *nonce = NULL; | ||
1765 | // struct GNUNET_TIME_Absolute current_time, *relog_time; | ||
1766 | // char *login_base_url; | ||
1767 | // char *new_redirect; | ||
1768 | // char *expected_redirect_uri; | ||
1769 | // json_t *cache_object; | ||
1770 | // const struct GNUNET_CRYPTO_EcdsaPrivateKey *zone_pkey; | ||
1771 | // struct GNUNET_CRYPTO_EcdsaPublicKey pubkey; | ||
1772 | // struct GNUNET_HashCode cache_key; | ||
1773 | // int number_of_ignored_parameter, iterator; | ||
1774 | // | ||
1775 | // json_t *root; | ||
1776 | // json_error_t error; | ||
1777 | // root = json_loads (handle->rest_handle->data, 0, &error); | ||
1778 | // | ||
1779 | // // REQUIRED value: client_id | ||
1780 | // cache_object = json_object_get (root, OIDC_CLIENT_ID_KEY); | ||
1781 | // if( NULL==cache_object || !json_is_string(cache_object)) | ||
1782 | // { | ||
1783 | // handle->emsg=GNUNET_strdup("invalid_request"); | ||
1784 | // handle->edesc=GNUNET_strdup("Missing parameter: client_id"); | ||
1785 | // GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
1786 | // return; | ||
1787 | // } | ||
1788 | // client_id = json_string_value(cache_object); | ||
1789 | // if ( GNUNET_OK | ||
1790 | // != GNUNET_CRYPTO_ecdsa_public_key_from_string (client_id, | ||
1791 | // strlen (client_id), | ||
1792 | // &pubkey) ) | ||
1793 | // { | ||
1794 | // handle->emsg=GNUNET_strdup("unauthorized_client"); | ||
1795 | // handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR; | ||
1796 | // GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
1797 | // } | ||
1798 | // | ||
1799 | // // Checks if client_id is valid: | ||
1800 | // handle->namestore_handle = GNUNET_NAMESTORE_connect(cfg); | ||
1801 | // zone_pkey = GNUNET_IDENTITY_ego_get_private_key (handle->ego_entry->ego); | ||
1802 | // //TODO: fix | ||
1803 | //// GNUNET_NAMESTORE_zone_to_name (handle->namestore_handle, zone_pkey, &pubkey, | ||
1804 | //// zone_to_name_error, handle, zone_to_name_cb, | ||
1805 | //// handle); | ||
1806 | // | ||
1807 | // // REQUIRED value: redirect_uri | ||
1808 | // cache_object = json_object_get (root, OIDC_REDIRECT_URI_KEY); | ||
1809 | // if( NULL==cache_object || !json_is_string(cache_object)) | ||
1810 | // { | ||
1811 | // handle->emsg=GNUNET_strdup("invalid_request"); | ||
1812 | // handle->edesc=GNUNET_strdup("Missing parameter: redirect_uri"); | ||
1813 | // GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
1814 | // return; | ||
1815 | // } | ||
1816 | // redirect_uri = json_string_value(cache_object); | ||
1817 | // | ||
1818 | // GNUNET_asprintf (&expected_redirect_uri, "https://%s.zkey", client_id); | ||
1819 | // | ||
1820 | // // verify the redirect uri matches https://<client_id>.zkey[/xyz] | ||
1821 | // if( 0 != strncmp( expected_redirect_uri, redirect_uri, strlen(expected_redirect_uri)) ) | ||
1822 | // { | ||
1823 | // handle->emsg=GNUNET_strdup("invalid_request"); | ||
1824 | // handle->edesc=GNUNET_strdup("Invalid redirect_uri"); | ||
1825 | // GNUNET_free(expected_redirect_uri); | ||
1826 | // GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
1827 | // return; | ||
1828 | // } | ||
1829 | // handle->oidc->redirect_uri = GNUNET_strdup(redirect_uri); | ||
1830 | // | ||
1831 | // // REQUIRED value: response_type | ||
1832 | // cache_object = json_object_get (root, OIDC_RESPONSE_TYPE_KEY); | ||
1833 | // if( NULL==cache_object || !json_is_string(cache_object)) | ||
1834 | // { | ||
1835 | // handle->emsg=GNUNET_strdup("invalid_request"); | ||
1836 | // handle->edesc=GNUNET_strdup("Missing parameter: response_type"); | ||
1837 | // GNUNET_SCHEDULER_add_now (&do_redirect_error, handle); | ||
1838 | // return; | ||
1839 | // } | ||
1840 | // response_type = json_string_value(cache_object); | ||
1841 | // | ||
1842 | // // REQUIRED value: scope | ||
1843 | // cache_object = json_object_get (root, OIDC_SCOPE_KEY); | ||
1844 | // if( NULL==cache_object || !json_is_string(cache_object)) | ||
1845 | // { | ||
1846 | // handle->emsg=GNUNET_strdup("invalid_request"); | ||
1847 | // handle->edesc=GNUNET_strdup("Missing parameter: scope"); | ||
1848 | // GNUNET_SCHEDULER_add_now (&do_redirect_error, handle); | ||
1849 | // return; | ||
1850 | // } | ||
1851 | // scope = json_string_value(cache_object); | ||
1852 | // | ||
1853 | // //RECOMMENDED value: state | ||
1854 | // cache_object = json_object_get (root, OIDC_STATE_KEY); | ||
1855 | // if( NULL!=cache_object || json_is_string(cache_object)) | ||
1856 | // { | ||
1857 | // state = json_string_value(cache_object); | ||
1858 | // } | ||
1859 | // | ||
1860 | // //OPTIONAL value: nonce | ||
1861 | // cache_object = json_object_get (root, OIDC_NONCE_KEY); | ||
1862 | // if( NULL!=cache_object || json_is_string(cache_object)) | ||
1863 | // { | ||
1864 | // nonce = json_string_value(cache_object); | ||
1865 | // } | ||
1866 | // | ||
1867 | // //TODO check other values and use them accordingly | ||
1868 | // number_of_ignored_parameter = sizeof(OIDC_ignored_parameter_array) / sizeof(char *); | ||
1869 | // for( iterator = 0; iterator < number_of_ignored_parameter; iterator++ ) | ||
1870 | // { | ||
1871 | // cache_object = json_object_get (root, OIDC_ignored_parameter_array[iterator]); | ||
1872 | // if(json_is_string(cache_object)) | ||
1873 | // { | ||
1874 | // handle->emsg=GNUNET_strdup("access_denied"); | ||
1875 | // GNUNET_asprintf (&handle->edesc, "Server will not handle parameter: %s", | ||
1876 | // OIDC_ignored_parameter_array[iterator]); | ||
1877 | // GNUNET_SCHEDULER_add_now (&do_redirect_error, handle); | ||
1878 | // return; | ||
1879 | // } | ||
1880 | // } | ||
1881 | // | ||
1882 | // // Checks if response_type is 'code' | ||
1883 | // if( 0 != strcmp( response_type, OIDC_EXPECTED_AUTHORIZATION_RESPONSE_TYPE ) ) | ||
1884 | // { | ||
1885 | // handle->emsg=GNUNET_strdup("unsupported_response_type"); | ||
1886 | // handle->edesc=GNUNET_strdup("The authorization server does not support " | ||
1887 | // "obtaining this authorization code."); | ||
1888 | // GNUNET_SCHEDULER_add_now (&do_redirect_error, handle); | ||
1889 | // return; | ||
1890 | // } | ||
1891 | // // Checks if scope contains 'openid' | ||
1892 | // if( NULL == strstr( scope, OIDC_EXPECTED_AUTHORIZATION_SCOPE ) ) | ||
1893 | // { | ||
1894 | // handle->emsg=GNUNET_strdup("invalid_scope"); | ||
1895 | // handle->edesc=GNUNET_strdup("The requested scope is invalid, unknown, or " | ||
1896 | // "malformed."); | ||
1897 | // GNUNET_SCHEDULER_add_now (&do_redirect_error, handle); | ||
1898 | // return; | ||
1899 | // } | ||
1900 | // | ||
1901 | // | ||
1902 | // GNUNET_CRYPTO_hash (OIDC_COOKIE_HEADER_KEY, strlen (OIDC_COOKIE_HEADER_KEY), | ||
1903 | // &cache_key); | ||
1904 | // //No identity-cookie -> redirect to login | ||
1905 | // if ( GNUNET_YES | ||
1906 | // == GNUNET_CONTAINER_multihashmap_contains (con_handle->header_param_map, | ||
1907 | // &cache_key) ) | ||
1908 | // { | ||
1909 | // //split cookies and find 'Identity' cookie | ||
1910 | // char* cookies = GNUNET_CONTAINER_multihashmap_get ( | ||
1911 | // con_handle->header_param_map, &cache_key); | ||
1912 | // char delimiter[] = "; "; | ||
1913 | // char *identity_cookie; | ||
1914 | // identity_cookie = strtok(cookies, delimiter); | ||
1915 | // | ||
1916 | // while ( NULL != identity_cookie ) | ||
1917 | // { | ||
1918 | // if ( NULL != strstr (identity_cookie, OIDC_COOKIE_HEADER_INFORMATION_KEY) ) | ||
1919 | // { | ||
1920 | // break; | ||
1921 | // } | ||
1922 | // identity_cookie = strtok (NULL, delimiter); | ||
1923 | // } | ||
1924 | // GNUNET_CRYPTO_hash (identity_cookie, strlen (identity_cookie), &cache_key); | ||
1925 | // | ||
1926 | // //No login time for identity -> redirect to login | ||
1927 | // if ( GNUNET_YES | ||
1928 | // == GNUNET_CONTAINER_multihashmap_contains (OIDC_authorized_identities, | ||
1929 | // &cache_key) ) | ||
1930 | // { | ||
1931 | // relog_time = GNUNET_CONTAINER_multihashmap_get ( | ||
1932 | // OIDC_authorized_identities, &cache_key); | ||
1933 | // | ||
1934 | // current_time = GNUNET_TIME_absolute_get(); | ||
1935 | // | ||
1936 | // GNUNET_CONTAINER_multihashmap_remove_all(OIDC_authorized_identities, &cache_key); | ||
1937 | // // 30 min after old login -> redirect to login | ||
1938 | // if ( current_time.abs_value_us <= relog_time->abs_value_us ) | ||
1939 | // { | ||
1940 | // resp = GNUNET_REST_create_response (""); | ||
1941 | // | ||
1942 | // GNUNET_CRYPTO_ecdsa_public_key_from_string (identity_cookie, | ||
1943 | // strlen (identity_cookie), | ||
1944 | // &pubkey); | ||
1945 | // | ||
1946 | // // iterate over egos and compare their public key | ||
1947 | //// GNUNET_IDENTITY_PROVIDER_get_attributes_start | ||
1948 | // // iterate over scope variables | ||
1949 | // char delimiter[] = " "; | ||
1950 | // char *scope_attribute; | ||
1951 | // scope_attribute = strtok(scope, delimiter); | ||
1952 | // | ||
1953 | // while ( NULL != scope_attribute ) | ||
1954 | // { | ||
1955 | // if ( NULL == strstr (scope_attribute, OIDC_EXPECTED_AUTHORIZATION_SCOPE) ) | ||
1956 | // { | ||
1957 | // // claim attribute from ego | ||
1958 | // scope_attribute = strtok (NULL, delimiter); | ||
1959 | // } | ||
1960 | // } | ||
1961 | // // create an authorization code | ||
1962 | // | ||
1963 | //// GNUNET_IDENTITY_PROVIDER_t | ||
1964 | // | ||
1965 | // MHD_add_response_header (resp, "Location", redirect_uri); | ||
1966 | // handle->proc (handle->proc_cls, resp, MHD_HTTP_FOUND); | ||
1967 | // cleanup_handle (handle); | ||
1968 | // GNUNET_free(relog_time); | ||
1969 | // return; | ||
1970 | // } | ||
1971 | // GNUNET_free(relog_time); | ||
1972 | // } | ||
1973 | // } | ||
1974 | // | ||
1975 | // | ||
1976 | // // login redirection | ||
1977 | // if ( GNUNET_OK | ||
1978 | // == GNUNET_CONFIGURATION_get_value_string (cfg, "identity-rest-plugin", | ||
1979 | // "address", &login_base_url) ) | ||
1980 | // { | ||
1981 | // GNUNET_asprintf (&new_redirect, "%s?%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s", | ||
1982 | // login_base_url, | ||
1983 | // OIDC_RESPONSE_TYPE_KEY, | ||
1984 | // response_type, | ||
1985 | // OIDC_CLIENT_ID_KEY, | ||
1986 | // client_id, | ||
1987 | // OIDC_REDIRECT_URI_KEY, | ||
1988 | // redirect_uri, | ||
1989 | // OIDC_SCOPE_KEY, | ||
1990 | // scope, | ||
1991 | // OIDC_STATE_KEY, | ||
1992 | // (NULL == state) ? state : "", | ||
1993 | // OIDC_NONCE_KEY, | ||
1994 | // (NULL == nonce) ? nonce : ""); | ||
1995 | // resp = GNUNET_REST_create_response (""); | ||
1996 | // MHD_add_response_header (resp, "Location", new_redirect); | ||
1997 | // } | ||
1998 | // else | ||
1999 | // { | ||
2000 | // handle->emsg = GNUNET_strdup("No server configuration"); | ||
2001 | // handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR; | ||
2002 | // GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
2003 | // return; | ||
2004 | // } | ||
2005 | // handle->proc (handle->proc_cls, resp, MHD_HTTP_FOUND); | ||
2006 | // cleanup_handle (handle); | ||
2007 | // GNUNET_free(new_redirect); | ||
2008 | // return; | ||
2009 | //} | ||
2010 | 1922 | ||
1923 | /** | ||
1924 | * Responds to authorization POST request | ||
1925 | * | ||
1926 | * @param con_handle the connection handle | ||
1927 | * @param url the url | ||
1928 | * @param cls the RequestHandle | ||
1929 | */ | ||
1930 | static void | ||
1931 | authorize_POST_cont (struct GNUNET_REST_RequestHandle *con_handle, | ||
1932 | const char* url, | ||
1933 | void *cls) | ||
1934 | { | ||
1935 | struct RequestHandle *handle = cls; | ||
1936 | json_t *cache_object; | ||
1937 | json_error_t error; | ||
1938 | handle->oidc->post_object = json_loads (handle->rest_handle->data, 0, &error); | ||
1939 | |||
1940 | //gets identity of login try with cookie | ||
1941 | cookie_identity_interpretation(handle); | ||
1942 | |||
1943 | //RECOMMENDED value: state - REQUIRED for answers | ||
1944 | cache_object = json_object_get (handle->oidc->post_object, OIDC_STATE_KEY); | ||
1945 | if ( NULL != cache_object && json_is_string(cache_object) ) | ||
1946 | { | ||
1947 | handle->oidc->state = json_string_value (cache_object); | ||
1948 | handle->oidc->state = GNUNET_strdup(handle->oidc->state); | ||
1949 | } | ||
1950 | |||
1951 | // REQUIRED value: client_id | ||
1952 | cache_object = json_object_get (handle->oidc->post_object, | ||
1953 | OIDC_CLIENT_ID_KEY); | ||
1954 | if ( NULL == cache_object || !json_is_string(cache_object) ) | ||
1955 | { | ||
1956 | handle->emsg = GNUNET_strdup("invalid_request"); | ||
1957 | handle->edesc = GNUNET_strdup("Missing parameter: client_id"); | ||
1958 | handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR; | ||
1959 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
1960 | return; | ||
1961 | } | ||
1962 | handle->oidc->client_id = json_string_value (cache_object); | ||
1963 | handle->oidc->client_id = GNUNET_strdup(handle->oidc->client_id); | ||
1964 | |||
1965 | if ( GNUNET_OK | ||
1966 | != GNUNET_CRYPTO_ecdsa_public_key_from_string ( | ||
1967 | handle->oidc->client_id, strlen (handle->oidc->client_id), | ||
1968 | &handle->oidc->client_pkey) ) | ||
1969 | { | ||
1970 | handle->emsg = GNUNET_strdup("unauthorized_client"); | ||
1971 | handle->edesc = GNUNET_strdup("The client is not authorized to request an " | ||
1972 | "authorization code using this method."); | ||
1973 | handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR; | ||
1974 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
1975 | return; | ||
1976 | } | ||
1977 | |||
1978 | if ( NULL == handle->ego_head ) | ||
1979 | { | ||
1980 | //TODO throw error or ignore if egos are missing? | ||
1981 | handle->emsg = GNUNET_strdup("server_error"); | ||
1982 | handle->edesc = GNUNET_strdup ("Egos are missing"); | ||
1983 | handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR; | ||
1984 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
1985 | return; | ||
1986 | } | ||
1987 | |||
1988 | handle->ego_entry = handle->ego_head; | ||
1989 | handle->priv_key = *GNUNET_IDENTITY_ego_get_private_key (handle->ego_head->ego); | ||
1990 | handle->oidc->is_client_trusted = GNUNET_NO; | ||
1991 | |||
1992 | // Checks if client_id is valid: | ||
1993 | handle->namestore_handle_it = GNUNET_NAMESTORE_zone_iteration_start ( | ||
1994 | handle->namestore_handle, &handle->priv_key, &oidc_iteration_error, | ||
1995 | handle, &namestore_iteration_callback, handle, | ||
1996 | &namestore_iteration_finished_POST, handle); | ||
1997 | } | ||
2011 | 1998 | ||
2012 | /** | 1999 | /** |
2013 | * Combines an identity with a login time and responds OK to login request | 2000 | * Combines an identity with a login time and responds OK to login request |
@@ -2025,6 +2012,7 @@ login_cont (struct GNUNET_REST_RequestHandle *con_handle, | |||
2025 | struct RequestHandle *handle = cls; | 2012 | struct RequestHandle *handle = cls; |
2026 | struct GNUNET_HashCode cache_key; | 2013 | struct GNUNET_HashCode cache_key; |
2027 | struct GNUNET_TIME_Absolute *current_time; | 2014 | struct GNUNET_TIME_Absolute *current_time; |
2015 | struct GNUNET_TIME_Absolute *last_time; | ||
2028 | char* cookie; | 2016 | char* cookie; |
2029 | json_t *root; | 2017 | json_t *root; |
2030 | json_error_t error; | 2018 | json_error_t error; |
@@ -2041,6 +2029,11 @@ login_cont (struct GNUNET_REST_RequestHandle *con_handle, | |||
2041 | *current_time = GNUNET_TIME_relative_to_absolute ( | 2029 | *current_time = GNUNET_TIME_relative_to_absolute ( |
2042 | GNUNET_TIME_relative_multiply (GNUNET_TIME_relative_get_minute_ (), | 2030 | GNUNET_TIME_relative_multiply (GNUNET_TIME_relative_get_minute_ (), |
2043 | 30)); | 2031 | 30)); |
2032 | last_time = GNUNET_CONTAINER_multihashmap_get(OIDC_authorized_identities, &cache_key); | ||
2033 | if (NULL != last_time) | ||
2034 | { | ||
2035 | GNUNET_free(last_time); | ||
2036 | } | ||
2044 | GNUNET_CONTAINER_multihashmap_put ( | 2037 | GNUNET_CONTAINER_multihashmap_put ( |
2045 | OIDC_authorized_identities, &cache_key, current_time, | 2038 | OIDC_authorized_identities, &cache_key, current_time, |
2046 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE); | 2039 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE); |
@@ -2070,9 +2063,9 @@ init_cont (struct RequestHandle *handle) | |||
2070 | {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY_ATTRIBUTES, &list_attribute_cont}, | 2063 | {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY_ATTRIBUTES, &list_attribute_cont}, |
2071 | {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY_ATTRIBUTES, &add_attribute_cont}, | 2064 | {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY_ATTRIBUTES, &add_attribute_cont}, |
2072 | {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY_TICKETS, &list_tickets_cont}, | 2065 | {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_IDENTITY_TICKETS, &list_tickets_cont}, |
2073 | {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_AUTHORIZE, &authorize_get_cont}, | 2066 | {MHD_HTTP_METHOD_GET, GNUNET_REST_API_NS_AUTHORIZE, &authorize_GET_cont}, |
2074 | {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_LOGIN, &login_cont}, | 2067 | {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_LOGIN, &login_cont}, |
2075 | // {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_AUTHORIZE, &authorize_post_cont}, | 2068 | {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_AUTHORIZE, &authorize_POST_cont}, |
2076 | {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY_REVOKE, &revoke_ticket_cont}, | 2069 | {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY_REVOKE, &revoke_ticket_cont}, |
2077 | {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY_CONSUME, &consume_ticket_cont}, | 2070 | {MHD_HTTP_METHOD_POST, GNUNET_REST_API_NS_IDENTITY_CONSUME, &consume_ticket_cont}, |
2078 | {MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_IDENTITY_PROVIDER, | 2071 | {MHD_HTTP_METHOD_OPTIONS, GNUNET_REST_API_NS_IDENTITY_PROVIDER, |
diff --git a/src/identity-provider/vgcore.2692 b/src/identity-provider/vgcore.2692 deleted file mode 100644 index d5691a6f6..000000000 --- a/src/identity-provider/vgcore.2692 +++ /dev/null | |||
Binary files differ | |||