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