1# -*-shell-script-*-
2# This should be sourced by bash (though we welcome changes to make it POSIX sh compliant)
3
4# Monkeysphere authentication update-users subcommand
5#
6# The monkeysphere scripts are written by:
7# Jameson Rollins <jrollins@finestructure.net>
8# Jamie McClelland <jm@mayfirst.org>
9# Daniel Kahn Gillmor <dkg@fifthhorseman.net>
10#
11# They are Copyright 2008-2009, and are all released under the GPL,
12# version 3 or later.
13
14update_users() {
15
16local returnCode=0
17local unames
18local uname
19local authorizedKeysDir
20local tmpAuthorizedKeys
21local authorizedUserIDs
22
23if [ "$1" ] ; then
24    # get users from command line
25    unames="$@"
26else
27    # or just look at all users if none specified
28    unames=$(list_users)
29fi
30
31# set gnupg home
32GNUPGHOME="$GNUPGHOME_SPHERE"
33
34# the authorized_keys directory
35authorizedKeysDir="${SYSDATADIR}/authorized_keys"
36
37# check to see if the gpg trust database has been initialized
38if [ ! -s "${GNUPGHOME}/trustdb.gpg" ] ; then
39    failure "GNUPG trust database uninitialized.  Please see MONKEYSPHERE-SERVER(8)."
40fi
41
42# make sure the authorized_keys directory exists
43mkdir -p "${authorizedKeysDir}"
44
45# loop over users
46for uname in $unames ; do
47    # check all specified users exist
48    if ! id "$uname" >/dev/null ; then
49	log error "----- unknown user '$uname' -----"
50	continue
51    fi
52
53    log verbose "----- user: $uname -----"
54
55    # make temporary directory
56    TMPLOC=$(mktemp -d ${MATMPDIR}/tmp.XXXXXXXXXX) || failure "Could not create temporary directory!"
57
58    # trap to delete temporary directory on exit
59    trap "rm -rf $TMPLOC" EXIT
60
61     # create temporary authorized_keys file
62    tmpAuthorizedKeys="${TMPLOC}/authorized_keys"
63    touch "$tmpAuthorizedKeys"
64
65    # set restrictive permissions on the temporary files
66    # FIXME: is there a better way to do this?
67    chmod 0700 "$TMPLOC"
68    chmod 0600 "$tmpAuthorizedKeys"
69    chown -R "$MONKEYSPHERE_USER" "$TMPLOC"
70
71    # process authorized_user_ids file
72    log debug "checking for authorized_user_ids..."
73    # translating ssh-style path variables
74    authorizedUserIDs=$(translate_ssh_variables "$uname" "$AUTHORIZED_USER_IDS")
75    if [ -s "$authorizedUserIDs" ] ; then
76	# check permissions on the authorized_user_ids file path
77	if check_key_file_permissions "$uname" "$authorizedUserIDs" ; then
78	    log verbose "processing authorized_user_ids..."
79
80	    # process authorized_user_ids file, as monkeysphere user
81	    su_monkeysphere_user \
82		/usr/bin/env "STRICT_MODES=$STRICT_MODES" bash -c "$(printf ". %q && process_authorized_user_ids -" "${SYSSHAREDIR}/common")"\
83		< "$authorizedUserIDs" \
84		> "$tmpAuthorizedKeys"
85
86	else
87	    log debug "not processing authorized_user_ids."
88	fi
89    else
90	log debug "empty or absent authorized_user_ids file."
91    fi
92
93    # add user-controlled authorized_keys file if specified translate
94    # ssh-style path variables
95    rawAuthorizedKeys=$(translate_ssh_variables "$uname" "$RAW_AUTHORIZED_KEYS")
96    if [ "$rawAuthorizedKeys" != 'none' ] ; then
97	log debug "checking for raw authorized_keys..."
98	if [ -s "$rawAuthorizedKeys" ] ; then
99	    # check permissions on the authorized_keys file path
100	    if check_key_file_permissions "$uname" "$rawAuthorizedKeys" ; then
101		log verbose "adding raw authorized_keys..."
102
103		cat "$rawAuthorizedKeys" >> "$tmpAuthorizedKeys"
104
105	    else
106		log debug "not adding raw authorized_keys."
107	    fi
108	else
109	    log debug "empty or absent authorized_keys file."
110	fi
111    fi
112
113    # move the new authorized_keys file into place
114    if [ -s "$tmpAuthorizedKeys" ] ; then
115	# openssh appears to check the contents of the authorized_keys
116	# file as the user in question, so the file must be readable
117	# by that user at least.
118
119	# but in general, we don't want the user tampering with this
120	# file directly, so we'll adopt this approach: Own the file by
121	# the monkeysphere-server invoker (usually root, but should be
122	# the same uid that sshd is launched as); change the group of
123	# the file so that members of the user's group can read it.
124
125	if [ "$OUTPUT_STDOUT" ] ; then
126	    log debug "outputting keys to stdout..."
127	    cat "$tmpAuthorizedKeys"
128	else
129	    log debug "moving new file to ${authorizedKeysDir}/${uname}..."
130	    # FIXME: is there a better way to do this?
131	    chown $(whoami) "$tmpAuthorizedKeys" && \
132		chgrp $(id -g "$uname") "$tmpAuthorizedKeys" && \
133		chmod g+r "$tmpAuthorizedKeys" && \
134		mv -f "$tmpAuthorizedKeys" "${authorizedKeysDir}/${uname}" || \
135		{
136		log error "Failed to install authorized_keys for '$uname'!"
137		rm -f "${authorizedKeysDir}/${uname}"
138		# indicate that there has been a failure:
139		returnCode=1
140	    }
141	fi
142    else
143	rm -f "${authorizedKeysDir}/${uname}"
144    fi
145
146    # unset the trap
147    trap - EXIT
148
149    # destroy temporary directory
150    rm -rf "$TMPLOC"
151done
152
153return $returnCode
154}
155