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