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