=== modified file 'DBUS-API'
--- DBUS-API 2011-03-17 18:14:34 +0000
+++ DBUS-API 2011-09-18 15:59:05 +0000
@@ -86,15 +86,17 @@
| CheckerRunning (c) | b | Read/Write | N/A |
| Created (d) | s | Read | N/A |
| Enabled (e) | b | Read/Write | N/A |
+ | Expires (f) | s | Read | N/A |
+ | ExtendedTimeout (a) | t | Read/Write | extended_timeout |
| Fingerprint | s | Read | fingerprint |
| Host | s | Read/Write | host |
| Interval (a) | t | Read/Write | interval |
- | LastApprovalRequest (f) | s | Read | N/A |
- | LastCheckedOK (g) | s | Read/Write | N/A |
- | LastEnabled (h) | s | Read | N/A |
+ | LastApprovalRequest (g) | s | Read | N/A |
+ | LastCheckedOK (h) | s | Read/Write | N/A |
+ | LastEnabled (i) | s | Read | N/A |
| Name | s | Read | (Section name) |
| ObjectPath | o | Read | N/A |
- | Secret (i) | ay | Write | secret (or secfile) |
+ | Secret (j) | ay | Write | secret (or secfile) |
| Timeout (a) | t | Read/Write | timeout |
a) Represented as milliseconds.
@@ -109,20 +111,23 @@
e) Setting this property is equivalent to calling Enable() or
Disable().
- f) The time of the last approval request, as an RFC 3339 string, or
- an empty string if this has not happened.
-
- g) The last time a checker was successful, as an RFC 3339 string,
- or an empty string if this has not happened. Setting this
- property is equivalent to calling CheckedOK(), i.e. the current
- time is set, regardless of the string sent. Please always use
- an empty string when setting this property, to allow for
- possible future expansion.
-
- h) The last time this client was enabled, as an RFC 3339 string, or
- an empty string if this has not happened.
-
- i) A raw byte array, not hexadecimal digits.
+ f) The date and time this client will be disabled, as an RFC 3339
+ string, or an empty string if this has not happened.
+
+ g) The date and time of the last approval request, as an RFC 3339
+ string, or an empty string if this has not happened.
+
+ h) The date and time a checker was last successful, as an RFC 3339
+ string, or an empty string if this has not happened. Setting
+ this property is equivalent to calling CheckedOK(), i.e. the
+ current time is set, regardless of the string sent. Please
+ always use an empty string when setting this property, to allow
+ for possible future expansion.
+
+ i) The date and time this client was last enabled, as an RFC 3339
+ string, or an empty string if this has not happened.
+
+ j) A raw byte array, not hexadecimal digits.
** Signals
*** CheckerCompleted(n: Exitcode, x: Waitstatus, s: Command)
=== modified file 'README'
--- README 2011-08-08 21:12:37 +0000
+++ README 2011-09-18 14:28:47 +0000
@@ -3,7 +3,7 @@
This information previously in this file has been moved to the
intro(8mandos) manual page. Go to the above URL, or run this command:
- make intro.8mandos && man -l intro.8mandos
+ man 8mandos intro
In short, this is the Mandos system; it allows computers to have
encrypted root file systems and at the same time be capable of remote
=== modified file 'TODO'
--- TODO 2011-08-17 22:46:35 +0000
+++ TODO 2011-09-18 14:28:47 +0000
@@ -38,6 +38,7 @@
** TODO [#B] Use openat()
* mandos (server)
+** TODO [#A] Make all attributes properties!
** TODO [#B] Log level :BUGS:
** TODO Persistent state :BUGS:
/var/lib/mandos/*
=== modified file 'mandos'
--- mandos 2011-07-27 17:58:27 +0000
+++ mandos 2011-09-18 15:59:05 +0000
@@ -297,7 +297,10 @@
secret: bytestring; sent verbatim (over TLS) to client
timeout: datetime.timedelta(); How long from last_checked_ok
until this client is disabled
+ extended_timeout: extra long timeout when password has been sent
runtime_expansions: Allowed attributes for runtime expansion.
+ expires: datetime.datetime(); time (UTC) when a client will be
+ disabled, or None
"""
runtime_expansions = ("approval_delay", "approval_duration",
@@ -315,6 +318,10 @@
def timeout_milliseconds(self):
"Return the 'timeout' attribute in milliseconds"
return self._timedelta_to_milliseconds(self.timeout)
+
+ def extended_timeout_milliseconds(self):
+ "Return the 'extended_timeout' attribute in milliseconds"
+ return self._timedelta_to_milliseconds(self.extended_timeout)
def interval_milliseconds(self):
"Return the 'interval' attribute in milliseconds"
@@ -354,11 +361,13 @@
self.last_enabled = None
self.last_checked_ok = None
self.timeout = string_to_delta(config["timeout"])
+ self.extended_timeout = string_to_delta(config["extended_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.expires = None
self.checker_callback_tag = None
self.checker_command = config["checker"]
self.current_checker_command = None
@@ -391,6 +400,7 @@
(self.interval_milliseconds(),
self.start_checker))
# Schedule a disable() when 'timeout' has passed
+ self.expires = datetime.datetime.utcnow() + self.timeout
self.disable_initiator_tag = (gobject.timeout_add
(self.timeout_milliseconds(),
self.disable))
@@ -409,6 +419,7 @@
if getattr(self, "disable_initiator_tag", False):
gobject.source_remove(self.disable_initiator_tag)
self.disable_initiator_tag = None
+ self.expires = None
if getattr(self, "checker_initiator_tag", False):
gobject.source_remove(self.checker_initiator_tag)
self.checker_initiator_tag = None
@@ -440,16 +451,19 @@
logger.warning("Checker for %(name)s crashed?",
vars(self))
- def checked_ok(self):
+ def checked_ok(self, timeout=None):
"""Bump up the timeout for this client.
This should only be called when the client has been seen,
alive and well.
"""
+ if timeout is None:
+ timeout = self.timeout
self.last_checked_ok = datetime.datetime.utcnow()
gobject.source_remove(self.disable_initiator_tag)
+ self.expires = datetime.datetime.utcnow() + timeout
self.disable_initiator_tag = (gobject.timeout_add
- (self.timeout_milliseconds(),
+ (self._timedelta_to_milliseconds(timeout),
self.disable))
def need_approval(self):
@@ -763,6 +777,16 @@
("/clients/" + client_object_name))
DBusObjectWithProperties.__init__(self, self.bus,
self.dbus_object_path)
+ def _set_expires(self, value):
+ old_value = getattr(self, "_expires", None)
+ self._expires = value
+ if hasattr(self, "dbus_object_path") and old_value != value:
+ dbus_time = (self._datetime_to_dbus(self._expires,
+ variant_level=1))
+ self.PropertyChanged(dbus.String("Expires"),
+ dbus_time)
+ expires = property(lambda self: self._expires, _set_expires)
+ del _set_expires
def _get_approvals_pending(self):
return self._approvals_pending
@@ -783,6 +807,8 @@
@staticmethod
def _datetime_to_dbus(dt, variant_level=0):
"""Convert a UTC datetime.datetime() to a D-Bus type."""
+ if dt is None:
+ return dbus.String("", variant_level = variant_level)
return dbus.String(dt.isoformat(),
variant_level=variant_level)
@@ -986,10 +1012,12 @@
def ApprovedByDefault_dbus_property(self, value=None):
if value is None: # get
return dbus.Boolean(self.approved_by_default)
+ old_value = self.approved_by_default
self.approved_by_default = bool(value)
# Emit D-Bus signal
- self.PropertyChanged(dbus.String("ApprovedByDefault"),
- dbus.Boolean(value, variant_level=1))
+ if old_value != self.approved_by_default:
+ self.PropertyChanged(dbus.String("ApprovedByDefault"),
+ dbus.Boolean(value, variant_level=1))
# ApprovalDelay - property
@dbus_service_property(_interface, signature="t",
@@ -997,10 +1025,12 @@
def ApprovalDelay_dbus_property(self, value=None):
if value is None: # get
return dbus.UInt64(self.approval_delay_milliseconds())
+ old_value = self.approval_delay
self.approval_delay = datetime.timedelta(0, 0, 0, value)
# Emit D-Bus signal
- self.PropertyChanged(dbus.String("ApprovalDelay"),
- dbus.UInt64(value, variant_level=1))
+ if old_value != self.approval_delay:
+ self.PropertyChanged(dbus.String("ApprovalDelay"),
+ dbus.UInt64(value, variant_level=1))
# ApprovalDuration - property
@dbus_service_property(_interface, signature="t",
@@ -1009,10 +1039,12 @@
if value is None: # get
return dbus.UInt64(self._timedelta_to_milliseconds(
self.approval_duration))
+ old_value = self.approval_duration
self.approval_duration = datetime.timedelta(0, 0, 0, value)
# Emit D-Bus signal
- self.PropertyChanged(dbus.String("ApprovalDuration"),
- dbus.UInt64(value, variant_level=1))
+ if old_value != self.approval_duration:
+ self.PropertyChanged(dbus.String("ApprovalDuration"),
+ dbus.UInt64(value, variant_level=1))
# Name - property
@dbus_service_property(_interface, signature="s", access="read")
@@ -1030,10 +1062,12 @@
def Host_dbus_property(self, value=None):
if value is None: # get
return dbus.String(self.host)
+ old_value = self.host
self.host = value
# Emit D-Bus signal
- self.PropertyChanged(dbus.String("Host"),
- dbus.String(value, variant_level=1))
+ if old_value != self.host:
+ self.PropertyChanged(dbus.String("Host"),
+ dbus.String(value, variant_level=1))
# Created - property
@dbus_service_property(_interface, signature="s", access="read")
@@ -1043,9 +1077,7 @@
# LastEnabled - property
@dbus_service_property(_interface, signature="s", access="read")
def LastEnabled_dbus_property(self):
- if self.last_enabled is None:
- return dbus.String("")
- return dbus.String(self._datetime_to_dbus(self.last_enabled))
+ return self._datetime_to_dbus(self.last_enabled)
# Enabled - property
@dbus_service_property(_interface, signature="b",
@@ -1065,19 +1097,17 @@
if value is not None:
self.checked_ok()
return
- if self.last_checked_ok is None:
- return dbus.String("")
- return dbus.String(self._datetime_to_dbus(self
- .last_checked_ok))
+ return self._datetime_to_dbus(self.last_checked_ok)
+
+ # Expires - property
+ @dbus_service_property(_interface, signature="s", access="read")
+ def Expires_dbus_property(self):
+ return self._datetime_to_dbus(self.expires)
# LastApprovalRequest - property
@dbus_service_property(_interface, signature="s", access="read")
def LastApprovalRequest_dbus_property(self):
- if self.last_approval_request is None:
- return dbus.String("")
- return dbus.String(self.
- _datetime_to_dbus(self
- .last_approval_request))
+ return self._datetime_to_dbus(self.last_approval_request)
# Timeout - property
@dbus_service_property(_interface, signature="t",
@@ -1085,15 +1115,18 @@
def Timeout_dbus_property(self, value=None):
if value is None: # get
return dbus.UInt64(self.timeout_milliseconds())
+ old_value = self.timeout
self.timeout = datetime.timedelta(0, 0, 0, value)
# Emit D-Bus signal
- self.PropertyChanged(dbus.String("Timeout"),
- dbus.UInt64(value, variant_level=1))
+ if old_value != self.timeout:
+ self.PropertyChanged(dbus.String("Timeout"),
+ dbus.UInt64(value, variant_level=1))
if getattr(self, "disable_initiator_tag", None) is None:
return
# Reschedule timeout
gobject.source_remove(self.disable_initiator_tag)
self.disable_initiator_tag = None
+ self.expires = None
time_to_die = (self.
_timedelta_to_milliseconds((self
.last_checked_ok
@@ -1104,19 +1137,36 @@
# The timeout has passed
self.disable()
else:
+ self.expires = (datetime.datetime.utcnow()
+ + datetime.timedelta(milliseconds = time_to_die))
self.disable_initiator_tag = (gobject.timeout_add
(time_to_die, self.disable))
-
+
+ # ExtendedTimeout - property
+ @dbus_service_property(_interface, signature="t",
+ access="readwrite")
+ def ExtendedTimeout_dbus_property(self, value=None):
+ if value is None: # get
+ return dbus.UInt64(self.extended_timeout_milliseconds())
+ old_value = self.extended_timeout
+ self.extended_timeout = datetime.timedelta(0, 0, 0, value)
+ # Emit D-Bus signal
+ if old_value != self.extended_timeout:
+ self.PropertyChanged(dbus.String("ExtendedTimeout"),
+ dbus.UInt64(value, variant_level=1))
+
# Interval - property
@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())
+ old_value = self.interval
self.interval = datetime.timedelta(0, 0, 0, value)
# Emit D-Bus signal
- self.PropertyChanged(dbus.String("Interval"),
- dbus.UInt64(value, variant_level=1))
+ if old_value != self.interval:
+ self.PropertyChanged(dbus.String("Interval"),
+ dbus.UInt64(value, variant_level=1))
if getattr(self, "checker_initiator_tag", None) is None:
return
# Reschedule checker run
@@ -1131,11 +1181,13 @@
def Checker_dbus_property(self, value=None):
if value is None: # get
return dbus.String(self.checker_command)
+ old_value = self.checker_command
self.checker_command = value
# Emit D-Bus signal
- self.PropertyChanged(dbus.String("Checker"),
- dbus.String(self.checker_command,
- variant_level=1))
+ if old_value != self.checker_command:
+ self.PropertyChanged(dbus.String("Checker"),
+ dbus.String(self.checker_command,
+ variant_level=1))
# CheckerRunning - property
@dbus_service_property(_interface, signature="b",
@@ -1329,7 +1381,7 @@
logger.info("Sending secret to %s", client.name)
# bump the timeout as if seen
- client.checked_ok()
+ client.checked_ok(client.extended_timeout)
if self.server.use_dbus:
# Emit D-Bus signal
client.GotSecret()
@@ -1796,8 +1848,9 @@
% server_settings["servicename"]))
# Parse config file with clients
- client_defaults = { "timeout": "1h",
- "interval": "5m",
+ client_defaults = { "timeout": "5m",
+ "extended_timeout": "15m",
+ "interval": "2m",
"checker": "fping -q -- %%(host)s",
"host": "",
"approval_delay": "0s",
=== modified file 'mandos-clients.conf.xml'
--- mandos-clients.conf.xml 2011-08-08 21:12:37 +0000
+++ mandos-clients.conf.xml 2011-09-18 14:28:47 +0000
@@ -229,7 +229,7 @@
will wait for a checker to complete until the below
timeout occurs, at which
time the client will be disabled, and any running checker
- killed. The default interval is 5 minutes.
+ killed. The default interval is 2 minutes.
The format of TIME is the same
@@ -302,7 +302,7 @@
The timeout is how long the server will wait (for either a
successful checker run or a client receiving its secret)
until a client is disabled and not allowed to get the data
- this server holds. By default Mandos will use 1 hour.
+ this server holds. By default Mandos will use 5 minutes.
The TIME is specified as a
@@ -319,6 +319,29 @@
+
+
+
+
+
+ This option is optional.
+
+
+ Extended timeout is an added timeout that is given once
+ after a password has been sent sucessfully to a client.
+ The timeout is by default longer than the normal timeout,
+ and is used for handling the extra long downtime while a
+ matchine is booting up. Time to take into consideration
+ when changing this value is system file checks and quota
+ checks. The default value is 15 minutes.
+
+
+ The format of TIME is the same
+ as for timeout above.
+
+
+
@@ -420,8 +443,8 @@
[DEFAULT]
-timeout = 1h
-interval = 5m
+timeout = 5m
+interval = 2m
checker = fping -q -- %%(host)s
# Client "foo"
=== modified file 'mandos-ctl'
--- mandos-ctl 2011-07-27 17:58:27 +0000
+++ mandos-ctl 2011-09-18 14:28:47 +0000
@@ -52,6 +52,7 @@
"ApprovalDelay": "Approval Delay",
"ApprovalDuration": "Approval Duration",
"Checker": "Checker",
+ "ExtendedTimeout" : "Extended Timeout"
}
defaultkeywords = ("Name", "Enabled", "Timeout", "LastCheckedOK")
domain = "se.bsnet.fukt"
@@ -149,6 +150,7 @@
options.remove,
options.checker is not None,
options.timeout is not None,
+ options.extended_timeout is not None,
options.interval is not None,
options.approved_by_default is not None,
options.approval_delay is not None,
@@ -185,6 +187,8 @@
help="Set checker command for client")
parser.add_argument("-t", "--timeout",
help="Set timeout for client")
+ parser.add_argument("--extended-timeout",
+ help="Set extended timeout for client")
parser.add_argument("-i", "--interval",
help="Set checker interval for client")
parser.add_argument("--approve-by-default", action="store_true",
@@ -270,7 +274,8 @@
"LastEnabled", "ApprovalPending",
"ApprovedByDefault",
"LastApprovalRequest", "ApprovalDelay",
- "ApprovalDuration", "Checker")
+ "ApprovalDuration", "Checker",
+ "ExtendedTimeout")
else:
keywords = defaultkeywords
@@ -325,6 +330,11 @@
timedelta_to_milliseconds
(string_to_delta(options.timeout)),
dbus_interface=dbus.PROPERTIES_IFACE)
+ if options.extended_timeout:
+ client.Set(client_interface, "ExtendedTimeout",
+ timedelta_to_milliseconds
+ (string_to_delta(options.extended_timeout)),
+ dbus_interface=dbus.PROPERTIES_IFACE)
if options.secret:
client.Set(client_interface, "Secret",
dbus.ByteArray(open(options.secret,
=== modified file 'mandos-ctl.xml'
--- mandos-ctl.xml 2011-08-08 21:12:37 +0000
+++ mandos-ctl.xml 2011-09-18 14:28:47 +0000
@@ -95,6 +95,11 @@
+
+
+
+