=== modified file '.bzrignore' --- .bzrignore 2019-12-04 23:52:20 +0000 +++ .bzrignore 2024-09-12 02:53:43 +0000 @@ -14,3 +14,6 @@ plugins.d/plymouth plugin-helpers/mandos-client-iprouteadddel dracut-module/password-agent +cl +.mypy_cache +*.c.local === modified file 'Makefile' --- Makefile 2023-02-08 00:05:18 +0000 +++ Makefile 2024-09-11 22:44:07 +0000 @@ -29,7 +29,8 @@ # For info about _FORTIFY_SOURCE, see feature_test_macros(7) # and . -FORTIFY:=-D_FORTIFY_SOURCE=3 -fstack-protector-all -fPIC +FORTIFY:=-fstack-protector-all -fPIC +CPPFLAGS+=-D_FORTIFY_SOURCE=3 LINK_FORTIFY_LD:=-z relro -z now LINK_FORTIFY:= @@ -41,7 +42,7 @@ #COVERAGE=--coverage OPTIMIZE:=-Os -fno-strict-aliasing LANGUAGE:=-std=gnu11 -FEATURES:=-D_FILE_OFFSET_BITS=64 +CPPFLAGS+=-D_FILE_OFFSET_BITS=64 -D_TIME_BITS=64 htmldir:=man version:=1.8.16 SED:=sed @@ -63,6 +64,7 @@ # DRACUTMODULE:=$(DESTDIR)/usr/lib/dracut/modules.d/90mandos # STATEDIR:=$(DESTDIR)/var/lib/mandos # LIBDIR:=$(PREFIX)/lib +# DBUSPOLICYDIR:=$(DESTDIR)/etc/dbus-1/system.d ## ## These settings are for a package-type install @@ -83,6 +85,7 @@ break; \ fi; \ done) +DBUSPOLICYDIR:=$(DESTDIR)/usr/share/dbus-1/system.d ## SYSTEMD:=$(DESTDIR)$(shell $(PKG_CONFIG) systemd \ @@ -108,7 +111,7 @@ # Do not change these two CFLAGS+=$(WARN) $(DEBUG) $(FORTIFY) $(COVERAGE) $(OPTIMIZE) \ - $(LANGUAGE) $(FEATURES) -DVERSION='"$(version)"' + $(LANGUAGE) -DVERSION='"$(version)"' LDFLAGS+=-Xlinker --as-needed $(COVERAGE) $(LINK_FORTIFY) $(strip \ ) $(foreach flag,$(LINK_FORTIFY_LD),-Xlinker $(flag)) @@ -286,6 +289,16 @@ --expression='s/\(mandos_\)[0-9.]\+\(\.orig\.tar\.gz\)/\1$(version)\2/' \ $@) +# Does the linker support the --no-warn-execstack option? +ifeq ($(shell echo 'int main(){}'|$(CC) --language=c /dev/stdin -o /dev/null -Xlinker --no-warn-execstack >/dev/null 2>&1 && echo yes),yes) +# These programs use nested functions, which uses an executable stack +plugin-runner: LDFLAGS += -Xlinker --no-warn-execstack +dracut-module/password-agent: LDFLAGS += -Xlinker --no-warn-execstack +plugins.d/password-prompt: LDFLAGS += -Xlinker --no-warn-execstack +plugins.d/mandos-client: LDFLAGS += -Xlinker --no-warn-execstack +plugins.d/plymouth: LDFLAGS += -Xlinker --no-warn-execstack +endif + # Need to add the GnuTLS, Avahi and GPGME libraries plugins.d/mandos-client: CFLAGS += $(GNUTLS_CFLAGS) $(strip \ ) $(AVAHI_CFLAGS) $(GPGME_CFLAGS) @@ -372,11 +385,9 @@ # Used by run-server confdir/mandos.conf: mandos.conf - install --directory confdir - install --mode=u=rw,go=r $^ $@ + install -D --mode=u=rw,go=r $^ $@ confdir/clients.conf: clients.conf keydir/seckey.txt keydir/tls-pubkey.pem - install --directory confdir - install --mode=u=rw $< $@ + install -D --mode=u=rw $< $@ # Add a client password ./mandos-keygen --dir keydir --password --no-ssh >> $@ statedir: @@ -387,50 +398,51 @@ .PHONY: install-html install-html: html - install --directory $(htmldir) - install --mode=u=rw,go=r --target-directory=$(htmldir) \ + install -D --mode=u=rw,go=r --target-directory=$(htmldir) \ $(htmldocs) .PHONY: install-server install-server: doc - install --directory $(CONFDIR) if install --directory --mode=u=rwx --owner=$(USER) \ --group=$(GROUP) $(STATEDIR); then \ :; \ elif install --directory --mode=u=rwx $(STATEDIR); then \ chown -- $(USER):$(GROUP) $(STATEDIR) || :; \ fi - if [ "$(TMPFILES)" != "$(DESTDIR)" \ - -a -d "$(TMPFILES)" ]; then \ - install --mode=u=rw,go=r tmpfiles.d-mandos.conf \ + if [ "$(TMPFILES)" != "$(DESTDIR)" ]; then \ + install -D --mode=u=rw,go=r tmpfiles.d-mandos.conf \ $(TMPFILES)/mandos.conf; \ fi - if [ "$(SYSUSERS)" != "$(DESTDIR)" \ - -a -d "$(SYSUSERS)" ]; then \ - install --mode=u=rw,go=r sysusers.d-mandos.conf \ + if [ "$(SYSUSERS)" != "$(DESTDIR)" ]; then \ + install -D --mode=u=rw,go=r sysusers.d-mandos.conf \ $(SYSUSERS)/mandos.conf; \ fi - install --mode=u=rwx,go=rx mandos $(PREFIX)/sbin/mandos + install --directory $(PREFIX)/sbin + install --mode=u=rwx,go=rx --target-directory=$(PREFIX)/sbin \ + mandos install --mode=u=rwx,go=rx --target-directory=$(PREFIX)/sbin \ mandos-ctl install --mode=u=rwx,go=rx --target-directory=$(PREFIX)/sbin \ mandos-monitor + install --directory $(CONFDIR) install --mode=u=rw,go=r --target-directory=$(CONFDIR) \ mandos.conf install --mode=u=rw --target-directory=$(CONFDIR) \ clients.conf - install --mode=u=rw,go=r dbus-mandos.conf \ - $(DESTDIR)/etc/dbus-1/system.d/mandos.conf - install --mode=u=rwx,go=rx init.d-mandos \ + install -D --mode=u=rw,go=r dbus-mandos.conf \ + $(DBUSPOLICYDIR)/mandos.conf + install -D --mode=u=rwx,go=rx init.d-mandos \ $(DESTDIR)/etc/init.d/mandos - if [ "$(SYSTEMD)" != "$(DESTDIR)" -a -d "$(SYSTEMD)" ]; then \ - install --mode=u=rw,go=r mandos.service $(SYSTEMD); \ + if [ "$(SYSTEMD)" != "$(DESTDIR)" ]; then \ + install -D --mode=u=rw,go=r mandos.service \ + $(SYSTEMD); \ fi - install --mode=u=rw,go=r default-mandos \ + install -D --mode=u=rw,go=r default-mandos \ $(DESTDIR)/etc/default/mandos if [ -z $(DESTDIR) ]; then \ update-rc.d mandos defaults 25 15;\ fi + install --directory $(MANDIR)/man8 $(MANDIR)/man5 gzip --best --to-stdout mandos.8 \ > $(MANDIR)/man8/mandos.8.gz gzip --best --to-stdout mandos-monitor.8 \ @@ -446,27 +458,26 @@ .PHONY: install-client-nokey install-client-nokey: all doc - install --directory $(LIBDIR)/mandos $(CONFDIR) install --directory --mode=u=rwx $(KEYDIR) \ $(LIBDIR)/mandos/plugins.d \ $(LIBDIR)/mandos/plugin-helpers - if [ "$(SYSUSERS)" != "$(DESTDIR)" \ - -a -d "$(SYSUSERS)" ]; then \ - install --mode=u=rw,go=r sysusers.d-mandos.conf \ + if [ "$(SYSUSERS)" != "$(DESTDIR)" ]; then \ + install -D --mode=u=rw,go=r sysusers.d-mandos.conf \ $(SYSUSERS)/mandos-client.conf; \ fi if [ "$(CONFDIR)" != "$(LIBDIR)/mandos" ]; then \ - install --mode=u=rwx \ - --directory "$(CONFDIR)/plugins.d" \ + install --directory \ + --mode=u=rwx "$(CONFDIR)/plugins.d" \ "$(CONFDIR)/plugin-helpers"; \ fi - install --mode=u=rwx,go=rx --directory \ + install --directory --mode=u=rwx,go=rx \ "$(CONFDIR)/network-hooks.d" install --mode=u=rwx,go=rx \ --target-directory=$(LIBDIR)/mandos plugin-runner install --mode=u=rwx,go=rx \ --target-directory=$(LIBDIR)/mandos \ mandos-to-cryptroot-unlock + install --directory $(PREFIX)/sbin install --mode=u=rwx,go=rx --target-directory=$(PREFIX)/sbin \ mandos-keygen install --mode=u=rwx,go=rx \ @@ -490,18 +501,18 @@ install --mode=u=rwx,go=rx \ --target-directory=$(LIBDIR)/mandos/plugin-helpers \ plugin-helpers/mandos-client-iprouteadddel - install initramfs-tools-hook \ + install -D initramfs-tools-hook \ $(INITRAMFSTOOLS)/hooks/mandos - install --mode=u=rw,go=r initramfs-tools-conf \ + install -D --mode=u=rw,go=r initramfs-tools-conf \ $(INITRAMFSTOOLS)/conf.d/mandos-conf - install --mode=u=rw,go=r initramfs-tools-conf-hook \ + install -D --mode=u=rw,go=r initramfs-tools-conf-hook \ $(INITRAMFSTOOLS)/conf-hooks.d/zz-mandos - install initramfs-tools-script \ + install -D initramfs-tools-script \ $(INITRAMFSTOOLS)/scripts/init-premount/mandos - install initramfs-tools-script-stop \ + install -D initramfs-tools-script-stop \ $(INITRAMFSTOOLS)/scripts/local-premount/mandos - install --directory $(DRACUTMODULE) - install --mode=u=rw,go=r --target-directory=$(DRACUTMODULE) \ + install -D --mode=u=rw,go=r \ + --target-directory=$(DRACUTMODULE) \ dracut-module/ask-password-mandos.path \ dracut-module/ask-password-mandos.service install --mode=u=rwxs,go=rx \ @@ -510,6 +521,7 @@ dracut-module/cmdline-mandos.sh \ dracut-module/password-agent install --mode=u=rw,go=r plugin-runner.conf $(CONFDIR) + install --directory $(MANDIR)/man8 gzip --best --to-stdout mandos-keygen.8 \ > $(MANDIR)/man8/mandos-keygen.8.gz gzip --best --to-stdout plugin-runner.8mandos \ @@ -612,9 +624,11 @@ $(DESTDIR)/etc/dbus-1/system.d/mandos.conf $(DESTDIR)/etc/default/mandos \ $(DESTDIR)/etc/init.d/mandos \ - $(SYSTEMD)/mandos.service \ $(DESTDIR)/run/mandos.pid \ $(DESTDIR)/var/run/mandos.pid + if [ "$(SYSTEMD)" != "$(DESTDIR)" -a -d "$(SYSTEMD)" ]; then \ + -rm --force -- $(SYSTEMD)/mandos.service; \ + fi -rmdir $(CONFDIR) .PHONY: purge-client === modified file 'NEWS' --- NEWS 2023-02-08 00:05:18 +0000 +++ NEWS 2023-02-08 01:38:30 +0000 @@ -1,7 +1,7 @@ This NEWS file records noteworthy changes, very tersely. See the manual for detailed information. -Version 1.8.15 (2023-02-08) +Version 1.8.16 (2023-02-08) * Server ** Bug fix: Start client checkers after a random delay === modified file 'TODO' --- TODO 2020-02-09 03:42:50 +0000 +++ TODO 2024-09-08 00:11:24 +0000 @@ -4,6 +4,7 @@ ** python-nemu * mandos-applet +** [[https://www.freedesktop.org/software/polkit/docs/latest/polkit-apps.html][Writing polkit applications]] * mandos-client ** TODO A ~--server~ option which only adds to the server list. === modified file 'debian/changelog' --- debian/changelog 2023-02-08 00:05:18 +0000 +++ debian/changelog 2024-09-09 03:16:17 +0000 @@ -1,3 +1,20 @@ +mandos (1.8.16-1.2) unstable; urgency=medium + + * Non-maintainer upload. + * Install mandos.service again. (Closes: #1069689) + + -- Helmut Grohne Mon, 22 Apr 2024 21:13:43 +0200 + +mandos (1.8.16-1.1) unstable; urgency=medium + + * Non-maintainer upload. + * Depend only on gnupg instead of transitional gnupg2 (Closes: #1055402). + * Build-Depend on systemd-dev instead of systemd (Closes: #1060546). + * Build-Depend on pkgconf instead of pkg-config. + * (Build-)Depend on current libgnutls. + + -- Bastian Germann Fri, 19 Apr 2024 13:08:30 +0200 + mandos (1.8.16-1) unstable; urgency=medium * New upstream release. === modified file 'debian/control' --- debian/control 2023-02-07 23:45:13 +0000 +++ debian/control 2024-09-09 03:08:13 +0000 @@ -8,10 +8,11 @@ libavahi-core-dev, libgpgme-dev | libgpgme11-dev, libglib2.0-dev (>=2.40), libgnutls28-dev (>= 3.3.0), libgnutls28-dev (>= 3.6.6) | libgnutls28-dev (<< 3.6.0), - xsltproc, pkg-config, libnl-route-3-dev, systemd + xsltproc, pkg-config, libnl-route-3-dev, + systemd-dev | systemd (<< 256~rc2-1) Build-Depends-Indep: python3 (>= 3), python3-dbus, python3-gi, po-debconf -Standards-Version: 4.6.2 +Standards-Version: 4.7.0 Vcs-Bzr: https://ftp.recompile.se/pub/mandos/trunk Vcs-Browser: https://bzr.recompile.se/loggerhead/mandos/trunk/files Homepage: https://www.recompile.se/mandos @@ -19,11 +20,11 @@ Package: mandos Architecture: all -Depends: ${misc:Depends}, python3 (>= 3), libgnutls30 (>= 3.3.0), - libgnutls30 (>= 3.6.6) | libgnutls30 (<< 3.6.0), +Depends: ${misc:Depends}, python3 (>= 3), + libgnutls30t64 | libgnutls30 (>= 3.3.0), + libgnutls30t64 | libgnutls30 (>= 3.6.6) | libgnutls30 (<< 3.6.0), python3-dbus, python3-gi, avahi-daemon, adduser, - python3-urwid, gnupg2 | gnupg, - systemd-sysv | lsb-base (>= 3.0-6), + python3-urwid, gnupg, systemd-sysv | lsb-base (>= 3.0-6), debconf (>= 1.5.5) | debconf-2.0 Recommends: ssh-client | fping Suggests: libc6-dev | libc-dev, c-compiler === modified file 'debian/mandos-client.README.Debian' --- debian/mandos-client.README.Debian 2019-07-27 10:11:45 +0000 +++ debian/mandos-client.README.Debian 2024-09-08 00:24:32 +0000 @@ -75,7 +75,7 @@ Any plugins found in "/etc/mandos/plugins.d" will override and add to the normal Mandos plugins. When adding or changing plugins, do - not forget to update the initital RAM disk image: + not forget to update the initial RAM disk image: (For initramfs-tools:) update-initramfs -k all -u @@ -100,20 +100,24 @@ "mandos=connect::" on the kernel command line. - For very advanced users, it is possible to specify simply - "mandos=connect" on the kernel command line to make the system only - set up the network (using the data in the "ip=" option) and not pass - any extra "--connect" options to mandos-client at boot. For this to - work, "--options-for=mandos-client:--connect=
:" needs - to be manually added to the file "/etc/mandos/plugin-runner.conf". + For very advanced users, it is possible to specify "mandos=connect" + on the kernel command line to make the system only set up the + network (using the data in the "ip=" option) and not pass any extra + "--connect" options to mandos-client at boot. For this to work, + "--options-for=mandos-client:--connect=
:" needs to be + manually added to the file "/etc/mandos/plugin-runner.conf" or, if + dracut is used with systemd, the "--connect=
:" + options needs to be added to an environment variable in an override + file for the "ask-password-mandos" service, as detailed in the file + "/usr/lib/dracut/modules.d/90mandos/ask-password-mandos.service". * Diffie-Hellman Parameters On installation, a file with Diffie-Hellman parameters, /etc/keys/mandos/dhparams.pem, will be generated and automatically - installed into the initital RAM disk image and also used by the + installed into the initial RAM disk image and also used by the Mandos Client on boot. If different parameters are needed for policy or other reasons, simply replace the existing dhparams.pem - file and update the initital RAM disk image. + file and update the initial RAM disk image. - -- Teddy Hogeborn , Mon, 15 Jul 2019 16:47:02 +0200 + -- Teddy Hogeborn , Sun, 8 Sep 2024 02:09:20 +0200 === modified file 'debian/mandos-client.dirs' --- debian/mandos-client.dirs 2019-08-18 04:14:31 +0000 +++ debian/mandos-client.dirs 2024-09-08 17:17:22 +0000 @@ -5,4 +5,3 @@ usr/share/initramfs-tools/conf-hooks.d usr/share/initramfs-tools/scripts/init-premount usr/share/initramfs-tools/scripts/local-premount -usr/lib/sysusers.d === modified file 'debian/mandos-client.lintian-overrides' --- debian/mandos-client.lintian-overrides 2022-04-23 21:14:38 +0000 +++ debian/mandos-client.lintian-overrides 2024-09-09 02:51:47 +0000 @@ -1,31 +1,31 @@ # This directory contains secret client key files. -mandos-client binary: non-standard-dir-perm etc/keys/mandos/ 0700 != 0755 +mandos-client binary: non-standard-dir-perm 0700 != 0755 [etc/keys/mandos/] # The directory /usr/lib//mandos/plugins.d contains setuid # binaries which are only meant to be run inside an initial RAM disk # environment (except for test purposes). It would be insecure to # allow anyone to run them. -mandos-client binary: non-standard-dir-perm usr/lib/*/mandos/plugins.d/ 0700 != 0755 +mandos-client binary: non-standard-dir-perm 0700 != 0755 [usr/lib/*/mandos/plugins.d/] # Likewise for helper executables for plugins -mandos-client binary: non-standard-dir-perm usr/lib/*/mandos/plugin-helpers/ 0700 != 0755 +mandos-client binary: non-standard-dir-perm 0700 != 0755 [usr/lib/*/mandos/plugin-helpers/] # These binaries must be setuid root, since they need root powers, but # are started by plugin-runner(8mandos), which runs all plugins as # user/group "_mandos". These binaries are never run in a running # system, but only in an initial RAM disk environment. Here they are # protected from non-root access by the directory permissions, above. -mandos-client binary: elevated-privileges usr/lib/*/mandos/plugins.d/mandos-client 4755 root/root -mandos-client binary: elevated-privileges usr/lib/*/mandos/plugins.d/askpass-fifo 4755 root/root -mandos-client binary: elevated-privileges usr/lib/*/mandos/plugins.d/splashy 4755 root/root -mandos-client binary: elevated-privileges usr/lib/*/mandos/plugins.d/usplash 4755 root/root -mandos-client binary: elevated-privileges usr/lib/*/mandos/plugins.d/plymouth 4755 root/root +mandos-client binary: elevated-privileges 4755 root/root [usr/lib/*/mandos/plugins.d/mandos-client] +mandos-client binary: elevated-privileges 4755 root/root [usr/lib/*/mandos/plugins.d/askpass-fifo] +mandos-client binary: elevated-privileges 4755 root/root [usr/lib/*/mandos/plugins.d/splashy] +mandos-client binary: elevated-privileges 4755 root/root [usr/lib/*/mandos/plugins.d/usplash] +mandos-client binary: elevated-privileges 4755 root/root [usr/lib/*/mandos/plugins.d/plymouth] # The directory /etc/mandos/plugins.d can be used by local system # administrators to place plugins in, overriding and complementing # /usr/lib//mandos/plugins.d, and must be likewise protected. -mandos-client binary: non-standard-dir-perm etc/mandos/plugins.d/ 0700 != 0755 +mandos-client binary: non-standard-dir-perm 0700 != 0755 [etc/mandos/plugins.d/] # Likewise for plugin-helpers directory -mandos-client binary: non-standard-dir-perm etc/mandos/plugin-helpers/ 0700 != 0755 +mandos-client binary: non-standard-dir-perm 0700 != 0755 [etc/mandos/plugin-helpers/] # The debconf templates is only used for displaying information # detected in the postinst, not for saving answers to questions, so we === modified file 'debian/mandos-client.postinst' --- debian/mandos-client.postinst 2019-07-27 10:11:45 +0000 +++ debian/mandos-client.postinst 2024-09-08 05:08:20 +0000 @@ -23,7 +23,7 @@ update_initramfs() { if command -v update-initramfs >/dev/null; then - update-initramfs -k all -u + update-initramfs -k all -u 1>&2 elif command -v dracut >/dev/null; then dracut_version="`dpkg-query --showformat='${Version}' --show dracut`" if dpkg --compare-versions "$dracut_version" lt 043-1 \ @@ -37,9 +37,21 @@ # Dracut preserves old permissions of initramfs image # files, so we adjust permissions before creating new # initramfs image containing secret keys. - chmod go-r /boot/initrd.img-"$kversion" + if [ -e /boot/initrd.img-"$kversion" ]; then + chmod go-r /boot/initrd.img-"$kversion" + else + # An initrd image has not yet been created for this + # kernel, possibly because this new kernel is about to + # be, but has not yet been, installed. In this case, + # we create an empty file with the right permissions + # so that Dracut will preserve those permissions when + # it creates the real, new initrd image for this + # kernel. + install --mode=u=rw /dev/null \ + /boot/initrd.img-"$kversion" + fi if [ "$kversion" != "*" ]; then - /etc/kernel/postinst.d/dracut "$kversion" + /etc/kernel/postinst.d/dracut "$kversion" 1>&2 fi done fi @@ -58,8 +70,8 @@ if dpkg --compare-versions "$2" lt "1.0.3-1"; then case "`getent passwd mandos`" in *:Mandos\ password\ system,,,:/nonexistent:/bin/false) - usermod --login _mandos mandos - groupmod --new-name _mandos mandos + usermod --login _mandos mandos 1>&2 + groupmod --new-name _mandos mandos 1>&2 return ;; esac @@ -68,7 +80,7 @@ if ! getent passwd _mandos >/dev/null; then adduser --system --force-badname --quiet --home /nonexistent \ --no-create-home --group --disabled-password \ - --gecos "Mandos password system" _mandos + --gecos "Mandos password system" _mandos 1>&2 fi } @@ -78,8 +90,8 @@ # mandos-keygen if ! [ -r /etc/keys/mandos/pubkey.txt \ -a -r /etc/keys/mandos/seckey.txt ]; then - mandos-keygen - gpg-connect-agent KILLAGENT /bye || : + mandos-keygen 1>&2 + gpg-connect-agent KILLAGENT /bye 1>&2 || : return 0 fi @@ -90,7 +102,7 @@ if ! certtool --password='' \ --load-privkey=/etc/keys/mandos/tls-privkey.pem \ --outfile=/dev/null --pubkey-info --no-text \ - 2>/dev/null; then + 1>&2 2>/dev/null; then shred --remove -- /etc/keys/mandos/tls-privkey.pem \ 2>/dev/null || : rm --force -- /etc/keys/mandos/tls-pubkey.pem @@ -109,7 +121,8 @@ if certtool --generate-privkey --password='' \ --outfile "$TLS_PRIVKEYTMP" --sec-param ultra \ - --key-type=ed25519 --pkcs8 --no-text 2>/dev/null; then + --key-type=ed25519 --pkcs8 --no-text 1>&2 \ + 2>/dev/null; then local umask=$(umask) umask 077 @@ -120,10 +133,11 @@ if ! certtool --password='' \ --load-privkey=/etc/keys/mandos/tls-privkey.pem \ --outfile=/etc/keys/mandos/tls-pubkey.pem --pubkey-info \ - --no-text 2>/dev/null; then + --no-text 1>&2 2>/dev/null; then # Otherwise try OpenSSL if ! openssl pkey -in /etc/keys/mandos/tls-privkey.pem \ - -out /etc/keys/mandos/tls-pubkey.pem -pubout; then + -out /etc/keys/mandos/tls-pubkey.pem -pubout \ + 1>&2; then rm --force /etc/keys/mandos/tls-pubkey.pem # None of the commands succeded; give up umask $umask @@ -155,12 +169,12 @@ DHFILE="`mktemp -t mandos-client-dh-parameters.XXXXXXXXXX.pem`" # First try certtool from GnuTLS if ! certtool --generate-dh-params --sec-param high \ - --outfile "$DHFILE"; then + --outfile "$DHFILE" 1>&2; then # Otherwise try OpenSSL if ! openssl genpkey -genparam -algorithm DH -out "$DHFILE" \ - -pkeyopt dh_paramgen_prime_len:3072; then + -pkeyopt dh_paramgen_prime_len:3072 1>&2; then # None of the commands succeded; give up - rm -- "$DHFILE" + rm --force -- "$DHFILE" return 1 fi fi @@ -169,7 +183,7 @@ sed --in-place --expression='1i-----BEGIN DH PARAMETERS-----' \ "$DHFILE" cp --archive "$DHFILE" /etc/keys/mandos/dhparams.pem - rm -- "$DHFILE" + rm --force -- "$DHFILE" } case "$1" in === modified file 'debian/mandos-client.postrm' --- debian/mandos-client.postrm 2019-08-05 14:31:51 +0000 +++ debian/mandos-client.postrm 2024-09-08 05:08:20 +0000 @@ -32,13 +32,13 @@ update_initramfs() { if command -v update-initramfs >/dev/null; then - update-initramfs -k all -u + update-initramfs -k all -u 1>&2 elif command -v dracut >/dev/null; then # Logic taken from dracut.postinst for kernel in /boot/vmlinu[xz]-*; do kversion="${kernel#/boot/vmlinu[xz]-}" if [ "$kversion" != "*" ]; then - /etc/kernel/postinst.d/dracut "$kversion" + /etc/kernel/postinst.d/dracut "$kversion" 1>&2 fi done fi @@ -50,7 +50,8 @@ ;; purge) - shred --remove /etc/keys/mandos/seckey.txt 2>/dev/null || : + shred --remove /etc/keys/mandos/seckey.txt \ + /etc/keys/mandos/tls-privkey.pem 2>/dev/null || : rm --force /etc/mandos/plugin-runner.conf \ /etc/keys/mandos/pubkey.txt \ /etc/keys/mandos/seckey.txt \ === modified file 'debian/mandos.dirs' --- debian/mandos.dirs 2019-08-18 00:23:21 +0000 +++ debian/mandos.dirs 2024-09-08 17:17:22 +0000 @@ -2,9 +2,6 @@ usr/share/man/man8 etc/init.d etc/default -etc/dbus-1/system.d usr/sbin var/lib/mandos -lib/systemd/system -usr/lib/tmpfiles.d -usr/lib/sysusers.d +usr/share/dbus-1/system.d === modified file 'debian/mandos.lintian-overrides' --- debian/mandos.lintian-overrides 2019-08-05 21:14:05 +0000 +++ debian/mandos.lintian-overrides 2024-09-09 02:51:47 +0000 @@ -1,7 +1,7 @@ # This config file will normally have encrypted secret client keys in # it, so it must be kept unreadable for non-root users. # -mandos binary: non-standard-file-perm etc/mandos/clients.conf 0600 != 0644 +mandos binary: non-standard-file-perm 0600 != 0644 [etc/mandos/clients.conf] # The debconf templates is only used for displaying information # detected in the postinst, not for saving answers to questions, so we === added file 'debian/mandos.maintscript' --- debian/mandos.maintscript 1970-01-01 00:00:00 +0000 +++ debian/mandos.maintscript 2023-02-12 17:49:24 +0000 @@ -0,0 +1,1 @@ +rm_conffile /etc/dbus-1/system.d/mandos.conf 1.8.17-1~ === modified file 'debian/rules' --- debian/rules 2023-02-07 19:40:12 +0000 +++ debian/rules 2024-09-08 17:17:22 +0000 @@ -9,9 +9,25 @@ MAKEFLAGS += -j$(NUMJOBS) endif +PKG_CONFIG?=pkg-config + %: dh $@ +override_dh_installdirs-indep: + dh_installdirs + dh_installdirs $(patsubst /%,%,$(shell $(PKG_CONFIG) \ + systemd --variable=systemdsystemunitdir)) \ + $(patsubst /%,%,$(shell $(PKG_CONFIG) \ + systemd --variable=tmpfilesdir)) \ + $(patsubst /%,%,$(shell $(PKG_CONFIG) \ + systemd --variable=sysusersdir)) + +override_dh_installdirs-arch: + dh_installdirs + dh_installdirs $(patsubst /%,%,$(shell $(PKG_CONFIG) \ + systemd --variable=sysusersdir)) + override_dh_auto_build-arch: LC_ALL=en_US.utf8 dh_auto_build -- all doc === modified file 'dracut-module/ask-password-mandos.service' --- dracut-module/ask-password-mandos.service 2020-07-04 11:58:52 +0000 +++ dracut-module/ask-password-mandos.service 2024-09-08 00:24:32 +0000 @@ -1,7 +1,7 @@ # -*- systemd -*- # -# Copyright © 2019-2020 Teddy Hogeborn -# Copyright © 2019-2020 Björn Påhlsson +# Copyright © 2019-2023 Teddy Hogeborn +# Copyright © 2019-2023 Björn Påhlsson # # This file is part of Mandos. # @@ -49,3 +49,26 @@ [Service] ExecStart=/lib/mandos/password-agent $PASSWORD_AGENT_OPTIONS -- /lib/mandos/mandos-client --pubkey=/etc/mandos/keys/pubkey.txt --seckey=/etc/mandos/keys/seckey.txt --tls-pubkey=/etc/mandos/keys/tls-pubkey.pem --tls-privkey=/etc/mandos/keys/tls-privkey.pem $MANDOS_CLIENT_OPTIONS +# +# Please keep the above line intact, exactly as it is! To add extra +# options to mandos-client, instead create an override file (e.g. with +# the command "systemctl edit --force ask-password-mandos.service"), +# and, in that file, put something like the following: +# +# [Service] +# Environment=MANDOS_CLIENT_OPTIONS=--debug +# +# Rebuild the initramfs using this command: +# +# dpkg-reconfigure dracut +# +# Once the system has booted (possibly by typing in the password +# manually), you can see the log using this command: +# +# journalctl --unit=ask-password-mandos.service +# +# Lastly, to remove the override file with extra options, run: +# +# systemctl revert ask-password-mandos.service +# +# And rebuild the initramfs again, as above. === modified file 'dracut-module/password-agent.c' --- dracut-module/password-agent.c 2023-02-07 19:50:53 +0000 +++ dracut-module/password-agent.c 2023-02-11 06:58:15 +0000 @@ -1488,7 +1488,15 @@ if(send_buffer == NULL){ error(0, errno, "Failed to allocate send_buffer"); } else { +#if defined(__GNUC__) and __GNUC__ >= 5 +#pragma GCC diagnostic push + /* mlock() does not access the memory */ +#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +#endif if(mlock(send_buffer, send_buffer_length) != 0){ +#if defined(__GNUC__) and __GNUC__ >= 5 +#pragma GCC diagnostic pop +#endif /* Warn but do not treat as fatal error */ if(errno != EPERM and errno != ENOMEM){ error(0, errno, "Failed to lock memory for password" @@ -4847,8 +4855,16 @@ memcpy(ievent->name, dummy_file_name, sizeof(dummy_file_name)); const size_t ievent_size = (sizeof(struct inotify_event) + sizeof(dummy_file_name)); +#if defined(__GNUC__) and __GNUC__ >= 11 +#pragma GCC diagnostic push + /* ievent is pointing into a struct which is of sufficient size */ +#pragma GCC diagnostic ignored "-Wstringop-overread" +#endif g_assert_cmpint(write(pipefds[1], (char *)ievent, ievent_size), ==, ievent_size); +#if defined(__GNUC__) and __GNUC__ >= 11 +#pragma GCC diagnostic pop +#endif g_assert_cmpint(close(pipefds[1]), ==, 0); bool quit_now = false; === modified file 'initramfs-tools-hook' --- initramfs-tools-hook 2020-02-09 17:57:08 +0000 +++ initramfs-tools-hook 2024-09-08 03:42:04 +0000 @@ -180,7 +180,7 @@ # GPGME needs GnuPG gpg=/usr/bin/gpg -libgpgme11_version="`dpkg-query --showformat='${Version}' --show libgpgme11`" +libgpgme11_version="`dpkg-query --showformat='${Version}\n' --show libgpgme11t64 libgpgme11 2>/dev/null | head --lines=1`" if dpkg --compare-versions "$libgpgme11_version" ge 1.5.0-0.1; then if [ -e /usr/bin/gpgconf ]; then if [ ! -e "${DESTDIR}/usr/bin/gpgconf" ]; then === modified file 'mandos' --- mandos 2023-02-08 00:05:18 +0000 +++ mandos 2024-09-08 02:18:57 +0000 @@ -961,8 +961,14 @@ # key_id() and fingerprint() functions client["key_id"] = (section.get("key_id", "").upper() .replace(" ", "")) - client["fingerprint"] = (section["fingerprint"].upper() + client["fingerprint"] = (section.get("fingerprint", + "").upper() .replace(" ", "")) + if not (client["key_id"] or client["fingerprint"]): + log.error("Skipping client %s without key_id or" + " fingerprint", client_name) + del settings[client_name] + continue if "secret" in section: client["secret"] = codecs.decode(section["secret"] .encode("utf-8"), === modified file 'mandos-ctl' --- mandos-ctl 2023-02-08 00:05:18 +0000 +++ mandos-ctl 2024-09-07 23:55:04 +0000 @@ -50,12 +50,15 @@ str = unicode input = raw_input + class gi: """Dummy gi module, for the tests""" class repository: class GLib: class Error(Exception): pass + + dbussy = None ravel = None dbus_python = None @@ -78,7 +81,7 @@ warnings.simplefilter("default") log = logging.getLogger(os.path.basename(sys.argv[0])) -logging.basicConfig(level="INFO", # Show info level messages +logging.basicConfig(level="INFO", # Show info level messages format="%(message)s") # Show basic log messages logging.captureWarnings(True) # Show warnings via the logging system @@ -392,7 +395,7 @@ def parse_pre_1_6_1_interval(interval): - """Parse an interval string as documented by Mandos before 1.6.1, + r"""Parse an interval string as documented by Mandos before 1.6.1, and return a datetime.timedelta >>> parse_pre_1_6_1_interval("7d") == datetime.timedelta(days=7) @@ -410,7 +413,8 @@ >>> parse_pre_1_6_1_interval("") == datetime.timedelta(0) True >>> # Ignore unknown characters, allow any order and repetitions - >>> parse_pre_1_6_1_interval("2dxy7zz11y3m5m") == datetime.timedelta(2, 480, 18000) + >>> parse_pre_1_6_1_interval("2dxy7zz11y3m5m") \ + ... == datetime.timedelta(2, 480, 18000) True """ @@ -485,12 +489,14 @@ class SystemBus: object_manager_iface = "org.freedesktop.DBus.ObjectManager" + def get_managed_objects(self, busname, objectpath): return self.call_method("GetManagedObjects", busname, objectpath, self.object_manager_iface) properties_iface = "org.freedesktop.DBus.Properties" + def set_property(self, busname, objectpath, interface, key, value): self.call_method("Set", busname, objectpath, @@ -501,7 +507,6 @@ interface, *args): raise NotImplementedError() - class MandosBus(SystemBus): busname_domain = "se.recompile" busname = busname_domain + ".Mandos" @@ -600,6 +605,7 @@ class SilenceLogger: "Simple context manager to silence a particular logger" + def __init__(self, loggername): self.logger = logging.getLogger(loggername) @@ -615,13 +621,14 @@ def __exit__(self, exc_type, exc_val, exc_tb): self.logger.removeFilter(self.nullfilter) - class CachingBus(SystemBus): """A caching layer for dbus_python_adapter.SystemBus""" + def __init__(self, *args, **kwargs): self.object_cache = {} super(dbus_python_adapter.CachingBus, self).__init__(*args, **kwargs) + def get_object(self, busname, objectpath): try: return self.object_cache[(busname, objectpath)] @@ -629,7 +636,7 @@ new_object = super( dbus_python_adapter.CachingBus, self).get_object(busname, objectpath) - self.object_cache[(busname, objectpath)] = new_object + self.object_cache[(busname, objectpath)] = new_object return new_object @@ -682,17 +689,19 @@ class CachingBus(SystemBus): """A caching layer for pydbus_adapter.SystemBus""" + def __init__(self, *args, **kwargs): self.object_cache = {} super(pydbus_adapter.CachingBus, self).__init__(*args, **kwargs) + def get(self, busname, objectpath): try: return self.object_cache[(busname, objectpath)] except KeyError: new_object = (super(pydbus_adapter.CachingBus, self) .get(busname, objectpath)) - self.object_cache[(busname, objectpath)] = new_object + self.object_cache[(busname, objectpath)] = new_object return new_object @@ -724,7 +733,7 @@ iface = proxy_object.get_interface(interface) method = getattr(iface, methodname) with self.convert_exception(dbus.Error): - value = method(*args) + value = method(*args) # DBussy returns values either as an empty list or as a # list of one element with the return value if value: @@ -771,10 +780,12 @@ class CachingBus(MandosBus): """A caching layer for dbussy_adapter.MandosBus""" + def __init__(self, *args, **kwargs): self.object_cache = {} super(dbussy_adapter.CachingBus, self).__init__(*args, **kwargs) + def get_object(self, busname, objectpath): try: return self.object_cache[(busname, objectpath)] @@ -782,7 +793,7 @@ new_object = super( dbussy_adapter.CachingBus, self).get_object(busname, objectpath) - self.object_cache[(busname, objectpath)] = new_object + self.object_cache[(busname, objectpath)] = new_object return new_object @@ -824,6 +835,7 @@ class Base: """Abstract base class for commands""" + def run(self, clients, bus=None): """Normal commands should implement run_on_one_client(), but commands which want to operate on all clients at the same time can @@ -833,7 +845,6 @@ for client, properties in clients.items(): self.run_on_one_client(client, properties) - class IsEnabled(Base): def run(self, clients, bus=None): properties = next(iter(clients.values())) @@ -841,23 +852,19 @@ sys.exit(0) sys.exit(1) - class Approve(Base): def run_on_one_client(self, client, properties): self.bus.call_client_method(client, "Approve", True) - class Deny(Base): def run_on_one_client(self, client, properties): self.bus.call_client_method(client, "Approve", False) - class Remove(Base): def run(self, clients, bus): for clientpath in frozenset(clients.keys()): bus.call_server_method("RemoveClient", clientpath) - class Output(Base): """Abstract class for commands outputting client details""" all_keywords = ("Name", "Enabled", "Timeout", "LastCheckedOK", @@ -869,7 +876,6 @@ "Checker", "ExtendedTimeout", "Expires", "LastCheckerStatus") - class DumpJSON(Output): def run(self, clients, bus=None): data = {properties["Name"]: @@ -878,7 +884,6 @@ for properties in clients.values()} print(json.dumps(data, indent=4, separators=(",", ": "))) - class PrintTable(Output): def __init__(self, verbose=False): self.verbose = verbose @@ -924,6 +929,7 @@ if sys.version_info.major == 2: __unicode__ = __str__ + def __str__(self): return str(self).encode( locale.getpreferredencoding()) @@ -975,7 +981,6 @@ minutes=(td.seconds % 3600) // 60, seconds=td.seconds % 60)) - class PropertySetter(Base): "Abstract class for Actions for setting one client property" @@ -988,45 +993,38 @@ def propname(self): raise NotImplementedError() - class Enable(PropertySetter): propname = "Enabled" value_to_set = True - class Disable(PropertySetter): propname = "Enabled" value_to_set = False - class BumpTimeout(PropertySetter): propname = "LastCheckedOK" value_to_set = "" - class StartChecker(PropertySetter): propname = "CheckerRunning" value_to_set = True - class StopChecker(PropertySetter): propname = "CheckerRunning" value_to_set = False - class ApproveByDefault(PropertySetter): propname = "ApprovedByDefault" value_to_set = True - class DenyByDefault(PropertySetter): propname = "ApprovedByDefault" value_to_set = False - class PropertySetterValue(PropertySetter): """Abstract class for PropertySetter recieving a value as constructor argument instead of a class attribute.""" + def __init__(self, value): self.value_to_set = value @@ -1039,11 +1037,9 @@ class SetChecker(PropertySetterValue): propname = "Checker" - class SetHost(PropertySetterValue): propname = "Host" - class SetSecret(PropertySetterValue): propname = "Secret" @@ -1057,7 +1053,6 @@ self._vts = value.read() value.close() - class PropertySetterValueMilliseconds(PropertySetterValue): """Abstract class for PropertySetterValue taking a value argument as a datetime.timedelta() but should store it as @@ -1072,23 +1067,18 @@ "When setting, convert value from a datetime.timedelta" self._vts = int(round(value.total_seconds() * 1000)) - class SetTimeout(PropertySetterValueMilliseconds): propname = "Timeout" - class SetExtendedTimeout(PropertySetterValueMilliseconds): propname = "ExtendedTimeout" - class SetInterval(PropertySetterValueMilliseconds): propname = "Interval" - class SetApprovalDelay(PropertySetterValueMilliseconds): propname = "ApprovalDelay" - class SetApprovalDuration(PropertySetterValueMilliseconds): propname = "ApprovalDuration" @@ -1765,8 +1755,6 @@ self.assertIs(ret, expected_method_return) def test_call_method_handles_exception(self): - dbus_logger = logging.getLogger("dbus.proxies") - def func(): raise gi.repository.GLib.Error() === modified file 'mandos.conf.xml' --- mandos.conf.xml 2019-06-20 18:54:10 +0000 +++ mandos.conf.xml 2024-09-08 00:08:15 +0000 @@ -3,7 +3,7 @@ "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [ /etc/mandos/mandos.conf"> - + %common; ]> @@ -69,7 +69,7 @@ DESCRIPTION - The file &CONFPATH; is a simple configuration file for + The file &CONFPATH; is a configuration file for mandos 8, and is read by it at startup. The configuration file starts with - + %common; ]> @@ -423,9 +423,9 @@ PLUGINS This program will get a password by running a number of - plugins, which are simply executable - programs in a directory in the initial RAM - disk environment. The default directory is + plugins, which are executable programs in + a directory in the initial RAM disk + environment. The default directory is /lib/mandos/plugins.d, but this can be changed with the option. The plugins are started in parallel, and the first plugin to output @@ -437,9 +437,9 @@ WRITING PLUGINS - A plugin is simply a program which prints a password to its - standard output and then exits with a successful (zero) exit - status. If the exit status is not zero, any output on + A plugin is an executable program which prints a password to + its standard output and then exits with a successful (zero) + exit status. If the exit status is not zero, any output on standard output will be ignored by the plugin runner. Any output on its standard error channel will simply be passed to the standard error of the plugin runner, usually the system === modified file 'plugins.d/mandos-client.xml' --- plugins.d/mandos-client.xml 2019-07-27 10:11:45 +0000 +++ plugins.d/mandos-client.xml 2024-09-08 00:08:15 +0000 @@ -2,7 +2,7 @@ - + %common; ]> @@ -196,13 +196,9 @@ This program is not meant to be run directly; it is really meant - to run as a plugin of the Mandos - plugin-runner - 8mandos, which runs in the - initial RAM disk environment because it is - specified as a keyscript in the - crypttab5 - file. + to be run by other programs in the initial + RAM disk environment; see . @@ -220,12 +216,10 @@ OPTIONS This program is commonly not invoked from the command line; it - is normally started by the Mandos - plugin runner, see plugin-runner8mandos - . Any command line options this program accepts - are therefore normally provided by the plugin runner, and not - directly. + is normally started by another program as described in . Any command line options this program + accepts are therefore normally provided by the invoking program, + and not directly. @@ -482,24 +476,38 @@ OVERVIEW - This program is the client part. It is a plugin started by - plugin-runner - 8mandos which will run in - an initial RAM disk environment. + This program is the client part. It is run automatically in an + initial RAM disk environment. + + + In an initial RAM disk environment using + systemd + 1, this program is started + by the Mandos + password-agent + 8mandos, which in turn is + started automatically by the + systemd1 + Password Agent system. + + + In the case of a non- + systemd1 + environment, this program is started as a plugin + of the Mandos + plugin-runner + 8mandos, which runs in the + initial RAM disk environment because it is + specified as a keyscript in the + crypttab5 + file. This program could, theoretically, be used as a keyscript in /etc/crypttab, but it would then be impossible to enter a password for the encrypted root disk at the console, since this program does not read from the console - at all. This is why a separate plugin runner ( - plugin-runner - 8mandos) is used to run - both this program and others in in parallel, - one of which ( - password-prompt - 8mandos) will prompt for - passwords on the system console. + at all. @@ -762,9 +770,8 @@ EXAMPLE Note that normally, command line options will not be given - directly, but via options for the Mandos plugin-runner - 8mandos. + directly, but passed on via the program responsible for starting + this program; see . @@ -872,7 +879,7 @@ 5, mandos 8, - password-prompt + password-agent 8mandos, plugin-runner 8mandos === modified file 'plugins.d/plymouth.c' --- plugins.d/plymouth.c 2022-04-24 16:54:30 +0000 +++ plugins.d/plymouth.c 2024-09-09 04:24:39 +0000 @@ -372,7 +372,8 @@ error_plus(0, errno, "scandir"); } if(ret > 0){ - for(int i = ret-1; i >= 0; i--){ + const int num_entries = ret; + for(int i = 0; i < num_entries; i++){ if(proc_id == 0){ ret = sscanf(direntries[i]->d_name, "%" SCNuMAX, &proc_id); if(ret < 0){