=== modified file '.bzrignore' --- .bzrignore 2008-09-06 16:33:54 +0000 +++ .bzrignore 2008-08-27 01:18:25 +0000 @@ -3,6 +3,6 @@ *.8mandos plugin-runner plugins.d/password-prompt -plugins.d/mandos-client +plugins.d/password-request confdir keydir === modified file 'Makefile' --- Makefile 2008-09-07 09:36:35 +0000 +++ Makefile 2008-09-03 19:04:05 +0000 @@ -4,31 +4,21 @@ -Wunsafe-loop-optimizations -Wpointer-arith \ -Wbad-function-cast -Wcast-qual -Wcast-align -Wwrite-strings \ -Wconversion -Wstrict-prototypes -Wold-style-definition \ - -Wpacked -Wnested-externs -Winline -Wvolatile-register-var -# -Wunreachable-code -#DEBUG=-ggdb3 + -Wpacked -Wnested-externs -Wunreachable-code -Winline \ + -Wvolatile-register-var +DEBUG=-ggdb3 # For info about _FORTIFY_SOURCE, see # FORTIFY=-D_FORTIFY_SOURCE=2 # -fstack-protector-all #COVERAGE=--coverage OPTIMIZE=-Os LANGUAGE=-std=gnu99 - -## Use these settings for a traditional /usr/local install -# PREFIX=$(DESTDIR)/usr/local -# CONFDIR=$(DESTDIR)/etc/mandos -# KEYDIR=$(DESTDIR)/etc/mandos/keys -# MANDIR=$(PREFIX)/man -# INITRAMFSTOOLS=$(DESTDIR)/etc/initramfs-tools -## - -## These settings are for a package-type install +# PREFIX=/usr/local PREFIX=$(DESTDIR)/usr +# CONFDIR=/usr/local/lib/mandos CONFDIR=$(DESTDIR)/etc/mandos -KEYDIR=$(DESTDIR)/etc/keys/mandos -MANDIR=$(PREFIX)/share/man -INITRAMFSTOOLS=$(DESTDIR)/usr/share/initramfs-tools -## +# MANDIR=/usr/local/man +MANDIR=$(DESTDIR)/usr/share/man GNUTLS_CFLAGS=$(shell libgnutls-config --cflags) GNUTLS_LIBS=$(shell libgnutls-config --libs) @@ -42,7 +32,7 @@ $(LANGUAGE) $(GNUTLS_CFLAGS) $(AVAHI_CFLAGS) $(GPGME_CFLAGS) LDFLAGS=$(COVERAGE) -# Commands to format a DocBook document into a manual page +# Commands to format a DocBook refentry document into a manual page DOCBOOKTOMAN=cd $(dir $<); xsltproc --nonet --xinclude \ --param man.charmap.use.subset 0 \ --param make.year.ranges 1 \ @@ -52,13 +42,13 @@ /usr/share/xml/docbook/stylesheet/nwalsh/manpages/docbook.xsl \ $(notdir $<); \ $(MANPOST) $(notdir $@) -# DocBook-to-man post-processing to fix a '\n' escape bug +# DocBook-to-man post-processing to fix a \n escape bug MANPOST=sed --in-place --expression='s,\\\\en,\\en,g;s,\\n,\\en,g' -PLUGINS=plugins.d/password-prompt plugins.d/mandos-client +PLUGINS=plugins.d/password-prompt plugins.d/password-request PROGS=plugin-runner $(PLUGINS) DOCS=mandos.8 plugin-runner.8mandos mandos-keygen.8 \ - plugins.d/mandos-client.8mandos \ + plugins.d/password-request.8mandos \ plugins.d/password-prompt.8mandos mandos.conf.5 \ mandos-clients.conf.5 @@ -89,12 +79,12 @@ plugin-runner.8mandos: plugin-runner.xml overview.xml legalnotice.xml $(DOCBOOKTOMAN) -plugins.d/mandos-client.8mandos: plugins.d/mandos-client.xml \ +plugins.d/password-request.8mandos: plugins.d/password-request.xml \ mandos-options.xml \ overview.xml legalnotice.xml $(DOCBOOKTOMAN) -plugins.d/mandos-client: plugins.d/mandos-client.o +plugins.d/password-request: plugins.d/password-request.o $(LINK.o) $(GNUTLS_LIBS) $(AVAHI_LIBS) $(GPGME_LIBS) \ $(COMMON) $^ $(LOADLIBES) $(LDLIBS) -o $@ @@ -114,12 +104,17 @@ ./mandos --check # Run the client with a local config and key -run-client: all keydir/seckey.txt keydir/pubkey.txt +run-client: all keydir/seckey.txt keydir/pubkey.txt \ + keydir/secring.gpg keydir/pubring.gpg ./plugin-runner --plugin-dir=plugins.d \ --config-file=plugin-runner.conf \ - --options-for=mandos-client:--seckey=keydir/seckey.txt,--pubkey=keydir/pubkey.txt + --options-for=password-request:--seckey=keydir/seckey.txt,--pubkey=keydir/pubkey.txt # Used by run-client +keydir/secring.gpg: keydir/seckey.txt + gpg --homedir $(dir $<) --import $^ +keydir/pubring.gpg: keydir/pubkey.txt + gpg --homedir $(dir $<) --import $^ keydir/seckey.txt keydir/pubkey.txt: mandos-keygen install --directory keydir ./mandos-keygen --dir keydir --force @@ -131,28 +126,22 @@ # Used by run-server confdir/mandos.conf: mandos.conf install --directory confdir - install --mode=u=rw,go=r $^ $@ + install $^ $@ confdir/clients.conf: clients.conf keydir/seckey.txt install --directory confdir - install --mode=u=rw $< $@ + install clients.conf $@ # Add a client password ./mandos-keygen --dir keydir --password >> $@ install: install-server install-client install-server: doc - install --directory $(CONFDIR) $(MANDIR)/man5 \ + install --directory --parents $(CONFDIR) $(MANDIR)/man5 \ $(MANDIR)/man8 - install --mode=u=rwx,go=rx mandos $(PREFIX)/sbin/mandos - install --mode=u=rw,go=r --target-directory=$(CONFDIR) \ - mandos.conf - install --mode=u=rw --target-directory=$(CONFDIR) \ + install --mode=0755 mandos $(PREFIX)/sbin/mandos + install --mode=0644 --target-directory=$(CONFDIR) mandos.conf + install --mode=0640 --target-directory=$(CONFDIR) \ clients.conf - install --mode=u=rwx,go=rx init.d-mandos \ - $(DESTDIR)/etc/init.d/mandos - install --mode=u=rw,go=r default-mandos \ - $(DESTDIR)/etc/default/mandos - update-rc.d mandos defaults gzip --best --to-stdout mandos.8 \ > $(MANDIR)/man8/mandos.8.gz gzip --best --to-stdout mandos.conf.5 \ @@ -160,96 +149,72 @@ gzip --best --to-stdout mandos-clients.conf.5 \ > $(MANDIR)/man5/mandos-clients.conf.5.gz -install-client: all doc $(INITRAMFSTOOLS)/hooks/. - install --directory $(PREFIX)/lib/mandos $(CONFDIR) \ - $(MANDIR)/man8 - install --directory --mode=u=rwx $(KEYDIR) - install --directory --mode=u=rwx \ - $(PREFIX)/lib/mandos/plugins.d - if [ "$(CONFDIR)" != "$(PREFIX)/lib/mandos" ]; then \ - install --mode=u=rwx \ - --directory "$(CONFDIR)/plugins.d"; \ - install --mode=u=rw,go=r etc-plugins.d-README \ - $(CONFDIR)/plugins.d/README ; \ - fi - install --mode=u=rwx,go=rx \ - --target-directory=$(PREFIX)/lib/mandos plugin-runner - install --mode=u=rwx,go=rx --target-directory=$(PREFIX)/sbin \ +install-client: all doc /usr/share/initramfs-tools/hooks/. + install --directory --parents $(PREFIX)/lib/mandos \ + $(CONFDIR) $(MANDIR)/man8 + install --directory --mode=0700 $(PREFIX)/lib/mandos/plugins.d + chmod u=rwx,g=,o= $(PREFIX)/lib/mandos/plugins.d + install --mode=0755 --target-directory=$(PREFIX)/lib/mandos \ + plugin-runner + install --mode=0755 --target-directory=$(PREFIX)/sbin \ mandos-keygen - install --mode=u=rwx,go=rx \ + install --mode=0755 \ --target-directory=$(PREFIX)/lib/mandos/plugins.d \ plugins.d/password-prompt - install --mode=u=rwxs,go=rx \ - --target-directory=$(PREFIX)/lib/mandos/plugins.d \ - plugins.d/mandos-client - install --mode=u=rwx,go=rx \ - --target-directory=$(PREFIX)/lib/mandos/plugins.d \ - plugins.d/usplash + install --mode=4755 \ + --target-directory=$(PREFIX)/lib/mandos/plugins.d \ + plugins.d/password-request install initramfs-tools-hook \ - $(INITRAMFSTOOLS)/hooks/mandos + /usr/share/initramfs-tools/hooks/mandos install initramfs-tools-hook-conf \ - $(INITRAMFSTOOLS)/conf-hooks.d/mandos + /usr/share/initramfs-tools/conf-hooks.d/mandos install initramfs-tools-script \ - $(INITRAMFSTOOLS)/scripts/local-top/mandos - install --mode=u=rw,go=r plugin-runner.conf $(CONFDIR) + /usr/share/initramfs-tools/scripts/local-top/mandos gzip --best --to-stdout mandos-keygen.8 \ > $(MANDIR)/man8/mandos-keygen.8.gz gzip --best --to-stdout plugin-runner.8mandos \ > $(MANDIR)/man8/plugin-runner.8mandos.gz gzip --best --to-stdout plugins.d/password-prompt.8mandos \ > $(MANDIR)/man8/password-prompt.8mandos.gz - gzip --best --to-stdout plugins.d/mandos-client.8mandos \ - > $(MANDIR)/man8/mandos-client.8mandos.gz -# Post-installation stuff - -$(PREFIX)/sbin/mandos-keygen --dir "$(KEYDIR)" + gzip --best --to-stdout plugins.d/password-request.8mandos \ + > $(MANDIR)/man8/password-request.8mandos.gz + -$(PREFIX)/sbin/mandos-keygen update-initramfs -k all -u - echo "Now run mandos-keygen --password --dir $(KEYDIR)" uninstall: uninstall-server uninstall-client -uninstall-server: +uninstall-server: $(PREFIX)/sbin/mandos -rm --force $(PREFIX)/sbin/mandos \ $(MANDIR)/man8/mandos.8.gz \ $(MANDIR)/man5/mandos.conf.5.gz \ $(MANDIR)/man5/mandos-clients.conf.5.gz - update-rc.d -f mandos remove -rmdir $(CONFDIR) uninstall-client: # Refuse to uninstall client if /etc/crypttab is explicitly configured # to use it. ! grep --regexp='^ *[^ #].*keyscript=[^,=]*/mandos/' \ - $(DESTDIR)/etc/crypttab + /etc/crypttab -rm --force $(PREFIX)/sbin/mandos-keygen \ $(PREFIX)/lib/mandos/plugin-runner \ $(PREFIX)/lib/mandos/plugins.d/password-prompt \ - $(PREFIX)/lib/mandos/plugins.d/mandos-client \ - $(PREFIX)/lib/mandos/plugins.d/usplash \ - $(INITRAMFSTOOLS)/hooks/mandos \ - $(INITRAMFSTOOLS)/conf-hooks.d/mandos \ - $(INITRAMFSTOOLS)/scripts/local-top/mandos \ + $(PREFIX)/lib/mandos/plugins.d/password-request \ + /usr/share/initramfs-tools/hooks/mandos \ + /usr/share/initramfs-tools/conf-hooks.d/mandos \ $(MANDIR)/man8/plugin-runner.8mandos.gz \ $(MANDIR)/man8/mandos-keygen.8.gz \ $(MANDIR)/man8/password-prompt.8mandos.gz \ - $(MANDIR)/man8/mandos-client.8mandos.gz - if [ "$(CONFDIR)" != "$(PREFIX)/lib/mandos" ]; then \ - rm --force $(CONFDIR)/plugins.d/README; \ - fi + $(MANDIR)/man8/password-request.8mandos.gz -rmdir $(PREFIX)/lib/mandos/plugins.d $(CONFDIR)/plugins.d \ - $(PREFIX)/lib/mandos $(CONFDIR) $(KEYDIR) + $(PREFIX)/lib/mandos $(CONFDIR) update-initramfs -k all -u purge: purge-server purge-client purge-server: uninstall-server - -rm --force $(CONFDIR)/mandos.conf $(CONFDIR)/clients.conf \ - $(DESTDIR)/etc/default/mandos \ - $(DESTDIR)/etc/init.d/mandos \ - $(DESTDIR)/var/run/mandos.pid + -rm --force $(CONFDIR)/mandos.conf $(CONFDIR)/clients.conf -rmdir $(CONFDIR) purge-client: uninstall-client - -shred --remove $(KEYDIR)/seckey.txt - -rm --force $(CONFDIR)/plugin-runner.conf \ - $(KEYDIR)/pubkey.txt $(KEYDIR)/seckey.txt - -rmdir $(KEYDIR) $(CONFDIR)/plugins.d $(CONFDIR) + -rm --force $(CONFDIR)/seckey.txt $(CONFDIR)/pubkey.txt + -rmdir $(CONFDIR) $(CONFDIR)/plugins.d === modified file 'README' --- README 2008-09-05 07:11:24 +0000 +++ README 2008-09-04 07:44:49 +0000 @@ -77,10 +77,10 @@ not likely. If someone does that, the whole system *will* lock itself up completely, since Mandos servers are no longer running. - For sophisticated attackers who *could* do the clever thing, *and* - had physical access to the server for enough time, it would be - simpler to get a key for an encrypted file system by using hardware - memory scanners and reading it right off the memory bus. + For sophisticated attackers who *could* do such a thing, *and* had + physical access to the server for enough time, it would be simpler + to get a key for an encrypted file system by using hardware memory + scanners and reading it right off the memory bus. ** Replay attacks? Nope, the network stuff is all done over TLS, which provides @@ -125,7 +125,7 @@ just as well open your servers and read the file system keys right off the memory by running wires to the memory bus. - What Mandos is designed to protect against is *not* such determined, - focused, and competent attacks, but against the early morning knock - on your door and the sudden absence of all the servers in your - server room. Which it does nicely. + What this system is designed to protect against is *not* such + determined, focused, and competent attacks, but against the early + morning knock on your door and the sudden absence of all the servers + in your server room. Which it does nicely. === modified file 'TODO' --- TODO 2008-09-06 16:31:49 +0000 +++ TODO 2008-09-04 07:30:58 +0000 @@ -2,7 +2,7 @@ * plugin-runner -* mandos-client +* password-request ** [#B] Temporarily lower kernel log level for less printouts during sucessfull boot. ** IPv4 support @@ -50,6 +50,8 @@ This seems to use some kind of "trigger" system [[file:/usr/share/doc/dpkg/triggers.txt.gz]] dpkg-trigger(1), deb-triggers(5) +*** Keydir move: /etc/mandos -> /etc/keys/mandos + Must create in preinst if not pre-depending on cryptsetup *** mandos-keygen **** "--passfile" option Using the "secfile" option instead of "secret" @@ -58,9 +60,6 @@ ** Server-side *** [#A] Create mandos user and group for server *** [#A] Create /var/run/mandos directory with perm and ownership -*** [#A] install rc.d script and do update-rc.d - between config files and man pages - * [#A] Package ** /usr/share/initramfs-tools/hooks/mandos === removed file 'default-mandos' --- default-mandos 2008-09-05 08:38:30 +0000 +++ default-mandos 1970-01-01 00:00:00 +0000 @@ -1,4 +0,0 @@ -# Directory where configuration files are located. Default is -# "/etc/mandos". -# -#CONFIGDIR=/etc/mandos === removed file 'etc-plugins.d-README' --- etc-plugins.d-README 2008-09-06 16:11:50 +0000 +++ etc-plugins.d-README 1970-01-01 00:00:00 +0000 @@ -1,5 +0,0 @@ -Any plugins found here 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: - -# update-initramfs -k all -u === removed file 'init.d-mandos' --- init.d-mandos 2008-09-05 16:24:33 +0000 +++ init.d-mandos 1970-01-01 00:00:00 +0000 @@ -1,159 +0,0 @@ -#! /bin/sh -### BEGIN INIT INFO -# Provides: mandos -# Required-Start: $remote_fs -# Required-Stop: $remote_fs -# Default-Start: 2 3 4 5 -# Default-Stop: 0 1 6 -# Short-Description: Mandos server -# Description: Gives encrypted passwords to Mandos clients -### END INIT INFO - -# Author: Teddy Hogeborn -# Author: Björn Påhlsson -# -# Please remove the "Author" lines above and replace them -# with your own name if you copy and modify this script. - -# Do NOT "set -e" - -# PATH should only include /usr/* if it runs after the mountnfs.sh script -PATH=/sbin:/usr/sbin:/bin:/usr/bin -DESC="Mandos root file system password server" -NAME=mandos -DAEMON=/usr/sbin/$NAME -DAEMON_ARGS="" -PIDFILE=/var/run/$NAME.pid -SCRIPTNAME=/etc/init.d/$NAME - -# Exit if the package is not installed -[ -x "$DAEMON" ] || exit 0 - -# Read configuration variable file if it is present -[ -r /etc/default/$NAME ] && . /etc/default/$NAME - -if [ -n "$CONFIGDIR" ]; then - DAEMON_ARGS="$DAEMON_ARGS --configdir $CONFIGDIR" -fi - -# Load the VERBOSE setting and other rcS variables -. /lib/init/vars.sh - -# Define LSB log_* functions. -# Depend on lsb-base (>= 3.0-6) to ensure that this file is present. -. /lib/lsb/init-functions - -# -# Function that starts the daemon/service -# -do_start() -{ - # Return - # 0 if daemon has been started - # 1 if daemon was already running - # 2 if daemon could not be started - start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \ - || return 1 - start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- \ - $DAEMON_ARGS \ - || return 2 - # Add code here, if necessary, that waits for the process to be ready - # to handle requests from services started subsequently which depend - # on this one. As a last resort, sleep for some time. -} - -# -# Function that stops the daemon/service -# -do_stop() -{ - # Return - # 0 if daemon has been stopped - # 1 if daemon was already stopped - # 2 if daemon could not be stopped - # other if a failure occurred - start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME - RETVAL="$?" - [ "$RETVAL" = 2 ] && return 2 - # Wait for children to finish too if this is a daemon that forks - # and if the daemon is only ever run from this initscript. - # If the above conditions are not satisfied then add some other code - # that waits for the process to drop all resources that could be - # needed by services started subsequently. A last resort is to - # sleep for some time. - start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON - [ "$?" = 2 ] && return 2 - # Many daemons don't delete their pidfiles when they exit. - rm -f $PIDFILE - return "$RETVAL" -} - -# -# Function that sends a SIGHUP to the daemon/service -# -do_reload() { - # - # If the daemon can reload its configuration without - # restarting (for example, when it is sent a SIGHUP), - # then implement that here. - # - start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME - return 0 -} - -case "$1" in - start) - [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME" - do_start - case "$?" in - 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; - 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; - esac - ;; - stop) - [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME" - do_stop - case "$?" in - 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; - 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; - esac - ;; - #reload|force-reload) - # - # If do_reload() is not implemented then leave this commented out - # and leave 'force-reload' as an alias for 'restart'. - # - #log_daemon_msg "Reloading $DESC" "$NAME" - #do_reload - #log_end_msg $? - #;; - restart|force-reload) - # - # If the "reload" option is implemented then remove the - # 'force-reload' alias - # - log_daemon_msg "Restarting $DESC" "$NAME" - do_stop - case "$?" in - 0|1) - do_start - case "$?" in - 0) log_end_msg 0 ;; - 1) log_end_msg 1 ;; # Old process is still running - *) log_end_msg 1 ;; # Failed to start - esac - ;; - *) - # Failed to stop - log_end_msg 1 - ;; - esac - ;; - *) - #echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2 - echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2 - exit 3 - ;; -esac - -: === modified file 'initramfs-tools-hook' --- initramfs-tools-hook 2008-09-07 09:36:35 +0000 +++ initramfs-tools-hook 2008-08-24 23:18:18 +0000 @@ -29,37 +29,15 @@ . /usr/share/initramfs-tools/hook-functions -for d in /usr /usr/local; do - if [ -d "$d"/lib/mandos ]; then - prefix="$d" - break - fi -done -if [ -z "$prefix" ]; then +if [ -d /usr/lib/mandos ]; then + prefix=/usr +elif [ -d /usr/local/lib/mandos ]; then + prefix=/usr/local +else # Mandos not found exit 1 fi -for d in /etc/keys/mandos /etc/mandos/keys; do - if [ -d "$d" ]; then - keydir="$d" - break - fi -done -if [ -z "$keydir" ]; then - # Mandos key directory not found - exit 1 -fi - -mandos_user="`{ getent passwd mandos \ - || getent passwd nobody \ - || echo ::65534::::; } \ - | awk --field-separator=: '{ print $3 }'`" -mandos_group="`{ getent group mandos \ - || getent group nogroup \ - || echo ::65534:; } \ - | awk --field-separator=: '{ print $3 }'`" - # The Mandos network client uses the network auto_add_modules net # The Mandos network client uses IPv6 @@ -71,13 +49,11 @@ PLUGINDIR="${MANDOSDIR}/plugins.d" # Make directories -install --directory --mode=u=rwx,go=rx "${DESTDIR}${CONFDIR}" \ - "${DESTDIR}${MANDOSDIR}" -install --owner=${mandos_user} --group=${mandos_group} --directory \ - --mode=u=rwx "${DESTDIR}${PLUGINDIR}" +mkdir --parents "${DESTDIR}${CONFDIR}" +mkdir --parents "${DESTDIR}${PLUGINDIR}" # Copy the Mandos plugin runner -copy_exec "$prefix"/lib/mandos/plugin-runner "${MANDOSDIR}" +copy_exec "$prefix"/lib/mandos/plugin-runner "${DESTDIR}${MANDOSDIR}" # Copy the plugins @@ -90,7 +66,6 @@ fi case "$base" in *~|.*|\#*\#|*.dpkg-old|*.dpkg-new|*.dpkg-divert) : ;; - "*") :;; *) copy_exec "$file" "${PLUGINDIR}";; esac done @@ -99,36 +74,31 @@ for file in /etc/mandos/plugins.d/*; do base="`basename \"$file\"`" case "$base" in - *~|.*|\#*\#|*.dpkg-old|*.dpkg-new|*.dpkg-divert) : ;; - "*") :;; + *~|.*|*.dpkg-old|*.dpkg-new|*.dpkg-divert) : ;; *) copy_exec "$file" "${PLUGINDIR}";; esac done # GPGME needs /usr/bin/gpg -if [ ! -e "${DESTDIR}/usr/bin/gpg" \ - -a -n "`ls \"${DESTDIR}\"/usr/lib/libgpgme.so* \ - 2>/dev/null`" ]; then +if ! [ -e "${DESTDIR}/usr/bin/gpg" ] \ + && [ -n "`ls \"${DESTDIR}\"/usr/lib/libgpgme.so* 2>/dev/null`" ]; then copy_exec /usr/bin/gpg fi -# Config files +# Key files for file in /etc/mandos/*; do if [ -d "$file" ]; then continue fi cp --archive --sparse=always "$file" "${DESTDIR}${CONFDIR}" done - -# Key files -for file in "$keydir"/*; do - if [ -d "$file" ]; then - continue - fi - cp --archive --sparse=always "$file" "${DESTDIR}${CONFDIR}" - chown ${mandos_user}:${mandos_group} \ - "${DESTDIR}${CONFDIR}/`basename \"$file\"`" -done +# Create key ring files +gpg --no-random-seed-file --quiet --batch --no-tty --armor \ + --no-default-keyring --no-options --enable-dsa2 \ + --homedir "${DESTDIR}${CONFDIR}" --no-permission-warning \ + --trust-model always --import-options import-minimal \ + --import "${DESTDIR}${CONFDIR}/seckey.txt" +chown nobody "${DESTDIR}${CONFDIR}/secring.gpg" # /lib/mandos/plugin-runner will drop priviliges, but needs access to # its plugin directory and its config file. However, since almost all @@ -142,7 +112,7 @@ # condition. This umask is set by "initramfs-tools-hook-conf", # installed as "/usr/share/initramfs-tools/conf-hooks.d/mandos".) # -for full in "${MANDOSDIR}" "${CONFDIR}"; do +for full in "${PLUGINDIR}" "${CONFDIR}"; do while [ "$full" != "/" ]; do chmod a+rX "${DESTDIR}$full" full="`dirname \"$full\"`" @@ -152,11 +122,8 @@ # Reset some other things to sane permissions which we have # inadvertently affected with our umask setting. for dir in / /bin /etc /keyscripts /sbin /scripts /usr /usr/bin; do - if [ -d "${DESTDIR}$dir" ]; then - chmod a+rX "${DESTDIR}$dir" - fi + chmod a+rX "${DESTDIR}$dir" done for dir in /lib /usr/lib; do - find "${DESTDIR}$dir" \! -perm -u+rw,g+r -prune -or -print0 \ - | xargs --null --no-run-if-empty chmod a+rX + chmod --recursive a+rX "${DESTDIR}$dir" done === modified file 'initramfs-tools-script' --- initramfs-tools-script 2008-09-07 15:42:11 +0000 +++ initramfs-tools-script 2008-08-14 02:24:59 +0000 @@ -24,8 +24,6 @@ ;; esac -chmod a=rwxt /tmp - test -w /conf/conf.d/cryptroot # Do not replace cryptroot file unless we need to. === modified file 'legalnotice.xml' --- legalnotice.xml 2008-09-06 17:24:58 +0000 +++ legalnotice.xml 2008-08-31 15:06:39 +0000 @@ -4,24 +4,21 @@ This manual page is free software: you can redistribute it and/or - modify it under the terms of the GNU General - Public License as published by the Free Software Foundation, - either version 3 of the License, or (at your option) any later - version. + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the + License, or (at your option) any later version. This manual page is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - See the GNU General Public License for more - details. + See the GNU General Public License for more details. - You should have received a copy of the GNU - General Public License along with this program. If not, see - http://www.gnu.org/licenses/. + You should have received a copy of the GNU General Public License + along with this program; If not, see . === modified file 'mandos' --- mandos 2008-09-05 18:37:28 +0000 +++ mandos 2008-08-27 01:18:25 +0000 @@ -55,7 +55,6 @@ import stat import logging import logging.handlers -import pwd import dbus import gobject @@ -518,7 +517,6 @@ Attributes: settings: Server settings clients: Set() of Client objects - enabled: Boolean; whether this server is activated yet """ address_family = socket.AF_INET6 def __init__(self, *args, **kwargs): @@ -528,7 +526,6 @@ if "clients" in kwargs: self.clients = kwargs["clients"] del kwargs["clients"] - self.enabled = False return super(type(self), self).__init__(*args, **kwargs) def server_bind(self): """This overrides the normal server_bind() function @@ -565,11 +562,6 @@ # (self.settings # ["interface"])) return super(type(self), self).server_bind() - def server_activate(self): - if self.enabled: - return super(type(self), self).server_activate() - def enable(self): - self.enabled = True def string_to_delta(interval): @@ -766,41 +758,6 @@ client_config.read(os.path.join(server_settings["configdir"], "clients.conf")) - clients = Set() - tcp_server = IPv6_TCPServer((server_settings["address"], - server_settings["port"]), - tcp_handler, - settings=server_settings, - clients=clients) - pidfilename = "/var/run/mandos.pid" - try: - pidfile = open(pidfilename, "w") - except IOError, error: - logger.error("Could not open file %r", pidfilename) - - uid = 65534 - gid = 65534 - try: - uid = pwd.getpwnam("mandos").pw_uid - except KeyError: - try: - uid = pwd.getpwnam("nobody").pw_uid - except KeyError: - pass - try: - gid = pwd.getpwnam("mandos").pw_gid - except KeyError: - try: - gid = pwd.getpwnam("nogroup").pw_gid - except KeyError: - pass - try: - os.setuid(uid) - os.setgid(gid) - except OSError, error: - if error[0] != errno.EPERM: - raise error - global service service = AvahiService(name = server_settings["servicename"], type = "_mandos._tcp", ); @@ -820,6 +777,7 @@ avahi.DBUS_INTERFACE_SERVER) # End of Avahi example code + clients = Set() def remove_from_clients(client): clients.remove(client) if not clients: @@ -847,18 +805,16 @@ # Close all input and output, do double fork, etc. daemon() + pidfilename = "/var/run/mandos/mandos.pid" + pid = os.getpid() try: - pid = os.getpid() + pidfile = open(pidfilename, "w") pidfile.write(str(pid) + "\n") pidfile.close() del pidfile except IOError, err: - logger.error(u"Could not write to file %r with PID %d", - pidfilename, pid) - except NameError: - # "pidfile" was never created - pass - del pidfilename + logger.error(u"Could not write %s file with PID %d", + pidfilename, os.getpid()) def cleanup(): "Cleanup function; run on exit" @@ -884,9 +840,11 @@ for client in clients: client.start() - tcp_server.enable() - tcp_server.server_activate() - + tcp_server = IPv6_TCPServer((server_settings["address"], + server_settings["port"]), + tcp_handler, + settings=server_settings, + clients=clients) # Find out what port we got service.port = tcp_server.socket.getsockname()[1] logger.info(u"Now listening on address %r, port %d, flowinfo %d," === modified file 'mandos-clients.conf.xml' --- mandos-clients.conf.xml 2008-09-04 13:36:59 +0000 +++ mandos-clients.conf.xml 2008-09-03 19:37:07 +0000 @@ -4,7 +4,7 @@ /etc/mandos/clients.conf"> - + ]> @@ -93,7 +93,7 @@ start time expansion, see . - Unknown options are ignored. The used options are as follows: + Uknown options are ignored. The used options are as follows: === modified file 'mandos-keygen' --- mandos-keygen 2008-09-06 15:34:21 +0000 +++ mandos-keygen 2008-08-31 08:47:38 +0000 @@ -22,7 +22,7 @@ VERSION="1.0" -KEYDIR="/etc/keys/mandos" +KEYDIR="/etc/mandos" KEYTYPE=DSA KEYLENGTH=2048 SUBKEYTYPE=ELG-E @@ -108,20 +108,21 @@ PUBKEYFILE="$KEYDIR/pubkey.txt" # Check for some invalid values -if [ ! -d "$KEYDIR" ]; then +if [ -d "$KEYDIR" ]; then :; else echo "$KEYDIR not a directory" >&2 exit 1 fi -if [ ! -r "$KEYDIR" ]; then - echo "Directory $KEYDIR not readable" >&2 +if [ -w "$KEYDIR" ]; then :; else + echo "Directory $KEYDIR not writeable" >&2 + exit 1 +fi + +if [ "$mode" = password -a -e "$KEYDIR/trustdb.gpg.lock" ]; then + echo "Key directory has locked trustdb; aborting." >&2 exit 1 fi if [ "$mode" = keygen ]; then - if [ ! -w "$KEYDIR" ]; then - echo "Directory $KEYDIR not writeable" >&2 - exit 1 - fi if [ -z "$KEYTYPE" ]; then echo "Empty key type" >&2 exit 1 @@ -148,8 +149,8 @@ [Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|*) FORCE=0;; esac - if [ \( -e "$SECKEYFILE" -o -e "$PUBKEYFILE" \) \ - -a "$FORCE" -eq 0 ]; then + if { [ -e "$SECKEYFILE" ] || [ -e "$PUBKEYFILE" ]; } \ + && [ "$FORCE" -eq 0 ]; then echo "Refusing to overwrite old key files; use --force" >&2 exit 1 fi @@ -163,28 +164,35 @@ fi # Create temporary gpg batch file - BATCHFILE="`mktemp -t mandos-keygen-batch.XXXXXXXXXX`" + BATCHFILE="`mktemp -t mandos-gpg-batch.XXXXXXXXXX`" fi if [ "$mode" = password ]; then # Create temporary encrypted password file - SECFILE="`mktemp -t mandos-keygen-secfile.XXXXXXXXXX`" -fi - -# Create temporary key ring directory -RINGDIR="`mktemp -d -t mandos-keygen-keyrings.XXXXXXXXXX`" + SECFILE="`mktemp -t mandos-gpg-secfile.XXXXXXXXXX`" +fi + +# Create temporary key rings +SECRING="`mktemp -t mandos-gpg-secring.XXXXXXXXXX`" +PUBRING="`mktemp -t mandos-gpg-pubring.XXXXXXXXXX`" + +if [ "$mode" = password ]; then + # If a trustdb.gpg file does not already exist, schedule it for + # deletion when we are done. + if ! [ -e "$KEYDIR/trustdb.gpg" ]; then + TRUSTDB="$KEYDIR/trustdb.gpg" + fi +fi # Remove temporary files on exit trap " set +e; \ -test -n \"$SECFILE\" && shred --remove \"$SECFILE\"; \ -shred --remove \"$RINGDIR\"/sec*; -test -n \"$BATCHFILE\" && rm --force \"$BATCHFILE\"; \ -rm --recursive --force \"$RINGDIR\"; +rm --force $PUBRING ${PUBRING}~ $BATCHFILE $TRUSTDB; \ +shred --remove $SECRING $SECFILE; \ stty echo; \ " EXIT -umask 077 +umask 027 if [ "$mode" = keygen ]; then # Create batch file for GnuPG @@ -201,17 +209,18 @@ Expire-Date: $KEYEXPIRE #Preferences: #Handle: - #%pubring pubring.gpg - #%secring secring.gpg + %pubring $PUBRING + %secring $SECRING %commit EOF # Generate a new key in the key rings - gpg --quiet --batch --no-tty --no-options --enable-dsa2 \ - --homedir "$RINGDIR" --trust-model always \ + gpg --no-random-seed-file --quiet --batch --no-tty \ + --no-default-keyring --no-options --enable-dsa2 \ + --secret-keyring "$SECRING" --keyring "$PUBRING" \ --gen-key "$BATCHFILE" rm --force "$BATCHFILE" - + # Backup any old key files if cp --backup=numbered --force "$SECKEYFILE" "$SECKEYFILE" \ 2>/dev/null; then @@ -232,30 +241,38 @@ fi # Export keys from key rings to key files - gpg --quiet --batch --no-tty --no-options --enable-dsa2 \ - --homedir "$RINGDIR" --armor --export-options export-minimal \ - --comment "$FILECOMMENT" --output "$SECKEYFILE" \ - --export-secret-keys - gpg --quiet --batch --no-tty --no-options --enable-dsa2 \ - --homedir "$RINGDIR" --armor --export-options export-minimal \ - --comment "$FILECOMMENT" --output "$PUBKEYFILE" --export + gpg --no-random-seed-file --quiet --batch --no-tty --armor \ + --no-default-keyring --no-options --enable-dsa2 \ + --secret-keyring "$SECRING" --keyring "$PUBRING" \ + --export-options export-minimal --comment "$FILECOMMENT" \ + --output "$SECKEYFILE" --export-secret-keys + gpg --no-random-seed-file --quiet --batch --no-tty --armor \ + --no-default-keyring --no-options --enable-dsa2 \ + --secret-keyring "$SECRING" --keyring "$PUBRING" \ + --export-options export-minimal --comment "$FILECOMMENT" \ + --output "$PUBKEYFILE" --export fi if [ "$mode" = password ]; then # Import keys into temporary key rings - gpg --quiet --batch --no-tty --no-options --enable-dsa2 \ - --homedir "$RINGDIR" --trust-model always --armor \ - --import "$SECKEYFILE" - gpg --quiet --batch --no-tty --no-options --enable-dsa2 \ - --homedir "$RINGDIR" --trust-model always --armor \ - --import "$PUBKEYFILE" - + gpg --no-random-seed-file --quiet --batch --no-tty --armor \ + --no-default-keyring --no-options --enable-dsa2 \ + --homedir "$KEYDIR" --no-permission-warning \ + --secret-keyring "$SECRING" --keyring "$PUBRING" \ + --trust-model always --import "$SECKEYFILE" + gpg --no-random-seed-file --quiet --batch --no-tty --armor \ + --no-default-keyring --no-options --enable-dsa2 \ + --homedir "$KEYDIR" --no-permission-warning \ + --secret-keyring "$SECRING" --keyring "$PUBRING" \ + --trust-model always --import "$PUBKEYFILE" + # Get fingerprint of key - FINGERPRINT="`gpg --quiet --batch --no-tty --no-options \ - --enable-dsa2 --homedir \"$RINGDIR\" --trust-model always \ - --fingerprint --with-colons \ - | sed --quiet \ - --expression='/^fpr:/{s/^fpr:.*:\\([0-9A-Z]*\\):\$/\\1/p;q}'`" + FINGERPRINT="`gpg --no-random-seed-file --quiet --batch --no-tty \ + --armor --no-default-keyring --no-options --enable-dsa2 \ + --homedir \"$KEYDIR\" --no-permission-warning \ + --secret-keyring \"$SECRING\" --keyring \"$PUBRING\" \ + --trust-model always --fingerprint --with-colons \ + | sed -n -e '/^fpr:/{s/^fpr:.*:\\([0-9A-Z]*\\):\$/\\1/p;q}'`" test -n "$FINGERPRINT" @@ -263,10 +280,13 @@ stty -echo echo -n "Enter passphrase: " >&2 - head --lines=1 | tr --delete '\n' \ - | gpg --quiet --batch --no-tty --no-options --enable-dsa2 \ - --homedir "$RINGDIR" --trust-model always --armor --encrypt \ - --recipient "$FINGERPRINT" --comment "$FILECOMMENT" \ + sed -e '1q' \ + | gpg --no-random-seed-file --batch --no-tty --armor \ + --no-default-keyring --no-options --enable-dsa2 \ + --homedir "$KEYDIR" --no-permission-warning \ + --secret-keyring "$SECRING" --keyring "$PUBRING" \ + --trust-model always --encrypt --recipient "$FINGERPRINT" \ + --comment "$FILECOMMENT" \ > "$SECFILE" echo >&2 stty echo @@ -277,7 +297,7 @@ fingerprint = $FINGERPRINT secret = EOF - sed --quiet --expression=' + sed -n -e ' /^-----BEGIN PGP MESSAGE-----$/,/^-----END PGP MESSAGE-----$/{ /^$/,${ # Remove 24-bit Radix-64 checksum @@ -296,5 +316,9 @@ shred --remove "$SECFILE" fi # Remove the key rings -shred --remove "$RINGDIR"/sec* -rm --recursive --force "$RINGDIR" +shred --remove "$SECRING" +rm --force "$PUBRING" "${PUBRING}~" +# Remove the trustdb, if one did not exist when we started +if [ -n "$TRUSTDB" ]; then + rm --force "$TRUSTDB" +fi === modified file 'mandos-keygen.xml' --- mandos-keygen.xml 2008-09-06 16:31:49 +0000 +++ mandos-keygen.xml 2008-09-03 19:13:50 +0000 @@ -3,7 +3,7 @@ "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [ - + ]> @@ -159,7 +159,7 @@ &COMMANDNAME; is a program to generate the OpenPGP key used by - mandos-client + password-request 8mandos. The key is normally written to /etc/mandos for later installation into the initrd image, but this, and most other things, can be changed @@ -479,7 +479,7 @@ 5, mandos 8, - mandos-client + password-request 8mandos === modified file 'mandos-options.xml' --- mandos-options.xml 2008-09-06 16:31:49 +0000 +++ mandos-options.xml 2008-09-03 05:04:40 +0000 @@ -6,7 +6,7 @@ This file is used by both mandos(8) and mandos.conf(5), since these options can be used both on the command line and in the config file. -It is also used for some texts by mandos-client(8mandos). +It is also used for some texts by password-request(8mandos). -->
=== modified file 'mandos.conf.xml' --- mandos.conf.xml 2008-09-04 13:36:59 +0000 +++ mandos.conf.xml 2008-08-31 15:06:39 +0000 @@ -4,7 +4,7 @@ /etc/mandos/mandos.conf"> - + ]> @@ -144,7 +144,7 @@ The [DEFAULT] is necessary because the Python built-in module ConfigParser - requires it. + requres it. === modified file 'mandos.xml' --- mandos.xml 2008-09-06 16:31:49 +0000 +++ mandos.xml 2008-09-03 19:13:50 +0000 @@ -3,7 +3,7 @@ "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [ - + ]> @@ -379,7 +379,7 @@ - /var/run/mandos.pid + /var/run/mandos/mandos.pid The file containing the process id of @@ -434,7 +434,7 @@ Debug mode is conflated with running in the foreground. - The console log messages does not show a time stamp. + The console log messages does not show a timestamp. This server does not check the expire time of clients’ OpenPGP @@ -487,8 +487,8 @@ Running this &COMMANDNAME; server program should not in itself present any security risk to the host - computer running it. The program switches to a non-root user - soon after startup. + computer running it. The program does not need any special + privileges to run, and is designed to run as a non-root user. @@ -529,7 +529,7 @@ For more details on client-side security, see - mandos-client + password-request 8mandos. @@ -543,7 +543,7 @@ 5, mandos.conf 5, - mandos-client + password-request 8mandos, sh1 === modified file 'plugin-runner.c' --- plugin-runner.c 2008-09-07 15:42:11 +0000 +++ plugin-runner.c 2008-09-02 06:13:47 +0000 @@ -96,7 +96,7 @@ static plugin *plugin_list = NULL; -/* Gets an existing plugin based on name, +/* Gets a existing plugin based on name, or if none is found, creates a new one */ static plugin *getplugin(char *name){ /* Check for exiting plugin with that name */ @@ -118,7 +118,7 @@ return NULL; } } - + *new_plugin = (plugin) { .name = copy_name, .argc = 1, .disabled = false, @@ -187,10 +187,10 @@ size_t namelen = (size_t)(strchrnul(def, '=') - def); /* Search for this environment variable */ for(char **e = p->environ; *e != NULL; e++){ - if(strncmp(*e, def, namelen + 1) == 0){ + if(strncmp(*e, def, namelen+1) == 0){ /* It already exists */ if(replace){ - char *new = realloc(*e, strlen(def) + 1); + char *new = realloc(*e, strlen(def)); if(new == NULL){ return false; } @@ -238,7 +238,7 @@ /* No child processes */ break; } - + /* A child exited, find it in process_list */ while(proc != NULL and proc->pid != pid){ proc = proc->next; @@ -255,6 +255,9 @@ /* Prints out a password to stdout */ bool print_out_password(const char *buffer, size_t length){ ssize_t ret; + if(length>0 and buffer[length-1] == '\n'){ + length--; + } for(size_t written = 0; written < length; written += (size_t)ret){ ret = TEMP_FAILURE_RETRY(write(STDOUT_FILENO, buffer + written, length - written)); @@ -394,28 +397,36 @@ if(arg == NULL){ break; } - if(not add_environment(getplugin(NULL), arg, true)){ - perror("add_environment"); + { + char *envdef = strdup(arg); + if(envdef == NULL){ + break; + } + if(not add_environment(getplugin(NULL), envdef, true)){ + perror("add_environment"); + } } break; case 'o': /* --options-for */ if (arg != NULL){ char *p_name = strsep(&arg, ":"); - if(p_name[0] == '\0' or arg == NULL){ + if(p_name[0] == '\0'){ break; } char *opt = strsep(&arg, ":"); - if(opt[0] == '\0' or opt == NULL){ + if(opt[0] == '\0'){ break; } - char *p; - while((p = strsep(&opt, ",")) != NULL){ - if(p[0] == '\0'){ - continue; - } - if(not add_argument(getplugin(p_name), p)){ - perror("add_argument"); - return ARGP_ERR_UNKNOWN; + if(opt != NULL){ + char *p; + while((p = strsep(&opt, ",")) != NULL){ + if(p[0] == '\0'){ + continue; + } + if(not add_argument(getplugin(p_name), p)){ + perror("add_argument"); + return ARGP_ERR_UNKNOWN; + } } } } @@ -429,8 +440,12 @@ if(envdef == NULL){ break; } - *envdef = '\0'; - if(not add_environment(getplugin(arg), envdef+1, true)){ + char *p_name = strndup(arg, (size_t) (envdef-arg)); + if(p_name == NULL){ + break; + } + envdef++; + if(not add_environment(getplugin(p_name), envdef, true)){ perror("add_environment"); } } @@ -454,7 +469,6 @@ } break; case 128: /* --plugin-dir */ - free(plugindir); plugindir = strdup(arg); if(plugindir == NULL){ perror("strdup"); @@ -473,12 +487,7 @@ debug = true; break; case ARGP_KEY_ARG: - /* Cryptsetup always passes an argument, which is an empty - string if "none" was specified in /etc/crypttab. So if - argument was empty, we ignore it silently. */ - if(arg[0] != '\0'){ - fprintf(stderr, "Ignoring unknown argument \"%s\"\n", arg); - } + fprintf(stderr, "Ignoring unknown argument \"%s\"\n", arg); break; case ARGP_KEY_END: break; @@ -503,7 +512,6 @@ case 128: /* --plugin-dir */ break; case 129: /* --config-file */ - free(argfile); argfile = strdup(arg); if(argfile == NULL){ perror("strdup"); @@ -739,11 +747,7 @@ } char *filename; - if(plugindir == NULL){ - ret = asprintf(&filename, PDIR "/%s", dirst->d_name); - } else { - ret = asprintf(&filename, "%s/%s", plugindir, dirst->d_name); - } + ret = asprintf(&filename, "%s/%s", plugindir, dirst->d_name); if(ret < 0){ perror("asprintf"); continue; @@ -938,7 +942,7 @@ } /* OK, now either a process completed, or something can be read from one of them */ - for(plugin *proc = plugin_list; proc != NULL;){ + for(plugin *proc = plugin_list; proc != NULL; proc = proc->next){ /* Is this process completely done? */ if(proc->eof and proc->completed){ /* Only accept the plugin output if it exited cleanly */ @@ -971,7 +975,7 @@ exitstatus = EXIT_FAILURE; goto fallback; } - + free_plugin(proc); /* We are done modifying process list, so unblock signal */ ret = sigprocmask (SIG_UNBLOCK, &sigchld_action.sa_mask, NULL); @@ -984,10 +988,6 @@ if(plugin_list == NULL){ break; } - - plugin *next_plugin = proc->next; - free_plugin(proc); - proc = next_plugin; continue; } @@ -1005,7 +1005,6 @@ /* This process has not completed. Does it have any output? */ if(proc->eof or not FD_ISSET(proc->fd, &rfds)){ /* This process had nothing to say at this time */ - proc = proc->next; continue; } /* Before reading, make the process' data buffer large enough */ @@ -1024,7 +1023,6 @@ BUFFER_SIZE); if(ret < 0){ /* Read error from this process; ignore the error */ - proc = proc->next; continue; } if(ret == 0){ @@ -1045,13 +1043,7 @@ bool bret; fprintf(stderr, "Going to fallback mode using getpass(3)\n"); char *passwordbuffer = getpass("Password: "); - size_t len = strlen(passwordbuffer); - /* Strip trailing newline */ - if(len > 0 and passwordbuffer[len-1] == '\n'){ - passwordbuffer[len-1] = '\0'; /* not strictly necessary */ - len--; - } - bret = print_out_password(passwordbuffer, len); + bret = print_out_password(passwordbuffer, strlen(passwordbuffer)); if(not bret){ perror("print_out_password"); exitstatus = EXIT_FAILURE; === removed file 'plugin-runner.conf' --- plugin-runner.conf 2008-09-06 16:31:49 +0000 +++ plugin-runner.conf 1970-01-01 00:00:00 +0000 @@ -1,9 +0,0 @@ -## This is the configuration file for plugin-runner. It should be -## installed as "/etc/mandos/plugin-runner.conf", which will be copied -## to "/conf/conf.d/mandos/plugin-runner.conf" in the initrd.img file. -## -## The default network interface for mandos-client(8mandos) is -## "eth0". Uncomment this line and change it if necessary. -## - -#--options-for=mandos-client:--interface=eth0 === modified file 'plugin-runner.xml' --- plugin-runner.xml 2008-09-06 16:31:49 +0000 +++ plugin-runner.xml 2008-09-02 13:04:42 +0000 @@ -3,7 +3,7 @@ "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [ - + ]> @@ -45,7 +45,7 @@ &COMMANDNAME; - Run Mandos plugins, pass data from first to succeed. + Run Mandos plugins. Pass data from first succesful one. @@ -140,11 +140,11 @@ DESCRIPTION &COMMANDNAME; is a program which is meant to - be specified as a keyscript for the root disk in - crypttab - 5. The aim of this - program is therefore to output a password, which then - cryptsetup + be specified as keyscript in + crypttab + 5 for the root disk. The + aim of this program is therefore to output a password, which + then cryptsetup 8 will use to unlock the root disk. @@ -272,7 +272,7 @@ Re-enable the plugin named PLUGIN. This is only useful to undo a previous option, maybe - from the configuration file. + from the config file. @@ -416,11 +416,6 @@ console. - If the password is a single-line, manually entered passprase, - a final trailing newline character should - not be printed. - - The plugin will run in the initial RAM disk environment, so care must be taken not to depend on any files or running services not available there. @@ -433,8 +428,8 @@ The plugin must not use resources, like for instance reading - from the standard input, without knowing that no other plugin - is also using it. + from the standard input, without knowing that no other plugins + are also using it. It is useful, but not required, for the plugin to take the @@ -472,7 +467,7 @@ only passes on its environment to all the plugins. The environment passed to plugins can be modified using the and - options. + optins. @@ -515,13 +510,11 @@ - - BUGS - - The option is ignored when - specified from within a configuration file. - - + + + + + EXAMPLE @@ -569,15 +562,15 @@ - Run plugins from a different directory, read a different - configuration file, and add two options to the - mandos-client + Run plugins from a different directory and add a special + option to the password-request 8mandos plugin: -&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 +&COMMANDNAME; --plugin-dir=plugins.d --options-for=password-request:--keydir=keydir @@ -591,16 +584,16 @@ non-privileged. This user and group is then what all plugins will be started as. Therefore, the only way to run a plugin as a privileged user is to have the set-user-ID or set-group-ID bit - set on the plugin executable file (see + set on the plugin executable files (see execve2 ). If this program is used as a keyscript in crypttab5 - , there is a slight risk that if this program - fails to work, there might be no way to boot the system except - for booting from another media and editing the initial RAM disk + , there is a risk that if this program fails to + work, there might be no way to boot the system except for + booting from another media and editing the initial RAM disk image to not run this program. This is, however, unlikely, since the password-prompt8mandos @@ -625,7 +618,7 @@ 8, password-prompt 8mandos, - mandos-client + password-request 8mandos === modified file 'plugins.d/password-prompt.c' --- plugins.d/password-prompt.c 2008-09-07 01:44:44 +0000 +++ plugins.d/password-prompt.c 2008-08-29 05:53:59 +0000 @@ -216,11 +216,6 @@ status = EXIT_SUCCESS; /* Make n = data size instead of allocated buffer size */ n = (size_t)ret; - /* Strip final newline */ - if(n>0 and buffer[n-1] == '\n'){ - buffer[n-1] = '\0'; /* not strictly necessary */ - n--; - } size_t written = 0; while(written < n){ ret = write(STDOUT_FILENO, buffer + written, n - written); @@ -249,8 +244,6 @@ fprintf(stderr, "getline() returned 0, retrying.\n"); } } - - free(buffer); if (debug){ fprintf(stderr, "Restoring terminal attributes\n"); @@ -263,9 +256,6 @@ fprintf(stderr, "%s is exiting with status %d\n", argv[0], status); } - if(status == EXIT_SUCCESS){ - fputc('\n', stderr); - } return status; } === modified file 'plugins.d/password-prompt.xml' --- plugins.d/password-prompt.xml 2008-09-06 16:31:49 +0000 +++ plugins.d/password-prompt.xml 2008-09-01 08:29:23 +0000 @@ -3,7 +3,7 @@ "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [ - + ]> @@ -87,7 +87,7 @@ is not very useful on its own. This program is really meant to run as a plugin in the Mandos client-side system, where it is used as a fallback and - alternative to retrieving passwords from a Mandos server. @@ -240,7 +240,7 @@ Show a prefix before the prompt; in this case, a host name. It might be useful to be reminded of which host needs a - password, in case of KVM switches, etc. + password, in case of KVM switches, etc. @@ -270,7 +270,7 @@ >plugin-runner8mandos , and will, when run standalone, outside, in a normal environment, immediately output on its standard output - any presumably secret password it just received. Therefore, + any presumably secret password it just recieved. Therefore, when running this program standalone (which should never normally be done), take care not to type in any real secret password by force of habit, since it would then immediately be @@ -290,7 +290,7 @@ crypttab 5 - mandos-client + password-request 8mandos plugin-runner 8mandos, === renamed file 'plugins.d/mandos-client.c' => 'plugins.d/password-request.c' --- plugins.d/mandos-client.c 2008-09-07 01:44:44 +0000 +++ plugins.d/password-request.c 2008-09-03 19:04:05 +0000 @@ -107,11 +107,11 @@ #define PATHDIR "/conf/conf.d/mandos" #define SECKEY "seckey.txt" -#define PUBKEY "pubkey.txt" +#define PUBKEY "pupkey.txt" bool debug = false; static const char mandos_protocol_version[] = "1"; -const char *argp_program_version = "mandos-client 1.0"; +const char *argp_program_version = "password-request 1.0"; const char *argp_program_bug_address = ""; /* Used for passing in values through the Avahi callback functions */ @@ -150,7 +150,7 @@ int ret; gpgme_error_t rc; gpgme_engine_info_t engine_info; - + /* * Helper function to insert pub and seckey to the enigne keyring. @@ -171,14 +171,14 @@ gpgme_strsource(rc), gpgme_strerror(rc)); return false; } - + rc = gpgme_op_import(mc->ctx, pgp_data); if (rc != GPG_ERR_NO_ERROR){ fprintf(stderr, "bad gpgme_op_import: %s: %s\n", gpgme_strsource(rc), gpgme_strerror(rc)); return false; } - + ret = TEMP_FAILURE_RETRY(close(fd)); if(ret == -1){ perror("close"); @@ -190,7 +190,7 @@ if (debug){ fprintf(stderr, "Initialize gpgme\n"); } - + /* Init GPGME */ gpgme_check_version(NULL); rc = gpgme_engine_check_version(GPGME_PROTOCOL_OpenPGP); @@ -199,7 +199,7 @@ gpgme_strsource(rc), gpgme_strerror(rc)); return false; } - + /* Set GPGME home directory for the OpenPGP engine only */ rc = gpgme_get_engine_info (&engine_info); if (rc != GPG_ERR_NO_ERROR){ @@ -219,7 +219,7 @@ fprintf(stderr, "Could not set GPGME home dir to %s\n", tempdir); return false; } - + /* Create new GPGME "context" */ rc = gpgme_new(&(mc->ctx)); if (rc != GPG_ERR_NO_ERROR){ @@ -315,7 +315,7 @@ /* Seek back to the beginning of the GPGME plaintext data buffer */ if (gpgme_data_seek(dh_plain, (off_t) 0, SEEK_SET) == -1){ - perror("gpgme_data_seek"); + perror("pgpme_data_seek"); plaintext_length = -1; goto decrypt_end; } @@ -451,7 +451,6 @@ gnutls_certificate_free_credentials(mc->cred); gnutls_global_deinit(); - gnutls_dh_params_deinit(mc->dh_params); return -1; } @@ -831,7 +830,7 @@ .dh_bits = 1024, .priority = "SECURE256" ":!CTYPE-X.509:+CTYPE-OPENPGP" }; bool gnutls_initalized = false; - bool gpgme_initalized = false; + bool pgpme_initalized = false; { struct argp_option options[] = { @@ -919,6 +918,29 @@ } } + ret = init_gnutls_global(&mc, pubkey, seckey); + if (ret == -1){ + fprintf(stderr, "init_gnutls_global failed\n"); + exitcode = EXIT_FAILURE; + goto end; + } else { + gnutls_initalized = true; + } + + if(mkdtemp(tempdir) == NULL){ + perror("mkdtemp"); + tempdir[0] = '\0'; + goto end; + } + + if(not init_gpgme(&mc, pubkey, seckey, tempdir)){ + fprintf(stderr, "pgpme_initalized failed\n"); + exitcode = EXIT_FAILURE; + goto end; + } else { + pgpme_initalized = true; + } + /* If the interface is down, bring it up */ { sd = socket(PF_INET6, SOCK_DGRAM, IPPROTO_IP); @@ -962,29 +984,6 @@ perror("setgid"); } - ret = init_gnutls_global(&mc, pubkey, seckey); - if (ret == -1){ - fprintf(stderr, "init_gnutls_global failed\n"); - exitcode = EXIT_FAILURE; - goto end; - } else { - gnutls_initalized = true; - } - - if(mkdtemp(tempdir) == NULL){ - perror("mkdtemp"); - tempdir[0] = '\0'; - goto end; - } - - if(not init_gpgme(&mc, pubkey, seckey, tempdir)){ - fprintf(stderr, "gpgme_initalized failed\n"); - exitcode = EXIT_FAILURE; - goto end; - } else { - gpgme_initalized = true; - } - if_index = (AvahiIfIndex) if_nametoindex(interface); if(if_index == 0){ fprintf(stderr, "No such interface: \"%s\"\n", interface); @@ -1099,13 +1098,12 @@ if (gnutls_initalized){ gnutls_certificate_free_credentials(mc.cred); gnutls_global_deinit (); - gnutls_dh_params_deinit(mc.dh_params); } - - if(gpgme_initalized){ + + if(pgpme_initalized){ gpgme_release(mc.ctx); } - + /* Removes the temp directory used by GPGME */ if(tempdir[0] != '\0'){ DIR *d; @@ -1135,7 +1133,6 @@ free(fullname); } } - closedir(d); } ret = rmdir(tempdir); if(ret == -1){ === renamed file 'plugins.d/mandos-client.xml' => 'plugins.d/password-request.xml' --- plugins.d/mandos-client.xml 2008-09-06 16:33:08 +0000 +++ plugins.d/password-request.xml 2008-09-03 20:31:19 +0000 @@ -2,8 +2,8 @@ - - + + ]> @@ -45,7 +45,7 @@ &COMMANDNAME; - Client for Mandos + Client for mandos @@ -54,10 +54,10 @@ &COMMANDNAME; @@ -124,7 +124,7 @@ network connectivity, Zeroconf to find servers, and TLS with an OpenPGP key to ensure authenticity and confidentiality. It keeps running, trying all servers on the network, until it - receives a satisfactory reply or a TERM signal is received. + receives a satisfactory reply or a TERM signal is recieved. This program is not meant to be run directly; it is really meant @@ -311,12 +311,10 @@ /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 will prompt for passwords on - the system console. + at all. This is why a separate plugin ( + password-prompt + 8mandos) does that, which + will be run in parallell to this one by the plugin runner. @@ -329,7 +327,7 @@ program will exit with a non-zero exit status only if a critical error occurs. Otherwise, it will forever connect to new Mandos servers as they appear, trying - to get a decryptable password and print it. + to get a decryptable password. @@ -388,8 +386,7 @@ - Search for Mandos servers (and connect to them) using another - interface: + Search for Mandos servers on another interface: