=== modified file 'TODO' --- TODO 2009-01-12 22:02:33 +0000 +++ TODO 2009-01-18 00:16:57 +0000 @@ -53,16 +53,13 @@ ** TODO [#B] "--test" option For testing decryption before rebooting. -* [#A] Package +* Package ** /usr/share/initramfs-tools/hooks/mandos *** TODO [#C] Do not install in initrd.img if configured not to. Use "/etc/initramfs-tools/conf.d/mandos"? Definitely a debconf question. ** TODO [#C] /etc/bash_completion.d/mandos From XML sources directly? -** TODO initramfs-tools-script :test: - Do not insert plugin-runner as keyscript if a kernel parameter - "mandos=off" is passed. #+STARTUP: showall === modified file 'debian/mandos-client.lintian-overrides' --- debian/mandos-client.lintian-overrides 2008-10-01 15:29:01 +0000 +++ debian/mandos-client.lintian-overrides 2009-01-18 06:41:57 +0000 @@ -1,8 +1,3 @@ -# This example command line is long without spaces, but it must be -# that way; it's part of the point of showing it. -# -mandos-client binary: manpage-has-errors-from-man usr/share/man/man8/plugin-runner.8mandos.gz 297: warning [p 4, 5.8i]: can't break line - # This directory contains secret client key files. # mandos-client binary: non-standard-dir-perm etc/keys/mandos/ 0700 != 0755 @@ -16,7 +11,7 @@ # 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 not run in a running +# user/group "_mandos". These binaries are not run in a running # system, but in an initial RAM disk environment. Here they are # protected from non-root access by the directory permissions, above. # === modified file 'debian/mandos-client.postinst' --- debian/mandos-client.postinst 2009-01-06 05:08:37 +0000 +++ debian/mandos-client.postinst 2009-01-18 00:16:57 +0000 @@ -1,4 +1,4 @@ -#!/bin/bash -e +#!/bin/sh -e # This script can be called in the following ways: # # After the package was installed: @@ -26,7 +26,7 @@ # Add user and group add_mandos_user(){ # Rename old "mandos" user and group - case "$(getent passwd mandos)" in + case "`getent passwd mandos`" in *:Mandos\ password\ system,,,:/nonexistent:/bin/false) usermod --login _mandos mandos groupmod --new-name _mandos mandos @@ -62,7 +62,7 @@ ;; *) - echo "$0 called with unknown argument \`$1'" 1>&2 + echo "$0 called with unknown argument '$1'" 1>&2 exit 1 ;; esac === modified file 'debian/mandos-client.postrm' --- debian/mandos-client.postrm 2008-09-19 20:54:58 +0000 +++ debian/mandos-client.postrm 2009-01-18 00:16:57 +0000 @@ -50,7 +50,7 @@ ;; *) - echo "$0 called with unknown argument \`$1'" 1>&2 + echo "$0 called with unknown argument '$1'" 1>&2 exit 1 ;; esac === modified file 'debian/mandos.postinst' --- debian/mandos.postinst 2009-01-06 05:08:37 +0000 +++ debian/mandos.postinst 2009-01-18 00:16:57 +0000 @@ -1,4 +1,4 @@ -#!/bin/bash -e +#!/bin/sh -e # This script can be called in the following ways: # # After the package was installed: @@ -18,7 +18,7 @@ case "$1" in configure) # Rename old "mandos" user and group - case "$(getent passwd mandos)" in + case "`getent passwd mandos`" in *:Mandos\ password\ system,,,:/nonexistent:/bin/false) usermod --login _mandos mandos groupmod --new-name _mandos mandos @@ -37,7 +37,7 @@ ;; *) - echo "$0 called with unknown argument \`$1'" 1>&2 + echo "$0 called with unknown argument '$1'" 1>&2 exit 1 ;; esac === modified file 'debian/mandos.prerm' --- debian/mandos.prerm 2008-09-21 13:42:34 +0000 +++ debian/mandos.prerm 2009-01-18 00:16:57 +0000 @@ -6,12 +6,12 @@ set -e # summary of how this script can be called: -# * `remove' -# * `upgrade' -# * `failed-upgrade' -# * `remove' `in-favour' -# * `deconfigure' `in-favour' -# `removing' +# * 'remove' +# * 'upgrade' +# * 'failed-upgrade' +# * 'remove' 'in-favour' +# * 'deconfigure' 'in-favour' +# 'removing' # # for details, see /usr/share/doc/packaging-manual/ @@ -28,7 +28,7 @@ upgrade|failed-upgrade) ;; *) - echo "prerm called with unknown argument \`$1'" >&2 + echo "prerm called with unknown argument '$1'" >&2 exit 0 ;; esac === modified file 'debian/rules' --- debian/rules 2009-01-04 22:26:07 +0000 +++ debian/rules 2009-01-18 00:18:50 +0000 @@ -47,7 +47,7 @@ dh_installdirs --indep $(MAKE) DESTDIR=$(CURDIR)/debian/mandos install-server dh_lintian - dh_installinit --onlyscripts --no-start \ + dh_installinit --onlyscripts \ --update-rcd-params="defaults 25 15" dh_install --indep === modified file 'mandos' --- mandos 2009-01-17 02:12:05 +0000 +++ mandos 2009-01-23 16:49:50 +0000 @@ -178,7 +178,8 @@ class Client(dbus.service.Object): """A representation of a client host served by this server. Attributes: - name: string; from the config file, used in log messages + name: string; from the config file, used in log messages and + D-Bus identifiers fingerprint: string (40 or 32 hexadecimal digits); used to uniquely identify the client secret: bytestring; sent verbatim (over TLS) to client @@ -225,13 +226,7 @@ if config is None: config = {} logger.debug(u"Creating client %r", self.name) - self.use_dbus = use_dbus - if self.use_dbus: - self.dbus_object_path = (dbus.ObjectPath - ("/Mandos/clients/" - + self.name.replace(".", "_"))) - dbus.service.Object.__init__(self, bus, - self.dbus_object_path) + self.use_dbus = False # During __init__ # Uppercase and remove spaces from fingerprint for later # comparison purposes with return value from the fingerprint() # function @@ -261,6 +256,16 @@ self.disable_initiator_tag = None self.checker_callback_tag = None self.checker_command = config["checker"] + self.last_connect = None + # Only now, when this client is initialized, can it show up on + # the D-Bus + self.use_dbus = use_dbus + if self.use_dbus: + self.dbus_object_path = (dbus.ObjectPath + ("/clients/" + + self.name.replace(".", "_"))) + dbus.service.Object.__init__(self, bus, + self.dbus_object_path) def enable(self): """Start this client's checker and timeout hooks""" @@ -319,34 +324,30 @@ # Emit D-Bus signal self.PropertyChanged(dbus.String(u"checker_running"), dbus.Boolean(False, variant_level=1)) - if (os.WIFEXITED(condition) - and (os.WEXITSTATUS(condition) == 0)): - logger.info(u"Checker for %(name)s succeeded", - vars(self)) + if os.WIFEXITED(condition): + exitstatus = os.WEXITSTATUS(condition) + if exitstatus == 0: + logger.info(u"Checker for %(name)s succeeded", + vars(self)) + self.checked_ok() + else: + logger.info(u"Checker for %(name)s failed", + vars(self)) if self.use_dbus: # Emit D-Bus signal - self.CheckerCompleted(dbus.Boolean(True), - dbus.UInt16(condition), + self.CheckerCompleted(dbus.Int16(exitstatus), + dbus.Int64(condition), dbus.String(command)) - self.bump_timeout() - elif not os.WIFEXITED(condition): + else: logger.warning(u"Checker for %(name)s crashed?", vars(self)) if self.use_dbus: # Emit D-Bus signal - self.CheckerCompleted(dbus.Boolean(False), - dbus.UInt16(condition), - dbus.String(command)) - else: - logger.info(u"Checker for %(name)s failed", - vars(self)) - if self.use_dbus: - # Emit D-Bus signal - self.CheckerCompleted(dbus.Boolean(False), - dbus.UInt16(condition), + self.CheckerCompleted(dbus.Int16(-1), + dbus.Int64(condition), dbus.String(command)) - def bump_timeout(self): + def checked_ok(self): """Bump up the timeout for this client. This should only be called when the client has been seen, alive and well. @@ -448,15 +449,15 @@ return now < (self.last_checked_ok + self.timeout) ## D-Bus methods & signals - _interface = u"org.mandos_system.Mandos.Client" + _interface = u"se.bsnet.fukt.Mandos.Client" - # BumpTimeout - method - BumpTimeout = dbus.service.method(_interface)(bump_timeout) - BumpTimeout.__name__ = "BumpTimeout" + # CheckedOK - method + CheckedOK = dbus.service.method(_interface)(checked_ok) + CheckedOK.__name__ = "CheckedOK" # CheckerCompleted - signal - @dbus.service.signal(_interface, signature="bqs") - def CheckerCompleted(self, success, condition, command): + @dbus.service.signal(_interface, signature="nxs") + def CheckerCompleted(self, exitcode, waitstatus, command): "D-Bus signal" pass @@ -503,6 +504,9 @@ dbus.String("checker_running"): dbus.Boolean(self.checker is not None, variant_level=1), + dbus.String("object_path"): + dbus.ObjectPath(self.dbus_object_path, + variant_level=1) }, signature="sv") # IsStillValid - method @@ -709,7 +713,7 @@ session.bye() return ## This won't work here, since we're in a fork. - # client.bump_timeout() + # client.checked_ok() sent_size = 0 while sent_size < len(client.secret): sent = session.send(client.secret[sent_size:]) @@ -1031,8 +1035,7 @@ avahi.DBUS_INTERFACE_SERVER) # End of Avahi example code if use_dbus: - bus_name = dbus.service.BusName(u"org.mandos-system.Mandos", - bus) + bus_name = dbus.service.BusName(u"se.bsnet.fukt.Mandos", bus) clients.update(Set(Client(name = section, config @@ -1092,31 +1095,30 @@ class MandosServer(dbus.service.Object): """A D-Bus proxy object""" def __init__(self): - dbus.service.Object.__init__(self, bus, - "/Mandos") - _interface = u"org.mandos_system.Mandos" - + dbus.service.Object.__init__(self, bus, "/") + _interface = u"se.bsnet.fukt.Mandos" + @dbus.service.signal(_interface, signature="oa{sv}") def ClientAdded(self, objpath, properties): "D-Bus signal" pass - - @dbus.service.signal(_interface, signature="o") - def ClientRemoved(self, objpath): + + @dbus.service.signal(_interface, signature="os") + def ClientRemoved(self, objpath, name): "D-Bus signal" pass - + @dbus.service.method(_interface, out_signature="ao") def GetAllClients(self): return dbus.Array(c.dbus_object_path for c in clients) - + @dbus.service.method(_interface, out_signature="a{oa{sv}}") def GetAllClientsWithProperties(self): return dbus.Dictionary( ((c.dbus_object_path, c.GetAllProperties()) for c in clients), signature="oa{sv}") - + @dbus.service.method(_interface, in_signature="o") def RemoveClient(self, object_path): for c in clients: @@ -1126,15 +1128,12 @@ c.use_dbus = False c.disable() # Emit D-Bus signal - self.ClientRemoved(object_path) + self.ClientRemoved(object_path, c.name) return raise KeyError - @dbus.service.method(_interface) - def Quit(self): - main_loop.quit() - + del _interface - + mandos_server = MandosServer() for client in clients: === modified file 'mandos-keygen' --- mandos-keygen 2009-01-17 02:12:05 +0000 +++ mandos-keygen 2009-01-17 09:46:54 +0000 @@ -147,7 +147,7 @@ echo "Invalid key length" >&2 exit 1 fi - + if [ -z "$KEYEXPIRE" ]; then echo "Empty key expiration" >&2 exit 1 @@ -172,7 +172,7 @@ if [ -n "$KEYEMAIL" ]; then KEYEMAILLINE="Name-Email: $KEYEMAIL" fi - + # Create temporary gpg batch file BATCHFILE="`mktemp -t mandos-keygen-batch.XXXXXXXXXX`" fi @@ -284,7 +284,7 @@ stty echo if [ "$first" != "$second" ]; then echo -e "Passphrase mismatch" >&2 - false + touch "$RINGDIR"/mismatch else echo -n "$first" fi @@ -292,9 +292,9 @@ --homedir "$RINGDIR" --trust-model always --armor --encrypt \ --sign --recipient "$FINGERPRINT" --comment "$FILECOMMENT" \ > "$SECFILE" - status="${PIPESTATUS[0]}" - if [ "$status" -ne 0 ]; then - exit "$status" + if [ -e "$RINGDIR"/mismatch ]; then + rm --force "$RINGDIR"/mismatch + exit 1 fi cat <<-EOF === modified file 'plugin-runner.xml' --- plugin-runner.xml 2009-01-04 21:54:55 +0000 +++ plugin-runner.xml 2009-01-18 06:41:57 +0000 @@ -2,7 +2,7 @@ - + %common; ]> @@ -579,7 +579,7 @@ -&COMMANDNAME; --config-file=/etc/mandos/plugin-runner.conf --plugin-dir /usr/lib/mandos/plugins.d --options-for=mandos-client:--pubkey=/etc/keys/mandos/pubkey.txt,--seckey=/etc/keys/mandos/seckey.txt +cd /etc/keys/mandos; &COMMANDNAME; --config-file=/etc/mandos/plugin-runner.conf --plugin-dir /usr/lib/mandos/plugins.d --options-for=mandos-client:--pubkey=pubkey.txt,--seckey=seckey.txt