1 /***************************************************************************
2  begin       : Thu Oct 04 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 /* This file is included by banking.c */
12 
13 
14 
AB_Banking_CheckTransactionAgainstLimits_Purpose(const AB_TRANSACTION * t,const AB_TRANSACTION_LIMITS * lim)15 int AB_Banking_CheckTransactionAgainstLimits_Purpose(const AB_TRANSACTION *t, const AB_TRANSACTION_LIMITS *lim)
16 {
17   int maxn;
18   int maxs;
19   const char *purpose;
20 
21   /* check purpose */
22   if (lim) {
23     maxn=AB_TransactionLimits_GetMaxLinesPurpose(lim);
24     maxs=AB_TransactionLimits_GetMaxLenPurpose(lim);
25   }
26   else {
27     DBG_INFO(AQBANKING_LOGDOMAIN, "No transaction limits");
28     maxn=0;
29     maxs=0;
30   }
31 
32   purpose=AB_Transaction_GetPurpose(t);
33   if (purpose && *purpose) {
34     GWEN_STRINGLIST *sl;
35 
36     sl=GWEN_StringList_fromString(purpose, "\n", 0);
37     if (sl && GWEN_StringList_Count(sl)) {
38       int n;
39       GWEN_STRINGLISTENTRY *se;
40       const char *p;
41 
42       n=0;
43       se=GWEN_StringList_FirstEntry(sl);
44       while (se) {
45         p=GWEN_StringListEntry_Data(se);
46         if (p && *p) {
47           n++;
48           if (maxn && n>maxn) {
49             DBG_ERROR(AQBANKING_LOGDOMAIN, "Too many purpose lines (%d>%d)", n, maxn);
50             GWEN_Gui_ProgressLog2(0,
51                                   GWEN_LoggerLevel_Error,
52                                   I18N("Too many purpose lines (%d>%d)"),
53                                   n, maxn);
54             GWEN_StringList_free(sl);
55             return GWEN_ERROR_INVALID;
56           }
57           else if (maxs>0) {
58             int l;
59             GWEN_BUFFER *tbuf;
60 
61             tbuf=GWEN_Buffer_new(0, maxs, 0, 1);
62             AB_ImExporter_Utf8ToDta(p, -1, tbuf);
63             GWEN_Text_CondenseBuffer(tbuf);
64             l=GWEN_Buffer_GetUsedBytes(tbuf);
65             if (maxs && l>maxs) {
66               DBG_ERROR(AQBANKING_LOGDOMAIN, "Too many chars in purpose line %d (%d>%d)", n, l, maxs);
67               GWEN_Gui_ProgressLog2(0,
68                                     GWEN_LoggerLevel_Error,
69                                     I18N("Too many chars in purpose line %d (%d>%d)"),
70                                     n, l, maxs);
71               GWEN_Buffer_free(tbuf);
72               GWEN_StringList_free(sl);
73               return GWEN_ERROR_INVALID;
74             }
75             GWEN_Buffer_free(tbuf);
76           }
77         }
78         se=GWEN_StringListEntry_Next(se);
79       } /* while */
80       if (!n) {
81         DBG_ERROR(AQBANKING_LOGDOMAIN, "No purpose lines");
82         GWEN_StringList_free(sl);
83         return GWEN_ERROR_INVALID;
84       }
85     }
86     GWEN_StringList_free(sl);
87   }
88   return 0;
89 }
90 
91 
92 
AB_Banking_CheckTransactionAgainstLimits_Names(const AB_TRANSACTION * t,const AB_TRANSACTION_LIMITS * lim)93 int AB_Banking_CheckTransactionAgainstLimits_Names(const AB_TRANSACTION *t, const AB_TRANSACTION_LIMITS *lim)
94 {
95   int maxs;
96   const char *s;
97 
98   /* check remote name */
99   if (lim)
100     maxs=AB_TransactionLimits_GetMaxLenRemoteName(lim);
101   else
102     maxs=0;
103 
104   s=AB_Transaction_GetRemoteName(t);
105   if (s && *s) {
106     int l;
107     GWEN_BUFFER *tbuf;
108 
109     tbuf=GWEN_Buffer_new(0, 256, 0, 1);
110     AB_ImExporter_Utf8ToDta(s, -1, tbuf);
111     GWEN_Text_CondenseBuffer(tbuf);
112     l=GWEN_Buffer_GetUsedBytes(tbuf);
113     if (maxs>0 && l>maxs) {
114       DBG_ERROR(AQBANKING_LOGDOMAIN, "Too many chars in remote name (%d>%d)", l, maxs);
115       GWEN_Buffer_free(tbuf);
116       return GWEN_ERROR_INVALID;
117     }
118     GWEN_Buffer_free(tbuf);
119   }
120   else {
121     DBG_ERROR(AQBANKING_LOGDOMAIN, "Missing remote name");
122     return GWEN_ERROR_INVALID;
123   }
124 
125   /* check local name */
126   if (lim)
127     maxs=AB_TransactionLimits_GetMaxLenLocalName(lim);
128   else
129     maxs=0;
130   s=AB_Transaction_GetLocalName(t);
131   if (s && *s) {
132     int l;
133     GWEN_BUFFER *tbuf;
134 
135     tbuf=GWEN_Buffer_new(0, 256, 0, 1);
136     AB_ImExporter_Utf8ToDta(s, -1, tbuf);
137     GWEN_Text_CondenseBuffer(tbuf);
138     l=GWEN_Buffer_GetUsedBytes(tbuf);
139     if (maxs>0 && l>maxs) {
140       DBG_ERROR(AQBANKING_LOGDOMAIN, "Too many chars in local name (%d>%d)", l, maxs);
141       GWEN_Buffer_free(tbuf);
142       return GWEN_ERROR_INVALID;
143     }
144     GWEN_Buffer_free(tbuf);
145   }
146   else {
147     DBG_ERROR(AQBANKING_LOGDOMAIN, "Missing local name");
148     return GWEN_ERROR_INVALID;
149   }
150 
151   return 0;
152 }
153 
154 
155 
156 
157 
AB_Banking_CheckTransactionAgainstLimits_Recurrence(const AB_TRANSACTION * t,const AB_TRANSACTION_LIMITS * lim)158 int AB_Banking_CheckTransactionAgainstLimits_Recurrence(const AB_TRANSACTION *t, const AB_TRANSACTION_LIMITS *lim)
159 {
160   if (lim) {
161     /* check period */
162     if (AB_Transaction_GetPeriod(t)==AB_Transaction_PeriodMonthly) {
163       int n;
164 
165       n=AB_Transaction_GetCycle(t);
166       if (n==0) {
167         DBG_ERROR(AQBANKING_LOGDOMAIN, "No cycle given");
168         return GWEN_ERROR_INVALID;
169       }
170 
171       if (AB_TransactionLimits_GetValuesCycleMonthUsed(lim) &&
172           !AB_TransactionLimits_ValuesCycleMonthHas(lim, n) &&
173           !AB_TransactionLimits_ValuesCycleMonthHas(lim, 0)) {
174         DBG_ERROR(AQBANKING_LOGDOMAIN, "Month day \"%d\" not supported by bank", n);
175         GWEN_Gui_ProgressLog2(0,
176                               GWEN_LoggerLevel_Error,
177                               I18N("Month day \"%d\" not supported by bank"),
178                               n);
179         return GWEN_ERROR_INVALID;
180       }
181 
182       /* check execution day */
183       n=AB_Transaction_GetExecutionDay(t);
184       if (n==0) {
185         DBG_ERROR(AQBANKING_LOGDOMAIN,
186                   "No execution day given");
187         return GWEN_ERROR_INVALID;
188       }
189 
190       if (AB_TransactionLimits_GetValuesExecutionDayMonthUsed(lim) &&
191           !AB_TransactionLimits_ValuesExecutionDayMonthHas(lim, n) &&
192           !AB_TransactionLimits_ValuesExecutionDayMonthHas(lim, 0)) {
193         DBG_ERROR(AQBANKING_LOGDOMAIN, "Execution month day \"%d\" not supported by bank", n);
194         GWEN_Gui_ProgressLog2(0,
195                               GWEN_LoggerLevel_Error,
196                               I18N("Execution month day \"%d\" not supported by bank"),
197                               n);
198         return GWEN_ERROR_INVALID;
199       }
200     } /* if (AB_Transaction_GetPeriod(t)==AB_Transaction_PeriodMonthly) */
201     else if (AB_Transaction_GetPeriod(t)==AB_Transaction_PeriodWeekly) {
202       int n;
203 
204       n=AB_Transaction_GetCycle(t);
205       if (n==0) {
206         DBG_ERROR(AQBANKING_LOGDOMAIN, "No cycle given");
207         return GWEN_ERROR_INVALID;
208       }
209 
210       if (AB_TransactionLimits_GetValuesCycleWeekUsed(lim) &&
211           !AB_TransactionLimits_ValuesCycleWeekHas(lim, n) &&
212           !AB_TransactionLimits_ValuesCycleWeekHas(lim, 0)) {
213         DBG_ERROR(AQBANKING_LOGDOMAIN, "Week day \"%d\" not supported by bank", n);
214         GWEN_Gui_ProgressLog2(0,
215                               GWEN_LoggerLevel_Error,
216                               I18N("Week day \"%d\" not supported by bank"),
217                               n);
218         return GWEN_ERROR_INVALID;
219       }
220 
221       /* check execution day */
222       n=AB_Transaction_GetExecutionDay(t);
223       if (n==0) {
224         DBG_ERROR(AQBANKING_LOGDOMAIN,
225                   "No execution day given");
226         return GWEN_ERROR_INVALID;
227       }
228 
229       if (AB_TransactionLimits_GetValuesExecutionDayWeekUsed(lim) &&
230           !AB_TransactionLimits_ValuesExecutionDayWeekHas(lim, n) &&
231           !AB_TransactionLimits_ValuesExecutionDayWeekHas(lim, 0)) {
232         DBG_ERROR(AQBANKING_LOGDOMAIN, "Execution week day \"%d\" not supported by bank", n);
233         GWEN_Gui_ProgressLog2(0,
234                               GWEN_LoggerLevel_Error,
235                               I18N("Execution week day \"%d\" not supported by bank"),
236                               n);
237         return GWEN_ERROR_INVALID;
238       }
239     } /* if (AB_Transaction_GetPeriod(t)==AB_Transaction_PeriodWeekly) */
240     else {
241       DBG_ERROR(AQBANKING_LOGDOMAIN, "Unsupported period %d", AB_Transaction_GetPeriod(t));
242       return GWEN_ERROR_INVALID;
243     }
244   } /* if limits */
245 
246   return 0;
247 }
248 
249 
250 
AB_Banking_CheckTransactionAgainstLimits_ExecutionDate(const AB_TRANSACTION * t,const AB_TRANSACTION_LIMITS * lim)251 int AB_Banking_CheckTransactionAgainstLimits_ExecutionDate(const AB_TRANSACTION *t, const AB_TRANSACTION_LIMITS *lim)
252 {
253   if (lim) {
254     const GWEN_DATE *dt;
255 
256     /* check setup times */
257     dt=AB_Transaction_GetFirstDate(t);
258     if (dt) {
259       GWEN_DATE *currDate;
260       int diff;
261       int n;
262 
263       currDate=GWEN_Date_CurrentDate();
264       assert(currDate);
265       diff=GWEN_Date_Diff(dt, currDate);
266       GWEN_Date_free(currDate);
267 
268       /* check minimum setup time */
269       n=AB_TransactionLimits_GetMinValueSetupTime(lim);
270       if (n && diff<n) {
271         DBG_ERROR(AQBANKING_LOGDOMAIN, "Minimum setup time violated (given %d but required min=%d)", diff, n);
272         GWEN_Gui_ProgressLog2(0,
273                               GWEN_LoggerLevel_Error,
274                               I18N("Minimum setup time violated. "
275                                    "Dated transactions need to be at least %d days away"),
276                               n);
277         return GWEN_ERROR_INVALID;
278       }
279 
280       /* check maximum setup time */
281       n=AB_TransactionLimits_GetMaxValueSetupTime(lim);
282       if (n && diff>n) {
283         DBG_ERROR(AQBANKING_LOGDOMAIN, "Maximum setup time violated (given %d but allowed max=%d)", diff, n);
284         GWEN_Gui_ProgressLog2(0,
285                               GWEN_LoggerLevel_Error,
286                               I18N("Maximum setup time violated. "
287                                    "Dated transactions need to be at most %d days away"),
288                               n);
289         return GWEN_ERROR_INVALID;
290       }
291     }
292   }
293 
294   return 0;
295 }
296 
297 
298 
AB_Banking_CheckTransactionAgainstLimits_Date(const AB_TRANSACTION * t,const AB_TRANSACTION_LIMITS * lim)299 int AB_Banking_CheckTransactionAgainstLimits_Date(const AB_TRANSACTION *t, const AB_TRANSACTION_LIMITS *lim)
300 {
301   if (lim) {
302     const GWEN_DATE *dt;
303 
304     dt=AB_Transaction_GetDate(t);
305     if (dt) {
306       GWEN_DATE *currDate;
307       int diff;
308       int n;
309 
310       currDate=GWEN_Date_CurrentDate();
311       assert(currDate);
312       diff=GWEN_Date_Diff(dt, currDate);
313       GWEN_Date_free(currDate);
314 
315       /* check minimum setup time */
316       n=AB_TransactionLimits_GetMinValueSetupTime(lim);
317       if (n && diff<n) {
318         DBG_ERROR(AQBANKING_LOGDOMAIN, "Minimum setup time violated (given %d but required min=%d)", diff, n);
319         GWEN_Gui_ProgressLog2(0,
320                               GWEN_LoggerLevel_Error,
321                               I18N("Minimum setup time violated. "
322                                    "Dated transactions need to be at least %d days away"),
323                               n);
324         return GWEN_ERROR_INVALID;
325       }
326 
327       /* check maximum setup time */
328       n=AB_TransactionLimits_GetMaxValueSetupTime(lim);
329       if (n && diff>n) {
330         DBG_ERROR(AQBANKING_LOGDOMAIN, "Maximum setup time violated (given %d but allowed max=%d)", diff, n);
331         GWEN_Gui_ProgressLog2(0,
332                               GWEN_LoggerLevel_Error,
333                               I18N("Maximum setup time violated. "
334                                    "Dated transactions need to be at most %d days away"),
335                               n);
336         return GWEN_ERROR_INVALID;
337       }
338     }
339   }
340 
341   return 0;
342 }
343 
344 
345 
AB_Banking_CheckTransactionAgainstLimits_Sequence(const AB_TRANSACTION * t,const AB_TRANSACTION_LIMITS * lim)346 int AB_Banking_CheckTransactionAgainstLimits_Sequence(const AB_TRANSACTION *t, const AB_TRANSACTION_LIMITS *lim)
347 {
348   if (lim) {
349     const GWEN_DATE *dt;
350 
351     dt=AB_Transaction_GetDate(t);
352     if (dt) {
353       GWEN_DATE *currDate;
354       int diff;
355       int minTime=0;
356       int maxTime=0;
357 
358       currDate=GWEN_Date_CurrentDate();
359       assert(currDate);
360       diff=GWEN_Date_Diff(dt, currDate);
361       GWEN_Date_free(currDate);
362 
363       switch (AB_Transaction_GetSequence(t)) {
364       case AB_Transaction_SequenceOnce:
365         minTime=AB_TransactionLimits_GetMinValueSetupTimeOnce(lim);
366         maxTime=AB_TransactionLimits_GetMaxValueSetupTimeOnce(lim);
367         break;
368       case AB_Transaction_SequenceFirst:
369         minTime=AB_TransactionLimits_GetMinValueSetupTimeFirst(lim);
370         maxTime=AB_TransactionLimits_GetMaxValueSetupTimeFirst(lim);
371         break;
372       case AB_Transaction_SequenceFollowing:
373         minTime=AB_TransactionLimits_GetMinValueSetupTimeRecurring(lim);
374         maxTime=AB_TransactionLimits_GetMaxValueSetupTimeRecurring(lim);
375         break;
376       case AB_Transaction_SequenceFinal:
377         minTime=AB_TransactionLimits_GetMinValueSetupTimeFinal(lim);
378         maxTime=AB_TransactionLimits_GetMaxValueSetupTimeFinal(lim);
379         break;
380       case AB_Transaction_SequenceUnknown:
381         break;
382       }
383 
384       if (minTime==0)
385         minTime=AB_TransactionLimits_GetMinValueSetupTime(lim);
386       if (maxTime==0)
387         maxTime=AB_TransactionLimits_GetMaxValueSetupTime(lim);
388 
389       /* check minimum setup time */
390       if (minTime && diff<minTime) {
391         DBG_ERROR(AQBANKING_LOGDOMAIN,
392                   "Minimum setup time violated (given %d but required min=%d for sequence type=%s)",
393                   diff, minTime, AB_Transaction_Sequence_toString(AB_Transaction_GetSequence(t)));
394         GWEN_Gui_ProgressLog2(0,
395                               GWEN_LoggerLevel_Error,
396                               I18N("Minimum setup time violated. "
397                                    "Dated transactions need to be at least %d days away but %d days are requested"),
398                               minTime, dt);
399         return GWEN_ERROR_INVALID;
400       }
401 
402       /* check maximum setup time */
403       if (maxTime && diff>maxTime) {
404         DBG_ERROR(AQBANKING_LOGDOMAIN,
405                   "Maximum setup time violated (given %d but allowed max=%d for sequence type=%s)",
406                   diff, maxTime, AB_Transaction_Sequence_toString(AB_Transaction_GetSequence(t)));
407         GWEN_Gui_ProgressLog2(0,
408                               GWEN_LoggerLevel_Error,
409                               I18N("Maximum setup time violated. "
410                                    "Dated transactions need to be at most %d days away but %d days are requested"),
411                               maxTime, dt);
412         return GWEN_ERROR_INVALID;
413       }
414     }
415   }
416 
417   return 0;
418 }
419 
420 
421 
_checkStringForSepaCharset(const char * s,int restricted)422 static int _checkStringForSepaCharset(const char *s, int restricted)
423 {
424   char ascii_chars[]="'&*$%:?,-(+.)/ "; /* last is a blank! */
425   const char *ascii;
426 
427 #define RESTRICTED_CHARS_OFFSET 3
428 
429   assert(s);
430 
431   ascii=ascii_chars;
432   if (restricted)
433     ascii+=RESTRICTED_CHARS_OFFSET;
434 
435   while (*s) {
436     unsigned char c=*s++;
437 
438     if (!((c>='A' && c<='Z') ||
439           (c>='a' && c<='z') ||
440           (c>='0' && c<='9') ||
441           strchr(ascii, c)!=NULL)) {
442       char errchr[7];
443       int i = 0;
444 
445       if (c == 0xC3 && !restricted) {
446         c = *s++;
447         switch (c) {
448         case 0x84:  /* AE */
449         case 0xA4:  /* ae */
450         case 0x96:  /* OE */
451         case 0xB6:  /* oe */
452         case 0x9C:  /* UE */
453         case 0xBC:  /* ue */
454         case 0x9F:  /* ss */
455           if ((*s & 0xC0) != 0x80)
456             break;
457         /* these are no umlauts, after all, so fall through */
458 
459         default:
460           errchr[i++]=0xC3;
461           if ((c & 0xC0) == 0x80)
462             errchr[i++]=c;
463           else
464             /* UTF-8 sequence ended prematurely */
465             s--;
466           break;
467         }
468       }
469       else
470         errchr[i++] = c;
471 
472       if (i) {
473         while ((*s & 0xC0) == 0x80)
474           if (i<6)
475             errchr[i++]=*s++;
476           else {
477             i++;
478             s++;
479           }
480 
481         if (i<7 && (i>1 || !(c & 0x80))) {
482           errchr[i] = '\0';
483           DBG_ERROR(AQBANKING_LOGDOMAIN, "Invalid character in string: '%s'",
484                     errchr);
485         }
486         else {
487           DBG_ERROR(AQBANKING_LOGDOMAIN, "String not properly UTF-8 encoded");
488         }
489         return GWEN_ERROR_BAD_DATA;
490       }
491     }
492   }
493 
494   return 0;
495 }
496 
497 
498 
499 /* This function does not check full UTF8, it only checks whether the given string contains characters
500  * other than "A"-"Z", "a"-"z" and "0"-"9".
501  * We don't use isalnum here because I'm not sure how that function handles UTF-8 chars with umlauts...
502  */
_checkStringForAlNum(const char * s,int lcase)503 static int _checkStringForAlNum(const char *s, int lcase)
504 {
505   assert(s);
506   while (*s) {
507     unsigned char c=*s;
508 
509     if (!((c>='0' && c<='9') ||
510           (c>='A' && c<='Z') ||
511           (lcase && c>='a' && c<='z'))) {
512       DBG_ERROR(AQBANKING_LOGDOMAIN, "Invalid character in string: '%c'", c);
513       return GWEN_ERROR_BAD_DATA;
514     }
515     s++;
516   }
517 
518   return 0;
519 }
520 
521 
522 
AB_Banking_CheckTransactionForSepaConformity(const AB_TRANSACTION * t,int restricted)523 int AB_Banking_CheckTransactionForSepaConformity(const AB_TRANSACTION *t, int restricted)
524 {
525   if (t) {
526     const char *s;
527     int rv;
528 
529     s=AB_Transaction_GetLocalIban(t);
530     if (!(s && *s)) {
531       DBG_ERROR(AQBANKING_LOGDOMAIN, "Missing or empty local IBAN in transaction");
532       return GWEN_ERROR_BAD_DATA;
533     }
534     rv=_checkStringForAlNum(s, 1);
535     if (rv<0) {
536       DBG_ERROR(AQBANKING_LOGDOMAIN, "Invalid character in local IBAN");
537       return rv;
538     }
539 
540 #if 0
541     s=AB_Transaction_GetLocalBic(t);
542     if (!(s && *s)) {
543       DBG_ERROR(AQBANKING_LOGDOMAIN, "Missing or empty local BIC in transaction");
544       return GWEN_ERROR_BAD_DATA;
545     }
546     rv=_checkStringForAlNum(s, 0);
547     if (rv<0) {
548       DBG_ERROR(AQBANKING_LOGDOMAIN, "Invalid character in local BIC");
549       return rv;
550     }
551 #else
552     s=AB_Transaction_GetLocalBic(t);
553     if (s && *s) { /* BIC not requeired, but if it exists it must be valid */
554       rv=_checkStringForAlNum(s, 0);
555       if (rv<0) {
556         DBG_ERROR(AQBANKING_LOGDOMAIN, "Invalid character in local BIC");
557         return rv;
558       }
559     }
560 #endif
561 
562     s=AB_Transaction_GetRemoteIban(t);
563     if (!(s && *s)) {
564       DBG_ERROR(AQBANKING_LOGDOMAIN, "Missing or empty remote IBAN in transaction");
565       return GWEN_ERROR_BAD_DATA;
566     }
567     rv=_checkStringForAlNum(s, 1);
568     if (rv<0) {
569       DBG_ERROR(AQBANKING_LOGDOMAIN, "Invalid character in remote IBAN");
570       return rv;
571     }
572 
573 #if 0
574     s=AB_Transaction_GetRemoteBic(t);
575     if (!(s && *s)) {
576       if (strncmp(AB_Transaction_GetLocalIban(t), AB_Transaction_GetRemoteIban(t), 2)) {
577         DBG_ERROR(AQBANKING_LOGDOMAIN, "Missing or empty remote BIC in transaction");
578         return GWEN_ERROR_BAD_DATA;
579       }
580     }
581     else {
582       rv=_checkStringForAlNum(s, 0);
583       if (rv<0) {
584         DBG_ERROR(AQBANKING_LOGDOMAIN, "Invalid character in remote BIC");
585         return rv;
586       }
587     }
588 #else
589     s=AB_Transaction_GetRemoteBic(t);
590     if (s && *s) { /* BIC not requeired, but if it exists it must be valid */
591       rv=_checkStringForAlNum(s, 0);
592       if (rv<0) {
593         DBG_ERROR(AQBANKING_LOGDOMAIN, "Invalid character in remote BIC");
594         return rv;
595       }
596     }
597 #endif
598 
599     s=AB_Transaction_GetLocalName(t);
600     if (!(s && *s)) {
601       DBG_ERROR(AQBANKING_LOGDOMAIN, "Missing or empty local name in transaction");
602       return GWEN_ERROR_BAD_DATA;
603     }
604     rv=_checkStringForSepaCharset(s, restricted);
605     if (rv<0) {
606       DBG_ERROR(AQBANKING_LOGDOMAIN, "Invalid character in local name");
607       return rv;
608     }
609 
610     s=AB_Transaction_GetRemoteName(t);
611     if (!(s && *s)) {
612       DBG_ERROR(AQBANKING_LOGDOMAIN, "Missing or empty remote name in transaction");
613       return GWEN_ERROR_BAD_DATA;
614     }
615     rv=_checkStringForSepaCharset(s, restricted);
616     if (rv<0) {
617       DBG_ERROR(AQBANKING_LOGDOMAIN, "Invalid character in remote name");
618       return rv;
619     }
620   }
621   else {
622     DBG_ERROR(AQBANKING_LOGDOMAIN, "Missing transaction");
623     return GWEN_ERROR_BAD_DATA;
624   }
625 
626   DBG_INFO(AQBANKING_LOGDOMAIN, "Transaction conforms to restricted SEPA charset");
627   return 0;
628 }
629 
630 
631 
AB_Banking_FillTransactionFromAccountSpec(AB_TRANSACTION * t,const AB_ACCOUNT_SPEC * as)632 void AB_Banking_FillTransactionFromAccountSpec(AB_TRANSACTION *t, const AB_ACCOUNT_SPEC *as)
633 {
634   const char *s;
635 
636   assert(t);
637   assert(as);
638 
639   /* unique account id */
640   AB_Transaction_SetUniqueAccountId(t, AB_AccountSpec_GetUniqueId(as));
641 
642   /* local account */
643   s=AB_AccountSpec_GetCountry(as);
644   if (!s || !*s)
645     s="de";
646   AB_Transaction_SetLocalCountry(t, s);
647   AB_Transaction_SetRemoteCountry(t, s);
648 
649   s=AB_AccountSpec_GetBankCode(as);
650   if (s && *s)
651     AB_Transaction_SetLocalBankCode(t, s);
652 
653   s=AB_AccountSpec_GetAccountNumber(as);
654   if (s && *s)
655     AB_Transaction_SetLocalAccountNumber(t, s);
656 
657   s=AB_AccountSpec_GetOwnerName(as);
658   if (s && *s)
659     AB_Transaction_SetLocalName(t, s);
660 
661   s=AB_AccountSpec_GetBic(as);
662   if (s && *s)
663     AB_Transaction_SetLocalBic(t, s);
664 
665   s=AB_AccountSpec_GetIban(as);
666   if (s && *s)
667     AB_Transaction_SetLocalIban(t, s);
668 }
669 
670 
671 
672 
673 
674 
675 
676