merchant

Merchant backend to process payments, run by merchants
Log | Files | Refs | Submodules | README | LICENSE

taler-merchant-passwd.c (8230B)


      1 /*
      2   This file is part of TALER
      3   Copyright (C) 2023, 2025 Taler Systems SA
      4 
      5   TALER 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   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 General Public License for more details.
     12 
     13   You should have received a copy of the GNU General Public License along with
     14   TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
     15 */
     16 /**
     17  * @file merchant-tools/taler-merchant-passwd.c
     18  * @brief Reset access tokens for instances.
     19  * @author Christian Grothoff
     20  */
     21 #include "taler/platform.h"
     22 #include <taler/taler_util.h>
     23 #include <taler/taler_dbevents.h>
     24 #include <gnunet/gnunet_util_lib.h>
     25 #include "taler/taler_merchant_util.h"
     26 #include "taler/taler_merchantdb_lib.h"
     27 #include "taler/taler_merchantdb_lib.h"
     28 
     29 /**
     30  * Instance to set password for.
     31  */
     32 static char *instance;
     33 
     34 /**
     35  * Return value from main().
     36  */
     37 static int global_ret;
     38 
     39 /**
     40  * Main function that will be run.
     41  *
     42  * @param cls closure
     43  * @param args remaining command-line arguments
     44  * @param cfgfile name of the configuration file used (for saving, can be NULL!)
     45  * @param config configuration
     46  */
     47 static void
     48 run (void *cls,
     49      char *const *args,
     50      const char *cfgfile,
     51      const struct GNUNET_CONFIGURATION_Handle *config)
     52 {
     53   struct TALER_MERCHANTDB_Plugin *plugin;
     54   struct GNUNET_CONFIGURATION_Handle *cfg;
     55   const char *pw = args[0];
     56   struct TALER_MERCHANTDB_InstanceAuthSettings ias;
     57   enum GNUNET_DB_QueryStatus qs;
     58   unsigned int nxt = 1;
     59 
     60   if (NULL == pw)
     61   {
     62     pw = getenv ("TALER_MERCHANT_PASSWORD");
     63     nxt = 0;
     64   }
     65   if (NULL == pw)
     66   {
     67     fprintf (stderr,
     68              "New password not specified (pass on command-line or via TALER_MERCHANT_PASSWORD)\n");
     69     global_ret = -1;
     70     return;
     71   }
     72   if (NULL != args[nxt])
     73   {
     74     fprintf (stderr,
     75              "Superfluous command-line option `%s' specified\n",
     76              args[nxt]);
     77     global_ret = -1;
     78     return;
     79   }
     80   if (NULL == instance)
     81     instance = GNUNET_strdup ("admin");
     82   cfg = GNUNET_CONFIGURATION_dup (config);
     83   if (NULL ==
     84       (plugin = TALER_MERCHANTDB_plugin_load (cfg)))
     85   {
     86     fprintf (stderr,
     87              "Failed to initialize database plugin.\n");
     88     global_ret = 1;
     89     GNUNET_CONFIGURATION_destroy (cfg);
     90     return;
     91   }
     92 
     93   GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
     94                               &ias.auth_salt,
     95                               sizeof (ias.auth_salt));
     96   TALER_merchant_instance_auth_hash_with_salt (&ias.auth_hash,
     97                                                &ias.auth_salt,
     98                                                pw);
     99   if (GNUNET_OK !=
    100       plugin->connect (plugin->cls))
    101   {
    102     fprintf (stderr,
    103              "Failed to connect to database. Consider running taler-merchant-dbinit!\n");
    104     global_ret = 1;
    105     TALER_MERCHANTDB_plugin_unload (plugin);
    106     GNUNET_CONFIGURATION_destroy (cfg);
    107     return;
    108   }
    109   qs = plugin->update_instance_auth (plugin->cls,
    110                                      instance,
    111                                      &ias);
    112   switch (qs)
    113   {
    114   case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
    115     {
    116       struct GNUNET_DB_EventHeaderP es = {
    117         .size = ntohs (sizeof (es)),
    118         .type = ntohs (TALER_DBEVENT_MERCHANT_INSTANCE_SETTINGS)
    119       };
    120 
    121       plugin->event_notify (plugin->cls,
    122                             &es,
    123                             instance,
    124                             strlen (instance) + 1);
    125     }
    126     break;
    127   case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
    128     if (0 ==
    129         strcmp (instance,
    130                 "admin"))
    131     {
    132       struct TALER_MerchantPrivateKeyP merchant_priv;
    133       struct TALER_MerchantPublicKeyP merchant_pub;
    134       struct TALER_MERCHANTDB_InstanceSettings is = {
    135         .id = (char *) "admin",
    136         .name = (char *) "Administrator",
    137         .use_stefan = true,
    138         .address = json_object (),
    139         .jurisdiction = json_object (),
    140       };
    141 
    142       if (GNUNET_OK !=
    143           GNUNET_CONFIGURATION_get_value_time (config,
    144                                                "merchant",
    145                                                "DEFAULT_WIRE_TRANSFER_DELAY",
    146                                                &is.default_wire_transfer_delay)
    147           )
    148       {
    149         is.default_wire_transfer_delay = GNUNET_TIME_UNIT_MONTHS;
    150       }
    151       if (GNUNET_OK !=
    152           GNUNET_CONFIGURATION_get_value_time (config,
    153                                                "merchant",
    154                                                "DEFAULT_PAY_DELAY",
    155                                                &is.default_pay_delay))
    156       {
    157         is.default_pay_delay = GNUNET_TIME_UNIT_DAYS;
    158       }
    159       if (GNUNET_OK !=
    160           GNUNET_CONFIGURATION_get_value_time (config,
    161                                                "merchant",
    162                                                "DEFAULT_REFUND_DELAY",
    163                                                &is.default_refund_delay))
    164       {
    165         is.default_refund_delay = GNUNET_TIME_relative_multiply (
    166           GNUNET_TIME_UNIT_DAYS,
    167           15);
    168       }
    169 
    170       GNUNET_CRYPTO_eddsa_key_create (&merchant_priv.eddsa_priv);
    171       GNUNET_CRYPTO_eddsa_key_get_public (&merchant_priv.eddsa_priv,
    172                                           &merchant_pub.eddsa_pub);
    173       qs = plugin->insert_instance (plugin->cls,
    174                                     &merchant_pub,
    175                                     &merchant_priv,
    176                                     &is,
    177                                     &ias,
    178                                     false);
    179       json_decref (is.address);
    180       json_decref (is.jurisdiction);
    181       switch (qs)
    182       {
    183       case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
    184         fprintf (stderr,
    185                  "`%s' instance created with default settings\n",
    186                  instance);
    187         break;
    188       case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
    189         GNUNET_break (0);
    190         break;
    191       case GNUNET_DB_STATUS_SOFT_ERROR:
    192       case GNUNET_DB_STATUS_HARD_ERROR:
    193         fprintf (stderr,
    194                  "Internal database error.\n");
    195         global_ret = 3;
    196         break;
    197       }
    198       {
    199         struct GNUNET_DB_EventHeaderP es = {
    200           .size = ntohs (sizeof (es)),
    201           .type = ntohs (TALER_DBEVENT_MERCHANT_INSTANCE_SETTINGS)
    202         };
    203 
    204         plugin->event_notify (plugin->cls,
    205                               &es,
    206                               instance,
    207                               strlen (instance) + 1);
    208       }
    209     }
    210     else
    211     {
    212       fprintf (stderr,
    213                "Instance `%s' unknown, cannot reset token\n",
    214                instance);
    215       global_ret = 2;
    216     }
    217     break;
    218   case GNUNET_DB_STATUS_SOFT_ERROR:
    219   case GNUNET_DB_STATUS_HARD_ERROR:
    220     fprintf (stderr,
    221              "Internal database error.\n");
    222     global_ret = 3;
    223     break;
    224   }
    225   TALER_MERCHANTDB_plugin_unload (plugin);
    226   GNUNET_CONFIGURATION_destroy (cfg);
    227 }
    228 
    229 
    230 /**
    231  * The main function of the database initialization tool.
    232  * Used to initialize the Taler Exchange's database.
    233  *
    234  * @param argc number of arguments from the command line
    235  * @param argv command line arguments
    236  * @return 0 ok, 1 on error
    237  */
    238 int
    239 main (int argc,
    240       char *const *argv)
    241 {
    242   struct GNUNET_GETOPT_CommandLineOption options[] = {
    243     GNUNET_GETOPT_option_string ('i',
    244                                  "instance",
    245                                  "ID",
    246                                  "which instance to reset the password of",
    247                                  &instance),
    248 
    249     GNUNET_GETOPT_option_version (PACKAGE_VERSION "-" VCS_VERSION),
    250     GNUNET_GETOPT_OPTION_END
    251   };
    252   enum GNUNET_GenericReturnValue ret;
    253 
    254   ret = GNUNET_PROGRAM_run (
    255     TALER_MERCHANT_project_data (),
    256     argc, argv,
    257     "taler-merchant-passwd",
    258     gettext_noop ("Reset instance password"),
    259     options,
    260     &run, NULL);
    261   if (GNUNET_SYSERR == ret)
    262     return 3;
    263   if (GNUNET_NO == ret)
    264     return 0;
    265   return global_ret;
    266 }
    267 
    268 
    269 /* end of taler-merchant-passwd.c */