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 */