gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-challenger] branch master updated: implement OAuth2 error codes (


From: gnunet
Subject: [taler-challenger] branch master updated: implement OAuth2 error codes (rfc6749 - section-5.2) as found by schanzen
Date: Mon, 08 May 2023 20:47:54 +0200

This is an automated email from the git hooks/post-receive script.

grothoff pushed a commit to branch master
in repository challenger.

The following commit(s) were added to refs/heads/master by this push:
     new 206ebd2  implement OAuth2 error codes (rfc6749 - section-5.2) as found 
by schanzen
206ebd2 is described below

commit 206ebd255645426585bf21d005306bfc1a88430e
Author: Christian Grothoff <christian@grothoff.org>
AuthorDate: Mon May 8 20:47:51 2023 +0200

    implement OAuth2 error codes (rfc6749 - section-5.2) as found by schanzen
---
 src/challenger/challenger-httpd_common.c |  33 +++++++
 src/challenger/challenger-httpd_common.h |  19 ++++
 src/challenger/challenger-httpd_token.c  | 163 ++++++++++++++++++-------------
 3 files changed, 147 insertions(+), 68 deletions(-)

diff --git a/src/challenger/challenger-httpd_common.c 
b/src/challenger/challenger-httpd_common.c
index 3318215..b85be82 100644
--- a/src/challenger/challenger-httpd_common.c
+++ b/src/challenger/challenger-httpd_common.c
@@ -118,3 +118,36 @@ CH_code_to_nonce (const char *code,
   }
   return GNUNET_OK;
 }
+
+
+MHD_RESULT
+TALER_MHD_reply_with_oauth_error (
+  struct MHD_Connection *connection,
+  unsigned int http_status,
+  const char *oauth_error,
+  enum TALER_ErrorCode ec,
+  const char *detail)
+{
+  struct MHD_Response *resp;
+  MHD_RESULT mret;
+
+  resp = TALER_MHD_make_json (
+    GNUNET_JSON_PACK (
+      TALER_MHD_PACK_EC (ec),
+      GNUNET_JSON_pack_string ("error",
+                               oauth_error),
+      GNUNET_JSON_pack_allow_null (
+        GNUNET_JSON_pack_string ("detail",
+                                 detail))));
+  if (MHD_HTTP_UNAUTHORIZED == http_status)
+    GNUNET_break (MHD_YES ==
+                  MHD_add_response_header (
+                    resp,
+                    "WWW-Authenticate",
+                    "Bearer, error=\"invalid_token\""));
+  mret = MHD_queue_response (connection,
+                             http_status,
+                             resp);
+  MHD_destroy_response (resp);
+  return mret;
+}
diff --git a/src/challenger/challenger-httpd_common.h 
b/src/challenger/challenger-httpd_common.h
index aea6462..43d3c0d 100644
--- a/src/challenger/challenger-httpd_common.h
+++ b/src/challenger/challenger-httpd_common.h
@@ -66,4 +66,23 @@ CH_code_to_nonce (const char *code,
                   struct CHALLENGER_ValidationNonceP *nonce);
 
 
+/**
+ * Send a OAuth 2.0 response indicating an error following
+ * section 5.2 of RFC 6749.
+ *
+ * @param connection the MHD connection to use
+ * @param ec error code uniquely identifying the error
+ * @param oauth_error error as of the OAuth 2.0 protocol
+ * @param http_status HTTP status code to use
+ * @param detail additional optional detail about the error
+ * @return a MHD result code
+ */
+MHD_RESULT
+TALER_MHD_reply_with_oauth_error (struct MHD_Connection *connection,
+                                  unsigned int http_status,
+                                  const char *oauth_error,
+                                  enum TALER_ErrorCode ec,
+                                  const char *detail);
+
+
 #endif
diff --git a/src/challenger/challenger-httpd_token.c 
b/src/challenger/challenger-httpd_token.c
index 74cbf6a..da3a70e 100644
--- a/src/challenger/challenger-httpd_token.c
+++ b/src/challenger/challenger-httpd_token.c
@@ -224,43 +224,53 @@ CH_handler_token (struct CH_HandlerContext *hc,
                      "authorization_code")) )
   {
     GNUNET_break_op (0);
-    return TALER_MHD_reply_with_error (hc->connection,
-                                       MHD_HTTP_BAD_REQUEST,
-                                       TALER_EC_GENERIC_PARAMETER_MALFORMED,
-                                       "authorization_code");
+    return TALER_MHD_reply_with_oauth_error (
+      hc->connection,
+      MHD_HTTP_BAD_REQUEST,
+      "unsupported_grant_type",
+      TALER_EC_GENERIC_PARAMETER_MALFORMED,
+      "authorization_code");
   }
 
   if (NULL == bc->code)
   {
     GNUNET_break_op (0);
-    return TALER_MHD_reply_with_error (hc->connection,
-                                       MHD_HTTP_BAD_REQUEST,
-                                       TALER_EC_GENERIC_PARAMETER_MISSING,
-                                       "code");
+    return TALER_MHD_reply_with_oauth_error (
+      hc->connection,
+      MHD_HTTP_BAD_REQUEST,
+      "invalid_request",
+      TALER_EC_GENERIC_PARAMETER_MISSING,
+      "code");
   }
   if (NULL == bc->client_secret)
   {
     GNUNET_break_op (0);
-    return TALER_MHD_reply_with_error (hc->connection,
-                                       MHD_HTTP_BAD_REQUEST,
-                                       TALER_EC_GENERIC_PARAMETER_MISSING,
-                                       "client_secret");
+    return TALER_MHD_reply_with_oauth_error (
+      hc->connection,
+      MHD_HTTP_BAD_REQUEST,
+      "invalid_client",
+      TALER_EC_GENERIC_PARAMETER_MISSING,
+      "client_secret");
   }
   if (NULL == bc->client_id)
   {
     GNUNET_break_op (0);
-    return TALER_MHD_reply_with_error (hc->connection,
-                                       MHD_HTTP_BAD_REQUEST,
-                                       TALER_EC_GENERIC_PARAMETER_MISSING,
-                                       "client_id");
+    return TALER_MHD_reply_with_oauth_error (
+      hc->connection,
+      MHD_HTTP_BAD_REQUEST,
+      "invalid_client",
+      TALER_EC_GENERIC_PARAMETER_MISSING,
+      "client_id");
   }
   if (NULL == bc->redirect_uri)
   {
     GNUNET_break_op (0);
-    return TALER_MHD_reply_with_error (hc->connection,
-                                       MHD_HTTP_BAD_REQUEST,
-                                       TALER_EC_GENERIC_PARAMETER_MISSING,
-                                       "redirect_uri");
+    return TALER_MHD_reply_with_oauth_error (
+      hc->connection,
+      MHD_HTTP_BAD_REQUEST,
+      "invalid_request",
+      TALER_EC_GENERIC_PARAMETER_MISSING,
+      "redirect_uri");
   }
 
   /* Check this client is authorized to access the service */
@@ -276,10 +286,12 @@ CH_handler_token (struct CH_HandlerContext *hc,
                      &dummy))
     {
       GNUNET_break_op (0);
-      return TALER_MHD_reply_with_error (hc->connection,
-                                         MHD_HTTP_BAD_REQUEST,
-                                         TALER_EC_GENERIC_PARAMETER_MALFORMED,
-                                         "client_id");
+      return TALER_MHD_reply_with_oauth_error (
+        hc->connection,
+        MHD_HTTP_BAD_REQUEST,
+        "invalid_client",
+        TALER_EC_GENERIC_PARAMETER_MALFORMED,
+        "client_id");
     }
 
     qs = CH_db->client_check (CH_db->cls,
@@ -291,19 +303,22 @@ CH_handler_token (struct CH_HandlerContext *hc,
     {
     case GNUNET_DB_STATUS_HARD_ERROR:
       GNUNET_break (0);
-      return TALER_MHD_reply_with_error (hc->connection,
-                                         MHD_HTTP_INTERNAL_SERVER_ERROR,
-                                         TALER_EC_GENERIC_DB_FETCH_FAILED,
-                                         "client_check");
+      return TALER_MHD_reply_with_error (
+        hc->connection,
+        MHD_HTTP_INTERNAL_SERVER_ERROR,
+        TALER_EC_GENERIC_DB_FETCH_FAILED,
+        "client_check");
     case GNUNET_DB_STATUS_SOFT_ERROR:
       GNUNET_break (0);
       return MHD_NO;
     case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
       GNUNET_break_op (0);
-      return TALER_MHD_reply_with_error (hc->connection,
-                                         MHD_HTTP_NOT_FOUND,
-                                         
TALER_EC_CHALLENGER_GENERIC_CLIENT_UNKNOWN,
-                                         NULL);
+      return TALER_MHD_reply_with_oauth_error (
+        hc->connection,
+        MHD_HTTP_UNAUTHORIZED,
+        "invalid_client",
+        TALER_EC_CHALLENGER_GENERIC_CLIENT_UNKNOWN,
+        NULL);
     case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
       break;
     }
@@ -312,10 +327,12 @@ CH_handler_token (struct CH_HandlerContext *hc,
                        bc->redirect_uri)) )
     {
       GNUNET_break_op (0);
-      return TALER_MHD_reply_with_error (hc->connection,
-                                         MHD_HTTP_FORBIDDEN,
-                                         
TALER_EC_CHALLENGER_GENERIC_CLIENT_FORBIDDEN_BAD_REDIRECT_URI,
-                                         NULL);
+      return TALER_MHD_reply_with_oauth_error (
+        hc->connection,
+        MHD_HTTP_UNAUTHORIZED,
+        "invalid_client",
+        TALER_EC_CHALLENGER_GENERIC_CLIENT_FORBIDDEN_BAD_REDIRECT_URI,
+        NULL);
     }
     GNUNET_free (client_url);
   }
@@ -325,10 +342,12 @@ CH_handler_token (struct CH_HandlerContext *hc,
                         &bc->nonce))
   {
     GNUNET_break_op (0);
-    return TALER_MHD_reply_with_error (hc->connection,
-                                       MHD_HTTP_FORBIDDEN,
-                                       
TALER_EC_CHALLENGER_CLIENT_FORBIDDEN_BAD_CODE,
-                                       NULL);
+    return TALER_MHD_reply_with_oauth_error (
+      hc->connection,
+      MHD_HTTP_UNAUTHORIZED,
+      "invalid_grant",
+      TALER_EC_CHALLENGER_CLIENT_FORBIDDEN_BAD_CODE,
+      NULL);
   }
 
   /* Check code is valid */
@@ -352,19 +371,22 @@ CH_handler_token (struct CH_HandlerContext *hc,
     {
     case GNUNET_DB_STATUS_HARD_ERROR:
       GNUNET_break (0);
-      return TALER_MHD_reply_with_error (hc->connection,
-                                         MHD_HTTP_INTERNAL_SERVER_ERROR,
-                                         TALER_EC_GENERIC_DB_FETCH_FAILED,
-                                         "validation_get");
+      return TALER_MHD_reply_with_error (
+        hc->connection,
+        MHD_HTTP_INTERNAL_SERVER_ERROR,
+        TALER_EC_GENERIC_DB_FETCH_FAILED,
+        "validation_get");
     case GNUNET_DB_STATUS_SOFT_ERROR:
       GNUNET_break (0);
       return MHD_NO;
     case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
       GNUNET_break_op (0);
-      return TALER_MHD_reply_with_error (hc->connection,
-                                         MHD_HTTP_NOT_FOUND,
-                                         
TALER_EC_CHALLENGER_GENERIC_VALIDATION_UNKNOWN,
-                                         "validation_get");
+      return TALER_MHD_reply_with_oauth_error (
+        hc->connection,
+        MHD_HTTP_UNAUTHORIZED,
+        "invalid_grant",
+        TALER_EC_CHALLENGER_GENERIC_VALIDATION_UNKNOWN,
+        "validation_get");
     case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
       break;
     }
@@ -383,46 +405,51 @@ CH_handler_token (struct CH_HandlerContext *hc,
     {
       GNUNET_break_op (0);
       GNUNET_free (code);
-      return TALER_MHD_reply_with_error (hc->connection,
-                                         MHD_HTTP_FORBIDDEN,
-                                         
TALER_EC_CHALLENGER_CLIENT_FORBIDDEN_BAD_CODE,
-                                         "code");
+      return TALER_MHD_reply_with_oauth_error (
+        hc->connection,
+        MHD_HTTP_UNAUTHORIZED,
+        "invalid_grant",
+        TALER_EC_CHALLENGER_CLIENT_FORBIDDEN_BAD_CODE,
+        "code");
     }
     GNUNET_free (code);
   }
 
   {
-    struct CHALLENGER_AccessTokenP grant;
+    struct CHALLENGER_AccessTokenP token;
     enum GNUNET_DB_QueryStatus qs;
     /* FIXME: do not hard-code 1h? */
-    struct GNUNET_TIME_Relative grant_expiration
+    struct GNUNET_TIME_Relative token_expiration
       = GNUNET_TIME_UNIT_HOURS;
 
     GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
-                                &grant,
-                                sizeof (grant));
+                                &token,
+                                sizeof (token));
     qs = CH_db->token_add_grant (CH_db->cls,
                                  &bc->nonce,
-                                 &grant,
-                                 grant_expiration,
+                                 &token,
+                                 token_expiration,
                                  CH_validation_expiration);
     switch (qs)
     {
     case GNUNET_DB_STATUS_HARD_ERROR:
       GNUNET_break (0);
-      return TALER_MHD_reply_with_error (hc->connection,
-                                         MHD_HTTP_INTERNAL_SERVER_ERROR,
-                                         TALER_EC_GENERIC_DB_STORE_FAILED,
-                                         "token_add_grant");
+      return TALER_MHD_reply_with_error (
+        hc->connection,
+        MHD_HTTP_INTERNAL_SERVER_ERROR,
+        TALER_EC_GENERIC_DB_STORE_FAILED,
+        "token_add_grant");
     case GNUNET_DB_STATUS_SOFT_ERROR:
       GNUNET_break (0);
       return MHD_NO;
     case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
       GNUNET_break (0);
-      return TALER_MHD_reply_with_error (hc->connection,
-                                         MHD_HTTP_NOT_FOUND,
-                                         TALER_EC_CHALLENGER_GRANT_UNKNOWN,
-                                         "token_add_grant");
+      return TALER_MHD_reply_with_oauth_error (
+        hc->connection,
+        MHD_HTTP_UNAUTHORIZED,
+        "invalid_grant",
+        TALER_EC_CHALLENGER_GRANT_UNKNOWN,
+        "token_add_grant");
     case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
       break;
     }
@@ -432,11 +459,11 @@ CH_handler_token (struct CH_HandlerContext *hc,
       hc->connection,
       MHD_HTTP_OK,
       GNUNET_JSON_pack_data_auto ("access_token",
-                                  &grant),
+                                  &token),
       GNUNET_JSON_pack_string ("token_type",
                                "Bearer"),
       GNUNET_JSON_pack_uint64 ("expires_in",
-                               grant_expiration.rel_value_us
+                               token_expiration.rel_value_us
                                / GNUNET_TIME_UNIT_SECONDS.rel_value_us));
   }
 }

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]