/*
This file is part of Taler
Copyright (C) 2018-2023 Taler Systems SA
Taler is free software; you can redistribute it and/or modify it under the
terms of the GNU 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
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
Taler; see the file COPYING. If not, see
*/
/**
* @file bank/mb_parse.c
* @brief Convenience function to parse authentication configuration
* @author Christian Grothoff
*/
#include "platform.h"
#include "taler_merchant_bank_lib.h"
#include
/**
* Names of authentication methods available.
*/
static const struct
{
const char *m;
enum TALER_MERCHANT_BANK_AuthenticationMethod e;
} methods[] = {
{ "NONE", TALER_MERCHANT_BANK_AUTH_NONE },
{ "BASIC", TALER_MERCHANT_BANK_AUTH_BASIC },
{ "BEARER", TALER_MERCHANT_BANK_AUTH_BEARER },
{ NULL, TALER_MERCHANT_BANK_AUTH_NONE }
};
enum GNUNET_GenericReturnValue
TALER_MERCHANT_BANK_auth_parse_cfg (
const struct GNUNET_CONFIGURATION_Handle *cfg,
const char *section,
struct TALER_MERCHANT_BANK_AuthenticationData *auth)
{
char *method;
if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_string (cfg,
section,
"WIRE_GATEWAY_URL",
&auth->wire_gateway_url))
{
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
section,
"WIRE_GATEWAY_URL");
return GNUNET_SYSERR;
}
if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_string (cfg,
section,
"WIRE_GATEWAY_AUTH_METHOD",
&method))
{
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
section,
"WIRE_GATEWAY_AUTH_METHOD");
GNUNET_free (auth->wire_gateway_url);
return GNUNET_SYSERR;
}
for (unsigned int i = 0; NULL != methods[i].m; i++)
{
if (0 == strcasecmp (method,
methods[i].m))
{
switch (methods[i].e)
{
case TALER_MERCHANT_BANK_AUTH_NONE:
auth->method = TALER_MERCHANT_BANK_AUTH_NONE;
GNUNET_free (method);
return GNUNET_OK;
case TALER_MERCHANT_BANK_AUTH_BASIC:
if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_string (cfg,
section,
"USERNAME",
&auth->details.basic.username))
{
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
section,
"USERNAME");
GNUNET_free (method);
GNUNET_free (auth->wire_gateway_url);
return GNUNET_SYSERR;
}
if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_string (cfg,
section,
"PASSWORD",
&auth->details.basic.password))
{
GNUNET_free (auth->details.basic.username);
auth->details.basic.username = NULL;
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
section,
"PASSWORD");
GNUNET_free (method);
GNUNET_free (auth->wire_gateway_url);
return GNUNET_SYSERR;
}
auth->method = TALER_MERCHANT_BANK_AUTH_BASIC;
GNUNET_free (method);
return GNUNET_OK;
case TALER_MERCHANT_BANK_AUTH_BEARER:
if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_string (cfg,
section,
"TOKEN",
&auth->details.bearer.token))
{
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
section,
"TOKEN");
GNUNET_free (method);
GNUNET_free (auth->wire_gateway_url);
return GNUNET_SYSERR;
}
auth->method = TALER_MERCHANT_BANK_AUTH_BEARER;
GNUNET_free (method);
return GNUNET_OK;
}
}
}
GNUNET_free (method);
return GNUNET_SYSERR;
}
enum GNUNET_GenericReturnValue
TALER_MERCHANT_BANK_auth_parse_json (
const json_t *cred,
const char *backend_url,
struct TALER_MERCHANT_BANK_AuthenticationData *auth)
{
const char *method;
if (NULL == backend_url)
{
GNUNET_break_op (0);
return GNUNET_SYSERR;
}
if ( (0 == strlen (backend_url)) ||
('/' != backend_url[strlen (backend_url) - 1]) )
{
GNUNET_break_op (0);
return GNUNET_SYSERR;
}
auth->wire_gateway_url = GNUNET_strdup (backend_url);
method = json_string_value (json_object_get (cred,
"type"));
if (NULL == method)
{
GNUNET_break_op (0);
return GNUNET_SYSERR;
}
for (unsigned int i = 0; NULL != methods[i].m; i++)
{
if (0 == strcasecmp (method,
methods[i].m))
{
switch (methods[i].e)
{
case TALER_MERCHANT_BANK_AUTH_NONE:
auth->method = TALER_MERCHANT_BANK_AUTH_NONE;
return GNUNET_OK;
case TALER_MERCHANT_BANK_AUTH_BASIC:
{
const char *username;
const char *password;
struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_string ("username",
&username),
GNUNET_JSON_spec_string ("password",
&password),
GNUNET_JSON_spec_end ()
};
enum GNUNET_GenericReturnValue res;
const char *err;
unsigned int eline;
res = GNUNET_JSON_parse (cred,
spec,
&err,
&eline);
if (GNUNET_OK != res)
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"Credentials malformed: %s (%u)\n",
err,
eline);
GNUNET_free (auth->wire_gateway_url);
return GNUNET_SYSERR;
}
auth->details.basic.username = GNUNET_strdup (username);
auth->details.basic.password = GNUNET_strdup (password);
}
auth->method = TALER_MERCHANT_BANK_AUTH_BASIC;
return GNUNET_OK;
case TALER_MERCHANT_BANK_AUTH_BEARER:
{
const char *token;
struct GNUNET_JSON_Specification spec[] = {
GNUNET_JSON_spec_string ("token",
&token),
GNUNET_JSON_spec_end ()
};
enum GNUNET_GenericReturnValue res;
const char *err;
unsigned int eline;
res = GNUNET_JSON_parse (cred,
spec,
&err,
&eline);
if (GNUNET_OK != res)
{
GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
"Credentials malformed: %s (%u)\n",
err,
eline);
GNUNET_free (auth->wire_gateway_url);
return GNUNET_SYSERR;
}
auth->details.bearer.token = GNUNET_strdup (token);
}
auth->method = TALER_MERCHANT_BANK_AUTH_BEARER;
return GNUNET_OK;
}
}
}
return GNUNET_SYSERR;
}
void
TALER_MERCHANT_BANK_auth_free (
struct TALER_MERCHANT_BANK_AuthenticationData *auth)
{
switch (auth->method)
{
case TALER_MERCHANT_BANK_AUTH_NONE:
break;
case TALER_MERCHANT_BANK_AUTH_BASIC:
GNUNET_free (auth->details.basic.username);
GNUNET_free (auth->details.basic.password);
break;
case TALER_MERCHANT_BANK_AUTH_BEARER:
GNUNET_free (auth->details.bearer.token);
break;
}
GNUNET_free (auth->wire_gateway_url);
}
/* end of mb_parse.c */