Merge commit 'jrollins/master'
authorDaniel Kahn Gillmor <dkg@fifthhorseman.net>
Tue, 17 Jun 2008 17:34:32 +0000 (13:34 -0400)
committerDaniel Kahn Gillmor <dkg@fifthhorseman.net>
Tue, 17 Jun 2008 17:34:32 +0000 (13:34 -0400)
etc/monkeysphere-server.conf
etc/monkeysphere.conf
src/common
src/monkeysphere
src/monkeysphere-server
src/monkeysphere-ssh-proxycommand

index 82da49783f91fc3faff6c1fd240af84596efa2b1..3915bf46f4168d7c1a25e89148920c75566e3f66 100644 (file)
@@ -20,4 +20,5 @@
 # Whether to add user controlled authorized_keys file to
 # monkeysphere-generated authorized_keys file.  Should be path to file
 # where '%h' will be replaced by the home directory of the user.
+# To not add any user-controlled file, put "-"
 #USER_CONTROLLED_AUTHORIZED_KEYS=%h/.ssh/authorized_keys
index d478b9315843ddb0cd93437494e322dff038d642..003ecf689591c2b61440158564afac854a900e88 100644 (file)
 #REQUIRED_USER_KEY_CAPABILITY="a"
 
 # Path to user-controlled authorized_keys file to add to
-# Monkeysphere-generated authorized_keys file. If empty, then no
-# user-controlled file will be added.
+# Monkeysphere-generated authorized_keys file.
+# To not add any user-controlled file, put "-"
 #USER_CONTROLLED_AUTHORIZED_KEYS=~/.ssh/authorized_keys
 
 # User known_hosts file
 #USER_KNOWN_HOSTS=~/.ssh/known_hosts
 
-# Whether or not to hash the generated known_hosts lines
-# (empty mean "no").
-#HASH_KNOWN_HOSTS=
-
+# Whether or not to hash the generated known_hosts lines.
+# Should be "true" or "false"
+#HASH_KNOWN_HOSTS=true
index 8d8e5063258910ebb75f7fe032ff3a438648cc84..d1554a62c23ae9f44746d1e1114c0178d1d68f6a 100644 (file)
@@ -43,12 +43,22 @@ cutline() {
 # FIXME: need to figure out how to retrieve all matching keys
 # (not just first 5)
 gpg_fetch_userid() {
-    local id
-    id="$1"
+    local userID
+
+    userID="$1"
+
+    log "checking keyserver $KEYSERVER..."
     echo 1,2,3,4,5 | \
        gpg --quiet --batch --command-fd 0 --with-colons \
        --keyserver "$KEYSERVER" \
-       --search ="$id" >/dev/null 2>&1
+       --search ="$userID" >/dev/null 2>&1
+    if [ "$?" = 0 ] ; then
+       log "  user ID found on keyserver."
+       return 0
+    else
+       log "  user ID not found on keyserver."
+       return 1
+    fi
 }
 
 # check that characters are in a string (in an AND fashion).
@@ -117,7 +127,7 @@ gpg2authorized_keys() {
 
     gpg --export "$keyID" | \
        openpgp2ssh "$keyID" | tr -d '\n'
-    echo " MonkeySphere${DATE}:${userID}"
+    echo " MonkeySphere${DATE}: ${userID}"
 }
 
 # userid and key policy checking
@@ -157,8 +167,11 @@ process_user_id() {
     fi
     requiredPubCapability=$(echo "$requiredCapability" | tr "[:lower:]" "[:upper:]")
 
-    # fetch keys from keyserver, return 1 if none found
-    gpg_fetch_userid "$userID" || return 1
+    # if CHECK_KEYSERVER variable set, check the keyserver
+    # for the user ID
+    if [ "$CHECK_KEYSERVER" = "true" ] ; then
+       gpg_fetch_userid "$userID"
+    fi
 
     # output gpg info for (exact) userid and store
     gpgOut=$(gpg --fixed-list-mode --list-key --with-colons \
@@ -166,7 +179,7 @@ process_user_id() {
 
     # return 1 if there only "tru" lines are output from gpg
     if [ -z "$(echo "$gpgOut" | grep -v '^tru:')" ] ; then
-       log "  key not found."
+       log "  key not found in keychain."
        return 1
     fi
 
@@ -258,14 +271,14 @@ process_user_id() {
     # key cache file
     if [ "$keyOK" -a "$uidOK" -a "${keyIDs[*]}" ] ; then
        for keyID in ${keyIDs[@]} ; do
-           log "  acceptable key/uid found."
+           log "  acceptable key/userID found."
 
            if [ "$MODE" = 'known_hosts' ] ; then
                # export the key
                gpg2known_hosts "$keyID" "$userID" >> \
                    "$cacheDir"/"$userIDHash"."$pubKeyID"
                # hash the cache file if specified
-               if [ "$HASH_KNOWN_HOSTS" ] ; then
+               if [ "$HASH_KNOWN_HOSTS" = "true" ] ; then
                    ssh-keygen -H -f "$cacheDir"/"$userIDHash"."$pubKeyID" > /dev/null 2>&1
                    rm "$cacheDir"/"$userIDHash"."$pubKeyID".old
                fi
@@ -296,18 +309,23 @@ update_userid() {
 
     log "processing userid: '$userID'"
 
+    # return 1 if there is no output of the user ID processing
+    # ie. no key was found
     keyCachePath=$(process_user_id "$userID" "$cacheDir")
-
     if [ -z "$keyCachePath" ] ; then
        return 1
     fi
+
+    # check if user ID is in the authorized_user_ids file
     if ! grep -q "^${userID}\$" "$AUTHORIZED_USER_IDS" ; then
        read -p "user ID not currently authorized.  authorize? [Y|n]: " OK; OK=${OK:=Y}
        if [ ${OK/y/Y} = 'Y' ] ; then
+           # add if specified
            log -n "adding user ID to authorized_user_ids file... "
            echo "$userID" >> "$AUTHORIZED_USER_IDS"
            echo "done."
        else
+           # else do nothing
            log "authorized_user_ids file untouched."
        fi
     fi
@@ -340,7 +358,7 @@ process_host() {
     host="$1"
     cacheDir="$2"
 
-    log "processing host: '$host'"
+    log "processing host: $host"
 
     keyCachePath=$(process_user_id "ssh://${host}" "$cacheDir")
     if [ $? = 0 ] ; then
@@ -353,18 +371,15 @@ process_host() {
 # go through line-by-line, extract each host, and process with the
 # host processing function
 process_known_hosts() {
-    local knownHosts
     local cacheDir
     local hosts
     local host
 
-    knownHosts="$1"
-    cacheDir="$2"
+    cacheDir="$1"
 
     # take all the hosts from the known_hosts file (first field),
     # grep out all the hashed hosts (lines starting with '|')...
-    cut -d ' ' -f 1 "$knownHosts" | \
-    grep -v '^|.*$' | \
+    meat "$USER_KNOWN_HOSTS" | cut -d ' ' -f 1 | grep -v '^|.*$' | \
     while IFS=, read -r -a hosts ; do
        # ...and process each host
        for host in ${hosts[*]} ; do
@@ -396,7 +411,7 @@ update_authorized_keys() {
     else
        log "no gpg keys to add."
     fi
-    if [ "$userAuthorizedKeys" -a -s "$userAuthorizedKeys" ] ; then
+    if [ "$userAuthorizedKeys" != "-" -a -s "$userAuthorizedKeys" ] ; then
        log -n "adding user authorized_keys file... "
        cat "$userAuthorizedKeys" >> "$msAuthorizedKeys"
        echo "done."
index 23ebd63d0eedb8404a229e95853ac1f71e931b1f..230de06839e54f82f3392a128de135de86546cf7 100755 (executable)
@@ -113,9 +113,10 @@ MS_CONF=${MS_CONF:-"${MS_HOME}/monkeysphere.conf"}
 AUTHORIZED_USER_IDS=${AUTHORIZED_USER_IDS:-"${MS_HOME}/authorized_user_ids"}
 GNUPGHOME=${GNUPGHOME:-"${HOME}/.gnupg"}
 KEYSERVER=${KEYSERVER:-"subkeys.pgp.net"}
+CHECK_KEYSERVER=${CHECK_KEYSERVER:="true"}
 REQUIRED_HOST_KEY_CAPABILITY=${REQUIRED_HOST_KEY_CAPABILITY:-"e a"}
 REQUIRED_USER_KEY_CAPABILITY=${REQUIRED_USER_KEY_CAPABILITY:-"a"}
-USER_CONTROLLED_AUTHORIZED_KEYS=${USER_CONTROLLED_AUTHORIZED_KEYS:-"%h/.ssh/authorized_keys"}
+USER_CONTROLLED_AUTHORIZED_KEYS=${USER_CONTROLLED_AUTHORIZED_KEYS:-"${HOME}/.ssh/authorized_keys"}
 USER_KNOWN_HOSTS=${USER_KNOWN_HOSTS:-"${HOME}/.ssh/known_hosts"}
 HASH_KNOWN_HOSTS=${HASH_KNOWN_HOSTS:-"true"}
 
@@ -157,7 +158,7 @@ case $COMMAND in
                failure "known_hosts file '$USER_KNOWN_HOSTS' is empty."
            fi
            log "processing known_hosts file..."
-           process_known_hosts "$USER_KNOWN_HOSTS" "$hostKeysCacheDir"
+           process_known_hosts "$hostKeysCacheDir"
        fi
        ;;
 
@@ -191,11 +192,8 @@ case $COMMAND in
            failure "$AUTHORIZED_USER_IDS is empty."
        fi
 
-       # set user-controlled authorized_keys file path
-       userAuthorizedKeys=${USER_CONTROLLED_AUTHORIZED_KEYS/\%h/"$HOME"}
-
        # update authorized_keys
-       update_authorized_keys "$msAuthorizedKeys" "$userAuthorizedKeys" "$userKeysCacheDir"
+       update_authorized_keys "$msAuthorizedKeys" "$USER_CONTROLLED_AUTHORIZED_KEYS" "$userKeysCacheDir"
        ;;
 
     'gen-subkey'|'g')
index 3cc7454faec27528e4e9822020a373010e6e2144..6279c4561a324fc40dc7a358df409ef9bb06056c 100755 (executable)
@@ -32,7 +32,7 @@ MonkeySphere server admin tool.
 
 subcommands:
   update-users (s) [USER]...            update users authorized_keys files
-  gen-key (g)                           generate gpg key for the server
+  gen-key (g) [HOSTNAME]                generate gpg key for the server
   publish-key (p)                       publish server key to keyserver
   trust-keys (t) KEYID...               mark keyids as trusted
   update-user-userids (u) USER UID...   add/update user IDs for a user
@@ -44,14 +44,26 @@ EOF
 
 # generate server gpg key
 gen_key() {
+    local hostName
+
+    hostName=${1:-$(hostname --fqdn)}
+
     # set key defaults
     KEY_TYPE=${KEY_TYPE:-"RSA"}
     KEY_LENGTH=${KEY_LENGTH:-"2048"}
     KEY_USAGE=${KEY_USAGE:-"auth,encrypt"}
-    SERVICE=${SERVICE:-"ssh"}
-    HOSTNAME_FQDN=${HOSTNAME_FQDN:-$(hostname -f)}
+    cat <<EOF
+Please specify how long the key should be valid.
+         0 = key does not expire
+      <n>  = key expires in n days
+      <n>w = key expires in n weeks
+      <n>m = key expires in n months
+      <n>y = key expires in n years
+EOF
+    read -p "Key is valid for? ($EXPIRE) " EXPIRE; EXPIRE=${EXPIRE:-"0"}
 
-    USERID=${USERID:-"$SERVICE"://"$HOSTNAME_FQDN"}
+    SERVICE=${SERVICE:-"ssh"}
+    USERID=${USERID:-"$SERVICE"://"$hostName"}
 
     # set key parameters
     keyParameters=$(cat <<EOF
@@ -59,6 +71,7 @@ Key-Type: $KEY_TYPE
 Key-Length: $KEY_LENGTH
 Key-Usage: $KEY_USAGE
 Name-Real: $USERID
+Expire-Date: $EXPIRE
 EOF
 )
 
@@ -91,8 +104,9 @@ EOF
 EOF
 )
 
-    log "generating server key..."
+    log -n "generating server key... "
     echo "$keyParameters" | gpg --batch --gen-key
+    echo "done."
 }
 
 ########################################################################
@@ -111,10 +125,10 @@ MS_CONF=${MS_CONF:-"$MS_HOME"/monkeysphere-server.conf}
 [ -e "$MS_CONF" ] && . "$MS_CONF"
 
 # set empty config variable with defaults
-GNUPGHOME=${GNUPGHOME:-"$MS_HOME"/gnupg}
-KEYSERVER=${KEYSERVER:-subkeys.pgp.net}
+GNUPGHOME=${GNUPGHOME:-"${MS_HOME}/gnupg"}
+KEYSERVER=${KEYSERVER:-"subkeys.pgp.net"}
 REQUIRED_USER_KEY_CAPABILITY=${REQUIRED_USER_KEY_CAPABILITY:-"a"}
-USER_CONTROLLED_AUTHORIZED_KEYS=${USER_CONTROLLED_AUTHORIZED_KEYS:-%h/.ssh/authorized_keys}
+USER_CONTROLLED_AUTHORIZED_KEYS=${USER_CONTROLLED_AUTHORIZED_KEYS:-"%h/.ssh/authorized_keys"}
 
 export GNUPGHOME
 
@@ -162,7 +176,7 @@ case $COMMAND in
        ;;
 
     'gen-key'|'g')
-       gen_key
+       gen_key "$1"
        ;;
 
     'publish-key'|'p')
index 417d0131d4ad61d82e77f437806590c460d336b4..3887e4897d10eca20c7234761ae3e1451238c68c 100755 (executable)
 HOST="$1"
 PORT="$2"
 
+usage() {
+cat <<EOF >&2
+usage: ssh -o ProxyCommand="$(basename $0) %h %p" ...
+EOF
+}
+
+log() {
+    echo "$@" >&2
+}
+
+if [ -z "$HOST" ] ; then
+    log "host must be specified."
+    usage
+    exit 1
+fi
+if [ -z "$PORT" ] ; then
+    log "port must be specified."
+    usage
+    exit 1
+fi
+
+# check for the host key in the known_hosts file
+hostKey=$(ssh-keygen -F "$HOST")
+
+# if the host key is found in the known_hosts file,
+# don't check the keyserver
+if [ "$hostKey" ] ; then
+    CHECK_KEYSERVER="false"
+fi
+export CHECK_KEYSERVER
+
 # update the known_hosts file for the host
 monkeysphere update-known-hosts "$HOST"