230
289
if config is None:
232
291
logger.debug(u"Creating client %r", self.name)
233
self.use_dbus = False # During __init__
234
292
# Uppercase and remove spaces from fingerprint for later
235
293
# comparison purposes with return value from the fingerprint()
237
self.fingerprint = (config["fingerprint"].upper()
295
self.fingerprint = (config[u"fingerprint"].upper()
238
296
.replace(u" ", u""))
239
297
logger.debug(u" Fingerprint: %s", self.fingerprint)
240
if "secret" in config:
241
self.secret = config["secret"].decode(u"base64")
242
elif "secfile" in config:
243
with closing(open(os.path.expanduser
245
(config["secfile"])))) as secfile:
298
if u"secret" in config:
299
self.secret = config[u"secret"].decode(u"base64")
300
elif u"secfile" in config:
301
with open(os.path.expanduser(os.path.expandvars
302
(config[u"secfile"])),
246
304
self.secret = secfile.read()
306
#XXX Need to allow secret on demand!
248
307
raise TypeError(u"No secret or secfile for client %s"
250
self.host = config.get("host", "")
309
self.host = config.get(u"host", u"")
251
310
self.created = datetime.datetime.utcnow()
252
311
self.enabled = False
253
312
self.last_enabled = None
254
313
self.last_checked_ok = None
255
self.timeout = string_to_delta(config["timeout"])
256
self.interval = string_to_delta(config["interval"])
314
self.timeout = string_to_delta(config[u"timeout"])
315
self.interval = string_to_delta(config[u"interval"])
257
316
self.disable_hook = disable_hook
258
317
self.checker = None
259
318
self.checker_initiator_tag = None
260
319
self.disable_initiator_tag = None
261
320
self.checker_callback_tag = None
262
self.checker_command = config["checker"]
321
self.checker_command = config[u"checker"]
263
322
self.current_checker_command = None
264
323
self.last_connect = None
265
# Only now, when this client is initialized, can it show up on
267
self.use_dbus = use_dbus
269
self.dbus_object_path = (dbus.ObjectPath
271
+ self.name.replace(".", "_")))
272
dbus.service.Object.__init__(self, bus,
273
self.dbus_object_path)
324
self.approvals_pending = 0
325
self._approved = None
326
self.approved_by_default = config.get(u"approved_by_default",
328
self.approved_delay = string_to_delta(
329
config[u"approved_delay"])
330
self.approved_duration = string_to_delta(
331
config[u"approved_duration"])
332
self.changedstate = multiprocessing_manager.Condition(multiprocessing_manager.Lock())
334
def send_changedstate(self):
335
self.changedstate.acquire()
336
self.changedstate.notify_all()
337
self.changedstate.release()
275
339
def enable(self):
276
340
"""Start this client's checker and timeout hooks"""
341
if getattr(self, u"enabled", False):
344
self.send_changedstate()
277
345
self.last_enabled = datetime.datetime.utcnow()
278
346
# Schedule a new checker to be started an 'interval' from now,
279
347
# and every interval from then on.
280
348
self.checker_initiator_tag = (gobject.timeout_add
281
349
(self.interval_milliseconds(),
282
350
self.start_checker))
283
# Also start a new checker *right now*.
285
351
# Schedule a disable() when 'timeout' has passed
286
352
self.disable_initiator_tag = (gobject.timeout_add
287
353
(self.timeout_milliseconds(),
289
355
self.enabled = True
292
self.PropertyChanged(dbus.String(u"enabled"),
293
dbus.Boolean(True, variant_level=1))
294
self.PropertyChanged(dbus.String(u"last_enabled"),
295
(_datetime_to_dbus(self.last_enabled,
356
# Also start a new checker *right now*.
359
def disable(self, quiet=True):
299
360
"""Disable this client."""
300
361
if not getattr(self, "enabled", False):
302
logger.info(u"Disabling client %s", self.name)
303
if getattr(self, "disable_initiator_tag", False):
364
self.send_changedstate()
366
logger.info(u"Disabling client %s", self.name)
367
if getattr(self, u"disable_initiator_tag", False):
304
368
gobject.source_remove(self.disable_initiator_tag)
305
369
self.disable_initiator_tag = None
306
if getattr(self, "checker_initiator_tag", False):
370
if getattr(self, u"checker_initiator_tag", False):
307
371
gobject.source_remove(self.checker_initiator_tag)
308
372
self.checker_initiator_tag = None
309
373
self.stop_checker()
310
374
if self.disable_hook:
311
375
self.disable_hook(self)
312
376
self.enabled = False
315
self.PropertyChanged(dbus.String(u"enabled"),
316
dbus.Boolean(False, variant_level=1))
317
377
# Do not run this again if called by a gobject.timeout_add
444
488
if self.checker_callback_tag:
445
489
gobject.source_remove(self.checker_callback_tag)
446
490
self.checker_callback_tag = None
447
if getattr(self, "checker", None) is None:
491
if getattr(self, u"checker", None) is None:
449
493
logger.debug(u"Stopping checker for %(name)s", vars(self))
451
495
os.kill(self.checker.pid, signal.SIGTERM)
453
497
#if self.checker.poll() is None:
454
498
# os.kill(self.checker.pid, signal.SIGKILL)
455
499
except OSError, error:
456
500
if error.errno != errno.ESRCH: # No such process
458
502
self.checker = None
504
def dbus_service_property(dbus_interface, signature=u"v",
505
access=u"readwrite", byte_arrays=False):
506
"""Decorators for marking methods of a DBusObjectWithProperties to
507
become properties on the D-Bus.
509
The decorated method will be called with no arguments by "Get"
510
and with one argument by "Set".
512
The parameters, where they are supported, are the same as
513
dbus.service.method, except there is only "signature", since the
514
type from Get() and the type sent to Set() is the same.
516
# Encoding deeply encoded byte arrays is not supported yet by the
517
# "Set" method, so we fail early here:
518
if byte_arrays and signature != u"ay":
519
raise ValueError(u"Byte arrays not supported for non-'ay'"
520
u" signature %r" % signature)
522
func._dbus_is_property = True
523
func._dbus_interface = dbus_interface
524
func._dbus_signature = signature
525
func._dbus_access = access
526
func._dbus_name = func.__name__
527
if func._dbus_name.endswith(u"_dbus_property"):
528
func._dbus_name = func._dbus_name[:-14]
529
func._dbus_get_args_options = {u'byte_arrays': byte_arrays }
534
class DBusPropertyException(dbus.exceptions.DBusException):
535
"""A base class for D-Bus property-related exceptions
537
def __unicode__(self):
538
return unicode(str(self))
541
class DBusPropertyAccessException(DBusPropertyException):
542
"""A property's access permissions disallows an operation.
547
class DBusPropertyNotFound(DBusPropertyException):
548
"""An attempt was made to access a non-existing property.
553
class DBusObjectWithProperties(dbus.service.Object):
554
"""A D-Bus object with properties.
556
Classes inheriting from this can use the dbus_service_property
557
decorator to expose methods as D-Bus properties. It exposes the
558
standard Get(), Set(), and GetAll() methods on the D-Bus.
562
def _is_dbus_property(obj):
563
return getattr(obj, u"_dbus_is_property", False)
565
def _get_all_dbus_properties(self):
566
"""Returns a generator of (name, attribute) pairs
568
return ((prop._dbus_name, prop)
570
inspect.getmembers(self, self._is_dbus_property))
572
def _get_dbus_property(self, interface_name, property_name):
573
"""Returns a bound method if one exists which is a D-Bus
574
property with the specified name and interface.
576
for name in (property_name,
577
property_name + u"_dbus_property"):
578
prop = getattr(self, name, None)
580
or not self._is_dbus_property(prop)
581
or prop._dbus_name != property_name
582
or (interface_name and prop._dbus_interface
583
and interface_name != prop._dbus_interface)):
587
raise DBusPropertyNotFound(self.dbus_object_path + u":"
588
+ interface_name + u"."
591
@dbus.service.method(dbus.PROPERTIES_IFACE, in_signature=u"ss",
593
def Get(self, interface_name, property_name):
594
"""Standard D-Bus property Get() method, see D-Bus standard.
596
prop = self._get_dbus_property(interface_name, property_name)
597
if prop._dbus_access == u"write":
598
raise DBusPropertyAccessException(property_name)
600
if not hasattr(value, u"variant_level"):
602
return type(value)(value, variant_level=value.variant_level+1)
604
@dbus.service.method(dbus.PROPERTIES_IFACE, in_signature=u"ssv")
605
def Set(self, interface_name, property_name, value):
606
"""Standard D-Bus property Set() method, see D-Bus standard.
608
prop = self._get_dbus_property(interface_name, property_name)
609
if prop._dbus_access == u"read":
610
raise DBusPropertyAccessException(property_name)
611
if prop._dbus_get_args_options[u"byte_arrays"]:
612
# The byte_arrays option is not supported yet on
613
# signatures other than "ay".
614
if prop._dbus_signature != u"ay":
616
value = dbus.ByteArray(''.join(unichr(byte)
620
@dbus.service.method(dbus.PROPERTIES_IFACE, in_signature=u"s",
621
out_signature=u"a{sv}")
622
def GetAll(self, interface_name):
623
"""Standard D-Bus property GetAll() method, see D-Bus
626
Note: Will not include properties with access="write".
629
for name, prop in self._get_all_dbus_properties():
631
and interface_name != prop._dbus_interface):
632
# Interface non-empty but did not match
634
# Ignore write-only properties
635
if prop._dbus_access == u"write":
638
if not hasattr(value, u"variant_level"):
641
all[name] = type(value)(value, variant_level=
642
value.variant_level+1)
643
return dbus.Dictionary(all, signature=u"sv")
645
@dbus.service.method(dbus.INTROSPECTABLE_IFACE,
647
path_keyword='object_path',
648
connection_keyword='connection')
649
def Introspect(self, object_path, connection):
650
"""Standard D-Bus method, overloaded to insert property tags.
652
xmlstring = dbus.service.Object.Introspect(self, object_path,
655
document = xml.dom.minidom.parseString(xmlstring)
656
def make_tag(document, name, prop):
657
e = document.createElement(u"property")
658
e.setAttribute(u"name", name)
659
e.setAttribute(u"type", prop._dbus_signature)
660
e.setAttribute(u"access", prop._dbus_access)
662
for if_tag in document.getElementsByTagName(u"interface"):
663
for tag in (make_tag(document, name, prop)
665
in self._get_all_dbus_properties()
666
if prop._dbus_interface
667
== if_tag.getAttribute(u"name")):
668
if_tag.appendChild(tag)
669
# Add the names to the return values for the
670
# "org.freedesktop.DBus.Properties" methods
671
if (if_tag.getAttribute(u"name")
672
== u"org.freedesktop.DBus.Properties"):
673
for cn in if_tag.getElementsByTagName(u"method"):
674
if cn.getAttribute(u"name") == u"Get":
675
for arg in cn.getElementsByTagName(u"arg"):
676
if (arg.getAttribute(u"direction")
678
arg.setAttribute(u"name", u"value")
679
elif cn.getAttribute(u"name") == u"GetAll":
680
for arg in cn.getElementsByTagName(u"arg"):
681
if (arg.getAttribute(u"direction")
683
arg.setAttribute(u"name", u"props")
684
xmlstring = document.toxml(u"utf-8")
686
except (AttributeError, xml.dom.DOMException,
687
xml.parsers.expat.ExpatError), error:
688
logger.error(u"Failed to override Introspection method",
693
class ClientDBus(Client, DBusObjectWithProperties):
694
"""A Client class using D-Bus
697
dbus_object_path: dbus.ObjectPath
698
bus: dbus.SystemBus()
700
# dbus.service.Object doesn't use super(), so we can't either.
702
def __init__(self, bus = None, *args, **kwargs):
704
Client.__init__(self, *args, **kwargs)
705
# Only now, when this client is initialized, can it show up on
707
self.dbus_object_path = (dbus.ObjectPath
709
+ self.name.replace(u".", u"_")))
710
DBusObjectWithProperties.__init__(self, self.bus,
711
self.dbus_object_path)
714
def _datetime_to_dbus(dt, variant_level=0):
715
"""Convert a UTC datetime.datetime() to a D-Bus type."""
716
return dbus.String(dt.isoformat(),
717
variant_level=variant_level)
720
oldstate = getattr(self, u"enabled", False)
721
r = Client.enable(self)
722
if oldstate != self.enabled:
724
self.PropertyChanged(dbus.String(u"enabled"),
725
dbus.Boolean(True, variant_level=1))
726
self.PropertyChanged(
727
dbus.String(u"last_enabled"),
728
self._datetime_to_dbus(self.last_enabled,
732
def disable(self, quiet = False):
733
oldstate = getattr(self, u"enabled", False)
734
r = Client.disable(self, quiet=quiet)
735
if not quiet and oldstate != self.enabled:
737
self.PropertyChanged(dbus.String(u"enabled"),
738
dbus.Boolean(False, variant_level=1))
741
def __del__(self, *args, **kwargs):
743
self.remove_from_connection()
746
if hasattr(DBusObjectWithProperties, u"__del__"):
747
DBusObjectWithProperties.__del__(self, *args, **kwargs)
748
Client.__del__(self, *args, **kwargs)
750
def checker_callback(self, pid, condition, command,
752
self.checker_callback_tag = None
755
self.PropertyChanged(dbus.String(u"checker_running"),
756
dbus.Boolean(False, variant_level=1))
757
if os.WIFEXITED(condition):
758
exitstatus = os.WEXITSTATUS(condition)
760
self.CheckerCompleted(dbus.Int16(exitstatus),
761
dbus.Int64(condition),
762
dbus.String(command))
765
self.CheckerCompleted(dbus.Int16(-1),
766
dbus.Int64(condition),
767
dbus.String(command))
769
return Client.checker_callback(self, pid, condition, command,
772
def checked_ok(self, *args, **kwargs):
773
r = Client.checked_ok(self, *args, **kwargs)
775
self.PropertyChanged(
776
dbus.String(u"last_checked_ok"),
777
(self._datetime_to_dbus(self.last_checked_ok,
781
def start_checker(self, *args, **kwargs):
782
old_checker = self.checker
783
if self.checker is not None:
784
old_checker_pid = self.checker.pid
786
old_checker_pid = None
787
r = Client.start_checker(self, *args, **kwargs)
788
# Only if new checker process was started
789
if (self.checker is not None
790
and old_checker_pid != self.checker.pid):
792
self.CheckerStarted(self.current_checker_command)
793
self.PropertyChanged(
794
dbus.String(u"checker_running"),
795
dbus.Boolean(True, variant_level=1))
798
def stop_checker(self, *args, **kwargs):
799
old_checker = getattr(self, u"checker", None)
800
r = Client.stop_checker(self, *args, **kwargs)
801
if (old_checker is not None
802
and getattr(self, u"checker", None) is None):
460
803
self.PropertyChanged(dbus.String(u"checker_running"),
461
804
dbus.Boolean(False, variant_level=1))
463
def still_valid(self):
464
"""Has the timeout not yet passed for this client?"""
465
if not getattr(self, "enabled", False):
467
now = datetime.datetime.utcnow()
468
if self.last_checked_ok is None:
469
return now < (self.created + self.timeout)
471
return now < (self.last_checked_ok + self.timeout)
473
## D-Bus methods & signals
807
def _reset_approved(self):
808
self._approved = None
811
def approve(self, value=True):
812
self._approved = value
813
gobject.timeout_add(self._timedelta_to_milliseconds(self.approved_duration, self._reset_approved))
815
def approved_pending(self):
816
return self.approvals_pending > 0
819
## D-Bus methods, signals & properties
474
820
_interface = u"se.bsnet.fukt.Mandos.Client"
477
CheckedOK = dbus.service.method(_interface)(checked_ok)
478
CheckedOK.__name__ = "CheckedOK"
480
824
# CheckerCompleted - signal
481
@dbus.service.signal(_interface, signature="nxs")
825
@dbus.service.signal(_interface, signature=u"nxs")
482
826
def CheckerCompleted(self, exitcode, waitstatus, command):
486
830
# CheckerStarted - signal
487
@dbus.service.signal(_interface, signature="s")
831
@dbus.service.signal(_interface, signature=u"s")
488
832
def CheckerStarted(self, command):
492
# GetAllProperties - method
493
@dbus.service.method(_interface, out_signature="a{sv}")
494
def GetAllProperties(self):
496
return dbus.Dictionary({
498
dbus.String(self.name, variant_level=1),
499
dbus.String("fingerprint"):
500
dbus.String(self.fingerprint, variant_level=1),
502
dbus.String(self.host, variant_level=1),
503
dbus.String("created"):
504
_datetime_to_dbus(self.created, variant_level=1),
505
dbus.String("last_enabled"):
506
(_datetime_to_dbus(self.last_enabled,
508
if self.last_enabled is not None
509
else dbus.Boolean(False, variant_level=1)),
510
dbus.String("enabled"):
511
dbus.Boolean(self.enabled, variant_level=1),
512
dbus.String("last_checked_ok"):
513
(_datetime_to_dbus(self.last_checked_ok,
515
if self.last_checked_ok is not None
516
else dbus.Boolean (False, variant_level=1)),
517
dbus.String("timeout"):
518
dbus.UInt64(self.timeout_milliseconds(),
520
dbus.String("interval"):
521
dbus.UInt64(self.interval_milliseconds(),
523
dbus.String("checker"):
524
dbus.String(self.checker_command,
526
dbus.String("checker_running"):
527
dbus.Boolean(self.checker is not None,
529
dbus.String("object_path"):
530
dbus.ObjectPath(self.dbus_object_path,
534
# IsStillValid - method
535
IsStillValid = (dbus.service.method(_interface, out_signature="b")
537
IsStillValid.__name__ = "IsStillValid"
539
836
# PropertyChanged - signal
540
@dbus.service.signal(_interface, signature="sv")
837
@dbus.service.signal(_interface, signature=u"sv")
541
838
def PropertyChanged(self, property, value):
545
# SetChecker - method
546
@dbus.service.method(_interface, in_signature="s")
547
def SetChecker(self, checker):
548
"D-Bus setter method"
549
self.checker_command = checker
551
self.PropertyChanged(dbus.String(u"checker"),
552
dbus.String(self.checker_command,
556
@dbus.service.method(_interface, in_signature="s")
557
def SetHost(self, host):
558
"D-Bus setter method"
561
self.PropertyChanged(dbus.String(u"host"),
562
dbus.String(self.host, variant_level=1))
564
# SetInterval - method
565
@dbus.service.method(_interface, in_signature="t")
566
def SetInterval(self, milliseconds):
567
self.interval = datetime.timedelta(0, 0, 0, milliseconds)
569
self.PropertyChanged(dbus.String(u"interval"),
570
(dbus.UInt64(self.interval_milliseconds(),
574
@dbus.service.method(_interface, in_signature="ay",
576
def SetSecret(self, secret):
577
"D-Bus setter method"
578
self.secret = str(secret)
580
# SetTimeout - method
581
@dbus.service.method(_interface, in_signature="t")
582
def SetTimeout(self, milliseconds):
583
self.timeout = datetime.timedelta(0, 0, 0, milliseconds)
585
self.PropertyChanged(dbus.String(u"timeout"),
586
(dbus.UInt64(self.timeout_milliseconds(),
843
# Is sent after succesfull transfer of secret from mandos-server to mandos-client
844
@dbus.service.signal(_interface)
850
@dbus.service.signal(_interface, signature=u"s")
851
def Rejected(self, reason):
855
# NeedApproval - signal
856
@dbus.service.signal(_interface, signature=u"db")
857
def NeedApproval(self, timeout, default):
864
@dbus.service.method(_interface, in_signature=u"b")
865
def Approve(self, value):
869
@dbus.service.method(_interface)
871
return self.checked_ok()
589
873
# Enable - method
590
Enable = dbus.service.method(_interface)(enable)
591
Enable.__name__ = "Enable"
874
@dbus.service.method(_interface)
593
879
# StartChecker - method
594
880
@dbus.service.method(_interface)
605
891
# StopChecker - method
606
StopChecker = dbus.service.method(_interface)(stop_checker)
607
StopChecker.__name__ = "StopChecker"
892
@dbus.service.method(_interface)
893
def StopChecker(self):
898
# approved_pending - property
899
@dbus_service_property(_interface, signature=u"b", access=u"read")
900
def approved_pending_dbus_property(self):
901
return dbus.Boolean(self.approved_pending())
903
# approved_by_default - property
904
@dbus_service_property(_interface, signature=u"b",
906
def approved_by_default_dbus_property(self):
907
return dbus.Boolean(self.approved_by_default)
909
# approved_delay - property
910
@dbus_service_property(_interface, signature=u"t",
912
def approved_delay_dbus_property(self):
913
return dbus.UInt64(self.approved_delay_milliseconds())
915
# approved_duration - property
916
@dbus_service_property(_interface, signature=u"t",
918
def approved_duration_dbus_property(self):
919
return dbus.UInt64(self._timedelta_to_milliseconds(
920
self.approved_duration))
923
@dbus_service_property(_interface, signature=u"s", access=u"read")
924
def name_dbus_property(self):
925
return dbus.String(self.name)
927
# fingerprint - property
928
@dbus_service_property(_interface, signature=u"s", access=u"read")
929
def fingerprint_dbus_property(self):
930
return dbus.String(self.fingerprint)
933
@dbus_service_property(_interface, signature=u"s",
935
def host_dbus_property(self, value=None):
936
if value is None: # get
937
return dbus.String(self.host)
940
self.PropertyChanged(dbus.String(u"host"),
941
dbus.String(value, variant_level=1))
944
@dbus_service_property(_interface, signature=u"s", access=u"read")
945
def created_dbus_property(self):
946
return dbus.String(self._datetime_to_dbus(self.created))
948
# last_enabled - property
949
@dbus_service_property(_interface, signature=u"s", access=u"read")
950
def last_enabled_dbus_property(self):
951
if self.last_enabled is None:
952
return dbus.String(u"")
953
return dbus.String(self._datetime_to_dbus(self.last_enabled))
956
@dbus_service_property(_interface, signature=u"b",
958
def enabled_dbus_property(self, value=None):
959
if value is None: # get
960
return dbus.Boolean(self.enabled)
966
# last_checked_ok - property
967
@dbus_service_property(_interface, signature=u"s",
969
def last_checked_ok_dbus_property(self, value=None):
970
if value is not None:
973
if self.last_checked_ok is None:
974
return dbus.String(u"")
975
return dbus.String(self._datetime_to_dbus(self
979
@dbus_service_property(_interface, signature=u"t",
981
def timeout_dbus_property(self, value=None):
982
if value is None: # get
983
return dbus.UInt64(self.timeout_milliseconds())
984
self.timeout = datetime.timedelta(0, 0, 0, value)
986
self.PropertyChanged(dbus.String(u"timeout"),
987
dbus.UInt64(value, variant_level=1))
988
if getattr(self, u"disable_initiator_tag", None) is None:
991
gobject.source_remove(self.disable_initiator_tag)
992
self.disable_initiator_tag = None
994
_timedelta_to_milliseconds((self
1000
# The timeout has passed
1003
self.disable_initiator_tag = (gobject.timeout_add
1004
(time_to_die, self.disable))
1006
# interval - property
1007
@dbus_service_property(_interface, signature=u"t",
1008
access=u"readwrite")
1009
def interval_dbus_property(self, value=None):
1010
if value is None: # get
1011
return dbus.UInt64(self.interval_milliseconds())
1012
self.interval = datetime.timedelta(0, 0, 0, value)
1014
self.PropertyChanged(dbus.String(u"interval"),
1015
dbus.UInt64(value, variant_level=1))
1016
if getattr(self, u"checker_initiator_tag", None) is None:
1018
# Reschedule checker run
1019
gobject.source_remove(self.checker_initiator_tag)
1020
self.checker_initiator_tag = (gobject.timeout_add
1021
(value, self.start_checker))
1022
self.start_checker() # Start one now, too
1024
# checker - property
1025
@dbus_service_property(_interface, signature=u"s",
1026
access=u"readwrite")
1027
def checker_dbus_property(self, value=None):
1028
if value is None: # get
1029
return dbus.String(self.checker_command)
1030
self.checker_command = value
1032
self.PropertyChanged(dbus.String(u"checker"),
1033
dbus.String(self.checker_command,
1036
# checker_running - property
1037
@dbus_service_property(_interface, signature=u"b",
1038
access=u"readwrite")
1039
def checker_running_dbus_property(self, value=None):
1040
if value is None: # get
1041
return dbus.Boolean(self.checker is not None)
1043
self.start_checker()
1047
# object_path - property
1048
@dbus_service_property(_interface, signature=u"o", access=u"read")
1049
def object_path_dbus_property(self):
1050
return self.dbus_object_path # is already a dbus.ObjectPath
1053
@dbus_service_property(_interface, signature=u"ay",
1054
access=u"write", byte_arrays=True)
1055
def secret_dbus_property(self, value):
1056
self.secret = str(value)
612
def peer_certificate(session):
613
"Return the peer's OpenPGP certificate as a bytestring"
614
# If not an OpenPGP certificate...
615
if (gnutls.library.functions
616
.gnutls_certificate_type_get(session._c_object)
617
!= gnutls.library.constants.GNUTLS_CRT_OPENPGP):
618
# ...do the normal thing
619
return session.peer_certificate
620
list_size = ctypes.c_uint(1)
621
cert_list = (gnutls.library.functions
622
.gnutls_certificate_get_peers
623
(session._c_object, ctypes.byref(list_size)))
624
if not bool(cert_list) and list_size.value != 0:
625
raise gnutls.errors.GNUTLSError("error getting peer"
627
if list_size.value == 0:
630
return ctypes.string_at(cert.data, cert.size)
633
def fingerprint(openpgp):
634
"Convert an OpenPGP bytestring to a hexdigit fingerprint string"
635
# New GnuTLS "datum" with the OpenPGP public key
636
datum = (gnutls.library.types
637
.gnutls_datum_t(ctypes.cast(ctypes.c_char_p(openpgp),
640
ctypes.c_uint(len(openpgp))))
641
# New empty GnuTLS certificate
642
crt = gnutls.library.types.gnutls_openpgp_crt_t()
643
(gnutls.library.functions
644
.gnutls_openpgp_crt_init(ctypes.byref(crt)))
645
# Import the OpenPGP public key into the certificate
646
(gnutls.library.functions
647
.gnutls_openpgp_crt_import(crt, ctypes.byref(datum),
648
gnutls.library.constants
649
.GNUTLS_OPENPGP_FMT_RAW))
650
# Verify the self signature in the key
651
crtverify = ctypes.c_uint()
652
(gnutls.library.functions
653
.gnutls_openpgp_crt_verify_self(crt, 0, ctypes.byref(crtverify)))
654
if crtverify.value != 0:
655
gnutls.library.functions.gnutls_openpgp_crt_deinit(crt)
656
raise gnutls.errors.CertificateSecurityError("Verify failed")
657
# New buffer for the fingerprint
658
buf = ctypes.create_string_buffer(20)
659
buf_len = ctypes.c_size_t()
660
# Get the fingerprint from the certificate into the buffer
661
(gnutls.library.functions
662
.gnutls_openpgp_crt_get_fingerprint(crt, ctypes.byref(buf),
663
ctypes.byref(buf_len)))
664
# Deinit the certificate
665
gnutls.library.functions.gnutls_openpgp_crt_deinit(crt)
666
# Convert the buffer to a Python bytestring
667
fpr = ctypes.string_at(buf, buf_len.value)
668
# Convert the bytestring to hexadecimal notation
669
hex_fpr = u''.join(u"%02X" % ord(char) for char in fpr)
673
class TCP_handler(SocketServer.BaseRequestHandler, object):
674
"""A TCP request handler class.
675
Instantiated by IPv6_TCPServer for each request to handle it.
1061
class ProxyClient(object):
1062
def __init__(self, child_pipe, fpr, address):
1063
self._pipe = child_pipe
1064
self._pipe.send(('init', fpr, address))
1065
if not self._pipe.recv():
1068
def __getattribute__(self, name):
1069
if(name == '_pipe'):
1070
return super(ProxyClient, self).__getattribute__(name)
1071
self._pipe.send(('getattr', name))
1072
data = self._pipe.recv()
1073
if data[0] == 'data':
1075
if data[0] == 'function':
1076
def func(*args, **kwargs):
1077
self._pipe.send(('funcall', name, args, kwargs))
1078
return self._pipe.recv()[1]
1081
def __setattr__(self, name, value):
1082
if(name == '_pipe'):
1083
return super(ProxyClient, self).__setattr__(name, value)
1084
self._pipe.send(('setattr', name, value))
1087
class ClientHandler(socketserver.BaseRequestHandler, object):
1088
"""A class to handle client connections.
1090
Instantiated once for each connection to handle it.
676
1091
Note: This will run in its own forked process."""
678
1093
def handle(self):
679
logger.info(u"TCP connection from: %s",
680
unicode(self.client_address))
681
session = (gnutls.connection
682
.ClientSession(self.request,
686
line = self.request.makefile().readline()
687
logger.debug(u"Protocol version: %r", line)
689
if int(line.strip().split()[0]) > 1:
691
except (ValueError, IndexError, RuntimeError), error:
692
logger.error(u"Unknown protocol version: %s", error)
695
# Note: gnutls.connection.X509Credentials is really a generic
696
# GnuTLS certificate credentials object so long as no X.509
697
# keys are added to it. Therefore, we can use it here despite
698
# using OpenPGP certificates.
700
#priority = ':'.join(("NONE", "+VERS-TLS1.1", "+AES-256-CBC",
701
# "+SHA1", "+COMP-NULL", "+CTYPE-OPENPGP",
703
# Use a fallback default, since this MUST be set.
704
priority = self.server.settings.get("priority", "NORMAL")
705
(gnutls.library.functions
706
.gnutls_priority_set_direct(session._c_object,
711
except gnutls.errors.GNUTLSError, error:
712
logger.warning(u"Handshake failed: %s", error)
713
# Do not run session.bye() here: the session is not
714
# established. Just abandon the request.
716
logger.debug(u"Handshake succeeded")
718
fpr = fingerprint(peer_certificate(session))
719
except (TypeError, gnutls.errors.GNUTLSError), error:
720
logger.warning(u"Bad certificate: %s", error)
723
logger.debug(u"Fingerprint: %s", fpr)
725
for c in self.server.clients:
726
if c.fingerprint == fpr:
730
logger.warning(u"Client not found for fingerprint: %s",
734
# Have to check if client.still_valid(), since it is possible
735
# that the client timed out while establishing the GnuTLS
737
if not client.still_valid():
738
logger.warning(u"Client %(name)s is invalid",
742
## This won't work here, since we're in a fork.
743
# client.checked_ok()
745
while sent_size < len(client.secret):
746
sent = session.send(client.secret[sent_size:])
747
logger.debug(u"Sent: %d, remaining: %d",
748
sent, len(client.secret)
749
- (sent_size + sent))
754
class IPv6_TCPServer(SocketServer.ForkingMixIn,
755
SocketServer.TCPServer, object):
1094
with contextlib.closing(self.server.child_pipe) as child_pipe:
1095
logger.info(u"TCP connection from: %s",
1096
unicode(self.client_address))
1097
logger.debug(u"Pipe FD: %d",
1098
self.server.child_pipe.fileno())
1100
session = (gnutls.connection
1101
.ClientSession(self.request,
1103
.X509Credentials()))
1105
# Note: gnutls.connection.X509Credentials is really a
1106
# generic GnuTLS certificate credentials object so long as
1107
# no X.509 keys are added to it. Therefore, we can use it
1108
# here despite using OpenPGP certificates.
1110
#priority = u':'.join((u"NONE", u"+VERS-TLS1.1",
1111
# u"+AES-256-CBC", u"+SHA1",
1112
# u"+COMP-NULL", u"+CTYPE-OPENPGP",
1114
# Use a fallback default, since this MUST be set.
1115
priority = self.server.gnutls_priority
1116
if priority is None:
1117
priority = u"NORMAL"
1118
(gnutls.library.functions
1119
.gnutls_priority_set_direct(session._c_object,
1122
# Start communication using the Mandos protocol
1123
# Get protocol number
1124
line = self.request.makefile().readline()
1125
logger.debug(u"Protocol version: %r", line)
1127
if int(line.strip().split()[0]) > 1:
1129
except (ValueError, IndexError, RuntimeError), error:
1130
logger.error(u"Unknown protocol version: %s", error)
1133
# Start GnuTLS connection
1136
except gnutls.errors.GNUTLSError, error:
1137
logger.warning(u"Handshake failed: %s", error)
1138
# Do not run session.bye() here: the session is not
1139
# established. Just abandon the request.
1141
logger.debug(u"Handshake succeeded")
1143
approval_required = False
1146
fpr = self.fingerprint(self.peer_certificate
1148
except (TypeError, gnutls.errors.GNUTLSError), error:
1149
logger.warning(u"Bad certificate: %s", error)
1151
logger.debug(u"Fingerprint: %s", fpr)
1154
client = ProxyClient(child_pipe, fpr,
1155
self.client_address)
1159
if client.approved_delay:
1160
delay = client.approved_delay
1161
client.approvals_pending += 1
1162
approval_required = True
1165
if not client.enabled:
1166
logger.warning(u"Client %s is disabled",
1168
if self.server.use_dbus:
1170
client.Rejected("Disabled")
1173
if client._approved or not client.approved_delay:
1174
#We are approved or approval is disabled
1176
elif client._approved is None:
1177
logger.info(u"Client %s need approval",
1179
if self.server.use_dbus:
1181
client.NeedApproval(
1182
client.approved_delay_milliseconds(),
1183
client.approved_by_default)
1185
logger.warning(u"Client %s was not approved",
1187
if self.server.use_dbus:
1189
client.Rejected("Disapproved")
1192
#wait until timeout or approved
1193
#x = float(client._timedelta_to_milliseconds(delay))
1194
time = datetime.datetime.now()
1195
client.changedstate.acquire()
1196
client.changedstate.wait(float(client._timedelta_to_milliseconds(delay) / 1000))
1197
client.changedstate.release()
1198
time2 = datetime.datetime.now()
1199
if (time2 - time) >= delay:
1200
if not client.approved_by_default:
1201
logger.warning("Client %s timed out while"
1202
" waiting for approval",
1204
if self.server.use_dbus:
1206
client.Rejected("Time out")
1211
delay -= time2 - time
1214
while sent_size < len(client.secret):
1215
# XXX handle session exception
1216
sent = session.send(client.secret[sent_size:])
1217
logger.debug(u"Sent: %d, remaining: %d",
1218
sent, len(client.secret)
1219
- (sent_size + sent))
1222
logger.info(u"Sending secret to %s", client.name)
1223
# bump the timeout as if seen
1225
if self.server.use_dbus:
1230
if approval_required:
1231
client.approvals_pending -= 1
1235
def peer_certificate(session):
1236
"Return the peer's OpenPGP certificate as a bytestring"
1237
# If not an OpenPGP certificate...
1238
if (gnutls.library.functions
1239
.gnutls_certificate_type_get(session._c_object)
1240
!= gnutls.library.constants.GNUTLS_CRT_OPENPGP):
1241
# ...do the normal thing
1242
return session.peer_certificate
1243
list_size = ctypes.c_uint(1)
1244
cert_list = (gnutls.library.functions
1245
.gnutls_certificate_get_peers
1246
(session._c_object, ctypes.byref(list_size)))
1247
if not bool(cert_list) and list_size.value != 0:
1248
raise gnutls.errors.GNUTLSError(u"error getting peer"
1250
if list_size.value == 0:
1253
return ctypes.string_at(cert.data, cert.size)
1256
def fingerprint(openpgp):
1257
"Convert an OpenPGP bytestring to a hexdigit fingerprint"
1258
# New GnuTLS "datum" with the OpenPGP public key
1259
datum = (gnutls.library.types
1260
.gnutls_datum_t(ctypes.cast(ctypes.c_char_p(openpgp),
1263
ctypes.c_uint(len(openpgp))))
1264
# New empty GnuTLS certificate
1265
crt = gnutls.library.types.gnutls_openpgp_crt_t()
1266
(gnutls.library.functions
1267
.gnutls_openpgp_crt_init(ctypes.byref(crt)))
1268
# Import the OpenPGP public key into the certificate
1269
(gnutls.library.functions
1270
.gnutls_openpgp_crt_import(crt, ctypes.byref(datum),
1271
gnutls.library.constants
1272
.GNUTLS_OPENPGP_FMT_RAW))
1273
# Verify the self signature in the key
1274
crtverify = ctypes.c_uint()
1275
(gnutls.library.functions
1276
.gnutls_openpgp_crt_verify_self(crt, 0,
1277
ctypes.byref(crtverify)))
1278
if crtverify.value != 0:
1279
gnutls.library.functions.gnutls_openpgp_crt_deinit(crt)
1280
raise (gnutls.errors.CertificateSecurityError
1282
# New buffer for the fingerprint
1283
buf = ctypes.create_string_buffer(20)
1284
buf_len = ctypes.c_size_t()
1285
# Get the fingerprint from the certificate into the buffer
1286
(gnutls.library.functions
1287
.gnutls_openpgp_crt_get_fingerprint(crt, ctypes.byref(buf),
1288
ctypes.byref(buf_len)))
1289
# Deinit the certificate
1290
gnutls.library.functions.gnutls_openpgp_crt_deinit(crt)
1291
# Convert the buffer to a Python bytestring
1292
fpr = ctypes.string_at(buf, buf_len.value)
1293
# Convert the bytestring to hexadecimal notation
1294
hex_fpr = u''.join(u"%02X" % ord(char) for char in fpr)
1298
class MultiprocessingMixIn(object):
1299
"""Like socketserver.ThreadingMixIn, but with multiprocessing"""
1300
def sub_process_main(self, request, address):
1302
self.finish_request(request, address)
1304
self.handle_error(request, address)
1305
self.close_request(request)
1307
def process_request(self, request, address):
1308
"""Start a new process to process the request."""
1309
multiprocessing.Process(target = self.sub_process_main,
1310
args = (request, address)).start()
1312
class MultiprocessingMixInWithPipe(MultiprocessingMixIn, object):
1313
""" adds a pipe to the MixIn """
1314
def process_request(self, request, client_address):
1315
"""Overrides and wraps the original process_request().
1317
This function creates a new pipe in self.pipe
1319
parent_pipe, self.child_pipe = multiprocessing.Pipe()
1321
super(MultiprocessingMixInWithPipe,
1322
self).process_request(request, client_address)
1323
self.child_pipe.close()
1324
self.add_pipe(parent_pipe)
1326
def add_pipe(self, parent_pipe):
1327
"""Dummy function; override as necessary"""
1330
class IPv6_TCPServer(MultiprocessingMixInWithPipe,
1331
socketserver.TCPServer, object):
756
1332
"""IPv6-capable TCP server. Accepts 'None' as address and/or port
758
settings: Server settings
759
clients: Set() of Client objects
760
1335
enabled: Boolean; whether this server is activated yet
1336
interface: None or a network interface name (string)
1337
use_ipv6: Boolean; to use IPv6 or not
762
address_family = socket.AF_INET6
763
def __init__(self, *args, **kwargs):
764
if "settings" in kwargs:
765
self.settings = kwargs["settings"]
766
del kwargs["settings"]
767
if "clients" in kwargs:
768
self.clients = kwargs["clients"]
769
del kwargs["clients"]
770
if "use_ipv6" in kwargs:
771
if not kwargs["use_ipv6"]:
772
self.address_family = socket.AF_INET
773
del kwargs["use_ipv6"]
775
super(IPv6_TCPServer, self).__init__(*args, **kwargs)
1339
def __init__(self, server_address, RequestHandlerClass,
1340
interface=None, use_ipv6=True):
1341
self.interface = interface
1343
self.address_family = socket.AF_INET6
1344
socketserver.TCPServer.__init__(self, server_address,
1345
RequestHandlerClass)
776
1346
def server_bind(self):
777
1347
"""This overrides the normal server_bind() function
778
1348
to bind to an interface if one was specified, and also NOT to
779
1349
bind to an address or port if they were not specified."""
780
if self.settings["interface"]:
781
# 25 is from /usr/include/asm-i486/socket.h
782
SO_BINDTODEVICE = getattr(socket, "SO_BINDTODEVICE", 25)
784
self.socket.setsockopt(socket.SOL_SOCKET,
786
self.settings["interface"])
787
except socket.error, error:
788
if error[0] == errno.EPERM:
789
logger.error(u"No permission to"
790
u" bind to interface %s",
791
self.settings["interface"])
1350
if self.interface is not None:
1351
if SO_BINDTODEVICE is None:
1352
logger.error(u"SO_BINDTODEVICE does not exist;"
1353
u" cannot bind to interface %s",
1357
self.socket.setsockopt(socket.SOL_SOCKET,
1361
except socket.error, error:
1362
if error[0] == errno.EPERM:
1363
logger.error(u"No permission to"
1364
u" bind to interface %s",
1366
elif error[0] == errno.ENOPROTOOPT:
1367
logger.error(u"SO_BINDTODEVICE not available;"
1368
u" cannot bind to interface %s",
794
1372
# Only bind(2) the socket if we really need to.
795
1373
if self.server_address[0] or self.server_address[1]:
796
1374
if not self.server_address[0]:
797
1375
if self.address_family == socket.AF_INET6:
798
any_address = "::" # in6addr_any
1376
any_address = u"::" # in6addr_any
800
1378
any_address = socket.INADDR_ANY
801
1379
self.server_address = (any_address,
803
1381
elif not self.server_address[1]:
804
1382
self.server_address = (self.server_address[0],
806
# if self.settings["interface"]:
1384
# if self.interface:
807
1385
# self.server_address = (self.server_address[0],
810
1388
# if_nametoindex
813
return super(IPv6_TCPServer, self).server_bind()
1390
return socketserver.TCPServer.server_bind(self)
1393
class MandosServer(IPv6_TCPServer):
1397
clients: set of Client objects
1398
gnutls_priority GnuTLS priority string
1399
use_dbus: Boolean; to emit D-Bus signals or not
1401
Assumes a gobject.MainLoop event loop.
1403
def __init__(self, server_address, RequestHandlerClass,
1404
interface=None, use_ipv6=True, clients=None,
1405
gnutls_priority=None, use_dbus=True):
1406
self.enabled = False
1407
self.clients = clients
1408
if self.clients is None:
1409
self.clients = set()
1410
self.use_dbus = use_dbus
1411
self.gnutls_priority = gnutls_priority
1412
IPv6_TCPServer.__init__(self, server_address,
1413
RequestHandlerClass,
1414
interface = interface,
1415
use_ipv6 = use_ipv6)
814
1416
def server_activate(self):
815
1417
if self.enabled:
816
return super(IPv6_TCPServer, self).server_activate()
1418
return socketserver.TCPServer.server_activate(self)
817
1419
def enable(self):
818
1420
self.enabled = True
1421
def add_pipe(self, parent_pipe):
1422
# Call "handle_ipc" for both data and EOF events
1423
gobject.io_add_watch(parent_pipe.fileno(),
1424
gobject.IO_IN | gobject.IO_HUP,
1425
functools.partial(self.handle_ipc,
1426
parent_pipe = parent_pipe))
1428
def handle_ipc(self, source, condition, parent_pipe=None,
1429
client_object=None):
1431
gobject.IO_IN: u"IN", # There is data to read.
1432
gobject.IO_OUT: u"OUT", # Data can be written (without
1434
gobject.IO_PRI: u"PRI", # There is urgent data to read.
1435
gobject.IO_ERR: u"ERR", # Error condition.
1436
gobject.IO_HUP: u"HUP" # Hung up (the connection has been
1437
# broken, usually for pipes and
1440
conditions_string = ' | '.join(name
1442
condition_names.iteritems()
1443
if cond & condition)
1444
logger.debug(u"Handling IPC: FD = %d, condition = %s", source,
1447
# error or the other end of multiprocessing.Pipe has closed
1448
if condition & gobject.IO_HUP or condition & gobject.IO_ERR:
1451
# Read a request from the child
1452
request = parent_pipe.recv()
1453
logger.debug(u"IPC request: %s", repr(request))
1454
command = request[0]
1456
if command == 'init':
1458
address = request[2]
1460
for c in self.clients:
1461
if c.fingerprint == fpr:
1465
logger.warning(u"Client not found for fingerprint: %s, ad"
1466
u"dress: %s", fpr, address)
1469
mandos_dbus_service.ClientNotFound(fpr, address)
1470
parent_pipe.send(False)
1473
gobject.io_add_watch(parent_pipe.fileno(),
1474
gobject.IO_IN | gobject.IO_HUP,
1475
functools.partial(self.handle_ipc,
1476
parent_pipe = parent_pipe,
1477
client_object = client))
1478
parent_pipe.send(True)
1479
# remove the old hook in favor of the new above hook on same fileno
1481
if command == 'funcall':
1482
funcname = request[1]
1486
parent_pipe.send(('data', getattr(client_object, funcname)(*args, **kwargs)))
1488
if command == 'getattr':
1489
attrname = request[1]
1490
if callable(client_object.__getattribute__(attrname)):
1491
parent_pipe.send(('function',))
1493
parent_pipe.send(('data', client_object.__getattribute__(attrname)))
1495
if command == 'setattr':
1496
attrname = request[1]
1498
setattr(client_object, attrname, value)
821
1503
def string_to_delta(interval):
822
1504
"""Parse a string and return a datetime.timedelta
824
>>> string_to_delta('7d')
1506
>>> string_to_delta(u'7d')
825
1507
datetime.timedelta(7)
826
>>> string_to_delta('60s')
1508
>>> string_to_delta(u'60s')
827
1509
datetime.timedelta(0, 60)
828
>>> string_to_delta('60m')
1510
>>> string_to_delta(u'60m')
829
1511
datetime.timedelta(0, 3600)
830
>>> string_to_delta('24h')
1512
>>> string_to_delta(u'24h')
831
1513
datetime.timedelta(1)
832
1514
>>> string_to_delta(u'1w')
833
1515
datetime.timedelta(7)
834
>>> string_to_delta('5m 30s')
1516
>>> string_to_delta(u'5m 30s')
835
1517
datetime.timedelta(0, 330)
837
1519
timevalue = datetime.timedelta(0)
962
1628
# Default values for config file for server-global settings
963
server_defaults = { "interface": "",
968
"SECURE256:!CTYPE-X.509:+CTYPE-OPENPGP",
969
"servicename": "Mandos",
1629
server_defaults = { u"interface": u"",
1634
u"SECURE256:!CTYPE-X.509:+CTYPE-OPENPGP",
1635
u"servicename": u"Mandos",
1636
u"use_dbus": u"True",
1637
u"use_ipv6": u"True",
974
1640
# Parse config file for server-global settings
975
server_config = ConfigParser.SafeConfigParser(server_defaults)
1641
server_config = configparser.SafeConfigParser(server_defaults)
976
1642
del server_defaults
977
server_config.read(os.path.join(options.configdir, "mandos.conf"))
1643
server_config.read(os.path.join(options.configdir,
978
1645
# Convert the SafeConfigParser object to a dict
979
1646
server_settings = server_config.defaults()
980
1647
# Use the appropriate methods on the non-string config options
981
server_settings["debug"] = server_config.getboolean("DEFAULT",
983
server_settings["use_dbus"] = server_config.getboolean("DEFAULT",
985
server_settings["use_ipv6"] = server_config.getboolean("DEFAULT",
1648
for option in (u"debug", u"use_dbus", u"use_ipv6"):
1649
server_settings[option] = server_config.getboolean(u"DEFAULT",
987
1651
if server_settings["port"]:
988
server_settings["port"] = server_config.getint("DEFAULT",
1652
server_settings["port"] = server_config.getint(u"DEFAULT",
990
1654
del server_config
992
1656
# Override the settings from the config file with command line
993
1657
# options, if set.
994
for option in ("interface", "address", "port", "debug",
995
"priority", "servicename", "configdir",
996
"use_dbus", "use_ipv6"):
1658
for option in (u"interface", u"address", u"port", u"debug",
1659
u"priority", u"servicename", u"configdir",
1660
u"use_dbus", u"use_ipv6"):
997
1661
value = getattr(options, option)
998
1662
if value is not None:
999
1663
server_settings[option] = value
1665
# Force all strings to be unicode
1666
for option in server_settings.keys():
1667
if type(server_settings[option]) is str:
1668
server_settings[option] = unicode(server_settings[option])
1001
1669
# Now we have our good server settings in "server_settings"
1671
##################################################################
1003
1673
# For convenience
1004
debug = server_settings["debug"]
1005
use_dbus = server_settings["use_dbus"]
1006
use_dbus = False # XXX: Not done yet
1007
use_ipv6 = server_settings["use_ipv6"]
1674
debug = server_settings[u"debug"]
1675
use_dbus = server_settings[u"use_dbus"]
1676
use_ipv6 = server_settings[u"use_ipv6"]
1010
1679
syslogger.setLevel(logging.WARNING)
1011
1680
console.setLevel(logging.WARNING)
1013
if server_settings["servicename"] != "Mandos":
1682
if server_settings[u"servicename"] != u"Mandos":
1014
1683
syslogger.setFormatter(logging.Formatter
1015
('Mandos (%s): %%(levelname)s:'
1017
% server_settings["servicename"]))
1684
(u'Mandos (%s) [%%(process)d]:'
1685
u' %%(levelname)s: %%(message)s'
1686
% server_settings[u"servicename"]))
1019
1688
# Parse config file with clients
1020
client_defaults = { "timeout": "1h",
1022
"checker": "fping -q -- %%(host)s",
1689
client_defaults = { u"timeout": u"1h",
1691
u"checker": u"fping -q -- %%(host)s",
1693
u"approved_delay": u"5m",
1694
u"approved_duration": u"1s",
1025
client_config = ConfigParser.SafeConfigParser(client_defaults)
1026
client_config.read(os.path.join(server_settings["configdir"],
1030
tcp_server = IPv6_TCPServer((server_settings["address"],
1031
server_settings["port"]),
1033
settings=server_settings,
1034
clients=clients, use_ipv6=use_ipv6)
1035
pidfilename = "/var/run/mandos.pid"
1696
client_config = configparser.SafeConfigParser(client_defaults)
1697
client_config.read(os.path.join(server_settings[u"configdir"],
1700
global mandos_dbus_service
1701
mandos_dbus_service = None
1703
tcp_server = MandosServer((server_settings[u"address"],
1704
server_settings[u"port"]),
1706
interface=server_settings[u"interface"],
1709
server_settings[u"priority"],
1711
pidfilename = u"/var/run/mandos.pid"
1037
pidfile = open(pidfilename, "w")
1713
pidfile = open(pidfilename, u"w")
1038
1714
except IOError:
1039
logger.error("Could not open file %r", pidfilename)
1715
logger.error(u"Could not open file %r", pidfilename)
1042
uid = pwd.getpwnam("_mandos").pw_uid
1043
gid = pwd.getpwnam("_mandos").pw_gid
1718
uid = pwd.getpwnam(u"_mandos").pw_uid
1719
gid = pwd.getpwnam(u"_mandos").pw_gid
1044
1720
except KeyError:
1046
uid = pwd.getpwnam("mandos").pw_uid
1047
gid = pwd.getpwnam("mandos").pw_gid
1722
uid = pwd.getpwnam(u"mandos").pw_uid
1723
gid = pwd.getpwnam(u"mandos").pw_gid
1048
1724
except KeyError:
1050
uid = pwd.getpwnam("nobody").pw_uid
1051
gid = pwd.getpwnam("nogroup").pw_gid
1726
uid = pwd.getpwnam(u"nobody").pw_uid
1727
gid = pwd.getpwnam(u"nobody").pw_gid
1052
1728
except KeyError: