/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 debian/mandos-client.postinst

  • Committer: Teddy Hogeborn
  • Date: 2024-09-09 01:36:41 UTC
  • Revision ID: teddy@recompile.se-20240909013641-6zu6kx2f7meu134k
Make all required directories when installing

When installing into a normal system, one can assume that target
directories, such as /usr/bin, already exists.  But when installing
into a subdirectory for the purpose of creating a package, one cannot
assume that all directories already exist.  Therefore, when
installing, we must not check if any directories exist, and must
instead always create any directories we want to install into.

* Makefile (confdir/mandos.conf, confdir/clients.conf, install-html):
  Use the "-D" option to "install" instead of creating the directory
  separately.
  (install-server): Move creation of $(CONFDIR) down to before it is
  needed.  Don't check if the $(TMPFILES) or $(SYSUSERS) directories
  exist; instead create them by using the "-D" option to "install".
  Create the $(PREFIX)/sbin directory.  Always use
  "--target-directory" if possible; i.e. if the file name is the same.
  Create the $(DBUSPOLICYDIR) and $(DESTDIR)/etc/init.d directories by
  using the "-D" option to "install".  Don't check if the $(SYSTEMD)
  directory exists; instead create it by using the "-D" option to
  "install".  Create the $(DESTDIR)/etc/default and $(MANDIR)/man8
  directories by using the "-D" option to "install".  Create the
  $(MANDIR)/man5 directories explicitly.
  (install-client-nokey): Remove unnecessary creation of the
  $(CONFDIR) directory.  Don't check if the $(SYSUSERS) directory
  exists; instead create it by using the "-D" option to "install".
  Move the "--directory" argument to be the first argument, for
  clarity.  Create the $(PREFIX)/sbin directory.  Use the "-D"
  argument to "install" when installing
  $(INITRAMFSTOOLS)/hooks/mandos,
  $(INITRAMFSTOOLS)/conf.d/mandos-conf,
  $(INITRAMFSTOOLS)/conf-hooks.d/zz-mandos,
  $(INITRAMFSTOOLS)/scripts/init-premount/mandos,
  $(INITRAMFSTOOLS)/scripts/local-premount/mandos,
  $(DRACUTMODULE)/ask-password-mandos.path, and
  $(DRACUTMODULE)/dracut-module/ask-password-mandos.service.  Create
  the $(MANDIR)/man8 directory.

Reported-By: Erich Eckner <erich@eckner.net>
Thanks: Erich Eckner <erich@eckner.net> for analysis

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/bin/sh
 
2
# This script can be called in the following ways:
 
3
#
 
4
# After the package was installed:
 
5
#       <postinst> configure <old-version>
 
6
#
 
7
#
 
8
# If prerm fails during upgrade or fails on failed upgrade:
 
9
#       <old-postinst> abort-upgrade <new-version>
 
10
#
 
11
# If prerm fails during deconfiguration of a package:
 
12
#       <postinst> abort-deconfigure in-favour <new-package> <version>
 
13
#                  removing <old-package> <version>
 
14
#
 
15
# If prerm fails during replacement due to conflict:
 
16
#       <postinst> abort-remove in-favour <new-package> <version>
 
17
 
 
18
. /usr/share/debconf/confmodule
 
19
 
 
20
set -e
 
21
 
 
22
# Update the initial RAM file system image
 
23
update_initramfs()
 
24
{
 
25
    if command -v update-initramfs >/dev/null; then
 
26
        update-initramfs -k all -u 1>&2
 
27
    elif command -v dracut >/dev/null; then
 
28
        dracut_version="`dpkg-query --showformat='${Version}' --show dracut`"
 
29
        if dpkg --compare-versions "$dracut_version" lt 043-1 \
 
30
                && bash -c '. /etc/dracut.conf; . /etc/dracut.conf.d/*; [ "$hostonly" != yes ]'; then
 
31
            echo 'Dracut is not configured to use hostonly mode!' >&2
 
32
            return 1
 
33
        fi
 
34
        # Logic taken from dracut.postinst
 
35
        for kernel in /boot/vmlinu[xz]-*; do
 
36
            kversion="${kernel#/boot/vmlinu[xz]-}"
 
37
            # Dracut preserves old permissions of initramfs image
 
38
            # files, so we adjust permissions before creating new
 
39
            # initramfs image containing secret keys.
 
40
            if [ -e /boot/initrd.img-"$kversion" ]; then
 
41
                chmod go-r /boot/initrd.img-"$kversion"
 
42
            else
 
43
                # An initrd image has not yet been created for this
 
44
                # kernel, possibly because this new kernel is about to
 
45
                # be, but has not yet been, installed.  In this case,
 
46
                # we create an empty file with the right permissions
 
47
                # so that Dracut will preserve those permissions when
 
48
                # it creates the real, new initrd image for this
 
49
                # kernel.
 
50
                install --mode=u=rw /dev/null \
 
51
                        /boot/initrd.img-"$kversion"
 
52
            fi
 
53
            if [ "$kversion" != "*" ]; then
 
54
                /etc/kernel/postinst.d/dracut "$kversion" 1>&2
 
55
            fi
 
56
        done
 
57
    fi
 
58
    
 
59
    if dpkg --compare-versions "$2" lt-nl "1.0.10-1"; then
 
60
        # Make old initrd.img files unreadable too, in case they were
 
61
        # created with mandos-client 1.0.8 or older.
 
62
        find /boot -maxdepth 1 -type f -name "initrd.img-*.bak" \
 
63
            -print0 | xargs --null --no-run-if-empty chmod o-r
 
64
    fi
 
65
}
 
66
 
 
67
# Add user and group
 
68
add_mandos_user(){
 
69
    # Rename old "mandos" user and group
 
70
    if dpkg --compare-versions "$2" lt "1.0.3-1"; then
 
71
        case "`getent passwd mandos`" in
 
72
            *:Mandos\ password\ system,,,:/nonexistent:/bin/false)
 
73
                usermod --login _mandos mandos 1>&2
 
74
                groupmod --new-name _mandos mandos 1>&2
 
75
                return
 
76
                ;;
 
77
        esac
 
78
    fi
 
79
    # Create new user and group
 
80
    if ! getent passwd _mandos >/dev/null; then
 
81
        adduser --system --force-badname --quiet --home /nonexistent \
 
82
            --no-create-home --group --disabled-password \
 
83
            --gecos "Mandos password system" _mandos 1>&2
 
84
    fi
 
85
}
 
86
 
 
87
# Create client key pairs
 
88
create_keys(){
 
89
    # If the OpenPGP key files do not exist, generate all keys using
 
90
    # mandos-keygen
 
91
    if ! [ -r /etc/keys/mandos/pubkey.txt \
 
92
              -a -r /etc/keys/mandos/seckey.txt ]; then
 
93
        mandos-keygen 1>&2
 
94
        gpg-connect-agent KILLAGENT /bye 1>&2 || :
 
95
        return 0
 
96
    fi
 
97
 
 
98
    # Remove any bad TLS keys by 1.8.0-1
 
99
    if dpkg --compare-versions "$2" eq "1.8.0-1" \
 
100
       || dpkg --compare-versions "$2" eq "1.8.0-1~bpo9+1"; then
 
101
        # Is the key bad?
 
102
        if ! certtool --password='' \
 
103
             --load-privkey=/etc/keys/mandos/tls-privkey.pem \
 
104
             --outfile=/dev/null --pubkey-info --no-text \
 
105
              1>&2 2>/dev/null; then
 
106
            shred --remove -- /etc/keys/mandos/tls-privkey.pem \
 
107
                  2>/dev/null || :
 
108
            rm --force -- /etc/keys/mandos/tls-pubkey.pem
 
109
        fi
 
110
    fi
 
111
 
 
112
    # If the TLS keys already exists, do nothing
 
113
    if [ -r /etc/keys/mandos/tls-privkey.pem \
 
114
            -a -r /etc/keys/mandos/tls-pubkey.pem ]; then
 
115
        return 0
 
116
    fi
 
117
 
 
118
    # Try to create the TLS keys
 
119
 
 
120
    TLS_PRIVKEYTMP="`mktemp -t mandos-client-privkey.XXXXXXXXXX`"
 
121
 
 
122
    if certtool --generate-privkey --password='' \
 
123
                --outfile "$TLS_PRIVKEYTMP" --sec-param ultra \
 
124
                --key-type=ed25519 --pkcs8 --no-text 1>&2 \
 
125
                2>/dev/null; then
 
126
 
 
127
        local umask=$(umask)
 
128
        umask 077
 
129
        cp --archive "$TLS_PRIVKEYTMP" /etc/keys/mandos/tls-privkey.pem
 
130
        shred --remove -- "$TLS_PRIVKEYTMP" 2>/dev/null || :
 
131
 
 
132
        # First try certtool from GnuTLS
 
133
        if ! certtool --password='' \
 
134
             --load-privkey=/etc/keys/mandos/tls-privkey.pem \
 
135
             --outfile=/etc/keys/mandos/tls-pubkey.pem --pubkey-info \
 
136
             --no-text 1>&2 2>/dev/null; then
 
137
            # Otherwise try OpenSSL
 
138
            if ! openssl pkey -in /etc/keys/mandos/tls-privkey.pem \
 
139
                 -out /etc/keys/mandos/tls-pubkey.pem -pubout \
 
140
                 1>&2; then
 
141
                rm --force /etc/keys/mandos/tls-pubkey.pem
 
142
                # None of the commands succeded; give up
 
143
                umask $umask
 
144
                return 1
 
145
            fi
 
146
        fi
 
147
        umask $umask
 
148
 
 
149
        key_id=$(mandos-keygen --passfile=/dev/null \
 
150
                     | grep --regexp="^key_id[ =]")
 
151
 
 
152
        db_version 2.0
 
153
        db_fset mandos-client/key_id seen false
 
154
        db_reset mandos-client/key_id
 
155
        db_subst mandos-client/key_id key_id $key_id
 
156
        db_input critical mandos-client/key_id || true
 
157
        db_go
 
158
        db_stop
 
159
    else
 
160
        shred --remove -- "$TLS_PRIVKEYTMP" 2>/dev/null || :
 
161
    fi
 
162
}
 
163
 
 
164
create_dh_params(){
 
165
    if [ -r /etc/keys/mandos/dhparams.pem ]; then
 
166
        return 0
 
167
    fi
 
168
    # Create a Diffe-Hellman parameters file
 
169
    DHFILE="`mktemp -t mandos-client-dh-parameters.XXXXXXXXXX.pem`"
 
170
    # First try certtool from GnuTLS
 
171
    if ! certtool --generate-dh-params --sec-param high \
 
172
         --outfile "$DHFILE" 1>&2; then
 
173
        # Otherwise try OpenSSL
 
174
        if ! openssl genpkey -genparam -algorithm DH -out "$DHFILE" \
 
175
             -pkeyopt dh_paramgen_prime_len:3072 1>&2; then
 
176
            # None of the commands succeded; give up
 
177
            rm --force -- "$DHFILE"
 
178
            return 1
 
179
        fi
 
180
    fi
 
181
    sed --in-place --expression='0,/^-----BEGIN DH PARAMETERS-----$/d' \
 
182
        "$DHFILE"
 
183
    sed --in-place --expression='1i-----BEGIN DH PARAMETERS-----' \
 
184
            "$DHFILE"
 
185
    cp --archive "$DHFILE" /etc/keys/mandos/dhparams.pem
 
186
    rm --force -- "$DHFILE"
 
187
}
 
188
 
 
189
case "$1" in
 
190
    configure)
 
191
        add_mandos_user "$@"
 
192
        create_keys "$@"
 
193
        create_dh_params "$@" || :
 
194
        update_initramfs "$@"
 
195
        if dpkg --compare-versions "$2" lt-nl "1.7.10-1"; then
 
196
            PLUGINHELPERDIR=/usr/lib/$(dpkg-architecture -qDEB_HOST_MULTIARCH 2>/dev/null)/mandos/plugin-helpers
 
197
            if ! dpkg-statoverride --list "$PLUGINHELPERDIR" \
 
198
                 >/dev/null 2>&1; then
 
199
                chmod u=rwx,go= -- "$PLUGINHELPERDIR"
 
200
            fi
 
201
            if ! dpkg-statoverride --list /etc/mandos/plugin-helpers \
 
202
                 >/dev/null 2>&1; then
 
203
                chmod u=rwx,go= -- /etc/mandos/plugin-helpers
 
204
            fi
 
205
        fi
 
206
        ;;
 
207
    abort-upgrade|abort-deconfigure|abort-remove)
 
208
        ;;
 
209
 
 
210
    *)
 
211
        echo "$0 called with unknown argument '$1'" 1>&2
 
212
        exit 1
 
213
        ;;
 
214
esac
 
215
 
 
216
#DEBHELPER#
 
217
 
 
218
exit 0