LCOV - code coverage report
Current view: top level - lib - exchange_api_get-aml-OFFICER_PUB-measures.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 251 0
Test Date: 2026-04-14 15:39:31 Functions: 0.0 % 12 0

            Line data    Source code
       1              : /*
       2              :   This file is part of TALER
       3              :   Copyright (C) 2023, 2024, 2026 Taler Systems SA
       4              : 
       5              :   TALER is free software; you can redistribute it and/or modify it under the
       6              :   terms of the GNU General Public License as published by the Free Software
       7              :   Foundation; either version 3, or (at your option) any later version.
       8              : 
       9              :   TALER is distributed in the hope that it will be useful, but WITHOUT ANY
      10              :   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
      11              :   A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
      12              : 
      13              :   You should have received a copy of the GNU General Public License along with
      14              :   TALER; see the file COPYING.  If not, see
      15              :   <http://www.gnu.org/licenses/>
      16              : */
      17              : /**
      18              :  * @file lib/exchange_api_get-aml-OFFICER_PUB-measures.c
      19              :  * @brief Implementation of the GET /aml/$OFFICER_PUB/measures request
      20              :  * @author Christian Grothoff
      21              :  */
      22              : #include <microhttpd.h> /* just for HTTP status codes */
      23              : #include <gnunet/gnunet_util_lib.h>
      24              : #include <gnunet/gnunet_curl_lib.h>
      25              : #include "taler/taler_json_lib.h"
      26              : #include "taler/exchange/get-aml-OFFICER_PUB-measures.h"
      27              : #include "exchange_api_handle.h"
      28              : #include "taler/taler_signatures.h"
      29              : #include "exchange_api_curl_defaults.h"
      30              : 
      31              : 
      32              : /**
      33              :  * Scrap buffer of temporary arrays.
      34              :  */
      35              : struct Scrap
      36              : {
      37              :   /**
      38              :    * Kept in DLL.
      39              :    */
      40              :   struct Scrap *next;
      41              : 
      42              :   /**
      43              :    * Kept in DLL.
      44              :    */
      45              :   struct Scrap *prev;
      46              : 
      47              :   /**
      48              :    * Pointer to our allocation.
      49              :    */
      50              :   const char **ptr;
      51              : };
      52              : 
      53              : 
      54              : /**
      55              :  * @brief A GET /aml/$OFFICER_PUB/measures Handle
      56              :  */
      57              : struct TALER_EXCHANGE_GetAmlMeasuresHandle
      58              : {
      59              : 
      60              :   /**
      61              :    * The base URL of the exchange.
      62              :    */
      63              :   char *base_url;
      64              : 
      65              :   /**
      66              :    * The full URL for this request, set during _start.
      67              :    */
      68              :   char *url;
      69              : 
      70              :   /**
      71              :    * Handle for the request.
      72              :    */
      73              :   struct GNUNET_CURL_Job *job;
      74              : 
      75              :   /**
      76              :    * Function to call with the result.
      77              :    */
      78              :   TALER_EXCHANGE_GetAmlMeasuresCallback cb;
      79              : 
      80              :   /**
      81              :    * Closure for @e cb.
      82              :    */
      83              :   TALER_EXCHANGE_GET_AML_MEASURES_RESULT_CLOSURE *cb_cls;
      84              : 
      85              :   /**
      86              :    * Reference to the execution context.
      87              :    */
      88              :   struct GNUNET_CURL_Context *ctx;
      89              : 
      90              :   /**
      91              :    * Public key of the AML officer.
      92              :    */
      93              :   struct TALER_AmlOfficerPublicKeyP officer_pub;
      94              : 
      95              :   /**
      96              :    * Private key of the AML officer (for signing).
      97              :    */
      98              :   struct TALER_AmlOfficerPrivateKeyP officer_priv;
      99              : 
     100              :   /**
     101              :    * Head of scrap list.
     102              :    */
     103              :   struct Scrap *scrap_head;
     104              : 
     105              :   /**
     106              :    * Tail of scrap list.
     107              :    */
     108              :   struct Scrap *scrap_tail;
     109              : };
     110              : 
     111              : 
     112              : /**
     113              :  * Create array of length @a len in scrap book.
     114              :  *
     115              :  * @param[in,out] amh context for allocations
     116              :  * @param len length of array
     117              :  * @return scrap array
     118              :  */
     119              : static const char **
     120            0 : make_scrap (
     121              :   struct TALER_EXCHANGE_GetAmlMeasuresHandle *amh,
     122              :   unsigned int len)
     123              : {
     124            0 :   struct Scrap *s = GNUNET_new (struct Scrap);
     125              : 
     126            0 :   s->ptr = GNUNET_new_array (len,
     127              :                              const char *);
     128            0 :   GNUNET_CONTAINER_DLL_insert (amh->scrap_head,
     129              :                                amh->scrap_tail,
     130              :                                s);
     131            0 :   return s->ptr;
     132              : }
     133              : 
     134              : 
     135              : /**
     136              :  * Free all scrap space.
     137              :  *
     138              :  * @param[in,out] amh scrap context
     139              :  */
     140              : static void
     141            0 : free_scrap (struct TALER_EXCHANGE_GetAmlMeasuresHandle *amh)
     142              : {
     143              :   struct Scrap *s;
     144              : 
     145            0 :   while (NULL != (s = amh->scrap_head))
     146              :   {
     147            0 :     GNUNET_CONTAINER_DLL_remove (amh->scrap_head,
     148              :                                  amh->scrap_tail,
     149              :                                  s);
     150            0 :     GNUNET_free (s->ptr);
     151            0 :     GNUNET_free (s);
     152              :   }
     153            0 : }
     154              : 
     155              : 
     156              : /**
     157              :  * Convert JSON array of strings to string array.
     158              :  *
     159              :  * @param j JSON array to convert
     160              :  * @param[out] a array to initialize
     161              :  * @return true on success
     162              :  */
     163              : static bool
     164            0 : j_to_a (const json_t *j,
     165              :         const char **a)
     166              : {
     167              :   const json_t *e;
     168              :   size_t idx;
     169              : 
     170            0 :   json_array_foreach ((json_t *) j, idx, e)
     171              :   {
     172            0 :     if (NULL == (a[idx] = json_string_value (e)))
     173            0 :       return false;
     174              :   }
     175            0 :   return true;
     176              : }
     177              : 
     178              : 
     179              : /**
     180              :  * Parse AML root measures.
     181              :  *
     182              :  * @param jroots JSON object with measure data
     183              :  * @param[out] roots where to write the result
     184              :  * @return #GNUNET_OK on success
     185              :  */
     186              : static enum GNUNET_GenericReturnValue
     187            0 : parse_aml_roots (
     188              :   const json_t *jroots,
     189              :   struct TALER_EXCHANGE_GetAmlMeasuresMeasureInfo *roots)
     190              : {
     191              :   const json_t *obj;
     192              :   const char *name;
     193            0 :   size_t idx = 0;
     194              : 
     195            0 :   json_object_foreach ((json_t *) jroots, name, obj)
     196              :   {
     197            0 :     struct TALER_EXCHANGE_GetAmlMeasuresMeasureInfo *root = &roots[idx++];
     198              :     struct GNUNET_JSON_Specification spec[] = {
     199            0 :       GNUNET_JSON_spec_string ("check_name",
     200              :                                &root->check_name),
     201            0 :       GNUNET_JSON_spec_mark_optional (
     202              :         GNUNET_JSON_spec_string ("prog_name",
     203              :                                  &root->prog_name),
     204              :         NULL),
     205            0 :       GNUNET_JSON_spec_mark_optional (
     206              :         GNUNET_JSON_spec_object_const ("context",
     207              :                                        &root->context),
     208              :         NULL),
     209            0 :       GNUNET_JSON_spec_mark_optional (
     210              :         GNUNET_JSON_spec_string ("operation_type",
     211              :                                  &root->operation_type),
     212              :         NULL),
     213            0 :       GNUNET_JSON_spec_mark_optional (
     214              :         GNUNET_JSON_spec_bool ("voluntary",
     215              :                                &root->voluntary),
     216              :         NULL),
     217            0 :       GNUNET_JSON_spec_end ()
     218              :     };
     219              : 
     220            0 :     if (GNUNET_OK !=
     221            0 :         GNUNET_JSON_parse (obj,
     222              :                            spec,
     223              :                            NULL,
     224              :                            NULL))
     225              :     {
     226            0 :       GNUNET_break_op (0);
     227            0 :       return GNUNET_SYSERR;
     228              :     }
     229            0 :     root->measure_name = name;
     230              :   }
     231            0 :   return GNUNET_OK;
     232              : }
     233              : 
     234              : 
     235              : /**
     236              :  * Parse AML programs.
     237              :  *
     238              :  * @param[in,out] amh context for allocations
     239              :  * @param jprogs JSON object with program data
     240              :  * @param[out] progs where to write the result
     241              :  * @return #GNUNET_OK on success
     242              :  */
     243              : static enum GNUNET_GenericReturnValue
     244            0 : parse_aml_programs (
     245              :   struct TALER_EXCHANGE_GetAmlMeasuresHandle *amh,
     246              :   const json_t *jprogs,
     247              :   struct TALER_EXCHANGE_GetAmlMeasuresProgramRequirement *progs)
     248              : {
     249              :   const json_t *obj;
     250              :   const char *name;
     251            0 :   size_t idx = 0;
     252              : 
     253            0 :   json_object_foreach ((json_t *) jprogs, name, obj)
     254              :   {
     255            0 :     struct TALER_EXCHANGE_GetAmlMeasuresProgramRequirement *prog = &progs[idx++]
     256              :     ;
     257              :     const json_t *jcontext;
     258              :     const json_t *jinputs;
     259              :     struct GNUNET_JSON_Specification spec[] = {
     260            0 :       GNUNET_JSON_spec_string ("description",
     261              :                                &prog->description),
     262            0 :       GNUNET_JSON_spec_array_const ("context",
     263              :                                     &jcontext),
     264            0 :       GNUNET_JSON_spec_array_const ("inputs",
     265              :                                     &jinputs),
     266            0 :       GNUNET_JSON_spec_end ()
     267              :     };
     268              :     unsigned int len;
     269              :     const char **ptr;
     270              : 
     271            0 :     if (GNUNET_OK !=
     272            0 :         GNUNET_JSON_parse (obj,
     273              :                            spec,
     274              :                            NULL,
     275              :                            NULL))
     276              :     {
     277            0 :       GNUNET_break_op (0);
     278            0 :       return GNUNET_SYSERR;
     279              :     }
     280            0 :     prog->prog_name = name;
     281            0 :     prog->contexts_length = json_array_size (jcontext);
     282            0 :     prog->inputs_length = json_array_size (jinputs);
     283            0 :     len = (unsigned int) (prog->contexts_length + prog->inputs_length);
     284            0 :     if ( ((size_t) len) != prog->contexts_length + prog->inputs_length)
     285              :     {
     286            0 :       GNUNET_break_op (0);
     287            0 :       return GNUNET_SYSERR;
     288              :     }
     289            0 :     ptr = make_scrap (amh, len);
     290            0 :     prog->contexts = ptr;
     291            0 :     if (! j_to_a (jcontext, prog->contexts))
     292              :     {
     293            0 :       GNUNET_break_op (0);
     294            0 :       return GNUNET_SYSERR;
     295              :     }
     296            0 :     prog->inputs = &ptr[prog->contexts_length];
     297            0 :     if (! j_to_a (jinputs, prog->inputs))
     298              :     {
     299            0 :       GNUNET_break_op (0);
     300            0 :       return GNUNET_SYSERR;
     301              :     }
     302              :   }
     303            0 :   return GNUNET_OK;
     304              : }
     305              : 
     306              : 
     307              : /**
     308              :  * Parse KYC checks.
     309              :  *
     310              :  * @param[in,out] amh context for allocations
     311              :  * @param jchecks JSON object with check data
     312              :  * @param[out] checks where to write the result
     313              :  * @return #GNUNET_OK on success
     314              :  */
     315              : static enum GNUNET_GenericReturnValue
     316            0 : parse_aml_checks (
     317              :   struct TALER_EXCHANGE_GetAmlMeasuresHandle *amh,
     318              :   const json_t *jchecks,
     319              :   struct TALER_EXCHANGE_GetAmlMeasuresCheckInfo *checks)
     320              : {
     321              :   const json_t *obj;
     322              :   const char *name;
     323            0 :   size_t idx = 0;
     324              : 
     325            0 :   json_object_foreach ((json_t *) jchecks, name, obj)
     326              :   {
     327            0 :     struct TALER_EXCHANGE_GetAmlMeasuresCheckInfo *check = &checks[idx++];
     328              :     const json_t *jrequires;
     329              :     const json_t *joutputs;
     330              :     struct GNUNET_JSON_Specification spec[] = {
     331            0 :       GNUNET_JSON_spec_string ("description",
     332              :                                &check->description),
     333            0 :       GNUNET_JSON_spec_mark_optional (
     334              :         GNUNET_JSON_spec_object_const ("description_i18n",
     335              :                                        &check->description_i18n),
     336              :         NULL),
     337            0 :       GNUNET_JSON_spec_array_const ("requires",
     338              :                                     &jrequires),
     339            0 :       GNUNET_JSON_spec_array_const ("outputs",
     340              :                                     &joutputs),
     341            0 :       GNUNET_JSON_spec_string ("fallback",
     342              :                                &check->fallback),
     343            0 :       GNUNET_JSON_spec_end ()
     344              :     };
     345              :     unsigned int len;
     346              :     const char **ptr;
     347              : 
     348            0 :     if (GNUNET_OK !=
     349            0 :         GNUNET_JSON_parse (obj,
     350              :                            spec,
     351              :                            NULL,
     352              :                            NULL))
     353              :     {
     354            0 :       GNUNET_break_op (0);
     355            0 :       return GNUNET_SYSERR;
     356              :     }
     357            0 :     check->check_name = name;
     358            0 :     check->requires_length = json_array_size (jrequires);
     359            0 :     check->outputs_length = json_array_size (joutputs);
     360            0 :     len = (unsigned int) (check->requires_length + check->outputs_length);
     361            0 :     if ( ((size_t) len) != check->requires_length + check->outputs_length)
     362              :     {
     363            0 :       GNUNET_break_op (0);
     364            0 :       return GNUNET_SYSERR;
     365              :     }
     366            0 :     ptr = make_scrap (amh, len);
     367            0 :     check->requires = ptr;
     368            0 :     if (! j_to_a (jrequires, check->requires))
     369              :     {
     370            0 :       GNUNET_break_op (0);
     371            0 :       return GNUNET_SYSERR;
     372              :     }
     373            0 :     check->outputs = &ptr[check->requires_length];
     374            0 :     if (! j_to_a (joutputs, check->outputs))
     375              :     {
     376            0 :       GNUNET_break_op (0);
     377            0 :       return GNUNET_SYSERR;
     378              :     }
     379              :   }
     380            0 :   return GNUNET_OK;
     381              : }
     382              : 
     383              : 
     384              : /**
     385              :  * Parse default KYC rules from the default_rules array.
     386              :  *
     387              :  * @param[in,out] amh context for allocations
     388              :  * @param jrules JSON array with rule data
     389              :  * @param[out] rules where to write the result
     390              :  * @return #GNUNET_OK on success
     391              :  */
     392              : static enum GNUNET_GenericReturnValue
     393            0 : parse_default_rules (
     394              :   struct TALER_EXCHANGE_GetAmlMeasuresHandle *amh,
     395              :   const json_t *jrules,
     396              :   struct TALER_EXCHANGE_GetAmlMeasuresKycRule *rules)
     397              : {
     398              :   const json_t *obj;
     399              :   size_t idx;
     400              : 
     401            0 :   json_array_foreach ((json_t *) jrules, idx, obj)
     402              :   {
     403            0 :     struct TALER_EXCHANGE_GetAmlMeasuresKycRule *rule = &rules[idx];
     404              :     const json_t *jmeasures;
     405              :     struct GNUNET_JSON_Specification spec[] = {
     406            0 :       TALER_JSON_spec_kycte ("operation_type",
     407              :                              &rule->operation_type),
     408            0 :       GNUNET_JSON_spec_mark_optional (
     409              :         GNUNET_JSON_spec_string ("rule_name",
     410              :                                  &rule->rule_name),
     411              :         NULL),
     412            0 :       TALER_JSON_spec_amount_any ("threshold",
     413              :                                   &rule->threshold),
     414            0 :       GNUNET_JSON_spec_relative_time ("timeframe",
     415              :                                       &rule->timeframe),
     416            0 :       GNUNET_JSON_spec_array_const ("measures",
     417              :                                     &jmeasures),
     418            0 :       GNUNET_JSON_spec_mark_optional (
     419              :         GNUNET_JSON_spec_bool ("exposed",
     420              :                                &rule->exposed),
     421              :         NULL),
     422            0 :       GNUNET_JSON_spec_mark_optional (
     423              :         GNUNET_JSON_spec_bool ("is_and_combinator",
     424              :                                &rule->is_and_combinator),
     425              :         NULL),
     426            0 :       GNUNET_JSON_spec_int64 ("display_priority",
     427              :                               &rule->display_priority),
     428            0 :       GNUNET_JSON_spec_end ()
     429              :     };
     430              : 
     431            0 :     if (GNUNET_OK !=
     432            0 :         GNUNET_JSON_parse (obj,
     433              :                            spec,
     434              :                            NULL,
     435              :                            NULL))
     436              :     {
     437            0 :       GNUNET_break_op (0);
     438            0 :       return GNUNET_SYSERR;
     439              :     }
     440            0 :     rule->measures_length = json_array_size (jmeasures);
     441              :     {
     442            0 :       const char **ptr = make_scrap (amh,
     443            0 :                                      (unsigned int) rule->measures_length);
     444              : 
     445            0 :       rule->measures = ptr;
     446            0 :       if (! j_to_a (jmeasures,
     447              :                     ptr))
     448              :       {
     449            0 :         GNUNET_break_op (0);
     450            0 :         return GNUNET_SYSERR;
     451              :       }
     452              :     }
     453              :   }
     454            0 :   return GNUNET_OK;
     455              : }
     456              : 
     457              : 
     458              : /**
     459              :  * Parse the provided measures data from the "200 OK" response.
     460              :  *
     461              :  * @param[in,out] amh handle (callback may be zero'ed out)
     462              :  * @param json json reply with the data
     463              :  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
     464              :  */
     465              : static enum GNUNET_GenericReturnValue
     466            0 : parse_get_aml_measures_ok (struct TALER_EXCHANGE_GetAmlMeasuresHandle *amh,
     467              :                            const json_t *json)
     468              : {
     469            0 :   struct TALER_EXCHANGE_GetAmlMeasuresResponse lr = {
     470              :     .hr.reply = json,
     471              :     .hr.http_status = MHD_HTTP_OK
     472              :   };
     473              :   const json_t *jroots;
     474              :   const json_t *jprograms;
     475              :   const json_t *jchecks;
     476            0 :   const json_t *jdefault_rules = NULL;
     477              :   struct GNUNET_JSON_Specification spec[] = {
     478            0 :     GNUNET_JSON_spec_object_const ("roots",
     479              :                                    &jroots),
     480            0 :     GNUNET_JSON_spec_object_const ("programs",
     481              :                                    &jprograms),
     482            0 :     GNUNET_JSON_spec_object_const ("checks",
     483              :                                    &jchecks),
     484            0 :     GNUNET_JSON_spec_mark_optional (
     485              :       GNUNET_JSON_spec_array_const ("default_rules",
     486              :                                     &jdefault_rules),
     487              :       NULL),
     488            0 :     GNUNET_JSON_spec_end ()
     489              :   };
     490              : 
     491            0 :   if (GNUNET_OK !=
     492            0 :       GNUNET_JSON_parse (json,
     493              :                          spec,
     494              :                          NULL,
     495              :                          NULL))
     496              :   {
     497            0 :     GNUNET_break_op (0);
     498            0 :     return GNUNET_SYSERR;
     499              :   }
     500              : 
     501            0 :   lr.details.ok.roots_length = json_object_size (jroots);
     502            0 :   lr.details.ok.programs_length = json_object_size (jprograms);
     503            0 :   lr.details.ok.checks_length = json_object_size (jchecks);
     504            0 :   lr.details.ok.default_rules_length =
     505            0 :     (NULL != jdefault_rules) ? json_array_size (jdefault_rules) : 0;
     506              : 
     507            0 :   {
     508            0 :     struct TALER_EXCHANGE_GetAmlMeasuresMeasureInfo roots[
     509            0 :       GNUNET_NZL (lr.details.ok.roots_length)];
     510            0 :     struct TALER_EXCHANGE_GetAmlMeasuresProgramRequirement progs[
     511            0 :       GNUNET_NZL (lr.details.ok.programs_length)];
     512            0 :     struct TALER_EXCHANGE_GetAmlMeasuresCheckInfo checks[
     513            0 :       GNUNET_NZL (lr.details.ok.checks_length)];
     514            0 :     struct TALER_EXCHANGE_GetAmlMeasuresKycRule drules[
     515            0 :       GNUNET_NZL (lr.details.ok.default_rules_length)];
     516              :     enum GNUNET_GenericReturnValue ret;
     517              : 
     518            0 :     memset (roots, 0, sizeof (roots));
     519            0 :     memset (progs, 0, sizeof (progs));
     520            0 :     memset (checks, 0, sizeof (checks));
     521            0 :     memset (drules, 0, sizeof (drules));
     522            0 :     lr.details.ok.roots = roots;
     523            0 :     lr.details.ok.programs = progs;
     524            0 :     lr.details.ok.checks = checks;
     525            0 :     lr.details.ok.default_rules = drules;
     526              : 
     527            0 :     ret = parse_aml_roots (jroots, roots);
     528            0 :     if (GNUNET_OK == ret)
     529            0 :       ret = parse_aml_programs (amh, jprograms, progs);
     530            0 :     if (GNUNET_OK == ret)
     531            0 :       ret = parse_aml_checks (amh, jchecks, checks);
     532            0 :     if ( (GNUNET_OK == ret) && (NULL != jdefault_rules) )
     533            0 :       ret = parse_default_rules (amh, jdefault_rules, drules);
     534            0 :     if (GNUNET_OK == ret)
     535              :     {
     536            0 :       amh->cb (amh->cb_cls,
     537              :                &lr);
     538            0 :       amh->cb = NULL;
     539              :     }
     540            0 :     free_scrap (amh);
     541            0 :     return ret;
     542              :   }
     543              : }
     544              : 
     545              : 
     546              : /**
     547              :  * Function called when we're done processing the
     548              :  * HTTP GET /aml/$OFFICER_PUB/measures request.
     549              :  *
     550              :  * @param cls the `struct TALER_EXCHANGE_GetAmlMeasuresHandle`
     551              :  * @param response_code HTTP response code, 0 on error
     552              :  * @param response parsed JSON result, NULL on error
     553              :  */
     554              : static void
     555            0 : handle_get_aml_measures_finished (void *cls,
     556              :                                   long response_code,
     557              :                                   const void *response)
     558              : {
     559            0 :   struct TALER_EXCHANGE_GetAmlMeasuresHandle *amh = cls;
     560            0 :   const json_t *j = response;
     561            0 :   struct TALER_EXCHANGE_GetAmlMeasuresResponse lr = {
     562              :     .hr.reply = j,
     563            0 :     .hr.http_status = (unsigned int) response_code
     564              :   };
     565              : 
     566            0 :   amh->job = NULL;
     567            0 :   switch (response_code)
     568              :   {
     569            0 :   case 0:
     570            0 :     lr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
     571            0 :     break;
     572            0 :   case MHD_HTTP_OK:
     573            0 :     if (GNUNET_OK !=
     574            0 :         parse_get_aml_measures_ok (amh,
     575              :                                    j))
     576              :     {
     577            0 :       GNUNET_break_op (0);
     578            0 :       lr.hr.http_status = 0;
     579            0 :       lr.hr.ec = TALER_EC_GENERIC_REPLY_MALFORMED;
     580            0 :       break;
     581              :     }
     582            0 :     GNUNET_assert (NULL == amh->cb);
     583            0 :     TALER_EXCHANGE_get_aml_measures_cancel (amh);
     584            0 :     return;
     585            0 :   case MHD_HTTP_NO_CONTENT:
     586            0 :     break;
     587            0 :   case MHD_HTTP_BAD_REQUEST:
     588            0 :     lr.hr.ec = TALER_JSON_get_error_code (j);
     589            0 :     lr.hr.hint = TALER_JSON_get_error_hint (j);
     590            0 :     break;
     591            0 :   case MHD_HTTP_FORBIDDEN:
     592            0 :     lr.hr.ec = TALER_JSON_get_error_code (j);
     593            0 :     lr.hr.hint = TALER_JSON_get_error_hint (j);
     594            0 :     break;
     595            0 :   case MHD_HTTP_INTERNAL_SERVER_ERROR:
     596            0 :     lr.hr.ec = TALER_JSON_get_error_code (j);
     597            0 :     lr.hr.hint = TALER_JSON_get_error_hint (j);
     598            0 :     break;
     599            0 :   default:
     600              :     /* unexpected response code */
     601            0 :     GNUNET_break_op (0);
     602            0 :     lr.hr.ec = TALER_JSON_get_error_code (j);
     603            0 :     lr.hr.hint = TALER_JSON_get_error_hint (j);
     604            0 :     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     605              :                 "Unexpected response code %u/%d for GET AML measures\n",
     606              :                 (unsigned int) response_code,
     607              :                 (int) lr.hr.ec);
     608            0 :     break;
     609              :   }
     610            0 :   if (NULL != amh->cb)
     611            0 :     amh->cb (amh->cb_cls,
     612              :              &lr);
     613            0 :   TALER_EXCHANGE_get_aml_measures_cancel (amh);
     614              : }
     615              : 
     616              : 
     617              : struct TALER_EXCHANGE_GetAmlMeasuresHandle *
     618            0 : TALER_EXCHANGE_get_aml_measures_create (
     619              :   struct GNUNET_CURL_Context *ctx,
     620              :   const char *url,
     621              :   const struct TALER_AmlOfficerPrivateKeyP *officer_priv)
     622              : {
     623              :   struct TALER_EXCHANGE_GetAmlMeasuresHandle *amh;
     624              : 
     625            0 :   amh = GNUNET_new (struct TALER_EXCHANGE_GetAmlMeasuresHandle);
     626            0 :   amh->ctx = ctx;
     627            0 :   amh->base_url = GNUNET_strdup (url);
     628            0 :   amh->officer_priv = *officer_priv;
     629            0 :   GNUNET_CRYPTO_eddsa_key_get_public (&officer_priv->eddsa_priv,
     630              :                                       &amh->officer_pub.eddsa_pub);
     631            0 :   return amh;
     632              : }
     633              : 
     634              : 
     635              : enum TALER_ErrorCode
     636            0 : TALER_EXCHANGE_get_aml_measures_start (
     637              :   struct TALER_EXCHANGE_GetAmlMeasuresHandle *amh,
     638              :   TALER_EXCHANGE_GetAmlMeasuresCallback cb,
     639              :   TALER_EXCHANGE_GET_AML_MEASURES_RESULT_CLOSURE *cb_cls)
     640              : {
     641              :   CURL *eh;
     642              :   struct TALER_AmlOfficerSignatureP officer_sig;
     643              :   char arg_str[sizeof (struct TALER_AmlOfficerPublicKeyP) * 2 + 32];
     644            0 :   struct curl_slist *job_headers = NULL;
     645              : 
     646            0 :   amh->cb = cb;
     647            0 :   amh->cb_cls = cb_cls;
     648              : 
     649              :   /* Build AML officer signature */
     650            0 :   TALER_officer_aml_query_sign (&amh->officer_priv,
     651              :                                 &officer_sig);
     652              : 
     653              :   /* Build the path component: aml/{officer_pub}/measures */
     654              :   {
     655              :     char pub_str[sizeof (amh->officer_pub) * 2];
     656              :     char *end;
     657              : 
     658            0 :     end = GNUNET_STRINGS_data_to_string (
     659            0 :       &amh->officer_pub,
     660              :       sizeof (amh->officer_pub),
     661              :       pub_str,
     662              :       sizeof (pub_str));
     663            0 :     *end = '\0';
     664            0 :     GNUNET_snprintf (arg_str,
     665              :                      sizeof (arg_str),
     666              :                      "aml/%s/measures",
     667              :                      pub_str);
     668              :   }
     669              : 
     670            0 :   amh->url = TALER_url_join (amh->base_url,
     671              :                              arg_str,
     672              :                              NULL);
     673            0 :   if (NULL == amh->url)
     674            0 :     return TALER_EC_GENERIC_CONFIGURATION_INVALID;
     675              : 
     676            0 :   eh = TALER_EXCHANGE_curl_easy_get_ (amh->url);
     677            0 :   if (NULL == eh)
     678              :   {
     679            0 :     GNUNET_break (0);
     680            0 :     GNUNET_free (amh->url);
     681            0 :     amh->url = NULL;
     682            0 :     return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE;
     683              :   }
     684              : 
     685              :   /* Build job headers with AML officer signature */
     686              :   {
     687              :     char *hdr;
     688              :     char sig_str[sizeof (officer_sig) * 2];
     689              :     char *end;
     690              : 
     691            0 :     end = GNUNET_STRINGS_data_to_string (
     692              :       &officer_sig,
     693              :       sizeof (officer_sig),
     694              :       sig_str,
     695              :       sizeof (sig_str));
     696            0 :     *end = '\0';
     697              : 
     698            0 :     GNUNET_asprintf (&hdr,
     699              :                      "%s: %s",
     700              :                      TALER_AML_OFFICER_SIGNATURE_HEADER,
     701              :                      sig_str);
     702            0 :     job_headers = curl_slist_append (NULL,
     703              :                                      hdr);
     704            0 :     GNUNET_free (hdr);
     705              :   }
     706              : 
     707            0 :   amh->job = GNUNET_CURL_job_add2 (amh->ctx,
     708              :                                    eh,
     709              :                                    job_headers,
     710              :                                    &handle_get_aml_measures_finished,
     711              :                                    amh);
     712            0 :   curl_slist_free_all (job_headers);
     713              : 
     714            0 :   if (NULL == amh->job)
     715              :   {
     716            0 :     GNUNET_free (amh->url);
     717            0 :     amh->url = NULL;
     718            0 :     return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE;
     719              :   }
     720            0 :   return TALER_EC_NONE;
     721              : }
     722              : 
     723              : 
     724              : void
     725            0 : TALER_EXCHANGE_get_aml_measures_cancel (
     726              :   struct TALER_EXCHANGE_GetAmlMeasuresHandle *amh)
     727              : {
     728            0 :   if (NULL != amh->job)
     729              :   {
     730            0 :     GNUNET_CURL_job_cancel (amh->job);
     731            0 :     amh->job = NULL;
     732              :   }
     733            0 :   free_scrap (amh);
     734            0 :   GNUNET_free (amh->url);
     735            0 :   GNUNET_free (amh->base_url);
     736            0 :   GNUNET_free (amh);
     737            0 : }
     738              : 
     739              : 
     740              : /* end of exchange_api_get-aml-OFFICER_PUB-measures.c */
        

Generated by: LCOV version 2.0-1