devs/bin/qr_secret.sh
Mauro Rosero P. 57f59ddffe
[ADDED] Script qr_secret.sh para extraer secretos de imágenes QR
- Crear script para extraer secretos de imágenes QR usando zbar
- Implementar selección de archivos mediante dialog_input_filepath
- Validar nombres de archivos según criterios específicos (sin espacios, caracteres limitados)
- Guardar secretos encriptados con SOPS en DEVELOPER_DIR
- Detectar y procesar URLs de autenticación TOTP (otpauth://)
- Actualizar README con documentación del nuevo script

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

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

249 lines
No EOL
6.2 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"
# Variables globales
title="${head_000} ${head_002}"
apps_title="Extractor de Secretos QR"
# Verificar dependencias
check_dependencies() {
# Verificar si dialog está instalado
if ! command -v dialog &> /dev/null; then
echo "Error: dialog no está instalado. Por favor, ejecute bin/bootstrap.sh para instalarlo."
exit 1
fi
# Verificar si zbar está instalado
if ! command -v zbarimg &> /dev/null; then
echo "Error: zbar no está instalado. Por favor, ejecute bin/bootstrap.sh para instalarlo."
exit 1
fi
# Verificar si sops está instalado
if ! command -v sops &> /dev/null; then
echo "Error: SOPS no está instalado. Por favor, ejecute bin/bootstrap.sh para instalarlo."
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 "Nombre del archivo" "Ingrese un nombre para el archivo (solo letras, números, ., - y _)" ""
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 "Error" "El nombre no puede estar vacío."
;;
2)
dialog_error_box "Error" "El nombre no puede contener espacios."
;;
3)
dialog_error_box "Error" "El nombre solo puede contener letras, números, ., - y _."
;;
esac
done
echo "$name"
return 0
}
# Seleccionar archivo QR
select_qr_file() {
# Usar dialog_input_filepath para seleccionar un archivo
file_path="$HOME"
dialog_input_filepath "$file_path" "Seleccione una imagen QR"
if [ "$valid_file" == "2" ]; then
# Usuario canceló
return 1
fi
echo "$file_path"
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}.sops.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 "Operación cancelada."
exit 0
fi
# Seleccionar archivo QR
local qr_file=$(select_qr_file)
if [ $? -ne 0 ]; then
clear
echo "Operación cancelada."
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 "Error" "No se pudo extraer el secreto de la imagen QR seleccionada."
clear
exit 1
fi
# Guardar secreto encriptado
save_encrypted_secret "$output_name" "$secret"
if [ $? -eq 0 ]; then
dialog_error_box "Éxito" "Secreto guardado correctamente en ${DEVELOPER_DIR}/${output_name}.sops.yaml"
else
dialog_error_box "Error" "No se pudo guardar el secreto encriptado."
clear
exit 1
fi
clear
}
# Ejecutar función principal
main