Line data Source code
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 "taler/taler_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 62 : TALER_EXCHANGEDB_find_accounts (TALER_EXCHANGEDB_AccountCallback cb,
81 : void *cb_cls)
82 : {
83 62 : for (struct WireAccount *wa = wa_head;
84 234 : NULL != wa;
85 172 : wa = wa->next)
86 172 : cb (cb_cls,
87 172 : &wa->ai);
88 62 : }
89 :
90 :
91 : const struct TALER_EXCHANGEDB_AccountInfo *
92 117 : TALER_EXCHANGEDB_find_account_by_method (const char *method)
93 : {
94 117 : for (struct WireAccount *wa = wa_head;
95 117 : NULL != wa;
96 0 : wa = wa->next)
97 117 : if (0 == strcmp (method,
98 117 : wa->method))
99 117 : return &wa->ai;
100 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
101 : "No wire account known for method `%s'\n",
102 : method);
103 0 : return NULL;
104 : }
105 :
106 :
107 : const struct TALER_EXCHANGEDB_AccountInfo *
108 65 : 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 65 : method = TALER_payto_get_method (url.full_payto);
115 65 : if (NULL == method)
116 : {
117 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
118 : "Invalid payto:// URL `%s'\n",
119 : url.full_payto);
120 0 : return NULL;
121 : }
122 65 : ai = TALER_EXCHANGEDB_find_account_by_method (method);
123 65 : GNUNET_free (method);
124 65 : 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 8602 : add_account_cb (void *cls,
170 : const char *section)
171 : {
172 8602 : struct LoaderContext *lc = cls;
173 8602 : 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 8602 : if (0 != strncasecmp (section,
183 : "exchange-account-",
184 : strlen ("exchange-account-")))
185 8230 : return;
186 :
187 372 : debit = (GNUNET_YES ==
188 372 : GNUNET_CONFIGURATION_get_value_yesno (lc->cfg,
189 : section,
190 : "ENABLE_DEBIT"));
191 372 : credit = (GNUNET_YES ==
192 372 : GNUNET_CONFIGURATION_get_value_yesno (lc->cfg,
193 : section,
194 : "ENABLE_CREDIT"));
195 372 : if (! ( ( (debit) &&
196 372 : (lc->debit) ) ||
197 172 : ( (credit) &&
198 172 : (lc->credit) ) ) )
199 0 : return; /* not enabled for us, skip */
200 372 : if (GNUNET_OK !=
201 372 : GNUNET_CONFIGURATION_get_value_string (cfg,
202 : section,
203 : "PAYTO_URI",
204 : &payto_uri))
205 : {
206 0 : GNUNET_log_config_missing (GNUNET_ERROR_TYPE_WARNING,
207 : section,
208 : "PAYTO_URI");
209 0 : return;
210 : }
211 372 : full_payto.full_payto = payto_uri;
212 372 : method = TALER_payto_get_method (payto_uri);
213 372 : if ( (NULL != (err = TALER_payto_validate (full_payto))) ||
214 : (NULL == method) )
215 : {
216 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
217 : "payto URI in config ([%s]/PAYTO_URI) malformed: %s\n",
218 : section,
219 : err);
220 0 : lc->res = GNUNET_SYSERR;
221 0 : GNUNET_free (payto_uri);
222 0 : GNUNET_free (err);
223 0 : return;
224 : }
225 372 : GNUNET_assert (NULL != method);
226 372 : wa = GNUNET_new (struct WireAccount);
227 372 : wa->section_name = GNUNET_strdup (section);
228 372 : wa->payto_uri = full_payto;
229 372 : wa->method = method;
230 372 : wa->ai.debit_enabled = debit;
231 372 : wa->ai.credit_enabled = credit;
232 372 : wa->ai.auth = NULL;
233 372 : wa->ai.section_name = wa->section_name;
234 372 : wa->ai.method = wa->method;
235 372 : wa->ai.payto_uri = full_payto;
236 372 : if (lc->load_auth_data)
237 : {
238 : char *csn;
239 :
240 263 : GNUNET_asprintf (&csn,
241 : "exchange-accountcredentials-%s",
242 : §ion[strlen ("exchange-account-")]);
243 263 : if (GNUNET_OK !=
244 263 : TALER_BANK_auth_parse_cfg (cfg,
245 : csn,
246 : &wa->auth))
247 : {
248 0 : GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
249 : "Failed to load exchange account credentials from section `%s'\n",
250 : csn);
251 0 : GNUNET_free (csn);
252 0 : GNUNET_free (wa->section_name);
253 0 : GNUNET_free (wa->method);
254 0 : GNUNET_free (wa);
255 0 : return;
256 : }
257 263 : wa->ai.auth = &wa->auth;
258 263 : GNUNET_free (csn);
259 : }
260 372 : GNUNET_CONTAINER_DLL_insert (wa_head,
261 : wa_tail,
262 : wa);
263 : }
264 :
265 :
266 : enum GNUNET_GenericReturnValue
267 162 : TALER_EXCHANGEDB_load_accounts (
268 : const struct GNUNET_CONFIGURATION_Handle *cfg,
269 : enum TALER_EXCHANGEDB_AccountLoaderOptions options)
270 : {
271 162 : struct LoaderContext lc = {
272 : .cfg = cfg,
273 162 : .debit = 0 != (options & TALER_EXCHANGEDB_ALO_DEBIT),
274 162 : .credit = 0 != (options & TALER_EXCHANGEDB_ALO_CREDIT),
275 162 : .load_auth_data = 0 != (options & TALER_EXCHANGEDB_ALO_AUTHDATA),
276 : };
277 :
278 162 : GNUNET_CONFIGURATION_iterate_sections (cfg,
279 : &add_account_cb,
280 : &lc);
281 162 : if (GNUNET_SYSERR == lc.res)
282 0 : return GNUNET_SYSERR;
283 162 : if (NULL == wa_head)
284 0 : return GNUNET_NO;
285 162 : return GNUNET_OK;
286 : }
287 :
288 :
289 : void
290 162 : TALER_EXCHANGEDB_unload_accounts (void)
291 : {
292 : struct WireAccount *wa;
293 :
294 534 : while (NULL != (wa = wa_head))
295 : {
296 372 : GNUNET_CONTAINER_DLL_remove (wa_head,
297 : wa_tail,
298 : wa);
299 372 : if (NULL != wa->ai.auth)
300 263 : TALER_BANK_auth_free (&wa->auth);
301 372 : GNUNET_free (wa->section_name);
302 372 : GNUNET_free (wa->payto_uri.full_payto);
303 372 : GNUNET_free (wa->method);
304 372 : GNUNET_free (wa);
305 : }
306 162 : }
307 :
308 :
309 : /* end of exchangedb_accounts.c */
|