diff options
author | Phil <phil.buschmann@tum.de> | 2017-12-19 16:07:16 +0100 |
---|---|---|
committer | Phil <phil.buschmann@tum.de> | 2017-12-19 16:07:16 +0100 |
commit | 9f5ea1f7f809d73cbeb7ce5538550c42e978d340 (patch) | |
tree | b8c5733eddbb14004799a85f83caa380b25b28f0 /src | |
parent | 3428214e4513e1539256b19502ffb085539e01b3 (diff) | |
download | gnunet-9f5ea1f7f809d73cbeb7ce5538550c42e978d340.tar.gz gnunet-9f5ea1f7f809d73cbeb7ce5538550c42e978d340.zip |
-fix login time
Diffstat (limited to 'src')
-rw-r--r-- | src/identity-provider/plugin_rest_identity_provider.c | 229 |
1 files changed, 114 insertions, 115 deletions
diff --git a/src/identity-provider/plugin_rest_identity_provider.c b/src/identity-provider/plugin_rest_identity_provider.c index 30847ed3f..68644777f 100644 --- a/src/identity-provider/plugin_rest_identity_provider.c +++ b/src/identity-provider/plugin_rest_identity_provider.c | |||
@@ -132,9 +132,14 @@ | |||
132 | #define OIDC_NONCE_KEY "nonce" | 132 | #define OIDC_NONCE_KEY "nonce" |
133 | 133 | ||
134 | /** | 134 | /** |
135 | * OIDC authorization header key | 135 | * OIDC cookie header key |
136 | */ | 136 | */ |
137 | #define OIDC_AUTHORIZATION_HEADER_KEY "Authorization" | 137 | #define OIDC_COOKIE_HEADER_KEY "Cookie" |
138 | |||
139 | /** | ||
140 | * OIDC cookie header information key | ||
141 | */ | ||
142 | #define OIDC_COOKIE_HEADER_INFORMATION_KEY "Identity=" | ||
138 | 143 | ||
139 | /** | 144 | /** |
140 | * OIDC expected response_type while authorizing | 145 | * OIDC expected response_type while authorizing |
@@ -1139,9 +1144,7 @@ authorize_cont (struct GNUNET_REST_RequestHandle *con_handle, | |||
1139 | char *redirect_uri; | 1144 | char *redirect_uri; |
1140 | char *state = NULL; | 1145 | char *state = NULL; |
1141 | char *nonce = NULL; | 1146 | char *nonce = NULL; |
1142 | //TODO use gnunet_time_lib | 1147 | struct GNUNET_TIME_Absolute current_time, *relog_time; |
1143 | struct timeval now, login_time; | ||
1144 | OIDC_authorized_identities = GNUNET_CONTAINER_multihashmap_create( 10, GNUNET_NO ); | ||
1145 | char *login_base_url, *new_redirect; | 1148 | char *login_base_url, *new_redirect; |
1146 | struct GNUNET_HashCode cache_key; | 1149 | struct GNUNET_HashCode cache_key; |
1147 | 1150 | ||
@@ -1178,7 +1181,11 @@ authorize_cont (struct GNUNET_REST_RequestHandle *con_handle, | |||
1178 | } | 1181 | } |
1179 | client_id = GNUNET_CONTAINER_multihashmap_get(handle->rest_handle->url_param_map, | 1182 | client_id = GNUNET_CONTAINER_multihashmap_get(handle->rest_handle->url_param_map, |
1180 | &cache_key); | 1183 | &cache_key); |
1181 | 1184 | struct GNUNET_CRYPTO_EcdsaPublicKey pubkey; | |
1185 | GNUNET_CRYPTO_ecdsa_public_key_from_string(client_id, | ||
1186 | strlen (client_id), | ||
1187 | &pubkey); | ||
1188 | // GNUNET_NAMESTORE_zone_to_name(); | ||
1182 | // Checks if client_id is valid: | 1189 | // Checks if client_id is valid: |
1183 | // TODO use GNUNET_NAMESTORE_zone_to_name() function to verify that a delegation to the client_id exists | 1190 | // TODO use GNUNET_NAMESTORE_zone_to_name() function to verify that a delegation to the client_id exists |
1184 | // TODO change check (lookup trusted public_key?) | 1191 | // TODO change check (lookup trusted public_key?) |
@@ -1205,7 +1212,7 @@ authorize_cont (struct GNUNET_REST_RequestHandle *con_handle, | |||
1205 | redirect_uri = GNUNET_CONTAINER_multihashmap_get(handle->rest_handle->url_param_map, | 1212 | redirect_uri = GNUNET_CONTAINER_multihashmap_get(handle->rest_handle->url_param_map, |
1206 | &cache_key); | 1213 | &cache_key); |
1207 | 1214 | ||
1208 | // Checks if redirect_uri is valid: | 1215 | // verify the redirect uri matches https://<client_id>.zkey[/xyz] |
1209 | // TODO change check (check client_id->public key == address) | 1216 | // TODO change check (check client_id->public key == address) |
1210 | // if( strcmp( redirect_uri, "https://localhost:8000" ) != 0 ) | 1217 | // if( strcmp( redirect_uri, "https://localhost:8000" ) != 0 ) |
1211 | // { | 1218 | // { |
@@ -1302,121 +1309,96 @@ authorize_cont (struct GNUNET_REST_RequestHandle *con_handle, | |||
1302 | //TODO check other values and use them accordingly | 1309 | //TODO check other values and use them accordingly |
1303 | 1310 | ||
1304 | 1311 | ||
1305 | 1312 | GNUNET_CRYPTO_hash (OIDC_COOKIE_HEADER_KEY, strlen (OIDC_COOKIE_HEADER_KEY), | |
1306 | |||
1307 | //if header-authorization == ID | ||
1308 | //if ID is still logged | ||
1309 | // ego get Public Key of Identity | ||
1310 | // return token with public key? | ||
1311 | // save request | ||
1312 | |||
1313 | GNUNET_CRYPTO_hash (OIDC_AUTHORIZATION_HEADER_KEY, | ||
1314 | strlen (OIDC_AUTHORIZATION_HEADER_KEY), | ||
1315 | &cache_key); | 1313 | &cache_key); |
1316 | //No Authorization Parameter -> redirect to login | 1314 | //No identity-cookie -> redirect to login |
1317 | if(GNUNET_NO == GNUNET_CONTAINER_multihashmap_contains(con_handle->header_param_map, | 1315 | if ( GNUNET_YES |
1318 | &cache_key)) | 1316 | == GNUNET_CONTAINER_multihashmap_contains (con_handle->header_param_map, |
1319 | { | 1317 | &cache_key) ) |
1320 | if ( GNUNET_OK | ||
1321 | == GNUNET_CONFIGURATION_get_value_string (cfg, "identity-rest-plugin", | ||
1322 | "address", &login_base_url) ) | ||
1323 | { | ||
1324 | GNUNET_asprintf (&new_redirect, "%s?%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s", | ||
1325 | login_base_url, | ||
1326 | OIDC_RESPONSE_TYPE_KEY, | ||
1327 | response_type, | ||
1328 | OIDC_CLIENT_ID_KEY, | ||
1329 | client_id, | ||
1330 | OIDC_REDIRECT_URI_KEY, | ||
1331 | redirect_uri, | ||
1332 | OIDC_SCOPE_KEY, | ||
1333 | scope, | ||
1334 | OIDC_STATE_KEY, | ||
1335 | (NULL == state) ? state : "", | ||
1336 | OIDC_NONCE_KEY, | ||
1337 | (NULL == nonce) ? nonce : ""); | ||
1338 | resp = GNUNET_REST_create_response (""); | ||
1339 | MHD_add_response_header (resp, "Location", new_redirect); | ||
1340 | } | ||
1341 | else | ||
1342 | { | ||
1343 | handle->emsg = GNUNET_strdup("No server configuration"); | ||
1344 | handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR; | ||
1345 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
1346 | return; | ||
1347 | } | ||
1348 | handle->proc (handle->proc_cls, resp, MHD_HTTP_FOUND); | ||
1349 | cleanup_handle (handle); | ||
1350 | GNUNET_free(new_redirect); | ||
1351 | return; | ||
1352 | } | ||
1353 | else | ||
1354 | { | 1318 | { |
1355 | char* identity = GNUNET_CONTAINER_multihashmap_get ( con_handle->header_param_map, | 1319 | //split cookies and find 'Identity' cookie |
1356 | &cache_key); | 1320 | char* cookies = GNUNET_CONTAINER_multihashmap_get ( |
1357 | GNUNET_CRYPTO_hash (identity, strlen (identity), &cache_key); | 1321 | con_handle->header_param_map, &cache_key); |
1358 | if(GNUNET_YES == GNUNET_CONTAINER_multihashmap_contains(OIDC_authorized_identities, | 1322 | char delimiter[] = "; "; |
1359 | &cache_key)) | 1323 | char *identity_cookie; |
1324 | identity_cookie = strtok(cookies, delimiter); | ||
1325 | |||
1326 | while(identity_cookie != NULL) | ||
1360 | { | 1327 | { |
1361 | login_time = *(struct timeval *)GNUNET_CONTAINER_multihashmap_get(OIDC_authorized_identities, | 1328 | if(strstr( identity_cookie, OIDC_COOKIE_HEADER_INFORMATION_KEY ) != NULL) |
1362 | &cache_key); | ||
1363 | gettimeofday(&now, NULL); | ||
1364 | //After 30 minutes redirect to login | ||
1365 | if( now.tv_sec - login_time.tv_sec >= 1800) | ||
1366 | { | 1329 | { |
1367 | //TODO remove redundancy [redirect to login] | 1330 | break; |
1368 | if ( GNUNET_OK | ||
1369 | == GNUNET_CONFIGURATION_get_value_string (cfg, "identity-rest-plugin", | ||
1370 | "address", &login_base_url) ) | ||
1371 | { | ||
1372 | GNUNET_asprintf (&new_redirect, "%s?%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s", | ||
1373 | login_base_url, | ||
1374 | OIDC_RESPONSE_TYPE_KEY, | ||
1375 | response_type, | ||
1376 | OIDC_CLIENT_ID_KEY, | ||
1377 | client_id, | ||
1378 | OIDC_REDIRECT_URI_KEY, | ||
1379 | redirect_uri, | ||
1380 | OIDC_SCOPE_KEY, | ||
1381 | scope, | ||
1382 | OIDC_STATE_KEY, | ||
1383 | (state) ? state : "", | ||
1384 | OIDC_NONCE_KEY, | ||
1385 | (nonce) ? nonce : ""); | ||
1386 | resp = GNUNET_REST_create_response (""); | ||
1387 | MHD_add_response_header (resp, "Location", new_redirect); | ||
1388 | } | ||
1389 | else | ||
1390 | { | ||
1391 | handle->emsg = GNUNET_strdup("No server configuration"); | ||
1392 | handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR; | ||
1393 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
1394 | return; | ||
1395 | } | ||
1396 | handle->proc (handle->proc_cls, resp, MHD_HTTP_FOUND); | ||
1397 | cleanup_handle (handle); | ||
1398 | GNUNET_free(new_redirect); | ||
1399 | return; | ||
1400 | } | 1331 | } |
1332 | identity_cookie = strtok(NULL, delimiter); | ||
1401 | } | 1333 | } |
1402 | else | 1334 | GNUNET_CRYPTO_hash (identity_cookie, strlen (identity_cookie), &cache_key); |
1335 | |||
1336 | //No login time for identity -> redirect to login | ||
1337 | if ( GNUNET_YES | ||
1338 | == GNUNET_CONTAINER_multihashmap_contains (OIDC_authorized_identities, | ||
1339 | &cache_key) ) | ||
1403 | { | 1340 | { |
1404 | gettimeofday( &now, NULL ); | 1341 | relog_time = GNUNET_CONTAINER_multihashmap_get ( |
1405 | GNUNET_CONTAINER_multihashmap_put( OIDC_authorized_identities, &cache_key, &now, | 1342 | OIDC_authorized_identities, &cache_key); |
1406 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); | 1343 | |
1344 | current_time = GNUNET_TIME_absolute_get(); | ||
1345 | |||
1346 | GNUNET_CONTAINER_multihashmap_remove_all(OIDC_authorized_identities, &cache_key); | ||
1347 | // 30 min after old login -> redirect to login | ||
1348 | if ( current_time.abs_value_us <= relog_time->abs_value_us ) | ||
1349 | { | ||
1350 | resp = GNUNET_REST_create_response (""); | ||
1351 | // code = struct GNUNET_IDENTITY_PROVIDER_Ticket | ||
1352 | GNUNET_IDENTITY_PROVIDER_t | ||
1353 | MHD_add_response_header (resp, "Location", redirect_uri); | ||
1354 | handle->proc (handle->proc_cls, resp, MHD_HTTP_FOUND); | ||
1355 | cleanup_handle (handle); | ||
1356 | GNUNET_free(relog_time); | ||
1357 | return; | ||
1358 | } | ||
1359 | GNUNET_free(relog_time); | ||
1407 | } | 1360 | } |
1361 | } | ||
1362 | |||
1363 | |||
1364 | // login redirection | ||
1365 | if ( GNUNET_OK | ||
1366 | == GNUNET_CONFIGURATION_get_value_string (cfg, "identity-rest-plugin", | ||
1367 | "address", &login_base_url) ) | ||
1368 | { | ||
1369 | GNUNET_asprintf (&new_redirect, "%s?%s=%s&%s=%s&%s=%s&%s=%s&%s=%s&%s=%s", | ||
1370 | login_base_url, | ||
1371 | OIDC_RESPONSE_TYPE_KEY, | ||
1372 | response_type, | ||
1373 | OIDC_CLIENT_ID_KEY, | ||
1374 | client_id, | ||
1375 | OIDC_REDIRECT_URI_KEY, | ||
1376 | redirect_uri, | ||
1377 | OIDC_SCOPE_KEY, | ||
1378 | scope, | ||
1379 | OIDC_STATE_KEY, | ||
1380 | (NULL == state) ? state : "", | ||
1381 | OIDC_NONCE_KEY, | ||
1382 | (NULL == nonce) ? nonce : ""); | ||
1408 | resp = GNUNET_REST_create_response (""); | 1383 | resp = GNUNET_REST_create_response (""); |
1409 | // MHD_add_response_header (resp, "Access-Control-Allow-Origin", "*"); | 1384 | MHD_add_response_header (resp, "Location", new_redirect); |
1410 | MHD_add_response_header (resp, "Location", redirect_uri); | 1385 | } |
1411 | handle->proc (handle->proc_cls, resp, MHD_HTTP_FOUND); | 1386 | else |
1412 | cleanup_handle (handle); | 1387 | { |
1388 | handle->emsg = GNUNET_strdup("No server configuration"); | ||
1389 | handle->response_code = MHD_HTTP_INTERNAL_SERVER_ERROR; | ||
1390 | GNUNET_SCHEDULER_add_now (&do_error, handle); | ||
1413 | return; | 1391 | return; |
1414 | } | 1392 | } |
1393 | handle->proc (handle->proc_cls, resp, MHD_HTTP_FOUND); | ||
1394 | cleanup_handle (handle); | ||
1395 | GNUNET_free(new_redirect); | ||
1396 | return; | ||
1415 | } | 1397 | } |
1416 | 1398 | ||
1417 | 1399 | ||
1418 | /** | 1400 | /** |
1419 | * Respond to LOGIN request | 1401 | * Combines an identity with a login time and responds OK to login request |
1420 | * | 1402 | * |
1421 | * @param con_handle the connection handle | 1403 | * @param con_handle the connection handle |
1422 | * @param url the url | 1404 | * @param url the url |
@@ -1427,27 +1409,40 @@ login_cont (struct GNUNET_REST_RequestHandle *con_handle, | |||
1427 | const char* url, | 1409 | const char* url, |
1428 | void *cls) | 1410 | void *cls) |
1429 | { | 1411 | { |
1412 | |||
1413 | |||
1430 | struct MHD_Response *resp = GNUNET_REST_create_response (""); | 1414 | struct MHD_Response *resp = GNUNET_REST_create_response (""); |
1431 | struct RequestHandle *handle = cls; | 1415 | struct RequestHandle *handle = cls; |
1416 | struct GNUNET_HashCode cache_key; | ||
1417 | struct GNUNET_TIME_Absolute *current_time; | ||
1432 | char* cookie; | 1418 | char* cookie; |
1433 | json_t *root; | 1419 | json_t *root; |
1434 | json_error_t error; | 1420 | json_error_t error; |
1435 | json_t *identity; | 1421 | json_t *identity; |
1436 | root = json_loads( handle->rest_handle->data, 0, &error ); | 1422 | root = json_loads (handle->rest_handle->data, 0, &error); |
1437 | identity = json_object_get(root, "identity"); | 1423 | identity = json_object_get (root, "identity"); |
1438 | if(json_is_string(identity)) | 1424 | if ( json_is_string(identity) ) |
1439 | { | 1425 | { |
1440 | GNUNET_asprintf(&cookie,"Identity=%s",json_string_value(identity)); | 1426 | GNUNET_asprintf (&cookie, "Identity=%s", json_string_value (identity)); |
1441 | MHD_add_response_header (resp, "Set-Cookie", cookie); | 1427 | |
1428 | GNUNET_CRYPTO_hash (cookie, strlen (cookie), &cache_key); | ||
1429 | current_time = GNUNET_new(struct GNUNET_TIME_Absolute); | ||
1430 | *current_time = GNUNET_TIME_relative_to_absolute ( | ||
1431 | GNUNET_TIME_relative_multiply (GNUNET_TIME_relative_get_minute_ (), | ||
1432 | 30)); | ||
1433 | GNUNET_CONTAINER_multihashmap_put ( | ||
1434 | OIDC_authorized_identities, &cache_key, current_time, | ||
1435 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE); | ||
1436 | |||
1442 | handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); | 1437 | handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); |
1443 | } | 1438 | } |
1444 | else | 1439 | else |
1445 | { | 1440 | { |
1446 | handle->proc (handle->proc_cls, resp, MHD_HTTP_BAD_REQUEST); | 1441 | handle->proc (handle->proc_cls, resp, MHD_HTTP_BAD_REQUEST); |
1447 | } | 1442 | } |
1448 | json_decref(root); | ||
1449 | cleanup_handle (handle); | ||
1450 | GNUNET_free(cookie); | 1443 | GNUNET_free(cookie); |
1444 | json_decref (root); | ||
1445 | cleanup_handle (handle); | ||
1451 | return; | 1446 | return; |
1452 | } | 1447 | } |
1453 | 1448 | ||
@@ -1562,7 +1557,11 @@ rest_identity_process_request(struct GNUNET_REST_RequestHandle *rest_handle, | |||
1562 | void *proc_cls) | 1557 | void *proc_cls) |
1563 | { | 1558 | { |
1564 | struct RequestHandle *handle = GNUNET_new (struct RequestHandle); | 1559 | struct RequestHandle *handle = GNUNET_new (struct RequestHandle); |
1565 | 1560 | if ( NULL == OIDC_authorized_identities ) | |
1561 | { | ||
1562 | OIDC_authorized_identities = GNUNET_CONTAINER_multihashmap_create (10, | ||
1563 | GNUNET_NO); | ||
1564 | } | ||
1566 | handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL; | 1565 | handle->timeout = GNUNET_TIME_UNIT_FOREVER_REL; |
1567 | handle->proc_cls = proc_cls; | 1566 | handle->proc_cls = proc_cls; |
1568 | handle->proc = proc; | 1567 | handle->proc = proc; |