1 /***************************************************************************
2 begin : Tue May 03 2005
3 copyright : (C) 2018 by Martin Preuss
4 email : martin@libchipcard.de
5
6 ***************************************************************************
7 * Please see toplevel file COPYING for license details *
8 ***************************************************************************/
9
10 #ifdef HAVE_CONFIG_H
11 # include <config.h>
12 #endif
13
14
15 #include "globals_l.h"
16 #include "aqhbci/banking/user.h"
17 #include "aqhbci/banking/provider_l.h"
18 #include "aqhbci/banking/provider_tan.h"
19
20 #include <gwenhywfar/text.h>
21
22
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <errno.h>
26
27
28
29
30 static GWEN_DB_NODE *_readCommandLine(GWEN_DB_NODE *dbArgs, int argc, char **argv);
31 static int _readFile(const char *fname, GWEN_BUFFER *dbuf);
32 static const AH_TAN_METHOD *_getSelectedTanMethod(AB_USER *u, int tanMethodId);
33
34
35
36
37
AH_Control_Test1(AB_PROVIDER * pro,GWEN_DB_NODE * dbArgs,int argc,char ** argv)38 int AH_Control_Test1(AB_PROVIDER *pro,
39 GWEN_DB_NODE *dbArgs,
40 int argc,
41 char **argv)
42 {
43 int rv;
44 GWEN_DB_NODE *db;
45 uint32_t uid;
46 AB_USER *u=NULL;
47 uint32_t tanMethodId;
48 const char *challengFile;
49 GWEN_BUFFER *challengeBuf=NULL;
50
51 db=_readCommandLine(dbArgs, argc, argv);
52 if (db==NULL) {
53 fprintf(stderr, "ERROR: Could not parse arguments\n");
54 return 1;
55 }
56
57 challengFile=GWEN_DB_GetCharValue(db, "challengeFile", 0, NULL);
58 if (!(challengFile && *challengFile)) {
59 fprintf(stderr, "ERROR: Missing challenge file\n");
60 return 1;
61 }
62
63 uid=(uint32_t) GWEN_DB_GetIntValue(db, "userId", 0, 0);
64 if (uid==0) {
65 fprintf(stderr, "ERROR: Invalid or missing unique user id\n");
66 return 1;
67 }
68
69 tanMethodId=(uint32_t) GWEN_DB_GetIntValue(db, "tanMethodId", 0, 0);
70 if (tanMethodId==0) {
71 fprintf(stderr, "ERROR: Invalid or missing tan method if\n");
72 return 1;
73 }
74
75 if (challengFile) {
76 GWEN_BUFFER *dbuf;
77
78 dbuf=GWEN_Buffer_new(0, 256, 0, 1);
79 rv=_readFile(challengFile, dbuf);
80 if (rv<0) {
81 fprintf(stderr, "ERROR: Could not read file \"%s\": %d\n", challengFile, rv);
82 GWEN_Buffer_free(dbuf);
83 return 2;
84 }
85
86 challengeBuf=GWEN_Buffer_new(0, 256, 0, 1);
87 rv=GWEN_Text_ToHexBuffer(GWEN_Buffer_GetStart(dbuf),
88 GWEN_Buffer_GetUsedBytes(dbuf),
89 challengeBuf,
90 0, 0, 0);
91 if (rv<0) {
92 fprintf(stderr, "ERROR: Could not hex encode file \"%s\": %d\n", challengFile, rv);
93 GWEN_Buffer_free(challengeBuf);
94 GWEN_Buffer_free(dbuf);
95 return 2;
96 }
97 GWEN_Buffer_free(dbuf);
98 }
99
100
101 rv=AB_Provider_HasUser(pro, uid);
102 if (rv<0) {
103 fprintf(stderr, "ERROR: User with id %lu not found\n", (unsigned long int) uid);
104 GWEN_Buffer_free(challengeBuf);
105 return 2;
106 }
107 rv=AB_Provider_GetUser(pro, uid, 1, 1, &u);
108 if (rv<0) {
109 fprintf(stderr, "ERROR: User with id %lu not found\n", (unsigned long int) uid);
110 GWEN_Buffer_free(challengeBuf);
111 return 2;
112 }
113 else {
114 const AH_TAN_METHOD *tanMethod;
115 char tanBuffer[16];
116
117 tanMethod=_getSelectedTanMethod(u, tanMethodId);
118 if (tanMethod==NULL) {
119 fprintf(stderr, "ERROR: TAN method with id %lu not found\n", (unsigned long int) tanMethodId);
120 GWEN_Buffer_free(challengeBuf);
121 return 2;
122 }
123
124 rv=AH_Provider_InputTanWithChallenge(pro,
125 u,
126 tanMethod,
127 "Could be a real challenge string but it isn't",
128 GWEN_Buffer_GetStart(challengeBuf),
129 tanBuffer,
130 1,
131 sizeof(tanBuffer)-1);
132 if (rv<0) {
133 fprintf(stderr, "ERROR: Error in TAN input (%d)\n", rv);
134 GWEN_Buffer_free(challengeBuf);
135 return 2;
136 }
137 }
138
139
140 AB_User_free(u);
141
142 return 0;
143 }
144
145
146
147
_readCommandLine(GWEN_DB_NODE * dbArgs,int argc,char ** argv)148 GWEN_DB_NODE *_readCommandLine(GWEN_DB_NODE *dbArgs, int argc, char **argv)
149 {
150 GWEN_DB_NODE *db;
151 int rv;
152 const GWEN_ARGS args[]= {
153 {
154 GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
155 GWEN_ArgsType_Int, /* type */
156 "userId", /* name */
157 0, /* minnum */
158 1, /* maxnum */
159 "u", /* short option */
160 "user", /* long option */
161 "Specify the unique user id", /* short description */
162 "Specify the unique user id" /* long description */
163 },
164 {
165 GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
166 GWEN_ArgsType_Int, /* type */
167 "tanMethodId", /* name */
168 1, /* minnum */
169 1, /* maxnum */
170 "m", /* short option */
171 NULL, /* long option */
172 "Specify the TAN method id", /* short description */
173 "Specify the TAN method id" /* long description */
174 },
175 {
176 GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */
177 GWEN_ArgsType_Char, /* type */
178 "challengeFile", /* name */
179 1, /* minnum */
180 1, /* maxnum */
181 "f", /* short option */
182 NULL, /* long option */
183 "Specify the challenge file to load", /* short */
184 "Specify the challenge file to load" /* long */
185 },
186 {
187 GWEN_ARGS_FLAGS_HELP | GWEN_ARGS_FLAGS_LAST, /* flags */
188 GWEN_ArgsType_Int, /* type */
189 "help", /* name */
190 0, /* minnum */
191 0, /* maxnum */
192 "h", /* short option */
193 "help", /* long option */
194 "Show this help screen", /* short description */
195 "Show this help screen" /* long description */
196 }
197 };
198
199 db=GWEN_DB_GetGroup(dbArgs, GWEN_DB_FLAGS_DEFAULT, "local");
200 rv=GWEN_Args_Check(argc, argv, 1,
201 0 /*GWEN_ARGS_MODE_ALLOW_FREEPARAM*/,
202 args,
203 db);
204 if (rv==GWEN_ARGS_RESULT_ERROR) {
205 fprintf(stderr, "ERROR: Could not parse arguments\n");
206 return NULL;
207 }
208 else if (rv==GWEN_ARGS_RESULT_HELP) {
209 GWEN_BUFFER *ubuf;
210
211 ubuf=GWEN_Buffer_new(0, 1024, 0, 1);
212 if (GWEN_Args_Usage(args, ubuf, GWEN_ArgsOutType_Txt)) {
213 fprintf(stderr, "ERROR: Could not create help string\n");
214 return NULL;
215 }
216 fprintf(stdout, "%s\n", GWEN_Buffer_GetStart(ubuf));
217 GWEN_Buffer_free(ubuf);
218 return NULL;
219 }
220
221 return db;
222 }
223
224
225
226
_readFile(const char * fname,GWEN_BUFFER * dbuf)227 int _readFile(const char *fname, GWEN_BUFFER *dbuf)
228 {
229 FILE *f;
230
231 f=fopen(fname, "rb");
232 if (f) {
233 while (!feof(f)) {
234 uint32_t l;
235 ssize_t s;
236 char *p;
237
238 GWEN_Buffer_AllocRoom(dbuf, 1024);
239 l=GWEN_Buffer_GetMaxUnsegmentedWrite(dbuf);
240 p=GWEN_Buffer_GetPosPointer(dbuf);
241 s=fread(p, 1, l, f);
242 if (s==0)
243 break;
244 if (s==(ssize_t)-1) {
245 DBG_ERROR(0,
246 "fread(%s): %s",
247 fname, strerror(errno));
248 fclose(f);
249 return GWEN_ERROR_IO;
250 }
251
252 GWEN_Buffer_IncrementPos(dbuf, s);
253 GWEN_Buffer_AdjustUsedBytes(dbuf);
254 }
255
256 fclose(f);
257 return 0;
258 }
259 else {
260 DBG_ERROR(0,
261 "fopen(%s): %s",
262 fname, strerror(errno));
263 return GWEN_ERROR_IO;
264 }
265 }
266
267
268
_getSelectedTanMethod(AB_USER * u,int tanMethodId)269 const AH_TAN_METHOD *_getSelectedTanMethod(AB_USER *u, int tanMethodId)
270 {
271 const AH_TAN_METHOD_LIST *tanMethodList;
272
273 tanMethodList=AH_User_GetTanMethodDescriptions(u);
274 if (tanMethodList) {
275 const AH_TAN_METHOD *tanMethod;
276
277 tanMethod=AH_TanMethod_List_First(tanMethodList);
278 while (tanMethod) {
279 int combinedVersion;
280
281 combinedVersion=AH_TanMethod_GetFunction(tanMethod)+(AH_TanMethod_GetGvVersion(tanMethod)*1000);
282 if (combinedVersion==tanMethodId)
283 return tanMethod;
284 tanMethod=AH_TanMethod_List_Next(tanMethod);
285 }
286 }
287
288 return NULL;
289 }
290
291
292
293