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 "platform.h"
22 : #include "taler_exchangedb_lib.h"
23 :
24 :
25 : /**
26 : * Information we keep for each supported account of the exchange.
27 : */
28 : struct WireAccount
29 : {
30 : /**
31 : * Accounts are kept in a DLL.
32 : */
33 : struct WireAccount *next;
34 :
35 : /**
36 : * Plugins are kept in a DLL.
37 : */
38 : struct WireAccount *prev;
39 :
40 : /**
41 : * Externally visible account information.
42 : */
43 : struct TALER_EXCHANGEDB_AccountInfo ai;
44 :
45 : /**
46 : * Authentication data. Only parsed if
47 : * #TALER_EXCHANGEDB_ALO_AUTHDATA was set.
48 : */
49 : struct TALER_BANK_AuthenticationData auth;
50 :
51 : /**
52 : * Name of the section that configures this account.
53 : */
54 : char *section_name;
55 :
56 : /**
57 : * Name of the wire method underlying the account.
58 : */
59 : char *method;
60 :
61 : /**
62 : * Full payto://-URI of the account.
63 : */
64 : struct TALER_FullPayto payto_uri;
65 :
66 : };
67 :
68 :
69 : /**
70 : * Head of list of wire accounts of the exchange.
71 : */
72 : static struct WireAccount *wa_head;
73 :
74 : /**
75 : * Tail of list of wire accounts of the exchange.
76 : */
77 : static struct WireAccount *wa_tail;
78 :
79 :
80 : void
81 200 : TALER_EXCHANGEDB_find_accounts (TALER_EXCHANGEDB_AccountCallback cb,
82 : void *cb_cls)
83 : {
84 200 : for (struct WireAccount *wa = wa_head;
85 460 : NULL != wa;
86 260 : wa = wa->next)
87 260 : cb (cb_cls,
88 260 : &wa->ai);
89 200 : }
90 :
91 :
92 : const struct TALER_EXCHANGEDB_AccountInfo *
93 146 : TALER_EXCHANGEDB_find_account_by_method (const char *method)
94 : {
95 146 : for (struct WireAccount *wa = wa_head;
96 146 : NULL != wa;
97 0 : wa = wa->next)
98 146 : if (0 == strcmp (method,
99 146 : wa->method))
100 146 : return &wa->ai;
101 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
102 : "No wire account known for method `%s'\n",
103 : method);
104 0 : return NULL;
105 : }
106 :
107 :
108 : const struct TALER_EXCHANGEDB_AccountInfo *
109 79 : TALER_EXCHANGEDB_find_account_by_payto_uri (
110 : const struct TALER_FullPayto url)
111 : {
112 : char *method;
113 : const struct TALER_EXCHANGEDB_AccountInfo *ai;
114 :
115 79 : method = TALER_payto_get_method (url.full_payto);
116 79 : if (NULL == method)
117 : {
118 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
119 : "Invalid payto:// URL `%s'\n",
120 : url.full_payto);
121 0 : return NULL;
122 : }
123 79 : ai = TALER_EXCHANGEDB_find_account_by_method (method);
124 79 : GNUNET_free (method);
125 79 : return ai;
126 : }
127 :
128 :
129 : /**
130 : * Closure for #add_account_cb().
131 : */
132 : struct LoaderContext
133 : {
134 : /**
135 : * Configuration to use.
136 : */
137 : const struct GNUNET_CONFIGURATION_Handle *cfg;
138 :
139 : /**
140 : * true if we are to load the authentication data
141 : * for the access to the bank account.
142 : */
143 : bool load_auth_data;
144 :
145 : /**
146 : * Load accounts enabled for CREDIT.
147 : */
148 : bool credit;
149 :
150 : /**
151 : * Load accounts enabled for DEBIT.
152 : */
153 : bool debit;
154 :
155 : /**
156 : * Loader status (set by callback).
157 : */
158 : enum GNUNET_GenericReturnValue res;
159 : };
160 :
161 :
162 : /**
163 : * Function called with information about a wire account. Adds
164 : * the account to our list.
165 : *
166 : * @param cls closure, a `struct LoaderContext`
167 : * @param section section to parse account information from
168 : */
169 : static void
170 15368 : add_account_cb (void *cls,
171 : const char *section)
172 : {
173 15368 : struct LoaderContext *lc = cls;
174 15368 : const struct GNUNET_CONFIGURATION_Handle *cfg = lc->cfg;
175 : struct WireAccount *wa;
176 : char *payto_uri;
177 : char *method;
178 : bool debit;
179 : bool credit;
180 : struct TALER_FullPayto full_payto;
181 : char *err;
182 :
183 15368 : if (0 != strncasecmp (section,
184 : "exchange-account-",
185 : strlen ("exchange-account-")))
186 14852 : return;
187 :
188 516 : debit = (GNUNET_YES ==
189 516 : GNUNET_CONFIGURATION_get_value_yesno (lc->cfg,
190 : section,
191 : "ENABLE_DEBIT"));
192 516 : credit = (GNUNET_YES ==
193 516 : GNUNET_CONFIGURATION_get_value_yesno (lc->cfg,
194 : section,
195 : "ENABLE_CREDIT"));
196 516 : if (! ( ( (debit) &&
197 516 : (lc->debit) ) ||
198 192 : ( (credit) &&
199 192 : (lc->credit) ) ) )
200 0 : return; /* not enabled for us, skip */
201 516 : if (GNUNET_OK !=
202 516 : GNUNET_CONFIGURATION_get_value_string (cfg,
203 : section,
204 : "PAYTO_URI",
205 : &payto_uri))
206 : {
207 0 : GNUNET_log_config_missing (GNUNET_ERROR_TYPE_WARNING,
208 : section,
209 : "PAYTO_URI");
210 0 : return;
211 : }
212 516 : full_payto.full_payto = payto_uri;
213 516 : method = TALER_payto_get_method (payto_uri);
214 516 : if ( (NULL != (err = TALER_payto_validate (full_payto))) ||
215 : (NULL == method) )
216 : {
217 0 : GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
218 : "payto URI in config ([%s]/PAYTO_URI) malformed: %s\n",
219 : section,
220 : err);
221 0 : lc->res = GNUNET_SYSERR;
222 0 : GNUNET_free (payto_uri);
223 0 : GNUNET_free (err);
224 0 : return;
225 : }
226 516 : GNUNET_assert (NULL != method);
227 516 : wa = GNUNET_new (struct WireAccount);
228 516 : wa->section_name = GNUNET_strdup (section);
229 516 : wa->payto_uri = full_payto;
230 516 : wa->method = method;
231 516 : wa->ai.debit_enabled = debit;
232 516 : wa->ai.credit_enabled = credit;
233 516 : wa->ai.auth = NULL;
234 516 : wa->ai.section_name = wa->section_name;
235 516 : wa->ai.method = wa->method;
236 516 : wa->ai.payto_uri = full_payto;
237 516 : if (lc->load_auth_data)
238 : {
239 : char *csn;
240 :
241 411 : GNUNET_asprintf (&csn,
242 : "exchange-accountcredentials-%s",
243 : §ion[strlen ("exchange-account-")]);
244 411 : if (GNUNET_OK !=
245 411 : TALER_BANK_auth_parse_cfg (cfg,
246 : csn,
247 : &wa->auth))
248 : {
249 0 : GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE,
250 : "Failed to load exchange account credentials from section `%s'\n",
251 : csn);
252 0 : GNUNET_free (csn);
253 0 : GNUNET_free (wa->section_name);
254 0 : GNUNET_free (wa->method);
255 0 : GNUNET_free (wa);
256 0 : return;
257 : }
258 411 : wa->ai.auth = &wa->auth;
259 411 : GNUNET_free (csn);
260 : }
261 516 : GNUNET_CONTAINER_DLL_insert (wa_head,
262 : wa_tail,
263 : wa);
264 : }
265 :
266 :
267 : enum GNUNET_GenericReturnValue
268 406 : TALER_EXCHANGEDB_load_accounts (
269 : const struct GNUNET_CONFIGURATION_Handle *cfg,
270 : enum TALER_EXCHANGEDB_AccountLoaderOptions options)
271 : {
272 406 : struct LoaderContext lc = {
273 : .cfg = cfg,
274 406 : .debit = 0 != (options & TALER_EXCHANGEDB_ALO_DEBIT),
275 406 : .credit = 0 != (options & TALER_EXCHANGEDB_ALO_CREDIT),
276 406 : .load_auth_data = 0 != (options & TALER_EXCHANGEDB_ALO_AUTHDATA),
277 : };
278 :
279 406 : GNUNET_CONFIGURATION_iterate_sections (cfg,
280 : &add_account_cb,
281 : &lc);
282 406 : if (GNUNET_SYSERR == lc.res)
283 0 : return GNUNET_SYSERR;
284 406 : if (NULL == wa_head)
285 0 : return GNUNET_NO;
286 406 : return GNUNET_OK;
287 : }
288 :
289 :
290 : void
291 406 : TALER_EXCHANGEDB_unload_accounts (void)
292 : {
293 : struct WireAccount *wa;
294 :
295 922 : while (NULL != (wa = wa_head))
296 : {
297 516 : GNUNET_CONTAINER_DLL_remove (wa_head,
298 : wa_tail,
299 : wa);
300 516 : if (NULL != wa->ai.auth)
301 411 : TALER_BANK_auth_free (&wa->auth);
302 516 : GNUNET_free (wa->section_name);
303 516 : GNUNET_free (wa->payto_uri.full_payto);
304 516 : GNUNET_free (wa->method);
305 516 : GNUNET_free (wa);
306 : }
307 406 : }
308 :
309 :
310 : /* end of exchangedb_accounts.c */
|