diff options
author | Christian Grothoff <christian@grothoff.org> | 2021-01-31 22:21:40 +0100 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2021-01-31 22:21:40 +0100 |
commit | 25c0b949ab5a77cc6aafc442cecbcaca0c49b3f1 (patch) | |
tree | 3a9fa189296b17b5523e656008d3951a2a682c5f /src/backend/taler-merchant-httpd.c | |
parent | 83f0cd871092dcd547eee18c2b67ec10ac1828ff (diff) | |
download | merchant-25c0b949ab5a77cc6aafc442cecbcaca0c49b3f1.tar.gz merchant-25c0b949ab5a77cc6aafc442cecbcaca0c49b3f1.tar.bz2 merchant-25c0b949ab5a77cc6aafc442cecbcaca0c49b3f1.zip |
implement access control (#6731)
Diffstat (limited to 'src/backend/taler-merchant-httpd.c')
-rw-r--r-- | src/backend/taler-merchant-httpd.c | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/src/backend/taler-merchant-httpd.c b/src/backend/taler-merchant-httpd.c index 6e6318d2..85318ad9 100644 --- a/src/backend/taler-merchant-httpd.c +++ b/src/backend/taler-merchant-httpd.c @@ -153,6 +153,10 @@ static struct GNUNET_SCHEDULER_Task *resume_timeout_task; */ static const struct GNUNET_CONFIGURATION_Handle *cfg; +/** + * Initial authorization token. + */ +static char *default_auth; /** * Holds data needed to determine when to resume a connection for @@ -179,6 +183,8 @@ TMH_check_auth (const char *token, { struct GNUNET_HashCode val; + if (GNUNET_is_zero (hash)) + return GNUNET_OK; GNUNET_assert (GNUNET_YES == GNUNET_CRYPTO_kdf (&val, sizeof (val), @@ -1476,6 +1482,15 @@ url_handler (void *cls, { /* use 'default' */ hc->instance = TMH_lookup_instance (NULL); + if ( (NULL != default_auth) && + (NULL != hc->instance) ) + { + /* Override default instance access control */ + TMH_compute_auth (default_auth, + &hc->instance->settings.auth_salt, + &hc->instance->settings.auth_hash); + GNUNET_free (default_auth); + } } if (NULL != hc->instance) hc->instance->rc++; @@ -1496,6 +1511,57 @@ url_handler (void *cls, handlers = (use_private) ? private_handlers : public_handlers; } } + + /* Access control for private handlers */ + if (use_private) + { + const char *auth; + + auth = MHD_lookup_connection_value (connection, + MHD_HEADER_KIND, + MHD_HTTP_HEADER_AUTHORIZATION); + if (NULL != auth) + { + if (0 != strncasecmp (auth, + "secret-token:", + strlen ("secret-token:"))) + { + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_UNAUTHORIZED, + TALER_EC_GENERIC_PARAMETER_MALFORMED, + "'secret-token:' prefix missing in 'Authorization' header"); + } + auth += strlen ("secret-token:"); + } + if (NULL == hc->instance) + { + /* maybe before default instance is even created? + Check against 'default_auth' */ + if ( (NULL != default_auth) && + (0 != strcmp (auth, + default_auth)) ) + { + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_UNAUTHORIZED, + TALER_EC_MERCHANT_GENERIC_UNAUTHORIZED, + "Command-line authentication override is in effect"); + } + } + else + { + if (GNUNET_OK != + TMH_check_auth (auth, + &hc->instance->settings.auth_salt, + &hc->instance->settings.auth_hash)) + { + return TALER_MHD_reply_with_error (connection, + MHD_HTTP_UNAUTHORIZED, + TALER_EC_MERCHANT_GENERIC_UNAUTHORIZED, + "Check 'Authentication' header"); + } + } + } + if (0 == strcmp (url, "")) url = "/"; /* code below does not like empty string */ @@ -1728,10 +1794,15 @@ run (void *cls, enum TALER_MHD_GlobalOptions go; int elen; int alen; + const char *tok; (void) cls; (void) args; (void) cfgfile; + tok = getenv ("TALER_MERCHANT_TOKEN"); + if ( (NULL != tok) && + (NULL == default_auth) ) + default_auth = GNUNET_strdup (tok); cfg = config; GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Starting taler-merchant-httpd\n"); @@ -1881,6 +1952,11 @@ main (int argc, &merchant_connection_close), GNUNET_GETOPT_option_timetravel ('T', "timetravel"), + GNUNET_GETOPT_option_string ('a', + "auth", + "TOKEN", + "use TOKEN to initially authenticate access to the default instance (you can also set the TALER_MERCHANT_TOKEN environment variable instead)", + &default_auth), GNUNET_GETOPT_OPTION_END }; |