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