/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 initramfs-tools-hook

  • Committer: Teddy Hogeborn
  • Date: 2018-08-15 09:26:02 UTC
  • Revision ID: teddy@recompile.se-20180815092602-xoyb5s6gf8376i7u
mandos-client: Set system clock if necessary

* plugins.d/mandos-client.c (init_gpgme/import_key): If the system
  clock is not set, or set to january 1970, set the system clock to
  the more plausible value that is the mtime of the key file.  This is
  required by GnuPG to be able to import the keys.  (We can't pass the
  --ignore-time-conflict or the --ignore-valid-from options though
  GPGME.)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
#!/bin/sh
2
2
 
3
 
#
4
 
# This is an example hook script.  It will be run by 'mkinitramfs'
5
 
# when it creates the image.  It's job is to decide which files to
6
 
# install, then install them into the staging area, where the
7
 
# initramfs is being created.  This happens when a new 'linux-image'
8
 
# package is installed, or when the administrator runs 'mkinitramfs'
9
 
# by hand to update an initramfs image.
10
 
#
11
 
# TODO: What about the case where you install something that should be
12
 
#       added to the initramfs, but the linux-image it relates to has
13
 
#       already been installed previously?  Does this happen often
14
 
#       enough that it needs to be handled?  How can it be handled?
15
 
#
16
 
#       * Think about the 'usplash'.  The initramfs will need to be
17
 
#        updated if a theme change or update is desired.  Maybe it
18
 
#        should not be totally automatic, but offered on upgrade
19
 
#        predicated on a user response to a debconf question?  That
20
 
#        issue needs to be explored and a solution specified.
21
 
#
22
 
#  * Do not assume that any needed subdirectories have been created
23
 
#       yet, but don't bail out if they are already there.
24
 
#
25
 
#  * All of the standard system tools are available, of course, since
26
 
#       this hook is running in the real system, not the initramfs.
27
 
#
28
 
#  * TODO: ... ?  Anything else to tell them in this bullet-list?
29
 
#
 
3
# This script will be run by 'mkinitramfs' when it creates the image.
 
4
# Its job is to decide which files to install, then install them into
 
5
# the staging area, where the initramfs is being created.  This
 
6
# happens when a new 'linux-image' package is installed, or when an
 
7
# administrator runs 'update-initramfs' by hand to update an initramfs
 
8
# image.
30
9
 
31
 
#
32
10
# The environment contains at least:
33
11
#
34
 
#  CONFDIR -- usually /etc/mkinitramfs, can be set on mkinitramfs
35
 
#                command line.
36
 
#
37
 
#  DESTDIR -- The staging directory where we are building the image.
38
 
#
39
 
# TODO: Decide what environment variables are meaningful and defined
40
 
#       in this context, then document them as part of the interface.
41
 
#
42
 
# TODO: May need a version_compare function for comparison of VERSION?
43
 
 
44
 
 
45
 
#
46
 
# List the soft prerequisites here.  This is a space separated list of
47
 
# names, of scripts that are in the same directory as this one, that
48
 
# must be run before this one can be.
49
 
#
 
12
#  DESTDIR -- The staging directory where the image is being built.
 
13
 
 
14
# No initramfs pre-requirements
50
15
PREREQ="cryptroot"
51
16
 
52
17
prereqs()
62
27
        ;;
63
28
esac
64
29
 
65
 
 
66
 
# You can do anything you need to from here on.
67
 
#
68
 
 
69
 
# Source the optional 'hook-functions' scriptlet, if you need the
70
 
# functions defined within it.  Read it to see what is available to
71
 
# you.  It contains functions for copying dynamically linked program
72
 
# binaries, and kernel modules into the DESTDIR.
73
 
#
74
30
. /usr/share/initramfs-tools/hook-functions
75
31
 
 
32
for d in /usr/lib \
 
33
    "/usr/lib/`dpkg-architecture -qDEB_HOST_MULTIARCH 2>/dev/null`" \
 
34
    "`rpm --eval='%{_libdir}' 2>/dev/null`" /usr/local/lib; do
 
35
    if [ -d "$d"/mandos ]; then
 
36
        libdir="$d"
 
37
        break
 
38
    fi
 
39
done
 
40
if [ -z "$libdir" ]; then
 
41
    # Mandos not found
 
42
    exit 1
 
43
fi
 
44
 
 
45
for d in /etc/keys/mandos /etc/mandos/keys; do
 
46
    if [ -d "$d" ]; then
 
47
        keydir="$d"
 
48
        break
 
49
    fi
 
50
done
 
51
if [ -z "$keydir" ]; then
 
52
    # Mandos key directory not found
 
53
    exit 1
 
54
fi
 
55
 
 
56
set `{ getent passwd _mandos \
 
57
    || getent passwd nobody \
 
58
    || echo ::65534:65534:::; } \
 
59
    | cut --delimiter=: --fields=3,4 --only-delimited \
 
60
    --output-delimiter=" "`
 
61
mandos_user="$1"
 
62
mandos_group="$2"
 
63
 
 
64
# The Mandos network client uses the network
76
65
auto_add_modules net
77
 
# force_load tg3
 
66
# The Mandos network client uses IPv6
78
67
force_load ipv6
79
68
 
 
69
# These are directories inside the initrd
80
70
CONFDIR="/conf/conf.d/mandos"
81
 
DESTCONFDIR="${DESTDIR}${CONFDIR}"
82
 
mkdir --parents "${DESTCONFDIR}"
83
 
PLUGINDIR="${CONFDIR}/plugins.d"
84
 
mkdir --parents "${DESTDIR}${PLUGINDIR}"
85
 
 
86
 
# We don't need to copy_exec mandos-client, hooks/cryptroot will do
87
 
# that.  That will not copy the plugins, however, so we do that here.
88
 
 
89
 
# The standard plugins
90
 
for file in /usr/lib/mandos/plugins.d/*; do
 
71
MANDOSDIR="/lib/mandos"
 
72
PLUGINDIR="${MANDOSDIR}/plugins.d"
 
73
PLUGINHELPERDIR="${MANDOSDIR}/plugin-helpers"
 
74
HOOKDIR="${MANDOSDIR}/network-hooks.d"
 
75
 
 
76
# Make directories
 
77
install --directory --mode=u=rwx,go=rx "${DESTDIR}${CONFDIR}" \
 
78
        "${DESTDIR}${MANDOSDIR}" "${DESTDIR}${HOOKDIR}"
 
79
install --owner=${mandos_user} --group=${mandos_group} --directory \
 
80
        --mode=u=rwx "${DESTDIR}${PLUGINDIR}" \
 
81
        "${DESTDIR}${PLUGINHELPERDIR}"
 
82
 
 
83
# Copy the Mandos plugin runner
 
84
copy_exec "$libdir"/mandos/plugin-runner "${MANDOSDIR}"
 
85
 
 
86
# Copy the plugins
 
87
 
 
88
# Copy the packaged plugins
 
89
for file in "$libdir"/mandos/plugins.d/*; do
91
90
    base="`basename \"$file\"`"
92
91
    # Is this plugin overridden?
93
92
    if [ -e "/etc/mandos/plugins.d/$base" ]; then
94
93
        continue
95
94
    fi
96
95
    case "$base" in
97
 
        *~|.*|\#*\#|*.dpkg-old|*.dpkg-new|*.dpkg-divert) : ;;
98
 
        *) copy_exec "$file" "${PLUGINDIR}";;
99
 
    esac
100
 
done
101
 
 
102
 
# Any user-supplied plugins
 
96
        *~|.*|\#*\#|*.dpkg-old|*.dpkg-bak|*.dpkg-new|*.dpkg-divert)
 
97
            : ;;
 
98
        "*") echo "W: Mandos client plugin directory is empty." >&2 ;;
 
99
        *) copy_exec "$file" "${PLUGINDIR}" ;;
 
100
    esac
 
101
done
 
102
 
 
103
# Copy the packaged plugin helpers
 
104
for file in "$libdir"/mandos/plugin-helpers/*; do
 
105
    base="`basename \"$file\"`"
 
106
    # Is this plugin overridden?
 
107
    if [ -e "/etc/mandos/plugin-helpers/$base" ]; then
 
108
        continue
 
109
    fi
 
110
    case "$base" in
 
111
        *~|.*|\#*\#|*.dpkg-old|*.dpkg-bak|*.dpkg-new|*.dpkg-divert)
 
112
            : ;;
 
113
        "*") : ;;
 
114
        *) copy_exec "$file" "${PLUGINHELPERDIR}" ;;
 
115
    esac
 
116
done
 
117
 
 
118
# Copy any user-supplied plugins
103
119
for file in /etc/mandos/plugins.d/*; do
104
120
    base="`basename \"$file\"`"
105
121
    case "$base" in
106
 
        *~|.*|*.dpkg-old|*.dpkg-new|*.dpkg-divert) : ;;
107
 
        *) copy_exec "$file" "${PLUGINDIR}";;
108
 
    esac
109
 
done
110
 
 
111
 
# GPGME needs /usr/bin/gpg
112
 
if [ -n "`ls \"${DESTDIR}\"/usr/lib/libgpgme.so* 2>/dev/null`" ]; then
113
 
    copy_exec /usr/bin/gpg
 
122
        *~|.*|\#*\#|*.dpkg-old|*.dpkg-bak|*.dpkg-new|*.dpkg-divert)
 
123
            : ;;
 
124
        "*") : ;;
 
125
        *) copy_exec "$file" "${PLUGINDIR}" ;;
 
126
    esac
 
127
done
 
128
 
 
129
# Copy any user-supplied plugin helpers
 
130
for file in /etc/mandos/plugin-helpers/*; do
 
131
    base="`basename \"$file\"`"
 
132
    case "$base" in
 
133
        *~|.*|\#*\#|*.dpkg-old|*.dpkg-bak|*.dpkg-new|*.dpkg-divert)
 
134
            : ;;
 
135
        "*") : ;;
 
136
        *) copy_exec "$file" "${PLUGINHELPERDIR}" ;;
 
137
    esac
 
138
done
 
139
 
 
140
# Get DEVICE from initramfs.conf and other files
 
141
. /etc/initramfs-tools/initramfs.conf
 
142
for conf in /etc/initramfs-tools/conf.d/*; do
 
143
    if [ -n `basename \"$conf\" | grep '^[[:alnum:]][[:alnum:]\._-]*$' \
 
144
        | grep -v '\.dpkg-.*$'` ]; then
 
145
        [ -f "${conf}" ] && . "${conf}"
 
146
    fi
 
147
done
 
148
export DEVICE
 
149
 
 
150
# Copy network hooks
 
151
for hook in /etc/mandos/network-hooks.d/*; do
 
152
    case "`basename \"$hook\"`" in
 
153
        "*") continue ;;
 
154
        *[!A-Za-z0-9_.-]*) continue ;;
 
155
        *) test -d "$hook" || copy_exec "$hook" "${HOOKDIR}" ;;
 
156
    esac
 
157
    if [ -x "$hook" ]; then
 
158
        # Copy any files needed by the network hook
 
159
        MANDOSNETHOOKDIR=/etc/mandos/network-hooks.d MODE=files \
 
160
            VERBOSITY=0 "$hook" files | while read -r file target; do
 
161
            if [ ! -e "${file}" ]; then
 
162
                echo "WARNING: file ${file} not found, requested by Mandos network hook '${hook##*/}'" >&2
 
163
            fi
 
164
            if [ -z "${target}" ]; then
 
165
                copy_exec "$file"
 
166
            else
 
167
                copy_exec "$file" "$target"
 
168
            fi
 
169
        done
 
170
        # Copy and load any modules needed by the network hook
 
171
        MANDOSNETHOOKDIR=/etc/mandos/network-hooks.d MODE=modules \
 
172
            VERBOSITY=0 "$hook" modules | while read -r module; do
 
173
            force_load "$module"
 
174
        done
 
175
    fi
 
176
done
 
177
 
 
178
# GPGME needs GnuPG
 
179
gpg=/usr/bin/gpg
 
180
libgpgme11_version="`dpkg-query --showformat='${Version}' --show libgpgme11`"
 
181
if dpkg --compare-versions "$libgpgme11_version" ge 1.5.0-0.1; then
 
182
    if [ -e /usr/bin/gpgconf ]; then
 
183
        if [ ! -e "${DESTDIR}/usr/bin/gpgconf" ]; then
 
184
            copy_exec /usr/bin/gpgconf
 
185
        fi
 
186
        gpg="`/usr/bin/gpgconf|sed --quiet --expression='s/^gpg:[^:]*://p'`"
 
187
        gpgagent="`/usr/bin/gpgconf|sed --quiet --expression='s/^gpg-agent:[^:]*://p'`"
 
188
        # Newer versions of GnuPG 2 requires the gpg-agent binary
 
189
        if [ -e "$gpgagent" ] && [ ! -e "${DESTDIR}$gpgagent" ]; then
 
190
            copy_exec "$gpgagent"
 
191
        fi
 
192
    fi
 
193
elif dpkg --compare-versions "$libgpgme11_version" ge 1.4.1-0.1; then
 
194
    gpg=/usr/bin/gpg2
 
195
fi
 
196
if [ ! -e "${DESTDIR}$gpg" ]; then
 
197
    copy_exec "$gpg"
 
198
fi
 
199
unset gpg
 
200
unset libgpgme11_version
 
201
 
 
202
# Config files
 
203
for file in /etc/mandos/plugin-runner.conf; do
 
204
    if [ -d "$file" ]; then
 
205
        continue
 
206
    fi
 
207
    cp --archive --sparse=always "$file" "${DESTDIR}${CONFDIR}"
 
208
done
 
209
 
 
210
if [ ${mandos_user} != 65534 ]; then
 
211
    sed --in-place --expression="1i--userid=${mandos_user}" \
 
212
        "${DESTDIR}${CONFDIR}/plugin-runner.conf"
 
213
fi
 
214
 
 
215
if [ ${mandos_group} != 65534 ]; then
 
216
    sed --in-place --expression="1i--groupid=${mandos_group}" \
 
217
        "${DESTDIR}${CONFDIR}/plugin-runner.conf"
114
218
fi
115
219
 
116
220
# Key files
117
 
for file in /etc/mandos/*; do
 
221
for file in "$keydir"/*; do
118
222
    if [ -d "$file" ]; then
119
223
        continue
120
224
    fi
121
 
    cp --archive --sparse=always "$file" "${DESTCONFDIR}"
 
225
    case "$file" in
 
226
        *~|.*|\#*\#|*.dpkg-old|*.dpkg-bak|*.dpkg-new|*.dpkg-divert)
 
227
            : ;;
 
228
        "*") : ;;
 
229
        *)
 
230
            cp --archive --sparse=always "$file" \
 
231
               "${DESTDIR}${CONFDIR}"
 
232
            chown ${mandos_user}:${mandos_group} \
 
233
                  "${DESTDIR}${CONFDIR}/`basename \"$file\"`"
 
234
            ;;
 
235
    esac
122
236
done
123
 
# Create key ring files
124
 
gpg --no-random-seed-file --quiet --batch --no-tty \
125
 
    --no-default-keyring --no-options --homedir "${DESTCONFDIR}" \
126
 
    --no-permission-warning --import-options import-minimal \
127
 
    --import "${DESTCONFDIR}/seckey.txt"
128
 
chown nobody "${DESTCONFDIR}/secring.gpg"
 
237
# Use Diffie-Hellman parameters file if available
 
238
if [ -e "${DESTDIR}${CONFDIR}"/dhparams.pem ]; then
 
239
    sed --in-place \
 
240
        --expression="1i--options-for=mandos-client:--dh-params=${CONFDIR}/dhparams.pem" \
 
241
        "${DESTDIR}/${CONFDIR}/plugin-runner.conf"
 
242
fi
129
243
 
130
 
# /keyscripts/mandos-client will drop priviliges, but needs access to
131
 
# its plugin directory.  However, since almost all files in initrd
132
 
# have been created with umask 027, this opening of permissions is needed.
 
244
# /lib/mandos/plugin-runner will drop priviliges, but needs access to
 
245
# its plugin directory and its config file.  However, since almost all
 
246
# files in initrd have been created with umask 027, this opening of
 
247
# permissions is needed.
133
248
134
249
# (The umask is not really intended to affect the files inside the
135
 
# initrd, but the initrd.img file itself, since it now contains secret
136
 
# key files.  There is, however, no other way to set the permission of
137
 
# the initrd.img file without a race condition. This umask is set by
138
 
# "/usr/share/initramfs-tools/conf-hooks.d/mandos".)
 
250
# initrd; it is intended to affect the initrd.img file itself, since
 
251
# it now contains secret key files.  There is, however, no other way
 
252
# to set the permission of the initrd.img file without a race
 
253
# condition.  This umask is set by "initramfs-tools-hook-conf",
 
254
# installed as "/usr/share/initramfs-tools/conf-hooks.d/mandos".)
139
255
140
 
full="${PLUGINDIR}"
141
 
while [ "$full" != "/" ]; do
142
 
    chmod a+rX "${DESTDIR}$full"
143
 
    full="`dirname \"$full\"`"
 
256
for full in "${MANDOSDIR}" "${CONFDIR}"; do
 
257
    while [ "$full" != "/" ]; do
 
258
        chmod a+rX "${DESTDIR}$full"
 
259
        full="`dirname \"$full\"`"
 
260
    done
144
261
done
 
262
 
 
263
# Reset some other things to sane permissions which we have
 
264
# inadvertently affected with our umask setting.
145
265
for dir in / /bin /etc /keyscripts /sbin /scripts /usr /usr/bin; do
146
 
    chmod a+rX "${DESTDIR}$dir"
 
266
    if [ -d "${DESTDIR}$dir" ]; then
 
267
        chmod a+rX "${DESTDIR}$dir"
 
268
    fi
147
269
done
148
 
for dir in /lib /usr/lib; do
149
 
    chmod --recursive a+rX "${DESTDIR}$dir"
 
270
for dir in "${DESTDIR}"/lib* "${DESTDIR}"/usr/lib*; do
 
271
    if [ -d "$dir" ]; then
 
272
        find "$dir" \! -perm -u+rw,g+r -prune -or \! -type l -print0 \
 
273
            | xargs --null --no-run-if-empty chmod a+rX --
 
274
    fi
150
275
done