diagnostics should now check for cruft from old versions of the monkeysphere.
[monkeysphere.git] / src / share / mh / diagnostics
1 # -*-shell-script-*-
2 # This should be sourced by bash (though we welcome changes to make it POSIX sh compliant)
3
4 # Monkeysphere host diagnostics 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
14 # check on the status and validity of the key and public certificates
15
16 diagnostics() {
17
18 local seckey
19 local keysfound
20 local curdate
21 local warnwindow
22 local warndate
23 local create
24 local expire
25 local uid
26 local fingerprint
27 local badhostkeys
28 local sshd_config
29 local problemsfound=0
30
31 report_cruft
32
33 # FIXME: what's the correct, cross-platform answer?
34 sshd_config=/etc/ssh/sshd_config
35 seckey=$(gpg_host --list-secret-keys --fingerprint --with-colons --fixed-list-mode)
36 keysfound=$(echo "$seckey" | grep -c ^sec:)
37 curdate=$(date +%s)
38 # warn when anything is 2 months away from expiration
39 warnwindow='2 months'
40 warndate=$(advance_date $warnwindow +%s)
41
42 if ! id monkeysphere >/dev/null ; then
43     echo "! No monkeysphere user found!  Please create a monkeysphere system user with bash as its shell."
44     problemsfound=$(($problemsfound+1))
45 fi
46
47 if ! [ -d "$SYSDATADIR" ] ; then
48     echo "! no $SYSDATADIR directory found.  Please create it."
49     problemsfound=$(($problemsfound+1))
50 fi
51
52 echo "Checking host GPG key..."
53 if (( "$keysfound" < 1 )); then
54     echo "! No host key found."
55     echo " - Recommendation: run 'monkeysphere-host gen-key' or 'monkeysphere-host import-key'"
56     problemsfound=$(($problemsfound+1))
57 elif (( "$keysfound" > 1 )); then
58     echo "! More than one host key found?"
59     # FIXME: recommend a way to resolve this
60     problemsfound=$(($problemsfound+1))
61 else
62     create=$(echo "$seckey" | grep ^sec: | cut -f6 -d:)
63     expire=$(echo "$seckey" | grep ^sec: | cut -f7 -d:)
64     fingerprint=$(echo "$seckey" | grep ^fpr: | head -n1 | cut -f10 -d:)
65     # check for key expiration:
66     if [ "$expire" ]; then
67         if (( "$expire"  < "$curdate" )); then
68             echo "! Host key is expired."
69             echo " - Recommendation: extend lifetime of key with 'monkeysphere-host extend-key'"
70             problemsfound=$(($problemsfound+1))
71         elif (( "$expire" < "$warndate" )); then
72             echo "! Host key expires in less than $warnwindow:" $(advance_date $(( $expire - $curdate )) seconds +%F)
73             echo " - Recommendation: extend lifetime of key with 'monkeysphere-host extend-key'"
74             problemsfound=$(($problemsfound+1))
75         fi
76     fi
77
78     # and weirdnesses:
79     if [ "$create" ] && (( "$create" > "$curdate" )); then
80         echo "! Host key was created in the future(?!). Is your clock correct?"
81         echo " - Recommendation: Check clock ($(date +%F_%T)); use NTP?"
82         problemsfound=$(($problemsfound+1))
83     fi
84     
85     # check for UserID expiration:
86     echo "$seckey" | grep ^uid: | cut -d: -f6,7,10 | \
87     while IFS=: read create expire uid ; do
88         # FIXME: should we be doing any checking on the form
89         # of the User ID?  Should we be unmangling it somehow?
90
91         if [ "$create" ] && (( "$create" > "$curdate" )); then
92             echo "! User ID '$uid' was created in the future(?!).  Is your clock correct?"
93             echo " - Recommendation: Check clock ($(date +%F_%T)); use NTP?"
94             problemsfound=$(($problemsfound+1))
95         fi
96         if [ "$expire" ] ; then
97             if (( "$expire" < "$curdate" )); then
98                 echo "! User ID '$uid' is expired."
99                 # FIXME: recommend a way to resolve this
100                 problemsfound=$(($problemsfound+1))
101             elif (( "$expire" < "$warndate" )); then
102                 echo "! User ID '$uid' expires in less than $warnwindow:" $(advance_date $(( $expire - $curdate )) seconds +%F)
103                 # FIXME: recommend a way to resolve this
104                 problemsfound=$(($problemsfound+1))
105             fi
106         fi
107     done
108             
109 # FIXME: verify that the host key is properly published to the
110 #   keyservers (do this with the non-privileged user)
111
112 # FIXME: check that there are valid, non-expired certifying signatures
113 #   attached to the host key after fetching from the public keyserver
114 #   (do this with the non-privileged user as well)
115
116 # FIXME: propose adding a revoker to the host key if none exist (do we
117 #   have a way to do that after key generation?)
118
119     # Ensure that the ssh_host_rsa_key file is present and non-empty:
120     echo
121     echo "Checking host SSH key..."
122     if [ ! -s "${SYSDATADIR}/ssh_host_rsa_key" ] ; then
123         echo "! The host key as prepared for SSH (${SYSDATADIR}/ssh_host_rsa_key) is missing or empty."
124         problemsfound=$(($problemsfound+1))
125     else
126         if [ $(ls -l "${SYSDATADIR}/ssh_host_rsa_key" | cut -f1 -d\ ) != '-rw-------' ] ; then
127             echo "! Permissions seem wrong for ${SYSDATADIR}/ssh_host_rsa_key -- should be 0600."
128             problemsfound=$(($problemsfound+1))
129         fi
130
131         # propose changes needed for sshd_config (if any)
132         if ! grep -q "^HostKey[[:space:]]\+${SYSDATADIR}/ssh_host_rsa_key$" "$sshd_config"; then
133             echo "! $sshd_config does not point to the monkeysphere host key (${SYSDATADIR}/ssh_host_rsa_key)."
134             echo " - Recommendation: add a line to $sshd_config: 'HostKey ${SYSDATADIR}/ssh_host_rsa_key'"
135             problemsfound=$(($problemsfound+1))
136         fi
137         if badhostkeys=$(grep -i '^HostKey' "$sshd_config" | grep -v "^HostKey[[:space:]]\+${SYSDATADIR}/ssh_host_rsa_key$") ; then
138             echo "! $sshd_config refers to some non-monkeysphere host keys:"
139             echo "$badhostkeys"
140             echo " - Recommendation: remove the above HostKey lines from $sshd_config"
141             problemsfound=$(($problemsfound+1))
142         fi
143
144         # FIXME: test (with ssh-keyscan?) that the running ssh
145         # daemon is actually offering the monkeysphere host key.
146
147     fi
148 fi
149
150 # FIXME: look at the ownership/privileges of the various keyrings,
151 #    directories housing them, etc (what should those values be?  can
152 #    we make them as minimal as possible?)
153
154
155 if [ "$problemsfound" -gt 0 ]; then
156     echo "When the above $problemsfound issue"$(if [ "$problemsfound" -eq 1 ] ; then echo " is" ; else echo "s are" ; fi)" resolved, please re-run:"
157     echo "  monkeysphere-host diagnostics"
158 else
159     echo "Everything seems to be in order!"
160 fi
161
162 }