exchangedb_accounts.c (7903B)
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 method = TALER_payto_get_method (payto_uri); 213 if ( (NULL != (err = TALER_payto_validate (full_payto))) || 214 (NULL == method) ) 215 { 216 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 217 "payto URI in config ([%s]/PAYTO_URI) malformed: %s\n", 218 section, 219 err); 220 lc->res = GNUNET_SYSERR; 221 GNUNET_free (payto_uri); 222 GNUNET_free (err); 223 return; 224 } 225 GNUNET_assert (NULL != method); 226 wa = GNUNET_new (struct WireAccount); 227 wa->section_name = GNUNET_strdup (section); 228 wa->payto_uri = full_payto; 229 wa->method = method; 230 wa->ai.debit_enabled = debit; 231 wa->ai.credit_enabled = credit; 232 wa->ai.auth = NULL; 233 wa->ai.section_name = wa->section_name; 234 wa->ai.method = wa->method; 235 wa->ai.payto_uri = full_payto; 236 if (lc->load_auth_data) 237 { 238 char *csn; 239 240 GNUNET_asprintf (&csn, 241 "exchange-accountcredentials-%s", 242 §ion[strlen ("exchange-account-")]); 243 if (GNUNET_OK != 244 TALER_BANK_auth_parse_cfg (cfg, 245 csn, 246 &wa->auth)) 247 { 248 GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, 249 "Failed to load exchange account credentials from section `%s'\n", 250 csn); 251 GNUNET_free (csn); 252 GNUNET_free (wa->section_name); 253 GNUNET_free (wa->method); 254 GNUNET_free (wa); 255 return; 256 } 257 wa->ai.auth = &wa->auth; 258 GNUNET_free (csn); 259 } 260 GNUNET_CONTAINER_DLL_insert (wa_head, 261 wa_tail, 262 wa); 263 } 264 265 266 enum GNUNET_GenericReturnValue 267 TALER_EXCHANGEDB_load_accounts ( 268 const struct GNUNET_CONFIGURATION_Handle *cfg, 269 enum TALER_EXCHANGEDB_AccountLoaderOptions options) 270 { 271 struct LoaderContext lc = { 272 .cfg = cfg, 273 .debit = 0 != (options & TALER_EXCHANGEDB_ALO_DEBIT), 274 .credit = 0 != (options & TALER_EXCHANGEDB_ALO_CREDIT), 275 .load_auth_data = 0 != (options & TALER_EXCHANGEDB_ALO_AUTHDATA), 276 }; 277 278 GNUNET_CONFIGURATION_iterate_sections (cfg, 279 &add_account_cb, 280 &lc); 281 if (GNUNET_SYSERR == lc.res) 282 return GNUNET_SYSERR; 283 if (NULL == wa_head) 284 return GNUNET_NO; 285 return GNUNET_OK; 286 } 287 288 289 void 290 TALER_EXCHANGEDB_unload_accounts (void) 291 { 292 struct WireAccount *wa; 293 294 while (NULL != (wa = wa_head)) 295 { 296 GNUNET_CONTAINER_DLL_remove (wa_head, 297 wa_tail, 298 wa); 299 if (NULL != wa->ai.auth) 300 TALER_BANK_auth_free (&wa->auth); 301 GNUNET_free (wa->section_name); 302 GNUNET_free (wa->payto_uri.full_payto); 303 GNUNET_free (wa->method); 304 GNUNET_free (wa); 305 } 306 } 307 308 309 /* end of exchangedb_accounts.c */