297
297
secret: bytestring; sent verbatim (over TLS) to client
298
298
timeout: datetime.timedelta(); How long from last_checked_ok
299
299
until this client is disabled
300
extended_timeout: extra long timeout when password has been sent
300
301
runtime_expansions: Allowed attributes for runtime expansion.
302
expire: datetime.datetime(); time (UTC) when a client will be
303
306
runtime_expansions = ("approval_delay", "approval_duration",
315
318
def timeout_milliseconds(self):
316
319
"Return the 'timeout' attribute in milliseconds"
317
320
return self._timedelta_to_milliseconds(self.timeout)
322
def extended_timeout_milliseconds(self):
323
"Return the 'extended_timeout' attribute in milliseconds"
324
return self._timedelta_to_milliseconds(self.extended_timeout)
319
326
def interval_milliseconds(self):
320
327
"Return the 'interval' attribute in milliseconds"
354
361
self.last_enabled = None
355
362
self.last_checked_ok = None
356
363
self.timeout = string_to_delta(config["timeout"])
364
self.extended_timeout = string_to_delta(config["extended_timeout"])
357
365
self.interval = string_to_delta(config["interval"])
358
366
self.disable_hook = disable_hook
359
367
self.checker = None
360
368
self.checker_initiator_tag = None
361
369
self.disable_initiator_tag = None
362
371
self.checker_callback_tag = None
363
372
self.checker_command = config["checker"]
364
373
self.current_checker_command = None
391
400
(self.interval_milliseconds(),
392
401
self.start_checker))
393
402
# Schedule a disable() when 'timeout' has passed
403
self.expires = datetime.datetime.utcnow() + self.timeout
394
404
self.disable_initiator_tag = (gobject.timeout_add
395
405
(self.timeout_milliseconds(),
409
419
if getattr(self, "disable_initiator_tag", False):
410
420
gobject.source_remove(self.disable_initiator_tag)
411
421
self.disable_initiator_tag = None
412
423
if getattr(self, "checker_initiator_tag", False):
413
424
gobject.source_remove(self.checker_initiator_tag)
414
425
self.checker_initiator_tag = None
440
451
logger.warning("Checker for %(name)s crashed?",
443
def checked_ok(self):
454
def checked_ok(self, timeout=None):
444
455
"""Bump up the timeout for this client.
446
457
This should only be called when the client has been seen,
461
timeout = self.timeout
449
462
self.last_checked_ok = datetime.datetime.utcnow()
450
463
gobject.source_remove(self.disable_initiator_tag)
464
self.expires = datetime.datetime.utcnow() + timeout
451
465
self.disable_initiator_tag = (gobject.timeout_add
452
(self.timeout_milliseconds(),
466
(self._timedelta_to_milliseconds(timeout),
455
469
def need_approval(self):
763
777
("/clients/" + client_object_name))
764
778
DBusObjectWithProperties.__init__(self, self.bus,
765
779
self.dbus_object_path)
780
def _set_expires(self, value):
781
old_value = getattr(self, "_expires", None)
782
self._expires = value
783
if hasattr(self, "dbus_object_path") and old_value != value:
784
dbus_time = (self._datetime_to_dbus(self._expires,
786
self.PropertyChanged(dbus.String("Expires"),
788
expires = property(lambda self: self._expires, _set_expires)
767
791
def _get_approvals_pending(self):
768
792
return self._approvals_pending
784
808
def _datetime_to_dbus(dt, variant_level=0):
785
809
"""Convert a UTC datetime.datetime() to a D-Bus type."""
811
return dbus.String("", variant_level = variant_level)
786
812
return dbus.String(dt.isoformat(),
787
813
variant_level=variant_level)
986
1012
def ApprovedByDefault_dbus_property(self, value=None):
987
1013
if value is None: # get
988
1014
return dbus.Boolean(self.approved_by_default)
1015
old_value = self.approved_by_default
989
1016
self.approved_by_default = bool(value)
990
1017
# Emit D-Bus signal
991
self.PropertyChanged(dbus.String("ApprovedByDefault"),
992
dbus.Boolean(value, variant_level=1))
1018
if old_value != self.approved_by_default:
1019
self.PropertyChanged(dbus.String("ApprovedByDefault"),
1020
dbus.Boolean(value, variant_level=1))
994
1022
# ApprovalDelay - property
995
1023
@dbus_service_property(_interface, signature="t",
997
1025
def ApprovalDelay_dbus_property(self, value=None):
998
1026
if value is None: # get
999
1027
return dbus.UInt64(self.approval_delay_milliseconds())
1028
old_value = self.approval_delay
1000
1029
self.approval_delay = datetime.timedelta(0, 0, 0, value)
1001
1030
# Emit D-Bus signal
1002
self.PropertyChanged(dbus.String("ApprovalDelay"),
1003
dbus.UInt64(value, variant_level=1))
1031
if old_value != self.approval_delay:
1032
self.PropertyChanged(dbus.String("ApprovalDelay"),
1033
dbus.UInt64(value, variant_level=1))
1005
1035
# ApprovalDuration - property
1006
1036
@dbus_service_property(_interface, signature="t",
1009
1039
if value is None: # get
1010
1040
return dbus.UInt64(self._timedelta_to_milliseconds(
1011
1041
self.approval_duration))
1042
old_value = self.approval_duration
1012
1043
self.approval_duration = datetime.timedelta(0, 0, 0, value)
1013
1044
# Emit D-Bus signal
1014
self.PropertyChanged(dbus.String("ApprovalDuration"),
1015
dbus.UInt64(value, variant_level=1))
1045
if old_value != self.approval_duration:
1046
self.PropertyChanged(dbus.String("ApprovalDuration"),
1047
dbus.UInt64(value, variant_level=1))
1017
1049
# Name - property
1018
1050
@dbus_service_property(_interface, signature="s", access="read")
1030
1062
def Host_dbus_property(self, value=None):
1031
1063
if value is None: # get
1032
1064
return dbus.String(self.host)
1065
old_value = self.host
1033
1066
self.host = value
1034
1067
# Emit D-Bus signal
1035
self.PropertyChanged(dbus.String("Host"),
1036
dbus.String(value, variant_level=1))
1068
if old_value != self.host:
1069
self.PropertyChanged(dbus.String("Host"),
1070
dbus.String(value, variant_level=1))
1038
1072
# Created - property
1039
1073
@dbus_service_property(_interface, signature="s", access="read")
1043
1077
# LastEnabled - property
1044
1078
@dbus_service_property(_interface, signature="s", access="read")
1045
1079
def LastEnabled_dbus_property(self):
1046
if self.last_enabled is None:
1047
return dbus.String("")
1048
return dbus.String(self._datetime_to_dbus(self.last_enabled))
1080
return self._datetime_to_dbus(self.last_enabled)
1050
1082
# Enabled - property
1051
1083
@dbus_service_property(_interface, signature="b",
1065
1097
if value is not None:
1066
1098
self.checked_ok()
1068
if self.last_checked_ok is None:
1069
return dbus.String("")
1070
return dbus.String(self._datetime_to_dbus(self
1100
return self._datetime_to_dbus(self.last_checked_ok)
1102
# Expires - property
1103
@dbus_service_property(_interface, signature="s", access="read")
1104
def Expires_dbus_property(self):
1105
return self._datetime_to_dbus(self.expires)
1073
1107
# LastApprovalRequest - property
1074
1108
@dbus_service_property(_interface, signature="s", access="read")
1075
1109
def LastApprovalRequest_dbus_property(self):
1076
if self.last_approval_request is None:
1077
return dbus.String("")
1078
return dbus.String(self.
1079
_datetime_to_dbus(self
1080
.last_approval_request))
1110
return self._datetime_to_dbus(self.last_approval_request)
1082
1112
# Timeout - property
1083
1113
@dbus_service_property(_interface, signature="t",
1085
1115
def Timeout_dbus_property(self, value=None):
1086
1116
if value is None: # get
1087
1117
return dbus.UInt64(self.timeout_milliseconds())
1118
old_value = self.timeout
1088
1119
self.timeout = datetime.timedelta(0, 0, 0, value)
1089
1120
# Emit D-Bus signal
1090
self.PropertyChanged(dbus.String("Timeout"),
1091
dbus.UInt64(value, variant_level=1))
1121
if old_value != self.timeout:
1122
self.PropertyChanged(dbus.String("Timeout"),
1123
dbus.UInt64(value, variant_level=1))
1092
1124
if getattr(self, "disable_initiator_tag", None) is None:
1094
1126
# Reschedule timeout
1095
1127
gobject.source_remove(self.disable_initiator_tag)
1096
1128
self.disable_initiator_tag = None
1097
1130
time_to_die = (self.
1098
1131
_timedelta_to_milliseconds((self
1099
1132
.last_checked_ok
1104
1137
# The timeout has passed
1140
self.expires = (datetime.datetime.utcnow()
1141
+ datetime.timedelta(milliseconds = time_to_die))
1107
1142
self.disable_initiator_tag = (gobject.timeout_add
1108
1143
(time_to_die, self.disable))
1145
# ExtendedTimeout - property
1146
@dbus_service_property(_interface, signature="t",
1148
def ExtendedTimeout_dbus_property(self, value=None):
1149
if value is None: # get
1150
return dbus.UInt64(self.extended_timeout_milliseconds())
1151
old_value = self.extended_timeout
1152
self.extended_timeout = datetime.timedelta(0, 0, 0, value)
1154
if old_value != self.extended_timeout:
1155
self.PropertyChanged(dbus.String("ExtendedTimeout"),
1156
dbus.UInt64(value, variant_level=1))
1110
1158
# Interval - property
1111
1159
@dbus_service_property(_interface, signature="t",
1112
1160
access="readwrite")
1113
1161
def Interval_dbus_property(self, value=None):
1114
1162
if value is None: # get
1115
1163
return dbus.UInt64(self.interval_milliseconds())
1164
old_value = self.interval
1116
1165
self.interval = datetime.timedelta(0, 0, 0, value)
1117
1166
# Emit D-Bus signal
1118
self.PropertyChanged(dbus.String("Interval"),
1119
dbus.UInt64(value, variant_level=1))
1167
if old_value != self.interval:
1168
self.PropertyChanged(dbus.String("Interval"),
1169
dbus.UInt64(value, variant_level=1))
1120
1170
if getattr(self, "checker_initiator_tag", None) is None:
1122
1172
# Reschedule checker run
1131
1181
def Checker_dbus_property(self, value=None):
1132
1182
if value is None: # get
1133
1183
return dbus.String(self.checker_command)
1184
old_value = self.checker_command
1134
1185
self.checker_command = value
1135
1186
# Emit D-Bus signal
1136
self.PropertyChanged(dbus.String("Checker"),
1137
dbus.String(self.checker_command,
1187
if old_value != self.checker_command:
1188
self.PropertyChanged(dbus.String("Checker"),
1189
dbus.String(self.checker_command,
1140
1192
# CheckerRunning - property
1141
1193
@dbus_service_property(_interface, signature="b",
1796
1848
% server_settings["servicename"]))
1798
1850
# Parse config file with clients
1799
client_defaults = { "timeout": "1h",
1851
client_defaults = { "timeout": "5m",
1852
"extended_timeout": "15m",
1801
1854
"checker": "fping -q -- %%(host)s",
1803
1856
"approval_delay": "0s",