LCOV - code coverage report
Current view: top level - lib - merchant_api_get-private-kyc.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 67.8 % 236 160
Test Date: 2026-09-11 17:45:24 Functions: 100.0 % 6 6

            Line data    Source code
       1              : /*
       2              :   This file is part of TALER
       3              :   Copyright (C) 2023-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 Lesser General Public License as published by the Free Software
       7              :   Foundation; either version 2.1, 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 Lesser General Public License for more details.
      12              : 
      13              :   You should have received a copy of the GNU Lesser General Public License along with
      14              :   TALER; see the file COPYING.LGPL.  If not, see
      15              :   <http://www.gnu.org/licenses/>
      16              : */
      17              : /**
      18              :  * @file src/lib/merchant_api_get-private-kyc.c
      19              :  * @brief Implementation of the GET /private/kyc request
      20              :  * @author Christian Grothoff
      21              :  */
      22              : #include "platform.h"
      23              : #include <curl/curl.h>
      24              : #include <jansson.h>
      25              : #include <microhttpd.h> /* just for HTTP status codes */
      26              : #include <gnunet/gnunet_util_lib.h>
      27              : #include <gnunet/gnunet_curl_lib.h>
      28              : #include <taler/merchant/get-private-kyc.h>
      29              : #include "merchant_api_curl_defaults.h"
      30              : #include <taler/taler_json_lib.h>
      31              : 
      32              : 
      33              : /**
      34              :  * Maximum length of the KYC arrays supported.
      35              :  */
      36              : #define MAX_KYC 1024
      37              : 
      38              : 
      39              : /**
      40              :  * Handle for a GET /private/kyc operation.
      41              :  */
      42              : struct TALER_MERCHANT_GetPrivateKycHandle
      43              : {
      44              :   /**
      45              :    * Base URL of the merchant backend.
      46              :    */
      47              :   char *base_url;
      48              : 
      49              :   /**
      50              :    * The full URL for this request.
      51              :    */
      52              :   char *url;
      53              : 
      54              :   /**
      55              :    * Handle for the request.
      56              :    */
      57              :   struct GNUNET_CURL_Job *job;
      58              : 
      59              :   /**
      60              :    * Function to call with the result.
      61              :    */
      62              :   TALER_MERCHANT_GetPrivateKycCallback cb;
      63              : 
      64              :   /**
      65              :    * Closure for @a cb.
      66              :    */
      67              :   TALER_MERCHANT_GET_PRIVATE_KYC_RESULT_CLOSURE *cb_cls;
      68              : 
      69              :   /**
      70              :    * Reference to the execution context.
      71              :    */
      72              :   struct GNUNET_CURL_Context *ctx;
      73              : 
      74              :   /**
      75              :    * Hash of the wire account to filter by, or NULL.
      76              :    */
      77              :   const struct TALER_MerchantWireHashP *h_wire;
      78              : 
      79              :   /**
      80              :    * Storage for the h_wire value (if set).
      81              :    */
      82              :   struct TALER_MerchantWireHashP h_wire_val;
      83              : 
      84              :   /**
      85              :    * True if @e h_wire was set.
      86              :    */
      87              :   bool have_h_wire;
      88              : 
      89              :   /**
      90              :    * Exchange URL filter, or NULL.
      91              :    */
      92              :   char *exchange_url;
      93              : 
      94              :   /**
      95              :    * Long-poll target.
      96              :    */
      97              :   enum TALER_EXCHANGE_KycLongPollTarget lpt;
      98              : 
      99              :   /**
     100              :    * Long polling timeout.
     101              :    */
     102              :   struct GNUNET_TIME_Relative timeout;
     103              : 
     104              :   /**
     105              :    * Instance ID for management mode, or NULL.
     106              :    */
     107              :   char *instance_id;
     108              : 
     109              :   /**
     110              :    * Long-poll status filter, or NULL.
     111              :    */
     112              :   char *lp_status;
     113              : 
     114              :   /**
     115              :    * Long-poll negated status filter, or NULL.
     116              :    */
     117              :   char *lp_not_status;
     118              : 
     119              :   /**
     120              :    * Long-poll ETag to suppress unchanged responses.
     121              :    */
     122              :   struct GNUNET_ShortHashCode lp_not_etag;
     123              : 
     124              :   /**
     125              :    * True if @e lp_not_etag was set.
     126              :    */
     127              :   bool have_lp_not_etag;
     128              : };
     129              : 
     130              : 
     131              : /**
     132              :  * Parse @a jkyc response and call the continuation on success.
     133              :  *
     134              :  * @param kyc operation handle
     135              :  * @param[in,out] kr response details
     136              :  * @param jkyc array from the reply
     137              :  * @return #GNUNET_OK on success (callback was called)
     138              :  */
     139              : static enum GNUNET_GenericReturnValue
     140            7 : parse_kyc (struct TALER_MERCHANT_GetPrivateKycHandle *kyc,
     141              :            struct TALER_MERCHANT_GetPrivateKycResponse *kr,
     142              :            const json_t *jkyc)
     143              : {
     144            7 :   unsigned int num_kycs = (unsigned int) json_array_size (jkyc);
     145            7 :   unsigned int num_limits = 0;
     146            7 :   unsigned int num_kycauths = 0;
     147            7 :   unsigned int pos_limits = 0;
     148            7 :   unsigned int pos_kycauths = 0;
     149              : 
     150            7 :   if ( (json_array_size (jkyc) != (size_t) num_kycs) ||
     151              :        (num_kycs > MAX_KYC) )
     152              :   {
     153            0 :     GNUNET_break_op (0);
     154            0 :     return GNUNET_SYSERR;
     155              :   }
     156              : 
     157           14 :   for (unsigned int i = 0; i<num_kycs; i++)
     158              :   {
     159            7 :     const json_t *jlimits = NULL;
     160            7 :     const json_t *jkycauths = NULL;
     161              :     struct GNUNET_JSON_Specification spec[] = {
     162            7 :       GNUNET_JSON_spec_mark_optional (
     163              :         GNUNET_JSON_spec_array_const (
     164              :           "limits",
     165              :           &jlimits),
     166              :         NULL),
     167            7 :       GNUNET_JSON_spec_mark_optional (
     168              :         GNUNET_JSON_spec_array_const (
     169              :           "payto_kycauths",
     170              :           &jkycauths),
     171              :         NULL),
     172            7 :       GNUNET_JSON_spec_end ()
     173              :     };
     174              : 
     175            7 :     if (GNUNET_OK !=
     176            7 :         GNUNET_JSON_parse (json_array_get (jkyc,
     177              :                                            i),
     178              :                            spec,
     179              :                            NULL, NULL))
     180              :     {
     181            0 :       GNUNET_break_op (0);
     182            0 :       return GNUNET_SYSERR;
     183              :     }
     184            7 :     num_limits += json_array_size (jlimits);
     185            7 :     num_kycauths += json_array_size (jkycauths);
     186            7 :     if ( (num_limits > MAX_KYC) ||
     187              :          (num_kycauths > MAX_KYC) )
     188              :     {
     189              :       /* Bound the stack VLAs declared below by an untrusted response. */
     190            0 :       GNUNET_break_op (0);
     191            0 :       return GNUNET_SYSERR;
     192              :     }
     193              :   }
     194              : 
     195            7 :   {
     196            7 :     struct TALER_MERCHANT_GetPrivateKycRedirectDetail kycs[
     197            7 :       GNUNET_NZL (num_kycs)];
     198            7 :     struct TALER_EXCHANGE_AccountLimit limits[
     199            7 :       GNUNET_NZL (num_limits)];
     200            7 :     struct TALER_FullPayto payto_kycauths[
     201            7 :       GNUNET_NZL (num_kycauths)];
     202              : 
     203            7 :     memset (kycs,
     204              :             0,
     205              :             sizeof (kycs));
     206           14 :     for (unsigned int i = 0; i<num_kycs; i++)
     207              :     {
     208            7 :       struct TALER_MERCHANT_GetPrivateKycRedirectDetail *rd
     209              :         = &kycs[i];
     210            7 :       const json_t *jlimits = NULL;
     211            7 :       const json_t *jkycauths = NULL;
     212              :       uint32_t hs;
     213              :       struct GNUNET_JSON_Specification spec[] = {
     214            7 :         TALER_JSON_spec_full_payto_uri (
     215              :           "payto_uri",
     216              :           &rd->payto_uri),
     217            7 :         TALER_JSON_spec_web_url (
     218              :           "exchange_url",
     219              :           &rd->exchange_url),
     220            7 :         GNUNET_JSON_spec_uint32 (
     221              :           "exchange_http_status",
     222              :           &hs),
     223            7 :         GNUNET_JSON_spec_bool (
     224              :           "no_keys",
     225              :           &rd->no_keys),
     226            7 :         GNUNET_JSON_spec_bool (
     227              :           "auth_conflict",
     228              :           &rd->auth_conflict),
     229            7 :         GNUNET_JSON_spec_mark_optional (
     230              :           TALER_JSON_spec_ec (
     231              :             "exchange_code",
     232              :             &rd->exchange_code),
     233              :           NULL),
     234            7 :         GNUNET_JSON_spec_mark_optional (
     235            7 :           GNUNET_JSON_spec_fixed_auto (
     236              :             "access_token",
     237              :             &rd->access_token),
     238              :           &rd->no_access_token),
     239            7 :         GNUNET_JSON_spec_fixed_auto (
     240              :           "h_wire",
     241              :           &rd->h_wire),
     242            7 :         GNUNET_JSON_spec_mark_optional (
     243              :           GNUNET_JSON_spec_string (
     244              :             "status",
     245              :             &rd->status),
     246              :           NULL),
     247              :         /* Mandatory since **v25** */
     248            7 :         GNUNET_JSON_spec_mark_optional (
     249              :           GNUNET_JSON_spec_string (
     250              :             "exchange_currency",
     251              :             &rd->exchange_currency),
     252              :           NULL),
     253            7 :         GNUNET_JSON_spec_mark_optional (
     254              :           GNUNET_JSON_spec_array_const (
     255              :             "limits",
     256              :             &jlimits),
     257              :           NULL),
     258            7 :         GNUNET_JSON_spec_mark_optional (
     259              :           GNUNET_JSON_spec_array_const (
     260              :             "payto_kycauths",
     261              :             &jkycauths),
     262              :           NULL),
     263            7 :         GNUNET_JSON_spec_end ()
     264              :       };
     265              :       size_t j;
     266              :       json_t *jlimit;
     267              :       json_t *jkycauth;
     268              : 
     269            7 :       if (GNUNET_OK !=
     270            7 :           GNUNET_JSON_parse (json_array_get (jkyc,
     271              :                                              i),
     272              :                              spec,
     273              :                              NULL, NULL))
     274              :       {
     275            0 :         GNUNET_break_op (0);
     276            0 :         return GNUNET_SYSERR;
     277              :       }
     278            7 :       rd->exchange_http_status = (unsigned int) hs;
     279            7 :       rd->limits = &limits[pos_limits];
     280            7 :       rd->limits_length = json_array_size (jlimits);
     281           10 :       json_array_foreach (jlimits, j, jlimit)
     282              :       {
     283            3 :         struct TALER_EXCHANGE_AccountLimit *limit
     284              :           = &limits[pos_limits];
     285              :         struct GNUNET_JSON_Specification jspec[] = {
     286            3 :           TALER_JSON_spec_kycte (
     287              :             "operation_type",
     288              :             &limit->operation_type),
     289            3 :           GNUNET_JSON_spec_relative_time (
     290              :             "timeframe",
     291              :             &limit->timeframe),
     292            3 :           TALER_JSON_spec_amount_any (
     293              :             "threshold",
     294              :             &limit->threshold),
     295            3 :           GNUNET_JSON_spec_mark_optional (
     296              :             GNUNET_JSON_spec_bool (
     297              :               "soft_limit",
     298              :               &limit->soft_limit),
     299              :             NULL),
     300            3 :           GNUNET_JSON_spec_end ()
     301              :         };
     302              : 
     303            3 :         GNUNET_assert (pos_limits < num_limits);
     304            3 :         limit->soft_limit = false;
     305            3 :         if (GNUNET_OK !=
     306            3 :             GNUNET_JSON_parse (jlimit,
     307              :                                jspec,
     308              :                                NULL, NULL))
     309              :         {
     310            0 :           GNUNET_break_op (0);
     311            0 :           return GNUNET_SYSERR;
     312              :         }
     313            3 :         pos_limits++;
     314              :       }
     315            7 :       rd->payto_kycauths = &payto_kycauths[pos_kycauths];
     316            7 :       rd->pkycauth_length = json_array_size (jkycauths);
     317            8 :       json_array_foreach (jkycauths, j, jkycauth)
     318              :       {
     319            1 :         GNUNET_assert (pos_kycauths < num_kycauths);
     320              :         payto_kycauths[pos_kycauths].full_payto
     321            1 :           = (char *) json_string_value (jkycauth);
     322            1 :         if (NULL == payto_kycauths[pos_kycauths].full_payto)
     323              :         {
     324            0 :           GNUNET_break_op (0);
     325            0 :           return GNUNET_SYSERR;
     326              :         }
     327            1 :         pos_kycauths++;
     328              :       }
     329              :     }
     330            7 :     kr->details.ok.kycs = kycs;
     331            7 :     kr->details.ok.kycs_length = num_kycs;
     332            7 :     kyc->cb (kyc->cb_cls,
     333              :              kr);
     334            7 :     kyc->cb = NULL;
     335              :   }
     336            7 :   return GNUNET_OK;
     337              : }
     338              : 
     339              : 
     340              : /**
     341              :  * Function called when we're done processing the
     342              :  * HTTP GET /private/kyc request.
     343              :  *
     344              :  * @param cls the `struct TALER_MERCHANT_GetPrivateKycHandle`
     345              :  * @param response_code HTTP response code, 0 on error
     346              :  * @param response response body, NULL if not in JSON
     347              :  */
     348              : static void
     349            9 : handle_get_kyc_finished (void *cls,
     350              :                          long response_code,
     351              :                          const void *response)
     352              : {
     353            9 :   struct TALER_MERCHANT_GetPrivateKycHandle *kyc = cls;
     354            9 :   const json_t *json = response;
     355            9 :   struct TALER_MERCHANT_GetPrivateKycResponse kr = {
     356            9 :     .hr.http_status = (unsigned int) response_code,
     357              :     .hr.reply = json
     358              :   };
     359              : 
     360            9 :   kyc->job = NULL;
     361            9 :   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
     362              :               "Got /private/kyc response with status code %u\n",
     363              :               (unsigned int) response_code);
     364            9 :   switch (response_code)
     365              :   {
     366            7 :   case MHD_HTTP_OK:
     367              :     {
     368              :       const json_t *jkyc;
     369              :       struct GNUNET_JSON_Specification spec[] = {
     370            7 :         GNUNET_JSON_spec_array_const ("kyc_data",
     371              :                                       &jkyc),
     372            7 :         GNUNET_JSON_spec_end ()
     373              :       };
     374              : 
     375            7 :       if (GNUNET_OK !=
     376            7 :           GNUNET_JSON_parse (json,
     377              :                              spec,
     378              :                              NULL, NULL))
     379              :       {
     380            0 :         kr.hr.http_status = 0;
     381            0 :         kr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
     382            0 :         break;
     383              :       }
     384            7 :       if (GNUNET_OK !=
     385            7 :           parse_kyc (kyc,
     386              :                      &kr,
     387              :                      jkyc))
     388              :       {
     389            0 :         kr.hr.http_status = 0;
     390            0 :         kr.hr.ec = TALER_EC_GENERIC_INVALID_RESPONSE;
     391            0 :         break;
     392              :       }
     393              :       /* parse_kyc called the continuation already */
     394            7 :       TALER_MERCHANT_get_private_kyc_cancel (kyc);
     395            7 :       return;
     396              :     }
     397            2 :   case MHD_HTTP_NO_CONTENT:
     398            2 :     break;
     399            0 :   case MHD_HTTP_NOT_MODIFIED:
     400              :     /* ETag matched; nothing changed. No body expected. */
     401            0 :     break;
     402            0 :   case MHD_HTTP_BAD_REQUEST:
     403            0 :     kr.hr.ec = TALER_JSON_get_error_code (json);
     404            0 :     kr.hr.hint = TALER_JSON_get_error_hint (json);
     405            0 :     break;
     406            0 :   case MHD_HTTP_UNAUTHORIZED:
     407            0 :     kr.hr.ec = TALER_JSON_get_error_code (json);
     408            0 :     kr.hr.hint = TALER_JSON_get_error_hint (json);
     409            0 :     break;
     410            0 :   case MHD_HTTP_NOT_FOUND:
     411            0 :     kr.hr.ec = TALER_JSON_get_error_code (json);
     412            0 :     kr.hr.hint = TALER_JSON_get_error_hint (json);
     413            0 :     break;
     414            0 :   case MHD_HTTP_NOT_ACCEPTABLE:
     415            0 :     kr.hr.ec = TALER_JSON_get_error_code (json);
     416            0 :     kr.hr.hint = TALER_JSON_get_error_hint (json);
     417            0 :     break;
     418            0 :   case MHD_HTTP_SERVICE_UNAVAILABLE:
     419            0 :     break;
     420            0 :   default:
     421            0 :     kr.hr.ec = TALER_JSON_get_error_code (json);
     422            0 :     kr.hr.hint = TALER_JSON_get_error_hint (json);
     423            0 :     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
     424              :                 "Unexpected response code %u/%d\n",
     425              :                 (unsigned int) response_code,
     426              :                 (int) kr.hr.ec);
     427            0 :     break;
     428              :   }
     429            2 :   kyc->cb (kyc->cb_cls,
     430              :            &kr);
     431            2 :   TALER_MERCHANT_get_private_kyc_cancel (kyc);
     432              : }
     433              : 
     434              : 
     435              : struct TALER_MERCHANT_GetPrivateKycHandle *
     436            9 : TALER_MERCHANT_get_private_kyc_create (
     437              :   struct GNUNET_CURL_Context *ctx,
     438              :   const char *url)
     439              : {
     440              :   struct TALER_MERCHANT_GetPrivateKycHandle *kyc;
     441              : 
     442            9 :   kyc = GNUNET_new (struct TALER_MERCHANT_GetPrivateKycHandle);
     443            9 :   kyc->ctx = ctx;
     444            9 :   kyc->base_url = GNUNET_strdup (url);
     445            9 :   kyc->lpt = TALER_EXCHANGE_KLPT_NONE;
     446            9 :   return kyc;
     447              : }
     448              : 
     449              : 
     450              : enum GNUNET_GenericReturnValue
     451           15 : TALER_MERCHANT_get_private_kyc_set_options_ (
     452              :   struct TALER_MERCHANT_GetPrivateKycHandle *kyc,
     453              :   unsigned int num_options,
     454              :   const struct TALER_MERCHANT_GetPrivateKycOptionValue *options)
     455              : {
     456           34 :   for (unsigned int i = 0; i < num_options; i++)
     457              :   {
     458           34 :     const struct TALER_MERCHANT_GetPrivateKycOptionValue *opt =
     459           34 :       &options[i];
     460              : 
     461           34 :     switch (opt->option)
     462              :     {
     463           15 :     case TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_END:
     464           15 :       return GNUNET_OK;
     465            2 :     case TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_H_WIRE:
     466            2 :       if (NULL != opt->details.h_wire)
     467              :       {
     468            2 :         kyc->h_wire_val = *opt->details.h_wire;
     469            2 :         kyc->h_wire = &kyc->h_wire_val;
     470            2 :         kyc->have_h_wire = true;
     471              :       }
     472            2 :       break;
     473            9 :     case TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_EXCHANGE_URL:
     474            9 :       GNUNET_free (kyc->exchange_url);
     475            9 :       if (NULL != opt->details.exchange_url)
     476            9 :         kyc->exchange_url = GNUNET_strdup (opt->details.exchange_url);
     477            9 :       break;
     478            4 :     case TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_LPT:
     479            4 :       kyc->lpt = opt->details.lpt;
     480            4 :       break;
     481            4 :     case TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_TIMEOUT:
     482            4 :       kyc->timeout = opt->details.timeout;
     483            4 :       break;
     484            0 :     case TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_INSTANCE_ID:
     485            0 :       GNUNET_free (kyc->instance_id);
     486            0 :       if (NULL != opt->details.instance_id)
     487            0 :         kyc->instance_id = GNUNET_strdup (opt->details.instance_id);
     488            0 :       break;
     489            0 :     case TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_LP_STATUS:
     490            0 :       GNUNET_free (kyc->lp_status);
     491            0 :       if (NULL != opt->details.lp_status)
     492            0 :         kyc->lp_status = GNUNET_strdup (opt->details.lp_status);
     493            0 :       break;
     494            0 :     case TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_LP_NOT_STATUS:
     495            0 :       GNUNET_free (kyc->lp_not_status);
     496            0 :       if (NULL != opt->details.lp_not_status)
     497            0 :         kyc->lp_not_status = GNUNET_strdup (opt->details.lp_not_status);
     498            0 :       break;
     499            0 :     case TALER_MERCHANT_GET_PRIVATE_KYC_OPTION_LP_NOT_ETAG:
     500            0 :       if (NULL != opt->details.lp_not_etag)
     501              :       {
     502            0 :         kyc->lp_not_etag = *opt->details.lp_not_etag;
     503            0 :         kyc->have_lp_not_etag = true;
     504              :       }
     505            0 :       break;
     506            0 :     default:
     507            0 :       GNUNET_break (0);
     508            0 :       return GNUNET_NO;
     509              :     }
     510              :   }
     511            0 :   return GNUNET_OK;
     512              : }
     513              : 
     514              : 
     515              : enum TALER_ErrorCode
     516            9 : TALER_MERCHANT_get_private_kyc_start (
     517              :   struct TALER_MERCHANT_GetPrivateKycHandle *kyc,
     518              :   TALER_MERCHANT_GetPrivateKycCallback cb,
     519              :   TALER_MERCHANT_GET_PRIVATE_KYC_RESULT_CLOSURE *cb_cls)
     520              : {
     521              :   CURL *eh;
     522              :   unsigned long long tms;
     523              :   char timeout_ms[32];
     524              :   char lpt_str[32];
     525              :   char *base_path;
     526              : 
     527            9 :   kyc->cb = cb;
     528            9 :   kyc->cb_cls = cb_cls;
     529              : 
     530              :   /* Build the base path depending on whether instance_id is set */
     531            9 :   if (NULL != kyc->instance_id)
     532              :   {
     533            0 :     GNUNET_asprintf (&base_path,
     534              :                      "%smanagement/instances/%s/",
     535              :                      kyc->base_url,
     536              :                      kyc->instance_id);
     537              :   }
     538              :   else
     539              :   {
     540            9 :     GNUNET_asprintf (&base_path,
     541              :                      "%sprivate/",
     542              :                      kyc->base_url);
     543              :   }
     544              : 
     545            9 :   GNUNET_snprintf (lpt_str,
     546              :                    sizeof (lpt_str),
     547              :                    "%d",
     548            9 :                    (int) kyc->lpt);
     549           18 :   tms = kyc->timeout.rel_value_us
     550            9 :         / GNUNET_TIME_UNIT_MILLISECONDS.rel_value_us;
     551            9 :   GNUNET_snprintf (timeout_ms,
     552              :                    sizeof (timeout_ms),
     553              :                    "%llu",
     554              :                    tms);
     555              :   {
     556              :     char etag_str[sizeof (struct GNUNET_ShortHashCode) * 2 + 1];
     557              : 
     558            9 :     if (kyc->have_lp_not_etag)
     559              :     {
     560              :       char *end;
     561              : 
     562            0 :       end = GNUNET_STRINGS_data_to_string (
     563            0 :         &kyc->lp_not_etag,
     564              :         sizeof (kyc->lp_not_etag),
     565              :         etag_str,
     566              :         sizeof (etag_str) - 1);
     567            0 :       *end = '\0';
     568              :     }
     569              :     kyc->url
     570           36 :       = TALER_url_join (
     571              :           base_path,
     572              :           "kyc",
     573              :           "h_wire",
     574            9 :           kyc->have_h_wire
     575            2 :           ? GNUNET_h2s_full (&kyc->h_wire_val.hash)
     576              :           : NULL,
     577              :           "exchange_url",
     578              :           kyc->exchange_url,
     579              :           "timeout_ms",
     580            9 :           GNUNET_TIME_relative_is_zero (kyc->timeout)
     581              :           ? NULL
     582              :           : timeout_ms,
     583              :           "lpt",
     584            9 :           TALER_EXCHANGE_KLPT_NONE == kyc->lpt
     585              :           ? NULL
     586              :           : lpt_str,
     587              :           "lp_status",
     588              :           kyc->lp_status,
     589              :           "lp_not_status",
     590              :           kyc->lp_not_status,
     591              :           "lp_not_etag",
     592            9 :           kyc->have_lp_not_etag
     593              :           ? etag_str
     594              :           : NULL,
     595              :           NULL);
     596              :   }
     597            9 :   GNUNET_free (base_path);
     598            9 :   if (NULL == kyc->url)
     599            0 :     return TALER_EC_GENERIC_CONFIGURATION_INVALID;
     600            9 :   eh = TALER_MERCHANT_curl_easy_get_ (kyc->url);
     601            9 :   if (NULL == eh)
     602            0 :     return TALER_EC_GENERIC_CONFIGURATION_INVALID;
     603            9 :   if (0 != tms)
     604              :   {
     605            4 :     GNUNET_break (CURLE_OK ==
     606              :                   curl_easy_setopt (eh,
     607              :                                     CURLOPT_TIMEOUT_MS,
     608              :                                     (long) (tms + 100L)));
     609              :   }
     610            9 :   kyc->job = GNUNET_CURL_job_add (kyc->ctx,
     611              :                                   eh,
     612              :                                   &handle_get_kyc_finished,
     613              :                                   kyc);
     614            9 :   if (NULL == kyc->job)
     615            0 :     return TALER_EC_GENERIC_INTERNAL_INVARIANT_FAILURE;
     616            9 :   return TALER_EC_NONE;
     617              : }
     618              : 
     619              : 
     620              : void
     621            9 : TALER_MERCHANT_get_private_kyc_cancel (
     622              :   struct TALER_MERCHANT_GetPrivateKycHandle *kyc)
     623              : {
     624            9 :   if (NULL != kyc->job)
     625              :   {
     626            0 :     GNUNET_CURL_job_cancel (kyc->job);
     627            0 :     kyc->job = NULL;
     628              :   }
     629            9 :   GNUNET_free (kyc->url);
     630            9 :   GNUNET_free (kyc->exchange_url);
     631            9 :   GNUNET_free (kyc->instance_id);
     632            9 :   GNUNET_free (kyc->lp_status);
     633            9 :   GNUNET_free (kyc->lp_not_status);
     634            9 :   GNUNET_free (kyc->base_url);
     635            9 :   GNUNET_free (kyc);
     636            9 : }
     637              : 
     638              : 
     639              : /* end of merchant_api_get-private-kyc-new.c */
        

Generated by: LCOV version 2.0-1