exchangedb_accounts.c (8078B)
1 /* 2 This file is part of TALER 3 Copyright (C) 2018-2021 Taler Systems SA 4 5 TALER is free software; you can redistribute it and/or modify it under the 6 terms of the GNU General Public License as published by the Free Software 7 Foundation; either version 3, or (at your option) any later version. 8 9 TALER is distributed in the hope that it will be useful, but WITHOUT ANY 10 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 11 A PARTICULAR PURPOSE. See the GNU General Public License for more details. 12 13 You should have received a copy of the GNU General Public License along with 14 TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> 15 */ 16 /** 17 * @file exchangedb/exchangedb_accounts.c 18 * @brief Logic to parse account information from the configuration 19 * @author Christian Grothoff 20 */ 21 #include "exchangedb_lib.h" 22 23 24 /** 25 * Information we keep for each supported account of the exchange. 26 */ 27 struct WireAccount 28 { 29 /** 30 * Accounts are kept in a DLL. 31 */ 32 struct WireAccount *next; 33 34 /** 35 * Plugins are kept in a DLL. 36 */ 37 struct WireAccount *prev; 38 39 /** 40 * Externally visible account information. 41 */ 42 struct TALER_EXCHANGEDB_AccountInfo ai; 43 44 /** 45 * Authentication data. Only parsed if 46 * #TALER_EXCHANGEDB_ALO_AUTHDATA was set. 47 */ 48 struct TALER_BANK_AuthenticationData auth; 49 50 /** 51 * Name of the section that configures this account. 52 */ 53 char *section_name; 54 55 /** 56 * Name of the wire method underlying the account. 57 */ 58 char *method; 59 60 /** 61 * Full payto://-URI of the account. 62 */ 63 struct TALER_FullPayto payto_uri; 64 65 }; 66 67 68 /** 69 * Head of list of wire accounts of the exchange. 70 */ 71 static struct WireAccount *wa_head; 72 73 /** 74 * Tail of list of wire accounts of the exchange. 75 */ 76 static struct WireAccount *wa_tail; 77 78 79 void 80 TALER_EXCHANGEDB_find_accounts (TALER_EXCHANGEDB_AccountCallback cb, 81 void *cb_cls) 82 { 83 for (struct WireAccount *wa = wa_head; 84 NULL != wa; 85 wa = wa->next) 86 cb (cb_cls, 87 &wa->ai); 88 } 89 90 91 const struct TALER_EXCHANGEDB_AccountInfo * 92 TALER_EXCHANGEDB_find_account_by_method (const char *method) 93 { 94 for (struct WireAccount *wa = wa_head; 95 NULL != wa; 96 wa = wa->next) 97 if (0 == strcmp (method, 98 wa->method)) 99 return &wa->ai; 100 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 101 "No wire account known for method `%s'\n", 102 method); 103 return NULL; 104 } 105 106 107 const struct TALER_EXCHANGEDB_AccountInfo * 108 TALER_EXCHANGEDB_find_account_by_payto_uri ( 109 const struct TALER_FullPayto url) 110 { 111 char *method; 112 const struct TALER_EXCHANGEDB_AccountInfo *ai; 113 114 method = TALER_payto_get_method (url.full_payto); 115 if (NULL == method) 116 { 117 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 118 "Invalid payto:// URL `%s'\n", 119 url.full_payto); 120 return NULL; 121 } 122 ai = TALER_EXCHANGEDB_find_account_by_method (method); 123 GNUNET_free (method); 124 return ai; 125 } 126 127 128 /** 129 * Closure for #add_account_cb(). 130 */ 131 struct LoaderContext 132 { 133 /** 134 * Configuration to use. 135 */ 136 const struct GNUNET_CONFIGURATION_Handle *cfg; 137 138 /** 139 * true if we are to load the authentication data 140 * for the access to the bank account. 141 */ 142 bool load_auth_data; 143 144 /** 145 * Load accounts enabled for CREDIT. 146 */ 147 bool credit; 148 149 /** 150 * Load accounts enabled for DEBIT. 151 */ 152 bool debit; 153 154 /** 155 * Loader status (set by callback). 156 */ 157 enum GNUNET_GenericReturnValue res; 158 }; 159 160 161 /** 162 * Function called with information about a wire account. Adds 163 * the account to our list. 164 * 165 * @param cls closure, a `struct LoaderContext` 166 * @param section section to parse account information from 167 */ 168 static void 169 add_account_cb (void *cls, 170 const char *section) 171 { 172 struct LoaderContext *lc = cls; 173 const struct GNUNET_CONFIGURATION_Handle *cfg = lc->cfg; 174 struct WireAccount *wa; 175 char *payto_uri; 176 char *method; 177 bool debit; 178 bool credit; 179 struct TALER_FullPayto full_payto; 180 char *err; 181 182 if (0 != strncasecmp (section, 183 "exchange-account-", 184 strlen ("exchange-account-"))) 185 return; 186 187 debit = (GNUNET_YES == 188 GNUNET_CONFIGURATION_get_value_yesno (lc->cfg, 189 section, 190 "ENABLE_DEBIT")); 191 credit = (GNUNET_YES == 192 GNUNET_CONFIGURATION_get_value_yesno (lc->cfg, 193 section, 194 "ENABLE_CREDIT")); 195 if (! ( ( (debit) && 196 (lc->debit) ) || 197 ( (credit) && 198 (lc->credit) ) ) ) 199 return; /* not enabled for us, skip */ 200 if (GNUNET_OK != 201 GNUNET_CONFIGURATION_get_value_string (cfg, 202 section, 203 "PAYTO_URI", 204 &payto_uri)) 205 { 206 GNUNET_log_config_missing (GNUNET_ERROR_TYPE_WARNING, 207 section, 208 "PAYTO_URI"); 209 return; 210 } 211 full_payto.full_payto = payto_uri; 212 if (NULL != (err = TALER_payto_validate (full_payto))) 213 { 214 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 215 "payto URI in config ([%s]/PAYTO_URI) malformed: %s\n", 216 section, 217 err); 218 lc->res = GNUNET_SYSERR; 219 GNUNET_free (payto_uri); 220 GNUNET_free (err); 221 return; 222 } 223 if (NULL == (method = TALER_payto_get_method (payto_uri))) 224 { 225 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 226 "payto URI in config ([%s]/PAYTO_URI) malformed: no method!?\n", 227 section); 228 lc->res = GNUNET_SYSERR; 229 GNUNET_free (payto_uri); 230 return; 231 } 232 wa = GNUNET_new (struct WireAccount); 233 wa->section_name = GNUNET_strdup (section); 234 wa->payto_uri = full_payto; 235 wa->method = method; 236 wa->ai.debit_enabled = debit; 237 wa->ai.credit_enabled = credit; 238 wa->ai.auth = NULL; 239 wa->ai.section_name = wa->section_name; 240 wa->ai.method = wa->method; 241 wa->ai.payto_uri = full_payto; 242 if (lc->load_auth_data) 243 { 244 char *csn; 245 246 GNUNET_asprintf (&csn, 247 "exchange-accountcredentials-%s", 248 §ion[strlen ("exchange-account-")]); 249 if (GNUNET_OK != 250 TALER_BANK_auth_parse_cfg (cfg, 251 csn, 252 &wa->auth)) 253 { 254 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, 255 "Failed to load exchange account credentials from section `%s'\n", 256 csn); 257 GNUNET_free (csn); 258 GNUNET_free (wa->section_name); 259 GNUNET_free (wa->method); 260 GNUNET_free (wa); 261 return; 262 } 263 wa->ai.auth = &wa->auth; 264 GNUNET_free (csn); 265 } 266 GNUNET_CONTAINER_DLL_insert (wa_head, 267 wa_tail, 268 wa); 269 } 270 271 272 enum GNUNET_GenericReturnValue 273 TALER_EXCHANGEDB_load_accounts ( 274 const struct GNUNET_CONFIGURATION_Handle *cfg, 275 enum TALER_EXCHANGEDB_AccountLoaderOptions options) 276 { 277 struct LoaderContext lc = { 278 .cfg = cfg, 279 .debit = 0 != (options & TALER_EXCHANGEDB_ALO_DEBIT), 280 .credit = 0 != (options & TALER_EXCHANGEDB_ALO_CREDIT), 281 .load_auth_data = 0 != (options & TALER_EXCHANGEDB_ALO_AUTHDATA), 282 }; 283 284 GNUNET_CONFIGURATION_iterate_sections (cfg, 285 &add_account_cb, 286 &lc); 287 if (GNUNET_SYSERR == lc.res) 288 return GNUNET_SYSERR; 289 if (NULL == wa_head) 290 return GNUNET_NO; 291 return GNUNET_OK; 292 } 293 294 295 void 296 TALER_EXCHANGEDB_unload_accounts (void) 297 { 298 struct WireAccount *wa; 299 300 while (NULL != (wa = wa_head)) 301 { 302 GNUNET_CONTAINER_DLL_remove (wa_head, 303 wa_tail, 304 wa); 305 if (NULL != wa->ai.auth) 306 TALER_BANK_auth_free (&wa->auth); 307 GNUNET_free (wa->section_name); 308 GNUNET_free (wa->payto_uri.full_payto); 309 GNUNET_free (wa->method); 310 GNUNET_free (wa); 311 } 312 } 313 314 315 /* end of exchangedb_accounts.c */