int AH_Msg_VerifyRdh2(AH_MSG *hmsg, GWEN_DB_NODE *gr) { AH_HBCI *h; GWEN_LIST *sigheads; GWEN_LIST *sigtails; GWEN_DB_NODE *n; int nonSigHeads; int nSigheads; unsigned int dataBegin; char *dataStart; unsigned int dataLength; unsigned int i; AB_USER *u; GWEN_CRYPT_TOKEN *ct; const GWEN_CRYPT_TOKEN_CONTEXT *ctx; const GWEN_CRYPT_TOKEN_KEYINFO *ki; uint32_t keyId; int ksize; int rv; uint32_t gid; assert(hmsg); h=AH_Dialog_GetHbci(hmsg->dialog); assert(h); u=AH_Dialog_GetDialogOwner(hmsg->dialog); assert(u); gid=0; /* get crypt token of signer */ rv=AB_Banking_GetCryptToken(AH_HBCI_GetBankingApi(h), AH_User_GetTokenType(u), AH_User_GetTokenName(u), &ct); if (rv) { DBG_INFO(AQHBCI_LOGDOMAIN, "Could not get crypt token for user \"%s\" (%d)", AB_User_GetUserId(u), rv); return rv; } /* open CryptToken if necessary */ if (!GWEN_Crypt_Token_IsOpen(ct)) { GWEN_Crypt_Token_AddModes(ct, GWEN_CRYPT_TOKEN_MODE_DIRECT_SIGN); rv=GWEN_Crypt_Token_Open(ct, 0, gid); if (rv) { DBG_INFO(AQHBCI_LOGDOMAIN, "Could not open crypt token for user \"%s\" (%d)", AB_User_GetUserId(u), rv); return rv; } } /* get context and key info */ ctx=GWEN_Crypt_Token_GetContext(ct, AH_User_GetTokenContextId(u), gid); if (ctx==NULL) { DBG_INFO(AQHBCI_LOGDOMAIN, "Context %d not found on crypt token [%s:%s]", AH_User_GetTokenContextId(u), GWEN_Crypt_Token_GetTypeName(ct), GWEN_Crypt_Token_GetTokenName(ct)); return GWEN_ERROR_NOT_FOUND; } /* let's go */ sigheads=GWEN_List_new(); /* enumerate signature heads */ nonSigHeads=0; nSigheads=0; n=GWEN_DB_GetFirstGroup(gr); while(n) { if (strcasecmp(GWEN_DB_GroupName(n), "SigHead")==0) { /* found a signature head */ if (nonSigHeads) { DBG_ERROR(AQHBCI_LOGDOMAIN, "Found some unsigned parts at the beginning"); GWEN_List_free(sigheads); return GWEN_ERROR_BAD_DATA; } GWEN_List_PushBack(sigheads, n); nSigheads++; } else if (strcasecmp(GWEN_DB_GroupName(n), "MsgHead")!=0) { if (nSigheads) break; nonSigHeads++; } n=GWEN_DB_GetNextGroup(n); } /* while */ if (!n) { if (nSigheads) { DBG_ERROR(AQHBCI_LOGDOMAIN, "Found Signature heads but no other segments"); GWEN_List_free(sigheads); return GWEN_ERROR_BAD_DATA; } DBG_DEBUG(AQHBCI_LOGDOMAIN, "No signatures"); GWEN_List_free(sigheads); return 0; } /* only now we need the verify key */ keyId=GWEN_Crypt_Token_Context_GetVerifyKeyId(ctx); if (keyId==0) { DBG_INFO(AQHBCI_LOGDOMAIN, "No verify key id on crypt token [%s:%s]", GWEN_Crypt_Token_GetTypeName(ct), GWEN_Crypt_Token_GetTokenName(ct)); return GWEN_ERROR_NOT_FOUND; } ki=GWEN_Crypt_Token_GetKeyInfo(ct, keyId, 0xffffffff, gid); if (ki==NULL) { DBG_INFO(AQHBCI_LOGDOMAIN, "Keyinfo %04x not found on crypt token [%s:%s]", keyId, GWEN_Crypt_Token_GetTypeName(ct), GWEN_Crypt_Token_GetTokenName(ct)); /* no longer return an error, it might be ok to not have a key info * even if we do not propagate the error here the check functions will * later find out that the signature is missing */ return 0; } ksize=GWEN_Crypt_Token_KeyInfo_GetKeySize(ki); assert(ksize<=256); /* store begin of signed data */ dataBegin=GWEN_DB_GetIntValue(n, "segment/pos", 0, 0); if (!dataBegin) { DBG_ERROR(AQHBCI_LOGDOMAIN, "No position specifications in segment"); GWEN_List_free(sigheads); return GWEN_ERROR_BAD_DATA; } /* now get first signature tail */ while(n) { if (strcasecmp(GWEN_DB_GroupName(n), "SigTail")==0) { unsigned int currpos; /* found a signature tail */ currpos=GWEN_DB_GetIntValue(n, "segment/pos", 0, 0); if (!currpos || dataBegin>currpos) { DBG_ERROR(AQHBCI_LOGDOMAIN, "Bad position specification in Signature tail"); GWEN_List_free(sigheads); return GWEN_ERROR_BAD_DATA; } dataLength=currpos-dataBegin; break; } n=GWEN_DB_GetNextGroup(n); } /* while */ if (!n) { DBG_ERROR(AQHBCI_LOGDOMAIN, "No signature tail found"); GWEN_List_free(sigheads); return GWEN_ERROR_BAD_DATA; } sigtails=GWEN_List_new(); while(n) { if (strcasecmp(GWEN_DB_GroupName(n), "SigTail")!=0) break; GWEN_List_PushBack(sigtails, n); n=GWEN_DB_GetNextGroup(n); } /* while */ if (!n) { DBG_ERROR(AQHBCI_LOGDOMAIN, "Message tail expected"); GWEN_List_free(sigheads); GWEN_List_free(sigtails); return GWEN_ERROR_BAD_DATA; } if (strcasecmp(GWEN_DB_GroupName(n), "MsgTail")!=0) { DBG_ERROR(AQHBCI_LOGDOMAIN, "Unexpected segment (msg tail expected)"); GWEN_List_free(sigheads); GWEN_List_free(sigtails); return GWEN_ERROR_BAD_DATA; } n=GWEN_DB_GetNextGroup(n); if (n) { DBG_ERROR(AQHBCI_LOGDOMAIN, "Unexpected segment (end expected)"); GWEN_List_free(sigheads); GWEN_List_free(sigtails); return GWEN_ERROR_BAD_DATA; } if (GWEN_List_GetSize(sigheads)!= GWEN_List_GetSize(sigtails)) { DBG_ERROR(AQHBCI_LOGDOMAIN, "Number of signature heads (%d) does not match " "number of signature tails (%d)", GWEN_List_GetSize(sigheads), GWEN_List_GetSize(sigtails)); GWEN_List_free(sigheads); GWEN_List_free(sigtails); return GWEN_ERROR_BAD_DATA; } /* ok, now verify all signatures */ dataStart=GWEN_Buffer_GetStart(hmsg->buffer)+dataBegin; for (i=0; i< GWEN_List_GetSize(sigtails); i++) { GWEN_DB_NODE *sighead; GWEN_DB_NODE *sigtail; const uint8_t *p; uint32_t l; int rv; uint8_t hash[20]; const char *signerId; /* get signature tail */ sigtail=(GWEN_DB_NODE*)GWEN_List_GetBack(sigtails); /* get corresponding signature head */ sighead=(GWEN_DB_NODE*)GWEN_List_GetFront(sigheads); if (!sighead || !sigtail) { DBG_ERROR(AQHBCI_LOGDOMAIN, "No signature head/tail left (internal error)"); GWEN_List_free(sigheads); GWEN_List_free(sigtails); return GWEN_ERROR_INTERNAL; } GWEN_List_PopBack(sigtails); GWEN_List_PopFront(sigheads); signerId=GWEN_DB_GetCharValue(sighead, "key/userid", 0, I18N("unknown")); /* some checks */ if (strcasecmp(GWEN_DB_GetCharValue(sighead, "ctrlref", 0, ""), GWEN_DB_GetCharValue(sigtail, "ctrlref", 0, ""))!=0) { DBG_ERROR(AQHBCI_LOGDOMAIN, "Non-matching signature tail"); GWEN_List_free(sigheads); GWEN_List_free(sigtails); return GWEN_ERROR_BAD_DATA; } /* hash signature head and data */ if (1) { GWEN_MDIGEST *md; /* hash sighead + data */ p=(const uint8_t*)GWEN_Buffer_GetStart(hmsg->buffer); p+=GWEN_DB_GetIntValue(sighead, "segment/pos", 0, 0); l=GWEN_DB_GetIntValue(sighead, "segment/length", 0, 0); md=GWEN_MDigest_Rmd160_new(); rv=GWEN_MDigest_Begin(md); if (rv==0) /* digest signature head */ rv=GWEN_MDigest_Update(md, p, l); if (rv==0) /* digest data */ rv=GWEN_MDigest_Update(md, (const uint8_t*)dataStart, dataLength); if (rv==0) rv=GWEN_MDigest_End(md); if (rv<0) { DBG_ERROR(AQHBCI_LOGDOMAIN, "Hash error (%d)", rv); GWEN_MDigest_free(md); GWEN_List_free(sigheads); GWEN_List_free(sigtails); return rv; } memmove(hash, GWEN_MDigest_GetDigestPtr(md), GWEN_MDigest_GetDigestSize(md)); GWEN_MDigest_free(md); } /* verify signature */ p=GWEN_DB_GetBinValue(sigtail, "signature", 0, 0, 0, &l); if (p && l) { GWEN_CRYPT_PADDALGO *algo; algo=GWEN_Crypt_PaddAlgo_new(GWEN_Crypt_PaddAlgoId_Iso9796_2); GWEN_Crypt_PaddAlgo_SetPaddSize(algo, ksize); rv=GWEN_Crypt_Token_Verify(ct, keyId, algo, hash, 20, p, l, 0, gid); GWEN_Crypt_PaddAlgo_free(algo); if (rv) { if (rv==GWEN_ERROR_NO_KEY) { DBG_ERROR(AQHBCI_LOGDOMAIN, "Unable to verify signature of user \"%s\" (no key)", signerId); GWEN_Gui_ProgressLog(gid, GWEN_LoggerLevel_Error, I18N("Unable to verify signature (no key)")); } else { GWEN_BUFFER *tbuf; tbuf=GWEN_Buffer_new(0, 32, 0, 1); if (rv==GWEN_ERROR_VERIFY) { DBG_ERROR(AQHBCI_LOGDOMAIN, "Invalid signature of user \"%s\"", signerId); GWEN_Gui_ProgressLog(gid, GWEN_LoggerLevel_Error, I18N("Invalid signature!!!")); GWEN_Buffer_AppendString(tbuf, "!"); } else { GWEN_Gui_ProgressLog(gid, GWEN_LoggerLevel_Error, I18N("Could not verify signature")); DBG_ERROR(AQHBCI_LOGDOMAIN, "Could not verify data with medium of user \"%s\" (%d)", AB_User_GetUserId(u), rv); GWEN_Buffer_AppendString(tbuf, "?"); } GWEN_Buffer_AppendString(tbuf, signerId); AH_Msg_AddSignerId(hmsg, GWEN_Buffer_GetStart(tbuf)); GWEN_Buffer_free(tbuf); } } else { DBG_INFO(AQHBCI_LOGDOMAIN, "Message signed by \"%s\"", signerId); AH_Msg_AddSignerId(hmsg, signerId); } } else { DBG_DEBUG(AQHBCI_LOGDOMAIN, "No signature"); GWEN_List_free(sigheads); GWEN_List_free(sigtails); return GWEN_ERROR_BAD_DATA; } DBG_DEBUG(AQHBCI_LOGDOMAIN, "Verification done"); } /* for */ GWEN_List_free(sigheads); GWEN_List_free(sigtails); return 0; }
int addUser(AB_BANKING *ab, GWEN_DB_NODE *dbArgs, int argc, char **argv) { GWEN_DB_NODE *db; AB_PROVIDER *pro; int rv; GWEN_BUFFER *nameBuffer=NULL; const char *tokenName; const char *tokenType; const char *bankId; const char *userId; const char *customerId; const char *server; const char *userName; int hbciVersion; int rdhType; uint32_t cid; const GWEN_ARGS args[]={ { GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */ GWEN_ArgsType_Char, /* type */ "userName", /* name */ 1, /* minnum */ 1, /* maxnum */ "N", /* short option */ "username", /* long option */ "Specify the user name", /* short description */ "Specify the user name (not the userid!)" /* long description */ }, { GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */ GWEN_ArgsType_Char, /* type */ "bankId", /* name */ 0, /* minnum */ 1, /* maxnum */ "b", /* short option */ "bank", /* long option */ "Specify the bank code", /* short description */ "Specify the bank code" /* long description */ }, { GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */ GWEN_ArgsType_Char, /* type */ "userId", /* name */ 0, /* minnum */ 1, /* maxnum */ "u", /* short option */ "user", /* long option */ "Specify the user id (Benutzerkennung)", /* short description */ "Specify the user id (Benutzerkennung)" /* long description */ }, { GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */ GWEN_ArgsType_Char, /* type */ "customerId", /* name */ 0, /* minnum */ 1, /* maxnum */ "c", /* short option */ "customer", /* long option */ "Specify the customer id (Kundennummer)", /* short description */ "Specify the customer id (Kundennummer)" /* long description */ }, { GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */ GWEN_ArgsType_Char, /* type */ "tokenType", /* name */ 1, /* minnum */ 1, /* maxnum */ "t", /* short option */ "tokentype", /* long option */ "Specify the crypt token type", /* short description */ "Specify the crypt token type" /* long description */ }, { GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */ GWEN_ArgsType_Char, /* type */ "tokenName", /* name */ 0, /* minnum */ 1, /* maxnum */ "n", /* short option */ "tokenname", /* long option */ "Specify the crypt token name", /* short description */ "Specify the crypt token name" /* long description */ }, { GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */ GWEN_ArgsType_Char, /* type */ "serverAddr", /* name */ 0, /* minnum */ 1, /* maxnum */ "s", /* short option */ "server", /* long option */ "Specify the server URL", /* short description */ "Specify the server URL" /* long description */ }, { GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */ GWEN_ArgsType_Int, /* type */ "context", /* name */ 0, /* minnum */ 1, /* maxnum */ 0, /* short option */ "context", /* long option */ "Select a context on the medium", /* short description */ "Select a context on the medium" /* long description */ }, { GWEN_ARGS_FLAGS_HAS_ARGUMENT, GWEN_ArgsType_Int, "hbciversion", 0, 1, 0, "hbciversion", "Select the HBCI version", "Select the HBCI protocol version" }, { GWEN_ARGS_FLAGS_HAS_ARGUMENT, GWEN_ArgsType_Int, "rdhType", 0, 1, 0, "rdhtype", "Select the RDH profile type (1, 2, 3, 5, 10)", "Select the RDH profile type (1, 2, 3, 5, 10)" }, { GWEN_ARGS_FLAGS_HELP | GWEN_ARGS_FLAGS_LAST, /* flags */ GWEN_ArgsType_Int, /* type */ "help", /* name */ 0, /* minnum */ 0, /* maxnum */ "h", /* short option */ "help", /* long option */ "Show this help screen", /* short description */ "Show this help screen" /* long description */ } }; db=GWEN_DB_GetGroup(dbArgs, GWEN_DB_FLAGS_DEFAULT, "local"); rv=GWEN_Args_Check(argc, argv, 1, 0 /*GWEN_ARGS_MODE_ALLOW_FREEPARAM*/, args, db); if (rv==GWEN_ARGS_RESULT_ERROR) { fprintf(stderr, "ERROR: Could not parse arguments\n"); return 1; } else if (rv==GWEN_ARGS_RESULT_HELP) { GWEN_BUFFER *ubuf; ubuf=GWEN_Buffer_new(0, 1024, 0, 1); if (GWEN_Args_Usage(args, ubuf, GWEN_ArgsOutType_Txt)) { fprintf(stderr, "ERROR: Could not create help string\n"); return 1; } fprintf(stderr, "%s\n", GWEN_Buffer_GetStart(ubuf)); GWEN_Buffer_free(ubuf); return 0; } rv=AB_Banking_Init(ab); if (rv) { DBG_ERROR(0, "Error on init (%d)", rv); return 2; } rv=AB_Banking_OnlineInit(ab); if (rv) { DBG_ERROR(0, "Error on init (%d)", rv); return 2; } pro=AB_Banking_GetProvider(ab, "aqhbci"); assert(pro); tokenType=GWEN_DB_GetCharValue(db, "tokenType", 0, 0); tokenName=GWEN_DB_GetCharValue(db, "tokenName", 0, 0); bankId=GWEN_DB_GetCharValue(db, "bankId", 0, 0); userId=GWEN_DB_GetCharValue(db, "userId", 0, 0); customerId=GWEN_DB_GetCharValue(db, "customerId", 0, 0); server=GWEN_DB_GetCharValue(db, "serverAddr", 0, 0); cid=GWEN_DB_GetIntValue(db, "context", 0, 1); hbciVersion=GWEN_DB_GetIntValue(db, "hbciVersion", 0, 0); rdhType=GWEN_DB_GetIntValue(db, "rdhType", 0, 1); userName=GWEN_DB_GetCharValue(db, "userName", 0, 0); assert(userName); /* generic check for some arguments */ if (hbciVersion>0 && rdhType>1) { if (hbciVersion<300 && rdhType>1) { DBG_ERROR(0, "RDH Types 2 and above only work with HBCI version 300 or later"); return 1; } } if (hbciVersion>0) { switch(hbciVersion) { case 201: case 210: case 220: case 300: /* supported */ break; default: DBG_ERROR(0, "HBCI/FinTS version %d not supported", hbciVersion); return 1; } } if (rdhType>0) { switch(rdhType) { case 1: case 2: case 10: /* supported */ break; case 3: case 4: case 5: case 6: case 7: case 8: case 9: default: DBG_ERROR(0, "RDH type %d not supported", rdhType); return 1; } } if (1) { const char *lbankId; const char *luserId; const char *lcustomerId; const char *lserverAddr; AH_CRYPT_MODE cm; GWEN_URL *url; GWEN_CRYPT_TOKEN_CONTEXT *ctx=NULL; AB_USER *user; if (strcasecmp(tokenType, "pintan")==0) { lbankId=bankId; luserId=userId; lcustomerId=customerId?customerId:luserId; lserverAddr=server; cm=AH_CryptMode_Pintan; } else { GWEN_PLUGIN_MANAGER *pm; GWEN_PLUGIN *pl; GWEN_CRYPT_TOKEN *ct; const GWEN_CRYPT_TOKEN_CONTEXT *cctx; const GWEN_CRYPT_TOKEN_KEYINFO *ki; uint32_t keyId; GWEN_CRYPT_CRYPTALGOID algo; if (cid==0) { DBG_ERROR(0, "No context given."); return 1; } /* get crypt token */ pm=GWEN_PluginManager_FindPluginManager("ct"); if (pm==0) { DBG_ERROR(0, "Plugin manager not found"); return 3; } pl=GWEN_PluginManager_GetPlugin(pm, tokenType); if (pl==0) { DBG_ERROR(0, "Plugin not found"); return 3; } DBG_INFO(0, "Plugin found"); ct=GWEN_Crypt_Token_Plugin_CreateToken(pl, tokenName); if (ct==0) { DBG_ERROR(0, "Could not create crypt token"); return 3; } /* open crypt token */ rv=GWEN_Crypt_Token_Open(ct, 0, 0); if (rv) { DBG_ERROR(0, "Could not open token (%d)", rv); GWEN_Crypt_Token_free(ct); return 3; } /* get real token name */ nameBuffer=GWEN_Buffer_new(0, 64, 0, 1); GWEN_Buffer_AppendString(nameBuffer, GWEN_Crypt_Token_GetTokenName(ct)); tokenName=GWEN_Buffer_GetStart(nameBuffer); cctx=GWEN_Crypt_Token_GetContext(ct, cid, 0); if (cctx==NULL) { DBG_ERROR(0, "Context %02x not found", cid); GWEN_Buffer_free(nameBuffer); GWEN_Crypt_Token_Close(ct, 1, 0); GWEN_Crypt_Token_free(ct); return 3; } ctx=GWEN_Crypt_Token_Context_dup(cctx); lbankId=bankId?bankId:GWEN_Crypt_Token_Context_GetServiceId(ctx); luserId=userId?userId:GWEN_Crypt_Token_Context_GetUserId(ctx); lcustomerId=customerId?customerId:luserId; lserverAddr=server?server:GWEN_Crypt_Token_Context_GetAddress(ctx); /* determine crypt mode */ keyId=GWEN_Crypt_Token_Context_GetSignKeyId(ctx); if (keyId==0) keyId=GWEN_Crypt_Token_Context_GetVerifyKeyId(ctx); if (keyId==0) keyId=GWEN_Crypt_Token_Context_GetEncipherKeyId(ctx); if (keyId==0) keyId=GWEN_Crypt_Token_Context_GetDecipherKeyId(ctx); GWEN_Crypt_Token_Context_free(ctx); if (keyId==0) { DBG_ERROR(0, "No keys, unable to determine crypt mode"); GWEN_Buffer_free(nameBuffer); GWEN_Crypt_Token_Close(ct, 1, 0); GWEN_Crypt_Token_free(ct); return 3; } ki=GWEN_Crypt_Token_GetKeyInfo(ct, keyId, 0xffffffff, 0); if (ki==NULL) { DBG_ERROR(0, "Could not get keyinfo for key %d, " "unable to determine crypt mode", keyId); GWEN_Buffer_free(nameBuffer); GWEN_Crypt_Token_Close(ct, 1, 0); GWEN_Crypt_Token_free(ct); return 3; } algo=GWEN_Crypt_Token_KeyInfo_GetCryptAlgoId(ki); if (algo==GWEN_Crypt_CryptAlgoId_Des3K) cm=AH_CryptMode_Ddv; else if (algo==GWEN_Crypt_CryptAlgoId_Rsa) cm=AH_CryptMode_Rdh; else { DBG_ERROR(0, "Unexpected crypt algorithm \"%s\", " "unable to determine crypt mode", GWEN_Crypt_CryptAlgoId_toString(algo)); GWEN_Buffer_free(nameBuffer); GWEN_Crypt_Token_Close(ct, 1, 0); GWEN_Crypt_Token_free(ct); return 3; } rv=GWEN_Crypt_Token_Close(ct, 0, 0); GWEN_Crypt_Token_free(ct); if (rv) { DBG_ERROR(0, "Could not close token (%d)", rv); GWEN_Buffer_free(nameBuffer); return 3; } } if (!lbankId || !*lbankId) { DBG_ERROR(0, "No bank id stored and none given"); GWEN_Buffer_free(nameBuffer); return 3; } if (!luserId || !*luserId) { DBG_ERROR(0, "No user id (Benutzerkennung) stored and none given"); GWEN_Buffer_free(nameBuffer); return 3; } user=AB_Banking_FindUser(ab, AH_PROVIDER_NAME, "de", lbankId, luserId, lcustomerId); if (user) { DBG_ERROR(0, "User %s already exists", luserId); return 3; } user=AB_Banking_CreateUser(ab, AH_PROVIDER_NAME); assert(user); AB_User_SetUserName(user, userName); AB_User_SetCountry(user, "de"); AB_User_SetBankCode(user, lbankId); AB_User_SetUserId(user, luserId); AB_User_SetCustomerId(user, lcustomerId); AH_User_SetTokenType(user, tokenType); AH_User_SetTokenName(user, tokenName); AH_User_SetTokenContextId(user, cid); AH_User_SetCryptMode(user, cm); if (rdhType>0) AH_User_SetRdhType(user, rdhType); GWEN_Buffer_free(nameBuffer); if (hbciVersion==0) { if (cm==AH_CryptMode_Pintan) AH_User_SetHbciVersion(user, 220); else { if (rdhType>1) AH_User_SetHbciVersion(user, 300); else AH_User_SetHbciVersion(user, 210); } } else { AH_User_SetHbciVersion(user, hbciVersion); } /* try to get server address from database if still unknown */ if (!lserverAddr || *lserverAddr==0) { GWEN_BUFFER *tbuf; tbuf=GWEN_Buffer_new(0, 256, 0, 1); if (getBankUrl(ab, cm, lbankId, tbuf)) { DBG_INFO(0, "Could not find server address for \"%s\"", lbankId); } if (GWEN_Buffer_GetUsedBytes(tbuf)==0) { DBG_ERROR(0, "No address given and none available in internal db"); return 3; } url=GWEN_Url_fromString(GWEN_Buffer_GetStart(tbuf)); if (url==NULL) { DBG_ERROR(0, "Bad URL \"%s\" in internal db", GWEN_Buffer_GetStart(tbuf)); return 3; } GWEN_Buffer_free(tbuf); } else { /* set address */ url=GWEN_Url_fromString(lserverAddr); if (url==NULL) { DBG_ERROR(0, "Bad URL \"%s\"", lserverAddr); return 3; } } if (cm==AH_CryptMode_Pintan) { GWEN_Url_SetProtocol(url, "https"); if (GWEN_Url_GetPort(url)==0) GWEN_Url_SetPort(url, 443); } else { GWEN_Url_SetProtocol(url, "hbci"); if (GWEN_Url_GetPort(url)==0) GWEN_Url_SetPort(url, 3000); } AH_User_SetServerUrl(user, url); GWEN_Url_free(url); if (cm==AH_CryptMode_Ddv) AH_User_SetStatus(user, AH_UserStatusEnabled); AB_Banking_AddUser(ab, user); } rv=AB_Banking_OnlineFini(ab); if (rv) { fprintf(stderr, "ERROR: Error on deinit (%d)\n", rv); return 5; } rv=AB_Banking_Fini(ab); if (rv) { fprintf(stderr, "ERROR: Error on deinit (%d)\n", rv); return 5; } return 0; }
int showUser(GWEN_DB_NODE *dbArgs, int argc, char **argv) { GWEN_DB_NODE *db; const char *ttype; const char *tname; GWEN_CRYPT_TOKEN *ct; unsigned int cid; int shown=0; int rv; const GWEN_ARGS args[]= { { GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */ GWEN_ArgsType_Int, /* type */ "contextId", /* name */ 0, /* minnum */ 1, /* maxnum */ "i", /* short option */ "id", /* long option */ "Context id (0 for any)", /* short description */ "Context id (0 for any)" /* long description */ }, { GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */ GWEN_ArgsType_Char, /* type */ "tokenType", /* name */ 1, /* minnum */ 1, /* maxnum */ "t", /* short option */ "ttype", /* long option */ "Specify the crypt token type", /* short description */ "Specify the crypt token type" /* long description */ }, { GWEN_ARGS_FLAGS_HAS_ARGUMENT, /* flags */ GWEN_ArgsType_Char, /* type */ "tokenName", /* name */ 0, /* minnum */ 1, /* maxnum */ "n", /* short option */ "tname", /* long option */ "Specify the crypt token name", /* short description */ "Specify the crypt token name" /* long description */ }, { GWEN_ARGS_FLAGS_HELP | GWEN_ARGS_FLAGS_LAST, /* flags */ GWEN_ArgsType_Int, /* type */ "help", /* name */ 0, /* minnum */ 0, /* maxnum */ "h", /* short option */ "help", /* long option */ "Show this help screen", /* short description */ "Show this help screen" /* long description */ } }; db=GWEN_DB_GetGroup(dbArgs, GWEN_DB_FLAGS_DEFAULT, "local"); rv=GWEN_Args_Check(argc, argv, 1, GWEN_ARGS_MODE_ALLOW_FREEPARAM, args, db); if (rv==GWEN_ARGS_RESULT_ERROR) { fprintf(stderr, "ERROR: Could not parse arguments\n"); return 1; } else if (rv==GWEN_ARGS_RESULT_HELP) { GWEN_BUFFER *ubuf; ubuf=GWEN_Buffer_new(0, 1024, 0, 1); if (GWEN_Args_Usage(args, ubuf, GWEN_ArgsOutType_Txt)) { fprintf(stderr, "ERROR: Could not create help string\n"); return 1; } fprintf(stderr, "%s\n", GWEN_Buffer_GetStart(ubuf)); GWEN_Buffer_free(ubuf); return 0; } cid=GWEN_DB_GetIntValue(db, "contextId", 0, 0); ttype=GWEN_DB_GetCharValue(db, "tokenType", 0, 0); assert(ttype); tname=GWEN_DB_GetCharValue(db, "tokenName", 0, 0); /* get crypt token */ ct=getCryptToken(ttype, tname); if (ct==0) return 3; if (GWEN_DB_GetIntValue(dbArgs, "forcePin", 0, 0)) GWEN_Crypt_Token_AddModes(ct, GWEN_CRYPT_TOKEN_MODE_FORCE_PIN_ENTRY); /* open crypt token for use */ rv=GWEN_Crypt_Token_Open(ct, 0, 0); if (rv) { DBG_ERROR(0, "Could not open token"); return 3; } else { uint32_t ctxIds[32]; uint32_t ctxCount; uint32_t i; ctxCount=32; rv=GWEN_Crypt_Token_GetContextIdList(ct, ctxIds, &ctxCount, 0); if (rv<0) { DBG_ERROR(0, "Error filling context list"); GWEN_Crypt_Token_Close(ct, 0, 0); return 3; } for (i=0; i<ctxCount; i++) { if (cid==0 || cid==ctxIds[i]) { const GWEN_CRYPT_TOKEN_CONTEXT *ctx; const char *s; uint32_t kid; ctx=GWEN_Crypt_Token_GetContext(ct, ctxIds[i], 0); if (ctx) { fprintf(stdout, "-------------------------------------------------\n"); fprintf(stdout, "Context %u\n", (unsigned int)GWEN_Crypt_Token_Context_GetId(ctx)); s=GWEN_Crypt_Token_Context_GetServiceId(ctx); if (s) fprintf(stdout, "Service : %s\n", s); s=GWEN_Crypt_Token_Context_GetUserId(ctx); if (s) fprintf(stdout, "User Id : %s\n", s); s=GWEN_Crypt_Token_Context_GetCustomerId(ctx); if (s) fprintf(stdout, "Customer Id : %s\n", s); s=GWEN_Crypt_Token_Context_GetUserName(ctx); if (s) fprintf(stdout, "User Name : %s\n", s); s=GWEN_Crypt_Token_Context_GetPeerId(ctx); if (s) fprintf(stdout, "Peer Id : %s\n", s); s=GWEN_Crypt_Token_Context_GetPeerName(ctx); if (s) fprintf(stdout, "Peer Name : %s\n", s); s=GWEN_Crypt_Token_Context_GetAddress(ctx); if (s) fprintf(stdout, "Address : %s\n", s); fprintf(stdout, "Port : %d\n", GWEN_Crypt_Token_Context_GetPort(ctx)); s=GWEN_Crypt_Token_Context_GetSystemId(ctx); if (s) fprintf(stdout, "System Id : %s\n", s); kid=GWEN_Crypt_Token_Context_GetSignKeyId(ctx); if (kid!=0) fprintf(stdout, "Sign Key Id : %d\n", kid); kid=GWEN_Crypt_Token_Context_GetVerifyKeyId(ctx); if (kid!=0) fprintf(stdout, "Verify Key Id : %d\n", kid); kid=GWEN_Crypt_Token_Context_GetEncipherKeyId(ctx); if (kid!=0) fprintf(stdout, "Encipher Key Id: %d\n", kid); kid=GWEN_Crypt_Token_Context_GetDecipherKeyId(ctx); if (kid!=0) fprintf(stdout, "Decipher Key Id: %d\n", kid); shown++; } else { fprintf(stderr, "Context %d not found (%d)\n", i, ctxIds[i]); } } } } /* close crypt token */ rv=GWEN_Crypt_Token_Close(ct, 0, 0); if (rv) { DBG_ERROR(0, "Could not close token"); return 3; } if (!shown) { if (cid==0) { DBG_ERROR(0, "No context found"); } else { DBG_ERROR(0, "Context %u not found", cid); } return 1; } return 0; }