devs/bin/qr_secret.sh
Mauro Rosero P. efb5aa5d2a
[IMPROVED] Añadir soporte de localización a qr_secret.sh con developers.es
- Incorporar mensajes en developers.es para qr_secret.sh
- Mover todos los textos UI a variables localizables
- Reemplazar strings hardcodeados con referencias a variables de mensajes
- Seguir formato estándar de mensajes usado en otros scripts del proyecto
- Mejorar procesamiento de errores con mensajes consistentes

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-03-15 19:24:52 -05:00

255 lines
No EOL
6 KiB
Bash
Executable file

#!/bin/bash
#
# Script: qr_secret.sh
# Description: Extrae una contraseña secreta de una imagen QR y la guarda encriptada con SOPS
# Modified: 2025/03/15 19:30:00
# [Author] Cortana Rosero One <cortana@rosero.one>
# [Generated] Created by Claude Code (claude-3-7-sonnet-20250219)
#
# Derechos de Autor (C) [2025] [Mauro Rosero P. <mauro@roser.one>]
#
# Este programa es software libre: usted puede redistribuirlo y/o modificarlo
# bajo los términos de la Licencia Pública Affero General de GNU tal como
# lo publica la Free Software Foundation, ya sea la versión 3 de la licencia,
# o (a su elección) cualquier versión posterior.
#
# Este programa se distribuye con la esperanza de que sea útil,
# pero SIN NINGUNA GARANTÍA; sin siquiera la garantía implícita de
# COMERCIABILIDAD o IDONEIDAD PARA UN PROPÓSITO PARTICULAR. Consulte la
# Licencia Pública Affero General de GNU para obtener más detalles.
#
# Debería haber recibido una copia de la Licencia Pública Affero General
# junto con este programa. Si no la recibió, consulte <https://www.gnu.org/licenses/>.
# Configuración inicial
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# Leer DEVSPATH desde el archivo de configuración o usar "devs" por defecto
if [ -f "$SCRIPT_DIR/config/devspath.dat" ]; then
DEVSPATH=$(cat "$SCRIPT_DIR/config/devspath.dat")
else
DEVSPATH="devs"
fi
BIN_HOME="$HOME/$DEVSPATH"
BIN_BASE="bin"
BIN_LIBS="lib"
BIN_MESG="msg"
# CHECK SHELL LANGUAGE
BIN_LANG=${LANG:0:2}
# Importar bibliotecas necesarias
source "${BIN_HOME}/${BIN_BASE}/${BIN_LIBS}/base.lib"
source "${BIN_HOME}/${BIN_BASE}/${BIN_LIBS}/console.lib"
# Cargar mensajes en el idioma del sistema o español por defecto
load_messages "${BIN_HOME}/${BIN_BASE}" "${BIN_MESG}" "${BIN_LANG}" "head"
load_messages "${BIN_HOME}/${BIN_BASE}" "${BIN_MESG}" "${BIN_LANG}" "developers"
# Variables globales
title="${head_000} ${head_002}"
apps_title="${qrmsg_000}"
# Verificar dependencias
check_dependencies() {
# Verificar si dialog está instalado
if ! command -v dialog &> /dev/null; then
echo "Error: ${qrmsg_013}. ${cvmsg_014}"
exit 1
fi
# Verificar si zbar está instalado
if ! command -v zbarimg &> /dev/null; then
echo "Error: ${qrmsg_014}. ${cvmsg_014}"
exit 1
fi
# Verificar si sops está instalado
if ! command -v sops &> /dev/null; then
echo "Error: ${cvmsg_013}. ${cvmsg_014}"
exit 1
fi
}
# Validar formato del nombre
validate_name() {
local name="$1"
# Verificar si el nombre está vacío
if [ -z "$name" ]; then
return 1
fi
# Verificar si el nombre contiene espacios
if [[ "$name" =~ [[:space:]] ]]; then
return 2
fi
# Verificar si el nombre contiene caracteres no permitidos
if ! [[ "$name" =~ ^[a-zA-Z0-9._-]+$ ]]; then
return 3
fi
return 0
}
# Solicitar nombre del archivo
get_output_name() {
local name=""
local valid=false
while [ "$valid" != "true" ]; do
# Solicitar nombre
dialog_input_box "${qrmsg_001}" "${qrmsg_002}" ""
if [ $codex -ne 0 ]; then
# Usuario canceló
return 1
fi
name="$value"
# Validar nombre
validate_name "$name"
local validation_result=$?
case $validation_result in
0)
valid="true"
;;
1)
dialog_error_box "${qrmsg_012}" "${qrmsg_004}"
;;
2)
dialog_error_box "${qrmsg_012}" "${qrmsg_005}"
;;
3)
dialog_error_box "${qrmsg_012}" "${qrmsg_006}"
;;
esac
done
echo "$name"
return 0
}
# Seleccionar archivo QR
select_qr_file() {
# Usar dialog directamente para seleccionar un archivo
local home_dir="$HOME/"
exec 3>&1
local selected_file=$(dialog --backtitle "$title" --title "${qrmsg_003}" \
--stdout --fselect "$home_dir" 15 60)
local exit_code=$?
exec 3>&-
if [ $exit_code -ne 0 ] || [ ! -f "$selected_file" ]; then
# Usuario canceló o no seleccionó un archivo válido
return 1
fi
echo "$selected_file"
return 0
}
# Extraer secreto de imagen QR
extract_secret() {
local qr_file="$1"
# Usar zbarimg para extraer el texto del QR
local secret=$(zbarimg --quiet --raw "$qr_file")
local result=$?
if [ $result -ne 0 ] || [ -z "$secret" ]; then
return 1
fi
# Si el secreto comienza con "otpauth://", extraer solo el secreto
if [[ "$secret" == otpauth://* ]]; then
# Extraer el valor después de "secret="
secret=$(echo "$secret" | grep -oP 'secret=\K[A-Z0-9]+')
# Si no se pudo extraer el secreto, mostrar error
if [ -z "$secret" ]; then
return 2
fi
fi
echo "$secret"
return 0
}
# Guardar secreto encriptado con SOPS
save_encrypted_secret() {
local name="$1"
local secret="$2"
local output_file="${DEVELOPER_DIR}/${name}.totp.yaml"
# Crear archivo YAML temporal con el secreto
local temp_file=$(mktemp)
echo "secret: $secret" > "$temp_file"
# Encriptar el archivo con SOPS
sops --encrypt "$temp_file" > "$output_file"
local result=$?
# Eliminar archivo temporal
rm -f "$temp_file"
# Establecer permisos adecuados
if [ $result -eq 0 ]; then
chmod 600 "$output_file"
return 0
else
return 1
fi
}
# Función principal
main() {
# Verificar dependencias
check_dependencies
# Solicitar nombre del archivo
local output_name=$(get_output_name)
if [ $? -ne 0 ]; then
clear
echo "${qrmsg_010}"
exit 0
fi
# Seleccionar archivo QR
local qr_file=$(select_qr_file)
if [ $? -ne 0 ]; then
clear
echo "${qrmsg_010}"
exit 0
fi
# Extraer secreto de la imagen QR
local secret=$(extract_secret "$qr_file")
local extract_status=$?
if [ $extract_status -ne 0 ]; then
dialog_error_box "${qrmsg_012}" "${qrmsg_007}"
clear
exit 1
fi
# Guardar secreto encriptado
save_encrypted_secret "$output_name" "$secret"
if [ $? -eq 0 ]; then
dialog_error_box "${qrmsg_011}" "${qrmsg_008} ${DEVELOPER_DIR}/${output_name}.totp.yaml"
else
dialog_error_box "${qrmsg_012}" "${qrmsg_009}"
clear
exit 1
fi
clear
}
# Ejecutar función principal
main