amagovpt / autenticacao.gov

Middleware Oficial de Identificação Eletrónica em Portugal - Cartão de Cidadão, da Chave Móvel Digital e Sistema de Certificação de atributos profissionais
https://www.autenticacao.gov.pt
European Union Public License 1.2
174 stars 33 forks source link

Dependencias em falta = Setup impossível? #181

Open GusGusGusGus opened 3 months ago

GusGusGusGus commented 3 months ago

Boas,

tenho um sistema Windows 10 e estou a usar .Net 7 na minha solução.

Windows

Tentei seguir o tutorial para Windows mas o processo de setup é extremamente difícil por exigir que façamos o build de cada uma das bibliotecas em separado, por vezes com metodologias completamente diferentes (estou a usar o make, cmake, nmake, msbuild, etc; por vezes certas bibliotecas exigem a presença de outras tambem). Não é de todo claro qual é o processo correcto para fazer isto functionar em qualquer máquina, garantidamente.
Para além disto e mais importante, o build da biblioteca libzip falha por não encontrar o ficheiro zconf.h. Ou seja tive que desistir deste setup...

Linux

Preso no passo acima descrito, tentei fazer tudo por Linux (Ubuntu WSL 20). Estava entusiasmado até chamar o passo "make" e o build não encontrar o pacote/library eac, bloqueando o resto do build... Eis o erro:

PaceAuthentication.cpp:8:10: fatal error: eac/eac.h: No such file or directory
    8 | #include "eac/eac.h"
      |          ^~~~~~~~~~~
compilation terminated.
make[1]: *** [Makefile:705: PaceAuthentication.o] Error 1
make[1]: Leaving directory '/a-minha-directoria-de-desenvolvimento/autenticacao.gov/pteid-mw-pt/_src/eidmw/cardlayer'
make: *** [Makefile:254: sub-cardlayer-cardlayer-pro-install_subtargets-ordered] Error 2

Já não sei o que fazer. Encontrei uma library que trata de questões semelhantes ao eac (que parece ser relativa à Pace Authentication), que está neste repo ( https://github.com/frankmorgner/openpace ) mas ainda assim, nem sei se é compatível e não sei como a integrar com este build (git clone do repo + make + make install + acidionar ao MakeFile? onde? e como?)

Não há um script qualquer, ou uma docker image que já detenha tudo o que é necessário e que garanta que todas as dependências actualizadas estão incluídas? Ou outra maneira mais acessível de fazer isto funcionar com .Net? Uma wrapper library? Qualquer coisa?!

Obrigado pela atenção

GusGusGusGus commented 3 months ago

Cuidado: para além do acima descrito, tenho este bot a enviar me zips maliciosos que nem são aceites pelo browser alguns segundos depois de partilhar a pergunta.... mais uma razão para haver maior simplicidade na instalação e fontes oficiais que sejam mais seguras... Agradeço toda e qualquer ajuda para fazer isto funcionar

agrr commented 2 months ago

Boa tarde, quanto à utilização do SDK em aplicações .net 7 e 8 temos previsto para a próxima versão um wrapper .net atualizado que irá permitir uma integração mais fácil a partir dos ficheiros incluidos no instalador Windows e também o suporte a sistemas MacOS.

Quanto à questão colocada sobre a compilação em Ubuntu: deve faltar a biblioteca openpace que pode instalar através do pacote Ubuntu libeac-dev ou manualmente a partir da release que está no Github: OpenPACE.

GusGusGusGus commented 2 months ago

Obrigado pela resposta rápida. Mas ainda assim, procurei com o apt install libeac-dev e nada foi encontrado. Já manualmente, o próprio projecto nao dá quaisquer indicações... Clonei o repo e apesar de haver um makefile.am fiz 'make' na directoria da openpace e deu nisto:

openpace[master]$ make
make: *** No targets specified and no makefile found.  Stop.
agrr commented 2 months ago

O pacote libeac-dev existe nos repositórios do Ubuntu 24.04: https://packages.ubuntu.com/noble/libeac-dev

No buildsystem do openpace (baseado em GNU Autotools) o script ./bootstrap serve para gerar os ficheiros necessários para compilar com make e instalar com make install

GusGusGusGus commented 2 months ago

Boa tarde @agrr ,

deixei de ter problemas ao actualizar o Ubuntu da versão 20 para a versão 24. Dessa forma o build já completou em Linux sem problemas.

Agora, tenho outros problemas. Vou tentar ser completo a explicar tudo o que tentei. O meu objectivo é chamar o binário e as libs a partir dum projecto de .Net 7 em Windows 10.

  1. Tentei compilar para Windows mas não foi possível (ver problemas acima).
  2. Compilei para Ubuntu 24, produzindo o binario e umas libs (formato .so). De seguida tentei fazer um ficheiro wrapper.py expondo o binário através de uma API feita em Flask que executo ao através de um dockerfile com base no meu Ubuntu com tudo o que é necessário:
FROM ubuntu:24.04

# Install necessary dependencies, including python3-venv to create virtual environments
RUN apt-get update && apt-get install -y \
    python3 \
    python3-pip \
    python3-venv \
    && rm -rf /var/lib/apt/lists/*

# Set the working directory
WORKDIR /app

# Create a Python virtual environment in the /opt/venv directory
RUN python3 -m venv /opt/venv

# Activate the virtual environment and upgrade pip, then install Flask
RUN /opt/venv/bin/pip install --upgrade pip && \
    /opt/venv/bin/pip install Flask

# Copy the binary and .so files into the container
COPY ./eidguiV2 /app/eid_build/eidguiV2
COPY ./lib/*.so /app/eid_build/lib/

# Copy the Python wrapper script
COPY ./wrapper.py /app/eid_build/wrapper.py

# Set environment variables
ENV LD_LIBRARY_PATH=/app

# Ensure that the virtual environment is activated by adding it to the PATH
ENV PATH="/opt/venv/bin:$PATH"

# Expose the port your HTTP server will listen on
EXPOSE 8080

# Run the Python wrapper script using the virtual environment's Python
CMD ["python3", "/app/eid_build/wrapper.py"]

Resutado: API não dá resposta e como é natural, não consigo chamar os métodos das libs .so compiladas (ainda assim, usando um descompilador dotPeek consigo ver tudo o que contêm). Estava com esperança que pelo menos conseguisse algum output que não fosse erro...

  1. Mesmo assim, voltando à base Windows, e não tendo como referenciar os métodos e os tipos presentes nas bibliotecas para permitir que não hajam erros de sintaxe antes da compilação do meu projecto .Net, vi-me forçado a fazer o download do SDK e a referenciar o ficheiro DLL para obter os tipos e metodos necessários ao meu projecto:

    <ItemGroup>
    <Reference Include="pteidlib_dotnet">
      <HintPath>C:\Program Files\Portugal Identity Card\sdk\dotnet\pteidlib_dotnet.dll</HintPath>
    </Reference>
    </ItemGroup>

Nesta fase, o meu serviço não demonstra erros de linting e a minha solução em .Net 7 compila, mas tenho uma excepção em runtime ao chamar os métodos de 'pteidlib_dotnet.dll' ao chamar:

try
        {
            PTEID_ReaderSet.initSDK();
            readerContext = PTEID_ReaderSet.instance().getReader();
            return true;
        }

Eis um excerto do meu serviço, baseado no SDK publicado neste repo, que quero fazer funcionar (e que, graças à project reference mencionada acima, já não possui erros de sintaxe):

using System;
using System.Text;
using pt.portugal.eid;
using API.Intefaces;

public class IDService : IIDService
{

    private PTEID_ReaderContext readerContext;
    private PTEID_EIDCard card;
    private const string CertPath = @"C:\Program Files\Portugal Identity Card\eidstore\certs";    // confirmei e tenho os certs nesta directoria

    public IDService()
    {
        // Set the certificate store path
        // PTEID_Config.SetCertDir(CertPath);
        PTEID_Config.SetTestMode(true);
        // this.readerContext = null;
        // this.card = null;
    }

    public void Start()
    {
        try
        {
            Initialize();
            ReadCard();
        }
        catch (PTEID_ExNoReader)
        {
            Console.WriteLine("No reader found.");
        }
        catch (PTEID_ExNoCardPresent)
        {
            Console.WriteLine("No card inserted.");
        }
        catch (PTEID_Exception ex)
        {
            Console.WriteLine(ex.GetMessage());
        }
        finally
        {
            Release();
            Console.ReadLine();
        }
    }

    public bool Initialize()
    {
        try
        {
            PTEID_ReaderSet.initSDK();
            readerContext = PTEID_ReaderSet.instance().getReader();
            return true;
        }
        catch (PTEID_Exception ex)
        {
            Console.WriteLine($"Failed to initialize SDK: {ex.Message}");
            return false;
        }
    }

    public bool ReadCard()
    {
        try
        {
            if (!readerContext.isCardPresent())
                return false;

            var contactInterface = readerContext.getCardContactInterface();
            var cardType = readerContext.getCardType();
            Console.WriteLine("Contact Interface:" + (contactInterface == PTEID_CardContactInterface.PTEID_CARD_CONTACTLESS ? "CONTACTLESS" : "CONTACT"));
            card = readerContext.getEIDCard();
            //If the contactInterface is contactless and the card supports contactless then authenticate with PACE
            if (contactInterface == PTEID_CardContactInterface.PTEID_CARD_CONTACTLESS && cardType == PTEID_CardType.PTEID_CARDTYPE_IAS5)
            {
                Console.WriteLine("Insert the Card access number (CAN) for the card in use: ");
                string can_str = Console.ReadLine();
                uint can_size = (uint)can_str.Length;
                card.initPaceAuthentication(can_str, can_size, PTEID_CardPaceSecretType.PTEID_CARD_SECRET_CAN);
            }

            PTEID_EId eid = card.getID();

            GetPersonalInformation(eid);

            ShowAddressInfo();

            ////CARD NOTES: Writting on the card
            ////Ler notas atuais e imprimir na consola
            //String my_notes = eidCard.readPersonalNotes();
            //Console.WriteLine("Current notes: " + my_notes);

            ////Escrever novas notas
            //String notes = "We wrote successfully to the card!";

            //byte[] notesBytes = Encoding.UTF8.GetBytes(notes);
            //PTEID_ByteArray personalNotes = new PTEID_ByteArray(notesBytes, (uint)notesBytes.Length);
            //Boolean ok;

            //PTEID_Pins pins = eidCard.getPins();
            //PTEID_Pin pin = pins.getPinByPinRef(PTEID_Pin.AUTH_PIN); // AUTH_PIN - Código de Autenticação

            //ok = eidCard.writePersonalNotes(personalNotes, pin);
            //Console.WriteLine("Was writing successful? " + (ok ? "Yes!" : "No."));

            return true;
        }
        catch (PTEID_Exception ex)
        {
            Console.WriteLine($"Failed to read card: {ex.Message}");
            return false;
        }
    }

.......
  1. Nesta fase estou a tentar correr as libraries dentro do meu WSL Ubuntu 24, onde vou tentar criar uma API wrapper para o middleware, a qual vou tentar chamar a partir do meu .Net 7 em windows. [Update: executa mas n#ao detecta o cartão. Ver #183 ]

    Agradeço qualquer ajuda que possam disponibilizar.

agrr commented 1 month ago

Tal como indiquei noutro issue #167 já está disponível o SDK para .net 8 na versão 3.13.0.