=== modified file 'DBUS-API' --- DBUS-API 2010-09-26 18:32:58 +0000 +++ DBUS-API 2011-02-27 17:26:35 +0000 @@ -149,8 +149,8 @@ * Copyright - Copyright © 2010 Teddy Hogeborn - Copyright © 2010 Björn Påhlsson + Copyright © 2010-2011 Teddy Hogeborn + Copyright © 2010-2011 Björn Påhlsson ** License: === modified file 'INSTALL' --- INSTALL 2009-02-15 09:28:06 +0000 +++ INSTALL 2011-03-08 19:09:03 +0000 @@ -4,14 +4,14 @@ ** Operating System - Debian 5.0 "lenny" or Ubuntu 8.04 "Hardy Heron". + Debian 6.0 "squeeze" or Ubuntu 10.10 "Maverick Meerkat". 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 intended to be portable to other Unixes. + are not written with portabillity to other Unixes in mind. ** Libraries @@ -39,18 +39,18 @@ *** Mandos Server + GnuTLS 2.4 http://www.gnu.org/software/gnutls/ + Avahi 0.6.16 http://www.avahi.org/ - + Python 2.5 http://www.python.org/ + + Python 2.6 http://www.python.org/ + Python-GnuTLS 1.1.5 http://pypi.python.org/pypi/python-gnutls/ + dbus-python 0.82.4 http://dbus.freedesktop.org/doc/dbus-python/ - + python-ctypes 1.0.0 http://pypi.python.org/pypi/ctypes + PyGObject 2.14.2 http://library.gnome.org/devel/pygobject/ + + Urwid 0.9.8.3 http://excess.org/urwid/ Strongly recommended: + fping 2.4b2-to-ipv6 http://www.fping.com/ Package names: python-gnutls avahi-daemon python python-avahi python-dbus - python-ctypes python-gobject + python-gobject python-urwid *** Mandos Client + initramfs-tools 0.85i @@ -99,16 +99,20 @@ server computer*. 4. Configure the client to use the correct network interface. The - default is "eth0", and if this needs to be adjusted, it will be - necessary to edit /etc/mandos/plugin-runner.conf to uncomment and - change the line there. If that file is changed, the initrd.img - file must be updated, possibly using the following command: + 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: # update-initramfs -k all -u 5. On the server computer, start the server by running the command For Debian: su -c 'invoke-rc.d mandos start' - For Ubuntu: sudo invoke-rc.d mandos start + For Ubuntu: sudo service mandos start At this point, it is possible to verify that the correct password will be received by the client by running the command: === modified file 'README' --- README 2010-09-26 18:32:58 +0000 +++ README 2011-02-27 17:26:35 +0000 @@ -162,8 +162,8 @@ * Copyright - Copyright © 2008-2010 Teddy Hogeborn - Copyright © 2008-2010 Björn Påhlsson + Copyright © 2008-2011 Teddy Hogeborn + Copyright © 2008-2011 Björn Påhlsson ** License: === modified file 'TODO' --- TODO 2010-09-26 18:32:58 +0000 +++ TODO 2010-11-16 17:58:49 +0000 @@ -2,6 +2,8 @@ * Use _attribute_((nonnull)) wherever possible. +* mandos-applet + * mandos-client ** TODO [#B] use scandir(3) instead of readdir(3) ** TODO [#B] Prefix all debug output with "Mandos plugin " + program_invocation_short_name === modified file 'debian/control' --- debian/control 2010-10-01 18:40:55 +0000 +++ debian/control 2011-02-27 17:46:47 +0000 @@ -14,9 +14,9 @@ Package: mandos Architecture: all -Depends: ${misc:Depends}, python (>=2.5), python-gnutls, python-dbus, +Depends: ${misc:Depends}, python (>=2.6), python-gnutls, python-dbus, python-avahi, python-gobject, avahi-daemon, adduser, - python-urwid, python (>=2.6) | python-multiprocessing + python-urwid Recommends: fping Description: a server giving encrypted passwords to Mandos clients This is the server part of the Mandos system, which allows @@ -37,6 +37,7 @@ Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends}, adduser, cryptsetup, gnupg (<< 2) +Conflicts: dropbear (<< 0.52-5) Enhances: cryptsetup Description: do unattended reboots with an encrypted root file system This is the client part of the Mandos system, which allows === modified file 'debian/copyright' --- debian/copyright 2010-09-26 18:32:58 +0000 +++ debian/copyright 2011-02-27 17:26:35 +0000 @@ -5,8 +5,8 @@ Upstream-Source: Files: * -Copyright: Copyright © 2008-2010 Teddy Hogeborn -Copyright: Copyright © 2008-2010 Björn Påhlsson +Copyright: Copyright © 2008-2011 Teddy Hogeborn +Copyright: Copyright © 2008-2011 Björn Påhlsson License: GPL-3+ This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as === modified file 'debian/mandos-client.lintian-overrides' --- debian/mandos-client.lintian-overrides 2009-01-18 06:41:57 +0000 +++ debian/mandos-client.lintian-overrides 2010-10-13 06:12:52 +0000 @@ -19,6 +19,7 @@ mandos-client binary: setuid-binary usr/lib/mandos/plugins.d/askpass-fifo 4755 root/root mandos-client binary: setuid-binary usr/lib/mandos/plugins.d/splashy 4755 root/root mandos-client binary: setuid-binary usr/lib/mandos/plugins.d/usplash 4755 root/root +mandos-client binary: setuid-binary usr/lib/mandos/plugins.d/plymouth 4755 root/root # The directory /etc/mandos/plugins.d can be used by local system # administrators to place plugins in, overriding and complementing === modified file 'debian/mandos-client.postrm' --- debian/mandos-client.postrm 2009-01-18 00:16:57 +0000 +++ debian/mandos-client.postrm 2011-02-27 17:00:41 +0000 @@ -45,6 +45,7 @@ rm --force /etc/mandos/plugin-runner.conf \ /etc/keys/mandos/pubkey.txt \ /etc/keys/mandos/seckey.txt 2>/dev/null + update_initramfs ;; upgrade|failed-upgrade|disappear|abort-install|abort-upgrade) ;; === modified file 'mandos' --- mandos 2010-10-11 17:45:21 +0000 +++ mandos 2011-02-27 17:26:35 +0000 @@ -11,8 +11,8 @@ # "AvahiService" class, and some lines in "main". # # Everything else is -# Copyright © 2008-2010 Teddy Hogeborn -# Copyright © 2008-2010 Björn Påhlsson +# Copyright © 2008-2011 Teddy Hogeborn +# Copyright © 2008-2011 Björn Påhlsson # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -31,7 +31,8 @@ # Contact the authors at . # -from __future__ import division, with_statement, absolute_import +from __future__ import (division, absolute_import, print_function, + unicode_literals) import SocketServer as socketserver import socket @@ -83,20 +84,20 @@ version = "1.2.3" -#logger = logging.getLogger(u'mandos') -logger = logging.Logger(u'mandos') +#logger = logging.getLogger('mandos') +logger = logging.Logger('mandos') syslogger = (logging.handlers.SysLogHandler (facility = logging.handlers.SysLogHandler.LOG_DAEMON, - address = "/dev/log")) + address = str("/dev/log"))) syslogger.setFormatter(logging.Formatter - (u'Mandos [%(process)d]: %(levelname)s:' - u' %(message)s')) + ('Mandos [%(process)d]: %(levelname)s:' + ' %(message)s')) logger.addHandler(syslogger) console = logging.StreamHandler() -console.setFormatter(logging.Formatter(u'%(name)s [%(process)d]:' - u' %(levelname)s:' - u' %(message)s')) +console.setFormatter(logging.Formatter('%(name)s [%(process)d]:' + ' %(levelname)s:' + ' %(message)s')) logger.addHandler(console) class AvahiError(Exception): @@ -119,8 +120,8 @@ Attributes: interface: integer; avahi.IF_UNSPEC or an interface index. Used to optionally bind to the specified interface. - name: string; Example: u'Mandos' - type: string; Example: u'_mandos._tcp'. + name: string; Example: 'Mandos' + type: string; Example: '_mandos._tcp'. See port: integer; what port to announce TXT: list of strings; TXT record for the service @@ -135,7 +136,7 @@ """ def __init__(self, interface = avahi.IF_UNSPEC, name = None, servicetype = None, port = None, TXT = None, - domain = u"", host = u"", max_renames = 32768, + domain = "", host = "", max_renames = 32768, protocol = avahi.PROTO_UNSPEC, bus = None): self.interface = interface self.name = name @@ -153,22 +154,22 @@ def rename(self): """Derived from the Avahi example code""" if self.rename_count >= self.max_renames: - logger.critical(u"No suitable Zeroconf service name found" - u" after %i retries, exiting.", + logger.critical("No suitable Zeroconf service name found" + " after %i retries, exiting.", self.rename_count) - raise AvahiServiceError(u"Too many renames") + raise AvahiServiceError("Too many renames") self.name = unicode(self.server.GetAlternativeServiceName(self.name)) - logger.info(u"Changing Zeroconf service name to %r ...", + logger.info("Changing Zeroconf service name to %r ...", self.name) syslogger.setFormatter(logging.Formatter - (u'Mandos (%s) [%%(process)d]:' - u' %%(levelname)s: %%(message)s' + ('Mandos (%s) [%%(process)d]:' + ' %%(levelname)s: %%(message)s' % self.name)) self.remove() try: self.add() except dbus.exceptions.DBusException, error: - logger.critical(u"DBusException: %s", error) + logger.critical("DBusException: %s", error) self.cleanup() os._exit(1) self.rename_count += 1 @@ -186,7 +187,7 @@ self.group.connect_to_signal('StateChanged', self .entry_group_state_changed) - logger.debug(u"Adding Zeroconf service '%s' of type '%s' ...", + logger.debug("Adding Zeroconf service '%s' of type '%s' ...", self.name, self.type) self.group.AddService( self.interface, @@ -199,17 +200,17 @@ self.group.Commit() def entry_group_state_changed(self, state, error): """Derived from the Avahi example code""" - logger.debug(u"Avahi entry group state change: %i", state) + logger.debug("Avahi entry group state change: %i", state) if state == avahi.ENTRY_GROUP_ESTABLISHED: - logger.debug(u"Zeroconf service established.") + logger.debug("Zeroconf service established.") elif state == avahi.ENTRY_GROUP_COLLISION: - logger.warning(u"Zeroconf service name collision.") + logger.info("Zeroconf service name collision.") self.rename() elif state == avahi.ENTRY_GROUP_FAILURE: - logger.critical(u"Avahi: Error in group state changed %s", + logger.critical("Avahi: Error in group state changed %s", unicode(error)) - raise AvahiGroupError(u"State changed: %s" + raise AvahiGroupError("State changed: %s" % unicode(error)) def cleanup(self): """Derived from the Avahi example code""" @@ -218,9 +219,9 @@ self.group = None def server_state_changed(self, state): """Derived from the Avahi example code""" - logger.debug(u"Avahi server state change: %i", state) + logger.debug("Avahi server state change: %i", state) if state == avahi.SERVER_COLLISION: - logger.error(u"Zeroconf server name collision") + logger.error("Zeroconf server name collision") self.remove() elif state == avahi.SERVER_RUNNING: self.add() @@ -231,7 +232,7 @@ self.bus.get_object(avahi.DBUS_NAME, avahi.DBUS_PATH_SERVER), avahi.DBUS_INTERFACE_SERVER) - self.server.connect_to_signal(u"StateChanged", + self.server.connect_to_signal("StateChanged", self.server_state_changed) self.server_state_changed(self.server.GetState()) @@ -272,10 +273,10 @@ runtime_expansions: Allowed attributes for runtime expansion. """ - runtime_expansions = (u"approval_delay", u"approval_duration", - u"created", u"enabled", u"fingerprint", - u"host", u"interval", u"last_checked_ok", - u"last_enabled", u"name", u"timeout") + runtime_expansions = ("approval_delay", "approval_duration", + "created", "enabled", "fingerprint", + "host", "interval", "last_checked_ok", + "last_enabled", "name", "timeout") @staticmethod def _timedelta_to_milliseconds(td): @@ -302,47 +303,47 @@ self.name = name if config is None: config = {} - logger.debug(u"Creating client %r", self.name) + logger.debug("Creating client %r", self.name) # Uppercase and remove spaces from fingerprint for later # comparison purposes with return value from the fingerprint() # function - self.fingerprint = (config[u"fingerprint"].upper() - .replace(u" ", u"")) - logger.debug(u" Fingerprint: %s", self.fingerprint) - if u"secret" in config: - self.secret = config[u"secret"].decode(u"base64") - elif u"secfile" in config: + self.fingerprint = (config["fingerprint"].upper() + .replace(" ", "")) + logger.debug(" Fingerprint: %s", self.fingerprint) + if "secret" in config: + self.secret = config["secret"].decode("base64") + elif "secfile" in config: with open(os.path.expanduser(os.path.expandvars - (config[u"secfile"])), + (config["secfile"])), "rb") as secfile: self.secret = secfile.read() else: - raise TypeError(u"No secret or secfile for client %s" + raise TypeError("No secret or secfile for client %s" % self.name) - self.host = config.get(u"host", u"") + self.host = config.get("host", "") self.created = datetime.datetime.utcnow() self.enabled = False self.last_approval_request = None self.last_enabled = None self.last_checked_ok = None - self.timeout = string_to_delta(config[u"timeout"]) - self.interval = string_to_delta(config[u"interval"]) + self.timeout = string_to_delta(config["timeout"]) + self.interval = string_to_delta(config["interval"]) self.disable_hook = disable_hook self.checker = None self.checker_initiator_tag = None self.disable_initiator_tag = None self.checker_callback_tag = None - self.checker_command = config[u"checker"] + self.checker_command = config["checker"] self.current_checker_command = None self.last_connect = None self._approved = None - self.approved_by_default = config.get(u"approved_by_default", + self.approved_by_default = config.get("approved_by_default", True) self.approvals_pending = 0 self.approval_delay = string_to_delta( - config[u"approval_delay"]) + config["approval_delay"]) self.approval_duration = string_to_delta( - config[u"approval_duration"]) + config["approval_duration"]) self.changedstate = multiprocessing_manager.Condition(multiprocessing_manager.Lock()) def send_changedstate(self): @@ -352,7 +353,7 @@ def enable(self): """Start this client's checker and timeout hooks""" - if getattr(self, u"enabled", False): + if getattr(self, "enabled", False): # Already enabled return self.send_changedstate() @@ -377,11 +378,11 @@ if not quiet: self.send_changedstate() if not quiet: - logger.info(u"Disabling client %s", self.name) - if getattr(self, u"disable_initiator_tag", False): + logger.info("Disabling client %s", self.name) + if getattr(self, "disable_initiator_tag", False): gobject.source_remove(self.disable_initiator_tag) self.disable_initiator_tag = None - if getattr(self, u"checker_initiator_tag", False): + if getattr(self, "checker_initiator_tag", False): gobject.source_remove(self.checker_initiator_tag) self.checker_initiator_tag = None self.stop_checker() @@ -402,14 +403,14 @@ if os.WIFEXITED(condition): exitstatus = os.WEXITSTATUS(condition) if exitstatus == 0: - logger.info(u"Checker for %(name)s succeeded", + logger.info("Checker for %(name)s succeeded", vars(self)) self.checked_ok() else: - logger.info(u"Checker for %(name)s failed", + logger.info("Checker for %(name)s failed", vars(self)) else: - logger.warning(u"Checker for %(name)s crashed?", + logger.warning("Checker for %(name)s crashed?", vars(self)) def checked_ok(self): @@ -450,7 +451,7 @@ raise error else: if pid: - logger.warning(u"Checker was a zombie") + logger.warning("Checker was a zombie") gobject.source_remove(self.checker_callback_tag) self.checker_callback(pid, status, self.current_checker_command) @@ -463,21 +464,21 @@ # Escape attributes for the shell escaped_attrs = dict( (attr, - re.escape(unicode(str(getattr(self, attr, u"")), + re.escape(unicode(str(getattr(self, attr, "")), errors= - u'replace'))) + 'replace'))) for attr in self.runtime_expansions) try: command = self.checker_command % escaped_attrs except TypeError, error: - logger.error(u'Could not format string "%s":' - u' %s', self.checker_command, error) + logger.error('Could not format string "%s":' + ' %s', self.checker_command, error) return True # Try again later self.current_checker_command = command try: - logger.info(u"Starting checker %r for %s", + logger.info("Starting checker %r for %s", command, self.name) # We don't need to redirect stdout and stderr, since # in normal mode, that is already done by daemon(), @@ -485,7 +486,7 @@ # always replaced by /dev/null.) self.checker = subprocess.Popen(command, close_fds=True, - shell=True, cwd=u"/") + shell=True, cwd="/") self.checker_callback_tag = (gobject.child_watch_add (self.checker.pid, self.checker_callback, @@ -497,7 +498,7 @@ gobject.source_remove(self.checker_callback_tag) self.checker_callback(pid, status, command) except OSError, error: - logger.error(u"Failed to start subprocess: %s", + logger.error("Failed to start subprocess: %s", error) # Re-run this periodically if run by gobject.timeout_add return True @@ -507,9 +508,9 @@ if self.checker_callback_tag: gobject.source_remove(self.checker_callback_tag) self.checker_callback_tag = None - if getattr(self, u"checker", None) is None: + if getattr(self, "checker", None) is None: return - logger.debug(u"Stopping checker for %(name)s", vars(self)) + logger.debug("Stopping checker for %(name)s", vars(self)) try: os.kill(self.checker.pid, signal.SIGTERM) #time.sleep(0.5) @@ -520,8 +521,8 @@ raise self.checker = None -def dbus_service_property(dbus_interface, signature=u"v", - access=u"readwrite", byte_arrays=False): +def dbus_service_property(dbus_interface, signature="v", + access="readwrite", byte_arrays=False): """Decorators for marking methods of a DBusObjectWithProperties to become properties on the D-Bus. @@ -534,18 +535,18 @@ """ # Encoding deeply encoded byte arrays is not supported yet by the # "Set" method, so we fail early here: - if byte_arrays and signature != u"ay": - raise ValueError(u"Byte arrays not supported for non-'ay'" - u" signature %r" % signature) + if byte_arrays and signature != "ay": + raise ValueError("Byte arrays not supported for non-'ay'" + " signature %r" % signature) def decorator(func): func._dbus_is_property = True func._dbus_interface = dbus_interface func._dbus_signature = signature func._dbus_access = access func._dbus_name = func.__name__ - if func._dbus_name.endswith(u"_dbus_property"): + if func._dbus_name.endswith("_dbus_property"): func._dbus_name = func._dbus_name[:-14] - func._dbus_get_args_options = {u'byte_arrays': byte_arrays } + func._dbus_get_args_options = {'byte_arrays': byte_arrays } return func return decorator @@ -579,7 +580,7 @@ @staticmethod def _is_dbus_property(obj): - return getattr(obj, u"_dbus_is_property", False) + return getattr(obj, "_dbus_is_property", False) def _get_all_dbus_properties(self): """Returns a generator of (name, attribute) pairs @@ -593,7 +594,7 @@ property with the specified name and interface. """ for name in (property_name, - property_name + u"_dbus_property"): + property_name + "_dbus_property"): prop = getattr(self, name, None) if (prop is None or not self._is_dbus_property(prop) @@ -603,41 +604,41 @@ continue return prop # No such property - raise DBusPropertyNotFound(self.dbus_object_path + u":" - + interface_name + u"." + raise DBusPropertyNotFound(self.dbus_object_path + ":" + + interface_name + "." + property_name) - @dbus.service.method(dbus.PROPERTIES_IFACE, in_signature=u"ss", - out_signature=u"v") + @dbus.service.method(dbus.PROPERTIES_IFACE, in_signature="ss", + out_signature="v") def Get(self, interface_name, property_name): """Standard D-Bus property Get() method, see D-Bus standard. """ prop = self._get_dbus_property(interface_name, property_name) - if prop._dbus_access == u"write": + if prop._dbus_access == "write": raise DBusPropertyAccessException(property_name) value = prop() - if not hasattr(value, u"variant_level"): + if not hasattr(value, "variant_level"): return value return type(value)(value, variant_level=value.variant_level+1) - @dbus.service.method(dbus.PROPERTIES_IFACE, in_signature=u"ssv") + @dbus.service.method(dbus.PROPERTIES_IFACE, in_signature="ssv") def Set(self, interface_name, property_name, value): """Standard D-Bus property Set() method, see D-Bus standard. """ prop = self._get_dbus_property(interface_name, property_name) - if prop._dbus_access == u"read": + if prop._dbus_access == "read": raise DBusPropertyAccessException(property_name) - if prop._dbus_get_args_options[u"byte_arrays"]: + if prop._dbus_get_args_options["byte_arrays"]: # The byte_arrays option is not supported yet on # signatures other than "ay". - if prop._dbus_signature != u"ay": + if prop._dbus_signature != "ay": raise ValueError value = dbus.ByteArray(''.join(unichr(byte) for byte in value)) prop(value) - @dbus.service.method(dbus.PROPERTIES_IFACE, in_signature=u"s", - out_signature=u"a{sv}") + @dbus.service.method(dbus.PROPERTIES_IFACE, in_signature="s", + out_signature="a{sv}") def GetAll(self, interface_name): """Standard D-Bus property GetAll() method, see D-Bus standard. @@ -651,18 +652,18 @@ # Interface non-empty but did not match continue # Ignore write-only properties - if prop._dbus_access == u"write": + if prop._dbus_access == "write": continue value = prop() - if not hasattr(value, u"variant_level"): + if not hasattr(value, "variant_level"): all[name] = value continue all[name] = type(value)(value, variant_level= value.variant_level+1) - return dbus.Dictionary(all, signature=u"sv") + return dbus.Dictionary(all, signature="sv") @dbus.service.method(dbus.INTROSPECTABLE_IFACE, - out_signature=u"s", + out_signature="s", path_keyword='object_path', connection_keyword='connection') def Introspect(self, object_path, connection): @@ -673,38 +674,38 @@ try: document = xml.dom.minidom.parseString(xmlstring) def make_tag(document, name, prop): - e = document.createElement(u"property") - e.setAttribute(u"name", name) - e.setAttribute(u"type", prop._dbus_signature) - e.setAttribute(u"access", prop._dbus_access) + e = document.createElement("property") + e.setAttribute("name", name) + e.setAttribute("type", prop._dbus_signature) + e.setAttribute("access", prop._dbus_access) return e - for if_tag in document.getElementsByTagName(u"interface"): + for if_tag in document.getElementsByTagName("interface"): for tag in (make_tag(document, name, prop) for name, prop in self._get_all_dbus_properties() if prop._dbus_interface - == if_tag.getAttribute(u"name")): + == if_tag.getAttribute("name")): if_tag.appendChild(tag) # Add the names to the return values for the # "org.freedesktop.DBus.Properties" methods - if (if_tag.getAttribute(u"name") - == u"org.freedesktop.DBus.Properties"): - for cn in if_tag.getElementsByTagName(u"method"): - if cn.getAttribute(u"name") == u"Get": - for arg in cn.getElementsByTagName(u"arg"): - if (arg.getAttribute(u"direction") - == u"out"): - arg.setAttribute(u"name", u"value") - elif cn.getAttribute(u"name") == u"GetAll": - for arg in cn.getElementsByTagName(u"arg"): - if (arg.getAttribute(u"direction") - == u"out"): - arg.setAttribute(u"name", u"props") - xmlstring = document.toxml(u"utf-8") + if (if_tag.getAttribute("name") + == "org.freedesktop.DBus.Properties"): + for cn in if_tag.getElementsByTagName("method"): + if cn.getAttribute("name") == "Get": + for arg in cn.getElementsByTagName("arg"): + if (arg.getAttribute("direction") + == "out"): + arg.setAttribute("name", "value") + elif cn.getAttribute("name") == "GetAll": + for arg in cn.getElementsByTagName("arg"): + if (arg.getAttribute("direction") + == "out"): + arg.setAttribute("name", "props") + xmlstring = document.toxml("utf-8") document.unlink() except (AttributeError, xml.dom.DOMException, xml.parsers.expat.ExpatError), error: - logger.error(u"Failed to override Introspection method", + logger.error("Failed to override Introspection method", error) return xmlstring @@ -718,7 +719,7 @@ """ runtime_expansions = (Client.runtime_expansions - + (u"dbus_object_path",)) + + ("dbus_object_path",)) # dbus.service.Object doesn't use super(), so we can't either. @@ -729,10 +730,10 @@ # Only now, when this client is initialized, can it show up on # the D-Bus client_object_name = unicode(self.name).translate( - {ord(u"."): ord(u"_"), - ord(u"-"): ord(u"_")}) + {ord("."): ord("_"), + ord("-"): ord("_")}) self.dbus_object_path = (dbus.ObjectPath - (u"/clients/" + client_object_name)) + ("/clients/" + client_object_name)) DBusObjectWithProperties.__init__(self, self.bus, self.dbus_object_path) @@ -745,7 +746,7 @@ if (hasattr(self, "dbus_object_path") and bval is not bool(old_value)): dbus_bool = dbus.Boolean(bval, variant_level=1) - self.PropertyChanged(dbus.String(u"ApprovalPending"), + self.PropertyChanged(dbus.String("ApprovalPending"), dbus_bool) approvals_pending = property(_get_approvals_pending, @@ -759,24 +760,24 @@ variant_level=variant_level) def enable(self): - oldstate = getattr(self, u"enabled", False) + oldstate = getattr(self, "enabled", False) r = Client.enable(self) if oldstate != self.enabled: # Emit D-Bus signals - self.PropertyChanged(dbus.String(u"Enabled"), + self.PropertyChanged(dbus.String("Enabled"), dbus.Boolean(True, variant_level=1)) self.PropertyChanged( - dbus.String(u"LastEnabled"), + dbus.String("LastEnabled"), self._datetime_to_dbus(self.last_enabled, variant_level=1)) return r def disable(self, quiet = False): - oldstate = getattr(self, u"enabled", False) + oldstate = getattr(self, "enabled", False) r = Client.disable(self, quiet=quiet) if not quiet and oldstate != self.enabled: # Emit D-Bus signal - self.PropertyChanged(dbus.String(u"Enabled"), + self.PropertyChanged(dbus.String("Enabled"), dbus.Boolean(False, variant_level=1)) return r @@ -785,7 +786,7 @@ self.remove_from_connection() except LookupError: pass - if hasattr(DBusObjectWithProperties, u"__del__"): + if hasattr(DBusObjectWithProperties, "__del__"): DBusObjectWithProperties.__del__(self, *args, **kwargs) Client.__del__(self, *args, **kwargs) @@ -794,7 +795,7 @@ self.checker_callback_tag = None self.checker = None # Emit D-Bus signal - self.PropertyChanged(dbus.String(u"CheckerRunning"), + self.PropertyChanged(dbus.String("CheckerRunning"), dbus.Boolean(False, variant_level=1)) if os.WIFEXITED(condition): exitstatus = os.WEXITSTATUS(condition) @@ -815,7 +816,7 @@ r = Client.checked_ok(self, *args, **kwargs) # Emit D-Bus signal self.PropertyChanged( - dbus.String(u"LastCheckedOK"), + dbus.String("LastCheckedOK"), (self._datetime_to_dbus(self.last_checked_ok, variant_level=1))) return r @@ -824,7 +825,7 @@ r = Client.need_approval(self, *args, **kwargs) # Emit D-Bus signal self.PropertyChanged( - dbus.String(u"LastApprovalRequest"), + dbus.String("LastApprovalRequest"), (self._datetime_to_dbus(self.last_approval_request, variant_level=1))) return r @@ -842,16 +843,16 @@ # Emit D-Bus signal self.CheckerStarted(self.current_checker_command) self.PropertyChanged( - dbus.String(u"CheckerRunning"), + dbus.String("CheckerRunning"), dbus.Boolean(True, variant_level=1)) return r def stop_checker(self, *args, **kwargs): - old_checker = getattr(self, u"checker", None) + old_checker = getattr(self, "checker", None) r = Client.stop_checker(self, *args, **kwargs) if (old_checker is not None - and getattr(self, u"checker", None) is None): - self.PropertyChanged(dbus.String(u"CheckerRunning"), + and getattr(self, "checker", None) is None): + self.PropertyChanged(dbus.String("CheckerRunning"), dbus.Boolean(False, variant_level=1)) return r @@ -868,24 +869,24 @@ ## D-Bus methods, signals & properties - _interface = u"se.bsnet.fukt.Mandos.Client" + _interface = "se.bsnet.fukt.Mandos.Client" ## Signals # CheckerCompleted - signal - @dbus.service.signal(_interface, signature=u"nxs") + @dbus.service.signal(_interface, signature="nxs") def CheckerCompleted(self, exitcode, waitstatus, command): "D-Bus signal" pass # CheckerStarted - signal - @dbus.service.signal(_interface, signature=u"s") + @dbus.service.signal(_interface, signature="s") def CheckerStarted(self, command): "D-Bus signal" pass # PropertyChanged - signal - @dbus.service.signal(_interface, signature=u"sv") + @dbus.service.signal(_interface, signature="sv") def PropertyChanged(self, property, value): "D-Bus signal" pass @@ -900,13 +901,13 @@ pass # Rejected - signal - @dbus.service.signal(_interface, signature=u"s") + @dbus.service.signal(_interface, signature="s") def Rejected(self, reason): "D-Bus signal" pass # NeedApproval - signal - @dbus.service.signal(_interface, signature=u"tb") + @dbus.service.signal(_interface, signature="tb") def NeedApproval(self, timeout, default): "D-Bus signal" return self.need_approval() @@ -914,7 +915,7 @@ ## Methods # Approve - method - @dbus.service.method(_interface, in_signature=u"b") + @dbus.service.method(_interface, in_signature="b") def Approve(self, value): self.approve(value) @@ -949,80 +950,80 @@ ## Properties # ApprovalPending - property - @dbus_service_property(_interface, signature=u"b", access=u"read") + @dbus_service_property(_interface, signature="b", access="read") def ApprovalPending_dbus_property(self): return dbus.Boolean(bool(self.approvals_pending)) # ApprovedByDefault - property - @dbus_service_property(_interface, signature=u"b", - access=u"readwrite") + @dbus_service_property(_interface, signature="b", + access="readwrite") def ApprovedByDefault_dbus_property(self, value=None): if value is None: # get return dbus.Boolean(self.approved_by_default) self.approved_by_default = bool(value) # Emit D-Bus signal - self.PropertyChanged(dbus.String(u"ApprovedByDefault"), + self.PropertyChanged(dbus.String("ApprovedByDefault"), dbus.Boolean(value, variant_level=1)) # ApprovalDelay - property - @dbus_service_property(_interface, signature=u"t", - access=u"readwrite") + @dbus_service_property(_interface, signature="t", + access="readwrite") def ApprovalDelay_dbus_property(self, value=None): if value is None: # get return dbus.UInt64(self.approval_delay_milliseconds()) self.approval_delay = datetime.timedelta(0, 0, 0, value) # Emit D-Bus signal - self.PropertyChanged(dbus.String(u"ApprovalDelay"), + self.PropertyChanged(dbus.String("ApprovalDelay"), dbus.UInt64(value, variant_level=1)) # ApprovalDuration - property - @dbus_service_property(_interface, signature=u"t", - access=u"readwrite") + @dbus_service_property(_interface, signature="t", + access="readwrite") def ApprovalDuration_dbus_property(self, value=None): if value is None: # get return dbus.UInt64(self._timedelta_to_milliseconds( self.approval_duration)) self.approval_duration = datetime.timedelta(0, 0, 0, value) # Emit D-Bus signal - self.PropertyChanged(dbus.String(u"ApprovalDuration"), + self.PropertyChanged(dbus.String("ApprovalDuration"), dbus.UInt64(value, variant_level=1)) # Name - property - @dbus_service_property(_interface, signature=u"s", access=u"read") + @dbus_service_property(_interface, signature="s", access="read") def Name_dbus_property(self): return dbus.String(self.name) # Fingerprint - property - @dbus_service_property(_interface, signature=u"s", access=u"read") + @dbus_service_property(_interface, signature="s", access="read") def Fingerprint_dbus_property(self): return dbus.String(self.fingerprint) # Host - property - @dbus_service_property(_interface, signature=u"s", - access=u"readwrite") + @dbus_service_property(_interface, signature="s", + access="readwrite") def Host_dbus_property(self, value=None): if value is None: # get return dbus.String(self.host) self.host = value # Emit D-Bus signal - self.PropertyChanged(dbus.String(u"Host"), + self.PropertyChanged(dbus.String("Host"), dbus.String(value, variant_level=1)) # Created - property - @dbus_service_property(_interface, signature=u"s", access=u"read") + @dbus_service_property(_interface, signature="s", access="read") def Created_dbus_property(self): return dbus.String(self._datetime_to_dbus(self.created)) # LastEnabled - property - @dbus_service_property(_interface, signature=u"s", access=u"read") + @dbus_service_property(_interface, signature="s", access="read") def LastEnabled_dbus_property(self): if self.last_enabled is None: - return dbus.String(u"") + return dbus.String("") return dbus.String(self._datetime_to_dbus(self.last_enabled)) # Enabled - property - @dbus_service_property(_interface, signature=u"b", - access=u"readwrite") + @dbus_service_property(_interface, signature="b", + access="readwrite") def Enabled_dbus_property(self, value=None): if value is None: # get return dbus.Boolean(self.enabled) @@ -1032,37 +1033,37 @@ self.disable() # LastCheckedOK - property - @dbus_service_property(_interface, signature=u"s", - access=u"readwrite") + @dbus_service_property(_interface, signature="s", + access="readwrite") def LastCheckedOK_dbus_property(self, value=None): if value is not None: self.checked_ok() return if self.last_checked_ok is None: - return dbus.String(u"") + return dbus.String("") return dbus.String(self._datetime_to_dbus(self .last_checked_ok)) # LastApprovalRequest - property - @dbus_service_property(_interface, signature=u"s", access=u"read") + @dbus_service_property(_interface, signature="s", access="read") def LastApprovalRequest_dbus_property(self): if self.last_approval_request is None: - return dbus.String(u"") + return dbus.String("") return dbus.String(self. _datetime_to_dbus(self .last_approval_request)) # Timeout - property - @dbus_service_property(_interface, signature=u"t", - access=u"readwrite") + @dbus_service_property(_interface, signature="t", + access="readwrite") def Timeout_dbus_property(self, value=None): if value is None: # get return dbus.UInt64(self.timeout_milliseconds()) self.timeout = datetime.timedelta(0, 0, 0, value) # Emit D-Bus signal - self.PropertyChanged(dbus.String(u"Timeout"), + self.PropertyChanged(dbus.String("Timeout"), dbus.UInt64(value, variant_level=1)) - if getattr(self, u"disable_initiator_tag", None) is None: + if getattr(self, "disable_initiator_tag", None) is None: return # Reschedule timeout gobject.source_remove(self.disable_initiator_tag) @@ -1081,16 +1082,16 @@ (time_to_die, self.disable)) # Interval - property - @dbus_service_property(_interface, signature=u"t", - access=u"readwrite") + @dbus_service_property(_interface, signature="t", + access="readwrite") def Interval_dbus_property(self, value=None): if value is None: # get return dbus.UInt64(self.interval_milliseconds()) self.interval = datetime.timedelta(0, 0, 0, value) # Emit D-Bus signal - self.PropertyChanged(dbus.String(u"Interval"), + self.PropertyChanged(dbus.String("Interval"), dbus.UInt64(value, variant_level=1)) - if getattr(self, u"checker_initiator_tag", None) is None: + if getattr(self, "checker_initiator_tag", None) is None: return # Reschedule checker run gobject.source_remove(self.checker_initiator_tag) @@ -1099,20 +1100,20 @@ self.start_checker() # Start one now, too # Checker - property - @dbus_service_property(_interface, signature=u"s", - access=u"readwrite") + @dbus_service_property(_interface, signature="s", + access="readwrite") def Checker_dbus_property(self, value=None): if value is None: # get return dbus.String(self.checker_command) self.checker_command = value # Emit D-Bus signal - self.PropertyChanged(dbus.String(u"Checker"), + self.PropertyChanged(dbus.String("Checker"), dbus.String(self.checker_command, variant_level=1)) # CheckerRunning - property - @dbus_service_property(_interface, signature=u"b", - access=u"readwrite") + @dbus_service_property(_interface, signature="b", + access="readwrite") def CheckerRunning_dbus_property(self, value=None): if value is None: # get return dbus.Boolean(self.checker is not None) @@ -1122,13 +1123,13 @@ self.stop_checker() # ObjectPath - property - @dbus_service_property(_interface, signature=u"o", access=u"read") + @dbus_service_property(_interface, signature="o", access="read") def ObjectPath_dbus_property(self): return self.dbus_object_path # is already a dbus.ObjectPath # Secret = property - @dbus_service_property(_interface, signature=u"ay", - access=u"write", byte_arrays=True) + @dbus_service_property(_interface, signature="ay", + access="write", byte_arrays=True) def Secret_dbus_property(self, value): self.secret = str(value) @@ -1169,9 +1170,9 @@ def handle(self): with contextlib.closing(self.server.child_pipe) as child_pipe: - logger.info(u"TCP connection from: %s", + logger.info("TCP connection from: %s", unicode(self.client_address)) - logger.debug(u"Pipe FD: %d", + logger.debug("Pipe FD: %d", self.server.child_pipe.fileno()) session = (gnutls.connection @@ -1184,14 +1185,14 @@ # no X.509 keys are added to it. Therefore, we can use it # here despite using OpenPGP certificates. - #priority = u':'.join((u"NONE", u"+VERS-TLS1.1", - # u"+AES-256-CBC", u"+SHA1", - # u"+COMP-NULL", u"+CTYPE-OPENPGP", - # u"+DHE-DSS")) + #priority = ':'.join(("NONE", "+VERS-TLS1.1", + # "+AES-256-CBC", "+SHA1", + # "+COMP-NULL", "+CTYPE-OPENPGP", + # "+DHE-DSS")) # Use a fallback default, since this MUST be set. priority = self.server.gnutls_priority if priority is None: - priority = u"NORMAL" + priority = "NORMAL" (gnutls.library.functions .gnutls_priority_set_direct(session._c_object, priority, None)) @@ -1199,23 +1200,23 @@ # Start communication using the Mandos protocol # Get protocol number line = self.request.makefile().readline() - logger.debug(u"Protocol version: %r", line) + logger.debug("Protocol version: %r", line) try: if int(line.strip().split()[0]) > 1: raise RuntimeError except (ValueError, IndexError, RuntimeError), error: - logger.error(u"Unknown protocol version: %s", error) + logger.error("Unknown protocol version: %s", error) return # Start GnuTLS connection try: session.handshake() except gnutls.errors.GNUTLSError, error: - logger.warning(u"Handshake failed: %s", error) + logger.warning("Handshake failed: %s", error) # Do not run session.bye() here: the session is not # established. Just abandon the request. return - logger.debug(u"Handshake succeeded") + logger.debug("Handshake succeeded") approval_required = False try: @@ -1223,9 +1224,9 @@ fpr = self.fingerprint(self.peer_certificate (session)) except (TypeError, gnutls.errors.GNUTLSError), error: - logger.warning(u"Bad certificate: %s", error) + logger.warning("Bad certificate: %s", error) return - logger.debug(u"Fingerprint: %s", fpr) + logger.debug("Fingerprint: %s", fpr) try: client = ProxyClient(child_pipe, fpr, @@ -1240,7 +1241,7 @@ while True: if not client.enabled: - logger.warning(u"Client %s is disabled", + logger.warning("Client %s is disabled", client.name) if self.server.use_dbus: # Emit D-Bus signal @@ -1251,7 +1252,7 @@ #We are approved or approval is disabled break elif client._approved is None: - logger.info(u"Client %s needs approval", + logger.info("Client %s needs approval", client.name) if self.server.use_dbus: # Emit D-Bus signal @@ -1259,7 +1260,7 @@ client.approval_delay_milliseconds(), client.approved_by_default) else: - logger.warning(u"Client %s was not approved", + logger.warning("Client %s was not approved", client.name) if self.server.use_dbus: # Emit D-Bus signal @@ -1294,12 +1295,12 @@ except (gnutls.errors.GNUTLSError), error: logger.warning("gnutls send failed") return - logger.debug(u"Sent: %d, remaining: %d", + logger.debug("Sent: %d, remaining: %d", sent, len(client.secret) - (sent_size + sent)) sent_size += sent - logger.info(u"Sending secret to %s", client.name) + logger.info("Sending secret to %s", client.name) # bump the timeout as if seen client.checked_ok() if self.server.use_dbus: @@ -1328,8 +1329,8 @@ .gnutls_certificate_get_peers (session._c_object, ctypes.byref(list_size))) if not bool(cert_list) and list_size.value != 0: - raise gnutls.errors.GNUTLSError(u"error getting peer" - u" certificate") + raise gnutls.errors.GNUTLSError("error getting peer" + " certificate") if list_size.value == 0: return None cert = cert_list[0] @@ -1361,7 +1362,7 @@ if crtverify.value != 0: gnutls.library.functions.gnutls_openpgp_crt_deinit(crt) raise (gnutls.errors.CertificateSecurityError - (u"Verify failed")) + ("Verify failed")) # New buffer for the fingerprint buf = ctypes.create_string_buffer(20) buf_len = ctypes.c_size_t() @@ -1374,7 +1375,7 @@ # Convert the buffer to a Python bytestring fpr = ctypes.string_at(buf, buf_len.value) # Convert the bytestring to hexadecimal notation - hex_fpr = u''.join(u"%02X" % ord(char) for char in fpr) + hex_fpr = ''.join("%02X" % ord(char) for char in fpr) return hex_fpr @@ -1408,7 +1409,7 @@ def add_pipe(self, parent_pipe): """Dummy function; override as necessary""" - pass + raise NotImplementedError class IPv6_TCPServer(MultiprocessingMixInWithPipe, socketserver.TCPServer, object): @@ -1432,23 +1433,23 @@ bind to an address or port if they were not specified.""" if self.interface is not None: if SO_BINDTODEVICE is None: - logger.error(u"SO_BINDTODEVICE does not exist;" - u" cannot bind to interface %s", + logger.error("SO_BINDTODEVICE does not exist;" + " cannot bind to interface %s", self.interface) else: try: self.socket.setsockopt(socket.SOL_SOCKET, SO_BINDTODEVICE, str(self.interface - + u'\0')) + + '\0')) except socket.error, error: if error[0] == errno.EPERM: - logger.error(u"No permission to" - u" bind to interface %s", + logger.error("No permission to" + " bind to interface %s", self.interface) elif error[0] == errno.ENOPROTOOPT: - logger.error(u"SO_BINDTODEVICE not available;" - u" cannot bind to interface %s", + logger.error("SO_BINDTODEVICE not available;" + " cannot bind to interface %s", self.interface) else: raise @@ -1456,7 +1457,7 @@ if self.server_address[0] or self.server_address[1]: if not self.server_address[0]: if self.address_family == socket.AF_INET6: - any_address = u"::" # in6addr_any + any_address = "::" # in6addr_any else: any_address = socket.INADDR_ANY self.server_address = (any_address, @@ -1511,12 +1512,12 @@ def handle_ipc(self, source, condition, parent_pipe=None, client_object=None): condition_names = { - gobject.IO_IN: u"IN", # There is data to read. - gobject.IO_OUT: u"OUT", # Data can be written (without + gobject.IO_IN: "IN", # There is data to read. + gobject.IO_OUT: "OUT", # Data can be written (without # blocking). - gobject.IO_PRI: u"PRI", # There is urgent data to read. - gobject.IO_ERR: u"ERR", # Error condition. - gobject.IO_HUP: u"HUP" # Hung up (the connection has been + gobject.IO_PRI: "PRI", # There is urgent data to read. + gobject.IO_ERR: "ERR", # Error condition. + gobject.IO_HUP: "HUP" # Hung up (the connection has been # broken, usually for pipes and # sockets). } @@ -1541,8 +1542,8 @@ client = c break else: - logger.warning(u"Client not found for fingerprint: %s, ad" - u"dress: %s", fpr, address) + logger.warning("Client not found for fingerprint: %s, ad" + "dress: %s", fpr, address) if self.use_dbus: # Emit D-Bus signal mandos_dbus_service.ClientNotFound(fpr, address[0]) @@ -1582,17 +1583,17 @@ def string_to_delta(interval): """Parse a string and return a datetime.timedelta - >>> string_to_delta(u'7d') + >>> string_to_delta('7d') datetime.timedelta(7) - >>> string_to_delta(u'60s') + >>> string_to_delta('60s') datetime.timedelta(0, 60) - >>> string_to_delta(u'60m') + >>> string_to_delta('60m') datetime.timedelta(0, 3600) - >>> string_to_delta(u'24h') + >>> string_to_delta('24h') datetime.timedelta(1) - >>> string_to_delta(u'1w') + >>> string_to_delta('1w') datetime.timedelta(7) - >>> string_to_delta(u'5m 30s') + >>> string_to_delta('5m 30s') datetime.timedelta(0, 330) """ timevalue = datetime.timedelta(0) @@ -1600,20 +1601,20 @@ try: suffix = unicode(s[-1]) value = int(s[:-1]) - if suffix == u"d": + if suffix == "d": delta = datetime.timedelta(value) - elif suffix == u"s": + elif suffix == "s": delta = datetime.timedelta(0, value) - elif suffix == u"m": + elif suffix == "m": delta = datetime.timedelta(0, 0, 0, 0, value) - elif suffix == u"h": + elif suffix == "h": delta = datetime.timedelta(0, 0, 0, 0, 0, value) - elif suffix == u"w": + elif suffix == "w": delta = datetime.timedelta(0, 0, 0, 0, 0, 0, value) else: - raise ValueError(u"Unknown suffix %r" % suffix) + raise ValueError("Unknown suffix %r" % suffix) except (ValueError, IndexError), e: - raise ValueError(e.message) + raise ValueError(*(e.args)) timevalue += delta return timevalue @@ -1625,18 +1626,18 @@ global if_nametoindex try: if_nametoindex = (ctypes.cdll.LoadLibrary - (ctypes.util.find_library(u"c")) + (ctypes.util.find_library("c")) .if_nametoindex) except (OSError, AttributeError): - logger.warning(u"Doing if_nametoindex the hard way") + logger.warning("Doing if_nametoindex the hard way") def if_nametoindex(interface): "Get an interface index the hard way, i.e. using fcntl()" SIOCGIFINDEX = 0x8933 # From /usr/include/linux/sockios.h with contextlib.closing(socket.socket()) as s: ifreq = fcntl.ioctl(s, SIOCGIFINDEX, - struct.pack(str(u"16s16x"), + struct.pack(str("16s16x"), interface)) - interface_index = struct.unpack(str(u"I"), + interface_index = struct.unpack(str("I"), ifreq[16:20])[0] return interface_index return if_nametoindex(interface) @@ -1650,7 +1651,7 @@ sys.exit() os.setsid() if not nochdir: - os.chdir(u"/") + os.chdir("/") if os.fork(): sys.exit() if not noclose: @@ -1658,7 +1659,7 @@ null = os.open(os.path.devnull, os.O_NOCTTY | os.O_RDWR) if not stat.S_ISCHR(os.fstat(null).st_mode): raise OSError(errno.ENODEV, - u"%s not a character device" + "%s not a character device" % os.path.devnull) os.dup2(null, sys.stdin.fileno()) os.dup2(null, sys.stdout.fileno()) @@ -1673,32 +1674,32 @@ # Parsing of options, both command line and config file parser = optparse.OptionParser(version = "%%prog %s" % version) - parser.add_option("-i", u"--interface", type=u"string", - metavar="IF", help=u"Bind to interface IF") - parser.add_option("-a", u"--address", type=u"string", - help=u"Address to listen for requests on") - parser.add_option("-p", u"--port", type=u"int", - help=u"Port number to receive requests on") - parser.add_option("--check", action=u"store_true", - help=u"Run self-test") - parser.add_option("--debug", action=u"store_true", - help=u"Debug mode; run in foreground and log to" - u" terminal") - parser.add_option("--debuglevel", type=u"string", metavar="LEVEL", - help=u"Debug level for stdout output") - parser.add_option("--priority", type=u"string", help=u"GnuTLS" - u" priority string (see GnuTLS documentation)") - parser.add_option("--servicename", type=u"string", - metavar=u"NAME", help=u"Zeroconf service name") - parser.add_option("--configdir", type=u"string", - default=u"/etc/mandos", metavar=u"DIR", - help=u"Directory to search for configuration" - u" files") - parser.add_option("--no-dbus", action=u"store_false", - dest=u"use_dbus", help=u"Do not provide D-Bus" - u" system bus interface") - parser.add_option("--no-ipv6", action=u"store_false", - dest=u"use_ipv6", help=u"Do not use IPv6") + parser.add_option("-i", "--interface", type="string", + metavar="IF", help="Bind to interface IF") + parser.add_option("-a", "--address", type="string", + help="Address to listen for requests on") + parser.add_option("-p", "--port", type="int", + help="Port number to receive requests on") + parser.add_option("--check", action="store_true", + help="Run self-test") + parser.add_option("--debug", action="store_true", + help="Debug mode; run in foreground and log to" + " terminal") + parser.add_option("--debuglevel", type="string", metavar="LEVEL", + help="Debug level for stdout output") + parser.add_option("--priority", type="string", help="GnuTLS" + " priority string (see GnuTLS documentation)") + parser.add_option("--servicename", type="string", + metavar="NAME", help="Zeroconf service name") + parser.add_option("--configdir", type="string", + default="/etc/mandos", metavar="DIR", + help="Directory to search for configuration" + " files") + parser.add_option("--no-dbus", action="store_false", + dest="use_dbus", help="Do not provide D-Bus" + " system bus interface") + parser.add_option("--no-ipv6", action="store_false", + dest="use_ipv6", help="Do not use IPv6") options = parser.parse_args()[0] if options.check: @@ -1707,39 +1708,39 @@ sys.exit() # Default values for config file for server-global settings - server_defaults = { u"interface": u"", - u"address": u"", - u"port": u"", - u"debug": u"False", - u"priority": - u"SECURE256:!CTYPE-X.509:+CTYPE-OPENPGP", - u"servicename": u"Mandos", - u"use_dbus": u"True", - u"use_ipv6": u"True", - u"debuglevel": u"", + server_defaults = { "interface": "", + "address": "", + "port": "", + "debug": "False", + "priority": + "SECURE256:!CTYPE-X.509:+CTYPE-OPENPGP", + "servicename": "Mandos", + "use_dbus": "True", + "use_ipv6": "True", + "debuglevel": "", } # Parse config file for server-global settings server_config = configparser.SafeConfigParser(server_defaults) del server_defaults server_config.read(os.path.join(options.configdir, - u"mandos.conf")) + "mandos.conf")) # Convert the SafeConfigParser object to a dict server_settings = server_config.defaults() # Use the appropriate methods on the non-string config options - for option in (u"debug", u"use_dbus", u"use_ipv6"): - server_settings[option] = server_config.getboolean(u"DEFAULT", + for option in ("debug", "use_dbus", "use_ipv6"): + server_settings[option] = server_config.getboolean("DEFAULT", option) if server_settings["port"]: - server_settings["port"] = server_config.getint(u"DEFAULT", - u"port") + server_settings["port"] = server_config.getint("DEFAULT", + "port") del server_config # Override the settings from the config file with command line # options, if set. - for option in (u"interface", u"address", u"port", u"debug", - u"priority", u"servicename", u"configdir", - u"use_dbus", u"use_ipv6", u"debuglevel"): + for option in ("interface", "address", "port", "debug", + "priority", "servicename", "configdir", + "use_dbus", "use_ipv6", "debuglevel"): value = getattr(options, option) if value is not None: server_settings[option] = value @@ -1753,59 +1754,59 @@ ################################################################## # For convenience - debug = server_settings[u"debug"] - debuglevel = server_settings[u"debuglevel"] - use_dbus = server_settings[u"use_dbus"] - use_ipv6 = server_settings[u"use_ipv6"] + debug = server_settings["debug"] + debuglevel = server_settings["debuglevel"] + use_dbus = server_settings["use_dbus"] + use_ipv6 = server_settings["use_ipv6"] - if server_settings[u"servicename"] != u"Mandos": + if server_settings["servicename"] != "Mandos": syslogger.setFormatter(logging.Formatter - (u'Mandos (%s) [%%(process)d]:' - u' %%(levelname)s: %%(message)s' - % server_settings[u"servicename"])) + ('Mandos (%s) [%%(process)d]:' + ' %%(levelname)s: %%(message)s' + % server_settings["servicename"])) # Parse config file with clients - client_defaults = { u"timeout": u"1h", - u"interval": u"5m", - u"checker": u"fping -q -- %%(host)s", - u"host": u"", - u"approval_delay": u"0s", - u"approval_duration": u"1s", + client_defaults = { "timeout": "1h", + "interval": "5m", + "checker": "fping -q -- %%(host)s", + "host": "", + "approval_delay": "0s", + "approval_duration": "1s", } client_config = configparser.SafeConfigParser(client_defaults) - client_config.read(os.path.join(server_settings[u"configdir"], - u"clients.conf")) + client_config.read(os.path.join(server_settings["configdir"], + "clients.conf")) global mandos_dbus_service mandos_dbus_service = None - tcp_server = MandosServer((server_settings[u"address"], - server_settings[u"port"]), + tcp_server = MandosServer((server_settings["address"], + server_settings["port"]), ClientHandler, - interface=(server_settings[u"interface"] + interface=(server_settings["interface"] or None), use_ipv6=use_ipv6, gnutls_priority= - server_settings[u"priority"], + server_settings["priority"], use_dbus=use_dbus) if not debug: - pidfilename = u"/var/run/mandos.pid" + pidfilename = "/var/run/mandos.pid" try: - pidfile = open(pidfilename, u"w") + pidfile = open(pidfilename, "w") except IOError: - logger.error(u"Could not open file %r", pidfilename) + logger.error("Could not open file %r", pidfilename) try: - uid = pwd.getpwnam(u"_mandos").pw_uid - gid = pwd.getpwnam(u"_mandos").pw_gid + uid = pwd.getpwnam("_mandos").pw_uid + gid = pwd.getpwnam("_mandos").pw_gid except KeyError: try: - uid = pwd.getpwnam(u"mandos").pw_uid - gid = pwd.getpwnam(u"mandos").pw_gid + uid = pwd.getpwnam("mandos").pw_uid + gid = pwd.getpwnam("mandos").pw_gid except KeyError: try: - uid = pwd.getpwnam(u"nobody").pw_uid - gid = pwd.getpwnam(u"nobody").pw_gid + uid = pwd.getpwnam("nobody").pw_uid + gid = pwd.getpwnam("nobody").pw_gid except KeyError: uid = 65534 gid = 65534 @@ -1833,7 +1834,7 @@ @gnutls.library.types.gnutls_log_func def debug_gnutls(level, string): - logger.debug(u"GnuTLS: %s", string[:-1]) + logger.debug("GnuTLS: %s", string[:-1]) (gnutls.library.functions .gnutls_global_set_log_function(debug_gnutls)) @@ -1860,20 +1861,20 @@ # End of Avahi example code if use_dbus: try: - bus_name = dbus.service.BusName(u"se.bsnet.fukt.Mandos", + bus_name = dbus.service.BusName("se.bsnet.fukt.Mandos", bus, do_not_queue=True) except dbus.exceptions.NameExistsException, e: - logger.error(unicode(e) + u", disabling D-Bus") + logger.error(unicode(e) + ", disabling D-Bus") use_dbus = False - server_settings[u"use_dbus"] = False + server_settings["use_dbus"] = False tcp_server.use_dbus = False protocol = avahi.PROTO_INET6 if use_ipv6 else avahi.PROTO_INET - service = AvahiService(name = server_settings[u"servicename"], - servicetype = u"_mandos._tcp", + service = AvahiService(name = server_settings["servicename"], + servicetype = "_mandos._tcp", protocol = protocol, bus = bus) if server_settings["interface"]: service.interface = (if_nametoindex - (str(server_settings[u"interface"]))) + (str(server_settings["interface"]))) global multiprocessing_manager multiprocessing_manager = multiprocessing.Manager() @@ -1899,16 +1900,16 @@ client_config, section))) for section in client_config.sections())) if not tcp_server.clients: - logger.warning(u"No clients defined") + logger.warning("No clients defined") if not debug: try: with pidfile: pid = os.getpid() - pidfile.write(str(pid) + "\n") + pidfile.write(str(pid) + "\n".encode("utf-8")) del pidfile except IOError: - logger.error(u"Could not write to file %r with PID %d", + logger.error("Could not write to file %r with PID %d", pidfilename, pid) except NameError: # "pidfile" was never created @@ -1924,40 +1925,40 @@ class MandosDBusService(dbus.service.Object): """A D-Bus proxy object""" def __init__(self): - dbus.service.Object.__init__(self, bus, u"/") - _interface = u"se.bsnet.fukt.Mandos" + dbus.service.Object.__init__(self, bus, "/") + _interface = "se.bsnet.fukt.Mandos" - @dbus.service.signal(_interface, signature=u"o") + @dbus.service.signal(_interface, signature="o") def ClientAdded(self, objpath): "D-Bus signal" pass - @dbus.service.signal(_interface, signature=u"ss") + @dbus.service.signal(_interface, signature="ss") def ClientNotFound(self, fingerprint, address): "D-Bus signal" pass - @dbus.service.signal(_interface, signature=u"os") + @dbus.service.signal(_interface, signature="os") def ClientRemoved(self, objpath, name): "D-Bus signal" pass - @dbus.service.method(_interface, out_signature=u"ao") + @dbus.service.method(_interface, out_signature="ao") def GetAllClients(self): "D-Bus method" return dbus.Array(c.dbus_object_path for c in tcp_server.clients) @dbus.service.method(_interface, - out_signature=u"a{oa{sv}}") + out_signature="a{oa{sv}}") def GetAllClientsWithProperties(self): "D-Bus method" return dbus.Dictionary( - ((c.dbus_object_path, c.GetAll(u"")) + ((c.dbus_object_path, c.GetAll("")) for c in tcp_server.clients), - signature=u"oa{sv}") + signature="oa{sv}") - @dbus.service.method(_interface, in_signature=u"o") + @dbus.service.method(_interface, in_signature="o") def RemoveClient(self, object_path): "D-Bus method" for c in tcp_server.clients: @@ -2005,11 +2006,11 @@ # Find out what port we got service.port = tcp_server.socket.getsockname()[1] if use_ipv6: - logger.info(u"Now listening on address %r, port %d," + logger.info("Now listening on address %r, port %d," " flowinfo %d, scope_id %d" % tcp_server.socket.getsockname()) else: # IPv4 - logger.info(u"Now listening on address %r, port %d" + logger.info("Now listening on address %r, port %d" % tcp_server.socket.getsockname()) #service.interface = tcp_server.socket.getsockname()[3] @@ -2019,7 +2020,7 @@ try: service.activate() except dbus.exceptions.DBusException, error: - logger.critical(u"DBusException: %s", error) + logger.critical("DBusException: %s", error) cleanup() sys.exit(1) # End of Avahi example code @@ -2029,17 +2030,17 @@ (tcp_server.handle_request (*args[2:], **kwargs) or True)) - logger.debug(u"Starting main loop") + logger.debug("Starting main loop") main_loop.run() except AvahiError, error: - logger.critical(u"AvahiError: %s", error) + logger.critical("AvahiError: %s", error) cleanup() sys.exit(1) except KeyboardInterrupt: if debug: - print >> sys.stderr - logger.debug(u"Server received KeyboardInterrupt") - logger.debug(u"Server exiting") + print("", file=sys.stderr) + logger.debug("Server received KeyboardInterrupt") + logger.debug("Server exiting") # Must run before the D-Bus bus name gets deregistered cleanup() === modified file 'mandos-clients.conf.xml' --- mandos-clients.conf.xml 2010-09-27 18:57:12 +0000 +++ mandos-clients.conf.xml 2011-02-27 17:26:35 +0000 @@ -3,7 +3,7 @@ "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [ /etc/mandos/clients.conf"> - + %common; ]> @@ -35,6 +35,7 @@ 2008 2009 2010 + 2011 Teddy Hogeborn Björn Påhlsson === modified file 'mandos-ctl' --- mandos-ctl 2010-10-11 17:45:21 +0000 +++ mandos-ctl 2011-02-15 19:53:46 +0000 @@ -22,7 +22,9 @@ # Contact the authors at . # -from __future__ import division +from __future__ import (division, absolute_import, print_function, + unicode_literals) + import sys import dbus from optparse import OptionParser @@ -31,43 +33,43 @@ import re import os -locale.setlocale(locale.LC_ALL, u'') +locale.setlocale(locale.LC_ALL, "") tablewords = { - 'Name': u'Name', - 'Enabled': u'Enabled', - 'Timeout': u'Timeout', - 'LastCheckedOK': u'Last Successful Check', - 'LastApprovalRequest': u'Last Approval Request', - 'Created': u'Created', - 'Interval': u'Interval', - 'Host': u'Host', - 'Fingerprint': u'Fingerprint', - 'CheckerRunning': u'Check Is Running', - 'LastEnabled': u'Last Enabled', - 'ApprovalPending': u'Approval Is Pending', - 'ApprovedByDefault': u'Approved By Default', - 'ApprovalDelay': u"Approval Delay", - 'ApprovalDuration': u"Approval Duration", - 'Checker': u'Checker', + "Name": "Name", + "Enabled": "Enabled", + "Timeout": "Timeout", + "LastCheckedOK": "Last Successful Check", + "LastApprovalRequest": "Last Approval Request", + "Created": "Created", + "Interval": "Interval", + "Host": "Host", + "Fingerprint": "Fingerprint", + "CheckerRunning": "Check Is Running", + "LastEnabled": "Last Enabled", + "ApprovalPending": "Approval Is Pending", + "ApprovedByDefault": "Approved By Default", + "ApprovalDelay": "Approval Delay", + "ApprovalDuration": "Approval Duration", + "Checker": "Checker", } -defaultkeywords = ('Name', 'Enabled', 'Timeout', 'LastCheckedOK') -domain = 'se.bsnet.fukt' -busname = domain + '.Mandos' -server_path = '/' -server_interface = domain + '.Mandos' -client_interface = domain + '.Mandos.Client' +defaultkeywords = ("Name", "Enabled", "Timeout", "LastCheckedOK") +domain = "se.bsnet.fukt" +busname = domain + ".Mandos" +server_path = "/" +server_interface = domain + ".Mandos" +client_interface = domain + ".Mandos.Client" version = "1.2.3" def timedelta_to_milliseconds(td): - "Convert a datetime.timedelta object to milliseconds" + """Convert a datetime.timedelta object to milliseconds""" return ((td.days * 24 * 60 * 60 * 1000) + (td.seconds * 1000) + (td.microseconds // 1000)) def milliseconds_to_string(ms): td = datetime.timedelta(0, 0, 0, ms) - return (u"%(days)s%(hours)02d:%(minutes)02d:%(seconds)02d" + return ("%(days)s%(hours)02d:%(minutes)02d:%(seconds)02d" % { "days": "%dT" % td.days if td.days else "", "hours": td.seconds // 3600, "minutes": (td.seconds % 3600) // 60, @@ -78,17 +80,17 @@ def string_to_delta(interval): """Parse a string and return a datetime.timedelta - >>> string_to_delta('7d') + >>> string_to_delta("7d") datetime.timedelta(7) - >>> string_to_delta('60s') + >>> string_to_delta("60s") datetime.timedelta(0, 60) - >>> string_to_delta('60m') + >>> string_to_delta("60m") datetime.timedelta(0, 3600) - >>> string_to_delta('24h') + >>> string_to_delta("24h") datetime.timedelta(1) - >>> string_to_delta(u'1w') + >>> string_to_delta("1w") datetime.timedelta(7) - >>> string_to_delta('5m 30s') + >>> string_to_delta("5m 30s") datetime.timedelta(0, 330) """ timevalue = datetime.timedelta(0) @@ -98,15 +100,15 @@ try: suffix = unicode(s[-1]) value = int(s[:-1]) - if suffix == u"d": + if suffix == "d": delta = datetime.timedelta(value) - elif suffix == u"s": + elif suffix == "s": delta = datetime.timedelta(0, value) - elif suffix == u"m": + elif suffix == "m": delta = datetime.timedelta(0, 0, 0, 0, value) - elif suffix == u"h": + elif suffix == "h": delta = datetime.timedelta(0, 0, 0, 0, 0, value) - elif suffix == u"w": + elif suffix == "w": delta = datetime.timedelta(0, 0, 0, 0, 0, 0, value) else: raise ValueError @@ -118,25 +120,25 @@ def print_clients(clients, keywords): def valuetostring(value, keyword): if type(value) is dbus.Boolean: - return u"Yes" if value else u"No" - if keyword in (u"Timeout", u"Interval", u"ApprovalDelay", - u"ApprovalDuration"): + return "Yes" if value else "No" + if keyword in ("Timeout", "Interval", "ApprovalDelay", + "ApprovalDuration"): return milliseconds_to_string(value) return unicode(value) # Create format string to print table rows - format_string = u' '.join(u'%%-%ds' % - max(len(tablewords[key]), - max(len(valuetostring(client[key], - key)) - for client in - clients)) - for key in keywords) + format_string = " ".join("%%-%ds" % + max(len(tablewords[key]), + max(len(valuetostring(client[key], + key)) + for client in + clients)) + for key in keywords) # Print header line - print format_string % tuple(tablewords[key] for key in keywords) + print(format_string % tuple(tablewords[key] for key in keywords)) for client in clients: - print format_string % tuple(valuetostring(client[key], key) - for key in keywords) + print(format_string % tuple(valuetostring(client[key], key) + for key in keywords)) def has_actions(options): return any((options.enable, @@ -184,10 +186,10 @@ parser.add_option("-i", "--interval", type="string", help="Set checker interval for client") parser.add_option("--approve-by-default", action="store_true", - dest=u"approved_by_default", + dest="approved_by_default", help="Set client to be approved by default") parser.add_option("--deny-by-default", action="store_false", - dest=u"approved_by_default", + dest="approved_by_default", help="Set client to be denied by default") parser.add_option("--approval-delay", type="string", help="Set delay before client approve/deny") @@ -204,18 +206,19 @@ options, client_names = parser.parse_args() if has_actions(options) and not client_names and not options.all: - parser.error('Options require clients names or --all.') + parser.error("Options require clients names or --all.") if options.verbose and has_actions(options): - parser.error('--verbose can only be used alone or with' - ' --all.') + parser.error("--verbose can only be used alone or with" + " --all.") if options.all and not has_actions(options): - parser.error('--all requires an action.') + parser.error("--all requires an action.") try: bus = dbus.SystemBus() mandos_dbus_objc = bus.get_object(busname, server_path) except dbus.exceptions.DBusException: - print >> sys.stderr, "Could not connect to Mandos server" + print("Could not connect to Mandos server", + file=sys.stderr) sys.exit(1) mandos_serv = dbus.Interface(mandos_dbus_objc, @@ -234,7 +237,8 @@ os.dup2(stderrcopy, sys.stderr.fileno()) os.close(stderrcopy) except dbus.exceptions.DBusException, e: - print >> sys.stderr, "Access denied: Accessing mandos server through dbus." + print("Access denied: Accessing mandos server through dbus.", + file=sys.stderr) sys.exit(1) # Compile dict of (clients: properties) to process @@ -247,23 +251,24 @@ else: for name in client_names: for path, client in mandos_clients.iteritems(): - if client['Name'] == name: + if client["Name"] == name: client_objc = bus.get_object(busname, path) clients[client_objc] = client break else: - print >> sys.stderr, "Client not found on server: %r" % name + print("Client not found on server: %r" % name, + file=sys.stderr) sys.exit(1) if not has_actions(options) and clients: if options.verbose: - keywords = ('Name', 'Enabled', 'Timeout', - 'LastCheckedOK', 'Created', 'Interval', - 'Host', 'Fingerprint', 'CheckerRunning', - 'LastEnabled', 'ApprovalPending', - 'ApprovedByDefault', - 'LastApprovalRequest', 'ApprovalDelay', - 'ApprovalDuration', 'Checker') + keywords = ("Name", "Enabled", "Timeout", + "LastCheckedOK", "Created", "Interval", + "Host", "Fingerprint", "CheckerRunning", + "LastEnabled", "ApprovalPending", + "ApprovedByDefault", + "LastApprovalRequest", "ApprovalDelay", + "ApprovalDuration", "Checker") else: keywords = defaultkeywords @@ -285,44 +290,44 @@ client.StopChecker(dbus_interface=client_interface) if options.is_enabled: sys.exit(0 if client.Get(client_interface, - u"Enabled", + "Enabled", dbus_interface=dbus.PROPERTIES_IFACE) else 1) if options.checker: - client.Set(client_interface, u"Checker", options.checker, + client.Set(client_interface, "Checker", options.checker, dbus_interface=dbus.PROPERTIES_IFACE) if options.host: - client.Set(client_interface, u"Host", options.host, + client.Set(client_interface, "Host", options.host, dbus_interface=dbus.PROPERTIES_IFACE) if options.interval: - client.Set(client_interface, u"Interval", + client.Set(client_interface, "Interval", timedelta_to_milliseconds (string_to_delta(options.interval)), dbus_interface=dbus.PROPERTIES_IFACE) if options.approval_delay: - client.Set(client_interface, u"ApprovalDelay", + client.Set(client_interface, "ApprovalDelay", timedelta_to_milliseconds (string_to_delta(options. approval_delay)), dbus_interface=dbus.PROPERTIES_IFACE) if options.approval_duration: - client.Set(client_interface, u"ApprovalDuration", + client.Set(client_interface, "ApprovalDuration", timedelta_to_milliseconds (string_to_delta(options. approval_duration)), dbus_interface=dbus.PROPERTIES_IFACE) if options.timeout: - client.Set(client_interface, u"Timeout", + client.Set(client_interface, "Timeout", timedelta_to_milliseconds (string_to_delta(options.timeout)), dbus_interface=dbus.PROPERTIES_IFACE) if options.secret: - client.Set(client_interface, u"Secret", + client.Set(client_interface, "Secret", dbus.ByteArray(open(options.secret, - u'rb').read()), + "rb").read()), dbus_interface=dbus.PROPERTIES_IFACE) if options.approved_by_default is not None: - client.Set(client_interface, u"ApprovedByDefault", + client.Set(client_interface, "ApprovedByDefault", dbus.Boolean(options .approved_by_default), dbus_interface=dbus.PROPERTIES_IFACE) @@ -333,5 +338,5 @@ client.Approve(dbus.Boolean(False), dbus_interface=client_interface) -if __name__ == '__main__': +if __name__ == "__main__": main() === modified file 'mandos-ctl.xml' --- mandos-ctl.xml 2010-09-25 23:52:17 +0000 +++ mandos-ctl.xml 2011-02-27 17:26:35 +0000 @@ -2,7 +2,7 @@ - + %common; ]> @@ -32,6 +32,7 @@ 2010 + 2011 Teddy Hogeborn Björn Påhlsson === modified file 'mandos-keygen' --- mandos-keygen 2010-10-11 17:45:21 +0000 +++ mandos-keygen 2011-02-27 17:26:35 +0000 @@ -2,8 +2,8 @@ # # Mandos key generator - create a new OpenPGP key for a Mandos client # -# Copyright © 2008-2010 Teddy Hogeborn -# Copyright © 2008-2010 Björn Påhlsson +# Copyright © 2008-2011 Teddy Hogeborn +# Copyright © 2008-2011 Björn Påhlsson # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by === modified file 'mandos-monitor' --- mandos-monitor 2010-10-11 17:45:21 +0000 +++ mandos-monitor 2011-02-27 17:26:35 +0000 @@ -3,8 +3,8 @@ # # Mandos Monitor - Control and monitor the Mandos server # -# Copyright © 2009,2010 Teddy Hogeborn -# Copyright © 2009,2010 Björn Påhlsson +# Copyright © 2009-2011 Teddy Hogeborn +# Copyright © 2009-2011 Björn Påhlsson # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -22,7 +22,7 @@ # Contact the authors at . # -from __future__ import division, absolute_import, with_statement +from __future__ import division, absolute_import, print_function, unicode_literals import sys import os @@ -42,7 +42,7 @@ import locale -locale.setlocale(locale.LC_ALL, u'') +locale.setlocale(locale.LC_ALL, '') import logging logging.getLogger('dbus.proxies').setLevel(logging.CRITICAL) @@ -65,9 +65,9 @@ "Parse an ISO 8601 date string to a datetime.datetime()" if not iso: return None - d, t = iso.split(u"T", 1) - year, month, day = d.split(u"-", 2) - hour, minute, second = t.split(u":", 2) + d, t = iso.split("T", 1) + year, month, day = d.split("-", 2) + hour, minute, second = t.split(":", 2) second, fraction = divmod(float(second), 1) return datetime.datetime(int(year), int(month), @@ -86,7 +86,7 @@ self.proxy = proxy_object # Mandos Client proxy object self.properties = dict() - self.proxy.connect_to_signal(u"PropertyChanged", + self.proxy.connect_to_signal("PropertyChanged", self.property_changed, client_interface, byte_arrays=True) @@ -127,9 +127,9 @@ self.last_checker_failed = False # The widget shown normally - self._text_widget = urwid.Text(u"") + self._text_widget = urwid.Text("") # The widget shown when we have focus - self._focus_text_widget = urwid.Text(u"") + self._focus_text_widget = urwid.Text("") super(MandosClientWidget, self).__init__( update_hook=update_hook, delete_hook=delete_hook, *args, **kwargs) @@ -137,7 +137,7 @@ self.opened = False last_checked_ok = isoformat_to_datetime(self.properties - [u"LastCheckedOK"]) + ["LastCheckedOK"]) if last_checked_ok is None: self.last_checker_failed = True else: @@ -146,7 +146,7 @@ > datetime.timedelta (milliseconds= self.properties - [u"Interval"])) + ["Interval"])) if self.last_checker_failed: self.using_timer(True) @@ -154,23 +154,23 @@ if self.need_approval: self.using_timer(True) - self.proxy.connect_to_signal(u"CheckerCompleted", + self.proxy.connect_to_signal("CheckerCompleted", self.checker_completed, client_interface, byte_arrays=True) - self.proxy.connect_to_signal(u"CheckerStarted", + self.proxy.connect_to_signal("CheckerStarted", self.checker_started, client_interface, byte_arrays=True) - self.proxy.connect_to_signal(u"GotSecret", + self.proxy.connect_to_signal("GotSecret", self.got_secret, client_interface, byte_arrays=True) - self.proxy.connect_to_signal(u"NeedApproval", + self.proxy.connect_to_signal("NeedApproval", self.need_approval, client_interface, byte_arrays=True) - self.proxy.connect_to_signal(u"Rejected", + self.proxy.connect_to_signal("Rejected", self.rejected, client_interface, byte_arrays=True) @@ -178,7 +178,7 @@ def property_changed(self, property=None, value=None): super(self, MandosClientWidget).property_changed(property, value) - if property == u"ApprovalPending": + if property == "ApprovalPending": using_timer(bool(value)) def using_timer(self, flag): @@ -203,9 +203,9 @@ if self.last_checker_failed: self.last_checker_failed = False self.using_timer(False) - #self.logger(u'Checker for client %s (command "%s")' - # u' was successful' - # % (self.properties[u"Name"], command)) + #self.logger('Checker for client %s (command "%s")' + # ' was successful' + # % (self.properties["Name"], command)) self.update() return # Checker failed @@ -213,57 +213,57 @@ self.last_checker_failed = True self.using_timer(True) if os.WIFEXITED(condition): - self.logger(u'Checker for client %s (command "%s")' - u' failed with exit code %s' - % (self.properties[u"Name"], command, + self.logger('Checker for client %s (command "%s")' + ' failed with exit code %s' + % (self.properties["Name"], command, os.WEXITSTATUS(condition))) elif os.WIFSIGNALED(condition): - self.logger(u'Checker for client %s (command "%s")' - u' was killed by signal %s' - % (self.properties[u"Name"], command, + self.logger('Checker for client %s (command "%s")' + ' was killed by signal %s' + % (self.properties["Name"], command, os.WTERMSIG(condition))) elif os.WCOREDUMP(condition): - self.logger(u'Checker for client %s (command "%s")' - u' dumped core' - % (self.properties[u"Name"], command)) + self.logger('Checker for client %s (command "%s")' + ' dumped core' + % (self.properties["Name"], command)) else: - self.logger(u'Checker for client %s completed' - u' mysteriously') + self.logger('Checker for client %s completed' + ' mysteriously') self.update() def checker_started(self, command): - #self.logger(u'Client %s started checker "%s"' - # % (self.properties[u"Name"], unicode(command))) + #self.logger('Client %s started checker "%s"' + # % (self.properties["Name"], unicode(command))) pass def got_secret(self): self.last_checker_failed = False - self.logger(u'Client %s received its secret' - % self.properties[u"Name"]) + self.logger('Client %s received its secret' + % self.properties["Name"]) def need_approval(self, timeout, default): if not default: - message = u'Client %s needs approval within %s seconds' + message = 'Client %s needs approval within %s seconds' else: - message = u'Client %s will get its secret in %s seconds' + message = 'Client %s will get its secret in %s seconds' self.logger(message - % (self.properties[u"Name"], timeout/1000)) + % (self.properties["Name"], timeout/1000)) self.using_timer(True) def rejected(self, reason): - self.logger(u'Client %s was rejected; reason: %s' - % (self.properties[u"Name"], reason)) + self.logger('Client %s was rejected; reason: %s' + % (self.properties["Name"], reason)) def selectable(self): """Make this a "selectable" widget. This overrides the method from urwid.FlowWidget.""" return True - def rows(self, (maxcol,), focus=False): + def rows(self, maxcolrow, focus=False): """How many rows this widget will occupy might depend on whether we have focus or not. This overrides the method from urwid.FlowWidget""" - return self.current_widget(focus).rows((maxcol,), focus=focus) + return self.current_widget(focus).rows(maxcolrow, focus=focus) def current_widget(self, focus=False): if focus or self.opened: @@ -273,56 +273,56 @@ def update(self): "Called when what is visible on the screen should be updated." # How to add standout mode to a style - with_standout = { u"normal": u"standout", - u"bold": u"bold-standout", - u"underline-blink": - u"underline-blink-standout", - u"bold-underline-blink": - u"bold-underline-blink-standout", + with_standout = { "normal": "standout", + "bold": "bold-standout", + "underline-blink": + "underline-blink-standout", + "bold-underline-blink": + "bold-underline-blink-standout", } # Rebuild focus and non-focus widgets using current properties # Base part of a client. Name! - base = (u'%(name)s: ' - % {u"name": self.properties[u"Name"]}) - if not self.properties[u"Enabled"]: - message = u"DISABLED" - elif self.properties[u"ApprovalPending"]: + base = ('%(name)s: ' + % {"name": self.properties["Name"]}) + if not self.properties["Enabled"]: + message = "DISABLED" + elif self.properties["ApprovalPending"]: timeout = datetime.timedelta(milliseconds = self.properties - [u"ApprovalDelay"]) + ["ApprovalDelay"]) last_approval_request = isoformat_to_datetime( - self.properties[u"LastApprovalRequest"]) + self.properties["LastApprovalRequest"]) if last_approval_request is not None: timer = timeout - (datetime.datetime.utcnow() - last_approval_request) else: timer = datetime.timedelta() - if self.properties[u"ApprovedByDefault"]: - message = u"Approval in %s. (d)eny?" + if self.properties["ApprovedByDefault"]: + message = "Approval in %s. (d)eny?" else: - message = u"Denial in %s. (a)pprove?" + message = "Denial in %s. (a)pprove?" message = message % unicode(timer).rsplit(".", 1)[0] elif self.last_checker_failed: timeout = datetime.timedelta(milliseconds = self.properties - [u"Timeout"]) + ["Timeout"]) last_ok = isoformat_to_datetime( - max((self.properties[u"LastCheckedOK"] - or self.properties[u"Created"]), - self.properties[u"LastEnabled"])) + max((self.properties["LastCheckedOK"] + or self.properties["Created"]), + self.properties["LastEnabled"])) timer = timeout - (datetime.datetime.utcnow() - last_ok) - message = (u'A checker has failed! Time until client' - u' gets disabled: %s' + message = ('A checker has failed! Time until client' + ' gets disabled: %s' % unicode(timer).rsplit(".", 1)[0]) else: - message = u"enabled" + message = "enabled" self._text = "%s%s" % (base, message) if not urwid.supports_unicode(): self._text = self._text.encode("ascii", "replace") - textlist = [(u"normal", self._text)] + textlist = [("normal", self._text)] self._text_widget.set_text(textlist) self._focus_text_widget.set_text([(with_standout[text[0]], text[1]) @@ -348,40 +348,40 @@ if self.delete_hook is not None: self.delete_hook(self) - def render(self, (maxcol,), focus=False): + def render(self, maxcolrow, focus=False): """Render differently if we have focus. This overrides the method from urwid.FlowWidget""" - return self.current_widget(focus).render((maxcol,), + return self.current_widget(focus).render(maxcolrow, focus=focus) - def keypress(self, (maxcol,), key): + def keypress(self, maxcolrow, key): """Handle keys. This overrides the method from urwid.FlowWidget""" - if key == u"+": + if key == "+": self.proxy.Enable(dbus_interface = client_interface) - elif key == u"-": + elif key == "-": self.proxy.Disable(dbus_interface = client_interface) - elif key == u"a": + elif key == "a": self.proxy.Approve(dbus.Boolean(True, variant_level=1), dbus_interface = client_interface) - elif key == u"d": + elif key == "d": self.proxy.Approve(dbus.Boolean(False, variant_level=1), dbus_interface = client_interface) - elif key == u"R" or key == u"_" or key == u"ctrl k": + elif key == "R" or key == "_" or key == "ctrl k": self.server_proxy_object.RemoveClient(self.proxy .object_path) - elif key == u"s": + elif key == "s": self.proxy.StartChecker(dbus_interface = client_interface) - elif key == u"S": + elif key == "S": self.proxy.StopChecker(dbus_interface = client_interface) - elif key == u"C": + elif key == "C": self.proxy.CheckedOK(dbus_interface = client_interface) # xxx -# elif key == u"p" or key == "=": +# elif key == "p" or key == "=": # self.proxy.pause() -# elif key == u"u" or key == ":": +# elif key == "u" or key == ":": # self.proxy.unpause() -# elif key == u"RET": +# elif key == "RET": # self.open() else: return key @@ -403,10 +403,9 @@ "down" key presses, thus not allowing any containing widgets to use them as an excuse to shift focus away from this widget. """ - def keypress(self, (maxcol, maxrow), key): - ret = super(ConstrainedListBox, self).keypress((maxcol, - maxrow), key) - if ret in (u"up", u"down"): + def keypress(self, maxcolrow, key): + ret = super(ConstrainedListBox, self).keypress(maxcolrow, key) + if ret in ("up", "down"): return return ret @@ -421,31 +420,31 @@ self.screen = urwid.curses_display.Screen() self.screen.register_palette(( - (u"normal", - u"default", u"default", None), - (u"bold", - u"default", u"default", u"bold"), - (u"underline-blink", - u"default", u"default", u"underline"), - (u"standout", - u"default", u"default", u"standout"), - (u"bold-underline-blink", - u"default", u"default", (u"bold", u"underline")), - (u"bold-standout", - u"default", u"default", (u"bold", u"standout")), - (u"underline-blink-standout", - u"default", u"default", (u"underline", u"standout")), - (u"bold-underline-blink-standout", - u"default", u"default", (u"bold", u"underline", - u"standout")), + ("normal", + "default", "default", None), + ("bold", + "default", "default", "bold"), + ("underline-blink", + "default", "default", "underline"), + ("standout", + "default", "default", "standout"), + ("bold-underline-blink", + "default", "default", ("bold", "underline")), + ("bold-standout", + "default", "default", ("bold", "standout")), + ("underline-blink-standout", + "default", "default", ("underline", "standout")), + ("bold-underline-blink-standout", + "default", "default", ("bold", "underline", + "standout")), )) if urwid.supports_unicode(): - self.divider = u"─" # \u2500 - #self.divider = u"━" # \u2501 + self.divider = "─" # \u2500 + #self.divider = "━" # \u2501 else: - #self.divider = u"-" # \u002d - self.divider = u"_" # \u005f + #self.divider = "-" # \u002d + self.divider = "_" # \u005f self.screen.start() @@ -465,19 +464,19 @@ # This keeps track of whether self.uilist currently has # self.logbox in it or not self.log_visible = True - self.log_wrap = u"any" + self.log_wrap = "any" self.rebuild() - self.log_message_raw((u"bold", - u"Mandos Monitor version " + version)) - self.log_message_raw((u"bold", - u"q: Quit ?: Help")) + self.log_message_raw(("bold", + "Mandos Monitor version " + version)) + self.log_message_raw(("bold", + "q: Quit ?: Help")) self.busname = domain + '.Mandos' self.main_loop = gobject.MainLoop() self.bus = dbus.SystemBus() mandos_dbus_objc = self.bus.get_object( - self.busname, u"/", follow_name_owner_changes=True) + self.busname, "/", follow_name_owner_changes=True) self.mandos_serv = dbus.Interface(mandos_dbus_objc, dbus_interface = server_interface) @@ -488,17 +487,17 @@ mandos_clients = dbus.Dictionary() (self.mandos_serv - .connect_to_signal(u"ClientRemoved", + .connect_to_signal("ClientRemoved", self.find_and_remove_client, dbus_interface=server_interface, byte_arrays=True)) (self.mandos_serv - .connect_to_signal(u"ClientAdded", + .connect_to_signal("ClientAdded", self.add_new_client, dbus_interface=server_interface, byte_arrays=True)) (self.mandos_serv - .connect_to_signal(u"ClientNotFound", + .connect_to_signal("ClientNotFound", self.client_not_found, dbus_interface=server_interface, byte_arrays=True)) @@ -519,8 +518,8 @@ path=path) def client_not_found(self, fingerprint, address): - self.log_message((u"Client with address %s and fingerprint %s" - u" could not be found" % (address, + self.log_message(("Client with address %s and fingerprint %s" + " could not be found" % (address, fingerprint))) def rebuild(self): @@ -542,7 +541,7 @@ def log_message(self, message): timestamp = datetime.datetime.now().isoformat() - self.log_message_raw(timestamp + u": " + message) + self.log_message_raw(timestamp + ": " + message) def log_message_raw(self, markup): """Add a log message to the log buffer.""" @@ -551,26 +550,26 @@ and len(self.log) > self.max_log_length): del self.log[0:len(self.log)-self.max_log_length-1] self.logbox.set_focus(len(self.logbox.body.contents), - coming_from=u"above") + coming_from="above") self.refresh() def toggle_log_display(self): """Toggle visibility of the log buffer.""" self.log_visible = not self.log_visible self.rebuild() - #self.log_message(u"Log visibility changed to: " + #self.log_message("Log visibility changed to: " # + unicode(self.log_visible)) def change_log_display(self): """Change type of log display. Currently, this toggles wrapping of text lines.""" - if self.log_wrap == u"clip": - self.log_wrap = u"any" + if self.log_wrap == "clip": + self.log_wrap = "any" else: - self.log_wrap = u"clip" + self.log_wrap = "clip" for textwidget in self.log: textwidget.set_wrap_mode(self.log_wrap) - #self.log_message(u"Wrap mode: " + self.log_wrap) + #self.log_message("Wrap mode: " + self.log_wrap) def find_and_remove_client(self, path, name): """Find an client from its object path and remove it. @@ -603,7 +602,7 @@ if path is None: path = client.proxy.object_path self.clients_dict[path] = client - self.clients.sort(None, lambda c: c.properties[u"Name"]) + self.clients.sort(None, lambda c: c.properties["Name"]) self.refresh() def remove_client(self, client, path=None): @@ -640,15 +639,15 @@ def process_input(self, source, condition): keys = self.screen.get_input() - translations = { u"ctrl n": u"down", # Emacs - u"ctrl p": u"up", # Emacs - u"ctrl v": u"page down", # Emacs - u"meta v": u"page up", # Emacs - u" ": u"page down", # less - u"f": u"page down", # less - u"b": u"page up", # less - u"j": u"down", # vi - u"k": u"up", # vi + translations = { "ctrl n": "down", # Emacs + "ctrl p": "up", # Emacs + "ctrl v": "page down", # Emacs + "meta v": "page up", # Emacs + " ": "page down", # less + "f": "page down", # less + "b": "page up", # less + "j": "down", # vi + "k": "up", # vi } for key in keys: try: @@ -656,66 +655,66 @@ except KeyError: # :-) pass - if key == u"q" or key == u"Q": + if key == "q" or key == "Q": self.stop() break - elif key == u"window resize": + elif key == "window resize": self.size = self.screen.get_cols_rows() self.refresh() - elif key == u"\f": # Ctrl-L + elif key == "\f": # Ctrl-L self.refresh() - elif key == u"l" or key == u"D": + elif key == "l" or key == "D": self.toggle_log_display() self.refresh() - elif key == u"w" or key == u"i": + elif key == "w" or key == "i": self.change_log_display() self.refresh() - elif key == u"?" or key == u"f1" or key == u"esc": + elif key == "?" or key == "f1" or key == "esc": if not self.log_visible: self.log_visible = True self.rebuild() - self.log_message_raw((u"bold", - u" ". - join((u"q: Quit", - u"?: Help", - u"l: Log window toggle", - u"TAB: Switch window", - u"w: Wrap (log)")))) - self.log_message_raw((u"bold", - u" " - .join((u"Clients:", - u"+: Enable", - u"-: Disable", - u"R: Remove", - u"s: Start new checker", - u"S: Stop checker", - u"C: Checker OK", - u"a: Approve", - u"d: Deny")))) + self.log_message_raw(("bold", + " ". + join(("q: Quit", + "?: Help", + "l: Log window toggle", + "TAB: Switch window", + "w: Wrap (log)")))) + self.log_message_raw(("bold", + " " + .join(("Clients:", + "+: Enable", + "-: Disable", + "R: Remove", + "s: Start new checker", + "S: Stop checker", + "C: Checker OK", + "a: Approve", + "d: Deny")))) self.refresh() - elif key == u"tab": + elif key == "tab": if self.topwidget.get_focus() is self.logbox: self.topwidget.set_focus(0) else: self.topwidget.set_focus(self.logbox) self.refresh() - #elif (key == u"end" or key == u"meta >" or key == u"G" - # or key == u">"): + #elif (key == "end" or key == "meta >" or key == "G" + # or key == ">"): # pass # xxx end-of-buffer - #elif (key == u"home" or key == u"meta <" or key == u"g" - # or key == u"<"): + #elif (key == "home" or key == "meta <" or key == "g" + # or key == "<"): # pass # xxx beginning-of-buffer - #elif key == u"ctrl e" or key == u"$": + #elif key == "ctrl e" or key == "$": # pass # xxx move-end-of-line - #elif key == u"ctrl a" or key == u"^": + #elif key == "ctrl a" or key == "^": # pass # xxx move-beginning-of-line - #elif key == u"ctrl b" or key == u"meta (" or key == u"h": + #elif key == "ctrl b" or key == "meta (" or key == "h": # pass # xxx left - #elif key == u"ctrl f" or key == u"meta )" or key == u"l": + #elif key == "ctrl f" or key == "meta )" or key == "l": # pass # xxx right - #elif key == u"a": + #elif key == "a": # pass # scroll up log - #elif key == u"z": + #elif key == "z": # pass # scroll down log elif self.topwidget.selectable(): self.topwidget.keypress(self.size, key) === modified file 'mandos-monitor.xml' --- mandos-monitor.xml 2010-09-30 06:24:20 +0000 +++ mandos-monitor.xml 2011-02-27 17:26:35 +0000 @@ -2,7 +2,7 @@ - + %common; ]> @@ -32,6 +32,7 @@ 2010 + 2011 Teddy Hogeborn Björn Påhlsson === modified file 'mandos.xml' --- mandos.xml 2010-09-27 17:39:03 +0000 +++ mandos.xml 2011-02-27 17:26:35 +0000 @@ -2,7 +2,7 @@ - + %common; ]> @@ -34,6 +34,7 @@ 2008 2009 2010 + 2011 Teddy Hogeborn Björn Påhlsson === modified file 'plugins.d/askpass-fifo.c' --- plugins.d/askpass-fifo.c 2010-09-26 18:32:58 +0000 +++ plugins.d/askpass-fifo.c 2011-02-27 17:26:35 +0000 @@ -2,8 +2,8 @@ /* * Askpass-FIFO - Read a password from a FIFO and output it * - * Copyright © 2008-2010 Teddy Hogeborn - * Copyright © 2008-2010 Björn Påhlsson + * Copyright © 2008-2011 Teddy Hogeborn + * Copyright © 2008-2011 Björn Påhlsson * * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU General Public License as === modified file 'plugins.d/mandos-client.c' --- plugins.d/mandos-client.c 2010-09-26 21:27:28 +0000 +++ plugins.d/mandos-client.c 2011-02-27 17:26:35 +0000 @@ -9,8 +9,8 @@ * "browse_callback", and parts of "main". * * Everything else is - * Copyright © 2008-2010 Teddy Hogeborn - * Copyright © 2008-2010 Björn Påhlsson + * Copyright © 2008-2011 Teddy Hogeborn + * Copyright © 2008-2011 Björn Påhlsson * * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU General Public License as === modified file 'plugins.d/password-prompt.c' --- plugins.d/password-prompt.c 2010-09-26 18:32:58 +0000 +++ plugins.d/password-prompt.c 2011-03-08 11:08:35 +0000 @@ -22,22 +22,24 @@ * Contact the authors at . */ -#define _GNU_SOURCE /* getline() */ +#define _GNU_SOURCE /* getline(), asprintf() */ -#include /* struct termios, tcsetattr(), +#include /* struct termios, tcsetattr(), TCSAFLUSH, tcgetattr(), ECHO */ #include /* struct termios, tcsetattr(), STDIN_FILENO, TCSAFLUSH, - tcgetattr(), ECHO */ + tcgetattr(), ECHO, readlink() */ #include /* sig_atomic_t, raise(), struct sigaction, sigemptyset(), sigaction(), sigaddset(), SIGINT, SIGQUIT, SIGHUP, SIGTERM, raise() */ #include /* NULL, size_t, ssize_t */ -#include /* ssize_t */ +#include /* ssize_t, struct dirent, pid_t, + ssize_t, open() */ #include /* EXIT_SUCCESS, EXIT_FAILURE, - getenv() */ + getenv(), free() */ +#include /* scandir(), alphasort() */ #include /* fprintf(), stderr, getline(), stdin, feof(), fputc() */ @@ -47,7 +49,9 @@ #include /* error() */ #include /* or, not */ #include /* bool, false, true */ -#include /* strlen, rindex */ +#include /* strtoumax() */ +#include /* struct stat, lstat(), open() */ +#include /* strlen, rindex, memcmp */ #include /* struct argp_option, struct argp_state, struct argp, argp_parse(), error_t, @@ -55,6 +59,7 @@ ARGP_ERR_UNKNOWN */ #include /* EX_SOFTWARE, EX_OSERR, EX_UNAVAILABLE, EX_IOERR, EX_OK */ +#include /* open() */ volatile sig_atomic_t quit_now = 0; int signal_received; @@ -62,6 +67,9 @@ const char *argp_program_version = "password-prompt " VERSION; const char *argp_program_bug_address = ""; +/* Needed for conflict resolution */ +const char plymouth_name[] = "plymouthd"; + static void termination_handler(int signum){ if(quit_now){ return; @@ -70,6 +78,119 @@ signal_received = signum; } +bool conflict_detection(void){ + + /* plymouth conflicts with password-prompt since both want to read + from the terminal. Password-prompt will exit if it detects + plymouth since plymouth performs the same functionality. + */ + int is_plymouth(const struct dirent *proc_entry){ + int ret; + int cl_fd; + { + uintmax_t maxvalue; + char *tmp; + errno = 0; + maxvalue = strtoumax(proc_entry->d_name, &tmp, 10); + + if(errno != 0 or *tmp != '\0' + or maxvalue != (uintmax_t)((pid_t)maxvalue)){ + return 0; + } + } + + char *cmdline_filename; + ret = asprintf(&cmdline_filename, "/proc/%s/cmdline", + proc_entry->d_name); + if(ret == -1){ + error(0, errno, "asprintf"); + return 0; + } + + /* Open /proc//cmdline */ + cl_fd = open(cmdline_filename, O_RDONLY); + free(cmdline_filename); + if(cl_fd == -1){ + error(0, errno, "open"); + return 0; + } + + char *cmdline = NULL; + { + size_t cmdline_len = 0; + size_t cmdline_allocated = 0; + char *tmp; + const size_t blocksize = 1024; + ssize_t sret; + do { + /* Allocate more space? */ + if(cmdline_len + blocksize + 1 > cmdline_allocated){ + tmp = realloc(cmdline, cmdline_allocated + blocksize + 1); + if(tmp == NULL){ + error(0, errno, "realloc"); + free(cmdline); + close(cl_fd); + return 0; + } + cmdline = tmp; + cmdline_allocated += blocksize; + } + + /* Read data */ + sret = read(cl_fd, cmdline + cmdline_len, + cmdline_allocated - cmdline_len); + if(sret == -1){ + error(0, errno, "read"); + free(cmdline); + close(cl_fd); + return 0; + } + cmdline_len += (size_t)sret; + } while(sret != 0); + ret = close(cl_fd); + if(ret == -1){ + error(0, errno, "close"); + free(cmdline); + return 0; + } + cmdline[cmdline_len] = '\0'; /* Make sure it is terminated */ + } + /* we now have cmdline */ + + /* get basename */ + char *cmdline_base = strrchr(cmdline, '/'); + if(cmdline_base != NULL){ + cmdline_base += 1; /* skip the slash */ + } else { + cmdline_base = cmdline; + } + + if(strcmp(cmdline_base, plymouth_name) != 0){ + if(debug){ + fprintf(stderr, "\"%s\" is not \"%s\"\n", cmdline_base, + plymouth_name); + } + free(cmdline); + return 0; + } + if(debug){ + fprintf(stderr, "\"%s\" equals \"%s\"\n", cmdline_base, + plymouth_name); + } + free(cmdline); + return 1; + } + + struct dirent **direntries; + int ret; + ret = scandir("/proc", &direntries, is_plymouth, alphasort); + if (ret == -1){ + error(1, errno, "scandir"); + } + return ret > 0; +} + + int main(int argc, char **argv){ ssize_t sret; int ret; @@ -151,6 +272,14 @@ if(debug){ fprintf(stderr, "Starting %s\n", argv[0]); } + + if (conflict_detection()){ + if(debug){ + fprintf(stderr, "Stopping %s because of conflict\n", argv[0]); + } + return EXIT_FAILURE; + } + if(debug){ fprintf(stderr, "Storing current terminal attributes\n"); } @@ -354,8 +483,8 @@ break; } } - /* if(sret == 0), then the only sensible thing to do is to retry to - read from stdin */ + /* if(sret == 0), then the only sensible thing to do is to retry + to read from stdin */ fputc('\n', stderr); if(debug and not quit_now){ /* If quit_now is nonzero, we were interrupted by a signal, and === modified file 'plugins.d/plymouth.c' --- plugins.d/plymouth.c 2010-09-26 18:32:58 +0000 +++ plugins.d/plymouth.c 2011-02-27 17:26:35 +0000 @@ -1,9 +1,9 @@ /* -*- coding: utf-8 -*- */ /* - * Usplash - Read a password from usplash and output it + * Plymouth - Read a password from Plymouth and output it * - * Copyright © 2010 Teddy Hogeborn - * Copyright © 2010 Björn Påhlsson + * Copyright © 2010-2011 Teddy Hogeborn + * Copyright © 2010-2011 Björn Påhlsson * * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -76,21 +76,23 @@ char *prompt; const char *const cryptsource = getenv("cryptsource"); const char *const crypttarget = getenv("crypttarget"); - const char prompt_start[] = "Enter passphrase to unlock the disk"; + const char prompt_start[] = "Unlocking the disk"; + const char prompt_end[] = "Enter passphrase"; if(cryptsource == NULL){ if(crypttarget == NULL){ - ret = asprintf(&prompt, "%s: ", prompt_start); + ret = asprintf(&prompt, "%s\n%s", prompt_start, prompt_end); } else { - ret = asprintf(&prompt, "%s (%s): ", prompt_start, - crypttarget); + ret = asprintf(&prompt, "%s (%s)\n%s", prompt_start, + crypttarget, prompt_end); } } else { if(crypttarget == NULL){ - ret = asprintf(&prompt, "%s %s: ", prompt_start, cryptsource); + ret = asprintf(&prompt, "%s %s\n%s", prompt_start, cryptsource, + prompt_end); } else { - ret = asprintf(&prompt, "%s %s (%s): ", prompt_start, - cryptsource, crypttarget); + ret = asprintf(&prompt, "%s %s (%s)\n%s", prompt_start, + cryptsource, crypttarget, prompt_end); } } if(ret == -1){ @@ -142,21 +144,21 @@ _exit(EX_OSERR); } } - + char **new_argv = NULL; - char *tmp; + char **tmp; int i = 0; - for (; argv[i]!=(char *)NULL; i++){ + for (; argv[i]!=NULL; i++){ tmp = realloc(new_argv, sizeof(const char *) * ((size_t)i + 1)); if (tmp == NULL){ error(0, errno, "realloc"); free(new_argv); _exit(EX_OSERR); } - new_argv = (char **)tmp; + new_argv = tmp; new_argv[i] = strdup(argv[i]); } - new_argv[i] = (char *) NULL; + new_argv[i] = NULL; execv(path, (char *const *)new_argv); error(0, errno, "execv"); @@ -196,7 +198,7 @@ return 0; } } - char exe_target[sizeof(plymouth_path)]; + char exe_target[sizeof(plymouthd_path)]; char *exe_link; ret = asprintf(&exe_link, "/proc/%s/exe", proc_entry->d_name); if(ret == -1){ @@ -223,9 +225,9 @@ ssize_t sret = readlink(exe_link, exe_target, sizeof(exe_target)); free(exe_link); - if((sret != (ssize_t)sizeof(plymouth_path)-1) or - (memcmp(plymouth_path, exe_target, - sizeof(plymouth_path)-1) != 0)){ + if((sret != (ssize_t)sizeof(plymouthd_path)-1) or + (memcmp(plymouthd_path, exe_target, + sizeof(plymouthd_path)-1) != 0)){ return 0; } return 1; @@ -245,7 +247,15 @@ if(maxvalue == 0){ struct dirent **direntries; ret = scandir("/proc", &direntries, is_plymouth, alphasort); - sscanf(direntries[0]->d_name, "%" SCNuMAX, &maxvalue); + if (ret == -1){ + error(0, errno, "scandir"); + } + if (ret > 0){ + ret = sscanf(direntries[0]->d_name, "%" SCNuMAX, &maxvalue); + if (ret < 0){ + error(0, errno, "sscanf"); + } + } } pid_t pid; pid = (pid_t)maxvalue; === modified file 'plugins.d/plymouth.xml' --- plugins.d/plymouth.xml 2010-09-26 18:32:58 +0000 +++ plugins.d/plymouth.xml 2011-02-27 17:26:35 +0000 @@ -2,7 +2,7 @@ - + %common; ]> @@ -32,6 +32,7 @@ 2010 + 2011 Teddy Hogeborn Björn Påhlsson === modified file 'plugins.d/splashy.c' --- plugins.d/splashy.c 2010-10-07 17:46:56 +0000 +++ plugins.d/splashy.c 2011-02-27 17:26:35 +0000 @@ -2,8 +2,8 @@ /* * Splashy - Read a password from splashy and output it * - * Copyright © 2008-2010 Teddy Hogeborn - * Copyright © 2008-2010 Björn Påhlsson + * Copyright © 2008-2011 Teddy Hogeborn + * Copyright © 2008-2011 Björn Påhlsson * * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU General Public License as === modified file 'plugins.d/usplash.c' --- plugins.d/usplash.c 2010-09-26 18:32:58 +0000 +++ plugins.d/usplash.c 2011-02-27 17:26:35 +0000 @@ -2,8 +2,8 @@ /* * Usplash - Read a password from usplash and output it * - * Copyright © 2008-2010 Teddy Hogeborn - * Copyright © 2008-2010 Björn Påhlsson + * Copyright © 2008-2011 Teddy Hogeborn + * Copyright © 2008-2011 Björn Påhlsson * * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU General Public License as