Line data Source code
1 : /*
2 : This file is part of TALER
3 : (C) 2023 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_cmd_get_auditor.c
21 : * @brief Command to get an auditor handle
22 : * @author Christian Grothoff
23 : */
24 : #include "taler/taler_json_lib.h"
25 : #include <gnunet/gnunet_curl_lib.h>
26 : #include "taler/taler_testing_lib.h"
27 :
28 :
29 : /**
30 : * State for a "get auditor" CMD.
31 : */
32 : struct GetAuditorState
33 : {
34 :
35 : /**
36 : * Private key of the auditor.
37 : */
38 : struct TALER_AuditorPrivateKeyP auditor_priv;
39 :
40 : /**
41 : * Public key of the auditor.
42 : */
43 : struct TALER_AuditorPublicKeyP auditor_pub;
44 :
45 : /**
46 : * Our interpreter state.
47 : */
48 : struct TALER_TESTING_Interpreter *is;
49 :
50 : /**
51 : * Our configuration.
52 : */
53 : const struct GNUNET_CONFIGURATION_Handle *cfg;
54 :
55 : /**
56 : * Should we load and check the auditor's private key?
57 : */
58 : bool load_auditor_keys;
59 :
60 : /**
61 : * Auditor handle used to get the configuration.
62 : */
63 : struct TALER_AUDITOR_GetConfigHandle *auditor;
64 :
65 : /**
66 : * URL of the auditor.
67 : */
68 : char *auditor_url;
69 :
70 : /**
71 : * Filename of the master private key of the auditor.
72 : */
73 : char *priv_file;
74 :
75 : };
76 :
77 :
78 : /**
79 : * Function called with information about the auditor.
80 : *
81 : * @param cls closure
82 : * @param vr response data
83 : */
84 : static void
85 4 : version_cb (
86 : void *cls,
87 : const struct TALER_AUDITOR_ConfigResponse *vr)
88 : {
89 4 : struct GetAuditorState *gas = cls;
90 :
91 4 : gas->auditor = NULL;
92 4 : if (MHD_HTTP_OK != vr->hr.http_status)
93 : {
94 0 : TALER_TESTING_unexpected_status (gas->is,
95 : vr->hr.http_status,
96 : MHD_HTTP_OK);
97 0 : return;
98 : }
99 4 : if ( (NULL != gas->priv_file) &&
100 4 : (0 != GNUNET_memcmp (&gas->auditor_pub,
101 : &vr->details.ok.vi.auditor_pub)) )
102 : {
103 0 : GNUNET_break (0);
104 0 : TALER_TESTING_interpreter_fail (gas->is);
105 0 : return;
106 : }
107 4 : TALER_TESTING_interpreter_next (gas->is);
108 : }
109 :
110 :
111 : /**
112 : * Get the file name of the master private key file of the auditor from @a
113 : * cfg.
114 : *
115 : * @param cfg configuration to evaluate
116 : * @return base URL of the auditor according to @a cfg
117 : */
118 : static char *
119 4 : get_auditor_priv_file (
120 : const struct GNUNET_CONFIGURATION_Handle *cfg)
121 : {
122 : char *fn;
123 : struct GNUNET_CONFIGURATION_Handle *acfg;
124 : char *dfn;
125 :
126 4 : GNUNET_break (GNUNET_OK ==
127 : GNUNET_CONFIGURATION_get_value_filename (cfg,
128 : "PATHS",
129 : "DEFAULTCONFIG",
130 : &dfn));
131 4 : acfg = GNUNET_CONFIGURATION_create (TALER_AUDITOR_project_data ());
132 4 : GNUNET_break (GNUNET_OK ==
133 : GNUNET_CONFIGURATION_load (acfg,
134 : dfn));
135 4 : GNUNET_free (dfn);
136 4 : if (GNUNET_OK !=
137 4 : GNUNET_CONFIGURATION_get_value_filename (acfg,
138 : "auditor",
139 : "AUDITOR_PRIV_FILE",
140 : &fn))
141 : {
142 0 : GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
143 : "auditor",
144 : "AUDITOR_PRIV_FILE");
145 : }
146 4 : GNUNET_CONFIGURATION_destroy (acfg);
147 4 : GNUNET_log (GNUNET_ERROR_TYPE_INFO,
148 : "Loading auditor private key from %s\n",
149 : fn);
150 4 : return fn;
151 : }
152 :
153 :
154 : /**
155 : * Run the "get_auditor" command.
156 : *
157 : * @param cls closure.
158 : * @param cmd the command currently being executed.
159 : * @param is the interpreter state.
160 : */
161 : static void
162 4 : get_auditor_run (void *cls,
163 : const struct TALER_TESTING_Command *cmd,
164 : struct TALER_TESTING_Interpreter *is)
165 : {
166 4 : struct GetAuditorState *gas = cls;
167 :
168 : (void) cmd;
169 4 : if (gas->load_auditor_keys)
170 4 : gas->priv_file = get_auditor_priv_file (gas->cfg);
171 :
172 4 : if (NULL == gas->auditor_url)
173 : {
174 0 : GNUNET_break (0);
175 0 : TALER_TESTING_interpreter_fail (is);
176 0 : return;
177 : }
178 4 : if (NULL != gas->priv_file)
179 : {
180 4 : if (GNUNET_SYSERR ==
181 4 : GNUNET_CRYPTO_eddsa_key_from_file (gas->priv_file,
182 : GNUNET_YES,
183 : &gas->auditor_priv.eddsa_priv))
184 : {
185 0 : GNUNET_break (0);
186 0 : TALER_TESTING_interpreter_fail (is);
187 0 : return;
188 : }
189 4 : GNUNET_CRYPTO_eddsa_key_get_public (&gas->auditor_priv.eddsa_priv,
190 : &gas->auditor_pub.eddsa_pub);
191 : }
192 4 : gas->is = is;
193 : gas->auditor
194 4 : = TALER_AUDITOR_get_config (TALER_TESTING_interpreter_get_context (is),
195 4 : gas->auditor_url,
196 : &version_cb,
197 : gas);
198 4 : if (NULL == gas->auditor)
199 : {
200 0 : GNUNET_break (0);
201 0 : TALER_TESTING_interpreter_fail (is);
202 0 : return;
203 : }
204 : }
205 :
206 :
207 : /**
208 : * Cleanup the state.
209 : *
210 : * @param cls closure.
211 : * @param cmd the command which is being cleaned up.
212 : */
213 : static void
214 4 : get_auditor_cleanup (void *cls,
215 : const struct TALER_TESTING_Command *cmd)
216 : {
217 4 : struct GetAuditorState *gas = cls;
218 :
219 4 : if (NULL != gas->auditor)
220 : {
221 0 : GNUNET_break (0);
222 0 : TALER_AUDITOR_get_config_cancel (gas->auditor);
223 0 : gas->auditor = NULL;
224 : }
225 4 : GNUNET_free (gas->priv_file);
226 4 : GNUNET_free (gas->auditor_url);
227 4 : GNUNET_free (gas);
228 4 : }
229 :
230 :
231 : /**
232 : * Offer internal data to a "get_auditor" CMD state to other commands.
233 : *
234 : * @param cls closure
235 : * @param[out] ret result (could be anything)
236 : * @param trait name of the trait
237 : * @param index index number of the object to offer.
238 : * @return #GNUNET_OK on success
239 : */
240 : static enum GNUNET_GenericReturnValue
241 22 : get_auditor_traits (void *cls,
242 : const void **ret,
243 : const char *trait,
244 : unsigned int index)
245 : {
246 22 : struct GetAuditorState *gas = cls;
247 22 : unsigned int off = (NULL == gas->priv_file) ? 2 : 0;
248 : struct TALER_TESTING_Trait traits[] = {
249 22 : TALER_TESTING_make_trait_auditor_priv (&gas->auditor_priv),
250 22 : TALER_TESTING_make_trait_auditor_pub (&gas->auditor_pub),
251 22 : TALER_TESTING_make_trait_auditor_url (gas->auditor_url),
252 22 : TALER_TESTING_trait_end ()
253 : };
254 :
255 22 : return TALER_TESTING_get_trait (&traits[off],
256 : ret,
257 : trait,
258 : index);
259 : }
260 :
261 :
262 : /**
263 : * Get the base URL of the auditor from @a cfg.
264 : *
265 : * @param cfg configuration to evaluate
266 : * @return base URL of the auditor according to @a cfg
267 : */
268 : static char *
269 4 : get_auditor_base_url (
270 : const struct GNUNET_CONFIGURATION_Handle *cfg)
271 : {
272 : char *auditor_url;
273 :
274 4 : if (GNUNET_OK !=
275 4 : GNUNET_CONFIGURATION_get_value_string (cfg,
276 : "auditor",
277 : "BASE_URL",
278 : &auditor_url))
279 : {
280 0 : GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
281 : "auditor",
282 : "BASE_URL");
283 0 : return NULL;
284 : }
285 4 : return auditor_url;
286 : }
287 :
288 :
289 : struct TALER_TESTING_Command
290 4 : TALER_TESTING_cmd_get_auditor (
291 : const char *label,
292 : const struct GNUNET_CONFIGURATION_Handle *cfg,
293 : bool load_auditor_keys)
294 : {
295 : struct GetAuditorState *gas;
296 :
297 4 : gas = GNUNET_new (struct GetAuditorState);
298 4 : gas->auditor_url = get_auditor_base_url (cfg);
299 4 : gas->load_auditor_keys = load_auditor_keys;
300 4 : gas->cfg = cfg;
301 : {
302 4 : struct TALER_TESTING_Command cmd = {
303 : .cls = gas,
304 : .label = label,
305 : .run = &get_auditor_run,
306 : .cleanup = &get_auditor_cleanup,
307 : .traits = &get_auditor_traits,
308 : .name = "auditor"
309 : };
310 :
311 4 : return cmd;
312 : }
313 : }
|