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