=== modified file 'mandos' --- mandos 2012-05-07 19:13:15 +0000 +++ mandos 2012-05-12 15:45:57 +0000 @@ -572,29 +572,29 @@ if getattr(self, "enabled", False): # Already enabled return - self.send_changedstate() self.expires = datetime.datetime.utcnow() + self.timeout self.enabled = True self.last_enabled = datetime.datetime.utcnow() self.init_checker() + self.send_changedstate() def disable(self, quiet=True): """Disable this client.""" if not getattr(self, "enabled", False): return False if not quiet: - self.send_changedstate() - if not quiet: logger.info("Disabling client %s", self.name) - if getattr(self, "disable_initiator_tag", False): + if getattr(self, "disable_initiator_tag", None) is not None: gobject.source_remove(self.disable_initiator_tag) self.disable_initiator_tag = None self.expires = None - if getattr(self, "checker_initiator_tag", False): + if getattr(self, "checker_initiator_tag", None) is not None: gobject.source_remove(self.checker_initiator_tag) self.checker_initiator_tag = None self.stop_checker() self.enabled = False + if not quiet: + self.send_changedstate() # Do not run this again if called by a gobject.timeout_add return False @@ -604,10 +604,14 @@ def init_checker(self): # Schedule a new checker to be started an 'interval' from now, # and every interval from then on. + if self.checker_initiator_tag is not None: + gobject.source_remove(self.checker_initiator_tag) self.checker_initiator_tag = (gobject.timeout_add (self.interval_milliseconds(), self.start_checker)) # Schedule a disable() when 'timeout' has passed + if self.disable_initiator_tag is not None: + gobject.source_remove(self.disable_initiator_tag) self.disable_initiator_tag = (gobject.timeout_add (self.timeout_milliseconds(), self.disable)) @@ -644,6 +648,7 @@ timeout = self.timeout if self.disable_initiator_tag is not None: gobject.source_remove(self.disable_initiator_tag) + self.disable_initiator_tag = None if getattr(self, "enabled", False): self.disable_initiator_tag = (gobject.timeout_add (timedelta_to_milliseconds @@ -1335,11 +1340,11 @@ return False def approve(self, value=True): - self.send_changedstate() self.approved = value gobject.timeout_add(timedelta_to_milliseconds (self.approval_duration), self._reset_approved) + self.send_changedstate() ## D-Bus methods, signals & properties _interface = "se.recompile.Mandos.Client" @@ -1529,26 +1534,24 @@ def Timeout_dbus_property(self, value=None): if value is None: # get return dbus.UInt64(self.timeout_milliseconds()) + old_timeout = self.timeout self.timeout = datetime.timedelta(0, 0, 0, value) - # Reschedule timeout + # Reschedule disabling if self.enabled: now = datetime.datetime.utcnow() - time_to_die = timedelta_to_milliseconds( - (self.last_checked_ok + self.timeout) - now) - if time_to_die <= 0: + self.expires += self.timeout - old_timeout + if self.expires <= now: # The timeout has passed self.disable() else: - self.expires = (now + - datetime.timedelta(milliseconds = - time_to_die)) if (getattr(self, "disable_initiator_tag", None) is None): return gobject.source_remove(self.disable_initiator_tag) - self.disable_initiator_tag = (gobject.timeout_add - (time_to_die, - self.disable)) + self.disable_initiator_tag = ( + gobject.timeout_add( + timedelta_to_milliseconds(self.expires - now), + self.disable)) # ExtendedTimeout - property @dbus_service_property(_interface, signature="t", @@ -1742,9 +1745,9 @@ #wait until timeout or approved time = datetime.datetime.now() client.changedstate.acquire() - (client.changedstate.wait - (float(client.timedelta_to_milliseconds(delay) - / 1000))) + client.changedstate.wait( + float(timedelta_to_milliseconds(delay) + / 1000)) client.changedstate.release() time2 = datetime.datetime.now() if (time2 - time) >= delay: === modified file 'mandos-monitor' --- mandos-monitor 2012-05-07 20:46:51 +0000 +++ mandos-monitor 2012-05-12 15:45:57 +0000 @@ -134,7 +134,6 @@ self.logger = logger self._update_timer_callback_tag = None - self._update_timer_callback_lock = 0 # The widget shown normally self._text_widget = urwid.Text("") @@ -144,15 +143,6 @@ self.update() self.opened = False - last_checked_ok = isoformat_to_datetime(self.properties - ["LastCheckedOK"]) - - if self.properties ["LastCheckerStatus"] != 0: - self.using_timer(True) - - if self.need_approval: - self.using_timer(True) - self.match_objects = ( self.proxy.connect_to_signal("CheckerCompleted", self.checker_completed, @@ -177,32 +167,16 @@ #self.logger('Created client {0}' # .format(self.properties["Name"])) - def property_changed(self, property=None, value=None): - super(self, MandosClientWidget).property_changed(property, - value) - if property == "ApprovalPending": - using_timer(bool(value)) - if property == "LastCheckerStatus": - using_timer(value != 0) - #self.logger('Checker for client {0} (command "{1}") was ' - # ' successful'.format(self.properties["Name"], - # command)) - def using_timer(self, flag): """Call this method with True or False when timer should be activated or deactivated. """ - old = self._update_timer_callback_lock - if flag: - self._update_timer_callback_lock += 1 - else: - self._update_timer_callback_lock -= 1 - if old == 0 and self._update_timer_callback_lock: + if flag and self._update_timer_callback_tag is None: # Will update the shown timer value every second self._update_timer_callback_tag = (gobject.timeout_add (1000, self.update_timer)) - elif old and self._update_timer_callback_lock == 0: + elif not (flag or self._update_timer_callback_tag is None): gobject.source_remove(self._update_timer_callback_tag) self._update_timer_callback_tag = None @@ -250,7 +224,6 @@ message = 'Client {0} will get its secret in {1} seconds' self.logger(message.format(self.properties["Name"], timeout/1000)) - self.using_timer(True) def rejected(self, reason): self.logger('Client {0} was rejected; reason: {1}' @@ -282,13 +255,14 @@ "bold-underline-blink": "bold-underline-blink-standout", } - + # Rebuild focus and non-focus widgets using current properties - + # Base part of a client. Name! base = '{name}: '.format(name=self.properties["Name"]) if not self.properties["Enabled"]: message = "DISABLED" + self.using_timer(False) elif self.properties["ApprovalPending"]: timeout = datetime.timedelta(milliseconds = self.properties @@ -296,8 +270,9 @@ last_approval_request = isoformat_to_datetime( self.properties["LastApprovalRequest"]) if last_approval_request is not None: - timer = timeout - (datetime.datetime.utcnow() - - last_approval_request) + timer = max(timeout - (datetime.datetime.utcnow() + - last_approval_request), + datetime.timedelta()) else: timer = datetime.timedelta() if self.properties["ApprovedByDefault"]: @@ -305,6 +280,7 @@ else: message = "Denial in {0}. (a)pprove?" message = message.format(unicode(timer).rsplit(".", 1)[0]) + self.using_timer(True) elif self.properties["LastCheckerStatus"] != 0: # When checker has failed, show timer until client expires expires = self.properties["Expires"] @@ -313,14 +289,17 @@ else: expires = (datetime.datetime.strptime (expires, '%Y-%m-%dT%H:%M:%S.%f')) - timer = expires - datetime.datetime.utcnow() + timer = max(expires - datetime.datetime.utcnow(), + datetime.timedelta()) message = ('A checker has failed! Time until client' ' gets disabled: {0}' .format(unicode(timer).rsplit(".", 1)[0])) + self.using_timer(True) else: message = "enabled" + self.using_timer(False) self._text = "{0}{1}".format(base, message) - + if not urwid.supports_unicode(): self._text = self._text.encode("ascii", "replace") textlist = [("normal", self._text)]