Last active
June 1, 2023 16:48
-
-
Save BoxedBrain/d01fcdfcf00db947cf4780134faae89a to your computer and use it in GitHub Desktop.
Add publicly accessible GitHub user SSH public keys to 'authorized_keys'
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
############################################################ | |
# Script META # | |
############################################################ | |
MetaName="secs.sh" | |
MetaDesc="Add publicly accessible GitHub user SSH public keys to 'authorized_keys'" | |
MetaVersion="2023.6.1" | |
############################################################ | |
# Helpers # | |
# Color, Defaults, ... # | |
############################################################ | |
# Check if stdout is a terminal | |
if test -t 1; then | |
# Check if it supports colors | |
ncolors=$(tput colors) | |
if test -n "$ncolors" && test $ncolors -ge 8; then | |
BOLD="$(tput bold)" | |
UNDERLINE="$(tput smul)" | |
STANDOUT="$(tput smso)" | |
ENDCOLOR="$(tput sgr0)" | |
BLACK="$(tput setaf 0)" | |
RED="$(tput setaf 1)" | |
GREEN="$(tput setaf 2)" | |
YELLOW="$(tput setaf 3)" | |
BLUE="$(tput setaf 4)" | |
MAGENTA="$(tput setaf 5)" | |
CYAN="$(tput setaf 6)" | |
WHITE="$(tput setaf 7)" | |
fi | |
fi | |
# Set variables | |
Verbose=0 | |
Username="" | |
KeyDir="$HOME/.ssh" | |
KeyFile="authorized_keys" | |
KeyPath="$KeyDir/$KeyFile" | |
############################################################ | |
# Help # | |
############################################################ | |
OfferHelp="See '$MetaName -h' for help" | |
Help() | |
{ | |
# Display Help | |
echo $MetaName | |
echo $MetaDesc | |
echo | |
echo "Syntax: $MetaName [-h|V|u]" | |
echo "options:" | |
echo "-h Print this Help and exit." | |
echo "-V Print software version and exit." | |
echo "-u bob Specify username" | |
echo | |
echo "Example: curl -s link-to-$MetaName | bash -s -- -u BoxedBrain" | |
echo | |
} | |
############################################################ | |
# Version # | |
############################################################ | |
Version() | |
{ | |
# Display Version | |
echo "secs.sh@$(hostname)" | |
echo "Version: $MetaVersion" | |
echo "(c) Tobias Nessel" | |
} | |
############################################################ | |
# FixPermissions # | |
# Check and fix file/folder permissions # | |
############################################################ | |
FixPermissions() | |
{ | |
# check '~/.ssh' folder permissions | |
KeyDirPermissions=$(stat --format '%a' $KeyDir) | |
if [[ 700 -ne $KeyDirPermissions ]] | |
then | |
echo "${YELLOW}WARNING${ENDCOLOR} '${KeyDir}' insecure directory permissions: ${KeyDirPermissions}" | |
# fix permissions | |
chmod 700 $KeyDir | |
error=$? | |
if [[ $error -ne 0 ]] | |
then | |
echo "${RED}ERROR${ENDCOLOR} '${KeyDir}' failed to set directory permissions to 700" | |
exit 1 | |
else | |
echo "${GREEN}OK${ENDCOLOR} '${KeyDir}' directory permissions set to 700" | |
fi | |
else | |
[[ 1 -eq $Verbose ]] && echo "'${KeyDir}' permissions: ${KeyDirPermissions}" | |
fi | |
# check 'authorized_keys' file permissions | |
KeyFilePermissions=$(stat --format '%a' $KeyPath) | |
if [[ 600 -ne $KeyFilePermissions ]] | |
then | |
echo "${YELLOW}WARNING${ENDCOLOR} '${KeyPath}' insecure file permissions: ${KeyFilePermissions}" | |
# fix permissions | |
chmod 600 $KeyPath | |
error=$? | |
if [[ $error -ne 0 ]] | |
then | |
echo "${RED}ERROR${ENDCOLOR} '${KeyPath}' failed to set file permissions to 600" | |
exit 1 | |
else | |
echo "${GREEN}OK${ENDCOLOR} '${KeyPath}' file permissions set to 600" | |
fi | |
else | |
[[ 1 -eq $Verbose ]] && echo "'${KeyPath}' permissions: ${KeyFilePermissions}" | |
fi | |
} | |
############################################################ | |
# Process the input options. Add options as needed. # | |
############################################################ | |
# Get the options | |
while getopts ":hVvcu:" option; do | |
case $option in | |
h) # display Help | |
Help | |
exit;; | |
V) # display Version | |
Version | |
exit;; | |
v) # enable verbose mode | |
Verbose=1;; | |
c) # create folder or file if missing | |
Create=1;; | |
u) # enter username | |
Username=$OPTARG;; | |
\?) # invalid option | |
echo "${RED}ERROR${ENDCOLOR} Invalid option provided" | |
echo $OfferHelp | |
exit;; | |
esac | |
done | |
if [ -z $Username ] | |
then | |
echo "${RED}ERROR${ENDCOLOR} Missing argument '-u'" | |
echo $OfferHelp | |
exit 1 | |
fi | |
[[ 1 -eq $Verbose ]] && Version | |
############################################################ | |
############################################################ | |
# Main program # | |
############################################################ | |
############################################################ | |
# Check if folder and keyfile exist | |
# Folder | |
if [[ ! -d $KeyDir ]] | |
then | |
echo "${YELLOW}WARNING${ENDCOLOR} Directory ${KeyDir} does not exist" | |
# should we create it? | |
if [[ 1 -ne $Create ]] | |
then | |
echo "Use -c to create it." | |
exit 1 | |
else | |
mkdir -p $KeyDir | |
error=$? | |
# Check for errors | |
if [[ $error -ne 0 ]] | |
then | |
echo "${RED}ERROR${ENDCOLOR} failed to create '${KeyDir}'!" | |
exit 1 | |
else | |
echo "${GREEN}OK${ENDCOLOR} directory '${KeyDir}' created" | |
fi | |
fi | |
fi | |
# File | |
if [[ ! -f $KeyPath ]] | |
then | |
echo "${YELLOW}WARNING${ENDCOLOR} file '${KeyPath}' does not exist" | |
# should we create it? | |
if [[ 1 -ne $Create ]] | |
then | |
echo "Create it first or use parameter ${YELLOW}-c${ENDCOLOR} to create it" | |
exit 1 | |
else | |
touch $KeyPath | |
error=$? | |
# Check for errors | |
if [[ $error -ne 0 ]] | |
then | |
echo "${RED}ERROR${ENDCOLOR} failed to create '${KeyPath}'!" | |
exit 1 | |
else | |
echo "${GREEN}OK${ENDCOLOR} file '${KeyPath}' created" | |
fi | |
fi | |
fi | |
# Check for permission issues | |
FixPermissions | |
# get existing authorized SSH keys | |
ExistingUserKeys=$(cat $KeyPath) | |
[[ 1 -eq $Verbose ]] && echo -e "Current installed keys: \n ${ExistingUserKeys}" | |
# get available GitHub SSH keys for given user | |
NewKeys=$(curl -s --fail https://github.com/$Username.keys) | |
error=$? | |
if [[ $error -ne 0 ]] | |
then | |
echo "${RED}ERROR${ENDCOLOR} getting keys for '$Username'! Check username and network connection." | |
exit 1 | |
fi | |
[[ 1 -eq $Verbose ]] && echo -e "New keys: \n ${NewKeys}" | |
# add new keys if not already existing | |
IFS=$'\n' | |
CountTotal=0 | |
CountNew=0 | |
for NewKey in $NewKeys | |
do | |
CountTotal=$((CountTotal+1)) | |
if [[ "$ExistingUserKeys" != *"$NewKey"* ]]; then | |
[[ 1 -eq $Verbose ]] && echo $NewKey | |
echo $NewKey >> $KeyPath | |
CountNew=$((CountNew+1)) | |
fi | |
done | |
echo "Total: ${YELLOW}$CountTotal${ENDCOLOR} New: ${GREEN}$CountNew${ENDCOLOR}" | |
exit 0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Run in a terminal:
Run inside a docker container: