merchant

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

taler-merchant-passwd.c (8157B)


      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 "platform.h"
     22 #include <taler/taler_util.h>
     23 #include <taler/taler_dbevents.h>
     24 #include <gnunet/gnunet_util_lib.h>
     25 #include "taler_merchant_util.h"
     26 #include "taler_merchantdb_lib.h"
     27 #include "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 
     59   if (NULL != args[1])
     60   {
     61     fprintf (stderr,
     62              "Superfluous command-line option `%s' specified\n",
     63              args[1]);
     64     global_ret = -1;
     65     return;
     66   }
     67   if (NULL == pw)
     68     pw = getenv ("TALER_MERCHANT_PASSWORD");
     69   if (NULL == pw)
     70   {
     71     fprintf (stderr,
     72              "New password not specified (pass on command-line or via TALER_MERCHANT_PASSWORD)\n");
     73     global_ret = -1;
     74     return;
     75   }
     76   if (NULL == instance)
     77     instance = GNUNET_strdup ("admin");
     78   cfg = GNUNET_CONFIGURATION_dup (config);
     79   if (NULL ==
     80       (plugin = TALER_MERCHANTDB_plugin_load (cfg)))
     81   {
     82     fprintf (stderr,
     83              "Failed to initialize database plugin.\n");
     84     global_ret = 1;
     85     GNUNET_CONFIGURATION_destroy (cfg);
     86     return;
     87   }
     88 
     89   GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_NONCE,
     90                               &ias.auth_salt,
     91                               sizeof (ias.auth_salt));
     92   TALER_merchant_instance_auth_hash_with_salt (&ias.auth_hash,
     93                                                &ias.auth_salt,
     94                                                pw);
     95   if (GNUNET_OK !=
     96       plugin->connect (plugin->cls))
     97   {
     98     fprintf (stderr,
     99              "Failed to connect to database. Consider running taler-merchant-dbinit!\n");
    100     global_ret = 1;
    101     TALER_MERCHANTDB_plugin_unload (plugin);
    102     GNUNET_CONFIGURATION_destroy (cfg);
    103     return;
    104   }
    105   qs = plugin->update_instance_auth (plugin->cls,
    106                                      instance,
    107                                      &ias);
    108   switch (qs)
    109   {
    110   case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
    111     {
    112       struct GNUNET_DB_EventHeaderP es = {
    113         .size = ntohs (sizeof (es)),
    114         .type = ntohs (TALER_DBEVENT_MERCHANT_INSTANCE_SETTINGS)
    115       };
    116 
    117       plugin->event_notify (plugin->cls,
    118                             &es,
    119                             instance,
    120                             strlen (instance) + 1);
    121     }
    122     break;
    123   case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
    124     if (0 ==
    125         strcmp (instance,
    126                 "admin"))
    127     {
    128       struct TALER_MerchantPrivateKeyP merchant_priv;
    129       struct TALER_MerchantPublicKeyP merchant_pub;
    130       struct TALER_MERCHANTDB_InstanceSettings is = {
    131         .id = (char *) "admin",
    132         .name = (char *) "Administrator",
    133         .use_stefan = true,
    134         .address = json_object (),
    135         .jurisdiction = json_object (),
    136       };
    137 
    138       if (GNUNET_OK !=
    139           GNUNET_CONFIGURATION_get_value_time (config,
    140                                                "merchant",
    141                                                "DEFAULT_WIRE_TRANSFER_DELAY",
    142                                                &is.default_wire_transfer_delay)
    143           )
    144       {
    145         is.default_wire_transfer_delay = GNUNET_TIME_UNIT_MONTHS;
    146       }
    147       if (GNUNET_OK !=
    148           GNUNET_CONFIGURATION_get_value_time (config,
    149                                                "merchant",
    150                                                "DEFAULT_PAY_DELAY",
    151                                                &is.default_pay_delay))
    152       {
    153         is.default_pay_delay = GNUNET_TIME_UNIT_DAYS;
    154       }
    155       if (GNUNET_OK !=
    156           GNUNET_CONFIGURATION_get_value_time (config,
    157                                                "merchant",
    158                                                "DEFAULT_REFUND_DELAY",
    159                                                &is.default_refund_delay))
    160       {
    161         is.default_refund_delay = GNUNET_TIME_relative_multiply (
    162           GNUNET_TIME_UNIT_DAYS,
    163           15);
    164       }
    165 
    166       GNUNET_CRYPTO_eddsa_key_create (&merchant_priv.eddsa_priv);
    167       GNUNET_CRYPTO_eddsa_key_get_public (&merchant_priv.eddsa_priv,
    168                                           &merchant_pub.eddsa_pub);
    169       qs = plugin->insert_instance (plugin->cls,
    170                                     &merchant_pub,
    171                                     &merchant_priv,
    172                                     &is,
    173                                     &ias,
    174                                     false);
    175       json_decref (is.address);
    176       json_decref (is.jurisdiction);
    177       switch (qs)
    178       {
    179       case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT:
    180         fprintf (stderr,
    181                  "`%s' instance created with default settings\n",
    182                  instance);
    183         break;
    184       case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS:
    185         GNUNET_break (0);
    186         break;
    187       case GNUNET_DB_STATUS_SOFT_ERROR:
    188       case GNUNET_DB_STATUS_HARD_ERROR:
    189         fprintf (stderr,
    190                  "Internal database error.\n");
    191         global_ret = 3;
    192         break;
    193       }
    194       {
    195         struct GNUNET_DB_EventHeaderP es = {
    196           .size = ntohs (sizeof (es)),
    197           .type = ntohs (TALER_DBEVENT_MERCHANT_INSTANCE_SETTINGS)
    198         };
    199 
    200         plugin->event_notify (plugin->cls,
    201                               &es,
    202                               instance,
    203                               strlen (instance) + 1);
    204       }
    205     }
    206     else
    207     {
    208       fprintf (stderr,
    209                "Instance `%s' unknown, cannot reset token\n",
    210                instance);
    211       global_ret = 2;
    212     }
    213     break;
    214   case GNUNET_DB_STATUS_SOFT_ERROR:
    215   case GNUNET_DB_STATUS_HARD_ERROR:
    216     fprintf (stderr,
    217              "Internal database error.\n");
    218     global_ret = 3;
    219     break;
    220   }
    221   TALER_MERCHANTDB_plugin_unload (plugin);
    222   GNUNET_CONFIGURATION_destroy (cfg);
    223 }
    224 
    225 
    226 /**
    227  * The main function of the database initialization tool.
    228  * Used to initialize the Taler Exchange's database.
    229  *
    230  * @param argc number of arguments from the command line
    231  * @param argv command line arguments
    232  * @return 0 ok, 1 on error
    233  */
    234 int
    235 main (int argc,
    236       char *const *argv)
    237 {
    238   struct GNUNET_GETOPT_CommandLineOption options[] = {
    239     GNUNET_GETOPT_option_string ('i',
    240                                  "instance",
    241                                  "ID",
    242                                  "which instance to reset the password of",
    243                                  &instance),
    244 
    245     GNUNET_GETOPT_option_version (PACKAGE_VERSION "-" VCS_VERSION),
    246     GNUNET_GETOPT_OPTION_END
    247   };
    248   enum GNUNET_GenericReturnValue ret;
    249 
    250   ret = GNUNET_PROGRAM_run (
    251     TALER_MERCHANT_project_data (),
    252     argc, argv,
    253     "taler-merchant-passwd",
    254     gettext_noop ("Reset instance password"),
    255     options,
    256     &run, NULL);
    257   if (GNUNET_SYSERR == ret)
    258     return 3;
    259   if (GNUNET_NO == ret)
    260     return 0;
    261   return global_ret;
    262 }
    263 
    264 
    265 /* end of taler-merchant-passwd.c */