-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathghkeyfetch.sh
137 lines (120 loc) · 4.26 KB
/
ghkeyfetch.sh
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
#!/bin/bash
# Check if a username is provided as an argument
if [ $# -lt 1 ]; then
echo "Usage: $0 <github-username> [-c|--confirm] [-a|--add] [-q|--quiet] [-v|--verbose]"
exit 1
fi
# Variables
USERNAME="$1"
CONFIRM=false
ADD=false
QUIET=false
VERBOSE=false
# Parse additional arguments
for arg in "$@"; do
case $arg in
-c|--confirm)
CONFIRM=true
;;
-a|--add)
ADD=true
;;
-q|--quiet)
QUIET=true
;;
-v|--verbose)
VERBOSE=true
;;
*)
;;
esac
done
# Validate the username
if [[ ! "$USERNAME" =~ ^[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*$ ]]; then
echo "Error: Invalid GitHub username. Only letters, numbers, and hyphens are allowed, and hyphens cannot be at the start or end." >&2
exit 1
fi
GITHUB_URL="https://github.com/$USERNAME.keys"
AUTHORIZED_KEYS_FILE="$HOME/.ssh/authorized_keys"
# Create a secure temporary file
AUTHORIZED_KEYS_TEMP=$(mktemp /tmp/authorized_keys_temp.XXXXXX)
# Ensure all temporary files are removed on script exit
cleanup() {
rm -f "$AUTHORIZED_KEYS_TEMP"
[ -n "$AUTHORIZED_KEYS_FILE.new" ] && rm -f "${AUTHORIZED_KEYS_FILE}.new"
}
trap cleanup EXIT
# Function to fetch keys using curl
fetch_with_curl() {
curl -sSf "$GITHUB_URL" -o "$AUTHORIZED_KEYS_TEMP"
}
# Function to fetch keys using wget
fetch_with_wget() {
wget -qO "$AUTHORIZED_KEYS_TEMP" "$GITHUB_URL"
}
# Attempt to download the authorized_keys file using curl or wget
if command -v curl > /dev/null; then
$VERBOSE && echo "Using curl to fetch keys..."
fetch_with_curl
elif command -v wget > /dev/null; then
$VERBOSE && echo "curl not found, using wget to fetch keys..."
fetch_with_wget
else
echo "Error: Neither curl nor wget is available. Please install one of these tools to proceed." >&2
exit 1
fi
# Check if the download was successful
if [ ! -s "$AUTHORIZED_KEYS_TEMP" ]; then
echo "Error: Failed to download the authorized_keys file from GitHub." >&2
exit 1
fi
# Validate each SSH key in the downloaded file using ssh-keygen
VALID=true
while read -r line; do
echo "$line" | ssh-keygen -l -f /dev/stdin > /dev/null 2>&1
if [ $? -ne 0 ]; then
echo "Validation failed: Invalid SSH key detected." >&2
VALID=false
break
fi
done < "$AUTHORIZED_KEYS_TEMP"
if [ "$VALID" = true ]; then
$VERBOSE && echo "All keys are valid."
if [ "$CONFIRM" = true ]; then
if [ "$ADD" = true ]; then
$VERBOSE && echo "Adding new keys to existing authorized_keys file."
# Count existing keys
existing_count=$(grep -c "ssh-" "$AUTHORIZED_KEYS_FILE" 2>/dev/null || echo "0")
# Concatenate the existing keys and new keys, then dedupe
cat "$AUTHORIZED_KEYS_TEMP" "$AUTHORIZED_KEYS_FILE" 2>/dev/null | sort | uniq > "${AUTHORIZED_KEYS_FILE}.new"
# Count total keys after addition and deduplication
total_count=$(grep -c "ssh-" "${AUTHORIZED_KEYS_FILE}.new")
# Calculate the number of keys added
added_count=$((total_count - existing_count))
mv "${AUTHORIZED_KEYS_FILE}.new" "$AUTHORIZED_KEYS_FILE"
else
$VERBOSE && echo "Replacing existing authorized_keys file with new keys."
# Backup the current authorized_keys file (optional)
if [ -f "$AUTHORIZED_KEYS_FILE" ]; then
cp "$AUTHORIZED_KEYS_FILE" "$AUTHORIZED_KEYS_FILE.bak"
fi
# Count the number of keys to be added
added_count=$(grep -c "ssh-" "$AUTHORIZED_KEYS_TEMP")
mv "$AUTHORIZED_KEYS_TEMP" "$AUTHORIZED_KEYS_FILE"
fi
# Set the correct permissions
chmod 600 "$AUTHORIZED_KEYS_FILE"
$VERBOSE && echo "The authorized_keys file has been updated successfully."
# Report keys added if greater than zero (default mode) or in verbose mode
if [ "$added_count" -gt 0 ]; then
$QUIET || echo "Keys added: $added_count"
fi
else
$VERBOSE && echo "Confirmation switch not provided. Skipping the update of the authorized_keys file."
fi
else
echo "Validation failed: No valid SSH key entries found." >&2
exit 1
fi
# Exit with a success status code
exit 0