Skip to content

Instantly share code, notes, and snippets.

@BoxedBrain
Last active June 1, 2023 16:48
Show Gist options
  • Save BoxedBrain/d01fcdfcf00db947cf4780134faae89a to your computer and use it in GitHub Desktop.
Save BoxedBrain/d01fcdfcf00db947cf4780134faae89a to your computer and use it in GitHub Desktop.
Add publicly accessible GitHub user SSH public keys to 'authorized_keys'
#!/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
@BoxedBrain
Copy link
Author

BoxedBrain commented Jun 1, 2023

Run in a terminal:

curl -s https://gist.githubusercontent.com/BoxedBrain/d01fcdfcf00db947cf4780134faae89a/raw/secs.sh | bash -s -- -u <username>

Run inside a docker container:

docker exec <container> bash -c 'curl -s https://gist.githubusercontent.com/BoxedBrain/d01fcdfcf00db947cf4780134faae89a/raw/secs.sh | bash -s -- -u <username> -vc'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment