Merge commit 'mjgoins/master'
[monkeysphere.git] / src / monkeysphere
1 #!/usr/bin/env bash
2
3 # monkeysphere: Monkeysphere client 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 # Micah Anderson <micah@riseup.net>
10 #
11 # They are Copyright 2008-2009, and are all released under the GPL, version 3
12 # or later.
13
14 ########################################################################
15 PGRM=$(basename $0)
16
17 SYSSHAREDIR=${MONKEYSPHERE_SYSSHAREDIR:-"/usr/share/monkeysphere"}
18 export SYSSHAREDIR
19 . "${SYSSHAREDIR}/common" || exit 1
20
21 # sharedir for host functions
22 MSHAREDIR="${SYSSHAREDIR}/m"
23
24 # UTC date in ISO 8601 format if needed
25 DATE=$(date -u '+%FT%T')
26
27 # unset some environment variables that could screw things up
28 unset GREP_OPTIONS
29
30 # default return code
31 RETURN=0
32
33 # set the file creation mask to be only owner rw
34 umask 077
35
36 ########################################################################
37 # FUNCTIONS
38 ########################################################################
39
40 usage() {
41     cat <<EOF >&2
42 usage: $PGRM <subcommand> [options] [args]
43 Monkeysphere client tool.
44
45 subcommands:
46  update-known_hosts (k) [HOST]...    update known_hosts file
47  update-authorized_keys (a)          update authorized_keys file
48  import-subkey (i)                   import existing ssh key as gpg subkey
49    --keyfile (-f) FILE                 key file to import
50    --expire (-e) EXPIRE                date to expire
51  gen-subkey (g) [KEYID]              generate an authentication subkey
52    --length (-l) BITS                  key length in bits (2048)
53    --expire (-e) EXPIRE                date to expire
54  ssh-proxycommand                    ssh proxycommand
55  subkey-to-ssh-agent (s)             store authentication subkey in ssh-agent
56  version (v)                         show version number
57  help (h,?)                          this help
58
59 EOF
60 }
61
62 ########################################################################
63 # MAIN
64 ########################################################################
65
66 # unset variables that should be defined only in config file
67 unset KEYSERVER
68 unset CHECK_KEYSERVER
69 unset KNOWN_HOSTS
70 unset HASH_KNOWN_HOSTS
71 unset AUTHORIZED_KEYS
72
73 # load global config
74 [ -r "${SYSCONFIGDIR}/monkeysphere.conf" ] && . "${SYSCONFIGDIR}/monkeysphere.conf"
75
76 # set monkeysphere home directory
77 MONKEYSPHERE_HOME=${MONKEYSPHERE_HOME:="${HOME}/.monkeysphere"}
78 mkdir -p -m 0700 "$MONKEYSPHERE_HOME"
79
80 # load local config
81 [ -e ${MONKEYSPHERE_CONFIG:="${MONKEYSPHERE_HOME}/monkeysphere.conf"} ] && . "$MONKEYSPHERE_CONFIG"
82
83 # set empty config variables with ones from the environment, or from
84 # config file, or with defaults
85 LOG_LEVEL=${MONKEYSPHERE_LOG_LEVEL:=${LOG_LEVEL:="INFO"}}
86 GNUPGHOME=${MONKEYSPHERE_GNUPGHOME:=${GNUPGHOME:="${HOME}/.gnupg"}}
87 KEYSERVER=${MONKEYSPHERE_KEYSERVER:="$KEYSERVER"}
88 # if keyserver not specified in env or monkeysphere.conf,
89 # look in gpg.conf
90 if [ -z "$KEYSERVER" ] ; then
91     if [ -f "${GNUPGHOME}/gpg.conf" ] ; then
92         KEYSERVER=$(grep -e "^[[:space:]]*keyserver " "${GNUPGHOME}/gpg.conf" | tail -1 | awk '{ print $2 }')
93     fi
94 fi
95 # if it's still not specified, use the default
96 KEYSERVER=${KEYSERVER:="subkeys.pgp.net"}
97 CHECK_KEYSERVER=${MONKEYSPHERE_CHECK_KEYSERVER:=${CHECK_KEYSERVER:="true"}}
98 KNOWN_HOSTS=${MONKEYSPHERE_KNOWN_HOSTS:=${KNOWN_HOSTS:="${HOME}/.ssh/known_hosts"}}
99 HASH_KNOWN_HOSTS=${MONKEYSPHERE_HASH_KNOWN_HOSTS:=${HASH_KNOWN_HOSTS:="true"}}
100 AUTHORIZED_KEYS=${MONKEYSPHERE_AUTHORIZED_KEYS:=${AUTHORIZED_KEYS:="${HOME}/.ssh/authorized_keys"}}
101
102 # other variables not in config file
103 AUTHORIZED_USER_IDS=${MONKEYSPHERE_AUTHORIZED_USER_IDS:="${MONKEYSPHERE_HOME}/authorized_user_ids"}
104 REQUIRED_HOST_KEY_CAPABILITY=${MONKEYSPHERE_REQUIRED_HOST_KEY_CAPABILITY:="a"}
105 REQUIRED_USER_KEY_CAPABILITY=${MONKEYSPHERE_REQUIRED_USER_KEY_CAPABILITY:="a"}
106
107 # export GNUPGHOME and make sure gpg home exists with proper
108 # permissions
109 export GNUPGHOME
110 mkdir -p -m 0700 "$GNUPGHOME"
111 export LOG_LEVEL
112
113 # get subcommand
114 COMMAND="$1"
115 [ "$COMMAND" ] || failure "Type '$PGRM help' for usage."
116 shift
117
118 case $COMMAND in
119     'update-known_hosts'|'update-known-hosts'|'k')
120         MODE='known_hosts'
121
122         # touch the known_hosts file so that the file permission check
123         # below won't fail upon not finding the file
124         (umask 0022 && touch "$KNOWN_HOSTS")
125
126         # check permissions on the known_hosts file path
127         check_key_file_permissions "$USER" "$KNOWN_HOSTS" || failure
128
129         # if hosts are specified on the command line, process just
130         # those hosts
131         if [ "$1" ] ; then
132             update_known_hosts "$@"
133             RETURN="$?"
134
135         # otherwise, if no hosts are specified, process every host
136         # in the user's known_hosts file
137         else
138             # exit if the known_hosts file does not exist
139             if [ ! -e "$KNOWN_HOSTS" ] ; then
140                 log error "known_hosts file '$KNOWN_HOSTS' does not exist."
141                 exit
142             fi
143
144             process_known_hosts
145             RETURN="$?"
146         fi
147         ;;
148
149     'update-authorized_keys'|'update-authorized-keys'|'a')
150         MODE='authorized_keys'
151
152         # check permissions on the authorized_user_ids file path
153         check_key_file_permissions "$USER" "$AUTHORIZED_USER_IDS" || failure
154
155         # check permissions on the authorized_keys file path
156         check_key_file_permissions "$USER" "$AUTHORIZED_KEYS" || failure
157
158         # exit if the authorized_user_ids file is empty
159         if [ ! -e "$AUTHORIZED_USER_IDS" ] ; then
160             log error "authorized_user_ids file '$AUTHORIZED_USER_IDS' does not exist."
161             exit
162         fi
163
164         # process authorized_user_ids file
165         process_authorized_user_ids "$AUTHORIZED_USER_IDS"
166         RETURN="$?"
167         ;;
168
169     'import-subkey'|'i')
170         source "${MSHAREDIR}/import_subkey"
171         import_subkey "$@"
172         ;;
173
174     'gen-subkey'|'g')
175         source "${MSHAREDIR}/gen_subkey"
176         gen_subkey "$@"
177         ;;
178
179     'ssh-proxycommand'|'p')
180         source "${MSHAREDIR}/ssh_proxycommand"
181         ssh_proxycommand "$@"
182         ;;
183
184     'subkey-to-ssh-agent'|'s')
185         source "${MSHAREDIR}/subkey_to_ssh_agent"
186         subkey_to_ssh_agent "$@"
187         ;;
188
189     'version'|'v')
190         echo "$VERSION"
191         ;;
192
193     '--help'|'help'|'-h'|'h'|'?')
194         usage
195         ;;
196
197     *)
198         failure "Unknown command: '$COMMAND'
199 Type '$PGRM help' for usage."
200         ;;
201 esac
202
203 exit "$RETURN"