Merge commit 'jrollins/master'
authorDaniel Kahn Gillmor <dkg@fifthhorseman.net>
Fri, 20 Feb 2009 03:42:43 +0000 (22:42 -0500)
committerDaniel Kahn Gillmor <dkg@fifthhorseman.net>
Fri, 20 Feb 2009 03:42:43 +0000 (22:42 -0500)
20 files changed:
man/man1/monkeysphere.1
man/man8/monkeysphere-authentication.8
man/man8/monkeysphere-host.8
packaging/debian/changelog
src/monkeysphere
src/monkeysphere-authentication
src/monkeysphere-host
src/share/common
src/share/m/gen_subkey
src/share/m/import_subkey
src/share/m/ssh_proxycommand
src/share/m/subkey_to_ssh_agent
src/share/ma/add_certifier
src/share/ma/setup
src/share/mh/add_revoker
src/share/mh/import_key
src/share/mh/publish_key
tests/basic
website/getting-started-admin.mdwn
website/getting-started-user.mdwn

index 3ed43e1c87e394918078918d9f508f0d76af74a3..887b5df1d9de1a59b1179240ba08ca99c629949c 100644 (file)
@@ -58,22 +58,22 @@ were found but none were acceptable.  `a' may be used in place of
 .TP
 .B gen-subkey [KEYID]
 Generate an authentication subkey for a private key in your GnuPG
-keyring.  For the primary key with the specified key ID, generate a
-subkey with "authentication" capability that can be used for
-monkeysphere transactions.  An expiration length can be specified with
-the `-e' or `--expire' option (prompt otherwise).  If no key ID is
+keyring.  KEYID is the key ID for the primary key for which the subkey
+with "authentication" capability will be generated.  If no key ID is
 specified, but only one key exists in the secret keyring, that key
-will be used.  `g' may be used in place of `gen-subkey'.
+will be used.  The length of the generated key can be specified with
+the `--length` or `-l` option.  `g' may be used in place of
+`gen-subkey'.
 .TP
 .B ssh-proxycommand
-an ssh proxy command that can be used
-to trigger a monkeysphere update of the ssh known_hosts file for a
-host that is being connected to with ssh.  This works by updating the
-known_hosts file for the host first, before an attempted connection to
-the host is made.  Once the known_hosts file has been updated, a TCP
-connection to the host is made by exec'ing netcat(1).  Regular ssh
-communication is then done over this netcat TCP connection (see
-ProxyCommand in ssh_config(5) for more info).
+An ssh ProxyCommand that can be used to trigger a monkeysphere update
+of the ssh known_hosts file for a host that is being connected to with
+ssh.  This works by updating the known_hosts file for the host first,
+before an attempted connection to the host is made.  Once the
+known_hosts file has been updated, a TCP connection to the host is
+made by exec'ing netcat(1).  Regular ssh communication is then done
+over this netcat TCP connection (see ProxyCommand in ssh_config(5) for
+more info).
 
 This command is meant to be run as the ssh "ProxyCommand".  This can
 either be done by specifying the proxy command on the command line:
@@ -108,9 +108,10 @@ change in the future, possibly by adding a deferred check, so that
 hosts that go from non-monkeysphere-enabled to monkeysphere-enabled
 will be properly checked.
 
-Setting the MONKEYSPHERE_CHECK_KEYSERVER
-variable (to `true' or `false') will override the keyserver-checking policy
-defined above.
+Setting the CHECK_KEYSERVER variable in the config file or the
+MONKEYSPHERE_CHECK_KEYSERVER environment variable to either `true' or
+`false' will override the keyserver-checking policy defined above and
+either always or never check the keyserver for host key updates.
 
 .TP
 .B subkey-to-ssh-agent [ssh-add arguments]
index 38df65dbf396d659dfe6efe23ebaad303aba9241..361822d4382b9fe6bb742c50a3a2868a31c79e26 100644 (file)
@@ -37,8 +37,11 @@ monkeysphere-controlled authorized_keys file.  If no accounts are
 specified, then all accounts on the system are processed.  `u' may be
 used in place of `update-users'.
 .TP
-.B add-id-certifier KEYID
+.B add-id-certifier KEYID|FILE
 Instruct system to trust user identity certifications made by KEYID.
+The key ID will be loaded from the keyserver.  A file may be loaded
+instead of pulling the key from the keyserver by specifying the path
+to the file as the argument, or by specifying `-` to load from stdin.
 Using the `-n' or `--domain' option allows you to indicate that you
 only trust the given KEYID to make identifications within a specific
 domain (e.g. "trust KEYID to certify user identities within the
index f33aea635dcfa8535ecd88425c2b5c75d7c3fdb3..2b7180759c187e744bb6108bbdf2f045080ea85b 100644 (file)
@@ -58,8 +58,11 @@ place of `add-hostname'.
 Revoke a hostname user ID from the server host key.  `n-' may be used
 in place of `revoke-hostname'.
 .TP
-.B add-revoker FINGERPRINT
-Add a revoker to the host's OpenPGP key.  `o' may be be used in place
+.B add-revoker KEYID|FILE
+Add a revoker to the host's OpenPGP key.  The key ID will be loaded
+from the keyserver.  A file may be loaded instead of pulling the key
+from the keyserver by specifying the path to the file as the argument,
+or by specifying `-` to load from stdin.  `o' may be be used in place
 of `add-revoker'.
 .TP
 .B revoke-key
index 6a9ea18f76e4f08c7612464edaa2cc80640f6bd9..fc317d9e1b3935bcb09a3e3a4f043368ab1b7760 100644 (file)
@@ -16,12 +16,12 @@ monkeysphere (0.23~pre-1) UNRELEASED; urgency=low
     functions that require it to be there.
   * get rid of getopts dependency
   * added version output option
-  * check that existing authentication keys are valid in gen_key
-     function.
+  * better checks on validity of existing authentication subkeys when
+    doing monkeysphere {import,gen}_subkey.
   * add transition infrastructure for major changes between releases (see
     transitions/README.txt)
 
- -- Daniel Kahn Gillmor <dkg@fifthhorseman.net>  Thu, 19 Feb 2009 02:14:44 -0500
+ -- Jameson Graef Rollins <jrollins@finestructure.net>  Thu, 19 Feb 2009 15:11:04 -0500
 
 monkeysphere (0.22-1) unstable; urgency=low
 
index 992ca063ab475f5a554db0c09f787941f8807c34..a65cef62273e76671bc6fe658564195551a2ad8a 100755 (executable)
@@ -45,12 +45,8 @@ Monkeysphere client tool.
 subcommands:
  update-known_hosts (k) [HOST]...    update known_hosts file
  update-authorized_keys (a)          update authorized_keys file
- import-subkey (i)                   import existing ssh key as gpg subkey
-   --keyfile (-f) FILE                 key file to import
-   --expire (-e) EXPIRE                date to expire
  gen-subkey (g) [KEYID]              generate an authentication subkey
    --length (-l) BITS                  key length in bits (2048)
-   --expire (-e) EXPIRE                date to expire
  ssh-proxycommand                    monkeysphere ssh ProxyCommand
  subkey-to-ssh-agent (s)             store authentication subkey in ssh-agent
  version (v)                         show version number
@@ -59,6 +55,88 @@ subcommands:
 EOF
 }
 
+# user gpg command to define common options
+gpg_user() {
+    gpg --no-greeting --quiet --no-tty "$@"
+}
+
+# take a secret key ID and check that only zero or one ID is provided,
+# and that it corresponds to only a single secret key ID
+check_gpg_sec_key_id() {
+    local gpgSecOut
+
+    case "$#" in
+       0)
+           gpgSecOut=$(gpg_user --fixed-list-mode --list-secret-keys --with-colons 2>/dev/null | egrep '^sec:')
+           ;;
+       1)
+           gpgSecOut=$(gpg_user --fixed-list-mode --list-secret-keys --with-colons "$keyID" | egrep '^sec:') || failure
+           ;;
+       *)
+           failure "You must specify only a single primary key ID."
+           ;;
+    esac
+
+    # check that only a single secret key was found
+    case $(echo "$gpgSecOut" | grep -c '^sec:') in
+       0)
+           failure "No secret keys found.  Create an OpenPGP key with the following command:
+ gpg --gen-key"
+           ;;
+       1)
+           echo "$gpgSecOut" | cut -d: -f5
+           ;;
+       *)
+           echo "Multiple primary secret keys found:" | log error
+           echo "$gpgSecOut" | cut -d: -f5 | log error
+           echo "Please specify which primary key to use." | log error
+           failure
+           ;;
+    esac
+}
+
+# check that a valid authentication subkey does not already exist
+check_gpg_authentication_subkey() {
+    local keyID
+    local IFS
+    local line
+    local type
+    local validity
+    local usage
+
+    keyID="$1"
+
+    # check that a valid authentication key does not already exist
+    IFS=$'\n'
+    for line in $(gpg_user --fixed-list-mode --list-keys --with-colons "$keyID") ; do
+       type=$(echo "$line" | cut -d: -f1)
+       validity=$(echo "$line" | cut -d: -f2)
+       usage=$(echo "$line" | cut -d: -f12)
+
+       # look at keys only
+       if [ "$type" != 'pub' -a "$type" != 'sub' ] ; then
+           continue
+       fi
+       # check for authentication capability
+       if ! check_capability "$usage" 'a' ; then
+           continue
+       fi
+       # if authentication key is valid, prompt to continue
+       if [ "$validity" = 'u' ] ; then
+           echo "A valid authentication key already exists for primary key '$keyID'."
+           if [ "$PROMPT" = "true" ] ; then
+               read -p "Are you sure you would like to generate another one? (y/N) " OK; OK=${OK:N}
+               if [ "${OK/y/Y}" != 'Y' ] ; then
+                   failure "aborting."
+               fi
+               break
+           else
+               failure "aborting."
+           fi
+       fi
+    done
+}
+
 ########################################################################
 # MAIN
 ########################################################################
index 22cd018ba2877d23221f2f876dbb6be4b6cf7d79..497470dc88fc5d36d260c20f4832096042f0a2f7 100755 (executable)
@@ -57,7 +57,7 @@ Monkeysphere authentication admin tool.
 subcommands:
  update-users (u) [USER]...          update user authorized_keys files
 
- add-id-certifier (c+) KEYID         import and tsign a certification key
+ add-id-certifier (c+) [KEYID|FILE]  import and tsign a certification key
    --domain (-n) DOMAIN                limit ID certifications to DOMAIN
    --trust (-t) TRUST                  trust level of certifier (full)
    --depth (-d) DEPTH                  trust depth for certifier (1)
index 9d703c20b0c4e37a3498513bb67818caa1c5dc3a..4c7df88e31a72fdd18b63a8e59ee87d47e0ec4d9 100755 (executable)
@@ -59,7 +59,7 @@ subcommands:
  set-expire (e) [EXPIRE]             set host key expiration
  add-hostname (n+) NAME[:PORT]       add hostname user ID to host key
  revoke-hostname (n-) NAME[:PORT]    revoke hostname user ID
- add-revoker (o) FINGERPRINT         add a revoker to the host key
+ add-revoker (o) [KEYID|FILE]        add a revoker to the host key
  revoke-key (r)                      revoke host key
  publish-key (p)                     publish host key to keyserver
 
index d151e859c5b3367316167e64e2acba7e4fcc21cb..653d58ba0154941887a340e7889b391079db1bae 100644 (file)
@@ -1153,7 +1153,6 @@ process_authorized_user_ids() {
 # takes a gpg key or keys on stdin, and outputs a list of
 # fingerprints, one per line:
 list_primary_fingerprints() {
-    local file="$1"
     local fake=$(msmktempdir)
     GNUPGHOME="$fake" gpg --no-tty --quiet --import
     GNUPGHOME="$fake" gpg --with-colons --fingerprint --list-keys | \
index d926ad551116e57e6c3e4510b9923af5e7f23618..dbd9dd69da0da47ae2fc51bf0508b550794fd9ad 100644 (file)
 
 gen_subkey(){
     local keyLength
-    local keyExpire
+    local gpgSecOut
     local keyID
-    local gpgOut
-    local userID
+    local editCommands
+    local fifoDir
 
     # get options
     while true ; do
@@ -27,10 +27,6 @@ gen_subkey(){
                keyLength="$2"
                shift 2
                ;;
-           -e|--expire)
-               keyExpire="$2"
-               shift 2
-               ;;
            *)
                if [ "$(echo "$1" | cut -c 1)" = '-' ] ; then
                    failure "Unknown option '$1'.
@@ -41,67 +37,11 @@ Type '$PGRM help' for usage."
        esac
     done
 
-    case "$#" in
-       0)
-           gpgSecOut=$(gpg --quiet --fixed-list-mode --list-secret-keys --with-colons 2>/dev/null | egrep '^sec:')
-           ;;
-       1)
-           gpgSecOut=$(gpg --quiet --fixed-list-mode --list-secret-keys --with-colons "$1" | egrep '^sec:') || failure
-           ;;
-       *)
-           failure "You must specify only a single primary key ID."
-           ;;
-    esac
-
-    # check that only a single secret key was found
-    case $(echo "$gpgSecOut" | grep -c '^sec:') in
-       0)
-           failure "No secret keys found.  Create an OpenPGP key with the following command:
- gpg --gen-key"
-           ;;
-       1)
-           keyID=$(echo "$gpgSecOut" | cut -d: -f5)
-           ;;
-       *)
-           echo "Multiple primary secret keys found:"
-           echo "$gpgSecOut" | cut -d: -f5
-           failure "Please specify which primary key to use."
-           ;;
-    esac
+    # check that the keyID is unique
+    keyID=$(check_gpg_sec_key_id "$@")
 
-    # check that a valid authentication key does not already exist
-    IFS=$'\n'
-    for line in $(gpg --quiet --fixed-list-mode --list-keys --with-colons "$keyID") ; do
-       type=$(echo "$line" | cut -d: -f1)
-       validity=$(echo "$line" | cut -d: -f2)
-       usage=$(echo "$line" | cut -d: -f12)
-
-       # look at keys only
-       if [ "$type" != 'pub' -a "$type" != 'sub' ] ; then
-           continue
-       fi
-       # check for authentication capability
-       if ! check_capability "$usage" 'a' ; then
-           continue
-       fi
-       # if authentication key is valid, prompt to continue
-       if [ "$validity" = 'u' ] ; then
-           log error "A valid authentication key already exists for primary key '$keyID'."
-           if [ "$PROMPT" = "true" ] ; then
-               read -p "Are you sure you would like to generate another one? (y/N) " OK; OK=${OK:N}
-               if [ "${OK/y/Y}" != 'Y' ] ; then
-                   failure "aborting."
-               fi
-               break
-           else
-               failure "aborting."
-           fi
-       fi
-    done
-
-    # set subkey defaults
-    # prompt about key expiration if not specified
-    keyExpire=$(get_gpg_expiration "$keyExpire")
+    # check that an authentication subkey does not already exist
+    check_gpg_authentication_subkey "$keyID"
 
     # generate the list of commands that will be passed to edit-key
     editCommands=$(cat <<EOF
@@ -112,19 +52,24 @@ E
 A
 Q
 $keyLength
-$keyExpire
+0
 save
 EOF
 )
 
-    log verbose "generating subkey..."
+    # setup the temp fifo dir for retrieving the key password
+    log debug "creating password fifo..."
     fifoDir=$(msmktempdir)
+    trap "rm -rf $fifoDir" EXIT
     (umask 077 && mkfifo "$fifoDir/pass")
-    echo "$editCommands" | gpg --passphrase-fd 3 3< "$fifoDir/pass" --expert --command-fd 0 --edit-key "$keyID" &
+
+    log verbose "generating subkey..."
+    echo "$editCommands" | gpg_user --passphrase-fd 3 3< "$fifoDir/pass" --expert --command-fd 0 --edit-key "$keyID" &
 
     # FIXME: this needs to fail more gracefully if the passphrase is incorrect
     passphrase_prompt  "Please enter your passphrase for $keyID: " "$fifoDir/pass"
 
+    trap - EXIT
     rm -rf "$fifoDir"
     wait
     log verbose "done."
index 8b044568848c2ab6ca22a8717e6ed2b678b1e87c..7333f808d8c8a0f3fe9b14153c53fa02f2a329a7 100644 (file)
 # import an existing ssh key as a gpg subkey
 
 import_subkey() {
-    local keyFile="~/.ssh/id_rsa"
-    local keyExpire
+    local sshKeyFile
     local keyID
-    local gpgOut
-    local userID
-
-    # get options
-    while true ; do
-       case "$1" in
-           -f|--keyfile)
-               keyFile="$2"
-               shift 2
-               ;;
-           -e|--expire)
-               keyExpire="$2"
-               shift 2
-               ;;
-           *)
-               if [ "$(echo "$1" | cut -c 1)" = '-' ] ; then
-                   failure "Unknown option '$1'.
-Type '$PGRM help' for usage."
-               fi
-               break
-               ;;
-       esac
-    done
-
-    log verbose "importing ssh key..."
+    local gpgSecOut
+    local fifoDir
+
+    # FIXME: implement!
+    failure "implement me!"
+
+    sshKeyFile="$1"
+    shift
+
+    # check that key file specified
+    if [ -z "$sshKeyFile" ] ; then
+       failure "Must specify ssh key file to import, or specify '-' for stdin."
+    fi
+
+    # check that the keyID is unique
+    keyID=$(check_gpg_sec_key_id "$@")
+
+    # check that an authentication subkey does not already exist
+    check_gpg_authentication_subkey "$keyID"
+
+    # setup the temp fifo dir for retrieving the key password
+    log debug "creating password fifo..."
     fifoDir=$(msmktempdir)
+    trap "rm -rf $fifoDir" EXIT
     (umask 077 && mkfifo "$fifoDir/pass")
-    ssh2openpgp | gpg --passphrase-fd 3 3< "$fifoDir/pass" --expert --command-fd 0 --import &
 
+    # import ssh key to as authentication subkey
+    if [ "$sshKeyFile" = '-' ] ; then
+       log verbose "importing ssh key from stdin..."
+       PEM2OPENPGP_USAGE_FLAGS=authenticate pem2openpgp "$userID" \
+           | gpg_user --passphrase-fd 3 3< "$fifoDir/pass" --expert --command-fd 0 --import &
+    else
+       log verbose "importing ssh key from file '$sshKeyFile'..."
+       PEM2OPENPGP_USAGE_FLAGS=authenticate pem2openpgp "$userID" <"$sshKeyFile" \
+           | gpg_user --passphrase-fd 3 3< "$fifoDir/pass" --expert --command-fd 0 --import &
+    fi
+
+    # get the password if needed
     passphrase_prompt  "Please enter your passphrase for $keyID: " "$fifoDir/pass"
 
+    trap - EXIT
     rm -rf "$fifoDir"
     wait
     log verbose "done."
index 0a8150088a861cca963eb54f14c0f54645ad4103..bd095889e528f61b0a75a503fcb5a12ba7942c57 100644 (file)
@@ -43,7 +43,7 @@ EOF
     # found?
 
     # get the gpg info for userid
-    gpgOut=$(gpg --list-key --fixed-list-mode --with-colon \
+    gpgOut=$(gpg_user --list-key --fixed-list-mode --with-colon \
        --with-fingerprint --with-fingerprint \
        ="$userID" 2>/dev/null)
 
@@ -71,7 +71,7 @@ EOF
                    rm -f "$sshKeyGPGFile"
 
                    # get the sigs for the matching key
-                   gpgSigOut=$(gpg --check-sigs \
+                   gpgSigOut=$(gpg_user --check-sigs \
                        --list-options show-uid-validity \
                        "$keyid")
 
@@ -171,7 +171,7 @@ URI="ssh://${HOSTP}"
 # CHECK_KEYSERVER variable in the monkeysphere.conf file.
 
 # if the host is in the gpg keyring...
-if gpg --list-key ="${URI}" 2>&1 >/dev/null ; then
+if gpg_user --list-key ="${URI}" 2>&1 >/dev/null ; then
     # do not check the keyserver
     CHECK_KEYSERVER=${CHECK_KEYSERVER:="false"}
 
index a92718efee93ce042fe82b848e0573c2df790365..818f4f70c3ae65a86ed58c169a02c31b89884d5e 100644 (file)
@@ -46,7 +46,8 @@ For more details, see:
     
     # get list of secret keys (to work around bug
     # https://bugs.g10code.com/gnupg/issue945):
-    secretkeys=$(gpg --list-secret-keys --with-colons --fixed-list-mode --fingerprint | \
+    secretkeys=$(gpg_user --list-secret-keys --with-colons --fixed-list-mode \
+       --fingerprint | \
        grep '^fpr:' | cut -f10 -d: | awk '{ print "0x" $1 "!" }')
 
     if [ -z "$secretkeys" ]; then
@@ -54,7 +55,7 @@ For more details, see:
 You might want to run 'gpg --gen-key'."
     fi
     
-    authsubkeys=$(gpg --list-secret-keys --with-colons --fixed-list-mode \
+    authsubkeys=$(gpg_user --list-secret-keys --with-colons --fixed-list-mode \
        --fingerprint --fingerprint $secretkeys | \
        cut -f1,5,10,12 -d: | grep -A1 '^ssb:[^:]*::[^:]*a[^:]*$' | \
        grep '^fpr::' | cut -f3 -d: | sort -u)
@@ -65,6 +66,7 @@ You might want to 'monkeysphere gen-subkey'"
     fi
 
     workingdir=$(msmktempdir)
+    trap "rm -rf $workingdir" EXIT
     umask 077
     mkfifo "$workingdir/passphrase"
     keysuccess=1
@@ -79,19 +81,19 @@ You might want to 'monkeysphere gen-subkey'"
        # fingerprint, but filtering out all / characters to make sure
        # the filename is legit.
 
-       primaryuid=$(gpg --with-colons --list-key "0x${subkey}!" | grep '^pub:' | cut -f10 -d: | tr -d /)
+       primaryuid=$(gpg_user --with-colons --list-key "0x${subkey}!" | grep '^pub:' | cut -f10 -d: | tr -d /)
 
        #kname="[monkeysphere] $primaryuid"
        kname="$primaryuid"
 
        if [ "$1" = '-d' ]; then
            # we're removing the subkey:
-           gpg --export "0x${subkey}!" | openpgp2ssh "$subkey" > "$workingdir/$kname"
+           gpg_user --export "0x${subkey}!" | openpgp2ssh "$subkey" > "$workingdir/$kname"
            (cd "$workingdir" && ssh-add -d "$kname")
        else
            # we're adding the subkey:
            mkfifo "$workingdir/$kname"
-           gpg --quiet --passphrase-fd 3 3<"$workingdir/passphrase" \
+           gpg_user --passphrase-fd 3 3<"$workingdir/passphrase" \
                --export-options export-reset-subkey-passwd,export-minimal,no-export-attributes \
                --export-secret-subkeys "0x${subkey}!" | openpgp2ssh "$subkey" > "$workingdir/$kname" &
            (cd "$workingdir" && DISPLAY=nosuchdisplay SSH_ASKPASS=/bin/false ssh-add "$@" "$kname" </dev/null )&
@@ -104,6 +106,7 @@ You might want to 'monkeysphere gen-subkey'"
        rm -f "$workingdir/$kname"
     done
 
+    trap - EXIT
     rm -rf "$workingdir"
 
     # FIXME: sort out the return values: we're just returning the
index bd41f23966e2c46958ed150e9cc4e3450b0d28a7..e2df1d3b0072786109544d8fb5bff04b9c073880 100644 (file)
@@ -51,6 +51,9 @@ while true ; do
            depth="$2"
            shift 2
            ;;
+       -)
+           break
+           ;;
        *)
            if [ "$(echo "$1" | cut -c 1)" = '-' ] ; then
                failure "Unknown option '$1'.
@@ -62,30 +65,48 @@ Type '$PGRM help' for usage."
 done
 
 keyID="$1"
+
+# check that key ID or file is specified
 if [ -z "$keyID" ] ; then
     failure "You must specify the key ID of a key to add, or specify a file to read the key from."
 fi
-if [ -f "$keyID" ] ; then
-    log info "Reading key from file '$keyID':"
 
-    fingerprints=$(su_monkeysphere_user \
+# if file is specified
+if [ -f "$keyID" -o "$keyID" = '-' ] ; then
+    # load the key from stdin
+    if [ "$keyID" = '-' ] ; then
+       local keyID=$(msmktempfile)
+       trap "rm -f $keyID" EXIT
+       log verbose "reading key from stdin..."
+       cat > "$keyID"
+
+    # load the key from the file
+    elif [ -f "$keyID" ] ; then
+       log verbose "reading key from file '$keyID'..."
+    fi
+
+    # check the key is ok as monkeysphere user before loading
+    log debug "checking keys in file..."
+    fingerprint=$(su_monkeysphere_user \
        ". ${SYSSHAREDIR}/common; list_primary_fingerprints" < "$keyID")
 
-    if [ $(printf "%s" "$fingerprints" | egrep -c '^[A-F0-9]{40}$') -ne 1 ] ; then
+    if [ $(printf "%s" "$fingerprint" | egrep -c '^[A-F0-9]{40}$') -ne 1 ] ; then
        failure "There was not exactly one gpg key in the file."
     fi
 
-    gpg_sphere "--import" < "$keyID" || failure "could not read key from '$keyID'"
+    # load the key
+    gpg_sphere "--import" <"$keyID" \
+       || failure "could not read key from '$keyID'"
+
+    keyID="$fingerprint"
 
-    keyID="$fingerprints"
+# else, get the key from the keyserver
 else
-    # get the key from the key server
-    log debug "retrieving key from keyserver..."
-    gpg_sphere "--keyserver $KEYSERVER --recv-key '0x${keyID}!'" || failure "Could not receive a key with this ID from the '$KEYSERVER' keyserver."
+    log verbose "searching keyserver $KEYSERVER for keyID $keyID..."
+    gpg_sphere "--keyserver $KEYSERVER --recv-key '0x${keyID}!'" \
+       || failure "Could not receive a key with this ID from the '$KEYSERVER' keyserver."
 fi
 
-export keyID
-
 # get the full fingerprint of new certifier key
 log debug "getting fingerprint of certifier key..."
 fingerprint=$(gpg_sphere "--list-key --with-colons --with-fingerprint 0x${keyID}!" \
index 89298711e01ea77853924734ff8da2ca7be9a8ea..e77afff4299795c7a442bccf43e74dea1f2884e3 100644 (file)
@@ -13,7 +13,7 @@
 
 setup() {
     # make all needed directories
-    log debug "make authentication directory structure..."
+    log debug "checking authentication directory structure..."
     mkdir -p "${MADATADIR}"
     chmod 0750 "${MADATADIR}"
     chgrp "$MONKEYSPHERE_USER" "${MADATADIR}"
index 21dc0bb11a7191674d9b48986c0a289fe61014cf..2275f6119688bbaf199f32086111b4f080e72942 100644 (file)
@@ -25,48 +25,62 @@ local ltsignCommand
 local trustval
 
 keyID="$1"
+
+# check that key ID or file is specified
 if [ -z "$keyID" ] ; then
     failure "You must specify the key ID of a revoker key, or specify a file to read the key from."
 fi
-if [ -f "$keyID" ] ; then
-    log info "Reading key from file '$keyID':"
-    importinfo=$(gpg_host --import < "$keyID" 2>&1) || failure "could not read key from '$keyID'"
-    # FIXME: if this is tried when the key database is not
-    # up-to-date, i got these errors (using set -x):
-
-    # ++ su -m monkeysphere -c '\''gpg --import'\''
-    # Warning: using insecure memory!
-    # gpg: key D21739E9: public key "Daniel Kahn Gillmor <dkg@fifthhorseman.net>" imported
-    # gpg: Total number processed: 1
-    # gpg:               imported: 1  (RSA: 1)
-    # gpg: can'\''t create `/var/monkeysphere/gnupg-host/pubring.gpg.tmp'\'': Permission denied
-    # gpg: failed to rebuild keyring cache: Permission denied
-    # gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
-    # gpg: depth: 0  valid:   1  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 1u
-    # gpg: next trustdb check due at 2009-01-10'
-    # + failure 'could not read key from '\''/root/dkg.gpg'\'''
-    # + echo 'could not read key from '\''/root/dkg.gpg'\'''
-
-    keyID=$(echo "$importinfo" | grep '^gpg: key ' | cut -f2 -d: | cut -f3 -d\ )
-    if [ -z "$keyID" ] || [ $(echo "$keyID" | wc -l) -ne 1 ] ; then
+
+# if file is specified
+if [ -f "$keyID" -o "$keyID" = '-' ] ; then
+    # load the key from stdin
+    if [ "$keyID" = '-' ] ; then
+       local keyID=$(msmktempfile)
+       trap "rm -f $keyID" EXIT
+       log verbose "reading key from stdin..."
+       cat > "$keyID"
+
+    # load the key from the file
+    elif [ -f "$keyID" ] ; then
+       log verbose "reading key from file '$keyID'..."
+    fi
+
+    # check the key is ok as monkeysphere user before loading
+    log debug "checking keys in file..."
+    fingerprint=$(su_monkeysphere_user \
+       ". ${SYSSHAREDIR}/common; list_primary_fingerprints" < "$keyID")
+
+    if [ $(printf "%s" "$fingerprint" | egrep -c '^[A-F0-9]{40}$') -ne 1 ] ; then
        failure "There was not exactly one gpg key in the file."
     fi
+
+    # load the key
+    gpg_host --import <"$keyID" \
+       || failure "could not read key from '$keyID'"
+
+    keyID="$fingerprint"
+
+# else, get the key from the keyserver
 else
     # create a temporary directory for storing the downloaded key
-    TMPLOC=$(msmktempdir) || failure "Could not create temporary directory!"
+    local TMPLOC=$(msmktempdir)
+    chmod 0700 "$GNUPGHOME"
+    chown "$MONKEYSPHERE_USER":"$MONKEYSPHERE_USER" "$GNUPGHOME"
 
     # download the key from the keyserver as the monkeysphere user
+    log verbose "searching keyserver $KEYSERVER for keyID $keyID..."
     su_monkeysphere_user \
-       "GNUPGHOME=$TMPLOC gpg --quiet --keyserver $KEYSERVER --recv-key 0x${keyID}!"
+       "GNUPGHOME=$TMPLOC gpg --quiet --keyserver $KEYSERVER --recv-key 0x${keyID}!" \
+       || failure "Could not receive a key with this ID from the '$KEYSERVER' keyserver."
 
     # export the new key to the host keyring
+    log verbose "loading key $keyID..."
     su_monkeysphere_user "GNUPGHOME=$TMPLOC gpg --quiet --export 0x${keyID}!" \
        | gpg_host --import
 fi
 
-export keyID
-
-# get the full fingerprint of the revoker key ID
+# get the full fingerprint of new revoker key
+log debug "getting fingerprint of revoker key..."
 fingerprint=$(gpg_host --list-key --with-colons --with-fingerprint "0x${keyID}!" \
     | grep '^fpr:' | grep "$keyID" | cut -d: -f10)
 
index 6394ad734fec1e601f92d1362329ae9ba51f06ad..040b41c57140862760b9e10dcac2189bdcb44f65 100644 (file)
@@ -21,6 +21,11 @@ local userID
 sshKeyFile="$1"
 hostName="$2"
 
+# check that key file specified
+if [ -z "$sshKeyFile" ] ; then
+    failure "Must specify ssh key file to import, or specify '-' for stdin."
+fi
+
 # use the default hostname if not specified
 if [ -z "$hostName" ] ; then
     hostName=$(hostname -f) || failure "Could not determine hostname."
@@ -45,9 +50,7 @@ mkdir -p "${GNUPGHOME_HOST}"
 chmod 700 "${GNUPGHOME_HOST}"
 
 # import ssh key to a private key
-if [ -z "$sshKeyFile" ] ; then
-    failure "Must specify ssh key file to import, or specify '-' for stdin."
-elif [ "$sshKeyFile" = '-' ] ; then
+if [ "$sshKeyFile" = '-' ] ; then
     log verbose "importing ssh key from stdin..."
     PEM2OPENPGP_USAGE_FLAGS=authenticate pem2openpgp "$userID" \
        | gpg_host --import
index 05faa0be25e55b9a7e1ea7ce9c2bdda00370a09e..b0ffd93b96ae124f4717b85e2256e88c67d6187a 100644 (file)
@@ -28,6 +28,8 @@ fi
 
 # create a temporary gnupg directory from which to publish the key
 export GNUPGHOME=$(msmktempdir)
+chmod 0700 "$GNUPGHOME"
+chown "$MONKEYSPHERE_USER":"$MONKEYSPHERE_USER" "$GNUPGHOME"
 
 # trap to remove tmp dir if break
 trap "rm -rf $GNUPGHOME" EXIT
index 0b91531124d00e5caa4ac419615c7a132036d0a3..3d5097791196055e89ab8c85d69d068839ef7cbd 100755 (executable)
@@ -243,7 +243,7 @@ monkeysphere-authentication list-certifiers
 # generate an auth subkey for the test user that expires in 2 days
 echo "##################################################"
 echo "### generating key for testuser..."
-monkeysphere gen-subkey --expire 2
+monkeysphere gen-subkey
 
 # add server key to testuser keychain
 echo "##################################################"
index 5c7203ddda6d8afc746bd34e61f6c05cdb680222..9010132db7412b7f054ab2050a97aaccf66ec62c 100644 (file)
@@ -4,11 +4,11 @@ Monkeysphere Server Administrator README
 As the administrator of an SSH server, you can take advantage of the
 monkeysphere in two ways:
 
-1. you can publish the host key of your machine so that your users can
-have it automatically verified, and
+1. you can publish the host key of your machine to the Web of Trust
+(WoT) so that your users can have it automatically verified, and
 
 2. you can set up your machine to automatically identify connecting
-users by their presence in the OpenPGP web of trust.
+users by their presence in the OpenPGP Web of Trust.
 
 These things are not mutually required, and it is in fact possible to
 do one without the other.  However, it is highly recommend that you at
@@ -18,26 +18,28 @@ least the host key into the Web of Trust so that your users can be
 sure they're connecting to the correct machine.
 
 
-Monkeysphere for host verification
-==================================
+Monkeysphere for host verification (monkeysphere-host)
+======================================================
 
 Server host key publication
 ---------------------------
 
-To begin, you must first generate a server host key:
+To begin, you must first import an ssh host key.  This assumes that
+you have the ssh server installed, and that you have generated a host
+RSA key.  Once that has been done, import the key:
 
-       # monkeysphere-server gen-key
+       # monkeysphere-host /etc/ssh/ssh\_host\_rsa\_key
 
 This will generate the key for server with the service URI
-(`ssh://server.example.net`).  Output the new key information with the
-'show-key' command:
+(`ssh://server.example.net`).  You can output the new key information
+with the 'show-key' command:
 
-       # monkeysphere-server show-key
+       # monkeysphere-host show-key
 
-Once the key has been generated, it needs to be publish to the Web of
+Once the key has been imported, it needs to be publish to the Web of
 Trust:
 
-       # monkeysphere-server publish-key
+       # monkeysphere-host publish-key
 
 The server admin should now sign the server key so that people in the
 admin's web of trust can identify the server without manual host key
@@ -56,49 +58,17 @@ keyservers:
 
        $ gpg --send-key '=ssh://server.example.net'
 
-Update OpenSSH configuration files
-----------------------------------
+See http://web.monkeysphere.info/signing-host-keys/ for more info
+signing host keys.
 
-To use the newly-generated host key for ssh connections, put the
-following line in `/etc/ssh/sshd_config` (be sure to comment out or
-remove any other HostKey references):
-
-       HostKey /var/lib/monkeysphere/ssh_host_rsa_key
-
-FIXME: What about DSA host keys?  The SSH RFC seems to require
-implementations support DSA, though OpenSSH will work without a DSA
-host key.
-
-
-Monkeysphere for user authentication
-====================================
+Monkeysphere for user authentication (monkeysphere-authentication)
+==================================================================
 
 A host can maintain ssh `authorized_keys` files automatically for its
 users with the Monkeysphere.  These `authorized_keys` files can then
 be used to enable users to use the monkeysphere to authenticate to
 your machine using the OpenPGP web of trust.
 
-Before this can happen, the host must first have a host key to use for
-user key verification.  If you have not already generated a host key
-(as in the host verification instructions above), generate one now:
-
-       # monkeysphere-server gen-key
-
-Update OpenSSH configuration files
-----------------------------------
-
-SSH must be configured to point to the monkeysphere generated
-`authorized_keys` file.  Add this line to `/etc/ssh/sshd_config`
-(again, making sure that no other AuthorizedKeysFile directive is left
-uncommented):
-
-       AuthorizedKeysFile /var/lib/monkeysphere/authorized_keys/%u
-
-You'll need to restart `sshd` to have your changes take effect.  As
-with any change to `sshd_config`, be sure to retain an existing
-session to the machine while you test your changes so you don't get
-locked out.
-
 Monkeysphere authorized_keys maintenance
 ----------------------------------------
 
@@ -113,22 +83,36 @@ means that the server must fully trust at least one person whose
 signature on the connecting user's key would validate the relevant
 user ID.  The individuals trusted to identify users like this are
 known in the Monkeysphere as "Identity Certifiers".  In a simple
-scenario, the host's administrator would be trusted identity certifer.
-If the admin's OpenPGP keyid is `$GPGID`, then on the server run:
+scenario, the host's administrator would be a trusted identity
+certifer.  If the admin's OpenPGP keyid is `$GPGID`, then on the
+server run:
 
-       # monkeysphere-server add-identity-certifier $GPGID
+       # monkeysphere-authentication add-identity-certifier $GPGID
 
 To update the monkeysphere `authorized_keys` file for user "bob" using
 the current set of identity certifiers, run:
 
-       # monkeysphere-server update-users bob
+       # monkeysphere-authentication update-users bob
 
 To update the monkeysphere `authorized_keys` file for all users on the
 the system, run the same command with no arguments:
 
-       # monkeysphere-server update-users
+       # monkeysphere-authentication update-users
 
 You probably want to set up a regularly scheduled job (e.g. with cron)
 to take care of this automatically.
 
-FIXME: document other likely problems and troubleshooting techniques
+Update OpenSSH server AuthorizedKeysFile configuration
+------------------------------------------------------
+
+SSH must be configured to point to the monkeysphere generated
+`authorized_keys` file.  Add this line to `/etc/ssh/sshd_config`
+(again, making sure that no other AuthorizedKeysFile directive is left
+uncommented):
+
+       AuthorizedKeysFile /var/lib/monkeysphere/authorized_keys/%u
+
+You'll need to restart `sshd` to have your changes take effect.  As
+with any change to `sshd_config`, be sure to retain an existing
+session to the machine while you test your changes so you don't get
+locked out.
index 9b04edc819612249349d6b3b5dc9184b13aa642b..d96e5b06216c11854d7fb963f8527983bf1281b8 100644 (file)
@@ -49,7 +49,6 @@ key for that host to the `known_hosts` file if one is found.  This
 command could be added to a crontab as well, if desired.
 
 
-
 Using `monkeysphere-ssh-proxycommand`(1)
 ----------------------------------------
 
@@ -59,7 +58,7 @@ up-to-date for the host you are connecting to with ssh.  The best way
 to integrate this is to add the following line to the "Host *" section
 of your `~/.ssh/config` file:
 
-       ProxyCommand monkeysphere-ssh-proxycommand %h %p
+       ProxyCommand monkeysphere ssh-proxycommand %h %p
 
 The "Host *" section specifies what ssh options to use for all
 connections. If you don't already have a "Host *" line, you can add it
@@ -84,15 +83,19 @@ verify you based on your OpenPGP key.
 Setting up an OpenPGP authentication key
 ----------------------------------------
 
-First things first: you'll need to create an "authentication" subkey
-for your current key, if you don't already have one.  If you already
-have a GPG key, you can add an authentication subkey with:
+First things first: you'll need to have a OpenPGP "authentication"
+subkey for your current key, if you don't already have one.  If you
+already have a GPG key, you can generate an authentication subkey with
+the `gen-subkey` command:
 
        $ monkeysphere gen-subkey
 
 If you have more than one secret key, you'll need to specify the key
-you want to add the subkey to on the command line.
+you want to add the subkey to on the command line.  It have already
+have an ssh pub key that you use regularly, you can import this key
+into GPG with the `import-subkey` command:
 
+       $ monkeysphere import-subkey ~/.ssh/id_rsa
 
 
 Using your OpenPGP authentication key for SSH