/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:
1
1
#!/bin/sh -e
2
2
3
 
# Mandos key generator - create new keys for a Mandos client
4
 
5
 
# Copyright © 2008-2019 Teddy Hogeborn
6
 
# Copyright © 2008-2019 Björn Påhlsson
7
 
8
 
# This file is part of Mandos.
9
 
#
10
 
# Mandos is free software: you can redistribute it and/or modify it
11
 
# under the terms of the GNU General Public License as published by
 
3
# Mandos key generator - create a new OpenPGP key for a Mandos client
 
4
 
5
# Copyright © 2007-2008 Teddy Hogeborn & Björn Påhlsson
 
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
12
9
# the Free Software Foundation, either version 3 of the License, or
13
10
# (at your option) any later version.
14
11
#
15
 
#     Mandos is distributed in the hope that it will be useful, but
16
 
#     WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
#     This program is distributed in the hope that it will be useful,
 
13
#     but WITHOUT ANY WARRANTY; without even the implied warranty of
17
14
#     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
15
#     GNU General Public License for more details.
19
16
20
17
# You should have received a copy of the GNU General Public License
21
 
# along with Mandos.  If not, see <http://www.gnu.org/licenses/>.
22
 
23
 
# Contact the authors at <mandos@recompile.se>.
24
 
25
 
 
26
 
VERSION="1.8.17"
27
 
 
28
 
KEYDIR="/etc/keys/mandos"
29
 
KEYTYPE=RSA
30
 
KEYLENGTH=4096
31
 
SUBKEYTYPE=RSA
32
 
SUBKEYLENGTH=4096
33
 
KEYNAME="`hostname --fqdn 2>/dev/null || hostname`"
 
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
 
 
23
VERSION="1.0"
 
24
 
 
25
KEYDIR="/etc/mandos"
 
26
KEYTYPE=DSA
 
27
KEYLENGTH=2048
 
28
SUBKEYTYPE=ELG-E
 
29
SUBKEYLENGTH=2048
 
30
KEYNAME="`hostname --fqdn`"
34
31
KEYEMAIL=""
35
 
KEYCOMMENT=""
 
32
KEYCOMMENT="Mandos client key"
36
33
KEYEXPIRE=0
37
 
TLS_KEYTYPE=ed25519
38
34
FORCE=no
39
 
SSH=yes
40
35
KEYCOMMENT_ORIG="$KEYCOMMENT"
41
36
mode=keygen
42
37
 
43
 
if [ ! -d "$KEYDIR" ]; then
44
 
    KEYDIR="/etc/mandos/keys"
45
 
fi
46
 
 
47
38
# Parse options
48
 
TEMP=`getopt --options vhpF:d:t:l:s:L:n:e:c:x:T:fS \
49
 
    --longoptions version,help,password,passfile:,dir:,type:,length:,subtype:,sublength:,name:,email:,comment:,expire:,tls-keytype:,force,no-ssh \
 
39
TEMP=`getopt --options vhd:t:l:n:e:c:x:f \
 
40
    --longoptions version,help,password,dir:,type:,length:,subtype:,sublength:,name:,email:,comment:,expire:,force \
50
41
    --name "$0" -- "$@"`
51
42
 
52
43
help(){
53
 
basename="`basename "$0"`"
 
44
basename="`basename $0`"
54
45
cat <<EOF
55
46
Usage: $basename [ -v | --version ]
56
47
       $basename [ -h | --help ]
58
49
       $basename [ OPTIONS ]
59
50
   Encrypted password creation:
60
51
       $basename { -p | --password } [ --name NAME ] [ --dir DIR]
61
 
       $basename { -F | --passfile } FILE [ --name NAME ] [ --dir DIR]
62
52
 
63
53
Key creation options:
64
54
  -v, --version         Show program's version number and exit
65
55
  -h, --help            Show this help message and exit
66
56
  -d DIR, --dir DIR     Target directory for key files
67
 
  -t TYPE, --type TYPE  OpenPGP key type.  Default is RSA.
 
57
  -t TYPE, --type TYPE  Key type.  Default is DSA.
68
58
  -l BITS, --length BITS
69
 
                        OpenPGP key length in bits.  Default is 4096.
 
59
                        Key length in bits.  Default is 2048.
70
60
  -s TYPE, --subtype TYPE
71
 
                        OpenPGP subkey type.  Default is RSA.
 
61
                        Subkey type.  Default is ELG-E.
72
62
  -L BITS, --sublength BITS
73
 
                        OpenPGP subkey length in bits.  Default 4096.
 
63
                        Subkey length in bits.  Default is 2048.
74
64
  -n NAME, --name NAME  Name of key.  Default is the FQDN.
75
65
  -e ADDRESS, --email ADDRESS
76
 
                        Email address of OpenPGP key.  Default empty.
77
 
  -c TEXT, --comment TEXT
78
 
                        Comment field for OpenPGP key.  Default empty.
 
66
                        Email address of key.  Default is empty.
 
67
  -c COMMENT, --comment COMMENT
 
68
                        Comment field for key.  The default value is
 
69
                        "Mandos client key".
79
70
  -x TIME, --expire TIME
80
 
                        OpenPGP key expire time.  Default is none.
 
71
                        Key expire time.  Default is no expiration.
81
72
                        See gpg(1) for syntax.
82
 
  -T TYPE, --tls-keytype TYPE
83
 
                        TLS key type.  Default is ed25519.
84
 
  -f, --force           Force overwriting old key files.
 
73
  -f, --force           Force overwriting old keys.
85
74
 
86
75
Password creation options:
87
 
  -p, --password        Create an encrypted password using the key in
88
 
                        the key directory.  All options other than
89
 
                        --dir and --name are ignored.
90
 
  -F FILE, --passfile FILE
91
 
                        Encrypt a password from FILE using the key in
92
 
                        the key directory.  All options other than
93
 
                        --dir and --name are ignored.
94
 
  -S, --no-ssh          Don't get SSH key or set "checker" option.
 
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.
95
79
EOF
96
80
}
97
81
 
99
83
while :; do
100
84
    case "$1" in
101
85
        -p|--password) mode=password; shift;;
102
 
        -F|--passfile) mode=password; PASSFILE="$2"; shift 2;;
103
86
        -d|--dir) KEYDIR="$2"; shift 2;;
104
87
        -t|--type) KEYTYPE="$2"; shift 2;;
105
88
        -s|--subtype) SUBKEYTYPE="$2"; shift 2;;
109
92
        -e|--email) KEYEMAIL="$2"; shift 2;;
110
93
        -c|--comment) KEYCOMMENT="$2"; shift 2;;
111
94
        -x|--expire) KEYEXPIRE="$2"; shift 2;;
112
 
        -T|--tls-keytype) TLS_KEYTYPE="$2"; shift 2;;
113
95
        -f|--force) FORCE=yes; shift;;
114
 
        -S|--no-ssh) SSH=no; shift;;
115
96
        -v|--version) echo "$0 $VERSION"; exit;;
116
97
        -h|--help) help; exit;;
117
98
        --) shift; break;;
119
100
    esac
120
101
done
121
102
if [ "$#" -gt 0 ]; then
122
 
    echo "Unknown arguments: '$*'" >&2
 
103
    echo "Unknown arguments: '$@'" >&2
123
104
    exit 1
124
105
fi
125
106
 
126
107
SECKEYFILE="$KEYDIR/seckey.txt"
127
108
PUBKEYFILE="$KEYDIR/pubkey.txt"
128
 
TLS_PRIVKEYFILE="$KEYDIR/tls-privkey.pem"
129
 
TLS_PUBKEYFILE="$KEYDIR/tls-pubkey.pem"
130
109
 
131
110
# Check for some invalid values
132
 
if [ ! -d "$KEYDIR" ]; then
 
111
if [ -d "$KEYDIR" ]; then :; else
133
112
    echo "$KEYDIR not a directory" >&2
134
113
    exit 1
135
114
fi
136
 
if [ ! -r "$KEYDIR" ]; then
137
 
    echo "Directory $KEYDIR not readable" >&2
 
115
if [ -w "$KEYDIR" ]; then :; else
 
116
    echo "Directory $KEYDIR not writeable" >&2
 
117
    exit 1
 
118
fi
 
119
 
 
120
if [ "$mode" = password -a -e "$KEYDIR/trustdb.gpg.lock" ]; then
 
121
    echo "Key directory has locked trustdb; aborting." >&2
138
122
    exit 1
139
123
fi
140
124
 
141
125
if [ "$mode" = keygen ]; then
142
 
    if [ ! -w "$KEYDIR" ]; then
143
 
        echo "Directory $KEYDIR not writeable" >&2
144
 
        exit 1
145
 
    fi
146
126
    if [ -z "$KEYTYPE" ]; then
147
127
        echo "Empty key type" >&2
148
128
        exit 1
149
129
    fi
150
 
 
 
130
    
151
131
    if [ -z "$KEYNAME" ]; then
152
132
        echo "Empty key name" >&2
153
133
        exit 1
154
134
    fi
155
 
 
 
135
    
156
136
    if [ -z "$KEYLENGTH" ] || [ "$KEYLENGTH" -lt 512 ]; then
157
137
        echo "Invalid key length" >&2
158
138
        exit 1
162
142
        echo "Empty key expiration" >&2
163
143
        exit 1
164
144
    fi
165
 
 
 
145
    
166
146
    # Make FORCE be 0 or 1
167
147
    case "$FORCE" in
168
148
        [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]) FORCE=1;;
169
149
        [Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|*) FORCE=0;;
170
150
    esac
171
 
 
172
 
    if { [ -e "$SECKEYFILE" ] || [ -e "$PUBKEYFILE" ] \
173
 
             || [ -e "$TLS_PRIVKEYFILE" ] \
174
 
             || [ -e "$TLS_PUBKEYFILE" ]; } \
 
151
    
 
152
    if { [ -e "$SECKEYFILE" ] || [ -e "$PUBKEYFILE" ]; } \
175
153
        && [ "$FORCE" -eq 0 ]; then
176
154
        echo "Refusing to overwrite old key files; use --force" >&2
177
155
        exit 1
178
156
    fi
179
 
 
 
157
    
180
158
    # Set lines for GnuPG batch file
181
159
    if [ -n "$KEYCOMMENT" ]; then
182
160
        KEYCOMMENTLINE="Name-Comment: $KEYCOMMENT"
186
164
    fi
187
165
 
188
166
    # Create temporary gpg batch file
189
 
    BATCHFILE="`mktemp -t mandos-keygen-batch.XXXXXXXXXX`"
190
 
    TLS_PRIVKEYTMP="`mktemp -t mandos-keygen-privkey.XXXXXXXXXX`"
 
167
    BATCHFILE="`mktemp -t mandos-gpg-batch.XXXXXXXXXX`"
191
168
fi
192
169
 
193
170
if [ "$mode" = password ]; then
194
171
    # Create temporary encrypted password file
195
 
    SECFILE="`mktemp -t mandos-keygen-secfile.XXXXXXXXXX`"
196
 
fi
197
 
 
198
 
# Create temporary key ring directory
199
 
RINGDIR="`mktemp -d -t mandos-keygen-keyrings.XXXXXXXXXX`"
 
172
    SECFILE="`mktemp -t mandos-gpg-secfile.XXXXXXXXXX`"
 
173
fi
 
174
 
 
175
# Create temporary key rings
 
176
SECRING="`mktemp -t mandos-gpg-secring.XXXXXXXXXX`"
 
177
PUBRING="`mktemp -t mandos-gpg-pubring.XXXXXXXXXX`"
 
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
200
186
 
201
187
# Remove temporary files on exit
202
188
trap "
203
189
set +e; \
204
 
test -n \"$SECFILE\" && shred --remove \"$SECFILE\"; \
205
 
test -n \"$TLS_PRIVKEYTMP\" && shred --remove \"$TLS_PRIVKEYTMP\"; \
206
 
shred --remove \"$RINGDIR\"/sec* 2>/dev/null;
207
 
test -n \"$BATCHFILE\" && rm --force \"$BATCHFILE\"; \
208
 
rm --recursive --force \"$RINGDIR\";
209
 
tty --quiet && stty echo; \
 
190
rm --force $PUBRING ${PUBRING}~ $BATCHFILE $TRUSTDB; \
 
191
shred --remove $SECRING $SECFILE; \
 
192
stty echo; \
210
193
" EXIT
211
194
 
212
 
set -e
213
 
 
214
 
umask 077
 
195
umask 027
215
196
 
216
197
if [ "$mode" = keygen ]; then
217
198
    # Create batch file for GnuPG
218
199
    cat >"$BATCHFILE" <<-EOF
219
200
        Key-Type: $KEYTYPE
220
201
        Key-Length: $KEYLENGTH
221
 
        Key-Usage: sign,auth
 
202
        #Key-Usage: encrypt,sign,auth
222
203
        Subkey-Type: $SUBKEYTYPE
223
204
        Subkey-Length: $SUBKEYLENGTH
224
 
        Subkey-Usage: encrypt
 
205
        #Subkey-Usage: encrypt,sign,auth
225
206
        Name-Real: $KEYNAME
226
207
        $KEYCOMMENTLINE
227
208
        $KEYEMAILLINE
228
209
        Expire-Date: $KEYEXPIRE
229
210
        #Preferences: <string>
230
211
        #Handle: <no-spaces>
231
 
        #%pubring pubring.gpg
232
 
        #%secring secring.gpg
233
 
        %no-protection
 
212
        %pubring $PUBRING
 
213
        %secring $SECRING
234
214
        %commit
235
215
        EOF
236
 
 
237
 
    if tty --quiet; then
238
 
        cat <<-EOF
239
 
        Note: Due to entropy requirements, key generation could take
240
 
        anything from a few minutes to SEVERAL HOURS.  Please be
241
 
        patient and/or supply the system with more entropy if needed.
242
 
        EOF
243
 
        echo -n "Started: "
244
 
        date
245
 
    fi
246
 
 
247
 
    # Generate TLS private key
248
 
    if certtool --generate-privkey --password='' \
249
 
                --outfile "$TLS_PRIVKEYTMP" --sec-param ultra \
250
 
                --key-type="$TLS_KEYTYPE" --pkcs8 --no-text 2>/dev/null; then
251
 
        
252
 
        # Backup any old key files
253
 
        if cp --backup=numbered --force "$TLS_PRIVKEYFILE" "$TLS_PRIVKEYFILE" \
254
 
              2>/dev/null; then
255
 
            shred --remove "$TLS_PRIVKEYFILE" 2>/dev/null || :
256
 
        fi
257
 
        if cp --backup=numbered --force "$TLS_PUBKEYFILE" "$TLS_PUBKEYFILE" \
258
 
              2>/dev/null; then
259
 
            rm --force "$TLS_PUBKEYFILE"
260
 
        fi
261
 
        cp --archive "$TLS_PRIVKEYTMP" "$TLS_PRIVKEYFILE"
262
 
        shred --remove "$TLS_PRIVKEYTMP" 2>/dev/null || :
263
 
 
264
 
        ## TLS public key
265
 
 
266
 
        # First try certtool from GnuTLS
267
 
        if ! certtool --password='' --load-privkey="$TLS_PRIVKEYFILE" \
268
 
             --outfile="$TLS_PUBKEYFILE" --pubkey-info --no-text \
269
 
             2>/dev/null; then
270
 
            # Otherwise try OpenSSL
271
 
            if ! openssl pkey -in "$TLS_PRIVKEYFILE" \
272
 
                 -out "$TLS_PUBKEYFILE" -pubout; then
273
 
                rm --force "$TLS_PUBKEYFILE"
274
 
                # None of the commands succeded; give up
275
 
                return 1
276
 
            fi
277
 
        fi
278
 
    fi
279
 
 
280
 
    # Make sure trustdb.gpg exists;
281
 
    # this is a workaround for Debian bug #737128
282
 
    gpg --quiet --batch --no-tty --no-options --enable-dsa2 \
283
 
        --homedir "$RINGDIR" \
284
 
        --import-ownertrust < /dev/null
 
216
    
285
217
    # Generate a new key in the key rings
286
 
    gpg --quiet --batch --no-tty --no-options --enable-dsa2 \
287
 
        --homedir "$RINGDIR" --trust-model always \
 
218
    gpg --no-random-seed-file --quiet --batch --no-tty \
 
219
        --no-default-keyring --no-options --enable-dsa2 \
 
220
        --secret-keyring "$SECRING" --keyring "$PUBRING" \
288
221
        --gen-key "$BATCHFILE"
289
222
    rm --force "$BATCHFILE"
290
223
 
291
 
    if tty --quiet; then
292
 
        echo -n "Finished: "
293
 
        date
294
 
    fi
295
 
 
296
224
    # Backup any old key files
297
225
    if cp --backup=numbered --force "$SECKEYFILE" "$SECKEYFILE" \
298
226
        2>/dev/null; then
299
 
        shred --remove "$SECKEYFILE" 2>/dev/null || :
 
227
        shred --remove "$SECKEYFILE"
300
228
    fi
301
229
    if cp --backup=numbered --force "$PUBKEYFILE" "$PUBKEYFILE" \
302
230
        2>/dev/null; then
303
231
        rm --force "$PUBKEYFILE"
304
232
    fi
305
 
 
 
233
    
306
234
    FILECOMMENT="Mandos client key for $KEYNAME"
307
235
    if [ "$KEYCOMMENT" != "$KEYCOMMENT_ORIG" ]; then
308
236
        FILECOMMENT="$FILECOMMENT ($KEYCOMMENT)"
309
237
    fi
310
 
 
 
238
    
311
239
    if [ -n "$KEYEMAIL" ]; then
312
240
        FILECOMMENT="$FILECOMMENT <$KEYEMAIL>"
313
241
    fi
314
 
 
315
 
    # Export key from key rings to key files
316
 
    gpg --quiet --batch --no-tty --no-options --enable-dsa2 \
317
 
        --homedir "$RINGDIR" --armor --export-options export-minimal \
318
 
        --comment "$FILECOMMENT" --output "$SECKEYFILE" \
319
 
        --export-secret-keys
320
 
    gpg --quiet --batch --no-tty --no-options --enable-dsa2 \
321
 
        --homedir "$RINGDIR" --armor --export-options export-minimal \
322
 
        --comment "$FILECOMMENT" --output "$PUBKEYFILE" --export
 
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
323
254
fi
324
255
 
325
256
if [ "$mode" = password ]; then
326
 
 
327
 
    # Make SSH be 0 or 1
328
 
    case "$SSH" in
329
 
        [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]) SSH=1;;
330
 
        [Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|*) SSH=0;;
331
 
    esac
332
 
 
333
 
    if [ $SSH -eq 1 ]; then
334
 
        # The -q option is new in OpenSSH 9.8
335
 
        for ssh_keyscan_quiet in "-q " ""; do
336
 
            for ssh_keytype in ecdsa-sha2-nistp256 ed25519 rsa; do
337
 
                set +e
338
 
                ssh_fingerprint="`ssh-keyscan ${ssh_keyscan_quiet}-t $ssh_keytype localhost 2>/dev/null`"
339
 
                err=$?
340
 
                set -e
341
 
                if [ $err -ne 0 ]; then
342
 
                    ssh_fingerprint=""
343
 
                    continue
344
 
                fi
345
 
                if [ -n "$ssh_fingerprint" ]; then
346
 
                    ssh_fingerprint="${ssh_fingerprint#localhost }"
347
 
                    break 2
348
 
                fi
349
 
            done
350
 
        done
351
 
    fi
352
 
 
353
 
    # Import key into temporary key rings
354
 
    gpg --quiet --batch --no-tty --no-options --enable-dsa2 \
355
 
        --homedir "$RINGDIR" --trust-model always --armor \
356
 
        --import "$SECKEYFILE"
357
 
    gpg --quiet --batch --no-tty --no-options --enable-dsa2 \
358
 
        --homedir "$RINGDIR" --trust-model always --armor \
359
 
        --import "$PUBKEYFILE"
 
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"
360
268
 
361
269
    # Get fingerprint of key
362
 
    FINGERPRINT="`gpg --quiet --batch --no-tty --no-options \
363
 
        --enable-dsa2 --homedir "$RINGDIR" --trust-model always \
364
 
        --fingerprint --with-colons \
365
 
        | sed --quiet \
366
 
        --expression='/^fpr:/{s/^fpr:.*:\\([0-9A-Z]*\\):\$/\\1/p;q}'`"
367
 
 
 
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
    
368
277
    test -n "$FINGERPRINT"
369
 
 
370
 
    if [ -r "$TLS_PUBKEYFILE" ]; then
371
 
       KEY_ID="$(certtool --key-id --hash=sha256 \
372
 
                       --infile="$TLS_PUBKEYFILE" 2>/dev/null || :)"
373
 
 
374
 
       if [ -z "$KEY_ID" ]; then
375
 
           KEY_ID=$(openssl pkey -pubin -in "$TLS_PUBKEYFILE" \
376
 
                            -outform der \
377
 
                        | openssl sha256 \
378
 
                        | sed --expression='s/^.*[^[:xdigit:]]//')
379
 
       fi
380
 
       test -n "$KEY_ID"
381
 
    fi
382
 
 
 
278
    
383
279
    FILECOMMENT="Encrypted password for a Mandos client"
384
 
 
385
 
    while [ ! -s "$SECFILE" ]; do
386
 
        if [ -n "$PASSFILE" ]; then
387
 
            cat -- "$PASSFILE"
388
 
        else
389
 
            tty --quiet && stty -echo
390
 
            echo -n "Enter passphrase: " >/dev/tty
391
 
            read -r first
392
 
            tty --quiet && echo >&2
393
 
            echo -n "Repeat passphrase: " >/dev/tty
394
 
            read -r second
395
 
            if tty --quiet; then
396
 
                echo >&2
397
 
                stty echo
398
 
            fi
399
 
            if [ "$first" != "$second" ]; then
400
 
                echo "Passphrase mismatch" >&2
401
 
                touch "$RINGDIR"/mismatch
402
 
            else
403
 
                printf "%s" "$first"
404
 
            fi
405
 
        fi | gpg --quiet --batch --no-tty --no-options --enable-dsa2 \
406
 
            --homedir "$RINGDIR" --trust-model always --armor \
407
 
            --encrypt --sign --recipient "$FINGERPRINT" --comment \
408
 
            "$FILECOMMENT" > "$SECFILE"
409
 
        if [ -e "$RINGDIR"/mismatch ]; then
410
 
            rm --force "$RINGDIR"/mismatch
411
 
            if tty --quiet; then
412
 
                > "$SECFILE"
413
 
            else
414
 
                exit 1
415
 
            fi
416
 
        fi
417
 
    done
418
 
 
 
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
    
419
294
    cat <<-EOF
420
295
        [$KEYNAME]
421
296
        host = $KEYNAME
422
 
        EOF
423
 
    if [ -n "$KEY_ID" ]; then
424
 
        echo "key_id = $KEY_ID"
425
 
    fi
426
 
    cat <<-EOF
427
297
        fingerprint = $FINGERPRINT
428
298
        secret =
429
 
        EOF
430
 
    sed --quiet --expression='
 
299
EOF
 
300
    sed -n -e '
431
301
        /^-----BEGIN PGP MESSAGE-----$/,/^-----END PGP MESSAGE-----$/{
432
302
            /^$/,${
433
303
                # Remove 24-bit Radix-64 checksum
436
306
                /^[^-]/s/^/    /p
437
307
            }
438
308
        }' < "$SECFILE"
439
 
    if [ -n "$ssh_fingerprint" ]; then
440
 
        if [ -n "$ssh_keyscan_quiet" ]; then
441
 
            echo "# Note: if the Mandos server has OpenSSH older than 9.8, the ${ssh_keyscan_quiet}"
442
 
            echo "# option *must* be removed from the 'checker' setting below"
443
 
        fi
444
 
        echo 'checker = ssh-keyscan '"$ssh_keyscan_quiet"'-t '"$ssh_keytype"' %%(host)s 2>/dev/null | grep --fixed-strings --line-regexp --quiet --regexp=%%(host)s" %(ssh_fingerprint)s"'
445
 
        echo "ssh_fingerprint = ${ssh_fingerprint}"
446
 
    fi
447
309
fi
448
310
 
449
311
trap - EXIT
451
313
set +e
452
314
# Remove the password file, if any
453
315
if [ -n "$SECFILE" ]; then
454
 
    shred --remove "$SECFILE" 2>/dev/null
 
316
    shred --remove "$SECFILE"
455
317
fi
456
318
# Remove the key rings
457
 
shred --remove "$RINGDIR"/sec* 2>/dev/null
458
 
rm --recursive --force "$RINGDIR"
 
319
shred --remove "$SECRING"
 
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