Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Add the public key of a keybase.io user to authorized_keys without handling the user's private key or installing the keybase client
#!/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"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment