testing_api_cmd_get_auditor.c (8101B)
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/platform.h" 25 #include "taler/taler_json_lib.h" 26 #include <gnunet/gnunet_curl_lib.h> 27 #include "taler/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 version_cb ( 87 void *cls, 88 const struct TALER_AUDITOR_ConfigResponse *vr) 89 { 90 struct GetAuditorState *gas = cls; 91 92 gas->auditor = NULL; 93 if (MHD_HTTP_OK != vr->hr.http_status) 94 { 95 TALER_TESTING_unexpected_status (gas->is, 96 vr->hr.http_status, 97 MHD_HTTP_OK); 98 return; 99 } 100 if ( (NULL != gas->priv_file) && 101 (0 != GNUNET_memcmp (&gas->auditor_pub, 102 &vr->details.ok.vi.auditor_pub)) ) 103 { 104 GNUNET_break (0); 105 TALER_TESTING_interpreter_fail (gas->is); 106 return; 107 } 108 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 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 GNUNET_break (GNUNET_OK == 128 GNUNET_CONFIGURATION_get_value_filename (cfg, 129 "PATHS", 130 "DEFAULTCONFIG", 131 &dfn)); 132 acfg = GNUNET_CONFIGURATION_create (TALER_AUDITOR_project_data ()); 133 GNUNET_break (GNUNET_OK == 134 GNUNET_CONFIGURATION_load (acfg, 135 dfn)); 136 GNUNET_free (dfn); 137 if (GNUNET_OK != 138 GNUNET_CONFIGURATION_get_value_filename (acfg, 139 "auditor", 140 "AUDITOR_PRIV_FILE", 141 &fn)) 142 { 143 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, 144 "auditor", 145 "AUDITOR_PRIV_FILE"); 146 } 147 GNUNET_CONFIGURATION_destroy (acfg); 148 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 149 "Loading auditor private key from %s\n", 150 fn); 151 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 get_auditor_run (void *cls, 164 const struct TALER_TESTING_Command *cmd, 165 struct TALER_TESTING_Interpreter *is) 166 { 167 struct GetAuditorState *gas = cls; 168 169 (void) cmd; 170 if (gas->load_auditor_keys) 171 gas->priv_file = get_auditor_priv_file (gas->cfg); 172 173 if (NULL == gas->auditor_url) 174 { 175 GNUNET_break (0); 176 TALER_TESTING_interpreter_fail (is); 177 return; 178 } 179 if (NULL != gas->priv_file) 180 { 181 if (GNUNET_SYSERR == 182 GNUNET_CRYPTO_eddsa_key_from_file (gas->priv_file, 183 GNUNET_YES, 184 &gas->auditor_priv.eddsa_priv)) 185 { 186 GNUNET_break (0); 187 TALER_TESTING_interpreter_fail (is); 188 return; 189 } 190 GNUNET_CRYPTO_eddsa_key_get_public (&gas->auditor_priv.eddsa_priv, 191 &gas->auditor_pub.eddsa_pub); 192 } 193 gas->is = is; 194 gas->auditor 195 = TALER_AUDITOR_get_config (TALER_TESTING_interpreter_get_context (is), 196 gas->auditor_url, 197 &version_cb, 198 gas); 199 if (NULL == gas->auditor) 200 { 201 GNUNET_break (0); 202 TALER_TESTING_interpreter_fail (is); 203 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 get_auditor_cleanup (void *cls, 216 const struct TALER_TESTING_Command *cmd) 217 { 218 struct GetAuditorState *gas = cls; 219 220 if (NULL != gas->auditor) 221 { 222 GNUNET_break (0); 223 TALER_AUDITOR_get_config_cancel (gas->auditor); 224 gas->auditor = NULL; 225 } 226 GNUNET_free (gas->priv_file); 227 GNUNET_free (gas->auditor_url); 228 GNUNET_free (gas); 229 } 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 get_auditor_traits (void *cls, 243 const void **ret, 244 const char *trait, 245 unsigned int index) 246 { 247 struct GetAuditorState *gas = cls; 248 unsigned int off = (NULL == gas->priv_file) ? 2 : 0; 249 struct TALER_TESTING_Trait traits[] = { 250 TALER_TESTING_make_trait_auditor_priv (&gas->auditor_priv), 251 TALER_TESTING_make_trait_auditor_pub (&gas->auditor_pub), 252 TALER_TESTING_make_trait_auditor_url (gas->auditor_url), 253 TALER_TESTING_trait_end () 254 }; 255 256 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 get_auditor_base_url ( 271 const struct GNUNET_CONFIGURATION_Handle *cfg) 272 { 273 char *auditor_url; 274 275 if (GNUNET_OK != 276 GNUNET_CONFIGURATION_get_value_string (cfg, 277 "auditor", 278 "BASE_URL", 279 &auditor_url)) 280 { 281 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, 282 "auditor", 283 "BASE_URL"); 284 return NULL; 285 } 286 return auditor_url; 287 } 288 289 290 struct TALER_TESTING_Command 291 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 gas = GNUNET_new (struct GetAuditorState); 299 gas->auditor_url = get_auditor_base_url (cfg); 300 gas->load_auditor_keys = load_auditor_keys; 301 gas->cfg = cfg; 302 { 303 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 return cmd; 313 } 314 }