=== modified file 'INSTALL' --- INSTALL 2014-06-22 02:19:30 +0000 +++ INSTALL 2014-07-17 02:45:02 +0000 @@ -4,14 +4,15 @@ ** Operating System - Debian 6.0 "squeeze" or Ubuntu 10.10 "Maverick Meerkat". + Debian 6.0 "squeeze" or Ubuntu 10.10 "Maverick Meerkat" (or later). This is mostly for the support scripts which make sure that the client is installed and started in the initial RAM disk environment - and that the initrd.img file is automatically made unreadable. The - server and client programs themselves *could* be run in other - distributions, but they *are* specific to GNU/Linux systems, and - are not written with portabillity to other Unixes in mind. + and that the initial RAM file system image file is automatically + made unreadable. The server and client programs themselves *could* + be run in other distributions, but they *are* specific to GNU/Linux + systems, and are not written with portabillity to other Unixes in + mind. ** Libraries @@ -27,7 +28,7 @@ + DocBook 4.5 http://www.docbook.org/ Note: DocBook 5.0 is not compatible. + DocBook XSL stylesheets 1.71.0 - http://wiki.docbook.org/topic/DocBookXslStylesheets + http://wiki.docbook.org/DocBookXslStylesheets Package names: docbook docbook-xsl @@ -37,36 +38,41 @@ "man -l mandos.8". *** Mandos Server - + GnuTLS 2.4 http://www.gnu.org/software/gnutls/ + + GnuTLS 2.4 http://www.gnutls.org/ + Note: GnuTLS 3 will only work with Python-GnuTLS 2 + Avahi 0.6.16 http://www.avahi.org/ - + Python 2.6 http://www.python.org/ - + Python-GnuTLS 1.1.5 http://pypi.python.org/pypi/python-gnutls/ + + Python 2.6 https://www.python.org/ + + Python-GnuTLS 1.1.5 https://pypi.python.org/pypi/python-gnutls/ + dbus-python 0.82.4 http://dbus.freedesktop.org/doc/dbus-python/ - + PyGObject 2.14.2 http://library.gnome.org/devel/pygobject/ - + Urwid 0.9.8.3 http://excess.org/urwid/ + + PyGObject 2.14.2 https://developer.gnome.org/pygobject/ + + pkg-config http://www.freedesktop.org/wiki/Software/pkg-config/ + + Python-argparse https://pypi.python.org/pypi/argparse + + Urwid 1.0.1 http://urwid.org/ + (Only needed by the "mandos-monitor" tool.) Strongly recommended: - + fping 2.4b2-to-ipv6 http://www.fping.com/ + + fping 2.4b2-to-ipv6 http://www.fping.org/ + ssh-keyscan from OpenSSH http://www.openssh.com/ Package names: python-gnutls avahi-daemon python python-avahi python-dbus - python-gobject python-urwid ssh-client + python-gobject python-urwid pkg-config fping ssh-client *** Mandos Client + initramfs-tools 0.85i - http://packages.qa.debian.org/i/initramfs-tools.html - + GnuTLS 2.4 http://www.gnu.org/software/gnutls/ - + Avahi 0.6.16 http://www.avahi.org/ - + GnuPG 1.4.9 http://www.gnupg.org/ - + GPGME 1.1.6 http://www.gnupg.org/related_software/gpgme/ + https://tracker.debian.org/pkg/initramfs-tools + + GnuTLS 2.4 http://www.gnutls.org/ + + Avahi 0.6.16 http://www.avahi.org/ + + GnuPG 1.4.9 https://www.gnupg.org/ + + GPGME 1.1.6 https://www.gnupg.org/related_software/gpgme/ + + pkg-config http://www.freedesktop.org/wiki/Software/pkg-config/ Strongly recommended: - + OpenSSH http://www.openssh.com/ + + OpenSSH http://www.openssh.com/ Package names: initramfs-tools libgnutls-dev libavahi-core-dev gnupg - libgpgme11-dev ssh + libgpgme11-dev pkg-config ssh * Installing the Mandos server @@ -102,15 +108,11 @@ and append this to the file "/etc/mandos/clients.conf" *on the server computer*. - 4. Configure the client to use the correct network interface. The - interface to use is automatically chosen at boot, and if this - needs to be adjusted, it will be necessary to edit - /etc/initramfs-tools/initramfs.conf to change the DEVICE setting - there. Alternatively, the file /etc/mandos/plugin-runner.conf - can be edited to add a "--device" parameter for the - mandos-client(8) plugin. Please note: If any of those files are - changed, the initrd.img file must be updated, possibly using the - following command: + 4. Configure the client to use any special configuration needed for + your local system. Note: This is not necessary if the server is + present on the same wired local network as the client. If you do + make changes to /etc/mandos/plugin-runner.conf, the initrd.img + file must be updated, possibly using the following command: # update-initramfs -k all -u @@ -130,7 +132,7 @@ After this, the client computer should be able to reboot without needing a password entered on the console, as long as it does not - take more than an hour to reboot. + take more than five minutes to reboot. * Further customizations === modified file 'TODO' --- TODO 2014-06-22 02:19:30 +0000 +++ TODO 2014-07-14 21:41:08 +0000 @@ -106,7 +106,6 @@ *** Properties popup ** Print a nice "We are sorry" message, save stack trace to log. ** Rename module "gobject" to "GObject". -** TODO Optional verbose mode to see checkers starting and succeeding * mandos-keygen ** TODO "--secfile" option === modified file 'initramfs-tools-hook' --- initramfs-tools-hook 2013-10-28 08:38:47 +0000 +++ initramfs-tools-hook 2014-07-16 23:44:54 +0000 @@ -150,11 +150,17 @@ done # GPGME needs GnuPG +gpg=/usr/bin/gpg libgpgme11_version="`dpkg-query --showformat='${Version}' --show libgpgme11`" -if dpkg --compare-versions "$libgpgme11_version" ge 1.4.1-0.1; then +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 + copy_exec /usr/bin/gpgconf + fi + gpg="`/usr/bin/gpgconf|sed --quiet --expression='s/^gpg:[^:]*://p'`" + fi +elif dpkg --compare-versions "$libgpgme11_version" ge 1.4.1-0.1; then gpg=/usr/bin/gpg2 -else - gpg=/usr/bin/gpg fi if [ ! -e "${DESTDIR}$gpg" ]; then copy_exec "$gpg" === modified file 'mandos-ctl' --- mandos-ctl 2014-07-13 21:02:53 +0000 +++ mandos-ctl 2014-07-17 00:49:30 +0000 @@ -26,7 +26,10 @@ from __future__ import (division, absolute_import, print_function, unicode_literals) -from future_builtins import * +try: + from future_builtins import * +except ImportError: + pass import sys import argparse @@ -39,6 +42,9 @@ import dbus +if sys.version_info[0] == 2: + str = unicode + locale.setlocale(locale.LC_ALL, "") tablewords = { @@ -230,7 +236,7 @@ if keyword in ("Timeout", "Interval", "ApprovalDelay", "ApprovalDuration", "ExtendedTimeout"): return milliseconds_to_string(value) - return unicode(value) + return str(value) # Create format string to print table rows format_string = " ".join("{{{key}:{width}}}".format( @@ -310,7 +316,8 @@ parser.add_argument("--approval-duration", help="Set duration of one client approval") parser.add_argument("-H", "--host", help="Set host for client") - parser.add_argument("-s", "--secret", type=file, + parser.add_argument("-s", "--secret", + type=argparse.FileType(mode="rb"), help="Set password blob (file) for client") parser.add_argument("-A", "--approve", action="store_true", help="Approve any current client request") @@ -367,7 +374,7 @@ if options.all or not options.client: clients = dict((bus.get_object(busname, path), properties) for path, properties in - mandos_clients.iteritems()) + mandos_clients.items()) else: for name in options.client: for path, client in mandos_clients.iteritems(): === modified file 'mandos-monitor' --- mandos-monitor 2014-07-13 21:02:53 +0000 +++ mandos-monitor 2014-07-14 21:41:08 +0000 @@ -161,8 +161,8 @@ self.rejected, client_interface, byte_arrays=True)) - #self.logger('Created client {0}' - # .format(self.properties["Name"])) + self.logger('Created client {0}' + .format(self.properties["Name"]), level=0) def using_timer(self, flag): """Call this method with True or False when timer should be @@ -179,6 +179,9 @@ def checker_completed(self, exitstatus, condition, command): if exitstatus == 0: + self.logger('Checker for client {0} (command "{1}")' + ' succeeded'.format(self.properties["Name"], + command), level=0) self.update() return # Checker failed @@ -203,12 +206,10 @@ self.update() def checker_started(self, command): - """Server signals that a checker started. This could be useful - to log in the future. """ - #self.logger('Client {0} started checker "{1}"' - # .format(self.properties["Name"], - # str(command))) - pass + """Server signals that a checker started.""" + self.logger('Client {0} started checker "{1}"' + .format(self.properties["Name"], + command), level=0) def got_secret(self): self.logger('Client {0} received its secret' @@ -403,7 +404,7 @@ """This is the entire user interface - the whole screen with boxes, lists of client widgets, etc. """ - def __init__(self, max_log_length=1000): + def __init__(self, max_log_length=1000, log_level=1): DBusGMainLoop(set_as_default=True) self.screen = urwid.curses_display.Screen() @@ -447,6 +448,8 @@ self.log = [] self.max_log_length = max_log_length + self.log_level = log_level + # We keep a reference to the log widget so we can remove it # from the ListWalker without it getting destroyed self.logbox = ConstrainedListBox(self.log) @@ -486,13 +489,18 @@ self.uilist.append(self.logbox) self.topwidget = urwid.Pile(self.uilist) - def log_message(self, message): + def log_message(self, message, level=1): """Log message formatted with timestamp""" + if level < self.log_level: + return timestamp = datetime.datetime.now().isoformat() - self.log_message_raw(timestamp + ": " + message) + self.log_message_raw("{0}: {1}".format(timestamp, message), + level=level) - def log_message_raw(self, markup): + def log_message_raw(self, markup, level=1): """Add a log message to the log buffer.""" + if level < self.log_level: + return self.log.append(urwid.Text(markup, wrap=self.log_wrap)) if (self.max_log_length and len(self.log) > self.max_log_length): @@ -505,8 +513,8 @@ """Toggle visibility of the log buffer.""" self.log_visible = not self.log_visible self.rebuild() - #self.log_message("Log visibility changed to: " - # + str(self.log_visible)) + self.log_message("Log visibility changed to: {0}" + .format(self.log_visible), level=0) def change_log_display(self): """Change type of log display. @@ -517,7 +525,8 @@ self.log_wrap = "clip" for textwidget in self.log: textwidget.set_wrap_mode(self.log_wrap) - #self.log_message("Wrap mode: " + self.log_wrap) + self.log_message("Wrap mode: {0}".format(self.log_wrap), + level=0) def find_and_remove_client(self, path, name): """Find a client by its object path and remove it. @@ -670,7 +679,9 @@ "?: Help", "l: Log window toggle", "TAB: Switch window", - "w: Wrap (log)")))) + "w: Wrap (log lines)", + "v: Toggle verbose log", + )))) self.log_message_raw(("bold", " " .join(("Clients:", @@ -689,6 +700,13 @@ else: self.topwidget.set_focus(self.logbox) self.refresh() + elif key == "v": + if self.log_level == 0: + self.log_level = 1 + self.log_message("Verbose mode: Off") + else: + self.log_level = 0 + self.log_message("Verbose mode: On") #elif (key == "end" or key == "meta >" or key == "G" # or key == ">"): # pass # xxx end-of-buffer === modified file 'mandos-monitor.xml' --- mandos-monitor.xml 2011-12-31 23:05:34 +0000 +++ mandos-monitor.xml 2014-07-14 21:41:08 +0000 @@ -2,7 +2,7 @@ - + %common; ]> @@ -129,6 +129,10 @@ Toggle log window line wrap + v + Toggle verbose logging + + Up, Ctrl-P, k Move up a line === modified file 'mandos.lsm' --- mandos.lsm 2014-07-13 21:02:53 +0000 +++ mandos.lsm 2014-07-14 10:03:10 +0000 @@ -11,13 +11,13 @@ belorn@recompile.se (Björn Påhlsson) Maintained-by: teddy@recompile.se (Teddy Hogeborn), belorn@recompile.se (Björn Påhlsson) -Primary-site: http://www.recompile.se/mandos - 160K mandos_1.6.6.orig.tar.gz -Alternate-site: ftp://ftp.recompile.se/pub/mandos +Primary-site: http://www.recompile.se/mandos + 160K mandos_1.6.6.orig.tar.gz +Alternate-site: ftp://ftp.recompile.se/pub/mandos 160K mandos_1.6.6.orig.tar.gz Platforms: Requires GCC, GNU libC, Avahi, GnuPG, Python 2.6, and various other libraries. While made for Debian GNU/Linux, it is probably portable to other - distributions, but not other Unixes. -Copying-policy: GNU General Public License version 3.0 or later + distributions, but not other Unixes. +Copying-policy: GNU General Public License version 3.0 or later End === modified file 'plugin-runner.c' --- plugin-runner.c 2014-06-14 23:43:07 +0000 +++ plugin-runner.c 2014-07-16 01:41:23 +0000 @@ -887,12 +887,14 @@ int plugin_fd = openat(dir_fd, direntries[i]->d_name, O_RDONLY); if(plugin_fd == -1){ error(0, errno, "Could not open plugin"); + free(direntries[i]); continue; } ret = (int)TEMP_FAILURE_RETRY(fstat(plugin_fd, &st)); if(ret == -1){ error(0, errno, "stat"); TEMP_FAILURE_RETRY(close(plugin_fd)); + free(direntries[i]); continue; } @@ -907,6 +909,7 @@ direntries[i]->d_name); } TEMP_FAILURE_RETRY(close(plugin_fd)); + free(direntries[i]); continue; } @@ -914,6 +917,7 @@ if(p == NULL){ error(0, errno, "getplugin"); TEMP_FAILURE_RETRY(close(plugin_fd)); + free(direntries[i]); continue; } if(p->disabled){ @@ -922,6 +926,7 @@ direntries[i]->d_name); } TEMP_FAILURE_RETRY(close(plugin_fd)); + free(direntries[i]); continue; } { @@ -960,6 +965,7 @@ if(ret == -1){ error(0, errno, "pipe"); exitstatus = EX_OSERR; + free(direntries[i]); goto fallback; } if(pipefd[0] >= FD_SETSIZE){ @@ -968,6 +974,7 @@ TEMP_FAILURE_RETRY(close(pipefd[0])); TEMP_FAILURE_RETRY(close(pipefd[1])); exitstatus = EX_OSERR; + free(direntries[i]); goto fallback; } #ifndef O_CLOEXEC @@ -978,6 +985,7 @@ TEMP_FAILURE_RETRY(close(pipefd[0])); TEMP_FAILURE_RETRY(close(pipefd[1])); exitstatus = EX_OSERR; + free(direntries[i]); goto fallback; } ret = set_cloexec_flag(pipefd[1]); @@ -986,6 +994,7 @@ TEMP_FAILURE_RETRY(close(pipefd[0])); TEMP_FAILURE_RETRY(close(pipefd[1])); exitstatus = EX_OSERR; + free(direntries[i]); goto fallback; } #endif /* not O_CLOEXEC */ @@ -996,6 +1005,7 @@ if(ret < 0){ error(0, errno, "sigprocmask"); exitstatus = EX_OSERR; + free(direntries[i]); goto fallback; } /* Starting a new process to be watched */ @@ -1010,6 +1020,7 @@ TEMP_FAILURE_RETRY(close(pipefd[0])); TEMP_FAILURE_RETRY(close(pipefd[1])); exitstatus = EX_OSERR; + free(direntries[i]); goto fallback; } if(pid == 0){ @@ -1054,8 +1065,10 @@ error(0, errno, "sigprocmask"); } exitstatus = EX_OSERR; + free(direntries[i]); goto fallback; } + free(direntries[i]); new_plugin->pid = pid; new_plugin->fd = pipefd[0]; === modified file 'plugins.d/mandos-client.c' --- plugins.d/mandos-client.c 2014-07-12 13:13:28 +0000 +++ plugins.d/mandos-client.c 2014-07-15 23:52:00 +0000 @@ -240,7 +240,14 @@ ret = clock_gettime(CLOCK_MONOTONIC, &(new_server->last_seen)); if(ret == -1){ perror_plus("clock_gettime"); - free(new_server->ip); +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-qual" +#endif + free((char *)(new_server->ip)); +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif free(new_server); return false; } @@ -1069,6 +1076,7 @@ timed out */ if(quit_now){ + avahi_s_service_resolver_free(r); return; } @@ -1645,6 +1653,7 @@ int status; if(TEMP_FAILURE_RETRY(waitpid(hook_pid, &status, 0)) == -1){ perror_plus("waitpid"); + free(direntry); continue; } if(WIFEXITED(status)){ @@ -1652,16 +1661,19 @@ fprintf_plus(stderr, "Warning: network hook \"%s\" exited" " with status %d\n", direntry->d_name, WEXITSTATUS(status)); + free(direntry); continue; } } else if(WIFSIGNALED(status)){ fprintf_plus(stderr, "Warning: network hook \"%s\" died by" " signal %d\n", direntry->d_name, WTERMSIG(status)); + free(direntry); continue; } else { fprintf_plus(stderr, "Warning: network hook \"%s\"" " crashed\n", direntry->d_name); + free(direntry); continue; } } @@ -1669,6 +1681,7 @@ fprintf_plus(stderr, "Network hook \"%s\" ran successfully\n", direntry->d_name); } + free(direntry); } free(direntries); if((int)TEMP_FAILURE_RETRY(close(hookdir_fd)) == -1){ @@ -2268,12 +2281,14 @@ if(ret_errno != 0){ errno = ret_errno; perror_plus("argz_add"); + free(direntries[i]); continue; } if(debug){ fprintf_plus(stderr, "Will use interface \"%s\"\n", direntries[i]->d_name); } + free(direntries[i]); } free(direntries); } else { @@ -2549,6 +2564,14 @@ mc.current_server->prev->next = NULL; while(mc.current_server != NULL){ server *next = mc.current_server->next; +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-qual" +#endif + free((char *)(mc.current_server->ip)); +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif free(mc.current_server); mc.current_server = next; } @@ -2623,6 +2646,7 @@ " \"%s\", 0): %s\n", tempdir, direntries[i]->d_name, strerror(errno)); } + free(direntries[i]); } /* need to clean even if 0 because man page doesn't specify */