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