1# -*-shell-script-*- 2# This should be sourced by bash (though we welcome changes to make it POSIX sh compliant) 3 4# Monkeysphere authentication add-certifier subcommand 5# 6# This function adds a certifier whose signatures will be used to 7# calculate validity of keys used to connect to user accounts on the 8# server. The specified certifier key is first retrieved from the Web 9# of Trust with the monkeysphere-user-controlled gpg_sphere keyring. 10# Once then new key is retrieved, it is imported into the core 11# keyring. The gpg_core then ltsigns the key with the desired trust 12# level, and then the key is exported back to the gpg_sphere keyring. 13# The gpg_sphere has ultimate owner trust of the core key, so the core 14# ltsigs on the new certifier key can then be used by gpg_sphere 15# calculate validity for keys inserted in the authorized_keys file. 16# 17# This is all to keep the monkeysphere user that connects to the 18# keyservers from accessing the core secret key. 19# 20# The monkeysphere scripts are written by: 21# Jameson Rollins <jrollins@finestructure.net> 22# Jamie McClelland <jm@mayfirst.org> 23# Daniel Kahn Gillmor <dkg@fifthhorseman.net> 24# 25# They are Copyright 2008-2009, and are all released under the GPL, 26# version 3 or later. 27 28add_certifier() { 29 30local domain= 31local trust=full 32local depth=1 33local keyID 34local fingerprint 35local ltsignCommand 36local trustval 37 38# get options 39while true ; do 40 case "$1" in 41 -n|--domain) 42 domain="$2" 43 shift 2 44 ;; 45 -t|--trust) 46 trust="$2" 47 shift 2 48 ;; 49 -d|--depth) 50 depth="$2" 51 shift 2 52 ;; 53 -) 54 break 55 ;; 56 *) 57 if [ "$(echo "$1" | cut -c 1)" = '-' ] ; then 58 failure "Unknown option '$1'. 59Type '$PGRM help' for usage." 60 fi 61 break 62 ;; 63 esac 64done 65 66keyID="$1" 67 68# check that key ID or file is specified 69if [ -z "$keyID" ] ; then 70 failure "You must specify the key ID of a key to add, or specify a file to read the key from." 71fi 72 73# check the trust value 74case "$trust" in 75 'marginal') 76 trustval=1 77 ;; 78 'full') 79 trustval=2 80 ;; 81 *) 82 failure "Trust value requested ('$trust') was unclear (only 'marginal' or 'full' are supported)." 83 ;; 84esac 85 86# if file is specified 87if [ -f "$keyID" -o "$keyID" = '-' ] ; then 88 # load the key from stdin 89 if [ "$keyID" = '-' ] ; then 90 # make a temporary file to hold the key from stdin 91 keyID=$(msmktempfile) 92 trap "rm -f $keyID" EXIT 93 log verbose "reading key from stdin..." 94 cat > "$keyID" 95 96 # load the key from the file 97 elif [ -f "$keyID" ] ; then 98 log verbose "reading key from file '$keyID'..." 99 fi 100 101 # check the key is ok as monkeysphere user before loading 102 log debug "checking keys in file..." 103 fingerprint=$(su_monkeysphere_user \ 104 bash -c "$(printf ". %q && list_primary_fingerprints" "${SYSSHAREDIR}/common")" < "$keyID") 105 106 if [ $(printf "%s" "$fingerprint" | egrep -c '^[A-F0-9]{40}$') -ne 1 ] ; then 107 failure "There was not exactly one gpg key in the file." 108 fi 109 110 # load the key 111 gpg_sphere --import <"$keyID" 2>/dev/null \ 112 || failure "could not read key from '$keyID'" 113 114# else, get the key from the keyserver 115else 116 log verbose "searching keyserver $KEYSERVER for keyID $keyID..." 117 gpg_sphere --keyserver "$KEYSERVER" --recv-key "0x${keyID}!" \ 118 || failure "Could not receive a key with this ID from the '$KEYSERVER' keyserver." 119 120 # get the full fingerprint of new certifier key 121 log debug "getting fingerprint of certifier key..." 122 fingerprint=$(gpg_sphere --list-key --with-colons --with-fingerprint "0x${keyID}!" \ 123 | awk -F: '/^fpr:/{ if (ok) { print $10 } ; ok=0 } /^pub:/{ ok=1 }') 124 125 # test that there is only a single fingerprint 126 if (( $(echo "$fingerprint" | wc -l) != 1 )) ; then 127 cat <<EOF 128More than one fingerprint found: 129$fingerprint 130Please use a more specific key ID. 131EOF 132 failure 133 fi 134 135 log info "key found:" 136 gpg_sphere --fingerprint "0x${fingerprint}!" 137 138 if [ "$PROMPT" != "false" ] ; then 139 printf "Are you sure you want to add the above key as a certifier\nof users on this system? (Y/n) " >&2 140 read OK; OK=${OK:-Y} 141 if [ "${OK/y/Y}" != 'Y' ] ; then 142 failure "Identity certifier not added." 143 fi 144 else 145 log debug "adding key without prompting." 146 fi 147fi 148 149# export the key to the core keyring so that the core can sign the 150# new certifier key 151log debug "loading key into core keyring..." 152gpg_sphere --export "0x${fingerprint}!" | gpg_core --import 153 154# edit-key script to ltsign key 155# NOTE: *all* user IDs will be ltsigned 156ltsignCommand="ltsign 157y 158$trustval 159$depth 160$domain 161y 162save" 163# end script 164 165# core ltsigns the newly imported certifier key 166log debug "executing core ltsign script..." 167if echo "$ltsignCommand" | \ 168 gpg_core --command-fd 0 --edit-key "0x${fingerprint}!" ; then 169 170 # transfer the new sigs back to the sphere keyring 171 gpg_core_sphere_sig_transfer 172 173 # update the sphere trustdb 174 log debug "updating sphere trustdb..." 175 gpg_sphere --check-trustdb 2>&1 | log debug 176 177 log info "Identity certifier added." 178else 179 failure "Problem adding identify certifier." 180fi 181 182} 183