taler-merchant-passwd.c (8040B)
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 (&ias.auth_salt, 96 sizeof (ias.auth_salt)); 97 TALER_merchant_instance_auth_hash_with_salt (&ias.auth_hash, 98 &ias.auth_salt, 99 pw); 100 qs = TALER_MERCHANTDB_update_instance_auth (pg, 101 instance, 102 &ias); 103 switch (qs) 104 { 105 case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: 106 { 107 struct GNUNET_DB_EventHeaderP es = { 108 .size = ntohs (sizeof (es)), 109 .type = ntohs (TALER_DBEVENT_MERCHANT_INSTANCE_SETTINGS) 110 }; 111 112 TALER_MERCHANTDB_event_notify (pg, 113 &es, 114 instance, 115 strlen (instance) + 1); 116 } 117 break; 118 case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: 119 if (0 == 120 strcmp (instance, 121 "admin")) 122 { 123 struct TALER_MerchantPrivateKeyP merchant_priv; 124 struct TALER_MerchantPublicKeyP merchant_pub; 125 struct TALER_MERCHANTDB_InstanceSettings is = { 126 .id = (char *) "admin", 127 .name = (char *) "Administrator", 128 .use_stefan = true, 129 .address = json_object (), 130 .jurisdiction = json_object (), 131 }; 132 133 if (GNUNET_OK != 134 GNUNET_CONFIGURATION_get_value_time (config, 135 "merchant", 136 "DEFAULT_WIRE_TRANSFER_DELAY", 137 &is.default_wire_transfer_delay) 138 ) 139 { 140 is.default_wire_transfer_delay = GNUNET_TIME_UNIT_MONTHS; 141 } 142 if (GNUNET_OK != 143 GNUNET_CONFIGURATION_get_value_time (config, 144 "merchant", 145 "DEFAULT_PAY_DELAY", 146 &is.default_pay_delay)) 147 { 148 is.default_pay_delay = GNUNET_TIME_UNIT_DAYS; 149 } 150 if (GNUNET_OK != 151 GNUNET_CONFIGURATION_get_value_time (config, 152 "merchant", 153 "DEFAULT_REFUND_DELAY", 154 &is.default_refund_delay)) 155 { 156 is.default_refund_delay = GNUNET_TIME_relative_multiply ( 157 GNUNET_TIME_UNIT_DAYS, 158 15); 159 } 160 161 GNUNET_CRYPTO_eddsa_key_create (&merchant_priv.eddsa_priv); 162 GNUNET_CRYPTO_eddsa_key_get_public (&merchant_priv.eddsa_priv, 163 &merchant_pub.eddsa_pub); 164 qs = TALER_MERCHANTDB_insert_instance (pg, 165 &merchant_pub, 166 &merchant_priv, 167 &is, 168 &ias); 169 json_decref (is.address); 170 json_decref (is.jurisdiction); 171 switch (qs) 172 { 173 case GNUNET_DB_STATUS_SUCCESS_ONE_RESULT: 174 fprintf (stderr, 175 "`%s' instance created with default settings\n", 176 instance); 177 break; 178 case GNUNET_DB_STATUS_SUCCESS_NO_RESULTS: 179 GNUNET_break (0); 180 break; 181 case GNUNET_DB_STATUS_SOFT_ERROR: 182 case GNUNET_DB_STATUS_HARD_ERROR: 183 fprintf (stderr, 184 "Internal database error.\n"); 185 global_ret = 3; 186 break; 187 } 188 { 189 struct GNUNET_DB_EventHeaderP es = { 190 .size = ntohs (sizeof (es)), 191 .type = ntohs (TALER_DBEVENT_MERCHANT_INSTANCE_SETTINGS) 192 }; 193 194 TALER_MERCHANTDB_event_notify (pg, 195 &es, 196 instance, 197 strlen (instance) + 1); 198 } 199 } 200 else 201 { 202 fprintf (stderr, 203 "Instance `%s' unknown, cannot reset token\n", 204 instance); 205 global_ret = 2; 206 } 207 break; 208 case GNUNET_DB_STATUS_SOFT_ERROR: 209 case GNUNET_DB_STATUS_HARD_ERROR: 210 fprintf (stderr, 211 "Internal database error.\n"); 212 global_ret = 3; 213 break; 214 } 215 TALER_MERCHANTDB_disconnect (pg); 216 GNUNET_CONFIGURATION_destroy (cfg); 217 } 218 219 220 /** 221 * The main function of the database initialization tool. 222 * Used to initialize the Taler Exchange's database. 223 * 224 * @param argc number of arguments from the command line 225 * @param argv command line arguments 226 * @return 0 ok, 1 on error 227 */ 228 int 229 main (int argc, 230 char *const *argv) 231 { 232 struct GNUNET_GETOPT_CommandLineOption options[] = { 233 GNUNET_GETOPT_option_string ('i', 234 "instance", 235 "ID", 236 "which instance to reset the password of", 237 &instance), 238 239 GNUNET_GETOPT_option_version (PACKAGE_VERSION), 240 GNUNET_GETOPT_OPTION_END 241 }; 242 enum GNUNET_GenericReturnValue ret; 243 244 ret = GNUNET_PROGRAM_run ( 245 TALER_MERCHANT_project_data (), 246 argc, argv, 247 "taler-merchant-passwd", 248 gettext_noop ("Reset instance password"), 249 options, 250 &run, NULL); 251 if (GNUNET_SYSERR == ret) 252 return 3; 253 if (GNUNET_NO == ret) 254 return 0; 255 return global_ret; 256 } 257 258 259 /* end of taler-merchant-passwd.c */