From: Jamie McClelland Date: Sat, 3 May 2008 15:29:45 +0000 (-0400) Subject: Merge commit 'remotes/dkg/master'; commit 'remotes/enw/master'; commit 'remotes/greg... X-Git-Tag: monkeysphere_0.1-1~75^2 X-Git-Url: https://codewiz.org/gitweb?a=commitdiff_plain;h=d19ed9fb6cc0bd7de9eb14b6d192c9eaccedc427;hp=c83951904066fedc425b82ea4dbf6cab64db7cd6;p=monkeysphere.git Merge commit 'remotes/dkg/master'; commit 'remotes/enw/master'; commit 'remotes/greg/master'; commit 'remotes/jrollins/master'; commit 'remotes/micah/master'; commit 'remotes/mjgoins/master'; commit 'remotes/mlcastle/master'; commit 'remotes/rossg/master' --- diff --git a/doc/MonkeySpec b/doc/MonkeySpec new file mode 100644 index 0000000..7a19df0 --- /dev/null +++ b/doc/MonkeySpec @@ -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. +* 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 index 0000000..4c70d1d --- /dev/null +++ b/doc/README @@ -0,0 +1,5 @@ + Monkeysphere + ------------ + + +This is the README! diff --git a/doc/git init b/doc/git init new file mode 100644 index 0000000..7ba5071 --- /dev/null +++ b/doc/git init @@ -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 {} + diff --git a/monkeysphere.conf b/monkeysphere.conf index 1e3abf9..1a6cff1 100644 --- a/monkeysphere.conf +++ b/monkeysphere.conf @@ -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' diff --git a/rhesus/rhesus b/rhesus/rhesus index fe98b39..0c7e100 100755 --- a/rhesus/rhesus +++ b/rhesus/rhesus @@ -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