749 lines
24 KiB
Org Mode
749 lines
24 KiB
Org Mode
#+title: instalador-firma.sh
|
|
#+property: header-args :tangle instalador-firma.sh
|
|
|
|
Script de instalación de firma digital. Busca ser compatible con el estándar de
|
|
shell de POSIX a nivel de sintaxis, pero su funcionalidad está limitada a Linux
|
|
y macOS.
|
|
|
|
*Probado en estas distribuciones:*
|
|
|
|
- [X] Debian 12
|
|
- [ ] Fedora 40
|
|
- [ ] Arch Linux [date]
|
|
|
|
* TODO [0/4]
|
|
|
|
- [ ] Configurar opciones como variables
|
|
e.g. definir previamente =$MENU= para utilizar la terminal como menu en lugar
|
|
de la opción disponible como zenity o kdialog
|
|
|
|
- [ ] Permitir instalación no interactiva
|
|
e.g. Si se tiene todo para proceder (con variables), no pedir nada.
|
|
|
|
- [ ] Funciones =reinstall_certs=, =uninstall_certs=
|
|
*Nota:* Mantener el uso de =$PROMPT...= en =Main=
|
|
|
|
- [ ] Menu instalar/desinstalar/salir
|
|
*Nota:* Mantener el uso de =$PROMPT...= en =Main=
|
|
- [ ] Función =is_installed=
|
|
=0= dispara el menu, =1= dispara la instalación, =2= dispara el menu con
|
|
aviso de instalación previa fallida.
|
|
|
|
* Script
|
|
** Shebang
|
|
|
|
#+begin_src shell
|
|
#!/bin/sh
|
|
#+end_src
|
|
|
|
** Utilidades
|
|
|
|
** =pseudo=
|
|
|
|
``Pseudo sudo'' facilidad para ejecutar comandos como administrador.
|
|
|
|
#+begin_src shell
|
|
alias pseudo='printf "%s" "$SUDO_PASSWORD" | sudo -Skp ""'
|
|
#+end_src
|
|
|
|
** =echo_debug=
|
|
|
|
Notificaciones del estado del script. Uso: =echo_debug "Mensaje"=
|
|
|
|
#+begin_src shell
|
|
echo_debug() {
|
|
printf '\033[1mDEBUG:\033[0m \033[2m%s...\033[0m\n' "$1"
|
|
}
|
|
#+end_src
|
|
|
|
** =urlencode=
|
|
|
|
Función para convertir texto al formato correcto de URL, existen programas
|
|
externos o quizás se pueda lograr solamente con =sed= pero esta forma es más
|
|
robusta. También es menos portable, pero el script depende de =curl= de todas
|
|
formas.
|
|
|
|
Uso: =printf 'hól#a' | urlencode=, output: =h%c3%b3l%23a=
|
|
|
|
#+begin_src shell
|
|
urlencode() {
|
|
ENCODEDURL="$(curl -Gs -w '%{url_effective}' --data-urlencode @- ./ ||: )"
|
|
printf '%s' "$ENCODEDURL" | sed 's/%0[aA]$//;s/^.*[?]//' # %0a al final de la línea es
|
|
} # un comportamiento no deseado.
|
|
#+end_src
|
|
|
|
** =get_asp_var=
|
|
|
|
Esta función requiere de una variable =$RESPONSE= que sería el html respuesta
|
|
de un request, a partir de esto, devuelve la string de data que tiene retorna al
|
|
servicio en un request posterior.
|
|
|
|
#+begin_src shell
|
|
get_asp_var() {
|
|
i=0
|
|
for VAR in __VIEWSTATE __VIEWSTATEGENERATOR __EVENTVALIDATION ; do
|
|
VAL="$(printf '%s' "$RESPONSE" | grep "id=\"$VAR\"" | cut -d '"' -f 8 | urlencode)"
|
|
[ "$i" != 0 ] && printf '&'
|
|
printf '%s=%s' "$VAR" "$VAL"
|
|
i=+1
|
|
done
|
|
}
|
|
#+end_src
|
|
|
|
** =set_version=
|
|
|
|
Sin ninguna dependiencia, solamente funciones incluidas en el estándar POSIX,
|
|
determina la variable =$VERSION= que será utilizada para seleccionar
|
|
automáticamente el fichero que debe descargar en =get_archive=.
|
|
|
|
Nota: Se desactiva el error de =SC1090=, ya que es una limitación de
|
|
=shellcheck= y es una funcionalidad válida dentro del estándar POSIX.
|
|
|
|
#+begin_src shell
|
|
set_version() {
|
|
# shellcheck disable=SC1090
|
|
for os in /etc/os-release /usr/lib/os-release; do
|
|
[ -f $os ] && . $os && break
|
|
done
|
|
|
|
case "$ID" in
|
|
centos) [ -n "$VERSION_ID" ] && [ "$VERSION_ID" -ge 9 ] &&
|
|
ID="fedora" ;;
|
|
*suse*|sles|sled) ID="suse" ;;
|
|
debian|ubuntu) ID="debian" ;;
|
|
fedora|rhel) ID="fedora" ;;
|
|
arch|manjaro) ID="arch" ;;
|
|
*) ID="${ID_LIKE%% *}" ;;
|
|
esac
|
|
|
|
[ "$ID" = "ubuntu" ] && ID="debian"
|
|
[ "$ID" = "rhel" ] && ID="fedora"
|
|
[ -f /System/Library/CoreServices/SystemVersion.plist ] && ID="macos"
|
|
|
|
case "$ID" in
|
|
debian) VERSION="Usuarios Linux (DEB 64bits)" ;;
|
|
fedora) VERSION="Usuarios Linux (RPM 64bits)" ;;
|
|
suse) VERSION="Usuarios Linux (RPM 64bits)" ;;
|
|
arch) VERSION="Usuarios Linux (RPM 64bits)" ;;
|
|
centos) VERSION="Usuarios Linux RPM (CentOS 7)" ;;
|
|
macos) VERSION="Usuarios MAC" ;;
|
|
*) return 1 ;;
|
|
esac
|
|
}
|
|
#+end_src
|
|
|
|
** =get_archive=
|
|
|
|
Utiliza =urlencode= y =get_asp_var= para realizar el procedimiento de descarga.
|
|
Necesita que =$VERSION= esté definida (después de ejecutar =set_version=) ya que
|
|
utilizará este parámetro para consultar en el servicio el instalador que debe
|
|
descargar (el más actualizado de y correspondiente al sistema).
|
|
|
|
#+begin_src shell
|
|
get_archive() {
|
|
URL="https://soportefirmadigital.com/sfdj/dl.aspx"
|
|
VERSION="$(printf '%s' "$VERSION" | urlencode)"
|
|
RESPONSE="$(curl -s --compressed "$URL" -o -)"
|
|
ASP_VARS="$(get_asp_var)"
|
|
|
|
FILE="$(curl -s "$URL" --data-raw "$ASP_VARS" --data-raw "ctl00%24certContents%24ddlInstaladores=$VERSION" |
|
|
grep 'hiddenISO.*value="' | sed 's/^.*value="//g;s/".*$//g')"
|
|
[ -z "$FILE" ] && return 1
|
|
|
|
TEMPKEY="$(curl -s --compressed "$URL" --data-raw "$ASP_VARS" \
|
|
--data-raw "__EVENTTARGET=ctl00%24certContents%24LinkButton3" \
|
|
--data-raw "ctl00%24certContents%24hiddenISO=$FILE" \
|
|
--data-raw "ctl00%24certContents%24txtSerialNumber=$SERIAL" \
|
|
--data-raw "ctl00%24certContents%24chkConfirmo=on" \
|
|
-o - | sed '/tempkey/!d;s/.*tempkey=//g;s/".*$//g')"
|
|
[ -z "$TEMPKEY" ] && return 1
|
|
|
|
printf '%s %s' "$FILE" "$TEMPKEY"
|
|
}
|
|
#+end_src
|
|
|
|
** =set_menu= (revisar)
|
|
|
|
(No creo que este sea necesario)
|
|
|
|
#+begin_src shell
|
|
set_menu() {
|
|
if [ -z "$MENU" ] ; then
|
|
command -v zenity > /dev/null && MENU="zenity" && return 0
|
|
command -v kdialog > /dev/null && MENU="kdialog" && return 0
|
|
MENU="term"
|
|
fi
|
|
}
|
|
#+end_src
|
|
|
|
** =menu=
|
|
|
|
Esto más que nada es una forma de abreviar los comandos y de mantener
|
|
consistente la ejecución principal, de manera que se llama a esta función
|
|
y determina desde un lugar cómo proceder con la notificación y entrada del
|
|
usuario.
|
|
|
|
Nota: =SC2034= se desactiva porque a pesar de que =$nil= es una variable sin
|
|
utilizar, permite la portabilidad del script con otras implementaciones.
|
|
|
|
#+begin_src shell
|
|
menu() {
|
|
MODE="$1" PROMPT="$2"
|
|
|
|
if [ "$MENU" = "zenity" ] ; then
|
|
echo_debug "MENU: $MENU MODE: $MODE PROMPT: $PROMPT" > /dev/stderr
|
|
[ "$MODE" = "info" ] && zenity --title "$TITLE" --text "$PROMPT" --info
|
|
[ "$MODE" = "error" ] && zenity --title "$TITLE" --text "$PROMPT" --error > /dev/stderr
|
|
[ "$MODE" = "entry" ] && zenity --title "$TITLE" --text "$PROMPT" --entry
|
|
[ "$MODE" = "pass" ] && zenity --title "$TITLE" --password
|
|
|
|
elif [ "$MENU" = "term" ] ; then
|
|
# shellcheck disable=SC2034
|
|
[ "$MODE" = "info" ] &&
|
|
printf '\n\033[1m\033[34m=== %s ===\033[0m\n%s ENTER' "$TITLE" "$PROMPT" >/dev/stdin &&
|
|
read -r nil
|
|
|
|
[ "$MODE" = "error" ] &&
|
|
printf '\n\033[1m\033[31m=== %s ===\033[0m\n%s\n' "$TITLE" "$PROMPT" >/dev/stderr
|
|
|
|
[ "$MODE" = "entry" ] &&
|
|
printf '\n\033[1m\033[34m=== %s ===\033[0m\n%s\n -> ' "$TITLE" "$PROMPT" >/dev/stdin &&
|
|
IFS= read -r entry &&
|
|
printf '%s' "$entry"
|
|
|
|
[ "$MODE" = "pass" ] &&
|
|
printf '\n\033[1m\033[34m=== %s ===\033[0m\n%s\n -> ' "$TITLE" "$PROMPT" >/dev/stdin &&
|
|
IFS= read -r passwd &&
|
|
printf '%s' "$passwd"
|
|
fi
|
|
}
|
|
|
|
#+end_src
|
|
|
|
** Lenguaje
|
|
|
|
=/etc/default/locale= contiene información del lenguage por defecto, obtiene el
|
|
lenguaje de esta locación si no está previamente definido (por el sistema o por
|
|
el usuario utilizando, por ejemplo, =LANG=es=). Utiliza español por defecto
|
|
si logra definir el lenguaje.
|
|
|
|
#+begin_src shell
|
|
set_lang() {
|
|
# See: /var/lib/AccountsService/users/
|
|
! [ "$LANG" ] && [ -f "/etc/default/locale" ] && . /etc/default/locale
|
|
SLANG="${LANG%%_*}"
|
|
[ -z "$SLANG" ] && SLANG="es"
|
|
|
|
if [ "$SLANG" = "es" ] ; then
|
|
TITLE="Instalador firma digital"
|
|
PROMPT_WELCOME="Bienvenido al asistente de instalación de certificados para firma digial."
|
|
PROMPT_ERR_DEPS="Error, la instalación requiere de los siguientes programas no presentes: "
|
|
PROMPT_SERIAL="Ingrese el número serial impreso al reverso de la tarjeta."
|
|
PROMPT_ERR_SERIAL="Error al obtener el número serial de la tarjeta, abortando."
|
|
PROMPT_DOWNLOAD="Descargando desde Centro de Soporte Firma Digital..."
|
|
PROMPT_DEPS_INSTALL="Instalando dependencias y otros complementos..."
|
|
PROMPT_PASS_DEPS_INSTALL="Ingrese la contraseña del equipo para instalar los componentes"
|
|
PROMPT_ERR_DEPS_INSTALL="Error instalando dependencias."
|
|
PROMPT_ERR_DOWNLOAD="Error al descargar el fichero, abortando."
|
|
PROMPT_END_SUCCESS="El instalador ha concluido."
|
|
|
|
elif [ "$SLANG" = "en" ] ; then
|
|
TITLE="Digital signature installer"
|
|
PROMPT_WELCOME="Welcome to the digital signing certificate installation wizard."
|
|
PROMPT_ERR_DEPS="Error, installation requires the following programs not present: "
|
|
PROMPT_SERIAL="Enter the serial number printed on the back of the card."
|
|
PROMPT_ERR_SERIAL="Error obtaining the card serial number, aborting."
|
|
PROMPT_DOWNLOAD="Downloading from the Digital Signature Support Center..."
|
|
PROMPT_DEPS_INSTALL="Installing dependencies and other components..."
|
|
PROMPT_PASS_DEPS_INSTALL="Enter your computer password to install components"
|
|
PROMPT_ERR_DEPS_INSTALL="Error installing dependencies."
|
|
PROMPT_ERR_DOWNLOAD="Error downloading file, aborting."
|
|
PROMPT_END_SUCCESS="The installer has completed."
|
|
|
|
elif [ "$SLANG" = "fr" ] ; then
|
|
TITLE="Installation de signature"
|
|
PROMPT_WELCOME="Bienvenue dans l'assistant d'installation du certificat de signature."
|
|
PROMPT_ERR_DEPS="Erreur, l'installation requise des programmes suivants ne présente pas: "
|
|
PROMPT_SERIAL="Entrez le numéro de série imprimé au dos de la carte."
|
|
PROMPT_ERR_SERIAL="Erreur d'obtention du numéro de série de la carte, abandon."
|
|
PROMPT_DOWNLOAD="Téléchargement du fichier depuis le Centre de support des signatures numériques..."
|
|
PROMPT_DEPS_INSTALL="Installation des dépendances et d'autres composants..."
|
|
PROMPT_PASS_DEPS_INSTALL="Entrez le mot de passe de votre ordinateur pour installer les composants"
|
|
PROMPT_ERR_DEPS_INSTALL="Erreur lors de l'installation des dépendances."
|
|
PROMPT_ERR_DOWNLOAD="Erreur de téléchargement du fichier, abandon."
|
|
PROMPT_END_SUCCESS="Le programme d'installation est terminé."
|
|
|
|
fi
|
|
}
|
|
#+end_src
|
|
|
|
** Instalación
|
|
|
|
Proceso de instalación para dependiendo de su base, ya sea con el =$ID= o
|
|
=$ID_LIKE=, esto se define en =get_version=.
|
|
|
|
|
|
Se deshabilita =SC2016= ya que esta parte debe correr sin expandir las
|
|
variables.
|
|
|
|
** Debian
|
|
|
|
#+begin_src shell
|
|
debian_install_certs() {
|
|
# Source: https://fran.cr/instalar-firma-digital-costa-rica-gnu-linux-ubuntu-debian/
|
|
|
|
echo_debug "Instalando dependencias"
|
|
pseudo apt-get install -y unzip binutils p11-kit pcscd bubblewrap icedtea-netx > /dev/null || return 1
|
|
|
|
echo_debug "Extraer fichero"
|
|
[ -z "$SAVE_DIR" ] || [ -z "$SAVE_FILE" ] && return 1
|
|
(cd "$SAVE_DIR" && unzip -u "$SAVE_FILE" > /dev/null) || return 1
|
|
|
|
echo_debug "Copiar certificados"
|
|
for cert in "$(find "$SAVE_DIR" -name "Certificados")"/* ; do
|
|
certname="${cert##*/}"
|
|
pseudo cp "$cert" /usr/local/share/ca-certificates/"${certname%.cer}.crt"
|
|
done
|
|
|
|
echo_debug "Extraer módulo privativo"
|
|
PACKAGE="$(find "$SAVE_DIR" -name "idprotectclient[-_]*.deb")"
|
|
PACKAGE_DIR="${PACKAGE%/*}"
|
|
PACKAGE="${PACKAGE##*/}"
|
|
[ -z "$PACKAGE_DIR" ] || [ -z "$PACKAGE" ] && return 1
|
|
(cd "$PACKAGE_DIR" && ar p "$PACKAGE" data.tar.gz | tar zx ./usr/lib/x64-athena/libASEP11.so)
|
|
pseudo cp -p "$PACKAGE_DIR"/usr/lib/x64-athena/libASEP11.so /usr/lib/x86_64-linux-gnu/
|
|
|
|
echo_debug "Symlinks y componentes..."
|
|
# shellcheck disable=SC2016
|
|
pseudo sh -c '
|
|
# --- Certificados ---
|
|
for file in /usr/local/share/ca-certificates/*.crt ; do openssl x509 -inform DER -in "$file" -out "$file.tmp" 2> /dev/null ; done
|
|
find /usr/local/share/ca-certificates/ -type f -empty -delete
|
|
for i in /usr/local/share/ca-certificates/*.tmp ; do mv "$i" "${i%.tmp}" ; done
|
|
update-ca-certificates --fresh > /dev/null
|
|
# --- Instalación del módulo PKCS#11 ---
|
|
mkdir -p /usr/lib/x64-athena
|
|
mkdir -p /Firma_Digital/LIBRERIAS
|
|
ln -sf /usr/lib/x86_64-linux-gnu/libASEP11.so /usr/lib/x64-athena/
|
|
ln -sf /usr/lib/x86_64-linux-gnu/libASEP11.so /usr/lib/
|
|
ln -sf /usr/lib/x86_64-linux-gnu/libASEP11.so /usr/local/lib/
|
|
ln -sf /usr/lib/x86_64-linux-gnu/libASEP11.so /Firma_Digital/LIBRERIAS/
|
|
ln -sf /usr/local/share/ca-certificates /Firma_Digital/CERTIFICADOS
|
|
systemctl enable --now pcscd.socket > /dev/null
|
|
'
|
|
|
|
echo_debug "Configurando IDPClientDB"
|
|
pseudo sh -c "
|
|
mkdir -p /etc/Athena
|
|
echo \"<?xml version=\"1.0\" encoding=\"utf-8\" ?>
|
|
<IDProtect>
|
|
<TokenLibs>
|
|
<IDProtect>
|
|
<Cards>
|
|
<IDProtectXF>
|
|
<ATR type='hexBinary'>3BDC00FF8091FE1FC38073C821106600000000000000</ATR>
|
|
<ATRMask type='hexBinary'>FFFF00FFF0FFFFFFFFFFFFFFFFF0FF00000000000000</ATRMask>
|
|
</IDProtectXF>
|
|
</Cards>
|
|
</IDProtect>
|
|
<ChipDoc>
|
|
<Cards>
|
|
<ChipDocEMV>
|
|
<ATR type='hexBinary'>3BEA00008131FE450031C173C840000090007A</ATR>
|
|
<ATRMask type='hexBinary'>FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF</ATRMask>
|
|
</ChipDocEMV>
|
|
</Cards>
|
|
</ChipDoc>
|
|
</TokenLibs>
|
|
</IDProtect>\" > /etc/Athena/IDPClientDB.xml
|
|
"
|
|
|
|
echo_debug "Configurando p11-kit/modules"
|
|
pseudo sh -c "
|
|
mkdir -p /usr/share/p11-kit/modules
|
|
echo 'remote: |bwrap --unshare-all --dir /tmp --ro-bind /etc/Athena /etc/Athena --proc /proc --dev /dev --ro-bind /usr /usr --ro-bind /lib /lib --ro-bind /lib64 /lib64 --ro-bind /var/run/pcscd /var/run/pcscd --ro-bind /run/pcscd /run/pcscd p11-kit remote /usr/lib/x86_64-linux-gnu/libASEP11.so' > /usr/share/p11-kit/modules/firma-digital.module
|
|
"
|
|
|
|
echo_debug "Configurando p11-kit update symlinks"
|
|
pseudo sh -c "
|
|
mkdir -p /usr/local/sbin
|
|
echo \"#!/bin/sh
|
|
|
|
FIREFOX_LIB=/usr/lib/firefox/libnssckbi.so
|
|
FIREFOX_ESR_LIB=/usr/lib/firefox-esr/libnssckbi.so
|
|
THUNDERBIRD_LIB=/usr/lib/thunderbird/libnssckbi.so
|
|
NSS_LIB=/usr/lib/x86_64-linux-gnu/nss/libnssckbi.so
|
|
|
|
if [ -e \"\$FIREFOX_LIB\" ]
|
|
then
|
|
if ! [ -L \"\$FIREFOX_LIB\" ]
|
|
then
|
|
echo \"Firefox libnssckbi.so is not a symlink. Fixing...\"
|
|
mv -f \"\$FIREFOX_LIB\" \"\$FIREFOX_LIB\".bak
|
|
ln -s /usr/lib/x86_64-linux-gnu/p11-kit-proxy.so \"\$FIREFOX_LIB\"
|
|
fi
|
|
fi
|
|
|
|
if [ -e \"\$FIREFOX_ESR_LIB\" ]
|
|
then
|
|
if ! [ -L \"\$FIREFOX_ESR_LIB\" ]
|
|
then
|
|
echo \"Firefox ESR libnssckbi.so is not a symlink. Fixing...\"
|
|
mv -f \"\$FIREFOX_ESR_LIB\" \"\$FIREFOX_ESR_LIB\".bak
|
|
ln -s /usr/lib/x86_64-linux-gnu/p11-kit-proxy.so \"\$FIREFOX_ESR_LIB\"
|
|
fi
|
|
fi
|
|
|
|
if [ -e \"\$THUNDERBIRD_LIB\" ]
|
|
then
|
|
if ! [ -L \"\$THUNDERBIRD_LIB\" ]
|
|
then
|
|
echo \"Thunderbird libnssckbi.so is not a symlink. Fixing...\"
|
|
mv -f \"\$THUNDERBIRD_LIB\" \"\$THUNDERBIRD_LIB\".bak
|
|
ln -s /usr/lib/x86_64-linux-gnu/p11-kit-proxy.so \"\$THUNDERBIRD_LIB\"
|
|
fi
|
|
fi
|
|
|
|
if [ -e \"\$NSS_LIB\" ]
|
|
then
|
|
if ! [ -L \"\$NSS_LIB\" ]
|
|
then
|
|
echo \"NSS libnssckbi.so is not a symlink. Fixing...\"
|
|
mv -f \"\$NSS_LIB\" \"\$NSS_LIB\".bak
|
|
ln -s /usr/lib/x86_64-linux-gnu/p11-kit-proxy.so \"\$NSS_LIB\"
|
|
fi
|
|
fi\" > /usr/local/sbin/update-p11-kit-symlinks
|
|
chmod +x /usr/local/sbin/update-p11-kit-symlinks
|
|
"
|
|
|
|
echo_debug "Configurando módulo mantenimiento systemd"
|
|
pseudo sh -c "
|
|
mkdir -p /etc/systemd/system
|
|
echo \"[Unit]
|
|
Description=mantenimiento de enlaces a p11-kit-proxy
|
|
|
|
[Service]
|
|
Type=oneshot
|
|
ExecStart=/usr/local/sbin/update-p11-kit-symlinks
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
\" > /etc/systemd/system/p11-kit-proxy-updater.service
|
|
systemctl enable --now p11-kit-proxy-updater.service > /dev/null
|
|
"
|
|
|
|
echo_debug "Instalando trust module pk11"
|
|
pseudo sh -c "
|
|
mkdir -p /etc/pkcs11/modules
|
|
echo 'disable-in:' > /etc/pkcs11/modules/p11-kit-trust.module
|
|
"
|
|
}
|
|
#+end_src
|
|
|
|
** Fedora
|
|
|
|
#+begin_src shell
|
|
fedora_install_certs() {
|
|
# Source: https://fran.cr/instalar-firma-digital-costa-rica-gnu-linux-fedora/
|
|
|
|
echo_debug "Instalando dependencias"
|
|
pseudo dnf -y install unzip pcsc-lite icedtea-web > /dev/null || return 1
|
|
|
|
echo_debug "Extraer fichero"
|
|
[ -z "$SAVE_DIR" ] || [ -z "$SAVE_FILE" ] && return 1
|
|
(cd "$SAVE_DIR" && unzip -u "$SAVE_FILE" > /dev/null) || return 1
|
|
|
|
echo_debug "Copiar certificados"
|
|
pseudo cp -p "$(find "$SAVE_DIR" -name "Certificados")"/* /usr/share/pki/ca-trust-source/anchors/
|
|
pseudo update-ca-trust
|
|
|
|
echo_debug "Extraer módulo privativo"
|
|
PACKAGE="$(find "$SAVE_DIR" -name "idprotectclient[-_]*.rpm")"
|
|
PACKAGE_DIR="${PACKAGE%/*}"
|
|
PACKAGE="${PACKAGE##*/}"
|
|
[ -z "$PACKAGE_DIR" ] || [ -z "$PACKAGE" ] && return 1
|
|
(cd "$PACKAGE_DIR" &&
|
|
rm -r ./usr/lib/x64-athena/libASEP11.so
|
|
rpm2cpio "$PACKAGE" | cpio -dim ./usr/lib/x64-athena/libASEP11.so) || return 1
|
|
pseudo cp -p "$PACKAGE_DIR"/usr/lib/x64-athena/libASEP11.so /usr/lib64/
|
|
|
|
echo_debug "Symlinks y componentes..."
|
|
pseudo sh -c '
|
|
mkdir -p /usr/lib/x64-athena/
|
|
mkdir -p /Firma_Digital/LIBRERIAS/
|
|
ln -sf /usr/lib64/libASEP11.so /usr/lib/x64-athena/
|
|
ln -sf /usr/lib64/libASEP11.so /usr/lib/
|
|
ln -sf /usr/lib64/libASEP11.so /usr/local/lib/
|
|
ln -sf /usr/lib64/libASEP11.so /Firma_Digital/LIBRERIAS/
|
|
ln -sf /usr/share/pki/ca-trust-source/anchors /Firma_Digital/CERTIFICADOS
|
|
systemctl enable --now pcscd.socket > /dev/null
|
|
'
|
|
|
|
echo_debug "Configurando IDPClientDB"
|
|
pseudo sh -c "
|
|
mkdir -p /etc/Athena
|
|
echo \"<?xml version=\"1.0\" encoding=\"utf-8\" ?>
|
|
<IDProtect>
|
|
<TokenLibs>
|
|
<IDProtect>
|
|
<Cards>
|
|
<IDProtectXF>
|
|
<ATR type='hexBinary'>3BDC00FF8091FE1FC38073C821106600000000000000</ATR>
|
|
<ATRMask type='hexBinary'>FFFF00FFF0FFFFFFFFFFFFFFFFF0FF00000000000000</ATRMask>
|
|
</IDProtectXF>
|
|
</Cards>
|
|
</IDProtect>
|
|
<ChipDoc>
|
|
<Cards>
|
|
<ChipDocEMV>
|
|
<ATR type='hexBinary'>3BEA00008131FE450031C173C840000090007A</ATR>
|
|
<ATRMask type='hexBinary'>FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF</ATRMask>
|
|
</ChipDocEMV>
|
|
</Cards>
|
|
</ChipDoc>
|
|
</TokenLibs>
|
|
</IDProtect>\" > /etc/Athena/IDPClientDB.xml
|
|
"
|
|
|
|
echo_debug "Configurando p11-kit/modules"
|
|
pseudo sh -c "
|
|
mkdir -p /usr/share/p11-kit/modules
|
|
echo 'remote: |bwrap --unshare-all --dir /tmp --proc /proc --dev /dev --ro-bind /etc/Athena /etc/Athena --ro-bind /usr /usr --ro-bind /var/run/pcscd /var/run/pcscd --ro-bind /run/pcscd /run/pcscd --symlink /usr/lib64 /lib64 p11-kit remote /usr/lib64/libASEP11.so' > /usr/share/p11-kit/modules/firma-digital.module
|
|
"
|
|
}
|
|
#+end_src
|
|
|
|
** Arch Linux
|
|
|
|
#+begin_src shell
|
|
arch_install_certs() {
|
|
echo_debug "Instalando dependencias"
|
|
pseudo pacman -S --noconfirm --needed unzip cpio rpm-tools pcsclite ccid jre8-openjdk icedtea-web > /dev/null || return 1
|
|
|
|
echo_debug "Extraer fichero"
|
|
[ -z "$SAVE_DIR" ] || [ -z "$SAVE_FILE" ] && return 1
|
|
(cd "$SAVE_DIR" && unzip -u "$SAVE_FILE" > /dev/null)
|
|
|
|
echo_debug "Copiar certificados"
|
|
pseudo cp -p "$(find "$SAVE_DIR" -name "Certificados")"/* /usr/share/ca-certificates/trust-source/anchors/
|
|
pseudo update-ca-trust
|
|
|
|
echo_debug "Extraer módulo privativo"
|
|
[ -z "$PACKAGE_DIR" ] || [ -z "$PACKAGE" ] && return 1
|
|
(cd "$PACKAGE_DIR" && rpm2cpio "$PACKAGE" | cpio -dim ./usr/lib/x64-athena/libASEP11.so)
|
|
pseudo cp -p "$PACKAGE_DIR"/usr/lib/x64-athena/libASEP11.so /usr/lib/
|
|
|
|
echo_debug "Symlinks y componentes..."
|
|
pseudo sh -c '
|
|
mkdir -p /usr/lib/x64-athena/
|
|
mkdir -p /Firma_Digital/LIBRERIAS/
|
|
ln -sf /usr/lib/libASEP11.so /usr/lib/x64-athena/
|
|
ln -sf /usr/lib/libASEP11.so /usr/local/lib/
|
|
ln -sf /usr/lib/libASEP11.so /Firma_Digital/LIBRERIAS/
|
|
ln -sf /usr/share/ca-certificates/trust-source/anchors /Firma_Digital/CERTIFICADOS
|
|
ln -sf /usr/lib/p11-kit-proxy.so /usr/lib/firefox/libosclientcerts.so
|
|
systemctl enable --now pcscd.socket > /dev/null
|
|
'
|
|
|
|
echo_debug "Configurando IDPClientDB"
|
|
pseudo sh -c "
|
|
mkdir -p /etc/Athena
|
|
echo \"<?xml version=\"1.0\" encoding=\"utf-8\" ?>
|
|
<IDProtect>
|
|
<TokenLibs>
|
|
<IDProtect>
|
|
<Cards>
|
|
<IDProtectXF>
|
|
<ATR type='hexBinary'>3BDC00FF8091FE1FC38073C821106600000000000000</ATR>
|
|
<ATRMask type='hexBinary'>FFFF00FFF0FFFFFFFFFFFFFFFFF0FF00000000000000</ATRMask>
|
|
</IDProtectXF>
|
|
</Cards>
|
|
</IDProtect>
|
|
<ChipDoc>
|
|
<Cards>
|
|
<ChipDocEMV>
|
|
<ATR type='hexBinary'>3BEA00008131FE450031C173C840000090007A</ATR>
|
|
<ATRMask type='hexBinary'>FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF</ATRMask>
|
|
</ChipDocEMV>
|
|
</Cards>
|
|
</ChipDoc>
|
|
</TokenLibs>
|
|
</IDProtect>\" > /etc/Athena/IDPClientDB.xml
|
|
"
|
|
|
|
echo_debug "Configurando p11-kit/modules"
|
|
pseudo sh -c "
|
|
mkdir -p /usr/share/p11-kit/modules
|
|
echo 'remote: |bwrap --unshare-all --dir /tmp --proc /proc --dev /dev --ro-bind /etc/Athena /etc/Athena --ro-bind /usr /usr --ro-bind /lib64 /lib64 --ro-bind /run/pcscd /run/pcscd p11-kit remote /usr/lib/libASEP11.so' > /usr/share/p11-kit/modules/firma-digital.module
|
|
"
|
|
}
|
|
#+end_src
|
|
|
|
** Función wrapper
|
|
|
|
Encargarse de la instalación simplemente llamando =install_certs=.
|
|
|
|
#+begin_src shell
|
|
install_certs() {
|
|
[ -z "$SUDO_PASSWORD" ] && return 1
|
|
[ -z "$SAVE_FILE" ] && return 1
|
|
SAVE_DIR="${SAVE_FILE%/*}"
|
|
|
|
if [ "$ID" = "macos" ] ; then
|
|
open "$SAVE_FILE" || return 1
|
|
|
|
elif [ "$ID" = "debian" ] ; then
|
|
debian_install_certs || return 1
|
|
|
|
elif [ "$ID" = "fedora" ] ; then
|
|
fedora_install_certs || return 1
|
|
|
|
elif [ "$ID" = "arch" ] ; then
|
|
arch_install_certs || return 1
|
|
|
|
elif [ "$ID" = "centos" ] ; then
|
|
echo || return 1
|
|
|
|
fi
|
|
}
|
|
#+end_src
|
|
|
|
** Main
|
|
|
|
** TODO Inicializar [0/2]
|
|
|
|
- [ ] Tirar =exit 1= en caso de no poder seleccionar una versión o un menu.
|
|
- [ ] Agregar otras dependencias mínimas, o que no conviene instalarlas en el script (sudo)
|
|
|
|
#+begin_src shell
|
|
set_lang
|
|
set_version
|
|
set_menu
|
|
|
|
if ! command -v curl > /dev/null ; then
|
|
menu error "$PROMPT_ERR_DEPS curl"
|
|
exit 1
|
|
fi
|
|
|
|
menu info "$PROMPT_WELCOME"
|
|
#+end_src
|
|
|
|
** No. Serial
|
|
|
|
#+begin_src shell
|
|
SERIAL="${SERIAL:=$(menu entry "$PROMPT_SERIAL")}"
|
|
|
|
if [ -z "$SERIAL" ] ; then
|
|
menu error "$PROMPT_ERR_SERIAL"
|
|
exit 1
|
|
fi
|
|
#+end_src
|
|
|
|
** Proceso de descarga
|
|
|
|
*** Obtener URL e información del fichero
|
|
|
|
#+begin_src shell
|
|
ARCHIVE="$(get_archive)"
|
|
TEMPKEY="${ARCHIVE##* }"
|
|
FILE="${ARCHIVE%% *}"
|
|
|
|
DOWNLOAD_URL="$(
|
|
printf 'https://soportefirmadigital.com/sfdj/getiso.aspx?tempkey=%s' \
|
|
"$TEMPKEY"
|
|
)"
|
|
|
|
SIZE="$(curl -sI "$DOWNLOAD_URL" |
|
|
sed '/[Cc]ontent-[Ll]ength/!d;s/^.*: //g' |
|
|
awk '{$1/=1024;printf "%d",$1}'
|
|
)"
|
|
|
|
if [ "$SIZE" -lt 500 ] || [ -z "$FILE" ] ; then
|
|
menu error "$PROMPT_ERR_DOWNLOAD"
|
|
exit 1
|
|
fi
|
|
#+end_src
|
|
|
|
*** Descarga
|
|
|
|
Se desactiva =SC2009= para asegurarse de tener el ID correcto, ya que terminará
|
|
el proceso en caso de seguir activo.
|
|
|
|
#+begin_src shell
|
|
SAVE_DIR="/tmp/soportefirmadigital"
|
|
SAVE_FILE="$SAVE_DIR/$FILE"
|
|
mkdir -p "$SAVE_DIR"
|
|
|
|
if [ "$MENU" = "zenity" ] ; then
|
|
(curl -sL "$DOWNLOAD_URL" -o "$SAVE_FILE") &
|
|
while true ; do
|
|
sleep 0.5
|
|
DOWN="$(du "$SAVE_FILE" 2>/dev/null | awk '{print $1}')"
|
|
[ -z "$DOWN" ] && DOWN=0
|
|
r=$(((DOWN*10000)/SIZE))
|
|
printf '%d\n' ${r%??}
|
|
done | zenity --title "$TITLE" --text "$PROMPT_DOWNLOAD" --progress --auto-close
|
|
|
|
elif [ "$MENU" = "term" ] ; then
|
|
menu info "$PROMPT_DOWNLOAD" && echo
|
|
curl "$DOWNLOAD_URL" -o "$SAVE_FILE" --progress-bar
|
|
|
|
fi
|
|
|
|
# shellcheck disable=SC2009
|
|
ACTIVE="$(ps -t | grep 'curl.*soportefirmadigital' | sed '/grep/d')"
|
|
ACTIVE="${ACTIVE# }"
|
|
ACTIVEID="${ACTIVE%% *}"
|
|
|
|
if [ -n "$ACTIVE" ] ; then
|
|
menu error "$PROMPT_ERR_DOWNLOAD"
|
|
echo_debug "Killing process ID: $ACTIVEID from: $ACTIVE" # DEBUG
|
|
kill "$ACTIVEID"
|
|
exit 1
|
|
fi
|
|
#+end_src
|
|
|
|
** Proceso de instalación
|
|
|
|
*** Permisos elevados
|
|
|
|
#+begin_src shell
|
|
SUDO_PASSWORD="${SUDO_PASSWORD:=$(menu pass "$PROMPT_PASS_DEPS_INSTALL")}"
|
|
|
|
if [ -z "$SUDO_PASSWORD" ] || ! pseudo whoami >/dev/null 2>&1 ; then
|
|
menu error "$PROMPT_ERR_DEPS_INSTALL"
|
|
exit 1
|
|
fi
|
|
#+end_src
|
|
|
|
*** Instalación
|
|
|
|
#+begin_src shell
|
|
if [ "$MENU" = "zenity" ] ; then
|
|
# Attempt to install, forward output to program
|
|
# but keep exit code of install function
|
|
( ( ( (install_certs; echo $? >&3) |
|
|
zenity --title "$TITLE" --text "$PROMPT_DEPS_INSTALL" --progress --pulsate --auto-close >&4) 3>&1 ) |
|
|
(read -r xs; exit "$xs") ) 4>&1
|
|
#install_certs # Just run this instead to see debug info # DEBUG
|
|
# Ignore as this is needed for this "workaround"
|
|
# shellcheck disable=SC2181
|
|
if [ "$?" != "0" ] ; then
|
|
menu error "$PROMPT_ERR_DEPS_INSTALL"
|
|
exit 1
|
|
fi
|
|
|
|
elif [ "$MENU" = "term" ] ; then
|
|
menu info "$PROMPT_DEPS_INSTALL" && echo
|
|
! install_certs && menu error "$PROMPT_ERR_DEPS_INSTALL" && exit 1
|
|
|
|
fi
|
|
#+end_src
|
|
|
|
** Finalización
|
|
|
|
#+begin_src shell
|
|
menu info "$PROMPT_END_SUCCESS\n"
|
|
|
|
exit 0
|
|
#+end_src
|