240
235
"""A representation of a client host served by this server.
243
_approved: bool(); 'None' if not yet approved/disapproved
244
approval_delay: datetime.timedelta(); Time to wait for approval
245
approval_duration: datetime.timedelta(); Duration of one approval
238
name: string; from the config file, used in log messages and
240
fingerprint: string (40 or 32 hexadecimal digits); used to
241
uniquely identify the client
242
secret: bytestring; sent verbatim (over TLS) to client
243
host: string; available for use by the checker command
244
created: datetime.datetime(); (UTC) object creation
245
last_enabled: datetime.datetime(); (UTC)
247
last_checked_ok: datetime.datetime(); (UTC) or None
248
timeout: datetime.timedelta(); How long from last_checked_ok
249
until this client is disabled
250
interval: datetime.timedelta(); How often to start a new checker
251
disable_hook: If set, called by disable() as disable_hook(self)
246
252
checker: subprocess.Popen(); a running checker process used
247
253
to see if the client lives.
248
254
'None' if no process is running.
255
checker_initiator_tag: a gobject event source tag, or None
256
disable_initiator_tag: - '' -
249
257
checker_callback_tag: - '' -
250
checker_command: string; External command which is run to check
251
if client lives. %() expansions are done at
258
checker_command: string; External command which is run to check if
259
client lives. %() expansions are done at
252
260
runtime with vars(self) as dict, so that for
253
261
instance %(name)s can be used in the command.
254
checker_initiator_tag: a gobject event source tag, or None
255
created: datetime.datetime(); (UTC) object creation
256
262
current_checker_command: string; current running checker_command
257
disable_hook: If set, called by disable() as disable_hook(self)
258
disable_initiator_tag: - '' -
260
fingerprint: string (40 or 32 hexadecimal digits); used to
261
uniquely identify the client
262
host: string; available for use by the checker command
263
interval: datetime.timedelta(); How often to start a new checker
264
last_checked_ok: datetime.datetime(); (UTC) or None
265
last_enabled: datetime.datetime(); (UTC)
266
name: string; from the config file, used in log messages and
268
secret: bytestring; sent verbatim (over TLS) to client
269
timeout: datetime.timedelta(); How long from last_checked_ok
270
until this client is disabled
271
runtime_expansions: Allowed attributes for runtime expansion.
263
approved_delay: datetime.timedelta(); Time to wait for approval
264
_approved: bool(); 'None' if not yet approved/disapproved
265
approved_duration: datetime.timedelta(); Duration of one approval
274
runtime_expansions = (u"approval_delay", u"approval_duration",
275
u"created", u"enabled", u"fingerprint",
276
u"host", u"interval", u"last_checked_ok",
277
u"last_enabled", u"name", u"timeout")
280
269
def _timedelta_to_milliseconds(td):
281
270
"Convert a datetime.timedelta() to milliseconds"
333
323
self.checker_command = config[u"checker"]
334
324
self.current_checker_command = None
335
325
self.last_connect = None
326
self.approvals_pending = 0
336
327
self._approved = None
337
328
self.approved_by_default = config.get(u"approved_by_default",
339
self.approvals_pending = 0
340
self.approval_delay = string_to_delta(
341
config[u"approval_delay"])
342
self.approval_duration = string_to_delta(
343
config[u"approval_duration"])
330
self.approved_delay = string_to_delta(
331
config[u"approved_delay"])
332
self.approved_duration = string_to_delta(
333
config[u"approved_duration"])
344
334
self.changedstate = multiprocessing_manager.Condition(multiprocessing_manager.Lock())
346
336
def send_changedstate(self):
347
337
self.changedstate.acquire()
348
338
self.changedstate.notify_all()
711
699
dbus_object_path: dbus.ObjectPath
712
700
bus: dbus.SystemBus()
715
runtime_expansions = (Client.runtime_expansions
716
+ (u"dbus_object_path",))
718
702
# dbus.service.Object doesn't use super(), so we can't either.
720
704
def __init__(self, bus = None, *args, **kwargs):
721
self._approvals_pending = 0
723
706
Client.__init__(self, *args, **kwargs)
724
707
# Only now, when this client is initialized, can it show up on
726
client_object_name = unicode(self.name).translate(
727
{ord(u"."): ord(u"_"),
728
ord(u"-"): ord(u"_")})
729
709
self.dbus_object_path = (dbus.ObjectPath
730
(u"/clients/" + client_object_name))
711
+ self.name.replace(u".", u"_")))
731
712
DBusObjectWithProperties.__init__(self, self.bus,
732
713
self.dbus_object_path)
734
def _get_approvals_pending(self):
735
return self._approvals_pending
736
def _set_approvals_pending(self, value):
737
old_value = self._approvals_pending
738
self._approvals_pending = value
740
if (hasattr(self, "dbus_object_path")
741
and bval is not bool(old_value)):
742
dbus_bool = dbus.Boolean(bval, variant_level=1)
743
self.PropertyChanged(dbus.String(u"ApprovalPending"),
746
approvals_pending = property(_get_approvals_pending,
747
_set_approvals_pending)
748
del _get_approvals_pending, _set_approvals_pending
751
716
def _datetime_to_dbus(dt, variant_level=0):
879
844
# GotSecret - signal
880
845
@dbus.service.signal(_interface)
881
846
def GotSecret(self):
883
Is sent after a successful transfer of secret from the Mandos
884
server to mandos-client
848
if self.approved_pending():
849
self.PropertyChanged(dbus.String(u"checker_running"),
850
dbus.Boolean(False, variant_level=1))
888
852
# Rejected - signal
889
853
@dbus.service.signal(_interface, signature=u"s")
890
854
def Rejected(self, reason):
856
if self.approved_pending():
857
self.PropertyChanged(dbus.String(u"checker_running"),
858
dbus.Boolean(False, variant_level=1))
894
860
# NeedApproval - signal
895
@dbus.service.signal(_interface, signature=u"tb")
861
@dbus.service.signal(_interface, signature=u"db")
896
862
def NeedApproval(self, timeout, default):
864
if not self.approved_pending():
865
self.PropertyChanged(dbus.String(u"approved_pending"),
866
dbus.Boolean(True, variant_level=1))
937
# ApprovalPending - property
905
# approved_pending - property
938
906
@dbus_service_property(_interface, signature=u"b", access=u"read")
939
def ApprovalPending_dbus_property(self):
940
return dbus.Boolean(bool(self.approvals_pending))
907
def approved_pending_dbus_property(self):
908
return dbus.Boolean(self.approved_pending())
942
# ApprovedByDefault - property
910
# approved_by_default - property
943
911
@dbus_service_property(_interface, signature=u"b",
944
912
access=u"readwrite")
945
def ApprovedByDefault_dbus_property(self, value=None):
946
if value is None: # get
947
return dbus.Boolean(self.approved_by_default)
948
self.approved_by_default = bool(value)
950
self.PropertyChanged(dbus.String(u"ApprovedByDefault"),
951
dbus.Boolean(value, variant_level=1))
953
# ApprovalDelay - property
954
@dbus_service_property(_interface, signature=u"t",
956
def ApprovalDelay_dbus_property(self, value=None):
957
if value is None: # get
958
return dbus.UInt64(self.approval_delay_milliseconds())
959
self.approval_delay = datetime.timedelta(0, 0, 0, value)
961
self.PropertyChanged(dbus.String(u"ApprovalDelay"),
962
dbus.UInt64(value, variant_level=1))
964
# ApprovalDuration - property
965
@dbus_service_property(_interface, signature=u"t",
967
def ApprovalDuration_dbus_property(self, value=None):
968
if value is None: # get
969
return dbus.UInt64(self._timedelta_to_milliseconds(
970
self.approval_duration))
971
self.approval_duration = datetime.timedelta(0, 0, 0, value)
973
self.PropertyChanged(dbus.String(u"ApprovalDuration"),
974
dbus.UInt64(value, variant_level=1))
913
def approved_by_default_dbus_property(self):
914
return dbus.Boolean(self.approved_by_default)
916
# approved_delay - property
917
@dbus_service_property(_interface, signature=u"t",
919
def approved_delay_dbus_property(self):
920
return dbus.UInt64(self.approved_delay_milliseconds())
922
# approved_duration - property
923
@dbus_service_property(_interface, signature=u"t",
925
def approved_duration_dbus_property(self):
926
return dbus.UInt64(self._timedelta_to_milliseconds(
927
self.approved_duration))
977
930
@dbus_service_property(_interface, signature=u"s", access=u"read")
978
def Name_dbus_property(self):
931
def name_dbus_property(self):
979
932
return dbus.String(self.name)
981
# Fingerprint - property
934
# fingerprint - property
982
935
@dbus_service_property(_interface, signature=u"s", access=u"read")
983
def Fingerprint_dbus_property(self):
936
def fingerprint_dbus_property(self):
984
937
return dbus.String(self.fingerprint)
987
940
@dbus_service_property(_interface, signature=u"s",
988
941
access=u"readwrite")
989
def Host_dbus_property(self, value=None):
942
def host_dbus_property(self, value=None):
990
943
if value is None: # get
991
944
return dbus.String(self.host)
992
945
self.host = value
993
946
# Emit D-Bus signal
994
self.PropertyChanged(dbus.String(u"Host"),
947
self.PropertyChanged(dbus.String(u"host"),
995
948
dbus.String(value, variant_level=1))
998
951
@dbus_service_property(_interface, signature=u"s", access=u"read")
999
def Created_dbus_property(self):
952
def created_dbus_property(self):
1000
953
return dbus.String(self._datetime_to_dbus(self.created))
1002
# LastEnabled - property
955
# last_enabled - property
1003
956
@dbus_service_property(_interface, signature=u"s", access=u"read")
1004
def LastEnabled_dbus_property(self):
957
def last_enabled_dbus_property(self):
1005
958
if self.last_enabled is None:
1006
959
return dbus.String(u"")
1007
960
return dbus.String(self._datetime_to_dbus(self.last_enabled))
1009
# Enabled - property
1010
963
@dbus_service_property(_interface, signature=u"b",
1011
964
access=u"readwrite")
1012
def Enabled_dbus_property(self, value=None):
965
def enabled_dbus_property(self, value=None):
1013
966
if value is None: # get
1014
967
return dbus.Boolean(self.enabled)
1029
982
return dbus.String(self._datetime_to_dbus(self
1030
983
.last_checked_ok))
1032
# Timeout - property
1033
986
@dbus_service_property(_interface, signature=u"t",
1034
987
access=u"readwrite")
1035
def Timeout_dbus_property(self, value=None):
988
def timeout_dbus_property(self, value=None):
1036
989
if value is None: # get
1037
990
return dbus.UInt64(self.timeout_milliseconds())
1038
991
self.timeout = datetime.timedelta(0, 0, 0, value)
1039
992
# Emit D-Bus signal
1040
self.PropertyChanged(dbus.String(u"Timeout"),
993
self.PropertyChanged(dbus.String(u"timeout"),
1041
994
dbus.UInt64(value, variant_level=1))
1042
995
if getattr(self, u"disable_initiator_tag", None) is None:
1057
1010
self.disable_initiator_tag = (gobject.timeout_add
1058
1011
(time_to_die, self.disable))
1060
# Interval - property
1013
# interval - property
1061
1014
@dbus_service_property(_interface, signature=u"t",
1062
1015
access=u"readwrite")
1063
def Interval_dbus_property(self, value=None):
1016
def interval_dbus_property(self, value=None):
1064
1017
if value is None: # get
1065
1018
return dbus.UInt64(self.interval_milliseconds())
1066
1019
self.interval = datetime.timedelta(0, 0, 0, value)
1067
1020
# Emit D-Bus signal
1068
self.PropertyChanged(dbus.String(u"Interval"),
1021
self.PropertyChanged(dbus.String(u"interval"),
1069
1022
dbus.UInt64(value, variant_level=1))
1070
1023
if getattr(self, u"checker_initiator_tag", None) is None:
1075
1028
(value, self.start_checker))
1076
1029
self.start_checker() # Start one now, too
1078
# Checker - property
1031
# checker - property
1079
1032
@dbus_service_property(_interface, signature=u"s",
1080
1033
access=u"readwrite")
1081
def Checker_dbus_property(self, value=None):
1034
def checker_dbus_property(self, value=None):
1082
1035
if value is None: # get
1083
1036
return dbus.String(self.checker_command)
1084
1037
self.checker_command = value
1085
1038
# Emit D-Bus signal
1086
self.PropertyChanged(dbus.String(u"Checker"),
1039
self.PropertyChanged(dbus.String(u"checker"),
1087
1040
dbus.String(self.checker_command,
1088
1041
variant_level=1))
1090
# CheckerRunning - property
1043
# checker_running - property
1091
1044
@dbus_service_property(_interface, signature=u"b",
1092
1045
access=u"readwrite")
1093
def CheckerRunning_dbus_property(self, value=None):
1046
def checker_running_dbus_property(self, value=None):
1094
1047
if value is None: # get
1095
1048
return dbus.Boolean(self.checker is not None)
1224
1177
client.Rejected("Disabled")
1227
if client._approved or not client.approval_delay:
1180
if client._approved or not client.approved_delay:
1228
1181
#We are approved or approval is disabled
1230
1183
elif client._approved is None:
1231
logger.info(u"Client %s needs approval",
1184
logger.info(u"Client %s need approval",
1233
1186
if self.server.use_dbus:
1234
1187
# Emit D-Bus signal
1235
1188
client.NeedApproval(
1236
client.approval_delay_milliseconds(),
1189
client.approved_delay_milliseconds(),
1237
1190
client.approved_by_default)
1239
1192
logger.warning(u"Client %s was not approved",
1241
1194
if self.server.use_dbus:
1242
1195
# Emit D-Bus signal
1243
client.Rejected("Denied")
1196
client.Rejected("Disapproved")
1246
1199
#wait until timeout or approved
1759
1703
tcp_server = MandosServer((server_settings[u"address"],
1760
1704
server_settings[u"port"]),
1762
interface=(server_settings[u"interface"]
1706
interface=server_settings[u"interface"],
1764
1707
use_ipv6=use_ipv6,
1765
1708
gnutls_priority=
1766
1709
server_settings[u"priority"],
1767
1710
use_dbus=use_dbus)
1769
pidfilename = u"/var/run/mandos.pid"
1771
pidfile = open(pidfilename, u"w")
1773
logger.error(u"Could not open file %r", pidfilename)
1711
pidfilename = u"/var/run/mandos.pid"
1713
pidfile = open(pidfilename, u"w")
1715
logger.error(u"Could not open file %r", pidfilename)
1776
1718
uid = pwd.getpwnam(u"_mandos").pw_uid
1877
1793
for section in client_config.sections()))
1878
1794
if not tcp_server.clients:
1879
1795
logger.warning(u"No clients defined")
1798
# Redirect stdin so all checkers get /dev/null
1799
null = os.open(os.path.devnull, os.O_NOCTTY | os.O_RDWR)
1800
os.dup2(null, sys.stdin.fileno())
1804
# No console logging
1805
logger.removeHandler(console)
1806
# Close all input and output, do double fork, etc.
1812
pidfile.write(str(pid) + "\n")
1815
logger.error(u"Could not write to file %r with PID %d",
1818
# "pidfile" was never created
1885
pidfile.write(str(pid) + "\n")
1888
logger.error(u"Could not write to file %r with PID %d",
1891
# "pidfile" was never created
1895
1823
signal.signal(signal.SIGINT, signal.SIG_IGN)
1897
1824
signal.signal(signal.SIGHUP, lambda signum, frame: sys.exit())
1898
1825
signal.signal(signal.SIGTERM, lambda signum, frame: sys.exit())