Ir para conteúdo
  • Cadastre-se

dev botao

  • Este tópico foi criado há 1962 dias atrás.
  • Talvez seja melhor você criar um NOVO TÓPICO do que postar uma resposta aqui.

Recommended Posts

Postado

Olá Pessoal, 

Estou obtendo o erro strdup function failed ao realizar a assinatura do pedido de cancelamento utilizando XmlSec .

Testando com msXml consigo realizar o pedido de cancelamento e funciona perfeitamente.

Pelo que pude conferir a estrutura do XML está correta, conforme o exemplo disponibilizado pelo provedor, inclusive o atributo Id. 

Segue em anexo os XML de exemplo, cancelamento autorizado(msXml) e cancelamento com erro (XmlSec) .

Caso alguém tiver alguma sugestão fico agradecido.

Exemplo Cancelamento.xml Cancelamento erro assinatura.XML Cancelamento Autorizado.xml

  • 2 meses depois ...
Postado

Voltei a analisar essa situação e consegui autorizar o cancelamento, no entanto, gostaria de trocar uma ideia para ver a forma correta de resolver essa situação, pois da forma que fiz foi apenas um teste.

1) ALTERADO ARQUIVO ISSJoinville.ini

[Cancelar]
IncluiEncodingCab=0
IncluiEncodingDados=0
DocElemento=Pedido
InfElemento=InfPedidoCancelamento //Adicionei esta linha 
Texto1=<soapenv:Envelope xmlns="%NameSpace%/" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
Texto2=<soapenv:Body>
Texto3=%DadosMsg%
Texto4=</soapenv:Body>
Texto5=</soapenv:Envelope>

Suspeitei que o erro strdup function failed ocorria pelo fato de não ter o <!DOCTYPE Teste> no XML, portanto inclui o InfElemento para ser adicionado o DOCTYPE, coforme  o metodo de assinatura (TDFeSSLXmlSignXmlSec.Assinar)

/*cDTD é a constante do DOCTYPE*/ 
if InfElement <> '' then
  begin
    IdAttr_temp := IfEmptyThen(IdAttr, 'Id');

    DTD := StringReplace(cDTD, '&infElement&', InfElement, []);
    DTD := StringReplace(DTD, '&IdAttribute&', IdAttr_temp, []);

    AXml := InserirDTD(AXml, DTD);
  end;

Resolveu o erro strdup function failed, porém, o WS estava retornando erro de assinatura.

Analisando o XML assinado pude verificar que a TAG de assinatura estava sendo colocado no local errado, estava sendo inserida dentro da tag <CancelarNfseEnvio>, porém deveria ser dentro da TAG <Pedido> (docElement).

OBS: Em anexo consta o XML com a assinatura na TAG correta e a assinatura sendo inserida na TAG incorreta.

Ao depurar mais a fundo as rotinas encontrei a função XmlSecSign, onde verifica se já existe a TAG de assinatura no XML, caso contrario cria uma nova.

Na função para criar o node de assinatura (AdicionarNode) é encontrado o elemento para ser inserido a assinatura através do parâmetro docElement.

function TDFeSSLXmlSignLibXml2.AdicionarNode(var aDoc: xmlDocPtr;
  const ConteudoXML: String; docElement: String): xmlNodePtr;
Var
  NewNode, DocNode: xmlNodePtr;
  memDoc: xmlDocPtr;
  NewNodeXml, vdocElement: String;
begin
{$IFNDEF COMPILER23_UP}
  Result := nil;
{$ENDIF}
  NewNode := nil;
  memDoc := nil;
  try
    NewNodeXml := '<a>' + ConteudoXML + '</a>';
    memDoc := xmlReadMemory(PAnsiChar(AnsiString(NewNodeXml)), Length(NewNodeXml), nil, nil, 0);
    NewNode := xmlDocCopyNode(xmlDocGetRootElement(memDoc), aDoc.doc, 1);
    DocNode := xmlDocGetRootElement(aDoc);

    { Se docElement possui prefixo o mesmo tem que ser removido }
    vdocElement := copy(docElement, Pos(':', docElement) + 1, Length(docElement));

    if (vdocElement <> '') then
      DocNode := LibXmlLookUpNode(DocNode, vdocElement);

    if (DocNode = nil) then
      raise EACBrDFeException.Create(cErrElementsNotFound);

    Result := xmlAddChildList(DocNode, NewNode.children);
  finally
    if NewNode <> nil then
    begin
      NewNode.children := nil;
      NewNode.last := nil;
      xmlFreeNode(NewNode);
    end;

    if (memDoc <> nil) then
      xmlFreeDoc(memDoc);
  end;
end;

O erro esta ocorrendo pois na chamada da função AdicionarNode não é passado o docElement (Pedido), por este motivo é inserido a tag de assinatura na TAG <CancelarNfseEnvio> ao invés da tag <Pedido>.

SignNode := LibXmlFindSignatureNode(aDoc, SignatureNode, SelectionNamespaces, infElement);
if (SignNode = nil) then
  SignNode := AdicionarNode(aDoc, SignatureElement(URI, True, IdSignature, FpDFeSSL.SSLDgst));

Para fazer um teste alterei o ultimo parâmetro da função passando o DocElement (Pedido) que seria a TAG onde a assinatura deveria ser inserida.

SignNode := AdicionarNode(aDoc, SignatureElement(URI, True, IdSignature, FpDFeSSL.SSLDgst),'Pedido');

Dessa forma conseguir autorizar o cancelamento, porém tenho total certeza que não é a forma certa de resolver, gostaria de uma sugestão dos entendidos no assunto, estou tentando o possível aqui.

 

Grato!

XML Com assinatura no local errado.xml XML assinatura no local certo.xml

  • Consultores
Postado

Boa tarde João,

Já passei para o pessoal analisar a sua alteração no que diz respeito a unit.

Deste já muito obrigado pela colaboração.

Uma pergunta: porque você ainda usa o XsXmlSeg em vez de XsLibXml2?

  • Curtir 1
Consultor SAC ACBr

Italo Giurizzato Junior
Ajude o Projeto ACBr crescer - Assine o SAC

Projeto ACBr

Analista de Sistemas / Araraquara-SP

Araraquara - A era dos Trólebus

Postado (editado)

Bom dia, 

Certo Italo, Obrigado!

Referente a Lib, estou mantendo a Sec pois nos demais módulo do sistema é utilizado essa lib.

Na verdade não fui muito a fundo ainda para entender a diferença entre as duas e possivelmente realizar a migração.

Para utilizar a Xml2 preciso alterar apenas as Dlls da aplicação? Quais seriam as vantagens da xml2?

Editado por João Paulo Müller
  • Este tópico foi criado há 1962 dias atrás.
  • Talvez seja melhor você criar um NOVO TÓPICO do que postar uma resposta aqui.

Crie uma conta ou entre para comentar

Você precisar ser um membro para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar Agora
×
×
  • Criar Novo...

Informação Importante

Colocamos cookies em seu dispositivo para ajudar a tornar este site melhor. Você pode ajustar suas configurações de cookies, caso contrário, assumiremos que você está bem para continuar.