/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: 2019-08-02 22:16:53 UTC
  • Revision ID: teddy@recompile.se-20190802221653-ic1iko9hbefzwsk7
Fix bug in server Debian package: Fails to start on first install

There has been a very long-standing bug where installation of the
server (the "mandos" Debian package) would fail to start the server
properly right after installation.  It would work on manual (re)start
after installation, or after reboot, and even after package purge and
reinstall, it would then work the first time.  The problem, it turns
out, is when the new "_mandos" user (and corresponding group) is
created, the D-Bus server is not reloaded, and is therefore not aware
of that user, and does not recognize the user and group name in the
/etc/dbus-1/system.d/mandos.conf file.  The Mandos server, when it
tries to start and access the D-Bus, is then not permitted to connect
to its D-Bus bus name, and disables D-Bus use as a fallback measure;
i.e. the server works, but it is not controllable via D-Bus commands
(via mandos-ctl or mandos-monitor).  The next time the D-Bus daemon is
reloaded for any reason, the new user & group would become visible to
the D-Bus daemon and after that, any restart of the Mandos server
would succeed and it would bind to its D-Bus name properly, and
thereby be visible and controllable by mandos-ctl & mandos-monitor.
This was mostly invisible when using sysvinit, but systemd makes the
problem visible since the systemd service file for the Mandos server
is configured to not consider the Mandos server "started" until the
D-Bus name has been bound; this makes the starting of the service wait
for 90 seconds and then fail with a timeout error.

Fixing this should also make the Debian CI autopkgtest tests work.

* debian/mandos.postinst (configure): After creating (or renaming)
                                      user & group, reload D-Bus
                                      daemon (if present).

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
# Contact the authors at <mandos@recompile.se>.
24
24
25
25
 
26
 
VERSION="1.7.20"
 
26
VERSION="1.8.5"
27
27
 
28
28
KEYDIR="/etc/keys/mandos"
29
29
KEYTYPE=RSA
187
187
    
188
188
    # Create temporary gpg batch file
189
189
    BATCHFILE="`mktemp -t mandos-keygen-batch.XXXXXXXXXX`"
 
190
    TLS_PRIVKEYTMP="`mktemp -t mandos-keygen-privkey.XXXXXXXXXX`"
190
191
fi
191
192
 
192
193
if [ "$mode" = password ]; then
201
202
trap "
202
203
set +e; \
203
204
test -n \"$SECFILE\" && shred --remove \"$SECFILE\"; \
 
205
test -n \"$TLS_PRIVKEYTMP\" && shred --remove \"$TLS_PRIVKEYTMP\"; \
204
206
shred --remove \"$RINGDIR\"/sec* 2>/dev/null;
205
207
test -n \"$BATCHFILE\" && rm --force \"$BATCHFILE\"; \
206
208
rm --recursive --force \"$RINGDIR\";
241
243
        echo -n "Started: "
242
244
        date
243
245
    fi
244
 
    
245
 
    # Backup any old key files
246
 
    if cp --backup=numbered --force "$TLS_PRIVKEYFILE" "$TLS_PRIVKEYFILE" \
247
 
        2>/dev/null; then
248
 
        shred --remove "$TLS_PRIVKEYFILE"
249
 
    fi
250
 
    if cp --backup=numbered --force "$TLS_PUBKEYFILE" "$TLS_PUBKEYFILE" \
251
 
        2>/dev/null; then
252
 
        rm --force "$TLS_PUBKEYFILE"
253
 
    fi
254
 
 
255
 
    ## Generate TLS private key
256
 
 
257
 
    # First try certtool from GnuTLS
258
 
    if ! certtool --generate-privkey --password='' \
259
 
         --outfile "$TLS_PRIVKEYFILE" --sec-param ultra \
260
 
         --key-type="$TLS_KEYTYPE" --pkcs8 --no-text 2>/dev/null; then
261
 
        # Otherwise try OpenSSL
262
 
        if ! openssl genpkey -algorithm X25519 -out \
263
 
             /etc/keys/mandos/tls-privkey.pem; then
264
 
            rm --force /etc/keys/mandos/tls-privkey.pem
265
 
            # None of the commands succeded; give up
266
 
            return 1
 
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 || :
267
256
        fi
268
 
    fi
269
 
 
270
 
    ## TLS public key
271
 
 
272
 
    # First try certtool from GnuTLS
273
 
    if ! certtool --password='' --load-privkey="$TLS_PRIVKEYFILE" \
274
 
         --outfile="$TLS_PUBKEYFILE" --pubkey-info --no-text \
275
 
         2>/dev/null; then
276
 
        # Otherwise try OpenSSL
277
 
        if ! openssl pkey -in "$TLS_PRIVKEYFILE" \
278
 
             -out "$TLS_PUBKEYFILE" -pubout; then
 
257
        if cp --backup=numbered --force "$TLS_PUBKEYFILE" "$TLS_PUBKEYFILE" \
 
258
              2>/dev/null; then
279
259
            rm --force "$TLS_PUBKEYFILE"
280
 
            # None of the commands succeded; give up
281
 
            return 1
 
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
282
277
        fi
283
278
    fi
284
279
    
301
296
    # Backup any old key files
302
297
    if cp --backup=numbered --force "$SECKEYFILE" "$SECKEYFILE" \
303
298
        2>/dev/null; then
304
 
        shred --remove "$SECKEYFILE"
 
299
        shred --remove "$SECKEYFILE" 2>/dev/null || :
305
300
    fi
306
301
    if cp --backup=numbered --force "$PUBKEYFILE" "$PUBKEYFILE" \
307
302
        2>/dev/null; then
369
364
    
370
365
    test -n "$FINGERPRINT"
371
366
    
372
 
    KEY_ID="$(certtool --key-id --hash=sha256 \
 
367
    if [ -r "$TLS_PUBKEYFILE" ]; then
 
368
       KEY_ID="$(certtool --key-id --hash=sha256 \
373
369
                       --infile="$TLS_PUBKEYFILE" 2>/dev/null || :)"
374
370
 
375
 
    if [ -z "$KEY_ID" ]; then
376
 
        KEY_ID=$(openssl pkey -pubin -in /tmp/tls-pubkey.pem \
377
 
                         -outform der \
378
 
                     | openssl sha256 \
379
 
                     | sed --expression='s/^.*[^[:xdigit:]]//')
 
371
       if [ -z "$KEY_ID" ]; then
 
372
           KEY_ID=$(openssl pkey -pubin -in "$TLS_PUBKEYFILE" \
 
373
                            -outform der \
 
374
                        | openssl sha256 \
 
375
                        | sed --expression='s/^.*[^[:xdigit:]]//')
 
376
       fi
 
377
       test -n "$KEY_ID"
380
378
    fi
381
 
    test -n "$KEY_ID"
382
379
    
383
380
    FILECOMMENT="Encrypted password for a Mandos client"
384
381
    
385
382
    while [ ! -s "$SECFILE" ]; do
386
383
        if [ -n "$PASSFILE" ]; then
387
 
            cat "$PASSFILE"
 
384
            cat -- "$PASSFILE"
388
385
        else
389
386
            tty --quiet && stty -echo
390
387
            echo -n "Enter passphrase: " >/dev/tty
419
416
    cat <<-EOF
420
417
        [$KEYNAME]
421
418
        host = $KEYNAME
422
 
        key_id = $KEY_ID
 
419
        EOF
 
420
    if [ -n "$KEY_ID" ]; then
 
421
        echo "key_id = $KEY_ID"
 
422
    fi
 
423
    cat <<-EOF
423
424
        fingerprint = $FINGERPRINT
424
425
        secret =
425
426
        EOF
443
444
set +e
444
445
# Remove the password file, if any
445
446
if [ -n "$SECFILE" ]; then
446
 
    shred --remove "$SECFILE"
 
447
    shred --remove "$SECFILE" 2>/dev/null
447
448
fi
448
449
# Remove the key rings
449
450
shred --remove "$RINGDIR"/sec* 2>/dev/null