Ir para conteúdo
  • Cadastre-se

Delcio Sbeghen

Membros
  • Total de ítens

    16
  • Registro em

  • Última visita

Últimos Visitantes

1.442 visualizações

Delcio Sbeghen's Achievements

Apprentice

Apprentice (3/14)

  • First Post
  • Collaborator Rare
  • Conversation Starter
  • Week One Done
  • One Month Later

Recent Badges

4

Reputação

  1. Aconteceu hoje com um cliente que renovou o certificado dos correios a alguns dias, imagino que seja possível um vírus estar causando esse transtorno, vejam no código abaixo como é fácil excluir a chave privada de um certificado: function Remove-PrivateKey { [CmdletBinding()] param( [Parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] [Security.Cryptography.X509Certificates.X509Certificate2[]]$Certificate ) begin { # define unmanaged functions to retrieve private key information and delete the key. $signature = @" [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] public static extern bool CryptAcquireContext( ref IntPtr phProv, string pszContainer, string pszProvider, uint dwProvType, long dwFlags ); [DllImport("Crypt32.dll", SetLastError = true, CharSet = CharSet.Auto)] public static extern bool CryptAcquireCertificatePrivateKey( IntPtr pCert, uint dwFlags, IntPtr pvReserved, ref IntPtr phCryptProv, ref uint pdwKeySpec, ref bool pfCallerFreeProv ); [DllImport("NCrypt.dll", CharSet = CharSet.Auto, SetLastError = true)] public static extern int NCryptDeleteKey( IntPtr hKey, uint dwFlags ); [DllImport("Crypt32.dll", SetLastError = true, CharSet = CharSet.Auto)] public static extern bool CertGetCertificateContextProperty( IntPtr pCertContext, uint dwPropId, IntPtr pvData, ref uint pcbData ); [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)] public struct CRYPT_KEY_PROV_INFO { [MarshalAs(UnmanagedType.LPWStr)] public string pwszContainerName; [MarshalAs(UnmanagedType.LPWStr)] public string pwszProvName; public uint dwProvType; public uint dwFlags; public uint cProvParam; public IntPtr rgProvParam; public uint dwKeySpec; } "@ Add-Type -MemberDefinition $signature -Namespace PKI -Name PfxTools $CERT_KEY_PROV_INFO_PROP_ID = 0x2 $CRYPT_DELETEKEYSET = 0x10 $CRYPT_ACQUIRE_ONLY_NCRYPT_KEY_FLAG = 0x40000 } process { foreach ($cert in $Certificate) { # if the current certificate do not have private key -- skip if (!$cert.HasPrivateKey) {return} # if we reach this far and PrivateKey is $null -- the key is CNG key. if ($cert.PrivateKey -eq $null) { $phCryptProv = [IntPtr]::Zero $dwFlags = $CRYPT_ACQUIRE_ONLY_NCRYPT_KEY_FLAG $pdwKeySpec = 0 $pfCallerFreeProv = $false if (![PKI.PfxTools]::CryptAcquireCertificatePrivateKey( $cert.Handle, $dwFlags, 0, [ref]$phCryptProv, [ref]$pdwKeySpec, [ref]$pfCallerFreeProv)) {return} $hresult = [PKI.PfxTools]::NCryptDeleteKey($phCryptProv,0) if ($hresult -ne 0) { $message = "Cert '{0}' failed: {1}" -f $cert.Thumbprint, (New-Object ComponentModel.Win32Exception $hresult).Message Write-Warning $message } } else { # if the key is legacy, then just read the PrivateKey object of the X509Certificate2 object $phProv = [IntPtr]::Zero if (![PKI.PfxTools]::CryptAcquireContext( [ref]$phProv, $cert.PrivateKey.CspKeyContainerInfo.KeyContainerName, $cert.PrivateKey.CspKeyContainerInfo.ProviderName, $cert.PrivateKey.CspKeyContainerInfo.ProviderType, $CRYPT_DELETEKEYSET)) { $hresult = [Runtime.InteropServices.Marshal]::GetLastWin32Error() $message = "Cert '{0}' failed: {1}" -f $cert.Thumbprint, (New-Object ComponentModel.Win32Exception $hresult).Message Write-Warning $message } } } } } The usage is pretty simple: just pass a certificate object, and the function will delete private key when necessary. The function performs all required checks to properly handle various scenarios. Few considerations should be taken into account prior to using this function: This function DO NOT delete certificate from the store. The whole purpose of this function is to delete the private key. If two or more certificates share the same key, all they will stop working. If the key is stored on a hardware (smart card, HSM), the function call may raise a PIN dialog, where you will have to enter the PIN to access the private key. O código foi retirado de https://www.sysadmins.lv/blog-en/how-to-properly-delete-certificate-with-private-key-in-powershell.aspx e não testei se funciona com os tokens que usamos, mas a hora que tiver um tempo vou gravar uns certificados fakes em uns cartões que tenho aqui e testar. Isso prova a facilidade em excluir objetos no token, e qualquer coisa pode ser o culpado, inclusive um vírus. Só acho inadmissível essa fragilidade nos certificados.
  2. Em breve novidades quanto a isso, só não sei se vou conseguir manter open source, pelo fato de que precisava que o ele estivesse funcional o mais rápido possível, para dar continuidade no desenvolvimento do meu sistema comercial que é baseado nele. Trabalhei uns 3 meses sozinho nele, e vi que seria um projeto muito grande, iria demorar demais para tocar sozinho então acabei fechando uma parceria com mais duas empresas para desenvolver o framework e para conseguir essa parceria uma das exigências foi que fosse removido do Github pois havia interesse por parte dos parceiros em torná-lo um produto comercial, mesmo assim foram uns 6 meses para chegar em um estágio funcional, com uma boa paleta de componentes, praticamente todos os componentes do Bootstrap, falta apenas remover alguns bugs e efetuar mais testes. Estou com o meu sistema bem adiantado já, assim que tiver online coloco um link de demonstração. Qualquer novidade no sentido do licenciamento informarei aqui.
  3. Caso a NFe estivesse denegada, no DANFE imprimia 'PROTOCOLO DE AUTORIZAÇÃO DE USO' adicionei condição para imprimir 'PROTOCOLO DE DENEGAÇÃO DE USO' if ((FDANFEClassOwner.NFeCancelada) or (FNFe.procNFe.cStat in [101,151,155])) then FieldByName('Contingencia_Descricao').AsString := 'PROTOCOLO DE HOMOLOGAÇÃO DO CANCELAMENTO' else if ( FNFe.procNFe.cStat = 110 ) or ( FNFe.procNFe.cStat = 301 ) or ( FNFe.procNFe.cStat = 302 ) or ( FNFe.procNFe.cStat = 303 ) then FieldByName('Contingencia_Descricao').AsString := 'PROTOCOLO DE DENEGAÇÃO DE USO' else FieldByName('Contingencia_Descricao').AsString := 'PROTOCOLO DE AUTORIZAÇÃO DE USO'; Se alguém puder verificar e fazer o commit. ACBrNFeDANFEFRDM.pas
  4. É colega Italo, me exaltei um pouco mesmo, o difícil é achar um cliente que receba todos os XML dos fornecedores. oque me chateia é que antes funcionava tudo certo, tinha o status das notas recebidas, agora preciso de todos os es eventos para saber se a NFe está cancelada, e como não recebo todos, todo dia tem cliente meu ligando que a nota que ele recebeu foi cancelada e no sistema consta como autorizada. Aí o fornecedor não cumpre a legislação, a SEFAZ não cumpre os prazos que ela mesmo impõe e eu fico no fogo cruzado rsrsr.
  5. Parece que é o WebService que não está retornando, pois também não estou recebendo eventos de cancelamento, tenho algumas notas de fornecedores meus que foram canceladas, as quais recebi o resumo da NFe, recebi também a NFe, mas não recebi o evento de cancelamento. Acabei de verificar em todos os retornos, e realmente tenho todos os NSUs, quer dizer: sequer foi gerado um NSU na SEFAZ para esses eventos de cancelamento. Esse novo WebService tá uma bela duma porcaria. Como confiar num negócio que não retorna todos os documentos?
  6. Em apenas um cliente ocorria AV ao ao executar qualquer operação com danfe(imprimir, imprimirPdf, enviarEmail), nos outros tudo normal. Depois de muito penar e perder mais de meio dia nisso, acabei instalando o eurekalog e verifiquei que o AV ocorria na criação do ClientDataset no método TdmACBrNFeFR.CarregaIdentificacao, aí eu pensei: "MIDAS.DLL", provavelmente algum instalador alterou a versão dela. Coloquei a versão correta na pasta do aplicativo e não resolveu, substituí a do System32 e resolveu o problema. Caso alguém tenha um problema semelhante, pode ser isso. Uma sugestão para testar se pode-se evitar o uso da midas.dll adicionando a unit MidasLib na uses do componente.
  7. O delphi retorna o erro de conversão: Exception class EVariantTypeCastError with message 'Could not convert variant of type (String) into type (Double)'. Process AcbrBoletoDemo.exe (1752) Nos arquivos de relatório: Boleto.fr3 BoletoCarne.fr3 BoletoFatura.fr3 O BoletoFR.fr3 já foi corrigido no svn, mas esses outros três ainda não. GustavoKato anexou os arquivos com as modificações, pra mim funcionou perfeitamente, se alguém puder verificar e dar um commit. Mais informações no final do tópico: Grato a todos
  8. Olá pessoal. Favor Adicionar 4213153 - Planalto Alegre/SC - provedor Betha Grato
  9. Depois de quebrar a cabeça, consegui mostrar o DANFE no meu Preview personalizado sem alterar os fontes do ACBR, não gosto de alterar os fontes, pois aí quando atualizo, vira bagunça e lá vem os bugs. Adicionei a seguinte procedure no formulario que contém o ACBRDANFE: procedure TNfe.PreviewPersonalizado(ReportSystem: TRvSystem; OverrideMode: TOverrideMode; var OverrideForm: TForm); begin Case OverrideMode Of omCreate: Begin OverrideForm := TFrmVisualizarImpressao.Create(Application.MainForm); OverrideForm.Caption := ReportSystem.TitlePreview; OverrideForm.Width := ReportSystem.SystemPreview.FormWidth; OverrideForm.Height := ReportSystem.SystemPreview.FormHeight; OverrideForm.WindowState := ReportSystem.SystemPreview.FormState; ReportSystem.SystemSetups:= ReportSystem.SystemSetups - [ssAllowSetup]; (OverrideForm As TFrmVisualizarImpressao).RvSystem1 := ReportSystem; End; omShow: Begin ReportSystem.SystemPreview.InitPreview((OverrideForm As TFrmVisualizarImpressao).RvRenderPreview1); If Assigned(ReportSystem.OnPreviewSetup) Then Begin ReportSystem.OnPreviewSetup((OverrideForm As TFrmVisualizarImpressao).RvRenderPreview1); End; { if } //(OverrideForm As TFrmVisualizarImpressao).FileName := ReportSystem.SystemFiler.Filename; (OverrideForm As TFrmVisualizarImpressao).Stream.LoadFromStream(ReportSystem.SystemFiler.Stream); //(OverrideForm As TFrmVisualizarImpressao).CarregaRvSystem; (OverrideForm As TFrmVisualizarImpressao).RvRenderPreview1.ZoomFactor:=150; (* *) If soPreviewModal In ReportSystem.SystemOptions Then Begin OverrideForm.ShowModal; End Else Begin OverrideForm.Show; End; { else } End; omWait: Begin If Not (soPreviewModal In ReportSystem.SystemOptions) Then Begin // Wait for close Repeat Sleep(250); Application.ProcessMessages; Until Not OverrideForm.Visible; End; { if } End; omFree: Begin If (ReportSystem.SystemFiler.StreamMode In [smTempFile, smFile]) Then Begin (OverrideForm As TFrmVisualizarImpressao).RvRenderPreview1.NDRStream.Free; (OverrideForm As TFrmVisualizarImpressao).RvRenderPreview1.NDRStream := Nil; End; { if } FreeAndNil(OverrideForm); End; End; { case } end; Depois de configurar o componente ACBRNFE, adicionei a seguinte linha: Danfe.dmDanfe.RvSystem1.OverridePreview:= RelPreviewPersonalizado; Segue em anexo o fonte do meu Preview personalizado para que quiser ter uma ideia. Não está pronto ainda, mas já dá pra ter uma noção de como funciona. uVisualizarImpressao.pas
  10. Italo, desculpe a demora, estava terminando outro módulo que estava atrasado... Para xml's de inutilização com assinatura, ele me retorna cstat=0, teste no xml em anexo. para que funcione tive que alterar a linha do leitor: de if leitor.rExtrai(1, ' infInut ') <> '' then para if leitor.rExtrai(1, 'retInutNFe') <> '' then aí me retorna cstat=102 acho que está lendo somente o primeiro bloco <InfInut, e o cstat está no segundo bloco, veja no anexo. Grato pela disposição em implementar. xml.xml UnitStatusInutNfe.pas
  11. Pessoal, acabei criando uma classe herdada fora dos fontes ACBR, não gosto de alterar os fontes ACBR localmente, pois cada vez que baixo as atualizações deles, dá confusão, assim criei a seguinte classe: unit UnitStatusInutNfe; interface uses classes, pcnRetInutNFe, pcnConversao; type TStatusInutNfe = class(TRetInutNFe) public function LoadFromStream(Stream:Tstringstream): boolean; end; implementation { TStatusInutNfe } function TStatusInutNfe.LoadFromStream(Stream:Tstringstream): boolean; var ok: boolean; begin Result := False; try //carrega o stream para o leitor acbr Leitor.Arquivo:= Stream.DataString; //lê os dados do leitor.arquivo e carrega no objeto if leitor.rExtrai(1, 'retInutNFe') <> '' then //Basicamente aqui está a diferença: de infInut para retInutNFe pois os retornos conforme o anexo tem 2 tags infInut e ele só lia a primeira deixando o cstat que está na segunda como 0 begin (*DR05 *)self.tpAmb := StrToTpAmb(ok, Leitor.rCampo(tcStr, 'tpAmb')); (*DR06 *)self.verAplic := Leitor.rCampo(tcStr, 'verAplic'); (*DR07 *)self.cStat := Leitor.rCampo(tcInt, 'cStat'); (*DR08 *)self.xMotivo := Leitor.rCampo(tcStr, 'xMotivo'); (*DR09 *)self.cUF := Leitor.rCampo(tcInt, 'cUF'); (*DR10 *)self.ano := Leitor.rCampo(tcInt, 'ano'); (*DR11 *)self.CNPJ := Leitor.rCampo(tcStr, 'CNPJ'); (*DR12 *)self.Modelo := Leitor.rCampo(tcInt, 'mod'); (*DR13 *)self.Serie := Leitor.rCampo(tcInt, 'serie'); (*DR14 *)self.nNFIni := Leitor.rCampo(tcInt, 'nNFIni'); (*DR15 *)self.nNFFin := Leitor.rCampo(tcInt, 'nNFFin'); (*DR16 *)self.dhRecbto := Leitor.rCampo(tcDatHor, 'dhRecbto'); (*DR17 *)self.nProt := Leitor.rCampo(tcStr, 'nProt'); Result := True; end; except result := False; end; end; end. A minha função que verifica o XML ficou assim: function TFrmGedNfe.VerificaStatusXml: string; var Inut:TStatusInutNfe; Stream:TStringStream; begin try //para nfe rejeitada if FrmFuncoes.nfe.NotasFiscais.Items[0].NFe.procNFe.cStat > 200 then begin Result:='NFE REJEITADA'; exit; end; //para outros cstat case FrmFuncoes.nfe.NotasFiscais.Items[0].NFe.procNFe.cStat of 100: Result:='AUTORIZADA'; 101: Result:='CANCELADA'; 102: Result:='NUM. INUTILIZADA'; //caso o cstat retorne 0 0: begin //testa se é xml de inutilização Stream:=TStringStream.Create; Stream.Clear; TBlobField(dm.TblGedNfe.FieldByName('xml')).SaveToStream(Stream); //carrega o xml no stream Inut:=TStatusInutNfe.Create; if Inut.LoadFromStream(Stream) then //carrega e lê o xml a partir do Stream begin if Inut.cStat = 102 then Result:='NUM. INUTILIZADA' else if Inut.cStat > 200 then Result:='INUT. REJEITADA' else Result:='DESCONHECIDA'; end; try FreeAndNil(Stream) except end; //depois de alguns problemas com try FreeAndNil(Inut) except end; //.free, passei a usar desta forma //assim, se o objeto por algum motivo não tiver sido criado, não me retorna //um AV e não preciso usar o assigned para testar se está instanciado. end; end; except Result:='DESCONHECIDA'; end; end; Agora funcionando, estou fazendo uns testes para ver se está tudo ok. Se alguém quiser adicionar o método TACBrNFe.InutNFe.LerXMLFromString(sXML); vai facilitar a vida de outros que por ventura vierem a precisar por hora vou utilizar desta forma. Obrigado a todos.
  12. Isso aí pessoal imaginei que seria por aí mesmo, apenas queria ter certeza que não existisse já essa implementação no acbr. As duas idéias foram bem vindas, vou utilizar as duas. Depois de pronto posto o código aí caso alguém mais precise. Por hora, obrigado pela atenção.
  13. Régys, Obrigado pela atenção, mas acho que não me expressei direito. O cenário é o seguinte: Tenho um sistema de gerenciamento eletrônico de documentos, nele existe uma tabela que armazena todos os xml importados pelo cliente, só que esses xml estão misturados, nfe autorizadas, canceladas, inutilizações de numeração. Preciso ler cada um desses xml e apresentar dados em um dbgrid, como por ex: Tipo de Xml, status, etc. Para isso carrego cada registro da tabela no acbrnfe e leio o cstat para poder saber se é Autorização, Cancelamento ou Inutilização. Para os xml de nfe autorizadas e canceladas, ele me retorna o cstat corretamente, mas quando carrego um xml de inutilização de numeração, ele me retorna cstat=0; A inutilização de numeração já foi processada, e tenho o xml dela, oque preciso é ler esse xml e obter o cstat.
  14. Pessoal não descobri como fazer para carregar um xml de Inutilização de numeração e obter o cstat tentei até fazer uma gambiarra aqui mas não deu certo: Stream:=TStringStream.Create; Stream.Clear; TBlobField(dm.TblGedNfe.FieldByName('xml')).SaveToStream(Stream); //carrega o xml Inut:=TRetInutNFe.Create; inut.Leitor.Arquivo:= Stream.DataString; if Inut.LerXml then begin if Inut.cStat = 102 then Result:='NUM. INUTILIZADA' else Result:='DESCONHECIDA'; end; Retorna cstat=0 Acho que devido essa parte do fonte do acbr: function TRetInutNFe.LerXml: boolean; var ok: boolean; begin Result := False; try if leitor.rExtrai(1, 'infInut') <> '' then //imagino que aqui deveria ser: if leitor.rExtrai(2, 'infInut') begin (*DR05 *)FtpAmb := StrToTpAmb(ok, Leitor.rCampo(tcStr, 'tpAmb')); (*DR06 *)FverAplic := Leitor.rCampo(tcStr, 'verAplic'); (*DR07 *)FcStat := Leitor.rCampo(tcInt, 'cStat'); (*DR08 *)FxMotivo := Leitor.rCampo(tcStr, 'xMotivo'); (*DR09 *)FcUF := Leitor.rCampo(tcInt, 'cUF'); (*DR10 *)Fano := Leitor.rCampo(tcInt, 'ano'); (*DR11 *)FCNPJ := Leitor.rCampo(tcStr, 'CNPJ'); (*DR12 *)FModelo := Leitor.rCampo(tcInt, 'mod'); (*DR13 *)FSerie := Leitor.rCampo(tcInt, 'serie'); (*DR14 *)FnNFIni := Leitor.rCampo(tcInt, 'nNFIni'); (*DR15 *)FnNFFin := Leitor.rCampo(tcInt, 'nNFFin'); (*DR16 *)FdhRecbto := Leitor.rCampo(tcDatHor, 'dhRecbto'); (*DR17 *)FnProt := Leitor.rCampo(tcStr, 'nProt'); Result := True; end; except result := False; end; end; Tem alguma maneira de fazer isso nativamente no componente ou o caminho criar uma nova classe baseada na TRetInutNFe mesmo? Segue em anexo xml Grato pela atenção. xml.xml
  15. Pessoal não descobri como fazer para carregar um xml de Inutilização de numeração e obter o cstat tentei até fazer uma gambiarra aqui mão não deu certo: Stream:=TStringStream.Create; Stream.Clear; TBlobField(dm.TblGedNfe.FieldByName('xml')).SaveToStream(Stream); Inut:=TRetInutNFe.Create; inut.Leitor.Arquivo:= Stream.DataString; if Inut.LerXml then begin if Inut.cStat = 102 then Result:='NUM. INUTILIZADA' else Result:='DESCONHECIDA'; end;
×
×
  • 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.