fix: pass connect command
parent
f42e8b5901
commit
0ee5b71b64
104
sshkeys.bash
104
sshkeys.bash
|
|
@ -9,7 +9,10 @@ PASS_DIR="$PASSWORD_STORE_DIR"
|
||||||
VERBOSE=0
|
VERBOSE=0
|
||||||
|
|
||||||
# Helper functions
|
# Helper functions
|
||||||
die() { echo "Error: $*" >&2; exit 1; }
|
die() {
|
||||||
|
echo "Error: $*" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
debug() { [[ $VERBOSE -eq 1 ]] && echo "DEBUG: $*" >&2; }
|
debug() { [[ $VERBOSE -eq 1 ]] && echo "DEBUG: $*" >&2; }
|
||||||
yesno() {
|
yesno() {
|
||||||
local answer
|
local answer
|
||||||
|
|
@ -44,7 +47,7 @@ cmd_import_with_deps() {
|
||||||
debug "Skipping comment line"
|
debug "Skipping comment line"
|
||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
if (( in_block )); then
|
if ((in_block)); then
|
||||||
if [[ "$line" =~ ^[Hh][Oo][Ss][Tt][[:space:]]+ ]]; then
|
if [[ "$line" =~ ^[Hh][Oo][Ss][Tt][[:space:]]+ ]]; then
|
||||||
debug "Found next Host block, stopping"
|
debug "Found next Host block, stopping"
|
||||||
break
|
break
|
||||||
|
|
@ -58,9 +61,9 @@ cmd_import_with_deps() {
|
||||||
host_block+=("$line")
|
host_block+=("$line")
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
done < "$CONFIG_FILE"
|
done <"$CONFIG_FILE"
|
||||||
|
|
||||||
(( ${#host_block[@]} )) || die "Host '$hostname' not found in $CONFIG_FILE"
|
((${#host_block[@]})) || die "Host '$hostname' not found in $CONFIG_FILE"
|
||||||
debug "Found ${#host_block[@]} lines in host block"
|
debug "Found ${#host_block[@]} lines in host block"
|
||||||
|
|
||||||
# Check for ProxyJump directive and import dependencies
|
# Check for ProxyJump directive and import dependencies
|
||||||
|
|
@ -70,7 +73,7 @@ cmd_import_with_deps() {
|
||||||
debug "Checking line for ProxyJump: $line"
|
debug "Checking line for ProxyJump: $line"
|
||||||
if [[ "$line" =~ ^[[:space:]]*[Pp][Rr][Oo][Xx][Yy][Jj][Uu][Mm][Pp][[:space:]]+([^[:space:]]+) ]]; then
|
if [[ "$line" =~ ^[[:space:]]*[Pp][Rr][Oo][Xx][Yy][Jj][Uu][Mm][Pp][[:space:]]+([^[:space:]]+) ]]; then
|
||||||
debug "Found ProxyJump directive: ${BASH_REMATCH[1]}"
|
debug "Found ProxyJump directive: ${BASH_REMATCH[1]}"
|
||||||
IFS=',' read -ra proxy_hosts <<< "${BASH_REMATCH[1]}"
|
IFS=',' read -ra proxy_hosts <<<"${BASH_REMATCH[1]}"
|
||||||
for proxy in "${proxy_hosts[@]}"; do
|
for proxy in "${proxy_hosts[@]}"; do
|
||||||
# Remove leading/trailing whitespace
|
# Remove leading/trailing whitespace
|
||||||
proxy="${proxy#"${proxy%%[![:space:]]*}"}"
|
proxy="${proxy#"${proxy%%[![:space:]]*}"}"
|
||||||
|
|
@ -95,7 +98,8 @@ cmd_import_with_deps() {
|
||||||
local identity_files=()
|
local identity_files=()
|
||||||
local identity_paths=()
|
local identity_paths=()
|
||||||
for line in "${host_block[@]}"; do
|
for line in "${host_block[@]}"; do
|
||||||
if [[ "$line" =~ ^[Ii][Dd][Ee][Nn][Tt][Ii][Tt][Yy][Ff][Ii][Ll][Ee][[:space:]]+([^[:space:]]+) ]]; then
|
debug "Checking line for IdentityFile: $line"
|
||||||
|
if [[ "$line" =~ ^[[:space:]]*[Ii][Dd][Ee][Nn][Tt][Ii][Tt][Yy][Ff][Ii][Ll][Ee][[:space:]]+([^[:space:]]+) ]]; then
|
||||||
identity_file="${BASH_REMATCH[1]}"
|
identity_file="${BASH_REMATCH[1]}"
|
||||||
debug "Found IdentityFile: $identity_file"
|
debug "Found IdentityFile: $identity_file"
|
||||||
identity_files+=("$identity_file")
|
identity_files+=("$identity_file")
|
||||||
|
|
@ -116,7 +120,7 @@ cmd_import_with_deps() {
|
||||||
for i in "${!identity_files[@]}"; do
|
for i in "${!identity_files[@]}"; do
|
||||||
identity_file="${identity_files[$i]}"
|
identity_file="${identity_files[$i]}"
|
||||||
rel_path="${identity_paths[$i]}"
|
rel_path="${identity_paths[$i]}"
|
||||||
debug "Processing IdentityFile $((i+1))/${#identity_files[@]}: $identity_file"
|
debug "Processing IdentityFile $((i + 1))/${#identity_files[@]}: $identity_file"
|
||||||
|
|
||||||
# Expand path
|
# Expand path
|
||||||
local expanded_path="${identity_file/#\~/$HOME}"
|
local expanded_path="${identity_file/#\~/$HOME}"
|
||||||
|
|
@ -146,7 +150,7 @@ cmd_import_with_deps() {
|
||||||
|
|
||||||
# Insert into pass
|
# Insert into pass
|
||||||
debug "Inserting key into pass store"
|
debug "Inserting key into pass store"
|
||||||
pass insert --multiline "$store_path" < "$expanded_path" || die "Failed to insert $store_path"
|
pass insert --multiline "$store_path" <"$expanded_path" || die "Failed to insert $store_path"
|
||||||
else
|
else
|
||||||
debug "IdentityFile not found: $expanded_path"
|
debug "IdentityFile not found: $expanded_path"
|
||||||
echo "Skipping non-existent IdentityFile: $identity_file"
|
echo "Skipping non-existent IdentityFile: $identity_file"
|
||||||
|
|
@ -186,7 +190,7 @@ cmd_export() {
|
||||||
if [[ "$line" =~ ^[Hh][Oo][Ss][Tt][[:space:]]+([^#]+) ]]; then
|
if [[ "$line" =~ ^[Hh][Oo][Ss][Tt][[:space:]]+([^#]+) ]]; then
|
||||||
existing_patterns+=("${BASH_REMATCH[1]}")
|
existing_patterns+=("${BASH_REMATCH[1]}")
|
||||||
fi
|
fi
|
||||||
done < "$CONFIG_FILE"
|
done <"$CONFIG_FILE"
|
||||||
|
|
||||||
# Check if exported Host patterns exist
|
# Check if exported Host patterns exist
|
||||||
local exported_patterns
|
local exported_patterns
|
||||||
|
|
@ -207,7 +211,7 @@ cmd_export() {
|
||||||
done
|
done
|
||||||
done
|
done
|
||||||
|
|
||||||
if (( conflict )) && ! yesno "Overwrite conflicting Host entries?"; then
|
if ((conflict)) && ! yesno "Overwrite conflicting Host entries?"; then
|
||||||
die "Export aborted"
|
die "Export aborted"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
@ -234,19 +238,19 @@ cmd_export() {
|
||||||
in_block { next }
|
in_block { next }
|
||||||
delete_lines { delete_lines=0; next }
|
delete_lines { delete_lines=0; next }
|
||||||
{ print }
|
{ print }
|
||||||
' "$backup" > "$CONFIG_FILE" || die "Failed to remove conflicts"
|
' "$backup" >"$CONFIG_FILE" || die "Failed to remove conflicts"
|
||||||
|
|
||||||
# Append new Host block
|
# Append new Host block
|
||||||
echo "Appending Host block for $hostname to $CONFIG_FILE"
|
echo "Appending Host block for $hostname to $CONFIG_FILE"
|
||||||
echo "$host_block" >> "$CONFIG_FILE"
|
echo "$host_block" >>"$CONFIG_FILE"
|
||||||
|
|
||||||
# Export IdentityFiles
|
# Export IdentityFiles
|
||||||
local identity_files=()
|
local identity_files=()
|
||||||
while IFS= read -r line; do
|
while IFS= read -r line; do
|
||||||
if [[ "$line" =~ ^[Ii][Dd][Ee][Nn][Tt][Ii][Tt][Yy][Ff][Ii][Ll][Ee][[:space:]]+([^[:space:]]+) ]]; then
|
if [[ "$line" =~ ^[[:space:]]*[Ii][Dd][Ee][Nn][Tt][Ii][Tt][Yy][Ff][Ii][Ll][Ee][[:space:]]+([^[:space:]]+) ]]; then
|
||||||
identity_files+=("${BASH_REMATCH[1]}")
|
identity_files+=("${BASH_REMATCH[1]}")
|
||||||
fi
|
fi
|
||||||
done <<< "$host_block"
|
done <<<"$host_block"
|
||||||
|
|
||||||
for identity_file in "${identity_files[@]}"; do
|
for identity_file in "${identity_files[@]}"; do
|
||||||
local expanded_path="${identity_file/#\~/$HOME}"
|
local expanded_path="${identity_file/#\~/$HOME}"
|
||||||
|
|
@ -273,7 +277,7 @@ cmd_export() {
|
||||||
|
|
||||||
echo "Exporting $store_path to $expanded_path"
|
echo "Exporting $store_path to $expanded_path"
|
||||||
mkdir -p "$(dirname "$expanded_path")"
|
mkdir -p "$(dirname "$expanded_path")"
|
||||||
pass show "$store_path" > "$expanded_path"
|
pass show "$store_path" >"$expanded_path"
|
||||||
chmod 600 "$expanded_path"
|
chmod 600 "$expanded_path"
|
||||||
done
|
done
|
||||||
|
|
||||||
|
|
@ -290,7 +294,7 @@ cmd_import_all() {
|
||||||
echo "Importing host: $hostname"
|
echo "Importing host: $hostname"
|
||||||
cmd_import_with_deps "$hostname" || echo "Failed to import $hostname"
|
cmd_import_with_deps "$hostname" || echo "Failed to import $hostname"
|
||||||
fi
|
fi
|
||||||
done < "$CONFIG_FILE"
|
done <"$CONFIG_FILE"
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd_export_all() {
|
cmd_export_all() {
|
||||||
|
|
@ -315,8 +319,14 @@ cmd_connect() {
|
||||||
|
|
||||||
# Create temporary directory for keys
|
# Create temporary directory for keys
|
||||||
local tmp_dir=$(mktemp -d)
|
local tmp_dir=$(mktemp -d)
|
||||||
|
debug "Created temporary directory: $tmp_dir"
|
||||||
trap 'rm -rf "$tmp_dir"' EXIT
|
trap 'rm -rf "$tmp_dir"' EXIT
|
||||||
|
|
||||||
|
# Create empty temporary SSH config
|
||||||
|
local tmp_config="$tmp_dir/config"
|
||||||
|
touch "$tmp_config"
|
||||||
|
debug "Created temporary config: $tmp_config"
|
||||||
|
|
||||||
# Function to process a host and its ProxyJump dependencies
|
# Function to process a host and its ProxyJump dependencies
|
||||||
process_host() {
|
process_host() {
|
||||||
local host="$1"
|
local host="$1"
|
||||||
|
|
@ -326,15 +336,18 @@ cmd_connect() {
|
||||||
local config_store="ssh/$host/config"
|
local config_store="ssh/$host/config"
|
||||||
local host_block
|
local host_block
|
||||||
host_block=$(pass show "$config_store" 2>/dev/null) || die "No config found for $host"
|
host_block=$(pass show "$config_store" 2>/dev/null) || die "No config found for $host"
|
||||||
|
debug "Retrieved host block from $config_store:"
|
||||||
|
debug "$host_block"
|
||||||
|
|
||||||
# Append to temporary SSH config
|
# Append to temporary SSH config
|
||||||
echo "$host_block" >> "$tmp_config"
|
echo "$host_block" >>"$tmp_config"
|
||||||
|
|
||||||
# Extract and restore keys
|
# Extract and restore keys
|
||||||
while IFS= read -r line; do
|
while IFS= read -r line; do
|
||||||
|
debug "Processing config line: $line"
|
||||||
if [[ "$line" =~ ^[[:space:]]*[Pp][Rr][Oo][Xx][Yy][Jj][Uu][Mm][Pp][[:space:]]+([^[:space:]]+) ]]; then
|
if [[ "$line" =~ ^[[:space:]]*[Pp][Rr][Oo][Xx][Yy][Jj][Uu][Mm][Pp][[:space:]]+([^[:space:]]+) ]]; then
|
||||||
debug "Found ProxyJump: ${BASH_REMATCH[1]}"
|
debug "Found ProxyJump: ${BASH_REMATCH[1]}"
|
||||||
IFS=',' read -ra proxy_hosts <<< "${BASH_REMATCH[1]}"
|
IFS=',' read -ra proxy_hosts <<<"${BASH_REMATCH[1]}"
|
||||||
for proxy in "${proxy_hosts[@]}"; do
|
for proxy in "${proxy_hosts[@]}"; do
|
||||||
# Remove leading/trailing whitespace
|
# Remove leading/trailing whitespace
|
||||||
proxy="${proxy#"${proxy%%[![:space:]]*}"}"
|
proxy="${proxy#"${proxy%%[![:space:]]*}"}"
|
||||||
|
|
@ -344,49 +357,61 @@ cmd_connect() {
|
||||||
process_host "$proxy"
|
process_host "$proxy"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
elif [[ "$line" =~ ^[Ii][Dd][Ee][Nn][Tt][Ii][Tt][Yy][Ff][Ii][Ll][Ee][[:space:]]+([^[:space:]]+) ]]; then
|
elif [[ "$line" =~ ^[[:space:]]*[Ii][Dd][Ee][Nn][Tt][Ii][Tt][Yy][Ff][Ii][Ll][Ee][[:space:]]+([^[:space:]]+) ]]; then
|
||||||
local identity_file="${BASH_REMATCH[1]}"
|
local identity_file="${BASH_REMATCH[1]}"
|
||||||
|
debug "Found IdentityFile: $identity_file"
|
||||||
|
|
||||||
local expanded_path="${identity_file/#\~/$HOME}"
|
local expanded_path="${identity_file/#\~/$HOME}"
|
||||||
expanded_path=$(realpath -m "$expanded_path")
|
expanded_path=$(realpath -m "$expanded_path")
|
||||||
|
debug "Expanded path: $expanded_path"
|
||||||
|
|
||||||
# Resolve relative to SSH_DIR if needed
|
# Resolve relative to SSH_DIR if needed
|
||||||
if [[ "$expanded_path" != "$SSH_DIR"/* ]]; then
|
if [[ "$expanded_path" != "$SSH_DIR"/* ]]; then
|
||||||
|
debug "Path not under SSH_DIR, adjusting"
|
||||||
expanded_path="$SSH_DIR/$identity_file"
|
expanded_path="$SSH_DIR/$identity_file"
|
||||||
fi
|
fi
|
||||||
|
debug "Final expanded path: $expanded_path"
|
||||||
|
|
||||||
local rel_path="${expanded_path#$SSH_DIR/}"
|
local rel_path="${expanded_path#$SSH_DIR/}"
|
||||||
rel_path="${rel_path//../_dotdot_}"
|
rel_path="${rel_path//../_dotdot_}"
|
||||||
local store_path="ssh/$host/$rel_path"
|
local store_path="ssh/$host/$rel_path"
|
||||||
local tmp_key="$tmp_dir/$(basename "$identity_file")"
|
local tmp_key="$tmp_dir/$(basename "$identity_file")"
|
||||||
|
debug "Store path: $store_path"
|
||||||
|
debug "Temporary key path: $tmp_key"
|
||||||
|
|
||||||
# Restore key to temporary location
|
# Restore key to temporary location
|
||||||
if pass show "$store_path" > "$tmp_key" 2>/dev/null; then
|
if pass show "$store_path" >"$tmp_key" 2>/dev/null; then
|
||||||
chmod 600 "$tmp_key"
|
chmod 600 "$tmp_key"
|
||||||
debug "Restored key $store_path to $tmp_key"
|
debug "Restored key $store_path to $tmp_key"
|
||||||
# Update config to use temporary key
|
# Update config to use temporary key
|
||||||
|
debug "Updating config to use temporary key"
|
||||||
|
debug "Replacing: $identity_file"
|
||||||
|
debug "With: $tmp_key"
|
||||||
sed -i "s|${identity_file}|${tmp_key}|g" "$tmp_config"
|
sed -i "s|${identity_file}|${tmp_key}|g" "$tmp_config"
|
||||||
else
|
else
|
||||||
|
debug "Failed to retrieve key from $store_path"
|
||||||
echo "Warning: Key $store_path not found in pass"
|
echo "Warning: Key $store_path not found in pass"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
done <<< "$host_block"
|
done <<<"$host_block"
|
||||||
}
|
|
||||||
|
|
||||||
# Create empty temporary SSH config
|
debug "Finished processing host: $host"
|
||||||
local tmp_config="$tmp_dir/config"
|
debug "Current temporary config contents:"
|
||||||
touch "$tmp_config"
|
debug "$(cat "$tmp_config")"
|
||||||
|
}
|
||||||
|
|
||||||
# Process the main host and its dependencies
|
# Process the main host and its dependencies
|
||||||
process_host "$hostname"
|
process_host "$hostname"
|
||||||
|
|
||||||
# Execute SSH command with temporary config
|
# Execute SSH command with temporary config
|
||||||
echo "Connecting to $hostname..."
|
echo "Connecting to $hostname..."
|
||||||
|
debug "Running: ssh -F \"$tmp_config\" \"$hostname\""
|
||||||
ssh -F "$tmp_config" "$hostname"
|
ssh -F "$tmp_config" "$hostname"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Main command handler
|
# Main command handler
|
||||||
case "$1" in
|
case "$1" in
|
||||||
-v|--verbose)
|
-v | --verbose)
|
||||||
VERBOSE=1
|
VERBOSE=1
|
||||||
debug "Verbose mode enabled"
|
debug "Verbose mode enabled"
|
||||||
shift
|
shift
|
||||||
|
|
@ -394,10 +419,25 @@ case "$1" in
|
||||||
esac
|
esac
|
||||||
|
|
||||||
case "$1" in
|
case "$1" in
|
||||||
import) shift; cmd_import_with_deps "$@" ;;
|
import)
|
||||||
import-all) shift; cmd_import_all ;;
|
shift
|
||||||
export) shift; cmd_export "$@" ;;
|
cmd_import_with_deps "$@"
|
||||||
export-all) shift; cmd_export_all ;;
|
;;
|
||||||
connect) shift; cmd_connect "$@" ;;
|
import-all)
|
||||||
*) die "Usage: pass ssh [-v|--verbose] import|import-all|export|export-all|connect [hostname]" ;;
|
shift
|
||||||
|
cmd_import_all
|
||||||
|
;;
|
||||||
|
export)
|
||||||
|
shift
|
||||||
|
cmd_export "$@"
|
||||||
|
;;
|
||||||
|
export-all)
|
||||||
|
shift
|
||||||
|
cmd_export_all
|
||||||
|
;;
|
||||||
|
connect)
|
||||||
|
shift
|
||||||
|
cmd_connect "$@"
|
||||||
|
;;
|
||||||
|
*) die "Usage: pass ssh [-v|--verbose] import|import-all|export|export-all|connect [hostname]" ;;
|
||||||
esac
|
esac
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue