anastasis

Credential backup and recovery protocol and service
Log | Files | Refs | Submodules | README | LICENSE

testing_api_cmd_truth_challenge.c (9735B)


      1 /*
      2   This file is part of Anastasis
      3   Copyright (C) 2020, 2022 Anastasis SARL
      4 
      5   Anastasis 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   Anastasis 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   Anastasis; see the file COPYING.GPL.  If not, see <http://www.gnu.org/licenses/>
     15 */
     16 /**
     17  * @file testing/testing_api_cmd_truth_challenge.c
     18  * @brief Testing of Implementation of the /truth GET
     19  * @author Christian Grothoff
     20  * @author Dennis Neufeld
     21  * @author Dominik Meister
     22  */
     23 
     24 #include "platform.h"
     25 struct TruthChallengeState;
     26 #define ANASTASIS_TRUTH_CHALLENGE_RESULT_CLOSURE struct TruthChallengeState
     27 #include "anastasis_testing_lib.h"
     28 #include <taler/taler_util.h>
     29 #include <taler/taler_testing_lib.h>
     30 #include <taler/taler_merchant_service.h>
     31 
     32 
     33 /**
     34  * State for a "keyshare lookup" CMD.
     35  */
     36 struct TruthChallengeState
     37 {
     38   /**
     39    * The interpreter state.
     40    */
     41   struct TALER_TESTING_Interpreter *is;
     42 
     43   /**
     44    * URL of the anastasis backend.
     45    */
     46   const char *anastasis_url;
     47 
     48   /**
     49    * Expected HTTP status code.
     50    */
     51   unsigned int expected_http_status;
     52 
     53   /**
     54    * The /truth GET operation handle.
     55    */
     56   struct ANASTASIS_TruthChallengeOperation *tco;
     57 
     58   /**
     59    * Reference to upload command we expect to lookup.
     60    */
     61   const char *upload_reference;
     62 
     63   /**
     64    * Reference to upload command we expect to lookup.
     65    */
     66   const char *payment_reference;
     67 
     68   /**
     69    * Payment secret requested by the service, if any.
     70    */
     71   struct ANASTASIS_PaymentSecretP payment_secret_response;
     72 
     73   /**
     74    * Taler-URI with payment request, if any.
     75    */
     76   char *pay_uri;
     77 
     78   /**
     79    * Order ID for payment request, if any.
     80    */
     81   char *order_id;
     82 
     83   /**
     84    * "code" returned by service, if any.
     85    */
     86   char *code;
     87 
     88   /**
     89    * "instructions" for how to solve the challenge as returned by service, if any.
     90    */
     91   char *instructions;
     92 
     93 };
     94 
     95 
     96 static void
     97 truth_challenge_cb (struct TruthChallengeState *ksls,
     98                     const struct ANASTASIS_TruthChallengeDetails *tcd)
     99 {
    100   ksls->tco = NULL;
    101   if (tcd->http_status != ksls->expected_http_status)
    102   {
    103     TALER_TESTING_unexpected_status (ksls->is,
    104                                      tcd->http_status,
    105                                      ksls->expected_http_status);
    106     return;
    107   }
    108   switch (tcd->http_status)
    109   {
    110   case MHD_HTTP_OK:
    111     switch (tcd->details.success.cs)
    112     {
    113     case ANASTASIS_CS_FILE_WRITTEN:
    114       {
    115         FILE *file;
    116         char code[22];
    117 
    118         file = fopen (tcd->details.success.details.challenge_filename,
    119                       "r");
    120         if (NULL == file)
    121         {
    122           GNUNET_log_strerror_file (
    123             GNUNET_ERROR_TYPE_ERROR,
    124             "open",
    125             tcd->details.success.details.challenge_filename);
    126           TALER_TESTING_interpreter_fail (ksls->is);
    127           return;
    128         }
    129         /* fscanf returns EOF (-1), not 0, on an empty/short file; checking
    130            `0 ==` misses that and would use the uninitialized `code` buffer. */
    131         if (1 != fscanf (file,
    132                          "%21s",
    133                          code))
    134         {
    135           GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
    136                                     "fscanf",
    137                                     tcd->details.success.details.
    138                                     challenge_filename);
    139           GNUNET_break (0 == fclose (file));
    140           TALER_TESTING_interpreter_fail (ksls->is);
    141           return;
    142         }
    143         GNUNET_break (0 == fclose (file));
    144         ksls->code = GNUNET_strdup (code);
    145         GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
    146                     "Read code `%s'\n",
    147                     code);
    148       }
    149       break;
    150     case ANASTASIS_CS_TAN_SENT:
    151       ksls->instructions = GNUNET_strdup (
    152         tcd->details.success.details.tan_address_hint);
    153       break;
    154     case ANASTASIS_CS_TAN_ALREADY_SENT:
    155       break;
    156     case ANASTASIS_CS_WIRE_FUNDS:
    157       /* FIXME: not implemented */
    158       GNUNET_break (0);
    159       return;
    160     }
    161     break;
    162   case MHD_HTTP_PAYMENT_REQUIRED:
    163     ksls->pay_uri = GNUNET_strdup (
    164       tcd->details.payment_required.payment_request);
    165     ksls->payment_secret_response = tcd->details.payment_required.ps;
    166     {
    167       struct TALER_MERCHANT_PayUriData pd;
    168 
    169       if (GNUNET_OK !=
    170           TALER_MERCHANT_parse_pay_uri (ksls->pay_uri,
    171                                         &pd))
    172       {
    173         GNUNET_break (0);
    174         TALER_TESTING_interpreter_fail (ksls->is);
    175         return;
    176       }
    177       ksls->order_id = GNUNET_strdup (pd.order_id);
    178       TALER_MERCHANT_parse_pay_uri_free (&pd);
    179     }
    180 
    181     break;
    182   default:
    183     break;
    184   }
    185   TALER_TESTING_interpreter_next (ksls->is);
    186 }
    187 
    188 
    189 static void
    190 truth_challenge_run (void *cls,
    191                      const struct TALER_TESTING_Command *cmd,
    192                      struct TALER_TESTING_Interpreter *is)
    193 {
    194   struct TruthChallengeState *ksls = cls;
    195   const struct ANASTASIS_CRYPTO_TruthKeyP *truth_key;
    196   const struct ANASTASIS_CRYPTO_TruthUUIDP *truth_uuid;
    197   const struct ANASTASIS_PaymentSecretP *payment_secret;
    198 
    199   ksls->is = is;
    200   if (NULL == ksls->upload_reference)
    201   {
    202     GNUNET_break (0);
    203     TALER_TESTING_interpreter_fail (ksls->is);
    204     return;
    205   }
    206   {
    207     const struct TALER_TESTING_Command *upload_cmd;
    208 
    209     upload_cmd = TALER_TESTING_interpreter_lookup_command (
    210       is,
    211       ksls->upload_reference);
    212     if (NULL == upload_cmd)
    213     {
    214       GNUNET_break (0);
    215       TALER_TESTING_interpreter_fail (ksls->is);
    216       return;
    217     }
    218     if (GNUNET_OK !=
    219         ANASTASIS_TESTING_get_trait_truth_uuid (upload_cmd,
    220                                                 &truth_uuid))
    221     {
    222       GNUNET_break (0);
    223       TALER_TESTING_interpreter_fail (ksls->is);
    224       return;
    225     }
    226     if (NULL == truth_uuid)
    227     {
    228       GNUNET_break (0);
    229       TALER_TESTING_interpreter_fail (ksls->is);
    230       return;
    231     }
    232     if (GNUNET_OK !=
    233         ANASTASIS_TESTING_get_trait_truth_key (upload_cmd,
    234                                                &truth_key))
    235     {
    236       GNUNET_break (0);
    237       TALER_TESTING_interpreter_fail (ksls->is);
    238       return;
    239     }
    240     if (NULL == truth_key)
    241     {
    242       GNUNET_break (0);
    243       TALER_TESTING_interpreter_fail (ksls->is);
    244       return;
    245     }
    246   }
    247 
    248   if (NULL != ksls->payment_reference)
    249   {
    250     const struct TALER_TESTING_Command *payment_cmd;
    251 
    252     payment_cmd = TALER_TESTING_interpreter_lookup_command (
    253       is,
    254       ksls->payment_reference);
    255     if (GNUNET_OK !=
    256         ANASTASIS_TESTING_get_trait_payment_secret (payment_cmd,
    257                                                     &payment_secret))
    258     {
    259       GNUNET_break (0);
    260       TALER_TESTING_interpreter_fail (ksls->is);
    261       return;
    262     }
    263   }
    264   else
    265   {
    266     payment_secret = NULL;
    267   }
    268 
    269   ksls->tco = ANASTASIS_truth_challenge (
    270     TALER_TESTING_interpreter_get_context (is),
    271     ksls->anastasis_url,
    272     truth_uuid,
    273     truth_key,
    274     payment_secret,
    275     &truth_challenge_cb,
    276     ksls);
    277   if (NULL == ksls->tco)
    278   {
    279     GNUNET_break (0);
    280     TALER_TESTING_interpreter_fail (ksls->is);
    281     return;
    282   }
    283 }
    284 
    285 
    286 static void
    287 truth_challenge_cleanup (void *cls,
    288                          const struct TALER_TESTING_Command *cmd)
    289 {
    290   struct TruthChallengeState *ksls = cls;
    291 
    292   if (NULL != ksls->tco)
    293   {
    294     GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
    295                 "Command '%s' did not complete (keyshare lookup)\n",
    296                 cmd->label);
    297     ANASTASIS_truth_challenge_cancel (ksls->tco);
    298     ksls->tco = NULL;
    299   }
    300   GNUNET_free (ksls->pay_uri);
    301   GNUNET_free (ksls->order_id);
    302   GNUNET_free (ksls->code);
    303   GNUNET_free (ksls->instructions);
    304   GNUNET_free (ksls);
    305 }
    306 
    307 
    308 /**
    309  * Offer internal data to other commands.
    310  *
    311  * @param cls closure
    312  * @param[out] ret result (could be anything)
    313  * @param[out] trait name of the trait
    314  * @param index index number of the object to extract.
    315  * @return #GNUNET_OK on success
    316  */
    317 static enum GNUNET_GenericReturnValue
    318 truth_challenge_traits (void *cls,
    319                         const void **ret,
    320                         const char *trait,
    321                         unsigned int index)
    322 {
    323   struct TruthChallengeState *ksls = cls;
    324   struct TALER_TESTING_Trait traits[] = {
    325     ANASTASIS_TESTING_make_trait_payment_secret (
    326       &ksls->payment_secret_response),
    327     TALER_TESTING_make_trait_taler_uri (ksls->pay_uri),
    328     TALER_TESTING_make_trait_order_id (ksls->order_id),
    329     ANASTASIS_TESTING_make_trait_code (ksls->code),
    330     TALER_TESTING_trait_end ()
    331   };
    332 
    333   return TALER_TESTING_get_trait (traits,
    334                                   ret,
    335                                   trait,
    336                                   index);
    337 }
    338 
    339 
    340 struct TALER_TESTING_Command
    341 ANASTASIS_TESTING_cmd_truth_challenge (
    342   const char *label,
    343   const char *anastasis_url,
    344   const char *payment_ref,
    345   const char *upload_ref,
    346   unsigned int http_status)
    347 {
    348   struct TruthChallengeState *ksls;
    349 
    350   GNUNET_assert (NULL != upload_ref);
    351   ksls = GNUNET_new (struct TruthChallengeState);
    352   ksls->expected_http_status = http_status;
    353   ksls->anastasis_url = anastasis_url;
    354   ksls->upload_reference = upload_ref;
    355   ksls->payment_reference = payment_ref;
    356   {
    357     struct TALER_TESTING_Command cmd = {
    358       .cls = ksls,
    359       .label = label,
    360       .run = &truth_challenge_run,
    361       .cleanup = &truth_challenge_cleanup,
    362       .traits = &truth_challenge_traits
    363     };
    364 
    365     return cmd;
    366   }
    367 }
    368 
    369 
    370 /* end of testing_api_cmd_truth_challenge.c */