/mandos/trunk

To get this branch, use:
bzr branch http://bzr.recompile.se/loggerhead/mandos/trunk
73 by Teddy Hogeborn
* Makefile (COVERAGE): Change back to "--coverage".
1
#!/bin/sh -e
67 by Teddy Hogeborn
* mandos-keygen: New program to generate new client keys on
2
# 
73 by Teddy Hogeborn
* Makefile (COVERAGE): Change back to "--coverage".
3
# Mandos key generator - create a new OpenPGP key for a Mandos client
67 by Teddy Hogeborn
* mandos-keygen: New program to generate new client keys on
4
# 
24.1.102 by Björn Påhlsson
changed 2007-2008 copyright notice to 2008
5
# Copyright © 2008 Teddy Hogeborn & Björn Påhlsson
67 by Teddy Hogeborn
* mandos-keygen: New program to generate new client keys on
6
# 
7
# This program is free software: you can redistribute it and/or modify
8
# it under the terms of the GNU General Public License as published by
9
# the Free Software Foundation, either version 3 of the License, or
10
# (at your option) any later version.
11
#
12
#     This program is distributed in the hope that it will be useful,
13
#     but WITHOUT ANY WARRANTY; without even the implied warranty of
14
#     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
#     GNU General Public License for more details.
16
# 
17
# You should have received a copy of the GNU General Public License
18
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
# 
20
# Contact the authors at <mandos@fukt.bsnet.se>.
21
# 
22
73 by Teddy Hogeborn
* Makefile (COVERAGE): Change back to "--coverage".
23
VERSION="1.0"
24
163 by Teddy Hogeborn
* Makefile (PIDDIR, USER, GROUP): Removed.
25
KEYDIR="/etc/keys/mandos"
67 by Teddy Hogeborn
* mandos-keygen: New program to generate new client keys on
26
KEYTYPE=DSA
104 by Teddy Hogeborn
* Makefile (maintainer-clean): Also remove "confdir".
27
KEYLENGTH=2048
96 by Teddy Hogeborn
* Makefile (PREFIX, CONFDIR, MANDIR): Use $(DESTDIR).
28
SUBKEYTYPE=ELG-E
29
SUBKEYLENGTH=2048
196 by Teddy Hogeborn
* mandos-keygen (KEYNAME): Fall back to plain "hostname" if the
30
KEYNAME="`hostname --fqdn 2>/dev/null || hostname`"
67 by Teddy Hogeborn
* mandos-keygen: New program to generate new client keys on
31
KEYEMAIL=""
32
KEYCOMMENT="Mandos client key"
33
KEYEXPIRE=0
34
FORCE=no
35
KEYCOMMENT_ORIG="$KEYCOMMENT"
97 by Teddy Hogeborn
* mandos-keygen: Bug fix: Recognize new options --subtype and
36
mode=keygen
67 by Teddy Hogeborn
* mandos-keygen: New program to generate new client keys on
37
179 by Teddy Hogeborn
* INSTALL: New file.
38
if [ ! -d "$KEYDIR" ]; then
39
    KEYDIR="/etc/mandos/keys"
40
fi
41
67 by Teddy Hogeborn
* mandos-keygen: New program to generate new client keys on
42
# Parse options
198 by Teddy Hogeborn
* mandos-keygen: New "--passfile" option. Confirm entered password.
43
TEMP=`getopt --options vhpF:d:t:l:s:L:n:e:c:x:f \
44
    --longoptions version,help,password,passfile:,dir:,type:,length:,subtype:,sublength:,name:,email:,comment:,expire:,force \
67 by Teddy Hogeborn
* mandos-keygen: New program to generate new client keys on
45
    --name "$0" -- "$@"`
46
73 by Teddy Hogeborn
* Makefile (COVERAGE): Change back to "--coverage".
47
help(){
97 by Teddy Hogeborn
* mandos-keygen: Bug fix: Recognize new options --subtype and
48
basename="`basename $0`"
73 by Teddy Hogeborn
* Makefile (COVERAGE): Change back to "--coverage".
49
cat <<EOF
97 by Teddy Hogeborn
* mandos-keygen: Bug fix: Recognize new options --subtype and
50
Usage: $basename [ -v | --version ]
51
       $basename [ -h | --help ]
52
   Key creation:
53
       $basename [ OPTIONS ]
54
   Encrypted password creation:
55
       $basename { -p | --password } [ --name NAME ] [ --dir DIR]
198 by Teddy Hogeborn
* mandos-keygen: New "--passfile" option. Confirm entered password.
56
       $basename { -F | --passfile } FILE [ --name NAME ] [ --dir DIR]
73 by Teddy Hogeborn
* Makefile (COVERAGE): Change back to "--coverage".
57
97 by Teddy Hogeborn
* mandos-keygen: Bug fix: Recognize new options --subtype and
58
Key creation options:
73 by Teddy Hogeborn
* Makefile (COVERAGE): Change back to "--coverage".
59
  -v, --version         Show program's version number and exit
60
  -h, --help            Show this help message and exit
61
  -d DIR, --dir DIR     Target directory for key files
62
  -t TYPE, --type TYPE  Key type.  Default is DSA.
63
  -l BITS, --length BITS
104 by Teddy Hogeborn
* Makefile (maintainer-clean): Also remove "confdir".
64
                        Key length in bits.  Default is 2048.
96 by Teddy Hogeborn
* Makefile (PREFIX, CONFDIR, MANDIR): Use $(DESTDIR).
65
  -s TYPE, --subtype TYPE
66
                        Subkey type.  Default is ELG-E.
67
  -L BITS, --sublength BITS
68
                        Subkey length in bits.  Default is 2048.
73 by Teddy Hogeborn
* Makefile (COVERAGE): Change back to "--coverage".
69
  -n NAME, --name NAME  Name of key.  Default is the FQDN.
97 by Teddy Hogeborn
* mandos-keygen: Bug fix: Recognize new options --subtype and
70
  -e ADDRESS, --email ADDRESS
73 by Teddy Hogeborn
* Makefile (COVERAGE): Change back to "--coverage".
71
                        Email address of key.  Default is empty.
123 by Teddy Hogeborn
* mandos-keygen: Minor help text change.
72
  -c TEXT, --comment TEXT
73 by Teddy Hogeborn
* Makefile (COVERAGE): Change back to "--coverage".
73
                        Comment field for key.  The default value is
74
                        "Mandos client key".
75
  -x TIME, --expire TIME
76
                        Key expire time.  Default is no expiration.
77
                        See gpg(1) for syntax.
198 by Teddy Hogeborn
* mandos-keygen: New "--passfile" option. Confirm entered password.
78
  -f, --force           Force overwriting old key files.
97 by Teddy Hogeborn
* mandos-keygen: Bug fix: Recognize new options --subtype and
79
80
Password creation options:
198 by Teddy Hogeborn
* mandos-keygen: New "--passfile" option. Confirm entered password.
81
  -p, --password        Create an encrypted password using the key in
82
                        the key directory.  All options other than
83
                        --dir and --name are ignored.
84
  -F FILE, --passfile FILE
85
                        Encrypt a password from FILE using the key in
97 by Teddy Hogeborn
* mandos-keygen: Bug fix: Recognize new options --subtype and
86
                        the key directory.  All options other than
123 by Teddy Hogeborn
* mandos-keygen: Minor help text change.
87
                        --dir and --name are ignored.
73 by Teddy Hogeborn
* Makefile (COVERAGE): Change back to "--coverage".
88
EOF
89
}
90
67 by Teddy Hogeborn
* mandos-keygen: New program to generate new client keys on
91
eval set -- "$TEMP"
92
while :; do
93
    case "$1" in
97 by Teddy Hogeborn
* mandos-keygen: Bug fix: Recognize new options --subtype and
94
	-p|--password) mode=password; shift;;
198 by Teddy Hogeborn
* mandos-keygen: New "--passfile" option. Confirm entered password.
95
	-F|--passfile) mode=password; PASSFILE="$2"; shift 2;;
67 by Teddy Hogeborn
* mandos-keygen: New program to generate new client keys on
96
	-d|--dir) KEYDIR="$2"; shift 2;;
97
	-t|--type) KEYTYPE="$2"; shift 2;;
96 by Teddy Hogeborn
* Makefile (PREFIX, CONFDIR, MANDIR): Use $(DESTDIR).
98
	-s|--subtype) SUBKEYTYPE="$2"; shift 2;;
67 by Teddy Hogeborn
* mandos-keygen: New program to generate new client keys on
99
	-l|--length) KEYLENGTH="$2"; shift 2;;
96 by Teddy Hogeborn
* Makefile (PREFIX, CONFDIR, MANDIR): Use $(DESTDIR).
100
	-L|--sublength) SUBKEYLENGTH="$2"; shift 2;;
67 by Teddy Hogeborn
* mandos-keygen: New program to generate new client keys on
101
	-n|--name) KEYNAME="$2"; shift 2;;
102
	-e|--email) KEYEMAIL="$2"; shift 2;;
103
	-c|--comment) KEYCOMMENT="$2"; shift 2;;
87 by Teddy Hogeborn
* Makefile: Bug fix: fixed creation of man pages in "plugins.d".
104
	-x|--expire) KEYEXPIRE="$2"; shift 2;;
67 by Teddy Hogeborn
* mandos-keygen: New program to generate new client keys on
105
	-f|--force) FORCE=yes; shift;;
73 by Teddy Hogeborn
* Makefile (COVERAGE): Change back to "--coverage".
106
	-v|--version) echo "$0 $VERSION"; exit;;
107
	-h|--help) help; exit;;
67 by Teddy Hogeborn
* mandos-keygen: New program to generate new client keys on
108
	--) shift; break;;
109
	*) echo "Internal error" >&2; exit 1;;
110
    esac
111
done
112
if [ "$#" -gt 0 ]; then
113
    echo "Unknown arguments: '$@'" >&2
114
    exit 1
115
fi
116
117
SECKEYFILE="$KEYDIR/seckey.txt"
118
PUBKEYFILE="$KEYDIR/pubkey.txt"
119
120
# Check for some invalid values
159 by Teddy Hogeborn
* Makefile (run-client): Do not depend on the key ring files.
121
if [ ! -d "$KEYDIR" ]; then
67 by Teddy Hogeborn
* mandos-keygen: New program to generate new client keys on
122
    echo "$KEYDIR not a directory" >&2
123
    exit 1
124
fi
159 by Teddy Hogeborn
* Makefile (run-client): Do not depend on the key ring files.
125
if [ ! -r "$KEYDIR" ]; then
126
    echo "Directory $KEYDIR not readable" >&2
97 by Teddy Hogeborn
* mandos-keygen: Bug fix: Recognize new options --subtype and
127
    exit 1
128
fi
129
130
if [ "$mode" = keygen ]; then
159 by Teddy Hogeborn
* Makefile (run-client): Do not depend on the key ring files.
131
    if [ ! -w "$KEYDIR" ]; then
132
	echo "Directory $KEYDIR not writeable" >&2
133
	exit 1
134
    fi
97 by Teddy Hogeborn
* mandos-keygen: Bug fix: Recognize new options --subtype and
135
    if [ -z "$KEYTYPE" ]; then
136
	echo "Empty key type" >&2
137
	exit 1
138
    fi
139
    
140
    if [ -z "$KEYNAME" ]; then
141
	echo "Empty key name" >&2
142
	exit 1
143
    fi
144
    
145
    if [ -z "$KEYLENGTH" ] || [ "$KEYLENGTH" -lt 512 ]; then
146
	echo "Invalid key length" >&2
147
	exit 1
148
    fi
149
150
    if [ -z "$KEYEXPIRE" ]; then
151
	echo "Empty key expiration" >&2
152
	exit 1
153
    fi
154
    
155
    # Make FORCE be 0 or 1
156
    case "$FORCE" in
157
	[Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]) FORCE=1;;
158
	[Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|*) FORCE=0;;
159
    esac
160
    
168 by Teddy Hogeborn
* initramfs-tools-hook: Use long options where available. Use only
161
    if [ \( -e "$SECKEYFILE" -o -e "$PUBKEYFILE" \) \
162
	-a "$FORCE" -eq 0 ]; then
97 by Teddy Hogeborn
* mandos-keygen: Bug fix: Recognize new options --subtype and
163
	echo "Refusing to overwrite old key files; use --force" >&2
164
	exit 1
165
    fi
166
    
167
    # Set lines for GnuPG batch file
168
    if [ -n "$KEYCOMMENT" ]; then
169
	KEYCOMMENTLINE="Name-Comment: $KEYCOMMENT"
170
    fi
171
    if [ -n "$KEYEMAIL" ]; then
172
	KEYEMAILLINE="Name-Email: $KEYEMAIL"
173
    fi
174
175
    # Create temporary gpg batch file
159 by Teddy Hogeborn
* Makefile (run-client): Do not depend on the key ring files.
176
    BATCHFILE="`mktemp -t mandos-keygen-batch.XXXXXXXXXX`"
97 by Teddy Hogeborn
* mandos-keygen: Bug fix: Recognize new options --subtype and
177
fi
178
179
if [ "$mode" = password ]; then
180
    # Create temporary encrypted password file
159 by Teddy Hogeborn
* Makefile (run-client): Do not depend on the key ring files.
181
    SECFILE="`mktemp -t mandos-keygen-secfile.XXXXXXXXXX`"
182
fi
183
184
# Create temporary key ring directory
185
RINGDIR="`mktemp -d -t mandos-keygen-keyrings.XXXXXXXXXX`"
97 by Teddy Hogeborn
* mandos-keygen: Bug fix: Recognize new options --subtype and
186
73 by Teddy Hogeborn
* Makefile (COVERAGE): Change back to "--coverage".
187
# Remove temporary files on exit
94 by Teddy Hogeborn
* clients.conf ([DEFAULT]/checker): Update to new default value.
188
trap "
96 by Teddy Hogeborn
* Makefile (PREFIX, CONFDIR, MANDIR): Use $(DESTDIR).
189
set +e; \
159 by Teddy Hogeborn
* Makefile (run-client): Do not depend on the key ring files.
190
test -n \"$SECFILE\" && shred --remove \"$SECFILE\"; \
191
shred --remove \"$RINGDIR\"/sec*;
192
test -n \"$BATCHFILE\" && rm --force \"$BATCHFILE\"; \
193
rm --recursive --force \"$RINGDIR\";
96 by Teddy Hogeborn
* Makefile (PREFIX, CONFDIR, MANDIR): Use $(DESTDIR).
194
stty echo; \
94 by Teddy Hogeborn
* clients.conf ([DEFAULT]/checker): Update to new default value.
195
" EXIT
67 by Teddy Hogeborn
* mandos-keygen: New program to generate new client keys on
196
166 by Teddy Hogeborn
* Makefile (confdir/clients.conf): Tighten permissions to "u=rw".
197
umask 077
73 by Teddy Hogeborn
* Makefile (COVERAGE): Change back to "--coverage".
198
97 by Teddy Hogeborn
* mandos-keygen: Bug fix: Recognize new options --subtype and
199
if [ "$mode" = keygen ]; then
200
    # Create batch file for GnuPG
201
    cat >"$BATCHFILE" <<-EOF
202
	Key-Type: $KEYTYPE
203
	Key-Length: $KEYLENGTH
204
	#Key-Usage: encrypt,sign,auth
205
	Subkey-Type: $SUBKEYTYPE
206
	Subkey-Length: $SUBKEYLENGTH
207
	#Subkey-Usage: encrypt,sign,auth
208
	Name-Real: $KEYNAME
209
	$KEYCOMMENTLINE
210
	$KEYEMAILLINE
211
	Expire-Date: $KEYEXPIRE
212
	#Preferences: <string>
213
	#Handle: <no-spaces>
159 by Teddy Hogeborn
* Makefile (run-client): Do not depend on the key ring files.
214
	#%pubring pubring.gpg
215
	#%secring secring.gpg
97 by Teddy Hogeborn
* mandos-keygen: Bug fix: Recognize new options --subtype and
216
	%commit
217
	EOF
218
    
219
    # Generate a new key in the key rings
159 by Teddy Hogeborn
* Makefile (run-client): Do not depend on the key ring files.
220
    gpg --quiet --batch --no-tty --no-options --enable-dsa2 \
221
	--homedir "$RINGDIR" --trust-model always \
97 by Teddy Hogeborn
* mandos-keygen: Bug fix: Recognize new options --subtype and
222
	--gen-key "$BATCHFILE"
223
    rm --force "$BATCHFILE"
159 by Teddy Hogeborn
* Makefile (run-client): Do not depend on the key ring files.
224
    
97 by Teddy Hogeborn
* mandos-keygen: Bug fix: Recognize new options --subtype and
225
    # Backup any old key files
226
    if cp --backup=numbered --force "$SECKEYFILE" "$SECKEYFILE" \
227
	2>/dev/null; then
228
	shred --remove "$SECKEYFILE"
229
    fi
230
    if cp --backup=numbered --force "$PUBKEYFILE" "$PUBKEYFILE" \
231
	2>/dev/null; then
232
	rm --force "$PUBKEYFILE"
233
    fi
234
    
235
    FILECOMMENT="Mandos client key for $KEYNAME"
236
    if [ "$KEYCOMMENT" != "$KEYCOMMENT_ORIG" ]; then
237
	FILECOMMENT="$FILECOMMENT ($KEYCOMMENT)"
238
    fi
239
    
240
    if [ -n "$KEYEMAIL" ]; then
241
	FILECOMMENT="$FILECOMMENT <$KEYEMAIL>"
242
    fi
243
    
198 by Teddy Hogeborn
* mandos-keygen: New "--passfile" option. Confirm entered password.
244
    # Export key from key rings to key files
159 by Teddy Hogeborn
* Makefile (run-client): Do not depend on the key ring files.
245
    gpg --quiet --batch --no-tty --no-options --enable-dsa2 \
246
	--homedir "$RINGDIR" --armor --export-options export-minimal \
247
	--comment "$FILECOMMENT" --output "$SECKEYFILE" \
248
	--export-secret-keys
249
    gpg --quiet --batch --no-tty --no-options --enable-dsa2 \
250
	--homedir "$RINGDIR" --armor --export-options export-minimal \
251
	--comment "$FILECOMMENT" --output "$PUBKEYFILE" --export
97 by Teddy Hogeborn
* mandos-keygen: Bug fix: Recognize new options --subtype and
252
fi
253
254
if [ "$mode" = password ]; then
198 by Teddy Hogeborn
* mandos-keygen: New "--passfile" option. Confirm entered password.
255
    # Import key into temporary key rings
159 by Teddy Hogeborn
* Makefile (run-client): Do not depend on the key ring files.
256
    gpg --quiet --batch --no-tty --no-options --enable-dsa2 \
257
	--homedir "$RINGDIR" --trust-model always --armor \
258
	--import "$SECKEYFILE"
259
    gpg --quiet --batch --no-tty --no-options --enable-dsa2 \
260
	--homedir "$RINGDIR" --trust-model always --armor \
261
	--import "$PUBKEYFILE"
262
    
97 by Teddy Hogeborn
* mandos-keygen: Bug fix: Recognize new options --subtype and
263
    # Get fingerprint of key
159 by Teddy Hogeborn
* Makefile (run-client): Do not depend on the key ring files.
264
    FINGERPRINT="`gpg --quiet --batch --no-tty --no-options \
265
	--enable-dsa2 --homedir \"$RINGDIR\" --trust-model always \
266
	--fingerprint --with-colons \
168 by Teddy Hogeborn
* initramfs-tools-hook: Use long options where available. Use only
267
	| sed --quiet \
268
	--expression='/^fpr:/{s/^fpr:.*:\\([0-9A-Z]*\\):\$/\\1/p;q}'`"
97 by Teddy Hogeborn
* mandos-keygen: Bug fix: Recognize new options --subtype and
269
    
270
    test -n "$FINGERPRINT"
271
    
272
    FILECOMMENT="Encrypted password for a Mandos client"
273
    
198 by Teddy Hogeborn
* mandos-keygen: New "--passfile" option. Confirm entered password.
274
    if [ -n "$PASSFILE" ]; then
275
	cat "$PASSFILE"
276
    else
277
	stty -echo
278
	echo -n "Enter passphrase: " >&2
279
	first="$(head --lines=1 | tr --delete '\n')"
280
	echo -n -e "\nRepeat passphrase: " >&2
281
	second="$(head --lines=1 | tr --delete '\n')"
282
	echo >&2
283
	stty echo
284
	if [ "$first" != "$second" ]; then
285
	    echo -e "Passphrase mismatch" >&2
286
	    false
287
	else
288
	    echo -n "$first"
289
	fi
290
    fi | gpg --quiet --batch --no-tty --no-options --enable-dsa2 \
159 by Teddy Hogeborn
* Makefile (run-client): Do not depend on the key ring files.
291
	--homedir "$RINGDIR" --trust-model always --armor --encrypt \
292
	--recipient "$FINGERPRINT" --comment "$FILECOMMENT" \
97 by Teddy Hogeborn
* mandos-keygen: Bug fix: Recognize new options --subtype and
293
	> "$SECFILE"
198 by Teddy Hogeborn
* mandos-keygen: New "--passfile" option. Confirm entered password.
294
    status="${PIPESTATUS[0]}"
295
    if [ "$status" -ne 0 ]; then
296
	exit "$status"
297
    fi
97 by Teddy Hogeborn
* mandos-keygen: Bug fix: Recognize new options --subtype and
298
    
299
    cat <<-EOF
300
	[$KEYNAME]
99 by Teddy Hogeborn
* mandos (fingerprint): Bug fix: Check crtverify.value, not crtverify.
301
	host = $KEYNAME
97 by Teddy Hogeborn
* mandos-keygen: Bug fix: Recognize new options --subtype and
302
	fingerprint = $FINGERPRINT
303
	secret =
198 by Teddy Hogeborn
* mandos-keygen: New "--passfile" option. Confirm entered password.
304
	EOF
168 by Teddy Hogeborn
* initramfs-tools-hook: Use long options where available. Use only
305
    sed --quiet --expression='
97 by Teddy Hogeborn
* mandos-keygen: Bug fix: Recognize new options --subtype and
306
	/^-----BEGIN PGP MESSAGE-----$/,/^-----END PGP MESSAGE-----$/{
307
	    /^$/,${
103 by Teddy Hogeborn
* mandos-keygen: Strip 24-bit checksum of Radix-64 from output to make
308
		# Remove 24-bit Radix-64 checksum
309
		s/=....$//
97 by Teddy Hogeborn
* mandos-keygen: Bug fix: Recognize new options --subtype and
310
		# Indent four spaces
311
		/^[^-]/s/^/    /p
312
	    }
313
	}' < "$SECFILE"
314
fi
73 by Teddy Hogeborn
* Makefile (COVERAGE): Change back to "--coverage".
315
316
trap - EXIT
317
97 by Teddy Hogeborn
* mandos-keygen: Bug fix: Recognize new options --subtype and
318
set +e
319
# Remove the password file, if any
320
if [ -n "$SECFILE" ]; then
321
    shred --remove "$SECFILE"
322
fi
73 by Teddy Hogeborn
* Makefile (COVERAGE): Change back to "--coverage".
323
# Remove the key rings
159 by Teddy Hogeborn
* Makefile (run-client): Do not depend on the key ring files.
324
shred --remove "$RINGDIR"/sec*
325
rm --recursive --force "$RINGDIR"