|
#!/bin/bash |
|
|
|
function die() { |
|
local message="$1" code=$2 |
|
if [[ -z "$code" ]]; then |
|
code=1 |
|
fi |
|
|
|
(>&2 echo -e "$message") |
|
exit $code |
|
} |
|
|
|
function log() { |
|
local message="$1" |
|
if [[ "$silent" == "yes" ]]; then |
|
return 0 |
|
fi |
|
echo "$message" |
|
} |
|
|
|
function testVersion() { |
|
local version="$1" expectedVersion="$2" |
|
[ -z "$expectedVersion" ] && die "testVersion requires that expectedVersion is set" |
|
[ -z "$version" ] && return 1 |
|
local result=`echo -n "$version" | awk -v expected="$expectedVersion" '{split($0,v,"."); split(expected,ev,"."); if ((v[1] == ev[1]) && ((v[2] == ev[2] && v[3] >= ev[3]) || (v[2] > ev[2]))) print $0}'` |
|
[ -z "$result" ] && return 1 |
|
return 0 |
|
} |
|
|
|
function testGpgVersion() { |
|
local gpgPath="$1" |
|
([ -n "$gpgPath" ] && [ -e "$gpgPath" ]) || return 1 |
|
local gpgVersion=`$gpgPath --version | awk '/^gpg/ { print $3 }'` |
|
testVersion "$gpgVersion" "2.1.11" && return 0 |
|
return 1 |
|
} |
|
|
|
function getGpg { |
|
local gpgPath="`which gpg`" |
|
if [[ -n "$gpgPath" ]]; then |
|
testGpgVersion "$gpgPath" && echo -n "$gpgPath" && return 0 |
|
gpgPath="`which gpg2`" |
|
else |
|
gpgPath="`which gpg2`" |
|
fi |
|
|
|
[ -z "$gpgPath" ] && die "gpg was not at least version 2.11.17 and gpg2 was not found. Have you installed gpg2?" |
|
testGpgVersion "$gpgPath" || die "gpg/gpg2 were not at least version 2.11.17." |
|
echo -n "$gpgPath" |
|
} |
|
|
|
function echoHelp { |
|
local errorMessage="$1" |
|
echo |
|
echo "Keybase Public Key SSH Authorizer" |
|
echo |
|
echo "Usage: authorizedKeybaseId.sh [--help] [-s] keybaseID " |
|
echo |
|
echo "Required Parameters: " |
|
echo "keybaseID - The keybase user ID to import (only keybase format IDs are supported, twitter handles and others are not)" |
|
echo |
|
echo "Optional Parameters: " |
|
echo "--help - This help information" |
|
echo "-s - Execute with only error output enabled" |
|
echo |
|
[ -z "$errorMessage" ] && die "$errorMessage" |
|
exit 2 |
|
} |
|
|
|
silent="no" |
|
account="$1" |
|
|
|
[ "$USER" == "root" ] && die "This script should be run as the user who is authorizing a key, not root" |
|
|
|
[ "$1" == "--help" ] && echoHelp |
|
if [[ "$1" == "--s" ]]; then |
|
account="$2" |
|
fi |
|
[ -z "$account" ] && echoHelp "Required parameter, 'keybaseID', was not provided" |
|
|
|
gpg=`getGpg` |
|
log "Found gpg at $gpg" |
|
# On different machines, I get a 64-bit or 32-bit hash. We want the 64-bit one, so one more step to get that |
|
keyHash=`curl "https://keybase.io/$account/pgp_keys.asc" -s | $gpg --import 2>&1 | awk '/gpg\: key [0-9A-F]{8}/ { print substr($3,1,8) }'` |
|
[ -z keyHash ] && die "Failed to get the key for the keybase account of $account" |
|
keyHash64=`$gpg --list-keys --fingerprint --with-colon | awk -v fp="$keyHash" -F ":" '{ if ($10 ~ fp) print "0x" substr($10, 25, 16) }'` |
|
[ -z keyHash64 ] && die "Failed to get the key for the keybase account of $account" |
|
|
|
# GPG keys should have a sub-key that is configured for authorization. Ours will not, so we force the export |
|
# with the bang. If you imported the SSH key and generated the authorization sub key, this will still allow you |
|
# to login with that private key |
|
sshAuthorizedKey=`$gpg --export-ssh-key "${keyHash64}!"` |
|
sshKeyComment="# Key from https://keybase.io/$account/pgp_keys.asc for $account" |
|
[ -z "$sshAuthorizedKey" ] && die "Couldn't export the key for '${keyHash64}'" |
|
|
|
sshDir="${HOME}/.ssh" |
|
authKeys="${sshDir}/authorized_keys" |
|
|
|
[ -d "$sshDir" ] || mkdir "$sshDir" |
|
if [ ! -f "${authKeys}" ]; then |
|
echo "$sshKeyComment" > "$authKeys" |
|
chown "${USER}":"${USER}" "$authKeys" |
|
chmod 600 "$authKeys" |
|
else |
|
sshKey=`echo "$sshAuthorizedKey" | awk '{print $2}'` |
|
existingKey=`cat "$authKeys" | awk -v key="$sshKey" '{ if ($2 ~ key) print $0 }'` |
|
[ -n $existingKey ] && die "User's key is already authorized" |
|
echo "$sshKeyComment" >> "$authKeys" |
|
fi |
|
echo "$sshAuthorizedKey" >> "$authKeys" |