merging jrollins and micah work, reverting ui changes for m-h gen-key and import-key
[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 ########################################################################
138 # MAIN
139 ########################################################################
140
141 # unset variables that should be defined only in config file
142 unset KEYSERVER
143 unset AUTHORIZED_USER_IDS
144 unset RAW_AUTHORIZED_KEYS
145 unset MONKEYSPHERE_USER
146
147 # load configuration file
148 [ -e ${MONKEYSPHERE_SERVER_CONFIG:="${SYSCONFIGDIR}/monkeysphere-server.conf"} ] && . "$MONKEYSPHERE_SERVER_CONFIG"
149
150 # set empty config variable with ones from the environment, or with
151 # defaults
152 LOG_LEVEL=${MONKEYSPHERE_LOG_LEVEL:=${LOG_LEVEL:="INFO"}}
153 KEYSERVER=${MONKEYSPHERE_KEYSERVER:=${KEYSERVER:="pool.sks-keyservers.net"}}
154 AUTHORIZED_USER_IDS=${MONKEYSPHERE_AUTHORIZED_USER_IDS:=${AUTHORIZED_USER_IDS:="%h/.monkeysphere/authorized_user_ids"}}
155 RAW_AUTHORIZED_KEYS=${MONKEYSPHERE_RAW_AUTHORIZED_KEYS:=${RAW_AUTHORIZED_KEYS:="%h/.ssh/authorized_keys"}}
156 MONKEYSPHERE_USER=${MONKEYSPHERE_MONKEYSPHERE_USER:=${MONKEYSPHERE_USER:="monkeysphere"}}
157
158 # other variables
159 CHECK_KEYSERVER=${MONKEYSPHERE_CHECK_KEYSERVER:="true"}
160 REQUIRED_USER_KEY_CAPABILITY=${MONKEYSPHERE_REQUIRED_USER_KEY_CAPABILITY:="a"}
161 GNUPGHOME_HOST=${MONKEYSPHERE_GNUPGHOME_HOST:="${SYSDATADIR}/gnupg-host"}
162 GNUPGHOME_AUTHENTICATION=${MONKEYSPHERE_GNUPGHOME_AUTHENTICATION:="${SYSDATADIR}/gnupg-authentication"}
163
164 # export variables needed in su invocation
165 export DATE
166 export MODE
167 export MONKEYSPHERE_USER
168 export LOG_LEVEL
169 export KEYSERVER
170 export CHECK_KEYSERVER
171 export REQUIRED_USER_KEY_CAPABILITY
172 export GNUPGHOME_HOST
173 export GNUPGHOME_AUTHENTICATION
174 export GNUPGHOME
175
176 # get subcommand
177 COMMAND="$1"
178 [ "$COMMAND" ] || failure "Type '$PGRM help' for usage."
179 shift
180
181 case $COMMAND in
182     'update-users'|'update-user'|'u')
183         check_user
184         check_host_keyring
185         update_users "$@"
186         ;;
187
188     'add-identity-certifier'|'add-id-certifier'|'add-certifier'|'c+')
189         check_user
190         check_host_keyring
191         add_certifier "$@"
192         ;;
193
194     'remove-identity-certifier'|'remove-id-certifier'|'remove-certifier'|'c-')
195         check_user
196         check_host_keyring
197         remove_certifier "$@"
198         ;;
199
200     'list-identity-certifiers'|'list-id-certifiers'|'list-certifiers'|'list-certifier'|'c')
201         check_user
202         check_host_keyring
203         list_certifiers "$@"
204         ;;
205
206     'expert'|'e')
207         check_user
208         SUBCOMMAND="$1"
209         shift
210         case "$SUBCOMMAND" in
211             'diagnostics'|'d')
212                 diagnostics
213                 ;;
214
215             'gpg-cmd')
216                 gpg_authentication "$@"
217                 ;;
218
219             *)
220                 failure "Unknown expert subcommand: '$COMMAND'
221 Type '$PGRM help' for usage."
222                 ;;
223         esac
224         ;;
225
226     'version'|'v')
227         echo "$VERSION"
228         ;;
229
230     '--help'|'help'|'-h'|'h'|'?')
231         usage
232         ;;
233
234     *)
235         failure "Unknown command: '$COMMAND'
236 Type '$PGRM help' for usage."
237         ;;
238 esac
239
240 exit "$RETURN"