challenger

OAuth 2.0-based authentication service that validates user can receive messages at a certain address
Log | Files | Refs | Submodules | README | LICENSE

commit 0f641329a9681509235cd679f3e775041a344d94
parent ff79e455b8947581000f2e4afb992938909224b9
Author: Christian Grothoff <grothoff@gnunet.org>
Date:   Wed, 26 Apr 2023 17:19:23 +0200

-cfg

Diffstat:
Msrc/challenger/Makefile.am | 1+
Msrc/challenger/challenger-httpd.c | 13+++++++++++++
Msrc/challenger/challenger-httpd.h | 5+++++
Asrc/challenger/challenger-httpd_common.c | 50++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/challenger/challenger-httpd_common.h | 37+++++++++++++++++++++++++++++++++++++
Msrc/challenger/challenger-httpd_setup.c | 98+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
Msrc/challenger/challenger-httpd_setup.h | 14+++++++-------
Msrc/challenger/challenger.conf | 4++++
8 files changed, 211 insertions(+), 11 deletions(-)

diff --git a/src/challenger/Makefile.am b/src/challenger/Makefile.am @@ -28,6 +28,7 @@ challenger_httpd_SOURCES = \ challenger-httpd.c challenger-httpd.h \ challenger-httpd_auth.c challenger-httpd_auth.h \ challenger-httpd_challenge.c challenger-httpd_challenge.h \ + challenger-httpd_common.c challenger-httpd_common.h \ challenger-httpd_config.c challenger-httpd_config.h \ challenger-httpd_info.c challenger-httpd_info.h \ challenger-httpd_login.c challenger-httpd_login.h \ diff --git a/src/challenger/challenger-httpd.c b/src/challenger/challenger-httpd.c @@ -490,6 +490,19 @@ run (void *cls, go = TALER_MHD_GO_NONE; if (CH_challenger_connection_close) go |= TALER_MHD_GO_FORCE_CONNECTION_CLOSE; + + if (GNUNET_OK != + GNUNET_CONFIGURATION_get_relative_time (config, + "CHALLENGER", + "VALIDATION_DURATION", + &CH_validation_duration)) + { + GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, + "CHALLENGER", + "VALIDATION_DURATION"); + return; + } + TALER_MHD_setup (go); result = EXIT_NOTCONFIGURED; GNUNET_SCHEDULER_add_shutdown (&do_shutdown, diff --git a/src/challenger/challenger-httpd.h b/src/challenger/challenger-httpd.h @@ -130,6 +130,11 @@ extern struct CHALLENGER_DatabasePlugin *db; extern struct GNUNET_CURL_Context *CH_ctx; /** + * How long is an individual validation request valid? + */ +extern struct GNUNET_TIME_Relative CH_validation_duration; + +/** * Kick MHD to run now, to be called after MHD_resume_connection(). * Basically, we need to explicitly resume MHD's event loop whenever * we made progress serving a request. This function re-schedules diff --git a/src/challenger/challenger-httpd_common.c b/src/challenger/challenger-httpd_common.c @@ -0,0 +1,50 @@ +/* + This file is part of Challenger + Copyright (C) 2023 Taler Systems SA + + Challenger is free software; you can redistribute it and/or modify it under the + terms of the GNU Affero General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + Challenger is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License along with + Challenger; see the file COPYING. If not, see <http://www.gnu.org/licenses/> +*/ +/** + * @file challenger-httpd_common.c + * @brief common helper functions + * @author Christian Grothoff + */ +#include "challenger-httpd_common.h" + + +const char * +CH_get_client_secret (struct MHD_Connection *connection) +{ + const char *auth; + const char *bearer = "Bearer "; + const char *tok = *auth; + + auth = MHD_lookup_connection_value (connection, + MHD_HEADER_KIND, + MHD_HTTP_HEADER_AUTHORIZATION); + if (0 != strncmp (tok, + bearer, + strlen (bearer))) + { + return NULL; + } + tok = tok + strlen (bearer); + while (' ' == *tok) + tok++; + if (0 != strncasecmp (tok, + RFC_8959_PREFIX, + strlen (RFC_8959_PREFIX))) + { + return NULL; + } + return tok; +} diff --git a/src/challenger/challenger-httpd_common.h b/src/challenger/challenger-httpd_common.h @@ -0,0 +1,37 @@ +/* + This file is part of Challenger + Copyright (C) 2023 Taler Systems SA + + Challenger is free software; you can redistribute it and/or modify it under the + terms of the GNU Affero General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + Challenger is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License along with + Challenger; see the file COPYING. If not, see <http://www.gnu.org/licenses/> +*/ +/** + * @file challenger-httpd_common.h + * @brief common helper functions + * @author Christian Grothoff + */ +#ifndef CHALLENGER_HTTPD_COMMON_H +#define CHALLENGER_HTTPD_COMMON_H + +#include <microhttpd.h> + +/** + * Extract the client secret from the + * authorization header of @a connection. + * + * @param connection HTTP connection to get client secret from + * @return NULL if there is no well-formed secret + */ +const char * +CH_get_client_secret (struct MHD_Connection *connection); + + +#endif diff --git a/src/challenger/challenger-httpd_setup.c b/src/challenger/challenger-httpd_setup.c @@ -22,6 +22,7 @@ #include "challenger-httpd.h" #include <gnunet/gnunet_util_lib.h> #include "challenger-httpd_setup.h" +#include "challenger-httpd_common.h" MHD_RESULT @@ -29,8 +30,97 @@ CH_handler_setup (struct CH_HandlerContext *hc, const char *upload_data, size_t *upload_data_size) { - return TALER_MHD_reply_with_error (hc->connection, - MHD_HTTP_INTERNAL_SERVER_ERROR, - TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE, - NULL); + unsigned long long client_id; + const char *client_secret; + + { + char dummy; + + if (1 != sscanf (hc->path, + "%llu%c", + &client_id, + &dummy)) + { + GNUNET_break_op (0); + return TALER_MHD_reply_with_error (hc->connection, + MHD_HTTP_NOT_FOUND, + TALER_EC_GENERIC_ENDPOINT_UNKNOWN, + hc->path); + } + } + client_secret = CH_get_client_secret (connection); + if (NULL == client_secret) + { + GNUNET_break_op (0); + return TALER_MHD_reply_with_error (hc->connection, + MHD_HTTP_NOT_FOUND, + TALER_EC_GENERIC_PARAMETER_MISSING, + MHD_HTTP_HEADER_AUTHORIZATION); + } + + { + enum GNUNET_DB_QueryStatus qs; + char *client_url = NULL; + + qs = db->client_check (db->cls, + (uint64_t) client_id, + client_secret, + 1, + &client_url); + switch (qs) + { + case GNUNET_DB_STATUS_HARD_ERROR: + case GNUNET_DB_STATUS_SOFT_ERROR: + GNUNET_break (0); + return TALER_MHD_reply_with_error (hc->connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_GENERIC_DB_FETCH_FAILED, + NULL); + case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: + return TALER_MHD_reply_with_error (hc->connection, + MHD_HTTP_NOT_FOUND, + TALER_EC_CHALLENGER_GENERIC_CLIENT_UNKNOWN, + NULL); + case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: + break; + } + GNUNET_free (client_url); + } + + { + struct CHALLENGER_ValidationNonceP nonce; + struct GNUNET_TIME_Absolute expiration_time; + enum GNUNET_DB_QueryStatus qs; + + expiration_time = GNUNET_TIME_relative_to_absolute (CH_validation_duration); + GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE, + &nonce, + sizeof (nonce)); + qs = db->validation_setup (db->cls, + &nonce, + expiration_time); + switch (qs) + { + case GNUNET_DB_STATUS_HARD_ERROR: + case GNUNET_DB_STATUS_SOFT_ERROR: + GNUNET_break (0); + return TALER_MHD_reply_with_error (hc->connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE, + NULL); + case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: + GNUNET_break (0); + return TALER_MHD_reply_with_error (hc->connection, + MHD_HTTP_INTERNAL_SERVER_ERROR, + TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE, + NULL); + case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: + break; + } + } + return TALER_MHD_REPLY_JSON_PACK ( + hc->connection, + MHD_HTTP_OK, + GNUNET_JSON_pack_data_auto ("nonce", + &nonce)); } diff --git a/src/challenger/challenger-httpd_setup.h b/src/challenger/challenger-httpd_setup.h @@ -1,27 +1,27 @@ /* - This file is part of TALER + This file is part of Challenger Copyright (C) 2023 Taler Systems SA - TALER is free software; you can redistribute it and/or modify it under the + Challenger is free software; you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. - TALER is distributed in the hope that it will be useful, but WITHOUT ANY + Challenger is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with - TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + Challenger; see the file COPYING. If not, see <http://www.gnu.org/licenses/> */ /** - * @file challenger-httpd_login.h - * @brief functions to handle incoming requests on /login + * @file challenger-httpd_setup.h + * @brief functions to handle incoming requests on /setup * @author Christian Grothoff */ #ifndef CHALLENGER_HTTPD_SETUP_H #define CHALLENGER_HTTPD_SETUP_H -#include <microhttpd.h> +#include "challenger-httpd.h" /** diff --git a/src/challenger/challenger.conf b/src/challenger/challenger.conf @@ -23,3 +23,7 @@ UNIXPATH_MODE = 660 # Which database backend do we use? DB = postgres + +# How long is an individual validation request valid? +VALIDATION_DURATION = 1d +