merging changes from micah
[monkeysphere.git] / src / monkeysphere-authentication
1 #!/usr/bin/env bash
2
3 # monkeysphere-authentication: Monkeysphere authentication admin tool
4 #
5 # The monkeysphere scripts are written by:
6 # Jameson Rollins <jrollins@fifthhorseman.net>
7 # Jamie McClelland <jm@mayfirst.org>
8 # Daniel Kahn Gillmor <dkg@fifthhorseman.net>
9 #
10 # They are Copyright 2008, and are all released under the GPL, version 3
11 # or later.
12
13 ########################################################################
14 PGRM=$(basename $0)
15
16 SYSSHAREDIR=${MONKEYSPHERE_SYSSHAREDIR:-"/usr/share/monkeysphere"}
17 export SYSSHAREDIR
18 . "${SYSSHAREDIR}/common" || exit 1
19
20 SYSDATADIR=${MONKEYSPHERE_SYSDATADIR:-"/var/lib/monkeysphere/authentication"}
21 export SYSDATADIR
22
23 # monkeysphere temp directory, in sysdatadir to enable atomic moves of
24 # authorized_keys files
25 MSTMPDIR="${SYSDATADIR}/tmp"
26 export MSTMPDIR
27
28 # UTC date in ISO 8601 format if needed
29 DATE=$(date -u '+%FT%T')
30
31 # unset some environment variables that could screw things up
32 unset GREP_OPTIONS
33
34 # default return code
35 RETURN=0
36
37 ########################################################################
38 # FUNCTIONS
39 ########################################################################
40
41 usage() {
42     cat <<EOF >&2
43 usage: $PGRM <subcommand> [options] [args]
44 Monkeysphere authentication admin tool.
45
46 subcommands:
47  update-users (u) [USER]...          update user authorized_keys files
48  add-id-certifier (c+) KEYID         import and tsign a certification key
49    --domain (-n) DOMAIN                limit ID certifications to DOMAIN
50    --trust (-t) TRUST                  trust level of certifier (full)
51    --depth (-d) DEPTH                  trust depth for certifier (1)
52  remove-id-certifier (c-) KEYID      remove a certification key
53  list-id-certifiers (c)              list certification keys
54
55  expert
56   diagnostics (d)                    monkeysphere authentication status
57   gpg-cmd CMD                        execute gpg command
58
59  version (v)                         show version number
60  help (h,?)                          this help
61
62 EOF
63 }
64
65 # function to run command as monkeysphere user
66 su_monkeysphere_user() {
67     # if the current user is the monkeysphere user, then just eval
68     # command
69     if [ $(id -un) = "$MONKEYSPHERE_USER" ] ; then
70         eval "$@"
71
72     # otherwise su command as monkeysphere user
73     else
74         su "$MONKEYSPHERE_USER" -c "$@"
75     fi
76 }
77
78 # function to interact with the host gnupg keyring
79 gpg_host() {
80     local returnCode
81
82     GNUPGHOME="$GNUPGHOME_HOST"
83     export GNUPGHOME
84
85     # NOTE: we supress this warning because we need the monkeysphere
86     # user to be able to read the host pubring.  we realize this might
87     # be problematic, but it's the simplest solution, without too much
88     # loss of security.
89     gpg --no-permission-warning "$@"
90     returnCode="$?"
91
92     # always reset the permissions on the host pubring so that the
93     # monkeysphere user can read the trust signatures
94     chgrp "$MONKEYSPHERE_USER" "${GNUPGHOME_HOST}/pubring.gpg"
95     chmod g+r "${GNUPGHOME_HOST}/pubring.gpg"
96     
97     return "$returnCode"
98 }
99
100 # function to interact with the authentication gnupg keyring
101 # FIXME: this function requires basically accepts only a single
102 # argument because of problems with quote expansion.  this needs to be
103 # fixed/improved.
104 gpg_authentication() {
105     GNUPGHOME="$GNUPGHOME_AUTHENTICATION"
106     export GNUPGHOME
107
108     su_monkeysphere_user "gpg $@"
109 }
110
111 # check if user is root
112 is_root() {
113     [ $(id -u 2>/dev/null) = '0' ]
114 }
115
116 # check that user is root, for functions that require root access
117 check_user() {
118     is_root || failure "You must be root to run this command."
119 }
120
121 # output just key fingerprint
122 fingerprint_server_key() {
123     # set the pipefail option so functions fails if can't read sec key
124     set -o pipefail
125
126     gpg_host --list-secret-keys --fingerprint \
127         --with-colons --fixed-list-mode 2> /dev/null | \
128         grep '^fpr:' | head -1 | cut -d: -f10 2>/dev/null
129 }
130
131 # function to check for host secret key
132 check_host_keyring() {
133     fingerprint_server_key >/dev/null \
134         || failure "You don't appear to have a Monkeysphere host key on this server.  Please run 'monkeysphere-server gen-key' first."
135 }
136
137 # update authorized_keys for users
138 update_users() {
139     if [ "$1" ] ; then
140         # get users from command line
141         unames="$@"
142     else
143         # or just look at all users if none specified
144         unames=$(getent passwd | cut -d: -f1)
145     fi
146
147     RETCODE=0
148
149     # set mode
150     MODE="authorized_keys"
151
152     # set gnupg home
153     GNUPGHOME="$GNUPGHOME_AUTHENTICATION"
154
155     # check to see if the gpg trust database has been initialized
156     if [ ! -s "${GNUPGHOME}/trustdb.gpg" ] ; then
157         failure "GNUPG trust database uninitialized.  Please see MONKEYSPHERE-SERVER(8)."
158     fi
159
160     # make sure the authorized_keys directory exists
161     mkdir -p "${SYSDATADIR}/authorized_keys"
162
163     # loop over users
164     for uname in $unames ; do
165         # check all specified users exist
166         if ! id "$uname" >/dev/null ; then
167             log error "----- unknown user '$uname' -----"
168             continue
169         fi
170
171         log verbose "----- user: $uname -----"
172
173         # make temporary directory
174         TMPLOC=$(mktemp -d ${MSTMPDIR}/tmp.XXXXXXXXXX) || failure "Could not create temporary directory!"
175
176         # trap to delete temporary directory on exit
177         trap "rm -rf $TMPLOC" EXIT
178
179         # create temporary authorized_user_ids file
180         TMP_AUTHORIZED_USER_IDS="${TMPLOC}/authorized_user_ids"
181         touch "$TMP_AUTHORIZED_USER_IDS"
182
183         # create temporary authorized_keys file
184         AUTHORIZED_KEYS="${TMPLOC}/authorized_keys"
185         touch "$AUTHORIZED_KEYS"
186
187         # set restrictive permissions on the temporary files
188         # FIXME: is there a better way to do this?
189         chmod 0700 "$TMPLOC"
190         chmod 0600 "$AUTHORIZED_KEYS"
191         chmod 0600 "$TMP_AUTHORIZED_USER_IDS"
192         chown -R "$MONKEYSPHERE_USER" "$TMPLOC"
193
194         # process authorized_user_ids file
195         log debug "checking for authorized_user_ids..."
196         # translating ssh-style path variables
197         authorizedUserIDs=$(translate_ssh_variables "$uname" "$AUTHORIZED_USER_IDS")
198         if [ -s "$authorizedUserIDs" ] ; then
199             # check permissions on the authorized_user_ids file path
200             if check_key_file_permissions "$uname" "$authorizedUserIDs" ; then
201                 # copy user authorized_user_ids file to temporary
202                 # location
203                 cat "$authorizedUserIDs" > "$TMP_AUTHORIZED_USER_IDS"
204
205                 # export needed variables
206                 export AUTHORIZED_KEYS
207                 export TMP_AUTHORIZED_USER_IDS
208
209                 # process authorized_user_ids file, as monkeysphere
210                 # user
211                 su_monkeysphere_user \
212                     ". ${SYSSHAREDIR}/common; process_authorized_user_ids $TMP_AUTHORIZED_USER_IDS"
213                 RETURN="$?"
214             else
215                 log debug "not processing authorized_user_ids."
216             fi
217         else
218             log debug "empty or absent authorized_user_ids file."
219         fi
220
221         # add user-controlled authorized_keys file if specified
222         # translate ssh-style path variables
223         rawAuthorizedKeys=$(translate_ssh_variables "$uname" "$RAW_AUTHORIZED_KEYS")
224         if [ "$rawAuthorizedKeys" != 'none' ] ; then
225             log debug "checking for raw authorized_keys..."
226             if [ -s "$rawAuthorizedKeys" ] ; then
227                 # check permissions on the authorized_keys file path
228                 if check_key_file_permissions "$uname" "$rawAuthorizedKeys" ; then
229                     log verbose "adding raw authorized_keys file... "
230                     cat "$rawAuthorizedKeys" >> "$AUTHORIZED_KEYS"
231                 else
232                     log debug "not adding raw authorized_keys file."            
233                 fi
234             else
235                 log debug "empty or absent authorized_keys file."
236             fi
237         fi
238
239         # move the new authorized_keys file into place
240         if [ -s "$AUTHORIZED_KEYS" ] ; then
241             # openssh appears to check the contents of the
242             # authorized_keys file as the user in question, so the
243             # file must be readable by that user at least.
244
245             # but in general, we don't want the user tampering with
246             # this file directly, so we'll adopt this approach: Own
247             # the file by the monkeysphere-server invoker (usually
248             # root, but should be the same uid that sshd is launched
249             # as); change the group of the file so that members of the
250             # user's group can read it.
251
252             # FIXME: is there a better way to do this?
253             chown $(whoami) "$AUTHORIZED_KEYS" && \
254                 chgrp $(id -g "$uname") "$AUTHORIZED_KEYS" && \
255                 chmod g+r "$AUTHORIZED_KEYS" && \
256                 mv -f "$AUTHORIZED_KEYS" "${SYSDATADIR}/authorized_keys/${uname}" || \
257                 { 
258                 log error "Failed to install authorized_keys for '$uname'!"
259                 rm -f "${SYSDATADIR}/authorized_keys/${uname}"
260                 # indicate that there has been a failure:
261                 RETURN=1
262                 }
263         else
264             rm -f "${SYSDATADIR}/authorized_keys/${uname}"
265         fi
266
267         # unset the trap
268         trap - EXIT
269
270         # destroy temporary directory
271         rm -rf "$TMPLOC"
272     done
273 }
274
275 diagnostics() {
276 #  * check on the status and validity of the key and public certificates
277     local seckey
278     local keysfound
279     local curdate
280     local warnwindow
281     local warndate
282     local create
283     local expire
284     local uid
285     local fingerprint
286     local badhostkeys
287     local sshd_config
288     local problemsfound=0
289
290     # FIXME: what's the correct, cross-platform answer?
291     sshd_config=/etc/ssh/sshd_config
292     seckey=$(gpg_host --list-secret-keys --fingerprint --with-colons --fixed-list-mode)
293     keysfound=$(echo "$seckey" | grep -c ^sec:)
294     curdate=$(date +%s)
295     # warn when anything is 2 months away from expiration
296     warnwindow='2 months'
297     warndate=$(advance_date $warnwindow +%s)
298
299     if ! id monkeysphere >/dev/null ; then
300         echo "! No monkeysphere user found!  Please create a monkeysphere system user with bash as its shell."
301         problemsfound=$(($problemsfound+1))
302     fi
303
304     if ! [ -d "$SYSDATADIR" ] ; then
305         echo "! no $SYSDATADIR directory found.  Please create it."
306         problemsfound=$(($problemsfound+1))
307     fi
308
309     echo "Checking host GPG key..."
310     if (( "$keysfound" < 1 )); then
311         echo "! No host key found."
312         echo " - Recommendation: run 'monkeysphere-server gen-key'"
313         problemsfound=$(($problemsfound+1))
314     elif (( "$keysfound" > 1 )); then
315         echo "! More than one host key found?"
316         # FIXME: recommend a way to resolve this
317         problemsfound=$(($problemsfound+1))
318     else
319         create=$(echo "$seckey" | grep ^sec: | cut -f6 -d:)
320         expire=$(echo "$seckey" | grep ^sec: | cut -f7 -d:)
321         fingerprint=$(echo "$seckey" | grep ^fpr: | head -n1 | cut -f10 -d:)
322         # check for key expiration:
323         if [ "$expire" ]; then
324             if (( "$expire"  < "$curdate" )); then
325                 echo "! Host key is expired."
326                 echo " - Recommendation: extend lifetime of key with 'monkeysphere-server extend-key'"
327                 problemsfound=$(($problemsfound+1))
328             elif (( "$expire" < "$warndate" )); then
329                 echo "! Host key expires in less than $warnwindow:" $(advance_date $(( $expire - $curdate )) seconds +%F)
330                 echo " - Recommendation: extend lifetime of key with 'monkeysphere-server extend-key'"
331                 problemsfound=$(($problemsfound+1))
332             fi
333         fi
334
335         # and weirdnesses:
336         if [ "$create" ] && (( "$create" > "$curdate" )); then
337             echo "! Host key was created in the future(?!). Is your clock correct?"
338             echo " - Recommendation: Check clock ($(date +%F_%T)); use NTP?"
339             problemsfound=$(($problemsfound+1))
340         fi
341
342         # check for UserID expiration:
343         echo "$seckey" | grep ^uid: | cut -d: -f6,7,10 | \
344         while IFS=: read create expire uid ; do
345             # FIXME: should we be doing any checking on the form
346             # of the User ID?  Should we be unmangling it somehow?
347
348             if [ "$create" ] && (( "$create" > "$curdate" )); then
349                 echo "! User ID '$uid' was created in the future(?!).  Is your clock correct?"
350                 echo " - Recommendation: Check clock ($(date +%F_%T)); use NTP?"
351                 problemsfound=$(($problemsfound+1))
352             fi
353             if [ "$expire" ] ; then
354                 if (( "$expire" < "$curdate" )); then
355                     echo "! User ID '$uid' is expired."
356                     # FIXME: recommend a way to resolve this
357                     problemsfound=$(($problemsfound+1))
358                 elif (( "$expire" < "$warndate" )); then
359                     echo "! User ID '$uid' expires in less than $warnwindow:" $(advance_date $(( $expire - $curdate )) seconds +%F)             
360                     # FIXME: recommend a way to resolve this
361                     problemsfound=$(($problemsfound+1))
362                 fi
363             fi
364         done
365             
366 # FIXME: verify that the host key is properly published to the
367 #   keyservers (do this with the non-privileged user)
368
369 # FIXME: check that there are valid, non-expired certifying signatures
370 #   attached to the host key after fetching from the public keyserver
371 #   (do this with the non-privileged user as well)
372
373 # FIXME: propose adding a revoker to the host key if none exist (do we
374 #   have a way to do that after key generation?)
375
376         # Ensure that the ssh_host_rsa_key file is present and non-empty:
377         echo
378         echo "Checking host SSH key..."
379         if [ ! -s "${SYSDATADIR}/ssh_host_rsa_key" ] ; then
380             echo "! The host key as prepared for SSH (${SYSDATADIR}/ssh_host_rsa_key) is missing or empty."
381             problemsfound=$(($problemsfound+1))
382         else
383             if [ $(ls -l "${SYSDATADIR}/ssh_host_rsa_key" | cut -f1 -d\ ) != '-rw-------' ] ; then
384                 echo "! Permissions seem wrong for ${SYSDATADIR}/ssh_host_rsa_key -- should be 0600."
385                 problemsfound=$(($problemsfound+1))
386             fi
387
388             # propose changes needed for sshd_config (if any)
389             if ! grep -q "^HostKey[[:space:]]\+${SYSDATADIR}/ssh_host_rsa_key$" "$sshd_config"; then
390                 echo "! $sshd_config does not point to the monkeysphere host key (${SYSDATADIR}/ssh_host_rsa_key)."
391                 echo " - Recommendation: add a line to $sshd_config: 'HostKey ${SYSDATADIR}/ssh_host_rsa_key'"
392                 problemsfound=$(($problemsfound+1))
393             fi
394             if badhostkeys=$(grep -i '^HostKey' "$sshd_config" | grep -v "^HostKey[[:space:]]\+${SYSDATADIR}/ssh_host_rsa_key$") ; then
395                 echo "! $sshd_config refers to some non-monkeysphere host keys:"
396                 echo "$badhostkeys"
397                 echo " - Recommendation: remove the above HostKey lines from $sshd_config"
398                 problemsfound=$(($problemsfound+1))
399             fi
400
401         # FIXME: test (with ssh-keyscan?) that the running ssh
402         # daemon is actually offering the monkeysphere host key.
403
404         fi
405     fi
406
407 # FIXME: look at the ownership/privileges of the various keyrings,
408 #    directories housing them, etc (what should those values be?  can
409 #    we make them as minimal as possible?)
410
411 # FIXME: look to see that the ownertrust rules are set properly on the
412 #    authentication keyring
413
414 # FIXME: make sure that at least one identity certifier exists
415
416 # FIXME: look at the timestamps on the monkeysphere-generated
417 # authorized_keys files -- warn if they seem out-of-date.
418
419 # FIXME: check for a cronjob that updates monkeysphere-generated
420 # authorized_keys?
421
422     echo
423     echo "Checking for MonkeySphere-enabled public-key authentication for users ..."
424     # Ensure that User ID authentication is enabled:
425     if ! grep -q "^AuthorizedKeysFile[[:space:]]\+${SYSDATADIR}/authorized_keys/%u$" "$sshd_config"; then
426         echo "! $sshd_config does not point to monkeysphere authorized keys."
427         echo " - Recommendation: add a line to $sshd_config: 'AuthorizedKeysFile ${SYSDATADIR}/authorized_keys/%u'"
428         problemsfound=$(($problemsfound+1))
429     fi
430     if badauthorizedkeys=$(grep -i '^AuthorizedKeysFile' "$sshd_config" | grep -v "^AuthorizedKeysFile[[:space:]]\+${SYSDATADIR}/authorized_keys/%u$") ; then
431         echo "! $sshd_config refers to non-monkeysphere authorized_keys files:"
432         echo "$badauthorizedkeys"
433         echo " - Recommendation: remove the above AuthorizedKeysFile lines from $sshd_config"
434         problemsfound=$(($problemsfound+1))
435     fi
436
437     if [ "$problemsfound" -gt 0 ]; then
438         echo "When the above $problemsfound issue"$(if [ "$problemsfound" -eq 1 ] ; then echo " is" ; else echo "s are" ; fi)" resolved, please re-run:"
439         echo "  monkeysphere-server diagnostics"
440     else
441         echo "Everything seems to be in order!"
442     fi
443 }
444
445 # retrieve key from web of trust, import it into the host keyring, and
446 # ltsign the key in the host keyring so that it may certify other keys
447 add_certifier() {
448     local domain
449     local trust
450     local depth
451     local keyID
452     local fingerprint
453     local ltsignCommand
454     local trustval
455
456     # set default values for trust depth and domain
457     domain=
458     trust=full
459     depth=1
460
461     # get options
462     while true ; do
463         case "$1" in
464             -n|--domain)
465                 domain="$2"
466                 shift 2
467                 ;;
468             -t|--trust)
469                 trust="$2"
470                 shift 2
471                 ;;
472             -d|--depth)
473                 depth="$2"
474                 shift 2
475                 ;;
476             *)
477                 if [ "$(echo "$1" | cut -c 1)" = '-' ] ; then
478                     failure "Unknown option '$1'.
479 Type '$PGRM help' for usage."
480                 fi
481                 break
482                 ;;
483         esac
484     done
485
486     keyID="$1"
487     if [ -z "$keyID" ] ; then
488         failure "You must specify the key ID of a key to add, or specify a file to read the key from."
489     fi
490     if [ -f "$keyID" ] ; then
491         echo "Reading key from file '$keyID':"
492         importinfo=$(gpg_authentication "--import" < "$keyID" 2>&1) || failure "could not read key from '$keyID'"
493         # FIXME: if this is tried when the key database is not
494         # up-to-date, i got these errors (using set -x):
495
496 # ++ su -m monkeysphere -c '\''gpg --import'\''
497 # Warning: using insecure memory!
498 # gpg: key D21739E9: public key "Daniel Kahn Gillmor <dkg@fifthhorseman.net>" imported
499 # gpg: Total number processed: 1
500 # gpg:               imported: 1  (RSA: 1)
501 # gpg: can'\''t create `/var/monkeysphere/gnupg-host/pubring.gpg.tmp'\'': Permission denied
502 # gpg: failed to rebuild keyring cache: Permission denied
503 # gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
504 # gpg: depth: 0  valid:   1  signed:   0  trust: 0-, 0q, 0n, 0m, 0f, 1u
505 # gpg: next trustdb check due at 2009-01-10'
506 # + failure 'could not read key from '\''/root/dkg.gpg'\'''
507 # + echo 'could not read key from '\''/root/dkg.gpg'\'''
508
509         keyID=$(echo "$importinfo" | grep '^gpg: key ' | cut -f2 -d: | cut -f3 -d\ )
510         if [ -z "$keyID" ] || [ $(echo "$keyID" | wc -l) -ne 1 ] ; then
511             failure "Expected there to be a single gpg key in the file."
512         fi
513     else
514         # get the key from the key server
515         gpg_authentication "--keyserver $KEYSERVER --recv-key '0x${keyID}!'" || failure "Could not receive a key with this ID from the '$KEYSERVER' keyserver."
516     fi
517
518     export keyID
519
520
521     # get the full fingerprint of a key ID
522     fingerprint=$(gpg_authentication "--list-key --with-colons --with-fingerprint 0x${keyID}!" | \
523         grep '^fpr:' | grep "$keyID" | cut -d: -f10)
524
525     if [ -z "$fingerprint" ] ; then
526         failure "Key '$keyID' not found."
527     fi
528
529     echo
530     echo "key found:"
531     gpg_authentication "--fingerprint 0x${fingerprint}!"
532
533     echo "Are you sure you want to add the above key as a"
534     read -p "certifier of users on this system? (y/N) " OK; OK=${OK:-N}
535     if [ "${OK/y/Y}" != 'Y' ] ; then
536         failure "Identity certifier not added."
537     fi
538
539     # export the key to the host keyring
540     gpg_authentication "--export 0x${fingerprint}!" | gpg_host --import
541
542     if [ "$trust" = marginal ]; then
543         trustval=1
544     elif [ "$trust" = full ]; then
545         trustval=2
546     else
547         failure "Trust value requested ('$trust') was unclear (only 'marginal' or 'full' are supported)."
548     fi
549
550     # ltsign command
551     # NOTE: *all* user IDs will be ltsigned
552     ltsignCommand=$(cat <<EOF
553 ltsign
554 y
555 $trustval
556 $depth
557 $domain
558 y
559 save
560 EOF
561         )
562
563     # ltsign the key
564     if echo "$ltsignCommand" | \
565         gpg_host --quiet --command-fd 0 --edit-key "0x${fingerprint}!" ; then
566
567         # update the trustdb for the authentication keyring
568         gpg_authentication "--check-trustdb"
569
570         echo
571         echo "Identity certifier added."
572     else
573         failure "Problem adding identify certifier."
574     fi
575 }
576
577 # delete a certifiers key from the host keyring
578 remove_certifier() {
579     local keyID
580     local fingerprint
581
582     keyID="$1"
583     if [ -z "$keyID" ] ; then
584         failure "You must specify the key ID of a key to remove."
585     fi
586
587     if gpg_authentication "--no-options --list-options show-uid-validity --keyring ${GNUPGHOME_AUTHENTICATION}/pubring.gpg --list-key 0x${keyID}!" ; then
588         read -p "Really remove above listed identity certifier? (y/N) " OK; OK=${OK:-N}
589         if [ "${OK/y/Y}" != 'Y' ] ; then
590             failure "Identity certifier not removed."
591         fi
592     else
593         failure
594     fi
595
596     # delete the requested key
597     if gpg_authentication "--delete-key --batch --yes 0x${keyID}!" ; then
598         # delete key from host keyring as well
599         gpg_host --delete-key --batch --yes "0x${keyID}!"
600
601         # update the trustdb for the authentication keyring
602         gpg_authentication "--check-trustdb"
603
604         echo
605         echo "Identity certifier removed."
606     else
607         failure "Problem removing identity certifier."
608     fi
609 }
610
611 # list the host certifiers
612 list_certifiers() {
613     local keys
614     local key
615
616     # find trusted keys in authentication keychain
617     keys=$(gpg_authentication "--no-options --list-options show-uid-validity --keyring ${GNUPGHOME_AUTHENTICATION}/pubring.gpg --list-keys --with-colons --fingerprint" | \
618         grep ^pub: | cut -d: -f2,5 | egrep '^(u|f):' | cut -d: -f2)
619
620     # output keys
621     for key in $keys ; do
622         gpg_authentication "--no-options --list-options show-uid-validity --keyring ${GNUPGHOME_AUTHENTICATION}/pubring.gpg --list-key --fingerprint $key"
623     done
624 }
625
626 ########################################################################
627 # MAIN
628 ########################################################################
629
630 # unset variables that should be defined only in config file
631 unset KEYSERVER
632 unset AUTHORIZED_USER_IDS
633 unset RAW_AUTHORIZED_KEYS
634 unset MONKEYSPHERE_USER
635
636 # load configuration file
637 [ -e ${MONKEYSPHERE_SERVER_CONFIG:="${SYSCONFIGDIR}/monkeysphere-server.conf"} ] && . "$MONKEYSPHERE_SERVER_CONFIG"
638
639 # set empty config variable with ones from the environment, or with
640 # defaults
641 LOG_LEVEL=${MONKEYSPHERE_LOG_LEVEL:=${LOG_LEVEL:="INFO"}}
642 KEYSERVER=${MONKEYSPHERE_KEYSERVER:=${KEYSERVER:="pool.sks-keyservers.net"}}
643 AUTHORIZED_USER_IDS=${MONKEYSPHERE_AUTHORIZED_USER_IDS:=${AUTHORIZED_USER_IDS:="%h/.monkeysphere/authorized_user_ids"}}
644 RAW_AUTHORIZED_KEYS=${MONKEYSPHERE_RAW_AUTHORIZED_KEYS:=${RAW_AUTHORIZED_KEYS:="%h/.ssh/authorized_keys"}}
645 MONKEYSPHERE_USER=${MONKEYSPHERE_MONKEYSPHERE_USER:=${MONKEYSPHERE_USER:="monkeysphere"}}
646
647 # other variables
648 CHECK_KEYSERVER=${MONKEYSPHERE_CHECK_KEYSERVER:="true"}
649 REQUIRED_USER_KEY_CAPABILITY=${MONKEYSPHERE_REQUIRED_USER_KEY_CAPABILITY:="a"}
650 GNUPGHOME_HOST=${MONKEYSPHERE_GNUPGHOME_HOST:="${SYSDATADIR}/gnupg-host"}
651 GNUPGHOME_AUTHENTICATION=${MONKEYSPHERE_GNUPGHOME_AUTHENTICATION:="${SYSDATADIR}/gnupg-authentication"}
652
653 # export variables needed in su invocation
654 export DATE
655 export MODE
656 export MONKEYSPHERE_USER
657 export LOG_LEVEL
658 export KEYSERVER
659 export CHECK_KEYSERVER
660 export REQUIRED_USER_KEY_CAPABILITY
661 export GNUPGHOME_HOST
662 export GNUPGHOME_AUTHENTICATION
663 export GNUPGHOME
664
665 # get subcommand
666 COMMAND="$1"
667 [ "$COMMAND" ] || failure "Type '$PGRM help' for usage."
668 shift
669
670 case $COMMAND in
671     'update-users'|'update-user'|'u')
672         check_user
673         check_host_keyring
674         update_users "$@"
675         ;;
676
677     'add-identity-certifier'|'add-id-certifier'|'add-certifier'|'c+')
678         check_user
679         check_host_keyring
680         add_certifier "$@"
681         ;;
682
683     'remove-identity-certifier'|'remove-id-certifier'|'remove-certifier'|'c-')
684         check_user
685         check_host_keyring
686         remove_certifier "$@"
687         ;;
688
689     'list-identity-certifiers'|'list-id-certifiers'|'list-certifiers'|'list-certifier'|'c')
690         check_user
691         check_host_keyring
692         list_certifiers "$@"
693         ;;
694
695     'expert'|'e')
696         check_user
697         SUBCOMMAND="$1"
698         shift
699         case "$SUBCOMMAND" in
700             'diagnostics'|'d')
701                 diagnostics
702                 ;;
703
704             'gpg-cmd')
705                 gpg_authentication "$@"
706                 ;;
707
708             *)
709                 failure "Unknown expert subcommand: '$COMMAND'
710 Type '$PGRM help' for usage."
711                 ;;
712         esac
713         ;;
714
715     'version'|'v')
716         echo "$VERSION"
717         ;;
718
719     '--help'|'help'|'-h'|'h'|'?')
720         usage
721         ;;
722
723     *)
724         failure "Unknown command: '$COMMAND'
725 Type '$PGRM help' for usage."
726         ;;
727 esac
728
729 exit "$RETURN"