summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Kahn Gillmor <dkg@fifthhorseman.net>2009-02-19 22:42:43 -0500
committerDaniel Kahn Gillmor <dkg@fifthhorseman.net>2009-02-19 22:42:43 -0500
commite13bbc823bc8fe7a28303e45055643e15d0849cd (patch)
tree29a8318fed9d344c637eec3ef8dd0df9cacaae11
parent826bfb547cc82252f18e63a25bb7ee5aeaaebc72 (diff)
parent21e298b8df5108b1337d66ba1a39184be4ce0e4e (diff)
Merge commit 'jrollins/master'
-rw-r--r--man/man1/monkeysphere.133
-rw-r--r--man/man8/monkeysphere-authentication.85
-rw-r--r--man/man8/monkeysphere-host.87
-rw-r--r--packaging/debian/changelog6
-rwxr-xr-xsrc/monkeysphere86
-rwxr-xr-xsrc/monkeysphere-authentication2
-rwxr-xr-xsrc/monkeysphere-host2
-rw-r--r--src/share/common1
-rw-r--r--src/share/m/gen_subkey85
-rw-r--r--src/share/m/import_subkey65
-rw-r--r--src/share/m/ssh_proxycommand6
-rw-r--r--src/share/m/subkey_to_ssh_agent13
-rw-r--r--src/share/ma/add_certifier43
-rw-r--r--src/share/ma/setup2
-rw-r--r--src/share/mh/add_revoker66
-rw-r--r--src/share/mh/import_key9
-rw-r--r--src/share/mh/publish_key2
-rwxr-xr-xtests/basic2
-rw-r--r--website/getting-started-admin.mdwn92
-rw-r--r--website/getting-started-user.mdwn15
20 files changed, 305 insertions, 237 deletions
diff --git a/man/man1/monkeysphere.1 b/man/man1/monkeysphere.1
index 3ed43e1..887b5df 100644
--- a/man/man1/monkeysphere.1
+++ b/man/man1/monkeysphere.1
@@ -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]
diff --git a/man/man8/monkeysphere-authentication.8 b/man/man8/monkeysphere-authentication.8
index 38df65d..361822d 100644
--- a/man/man8/monkeysphere-authentication.8
+++ b/man/man8/monkeysphere-authentication.8
@@ -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
diff --git a/man/man8/monkeysphere-host.8 b/man/man8/monkeysphere-host.8
index f33aea6..2b71807 100644
--- a/man/man8/monkeysphere-host.8
+++ b/man/man8/monkeysphere-host.8
@@ -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
diff --git a/packaging/debian/changelog b/packaging/debian/changelog
index 6a9ea18..fc317d9 100644
--- a/packaging/debian/changelog
+++ b/packaging/debian/changelog
@@ -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
diff --git a/src/monkeysphere b/src/monkeysphere
index 992ca06..a65cef6 100755
--- a/src/monkeysphere
+++ b/src/monkeysphere
@@ -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
########################################################################
diff --git a/src/monkeysphere-authentication b/src/monkeysphere-authentication
index 22cd018..497470d 100755
--- a/src/monkeysphere-authentication
+++ b/src/monkeysphere-authentication
@@ -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)
diff --git a/src/monkeysphere-host b/src/monkeysphere-host
index 9d703c2..4c7df88 100755
--- a/src/monkeysphere-host
+++ b/src/monkeysphere-host
@@ -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
diff --git a/src/share/common b/src/share/common
index d151e85..653d58b 100644
--- a/src/share/common
+++ b/src/share/common
@@ -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 | \
diff --git a/src/share/m/gen_subkey b/src/share/m/gen_subkey
index d926ad5..dbd9dd6 100644
--- a/src/share/m/gen_subkey
+++ b/src/share/m/gen_subkey
@@ -15,10 +15,10 @@
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."
diff --git a/src/share/m/import_subkey b/src/share/m/import_subkey
index 8b04456..7333f80 100644
--- a/src/share/m/import_subkey
+++ b/src/share/m/import_subkey
@@ -14,40 +14,49 @@
# 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."
diff --git a/src/share/m/ssh_proxycommand b/src/share/m/ssh_proxycommand
index 0a81500..bd09588 100644
--- a/src/share/m/ssh_proxycommand
+++ b/src/share/m/ssh_proxycommand
@@ -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"}
diff --git a/src/share/m/subkey_to_ssh_agent b/src/share/m/subkey_to_ssh_agent
index a92718e..818f4f7 100644
--- a/src/share/m/subkey_to_ssh_agent
+++ b/src/share/m/subkey_to_ssh_agent
@@ -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
diff --git a/src/share/ma/add_certifier b/src/share/ma/add_certifier
index bd41f23..e2df1d3 100644
--- a/src/share/ma/add_certifier
+++ b/src/share/ma/add_certifier
@@ -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}!" \
diff --git a/src/share/ma/setup b/src/share/ma/setup
index 8929871..e77afff 100644
--- a/src/share/ma/setup
+++ b/src/share/ma/setup
@@ -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}"
diff --git a/src/share/mh/add_revoker b/src/share/mh/add_revoker
index 21dc0bb..2275f61 100644
--- a/src/share/mh/add_revoker
+++ b/src/share/mh/add_revoker
@@ -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)
diff --git a/src/share/mh/import_key b/src/share/mh/import_key
index 6394ad7..040b41c 100644
--- a/src/share/mh/import_key
+++ b/src/share/mh/import_key
@@ -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
diff --git a/src/share/mh/publish_key b/src/share/mh/publish_key
index 05faa0b..b0ffd93 100644
--- a/src/share/mh/publish_key
+++ b/src/share/mh/publish_key
@@ -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
diff --git a/tests/basic b/tests/basic
index 0b91531..3d50977 100755
--- a/tests/basic
+++ b/tests/basic
@@ -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 "##################################################"
diff --git a/website/getting-started-admin.mdwn b/website/getting-started-admin.mdwn
index 5c7203d..9010132 100644
--- a/website/getting-started-admin.mdwn
+++ b/website/getting-started-admin.mdwn
@@ -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.
diff --git a/website/getting-started-user.mdwn b/website/getting-started-user.mdwn
index 9b04edc..d96e5b0 100644
--- a/website/getting-started-user.mdwn
+++ b/website/getting-started-user.mdwn
@@ -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