Project

General

Profile

Statistics
| Branch: | Tag: | Revision:

aqbanking / src / libs / plugins / backends / aqhbci / banking / provider_online.c @ 5bc3f3e7

History | View | Annotate | Download (27.5 KB)

1
/***************************************************************************
2
    begin       : Tue Jun 03 2018
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

    
11
/*
12
 * This file is included by provider.c
13
 */
14

    
15

    
16

    
17

    
18

    
19
int AH_Provider_GetAccounts(AB_PROVIDER *pro, AB_USER *u,
20
                            AB_IMEXPORTER_CONTEXT *ctx,
21
                            int withProgress, int nounmount, int doLock) {
22
  AB_BANKING *ab;
23
  AH_HBCI *h;
24
  AH_JOB *job;
25
  AH_OUTBOX *ob;
26
  int rv;
27
  AH_PROVIDER *hp;
28

    
29
  assert(pro);
30
  hp=GWEN_INHERIT_GETDATA(AB_PROVIDER, AH_PROVIDER, pro);
31
  assert(hp);
32

    
33
  assert(u);
34

    
35
  ab=AB_Provider_GetBanking(pro);
36
  assert(ab);
37

    
38
  h=AH_Provider_GetHbci(pro);
39
  assert(h);
40

    
41
  job=AH_Job_UpdateBank_new(pro, u);
42
  if (!job) {
43
    DBG_ERROR(AQHBCI_LOGDOMAIN, "Job not supported, should not happen");
44
    return GWEN_ERROR_GENERIC;
45
  }
46
  AH_Job_AddSigner(job, AB_User_GetUserId(u));
47

    
48
  ob=AH_Outbox_new(pro);
49
  AH_Outbox_AddJob(ob, job);
50

    
51
  rv=AH_Outbox_Execute(ob, ctx, withProgress, 1, doLock);
52
  AH_Outbox_free(ob);
53
  if (rv) {
54
    DBG_ERROR(AQHBCI_LOGDOMAIN, "Could not execute outbox.\n");
55
    AH_Job_free(job);
56
    if (!nounmount)
57
      AB_Banking_ClearCryptTokenList(AH_HBCI_GetBankingApi(h));
58
    return rv;
59
  }
60

    
61
  if (AH_Job_HasErrors(job)) {
62
    DBG_ERROR(AQHBCI_LOGDOMAIN, "Job has errors");
63
    // TODO: show errors
64
    AH_Job_free(job);
65
    if (!nounmount)
66
      AB_Banking_ClearCryptTokenList(AH_HBCI_GetBankingApi(h));
67
    return GWEN_ERROR_GENERIC;
68
  }
69
  else {
70
    rv=AH_Job_Commit(job, doLock);
71
    if (rv) {
72
      DBG_ERROR(AQHBCI_LOGDOMAIN, "Could not commit result.\n");
73
      AH_Job_free(job);
74
      if (!nounmount)
75
        AB_Banking_ClearCryptTokenList(AH_HBCI_GetBankingApi(h));
76
      return rv;
77
    }
78
  }
79

    
80
  AH_Job_free(job);
81
  if (!nounmount)
82
    AB_Banking_ClearCryptTokenList(AH_HBCI_GetBankingApi(h));
83
  return 0;
84
}
85

    
86

    
87

    
88
int AH_Provider_GetSysId(AB_PROVIDER *pro, AB_USER *u,
89
                         AB_IMEXPORTER_CONTEXT *ctx,
90
                         int withProgress, int nounmount, int doLock) {
91
  AB_BANKING *ab;
92
  AH_HBCI *h;
93
  AH_JOB *job;
94
  int rv;
95
  AH_PROVIDER *hp;
96
  const char *s;
97
  int i;
98
  char tbuf[256];
99

    
100
  assert(pro);
101
  hp=GWEN_INHERIT_GETDATA(AB_PROVIDER, AH_PROVIDER, pro);
102
  assert(hp);
103

    
104
  assert(u);
105

    
106
  ab=AB_Provider_GetBanking(pro);
107
  assert(ab);
108

    
109
  h=AH_Provider_GetHbci(pro);
110
  assert(h);
111

    
112
  job=0;
113
  rv=0;
114
  for (i=0; ; i++) {
115
    AH_OUTBOX *ob;
116

    
117
    job=AH_Job_GetSysId_new(pro, u);
118
    if (!job) {
119
      DBG_ERROR(AQHBCI_LOGDOMAIN, "Job not supported, should not happen");
120
      return GWEN_ERROR_GENERIC;
121
    }
122
    AH_Job_AddSigner(job, AB_User_GetUserId(u));
123

    
124
    ob=AH_Outbox_new(pro);
125
    AH_Outbox_AddJob(ob, job);
126

    
127
    rv=AH_Outbox_Execute(ob, ctx, withProgress, 1, doLock);
128
    AH_Outbox_free(ob);
129
    if (rv) {
130
      DBG_ERROR(AQHBCI_LOGDOMAIN, "Could not execute outbox.\n");
131
      AH_Job_free(job);
132
      if (!nounmount)
133
        AB_Banking_ClearCryptTokenList(AH_HBCI_GetBankingApi(h));
134
      return rv;
135
    }
136

    
137
    /* check whether we received a sysid */
138
    s=AH_Job_GetSysId_GetSysId(job);
139
    if (s && *s) {
140
      /* we did, commit the job and break loop */
141
      rv=AH_Job_Commit(job, doLock);
142
      if (rv<0) {
143
        DBG_ERROR(AQHBCI_LOGDOMAIN, "Could not commit result.\n");
144
        AH_Job_free(job);
145
        if (!nounmount)
146
          AB_Banking_ClearCryptTokenList(AH_HBCI_GetBankingApi(h));
147
        return rv;
148
      }
149
      break;
150
    }
151

    
152
    if (AH_Job_HasItanResult(job)) {
153
      GWEN_Gui_ProgressLog(0,
154
                           GWEN_LoggerLevel_Notice,
155
                           I18N("Adjusting to iTAN modes of the server"));
156
      rv=AH_Job_Commit(job, doLock);
157
      if (rv) {
158
        DBG_ERROR(AQHBCI_LOGDOMAIN, "Could not commit result.\n");
159
        AH_Job_free(job);
160
        if (!nounmount)
161
          AB_Banking_ClearCryptTokenList(AH_HBCI_GetBankingApi(h));
162
        return rv;
163
      }
164

    
165
#if 0
166
      /* save user in order to get the info written to config database for
167
       * inspection while debugging
168
       */
169
      rv=AB_Banking_SaveUser(ab, u);
170
      if (rv<0) {
171
        DBG_ERROR(AQHBCI_LOGDOMAIN, "Error saving user (%d)", rv);
172
        AH_Outbox_free(ob);
173
        if (!nounmount)
174
          AB_Banking_ClearCryptTokenList(AH_HBCI_GetBankingApi(h));
175
        return rv;
176
      }
177
#endif
178

    
179
      rv=GWEN_Gui_ProgressLog(0,
180
                              GWEN_LoggerLevel_Notice,
181
                              I18N("Retrying to get system id."));
182
      if (rv) {
183
        DBG_ERROR(AQHBCI_LOGDOMAIN, "Error in progress log, maybe user aborted?");
184
        AH_Job_free(job);
185
        if (!nounmount)
186
          AB_Banking_ClearCryptTokenList(AH_HBCI_GetBankingApi(h));
187
        return rv;
188
      }
189
    }
190
    else {
191
      DBG_ERROR(AQHBCI_LOGDOMAIN, "Job has no system id and no iTAN results");
192
      // TODO: show errors
193
      AH_Job_free(job);
194
      if (!nounmount)
195
        AB_Banking_ClearCryptTokenList(AH_HBCI_GetBankingApi(h));
196
      return GWEN_ERROR_GENERIC;
197
    }
198

    
199
    AH_Job_free(job);
200
    if (i>1) {
201
      DBG_ERROR(AQHBCI_LOGDOMAIN, "Tried too often, giving up");
202
      GWEN_Gui_ProgressLog(0,
203
                           GWEN_LoggerLevel_Error,
204
                           I18N("Could not get system id after multiple trials"));
205
      if (!nounmount)
206
        AB_Banking_ClearCryptTokenList(AH_HBCI_GetBankingApi(h));
207
      return GWEN_ERROR_GENERIC;
208
    }
209
  } /* for */
210

    
211
  /* lock user */
212
  if (doLock) {
213
    rv=AB_Provider_BeginExclUseUser(pro, u);
214
    if (rv) {
215
      DBG_ERROR(AQHBCI_LOGDOMAIN, "Could not lock user (%d)\n", rv);
216
      AH_Job_free(job);
217
      if (!nounmount)
218
        AB_Banking_ClearCryptTokenList(AH_HBCI_GetBankingApi(h));
219
      return rv;
220
    }
221
  }
222

    
223
  s=AH_Job_GetSysId_GetSysId(job);
224
  if (!s) {
225
    DBG_ERROR(AQHBCI_LOGDOMAIN, "No system id");
226
    if (doLock)
227
      AB_Provider_EndExclUseUser(pro, u, 1);
228
    AH_Job_free(job);
229
    if (!nounmount)
230
      AB_Banking_ClearCryptTokenList(AH_HBCI_GetBankingApi(h));
231
    return GWEN_ERROR_NO_DATA;
232
  }
233

    
234
  AH_User_SetSystemId(u, s);
235
  AH_Job_free(job);
236

    
237
  /* unlock user */
238
  if (doLock) {
239
    rv=AB_Provider_EndExclUseUser(pro, u, 0);
240
    if (rv<0) {
241
      DBG_INFO(AQHBCI_LOGDOMAIN,
242
               "Could not unlock customer [%s] (%d)",
243
               AB_User_GetCustomerId(u), rv);
244
      snprintf(tbuf, sizeof(tbuf)-1,
245
               I18N("Could not unlock user %s (%d)"),
246
               AB_User_GetUserId(u), rv);
247
      tbuf[sizeof(tbuf)-1]=0;
248
      GWEN_Gui_ProgressLog(0,
249
                           GWEN_LoggerLevel_Error,
250
                           tbuf);
251
      AB_Provider_EndExclUseUser(pro, u, 1);
252
      if (!nounmount)
253
        AB_Banking_ClearCryptTokenList(AH_HBCI_GetBankingApi(h));
254
      return rv;
255
    }
256
  }
257

    
258
  if (!nounmount)
259
    AB_Banking_ClearCryptTokenList(AH_HBCI_GetBankingApi(h));
260

    
261
  return 0;
262
}
263

    
264

    
265

    
266
int AH_Provider_GetServerKeys(AB_PROVIDER *pro, AB_USER *u,
267
                              AB_IMEXPORTER_CONTEXT *ctx,
268
                              int withProgress, int nounmount, int doLock) {
269
  AB_BANKING *ab;
270
  AH_HBCI *h;
271
  AH_JOB *job;
272
  AH_OUTBOX *ob;
273
  int rv;
274
  AH_PROVIDER *hp;
275
  GWEN_CRYPT_TOKEN *ct;
276
  const GWEN_CRYPT_TOKEN_CONTEXT *cctx;
277
  const char *s;
278

    
279
  assert(pro);
280
  hp=GWEN_INHERIT_GETDATA(AB_PROVIDER, AH_PROVIDER, pro);
281
  assert(hp);
282

    
283
  assert(u);
284

    
285
  ab=AB_Provider_GetBanking(pro);
286
  assert(ab);
287

    
288
  h=AH_Provider_GetHbci(pro);
289
  assert(h);
290

    
291
  job=AH_Job_GetKeys_new(pro, u);
292
  if (!job) {
293
    DBG_ERROR(AQHBCI_LOGDOMAIN, "Job not supported, should not happen");
294
    return GWEN_ERROR_GENERIC;
295
  }
296

    
297
  ob=AH_Outbox_new(pro);
298
  AH_Outbox_AddJob(ob, job);
299

    
300
  rv=AH_Outbox_Execute(ob, ctx, withProgress, 1, doLock);
301

    
302
  AH_Outbox_free(ob);
303
  if (rv) {
304
    GWEN_Gui_ProgressLog(0,
305
                         GWEN_LoggerLevel_Error,
306
                         I18N("Could not execute outbox."));
307
    AH_Job_free(job);
308
    if (!nounmount)
309
      AB_Banking_ClearCryptTokenList(AH_HBCI_GetBankingApi(h));
310
    return rv;
311
  }
312

    
313
  if (AH_Job_GetKeys_GetCryptKeyInfo(job)==NULL) {
314
    DBG_ERROR(AQHBCI_LOGDOMAIN, "No crypt key received");
315
    GWEN_Gui_ProgressLog(0,
316
                         GWEN_LoggerLevel_Error,
317
                         I18N("No crypt key received."));
318
    AH_Job_free(job);
319
    if (!nounmount)
320
      AB_Banking_ClearCryptTokenList(AH_HBCI_GetBankingApi(h));
321
    return GWEN_ERROR_GENERIC;
322
  }
323
  else {
324
    rv=AH_Job_Commit(job, doLock);
325
    if (rv) {
326
      DBG_ERROR(AQHBCI_LOGDOMAIN, "Could not commit result.\n");
327
      GWEN_Gui_ProgressLog(0,
328
                           GWEN_LoggerLevel_Error,
329
                           I18N("Could not commit result"));
330
      AH_Job_free(job);
331
      if (!nounmount)
332
        AB_Banking_ClearCryptTokenList(AH_HBCI_GetBankingApi(h));
333
      return rv;
334
    }
335
  }
336

    
337
  if (AH_Job_GetKeys_GetSignKeyInfo(job)==0) {
338
    GWEN_Gui_ProgressLog(0,
339
                         GWEN_LoggerLevel_Notice,
340
                         I18N("Bank does not use a sign key."));
341
  }
342

    
343
  /* lock user */
344
  if (doLock) {
345
    rv=AB_Provider_BeginExclUseUser(pro, u);
346
    if (rv) {
347
      DBG_ERROR(AQHBCI_LOGDOMAIN, "Could not lock user (%d)\n", rv);
348
      AH_Job_free(job);
349
      if (!nounmount)
350
        AB_Banking_ClearCryptTokenList(AH_HBCI_GetBankingApi(h));
351
      return rv;
352
    }
353
  }
354

    
355
  s=AH_User_GetPeerId(u);
356
  if (!s || !*s) {
357
    s=AH_Job_GetKeys_GetPeerId(job);
358
    if (s && *s) {
359
      char tbuf[256];
360

    
361
      snprintf(tbuf, sizeof(tbuf)-1, I18N("Setting peer ID to \"%s\")"), s);
362
      tbuf[sizeof(tbuf)-1]=0;
363
      GWEN_Gui_ProgressLog(0,
364
                           GWEN_LoggerLevel_Notice,
365
                           tbuf);
366
      AH_User_SetPeerId(u, s);
367
    }
368
  }
369

    
370
  /* get crypt token */
371
  rv=AB_Banking_GetCryptToken(AH_HBCI_GetBankingApi(h),
372
                              AH_User_GetTokenType(u),
373
                              AH_User_GetTokenName(u),
374
                              &ct);
375
  if (rv) {
376
    DBG_ERROR(AQHBCI_LOGDOMAIN, "Could not get crypt token (%d)", rv);
377
    GWEN_Gui_ProgressLog(0,
378
                         GWEN_LoggerLevel_Error,
379
                         I18N("Error getting crypt token"));
380
    if (doLock)
381
      AB_Provider_EndExclUseUser(pro, u, 0);
382
    AH_Job_free(job);
383
    if (!nounmount)
384
      AB_Banking_ClearCryptTokenList(AH_HBCI_GetBankingApi(h));
385
    return rv;
386
  }
387

    
388
  /* open crypt token */
389
  rv=GWEN_Crypt_Token_Open(ct, 1, 0);
390
  if (rv) {
391
    DBG_ERROR(AQHBCI_LOGDOMAIN, "Could not open crypt token (%d)", rv);
392
    GWEN_Gui_ProgressLog(0,
393
                         GWEN_LoggerLevel_Error,
394
                         I18N("Error opening crypt token"));
395
    if (doLock)
396
      AB_Provider_EndExclUseUser(pro, u, 0);
397
    AH_Job_free(job);
398
    if (!nounmount)
399
      AB_Banking_ClearCryptTokenList(AH_HBCI_GetBankingApi(h));
400
    return rv;
401
  }
402

    
403
  /* get context */
404
  cctx=GWEN_Crypt_Token_GetContext(ct, AH_User_GetTokenContextId(u), 0);
405
  if (!cctx) {
406
    DBG_ERROR(AQHBCI_LOGDOMAIN, "User context not found on crypt token");
407
    GWEN_Gui_ProgressLog(0,
408
                         GWEN_LoggerLevel_Error,
409
                         I18N("User context not found on crypt token"));
410
    if (doLock)
411
      AB_Provider_EndExclUseUser(pro, u, 0);
412
    AH_Job_free(job);
413
    if (!nounmount)
414
      AB_Banking_ClearCryptTokenList(AH_HBCI_GetBankingApi(h));
415
    return GWEN_ERROR_NOT_FOUND;
416
  }
417
  else {
418
    GWEN_CRYPT_TOKEN_KEYINFO *ki;
419
    uint32_t kid;
420

    
421
    /* store sign key (if any) */
422
    kid=GWEN_Crypt_Token_Context_GetVerifyKeyId(cctx);
423
    ki=AH_Job_GetKeys_GetSignKeyInfo(job);
424
    if (kid && ki) {
425
      rv=GWEN_Crypt_Token_SetKeyInfo(ct,
426
                                     kid,
427
                                     ki,
428
                                     0);
429
      if (rv) {
430
        DBG_ERROR(AQHBCI_LOGDOMAIN, "Could not save key info (%d)", rv);
431
        GWEN_Gui_ProgressLog(0,
432
                             GWEN_LoggerLevel_Error,
433
                             I18N("Error saving sign key"));
434
        if (doLock)
435
          AB_Provider_EndExclUseUser(pro, u, 0);
436
        AH_Job_free(job);
437
        if (!nounmount)
438
          AB_Banking_ClearCryptTokenList(AH_HBCI_GetBankingApi(h));
439
        return rv;
440
      }
441
      DBG_INFO(AQHBCI_LOGDOMAIN, "Sign key saved");
442
    }
443

    
444
    /* store crypt key */
445
    kid=GWEN_Crypt_Token_Context_GetEncipherKeyId(cctx);
446
    ki=AH_Job_GetKeys_GetCryptKeyInfo(job);
447
    if (kid && ki) {
448
      rv=GWEN_Crypt_Token_SetKeyInfo(ct,
449
                                     kid,
450
                                     ki,
451
                                     0);
452
      if (rv) {
453
        DBG_ERROR(AQHBCI_LOGDOMAIN, "Could not save key info (%d)", rv);
454
        GWEN_Gui_ProgressLog(0,
455
                             GWEN_LoggerLevel_Error,
456
                             I18N("Error saving crypt key"));
457
        if (doLock)
458
          AB_Provider_EndExclUseUser(pro, u, 0);
459
        AH_Job_free(job);
460
        if (!nounmount)
461
          AB_Banking_ClearCryptTokenList(AH_HBCI_GetBankingApi(h));
462
        return rv;
463
      }
464
      DBG_INFO(AQHBCI_LOGDOMAIN, "Crypt key saved");
465
    }
466

    
467
    /* store auth key (if any) */
468
    kid=GWEN_Crypt_Token_Context_GetAuthVerifyKeyId(cctx);
469
    ki=AH_Job_GetKeys_GetAuthKeyInfo(job);
470
    if (kid && ki) {
471
      rv=GWEN_Crypt_Token_SetKeyInfo(ct,
472
                                     kid,
473
                                     ki,
474
                                     0);
475
      if (rv) {
476
        DBG_ERROR(AQHBCI_LOGDOMAIN, "Could not save key info (%d)", rv);
477
        GWEN_Gui_ProgressLog(0,
478
                             GWEN_LoggerLevel_Error,
479
                             I18N("Error saving auth key"));
480
        if (doLock)
481
          AB_Provider_EndExclUseUser(pro, u, 0);
482
        AH_Job_free(job);
483
        if (!nounmount)
484
          AB_Banking_ClearCryptTokenList(AH_HBCI_GetBankingApi(h));
485
        return rv;
486
      }
487
      DBG_INFO(AQHBCI_LOGDOMAIN, "Auth key saved");
488
    }
489
  }
490

    
491
  AH_Job_free(job);
492
  GWEN_Gui_ProgressLog(0,
493
                       GWEN_LoggerLevel_Notice,
494
                       I18N("Keys saved."));
495

    
496
  /* unlock user */
497
  if (doLock) {
498
    rv=AB_Provider_EndExclUseUser(pro, u, 0);
499
    if (rv) {
500
      DBG_ERROR(AQHBCI_LOGDOMAIN, "Could not unlock user (%d)\n", rv);
501
      if (!nounmount)
502
        AB_Banking_ClearCryptTokenList(AH_HBCI_GetBankingApi(h));
503
      return rv;
504
    }
505
  }
506

    
507
  if (!nounmount)
508
    AB_Banking_ClearCryptTokenList(AH_HBCI_GetBankingApi(h));
509

    
510
  return 0;
511
}
512

    
513

    
514

    
515
int AH_Provider_SendUserKeys2(AB_PROVIDER *pro, AB_USER *u,
516
                              AB_IMEXPORTER_CONTEXT *ctx,
517
                              int withAuthKey,
518
                              int withProgress, int nounmount, int doLock) {
519
  AB_BANKING *ab;
520
  AH_HBCI *h;
521
  AH_JOB *job;
522
  AH_OUTBOX *ob;
523
  int rv;
524
  AH_PROVIDER *hp;
525
  GWEN_CRYPT_TOKEN *ct;
526
  uint32_t kid;
527
  const GWEN_CRYPT_TOKEN_CONTEXT *cctx;
528
  const GWEN_CRYPT_TOKEN_KEYINFO *signKeyInfo=NULL;
529
  const GWEN_CRYPT_TOKEN_KEYINFO *cryptKeyInfo=NULL;
530
  const GWEN_CRYPT_TOKEN_KEYINFO *authKeyInfo=NULL;
531
  int mounted=0;
532

    
533
  assert(pro);
534
  hp=GWEN_INHERIT_GETDATA(AB_PROVIDER, AH_PROVIDER, pro);
535
  assert(hp);
536

    
537
  assert(u);
538

    
539
  ab=AB_Provider_GetBanking(pro);
540
  assert(ab);
541

    
542
  h=AH_Provider_GetHbci(pro);
543
  assert(h);
544

    
545
  /* get crypt token */
546
  rv=AB_Banking_GetCryptToken(AH_HBCI_GetBankingApi(h),
547
                              AH_User_GetTokenType(u),
548
                              AH_User_GetTokenName(u),
549
                              &ct);
550
  if (rv) {
551
    DBG_ERROR(AQHBCI_LOGDOMAIN, "Could not get crypt token (%d)", rv);
552
    GWEN_Gui_ProgressLog(0,
553
                         GWEN_LoggerLevel_Error,
554
                         I18N("Error getting crypt token"));
555
    if (!nounmount)
556
      AB_Banking_ClearCryptTokenList(AH_HBCI_GetBankingApi(h));
557
    return rv;
558
  }
559

    
560
  /* open crypt token */
561
  rv=GWEN_Crypt_Token_Open(ct, 1, 0);
562
  if (rv) {
563
    DBG_ERROR(AQHBCI_LOGDOMAIN, "Could not open crypt token (%d)", rv);
564
    GWEN_Gui_ProgressLog(0,
565
                         GWEN_LoggerLevel_Error,
566
                         I18N("Error opening crypt token"));
567
    if (!nounmount)
568
      AB_Banking_ClearCryptTokenList(AH_HBCI_GetBankingApi(h));
569
    return rv;
570
  }
571

    
572
  /* get context */
573
  cctx=GWEN_Crypt_Token_GetContext(ct, AH_User_GetTokenContextId(u), 0);
574
  if (!cctx) {
575
    DBG_ERROR(AQHBCI_LOGDOMAIN, "User context not found on crypt token");
576
    GWEN_Gui_ProgressLog(0,
577
                         GWEN_LoggerLevel_Error,
578
                         I18N("User context not found on crypt token"));
579
    if (!nounmount)
580
      AB_Banking_ClearCryptTokenList(AH_HBCI_GetBankingApi(h));
581
    return GWEN_ERROR_NOT_FOUND;
582
  }
583

    
584
  /* get sign key info */
585
  kid=GWEN_Crypt_Token_Context_GetSignKeyId(cctx);
586
  if (kid) {
587
    signKeyInfo=GWEN_Crypt_Token_GetKeyInfo(ct, kid,
588
                                            GWEN_CRYPT_TOKEN_KEYFLAGS_HASMODULUS |
589
                                            GWEN_CRYPT_TOKEN_KEYFLAGS_HASEXPONENT |
590
                                            GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYVERSION |
591
                                            GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYNUMBER,
592
                                            0);
593
    if (signKeyInfo==NULL) {
594
      DBG_ERROR(AQHBCI_LOGDOMAIN, "Sign key info not found on crypt token");
595
      GWEN_Gui_ProgressLog(0,
596
                           GWEN_LoggerLevel_Error,
597
                           I18N("Sign key info not found on crypt token"));
598
      if (!nounmount)
599
        AB_Banking_ClearCryptTokenList(AH_HBCI_GetBankingApi(h));
600
      return GWEN_ERROR_NOT_FOUND;
601
    }
602
  }
603
  else {
604
    DBG_INFO(AQHBCI_LOGDOMAIN, "No sign key id");
605
  }
606

    
607
  /* get crypt key info */
608
  kid=GWEN_Crypt_Token_Context_GetDecipherKeyId(cctx);
609
  if (kid) {
610
    cryptKeyInfo=GWEN_Crypt_Token_GetKeyInfo(ct, kid,
611
                                             GWEN_CRYPT_TOKEN_KEYFLAGS_HASMODULUS |
612
                                             GWEN_CRYPT_TOKEN_KEYFLAGS_HASEXPONENT |
613
                                             GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYVERSION |
614
                                             GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYNUMBER,
615
                                             0);
616
    if (cryptKeyInfo==NULL) {
617
      DBG_ERROR(AQHBCI_LOGDOMAIN, "Crypt key info not found on crypt token");
618
      GWEN_Gui_ProgressLog(0,
619
                           GWEN_LoggerLevel_Error,
620
                           I18N("Crypt key info not found on crypt token"));
621
      if (!nounmount)
622
        AB_Banking_ClearCryptTokenList(AH_HBCI_GetBankingApi(h));
623
      return GWEN_ERROR_NOT_FOUND;
624
    }
625
  }
626
  else {
627
    DBG_INFO(AQHBCI_LOGDOMAIN, "No decipher key id");
628
  }
629

    
630
  /* get auth sign key info */
631
  if (withAuthKey) {
632
    kid=GWEN_Crypt_Token_Context_GetAuthSignKeyId(cctx);
633
    if (kid) {
634
      authKeyInfo=GWEN_Crypt_Token_GetKeyInfo(ct, kid,
635
                                              GWEN_CRYPT_TOKEN_KEYFLAGS_HASMODULUS |
636
                                              GWEN_CRYPT_TOKEN_KEYFLAGS_HASEXPONENT |
637
                                              GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYVERSION |
638
                                              GWEN_CRYPT_TOKEN_KEYFLAGS_HASKEYNUMBER,
639
                                              0);
640
      if (authKeyInfo==NULL) {
641
        DBG_ERROR(AQHBCI_LOGDOMAIN, "Auth key info not found on crypt token");
642
        GWEN_Gui_ProgressLog(0,
643
                             GWEN_LoggerLevel_Error,
644
                             I18N("Auth key info not found on crypt token"));
645
        if (!nounmount)
646
          AB_Banking_ClearCryptTokenList(AH_HBCI_GetBankingApi(h));
647
        return GWEN_ERROR_NOT_FOUND;
648
      }
649
    }
650
    else {
651
      DBG_INFO(AQHBCI_LOGDOMAIN, "No auth key id");
652
    }
653
  }
654

    
655
  /* create job */
656
  job=AH_Job_SendKeys_new(pro, u, cryptKeyInfo, signKeyInfo, authKeyInfo);
657
  if (!job) {
658
    DBG_ERROR(AQHBCI_LOGDOMAIN, "Job not supported, should not happen");
659
    GWEN_Gui_ProgressLog(0,
660
                         GWEN_LoggerLevel_Error,
661
                         I18N("Job not supported, should not happen"));
662
    if (!nounmount && mounted)
663
      AB_Banking_ClearCryptTokenList(AH_HBCI_GetBankingApi(h));
664
    return GWEN_ERROR_GENERIC;
665
  }
666
  AH_Job_AddSigner(job, AB_User_GetUserId(u));
667

    
668
  /* enqueue job */
669
  ob=AH_Outbox_new(pro);
670
  AH_Outbox_AddJob(ob, job);
671

    
672
  /* execute queue */
673
  rv=AH_Outbox_Execute(ob, ctx, withProgress, 0, doLock);
674
  AH_Outbox_free(ob);
675
  if (rv) {
676
    GWEN_Gui_ProgressLog(0,
677
                         GWEN_LoggerLevel_Error,
678
                         I18N("Could not execute outbox."));
679
    AH_Job_free(job);
680
    if (!nounmount && mounted)
681
      AB_Banking_ClearCryptTokenList(AH_HBCI_GetBankingApi(h));
682
    return rv;
683
  }
684

    
685
  /* check result */
686
  if (AH_Job_HasErrors(job)) {
687
    DBG_ERROR(AQHBCI_LOGDOMAIN, "Job has errors");
688
    GWEN_Gui_ProgressLog(0,
689
                         GWEN_LoggerLevel_Error,
690
                         I18N("Job contains errors."));
691
    AH_Job_free(job);
692
    if (!nounmount && mounted)
693
      AB_Banking_ClearCryptTokenList(AH_HBCI_GetBankingApi(h));
694
    return GWEN_ERROR_GENERIC;
695
  }
696
  else {
697
    rv=AH_Job_Commit(job, doLock);
698
    if (rv) {
699
      DBG_ERROR(AQHBCI_LOGDOMAIN, "Could not commit result.\n");
700
      GWEN_Gui_ProgressLog(0,
701
                           GWEN_LoggerLevel_Error,
702
                           I18N("Could not commit result"));
703
      AH_Job_free(job);
704
      if (!nounmount && mounted)
705
        AB_Banking_ClearCryptTokenList(AH_HBCI_GetBankingApi(h));
706
      return rv;
707
    }
708
  }
709

    
710
  GWEN_Gui_ProgressLog(0,
711
                       GWEN_LoggerLevel_Notice,
712
                       I18N("Keys sent"));
713

    
714
  AH_Job_free(job);
715
  if (!nounmount && mounted)
716
    AB_Banking_ClearCryptTokenList(AH_HBCI_GetBankingApi(h));
717

    
718
  return 0;
719
}
720

    
721

    
722

    
723
int AH_Provider_SendUserKeys(AB_PROVIDER *pro, AB_USER *u,
724
                             AB_IMEXPORTER_CONTEXT *ctx,
725
                             int withProgress, int nounmount, int doLock) {
726
  return AH_Provider_SendUserKeys2(pro, u, ctx, 0, withProgress, nounmount, doLock);
727
}
728

    
729

    
730

    
731
int AH_Provider_GetCert(AB_PROVIDER *pro,
732
                        AB_USER *u,
733
                        int withProgress, int nounmount, int doLock) {
734
  AB_BANKING *ab;
735
  AH_HBCI *h;
736
  int rv;
737
  AH_PROVIDER *hp;
738
  AH_DIALOG *dialog;
739
  uint32_t pid;
740

    
741
  assert(pro);
742
  hp=GWEN_INHERIT_GETDATA(AB_PROVIDER, AH_PROVIDER, pro);
743
  assert(hp);
744

    
745
  assert(u);
746

    
747
  ab=AB_Provider_GetBanking(pro);
748
  assert(ab);
749

    
750
  h=AH_Provider_GetHbci(pro);
751
  assert(h);
752

    
753
  pid=GWEN_Gui_ProgressStart(GWEN_GUI_PROGRESS_ALLOW_EMBED |
754
                             GWEN_GUI_PROGRESS_SHOW_PROGRESS |
755
                             GWEN_GUI_PROGRESS_SHOW_ABORT,
756
                             I18N("Getting Certificate"),
757
                             I18N("We are now asking the server for its "
758
                                  "SSL certificate"),
759
                             GWEN_GUI_PROGRESS_NONE,
760
                             0);
761
  /* first try */
762
  dialog=AH_Dialog_new(u, pro);
763
  assert(dialog);
764
  rv=AH_Dialog_TestServer_Https(dialog);
765
  AH_Dialog_Disconnect(dialog);
766
  AH_Dialog_free(dialog);
767

    
768
  if (rv) {
769
    DBG_ERROR(AQHBCI_LOGDOMAIN, "Could not connect to server (%d)", rv);
770
    GWEN_Gui_ProgressLog(pid,
771
                         GWEN_LoggerLevel_Error,
772
                         I18N("Could not connect to server"));
773
    GWEN_Gui_ProgressEnd(pid);
774
    return rv;
775
  }
776

    
777
  GWEN_Gui_ProgressLog(pid,
778
                       GWEN_LoggerLevel_Error,
779
                       I18N("Got certificate"));
780
  GWEN_Gui_ProgressEnd(pid);
781

    
782
  return 0;
783
}
784

    
785

    
786

    
787
int AH_Provider_GetItanModes(AB_PROVIDER *pro, AB_USER *u,
788
                             AB_IMEXPORTER_CONTEXT *ctx,
789
                             int withProgress, int nounmount, int doLock) {
790
  AB_BANKING *ab;
791
  AH_HBCI *h;
792
  AH_JOB *job;
793
  AH_OUTBOX *ob;
794
  int rv;
795
  AH_PROVIDER *hp;
796
  const int *tm;
797
  char tbuf[256];
798

    
799
  assert(pro);
800
  hp=GWEN_INHERIT_GETDATA(AB_PROVIDER, AH_PROVIDER, pro);
801
  assert(hp);
802

    
803
  assert(u);
804

    
805
  ab=AB_Provider_GetBanking(pro);
806
  assert(ab);
807

    
808
  h=AH_Provider_GetHbci(pro);
809
  assert(h);
810

    
811
  if (doLock) {
812
    rv=AB_Provider_BeginExclUseUser(pro, u);
813
    if (rv<0) {
814
      DBG_INFO(AQHBCI_LOGDOMAIN,
815
               "Could not lock customer [%s] (%d)",
816
               AB_User_GetCustomerId(u), rv);
817
      snprintf(tbuf, sizeof(tbuf)-1,
818
               I18N("Could not lock user %s (%d)"),
819
               AB_User_GetUserId(u), rv);
820
      tbuf[sizeof(tbuf)-1]=0;
821
      GWEN_Gui_ProgressLog(0,
822
                           GWEN_LoggerLevel_Error,
823
                           tbuf);
824
      return rv;
825
    }
826
  }
827

    
828
  job=AH_Job_GetItanModes_new(pro, u);
829
  if (!job) {
830
    DBG_ERROR(AQHBCI_LOGDOMAIN, "Job not supported, should not happen");
831
    if (doLock)
832
      AB_Provider_EndExclUseUser(pro, u, 1);
833
    return GWEN_ERROR_GENERIC;
834
  }
835
  AH_Job_AddSigner(job, AB_User_GetUserId(u));
836

    
837
  ob=AH_Outbox_new(pro);
838
  AH_Outbox_AddJob(ob, job);
839
  rv=AH_Outbox_Execute(ob, ctx, withProgress, 1, 0);
840
  AH_Outbox_free(ob);
841
  if (rv) {
842
    DBG_ERROR(AQHBCI_LOGDOMAIN, "Could not execute outbox.");
843
    if (doLock)
844
      AB_Provider_EndExclUseUser(pro, u, 1);
845
    AH_Job_free(job);
846
    if (!nounmount)
847
      AB_Banking_ClearCryptTokenList(AH_HBCI_GetBankingApi(h));
848
    return rv;
849
  }
850

    
851
  tm=AH_Job_GetItanModes_GetModes(job);
852
  if (tm[0]==-1) {
853
    DBG_ERROR(AQHBCI_LOGDOMAIN, "No iTAN modes reported");
854
    GWEN_Gui_ProgressLog(0,
855
                         GWEN_LoggerLevel_Error,
856
                         I18N("No iTAN modes reported."));
857
    if (doLock)
858
      AB_Provider_EndExclUseUser(pro, u, 1);
859
    AH_Job_free(job);
860
    if (!nounmount)
861
      AB_Banking_ClearCryptTokenList(AH_HBCI_GetBankingApi(h));
862
    return GWEN_ERROR_NO_DATA;
863
  }
864

    
865
  /* we have received tan methods, so there was a 3920 response. In this
866
   * special case we need to apply the job data, because otherwise we couldn't
867
   * fully connect to the server next time.
868
   */
869
  rv=AH_Job_Commit(job, 0);
870
  if (rv) {
871
    DBG_ERROR(AQHBCI_LOGDOMAIN, "Could not commit result.\n");
872
    GWEN_Gui_ProgressLog(0,
873
                         GWEN_LoggerLevel_Error,
874
                         I18N("Could not commit result to the system"));
875
    if (doLock)
876
      AB_Provider_EndExclUseUser(pro, u, 1);
877
    AH_Job_free(job);
878
    if (!nounmount)
879
      AB_Banking_ClearCryptTokenList(AH_HBCI_GetBankingApi(h));
880
    return rv;
881
  }
882

    
883
  if (doLock) {
884
    rv=AB_Provider_EndExclUseUser(pro, u, 0);
885
    if (rv<0) {
886
      DBG_INFO(AQHBCI_LOGDOMAIN,
887
               "Could not unlock customer [%s] (%d)",
888
               AB_User_GetCustomerId(u), rv);
889
      snprintf(tbuf, sizeof(tbuf)-1,
890
               I18N("Could not unlock user %s (%d)"),
891
               AB_User_GetUserId(u), rv);
892
      tbuf[sizeof(tbuf)-1]=0;
893
      GWEN_Gui_ProgressLog(0,
894
                           GWEN_LoggerLevel_Error,
895
                           tbuf);
896
      AB_Provider_EndExclUseUser(pro, u, 1);
897
      AH_Job_free(job);
898
      if (!nounmount)
899
        AB_Banking_ClearCryptTokenList(AH_HBCI_GetBankingApi(h));
900
      return rv;
901
    }
902
  }
903

    
904
  AH_Job_free(job);
905

    
906
  if (!nounmount)
907
    AB_Banking_ClearCryptTokenList(AH_HBCI_GetBankingApi(h));
908

    
909
  return 0;
910
}
911

    
912

    
913

    
914
int AH_Provider_ChangePin(AB_PROVIDER *pro, AB_USER *u,
915
                          AB_IMEXPORTER_CONTEXT *ctx,
916
                          int withProgress, int nounmount, int doLock) {
917
  AB_BANKING *ab;
918
  AH_HBCI *h;
919
  AH_JOB *job;
920
  AH_OUTBOX *ob;
921
  int rv;
922
  AH_PROVIDER *hp;
923
  char pwbuf[32];
924

    
925
  assert(pro);
926
  hp=GWEN_INHERIT_GETDATA(AB_PROVIDER, AH_PROVIDER, pro);
927
  assert(hp);
928

    
929
  assert(u);
930

    
931
  ab=AB_Provider_GetBanking(pro);
932
  assert(ab);
933

    
934
  h=AH_Provider_GetHbci(pro);
935
  assert(h);
936

    
937
  memset(pwbuf, 0, sizeof(pwbuf));
938
  rv=GWEN_Gui_InputBox(GWEN_GUI_INPUT_FLAGS_NUMERIC |
939
                       GWEN_GUI_INPUT_FLAGS_CONFIRM,
940
                       I18N("Enter New Banking PIN"),
941
                       I18N("Please enter a new banking PIN.\n"
942
                            "You must only enter numbers, not letters.\n"
943
                            "<html>"
944
                            "<p>"
945
                            "Please enter a new banking PIN."
946
                            "</p>"
947
                            "<p>"
948
                            "You must only enter numbers, not letters."
949
                            "</p>"
950
                            "</html>"),
951
                       pwbuf,
952
                       0, 8, 0);
953
  if (rv<0) {
954
    DBG_INFO(AQHBCI_LOGDOMAIN, "here (%d)", rv);
955
    return rv;
956
  }
957
  job=AH_Job_ChangePin_new(pro, u, pwbuf);
958
  if (!job) {
959
    DBG_ERROR(AQHBCI_LOGDOMAIN, "Job not supported, should not happen");
960
    return GWEN_ERROR_GENERIC;
961
  }
962
  AH_Job_AddSigner(job, AB_User_GetUserId(u));
963

    
964
  ob=AH_Outbox_new(pro);
965
  AH_Outbox_AddJob(ob, job);
966

    
967
  rv=AH_Outbox_Execute(ob, ctx, withProgress, nounmount, doLock);
968
  AH_Outbox_free(ob);
969
  if (rv) {
970
    DBG_ERROR(AQHBCI_LOGDOMAIN, "Could not execute outbox.\n");
971
    AH_Job_free(job);
972
    if (!nounmount)
973
      AB_Banking_ClearCryptTokenList(AH_HBCI_GetBankingApi(h));
974
    return rv;
975
  }
976

    
977
  if (AH_Job_HasErrors(job)) {
978
    DBG_ERROR(AQHBCI_LOGDOMAIN, "Job has errors");
979
    // TODO: show errors
980
    AH_Job_free(job);
981
    if (!nounmount)
982
      AB_Banking_ClearCryptTokenList(AH_HBCI_GetBankingApi(h));
983
    return GWEN_ERROR_GENERIC;
984
  }
985
  else {
986
    rv=AH_Job_Commit(job, doLock);
987
    if (rv) {
988
      DBG_ERROR(AQHBCI_LOGDOMAIN, "Could not commit result.\n");
989
      AH_Job_free(job);
990
      if (!nounmount)
991
        AB_Banking_ClearCryptTokenList(AH_HBCI_GetBankingApi(h));
992
      return rv;
993
    }
994
  }
995

    
996
  AH_Job_free(job);
997

    
998
  if (!nounmount)
999
    AB_Banking_ClearCryptTokenList(AH_HBCI_GetBankingApi(h));
1000

    
1001
  return 0;
1002
}
1003

    
1004

    
1005

    
1006
int AH_Provider_GetAccountSepaInfo(AB_PROVIDER *pro,
1007
                                   AB_ACCOUNT *a,
1008
                                   AB_IMEXPORTER_CONTEXT *ctx,
1009
                                   int withProgress, int nounmount, int doLock) {
1010
  AH_PROVIDER *hp;
1011
  AB_BANKING *ab;
1012
  AH_HBCI *h;
1013
  AH_OUTBOX *ob;
1014
  uint32_t uid;
1015
  int rv;
1016

    
1017
  assert(pro);
1018
  hp=GWEN_INHERIT_GETDATA(AB_PROVIDER, AH_PROVIDER, pro);
1019
  assert(hp);
1020

    
1021
  ab=AB_Provider_GetBanking(pro);
1022
  assert(ab);
1023

    
1024
  h=AH_Provider_GetHbci(pro);
1025
  assert(h);
1026

    
1027

    
1028
  ob=AH_Outbox_new(pro);
1029

    
1030
  uid=AB_Account_GetUserId(a);
1031
  if (uid==0) {
1032
    DBG_ERROR(AQHBCI_LOGDOMAIN, "No user for this account");
1033
  }
1034
  else {
1035
    AB_USER *u;
1036

    
1037
    rv=AB_Provider_GetUser(pro, uid, 1, 1, &u);
1038
    if (rv<0) {
1039
      DBG_ERROR(AQHBCI_LOGDOMAIN, "Unknown user for this account");
1040
    }
1041
    else {
1042
      AH_JOB *job;
1043

    
1044
      /* TODO: store user to free it later */
1045
      job=AH_Job_GetAccountSepaInfo_new(pro, u, a);
1046
      if (!job) {
1047
        DBG_WARN(AQHBCI_LOGDOMAIN, "Job not supported with this account");
1048
        AH_Outbox_free(ob);
1049
        return GWEN_ERROR_GENERIC;
1050
      }
1051
      AH_Job_AddSigner(job, AB_User_GetUserId(u));
1052
      AH_Outbox_AddJob(ob, job);
1053
      AH_Job_free(job);
1054
    }
1055
  }
1056

    
1057
  rv=AH_Outbox_Execute(ob, ctx, withProgress, nounmount, doLock);
1058
  if (rv) {
1059
    DBG_ERROR(AQHBCI_LOGDOMAIN, "Could not execute outbox.\n");
1060
    AH_Outbox_free(ob);
1061
    if (!nounmount)
1062
      AB_Banking_ClearCryptTokenList(AH_HBCI_GetBankingApi(h));
1063
    return rv;
1064
  }
1065

    
1066
  AH_Outbox_free(ob);
1067

    
1068
  if (!nounmount)
1069
    AB_Banking_ClearCryptTokenList(AH_HBCI_GetBankingApi(h));
1070

    
1071
  return 0;
1072
}
1073

    
1074

    
1075

    
1076

    
1077