172
except dbus.exceptions.DBusException as error:
171
except dbus.exceptions.DBusException, error:
173
172
logger.critical("DBusException: %s", error)
176
175
self.rename_count += 1
177
176
def remove(self):
178
177
"""Derived from the Avahi example code"""
179
if self.entry_group_state_changed_match is not None:
180
self.entry_group_state_changed_match.remove()
181
self.entry_group_state_changed_match = None
182
178
if self.group is not None:
183
179
self.group.Reset()
185
181
"""Derived from the Avahi example code"""
187
182
if self.group is None:
188
183
self.group = dbus.Interface(
189
184
self.bus.get_object(avahi.DBUS_NAME,
190
185
self.server.EntryGroupNew()),
191
186
avahi.DBUS_INTERFACE_ENTRY_GROUP)
192
self.entry_group_state_changed_match = (
193
self.group.connect_to_signal(
194
'StateChanged', self .entry_group_state_changed))
187
self.group.connect_to_signal('StateChanged',
189
.entry_group_state_changed)
195
190
logger.debug("Adding Zeroconf service '%s' of type '%s' ...",
196
191
self.name, self.type)
197
192
self.group.AddService(
220
215
def cleanup(self):
221
216
"""Derived from the Avahi example code"""
222
217
if self.group is not None:
225
except (dbus.exceptions.UnknownMethodException,
226
dbus.exceptions.DBusException) as e:
228
219
self.group = None
230
def server_state_changed(self, state, error=None):
220
def server_state_changed(self, state):
231
221
"""Derived from the Avahi example code"""
232
222
logger.debug("Avahi server state change: %i", state)
233
bad_states = { avahi.SERVER_INVALID:
234
"Zeroconf server invalid",
235
avahi.SERVER_REGISTERING: None,
236
avahi.SERVER_COLLISION:
237
"Zeroconf server name collision",
238
avahi.SERVER_FAILURE:
239
"Zeroconf server failure" }
240
if state in bad_states:
241
if bad_states[state] is not None:
243
logger.error(bad_states[state])
245
logger.error(bad_states[state] + ": %r", error)
223
if state == avahi.SERVER_COLLISION:
224
logger.error("Zeroconf server name collision")
247
226
elif state == avahi.SERVER_RUNNING:
251
logger.debug("Unknown state: %r", state)
253
logger.debug("Unknown state: %r: %r", state, error)
254
228
def activate(self):
255
229
"""Derived from the Avahi example code"""
256
230
if self.server is None:
257
231
self.server = dbus.Interface(
258
232
self.bus.get_object(avahi.DBUS_NAME,
259
avahi.DBUS_PATH_SERVER,
260
follow_name_owner_changes=True),
233
avahi.DBUS_PATH_SERVER),
261
234
avahi.DBUS_INTERFACE_SERVER)
262
235
self.server.connect_to_signal("StateChanged",
263
236
self.server_state_changed)
297
270
secret: bytestring; sent verbatim (over TLS) to client
298
271
timeout: datetime.timedelta(); How long from last_checked_ok
299
272
until this client is disabled
300
extended_timeout: extra long timeout when password has been sent
301
273
runtime_expansions: Allowed attributes for runtime expansion.
302
expires: datetime.datetime(); time (UTC) when a client will be
306
276
runtime_expansions = ("approval_delay", "approval_duration",
318
288
def timeout_milliseconds(self):
319
289
"Return the 'timeout' attribute in milliseconds"
320
290
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)
326
292
def interval_milliseconds(self):
327
293
"Return the 'interval' attribute in milliseconds"
361
327
self.last_enabled = None
362
328
self.last_checked_ok = None
363
329
self.timeout = string_to_delta(config["timeout"])
364
self.extended_timeout = string_to_delta(config["extended_timeout"])
365
330
self.interval = string_to_delta(config["interval"])
366
331
self.disable_hook = disable_hook
367
332
self.checker = None
368
333
self.checker_initiator_tag = None
369
334
self.disable_initiator_tag = None
371
335
self.checker_callback_tag = None
372
336
self.checker_command = config["checker"]
373
337
self.current_checker_command = None
400
364
(self.interval_milliseconds(),
401
365
self.start_checker))
402
366
# Schedule a disable() when 'timeout' has passed
403
self.expires = datetime.datetime.utcnow() + self.timeout
404
367
self.disable_initiator_tag = (gobject.timeout_add
405
368
(self.timeout_milliseconds(),
419
382
if getattr(self, "disable_initiator_tag", False):
420
383
gobject.source_remove(self.disable_initiator_tag)
421
384
self.disable_initiator_tag = None
423
385
if getattr(self, "checker_initiator_tag", False):
424
386
gobject.source_remove(self.checker_initiator_tag)
425
387
self.checker_initiator_tag = None
451
413
logger.warning("Checker for %(name)s crashed?",
454
def checked_ok(self, timeout=None):
416
def checked_ok(self):
455
417
"""Bump up the timeout for this client.
457
419
This should only be called when the client has been seen,
461
timeout = self.timeout
462
422
self.last_checked_ok = datetime.datetime.utcnow()
463
423
gobject.source_remove(self.disable_initiator_tag)
464
self.expires = datetime.datetime.utcnow() + timeout
465
424
self.disable_initiator_tag = (gobject.timeout_add
466
(self._timedelta_to_milliseconds(timeout),
425
(self.timeout_milliseconds(),
469
428
def need_approval(self):
486
445
# If a checker exists, make sure it is not a zombie
488
447
pid, status = os.waitpid(self.checker.pid, os.WNOHANG)
489
except (AttributeError, OSError) as error:
448
except (AttributeError, OSError), error:
490
449
if (isinstance(error, OSError)
491
450
and error.errno != errno.ECHILD):
515
474
command = self.checker_command % escaped_attrs
516
except TypeError as error:
475
except TypeError, error:
517
476
logger.error('Could not format string "%s":'
518
477
' %s', self.checker_command, error)
519
478
return True # Try again later
539
498
gobject.source_remove(self.checker_callback_tag)
540
499
self.checker_callback(pid, status, command)
541
except OSError as error:
500
except OSError, error:
542
501
logger.error("Failed to start subprocess: %s",
544
503
# Re-run this periodically if run by gobject.timeout_add
745
704
xmlstring = document.toxml("utf-8")
746
705
document.unlink()
747
706
except (AttributeError, xml.dom.DOMException,
748
xml.parsers.expat.ExpatError) as error:
707
xml.parsers.expat.ExpatError), error:
749
708
logger.error("Failed to override Introspection method",
777
736
("/clients/" + client_object_name))
778
737
DBusObjectWithProperties.__init__(self, self.bus,
779
738
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)
791
740
def _get_approvals_pending(self):
792
741
return self._approvals_pending
808
757
def _datetime_to_dbus(dt, variant_level=0):
809
758
"""Convert a UTC datetime.datetime() to a D-Bus type."""
811
return dbus.String("", variant_level = variant_level)
812
759
return dbus.String(dt.isoformat(),
813
760
variant_level=variant_level)
868
815
def checked_ok(self, *args, **kwargs):
869
Client.checked_ok(self, *args, **kwargs)
816
r = Client.checked_ok(self, *args, **kwargs)
870
817
# Emit D-Bus signal
871
818
self.PropertyChanged(
872
819
dbus.String("LastCheckedOK"),
873
820
(self._datetime_to_dbus(self.last_checked_ok,
874
821
variant_level=1)))
876
824
def need_approval(self, *args, **kwargs):
877
825
r = Client.need_approval(self, *args, **kwargs)
1012
960
def ApprovedByDefault_dbus_property(self, value=None):
1013
961
if value is None: # get
1014
962
return dbus.Boolean(self.approved_by_default)
1015
old_value = self.approved_by_default
1016
963
self.approved_by_default = bool(value)
1017
964
# Emit D-Bus signal
1018
if old_value != self.approved_by_default:
1019
self.PropertyChanged(dbus.String("ApprovedByDefault"),
1020
dbus.Boolean(value, variant_level=1))
965
self.PropertyChanged(dbus.String("ApprovedByDefault"),
966
dbus.Boolean(value, variant_level=1))
1022
968
# ApprovalDelay - property
1023
969
@dbus_service_property(_interface, signature="t",
1025
971
def ApprovalDelay_dbus_property(self, value=None):
1026
972
if value is None: # get
1027
973
return dbus.UInt64(self.approval_delay_milliseconds())
1028
old_value = self.approval_delay
1029
974
self.approval_delay = datetime.timedelta(0, 0, 0, value)
1030
975
# Emit D-Bus signal
1031
if old_value != self.approval_delay:
1032
self.PropertyChanged(dbus.String("ApprovalDelay"),
1033
dbus.UInt64(value, variant_level=1))
976
self.PropertyChanged(dbus.String("ApprovalDelay"),
977
dbus.UInt64(value, variant_level=1))
1035
979
# ApprovalDuration - property
1036
980
@dbus_service_property(_interface, signature="t",
1039
983
if value is None: # get
1040
984
return dbus.UInt64(self._timedelta_to_milliseconds(
1041
985
self.approval_duration))
1042
old_value = self.approval_duration
1043
986
self.approval_duration = datetime.timedelta(0, 0, 0, value)
1044
987
# Emit D-Bus signal
1045
if old_value != self.approval_duration:
1046
self.PropertyChanged(dbus.String("ApprovalDuration"),
1047
dbus.UInt64(value, variant_level=1))
988
self.PropertyChanged(dbus.String("ApprovalDuration"),
989
dbus.UInt64(value, variant_level=1))
1049
991
# Name - property
1050
992
@dbus_service_property(_interface, signature="s", access="read")
1062
1004
def Host_dbus_property(self, value=None):
1063
1005
if value is None: # get
1064
1006
return dbus.String(self.host)
1065
old_value = self.host
1066
1007
self.host = value
1067
1008
# Emit D-Bus signal
1068
if old_value != self.host:
1069
self.PropertyChanged(dbus.String("Host"),
1070
dbus.String(value, variant_level=1))
1009
self.PropertyChanged(dbus.String("Host"),
1010
dbus.String(value, variant_level=1))
1072
1012
# Created - property
1073
1013
@dbus_service_property(_interface, signature="s", access="read")
1077
1017
# LastEnabled - property
1078
1018
@dbus_service_property(_interface, signature="s", access="read")
1079
1019
def LastEnabled_dbus_property(self):
1080
return self._datetime_to_dbus(self.last_enabled)
1020
if self.last_enabled is None:
1021
return dbus.String("")
1022
return dbus.String(self._datetime_to_dbus(self.last_enabled))
1082
1024
# Enabled - property
1083
1025
@dbus_service_property(_interface, signature="b",
1097
1039
if value is not None:
1098
1040
self.checked_ok()
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)
1042
if self.last_checked_ok is None:
1043
return dbus.String("")
1044
return dbus.String(self._datetime_to_dbus(self
1107
1047
# LastApprovalRequest - property
1108
1048
@dbus_service_property(_interface, signature="s", access="read")
1109
1049
def LastApprovalRequest_dbus_property(self):
1110
return self._datetime_to_dbus(self.last_approval_request)
1050
if self.last_approval_request is None:
1051
return dbus.String("")
1052
return dbus.String(self.
1053
_datetime_to_dbus(self
1054
.last_approval_request))
1112
1056
# Timeout - property
1113
1057
@dbus_service_property(_interface, signature="t",
1115
1059
def Timeout_dbus_property(self, value=None):
1116
1060
if value is None: # get
1117
1061
return dbus.UInt64(self.timeout_milliseconds())
1118
old_value = self.timeout
1119
1062
self.timeout = datetime.timedelta(0, 0, 0, value)
1120
1063
# Emit D-Bus signal
1121
if old_value != self.timeout:
1122
self.PropertyChanged(dbus.String("Timeout"),
1123
dbus.UInt64(value, variant_level=1))
1064
self.PropertyChanged(dbus.String("Timeout"),
1065
dbus.UInt64(value, variant_level=1))
1124
1066
if getattr(self, "disable_initiator_tag", None) is None:
1126
1068
# Reschedule timeout
1127
1069
gobject.source_remove(self.disable_initiator_tag)
1128
1070
self.disable_initiator_tag = None
1130
1071
time_to_die = (self.
1131
1072
_timedelta_to_milliseconds((self
1132
1073
.last_checked_ok
1137
1078
# The timeout has passed
1140
self.expires = (datetime.datetime.utcnow()
1141
+ datetime.timedelta(milliseconds = time_to_die))
1142
1081
self.disable_initiator_tag = (gobject.timeout_add
1143
1082
(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))
1158
1084
# Interval - property
1159
1085
@dbus_service_property(_interface, signature="t",
1160
1086
access="readwrite")
1161
1087
def Interval_dbus_property(self, value=None):
1162
1088
if value is None: # get
1163
1089
return dbus.UInt64(self.interval_milliseconds())
1164
old_value = self.interval
1165
1090
self.interval = datetime.timedelta(0, 0, 0, value)
1166
1091
# Emit D-Bus signal
1167
if old_value != self.interval:
1168
self.PropertyChanged(dbus.String("Interval"),
1169
dbus.UInt64(value, variant_level=1))
1092
self.PropertyChanged(dbus.String("Interval"),
1093
dbus.UInt64(value, variant_level=1))
1170
1094
if getattr(self, "checker_initiator_tag", None) is None:
1172
1096
# Reschedule checker run
1181
1105
def Checker_dbus_property(self, value=None):
1182
1106
if value is None: # get
1183
1107
return dbus.String(self.checker_command)
1184
old_value = self.checker_command
1185
1108
self.checker_command = value
1186
1109
# Emit D-Bus signal
1187
if old_value != self.checker_command:
1188
self.PropertyChanged(dbus.String("Checker"),
1189
dbus.String(self.checker_command,
1110
self.PropertyChanged(dbus.String("Checker"),
1111
dbus.String(self.checker_command,
1192
1114
# CheckerRunning - property
1193
1115
@dbus_service_property(_interface, signature="b",
1283
1205
if int(line.strip().split()[0]) > 1:
1284
1206
raise RuntimeError
1285
except (ValueError, IndexError, RuntimeError) as error:
1207
except (ValueError, IndexError, RuntimeError), error:
1286
1208
logger.error("Unknown protocol version: %s", error)
1289
1211
# Start GnuTLS connection
1291
1213
session.handshake()
1292
except gnutls.errors.GNUTLSError as error:
1214
except gnutls.errors.GNUTLSError, error:
1293
1215
logger.warning("Handshake failed: %s", error)
1294
1216
# Do not run session.bye() here: the session is not
1295
1217
# established. Just abandon the request.
1302
1224
fpr = self.fingerprint(self.peer_certificate
1305
gnutls.errors.GNUTLSError) as error:
1226
except (TypeError, gnutls.errors.GNUTLSError), error:
1306
1227
logger.warning("Bad certificate: %s", error)
1308
1229
logger.debug("Fingerprint: %s", fpr)
1371
1292
while sent_size < len(client.secret):
1373
1294
sent = session.send(client.secret[sent_size:])
1374
except gnutls.errors.GNUTLSError as error:
1295
except (gnutls.errors.GNUTLSError), error:
1375
1296
logger.warning("gnutls send failed")
1377
1298
logger.debug("Sent: %d, remaining: %d",
1391
1312
client.approvals_pending -= 1
1394
except gnutls.errors.GNUTLSError as error:
1315
except (gnutls.errors.GNUTLSError), error:
1395
1316
logger.warning("GnuTLS bye failed")
1521
1442
SO_BINDTODEVICE,
1522
1443
str(self.interface
1524
except socket.error as error:
1445
except socket.error, error:
1525
1446
if error[0] == errno.EPERM:
1526
1447
logger.error("No permission to"
1527
1448
" bind to interface %s",
1624
logger.info("Client not found for fingerprint: %s, ad"
1625
"dress: %s", fpr, address)
1545
logger.warning("Client not found for fingerprint: %s, ad"
1546
"dress: %s", fpr, address)
1626
1547
if self.use_dbus:
1627
1548
# Emit D-Bus signal
1628
1549
mandos_dbus_service.ClientNotFound(fpr, address[0])
1692
1613
delta = datetime.timedelta(0, 0, 0, 0, 0, 0, value)
1694
1615
raise ValueError("Unknown suffix %r" % suffix)
1695
except (ValueError, IndexError) as e:
1616
except (ValueError, IndexError), e:
1696
1617
raise ValueError(*(e.args))
1697
1618
timevalue += delta
1698
1619
return timevalue
1848
1769
% server_settings["servicename"]))
1850
1771
# Parse config file with clients
1851
client_defaults = { "timeout": "5m",
1852
"extended_timeout": "15m",
1772
client_defaults = { "timeout": "1h",
1854
1774
"checker": "fping -q -- %%(host)s",
1856
1776
"approval_delay": "0s",
1947
1867
bus_name = dbus.service.BusName("se.bsnet.fukt.Mandos",
1948
1868
bus, do_not_queue=True)
1949
except dbus.exceptions.NameExistsException as e:
1869
except dbus.exceptions.NameExistsException, e:
1950
1870
logger.error(unicode(e) + ", disabling D-Bus")
1951
1871
use_dbus = False
1952
1872
server_settings["use_dbus"] = False
2102
2022
# From the Avahi example code
2104
2024
service.activate()
2105
except dbus.exceptions.DBusException as error:
2025
except dbus.exceptions.DBusException, error:
2106
2026
logger.critical("DBusException: %s", error)
2116
2036
logger.debug("Starting main loop")
2117
2037
main_loop.run()
2118
except AvahiError as error:
2038
except AvahiError, error:
2119
2039
logger.critical("AvahiError: %s", error)