work on fleshing out the new functionality for the next release,
authorJameson Graef Rollins <jrollins@finestructure.net>
Fri, 16 Jan 2009 03:32:45 +0000 (22:32 -0500)
committerJameson Graef Rollins <jrollins@finestructure.net>
Fri, 16 Jan 2009 03:32:45 +0000 (22:32 -0500)
including new functions: import-key, add-revoker, revoke-key, etc.

src/monkeysphere
src/monkeysphere-server

index 5444cb012156adb91730046e9b1602153a99f549..463a1b119310e53d803f40ed7a65c78776ad373c 100755 (executable)
@@ -41,6 +41,9 @@ Monkeysphere client tool.
 subcommands:
  update-known_hosts (k) [HOST]...    update known_hosts file
  update-authorized_keys (a)          update authorized_keys file
+ import-subkey (i)                   import existing ssh key as gpg subkey
+   --keyfile (-f) FILE                 key file to import
+   --expire (-e) EXPIRE                date to expire
  gen-subkey (g) [KEYID]              generate an authentication subkey
    --length (-l) BITS                  key length in bits (2048)
    --expire (-e) EXPIRE                date to expire
@@ -51,6 +54,47 @@ subcommands:
 EOF
 }
 
+# import an existing ssh key as a gpg subkey
+import_subkey() {
+    local keyFile="~/.ssh/id_rsa"
+    local keyExpire
+    local keyID
+    local gpgOut
+    local userID
+
+    # get options
+    while true ; do
+       case "$1" in
+           -f|--keyfile)
+               keyFile="$2"
+               shift 2
+               ;;
+           -e|--expire)
+               keyExpire="$2"
+               shift 2
+               ;;
+           *)
+               if [ "$(echo "$1" | cut -c 1)" = '-' ] ; then
+                   failure "Unknown option '$1'.
+Type '$PGRM help' for usage."
+               fi
+               break
+               ;;
+       esac
+    done
+
+    log verbose "importing ssh key..."
+    fifoDir=$(mktemp -d ${TMPDIR:-/tmp}/tmp.XXXXXXXXXX)
+    (umask 077 && mkfifo "$fifoDir/pass")
+    ssh2openpgp | gpg --passphrase-fd 3 3< "$fifoDir/pass" --expert --command-fd 0 --import &
+
+    passphrase_prompt  "Please enter your passphrase for $keyID: " "$fifoDir/pass"
+
+    rm -rf "$fifoDir"
+    wait
+    log verbose "done."
+}
+
 # generate a subkey with the 'a' usage flags set
 gen_subkey(){
     local keyLength
@@ -59,10 +103,6 @@ gen_subkey(){
     local gpgOut
     local userID
 
-    # set default key parameter values
-    keyLength=
-    keyExpire=
-
     # get options
     while true ; do
        case "$1" in
@@ -376,6 +416,10 @@ case $COMMAND in
        RETURN="$?"
        ;;
 
+    'import-subkey'|'i')
+       import_key "$@"
+       ;;
+
     'gen-subkey'|'g')
        gen_subkey "$@"
        ;;
index ba3fa8de409b350ca57e255045d52cf09446206e..96f5b5618b2d58633e3848b6cba2feedb5668367 100755 (executable)
@@ -46,13 +46,20 @@ Monkeysphere server admin tool.
 subcommands:
  update-users (u) [USER]...          update user authorized_keys files
 
- gen-key (g) [NAME[:PORT]]           generate gpg key for the server
+ import-key (i)                      import existing ssh key to gpg
+   --hostname (-h) NAME[:PORT]         hostname for key user ID
+   --keyfile (-f) FILE                 key file to import
+   --expire (-e) EXPIRE                date to expire
+ gen-key (g)                         generate gpg key for the host
+   --hostname (-h) NAME[:PORT]         hostname for key user ID
    --length (-l) BITS                  key length in bits (2048)
    --expire (-e) EXPIRE                date to expire
    --revoker (-r) FINGERPRINT          add a revoker
- extend-key (e) EXPIRE               extend expiration to EXPIRE
- add-hostname (n+) NAME[:PORT]       add hostname user ID to server key
+ extend-key (e) EXPIRE               extend host key expiration
+ add-hostname (n+) NAME[:PORT]       add hostname user ID to host key
  revoke-hostname (n-) NAME[:PORT]    revoke hostname user ID
+ add-revoker (o) FINGERPRINT         add a revoker to the host key
+ revoke-key (r)                      revoke host key
  show-key (s)                        output all server host key information
  publish-key (p)                     publish server host key to keyserver
  diagnostics (d)                     report on server monkeysphere status
@@ -64,7 +71,8 @@ subcommands:
  remove-id-certifier (c-) KEYID      remove a certification key
  list-id-certifiers (c)              list certification keys
 
- gpg-authentication-cmd CMD          gnupg-authentication command
+ gpg-authentication-cmd CMD          give a gpg command to the
+                                     authentication keyring
 
  version (v)                         show version number
  help (h,?)                          this help
@@ -311,28 +319,107 @@ update_users() {
     done
 }
 
+# import an existing ssh key to a gpg key
+import_key() {
+    local hostName=$(hostname -f)
+    local keyFile="/etc/ssh/ssh_host_rsa_key"
+    local keyExpire
+    local userID
+
+    # check for presense of secret key
+    # FIXME: is this the proper test to be doing here?
+    fingerprint_server_key >/dev/null \
+       && failure "An OpenPGP host key already exists."
+
+    # get options
+    while true ; do
+       case "$1" in
+           -h|--hostname)
+               hostName="$2"
+               shift 2
+               ;;
+           -f|--keyfile)
+               keyFile="$2"
+               shift 2
+               ;;
+           -e|--expire)
+               keyExpire="$2"
+               shift 2
+               ;;
+           *)
+               if [ "$(echo "$1" | cut -c 1)" = '-' ] ; then
+                   failure "Unknown option '$1'.
+Type '$PGRM help' for usage."
+               fi
+               break
+               ;;
+       esac
+    done
+
+    if [ ! -f "$keyFile" ] ; then
+       failure "SSH secret key file '$keyFile' not found."
+    fi
+
+    userID="ssh://${hostName}"
+
+    # prompt about key expiration if not specified
+    keyExpire=$(get_gpg_expiration "$keyExpire")
+
+    echo "The following key parameters will be used for the host private key:"
+    echo "Import: $keyFile"
+    echo "Name-Real: $userID"
+    echo "Expire-Date: $keyExpire"
+
+    read -p "Import key? (Y/n) " OK; OK=${OK:=Y}
+    if [ ${OK/y/Y} != 'Y' ] ; then
+       failure "aborting."
+    fi
+
+    log verbose "importing ssh key..."
+    # translate ssh key to a private key
+    (umask 077 && \
+       pem2openpgp "$userID" "$keyExpire" < "$sshKey" | gpg_host --import)
+
+    # find the key fingerprint of the newly converted key
+    fingerprint=$(fingerprint_server_key)
+
+    # export host ownertrust to authentication keyring
+    log verbose "setting ultimate owner trust for host key..."
+    echo "${fingerprint}:6:" | gpg_host "--import-ownertrust"
+    echo "${fingerprint}:6:" | gpg_authentication "--import-ownertrust"
+
+    # export public key to file
+    gpg_authentication "--export-options export-minimal --armor --export 0x${fingerprint}\!" > "${SYSDATADIR}/ssh_host_rsa_key.pub.gpg"
+    log info "SSH host public key in OpenPGP form: ${SYSDATADIR}/ssh_host_rsa_key.pub.gpg"
+
+    # show info about new key
+    show_server_key
+}
+
 # generate server gpg key
 gen_key() {
-    local keyType
-    local keyLength
-    local keyUsage
+    local keyType="RSA"
+    local keyLength="2048"
+    local keyUsage="auth"
     local keyExpire
     local revoker
-    local hostName
+    local hostName=$(hostname -f)
     local userID
     local keyParameters
     local fingerprint
 
-    # set default key parameter values
-    keyType="RSA"
-    keyLength="2048"
-    keyUsage="auth"
-    keyExpire=
-    revoker=
+    # check for presense of secret key
+    # FIXME: is this the proper test to be doing here?
+    fingerprint_server_key >/dev/null \
+       && failure "An OpenPGP host key already exists."
 
     # get options
     while true ; do
        case "$1" in
+           -h|--hostname)
+               hostName="$2"
+               shift 2
+               ;;
            -l|--length)
                keyLength="$2"
                shift 2
@@ -355,14 +442,8 @@ Type '$PGRM help' for usage."
        esac
     done
 
-    hostName=${1:-$(hostname -f)}
     userID="ssh://${hostName}"
 
-    # check for presense of secret key
-    # FIXME: is this the proper test to be doing here?
-    fingerprint_server_key >/dev/null \
-       && failure "A key for this host already exists."
-
     # prompt about key expiration if not specified
     keyExpire=$(get_gpg_expiration "$keyExpire")
 
@@ -399,14 +480,14 @@ Revoker: 1:${revoker} sensitive"
 %commit
 %echo done"
 
-    log verbose "generating server key..."
+    log verbose "generating host key..."
     echo "$keyParameters" | gpg_host --batch --gen-key
 
     # find the key fingerprint of the newly generated key
     fingerprint=$(fingerprint_server_key)
 
     # export host ownertrust to authentication keyring
-    log verbose "setting ultimate owner trust for server key..."
+    log verbose "setting ultimate owner trust for host key..."
     echo "${fingerprint}:6:" | gpg_authentication "--import-ownertrust"
 
     # translate the private key to ssh format, and export to a file
@@ -584,6 +665,18 @@ EOF
     fi
 }
 
+# add a revoker to the host key
+add_revoker() {
+    # FIXME: implement!
+    failure "not implemented yet!"
+}
+
+# revoke the host key
+revoke_key() {
+    # FIXME: implement!
+    failure "not implemented yet!"
+}
+
 # publish server key to keyserver
 publish_server_key() {
     read -p "Really publish host key to $KEYSERVER? (y/N) " OK; OK=${OK:=N}
@@ -1006,6 +1099,11 @@ case $COMMAND in
        update_users "$@"
        ;;
 
+    'import-key'|'i')
+       check_user
+       import_key "$@"
+       ;;
+
     'gen-key'|'g')
        check_user
        gen_key "$@"
@@ -1029,6 +1127,18 @@ case $COMMAND in
        revoke_hostname "$@"
        ;;
 
+    'add-revoker'|'o')
+       check_user
+       check_host_keyring
+       add_revoker "$@"
+       ;;
+
+    'revoke-key'|'r')
+       check_user
+       check_host_keyring
+       revoke_key "$@"
+       ;;
+
     'show-key'|'show'|'s')
        show_server_key
        ;;