/* This file is part of TALER Copyright (C) 2023 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. TALER 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 General Public License for more details. You should have received a copy of the GNU General Public License along with TALER; see the file COPYING. If not, see */ /** * @file merchant-tools/taler-merchant-passwd.c * @brief Reset access tokens for instances. * @author Christian Grothoff */ #include "platform.h" #include #include #include #include "taler_merchantdb_lib.h" #include "taler_merchantdb_lib.h" /** * Instance to set password for. */ static char *instance; /** * Return value from main(). */ static int global_ret; /** * Main function that will be run. * * @param cls closure * @param args remaining command-line arguments * @param cfgfile name of the configuration file used (for saving, can be NULL!) * @param config configuration */ static void run (void *cls, char *const *args, const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *config) { struct TALER_MERCHANTDB_Plugin *plugin; struct GNUNET_CONFIGURATION_Handle *cfg; const char *pw = args[0]; struct TALER_MERCHANTDB_InstanceAuthSettings ias; enum GNUNET_DB_QueryStatus qs; if (NULL == pw) pw = getenv ("TALER_MERCHANT_PASSWORD"); if (NULL == pw) { fprintf (stderr, "New password not specified (pass on command-line or via TALER_MERCHANT_PASSWORD)\n"); global_ret = -1; return; } if (0 != strncmp (pw, RFC_8959_PREFIX, strlen (RFC_8959_PREFIX))) { fprintf (stderr, "Invalid password specified, does not begin with `%s'\n", RFC_8959_PREFIX); global_ret = 1; return; } if (NULL == instance) instance = GNUNET_strdup ("default"); cfg = GNUNET_CONFIGURATION_dup (config); if (NULL == (plugin = TALER_MERCHANTDB_plugin_load (cfg))) { fprintf (stderr, "Failed to initialize database plugin.\n"); global_ret = 1; GNUNET_CONFIGURATION_destroy (cfg); return; } GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE, &ias.auth_salt, sizeof (ias.auth_salt)); GNUNET_assert (GNUNET_YES == GNUNET_CRYPTO_kdf (&ias.auth_hash, sizeof (ias.auth_hash), &ias.auth_salt, sizeof (ias.auth_salt), pw, strlen (pw), "merchant-instance-auth", strlen ("merchant-instance-auth"), NULL, 0)); if (GNUNET_OK != plugin->connect (plugin->cls)) { fprintf (stderr, "Failed to connect to database. Consider running taler-merchant-dbinit!\n"); global_ret = 1; TALER_MERCHANTDB_plugin_unload (plugin); GNUNET_CONFIGURATION_destroy (cfg); return; } qs = plugin->update_instance_auth (plugin->cls, instance, &ias); switch (qs) { case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: { struct GNUNET_DB_EventHeaderP es = { .size = ntohs (sizeof (es)), .type = ntohs (TALER_DBEVENT_MERCHANT_INSTANCE_SETTINGS) }; plugin->event_notify (plugin->cls, &es, instance, strlen (instance) + 1); } break; case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: fprintf (stderr, "Instance `%s' unknown, cannot reset token\n", instance); global_ret = 2; break; case GNUNET_DB_STATUS_SOFT_ERROR: case GNUNET_DB_STATUS_HARD_ERROR: fprintf (stderr, "Internal database error.\n"); global_ret = 3; break; } TALER_MERCHANTDB_plugin_unload (plugin); GNUNET_CONFIGURATION_destroy (cfg); } /** * The main function of the database initialization tool. * Used to initialize the Taler Exchange's database. * * @param argc number of arguments from the command line * @param argv command line arguments * @return 0 ok, 1 on error */ int main (int argc, char *const *argv) { struct GNUNET_GETOPT_CommandLineOption options[] = { GNUNET_GETOPT_option_string ('i', "instance", "ID", "which instance to reset the password of", &instance), GNUNET_GETOPT_option_version (PACKAGE_VERSION "-" VCS_VERSION), GNUNET_GETOPT_OPTION_END }; enum GNUNET_GenericReturnValue ret; /* force linker to link against libtalerutil; if we do not do this, the linker may "optimize" libtalerutil away and skip #TALER_OS_init(), which we do need */ (void) TALER_project_data_default (); ret = GNUNET_PROGRAM_run ( argc, argv, "taler-merchant-passwd", gettext_noop ("Reset instance password"), options, &run, NULL); if (GNUNET_SYSERR == ret) return 3; if (GNUNET_NO == ret) return 0; return global_ret; } /* end of taler-merchant-passwd.c */