anastasis

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

anastasis-cli-discover.c (7121B)


      1 /*
      2   This file is part of Anastasis
      3   Copyright (C) 2022 Anastasis SARL
      4 
      5   Anastasis 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 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 Affero General Public License for more details.
     12 
     13   You should have received a copy of the GNU Affero General Public License along with
     14   Anastasis; see the file COPYING.GPL.  If not, see <http://www.gnu.org/licenses/>
     15 */
     16 /**
     17  * @file cli/anastasis-cli-discover.c
     18  * @brief command line tool to discover recovery policies
     19  * @author Christian Grothoff
     20  */
     21 
     22 #include "platform.h"
     23 #include <gnunet/gnunet_util_lib.h>
     24 #include <gnunet/gnunet_curl_lib.h>
     25 #include "anastasis_redux.h"
     26 #include <taler/taler_util.h>
     27 #include <taler/taler_error_codes.h>
     28 #include <taler/taler_json_lib.h>
     29 #include "anastasis_util_lib.h"
     30 
     31 /**
     32  * Closure for #GNUNET_CURL_gnunet_scheduler_reschedule().
     33  */
     34 static struct GNUNET_CURL_RescheduleContext *rc;
     35 
     36 /**
     37  * Curl context for communication with anastasis backend
     38  */
     39 static struct GNUNET_CURL_Context *ctx;
     40 
     41 /**
     42  * Input to -a option given.
     43  */
     44 static char *input;
     45 
     46 /**
     47  * JSON containing previous state
     48  */
     49 static json_t *prev_state;
     50 
     51 /**
     52  * JSON containing arguments for action
     53  */
     54 static json_t *arguments;
     55 
     56 /**
     57  * Handle to an ongoing action.
     58  */
     59 struct ANASTASIS_PolicyDiscovery *pd;
     60 
     61 /**
     62  * Return value from main.
     63  */
     64 static int global_ret;
     65 
     66 
     67 /**
     68  * Function called on each discovered recovery policy. Called
     69  * with all arguments NULL if we have received all policies that
     70  * we could possibly receive for the current operation.
     71  *
     72  * The client can then start a new policy discovery process, using the
     73  * smallest (also most recent) @a version received per @a provider_url
     74  * in the cursor to resume.  Note that in this case, the application
     75  * logic is responsible for de-duplication using @a hcpd, or it may show
     76  * policies again if they are at different providers under versions not
     77  * queried up to the cursor.
     78  *
     79  * @param cls closure
     80  * @param hcpd hash of the compressed policy document (unique per policy)
     81  * @param provider_url which provider claims to have this policy
     82  * @param version version of the policy at this provider
     83  * @param attribute_mask combination of optional identity attributes
     84  *           present in the state that was used to locate this version
     85  * @param server_time when did the provider receive the upload
     86  * @param secret_name name the user assigned to the backup
     87  */
     88 static void
     89 print_policy_cb (void *cls,
     90                  const struct GNUNET_HashCode *hcpd,
     91                  const char *provider_url,
     92                  uint32_t version,
     93                  json_int_t attribute_mask,
     94                  struct GNUNET_TIME_Timestamp server_time,
     95                  const char *secret_name,
     96                  const json_t *providers)
     97 {
     98   if (NULL == hcpd)
     99   {
    100     fprintf (stderr,
    101              "All results received, terminating\n");
    102     pd = NULL;
    103     global_ret = 0;
    104     GNUNET_SCHEDULER_shutdown ();
    105     return;
    106   }
    107   fprintf (stdout,
    108            "%s %u %u : \"%s\" \"%s\" (%s)\n",
    109            provider_url,
    110            (unsigned int) version,
    111            (unsigned int) attribute_mask,
    112            GNUNET_TIME_timestamp2s (server_time),
    113            secret_name,
    114            GNUNET_h2s (hcpd));
    115 }
    116 
    117 
    118 /**
    119  * @brief Shutdown the application.
    120  *
    121  * @param cls closure
    122  */
    123 static void
    124 shutdown_task (void *cls)
    125 {
    126   (void) cls;
    127 
    128   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
    129               "Shutdown initiated\n");
    130   if (NULL != pd)
    131   {
    132     ANASTASIS_policy_discovery_stop (pd);
    133     pd = NULL;
    134   }
    135   ANASTASIS_redux_done ();
    136   if (NULL != ctx)
    137   {
    138     GNUNET_CURL_fini (ctx);
    139     ctx = NULL;
    140   }
    141   if (NULL != rc)
    142   {
    143     GNUNET_CURL_gnunet_rc_destroy (rc);
    144     rc = NULL;
    145   }
    146   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
    147               "Shutdown complete\n");
    148 }
    149 
    150 
    151 /**
    152  * @brief Start the application
    153  *
    154  * @param cls closure
    155  * @param args arguments left
    156  * @param cfgfile config file name
    157  * @param cfg handle for the configuration file
    158  */
    159 static void
    160 run (void *cls,
    161      char *const *args,
    162      const char *cfgfile,
    163      const struct GNUNET_CONFIGURATION_Handle *cfg)
    164 {
    165   json_error_t error;
    166 
    167   (void) cls;
    168   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
    169               "Starting anastasis-discover\n");
    170   GNUNET_SCHEDULER_add_shutdown (&shutdown_task,
    171                                  NULL);
    172   /* load cursor */
    173   if (NULL != input)
    174   {
    175     arguments = json_loads (input,
    176                             JSON_DECODE_ANY,
    177                             &error);
    178     if (NULL == arguments)
    179     {
    180       GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
    181                   "Failed to parse arguments on line %u:%u: %s!\n",
    182                   error.line,
    183                   error.column,
    184                   error.text);
    185       GNUNET_SCHEDULER_shutdown ();
    186       return;
    187     }
    188   }
    189   /* load state */
    190   if (NULL != args[0])
    191   {
    192     prev_state = json_load_file (args[0],
    193                                  JSON_DECODE_ANY,
    194                                  &error);
    195     args++;
    196   }
    197   else
    198   {
    199     prev_state = json_loadf (stdin,
    200                              JSON_DECODE_ANY,
    201                              &error);
    202   }
    203   if (NULL == prev_state)
    204   {
    205     GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
    206                 "Failed to parse initial state on line %u:%u: %s!\n",
    207                 error.line,
    208                 error.column,
    209                 error.text);
    210     GNUNET_SCHEDULER_shutdown ();
    211     return;
    212   }
    213   /* initialize HTTP client event loop */
    214   ctx = GNUNET_CURL_init (&GNUNET_CURL_gnunet_scheduler_reschedule,
    215                           &rc);
    216   rc = GNUNET_CURL_gnunet_rc_create (ctx);
    217   ANASTASIS_redux_init (ctx);
    218   pd = ANASTASIS_policy_discovery_start (prev_state,
    219                                          arguments,
    220                                          &print_policy_cb,
    221                                          NULL);
    222 }
    223 
    224 
    225 int
    226 main (int argc,
    227       char *const *argv)
    228 {
    229   /* the available command line options */
    230   struct GNUNET_GETOPT_CommandLineOption options[] = {
    231     GNUNET_GETOPT_option_string ('a',
    232                                  "arguments",
    233                                  "JSON",
    234                                  "pass a JSON string containing cursor to use",
    235                                  &input),
    236 
    237     GNUNET_GETOPT_OPTION_END
    238   };
    239   enum GNUNET_GenericReturnValue ret;
    240 
    241   ret = GNUNET_PROGRAM_run (ANASTASIS_project_data (),
    242                             argc,
    243                             argv,
    244                             "anastasis-discover",
    245                             "This is an application for finding secrets that could be recovered.\n",
    246                             options,
    247                             &run,
    248                             NULL);
    249   if (GNUNET_SYSERR == ret)
    250     return 3;
    251   if (GNUNET_NO == ret)
    252     return 0;
    253   return global_ret;
    254 }
    255 
    256 
    257 /* end of anastasis-cli-discover.c */