示例#1
0
int GWEN_Directory_FindFileInPaths(const GWEN_STRINGLIST *paths,
                                   const char *filePath,
                                   GWEN_BUFFER *fbuf) {
  GWEN_STRINGLISTENTRY *se;

  se=GWEN_StringList_FirstEntry(paths);
  while(se) {
    GWEN_BUFFER *tbuf;
    FILE *f;

    tbuf=GWEN_Buffer_new(0, 256, 0, 1);
    GWEN_Buffer_AppendString(tbuf, GWEN_StringListEntry_Data(se));
    GWEN_Buffer_AppendString(tbuf, DIRSEP);
    GWEN_Buffer_AppendString(tbuf, filePath);
    DBG_VERBOUS(GWEN_LOGDOMAIN, "Trying \"%s\"",
                GWEN_Buffer_GetStart(tbuf));
    f=fopen(GWEN_Buffer_GetStart(tbuf), "r");
    if (f) {
      fclose(f);
      DBG_DEBUG(GWEN_LOGDOMAIN,
                "File \"%s\" found in folder \"%s\"",
                filePath,
                GWEN_StringListEntry_Data(se));
      GWEN_Buffer_AppendBuffer(fbuf, tbuf);
      GWEN_Buffer_free(tbuf);
      return 0;
    }
    GWEN_Buffer_free(tbuf);

    se=GWEN_StringListEntry_Next(se);
  }

  DBG_INFO(GWEN_LOGDOMAIN, "File \"%s\" not found", filePath);
  return GWEN_ERROR_NOT_FOUND;
}
示例#2
0
int GWEN_PathManager_FindFile(const char *destLib,
                              const char *pathName,
                              const char *fileName,
                              GWEN_BUFFER *fbuf) {
  GWEN_DB_NODE *dbT;

  assert(gwen__paths);
  dbT=GWEN_DB_GetGroup(gwen__paths, GWEN_PATH_FLAGS_NAMEMUSTEXIST,
                       destLib);
  if (dbT) {
    dbT=GWEN_DB_GetGroup(dbT, GWEN_PATH_FLAGS_NAMEMUSTEXIST,
                         pathName);
    if (dbT) {
      int i;
      const char *s;
      GWEN_DB_NODE *dbN;
      GWEN_BUFFER *tbuf;

      tbuf=GWEN_Buffer_new(0, 256, 0, 1);

      /* check all paths */
      dbN=GWEN_DB_FindFirstGroup(dbT, "pair");
      while(dbN) {
        for (i=0; ; i++) {
          s=GWEN_DB_GetCharValue(dbN, "path", i, 0);
          if (!s)
            break;
          else {
            FILE *f;

            GWEN_Buffer_AppendString(tbuf, s);
            GWEN_Buffer_AppendString(tbuf, GWEN_DIR_SEPARATOR_S);
            GWEN_Buffer_AppendString(tbuf, fileName);
            DBG_DEBUG(GWEN_LOGDOMAIN, "Trying \"%s\"",
                      GWEN_Buffer_GetStart(tbuf));
            f=fopen(GWEN_Buffer_GetStart(tbuf), "r");
            if (f) {
              fclose(f);
              DBG_DEBUG(GWEN_LOGDOMAIN,
                        "File \"%s\" found in folder \"%s\"",
                        fileName,
                        s);
              GWEN_Buffer_AppendBuffer(fbuf, tbuf);
              GWEN_Buffer_free(tbuf);
              return 0;
            }
            GWEN_Buffer_Reset(tbuf);
          }
        }

        dbN=GWEN_DB_FindNextGroup(dbN, "pair");
      }
      GWEN_Buffer_free(tbuf);
    }
  }

  DBG_INFO(GWEN_LOGDOMAIN, "File \"%s\" not found", fileName);
  return GWEN_ERROR_NOT_FOUND;
}
示例#3
0
GWENHYWFAR_CB
int GWEN_CryptMgrKeys_DecryptKey(GWEN_CRYPTMGR *cm,
                                 const uint8_t *pData, uint32_t lData,
                                 GWEN_BUFFER *dbuf) {
  GWEN_CRYPTMGR_KEYS *xcm;
  int rv;
  GWEN_BUFFER *tbuf;
  int ksize;
  uint32_t l;

  assert(cm);
  xcm=GWEN_INHERIT_GETDATA(GWEN_CRYPTMGR, GWEN_CRYPTMGR_KEYS, cm);
  assert(xcm);

  if (xcm->localKey==NULL) {
    DBG_ERROR(GWEN_LOGDOMAIN, "No local key");
    return GWEN_ERROR_GENERIC;
  }

  ksize=GWEN_Crypt_Key_GetKeySize(xcm->localKey);

  tbuf=GWEN_Buffer_new(0, ksize, 0, 1);
  l=GWEN_Buffer_GetMaxUnsegmentedWrite(tbuf);
  rv=GWEN_Crypt_Key_Decipher(xcm->localKey,
                             pData, lData,
                             (uint8_t*)GWEN_Buffer_GetPosPointer(tbuf),
                             &l);
  if (rv<0) {
    DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
    GWEN_Buffer_free(tbuf);
    return rv;
  }
  GWEN_Buffer_IncrementPos(tbuf, l);
  GWEN_Buffer_AdjustUsedBytes(tbuf);

  /* unpadd data */
  rv=GWEN_Padd_UnpaddWithIso9796_2(tbuf);
  if (rv<0) {
    DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
    GWEN_Buffer_free(tbuf);
    return rv;
  }

  GWEN_Buffer_AppendBuffer(dbuf, tbuf);
  GWEN_Buffer_free(tbuf);

  return 0;
}
示例#4
0
int AH_Msg_SignPinTan(AH_MSG *hmsg,
		      GWEN_BUFFER *rawBuf,
		      const char *signer) {
  AH_HBCI *h;
  GWEN_XMLNODE *node;
  GWEN_DB_NODE *cfg;
  GWEN_BUFFER *hbuf;
  int rv;
  char ctrlref[15];
  const char *p;
  GWEN_MSGENGINE *e;
  AB_USER *su;
  uint32_t uFlags;
  char pin[64];
  uint32_t tm;

  assert(hmsg);
  h=AH_Dialog_GetHbci(hmsg->dialog);
  assert(h);
  e=AH_Dialog_GetMsgEngine(hmsg->dialog);
  assert(e);
  GWEN_MsgEngine_SetMode(e, "pintan");

  su=AB_Banking_FindUser(AH_HBCI_GetBankingApi(h),
			 AH_PROVIDER_NAME,
			 "de", "*",
			 signer, "*");
  if (!su) {
    DBG_ERROR(AQHBCI_LOGDOMAIN,
	      "Unknown user \"%s\"",
	      signer);
    return GWEN_ERROR_NOT_FOUND;
  }

  uFlags=AH_User_GetFlags(su);

  node=GWEN_MsgEngine_FindNodeByPropertyStrictProto(e,
						    "SEG",
						    "id",
						    0,
						    "SigHead");
  if (!node) {
    DBG_INFO(AQHBCI_LOGDOMAIN, "Segment \"SigHead\" not found");
    return GWEN_ERROR_INTERNAL;
  }

  /* for iTAN mode: set selected mode (Sicherheitsfunktion, kodiert) */
  tm=AH_Msg_GetItanMethod(hmsg);
  if (tm==0) {
    tm=AH_Dialog_GetItanMethod(hmsg->dialog);
    if (tm)
      /* this is needed by AH_MsgPinTan_PrepareCryptoSeg */
      AH_Msg_SetItanMethod(hmsg, tm);
  }

  /* prepare config for segment */
  cfg=GWEN_DB_Group_new("sighead");
  rv=AH_MsgPinTan_PrepareCryptoSeg(hmsg, su, cfg, 0, 1);
  if (rv) {
    DBG_INFO(AQHBCI_LOGDOMAIN, "here (%d)", rv);
    GWEN_DB_Group_free(cfg);
    return rv;
  }

  /* set expected signer */
  if (!(uFlags & AH_USER_FLAGS_BANK_DOESNT_SIGN)) {
    const char *remoteId;

    remoteId=AH_User_GetPeerId(su);
    if (!remoteId || *remoteId==0)
      remoteId=AB_User_GetUserId(su);
    assert(remoteId);
    assert(*remoteId);

    DBG_DEBUG(AQHBCI_LOGDOMAIN,
	      "Expecting \"%s\" to sign the response",
	      remoteId);
    AH_Msg_SetExpectedSigner(hmsg, remoteId);
  }

  /* store system id */
  p=NULL;
  if (!hmsg->noSysId)
    p=AH_User_GetSystemId(su);
  if (!p)
    p="0";
  GWEN_DB_SetCharValue(cfg, GWEN_DB_FLAGS_DEFAULT, "SecDetails/SecId", p);

  if (tm) {
    GWEN_DB_SetIntValue(cfg, GWEN_DB_FLAGS_DEFAULT,
			"function", tm);
  }

  /* retrieve control reference for sigtail (to be used later) */
  p=GWEN_DB_GetCharValue(cfg, "ctrlref", 0, "");
  if (strlen(p)>=sizeof(ctrlref)) {
    DBG_INFO(AQHBCI_LOGDOMAIN,
	     "Control reference too long (14 bytes maximum)");
    GWEN_DB_Group_free(cfg);
    return -1;
  }
  strcpy(ctrlref, p);

  /* create SigHead */
  hbuf=GWEN_Buffer_new(0, 128+GWEN_Buffer_GetUsedBytes(rawBuf), 0, 1);
  GWEN_DB_SetIntValue(cfg, GWEN_DB_FLAGS_DEFAULT,
                      "head/seq", hmsg->firstSegment-1);
  GWEN_DB_SetIntValue(cfg, GWEN_DB_FLAGS_DEFAULT,
		      "signseq", 1);

  /* create signature head segment */
  rv=GWEN_MsgEngine_CreateMessageFromNode(e, node, hbuf, cfg);
  GWEN_DB_Group_free(cfg);
  cfg=0;
  if (rv) {
    DBG_INFO(AQHBCI_LOGDOMAIN, "Could not create SigHead");
    GWEN_Buffer_free(hbuf);
    return rv;
  }

  /* insert new SigHead at beginning of message buffer */
  DBG_DEBUG(AQHBCI_LOGDOMAIN, "Inserting signature head");
  GWEN_Buffer_Rewind(hmsg->buffer);
  GWEN_Buffer_InsertBytes(hmsg->buffer,
			  GWEN_Buffer_GetStart(hbuf),
			  GWEN_Buffer_GetUsedBytes(hbuf));

  /* create sigtail */
  DBG_DEBUG(AQHBCI_LOGDOMAIN, "Completing signature tail");
  cfg=GWEN_DB_Group_new("sigtail");
  GWEN_Buffer_Reset(hbuf);
  GWEN_DB_SetIntValue(cfg, GWEN_DB_FLAGS_DEFAULT,
                      "head/seq", hmsg->lastSegment+1);
  /* store to DB */
  GWEN_DB_SetBinValue(cfg, GWEN_DB_FLAGS_DEFAULT,
		      "signature",
		      "NOSIGNATURE",
                      11);
  GWEN_DB_SetCharValue(cfg, GWEN_DB_FLAGS_DEFAULT,
		       "ctrlref", ctrlref);

  /* handle pin */
  memset(pin, 0, sizeof(pin));
  rv=AH_User_InputPin(su, pin, 4, sizeof(pin), 0);
  if (rv<0) {
    DBG_ERROR(AQHBCI_LOGDOMAIN,
	      "Error getting pin from medium (%d)", rv);
    GWEN_DB_Group_free(cfg);
    GWEN_Buffer_free(hbuf);
    memset(pin, 0, sizeof(pin));
    return rv;
  }
  GWEN_DB_SetCharValue(cfg, GWEN_DB_FLAGS_DEFAULT, "pin", pin);
  AH_Msg_SetPin(hmsg, pin);
  memset(pin, 0, sizeof(pin));

  /* handle tan */
  if (hmsg->needTan) {
    DBG_NOTICE(AQHBCI_LOGDOMAIN,
	       "This queue needs a TAN");
    if (hmsg->usedTan) {
      DBG_NOTICE(AQHBCI_LOGDOMAIN,
		 "Using existing TAN");
      GWEN_DB_SetCharValue(cfg, GWEN_DB_FLAGS_DEFAULT,
			   "tan", hmsg->usedTan);
    }
    else {
      char tan[16];

      memset(tan, 0, sizeof(tan));
      DBG_NOTICE(AQHBCI_LOGDOMAIN, "Asking for TAN");
      rv=AH_User_InputTan(su, tan, 4, sizeof(tan));
      if (rv<0) {
	DBG_ERROR(AQHBCI_LOGDOMAIN, "Error getting TAN from medium");
	GWEN_DB_Group_free(cfg);
	GWEN_Buffer_free(hbuf);
	return rv;
      }
      GWEN_DB_SetCharValue(cfg, GWEN_DB_FLAGS_DEFAULT,
			   "tan", tan);
      AH_Msg_SetTan(hmsg, tan);
    }
  }
  else {
    DBG_NOTICE(AQHBCI_LOGDOMAIN,
	       "This queue doesn't need a TAN");
  }

  /* get node */
  node=GWEN_MsgEngine_FindNodeByPropertyStrictProto(e,
						    "SEG",
						    "id",
						    0,
						    "SigTail");
  if (!node) {
    DBG_INFO(AQHBCI_LOGDOMAIN, "Segment \"SigTail\"not found");
    GWEN_Buffer_free(hbuf);
    GWEN_DB_Group_free(cfg);
    return GWEN_ERROR_INTERNAL;
  }

  rv=GWEN_MsgEngine_CreateMessageFromNode(e, node, hbuf, cfg);
  if (rv) {
    DBG_INFO(AQHBCI_LOGDOMAIN, "Could not create SigTail (%d)", rv);
    GWEN_Buffer_free(hbuf);
    GWEN_DB_Group_free(cfg);
    return rv;
  }

  /* append sigtail */
  DBG_DEBUG(AQHBCI_LOGDOMAIN, "Appending signature tail");
  if (GWEN_Buffer_AppendBuffer(hmsg->buffer, hbuf)) {
    DBG_INFO(AQHBCI_LOGDOMAIN, "here");
    GWEN_Buffer_free(hbuf);
    GWEN_DB_Group_free(cfg);
    return GWEN_ERROR_MEMORY_FULL;
  }
  DBG_DEBUG(AQHBCI_LOGDOMAIN, "Appending signature tail: done");

  GWEN_Buffer_free(hbuf);
  GWEN_DB_Group_free(cfg);

  /* adjust segment numbers (for next signature and message tail */
  hmsg->firstSegment--;
  hmsg->lastSegment++;

  return 0;
}
示例#5
0
void EBC_Provider_LogRequestResults(AB_PROVIDER *pro,
				    EB_MSG *mRsp,
				    GWEN_BUFFER *logbuf) {
  const char *tcode;
  const char *bcode;
  const char *s;
  GWEN_BUFFER *tbuf;

  tcode=EB_Msg_GetCharValue(mRsp, "header/mutable/ReturnCode", NULL);
  bcode=EB_Msg_GetCharValue(mRsp, "body/ReturnCode", NULL);

  tbuf=GWEN_Buffer_new(0, 256, 0, 1);
  if (tcode) {
    GWEN_Buffer_AppendString(tbuf, I18N("EBICS (Technical Code):"));
    GWEN_Buffer_AppendString(tbuf, " ");
    GWEN_Buffer_AppendString(tbuf, tcode);
    s=EBC_Provider_TechnicalCodeToString(tcode);
    if (s) {
      GWEN_Buffer_AppendString(tbuf, " [");
      GWEN_Buffer_AppendString(tbuf, s);
      GWEN_Buffer_AppendString(tbuf, "]");
    }
    if (logbuf) {
      GWEN_Buffer_AppendString(logbuf, "\t");
      GWEN_Buffer_AppendBuffer(logbuf, tbuf);
    }
    GWEN_Gui_ProgressLog(0,
			 EBC_Provider_ResultCodeToLogLevel(pro, tcode),
			 GWEN_Buffer_GetStart(tbuf));
    DBG_INFO(AQEBICS_LOGDOMAIN, "%s", GWEN_Buffer_GetStart(tbuf));
    GWEN_Buffer_Reset(tbuf);
  }

  s=EB_Msg_GetCharValue(mRsp, "header/mutable/ReportText", NULL);
  if (s) {
    GWEN_Buffer_AppendString(tbuf, I18N("EBICS (Technical Report):"));
    GWEN_Buffer_AppendString(tbuf, " ");
    GWEN_Buffer_AppendString(tbuf, s);
    if (logbuf) {
      GWEN_Buffer_AppendString(logbuf, "\t");
      GWEN_Buffer_AppendBuffer(logbuf, tbuf);
    }
    GWEN_Gui_ProgressLog(0,
			 GWEN_LoggerLevel_Notice,
			 GWEN_Buffer_GetStart(tbuf));
    DBG_INFO(AQEBICS_LOGDOMAIN, "%s", GWEN_Buffer_GetStart(tbuf));
    GWEN_Buffer_Reset(tbuf);
  }

  s=EB_Msg_GetCharValue(mRsp, "body/ReturnCode", NULL);
  if (bcode) {
    GWEN_Buffer_AppendString(tbuf, I18N("EBICS (Bank Code):"));
    GWEN_Buffer_AppendString(tbuf, " ");
    GWEN_Buffer_AppendString(tbuf, bcode);

    s=EBC_Provider_BankCodeToString(bcode);
    if (s) {
      GWEN_Buffer_AppendString(tbuf, " [");
      GWEN_Buffer_AppendString(tbuf, s);
      GWEN_Buffer_AppendString(tbuf, "]");
    }

    if (logbuf) {
      GWEN_Buffer_AppendString(logbuf, "\t");
      GWEN_Buffer_AppendBuffer(logbuf, tbuf);
    }

    GWEN_Gui_ProgressLog(0,
			 EBC_Provider_ResultCodeToLogLevel(pro, bcode),
			 GWEN_Buffer_GetStart(tbuf));
    DBG_INFO(AQEBICS_LOGDOMAIN, "%s", GWEN_Buffer_GetStart(tbuf));
    GWEN_Buffer_Reset(tbuf);
  }

  GWEN_Buffer_free(tbuf);
}
示例#6
0
int GWEN_CryptMgr_Decrypt(GWEN_CRYPTMGR *cm, const uint8_t *pData, uint32_t lData, GWEN_BUFFER *dbuf) {
  GWEN_TAG16 *tag;
  const uint8_t *p;
  uint32_t l;
  GWEN_CRYPTHEAD *ch=NULL;
  const uint8_t *pEncryptedData=NULL;
  uint32_t lEncryptedData=0;
  int rv;
  GWEN_BUFFER *tbuf;
  GWEN_CRYPT_KEY *mkey;

  assert(cm);
  if (lData<3) {
    DBG_ERROR(GWEN_LOGDOMAIN, "Too few bytes");
    return GWEN_ERROR_BAD_DATA;
  }

  tag=GWEN_Tag16_fromBuffer2(pData, lData, 0);
  if (tag==NULL) {
    DBG_ERROR(GWEN_LOGDOMAIN, "Data doesn't contain a valid TLV");
    return GWEN_ERROR_BAD_DATA;
  }

  if (GWEN_Tag16_GetTagType(tag)!=GWEN_CRYPTMGR_TLV_ENCRYPTEDOBJECT) {
    DBG_ERROR(GWEN_LOGDOMAIN, "Data does not contain an encrypted object");
    GWEN_Tag16_free(tag);
    return GWEN_ERROR_BAD_DATA;
  }

  p=GWEN_Tag16_GetTagData(tag);
  l=GWEN_Tag16_GetTagLength(tag);

  /* read crypthead */
  if (l) {
    GWEN_TAG16 *subtag;

    subtag=GWEN_Tag16_fromBuffer2(p, l, 0);
    if (subtag) {
      if (GWEN_Tag16_GetTagType(subtag)==GWEN_CRYPTMGR_TLV_CRYPTHEAD) {
        ch=GWEN_CryptHead_fromBuffer(GWEN_Tag16_GetTagData(subtag),
                                     GWEN_Tag16_GetTagLength(subtag));
      }
      p+=GWEN_Tag16_GetTagSize(subtag);
      l-=GWEN_Tag16_GetTagSize(subtag);
      GWEN_Tag16_free(subtag);
    }
  }

  /* read encrypted data */
  if (l) {
    GWEN_TAG16 *subtag;

    subtag=GWEN_Tag16_fromBuffer2(p, l, 0);
    if (subtag) {
      if (GWEN_Tag16_GetTagType(subtag)==GWEN_CRYPTMGR_TLV_CRYPTDATA) {
        pEncryptedData=GWEN_Tag16_GetTagData(subtag);
        lEncryptedData=GWEN_Tag16_GetTagLength(subtag);
      }
      p+=GWEN_Tag16_GetTagSize(subtag);
      l-=GWEN_Tag16_GetTagSize(subtag);
      GWEN_Tag16_free(subtag);
    }
  }

  /* check for all needed components */
  if (!(ch && pEncryptedData && lEncryptedData)) {
    DBG_ERROR(GWEN_LOGDOMAIN, "Encrypted object is not complete");
    GWEN_CryptHead_free(ch);
    GWEN_Tag16_free(tag);
    return GWEN_ERROR_BAD_DATA;
  }

  /* store or check peer key info */
  if (cm->localKeyName) {
    const char *s;

    /* compare peer info with expected info */
    s=GWEN_CryptHead_GetKeyName(ch);
    if (!(cm->localKeyName && s && (strcasecmp(cm->localKeyName, s)==0) &&
          (cm->localKeyNumber==GWEN_CryptHead_GetKeyNumber(ch)) &&
          (cm->localKeyVersion==GWEN_CryptHead_GetKeyVersion(ch)))) {
      DBG_ERROR(GWEN_LOGDOMAIN, "Unexpected local key information in signature");
      GWEN_CryptHead_free(ch);
      GWEN_Tag16_free(tag);

      return GWEN_ERROR_BAD_DATA;
    }
  }

  /* decrypt message key */
  tbuf=GWEN_Buffer_new(0, GWEN_CryptHead_GetKeyLen(ch), 0, 1);
  rv=GWEN_CryptMgr_DecryptKey(cm,
                              GWEN_CryptHead_GetKeyPtr(ch),
                              GWEN_CryptHead_GetKeyLen(ch),
                              tbuf);
  GWEN_CryptHead_free(ch);
  if (rv<0) {
    DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
    GWEN_Buffer_free(tbuf);
    GWEN_Tag16_free(tag);
    return rv;
  }

  /* create message key */
  mkey=GWEN_Crypt_KeyBlowFish_fromData(GWEN_Crypt_CryptMode_Cbc,
                                       256/8,
                                       (const uint8_t*) GWEN_Buffer_GetStart(tbuf),
                                       GWEN_Buffer_GetUsedBytes(tbuf));
  GWEN_Buffer_free(tbuf);
  if (mkey==NULL) {
    DBG_ERROR(GWEN_LOGDOMAIN, "Unable to create BLOWFISH key from received data");
    GWEN_Tag16_free(tag);
    return GWEN_ERROR_BAD_DATA;
  }


  /* decrypt data with message key */
  tbuf=GWEN_Buffer_new(0, lEncryptedData+256, 0, 1);
  l=GWEN_Buffer_GetMaxUnsegmentedWrite(tbuf);
  rv=GWEN_Crypt_Key_Decipher(mkey,
                             pEncryptedData, lEncryptedData,
                             (uint8_t*)GWEN_Buffer_GetStart(tbuf),
                             &l);
  if (rv<0) {
    DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
    GWEN_Buffer_free(tbuf);
    GWEN_Crypt_Key_free(mkey);
    GWEN_Tag16_free(tag);
    return rv;
  }
  GWEN_Buffer_IncrementPos(tbuf, l);
  GWEN_Buffer_AdjustUsedBytes(tbuf);

  /* unpadd data */
  rv=GWEN_Padd_UnpaddWithAnsiX9_23(tbuf);
  if (rv<0) {
    DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
    GWEN_Buffer_free(tbuf);
    GWEN_Crypt_Key_free(mkey);
    GWEN_Tag16_free(tag);
    return rv;
  }

  /* store data */
  GWEN_Buffer_AppendBuffer(dbuf, tbuf);

  GWEN_Buffer_free(tbuf);
  GWEN_Crypt_Key_free(mkey);
  GWEN_Tag16_free(tag);

  return 0;
}
示例#7
0
static int EBC_Provider_SignMessage_X001(AB_PROVIDER *pro,
					 EB_MSG *msg,
					 AB_USER *u,
					 xmlNodePtr node) {
  EBC_PROVIDER *dp;
  int rv;
  GWEN_CRYPT_TOKEN *ct;
  const GWEN_CRYPT_TOKEN_CONTEXT *ctx;
  const GWEN_CRYPT_TOKEN_KEYINFO *ki;
  uint32_t keyId;
  GWEN_BUFFER *hbuf;
  GWEN_BUFFER *bbuf;
  xmlNodePtr nodeX = NULL;
  xmlNodePtr nodeXX = NULL;
  xmlNodePtr nodeXXX = NULL;
  xmlNodePtr nodeXXXX = NULL;
  xmlNsPtr ns;

  assert(pro);
  dp=GWEN_INHERIT_GETDATA(AB_PROVIDER, EBC_PROVIDER, pro);
  assert(dp);

  /* get crypt token and context */
  rv=EBC_Provider_MountToken(pro, u, &ct, &ctx);
  if (rv<0) {
    DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv);
    return rv;
  }

  /* get key id */
  keyId=GWEN_Crypt_Token_Context_GetAuthSignKeyId(ctx);
  ki=GWEN_Crypt_Token_GetKeyInfo(ct,
				 keyId,
				 0xffffffff,
				 0);
  if (ki==NULL) {
    DBG_INFO(AQEBICS_LOGDOMAIN,
	     "Keyinfo %04x not found on crypt token [%s:%s]",
	     keyId,
	     GWEN_Crypt_Token_GetTypeName(ct),
	     GWEN_Crypt_Token_GetTokenName(ct));
    GWEN_Crypt_Token_Close(ct, 0, 0);
    return GWEN_ERROR_NOT_FOUND;
  }

  /* prepare signature nodes */
  ns=xmlSearchNs(EB_Msg_GetDoc(msg), node, BAD_CAST "ds");
  assert(ns);

  /* build hash */
  bbuf=GWEN_Buffer_new(0, 256, 0, 1);
  rv=EB_Msg_BuildHashSha1(msg, bbuf);
  if (rv) {
    DBG_ERROR(AQEBICS_LOGDOMAIN, "Could not build hash");
    GWEN_Buffer_free(bbuf);
    return rv;
  }

  /* base64 encode */
  hbuf=GWEN_Buffer_new(0, 256, 0, 1);
  rv=GWEN_Base64_Encode((const uint8_t*)GWEN_Buffer_GetStart(bbuf),
			GWEN_Buffer_GetUsedBytes(bbuf),
			hbuf, 0);
  if (rv<0) {
    DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv);
    GWEN_Buffer_free(hbuf);
    GWEN_Buffer_free(bbuf);
    return rv;
  }
  GWEN_Buffer_free(bbuf);

  /* create signature node */
  nodeX=xmlNewChild(node, ns, BAD_CAST "SignedInfo", NULL);
  nodeXX=xmlNewChild(nodeX, ns, BAD_CAST "CanonicalizationMethod", NULL);
  xmlNewProp(nodeXX,
	     BAD_CAST "Algorithm",
	     BAD_CAST "http://www.w3.org/TR/2001/REC-xml-c14n-20010315");
  nodeXX=xmlNewChild(nodeX, ns, BAD_CAST "SignatureMethod", NULL);
  xmlNewProp(nodeXX,
	     BAD_CAST "Algorithm",
	     BAD_CAST "http://www.w3.org/2000/09/xmldsig#rsa-sha1");
  nodeXX=xmlNewChild(nodeX, ns, BAD_CAST "Reference", NULL);
  xmlNewProp(nodeXX,
	     BAD_CAST "URI",
	     BAD_CAST "#xpointer(//*[@authenticate='true'])");
  nodeXXX=xmlNewChild(nodeXX, ns, BAD_CAST "Transforms", NULL);
  nodeXXXX=xmlNewChild(nodeXXX, ns, BAD_CAST "Transform", NULL);
  xmlNewProp(nodeXXXX,
	     BAD_CAST "Algorithm",
	     BAD_CAST "http://www.w3.org/TR/2001/REC-xml-c14n-20010315");

  nodeXXX=xmlNewChild(nodeXX, ns, BAD_CAST "DigestMethod", NULL);
  xmlNewProp(nodeXXX,
	     BAD_CAST "Algorithm",
	     BAD_CAST "http://www.w3.org/2000/09/xmldsig#sha1");

  /* store hash value */
  xmlNewTextChild(nodeXX, ns,
		  BAD_CAST "DigestValue",
		  BAD_CAST GWEN_Buffer_GetStart(hbuf));
  GWEN_Buffer_free(hbuf);

  /* build hash over SignedInfo */
  bbuf=GWEN_Buffer_new(0, 256, 0, 1);
  rv=EB_Xml_BuildNodeHashSha1(nodeX, "#xpointer(//*)", bbuf);
  if (rv<0) {
    DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv);
    GWEN_Buffer_free(bbuf);
    return rv;
  }

  /* sign hash */
  if (1) {
    GWEN_CRYPT_PADDALGO *algo;
    int ksize;
    uint32_t l;
    const uint8_t prefix[]={
      0x30, 0x21, 0x30, 0x09,
      0x06, 0x05, 0x2B, 0x0E,
      0x03, 0x02, 0x1A, 0x05,
      0x00, 0x04, 0x14};

    /* add prefix to hash of SignedInfo */
    hbuf=GWEN_Buffer_new(0, 256, 0, 1);
    ksize=GWEN_Crypt_Token_KeyInfo_GetKeySize(ki);
    GWEN_Buffer_AppendBytes(hbuf, (const char*)prefix, sizeof(prefix));
    GWEN_Buffer_AppendBuffer(hbuf, bbuf);
    GWEN_Buffer_Reset(bbuf);

    /* select padd algo */
    algo=GWEN_Crypt_PaddAlgo_new(GWEN_Crypt_PaddAlgoId_Pkcs1_1);
    GWEN_Crypt_PaddAlgo_SetPaddSize(algo, ksize);

    /* actually sign */
    GWEN_Buffer_AllocRoom(bbuf, ksize+16);
    l=GWEN_Buffer_GetMaxUnsegmentedWrite(bbuf);
    rv=GWEN_Crypt_Token_Sign(ct, keyId,
			     algo,
			     (const uint8_t*)GWEN_Buffer_GetStart(hbuf),
			     GWEN_Buffer_GetUsedBytes(hbuf),
			     (uint8_t*)GWEN_Buffer_GetPosPointer(bbuf),
			     &l,
			     NULL, /* ignore seq counter */
			     0);
    GWEN_Crypt_PaddAlgo_free(algo);
    if (rv<0) {
      DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv);
      GWEN_Buffer_free(bbuf);
      GWEN_Buffer_free(hbuf);
      return rv;
    }
    GWEN_Buffer_IncrementPos(bbuf, l);
    GWEN_Buffer_AdjustUsedBytes(bbuf);

    /* base 64 encode signature */
    GWEN_Buffer_Reset(hbuf);
    rv=GWEN_Base64_Encode((const uint8_t*)GWEN_Buffer_GetStart(bbuf),
			  GWEN_Buffer_GetUsedBytes(bbuf),
			  hbuf, 0);
    if (rv<0) {
      DBG_INFO(AQEBICS_LOGDOMAIN, "here (%d)", rv);
      GWEN_Buffer_free(hbuf);
      GWEN_Buffer_free(bbuf);
      return rv;
    }
    GWEN_Buffer_free(bbuf);

    /* store signature */
    xmlNewTextChild(node, ns,
		    BAD_CAST "SignatureValue",
		    BAD_CAST GWEN_Buffer_GetStart(hbuf));
    GWEN_Buffer_free(hbuf);
  }

  return 0;
}
示例#8
0
int AH_Msg_SignRdh2(AH_MSG *hmsg,
                    AB_USER *su,
		    GWEN_BUFFER *rawBuf,
		    const char *signer) {
  AH_HBCI *h;
  GWEN_XMLNODE *node;
  GWEN_DB_NODE *cfg;
  GWEN_BUFFER *sigbuf;
  GWEN_BUFFER *hbuf;
  unsigned int l;
  int rv;
  char ctrlref[15];
  const char *p;
  GWEN_MSGENGINE *e;
  uint32_t uFlags;
  GWEN_CRYPT_TOKEN *ct;
  const GWEN_CRYPT_TOKEN_CONTEXT *ctx;
  const GWEN_CRYPT_TOKEN_KEYINFO *ki;
  uint32_t keyId;
  uint32_t gid;

  assert(hmsg);
  h=AH_Dialog_GetHbci(hmsg->dialog);
  assert(h);
  e=AH_Dialog_GetMsgEngine(hmsg->dialog);
  assert(e);
  GWEN_MsgEngine_SetMode(e, "rdh");

  gid=0;

  uFlags=AH_User_GetFlags(su);

  /* get crypt token of signer */
  rv=AB_Banking_GetCryptToken(AH_HBCI_GetBankingApi(h),
			   AH_User_GetTokenType(su),
			   AH_User_GetTokenName(su),
			   &ct);
  if (rv) {
    DBG_INFO(AQHBCI_LOGDOMAIN,
	     "Could not get crypt token for user \"%s\" (%d)",
	     AB_User_GetUserId(su), 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(su), rv);
      return rv;
    }
  }

  /* get context and key info */
  ctx=GWEN_Crypt_Token_GetContext(ct,
				  AH_User_GetTokenContextId(su),
				  gid);
  if (ctx==NULL) {
    DBG_INFO(AQHBCI_LOGDOMAIN,
	     "Context %d not found on crypt token [%s:%s]",
	     AH_User_GetTokenContextId(su),
	     GWEN_Crypt_Token_GetTypeName(ct),
	     GWEN_Crypt_Token_GetTokenName(ct));
    return GWEN_ERROR_NOT_FOUND;
  }

  keyId=GWEN_Crypt_Token_Context_GetSignKeyId(ctx);
  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));
    return GWEN_ERROR_NOT_FOUND;
  }

  node=GWEN_MsgEngine_FindNodeByPropertyStrictProto(e,
						    "SEG",
						    "id",
						    0,
						    "SigHead");
  if (!node) {
    DBG_INFO(AQHBCI_LOGDOMAIN, "Segment \"SigHead\" not found");
    return GWEN_ERROR_INTERNAL;
  }

  /* prepare config for segment */
  cfg=GWEN_DB_Group_new("sighead");
  rv=AH_MsgRdh_PrepareCryptoSeg2(hmsg, su, ki, cfg, 0, 1);
  if (rv) {
    DBG_INFO(AQHBCI_LOGDOMAIN, "here (%d)", rv);
    GWEN_DB_Group_free(cfg);
    return rv;
  }

  /* set expected signer */
  if (!(uFlags & AH_USER_FLAGS_BANK_DOESNT_SIGN)) {
    const char *remoteId;

    remoteId=AH_User_GetPeerId(su);
    if (!remoteId || *remoteId==0)
      remoteId=AB_User_GetUserId(su);
    assert(remoteId);
    assert(*remoteId);

    DBG_DEBUG(AQHBCI_LOGDOMAIN,
	      "Expecting \"%s\" to sign the response",
	      remoteId);
    AH_Msg_SetExpectedSigner(hmsg, remoteId);
  }

  /* store system id */
  if (hmsg->noSysId) {
    GWEN_DB_SetCharValue(cfg, GWEN_DB_FLAGS_DEFAULT,
			 "SecDetails/SecId", "0");
  }
  else {
    p=AH_User_GetSystemId(su);
    if (p==NULL)
      p=GWEN_Crypt_Token_Context_GetSystemId(ctx);
    if (p)
      GWEN_DB_SetCharValue(cfg, GWEN_DB_FLAGS_DEFAULT,
			   "SecDetails/SecId", p);
    else {
      GWEN_DB_SetCharValue(cfg, GWEN_DB_FLAGS_DEFAULT,
			   "SecDetails/SecId", "0");
    }
  }

  /* retrieve control reference for sigtail (to be used later) */
  p=GWEN_DB_GetCharValue(cfg, "ctrlref", 0, "");
  if (strlen(p)>=sizeof(ctrlref)) {
    DBG_INFO(AQHBCI_LOGDOMAIN, "Control reference too long (14 bytes maximum)");
    GWEN_DB_Group_free(cfg);
    return -1;
  }
  strcpy(ctrlref, p);

  /* create SigHead */
  hbuf=GWEN_Buffer_new(0, 128+GWEN_Buffer_GetUsedBytes(rawBuf), 0, 1);
  GWEN_DB_SetIntValue(cfg, GWEN_DB_FLAGS_DEFAULT,
                      "head/seq", hmsg->firstSegment-1);
  GWEN_DB_SetIntValue(cfg, GWEN_DB_FLAGS_DEFAULT,
		      "signseq",
                      GWEN_Crypt_Token_KeyInfo_GetSignCounter(ki));

  /* create signature head segment */
  rv=GWEN_MsgEngine_CreateMessageFromNode(e, node, hbuf, cfg);
  GWEN_DB_Group_free(cfg);
  cfg=0;
  if (rv) {
    DBG_INFO(AQHBCI_LOGDOMAIN, "Could not create SigHead");
    GWEN_Buffer_free(hbuf);
    return rv;
  }

  /* remember size of sighead for now */
  l=GWEN_Buffer_GetUsedBytes(hbuf);

  /* add raw data to to-sign data buffer */
  GWEN_Buffer_AppendBuffer(hbuf, rawBuf);

  /* sign message */
  sigbuf=GWEN_Buffer_new(0, 512, 0, 1);
  if (1) {
    uint32_t signLen;
    GWEN_CRYPT_PADDALGO *algo;
    GWEN_MDIGEST *md;
    uint32_t seq;

    /* hash sighead + data */
    md=GWEN_MDigest_Rmd160_new();
    rv=GWEN_MDigest_Begin(md);
    if (rv==0)
      rv=GWEN_MDigest_Update(md,
			     (uint8_t*)GWEN_Buffer_GetStart(hbuf),
			     GWEN_Buffer_GetUsedBytes(hbuf));
    if (rv==0)
      rv=GWEN_MDigest_End(md);
    if (rv<0) {
      DBG_ERROR(AQHBCI_LOGDOMAIN, "Hash error (%d)", rv);
      GWEN_MDigest_free(md);
      GWEN_Buffer_free(sigbuf);
      GWEN_Buffer_free(hbuf);
      return rv;
    }

    /* sign hash */
    algo=GWEN_Crypt_PaddAlgo_new(GWEN_Crypt_PaddAlgoId_Iso9796_2);
    GWEN_Crypt_PaddAlgo_SetPaddSize(algo, GWEN_Crypt_Token_KeyInfo_GetKeySize(ki));
    signLen=GWEN_Buffer_GetMaxUnsegmentedWrite(sigbuf);
    rv=GWEN_Crypt_Token_Sign(ct, keyId,
			     algo,
			     GWEN_MDigest_GetDigestPtr(md),
			     GWEN_MDigest_GetDigestSize(md),
			     (uint8_t*)GWEN_Buffer_GetPosPointer(sigbuf),
			     &signLen,
			     &seq,
			     gid);
    GWEN_Crypt_PaddAlgo_free(algo);
    GWEN_MDigest_free(md);
    if (rv) {
      DBG_ERROR(AQHBCI_LOGDOMAIN,
		"Could not sign data with medium of user \"%s\" (%d)",
		AB_User_GetUserId(su), rv);
      GWEN_Buffer_free(sigbuf);
      GWEN_Buffer_free(hbuf);
      return rv;
    }
    GWEN_Buffer_IncrementPos(sigbuf, signLen);
    GWEN_Buffer_AdjustUsedBytes(sigbuf);
  }
  DBG_DEBUG(AQHBCI_LOGDOMAIN, "Signing done");

  /* insert new SigHead at beginning of message buffer */
  DBG_DEBUG(AQHBCI_LOGDOMAIN, "Inserting signature head");
  GWEN_Buffer_Rewind(hmsg->buffer);
  GWEN_Buffer_InsertBytes(hmsg->buffer, GWEN_Buffer_GetStart(hbuf), l);

  /* create sigtail */
  DBG_DEBUG(AQHBCI_LOGDOMAIN, "Completing signature tail");
  cfg=GWEN_DB_Group_new("sigtail");
  GWEN_Buffer_Reset(hbuf);
  GWEN_DB_SetIntValue(cfg, GWEN_DB_FLAGS_DEFAULT,
                      "head/seq", hmsg->lastSegment+1);
  /* store to DB */
  GWEN_DB_SetBinValue(cfg, GWEN_DB_FLAGS_DEFAULT,
                      "signature",
                      GWEN_Buffer_GetStart(sigbuf),
                      GWEN_Buffer_GetUsedBytes(sigbuf));
  GWEN_Buffer_free(sigbuf);
  GWEN_DB_SetCharValue(cfg, GWEN_DB_FLAGS_DEFAULT,
		       "ctrlref", ctrlref);

  /* get node */
  node=GWEN_MsgEngine_FindNodeByPropertyStrictProto(e,
						    "SEG",
						    "id",
						    0,
						    "SigTail");
  if (!node) {
    DBG_INFO(AQHBCI_LOGDOMAIN, "Segment \"SigTail\"not found");
    GWEN_Buffer_free(hbuf);
    GWEN_DB_Group_free(cfg);
    return -1;
  }
  rv=GWEN_MsgEngine_CreateMessageFromNode(e, node, hbuf, cfg);
  if (rv) {
    DBG_INFO(AQHBCI_LOGDOMAIN, "Could not create SigTail");
    GWEN_Buffer_free(hbuf);
    GWEN_DB_Group_free(cfg);
    return -1;
  }

  /* append sigtail */
  DBG_DEBUG(AQHBCI_LOGDOMAIN, "Appending signature tail");
  if (GWEN_Buffer_AppendBuffer(hmsg->buffer, hbuf)) {
    DBG_INFO(AQHBCI_LOGDOMAIN, "here");
    GWEN_Buffer_free(hbuf);
    GWEN_DB_Group_free(cfg);
    return -1;
  }
  DBG_DEBUG(AQHBCI_LOGDOMAIN, "Appending signature tail: done");

  GWEN_Buffer_free(hbuf);
  GWEN_DB_Group_free(cfg);

  /* adjust segment numbers (for next signature and message tail */
  hmsg->firstSegment--;
  hmsg->lastSegment++;

  return 0;
}
示例#9
0
int GWEN_Crypt_Token_PluginManager_CheckToken(GWEN_PLUGIN_MANAGER *pm,
                                              GWEN_CRYPT_TOKEN_DEVICE devt,
                                              GWEN_BUFFER *typeName,
                                              GWEN_BUFFER *tokenName,
                                              uint32_t guiid)
{
  GWEN_PLUGIN_DESCRIPTION_LIST2 *pdl;

  assert(pm);

  pdl=GWEN_Crypt_Token_PluginManager_GetPluginDescrs(pm, devt);
  if (pdl==NULL) {
    DBG_ERROR(GWEN_LOGDOMAIN, "No plugin descriptions found for this device type");
    GWEN_Gui_ProgressLog(guiid,
                         GWEN_LoggerLevel_Error,
                         I18N("No plugin found for this device type"));
    GWEN_Gui_ProgressLog(guiid,
                         GWEN_LoggerLevel_Error,
                         I18N("If you're using a Debian/Ubuntu based system "
                              "please consider to install package "
                              LIBCHIPCARD_GWENHYWFAR_PLUGIN_PACKAGE));
    return GWEN_ERROR_NOT_FOUND;
  }
  else {
    GWEN_PLUGIN_DESCRIPTION_LIST2_ITERATOR *pit;

    pit=GWEN_PluginDescription_List2_First(pdl);
    if (pit) {
      GWEN_PLUGIN_DESCRIPTION *pd;
      uint32_t progressId;
      unsigned int pdcount;
      unsigned int cnt=0;

      pdcount=GWEN_PluginDescription_List2_GetSize(pdl);
      progressId=GWEN_Gui_ProgressStart(GWEN_GUI_PROGRESS_DELAY |
                                        GWEN_GUI_PROGRESS_ALLOW_EMBED |
                                        GWEN_GUI_PROGRESS_SHOW_PROGRESS |
                                        GWEN_GUI_PROGRESS_SHOW_LOG |
                                        GWEN_GUI_PROGRESS_ALWAYS_SHOW_LOG |
                                        GWEN_GUI_PROGRESS_SHOW_ABORT,
                                        I18N("Determining plugin module..."),
                                        NULL,
                                        pdcount,
                                        guiid);

      pd=GWEN_PluginDescription_List2Iterator_Data(pit);
      assert(pd);
      while (pd) {
        GWEN_XMLNODE *n;
        int err;
        GWEN_PLUGIN *pl;
        char logbuffer[256];

        n=GWEN_PluginDescription_GetXmlNode(pd);
        assert(n);

        snprintf(logbuffer, sizeof(logbuffer)-1,
                 I18N("Loading plugin \"%s\""),
                 GWEN_PluginDescription_GetName(pd));
        logbuffer[sizeof(logbuffer)-1]=0;
        GWEN_Gui_ProgressLog(progressId,
                             GWEN_LoggerLevel_Notice,
                             logbuffer);

        /* device type matches, check this plugin */
        pl=GWEN_PluginManager_GetPlugin(pm, GWEN_PluginDescription_GetName(pd));
        if (pl) {
          GWEN_BUFFER *lTokenName;
          int rv;

          lTokenName=GWEN_Buffer_dup(tokenName);

          snprintf(logbuffer, sizeof(logbuffer)-1,
                   I18N("Checking plugin \"%s\""),
                   GWEN_Plugin_GetName(pl));
          logbuffer[sizeof(logbuffer)-1]=0;
          GWEN_Gui_ProgressLog(progressId,
                               GWEN_LoggerLevel_Notice,
                               logbuffer);

          DBG_INFO(GWEN_LOGDOMAIN,
                   "Checking plugin \"%s\" for [%s]",
                   GWEN_Plugin_GetName(pl),
                   GWEN_Buffer_GetStart(lTokenName));

          rv=GWEN_Crypt_Token_Plugin_CheckToken(pl, lTokenName);
          switch (rv) {
          case 0:
            /* responsive plugin found */
            snprintf(logbuffer, sizeof(logbuffer)-1,
                     I18N("Plugin \"%s\" supports this token"),
                     GWEN_Plugin_GetName(pl));
            logbuffer[sizeof(logbuffer)-1]=0;
            err=GWEN_Gui_ProgressLog(progressId,
                                     GWEN_LoggerLevel_Notice,
                                     logbuffer);
            if (err==GWEN_ERROR_USER_ABORTED) {
              GWEN_Gui_ProgressEnd(progressId);
              GWEN_Buffer_free(lTokenName);
              GWEN_PluginDescription_List2Iterator_free(pit);
              GWEN_PluginDescription_List2_freeAll(pdl);
              return err;
            }

            GWEN_Buffer_Reset(typeName);
            GWEN_Buffer_AppendString(typeName, GWEN_Plugin_GetName(pl));
            GWEN_Buffer_Reset(tokenName);
            GWEN_Buffer_AppendBuffer(tokenName, lTokenName);
            GWEN_Buffer_free(lTokenName);
            GWEN_PluginDescription_List2Iterator_free(pit);
            GWEN_PluginDescription_List2_freeAll(pdl);
            GWEN_Gui_ProgressEnd(progressId);
            return 0;

          case GWEN_ERROR_NOT_IMPLEMENTED:
            snprintf(logbuffer, sizeof(logbuffer)-1,
                     I18N("Plugin \"%s\": Function not implemented"),
                     GWEN_Plugin_GetName(pl));
            logbuffer[sizeof(logbuffer)-1]=0;
            GWEN_Gui_ProgressLog(progressId,
                                 GWEN_LoggerLevel_Notice,
                                 logbuffer);
            break;

          case GWEN_ERROR_NOT_SUPPORTED:
            snprintf(logbuffer, sizeof(logbuffer)-1,
                     I18N("Plugin \"%s\" does not support this token"),
                     GWEN_Plugin_GetName(pl));
            logbuffer[sizeof(logbuffer)-1]=0;
            GWEN_Gui_ProgressLog(progressId,
                                 GWEN_LoggerLevel_Info,
                                 logbuffer);
            break;

          case GWEN_ERROR_BAD_NAME:
            snprintf(logbuffer, sizeof(logbuffer)-1,
                     I18N("Plugin \"%s\" supports this token, but the name "
                          "did not match"),
                     GWEN_Plugin_GetName(pl));
            logbuffer[sizeof(logbuffer)-1]=0;
            GWEN_Gui_ProgressLog(progressId,
                                 GWEN_LoggerLevel_Info,
                                 logbuffer);
            break;

          default:
            snprintf(logbuffer, sizeof(logbuffer)-1,
                     I18N("Plugin \"%s\": Unexpected error (%d)"),
                     GWEN_Plugin_GetName(pl), rv);
            logbuffer[sizeof(logbuffer)-1]=0;
            GWEN_Gui_ProgressLog(progressId,
                                 GWEN_LoggerLevel_Info,
                                 logbuffer);
            break;
          } /* switch */
        } /* if plugin loaded */
        else {
          snprintf(logbuffer, sizeof(logbuffer)-1,
                   I18N("Could not load plugin \"%s\""),
                   GWEN_PluginDescription_GetName(pd));
          logbuffer[sizeof(logbuffer)-1]=0;
          GWEN_Gui_ProgressLog(progressId,
                               GWEN_LoggerLevel_Warning,
                               logbuffer);
        }

        cnt++;
        err=GWEN_Gui_ProgressAdvance(progressId, cnt);
        if (err) {
          DBG_INFO(GWEN_LOGDOMAIN, "User aborted");
          GWEN_Gui_ProgressEnd(progressId);
          GWEN_PluginDescription_List2Iterator_free(pit);
          GWEN_PluginDescription_List2_freeAll(pdl);
          GWEN_Gui_ProgressEnd(progressId);
          return err;
        }

        pd=GWEN_PluginDescription_List2Iterator_Next(pit);
      }

      GWEN_Gui_ProgressEnd(progressId);
      GWEN_PluginDescription_List2Iterator_free(pit);
    }
    GWEN_PluginDescription_List2_freeAll(pdl);
  }

  return GWEN_ERROR_NOT_SUPPORTED;
}
示例#10
0
int GWEN_XMLNode_GetXPath(const GWEN_XMLNODE *n1,
                          const GWEN_XMLNODE *n2,
                          GWEN_BUFFER *nbuf) {
  GWEN_BUFFER *lbuf;
  const GWEN_XMLNODE *ln1;
  const GWEN_XMLNODE *ln2;

  if (!n1 && !n2) {
    DBG_ERROR(GWEN_LOGDOMAIN, "Both nodes are NULL");
    return -1;
  }

  if (!n1) {
    n1=n2;
    while(n1->parent)
      n1=n1->parent;
  }

  if (!n2) {
    n2=n1;
    while(n2->parent)
      n2=n2->parent;
  }

  if (n2==n1) {
    GWEN_Buffer_AppendString(nbuf, "here()");
    return 0;
  }

  lbuf=GWEN_Buffer_new(0, 256, 0, 1);
  GWEN_Buffer_ReserveBytes(lbuf, 128);

  ln1=n1->parent;
  if (ln1) {
    GWEN_Buffer_AppendString(lbuf, "../");
    while(ln1) {
      if (ln1==n2) {
        /* found n2 */
        GWEN_Buffer_AppendBuffer(nbuf, lbuf);
        GWEN_Buffer_free(lbuf);
        return 0;
      }
      if (GWEN_XMLNode_IsChildOf(ln1, n2))
        break;
      ln1=ln1->parent;
      GWEN_Buffer_AppendString(lbuf, "../");
    }

    if (!ln1) {
      DBG_ERROR(GWEN_LOGDOMAIN, "Nodes do not share root node");
      GWEN_Buffer_free(lbuf);
      return -1;
    }

    /* append path to n1 */
    GWEN_Buffer_AppendBuffer(nbuf, lbuf);
  }
  DBG_ERROR(GWEN_LOGDOMAIN, "Path so far: %s", GWEN_Buffer_GetStart(lbuf));

  /* get path to n2 */
  GWEN_Buffer_Reset(lbuf);

  ln2=n2;
  while(ln2) {
    GWEN_XMLNODE *tn;
    int idx;
    char idxbuf[32];

    if (ln2->parent==ln1)
      break;

    /* count occurences of this tag in this level */
    idx=1;
    tn=ln2->parent;
    if (tn) {
      tn=GWEN_XMLNode_FindFirstTag(tn, ln2->data, 0, 0);

      while(tn) {
        if (tn==ln2)
          break;
        idx++;
        tn=GWEN_XMLNode_FindNextTag(tn, ln2->data, 0, 0);
      }
    }

    snprintf(idxbuf, sizeof(idxbuf), "[%d]", idx);
    idxbuf[sizeof(idxbuf)-1]=0;
    GWEN_Buffer_InsertString(lbuf, idxbuf);
    GWEN_Buffer_InsertString(lbuf, GWEN_XMLNode_GetData(ln2));
    GWEN_Buffer_InsertByte(lbuf, '/');
    ln2=ln2->parent;
  }
  DBG_ERROR(GWEN_LOGDOMAIN, "Path so far: %s", GWEN_Buffer_GetStart(lbuf));
  assert(ln2);

  /* append path to n2 */
  GWEN_Buffer_AppendBuffer(nbuf, lbuf);
  GWEN_Buffer_free(lbuf);
  return 0;
}