aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Schanzenbach <schanzen@gnunet.org>2022-06-22 20:14:04 +0200
committerMartin Schanzenbach <schanzen@gnunet.org>2022-06-22 20:14:04 +0200
commit84303b044db07e351e99c0338260ecea23012ec6 (patch)
treef5718cab374a8bf86c5f7b904f6bd45215f46536
parenta022af20e654100b99db1a9205bea43f9271526b (diff)
downloadgnunet-84303b044db07e351e99c0338260ecea23012ec6.tar.gz
gnunet-84303b044db07e351e99c0338260ecea23012ec6.zip
RECLAIM: Improve OIDC userinfo caching; add config option for timeout
-rw-r--r--src/reclaim/plugin_rest_openid_connect.c59
-rw-r--r--src/reclaim/reclaim.conf1
2 files changed, 47 insertions, 13 deletions
diff --git a/src/reclaim/plugin_rest_openid_connect.c b/src/reclaim/plugin_rest_openid_connect.c
index 0ffe1b6c8..769ce553f 100644
--- a/src/reclaim/plugin_rest_openid_connect.c
+++ b/src/reclaim/plugin_rest_openid_connect.c
@@ -307,6 +307,11 @@ static struct GNUNET_GNS_Handle *gns_handle;
307static struct GNUNET_RECLAIM_Handle *idp; 307static struct GNUNET_RECLAIM_Handle *idp;
308 308
309/** 309/**
310 * Timeout for consume call on userinfo
311 */
312static struct GNUNET_TIME_Relative consume_timeout;
313
314/**
310 * @brief struct returned by the initialization function of the plugin 315 * @brief struct returned by the initialization function of the plugin
311 */ 316 */
312struct Plugin 317struct Plugin
@@ -976,8 +981,8 @@ get_oidc_jwk_path (void *cls)
976{ 981{
977 char *oidc_directory; 982 char *oidc_directory;
978 char *oidc_jwk_path; 983 char *oidc_jwk_path;
979 984
980 oidc_directory = get_oidc_dir_path(cls); 985 oidc_directory = get_oidc_dir_path (cls);
981 986
982 // Create path to file 987 // Create path to file
983 GNUNET_asprintf (&oidc_jwk_path, "%s/%s", oidc_directory, 988 GNUNET_asprintf (&oidc_jwk_path, "%s/%s", oidc_directory,
@@ -2183,6 +2188,7 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle,
2183 json_t *oidc_jwk; 2188 json_t *oidc_jwk;
2184 char *oidc_jwk_path; 2189 char *oidc_jwk_path;
2185 char *oidc_directory; 2190 char *oidc_directory;
2191 char *tmp_at;
2186 2192
2187 /* 2193 /*
2188 * Check Authorization 2194 * Check Authorization
@@ -2312,7 +2318,7 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle,
2312 { 2318 {
2313 // Generate and save a new key 2319 // Generate and save a new key
2314 oidc_jwk = generate_jwk (); 2320 oidc_jwk = generate_jwk ();
2315 oidc_directory = get_oidc_dir_path(cls); 2321 oidc_directory = get_oidc_dir_path (cls);
2316 2322
2317 // Create new oidc directory 2323 // Create new oidc directory
2318 if (GNUNET_OK != GNUNET_DISK_directory_create (oidc_directory)) 2324 if (GNUNET_OK != GNUNET_DISK_directory_create (oidc_directory))
@@ -2374,14 +2380,25 @@ token_endpoint (struct GNUNET_REST_RequestHandle *con_handle,
2374 if (NULL != nonce) 2380 if (NULL != nonce)
2375 GNUNET_free (nonce); 2381 GNUNET_free (nonce);
2376 access_token = OIDC_access_token_new (&ticket); 2382 access_token = OIDC_access_token_new (&ticket);
2377 /* Store mapping from access token to code so we can later 2383 /**
2378 * fall back on the provided attributes in userinfo 2384 * Store mapping from access token to code so we can later
2385 * fall back on the provided attributes in userinfo one time.
2379 */ 2386 */
2380 GNUNET_CRYPTO_hash (access_token, 2387 GNUNET_CRYPTO_hash (access_token,
2381 strlen (access_token), 2388 strlen (access_token),
2382 &cache_key); 2389 &cache_key);
2383 char *tmp_at = GNUNET_CONTAINER_multihashmap_get (oidc_code_cache, 2390 /**
2384 &cache_key); 2391 * Note to future self: This cache has the following purpose:
2392 * Some OIDC plugins call the userendpoint right after receiving an
2393 * ID token and access token. There are reasons why this would make sense.
2394 * Others not so much.
2395 * In any case, in order to smoothen out the user experience upon login
2396 * (authorization), we speculatively cache the next
2397 * userinfo response in case the actual resolution through reclaim/GNS
2398 * takes too long.
2399 */
2400 tmp_at = GNUNET_CONTAINER_multihashmap_get (oidc_code_cache,
2401 &cache_key);
2385 GNUNET_CONTAINER_multihashmap_put (oidc_code_cache, 2402 GNUNET_CONTAINER_multihashmap_put (oidc_code_cache,
2386 &cache_key, 2403 &cache_key,
2387 code, 2404 code,
@@ -2490,15 +2507,18 @@ consume_ticket (void *cls,
2490 2507
2491 2508
2492static void 2509static void
2493consume_timeout (void*cls) 2510consume_fail (void *cls)
2494{ 2511{
2495 struct RequestHandle *handle = cls; 2512 struct RequestHandle *handle = cls;
2496 struct GNUNET_HashCode cache_key; 2513 struct GNUNET_HashCode cache_key;
2497 struct GNUNET_RECLAIM_AttributeList *cl = NULL; 2514 struct GNUNET_RECLAIM_AttributeList *cl = NULL;
2498 struct GNUNET_RECLAIM_PresentationList *pl = NULL; 2515 struct GNUNET_RECLAIM_PresentationList *pl = NULL;
2499 struct GNUNET_RECLAIM_Ticket ticket; 2516 struct GNUNET_RECLAIM_Ticket ticket;
2517 struct MHD_Response *resp;
2500 char *nonce; 2518 char *nonce;
2501 char *cached_code; 2519 char *cached_code;
2520 char *result_str;
2521
2502 2522
2503 handle->consume_timeout_op = NULL; 2523 handle->consume_timeout_op = NULL;
2504 if (NULL != handle->idp_op) 2524 if (NULL != handle->idp_op)
@@ -2520,6 +2540,12 @@ consume_timeout (void*cls)
2520 GNUNET_SCHEDULER_add_now (&do_userinfo_error, handle); 2540 GNUNET_SCHEDULER_add_now (&do_userinfo_error, handle);
2521 return; 2541 return;
2522 } 2542 }
2543 /**
2544 * Remove the cached item
2545 */
2546 GNUNET_CONTAINER_multihashmap_remove (oidc_code_cache,
2547 &cache_key,
2548 cached_code);
2523 2549
2524 // decode code 2550 // decode code
2525 if (GNUNET_OK != OIDC_parse_authz_code (&handle->ticket.audience, 2551 if (GNUNET_OK != OIDC_parse_authz_code (&handle->ticket.audience,
@@ -2537,8 +2563,7 @@ consume_timeout (void*cls)
2537 return; 2563 return;
2538 } 2564 }
2539 2565
2540 struct MHD_Response *resp; 2566 GNUNET_free (cached_code);
2541 char *result_str;
2542 2567
2543 result_str = OIDC_generate_userinfo (&handle->ticket.identity, 2568 result_str = OIDC_generate_userinfo (&handle->ticket.identity,
2544 cl, 2569 cl,
@@ -2652,8 +2677,8 @@ userinfo_endpoint (struct GNUNET_REST_RequestHandle *con_handle,
2652 2677
2653 /* If the consume takes too long, we use values from the cache */ 2678 /* If the consume takes too long, we use values from the cache */
2654 handle->access_token = GNUNET_strdup (authorization_access_token); 2679 handle->access_token = GNUNET_strdup (authorization_access_token);
2655 handle->consume_timeout_op = GNUNET_SCHEDULER_add_delayed (CONSUME_TIMEOUT, 2680 handle->consume_timeout_op = GNUNET_SCHEDULER_add_delayed (consume_timeout,
2656 &consume_timeout, 2681 &consume_fail,
2657 handle); 2682 handle);
2658 handle->idp_op = GNUNET_RECLAIM_ticket_consume (idp, 2683 handle->idp_op = GNUNET_RECLAIM_ticket_consume (idp,
2659 privkey, 2684 privkey,
@@ -2690,7 +2715,7 @@ jwks_endpoint (struct GNUNET_REST_RequestHandle *con_handle,
2690 { 2715 {
2691 // Generate and save a new key 2716 // Generate and save a new key
2692 oidc_jwk = generate_jwk (); 2717 oidc_jwk = generate_jwk ();
2693 oidc_directory = get_oidc_dir_path(cls); 2718 oidc_directory = get_oidc_dir_path (cls);
2694 2719
2695 // Create new oidc directory 2720 // Create new oidc directory
2696 if (GNUNET_OK != GNUNET_DISK_directory_create (oidc_directory)) 2721 if (GNUNET_OK != GNUNET_DISK_directory_create (oidc_directory))
@@ -3028,6 +3053,14 @@ libgnunet_plugin_rest_openid_connect_init (void *cls)
3028 identity_handle = GNUNET_IDENTITY_connect (cfg, &list_ego, NULL); 3053 identity_handle = GNUNET_IDENTITY_connect (cfg, &list_ego, NULL);
3029 gns_handle = GNUNET_GNS_connect (cfg); 3054 gns_handle = GNUNET_GNS_connect (cfg);
3030 idp = GNUNET_RECLAIM_connect (cfg); 3055 idp = GNUNET_RECLAIM_connect (cfg);
3056 if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_time (cfg,
3057 "reclaim-rest-plugin",
3058 "OIDC_USERINFO_CONSUME_TIMEOUT",
3059 &consume_timeout))
3060 {
3061 consume_timeout = CONSUME_TIMEOUT;
3062 }
3063
3031 3064
3032 state = ID_REST_STATE_INIT; 3065 state = ID_REST_STATE_INIT;
3033 GNUNET_asprintf (&allow_methods, 3066 GNUNET_asprintf (&allow_methods,
diff --git a/src/reclaim/reclaim.conf b/src/reclaim/reclaim.conf
index c685042db..07facc232 100644
--- a/src/reclaim/reclaim.conf
+++ b/src/reclaim/reclaim.conf
@@ -17,5 +17,6 @@ ADDRESS = https://ui.reclaim/#/login
17OIDC_JSON_WEB_ALGORITHM = RS256 17OIDC_JSON_WEB_ALGORITHM = RS256
18OIDC_CLIENT_HMAC_SECRET = secret 18OIDC_CLIENT_HMAC_SECRET = secret
19OIDC_DIR = $GNUNET_DATA_HOME/oidc 19OIDC_DIR = $GNUNET_DATA_HOME/oidc
20OIDC_USERINFO_CONSUME_TIMEOUT = 5s
20JWT_SECRET = secret 21JWT_SECRET = secret
21EXPIRATION_TIME = 1d 22EXPIRATION_TIME = 1d