=== modified file 'DBUS-API'
--- DBUS-API 2011-03-17 18:14:34 +0000
+++ DBUS-API 2011-09-18 14:28:47 +0000
@@ -86,15 +86,16 @@
| 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 |
| 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 +110,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
+ 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 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,
+ h) 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
+ i) 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.
+ 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 14:28:47 +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.
+ expire: 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 @@
+
+
+
+