/mandos/trunk

To get this branch, use:
bzr branch http://bzr.recompile.se/loggerhead/mandos/trunk

« back to all changes in this revision

Viewing changes to mandos-keygen

  • Committer: Teddy Hogeborn
  • Date: 2008-08-29 05:53:59 UTC
  • Revision ID: teddy@fukt.bsnet.se-20080829055359-wkdasnyxtylmnxus
* mandos.xml (EXAMPLE): Replaced all occurences of command name with
                        "&COMMANDNAME;".

* plugins.d/password-prompt.c (main): Improved some documentation
                                      strings.  Do perror() of
                                      tcgetattr() fails.  Add debug
                                      output if interrupted by signal.
                                      Loop over write() instead of
                                      using fwrite() when outputting
                                      password.  Add debug output if
                                      getline() returns 0, unless it
                                      was caused by a signal.  Add
                                      exit status code to debug
                                      output.

* plugins.d/password-prompt.xml: Changed all single quotes to double
                                 quotes for consistency.  Removed
                                 <?xml-stylesheet>.
  (ENTITY TIMESTAMP): New.  Automatically updated by Emacs time-stamp
                      by using Emacs local variables.
  (/refentry/refentryinfo/title): Changed to "Mandos Manual".
  (/refentry/refentryinfo/productname): Changed to "Mandos".
  (/refentry/refentryinfo/date): New; set to "&TIMESTAMP;".
  (/refentry/refentryinfo/copyright): Split copyright holders.
  (/refentry/refnamediv/refpurpose): Improved wording.
  (SYNOPSIS): Fix to use correct markup.  Add short options.
  (DESCRIPTION, OPTIONS): Improved wording.
  (OPTIONS): Improved wording.  Use more correct markup.  Document
             short options.
  (EXIT STATUS): Add text.
  (ENVIRONMENT): Document use of "cryptsource" and "crypttarget".
  (FILES): REMOVED.
  (BUGS): Add text.
  (EXAMPLE): Added some examples.
  (SECURITY): Added text.
  (SEE ALSO): Remove reference to mandos(8).  Add reference to
              crypttab(5).

Show diffs side-by-side

added added

removed removed

Lines of Context:
24
24
 
25
25
KEYDIR="/etc/mandos"
26
26
KEYTYPE=DSA
27
 
KEYLENGTH=1024
 
27
KEYLENGTH=2048
 
28
SUBKEYTYPE=ELG-E
 
29
SUBKEYLENGTH=2048
28
30
KEYNAME="`hostname --fqdn`"
29
31
KEYEMAIL=""
30
32
KEYCOMMENT="Mandos client key"
31
33
KEYEXPIRE=0
32
34
FORCE=no
33
35
KEYCOMMENT_ORIG="$KEYCOMMENT"
 
36
mode=keygen
34
37
 
35
38
# Parse options
36
39
TEMP=`getopt --options vhd:t:l:n:e:c:x:f \
37
 
    --longoptions version,help,dir:,type:,length:,name:,email:,comment:,expire:,force \
 
40
    --longoptions version,help,password,dir:,type:,length:,subtype:,sublength:,name:,email:,comment:,expire:,force \
38
41
    --name "$0" -- "$@"`
39
42
 
40
43
help(){
 
44
basename="`basename $0`"
41
45
cat <<EOF
42
 
Usage: `basename $0` [options]
 
46
Usage: $basename [ -v | --version ]
 
47
       $basename [ -h | --help ]
 
48
   Key creation:
 
49
       $basename [ OPTIONS ]
 
50
   Encrypted password creation:
 
51
       $basename { -p | --password } [ --name NAME ] [ --dir DIR]
43
52
 
44
 
Options:
 
53
Key creation options:
45
54
  -v, --version         Show program's version number and exit
46
55
  -h, --help            Show this help message and exit
47
56
  -d DIR, --dir DIR     Target directory for key files
48
57
  -t TYPE, --type TYPE  Key type.  Default is DSA.
49
58
  -l BITS, --length BITS
50
 
                        Key length in bits.  Default is 1024.
 
59
                        Key length in bits.  Default is 2048.
 
60
  -s TYPE, --subtype TYPE
 
61
                        Subkey type.  Default is ELG-E.
 
62
  -L BITS, --sublength BITS
 
63
                        Subkey length in bits.  Default is 2048.
51
64
  -n NAME, --name NAME  Name of key.  Default is the FQDN.
52
 
  -e EMAIL, --email EMAIL
 
65
  -e ADDRESS, --email ADDRESS
53
66
                        Email address of key.  Default is empty.
54
67
  -c COMMENT, --comment COMMENT
55
68
                        Comment field for key.  The default value is
58
71
                        Key expire time.  Default is no expiration.
59
72
                        See gpg(1) for syntax.
60
73
  -f, --force           Force overwriting old keys.
 
74
 
 
75
Password creation options:
 
76
  -p, --password        Create an encrypted password using the keys in
 
77
                        the key directory.  All options other than
 
78
                        --keydir and --name are ignored.
61
79
EOF
62
80
}
63
81
 
64
82
eval set -- "$TEMP"
65
83
while :; do
66
84
    case "$1" in
 
85
        -p|--password) mode=password; shift;;
67
86
        -d|--dir) KEYDIR="$2"; shift 2;;
68
87
        -t|--type) KEYTYPE="$2"; shift 2;;
 
88
        -s|--subtype) SUBKEYTYPE="$2"; shift 2;;
69
89
        -l|--length) KEYLENGTH="$2"; shift 2;;
 
90
        -L|--sublength) SUBKEYLENGTH="$2"; shift 2;;
70
91
        -n|--name) KEYNAME="$2"; shift 2;;
71
92
        -e|--email) KEYEMAIL="$2"; shift 2;;
72
93
        -c|--comment) KEYCOMMENT="$2"; shift 2;;
96
117
    exit 1
97
118
fi
98
119
 
99
 
if [ -z "$KEYTYPE" ]; then
100
 
    echo "Empty key type" >&2
101
 
    exit 1
102
 
fi
103
 
 
104
 
if [ -z "$KEYNAME" ]; then
105
 
    echo "Empty key name" >&2
106
 
    exit 1
107
 
fi
108
 
 
109
 
if [ -z "$KEYLENGTH" ] || [ "$KEYLENGTH" -lt 512 ]; then
110
 
    echo "Invalid key length" >&2
111
 
    exit 1
112
 
fi
113
 
 
114
 
if [ -z "$KEYEXPIRE" ]; then
115
 
    echo "Empty key expiration" >&2
116
 
    exit 1
117
 
fi
118
 
 
119
 
# Make FORCE be 0 or 1
120
 
case "$FORCE" in
121
 
    [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]) FORCE=1;;
122
 
    [Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|*) FORCE=0;;
123
 
esac
124
 
 
125
 
if { [ -e "$SECKEYFILE" ] || [ -e "$PUBKEYFILE" ]; } \
126
 
    && [ "$FORCE" -eq 0 ]; then
127
 
    echo "Refusing to overwrite old key files; use --force" >&2
128
 
    exit 1
129
 
fi
130
 
 
131
 
# Set lines for GnuPG batch file
132
 
if [ -n "$KEYCOMMENT" ]; then
133
 
    KEYCOMMENTLINE="Name-Comment: $KEYCOMMENT"
134
 
fi
135
 
if [ -n "$KEYEMAIL" ]; then
136
 
    KEYEMAILLINE="Name-Email: $KEYEMAIL"
137
 
fi
138
 
 
139
 
# Create temp files
140
 
BATCHFILE="`mktemp -t mandos-gpg-batch.XXXXXXXXXX`"
 
120
if [ "$mode" = password -a -e "$KEYDIR/trustdb.gpg.lock" ]; then
 
121
    echo "Key directory has locked trustdb; aborting." >&2
 
122
    exit 1
 
123
fi
 
124
 
 
125
if [ "$mode" = keygen ]; then
 
126
    if [ -z "$KEYTYPE" ]; then
 
127
        echo "Empty key type" >&2
 
128
        exit 1
 
129
    fi
 
130
    
 
131
    if [ -z "$KEYNAME" ]; then
 
132
        echo "Empty key name" >&2
 
133
        exit 1
 
134
    fi
 
135
    
 
136
    if [ -z "$KEYLENGTH" ] || [ "$KEYLENGTH" -lt 512 ]; then
 
137
        echo "Invalid key length" >&2
 
138
        exit 1
 
139
    fi
 
140
 
 
141
    if [ -z "$KEYEXPIRE" ]; then
 
142
        echo "Empty key expiration" >&2
 
143
        exit 1
 
144
    fi
 
145
    
 
146
    # Make FORCE be 0 or 1
 
147
    case "$FORCE" in
 
148
        [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]) FORCE=1;;
 
149
        [Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|*) FORCE=0;;
 
150
    esac
 
151
    
 
152
    if { [ -e "$SECKEYFILE" ] || [ -e "$PUBKEYFILE" ]; } \
 
153
        && [ "$FORCE" -eq 0 ]; then
 
154
        echo "Refusing to overwrite old key files; use --force" >&2
 
155
        exit 1
 
156
    fi
 
157
    
 
158
    # Set lines for GnuPG batch file
 
159
    if [ -n "$KEYCOMMENT" ]; then
 
160
        KEYCOMMENTLINE="Name-Comment: $KEYCOMMENT"
 
161
    fi
 
162
    if [ -n "$KEYEMAIL" ]; then
 
163
        KEYEMAILLINE="Name-Email: $KEYEMAIL"
 
164
    fi
 
165
 
 
166
    # Create temporary gpg batch file
 
167
    BATCHFILE="`mktemp -t mandos-gpg-batch.XXXXXXXXXX`"
 
168
fi
 
169
 
 
170
if [ "$mode" = password ]; then
 
171
    # Create temporary encrypted password file
 
172
    SECFILE="`mktemp -t mandos-gpg-secfile.XXXXXXXXXX`"
 
173
fi
 
174
 
 
175
# Create temporary key rings
141
176
SECRING="`mktemp -t mandos-gpg-secring.XXXXXXXXXX`"
142
177
PUBRING="`mktemp -t mandos-gpg-pubring.XXXXXXXXXX`"
143
178
 
 
179
if [ "$mode" = password ]; then
 
180
    # If a trustdb.gpg file does not already exist, schedule it for
 
181
    # deletion when we are done.
 
182
    if ! [ -e "$KEYDIR/trustdb.gpg" ]; then
 
183
        TRUSTDB="$KEYDIR/trustdb.gpg"
 
184
    fi
 
185
fi
 
186
 
144
187
# Remove temporary files on exit
145
188
trap "
146
 
set +e
147
 
rm --force $PUBRING $BATCHFILE;
148
 
shred --remove $SECRING;
149
 
stty echo
 
189
set +e; \
 
190
rm --force $PUBRING ${PUBRING}~ $BATCHFILE $TRUSTDB; \
 
191
shred --remove $SECRING $SECFILE; \
 
192
stty echo; \
150
193
" EXIT
151
194
 
152
 
# Create batch file for GnuPG
153
 
cat >"$BATCHFILE" <<EOF
154
 
Key-Type: $KEYTYPE
155
 
Key-Length: $KEYLENGTH
156
 
#Key-Usage: encrypt,sign,auth
157
 
Name-Real: $KEYNAME
158
 
$KEYCOMMENTLINE
159
 
$KEYEMAILLINE
160
 
Expire-Date: $KEYEXPIRE
161
 
%pubring $PUBRING
162
 
%secring $SECRING
163
 
%commit
164
 
EOF
165
 
 
166
195
umask 027
167
196
 
168
 
# Generate a new key in the key rings
169
 
gpg --no-random-seed-file --quiet --batch --no-tty \
170
 
    --no-default-keyring --no-options --batch \
171
 
    --secret-keyring "$SECRING" --keyring "$PUBRING" \
172
 
    --gen-key "$BATCHFILE"
173
 
rm --force "$BATCHFILE"
174
 
 
175
 
# Backup any old key files
176
 
if cp --backup=numbered --force "$SECKEYFILE" "$SECKEYFILE" \
177
 
    2>/dev/null; then
178
 
    shred --remove "$SECKEYFILE"
179
 
fi
180
 
if cp --backup=numbered --force "$PUBKEYFILE" "$PUBKEYFILE" \
181
 
    2>/dev/null; then
182
 
    rm --force "$PUBKEYFILE"
183
 
fi
184
 
 
185
 
FILECOMMENT="Mandos client key for $KEYNAME"
186
 
if [ "$KEYCOMMENT" != "$KEYCOMMENT_ORIG" ]; then
187
 
    FILECOMMENT="$FILECOMMENT ($KEYCOMMENT)"
188
 
fi
189
 
 
190
 
if [ -n "$KEYEMAIL" ]; then
191
 
    FILECOMMENT="$FILECOMMENT <$KEYEMAIL>"
192
 
fi
193
 
 
194
 
# Export keys from key rings to key files
195
 
gpg --no-random-seed-file --quiet --batch --no-tty --armor \
196
 
    --no-default-keyring --no-options --secret-keyring "$SECRING" \
197
 
    --keyring "$PUBRING" --export-options export-minimal \
198
 
    --comment "$FILECOMMENT" --output "$SECKEYFILE" \
199
 
    --export-secret-keys
200
 
gpg --no-random-seed-file --quiet --batch --no-tty --armor \
201
 
    --no-default-keyring --no-options --secret-keyring "$SECRING" \
202
 
    --keyring "$PUBRING" --export-options export-minimal \
203
 
    --comment "$FILECOMMENT" --output "$PUBKEYFILE" \
204
 
    --export
 
197
if [ "$mode" = keygen ]; then
 
198
    # Create batch file for GnuPG
 
199
    cat >"$BATCHFILE" <<-EOF
 
200
        Key-Type: $KEYTYPE
 
201
        Key-Length: $KEYLENGTH
 
202
        #Key-Usage: encrypt,sign,auth
 
203
        Subkey-Type: $SUBKEYTYPE
 
204
        Subkey-Length: $SUBKEYLENGTH
 
205
        #Subkey-Usage: encrypt,sign,auth
 
206
        Name-Real: $KEYNAME
 
207
        $KEYCOMMENTLINE
 
208
        $KEYEMAILLINE
 
209
        Expire-Date: $KEYEXPIRE
 
210
        #Preferences: <string>
 
211
        #Handle: <no-spaces>
 
212
        %pubring $PUBRING
 
213
        %secring $SECRING
 
214
        %commit
 
215
        EOF
 
216
    
 
217
    # Generate a new key in the key rings
 
218
    gpg --no-random-seed-file --quiet --batch --no-tty \
 
219
        --no-default-keyring --no-options --enable-dsa2 \
 
220
        --secret-keyring "$SECRING" --keyring "$PUBRING" \
 
221
        --gen-key "$BATCHFILE"
 
222
    rm --force "$BATCHFILE"
 
223
 
 
224
    # Backup any old key files
 
225
    if cp --backup=numbered --force "$SECKEYFILE" "$SECKEYFILE" \
 
226
        2>/dev/null; then
 
227
        shred --remove "$SECKEYFILE"
 
228
    fi
 
229
    if cp --backup=numbered --force "$PUBKEYFILE" "$PUBKEYFILE" \
 
230
        2>/dev/null; then
 
231
        rm --force "$PUBKEYFILE"
 
232
    fi
 
233
    
 
234
    FILECOMMENT="Mandos client key for $KEYNAME"
 
235
    if [ "$KEYCOMMENT" != "$KEYCOMMENT_ORIG" ]; then
 
236
        FILECOMMENT="$FILECOMMENT ($KEYCOMMENT)"
 
237
    fi
 
238
    
 
239
    if [ -n "$KEYEMAIL" ]; then
 
240
        FILECOMMENT="$FILECOMMENT <$KEYEMAIL>"
 
241
    fi
 
242
    
 
243
    # Export keys from key rings to key files
 
244
    gpg --no-random-seed-file --quiet --batch --no-tty --armor \
 
245
        --no-default-keyring --no-options --enable-dsa2 \
 
246
        --secret-keyring "$SECRING" --keyring "$PUBRING" \
 
247
        --export-options export-minimal --comment "$FILECOMMENT" \
 
248
        --output "$SECKEYFILE" --export-secret-keys
 
249
    gpg --no-random-seed-file --quiet --batch --no-tty --armor \
 
250
        --no-default-keyring --no-options --enable-dsa2 \
 
251
        --secret-keyring "$SECRING" --keyring "$PUBRING" \
 
252
        --export-options export-minimal --comment "$FILECOMMENT" \
 
253
        --output "$PUBKEYFILE" --export
 
254
fi
 
255
 
 
256
if [ "$mode" = password ]; then
 
257
    # Import keys into temporary key rings
 
258
    gpg --no-random-seed-file --quiet --batch --no-tty --armor \
 
259
        --no-default-keyring --no-options --enable-dsa2 \
 
260
        --homedir "$KEYDIR" --no-permission-warning \
 
261
        --secret-keyring "$SECRING" --keyring "$PUBRING" \
 
262
        --trust-model always --import "$SECKEYFILE"
 
263
    gpg --no-random-seed-file --quiet --batch --no-tty --armor \
 
264
        --no-default-keyring --no-options --enable-dsa2 \
 
265
        --homedir "$KEYDIR" --no-permission-warning \
 
266
        --secret-keyring "$SECRING" --keyring "$PUBRING" \
 
267
        --trust-model always --import "$PUBKEYFILE"
 
268
 
 
269
    # Get fingerprint of key
 
270
    FINGERPRINT="`gpg --no-random-seed-file --quiet --batch --no-tty \
 
271
        --armor --no-default-keyring --no-options --enable-dsa2 \
 
272
        --homedir \"$KEYDIR\" --no-permission-warning \
 
273
        --secret-keyring \"$SECRING\" --keyring \"$PUBRING\" \
 
274
        --trust-model always --fingerprint --with-colons \
 
275
        | sed -n -e '/^fpr:/{s/^fpr:.*:\\([0-9A-Z]*\\):\$/\\1/p;q}'`"
 
276
    
 
277
    test -n "$FINGERPRINT"
 
278
    
 
279
    FILECOMMENT="Encrypted password for a Mandos client"
 
280
    
 
281
    stty -echo
 
282
    echo -n "Enter passphrase: " >&2
 
283
    sed -e '1q' \
 
284
        | gpg --no-random-seed-file --batch --no-tty --armor \
 
285
        --no-default-keyring --no-options --enable-dsa2 \
 
286
        --homedir "$KEYDIR" --no-permission-warning \
 
287
        --secret-keyring "$SECRING" --keyring "$PUBRING" \
 
288
        --trust-model always --encrypt --recipient "$FINGERPRINT" \
 
289
        --comment "$FILECOMMENT" \
 
290
        > "$SECFILE"
 
291
    echo >&2
 
292
    stty echo
 
293
    
 
294
    cat <<-EOF
 
295
        [$KEYNAME]
 
296
        host = $KEYNAME
 
297
        fingerprint = $FINGERPRINT
 
298
        secret =
 
299
EOF
 
300
    sed -n -e '
 
301
        /^-----BEGIN PGP MESSAGE-----$/,/^-----END PGP MESSAGE-----$/{
 
302
            /^$/,${
 
303
                # Remove 24-bit Radix-64 checksum
 
304
                s/=....$//
 
305
                # Indent four spaces
 
306
                /^[^-]/s/^/    /p
 
307
            }
 
308
        }' < "$SECFILE"
 
309
fi
205
310
 
206
311
trap - EXIT
207
312
 
 
313
set +e
 
314
# Remove the password file, if any
 
315
if [ -n "$SECFILE" ]; then
 
316
    shred --remove "$SECFILE"
 
317
fi
208
318
# Remove the key rings
209
319
shred --remove "$SECRING"
210
 
rm --force "$PUBRING"
 
320
rm --force "$PUBRING" "${PUBRING}~"
 
321
# Remove the trustdb, if one did not exist when we started
 
322
if [ -n "$TRUSTDB" ]; then
 
323
    rm --force "$TRUSTDB"
 
324
fi