1 /***************************************************************************
2 begin : Wed Oct 03 2018
3 copyright : (C) 2018 by Martin Preuss
4 email : martin@libchipcard.de
5
6 ***************************************************************************
7 * This file is part of the project "AqBanking". *
8 * Please see toplevel file COPYING of that project for license details. *
9 ***************************************************************************/
10
11
12 #ifdef AQBANKING_WITH_PLUGIN_BANKINFO_DE
13 # include "src/libs/plugins/bankinfo/de/de.h"
14 #endif
15
16
17
AB_Banking_CreateImBankInfoPlugin(AB_BANKING * ab,const char * modname)18 AB_BANKINFO_PLUGIN *AB_Banking_CreateImBankInfoPlugin(AB_BANKING *ab, const char *modname)
19 {
20 if (modname && *modname) {
21 #ifdef AQBANKING_WITH_PLUGIN_BANKINFO_DE
22 if (strcasecmp(modname, "de")==0)
23 return AB_BankInfoPluginDE_new(ab);
24 #endif
25 DBG_ERROR(AQBANKING_LOGDOMAIN, "Plugin [%s] not compiled-in", modname);
26 }
27
28 return NULL;
29 }
30
31
32
AB_Banking_LoadBankInfoPlugin(AB_BANKING * ab,const char * modname)33 AB_BANKINFO_PLUGIN *AB_Banking_LoadBankInfoPlugin(AB_BANKING *ab, const char *modname)
34 {
35 GWEN_PLUGIN *pl;
36
37 pl=GWEN_PluginManager_GetPlugin(ab_pluginManagerBankInfo, modname);
38 if (pl) {
39 AB_BANKINFO_PLUGIN *bip;
40
41 bip=AB_Plugin_BankInfo_Factory(pl, ab);
42 if (!bip) {
43 DBG_ERROR(AQBANKING_LOGDOMAIN, "Error in plugin [%s]: No bank info created", modname);
44 return NULL;
45 }
46 return bip;
47 }
48 else {
49 DBG_INFO(AQBANKING_LOGDOMAIN, "Plugin [%s] not found", modname);
50 return NULL;
51 }
52 }
53
54
55
AB_Banking_FindBankInfoPlugin(AB_BANKING * ab,const char * country)56 AB_BANKINFO_PLUGIN *AB_Banking_FindBankInfoPlugin(AB_BANKING *ab, const char *country)
57 {
58 AB_BANKINFO_PLUGIN *bip;
59
60 bip=AB_BankInfoPlugin_List_First(ab_bankInfoPlugins);
61 while (bip) {
62 if (strcasecmp(AB_BankInfoPlugin_GetCountry(bip), country)==0)
63 break;
64 bip=AB_BankInfoPlugin_List_Next(bip);
65 }
66
67 return bip;
68 }
69
70
71
AB_Banking_GetBankInfoPlugin(AB_BANKING * ab,const char * country)72 AB_BANKINFO_PLUGIN *AB_Banking_GetBankInfoPlugin(AB_BANKING *ab, const char *country)
73 {
74 AB_BANKINFO_PLUGIN *bip;
75
76 assert(ab);
77 assert(country);
78
79 bip=AB_Banking_FindBankInfoPlugin(ab, country);
80 if (bip)
81 return bip;
82 bip=AB_Banking_CreateImBankInfoPlugin(ab, country);
83 if (bip)
84 return bip;
85 bip=AB_Banking_LoadBankInfoPlugin(ab, country);
86 if (bip)
87 AB_BankInfoPlugin_List_Add(bip, ab_bankInfoPlugins);
88
89 return bip;
90 }
91
92
93
AB_Banking_GetBankInfo(AB_BANKING * ab,const char * country,const char * branchId,const char * bankId)94 AB_BANKINFO *AB_Banking_GetBankInfo(AB_BANKING *ab,
95 const char *country,
96 const char *branchId,
97 const char *bankId)
98 {
99 AB_BANKINFO_PLUGIN *bip;
100
101 assert(ab);
102 assert(country);
103 bip=AB_Banking_GetBankInfoPlugin(ab, country);
104 if (!bip) {
105 DBG_INFO(AQBANKING_LOGDOMAIN, "BankInfo plugin for country \"%s\" not found", country);
106 return 0;
107 }
108
109 return AB_BankInfoPlugin_GetBankInfo(bip, branchId, bankId);
110 }
111
112
113
AB_Banking_GetBankInfoByTemplate(AB_BANKING * ab,const char * country,AB_BANKINFO * tbi,AB_BANKINFO_LIST2 * bl)114 int AB_Banking_GetBankInfoByTemplate(AB_BANKING *ab,
115 const char *country,
116 AB_BANKINFO *tbi,
117 AB_BANKINFO_LIST2 *bl)
118 {
119 AB_BANKINFO_PLUGIN *bip;
120
121 assert(ab);
122 assert(country);
123 bip=AB_Banking_GetBankInfoPlugin(ab, country);
124 if (!bip) {
125 DBG_INFO(AQBANKING_LOGDOMAIN,
126 "BankInfo plugin for country \"%s\" not found",
127 country);
128 return 0;
129 }
130
131 return AB_BankInfoPlugin_GetBankInfoByTemplate(bip, tbi, bl);
132 }
133
134
135
AB_Banking_CheckAccount(AB_BANKING * ab,const char * country,const char * branchId,const char * bankId,const char * accountId)136 AB_BANKINFO_CHECKRESULT AB_Banking_CheckAccount(AB_BANKING *ab,
137 const char *country,
138 const char *branchId,
139 const char *bankId,
140 const char *accountId)
141 {
142 AB_BANKINFO_PLUGIN *bip;
143
144 assert(ab);
145 assert(country);
146 bip=AB_Banking_GetBankInfoPlugin(ab, country);
147 if (!bip) {
148 DBG_INFO(AQBANKING_LOGDOMAIN, "BankInfo plugin for country \"%s\" not found", country);
149 return AB_BankInfoCheckResult_UnknownResult;
150 }
151
152 return AB_BankInfoPlugin_CheckAccount(bip, branchId, bankId, accountId);
153 }
154
155
156
AB_Banking__TransformIban(const char * iban,int len,char * newIban,int maxLen)157 int AB_Banking__TransformIban(const char *iban, int len, char *newIban, int maxLen)
158 {
159 int i, j;
160 const char *p;
161 char *s;
162
163 assert(iban);
164 /* format IBAN */
165 i=0;
166 j=0;
167 p=iban;
168 s=newIban;
169 while (j<len && i<maxLen) {
170 int c;
171
172 c=toupper(*p);
173 if (c!=' ') {
174 if (c>='A' && c<='Z') {
175 c=10+(c-'A');
176 *s='0'+(c/10);
177 s++;
178 i++;
179 if (i>=maxLen) {
180 DBG_ERROR(AQBANKING_LOGDOMAIN, "Bad IBAN (too long)");
181 return -1;
182 }
183 *s='0'+(c%10);
184 s++;
185 i++;
186 }
187 else if (isdigit(c)) {
188 *s=c;
189 s++;
190 i++;
191 }
192 else {
193 DBG_ERROR(AQBANKING_LOGDOMAIN, "Bad IBAN (bad char)");
194 return -1;
195 }
196 }
197 p++;
198 j++;
199 } /* while */
200 if (j<len) {
201 DBG_ERROR(AQBANKING_LOGDOMAIN, "Bad IBAN (too long)");
202 return -1;
203 }
204 *s=0;
205
206 return 0;
207 }
208
209
210
AB_Banking_CheckIban(const char * iban)211 int AB_Banking_CheckIban(const char *iban)
212 {
213 char newIban[256];
214 char tmp[10];
215 int i;
216 unsigned int j;
217 const char *p;
218 char *s;
219
220 if (strlen(iban)<5) {
221 DBG_INFO(AQBANKING_LOGDOMAIN, "Bad IBAN (too short) [%s]", iban);
222 return -1;
223 }
224 p=iban;
225 if (!(*p >= 'A' && *p++ <= 'Z' && *p >= 'A' && *p++ <= 'Z')) {
226 DBG_INFO(AQBANKING_LOGDOMAIN, "Bad IBAN (country code not in upper case) [%s]", iban);
227 return -1;
228 }
229 p+=2;
230
231 /* convert IBAN+4 to buffer */
232 if (AB_Banking__TransformIban(p, strlen(p),
233 newIban, sizeof(newIban)-1)) {
234 DBG_INFO(AQBANKING_LOGDOMAIN, "here");
235 return -1;
236 }
237
238 /* append country and checksum */
239 p=iban;
240 s=newIban+strlen(newIban);
241 if (AB_Banking__TransformIban(p, 4, s, sizeof(newIban)-strlen(newIban)-1)) {
242 DBG_INFO(AQBANKING_LOGDOMAIN, "here");
243 return -1;
244 }
245
246 /* calculate checksum in 9er steps */
247 p=newIban;
248 tmp[0]=0;
249 j=0;
250 while (*p) {
251 for (i=strlen(tmp); i<9; i++) {
252 if (!*p)
253 break;
254 tmp[i]=*(p++);
255 }
256 tmp[i]=0;
257 if (1!=sscanf(tmp, "%u", &j)) {
258 DBG_INFO(AQBANKING_LOGDOMAIN, "Bad IBAN (bad char) [%s]", iban);
259 return -1;
260 }
261 j=j%97; /* modulo 97 */
262 snprintf(tmp, sizeof(tmp), "%u", j);
263 } /* while */
264
265 if (j!=1) {
266 DBG_INFO(AQBANKING_LOGDOMAIN, "Bad IBAN (bad checksum) [%s]", iban);
267 return 1;
268 }
269
270 DBG_DEBUG(AQBANKING_LOGDOMAIN, "IBAN is valid [%s]", iban);
271 return 0;
272 }
273
274
275
AB_Banking_MakeGermanIban(const char * bankCode,const char * accountNumber,GWEN_BUFFER * ibanBuf)276 int AB_Banking_MakeGermanIban(const char *bankCode, const char *accountNumber, GWEN_BUFFER *ibanBuf)
277 {
278 GWEN_BUFFER *tbuf;
279 int i;
280 char numbuf[32];
281 char tmp[10];
282 int rv;
283 unsigned int j;
284 const char *p;
285
286 /* create BBAN */
287 tbuf=GWEN_Buffer_new(0, 256, 0, 1);
288
289 /* bank code */
290 i=strlen(bankCode);
291 if (i<8)
292 GWEN_Buffer_FillWithBytes(tbuf, '0', 8-i);
293 rv=AB_Banking__TransformIban(bankCode, strlen(bankCode), numbuf, sizeof(numbuf)-1);
294 if (rv<0) {
295 GWEN_Buffer_free(tbuf);
296 DBG_ERROR(AQBANKING_LOGDOMAIN, "Bad bank code (bad char) (%d)", rv);
297 return rv;
298 }
299 GWEN_Buffer_AppendString(tbuf, numbuf);
300
301 /* account number */
302 i=strlen(accountNumber);
303 if (i<10)
304 GWEN_Buffer_FillWithBytes(tbuf, '0', 10-i);
305 rv=AB_Banking__TransformIban(accountNumber, strlen(accountNumber), numbuf, sizeof(numbuf)-1);
306 if (rv<0) {
307 GWEN_Buffer_free(tbuf);
308 DBG_ERROR(AQBANKING_LOGDOMAIN, "Bad account number (bad char) (%d)", rv);
309 return rv;
310 }
311 GWEN_Buffer_AppendString(tbuf, numbuf);
312
313 /* add "DE00" */
314 GWEN_Buffer_AppendString(tbuf, "131400");
315
316 /* calculate checksum in 9er steps */
317 p=GWEN_Buffer_GetStart(tbuf);
318 tmp[0]=0;
319 j=0;
320 while (*p) {
321 for (i=strlen(tmp); i<9; i++) {
322 if (!*p)
323 break;
324 tmp[i]=*(p++);
325 }
326 tmp[i]=0;
327 if (1!=sscanf(tmp, "%u", &j)) {
328 GWEN_Buffer_free(tbuf);
329 DBG_ERROR(AQBANKING_LOGDOMAIN, "Bad IBAN (bad char)");
330 return -1;
331 }
332 j=j%97; /* modulo 97 */
333 snprintf(tmp, sizeof(tmp), "%u", j);
334 } /* while */
335
336 /* j contains the modulus */
337 snprintf(tmp, sizeof(tmp), "%02u", 98-j);
338
339 GWEN_Buffer_AppendString(ibanBuf, "DE"); /* DE */
340 GWEN_Buffer_AppendString(ibanBuf, tmp); /* checksum */
341 i=strlen(bankCode); /* bank code */
342 if (i<8)
343 GWEN_Buffer_FillWithBytes(ibanBuf, '0', 8-i);
344 GWEN_Buffer_AppendString(ibanBuf, bankCode);
345
346 i=strlen(accountNumber); /* account number */
347 if (i<10)
348 GWEN_Buffer_FillWithBytes(ibanBuf, '0', 10-i);
349 GWEN_Buffer_AppendString(ibanBuf, accountNumber);
350
351
352 DBG_INFO(AQBANKING_LOGDOMAIN, "IBAN is %s", GWEN_Buffer_GetStart(ibanBuf));
353 GWEN_Buffer_free(tbuf);
354 return 0;
355 }
356
357
358
359