Merge commit 'dkg/master'
[monkeysphere.git] / rhesus / rhesus
1 #!/bin/sh
2
3 # rhesus: monkeysphere authorized_keys update script
4 #
5 # Written by
6 # Jameson Rollins <jrollins@fifthhorseman.net>
7 #
8 # Copyright 2008, released under the GPL, version 3 or later
9
10 ##################################################
11 # load conf file
12 CONF_FILE=${CONF_FILE:-"/etc/monkeysphere/monkeysphere.conf"}
13 . "$CONF_FILE"
14
15 export GNUPGHOME
16 ##################################################
17
18 CMD=$(basename $0)
19
20 usage() {
21 cat <<EOF
22 usage: $CMD USERNAME
23 EOF
24 }
25
26 failure() {
27     echo "$1" >&2
28     exit ${2:-'1'}
29 }
30
31 meat() {
32     grep -v -e "^[[:space:]]*#" -e '^$' "$1"
33 }
34
35 cutline() {
36     head --line="$1" | tail -1
37 }
38
39 ### MAIN
40
41 if [ -z "$1" ] ; then
42     usage
43     exit 1
44 fi
45
46 # user name of user to update
47 USERNAME="$1"
48 if ! id "$USERNAME" > /dev/null ; then
49     failure "User '$USERNAME' does not exist."
50 fi
51
52 AUTH_USER_IDS="$AUTH_USER_IDS_DIR"/"$USERNAME"
53 if [ ! -e "$AUTH_USER_IDS" ] ; then
54     failure "No auth_user_ids file for user '$USERNAME'."
55 fi
56
57 KEYDIR="$AUTH_KEYS_DIR"/"$USERNAME"/keys
58 AUTH_KEYS="$AUTH_KEYS_DIR"/authorized_keys
59
60 # make sure the gnupg home exists with proper permissions
61 mkdir -p "$GNUPGHOME"
62 chmod 0700 "$GNUPGHOME"
63
64 # find number of user ids in auth_user_ids file
65 NLINES=$(meat "$AUTH_USER_IDS" | wc -l)
66
67 # clean out keys file and remake keys directory
68 rm -rf "$KEYDIR"
69 mkdir -p "$KEYDIR"
70
71 # loop through all user ids, and generate ssh keys
72 for (( N=1; N<=$NLINES; N=N+1 )) ; do
73     # get user id
74     USERID=$(meat "$AUTH_USER_IDS" | cutline "$N" )
75     USERID_HASH=$(echo "$USERID" | sha1sum | awk '{ print $1 }')
76
77     KEYFILE="$KEYDIR"/"$USERID_HASH"
78
79     # search for key on keyserver
80     echo "ms: validating: '$USERID'"
81     RETURN=$(echo 1 | gpg --quiet --batch --command-fd 0 --with-colons --keyserver "$KEYSERVER" --search ="$USERID")
82
83     # if the key was found...
84     if [ "$RETURN" ] ; then
85         echo "ms:   key found."
86         
87         # checking key attributes
88         # see /usr/share/doc/gnupg/DETAILS.gz:
89         
90         PUB_INFO=$(gpg --fixed-list-mode --with-colons --list-keys --with-fingerprint ="$USERID" | grep '^pub:')
91
92         # extract needed fields
93         KEY_TRUST=$(echo "$PUB_INFO" | cut -d: -f2)
94         KEY_CAPABILITY=$(echo "$PUB_INFO" | cut -d: -f12)
95         
96         # check if key disabled
97         if  echo "$KEY_CAPABILITY" | grep -q '[D]' ; then
98             echo "ms:   key disabled -> SKIPPING"
99             continue
100         fi
101
102         # check key capability
103         REQUIRED_KEY_CAPABILITY=${REQUIRED_KEY_CAPABILITY:-'a'}
104         if  echo "$KEY_CAPABILITY" | grep -q '[$REQUIRED_KEY_CAPABILITY]' ; then
105             echo "ms:   key capability verified ('$KEY_CAPABILITY')."
106         else
107             echo "ms:   unacceptable key capability ('$KEY_CAPABILITY') -> SKIPPING"
108             continue
109         fi
110
111         echo -n "ms:   key "
112
113         # if key is not fully trusted exit
114         # (this includes not revoked or expired)
115         # determine trust
116         case "$KEY_TRUST" in
117             'i')
118                 echo -n "invalid" ;;
119             'r')
120                 echo -n "revoked" ;;
121             'e')
122                 echo -n "expired" ;;
123             '-'|'q'|'n'|'m')
124                 echo -n "has unacceptable trust" ;;
125             'f'|'u')
126                 echo -n "fully trusted"
127                 # convert pgp key to ssh key, and write to cache file
128                 echo -n " -> generating ssh key..."
129                 #gpg2ssh "$KEYID" | sed -e "s/COMMENT/$USERID/" > "$KEYFILE"
130                 echo " done."
131                 continue
132             ;;
133             *)
134                 echo -n "has unknown trust" ;;
135         esac
136         echo ". -> SKIPPING"
137     else
138         echo "ms:   key not found."
139     fi
140 done
141
142 if [ $(ls "$KEYDIR") ]  ; then
143     echo "ms: writing ms authorized_keys file..."
144     cat "$KEYDIR"/* > "$AUTH_KEYS"
145 else
146     echo "ms: no gpg keys to add to authorized_keys file."
147 fi
148 if [ -s ~"$USERNAME"/.ssh/authorized_keys ] ; then
149     echo "ms: adding user authorized_keys..."
150     cat ~"$USERNAME"/.ssh/authorized_keys >> "$AUTH_KEYS"
151 fi