Line data Source code
1 : /*
2 : This file is part of TALER
3 : Copyright (C) 2018-2024 Taler Systems SA
4 :
5 : TALER is free software; you can redistribute it and/or modify
6 : it under the terms of the GNU General Public License as
7 : published by the Free Software Foundation; either version 3, or
8 : (at your option) any later version.
9 :
10 : TALER is distributed in the hope that it will be useful, but
11 : WITHOUT ANY WARRANTY; without even the implied warranty of
12 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 : GNU General Public License for more details.
14 :
15 : You should have received a copy of the GNU General Public
16 : License along with TALER; see the file COPYING. If not, see
17 : <http://www.gnu.org/licenses/>
18 : */
19 : /**
20 : * @file testing/testing_api_misc.c
21 : * @brief non-command functions useful for writing tests
22 : * @author Christian Grothoff
23 : */
24 : #include "platform.h"
25 : #include <gnunet/gnunet_util_lib.h>
26 : #include "taler_testing_lib.h"
27 : #include "taler_fakebank_lib.h"
28 :
29 :
30 : bool
31 3 : TALER_TESTING_has_in_name (const char *prog,
32 : const char *marker)
33 : {
34 : size_t name_pos;
35 : size_t pos;
36 :
37 3 : if (! prog || ! marker)
38 0 : return false;
39 :
40 3 : pos = 0;
41 3 : name_pos = 0;
42 159 : while (prog[pos])
43 : {
44 156 : if ('/' == prog[pos])
45 15 : name_pos = pos + 1;
46 156 : pos++;
47 : }
48 3 : if (name_pos == pos)
49 0 : return true;
50 3 : return (NULL != strstr (prog + name_pos,
51 : marker));
52 : }
53 :
54 :
55 : enum GNUNET_GenericReturnValue
56 19 : TALER_TESTING_get_credentials (
57 : const char *cfg_file,
58 : const char *exchange_account_section,
59 : enum TALER_TESTING_BankSystem bs,
60 : struct TALER_TESTING_Credentials *ua)
61 : {
62 : unsigned long long port;
63 : struct TALER_FullPayto exchange_payto_uri;
64 :
65 19 : ua->cfg = GNUNET_CONFIGURATION_create (TALER_EXCHANGE_project_data ());
66 19 : if (GNUNET_OK !=
67 19 : GNUNET_CONFIGURATION_load (ua->cfg,
68 : cfg_file))
69 : {
70 0 : GNUNET_break (0);
71 0 : GNUNET_CONFIGURATION_destroy (ua->cfg);
72 0 : return GNUNET_SYSERR;
73 : }
74 19 : if (0 !=
75 19 : strncasecmp (exchange_account_section,
76 : "exchange-account-",
77 : strlen ("exchange-account-")))
78 : {
79 0 : GNUNET_break (0);
80 0 : return GNUNET_SYSERR;
81 : }
82 19 : if (GNUNET_OK !=
83 19 : GNUNET_CONFIGURATION_get_value_string (
84 19 : ua->cfg,
85 : exchange_account_section,
86 : "PAYTO_URI",
87 : &exchange_payto_uri.full_payto))
88 : {
89 0 : GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
90 : exchange_account_section,
91 : "PAYTO_URI");
92 0 : return GNUNET_SYSERR;
93 : }
94 19 : if (GNUNET_OK !=
95 19 : GNUNET_CONFIGURATION_get_value_number (ua->cfg,
96 : "bank",
97 : "HTTP_PORT",
98 : &port))
99 : {
100 0 : GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
101 : "bank",
102 : "HTTP_PORT");
103 0 : return GNUNET_SYSERR;
104 : }
105 : {
106 : char *csn;
107 :
108 19 : GNUNET_asprintf (&csn,
109 : "exchange-accountcredentials-%s",
110 : &exchange_account_section[strlen ("exchange-account-")]);
111 19 : if (GNUNET_OK !=
112 19 : TALER_BANK_auth_parse_cfg (ua->cfg,
113 : csn,
114 : &ua->ba))
115 : {
116 0 : GNUNET_break (0);
117 0 : GNUNET_free (csn);
118 0 : return GNUNET_SYSERR;
119 : }
120 19 : GNUNET_free (csn);
121 : }
122 : {
123 : char *csn;
124 :
125 19 : GNUNET_asprintf (&csn,
126 : "admin-accountcredentials-%s",
127 : &exchange_account_section[strlen ("exchange-account-")]);
128 19 : if (GNUNET_OK !=
129 19 : TALER_BANK_auth_parse_cfg (ua->cfg,
130 : csn,
131 : &ua->ba_admin))
132 : {
133 0 : GNUNET_break (0);
134 0 : GNUNET_free (csn);
135 0 : return GNUNET_SYSERR;
136 : }
137 19 : GNUNET_free (csn);
138 : }
139 19 : if (GNUNET_OK !=
140 19 : GNUNET_CONFIGURATION_get_value_string (ua->cfg,
141 : "exchange",
142 : "BASE_URL",
143 : &ua->exchange_url))
144 : {
145 0 : GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
146 : "exchange",
147 : "BASE_URL");
148 0 : return GNUNET_SYSERR;
149 : }
150 19 : if (GNUNET_OK !=
151 19 : GNUNET_CONFIGURATION_get_value_string (ua->cfg,
152 : "auditor",
153 : "BASE_URL",
154 : &ua->auditor_url))
155 : {
156 0 : GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
157 : "auditor",
158 : "BASE_URL");
159 0 : return GNUNET_SYSERR;
160 : }
161 :
162 19 : switch (bs)
163 : {
164 18 : case TALER_TESTING_BS_FAKEBANK:
165 : ua->exchange_payto
166 18 : = exchange_payto_uri;
167 : ua->user42_payto.full_payto
168 18 : = GNUNET_strdup ("payto://x-taler-bank/localhost/42?receiver-name=42");
169 : ua->user43_payto.full_payto
170 18 : = GNUNET_strdup ("payto://x-taler-bank/localhost/43?receiver-name=43");
171 : ua->user44_payto.full_payto
172 18 : = GNUNET_strdup ("payto://x-taler-bank/localhost/44?receiver-name=44");
173 18 : break;
174 1 : case TALER_TESTING_BS_IBAN:
175 : ua->exchange_payto
176 1 : = exchange_payto_uri;
177 : ua->user42_payto.full_payto
178 1 : = GNUNET_strdup (
179 : "payto://iban/SANDBOXX/FR7630006000011234567890189?receiver-name=User42");
180 : ua->user43_payto.full_payto
181 1 : = GNUNET_strdup (
182 : "payto://iban/SANDBOXX/GB33BUKB20201555555555?receiver-name=User43");
183 : ua->user44_payto.full_payto
184 1 : = GNUNET_strdup (
185 : "payto://iban/SANDBOXX/NL05RABO5361965189?receiver-name=User44");
186 1 : break;
187 : }
188 19 : return GNUNET_OK;
189 : }
190 :
191 :
192 : json_t *
193 84 : TALER_TESTING_make_wire_details (struct TALER_FullPayto payto)
194 : {
195 : struct TALER_WireSaltP salt;
196 :
197 : /* salt must be constant for aggregation tests! */
198 84 : memset (&salt,
199 : 47,
200 : sizeof (salt));
201 84 : return GNUNET_JSON_PACK (
202 : TALER_JSON_pack_full_payto ("payto_uri",
203 : payto),
204 : GNUNET_JSON_pack_data_auto ("salt",
205 : &salt));
206 : }
207 :
208 :
209 : /**
210 : * Remove @a option directory from @a section in @a cfg.
211 : *
212 : * @return #GNUNET_OK on success
213 : */
214 : static enum GNUNET_GenericReturnValue
215 38 : remove_dir (const struct GNUNET_CONFIGURATION_Handle *cfg,
216 : const char *section,
217 : const char *option)
218 : {
219 : char *dir;
220 :
221 38 : if (GNUNET_OK !=
222 38 : GNUNET_CONFIGURATION_get_value_filename (cfg,
223 : section,
224 : option,
225 : &dir))
226 : {
227 0 : GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
228 : section,
229 : option);
230 0 : return GNUNET_SYSERR;
231 : }
232 38 : if (GNUNET_YES ==
233 38 : GNUNET_DISK_directory_test (dir,
234 : GNUNET_NO))
235 21 : GNUNET_break (GNUNET_OK ==
236 : GNUNET_DISK_directory_remove (dir));
237 38 : GNUNET_free (dir);
238 38 : return GNUNET_OK;
239 : }
240 :
241 :
242 : enum GNUNET_GenericReturnValue
243 19 : TALER_TESTING_cleanup_files_cfg (
244 : void *cls,
245 : const struct GNUNET_CONFIGURATION_Handle *cfg)
246 : {
247 : char *dir;
248 :
249 : (void) cls;
250 19 : if (GNUNET_OK !=
251 19 : GNUNET_CONFIGURATION_get_value_filename (cfg,
252 : "exchange-offline",
253 : "SECM_TOFU_FILE",
254 : &dir))
255 : {
256 0 : GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
257 : "exchange-offline",
258 : "SECM_TOFU_FILE");
259 0 : return GNUNET_SYSERR;
260 : }
261 19 : if ( (0 != unlink (dir)) &&
262 5 : (ENOENT != errno) )
263 : {
264 0 : GNUNET_log_strerror_file (GNUNET_ERROR_TYPE_ERROR,
265 : "unlink",
266 : dir);
267 0 : GNUNET_free (dir);
268 0 : return GNUNET_SYSERR;
269 : }
270 19 : GNUNET_free (dir);
271 19 : if (GNUNET_OK !=
272 19 : remove_dir (cfg,
273 : "taler-exchange-secmod-eddsa",
274 : "KEY_DIR"))
275 0 : return GNUNET_SYSERR;
276 19 : if (GNUNET_OK !=
277 19 : remove_dir (cfg,
278 : "taler-exchange-secmod-rsa",
279 : "KEY_DIR"))
280 0 : return GNUNET_SYSERR;
281 19 : return GNUNET_OK;
282 : }
283 :
284 :
285 : const struct TALER_EXCHANGE_DenomPublicKey *
286 169 : TALER_TESTING_find_pk (
287 : const struct TALER_EXCHANGE_Keys *keys,
288 : const struct TALER_Amount *amount,
289 : bool age_restricted)
290 : {
291 : struct GNUNET_TIME_Timestamp now;
292 : struct TALER_EXCHANGE_DenomPublicKey *pk;
293 : char *str;
294 :
295 169 : now = GNUNET_TIME_timestamp_get ();
296 47642 : for (unsigned int i = 0; i<keys->num_denom_keys; i++)
297 : {
298 47642 : pk = &keys->denom_keys[i];
299 47642 : if ( (0 == TALER_amount_cmp (amount,
300 47642 : &pk->value)) &&
301 12408 : (GNUNET_TIME_timestamp_cmp (now,
302 : >=,
303 260 : pk->valid_from)) &&
304 260 : (GNUNET_TIME_timestamp_cmp (now,
305 : <,
306 260 : pk->withdraw_valid_until)) &&
307 260 : (age_restricted == (0 != pk->key.age_mask.bits)) )
308 169 : return pk;
309 : }
310 : /* do 2nd pass to check if expiration times are to blame for
311 : * failure */
312 0 : str = TALER_amount_to_string (amount);
313 0 : for (unsigned int i = 0; i<keys->num_denom_keys; i++)
314 : {
315 0 : pk = &keys->denom_keys[i];
316 0 : if ( (0 == TALER_amount_cmp (amount,
317 0 : &pk->value)) &&
318 0 : (GNUNET_TIME_timestamp_cmp (now,
319 : <,
320 0 : pk->valid_from) ||
321 0 : GNUNET_TIME_timestamp_cmp (now,
322 : >,
323 0 : pk->withdraw_valid_until) ) &&
324 0 : (age_restricted == (0 != pk->key.age_mask.bits)) )
325 : {
326 0 : GNUNET_log
327 : (GNUNET_ERROR_TYPE_WARNING,
328 : "Have denomination key for `%s', but with wrong"
329 : " expiration range %llu vs [%llu,%llu)\n",
330 : str,
331 : (unsigned long long) now.abs_time.abs_value_us,
332 : (unsigned long long) pk->valid_from.abs_time.abs_value_us,
333 : (unsigned long long) pk->withdraw_valid_until.abs_time.abs_value_us);
334 0 : GNUNET_free (str);
335 0 : return NULL;
336 : }
337 : }
338 0 : GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
339 : "No denomination key for amount %s found\n",
340 : str);
341 0 : GNUNET_free (str);
342 0 : return NULL;
343 : }
344 :
345 :
346 : int
347 1 : TALER_TESTING_wait_httpd_ready (const char *base_url)
348 : {
349 : char *wget_cmd;
350 : unsigned int iter;
351 :
352 1 : GNUNET_asprintf (&wget_cmd,
353 : "wget -q -t 1 -T 1 %s -o /dev/null -O /dev/null",
354 : base_url); // make sure ends with '/'
355 : /* give child time to start and bind against the socket */
356 1 : GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
357 : "Waiting for HTTP service to be ready (check with: %s)\n",
358 : wget_cmd);
359 1 : iter = 0;
360 : do
361 : {
362 1 : if (10 == iter)
363 : {
364 0 : GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
365 : "Failed to launch HTTP service (or `wget')\n");
366 0 : GNUNET_free (wget_cmd);
367 0 : return 77;
368 : }
369 1 : sleep (1);
370 1 : iter++;
371 : }
372 1 : while (0 != system (wget_cmd));
373 1 : GNUNET_free (wget_cmd);
374 1 : return 0;
375 : }
376 :
377 :
378 : enum GNUNET_GenericReturnValue
379 0 : TALER_TESTING_url_port_free (const char *url)
380 : {
381 : const char *port;
382 : long pnum;
383 :
384 0 : port = strrchr (url,
385 : (unsigned char) ':');
386 0 : if (NULL == port)
387 0 : pnum = 80;
388 : else
389 0 : pnum = strtol (port + 1, NULL, 10);
390 0 : if (GNUNET_OK !=
391 0 : GNUNET_NETWORK_test_port_free (IPPROTO_TCP,
392 : pnum))
393 : {
394 0 : GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
395 : "Port %u not available.\n",
396 : (unsigned int) pnum);
397 0 : return GNUNET_SYSERR;
398 : }
399 0 : return GNUNET_OK;
400 : }
|