From 48cd196efb86f8661fbf77552ef6c26b11fe20c6 Mon Sep 17 00:00:00 2001 From: Jameson Graef Rollins Date: Tue, 10 Jun 2008 17:34:08 -0400 Subject: Add some skeletal debian packaging stuff and man pages, and moved conf files to etc directory. --- man/man1/monkeysphere.1 | 6 ++++++ man/man8/monkeysphere-server.8 | 6 ++++++ 2 files changed, 12 insertions(+) create mode 100644 man/man1/monkeysphere.1 create mode 100644 man/man8/monkeysphere-server.8 (limited to 'man') diff --git a/man/man1/monkeysphere.1 b/man/man1/monkeysphere.1 new file mode 100644 index 0000000..4c3d483 --- /dev/null +++ b/man/man1/monkeysphere.1 @@ -0,0 +1,6 @@ +.TH MONKEYSPHERE "1" "June 2008" "monkeysphere 0.1" "User Commands" +.SH NAME +monkeysphere \- monkeysphere client user interface +.SH SYNOPSIS +.B monkeysphere \fIcommand\fP [\fIargs\fP] +.SH DESCRIPTION diff --git a/man/man8/monkeysphere-server.8 b/man/man8/monkeysphere-server.8 new file mode 100644 index 0000000..302bffb --- /dev/null +++ b/man/man8/monkeysphere-server.8 @@ -0,0 +1,6 @@ +.TH MONKEYSPHERE-SERVER "1" "June 2008" "monkeysphere 0.1" "User Commands" +.SH NAME +monkeysphere-server \- monkeysphere server admin user interface +.SH SYNOPSIS +.B monkeysphere-server \fIcommand\fP [\fIargs\fP] +.SH DESCRIPTION -- cgit v1.2.3 From b489d119fc6c61e43c88efffb2ba4705ac4aeca8 Mon Sep 17 00:00:00 2001 From: Jameson Graef Rollins Date: Wed, 11 Jun 2008 12:00:36 -0400 Subject: Fill out a little of the man pages. --- man/man1/monkeysphere.1 | 76 ++++++++++++++++++++++++++++++++++++++++++ man/man8/monkeysphere-server.8 | 54 ++++++++++++++++++++++++++++++ 2 files changed, 130 insertions(+) (limited to 'man') diff --git a/man/man1/monkeysphere.1 b/man/man1/monkeysphere.1 index 4c3d483..fff16ba 100644 --- a/man/man1/monkeysphere.1 +++ b/man/man1/monkeysphere.1 @@ -4,3 +4,79 @@ monkeysphere \- monkeysphere client user interface .SH SYNOPSIS .B monkeysphere \fIcommand\fP [\fIargs\fP] .SH DESCRIPTION +.PP +\fBmonkeysphere\fP is the client monkeysphere tool. +.SH SUBCOMMANDS +\fBmonkeysphere\fP takes various subcommands: +.PD +.TP +.B update-known_hosts [HOST]... +Update the known_hosts file. For every host listed, search for a gpg +key for the host in the Web of Trust. If a key is found, any ssh keys +for the host are removed from the known_hosts file. If the found key +is acceptable (see KEY ACCEPTABILITY), then the gpg key is converted +to an ssh key and added to the known_hosts file. If now gpg key is +found for the host, then nothing is done. If no hosts are specified, +all hosts listed in the known_hosts file will be processed. If they +`k' may be used in place of `update-known_hosts'. +.TP +.B update-authorized_keys +Update the authorized_keys file. +.TP +.B update-userids [USERID]... +Update userid +.TP +.B gen-ae-subkey KEYID +Generate an `ae` capable subkey +.TP +.B help +Output a brief usage summary. `h' or `?' may be used in place of +`help'. +.PD +.SH KEY ACCEPTABILITY +GPG keys are considered acceptable if the following criteria are met: +.PD +.TP +.B capability +The key must have both the "authentication" and "encrypt" capability +flags. +.TP +.B validity +The key must be "fully" valid, and must not be expired or revoked. +.PD +.SH FILES +.PD 1 +.TP +~/.config/monkeysphere/monkeysphere.conf +User monkeysphere config file. +.TP +/etc/monkeysphere/monkeysphere.conf +System-wide monkeysphere config file. +.TP +~/.config/monkeysphere/authorized_user_ids +GPG user IDs to validate for addition to the authorized_keys file. +.TP +~/.config/monkeysphere/authorized_keys +Monkeysphere generated authorized_keys file. +.TP +~/.config/monkeysphere/user_keys +User keys cache directory. +.TP +~/.config/monkeysphere/host_keys +Host keys cache directory. +.PD +.SH AUTHOR +Written by Jameson Rollins +.SH "REPORTING BUGS" +Report bugs to . +.SH COPYRIGHT +Copyright \(co 2008 Jameson Graef Rollins and Daniel Kahn Gillmor +.br +This is free software. You may redistribute copies of it under the +terms of the GNU General Public License +. There is NO WARRANTY, to the +extent permitted by law. +.SH "SEE ALSO" +.BR ssh (1), +.BR gpg (1), +.BR monkeysphere-server (8) diff --git a/man/man8/monkeysphere-server.8 b/man/man8/monkeysphere-server.8 index 302bffb..39a8e5c 100644 --- a/man/man8/monkeysphere-server.8 +++ b/man/man8/monkeysphere-server.8 @@ -4,3 +4,57 @@ monkeysphere-server \- monkeysphere server admin user interface .SH SYNOPSIS .B monkeysphere-server \fIcommand\fP [\fIargs\fP] .SH DESCRIPTION +.PP +\fBmonkeysphere-server\fP is the server admin monkeysphere tool. +.SH SUBCOMMANDS +\fBmonkeysphere-server\fP takes various subcommands: +.PD +.TP +.B update-users [HOST]... +.TP +.B gen-key +.TP +.B publish-key +.TP +.B trust-keys KEYID... +.TP +.B update-user-userids USER USERID... +.TP +.B help +Output a brief usage summary. `h' or `?' may be used in place of +`help'. +.PD +.SH FILES +.PD 1 +.TP +/etc/monkeysphere/monkeysphere-server.conf +System monkeysphere-server config file. +.TP +/etc/monkeysphere/monkeysphere.conf +System-wide monkeysphere config file. +.TP +/etc/monkeysphere/gnupg +Monkeysphere GNUPG home directory. +.TP +/etc/monkeysphere/authorized_user_ids/USER +Server maintained authorized_user_ids files for users. +.TP +/var/lib/monkeysphere/stage/USER +Staging directory for user key caches. +.PD +.SH AUTHOR +Written by Jameson Rollins +.SH "REPORTING BUGS" +Report bugs to . +.SH COPYRIGHT +Copyright \(co 2008 Jameson Graef Rollins and Daniel Kahn Gillmor +.br +This is free software. You may redistribute copies of it under the +terms of the GNU General Public License +. There is NO WARRANTY, to the +extent permitted by law. +.SH "SEE ALSO" +.BR monkeysphere (1), +.BR gpg (1), +.BR ssh (1) + -- cgit v1.2.3 From 3250fce7979ada7e94782430801f5fb76fecbc90 Mon Sep 17 00:00:00 2001 From: Jameson Graef Rollins Date: Wed, 11 Jun 2008 14:08:29 -0400 Subject: Updates to use the new openpgp2ssh program that dkg wrote. --- man/man8/monkeysphere-server.8 | 1 - src/common | 55 +++++++++++++++++++++++++++--------------- src/monkeysphere-server | 4 ++- 3 files changed, 38 insertions(+), 22 deletions(-) (limited to 'man') diff --git a/man/man8/monkeysphere-server.8 b/man/man8/monkeysphere-server.8 index 39a8e5c..7a12e17 100644 --- a/man/man8/monkeysphere-server.8 +++ b/man/man8/monkeysphere-server.8 @@ -57,4 +57,3 @@ extent permitted by law. .BR monkeysphere (1), .BR gpg (1), .BR ssh (1) - diff --git a/src/common b/src/common index ff6ba59..d7caefd 100755 --- a/src/common +++ b/src/common @@ -82,27 +82,36 @@ unescape() { echo "$1" | sed 's/\\x3a/:/' } -# stand in until we get dkg's gpg2ssh program -gpg2ssh_tmp() { +# convert key from gpg to ssh known_hosts format +gpg2known_hosts() { local keyID - local userID local host keyID="$1" - userID="$2" - - if [ "$MODE" = 'authorized_keys' ] ; then - gpgkey2ssh "$keyID" | sed -e "s/COMMENT/MonkeySphere userID: ${userID}/" + host=$(echo "$2" | sed -e "s|ssh://||") # NOTE: it seems that ssh-keygen -R removes all comment fields from # all lines in the known_hosts file. why? # NOTE: just in case, the COMMENT can be matched with the # following regexp: # '^MonkeySphere[[:digit:]]{4}(-[[:digit:]]{2}){2}T[[:digit:]]{2}(:[[:digit:]]{2}){2}$' - elif [ "$MODE" = 'known_hosts' ] ; then - host=$(echo "$userID" | sed -e "s|ssh://||") - echo -n "$host "; gpgkey2ssh "$keyID" | sed -e "s/COMMENT/MonkeySphere${DATE}/" - fi + echo -n "$host " + gpg --export "$keyID" | \ + openpgp2ssh "$keyID" | tr -d '\n' + echo "MonkeySphere${DATE}" +} + +# convert key from gpg to ssh authorized_keys format +gpg2authorized_keys() { + local keyID + local userID + + keyID="$1" + userID="$2" + + echo -n "MonkeySphere${DATE}:${userID}" + gpg --export "$keyID" | \ + openpgp2ssh "$keyID" } # userid and key policy checking @@ -235,15 +244,21 @@ process_user_id() { for keyID in ${keyIDs[@]} ; do loge " acceptable key/uid found." - # export the key with gpg2ssh - # FIXME: needs to apply extra options for authorized_keys - # lines if specified - gpg2ssh_tmp "$keyID" "$userID" >> "$cacheDir"/"$userIDHash"."$pubKeyID" - - # hash the cache file if specified - if [ "$MODE" = 'known_hosts' -a "$HASH_KNOWN_HOSTS" ] ; then - ssh-keygen -H -f "$cacheDir"/"$userIDHash"."$pubKeyID" > /dev/null 2>&1 - rm "$cacheDir"/"$userIDHash"."$pubKeyID".old + 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 + ssh-keygen -H -f "$cacheDir"/"$userIDHash"."$pubKeyID" > /dev/null 2>&1 + rm "$cacheDir"/"$userIDHash"."$pubKeyID".old + fi + elif [ "$MODE" = 'authorized_keys' ] ; then + # export the key + # FIXME: needs to apply extra options for authorized_keys + # lines if specified + gpg2authorized_keys "$keyID" "$userID" >> \ + "$cacheDir"/"$userIDHash"."$pubKeyID" fi done fi diff --git a/src/monkeysphere-server b/src/monkeysphere-server index 6eeb702..34239b6 100755 --- a/src/monkeysphere-server +++ b/src/monkeysphere-server @@ -145,9 +145,10 @@ case $COMMAND in fi for uname in $unames ; do + MODE="authorized_keys" + log "----- user: $uname -----" - MODE="authorized_keys" AUTHORIZED_USER_IDS="$MS_HOME"/authorized_user_ids/"$uname" cacheDir="$STAGING_AREA"/"$uname"/user_keys msAuthorizedKeys="$STAGING_AREA"/"$uname"/authorized_keys @@ -167,6 +168,7 @@ case $COMMAND in # update authorized_keys update_authorized_keys "$cacheDir" "$msAuthorizedKeys" "$userAuthorizedKeys" done + log "----- done. -----" ;; -- cgit v1.2.3 From c1affebb2e24c129a4baec24d0627abd1ac0b977 Mon Sep 17 00:00:00 2001 From: Daniel Kahn Gillmor Date: Wed, 11 Jun 2008 16:04:15 -0400 Subject: fix typo in monkeysphere(1) --- man/man1/monkeysphere.1 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'man') diff --git a/man/man1/monkeysphere.1 b/man/man1/monkeysphere.1 index fff16ba..f9a6af4 100644 --- a/man/man1/monkeysphere.1 +++ b/man/man1/monkeysphere.1 @@ -15,9 +15,10 @@ Update the known_hosts file. For every host listed, search for a gpg key for the host in the Web of Trust. If a key is found, any ssh keys for the host are removed from the known_hosts file. If the found key is acceptable (see KEY ACCEPTABILITY), then the gpg key is converted -to an ssh key and added to the known_hosts file. If now gpg key is +to an ssh key and added to the known_hosts file. If no gpg key is found for the host, then nothing is done. If no hosts are specified, all hosts listed in the known_hosts file will be processed. If they + `k' may be used in place of `update-known_hosts'. .TP .B update-authorized_keys -- cgit v1.2.3 From 10100ce2910a95940540cb61d9b995b1e0deef5a Mon Sep 17 00:00:00 2001 From: Daniel Kahn Gillmor Date: Wed, 11 Jun 2008 17:08:43 -0400 Subject: first pass at openpgp2ssh man page. --- man/man1/openpgp2ssh.1 | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 man/man1/openpgp2ssh.1 (limited to 'man') diff --git a/man/man1/openpgp2ssh.1 b/man/man1/openpgp2ssh.1 new file mode 100644 index 0000000..cd79b6c --- /dev/null +++ b/man/man1/openpgp2ssh.1 @@ -0,0 +1,65 @@ +.\" -*- nroff -*- +.Dd $Mdocdate: June 11, 2008 $ +.Dt OPENPGP2SSH 1 +.Os +.Sh NAME +openpgp2ssh +.Nd translate OpenPGP keys to SSH keys +.Sh SYNOPSIS +.Nm openpgp2ssh < mykey.gpg + +.Nm gpg --export $KEYID | openpgp2ssh $KEYID + +.Nm gpg --export-secret-key $KEYID | openpgp2ssh $KEYID +.Sh DESCRIPTION +openpgp2ssh takes OpenPGP-formatted RSA and DSA keys on standard +input, and spits out the requested equivalent SSH-style key on +standard output. + +If the data on standard input contains only a single key, you can +invoke openpgp2ssh without arguments. If the data on standard input +contains multiple keys (e.g. a primary key and associated subkeys), +you must specify a specific OpenPGP keyid (e.g. CCD2ED94D21739E9) or +fingerprint as the first argument to indicate which key to export. +The keyid must be at least 8 hex characters. + +If the input contains an OpenPGP RSA or DSA public key, it will be +converted to the OpenSSH-style single-line keystring, prefixed with +the key type. This format is suitable (with minor alterations) for +insertion into known_hosts files and authorized_keys files. + +If the input contains an OpenPGP RSA or DSA secret key, it will be +converted to the equivalent PEM-encoded private key. + +Note that the output keys from this process are stripped of all +identifying information, including certifications, self-signatures, +etc. + +openpgp2ssh is part of the +.Xr monkeysphere 1 +framework for providing a PKI for SSH. +.Sh EXAMPLES +.Nm gpg --export-secret-key $KEYID | openpgp2ssh $KEYID | ssh-add -c /dev/stdin + +This pushes the secret key into the active +.Xr ssh-agent 1 . +Tools (such as +.Xr ssh 1 ) +which know how to talk to the +.Xr ssh-agent 1 +can now rely on the key. +.Sh AUTHOR +openpgp2ssh and this man page were written by Daniel Kahn Gillmor +. +.Sh BUGS +openpgp2ssh currently only exports into formats used by the OpenSSH. +It should support other key output formats, such as those used by +lsh(1) and putty(1). + +Secret key output is currently not passphrase-protected. + +This program is not yet implemented, and this man page currently only +describes expected functionality. +.Sh SEE ALSO +.Xr monkeysphere 1 , +.Xr monkeysphere-admin 8 -- cgit v1.2.3 From 1caaa3fef8c8256cbf9b867f5d4b947eacd63535 Mon Sep 17 00:00:00 2001 From: Jameson Graef Rollins Date: Wed, 11 Jun 2008 17:31:12 -0400 Subject: some very small tweaks to the openpgp2ssh man page --- man/man1/openpgp2ssh.1 | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'man') diff --git a/man/man1/openpgp2ssh.1 b/man/man1/openpgp2ssh.1 index cd79b6c..27bcb15 100644 --- a/man/man1/openpgp2ssh.1 +++ b/man/man1/openpgp2ssh.1 @@ -31,7 +31,7 @@ insertion into known_hosts files and authorized_keys files. If the input contains an OpenPGP RSA or DSA secret key, it will be converted to the equivalent PEM-encoded private key. -Note that the output keys from this process are stripped of all +Note that the keys output from this process are stripped of all identifying information, including certifications, self-signatures, etc. @@ -61,5 +61,6 @@ Secret key output is currently not passphrase-protected. This program is not yet implemented, and this man page currently only describes expected functionality. .Sh SEE ALSO -.Xr monkeysphere 1 , -.Xr monkeysphere-admin 8 +.Xr monkeysphere 1 , +.Xr ssh 1 , +.Xr monkeysphere-server 8 -- cgit v1.2.3 From 35a6f7cf8c455318078c7f94951dbc964bb41006 Mon Sep 17 00:00:00 2001 From: Jameson Graef Rollins Date: Thu, 12 Jun 2008 00:22:02 -0400 Subject: Man page work. - flesh out more of the man pages for monkeysphere and monkeysphere-server - move the server cache directory to /var/cache, where it should be. --- debian/dirs | 3 +- etc/monkeysphere-server.conf | 3 -- man/man1/monkeysphere.1 | 83 +++++++++++++++++++++++++++--------------- man/man8/monkeysphere-server.8 | 35 ++++++++++-------- src/common | 12 +++--- src/monkeysphere | 4 +- src/monkeysphere-server | 11 +++--- 7 files changed, 87 insertions(+), 64 deletions(-) (limited to 'man') diff --git a/debian/dirs b/debian/dirs index 277c0b5..bdf0fe0 100644 --- a/debian/dirs +++ b/debian/dirs @@ -1,5 +1,4 @@ -var/lib/monkeysphere -var/lib/monkeysphere/stage +var/cache/monkeysphere usr/bin usr/sbin usr/share diff --git a/etc/monkeysphere-server.conf b/etc/monkeysphere-server.conf index bed5c09..3c16c5f 100644 --- a/etc/monkeysphere-server.conf +++ b/etc/monkeysphere-server.conf @@ -18,6 +18,3 @@ # monkeysphere-generated authorized_keys file. Should be path to file # where '%h' will be substituted for the user's home directory. #USER_CONTROLLED_AUTHORIZED_KEYS=%h/.ssh/authorized_keys - -# where to cache user authorized_keys lines -#STAGING_AREA=/var/lib/monkeysphere/stage diff --git a/man/man1/monkeysphere.1 b/man/man1/monkeysphere.1 index f9a6af4..410a5d7 100644 --- a/man/man1/monkeysphere.1 +++ b/man/man1/monkeysphere.1 @@ -1,34 +1,53 @@ .TH MONKEYSPHERE "1" "June 2008" "monkeysphere 0.1" "User Commands" .SH NAME -monkeysphere \- monkeysphere client user interface +monkeysphere \- MonkeySphere client user interface .SH SYNOPSIS .B monkeysphere \fIcommand\fP [\fIargs\fP] .SH DESCRIPTION .PP -\fBmonkeysphere\fP is the client monkeysphere tool. +MonkeySphere is a system to leverage the OpenPGP Web of Trust for ssh +authentication and encryption. OpenPGP keys are tracked via GnuPG, +and added to the ssh authorized_keys and known_hosts files to be used +for authentication and encryption of ssh connection. + +\fBmonkeysphere\fP is the MonkeySphere client utility. +.PD .SH SUBCOMMANDS \fBmonkeysphere\fP takes various subcommands: -.PD .TP .B update-known_hosts [HOST]... -Update the known_hosts file. For every host listed, search for a gpg -key for the host in the Web of Trust. If a key is found, any ssh keys -for the host are removed from the known_hosts file. If the found key -is acceptable (see KEY ACCEPTABILITY), then the gpg key is converted -to an ssh key and added to the known_hosts file. If no gpg key is -found for the host, then nothing is done. If no hosts are specified, -all hosts listed in the known_hosts file will be processed. If they - -`k' may be used in place of `update-known_hosts'. -.TP -.B update-authorized_keys -Update the authorized_keys file. +Update the known_hosts file. For each specified host, gpg will be +queried for a key associated with the host URI (see HOST URIs), +querying a keyserver if none is found in the user's keychain. search +for a gpg key for the host in the Web of Trust. If a key is found, it +will be added to the host_keys cache (see KEY CACHES) and any ssh keys +for the host will be removed from the user's known_hosts file. If the +found key is acceptable (see KEY ACCEPTABILITY), then the host's gpg +key will be added to the known_hosts file. If no gpg key is found for +the host, then nothing is done. If no hosts are specified, all hosts +listed in the known_hosts file will be processed. `k' may be used in +place of `update-known_hosts'. .TP .B update-userids [USERID]... -Update userid +Add/update a userid in the authorized_user_ids file. The user IDs +specified should be exact matches to OpenPGP user IDs. For each +specified user ID, gpg will be queried for a key associated with that +user ID, querying a keyserver if none is found in the user's keychain. +If a key is found, it will be added to the user_keys cache (see KEY +CACHES) and the user ID will be added to the user's +authorized_user_ids file (if it wasn't already present). +.TP +.B update-authorized_keys +Update the monkeysphere authorized_keys file. The monkeysphere +authorized_keys file will be regenerated from the valid keys in the +user_key cache, and the user's independently controlled +authorized_keys file (usually ~/.ssh/authorized_keys). .TP .B gen-ae-subkey KEYID -Generate an `ae` capable subkey +Generate an `ae` capable subkey. For the primary key with the +specified key ID, generate a subkey with "authentication" and +"encryption" capability that can be used for MonkeySphere +transactions. .TP .B help Output a brief usage summary. `h' or `?' may be used in place of @@ -45,6 +64,20 @@ flags. .B validity The key must be "fully" valid, and must not be expired or revoked. .PD +.SH KEY CACHES +Monkeysphere keeps track of keys in key cache directories. The files +in the cache are named with the format "USERID_HASH.PUB_KEY_ID", where +USERID_HASH is a hash of the exact OpenPGP user ID, and PUB_KEY_ID is +the key ID of the primary key. If the user/key ID combo exists in the +Web of Trust but is not acceptable, then the file is empty. If the +primary key has at least one acceptable sub key, then an ssh-style +key, converted from the OpenPGP key, of all acceptable subkeys will be +stored in the cache file, one per line. known_hosts style key lines +will be stored in the host_keys cache files, and authorized_keys style +key lines will be stored in the user_keys cache files. OpenPGP keys +are converted to ssh-style keys with the openpgp2ssh utility (see `man +openpgp2ssh'). +.PD .SH FILES .PD 1 .TP @@ -55,7 +88,8 @@ User monkeysphere config file. System-wide monkeysphere config file. .TP ~/.config/monkeysphere/authorized_user_ids -GPG user IDs to validate for addition to the authorized_keys file. +GPG user IDs associated with keys that will be checked for addition to +the authorized_keys file. .TP ~/.config/monkeysphere/authorized_keys Monkeysphere generated authorized_keys file. @@ -67,17 +101,8 @@ User keys cache directory. Host keys cache directory. .PD .SH AUTHOR -Written by Jameson Rollins -.SH "REPORTING BUGS" -Report bugs to . -.SH COPYRIGHT -Copyright \(co 2008 Jameson Graef Rollins and Daniel Kahn Gillmor -.br -This is free software. You may redistribute copies of it under the -terms of the GNU General Public License -. There is NO WARRANTY, to the -extent permitted by law. -.SH "SEE ALSO" +Written by Jameson Rollins +.SH SEE ALSO .BR ssh (1), .BR gpg (1), .BR monkeysphere-server (8) diff --git a/man/man8/monkeysphere-server.8 b/man/man8/monkeysphere-server.8 index 7a12e17..cc07077 100644 --- a/man/man8/monkeysphere-server.8 +++ b/man/man8/monkeysphere-server.8 @@ -5,20 +5,32 @@ monkeysphere-server \- monkeysphere server admin user interface .B monkeysphere-server \fIcommand\fP [\fIargs\fP] .SH DESCRIPTION .PP -\fBmonkeysphere-server\fP is the server admin monkeysphere tool. +\fBMonkeySphere\fP is a system to leverage the OpenPGP Web of Trust +for ssh authentication and encryption. OpenPGP keys are tracked via +GnuPG, and added to the ssh authorized_keys and known_hosts files to +be used for authentication and encryption of ssh connection. + +\fBmonkeysphere-server\fP is the MonkeySphere server admin utility. +.PD .SH SUBCOMMANDS \fBmonkeysphere-server\fP takes various subcommands: -.PD .TP -.B update-users [HOST]... +.B update-users [USER]... +Update the admin-controlled authorized_keys files for user. For each +user specified, update the user's authorized_keys file in +/var/cache/monkeysphere/USER. See `man monkeysphere' for more info. .TP .B gen-key +Generate a gpg key for the host. .TP .B publish-key +Publish the host's gpg key to a keyserver. .TP .B trust-keys KEYID... +Mark key specified with KEYID with full owner trust. .TP .B update-user-userids USER USERID... +Add/update a userid in the authorized_user_ids file for USER. .TP .B help Output a brief usage summary. `h' or `?' may be used in place of @@ -39,21 +51,12 @@ Monkeysphere GNUPG home directory. /etc/monkeysphere/authorized_user_ids/USER Server maintained authorized_user_ids files for users. .TP -/var/lib/monkeysphere/stage/USER -Staging directory for user key caches. +/var/cachemonkeysphere/USER +User keys cache directories. .PD .SH AUTHOR -Written by Jameson Rollins -.SH "REPORTING BUGS" -Report bugs to . -.SH COPYRIGHT -Copyright \(co 2008 Jameson Graef Rollins and Daniel Kahn Gillmor -.br -This is free software. You may redistribute copies of it under the -terms of the GNU General Public License -. There is NO WARRANTY, to the -extent permitted by law. -.SH "SEE ALSO" +Written by Jameson Rollins +.SH SEE ALSO .BR monkeysphere (1), .BR gpg (1), .BR ssh (1) diff --git a/src/common b/src/common index d7caefd..914c800 100755 --- a/src/common +++ b/src/common @@ -14,8 +14,8 @@ # managed directories ETC="/etc/monkeysphere" export ETC -LIB="/var/lib/monkeysphere" -export LIB +CACHE="/var/cache/monkeysphere" +export CACHE ######################################################################## failure() { @@ -312,13 +312,13 @@ process_known_hosts() { # update an authorized_keys file after first processing the # authorized_user_ids file update_authorized_keys() { - local cacheDir local msAuthorizedKeys local userAuthorizedKeys + local cacheDir - cacheDir="$1" - msAuthorizedKeys="$2" - userAuthorizedKeys="$3" + msAuthorizedKeys="$1" + userAuthorizedKeys="$2" + cacheDir="$3" process_authorized_ids "$AUTHORIZED_USER_IDS" "$cacheDir" diff --git a/src/monkeysphere b/src/monkeysphere index aaeda11..5d865c9 100755 --- a/src/monkeysphere +++ b/src/monkeysphere @@ -35,8 +35,8 @@ Monkeysphere client tool. subcommands: update-known_hosts (k) [HOST]... update known_hosts file - update-authorized_keys (a) update authorized_keys file update-userids (u) [USERID]... add/update userid + update-authorized_keys (a) update authorized_keys file gen-ae-subkey (g) KEYID generate an 'ae' capable subkey help (h,?) this help @@ -170,7 +170,7 @@ case $COMMAND in userAuthorizedKeys=${USER_CONTROLLED_AUTHORIZED_KEYS/\%h/"$HOME"} # update authorized_keys - update_authorized_keys "$userKeysCacheDir" "$msAuthorizedKeys" "$userAuthorizedKeys" + update_authorized_keys "$msAuthorizedKeys" "$userAuthorizedKeys" "$userKeysCacheDir" ;; 'update-userids'|'u') diff --git a/src/monkeysphere-server b/src/monkeysphere-server index a109cf5..0ff06af 100755 --- a/src/monkeysphere-server +++ b/src/monkeysphere-server @@ -129,7 +129,6 @@ GNUPGHOME=${GNUPGHOME:-"$MS_HOME"/gnupg} KEYSERVER=${KEYSERVER:-subkeys.pgp.net} REQUIRED_KEY_CAPABILITY=${REQUIRED_KEY_CAPABILITY:-"e a"} USER_CONTROLLED_AUTHORIZED_KEYS=${USER_CONTROLLED_AUTHORIZED_KEYS:-%h/.ssh/authorized_keys} -STAGING_AREA=${STAGING_AREA:-"$LIB"/stage} export GNUPGHOME @@ -150,8 +149,8 @@ case $COMMAND in log "----- user: $uname -----" AUTHORIZED_USER_IDS="$MS_HOME"/authorized_user_ids/"$uname" - cacheDir="$STAGING_AREA"/"$uname"/user_keys - msAuthorizedKeys="$STAGING_AREA"/"$uname"/authorized_keys + msAuthorizedKeys="$CACHE"/"$uname"/authorized_keys + cacheDir="$CACHE"/"$uname"/user_keys # make sure authorized_user_ids file exists if [ ! -s "$AUTHORIZED_USER_IDS" ] ; then @@ -166,7 +165,7 @@ case $COMMAND in fi # update authorized_keys - update_authorized_keys "$cacheDir" "$msAuthorizedKeys" "$userAuthorizedKeys" + update_authorized_keys "$msAuthorizedKeys" "$userAuthorizedKeys" "$cacheDir" done log "----- done. -----" @@ -199,9 +198,9 @@ case $COMMAND in failure "you must specify at least one userid." fi AUTHORIZED_USER_IDS="$MS_HOME"/authorized_user_ids/"$uname" - userKeysCacheDir="$STAGING_AREA"/"$uname"/user_keys + cacheDir="$CACHE"/"$uname"/user_keys for userID ; do - update_userid "$userID" "$userKeysCacheDir" + update_userid "$userID" "$cacheDir" done ;; -- cgit v1.2.3 From e2314e2105e02ec0d2684a3b68b9187982ca812b Mon Sep 17 00:00:00 2001 From: Daniel Kahn Gillmor Date: Thu, 12 Jun 2008 13:27:54 -0400 Subject: massaging the language in openpgp2ssh(1). --- man/man1/openpgp2ssh.1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'man') diff --git a/man/man1/openpgp2ssh.1 b/man/man1/openpgp2ssh.1 index 27bcb15..6267141 100644 --- a/man/man1/openpgp2ssh.1 +++ b/man/man1/openpgp2ssh.1 @@ -31,7 +31,7 @@ insertion into known_hosts files and authorized_keys files. If the input contains an OpenPGP RSA or DSA secret key, it will be converted to the equivalent PEM-encoded private key. -Note that the keys output from this process are stripped of all +Note that the keys produced by this process are stripped of all identifying information, including certifications, self-signatures, etc. -- cgit v1.2.3 From 6f2d6f78cd11231d6f7ffd6361812b1bd49a4c34 Mon Sep 17 00:00:00 2001 From: Daniel Kahn Gillmor Date: Thu, 12 Jun 2008 17:25:55 -0400 Subject: Major openpgp2ssh overhaul. It's an unforgiving and brittle tool, but it should do what we expect it to do, and its major limitations should be documented in the man page. --- man/man1/openpgp2ssh.1 | 47 ++++-- src/keytrans/gnutls-helpers.c | 68 ++++++++ src/keytrans/gnutls-helpers.h | 4 + src/keytrans/openpgp2ssh.c | 357 +++++++++++++++++++++++++++++++----------- 4 files changed, 371 insertions(+), 105 deletions(-) (limited to 'man') diff --git a/man/man1/openpgp2ssh.1 b/man/man1/openpgp2ssh.1 index 6267141..1a02b38 100644 --- a/man/man1/openpgp2ssh.1 +++ b/man/man1/openpgp2ssh.1 @@ -12,16 +12,16 @@ openpgp2ssh .Nm gpg --export-secret-key $KEYID | openpgp2ssh $KEYID .Sh DESCRIPTION -openpgp2ssh takes OpenPGP-formatted RSA and DSA keys on standard -input, and spits out the requested equivalent SSH-style key on -standard output. +openpgp2ssh takes an OpenPGP-formatted primary key and associated +subkeys on standard input, and spits out the requested equivalent +SSH-style key on standard output. -If the data on standard input contains only a single key, you can -invoke openpgp2ssh without arguments. If the data on standard input -contains multiple keys (e.g. a primary key and associated subkeys), -you must specify a specific OpenPGP keyid (e.g. CCD2ED94D21739E9) or +If the data on standard input contains no subkeys, you can invoke +openpgp2ssh without arguments. If the data on standard input contains +multiple keys (e.g. a primary key and associated subkeys), you must +specify a specific OpenPGP keyid (e.g. CCD2ED94D21739E9) or fingerprint as the first argument to indicate which key to export. -The keyid must be at least 8 hex characters. +The keyid must be exactly 16 hex characters. If the input contains an OpenPGP RSA or DSA public key, it will be converted to the OpenSSH-style single-line keystring, prefixed with @@ -31,20 +31,29 @@ insertion into known_hosts files and authorized_keys files. If the input contains an OpenPGP RSA or DSA secret key, it will be converted to the equivalent PEM-encoded private key. -Note that the keys produced by this process are stripped of all -identifying information, including certifications, self-signatures, -etc. - openpgp2ssh is part of the .Xr monkeysphere 1 framework for providing a PKI for SSH. +.Sh CAVEATS +The keys produced by this process are stripped of all identifying +information, including certifications, self-signatures, etc. This is +intentional, since ssh attaches no inherent significance to these +features. + +openpgp2ssh only works with RSA or DSA keys, because those are the +only ones which work with ssh. + +Assuming a valid key type, though, openpgp2ssh will produce output for +any requested key. This means, among other things, that it will +happily export revoked keys, unverifiable keys, expired keys, etc. +Make sure you do your own key validation before using this tool! .Sh EXAMPLES .Nm gpg --export-secret-key $KEYID | openpgp2ssh $KEYID | ssh-add -c /dev/stdin This pushes the secret key into the active .Xr ssh-agent 1 . -Tools (such as -.Xr ssh 1 ) +Tools such as +.Xr ssh 1 which know how to talk to the .Xr ssh-agent 1 can now rely on the key. @@ -58,8 +67,14 @@ lsh(1) and putty(1). Secret key output is currently not passphrase-protected. -This program is not yet implemented, and this man page currently only -describes expected functionality. +openpgp2ssh currently cannot handle passphrase-protected secret keys on input. + +It would be nice to be able to use keyids shorter or longer than 16 +hex characters. + +openpgp2ssh only acts on keys associated with the first primary key +passed in. If you send it more than one primary key, it will silently +ignore later ones. .Sh SEE ALSO .Xr monkeysphere 1 , .Xr ssh 1 , diff --git a/src/keytrans/gnutls-helpers.c b/src/keytrans/gnutls-helpers.c index 6eae29e..7c342bb 100644 --- a/src/keytrans/gnutls-helpers.c +++ b/src/keytrans/gnutls-helpers.c @@ -12,6 +12,9 @@ /* for isalnum() */ #include +/* for exit() */ +#include + int loglevel = 0; @@ -46,6 +49,71 @@ void make_keyid_printable(printable_keyid out, gnutls_openpgp_keyid_t keyid) } } +unsigned char hex2bin(unsigned char x) { + if ((x >= '0') && (x <= '9')) + return x - '0'; + if ((x >= 'A') && (x <= 'F')) + return 10 + x - 'A'; + if ((x >= 'a') && (x <= 'f')) + return 10 + x - 'a'; + return 0xff; +} + +void collapse_printable_keyid(gnutls_openpgp_keyid_t out, printable_keyid in) { + unsigned int pkix = 0, outkix = 0; + + while (pkix < sizeof(printable_keyid)) { + unsigned hi = hex2bin(in[pkix]); + unsigned lo = hex2bin(in[pkix + 1]); + if (hi == 0xff) { + err("character '%c' is not a hex char\n", in[pkix]); + exit(1); + } + if (lo == 0xff) { + err("character '%c' is not a hex char\n", in[pkix + 1]); + exit(1); + } + out[outkix] = lo | (hi << 4); + + pkix += 2; + outkix++; + } +} + +int convert_string_to_keyid(gnutls_openpgp_keyid_t out, const char* str) { + printable_keyid p; + int ret; + + ret = convert_string_to_printable_keyid(p, str); + if (ret == 0) + collapse_printable_keyid(out, p); + return ret; +} +int convert_string_to_printable_keyid(printable_keyid pkeyid, const char* str) { + int arglen, x; + arglen = 0; + x = 0; + while ((arglen <= sizeof(printable_keyid)) && + (str[x] != '\0')) { + if (isxdigit(str[x])) { + if (arglen == sizeof(printable_keyid)) { + err("There are more than %d hex digits in the keyid '%s'\n", sizeof(printable_keyid), str); + return 1; + } + pkeyid[arglen] = str[x]; + arglen++; + } + x++; + } + + if (arglen != sizeof(printable_keyid)) { + err("keyid '%s' is not %d hex digits in length\n", str, sizeof(printable_keyid)); + return 1; + } + return 0; +} + + int init_gnutls() { const char* version = NULL; diff --git a/src/keytrans/gnutls-helpers.h b/src/keytrans/gnutls-helpers.h index 9ea22a3..00cdec7 100644 --- a/src/keytrans/gnutls-helpers.h +++ b/src/keytrans/gnutls-helpers.h @@ -44,6 +44,10 @@ typedef unsigned char printable_keyid[16]; void init_keyid(gnutls_openpgp_keyid_t keyid); void make_keyid_printable(printable_keyid out, gnutls_openpgp_keyid_t keyid); +void collapse_printable_keyid(gnutls_openpgp_keyid_t out, printable_keyid in); +int convert_string_to_keyid(gnutls_openpgp_keyid_t out, const char* str); +int convert_string_to_printable_keyid(printable_keyid out, const char* str); + /* functions to get data into datum objects: */ diff --git a/src/keytrans/openpgp2ssh.c b/src/keytrans/openpgp2ssh.c index d6bac68..30e19d5 100644 --- a/src/keytrans/openpgp2ssh.c +++ b/src/keytrans/openpgp2ssh.c @@ -3,47 +3,47 @@ #include #include +/* for waitpid() */ +#include +#include + /* Author: Daniel Kahn Gillmor - Date: Tue, 01 Apr 2008 + Date: 2008-06-12 13:47:41-0400 License: GPL v3 or later - monkeysphere private key translator: execute this with an GPG - secret key on stdin (at the moment, only passphraseless RSA keys - work). + monkeysphere key translator: execute this with an OpenPGP key on + stdin, (please indicate the specific keyid that you want as the + first argument if there are subkeys). At the moment, only public + keys and passphraseless secret keys work. - It will spit out a PEM-encoded version of the key on stdout, which - can be fed into ssh-add like this: + For secret keys, it will spit out a PEM-encoded version of the key + on stdout, which can be fed into ssh-add like this: - gpg --export-secret-keys $KEYID | monkeysphere | ssh-add -c /dev/stdin + gpg --export-secret-keys $KEYID | openpgp2ssh $KEYID | ssh-add -c /dev/stdin - Requirements: I've only built this so far with GnuTLS v2.3.4 -- - version 2.2.0 does not contain the appropriate pieces. + For public keys, it will spit out a single line of text that can + (with some massaging) be used in an openssh known_hosts or + authorized_keys file. For example: - Notes: gpgkey2ssh doesn't seem to provide the same public - keys. Mighty weird! + echo server.example.org $(gpg --export $KEYID | openpgp2ssh $KEYID) >> ~/.ssh/known_hosts -0 wt215@squeak:~/monkeysphere$ gpg --export-secret-keys 1DCDF89F | ~dkg/src/monkeysphere/monkeysphere | ssh-add -c /dev/stdin -gnutls version: 2.3.4 -OpenPGP RSA Key, with 1024 bits -Identity added: /dev/stdin (/dev/stdin) -The user has to confirm each use of the key -0 wt215@squeak:~/monkeysphere$ ssh-add -L -ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQC9gWQqfrnhQKDQnND/3eOexpddE64J+1zp9fcyCje7H5LKclb6DBV2HS6WgW32PJhIzvP+fYZM3dzXea3fpv14y1SicXiRBDgF9SnsNA1qWn2RyzkLcKy7PmM0PDYtU1oiLTcQj/xkWcqW2sLKHT/WW+vZP5XP7RMGN/yWNMfE2Q== /dev/stdin -0 wt215@squeak:~/monkeysphere$ gpgkey2ssh 1DCDF89F -ssh-rsa AAAAB3NzaC1yc2EAAACBAL2BZCp+ueFAoNCc0P/d457Gl10Trgn7XOn19zIKN7sfkspyVvoMFXYdLpaBbfY8mEjO8/59hkzd3Nd5rd+m/XjLVKJxeJEEOAX1Kew0DWpafZHLOQtwrLs+YzQ8Ni1TWiItNxCP/GRZypbawsodP9Zb69k/lc/tEwY3/JY0x8TZAAAAAwEAAQ== COMMENT -0 wt215@squeak:~/monkeysphere$ + Requirements: I've only built this so far with GnuTLS v2.3.x. + GnuTLS 2.2.x does not contain the appropriate functionality. */ -int convert_pgp_to_x509(gnutls_x509_privkey_t* output, gnutls_datum_t* input) { - gnutls_openpgp_privkey_t pgp_privkey; +/* FIXME: keyid should be const as well */ +int convert_private_pgp_to_x509(gnutls_x509_privkey_t* output, const gnutls_openpgp_privkey_t* pgp_privkey, gnutls_openpgp_keyid_t* keyid) { gnutls_datum_t m, e, d, p, q, u, g, y, x; gnutls_pk_algorithm_t pgp_algo; unsigned int pgp_bits; int ret; +/* FIXME: actually respect keyid argument. At the moment, we just + emit the primary key. */ + init_datum(&m); init_datum(&e); init_datum(&d); @@ -54,34 +54,14 @@ int convert_pgp_to_x509(gnutls_x509_privkey_t* output, gnutls_datum_t* input) { init_datum(&y); init_datum(&x); - if (ret = gnutls_openpgp_privkey_init(&pgp_privkey), ret) { - err("Failed to initialized OpenPGP private key (error: %d)\n", ret); - return 1; - } - - - /* format could be either: GNUTLS_OPENPGP_FMT_RAW, - GNUTLS_OPENPGP_FMT_BASE64; if MONKEYSPHERE_RAW is set, use RAW, - otherwise, use BASE64: */ - - if (getenv("MONKEYSPHERE_RAW")) { - err("assuming RAW formatted private keys\n"); - if (ret = gnutls_openpgp_privkey_import(pgp_privkey, input, GNUTLS_OPENPGP_FMT_RAW, NULL, 0), ret) - err("failed to import the OpenPGP private key in RAW format (error: %d)\n", ret); - } else { - err("assuming BASE64 formatted private keys\n"); - if (ret = gnutls_openpgp_privkey_import (pgp_privkey, input, GNUTLS_OPENPGP_FMT_BASE64, NULL, 0), ret) - err("failed to import the OpenPGP private key in BASE64 format (error: %d)\n", ret); - } - - pgp_algo = gnutls_openpgp_privkey_get_pk_algorithm(pgp_privkey, &pgp_bits); + pgp_algo = gnutls_openpgp_privkey_get_pk_algorithm(*pgp_privkey, &pgp_bits); if (pgp_algo < 0) { err("failed to get OpenPGP key algorithm (error: %d)\n", pgp_algo); return 1; } if (pgp_algo == GNUTLS_PK_RSA) { err("OpenPGP RSA Key, with %d bits\n", pgp_bits); - ret = gnutls_openpgp_privkey_export_rsa_raw(pgp_privkey, &m, &e, &d, &p, &q, &u); + ret = gnutls_openpgp_privkey_export_rsa_raw(*pgp_privkey, &m, &e, &d, &p, &q, &u); if (GNUTLS_E_SUCCESS != ret) { err ("failed to export RSA key parameters (error: %d)\n", ret); return 1; @@ -94,7 +74,7 @@ int convert_pgp_to_x509(gnutls_x509_privkey_t* output, gnutls_datum_t* input) { } } else if (pgp_algo == GNUTLS_PK_DSA) { err("OpenPGP DSA Key, with %d bits\n", pgp_bits); - ret = gnutls_openpgp_privkey_export_dsa_raw(pgp_privkey, &p, &q, &g, &y, &x); + ret = gnutls_openpgp_privkey_export_dsa_raw(*pgp_privkey, &p, &q, &g, &y, &x); if (GNUTLS_E_SUCCESS != ret) { err ("failed to export DSA key parameters (error: %d)\n", ret); return 1; @@ -116,10 +96,190 @@ int convert_pgp_to_x509(gnutls_x509_privkey_t* output, gnutls_datum_t* input) { return 1; } - gnutls_openpgp_privkey_deinit(pgp_privkey); return 0; } +/* FIXME: keyid should be const also */ +int emit_public_openssh_from_pgp(const gnutls_openpgp_crt_t* pgp_crt, gnutls_openpgp_keyid_t* keyid) { + gnutls_openpgp_keyid_t curkeyid; + int ret; + int subkeyidx; + int subkeycount; + int found = 0; + gnutls_datum_t m, e, p, q, g, y, algolabel; + unsigned int bits; + gnutls_pk_algorithm_t algo; + const gnutls_datum_t* all[5]; + const char* algoname; + int mpicount; + /* output_data must be at least 2 chars longer than the maximum possible + algorithm name: */ + char output_data[20]; + + /* variables for the output conversion: */ + int pipestatus; + int pipefd, child_pid; + char* const b64args[] = {"/usr/bin/base64", "--wrap=0", NULL}; + + init_datum(&m); + init_datum(&e); + init_datum(&p); + init_datum(&q); + init_datum(&g); + init_datum(&algolabel); + + + /* figure out if we've got the right thing: */ + subkeycount = gnutls_openpgp_crt_get_subkey_count(*pgp_crt); + if (subkeycount < 0) { + err("Could not determine subkey count (got value %d)\n", subkeycount); + return 1; + } + + if ((keyid == NULL) && + (subkeycount > 0)) { + err("No keyid passed in, but there were %d keys to choose from\n", subkeycount + 1); + return 1; + } + + if (keyid != NULL) { + ret = gnutls_openpgp_crt_get_key_id(*pgp_crt, curkeyid); + if (ret) { + err("Could not get keyid (error: %d)\n", ret); + return 1; + } + } + if ((keyid == NULL) || (memcmp(*keyid, curkeyid, sizeof(gnutls_openpgp_keyid_t)) == 0)) { + /* we want to export the primary key: */ + err("exporting primary key\n"); + + /* FIXME: this is almost identical to the block below for subkeys. + This clumsiness seems inherent in the gnutls OpenPGP API, + though. ugh. */ + algo = gnutls_openpgp_crt_get_pk_algorithm(*pgp_crt, &bits); + if (algo < 0) { + err("failed to get the algorithm of the OpenPGP public key (error: %d)\n", algo); + return algo; + } else if (algo == GNUTLS_PK_RSA) { + err("OpenPGP RSA certificate, with %d bits\n", bits); + ret = gnutls_openpgp_crt_get_pk_rsa_raw(*pgp_crt, &m, &e); + if (GNUTLS_E_SUCCESS != ret) { + err ("failed to export RSA key parameters (error: %d)\n", ret); + return 1; + } + } else if (algo == GNUTLS_PK_DSA) { + err("OpenPGP DSA Key, with %d bits\n", bits); + ret = gnutls_openpgp_crt_get_pk_dsa_raw(*pgp_crt, &p, &q, &g, &y); + if (GNUTLS_E_SUCCESS != ret) { + err ("failed to export DSA key parameters (error: %d)\n", ret); + return 1; + } + } + found = 1; + + } else { + /* lets trawl through the subkeys until we find the one we want: */ + for (subkeyidx = 0; (subkeyidx < subkeycount) && !found; subkeyidx++) { + ret = gnutls_openpgp_crt_get_subkey_id(*pgp_crt, subkeyidx, curkeyid); + if (ret) { + err("Could not get keyid of subkey with index %d (error: %d)\n", subkeyidx, ret); + return 1; + } + if (memcmp(*keyid, curkeyid, sizeof(gnutls_openpgp_keyid_t)) == 0) { + err("exporting subkey index %d\n", subkeyidx); + + /* FIXME: this is almost identical to the block above for the + primary key. */ + algo = gnutls_openpgp_crt_get_subkey_pk_algorithm(*pgp_crt, subkeyidx, &bits); + if (algo < 0) { + err("failed to get the algorithm of the OpenPGP public key (error: %d)\n", algo); + return algo; + } else if (algo == GNUTLS_PK_RSA) { + err("OpenPGP RSA certificate, with %d bits\n", bits); + ret = gnutls_openpgp_crt_get_subkey_pk_rsa_raw(*pgp_crt, subkeyidx, &m, &e); + if (GNUTLS_E_SUCCESS != ret) { + err ("failed to export RSA key parameters (error: %d)\n", ret); + return 1; + } + } else if (algo == GNUTLS_PK_DSA) { + err("OpenPGP DSA Key, with %d bits\n", bits); + ret = gnutls_openpgp_crt_get_subkey_pk_dsa_raw(*pgp_crt, subkeyidx, &p, &q, &g, &y); + if (GNUTLS_E_SUCCESS != ret) { + err ("failed to export DSA key parameters (error: %d)\n", ret); + return 1; + } + } + found = 1; + + } + } + } + + if (!found) { + err("Could not find key in input\n"); + return 1; + } + + /* if we made it this far, we've got MPIs, and we've got the + algorithm, so we just need to emit the info */ + if (algo == GNUTLS_PK_RSA) { + algoname = "ssh-rsa"; + mpicount = 3; + + all[0] = &algolabel; + all[1] = &e; + all[2] = &m; + } else if (algo == GNUTLS_PK_DSA) { + algoname = "ssh-dss"; + mpicount = 5; + + all[0] = &algolabel; + all[1] = &p; + all[2] = &q; + all[3] = &g; + all[4] = &y; + } else { + err("Key algorithm was neither DSA nor RSA (it was %d). Can't deal. Sorry!\n", algo); + return 1; + } + + if (ret = datum_from_string(&algolabel, algoname), ret) { + err("couldn't label string (error: %d)\n", ret); + return ret; + } + + snprintf(output_data, sizeof(output_data), "%s ", algoname); + + pipefd = create_writing_pipe(&child_pid, b64args[0], b64args); + if (pipefd < 0) { + err("failed to create a writing pipe (returned %d)\n", pipefd); + return pipefd; + } + + write(1, output_data, strlen(output_data)); + + if (0 != write_data_fd_with_length(pipefd, all, mpicount)) { + err("was not able to write out RSA key data\n"); + return 1; + } + close(pipefd); + if (child_pid != waitpid(child_pid, &pipestatus, 0)) { + err("could not wait for child process to return for some reason.\n"); + return 1; + } + if (pipestatus != 0) { + err("base64 pipe died with return code %d\n", pipestatus); + return pipestatus; + } + + write(1, "\n", 1); + + + return 0; +} + + + int convert_x509_to_pgp(gnutls_openpgp_privkey_t* output, gnutls_datum_t* input) { gnutls_x509_privkey_t x509_privkey; gnutls_datum_t m, e, d, p, q, u, g, y, x; @@ -203,69 +363,88 @@ int main(int argc, char* argv[]) { gnutls_datum_t data; int ret; gnutls_x509_privkey_t x509_privkey; + gnutls_openpgp_privkey_t pgp_privkey; + gnutls_openpgp_crt_t pgp_crt; char output_data[10240]; size_t ods = sizeof(output_data); + + gnutls_openpgp_keyid_t keyid; + gnutls_openpgp_keyid_t* use_keyid; init_gnutls(); + + /* figure out what keyid we should be looking for: */ + use_keyid = NULL; + if (argv[1] != NULL) { + ret = convert_string_to_keyid(keyid, argv[1]); + if (ret != 0) + return ret; + use_keyid = &keyid; + } + init_datum(&data); - /* slurp in the private key from stdin */ + /* slurp in the key from stdin */ if (ret = set_datum_fd(&data, 0), ret) { err("didn't read file descriptor 0\n"); return 1; } - - /* Or, instead, read in key from a file name: - if (ret = set_datum_file(&data, argv[1]), ret) { - err("didn't read file '%s'\n", argv[1]); + if (ret = gnutls_openpgp_privkey_init(&pgp_privkey), ret) { + err("Failed to initialized OpenPGP private key (error: %d)\n", ret); return 1; } -*/ - - /* treat the passed file as an X.509 private key, and extract its - component values: */ - -/* if (ret = gnutls_x509_privkey_import(x509_privkey, &data, GNUTLS_X509_FMT_PEM), ret) { */ -/* err("Failed to import the X.509 key (error: %d)\n", ret); */ -/* return 1; */ -/* } */ -/* gnutls_x509_privkey_export_rsa_raw(x509_privkey, &m, &e, &d, &p, &q, &u); */ - - /* try to print the PEM-encoded private key: */ -/* ret = gnutls_x509_privkey_export (x509_privkey, */ -/* GNUTLS_X509_FMT_PEM, */ -/* output_data, */ -/* &ods); */ -/* printf("ret: %u; ods: %u;\n", ret, ods); */ -/* if (ret == 0) { */ -/* write(0, output_data, ods); */ -/* } */ - - - if (ret = gnutls_x509_privkey_init(&x509_privkey), ret) { - err("Failed to initialize X.509 private key (error: %d)\n", ret); - return 1; + /* check whether it's a private key or a public key, by trying them: */ + if ((gnutls_openpgp_privkey_import(pgp_privkey, &data, GNUTLS_OPENPGP_FMT_RAW, NULL, 0) == 0) || + (gnutls_openpgp_privkey_import(pgp_privkey, &data, GNUTLS_OPENPGP_FMT_BASE64, NULL, 0) == 0)) { + /* we're dealing with a private key */ + err("Translating private key\n"); + if (ret = gnutls_x509_privkey_init(&x509_privkey), ret) { + err("Failed to initialize X.509 private key for output (error: %d)\n", ret); + return 1; + } + + ret = convert_private_pgp_to_x509(&x509_privkey, &pgp_privkey, use_keyid); + + gnutls_openpgp_privkey_deinit(pgp_privkey); + if (ret) + return ret; + + ret = gnutls_x509_privkey_export (x509_privkey, + GNUTLS_X509_FMT_PEM, + output_data, + &ods); + if (ret == 0) { + write(1, output_data, ods); + } + gnutls_x509_privkey_deinit(x509_privkey); + + } else { + if (ret = gnutls_openpgp_crt_init(&pgp_crt), ret) { + err("Failed to initialized OpenPGP certificate (error: %d)\n", ret); + return 1; + } + + if ((gnutls_openpgp_crt_import(pgp_crt, &data, GNUTLS_OPENPGP_FMT_RAW) == 0) || + (gnutls_openpgp_crt_import(pgp_crt, &data, GNUTLS_OPENPGP_FMT_BASE64) == 0)) { + /* we're dealing with a public key */ + err("Translating public key\n"); + + ret = emit_public_openssh_from_pgp(&pgp_crt, use_keyid); + + } else { + /* we have no idea what kind of key this is at all anyway! */ + err("Input does contain any form of OpenPGP key I recognize."); + return 1; + } } - if (ret = convert_pgp_to_x509(&x509_privkey, &data), ret) { - return ret; - } - ret = gnutls_x509_privkey_export (x509_privkey, - GNUTLS_X509_FMT_PEM, - output_data, - &ods); - printf("ret: %u; ods: %u;\n", ret, ods); - if (ret == 0) { - write(1, output_data, ods); - } - gnutls_x509_privkey_deinit(x509_privkey); gnutls_global_deinit(); return 0; } -- cgit v1.2.3 From 03cc847e6fc901ab4c1920324910126158655e37 Mon Sep 17 00:00:00 2001 From: Daniel Kahn Gillmor Date: Fri, 13 Jun 2008 11:18:00 -0400 Subject: monkeysphere debianization. Package can now be cleanly built with minimal lintian warnings. --- COPYING | 6 +++--- Makefile | 5 ++++- debian/changelog | 5 +++-- debian/control | 6 +++--- debian/copyright | 9 +++++++-- man/man1/openpgp2ssh.1 | 54 ++++++++++++++++++++++++++++++-------------------- src/keytrans/Makefile | 2 +- test.key | 27 ------------------------- 8 files changed, 53 insertions(+), 61 deletions(-) delete mode 100644 test.key (limited to 'man') diff --git a/COPYING b/COPYING index ab8788d..c920a0e 100644 --- a/COPYING +++ b/COPYING @@ -1,13 +1,13 @@ MonkeySphere is a system to use the OpenPGP web-of-trust to authenticate and encrypt ssh connections. -It is free software, written by: +It is free software, developed by: Jameson Rollins - Daniel Kahn Gillmor -with much help from: + Daniel Kahn Gillmor Jamie McClelland Micah Anderson Matthew Goins + Mike Castleman MonkeySphere is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/Makefile b/Makefile index b28e54e..64e6cbe 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,10 @@ all: keytrans keytrans: $(MAKE) -C src/keytrans +release: clean + tar c COPYING doc etc Makefile man src | gzip -n > ../monkeysphere_`head -n1 debian/changelog | sed 's/.*(\([^-]*\)-.*/\1/'`.orig.tar.gz + clean: $(MAKE) -C src/keytrans clean -.PHONY: all clean +.PHONY: all clean release diff --git a/debian/changelog b/debian/changelog index 2b68de6..ec744e1 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,6 +1,7 @@ monkeysphere (0.1-1) unstable; urgency=low - * to be first release... + * First release of debian package for monkeysphere. + * This is experimental -- please report bugs! - -- Jameson Graef Rollins Tue, 10 Jun 2008 17:20:16 -0400 + -- Daniel Kahn Gillmor Fri, 13 Jun 2008 10:53:43 -0400 diff --git a/debian/control b/debian/control index e190ae0..afd5bfa 100644 --- a/debian/control +++ b/debian/control @@ -1,18 +1,18 @@ Source: monkeysphere Section: net Priority: extra -Maintainer: Daniel Kahn Gillmor +Maintainer: Daniel Kahn Gillmor Uploaders: Jameson Rollins Build-Depends: debhelper (>= 7.0), libgnutls-dev (>= 2.3.14) Standards-Version: 3.8.0.1 Homepage: http://cmrg.fifthhorseman.net/wiki/OpenPGPandSSH -Enhances: openssh-client, openssh-server Dm-Upload-Allowed: yes Package: monkeysphere Architecture: any -Depends: openssh-client, gnupg | gnupg2, coreutils (>= 6) +Depends: openssh-client, gnupg | gnupg2, coreutils (>= 6), ${shlibs:Depends} Recommends: netcat +Enhances: openssh-client, openssh-server Description: use the OpenPGP web of trust to verify ssh connections SSH key-based authentication is tried-and-true, but it lacks a true Public Key Infrastructure for key certification, revocation and diff --git a/debian/copyright b/debian/copyright index 413f60f..11abe8b 100644 --- a/debian/copyright +++ b/debian/copyright @@ -4,8 +4,13 @@ Debianized-Date: Fri Jun 13 10:19:16 EDT 2008 Original-Source: http://lair.fifthhorseman.net/~dkg/git/monkeysphere.git/ Files: * -Copyright: Jameson Rollins , - Daniel Kahn Gillmor +Copyright: 2008 Jameson Rollins , + Daniel Kahn Gillmor , + Jamie McClelland , + Micah Anderson , + Matthew Goins , + Mike Castleman + License: GPL-3+ This package is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/man/man1/openpgp2ssh.1 b/man/man1/openpgp2ssh.1 index 1a02b38..83b6154 100644 --- a/man/man1/openpgp2ssh.1 +++ b/man/man1/openpgp2ssh.1 @@ -7,31 +7,34 @@ openpgp2ssh .Nd translate OpenPGP keys to SSH keys .Sh SYNOPSIS .Nm openpgp2ssh < mykey.gpg - +.Pp .Nm gpg --export $KEYID | openpgp2ssh $KEYID - +.Pp .Nm gpg --export-secret-key $KEYID | openpgp2ssh $KEYID .Sh DESCRIPTION -openpgp2ssh takes an OpenPGP-formatted primary key and associated +.Nm +takes an OpenPGP-formatted primary key and associated subkeys on standard input, and spits out the requested equivalent SSH-style key on standard output. - +.Pp If the data on standard input contains no subkeys, you can invoke -openpgp2ssh without arguments. If the data on standard input contains +.Nm +without arguments. If the data on standard input contains multiple keys (e.g. a primary key and associated subkeys), you must specify a specific OpenPGP keyid (e.g. CCD2ED94D21739E9) or fingerprint as the first argument to indicate which key to export. The keyid must be exactly 16 hex characters. - +.Pp If the input contains an OpenPGP RSA or DSA public key, it will be converted to the OpenSSH-style single-line keystring, prefixed with the key type. This format is suitable (with minor alterations) for insertion into known_hosts files and authorized_keys files. - +.Pp If the input contains an OpenPGP RSA or DSA secret key, it will be converted to the equivalent PEM-encoded private key. - -openpgp2ssh is part of the +.Pp +.Nm +is part of the .Xr monkeysphere 1 framework for providing a PKI for SSH. .Sh CAVEATS @@ -39,17 +42,20 @@ The keys produced by this process are stripped of all identifying information, including certifications, self-signatures, etc. This is intentional, since ssh attaches no inherent significance to these features. - -openpgp2ssh only works with RSA or DSA keys, because those are the +.Pp +.Nm +only works with RSA or DSA keys, because those are the only ones which work with ssh. - -Assuming a valid key type, though, openpgp2ssh will produce output for +.Pp +Assuming a valid key type, though, +.Nm +will produce output for any requested key. This means, among other things, that it will happily export revoked keys, unverifiable keys, expired keys, etc. Make sure you do your own key validation before using this tool! .Sh EXAMPLES .Nm gpg --export-secret-key $KEYID | openpgp2ssh $KEYID | ssh-add -c /dev/stdin - +.Pp This pushes the secret key into the active .Xr ssh-agent 1 . Tools such as @@ -58,21 +64,25 @@ which know how to talk to the .Xr ssh-agent 1 can now rely on the key. .Sh AUTHOR -openpgp2ssh and this man page were written by Daniel Kahn Gillmor +.Nm +and this man page were written by Daniel Kahn Gillmor . .Sh BUGS -openpgp2ssh currently only exports into formats used by the OpenSSH. +.Nm +currently only exports into formats used by the OpenSSH. It should support other key output formats, such as those used by lsh(1) and putty(1). - +.Pp Secret key output is currently not passphrase-protected. - -openpgp2ssh currently cannot handle passphrase-protected secret keys on input. - +.Pp +.Nm +currently cannot handle passphrase-protected secret keys on input. +.Pp It would be nice to be able to use keyids shorter or longer than 16 hex characters. - -openpgp2ssh only acts on keys associated with the first primary key +.Pp +.Nm +only acts on keys associated with the first primary key passed in. If you send it more than one primary key, it will silently ignore later ones. .Sh SEE ALSO diff --git a/src/keytrans/Makefile b/src/keytrans/Makefile index 53fa5dc..79602ef 100644 --- a/src/keytrans/Makefile +++ b/src/keytrans/Makefile @@ -1,7 +1,7 @@ all: openpgp2ssh openpgp2ssh: openpgp2ssh.c gnutls-helpers.o - gcc -g -Wall --pedantic -o openpgp2ssh openpgp2ssh.c `libgnutls-config --libs --cflags` -lgnutls-extra gnutls-helpers.o + gcc -g -Wall --pedantic -o openpgp2ssh openpgp2ssh.c `libgnutls-config --libs --cflags` gnutls-helpers.o %.o: %.c gcc -g -Wall --pedantic -o $@ -c $< diff --git a/test.key b/test.key deleted file mode 100644 index 4e05880..0000000 --- a/test.key +++ /dev/null @@ -1,27 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIEogIBAAKCAQEAxMv33LvWBZnKtahorHGYdBZqVxrNUQcVNrgxp4bf/FvgvSLG -kBrw6wHFdVYvWWViD5efrJugqA4+pKp16LEWlc7JZICrou4vEJGkvoqBIJC/4cVN -xcwV1a8jo9ZOYjt0JIyuHrEDGW/edQYWI41XO/H+QdMDsdI+oOmfPV/V4eMyjGKH -vRJ+xDae5izhUb3Lb00YnxpP2n/zhvHpn7weu+bzvwb3pMMo9336Ft7m5ulGPJzN -+3l595LW+lUSDUlUJbACp4Nyn+i9ODPV6xzghzirsh7rnD8jD2kaqIVkcvEhusoB -JN3daPXt9t6m5cfsCWu31BXdbpTWiLIZRUxDzQIBIwKCAQEAl9CMAg0+s90KFxuD -8r4H5IZSCK5GnZe/6GI07vMEj3oTxRrTsP7XG7DoyDsr1z+UyjMjZ+XFE+27S9P0 -ju8Cy1Zg2ICEZ78OXT0nUSkEhtYQXbV2gqTAYwNzQ9/WEUPOn9o9LZ5+u9n0wKzs -gdNvLj5WbUsC2aIwUD8xswDJkP5cA4RfKo8Mz40aXbK6b+S/bOKEkXRFvOor46pl -A8GHxUVcUPUG7LAXCm1FWrDob6FTlv3yW8DeVTCYwt6HdrTmc9b+yOinwMR6ZvUz -R6AESGG7czCvA6rpkCcprfCPx0gfntuzLiGRtl54GvbYWWtPDlxnPwcw1zcSALvM -pJNpawKBgQD/zze04kYZBNDTxolBrZltpPXtPpOrG2Otp8CHreOKn0TifCFPDnCb -ewUhxuDRA+L9KPLT311DtHfIzXJ8/RD6K/QE72ny39h2X2Pn2hWSgb9+iysHBDNc -jb136QFoKQcpqUpLEfTvA71Yqvuk6gsYiuWnIN5KJwy/AhwFQnK/WQKBgQDE8X87 -C+0JSg2ybUopOQVSrvildJEa8CWbM1SAL1j3E24U2fPh+zVmIxqa2m4X/PxFBBTv -WVGayzFkmJK2Dgt7F7hBqi5HelP0B38dXtkPlK6idTALNHoS/7HCDXISgHmDOhcQ -LHGQUuQMkTq6H4cOMwTNO5aM2zc5E9uF/hptlQKBgEHHkftQIKdZAn+Zc8Bud+j+ -iGGTv5JmIPIj0mwIJJFcJ6f0CJCr8RIJsNzMvXeTSP9FCz3LuOWGLW4mM2H37mw3 -MB6GtNgNrLC5cXYiIs3m2XhPq/p9bEr/4ENnzSlposGR7ohVExjjtFig/uFDfzIy -WE+MG+cunOCoxWBwLCKTAoGBALQP/0vtpYTV/eT2NS0A7uyCt3Kzt94dZDYgTUH/ -Z0hMR2OFcUOj2Qzs5R/dpnxVA+dUMGXOAXeVNHk7CcsFhtbxHX3dbCQYEj4yvVyu -fVAS6M8MDqsoqh//uHbnuMB1dmlZrq+zmwecPjdgNbF76TGNuz9MbGOGmOO6Yk6f -LhsLAoGAJoK+yRDaEFDwrjdvGazEy/d1CtknkGY2r4vb8giEodFJcQQhtVtjnYPl -gDIpbcpeT0GDiZd0pxAxpibbKM63pYz8PKtlq0B/qXgArRgJnbku01Jc4iLVWPqK -qitRgsz1HdN2tIqa8oQE0iuvyoq+r6+pqcQJd7sc6lKlk0gO0Mo= ------END RSA PRIVATE KEY----- -- cgit v1.2.3 From a8372a5e6f55e6d830c6aba09a92673b49110a22 Mon Sep 17 00:00:00 2001 From: Jameson Graef Rollins Date: Fri, 13 Jun 2008 11:57:50 -0400 Subject: add man page for the ssh proxy command script. needs to be filled in. --- man/man1/monkeysphere-ssh-proxycommand.1 | 25 +++++++++++++++++++++++++ man/man1/monkeysphere.1 | 3 +++ 2 files changed, 28 insertions(+) create mode 100644 man/man1/monkeysphere-ssh-proxycommand.1 (limited to 'man') diff --git a/man/man1/monkeysphere-ssh-proxycommand.1 b/man/man1/monkeysphere-ssh-proxycommand.1 new file mode 100644 index 0000000..41a95aa --- /dev/null +++ b/man/man1/monkeysphere-ssh-proxycommand.1 @@ -0,0 +1,25 @@ +.TH MONKEYSPHERE-SSH-PROXYCOMMAND "1" "June 2008" "monkeysphere 0.1" "User Commands" +.SH NAME +monkeysphere-ssh-proxycommand \- MonkeySphere ssh ProxyCommand script +.PD +.SH SYNOPSIS +.B ssh -o ProxyCommand="monkeysphere-ssh-proxycommand %h %p" ... +.PD +.SH DESCRIPTION +.PP +MonkeySphere is a system to leverage the OpenPGP Web of Trust for ssh +authentication and encryption. OpenPGP keys are tracked via GnuPG, +and added to the ssh authorized_keys and known_hosts files to be used +for authentication and encryption of ssh connection. + +\fBmonkeysphere-ssh-proxy\fP is an ssh proxy command that can be used +to trigger a monkeysphere update of the known_hosts file for the hosts +that are being connected to. +.PD +.SH AUTHOR +Written by Jameson Rollins +.PD +.SH SEE ALSO +.BR monkeypshere (1), +.BR ssh (1), +.BR gpg (1) diff --git a/man/man1/monkeysphere.1 b/man/man1/monkeysphere.1 index 410a5d7..636adcb 100644 --- a/man/man1/monkeysphere.1 +++ b/man/man1/monkeysphere.1 @@ -1,8 +1,10 @@ .TH MONKEYSPHERE "1" "June 2008" "monkeysphere 0.1" "User Commands" .SH NAME monkeysphere \- MonkeySphere client user interface +.PD .SH SYNOPSIS .B monkeysphere \fIcommand\fP [\fIargs\fP] +.PD .SH DESCRIPTION .PP MonkeySphere is a system to leverage the OpenPGP Web of Trust for ssh @@ -102,6 +104,7 @@ Host keys cache directory. .PD .SH AUTHOR Written by Jameson Rollins +.PD .SH SEE ALSO .BR ssh (1), .BR gpg (1), -- cgit v1.2.3 From 220a0fb50691a6cf3db9624275d46a6f730f55c6 Mon Sep 17 00:00:00 2001 From: Jameson Graef Rollins Date: Fri, 13 Jun 2008 12:37:08 -0400 Subject: fix bugs in ssh key export functions --- man/man1/monkeysphere.1 | 1 + src/common | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'man') diff --git a/man/man1/monkeysphere.1 b/man/man1/monkeysphere.1 index 636adcb..d00a9db 100644 --- a/man/man1/monkeysphere.1 +++ b/man/man1/monkeysphere.1 @@ -107,5 +107,6 @@ Written by Jameson Rollins .PD .SH SEE ALSO .BR ssh (1), +.BR monkeysphere-ssh-proxycommand (1), .BR gpg (1), .BR monkeysphere-server (8) diff --git a/src/common b/src/common index 914c800..8b0f41a 100644 --- a/src/common +++ b/src/common @@ -98,7 +98,7 @@ gpg2known_hosts() { echo -n "$host " gpg --export "$keyID" | \ openpgp2ssh "$keyID" | tr -d '\n' - echo "MonkeySphere${DATE}" + echo " MonkeySphere${DATE}" } # convert key from gpg to ssh authorized_keys format @@ -109,9 +109,9 @@ gpg2authorized_keys() { keyID="$1" userID="$2" - echo -n "MonkeySphere${DATE}:${userID}" gpg --export "$keyID" | \ - openpgp2ssh "$keyID" + openpgp2ssh "$keyID" | tr -d '\n' + echo " MonkeySphere${DATE}:${userID}" } # userid and key policy checking -- cgit v1.2.3 From ad0a9cc0958b30f5be851453ea22c151097fad0c Mon Sep 17 00:00:00 2001 From: Jameson Graef Rollins Date: Fri, 13 Jun 2008 15:36:11 -0400 Subject: More cleanup: - Batch mode for trust_key function. - fix some loggging. - Clean up publish_server_key function -> STILL NON-FUNCTIONING - more work on monkeysphere-ssh-proxycommand man page --- man/man1/monkeysphere-ssh-proxycommand.1 | 31 ++++++--- src/common | 108 +++++++++++++++++++++---------- src/monkeysphere | 23 +++---- src/monkeysphere-server | 19 +----- 4 files changed, 109 insertions(+), 72 deletions(-) (limited to 'man') diff --git a/man/man1/monkeysphere-ssh-proxycommand.1 b/man/man1/monkeysphere-ssh-proxycommand.1 index 41a95aa..63b5a5e 100644 --- a/man/man1/monkeysphere-ssh-proxycommand.1 +++ b/man/man1/monkeysphere-ssh-proxycommand.1 @@ -2,19 +2,32 @@ .SH NAME monkeysphere-ssh-proxycommand \- MonkeySphere ssh ProxyCommand script .PD -.SH SYNOPSIS -.B ssh -o ProxyCommand="monkeysphere-ssh-proxycommand %h %p" ... -.PD .SH DESCRIPTION .PP -MonkeySphere is a system to leverage the OpenPGP Web of Trust for ssh -authentication and encryption. OpenPGP keys are tracked via GnuPG, -and added to the ssh authorized_keys and known_hosts files to be used -for authentication and encryption of ssh connection. - \fBmonkeysphere-ssh-proxy\fP is an ssh proxy command that can be used to trigger a monkeysphere update of the known_hosts file for the hosts -that are being connected to. +that are being connected to. It is meant to be run as an ssh +ProxyCommand. This can either be done by specifying the proxy command +on the command line: + +.B ssh -o ProxyCommand="monkeysphere-ssh-proxycommand %h %p" ... + +or by adding the following line to your ~/.ssh/config script: + +.B ProxyCommand monkeysphere-ssh-proxycommand %h %p + +The script is very simple, and can easily be incorporated into other +ProxyCommand scripts. All it does is first runs + +.B monkeysphere update-known-hosts HOST + +and then + +.B exec nc HOST PORT + +Run the following command for more info: + +.B less $(which monkeysphere-ssh-proxycommand) .PD .SH AUTHOR Written by Jameson Rollins diff --git a/src/common b/src/common index 0f98923..d56028f 100644 --- a/src/common +++ b/src/common @@ -42,7 +42,7 @@ cutline() { # retrieve all keys with given user id from keyserver # FIXME: need to figure out how to retrieve all matching keys # (not just first 5) -gpg_fetch_keys() { +gpg_fetch_userid() { local id id="$1" echo 1,2,3,4,5 | \ @@ -69,6 +69,18 @@ check_capability() { return 0 } +# get the full fingerprint of a key ID +get_key_fingerprint() { + local keyID + + keyID="$1" + + gpg --list-key --with-colons --fixed-list-mode \ + --with-fingerprint "$keyID" | grep "$keyID" | \ + grep '^fpr:' | cut -d: -f10 +} + + # convert escaped characters from gpg output back into original # character # FIXME: undo all escape character translation in with-colons gpg output @@ -139,7 +151,7 @@ process_user_id() { requiredPubCapability=$(echo "$REQUIRED_KEY_CAPABILITY" | tr "[:lower:]" "[:upper:]") # fetch keys from keyserver, return 1 if none found - gpg_fetch_keys "$userID" || return 1 + gpg_fetch_userid "$userID" || return 1 # output gpg info for (exact) userid and store gpgOut=$(gpg --fixed-list-mode --list-key --with-colons \ @@ -261,6 +273,36 @@ process_user_id() { echo "$cacheDir"/"$userIDHash"."$pubKeyID" } +# update the cache for userid, and prompt to add file to +# authorized_user_ids file if the userid is found in gpg +# and not already in file. +update_userid() { + local userID + local cacheDir + local userIDKeyCache + + userID="$1" + cacheDir="$2" + + log "processing userid: '$userID'" + userIDKeyCache=$(process_user_id "$userID" "$cacheDir") + if [ -z "$userIDKeyCache" ] ; then + return 1 + fi + if ! grep -q "^${userID}\$" "$AUTHORIZED_USER_IDS" ; then + echo "the following userid is not in the authorized_user_ids file:" + echo " $userID" + read -p "would you like to add it? [Y|n]: " OK; OK=${OK:=Y} + if [ ${OK/y/Y} = 'Y' ] ; then + log -n "adding userid to authorized_user_ids file... " + echo "$userID" >> "$AUTHORIZED_USER_IDS" + echo "done." + else + log "authorized_user_ids file untouched." + fi + fi +} + # process a host for addition to a known_host file process_host() { local host @@ -392,42 +434,38 @@ process_userids_from_authorized_keys() { done } -# update the cache for userid, and prompt to add file to -# authorized_user_ids file if the userid is found in gpg -# and not already in file. -update_userid() { - local userID - local cacheDir - local userIDKeyCache - - userID="$1" - cacheDir="$2" - - log "processing userid: '$userID'" - userIDKeyCache=$(process_user_id "$userID" "$cacheDir") - if [ -z "$userIDKeyCache" ] ; then - return 1 - fi - if ! grep -q "^${userID}\$" "$AUTHORIZED_USER_IDS" ; then - echo "the following userid is not in the authorized_user_ids file:" - echo " $userID" - read -p "would you like to add? [Y|n]: " OK; OK=${OK:=Y} - if [ ${OK/y/Y} = 'Y' ] ; then - log -n " adding userid to authorized_user_ids file... " - echo "$userID" >> "$AUTHORIZED_USER_IDS" - echo "done." - fi - fi -} - # retrieve key from web of trust, and set owner trust to "full" # if key is found. trust_key() { # get the key from the key server - gpg --keyserver "$KEYSERVER" --recv-key "$keyID" || failure "could not retrieve key '$keyID'" + if ! gpg --keyserver "$KEYSERVER" --recv-key "$keyID" ; then + log "could not retrieve key '$keyID'" + return 1 + fi + + # get key fingerprint + fingerprint=$(get_key_fingerprint "$keyID") + + # import "full" trust for fingerprint into gpg + echo ${fingerprint}:5: | gpg --import-ownertrust + if [ $? = 0 ] ; then + log "owner trust updated." + else + failure "there was a problem changing owner trust." + fi +} + +# publish server key to keyserver +publish_server_key() { + read -p "really publish key to $KEYSERVER? [y|N]: " OK; OK=${OK:=N} + if [ ${OK/y/Y} != 'Y' ] ; then + failure "aborting." + fi - # edit the key to change trust - # FIXME: need to figure out how to automate this, - # in a batch mode or something. - gpg --edit-key "$keyID" + # publish host key + # FIXME: need to figure out better way to identify host key + # dummy command so as not to publish fakes keys during testing + # eventually: + #gpg --send-keys --keyserver "$KEYSERVER" $(hostname -f) + echo "NOT PUBLISHED: gpg --send-keys --keyserver $KEYSERVER $(hostname -f)" } diff --git a/src/monkeysphere b/src/monkeysphere index 69741e1..782ba5e 100755 --- a/src/monkeysphere +++ b/src/monkeysphere @@ -136,6 +136,7 @@ mkdir -p -m 0700 "$GNUPGHOME" mkdir -p -m 0700 "$MS_HOME" mkdir -p "$hostKeysCacheDir" mkdir -p "$userKeysCacheDir" +touch "$AUTHORIZED_USER_IDS" case $COMMAND in 'update-known_hosts'|'update-known-hosts'|'k') @@ -163,12 +164,21 @@ case $COMMAND in fi ;; + 'update-userids'|'u') + if [ -z "$1" ] ; then + failure "you must specify at least one userid." + fi + for userID ; do + update_userid "$userID" "$userKeysCacheDir" + done + ;; + 'update-authorized_keys'|'update-authorized-keys'|'a') MODE='authorized_keys' # make sure authorized_user_ids file exists if [ ! -s "$AUTHORIZED_USER_IDS" ] ; then - failure "authorized_user_ids file is empty or does not exist." + failure "$AUTHORIZED_USER_IDS is empty." fi # set user-controlled authorized_keys file path @@ -178,15 +188,6 @@ case $COMMAND in update_authorized_keys "$msAuthorizedKeys" "$userAuthorizedKeys" "$userKeysCacheDir" ;; - 'update-userids'|'u') - if [ -z "$1" ] ; then - failure "you must specify at least one userid." - fi - for userID ; do - update_userid "$userID" "$userKeysCacheDir" - done - ;; - 'gen-ae-subkey'|'g') keyID="$1" if [ -z "$keyID" ] ; then @@ -201,6 +202,6 @@ case $COMMAND in *) failure "Unknown command: '$COMMAND' -Type 'cereal-admin help' for usage." +Type '$PGRM help' for usage." ;; esac diff --git a/src/monkeysphere-server b/src/monkeysphere-server index 65a7dda..ffb3452 100755 --- a/src/monkeysphere-server +++ b/src/monkeysphere-server @@ -94,21 +94,6 @@ EOF echo "$keyParameters" | gpg --batch --gen-key } -# publish server key to keyserver -publish_key() { - read -p "publish key to $KEYSERVER? [Y|n]: " OK; OK=${OK:=Y} - if [ ${OK/y/Y} != 'Y' ] ; then - failure "aborting." - fi - - keyID=$(gpg --list-key --with-colons ="$USERID" 2> /dev/null | grep '^pub:' | cut -d: -f5) - - # dummy command so as not to publish fakes keys during testing - # eventually: - #gpg --send-keys --keyserver "$KEYSERVER" "$keyID" - echo "NOT PUBLISHED: gpg --send-keys --keyserver $KEYSERVER $keyID" -} - ######################################################################## # MAIN ######################################################################## @@ -176,7 +161,7 @@ case $COMMAND in ;; 'publish-key'|'p') - publish_key + publish_server_key ;; 'trust-keys'|'t') @@ -210,6 +195,6 @@ case $COMMAND in *) failure "Unknown command: '$COMMAND' -Type 'cereal-admin help' for usage." +Type '$PGRM help' for usage." ;; esac -- cgit v1.2.3 From 2ed952e2207d5278cfe96db2d7eeed40709f846b Mon Sep 17 00:00:00 2001 From: Jameson Graef Rollins Date: Fri, 13 Jun 2008 17:47:34 -0400 Subject: Add 'remove_userid' function, inverse of 'update_userids'. Also, tweaked some of the output and man pages. --- debian/control | 2 +- man/man1/monkeysphere.1 | 15 +++++++++++---- man/man8/monkeysphere-server.8 | 17 +++++++++++++---- src/common | 32 +++++++++++++++++++++++++++----- src/monkeysphere | 18 ++++++++++++++++-- src/monkeysphere-server | 33 +++++++++++++++++++++++++++++++-- 6 files changed, 99 insertions(+), 18 deletions(-) (limited to 'man') diff --git a/debian/control b/debian/control index afd5bfa..d4d25c6 100644 --- a/debian/control +++ b/debian/control @@ -10,7 +10,7 @@ Dm-Upload-Allowed: yes Package: monkeysphere Architecture: any -Depends: openssh-client, gnupg | gnupg2, coreutils (>= 6), ${shlibs:Depends} +Depends: openssh-client, gnupg | gnupg2, coreutils (>= 6), moreutils, ${shlibs:Depends} Recommends: netcat Enhances: openssh-client, openssh-server Description: use the OpenPGP web of trust to verify ssh connections diff --git a/man/man1/monkeysphere.1 b/man/man1/monkeysphere.1 index d00a9db..762f008 100644 --- a/man/man1/monkeysphere.1 +++ b/man/man1/monkeysphere.1 @@ -31,25 +31,32 @@ listed in the known_hosts file will be processed. `k' may be used in place of `update-known_hosts'. .TP .B update-userids [USERID]... -Add/update a userid in the authorized_user_ids file. The user IDs +Add/update a user ID to the authorized_user_ids file. The user IDs specified should be exact matches to OpenPGP user IDs. For each specified user ID, gpg will be queried for a key associated with that user ID, querying a keyserver if none is found in the user's keychain. If a key is found, it will be added to the user_keys cache (see KEY CACHES) and the user ID will be added to the user's -authorized_user_ids file (if it wasn't already present). +authorized_user_ids file (if it wasn't already present). `u' may be +used in place of `update-userids'. +.TP +.B remove-userids [USERID]... +Remove a user ID from the authorized_user_ids file. The user IDs +specified should be exact matches to OpenPGP user IDs. `r' may be +used in place of `remove-userids'. .TP .B update-authorized_keys Update the monkeysphere authorized_keys file. The monkeysphere authorized_keys file will be regenerated from the valid keys in the user_key cache, and the user's independently controlled -authorized_keys file (usually ~/.ssh/authorized_keys). +authorized_keys file (usually ~/.ssh/authorized_keys). `a' may be +used in place of `update-authorized_keys'. .TP .B gen-ae-subkey KEYID Generate an `ae` capable subkey. For the primary key with the specified key ID, generate a subkey with "authentication" and "encryption" capability that can be used for MonkeySphere -transactions. +transactions. `g' may be used in place of `gen-ae-subkey'. .TP .B help Output a brief usage summary. `h' or `?' may be used in place of diff --git a/man/man8/monkeysphere-server.8 b/man/man8/monkeysphere-server.8 index cc07077..8f62610 100644 --- a/man/man8/monkeysphere-server.8 +++ b/man/man8/monkeysphere-server.8 @@ -19,18 +19,27 @@ be used for authentication and encryption of ssh connection. Update the admin-controlled authorized_keys files for user. For each user specified, update the user's authorized_keys file in /var/cache/monkeysphere/USER. See `man monkeysphere' for more info. +`k' may be used in place of `update-known_hosts'. .TP .B gen-key -Generate a gpg key for the host. +Generate a gpg key for the host. `g' may be used in place of +`gen-key'. .TP .B publish-key -Publish the host's gpg key to a keyserver. +Publish the host's gpg key to a keyserver. `p' may be used in place +of `publish-key' .TP .B trust-keys KEYID... -Mark key specified with KEYID with full owner trust. +Mark key specified with KEYID with full owner trust. `t' may be used +in place of `trust-keys'. .TP .B update-user-userids USER USERID... -Add/update a userid in the authorized_user_ids file for USER. +Add/update a user ID to the authorized_user_ids file for USER. `u' may +be used in place of `update-user-userids'. +.TP +.B remove-user-userids USER USERID... +Remove a user ID from the authorized_user_ids file for USER. `r' may +be used in place of `remove-user-userids'. .TP .B help Output a brief usage summary. `h' or `?' may be used in place of diff --git a/src/common b/src/common index d56028f..01e6f32 100644 --- a/src/common +++ b/src/common @@ -240,6 +240,9 @@ process_user_id() { # hash userid for cache file name userIDHash=$(echo "$userID" | sha1sum | awk '{ print $1 }') + # make sure the cache directory exists + mkdir -p "$cacheDir" + # touch/clear key cache file # (will be left empty if there are noacceptable keys) > "$cacheDir"/"$userIDHash"."$pubKeyID" @@ -285,16 +288,16 @@ update_userid() { cacheDir="$2" log "processing userid: '$userID'" + userIDKeyCache=$(process_user_id "$userID" "$cacheDir") + if [ -z "$userIDKeyCache" ] ; then return 1 fi if ! grep -q "^${userID}\$" "$AUTHORIZED_USER_IDS" ; then - echo "the following userid is not in the authorized_user_ids file:" - echo " $userID" - read -p "would you like to add it? [Y|n]: " OK; OK=${OK:=Y} + read -p "user ID not currently authorized. authorize? [Y|n]: " OK; OK=${OK:=Y} if [ ${OK/y/Y} = 'Y' ] ; then - log -n "adding userid to authorized_user_ids file... " + log -n "adding user ID to authorized_user_ids file... " echo "$userID" >> "$AUTHORIZED_USER_IDS" echo "done." else @@ -303,6 +306,24 @@ update_userid() { fi } +# remove a userid from the authorized_user_ids file +remove_userid() { + local userID + + userID="$1" + + log "processing userid: '$userID'" + + if ! grep -q "^${userID}\$" "$AUTHORIZED_USER_IDS" ; then + log "user ID not currently authorized." + return 1 + fi + + log -n "removing user ID '$userID'... " + grep -v "$userID" "$AUTHORIZED_USER_IDS" | sponge "$AUTHORIZED_USER_IDS" + echo "done." +} + # process a host for addition to a known_host file process_host() { local host @@ -373,7 +394,8 @@ update_authorized_keys() { cat "$userAuthorizedKeys" >> "$msAuthorizedKeys" echo "done." fi - log "monkeysphere authorized_keys file generated: $msAuthorizedKeys" + log "monkeysphere authorized_keys file generated:" + log "$msAuthorizedKeys" } # process an authorized_*_ids file diff --git a/src/monkeysphere b/src/monkeysphere index 997ca58..1ba51d7 100755 --- a/src/monkeysphere +++ b/src/monkeysphere @@ -35,7 +35,8 @@ MonkeySphere client tool. subcommands: update-known_hosts (k) [HOST]... update known_hosts file - update-userids (u) [USERID]... add/update userid + update-userids (u) [USERID]... add/update user IDs + remove-userids (r) [USERID]... remove user IDs update-authorized_keys (a) update authorized_keys file gen-ae-subkey (g) KEYID generate an 'ae' capable subkey help (h,?) this help @@ -164,13 +165,26 @@ case $COMMAND in fi ;; - 'update-userids'|'u') + 'update-userids'|'update-userid'|'u') if [ -z "$1" ] ; then failure "you must specify at least one userid." fi for userID ; do update_userid "$userID" "$userKeysCacheDir" done + log "run the following to update your monkeysphere authorized_keys file:" + log "$PGRM update-authorized_keys" + ;; + + 'remove-userids'|'remove-userid'|'r') + if [ -z "$1" ] ; then + failure "you must specify at least one userid." + fi + for userID ; do + remove_userid "$userID" + done + log "run the following to update your monkeysphere authorized_keys file:" + log "$PGRM update-authorized_keys" ;; 'update-authorized_keys'|'update-authorized-keys'|'a') diff --git a/src/monkeysphere-server b/src/monkeysphere-server index 922aad3..13221c5 100755 --- a/src/monkeysphere-server +++ b/src/monkeysphere-server @@ -35,7 +35,8 @@ subcommands: gen-key (g) 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 userids for a user + update-user-userids (u) USER UID... add/update user IDs for a user + remove-user-userids (r) USER UID... remove user IDs for a user help (h,?) this help EOF @@ -179,7 +180,7 @@ case $COMMAND in done ;; - 'update-user-userids'|'u') + 'update-user-userids'|'update-user-userid'|'u') uname="$1" shift if [ -z "$uname" ] ; then @@ -200,6 +201,34 @@ case $COMMAND in for userID ; do update_userid "$userID" "$cacheDir" done + + log "run the following to update user's authorized_keys file:" + log "$PGRM update-users $uname" + ;; + + 'remove-user-userids'|'remove-user-userid'|'r') + uname="$1" + shift + if [ -z "$uname" ] ; then + failure "you must specify user." + fi + if [ -z "$1" ] ; then + failure "you must specify at least one userid." + fi + + # set variables for the user + AUTHORIZED_USER_IDS="$MS_HOME"/authorized_user_ids/"$uname" + + # make sure user's authorized_user_ids file exists + touch "$AUTHORIZED_USER_IDS" + + # process the user IDs + for userID ; do + remove_userid "$userID" + done + + log "run the following to update user's authorized_keys file:" + log "$PGRM update-users $uname" ;; 'help'|'h'|'?') -- cgit v1.2.3 From 28c7489bb830c8ef9bb7c6e40e3fc4d47a702614 Mon Sep 17 00:00:00 2001 From: Jameson Graef Rollins Date: Sat, 14 Jun 2008 15:58:34 -0400 Subject: More work on the man pages. --- man/man1/monkeysphere-ssh-proxycommand.1 | 12 ++++++--- man/man1/monkeysphere.1 | 44 ++++++++++++++++++++------------ man/man1/openpgp2ssh.1 | 2 +- man/man8/monkeysphere-server.8 | 25 ++++++++++++------ src/monkeysphere-server | 2 +- 5 files changed, 55 insertions(+), 30 deletions(-) (limited to 'man') diff --git a/man/man1/monkeysphere-ssh-proxycommand.1 b/man/man1/monkeysphere-ssh-proxycommand.1 index 63b5a5e..8392ae8 100644 --- a/man/man1/monkeysphere-ssh-proxycommand.1 +++ b/man/man1/monkeysphere-ssh-proxycommand.1 @@ -1,9 +1,11 @@ .TH MONKEYSPHERE-SSH-PROXYCOMMAND "1" "June 2008" "monkeysphere 0.1" "User Commands" + .SH NAME + monkeysphere-ssh-proxycommand \- MonkeySphere ssh ProxyCommand script -.PD + .SH DESCRIPTION -.PP + \fBmonkeysphere-ssh-proxy\fP is an ssh proxy command that can be used to trigger a monkeysphere update of the known_hosts file for the hosts that are being connected to. It is meant to be run as an ssh @@ -28,11 +30,13 @@ and then Run the following command for more info: .B less $(which monkeysphere-ssh-proxycommand) -.PD + .SH AUTHOR + Written by Jameson Rollins -.PD + .SH SEE ALSO + .BR monkeypshere (1), .BR ssh (1), .BR gpg (1) diff --git a/man/man1/monkeysphere.1 b/man/man1/monkeysphere.1 index 762f008..526cad6 100644 --- a/man/man1/monkeysphere.1 +++ b/man/man1/monkeysphere.1 @@ -1,20 +1,24 @@ .TH MONKEYSPHERE "1" "June 2008" "monkeysphere 0.1" "User Commands" + .SH NAME + monkeysphere \- MonkeySphere client user interface -.PD + .SH SYNOPSIS + .B monkeysphere \fIcommand\fP [\fIargs\fP] -.PD + .SH DESCRIPTION -.PP + MonkeySphere is a system to leverage the OpenPGP Web of Trust for ssh authentication and encryption. OpenPGP keys are tracked via GnuPG, and added to the ssh authorized_keys and known_hosts files to be used for authentication and encryption of ssh connection. \fBmonkeysphere\fP is the MonkeySphere client utility. -.PD + .SH SUBCOMMANDS + \fBmonkeysphere\fP takes various subcommands: .TP .B update-known_hosts [HOST]... @@ -61,10 +65,15 @@ transactions. `g' may be used in place of `gen-ae-subkey'. .B help Output a brief usage summary. `h' or `?' may be used in place of `help'. -.PD + +.SH HOST URIs + +Host OpenPGP keys have associated user IDs that use the ssh URI +specification for the host, ie. "ssh://host.full.domain". + .SH KEY ACCEPTABILITY + GPG keys are considered acceptable if the following criteria are met: -.PD .TP .B capability The key must have both the "authentication" and "encrypt" capability @@ -72,8 +81,9 @@ flags. .TP .B validity The key must be "fully" valid, and must not be expired or revoked. -.PD + .SH KEY CACHES + Monkeysphere keeps track of keys in key cache directories. The files in the cache are named with the format "USERID_HASH.PUB_KEY_ID", where USERID_HASH is a hash of the exact OpenPGP user ID, and PUB_KEY_ID is @@ -86,9 +96,9 @@ will be stored in the host_keys cache files, and authorized_keys style key lines will be stored in the user_keys cache files. OpenPGP keys are converted to ssh-style keys with the openpgp2ssh utility (see `man openpgp2ssh'). -.PD + .SH FILES -.PD 1 + .TP ~/.config/monkeysphere/monkeysphere.conf User monkeysphere config file. @@ -97,8 +107,8 @@ User monkeysphere config file. System-wide monkeysphere config file. .TP ~/.config/monkeysphere/authorized_user_ids -GPG user IDs associated with keys that will be checked for addition to -the authorized_keys file. +OpenPGP user IDs associated with keys that will be checked for +addition to the authorized_keys file. .TP ~/.config/monkeysphere/authorized_keys Monkeysphere generated authorized_keys file. @@ -108,12 +118,14 @@ User keys cache directory. .TP ~/.config/monkeysphere/host_keys Host keys cache directory. -.PD + .SH AUTHOR + Written by Jameson Rollins -.PD + .SH SEE ALSO -.BR ssh (1), + .BR monkeysphere-ssh-proxycommand (1), -.BR gpg (1), -.BR monkeysphere-server (8) +.BR monkeysphere-server (8), +.BR ssh (1), +.BR gpg (1) diff --git a/man/man1/openpgp2ssh.1 b/man/man1/openpgp2ssh.1 index 83b6154..bea1da5 100644 --- a/man/man1/openpgp2ssh.1 +++ b/man/man1/openpgp2ssh.1 @@ -69,7 +69,7 @@ and this man page were written by Daniel Kahn Gillmor . .Sh BUGS .Nm -currently only exports into formats used by the OpenSSH. +Currently only exports into formats used by the OpenSSH. It should support other key output formats, such as those used by lsh(1) and putty(1). .Pp diff --git a/man/man8/monkeysphere-server.8 b/man/man8/monkeysphere-server.8 index 8f62610..eafd6a8 100644 --- a/man/man8/monkeysphere-server.8 +++ b/man/man8/monkeysphere-server.8 @@ -1,18 +1,24 @@ .TH MONKEYSPHERE-SERVER "1" "June 2008" "monkeysphere 0.1" "User Commands" + .SH NAME + monkeysphere-server \- monkeysphere server admin user interface + .SH SYNOPSIS + .B monkeysphere-server \fIcommand\fP [\fIargs\fP] + .SH DESCRIPTION -.PP + \fBMonkeySphere\fP is a system to leverage the OpenPGP Web of Trust for ssh authentication and encryption. OpenPGP keys are tracked via GnuPG, and added to the ssh authorized_keys and known_hosts files to be used for authentication and encryption of ssh connection. \fBmonkeysphere-server\fP is the MonkeySphere server admin utility. -.PD + .SH SUBCOMMANDS + \fBmonkeysphere-server\fP takes various subcommands: .TP .B update-users [USER]... @@ -26,11 +32,11 @@ Generate a gpg key for the host. `g' may be used in place of `gen-key'. .TP .B publish-key -Publish the host's gpg key to a keyserver. `p' may be used in place +Publish the host's gpg key to the keyserver. `p' may be used in place of `publish-key' .TP .B trust-keys KEYID... -Mark key specified with KEYID with full owner trust. `t' may be used +Mark key specified with key IDs with full owner trust. `t' may be used in place of `trust-keys'. .TP .B update-user-userids USER USERID... @@ -44,9 +50,9 @@ be used in place of `remove-user-userids'. .B help Output a brief usage summary. `h' or `?' may be used in place of `help'. -.PD + .SH FILES -.PD 1 + .TP /etc/monkeysphere/monkeysphere-server.conf System monkeysphere-server config file. @@ -60,12 +66,15 @@ Monkeysphere GNUPG home directory. /etc/monkeysphere/authorized_user_ids/USER Server maintained authorized_user_ids files for users. .TP -/var/cachemonkeysphere/USER +/var/cache/monkeysphere/USER User keys cache directories. -.PD + .SH AUTHOR + Written by Jameson Rollins + .SH SEE ALSO + .BR monkeysphere (1), .BR gpg (1), .BR ssh (1) diff --git a/src/monkeysphere-server b/src/monkeysphere-server index 13221c5..e05b4b7 100755 --- a/src/monkeysphere-server +++ b/src/monkeysphere-server @@ -47,7 +47,7 @@ gen_key() { # set key defaults KEY_TYPE=${KEY_TYPE:-"RSA"} KEY_LENGTH=${KEY_LENGTH:-"2048"} - KEY_USAGE=${KEY_USAGE:-"encrypt,auth"} + KEY_USAGE=${KEY_USAGE:-"auth,encrypt"} SERVICE=${SERVICE:-"ssh"} HOSTNAME_FQDN=${HOSTNAME_FQDN:-$(hostname -f)} -- cgit v1.2.3 From 5ff6e131ad52ce4de7172e56170ea4f37e397a9e Mon Sep 17 00:00:00 2001 From: Jameson Graef Rollins Date: Sun, 15 Jun 2008 18:23:39 -0400 Subject: Fix gen-subkey function for client. --- man/man1/monkeysphere.1 | 15 ++++++----- src/monkeysphere | 68 ++++++++++++++++++++++++------------------------- src/monkeysphere-server | 2 +- 3 files changed, 42 insertions(+), 43 deletions(-) (limited to 'man') diff --git a/man/man1/monkeysphere.1 b/man/man1/monkeysphere.1 index 526cad6..95f1e59 100644 --- a/man/man1/monkeysphere.1 +++ b/man/man1/monkeysphere.1 @@ -56,11 +56,11 @@ user_key cache, and the user's independently controlled authorized_keys file (usually ~/.ssh/authorized_keys). `a' may be used in place of `update-authorized_keys'. .TP -.B gen-ae-subkey KEYID -Generate an `ae` capable subkey. For the primary key with the -specified key ID, generate a subkey with "authentication" and -"encryption" capability that can be used for MonkeySphere -transactions. `g' may be used in place of `gen-ae-subkey'. +.B gen-subkey KEYID +Generate an `a` capable subkey. For the primary key with the +specified key ID, generate a subkey with "authentication" capability +that can be used for MonkeySphere transactions. `g' may be used in +place of `gen-subkey'. .TP .B help Output a brief usage summary. `h' or `?' may be used in place of @@ -76,8 +76,9 @@ specification for the host, ie. "ssh://host.full.domain". GPG keys are considered acceptable if the following criteria are met: .TP .B capability -The key must have both the "authentication" and "encrypt" capability -flags. +For host keys, the key must have both the "authentication" ("a") and +"encrypt" ("e") capability flags. For user keys, the key must have +the "authentication" ("a") capability flag. .TP .B validity The key must be "fully" valid, and must not be expired or revoked. diff --git a/src/monkeysphere b/src/monkeysphere index ff4423b..6369197 100755 --- a/src/monkeysphere +++ b/src/monkeysphere @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash # monkeysphere: MonkeySphere client tool # @@ -38,14 +38,15 @@ subcommands: update-userids (u) [USERID]... add/update user IDs remove-userids (r) [USERID]... remove user IDs update-authorized_keys (a) update authorized_keys file - gen-ae-subkey (g) KEYID generate an 'ae' capable subkey + gen-subkey (g) KEYID generate an 'a' capable subkey help (h,?) this help EOF } -# generate a subkey with the 'a' and 'e' usage flags set -gen_ae_subkey(){ +# generate a subkey with the 'a' usage flags set +# FIXME: not working yet. +gen_subkey(){ local keyID local gpgOut local userID @@ -54,11 +55,6 @@ gen_ae_subkey(){ keyID="$1" - # set subkey defaults - SUBKEY_TYPE=${KEY_TYPE:-"RSA"} - SUBKEY_LENGTH=${KEY_LENGTH:-"1024"} - SUBKEY_USAGE=${KEY_USAGE:-"encrypt,auth"} - gpgOut=$(gpg --fixed-list-mode --list-keys --with-colons \ "$keyID" 2> /dev/null) @@ -68,35 +64,37 @@ gen_ae_subkey(){ return 1 fi - userID=$(echo "$gpgOut" | grep "^uid:" | cut -d: -f10) - - # set key parameters - keyParameters=$(cat < = key expires in n days + w = key expires in n weeks + m = key expires in n months + y = key expires in n years EOF -) - - echo "The following key parameters will be used:" - echo "$keyParameters" - - read -p "generate key? [Y|n]: " OK; OK=${OK:=Y} - if [ ${OK/y/Y} != 'Y' ] ; then - failure "aborting." - fi - - # add commit command - keyParameters="${keyParameters}"$(cat < Date: Tue, 17 Jun 2008 14:33:19 -0400 Subject: Update man pages and TODO. --- debian/dirs | 1 + debian/monkeysphere.dirs | 1 + doc/TODO | 12 +++++++ man/man1/monkeysphere-ssh-proxycommand.1 | 13 ++++--- man/man1/monkeysphere.1 | 60 +++++++++++--------------------- man/man8/monkeysphere-server.8 | 11 +++--- 6 files changed, 48 insertions(+), 50 deletions(-) (limited to 'man') diff --git a/debian/dirs b/debian/dirs index bdf0fe0..b458649 100644 --- a/debian/dirs +++ b/debian/dirs @@ -1,4 +1,5 @@ var/cache/monkeysphere +var/cache/monkeysphere/authorized_keys usr/bin usr/sbin usr/share diff --git a/debian/monkeysphere.dirs b/debian/monkeysphere.dirs index 4604eee..bc8abcf 100644 --- a/debian/monkeysphere.dirs +++ b/debian/monkeysphere.dirs @@ -1,4 +1,5 @@ usr/share/monkeysphere var/cache/monkeysphere +var/cache/monkeysphere/authorized_keys etc/monkeysphere etc/monkeysphere/authorized_user_ids diff --git a/doc/TODO b/doc/TODO index 6125fea..905d198 100644 --- a/doc/TODO +++ b/doc/TODO @@ -1,6 +1,18 @@ Next-Steps Monkeysphere Projects: --------------------------------- +Handle unknown hosts in such a way that they're not always removed + from known_hosts file. Ask user to lsign the host key? + +Handle multiple multiple hostnames (multiple user IDs?) when + generating host keys with gen-key. + +Make sure alternate ports are handled for known_hosts. + +Add environment variables sections to man pages. + +Script to import private key into ssh agent. + Provide a friendly interactive UI for marginal or failing client-side hostkey verifications. Handle the common cases smoothly, and provide good debugging info for the unusual cases. diff --git a/man/man1/monkeysphere-ssh-proxycommand.1 b/man/man1/monkeysphere-ssh-proxycommand.1 index 8392ae8..5fabb91 100644 --- a/man/man1/monkeysphere-ssh-proxycommand.1 +++ b/man/man1/monkeysphere-ssh-proxycommand.1 @@ -19,13 +19,12 @@ or by adding the following line to your ~/.ssh/config script: .B ProxyCommand monkeysphere-ssh-proxycommand %h %p The script is very simple, and can easily be incorporated into other -ProxyCommand scripts. All it does is first runs - -.B monkeysphere update-known-hosts HOST - -and then - -.B exec nc HOST PORT +ProxyCommand scripts. It first tests to see if the host is in the +known_hosts file. If it's not, the CHECK_KEYSERVER variable is set to +true and "update-known_hosts" is run for the host to check for a host +key for that host. If the host is found in the known_hosts file, +CHECK_KEYSERVER is set to false and "update-known_hosts" is run to +update from the local keychain. Run the following command for more info: diff --git a/man/man1/monkeysphere.1 b/man/man1/monkeysphere.1 index 95f1e59..8d89071 100644 --- a/man/man1/monkeysphere.1 +++ b/man/man1/monkeysphere.1 @@ -24,25 +24,23 @@ for authentication and encryption of ssh connection. .B update-known_hosts [HOST]... Update the known_hosts file. For each specified host, gpg will be queried for a key associated with the host URI (see HOST URIs), -querying a keyserver if none is found in the user's keychain. search -for a gpg key for the host in the Web of Trust. If a key is found, it -will be added to the host_keys cache (see KEY CACHES) and any ssh keys -for the host will be removed from the user's known_hosts file. If the -found key is acceptable (see KEY ACCEPTABILITY), then the host's gpg -key will be added to the known_hosts file. If no gpg key is found for -the host, then nothing is done. If no hosts are specified, all hosts -listed in the known_hosts file will be processed. `k' may be used in -place of `update-known_hosts'. +querying a keyserver if specified. If a key is found, it will be +converted to an ssh key, and any matching ssh keys will be removed +from the user's known_hosts file. If the found key is acceptable (see +KEY ACCEPTABILITY), then the key will be updated and re-added to the +known_hosts file. If no gpg key is found for the host, then nothing +is done. If no hosts are specified, all hosts listed in the +known_hosts file will be processed. `k' may be used in place of +`update-known_hosts'. .TP .B update-userids [USERID]... Add/update a user ID to the authorized_user_ids file. The user IDs specified should be exact matches to OpenPGP user IDs. For each specified user ID, gpg will be queried for a key associated with that -user ID, querying a keyserver if none is found in the user's keychain. -If a key is found, it will be added to the user_keys cache (see KEY -CACHES) and the user ID will be added to the user's -authorized_user_ids file (if it wasn't already present). `u' may be -used in place of `update-userids'. +user ID, querying a keyserver if specified. If a key is found, the +user ID will be added to the user's authorized_user_ids file (if it +wasn't already present). `u' may be used in place of +`update-userids'. .TP .B remove-userids [USERID]... Remove a user ID from the authorized_user_ids file. The user IDs @@ -50,11 +48,15 @@ specified should be exact matches to OpenPGP user IDs. `r' may be used in place of `remove-userids'. .TP .B update-authorized_keys -Update the monkeysphere authorized_keys file. The monkeysphere -authorized_keys file will be regenerated from the valid keys in the -user_key cache, and the user's independently controlled -authorized_keys file (usually ~/.ssh/authorized_keys). `a' may be -used in place of `update-authorized_keys'. +Update the monkeysphere authorized_keys file. For each user ID in the +user's authorized_user_ids file, gpg will be queried for keys +associated with that user ID, querying a keyserver if specified. If a +key is found, it will be converted to an ssh key, and any matching ssh +keys will be removed from the user's authorized_keys file. If the +found key is acceptable (see KEY ACCEPTABILITY), then the key will be +updated and re-added to the authorized_keys file. If no gpg key is +found for the user ID, then nothing is done. `a' may be used in place +of `update-authorized_keys'. .TP .B gen-subkey KEYID Generate an `a` capable subkey. For the primary key with the @@ -83,21 +85,6 @@ the "authentication" ("a") capability flag. .B validity The key must be "fully" valid, and must not be expired or revoked. -.SH KEY CACHES - -Monkeysphere keeps track of keys in key cache directories. The files -in the cache are named with the format "USERID_HASH.PUB_KEY_ID", where -USERID_HASH is a hash of the exact OpenPGP user ID, and PUB_KEY_ID is -the key ID of the primary key. If the user/key ID combo exists in the -Web of Trust but is not acceptable, then the file is empty. If the -primary key has at least one acceptable sub key, then an ssh-style -key, converted from the OpenPGP key, of all acceptable subkeys will be -stored in the cache file, one per line. known_hosts style key lines -will be stored in the host_keys cache files, and authorized_keys style -key lines will be stored in the user_keys cache files. OpenPGP keys -are converted to ssh-style keys with the openpgp2ssh utility (see `man -openpgp2ssh'). - .SH FILES .TP @@ -114,11 +101,6 @@ addition to the authorized_keys file. ~/.config/monkeysphere/authorized_keys Monkeysphere generated authorized_keys file. .TP -~/.config/monkeysphere/user_keys -User keys cache directory. -.TP -~/.config/monkeysphere/host_keys -Host keys cache directory. .SH AUTHOR diff --git a/man/man8/monkeysphere-server.8 b/man/man8/monkeysphere-server.8 index eafd6a8..5ca248a 100644 --- a/man/man8/monkeysphere-server.8 +++ b/man/man8/monkeysphere-server.8 @@ -24,8 +24,11 @@ be used for authentication and encryption of ssh connection. .B update-users [USER]... Update the admin-controlled authorized_keys files for user. For each user specified, update the user's authorized_keys file in -/var/cache/monkeysphere/USER. See `man monkeysphere' for more info. -`k' may be used in place of `update-known_hosts'. +/var/cache/monkeysphere/authorized_keys/USER. See `man monkeysphere' +for more info. If the USER_CONTROLLED_AUTHORIZED_KEYS variable is +set, then a user-controlled authorized_keys file (usually +~USER/.ssh/authorized_keys) is added to the authorized_keys file. `k' +may be used in place of `update-known_hosts'. .TP .B gen-key Generate a gpg key for the host. `g' may be used in place of @@ -66,8 +69,8 @@ Monkeysphere GNUPG home directory. /etc/monkeysphere/authorized_user_ids/USER Server maintained authorized_user_ids files for users. .TP -/var/cache/monkeysphere/USER -User keys cache directories. +/var/cache/monkeysphere/authorized_keys/USER +User authorized_keys file. .SH AUTHOR -- cgit v1.2.3 From ac63e6d6a916e4b51a183e60d7aeae3c2568f3af Mon Sep 17 00:00:00 2001 From: Jameson Graef Rollins Date: Tue, 17 Jun 2008 14:39:13 -0400 Subject: Fix small bug in man page. --- man/man1/monkeysphere.1 | 1 - 1 file changed, 1 deletion(-) (limited to 'man') diff --git a/man/man1/monkeysphere.1 b/man/man1/monkeysphere.1 index 8d89071..a5b422c 100644 --- a/man/man1/monkeysphere.1 +++ b/man/man1/monkeysphere.1 @@ -100,7 +100,6 @@ addition to the authorized_keys file. .TP ~/.config/monkeysphere/authorized_keys Monkeysphere generated authorized_keys file. -.TP .SH AUTHOR -- cgit v1.2.3