Some rearragement/cleanup in the monkeysphere-host:
[monkeysphere.git] / src / monkeysphere-host
1 #!/usr/bin/env bash
2
3 # monkeysphere-host: Monkeysphere host admin tool
4 #
5 # The monkeysphere scripts are written by:
6 # Jameson Rollins <jrollins@finestructure.net>
7 # Jamie McClelland <jm@mayfirst.org>
8 # Daniel Kahn Gillmor <dkg@fifthhorseman.net>
9 # Micah Anderson <micah@riseup.net>
10 #
11 # They are Copyright 2008-2009, and are all released under the GPL,
12 # version 3 or later.
13
14 ########################################################################
15 set -e
16
17 PGRM=$(basename $0)
18
19 SYSSHAREDIR=${MONKEYSPHERE_SYSSHAREDIR:-"/usr/share/monkeysphere"}
20 export SYSSHAREDIR
21 . "${SYSSHAREDIR}/common" || exit 1
22
23 SYSDATADIR=${MONKEYSPHERE_SYSDATADIR:-"/var/lib/monkeysphere"}
24 export SYSDATADIR
25
26 # sharedir for host functions
27 MHSHAREDIR="${SYSSHAREDIR}/mh"
28
29 # datadir for host functions
30 MHDATADIR="${SYSDATADIR}/host"
31
32 # UTC date in ISO 8601 format if needed
33 DATE=$(date -u '+%FT%T')
34
35 # unset some environment variables that could screw things up
36 unset GREP_OPTIONS
37
38 # default return code
39 RETURN=0
40
41 ########################################################################
42 # FUNCTIONS
43 ########################################################################
44
45 usage() {
46     cat <<EOF >&2
47 usage: $PGRM <subcommand> [options] [args]
48 Monkeysphere host admin tool.
49
50 subcommands:
51  show-key (s)                        output all host key information
52  set-expire (e) EXPIRE               set host key expiration
53  add-hostname (n+) NAME[:PORT]       add hostname user ID to host key
54  revoke-hostname (n-) NAME[:PORT]    revoke hostname user ID
55  add-revoker (o) FINGERPRINT         add a revoker to the host key
56  revoke-key (r)                      revoke host key
57  publish-key (p)                     publish host key to keyserver
58
59  expert <expert-subcommand>          run expert command
60  expert help                         expert command help
61
62  version (v)                         show version number
63  help (h,?)                          this help
64
65 EOF
66 }
67
68 # function to run command as monkeysphere user
69 su_monkeysphere_user() {
70     # if the current user is the monkeysphere user, then just eval
71     # command
72     if [ $(id -un) = "$MONKEYSPHERE_USER" ] ; then
73         eval "$@"
74
75     # otherwise su command as monkeysphere user
76     else
77         su "$MONKEYSPHERE_USER" -c "$@"
78     fi
79 }
80
81 # function to interact with the gpg keyring
82 gpg_host() {
83     GNUPGHOME="$GNUPGHOME_HOST" gpg "$@"
84 }
85
86 # command to list the info about the host key, in colon format
87 gpg_host_list() {
88     gpg_host --list-keys --with-colons --fixed-list-mode \
89         --with-fingerprint --with-fingerprint \
90         "0x${HOST_FINGERPRINT}!"
91
92 }
93
94 # command for edit key scripts, takes scripts on stdin
95 gpg_host_edit() {
96     gpg_host --quiet --command-fd 0 --edit-key \
97         "0x${HOST_FINGERPRINT}!" "$@"
98 }
99
100 # output just key fingerprint
101 fingerprint_host_key() {
102     # set the pipefail option so functions fails if can't read sec key
103     set -o pipefail
104
105     gpg_host --list-secret-keys --fingerprint \
106         --with-colons --fixed-list-mode 2> /dev/null | \
107         grep '^fpr:' | head -1 | cut -d: -f10 2>/dev/null
108 }
109
110 # output the index of a user ID on the host key
111 # return 1 if user ID not found
112 find_host_userid() {
113     local userID="$1"
114     local tmpuidMatch
115     local line
116
117     # match to only ultimately trusted user IDs
118     tmpuidMatch="u:$(echo $userID | gpg_escape)"
119
120     # find the index of the requsted user ID
121     # NOTE: this is based on circumstantial evidence that the order of
122     # this output is the appropriate index
123     line=$(gpg_host_list | egrep '^(uid|uat):' | cut -f2,10 -d: | \
124         grep -n -x -F "$tmpuidMatch" 2>/dev/null)
125
126     if [ "$line" ] ; then
127         echo ${line%%:*}
128         return 0
129     else
130         return 1
131     fi
132 }
133
134 # function to check for host secret key
135 check_host_fail() {
136     [ "$HOST_FINGERPRINT" ] || \
137         failure "You don't appear to have a Monkeysphere host key on this server.  Please run 'monkeysphere-host expert import-key' first."
138 }
139
140 # show info about the host key
141 show_key() {
142     local fingerprintSSH
143
144     # FIXME: should not have to be priviledged user to see this info.
145     # should be taken from publicly accessible key files, instead of
146     # the keyring.
147
148     gpg_host --fingerprint --list-key --list-options show-unusable-uids \
149         "0x${HOST_FINGERPRINT}!" 2>/dev/null
150
151     echo "OpenPGP fingerprint: $HOST_FINGERPRINT"
152
153     if [ -f "${MHDATADIR}/ssh_host_rsa_key.pub" ] ; then
154         fingerprintSSH=$(ssh-keygen -l -f "${MHDATADIR}/ssh_host_rsa_key.pub" | \
155             awk '{ print $1, $2, $4 }')
156         echo "ssh fingerprint: $fingerprintSSH"
157     else
158         log info "SSH host key not found."
159     fi
160
161     # FIXME: show expiration date
162     # FIXME: other relevant key parameters?
163 }
164
165 ########################################################################
166 # MAIN
167 ########################################################################
168
169 # unset variables that should be defined only in config file
170 unset KEYSERVER
171 unset MONKEYSPHERE_USER
172
173 # load configuration file
174 [ -e ${MONKEYSPHERE_HOST_CONFIG:="${SYSCONFIGDIR}/monkeysphere-host.conf"} ] && . "$MONKEYSPHERE_HOST_CONFIG"
175
176 # set empty config variable with ones from the environment, or with
177 # defaults
178 LOG_LEVEL=${MONKEYSPHERE_LOG_LEVEL:=${LOG_LEVEL:="INFO"}}
179 KEYSERVER=${MONKEYSPHERE_KEYSERVER:=${KEYSERVER:="pool.sks-keyservers.net"}}
180 AUTHORIZED_USER_IDS=${MONKEYSPHERE_AUTHORIZED_USER_IDS:=${AUTHORIZED_USER_IDS:="%h/.monkeysphere/authorized_user_ids"}}
181 RAW_AUTHORIZED_KEYS=${MONKEYSPHERE_RAW_AUTHORIZED_KEYS:=${RAW_AUTHORIZED_KEYS:="%h/.ssh/authorized_keys"}}
182 MONKEYSPHERE_USER=${MONKEYSPHERE_MONKEYSPHERE_USER:=${MONKEYSPHERE_USER:="monkeysphere"}}
183
184 # other variables
185 CHECK_KEYSERVER=${MONKEYSPHERE_CHECK_KEYSERVER:="true"}
186 GNUPGHOME_HOST=${MONKEYSPHERE_GNUPGHOME_HOST:="${MHDATADIR}"}
187
188 # host key fingerprint
189 HOST_FINGERPRINT=$(fingerprint_host_key)
190
191 # export variables needed in su invocation
192 export DATE
193 export MODE
194 export LOG_LEVEL
195 export MONKEYSPHERE_USER
196 export KEYSERVER
197 export GNUPGHOME_HOST
198 export GNUPGHOME
199 export HOST_FINGERPRINT
200
201 # get subcommand
202 COMMAND="$1"
203 [ "$COMMAND" ] || failure "Type '$PGRM help' for usage."
204 shift
205
206
207 case $COMMAND in
208     'show-key'|'show'|'s')
209         check_host_keyring
210         show_key
211         ;;
212
213     'set-expire'|'extend-key'|'e')
214         check_host_keyring
215         source "${MHSHAREDIR}/set_expire"
216         set_expire "$@"
217         ;;
218
219     'add-hostname'|'add-name'|'n+')
220         check_host_keyring
221         source "${MHSHAREDIR}/add_hostname"
222         add_hostname "$@"
223         ;;
224
225     'revoke-hostname'|'revoke-name'|'n-')
226         check_host_keyring
227         source "${MHSHAREDIR}/revoke_hostname"
228         revoke_hostname "$@"
229         ;;
230
231     'add-revoker'|'o')
232         check_host_keyring
233         source "${MHSHAREDIR}/add_revoker"
234         add_revoker "$@"
235         ;;
236
237     'revoke-key'|'r')
238         check_host_keyring
239         source "${MHSHAREDIR}/revoke_key"
240         revoke_key "$@"
241         ;;
242
243     'publish-key'|'publish'|'p')
244         check_host_keyring
245         source "${MHSHAREDIR}/publish_key"
246         publish_key
247         ;;
248
249     'expert')
250         SUBCOMMAND="$1"
251         shift
252         case "$SUBCOMMAND" in
253             'help'|'h'|'?')
254                 cat <<EOF
255 usage: $PGRM expert <subcommand> [options] [args]
256
257 expert subcommands:
258  import-key (i) [NAME[:PORT]]        import existing ssh key to gpg
259  gen-key (g) [NAME[:PORT]]           generate gpg key for the host
260    --length (-l) BITS                  key length in bits (2048)
261  diagnostics (d)                     monkeysphere host status
262
263 EOF
264                 ;;
265
266             'import-key'|'i')
267                 source "${MHSHAREDIR}/import_key"
268                 import_key "$@"
269                 ;;
270
271             'gen-key'|'g')
272                 source "${MHSHAREDIR}/gen_key"
273                 gen_key "$@"
274                 ;;
275
276             'diagnostics'|'d')
277                 source "${MHSHAREDIR}/diagnostics"
278                 diagnostics
279                 ;;
280
281             *)
282                 failure "Unknown expert subcommand: '$COMMAND'
283 Type '$PGRM help' for usage."
284                 ;;
285         esac
286         ;;
287
288     'version'|'v')
289         echo "$VERSION"
290         ;;
291
292     '--help'|'help'|'-h'|'h'|'?')
293         usage
294         ;;
295
296     *)
297         failure "Unknown command: '$COMMAND'
298 Type '$PGRM help' for usage."
299         ;;
300 esac
301
302 exit "$RETURN"