diff options
Diffstat (limited to 'src/lib/merchant_api_get_instances.c')
-rw-r--r-- | src/lib/merchant_api_get_instances.c | 181 |
1 files changed, 90 insertions, 91 deletions
diff --git a/src/lib/merchant_api_get_instances.c b/src/lib/merchant_api_get_instances.c index 52a462b9..b2f99853 100644 --- a/src/lib/merchant_api_get_instances.c +++ b/src/lib/merchant_api_get_instances.c @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014-2018, 2020 Taler Systems SA + Copyright (C) 2014-2023 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software @@ -32,6 +32,11 @@ /** + * Maximum number of instances permitted. + */ +#define MAX_INSTANCES 1024 + +/** * Handle for a GET /instances operation. */ struct TALER_MERCHANT_InstancesGetHandle @@ -67,79 +72,82 @@ struct TALER_MERCHANT_InstancesGetHandle /** * Parse instance information from @a ia. * + * @param json overall reply body * @param ia JSON array (or NULL!) with instance data * @param igh operation handle * @return #GNUNET_OK on success */ -static int -parse_instances (const json_t *ia, +static enum GNUNET_GenericReturnValue +parse_instances (const json_t *json, + const json_t *ia, struct TALER_MERCHANT_InstancesGetHandle *igh) { - unsigned int iis_len = json_array_size (ia); - struct TALER_MERCHANT_InstanceInformation iis[iis_len]; - size_t index; - json_t *value; - int ret; + unsigned int iis_len = (unsigned int) json_array_size (ia); - ret = GNUNET_OK; - json_array_foreach (ia, index, value) { - struct TALER_MERCHANT_InstanceInformation *ii = &iis[index]; - struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_string ("name", - &ii->name), - GNUNET_JSON_spec_string ("id", - &ii->id), - GNUNET_JSON_spec_fixed_auto ("merchant_pub", - &ii->merchant_pub), - GNUNET_JSON_spec_json ("payment_targets", - &ii->payment_targets), - GNUNET_JSON_spec_end () + if ( (json_array_size (ia) != (size_t) iis_len) || + (iis_len > MAX_INSTANCES) ) + { + GNUNET_break (0); + return GNUNET_SYSERR; + } + { + struct TALER_MERCHANT_InstanceInformation iis[GNUNET_NZL (iis_len)]; + size_t index; + json_t *value; + struct TALER_MERCHANT_InstancesGetResponse igr = { + .hr.http_status = MHD_HTTP_OK, + .hr.reply = json, + .details.ok.iis_length = iis_len, + .details.ok.iis = iis }; - if (GNUNET_OK != - GNUNET_JSON_parse (value, - spec, - NULL, NULL)) - { - GNUNET_break_op (0); - ret = GNUNET_SYSERR; - continue; - } - if (! json_is_array (ii->payment_targets)) - { - GNUNET_break_op (0); - ret = GNUNET_SYSERR; - break; - } - for (unsigned int i = 0; i<json_array_size (ii->payment_targets); i++) - { - if (! json_is_string (json_array_get (ii->payment_targets, - i))) + json_array_foreach (ia, index, value) { + struct TALER_MERCHANT_InstanceInformation *ii = &iis[index]; + const char *uts; + struct GNUNET_JSON_Specification spec[] = { + GNUNET_JSON_spec_string ("name", + &ii->name), + GNUNET_JSON_spec_string ("user_type", + &uts), + GNUNET_JSON_spec_string ("id", + &ii->id), + GNUNET_JSON_spec_fixed_auto ("merchant_pub", + &ii->merchant_pub), + GNUNET_JSON_spec_array_const ("payment_targets", + &ii->payment_targets), + GNUNET_JSON_spec_end () + }; + + if (GNUNET_OK != + GNUNET_JSON_parse (value, + spec, + NULL, NULL)) { GNUNET_break_op (0); - ret = GNUNET_SYSERR; - break; + return GNUNET_SYSERR; } - } - if (GNUNET_SYSERR == ret) - break; - } - if (GNUNET_OK == ret) - { - struct TALER_MERCHANT_HttpResponse hr = { - .http_status = MHD_HTTP_OK - }; - + if (GNUNET_OK != + TALER_KYCLOGIC_kyc_user_type_from_string (uts, + &ii->ut)) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + for (size_t i = 0; i<json_array_size (ii->payment_targets); i++) + { + if (! json_is_string (json_array_get (ii->payment_targets, + i))) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + } + } /* for all instances */ igh->cb (igh->cb_cls, - &hr, - iis_len, - iis); + &igr); igh->cb = NULL; /* just to be sure */ } - for (unsigned int i = 0; i<iis_len; i++) - if (NULL != iis[i].payment_targets) - json_decref (iis[i].payment_targets); - return ret; + return GNUNET_OK; } @@ -158,9 +166,9 @@ handle_instances_finished (void *cls, { struct TALER_MERCHANT_InstancesGetHandle *igh = cls; const json_t *json = response; - struct TALER_MERCHANT_HttpResponse hr = { - .http_status = (unsigned int) response_code, - .reply = json + struct TALER_MERCHANT_InstancesGetResponse igr = { + .hr.http_status = (unsigned int) response_code, + .hr.reply = json }; igh->job = NULL; @@ -171,10 +179,10 @@ handle_instances_finished (void *cls, { case MHD_HTTP_OK: { - json_t *instances; + const json_t *instances; struct GNUNET_JSON_Specification spec[] = { - GNUNET_JSON_spec_json ("instances", - &instances), + GNUNET_JSON_spec_array_const ("instances", + &instances), GNUNET_JSON_spec_end () }; @@ -183,47 +191,38 @@ handle_instances_finished (void *cls, spec, NULL, NULL)) { - hr.http_status = 0; - hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + igr.hr.http_status = 0; + igr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; + break; } - else + if (GNUNET_OK == + parse_instances (json, + instances, + igh)) { - if ( (! json_is_array (instances)) || - (GNUNET_OK == - parse_instances (instances, - igh)) ) - { - GNUNET_JSON_parse_free (spec); - TALER_MERCHANT_instances_get_cancel (igh); - return; - } - else - { - hr.http_status = 0; - hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; - } + TALER_MERCHANT_instances_get_cancel (igh); + return; } - GNUNET_JSON_parse_free (spec); + igr.hr.http_status = 0; + igr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE; break; } case MHD_HTTP_UNAUTHORIZED: - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + igr.hr.ec = TALER_JSON_get_error_code (json); + igr.hr.hint = TALER_JSON_get_error_hint (json); break; default: /* unexpected response code */ - hr.ec = TALER_JSON_get_error_code (json); - hr.hint = TALER_JSON_get_error_hint (json); + igr.hr.ec = TALER_JSON_get_error_code (json); + igr.hr.hint = TALER_JSON_get_error_hint (json); GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unexpected response code %u/%d\n", (unsigned int) response_code, - (int) hr.ec); + (int) igr.hr.ec); break; } igh->cb (igh->cb_cls, - &hr, - 0, - NULL); + &igr); TALER_MERCHANT_instances_get_cancel (igh); } |