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