Merge commit 'remotes/dkg/master'; commit 'remotes/enw/master'; commit 'remotes/greg...
authorJamie McClelland <jm@mayfirst.org>
Sat, 3 May 2008 15:29:45 +0000 (11:29 -0400)
committerJamie McClelland <jm@mayfirst.org>
Sat, 3 May 2008 15:29:45 +0000 (11:29 -0400)
doc/MonkeySpec [new file with mode: 0644]
doc/README [new file with mode: 0644]
doc/git init [new file with mode: 0644]
monkeysphere.conf
rhesus/rhesus

diff --git a/doc/MonkeySpec b/doc/MonkeySpec
new file mode 100644 (file)
index 0000000..7a19df0
--- /dev/null
@@ -0,0 +1,105 @@
+THE MONKEYSPHERE
+================
+
+AGENDA
+======
+[x] clowning
+[ ] work
+[x] jrollins will talk and gesture - in progress
+
+COMPONENTS
+==========
+* client-side componants
+** "Marmoset": update known_hosts file with public key of server(s):
+*** be responsible for removing keys from the file as key revocation happens 
+*** be responsible for updating a key in the file where there is a key replacement 
+*** must result in a file that is parsable by the existing ssh client without errors
+*** manual management must be allowed without stomping on it
+*** provide a simple, intelligible, clear policy for key acceptance
+*** questions: should this query keyserver & update known host files? (we already 
+    have awesome tool that queries keyservers and updates a web of trust (gpg) 
+** "Howler": simple script that could be placed as a trigger function (in your .ssh/config)
+*** runs on connection to a certain host
+*** triggers update to known_hosts file then makes connection
+*** proxy-command | pre-hook script | wrapper script
+** "Langur": policy-editor for viewing/editing policies
+
+* server-side componants
+** "Rhesus" updates a per-user authorized_keys file, instead of updating a
+   known_hosts file from a public key by matching a specified user-id (for given
+   user: update authkeys file with public keys derived from authorized_uids
+   file)
+*** Needs to operate with the same principles that Marmoset client-side does 
+** "Tamarin" triggers Rhesus during an attempt to initiate a connection or a scheduler (or both)
+** "Barbary" - policy editor / viewer
+
+* common componants
+** Create a ssh keypair from a openpgp keypair
+
+from ssh_config(5):
+     LocalCommand
+             Specifies a command to execute on the local machine after suc‐
+             cessfully connecting to the server.  The command string extends
+             to the end of the line, and is executed with /bin/sh.  This
+             directive is ignored unless PermitLocalCommand has been enabled.
+
+
+NOTES
+=====
+* Daniel and Elliot lie. <check>
+* We will use a distributed VCS, each developer will create their own git repository and publish it publically for others to pull from, mail out
+* public project page doesn't perhaps make sense yet
+* approximate goal - using the web of trust to authenticate ppl for SSH
+* outline of various components of monkeysphere
+* M: what does it mean to be in the monkeysphere?  not necessarily a great coder.
+* J: interested in seeing project happen, not in actually doing it.  anybody can contribute as much as they want.
+* J: if we put the structure in place to work on monkeysphere then we don't have to do anything
+* D: we are not creating 
+* understand gpg's keyring better, understanding tools better, building scripts
+* Some debian packages allow automated configuration of config files.
+
+
+* GENERAL GOAL - use openpgp web-of-trust to authenticate ppl for SSH
+* SPECIFIC GOAL - allow openssh to tie into pgp web-of-trust without modifying either openpgp and openssh
+* DESIGN GOALS - authentication, use the existing generic OpenSSH client, the admin can make it default, although end-user should be decide to use monkeysphere or not
+* DESIGN GOAL - use of monkeysphere should not radically change connecting-to-server experience
+* GOAL - pick a monkey-related name for each component 
+
+Dramatis Personae: http://en.wikipedia.org/wiki/Alice_and_Bob
+Backstory: http://www.conceptlabs.co.uk/alicebob.html
+
+* Use Case: Bob wants to sign on to the computer "mangabey" via monkeysphere
+  framework. He doesn't have access to the machine, but he knows Alice, who is
+  the admin of magabey. Alice creates a user bob and puts bob's userid in the
+  auth_user_ids file for bob. Tamarin triggers which causes Rhesus to take all
+  the things in the auth_userids file, takes those users, look son a keyserver
+  finds the public keys for the users, converts the gpg public keys into ssh
+  public keys and inserts those into a user_authorized_keys file. Bob goes to
+  connect, bob's ssh client which is monkeysphere enbaled, howler is triggered
+  which triggers marmoset which looks out into the web of trust and find an
+  OpenPGP key that has a userid that matches the URI of magabey. Marmoset checks
+  to see if this key for mangabey has been signed by any keys that you trust
+  (based on your policy). Has this key been signed by somebody that you trust?
+  If yes, connect, if no: abort or fail-through or whatever. Alice has signed 
+  this uid, so Marmoset says "OK, this server has been verified" it then
+  converts the gpg public key into a ssh public key and then adds this gpg key
+  to the known_host file. ssh says, "you" are about to connect to magabey and
+  you know this is magabey because alice says so and you trust alice". The gpg
+  private key of bob has to be converted (somehow, via agent or something) into
+  a ssh private_key. SSH connection happens.
+
+Host identity piece of monkeysphere could be used without buying into the 
+authorization component.
+
+Monkeysphere is authentication layer that allows the sysadmin to perform 
+authorization on user identities instead of on keys, it additionally allows the 
+sysadmin also to authenticate the server to the end-user.
+
+git clone http://git.mlcastle.net/monkeysphere.git/ monkeysphere
+
+Fix gpgkey2ssh so that the entire key fingerprint will work, accept full fingerprint, or accept a pipe and do the conversion
+Write manpage for gpgkey2ssh
+gpg private key (start with passwordless) to PEM encoded private key: perl libraries, libopencdk / gnutls, gpgme 
+setup remote git repo
+think through / plan merging of known_hosts (& auth_keys?)
+think about policies and their representation
\ No newline at end of file
diff --git a/doc/README b/doc/README
new file mode 100644 (file)
index 0000000..4c70d1d
--- /dev/null
@@ -0,0 +1,5 @@
+                               Monkeysphere
+                               ------------
+
+
+This is the README!
diff --git a/doc/git init b/doc/git init
new file mode 100644 (file)
index 0000000..7ba5071
--- /dev/null
@@ -0,0 +1,128 @@
+remote$ mkdir public_html/git
+(etch)
+remote$ GIT_DIR=~/public_html/git/monkeysphere.git git init-db
+remote$ cd ~/public_html/git/monkeysphere.git
+remote$ chmod a+x hooks/post-update
+# NOT SURE IF THIS IS NEEDED: remote$ git-update-server-info
+fetch = +refs/heads/*:refs/remotes/dkg/*
+
+(newer)
+remote$ mkdir -p public_html/git/monkey.git
+remote$ cd public_html/git/monkey.git
+remote$ git --bare init
+remote$ chmod a+x hooks/post-update
+remote$ git-update-server-info
+
+(new way! no origin/)
+$ cd ~/src
+$ mkdir monkeysphere
+$ cd monkeysphere
+$ git init
+$ git remote add -f mlcastle http://git.mlcastle.net/monkeysphere.git/
+$ git remote add grunt grunt:/whatever
+$ git config remote.grunt.push "+refs/heads/*"
+$ git merge mlcastle/master
+$ git push grunt
+
+(old way!)
+(in ~/src or wherever)
+local$ git clone http://git.mlcastle.net/monkeysphere.git/ monkeysphere
+local$ cd monkeysphere
+
+.git/config:
+
+[core]
+       repositoryformatversion = 0
+       filemode = true
+       bare = false
+       logallrefupdates = true
+
+## THIS ONE NEEDS TO BE CHANGED TO YOUR REMOTE URI
+[remote "post"]
+       url = YOUR-REMOTE-URL/git/monkeysphere.git
+       push = +refs/heads/*
+### THE ABOVE ONE NEEDS TO BE CHANGED
+
+[remote "mlcastle"]
+       url = http://git.mlcastle.net/monkeysphere.git/
+       fetch = +refs/heads/*:refs/remotes/mlcastle/*
+
+[remote "jrollins"]
+       url = http://lair.fifthhorseman.net/~jrollins/git/monkeysphere.git/
+       fetch = +refs/heads/*:refs/remotes/jrollins/*
+
+[remote "dkg"]
+       url = http://lair.fifthhorseman.net/~dkg/git/monkeysphere.git/
+       fetch = +refs/heads/*:refs/remotes/dkg/*
+
+[remote "mjgoins"] SEE: dkg, jrollins, etc.
+
+[remote "micah"]
+       url = http://micah.riseup.net/git/monkeysphere.git
+       fetch = +refs/heads/*:refs/remotes/micah/*
+       
+[remote "enw"]
+       url = http://lair.fifthhorseman.net/~enw/git/monkeysphere.git/
+       fetch = +refs/heads/*:refs/remotes/enw/*
+
+[remote "rossg"]
+       url = http://lair.fifthhorseman.net/~rossg/git/monkeysphere.git/
+       fetch = +refs/heads/*:refs/remotes/rossg/*
+
+[remote "greg"]
+       url = http://lair.fifthhorseman.net/~greg/git/monkeysphere.git/
+       fetch = +refs/heads/*:refs/remotes/greg/*
+        blood type = 
+
+-----------------
+[remote "upload"]
+       url = ssh://z.mlcastle.net/var/www/git/monkeysphere.git/
+       push = +refs/heads/*
+
+
+$ git fetch dkg
+$ git checkout master
+$ git merge remotes/dkg/master
+$ git push post
+
+
+
+
+
+
+
+grunt's fingerprint: be:43:9c:03:9c:04:1a:97:7a:61:8a:fe:71:9d:6c:67
+(grunt is lair.fifthhorseman.net)
+
+for foo in $(git remote); do git fetch $foo; done
+
+
+
+set mainfont {Arial 12}
+set textfont { Courier 12}
+set uifont {Arial 10 bold}
+set tabstop 8
+set findmergefiles 0
+set maxgraphpct 50
+set maxwidth 16
+set cmitmode patch
+set wrapcomment none
+set showneartags 1
+set showlocalchanges 1
+set datetimeformat {%Y-%m-%d %H:%M:%S}
+set limitdiffs 1
+set bgcolor white
+set fgcolor black
+set colors {green red blue magenta darkgrey brown orange}
+set diffcolors {red "#00a000" blue}
+set diffcontext 3
+set selectbgcolor gray85
+set geometry(main) 1280x936+14+28
+set geometry(topwidth) 1278
+set geometry(topheight) 286
+set geometry(pwsash0) "638 1"
+set geometry(pwsash1) "903 1"
+set geometry(botwidth) 1001
+set geometry(botheight) 638
+set permviews {}
+
index 1e3abf92d2ff6c3373a50b45147f786d9cc71cce..1a6cff19597873aa4753bfe8eb31368618ac1504 100644 (file)
@@ -1,7 +1,26 @@
 # monkeysphere configuration file
 # this is currently meant to be sourced by bash.
+
+# configuration directory
 CONF_DIR=/etc/monkeysphere
+
+# where the per-user authorized user id files are stored
 AUTH_USER_IDS_DIR="$CONF_DIR"/auth_user_ids
-KEYRING="$CONF_DIR"/keyring.gpg
-KEYSERVER=subkeys.pgp.net
+
+# where the per-user authorized_keys info is stored
+#AUTH_KEYS_DIR=/var/lib/monkeysphere/authorized_keys
+AUTH_KEYS_DIR="$CONF_DIR"/authorized_keys
+
+# gpg home directory for server
 GNUPGHOME="$CONF_DIR"/gnupg
+
+# gpg keyserver to search for keys
+KEYSERVER=subkeys.pgp.net
+
+# acceptable key capabilities for user keys
+# can be any combination of:
+#   e = encrypt
+#   s = sign
+#   c = certify
+#   a = authentication
+REQUIRED_KEY_CAPABILITY='sca'
index fe98b39da09d23b0959bb713dff3299f5c74a8c5..0c7e1003db01326e0c0a46282aa068c731ea9bb6 100755 (executable)
@@ -9,11 +9,8 @@
 
 ##################################################
 # load conf file
-#. /etc/monkeysphere/monkeysphere.conf
-. ~/ms/monkeysphere.conf
-
-#AUTH_KEYS_DIR_BASE=/var/lib/monkeysphere/authorized_keys/
-AUTH_KEYS_DIR_BASE=~/ms/authorized_keys
+CONF_FILE=${CONF_FILE:-"/etc/monkeysphere/monkeysphere.conf"}
+. "$CONF_FILE"
 
 export GNUPGHOME
 ##################################################
@@ -57,8 +54,8 @@ if [ ! -e "$AUTH_USER_IDS" ] ; then
     failure "No auth_user_ids file for user '$USERNAME'."
 fi
 
-AUTH_KEYS_DIR="$AUTH_KEYS_DIR_BASE"/"$USERNAME"/keys
-AUTH_KEYS_FILE="$AUTH_KEYS_DIR_BASE"/authorized_keys
+KEYDIR="$AUTH_KEYS_DIR"/"$USERNAME"/keys
+AUTH_KEYS="$AUTH_KEYS_DIR"/authorized_keys
 
 # make sure the gnupg home exists with proper permissions
 mkdir -p "$GNUPGHOME"
@@ -68,8 +65,8 @@ chmod 0700 "$GNUPGHOME"
 NLINES=$(meat "$AUTH_USER_IDS" | wc -l)
 
 # clean out keys file and remake keys directory
-rm -rf "$AUTH_KEYS_DIR"
-mkdir -p "$AUTH_KEYS_DIR"
+rm -rf "$KEYDIR"
+mkdir -p "$KEYDIR"
 
 # loop through all user ids, and generate ssh keys
 for (( N=1; N<=$NLINES; N=N+1 )) ; do
@@ -77,34 +74,46 @@ for (( N=1; N<=$NLINES; N=N+1 )) ; do
     USERID=$(meat "$AUTH_USER_IDS" | cutline "$N" )
     USERID_HASH=$(echo "$USERID" | sha1sum | awk '{ print $1 }')
 
-    KEYFILE="$AUTH_KEYS_DIR"/"$USERID_HASH"
+    KEYFILE="$KEYDIR"/"$USERID_HASH"
 
     # search for key on keyserver
-    echo -n "ms: finding key for '$USERID'..."
-    RETURN=$(echo 1 | gpg --quiet --batch --command-fd 0 --with-colons --keyserver "$KEYSERVER" --search ="$USERID" 2> /dev/null)
+    echo "ms: validating: '$USERID'"
+    RETURN=$(echo 1 | gpg --quiet --batch --command-fd 0 --with-colons --keyserver "$KEYSERVER" --search ="$USERID")
 
     # if the key was found...
     if [ "$RETURN" ] ; then
-       echo " found."
-
+       echo "ms:   key found."
+       
        # checking key attributes
        # see /usr/share/doc/gnupg/DETAILS.gz:
-
+       
        PUB_INFO=$(gpg --fixed-list-mode --with-colons --list-keys --with-fingerprint ="$USERID" | grep '^pub:')
 
-       echo -n "ms: "
-
-#      # if not an authorization key exit
-#      if echo "$PUB_INFO" | cut -d: -f12 | grep -v -q '[aA]' ; then
-#         echo "not an authorization key --> SKIPPING"
-#         continue
-#      fi
+       # extract needed fields
+       KEY_TRUST=$(echo "$PUB_INFO" | cut -d: -f2)
+       KEY_CAPABILITY=$(echo "$PUB_INFO" | cut -d: -f12)
+       
+       # check if key disabled
+       if  echo "$KEY_CAPABILITY" | grep -q '[D]' ; then
+           echo "ms:   key disabled -> SKIPPING"
+           continue
+       fi
+
+        # check key capability
+       REQUIRED_KEY_CAPABILITY=${REQUIRED_KEY_CAPABILITY:-'a'}
+       if  echo "$KEY_CAPABILITY" | grep -q '[$REQUIRED_KEY_CAPABILITY]' ; then
+           echo "ms:   key capability verified ('$KEY_CAPABILITY')."
+       else
+           echo "ms:   unacceptable key capability ('$KEY_CAPABILITY') -> SKIPPING"
+           continue
+       fi
+
+       echo -n "ms:   key "
 
        # if key is not fully trusted exit
         # (this includes not revoked or expired)
        # determine trust
-       TRUST=$(echo "$PUB_INFO" | cut -d: -f2)
-       case "$TRUST" in
+       case "$KEY_TRUST" in
            'i')
                echo -n "invalid" ;;
            'r')
@@ -112,28 +121,31 @@ for (( N=1; N<=$NLINES; N=N+1 )) ; do
            'e')
                echo -n "expired" ;;
            '-'|'q'|'n'|'m')
-               echo -n "unacceptable trust" ;;
+               echo -n "has unacceptable trust" ;;
            'f'|'u')
                echo -n "fully trusted"
                 # convert pgp key to ssh key, and write to cache file
-               echo " -> generating ssh key..."
-               gpgkey2ssh "$KEYID" | sed -e "s/COMMENT/$USERID/" > "$KEYFILE"
+               echo -n " -> generating ssh key..."
+               #gpg2ssh "$KEYID" | sed -e "s/COMMENT/$USERID/" > "$KEYFILE"
+               echo " done."
                continue
            ;;
            *)
-               echo -n "unknown trust" ;;
+               echo -n "has unknown trust" ;;
        esac
-       echo " -> SKIPPING"
+       echo ". -> SKIPPING"
+    else
+       echo "ms:   key not found."
     fi
 done
 
-if [ $(ls "$AUTH_KEYS_DIR") ]  ; then
+if [ $(ls "$KEYDIR") ]  ; then
     echo "ms: writing ms authorized_keys file..."
-    cat "$AUTH_KEYS_DIR"/* > "$AUTH_KEYS_FILE"
+    cat "$KEYDIR"/* > "$AUTH_KEYS"
 else
     echo "ms: no gpg keys to add to authorized_keys file."
 fi
 if [ -s ~"$USERNAME"/.ssh/authorized_keys ] ; then
     echo "ms: adding user authorized_keys..."
-    cat ~"$USERNAME"/.ssh/authorized_keys >> "$AUTH_KEYS_FILE"
+    cat ~"$USERNAME"/.ssh/authorized_keys >> "$AUTH_KEYS"
 fi