merchant

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

taler-merchant-passwd.c (8167B)


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