From fb0a95bb6676e81eafb3c2ded6f7f8ef469c8027 Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Wed, 19 Jan 2022 20:26:38 +0100 Subject: implement new CLI tool for the secret discovery logic --- src/cli/.gitignore | 1 + src/cli/Makefile.am | 15 +++ src/cli/anastasis-cli-discover.c | 257 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 273 insertions(+) create mode 100644 src/cli/anastasis-cli-discover.c (limited to 'src/cli') diff --git a/src/cli/.gitignore b/src/cli/.gitignore index dbf01fa..72921e1 100644 --- a/src/cli/.gitignore +++ b/src/cli/.gitignore @@ -4,3 +4,4 @@ test_reducer_home *.trs taler-bank.err wallet.err +anastasis-discover diff --git a/src/cli/Makefile.am b/src/cli/Makefile.am index 8434c91..ca7bfc2 100644 --- a/src/cli/Makefile.am +++ b/src/cli/Makefile.am @@ -2,6 +2,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/src/include bin_PROGRAMS = \ + anastasis-discover \ anastasis-reducer if USE_COVERAGE @@ -58,3 +59,17 @@ anastasis_reducer_LDADD = \ -lgnunetutil \ -ljansson \ $(XLIB) + + +anastasis_discover_SOURCES = \ + anastasis-cli-discover.c +anastasis_discover_LDADD = \ + $(top_builddir)/src/util/libanastasisutil.la \ + $(top_builddir)/src/reducer/libanastasisredux.la \ + -ltalerjson \ + -ltalerutil \ + -lgnunetjson \ + -lgnunetcurl \ + -lgnunetutil \ + -ljansson \ + $(XLIB) diff --git a/src/cli/anastasis-cli-discover.c b/src/cli/anastasis-cli-discover.c new file mode 100644 index 0000000..ee5f154 --- /dev/null +++ b/src/cli/anastasis-cli-discover.c @@ -0,0 +1,257 @@ +/* + This file is part of Anastasis + Copyright (C) 2022 Anastasis SARL + + Anastasis is free software; you can redistribute it and/or modify it under the + terms of the GNU Lesser General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + Anastasis is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License along with + Anastasis; see the file COPYING.GPL. If not, see +*/ +/** + * @file cli/anastasis-cli-discover.c + * @brief command line tool to discover recovery policies + * @author Christian Grothoff + */ + +#include "platform.h" +#include +#include +#include "anastasis_redux.h" +#include +#include +#include +#include "anastasis_util_lib.h" + +/** + * Closure for #GNUNET_CURL_gnunet_scheduler_reschedule(). + */ +static struct GNUNET_CURL_RescheduleContext *rc; + +/** + * Curl context for communication with anastasis backend + */ +static struct GNUNET_CURL_Context *ctx; + +/** + * Input to -a option given. + */ +static char *input; + +/** + * JSON containing previous state + */ +static json_t *prev_state; + +/** + * JSON containing arguments for action + */ +static json_t *arguments; + +/** + * Handle to an ongoing action. + */ +struct ANASTASIS_PolicyDiscovery *pd; + +/** + * Return value from main. + */ +static int global_ret; + + +/** + * Function called on each discovered recovery policy. Called + * with all arguments NULL if we have received all policies that + * we could possibly receive for the current operation. + * + * The client can then start a new policy discovery process, using the + * smallest (also most recent) @a version received per @a provider_url + * in the cursor to resume. Note that in this case, the application + * logic is responsible for de-duplication using @a hcpd, or it may show + * policies again if they are at different providers under versions not + * queried up to the cursor. + * + * @param cls closure + * @param hcpd hash of the compressed policy document (unique per policy) + * @param provider_url which provider claims to have this policy + * @param version version of the policy at this provider + * @param attribute_mask combination of optional identity attributes + * present in the state that was used to locate this version + * @param server_time when did the provider receive the upload + * @param secret_name name the user assigned to the backup + */ +static void +print_policy_cb (void *cls, + const struct GNUNET_HashCode *hcpd, + const char *provider_url, + uint32_t version, + json_int_t attribute_mask, + struct GNUNET_TIME_Timestamp server_time, + const char *secret_name) +{ + if (NULL == hcpd) + { + pd = NULL; + global_ret = 0; + GNUNET_SCHEDULER_shutdown (); + return; + } + fprintf (stdout, + "%s %u %u - %s %s\n", + provider_url, + (unsigned int) version, + (unsigned int) attribute_mask, + GNUNET_TIME_timestamp2s (server_time), + secret_name); +} + + +/** + * @brief Shutdown the application. + * + * @param cls closure + */ +static void +shutdown_task (void *cls) +{ + (void) cls; + + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Shutdown initiated\n"); + if (NULL != pd) + { + ANASTASIS_policy_discovery_stop (pd); + pd = NULL; + } + ANASTASIS_redux_done (); + if (NULL != ctx) + { + GNUNET_CURL_fini (ctx); + ctx = NULL; + } + if (NULL != rc) + { + GNUNET_CURL_gnunet_rc_destroy (rc); + rc = NULL; + } + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Shutdown complete\n"); +} + + +/** + * @brief Start the application + * + * @param cls closure + * @param args arguments left + * @param cfgfile config file name + * @param cfg handle for the configuration file + */ +static void +run (void *cls, + char *const *args, + const char *cfgfile, + const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + (void) cls; + json_error_t error; + + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "Starting anastasis-discover\n"); + GNUNET_SCHEDULER_add_shutdown (&shutdown_task, + NULL); + /* load cursor */ + if (NULL != input) + { + arguments = json_loads (input, + JSON_DECODE_ANY, + &error); + if (NULL == arguments) + { + GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, + "Failed to parse arguments on line %u:%u: %s!\n", + error.line, + error.column, + error.text); + GNUNET_SCHEDULER_shutdown (); + return; + } + } + /* load state */ + if (NULL != args[0]) + { + prev_state = json_load_file (args[0], + JSON_DECODE_ANY, + &error); + args++; + } + else + { + prev_state = json_loadf (stdin, + JSON_DECODE_ANY, + &error); + } + if (NULL == prev_state) + { + GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, + "Failed to parse initial state on line %u:%u: %s!\n", + error.line, + error.column, + error.text); + GNUNET_SCHEDULER_shutdown (); + return; + } + /* initialize HTTP client event loop */ + ctx = GNUNET_CURL_init (&GNUNET_CURL_gnunet_scheduler_reschedule, + &rc); + rc = GNUNET_CURL_gnunet_rc_create (ctx); + ANASTASIS_redux_init (ctx); + pd = ANASTASIS_policy_discovery_start (prev_state, + arguments, + &print_policy_cb, + NULL); +} + + +int +main (int argc, + char *const *argv) +{ + /* the available command line options */ + struct GNUNET_GETOPT_CommandLineOption options[] = { + GNUNET_GETOPT_option_string ('a', + "arguments", + "JSON", + "pass a JSON string containing cursor to use", + &input), + + GNUNET_GETOPT_OPTION_END + }; + enum GNUNET_GenericReturnValue ret; + + /* FIRST get the libtalerutil initialization out + of the way. Then throw that one away, and force + the SYNC defaults to be used! */ + (void) TALER_project_data_default (); + GNUNET_OS_init (ANASTASIS_project_data_default ()); + ret = GNUNET_PROGRAM_run (argc, + argv, + "anastasis-discover", + "This is an application for finding secrets that could be recovered.\n", + options, + &run, + NULL); + if (GNUNET_SYSERR == ret) + return 3; + if (GNUNET_NO == ret) + return 0; + return global_ret; +} + + +/* end of anastasis-cli-discover.c */ -- cgit v1.2.3