aboutsummaryrefslogtreecommitdiffstats
path: root/hyperterm/tools/ssh-agent.sh
blob: 8691742875e37160db8d126cc325cf205d4a1a06 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#!/bin/bash
# SPDX-License-Identifier: GPL-3.0-or-later
# This script manages the SSH agent, allowing you to start, stop, and reload it.
# Require script: core/lamguages.sh
# Usage:
#   sagent_start    - Start the SSH agent and add a private key.
#   sagent_stop     - Stop the SSH agent.
#   sagent_reload   - Reload the SSH agent and list added keys.

function sshagent_start {
    local ssh_dir="$HOME/.ssh"
    local default_lifetime="5d"
    local key_path=""
    local lifetime="$default_lifetime"
    local seconds=0
    local human_lifetime=""

    msg "Buscando claves privadas en $ssh_dir..." "Looking for private keys in $ssh_dir..."
    mapfile -t keys < <(find "$ssh_dir" -type f -not -name "*.pub" -exec grep -l "PRIVATE KEY" {} \;)

    local key_count=${#keys[@]}
    if [ "$key_count" -eq 0 ]; then
        msg_err "No se encontraron claves privadas en $ssh_dir" "No private keys found in $ssh_dir"
        return 1
    elif [ "$key_count" -eq 1 ]; then
        key_path="${keys[0]}"
        msg "Una sola clave encontrada: $key_path" "Single key found: $key_path"
    else
        msg "Selecciona la clave que deseas agregar al agente SSH:" "Select the key you want to add to the SSH agent:"
        select key in "${keys[@]}" "$(msg 'Cancelar' 'Cancel')"; do
            if [[ "$REPLY" =~ ^[0-9]+$ ]]; then
                if (( REPLY >= 1 && REPLY <= key_count )); then
                    key_path="$key"
                    break
                elif (( REPLY == key_count + 1 )); then
                    msg "Operación cancelada." "Operation cancelled."
                    return 0
                else
                    msg "Opción fuera de rango." "Option out of range."
                fi
            else
                msg "Entrada no válida. Solo números." "Invalid input. Numbers only."
            fi
        done
    fi

    read -rp "$(msg "¿Tiempo de vida del agente? (Ej: 5m, 2h, 1d) [${default_lifetime}]: " \
                    "Agent lifetime? (e.g., 5m, 2h, 1d) [${default_lifetime}]: ")" user_input
    lifetime="${user_input:-$default_lifetime}"

    local num=${lifetime//[!0-9]/}
    local unit=${lifetime//[0-9]/}
    case "$unit" in
        s|"") seconds=$num; human_lifetime="$(msg "$num segundo(s)" "$num second(s)")" ;;
        m)    seconds=$((num * 60)); human_lifetime="$(msg "$num minuto(s)" "$num minute(s)")" ;;
        h)    seconds=$((num * 3600)); human_lifetime="$(msg "$num hora(s)" "$num hour(s)")" ;;
        d)    seconds=$((num * 86400)); human_lifetime="$(msg "$num día(s)" "$num day(s)")" ;;
        *)    msg_err "Unidad de tiempo inválida. Usa s, m, h o d." "Invalid time unit. Use s, m, h or d."; return 1 ;;
    esac

    rm -rf /tmp/ssh-* > /dev/null
    SSH_ENV="$HOME/.ssh/environment"
    msg "Inicializando nuevo agente SSH..." "Initializing new SSH agent..."
    ssh-agent | sed 's/^echo/#echo/' > "$SSH_ENV"
    chmod 600 "$SSH_ENV"
    # shellcheck source=/dev/null
    source "$SSH_ENV" > /dev/null

    if ssh-add -t "$seconds" "$key_path" >/dev/null 2>&1; then
        msg "Clave agregada correctamente: $key_path (vida: $human_lifetime)" \
            "Key added successfully: $key_path (lifetime: $human_lifetime)"
    else
        msg_err "Error al agregar la clave." "Failed to add SSH key."
    fi
}

function sshagent_stop {
    rm -rf /tmp/ssh-* > /dev/null
    ssh-agent -k > /dev/null
    msg "Agente SSH detenido." "SSH agent stopped."
}

function sshagent_findsockets {
    find /tmp -uid "$(id -u)" -type s -name agent.\* 2>/dev/null
}

function sshagent_testsocket {
    if ! command -v ssh-add >/dev/null; then
        msg_err "ssh-add no está disponible. Cancelando prueba de socket." \
                "ssh-add is not available. Cancelling socket test."
        return 1
    fi

    [ -n "$1" ] && export SSH_AUTH_SOCK=$1
    [ -z "$SSH_AUTH_SOCK" ] && return 2

    if [ -S "$SSH_AUTH_SOCK" ]; then
        ssh-add -l > /dev/null
        case $? in
            2)
                msg "Socket $SSH_AUTH_SOCK no responde. Eliminando..." \
                    "Socket $SSH_AUTH_SOCK is unresponsive. Removing..."
                rm -f "$SSH_AUTH_SOCK"
                return 4
                ;;
            0)
                msg "Agente SSH encontrado en $SSH_AUTH_SOCK" \
                    "Found SSH agent at $SSH_AUTH_SOCK"
                return 0
                ;;
        esac
    else
        msg_err "$SSH_AUTH_SOCK no es un socket válido." "$SSH_AUTH_SOCK is not a valid socket."
        return 3
    fi
}

function sshagent_reload {
    local AGENTFOUND=0

    if sshagent_testsocket; then AGENTFOUND=1; fi

    if [ $AGENTFOUND -eq 0 ]; then
        for agentsocket in $(sshagent_findsockets); do
            if sshagent_testsocket "$agentsocket"; then
                AGENTFOUND=1
                break
            fi
        done
    fi

    if [ $AGENTFOUND -eq 0 ]; then
        eval "$(ssh-agent)"
    fi

    unset AGENTFOUND
    unset agentsocket

    ssh-add -l
}

if [[ -f "$HOME/.ssh/environment" ]]; then
    sshagent_reload > /dev/null 2>&1
fi

alias sagent_start="sshagent_start"
alias sagent_stop="sshagent_stop"

unset -f sshagent_findsockets sshagent_testsocket