Blob Blame History Raw
From 55bfa944ad0197ae294d85ac42abf98297fa3a5d Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Thu, 18 Aug 2022 14:19:59 +0200
Subject: [PATCH 23/24] oidc_child: increase wait interval by 5s if 'slow_down'
 is returned
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

While waiting for the user to authenticate with the IdP oidc_child
currently only handles the error code 'authorization_pending' and waits
for the given interval until a new request is send. But there is also
'slow_down' which should not be treated as fatal error but should just
increase the waiting time permanently for 5s.

Resolves: https://github.com/SSSD/sssd/issues/6146

Reviewed-by: Justin Stephenson <jstephen@redhat.com>
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
(cherry picked from commit 5ed7670766483040211713f8182510775c76b962)

Reviewed-by: Alexey Tikhonov <atikhono@redhat.com>
---
 src/oidc_child/oidc_child_curl.c | 8 +++++++-
 src/oidc_child/oidc_child_json.c | 6 ++++++
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/src/oidc_child/oidc_child_curl.c b/src/oidc_child/oidc_child_curl.c
index 6e80c3abf..cf0976021 100644
--- a/src/oidc_child/oidc_child_curl.c
+++ b/src/oidc_child/oidc_child_curl.c
@@ -378,8 +378,14 @@ errno_t get_token(TALLOC_CTX *mem_ctx,
             break;
         }
 
-        sleep(dc_ctx->interval);
         waiting_time += dc_ctx->interval;
+        if (waiting_time >= dc_ctx->expires_in) {
+            /* Next sleep will end after the request is expired on the
+             * server side, so we can just error out now. */
+            ret = ETIMEDOUT;
+            break;
+        }
+        sleep(dc_ctx->interval);
     } while (waiting_time < dc_ctx->expires_in);
 
     if (ret != EOK) {
diff --git a/src/oidc_child/oidc_child_json.c b/src/oidc_child/oidc_child_json.c
index efc1997aa..a89794c4c 100644
--- a/src/oidc_child/oidc_child_json.c
+++ b/src/oidc_child/oidc_child_json.c
@@ -413,6 +413,12 @@ errno_t parse_token_result(struct devicecode_ctx *dc_ctx,
         if (strcmp(json_string_value(tmp), "authorization_pending") == 0) {
             json_decref(result);
             return EAGAIN;
+        } else if (strcmp(json_string_value(tmp), "slow_down") == 0) {
+            /* RFC 8628: "... the interval MUST be increased by 5 seconds for"
+             *           "this and all subsequent requests." */
+            dc_ctx->interval += 5;
+            json_decref(result);
+            return EAGAIN;
         } else {
             *error_description = get_json_string(dc_ctx, result,
                                                  "error_description");
-- 
2.37.3