=== modified file 'TODO' --- TODO 2010-09-02 18:53:38 +0000 +++ TODO 2010-09-04 13:31:36 +0000 @@ -1,6 +1,7 @@ -*- org -*- * _attribute_((nonnull)) +* FIX XXX * mandos-client ** TODO [#B] use scandir(3) instead of readdir(3) @@ -107,6 +108,8 @@ ** Urwid client data displayer Better view of client data in the listing *** Properties popup +** Nicer crashes. Stack traces Messes up shell. +*** Print a nice "We are sorry" message, save stack trace to log. * mandos-keygen ** TODO Loop until passwords match when run interactively === modified file 'debian/control' --- debian/control 2010-01-01 15:17:12 +0000 +++ debian/control 2010-08-23 19:23:15 +0000 @@ -15,7 +15,8 @@ Package: mandos Architecture: all Depends: ${misc:Depends}, python (>=2.5), python-gnutls, python-dbus, - python-avahi, python-gobject, avahi-daemon, adduser + python-avahi, python-gobject, avahi-daemon, adduser, + python-urwid Recommends: fping Description: a server giving encrypted passwords to Mandos clients This is the server part of the Mandos system, which allows === modified file 'mandos' --- mandos 2010-09-02 18:53:38 +0000 +++ mandos 2010-09-04 13:31:36 +0000 @@ -83,6 +83,7 @@ version = "1.0.14" +#logger = logging.getLogger(u'mandos') logger = logging.Logger(u'mandos') syslogger = (logging.handlers.SysLogHandler (facility = logging.handlers.SysLogHandler.LOG_DAEMON, @@ -321,16 +322,16 @@ self.checker_command = config[u"checker"] self.current_checker_command = None self.last_connect = None + self._approved = None + self.approved_by_default = config.get(u"approved_by_default", + True) self.approvals_pending = 0 - self._approved = None - self.approved_by_default = config.get(u"approved_by_default", - False) self.approved_delay = string_to_delta( config[u"approved_delay"]) self.approved_duration = string_to_delta( config[u"approved_duration"]) self.changedstate = multiprocessing_manager.Condition(multiprocessing_manager.Lock()) - + def send_changedstate(self): self.changedstate.acquire() self.changedstate.notify_all() @@ -700,6 +701,7 @@ # dbus.service.Object doesn't use super(), so we can't either. def __init__(self, bus = None, *args, **kwargs): + self._approvals_pending = 0 self.bus = bus Client.__init__(self, *args, **kwargs) # Only now, when this client is initialized, can it show up on @@ -709,6 +711,24 @@ + self.name.replace(u".", u"_"))) DBusObjectWithProperties.__init__(self, self.bus, self.dbus_object_path) + + #Could possible return a bool(self._approvals_pending), + #but this could mess up approvals_pending += 1 XXX + def _get_approvals_pending(self): + return self._approvals_pending + def _set_approvals_pending(self, value): + old_value = self._approvals_pending + self._approvals_pending = value + bval = bool(value) + 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"approved_pending"), + dbus_bool) + + approvals_pending = property(_get_approvals_pending, + _set_approvals_pending) + del _get_approvals_pending, _set_approvals_pending @staticmethod def _datetime_to_dbus(dt, variant_level=0): @@ -809,12 +829,11 @@ return False def approve(self, value=True): + self.send_changedstate() self._approved = value - gobject.timeout_add(self._timedelta_to_milliseconds(self.approved_duration, self._reset_approved)) - - def approved_pending(self): - return self.approvals_pending > 0 - + gobject.timeout_add(self._timedelta_to_milliseconds(self.approved_duration), + self._reset_approved) + ## D-Bus methods, signals & properties _interface = u"se.bsnet.fukt.Mandos.Client" @@ -840,7 +859,7 @@ pass # GotSecret - signal - # Is sent after succesfull transfer of secret from mandos-server to mandos-client + # XXXTEDDY Is sent after succesfull transfer of secret from mandos-server to mandos-client @dbus.service.signal(_interface) def GotSecret(self): "D-Bus signal" @@ -898,7 +917,7 @@ # approved_pending - property @dbus_service_property(_interface, signature=u"b", access=u"read") def approved_pending_dbus_property(self): - return dbus.Boolean(self.approved_pending()) + return dbus.Boolean(bool(self.approvals_pending)) # approved_by_default - property @dbus_service_property(_interface, signature=u"b", @@ -1322,7 +1341,7 @@ self).process_request(request, client_address) self.child_pipe.close() self.add_pipe(parent_pipe) - + def add_pipe(self, parent_pipe): """Dummy function; override as necessary""" pass @@ -1444,7 +1463,7 @@ logger.debug(u"Handling IPC: FD = %d, condition = %s", source, conditions_string) - # error or the other end of multiprocessing.Pipe has closed + # XXXTEDDY error or the other end of multiprocessing.Pipe has closed if condition & gobject.IO_HUP or condition & gobject.IO_ERR: return False @@ -1491,12 +1510,12 @@ parent_pipe.send(('function',)) else: parent_pipe.send(('data', client_object.__getattribute__(attrname))) - + if command == 'setattr': attrname = request[1] value = request[2] setattr(client_object, attrname, value) - + return True @@ -1690,7 +1709,7 @@ u"interval": u"5m", u"checker": u"fping -q -- %%(host)s", u"host": u"", - u"approved_delay": u"5m", + u"approved_delay": u"0s", u"approved_duration": u"1s", } client_config = configparser.SafeConfigParser(client_defaults) === modified file 'mandos-monitor' --- mandos-monitor 2010-09-02 18:53:38 +0000 +++ mandos-monitor 2010-09-04 13:31:36 +0000 @@ -57,8 +57,10 @@ self.properties.update( self.proxy.GetAll(client_interface, dbus_interface = dbus.PROPERTIES_IFACE)) - super(MandosClientPropertyCache, self).__init__( - *args, **kwargs) + + #XXX This break good super behaviour! +# super(MandosClientPropertyCache, self).__init__( +# *args, **kwargs) def property_changed(self, property=None, value=None): """This is called whenever we get a PropertyChanged signal @@ -184,14 +186,24 @@ u"bold-underline-blink": u"bold-underline-blink-standout", } - + # Rebuild focus and non-focus widgets using current properties - self._text = (u'%(name)s: %(enabled)s' - % { u"name": self.properties[u"name"], - u"enabled": - (u"enabled" - if self.properties[u"enabled"] - else u"DISABLED")}) + + # Base part of a client. Name! + self._text = (u'%(name)s: ' + % {u"name": self.properties[u"name"]}) + + if self.properties[u"approved_pending"]: + if self.properties[u"approved_by_default"]: + self._text += u"Connection established to client. (d)eny?" + else: + self._text += u"Seeks approval to send secret. (a)pprove?" + else: + self._text += (u'%(enabled)s' + % {u"enabled": + (u"enabled" + if self.properties[u"enabled"] + else u"DISABLED")}) if not urwid.supports_unicode(): self._text = self._text.encode("ascii", "replace") textlist = [(u"normal", self._text)] @@ -221,19 +233,25 @@ def keypress(self, (maxcol,), key): """Handle keys. This overrides the method from urwid.FlowWidget""" - if key == u"e" or key == u"+": - self.proxy.Enable() - elif key == u"d" or key == u"-": - self.proxy.Disable() + if key == u"+": + self.proxy.Enable(dbus_interface = client_interface) + elif key == u"-": + self.proxy.Disable(dbus_interface = client_interface) + elif key == u"a": + self.proxy.Approve(dbus.Boolean(True, variant_level=1), + dbus_interface = client_interface) + elif key == u"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": self.server_proxy_object.RemoveClient(self.proxy .object_path) elif key == u"s": - self.proxy.StartChecker() + self.proxy.StartChecker(dbus_interface = client_interface) elif key == u"S": - self.proxy.StopChecker() + self.proxy.StopChecker(dbus_interface = client_interface) elif key == u"C": - self.proxy.CheckedOK() + self.proxy.CheckedOK(dbus_interface = client_interface) # xxx # elif key == u"p" or key == "=": # self.proxy.pause() @@ -241,10 +259,10 @@ # self.proxy.unpause() # elif key == u"RET": # self.open() - elif key == u"+": - self.proxy.Approve(True) - elif key == u"-": - self.proxy.Approve(False) +# elif key == u"+": +# self.proxy.Approve(True) +# elif key == u"-": +# self.proxy.Approve(False) else: return key @@ -547,7 +565,9 @@ u"r: Remove", u"s: Start new checker", u"S: Stop checker", - u"C: Checker OK")))) + u"C: Checker OK", + u"A: Approve", + u"D: Deny")))) self.refresh() elif key == u"tab": if self.topwidget.get_focus() is self.logbox: