465
434
if error.errno != errno.ESRCH: # No such process
467
436
self.checker = None
438
self.PropertyChanged(dbus.String(u"checker_running"),
439
dbus.Boolean(False, variant_level=1))
469
441
def still_valid(self):
470
442
"""Has the timeout not yet passed for this client?"""
471
if not getattr(self, u"enabled", False):
443
if not getattr(self, "enabled", False):
473
445
now = datetime.datetime.utcnow()
474
446
if self.last_checked_ok is None:
475
447
return now < (self.created + self.timeout)
477
449
return now < (self.last_checked_ok + self.timeout)
480
class ClientDBus(Client, dbus.service.Object):
481
"""A Client class using D-Bus
484
dbus_object_path: dbus.ObjectPath
485
bus: dbus.SystemBus()
487
# dbus.service.Object doesn't use super(), so we can't either.
489
def __init__(self, bus = None, *args, **kwargs):
491
Client.__init__(self, *args, **kwargs)
492
# Only now, when this client is initialized, can it show up on
494
self.dbus_object_path = (dbus.ObjectPath
496
+ self.name.replace(u".", u"_")))
497
dbus.service.Object.__init__(self, self.bus,
498
self.dbus_object_path)
501
def _datetime_to_dbus(dt, variant_level=0):
502
"""Convert a UTC datetime.datetime() to a D-Bus type."""
503
return dbus.String(dt.isoformat(),
504
variant_level=variant_level)
507
oldstate = getattr(self, u"enabled", False)
508
r = Client.enable(self)
509
if oldstate != self.enabled:
511
self.PropertyChanged(dbus.String(u"enabled"),
512
dbus.Boolean(True, variant_level=1))
513
self.PropertyChanged(
514
dbus.String(u"last_enabled"),
515
self._datetime_to_dbus(self.last_enabled,
519
def disable(self, signal = True):
520
oldstate = getattr(self, u"enabled", False)
521
r = Client.disable(self)
522
if signal and oldstate != self.enabled:
524
self.PropertyChanged(dbus.String(u"enabled"),
525
dbus.Boolean(False, variant_level=1))
528
def __del__(self, *args, **kwargs):
530
self.remove_from_connection()
533
if hasattr(dbus.service.Object, u"__del__"):
534
dbus.service.Object.__del__(self, *args, **kwargs)
535
Client.__del__(self, *args, **kwargs)
537
def checker_callback(self, pid, condition, command,
539
self.checker_callback_tag = None
542
self.PropertyChanged(dbus.String(u"checker_running"),
543
dbus.Boolean(False, variant_level=1))
544
if os.WIFEXITED(condition):
545
exitstatus = os.WEXITSTATUS(condition)
547
self.CheckerCompleted(dbus.Int16(exitstatus),
548
dbus.Int64(condition),
549
dbus.String(command))
552
self.CheckerCompleted(dbus.Int16(-1),
553
dbus.Int64(condition),
554
dbus.String(command))
556
return Client.checker_callback(self, pid, condition, command,
559
def checked_ok(self, *args, **kwargs):
560
r = Client.checked_ok(self, *args, **kwargs)
562
self.PropertyChanged(
563
dbus.String(u"last_checked_ok"),
564
(self._datetime_to_dbus(self.last_checked_ok,
568
def start_checker(self, *args, **kwargs):
569
old_checker = self.checker
570
if self.checker is not None:
571
old_checker_pid = self.checker.pid
573
old_checker_pid = None
574
r = Client.start_checker(self, *args, **kwargs)
575
# Only if new checker process was started
576
if (self.checker is not None
577
and old_checker_pid != self.checker.pid):
579
self.CheckerStarted(self.current_checker_command)
580
self.PropertyChanged(
581
dbus.String(u"checker_running"),
582
dbus.Boolean(True, variant_level=1))
585
def stop_checker(self, *args, **kwargs):
586
old_checker = getattr(self, u"checker", None)
587
r = Client.stop_checker(self, *args, **kwargs)
588
if (old_checker is not None
589
and getattr(self, u"checker", None) is None):
590
self.PropertyChanged(dbus.String(u"checker_running"),
591
dbus.Boolean(False, variant_level=1))
594
451
## D-Bus methods & signals
595
452
_interface = u"se.bsnet.fukt.Mandos.Client"
597
454
# CheckedOK - method
598
@dbus.service.method(_interface)
600
return self.checked_ok()
455
CheckedOK = dbus.service.method(_interface)(checked_ok)
456
CheckedOK.__name__ = "CheckedOK"
602
458
# CheckerCompleted - signal
603
@dbus.service.signal(_interface, signature=u"nxs")
459
@dbus.service.signal(_interface, signature="nxs")
604
460
def CheckerCompleted(self, exitcode, waitstatus, command):
608
464
# CheckerStarted - signal
609
@dbus.service.signal(_interface, signature=u"s")
465
@dbus.service.signal(_interface, signature="s")
610
466
def CheckerStarted(self, command):
614
470
# GetAllProperties - method
615
@dbus.service.method(_interface, out_signature=u"a{sv}")
471
@dbus.service.method(_interface, out_signature="a{sv}")
616
472
def GetAllProperties(self):
618
474
return dbus.Dictionary({
619
dbus.String(u"name"):
620
476
dbus.String(self.name, variant_level=1),
621
dbus.String(u"fingerprint"):
477
dbus.String("fingerprint"):
622
478
dbus.String(self.fingerprint, variant_level=1),
623
dbus.String(u"host"):
624
480
dbus.String(self.host, variant_level=1),
625
dbus.String(u"created"):
626
self._datetime_to_dbus(self.created,
628
dbus.String(u"last_enabled"):
629
(self._datetime_to_dbus(self.last_enabled,
481
dbus.String("created"):
482
_datetime_to_dbus(self.created, variant_level=1),
483
dbus.String("last_enabled"):
484
(_datetime_to_dbus(self.last_enabled,
631
486
if self.last_enabled is not None
632
487
else dbus.Boolean(False, variant_level=1)),
633
dbus.String(u"enabled"):
488
dbus.String("enabled"):
634
489
dbus.Boolean(self.enabled, variant_level=1),
635
dbus.String(u"last_checked_ok"):
636
(self._datetime_to_dbus(self.last_checked_ok,
490
dbus.String("last_checked_ok"):
491
(_datetime_to_dbus(self.last_checked_ok,
638
493
if self.last_checked_ok is not None
639
494
else dbus.Boolean (False, variant_level=1)),
640
dbus.String(u"timeout"):
495
dbus.String("timeout"):
641
496
dbus.UInt64(self.timeout_milliseconds(),
642
497
variant_level=1),
643
dbus.String(u"interval"):
498
dbus.String("interval"):
644
499
dbus.UInt64(self.interval_milliseconds(),
645
500
variant_level=1),
646
dbus.String(u"checker"):
501
dbus.String("checker"):
647
502
dbus.String(self.checker_command,
648
503
variant_level=1),
649
dbus.String(u"checker_running"):
504
dbus.String("checker_running"):
650
505
dbus.Boolean(self.checker is not None,
651
506
variant_level=1),
652
dbus.String(u"object_path"):
507
dbus.String("object_path"):
653
508
dbus.ObjectPath(self.dbus_object_path,
657
512
# IsStillValid - method
658
@dbus.service.method(_interface, out_signature=u"b")
659
def IsStillValid(self):
660
return self.still_valid()
513
IsStillValid = (dbus.service.method(_interface, out_signature="b")
515
IsStillValid.__name__ = "IsStillValid"
662
517
# PropertyChanged - signal
663
@dbus.service.signal(_interface, signature=u"sv")
518
@dbus.service.signal(_interface, signature="sv")
664
519
def PropertyChanged(self, property, value):
668
# ReceivedSecret - signal
669
@dbus.service.signal(_interface)
670
def ReceivedSecret(self):
675
@dbus.service.signal(_interface)
680
523
# SetChecker - method
681
@dbus.service.method(_interface, in_signature=u"s")
524
@dbus.service.method(_interface, in_signature="s")
682
525
def SetChecker(self, checker):
683
526
"D-Bus setter method"
684
527
self.checker_command = checker
742
583
# StopChecker - method
743
@dbus.service.method(_interface)
744
def StopChecker(self):
584
StopChecker = dbus.service.method(_interface)(stop_checker)
585
StopChecker.__name__ = "StopChecker"
750
class ClientHandler(socketserver.BaseRequestHandler, object):
751
"""A class to handle client connections.
753
Instantiated once for each connection to handle it.
590
def peer_certificate(session):
591
"Return the peer's OpenPGP certificate as a bytestring"
592
# If not an OpenPGP certificate...
593
if (gnutls.library.functions
594
.gnutls_certificate_type_get(session._c_object)
595
!= gnutls.library.constants.GNUTLS_CRT_OPENPGP):
596
# ...do the normal thing
597
return session.peer_certificate
598
list_size = ctypes.c_uint(1)
599
cert_list = (gnutls.library.functions
600
.gnutls_certificate_get_peers
601
(session._c_object, ctypes.byref(list_size)))
602
if not bool(cert_list) and list_size.value != 0:
603
raise gnutls.errors.GNUTLSError("error getting peer"
605
if list_size.value == 0:
608
return ctypes.string_at(cert.data, cert.size)
611
def fingerprint(openpgp):
612
"Convert an OpenPGP bytestring to a hexdigit fingerprint string"
613
# New GnuTLS "datum" with the OpenPGP public key
614
datum = (gnutls.library.types
615
.gnutls_datum_t(ctypes.cast(ctypes.c_char_p(openpgp),
618
ctypes.c_uint(len(openpgp))))
619
# New empty GnuTLS certificate
620
crt = gnutls.library.types.gnutls_openpgp_crt_t()
621
(gnutls.library.functions
622
.gnutls_openpgp_crt_init(ctypes.byref(crt)))
623
# Import the OpenPGP public key into the certificate
624
(gnutls.library.functions
625
.gnutls_openpgp_crt_import(crt, ctypes.byref(datum),
626
gnutls.library.constants
627
.GNUTLS_OPENPGP_FMT_RAW))
628
# Verify the self signature in the key
629
crtverify = ctypes.c_uint()
630
(gnutls.library.functions
631
.gnutls_openpgp_crt_verify_self(crt, 0, ctypes.byref(crtverify)))
632
if crtverify.value != 0:
633
gnutls.library.functions.gnutls_openpgp_crt_deinit(crt)
634
raise gnutls.errors.CertificateSecurityError("Verify failed")
635
# New buffer for the fingerprint
636
buf = ctypes.create_string_buffer(20)
637
buf_len = ctypes.c_size_t()
638
# Get the fingerprint from the certificate into the buffer
639
(gnutls.library.functions
640
.gnutls_openpgp_crt_get_fingerprint(crt, ctypes.byref(buf),
641
ctypes.byref(buf_len)))
642
# Deinit the certificate
643
gnutls.library.functions.gnutls_openpgp_crt_deinit(crt)
644
# Convert the buffer to a Python bytestring
645
fpr = ctypes.string_at(buf, buf_len.value)
646
# Convert the bytestring to hexadecimal notation
647
hex_fpr = u''.join(u"%02X" % ord(char) for char in fpr)
651
class TCP_handler(SocketServer.BaseRequestHandler, object):
652
"""A TCP request handler class.
653
Instantiated by IPv6_TCPServer for each request to handle it.
754
654
Note: This will run in its own forked process."""
756
656
def handle(self):
757
657
logger.info(u"TCP connection from: %s",
758
658
unicode(self.client_address))
759
logger.debug(u"IPC Pipe FD: %d", self.server.pipe[1])
760
# Open IPC pipe to parent process
761
with closing(os.fdopen(self.server.pipe[1], u"w", 1)) as ipc:
762
session = (gnutls.connection
763
.ClientSession(self.request,
767
line = self.request.makefile().readline()
768
logger.debug(u"Protocol version: %r", line)
770
if int(line.strip().split()[0]) > 1:
772
except (ValueError, IndexError, RuntimeError), error:
773
logger.error(u"Unknown protocol version: %s", error)
776
# Note: gnutls.connection.X509Credentials is really a
777
# generic GnuTLS certificate credentials object so long as
778
# no X.509 keys are added to it. Therefore, we can use it
779
# here despite using OpenPGP certificates.
781
#priority = u':'.join((u"NONE", u"+VERS-TLS1.1",
782
# u"+AES-256-CBC", u"+SHA1",
783
# u"+COMP-NULL", u"+CTYPE-OPENPGP",
785
# Use a fallback default, since this MUST be set.
786
priority = self.server.gnutls_priority
789
(gnutls.library.functions
790
.gnutls_priority_set_direct(session._c_object,
795
except gnutls.errors.GNUTLSError, error:
796
logger.warning(u"Handshake failed: %s", error)
797
# Do not run session.bye() here: the session is not
798
# established. Just abandon the request.
800
logger.debug(u"Handshake succeeded")
802
fpr = self.fingerprint(self.peer_certificate(session))
803
except (TypeError, gnutls.errors.GNUTLSError), error:
804
logger.warning(u"Bad certificate: %s", error)
807
logger.debug(u"Fingerprint: %s", fpr)
809
for c in self.server.clients:
810
if c.fingerprint == fpr:
814
ipc.write(u"NOTFOUND %s %s\n"
815
% (fpr, unicode(self.client_address)))
818
# Have to check if client.still_valid(), since it is
819
# possible that the client timed out while establishing
820
# the GnuTLS session.
821
if not client.still_valid():
822
ipc.write(u"INVALID %s\n" % client.name)
825
ipc.write(u"SENDING %s\n" % client.name)
827
while sent_size < len(client.secret):
828
sent = session.send(client.secret[sent_size:])
829
logger.debug(u"Sent: %d, remaining: %d",
830
sent, len(client.secret)
831
- (sent_size + sent))
836
def peer_certificate(session):
837
"Return the peer's OpenPGP certificate as a bytestring"
838
# If not an OpenPGP certificate...
839
if (gnutls.library.functions
840
.gnutls_certificate_type_get(session._c_object)
841
!= gnutls.library.constants.GNUTLS_CRT_OPENPGP):
842
# ...do the normal thing
843
return session.peer_certificate
844
list_size = ctypes.c_uint(1)
845
cert_list = (gnutls.library.functions
846
.gnutls_certificate_get_peers
847
(session._c_object, ctypes.byref(list_size)))
848
if not bool(cert_list) and list_size.value != 0:
849
raise gnutls.errors.GNUTLSError(u"error getting peer"
851
if list_size.value == 0:
854
return ctypes.string_at(cert.data, cert.size)
857
def fingerprint(openpgp):
858
"Convert an OpenPGP bytestring to a hexdigit fingerprint"
859
# New GnuTLS "datum" with the OpenPGP public key
860
datum = (gnutls.library.types
861
.gnutls_datum_t(ctypes.cast(ctypes.c_char_p(openpgp),
864
ctypes.c_uint(len(openpgp))))
865
# New empty GnuTLS certificate
866
crt = gnutls.library.types.gnutls_openpgp_crt_t()
867
(gnutls.library.functions
868
.gnutls_openpgp_crt_init(ctypes.byref(crt)))
869
# Import the OpenPGP public key into the certificate
870
(gnutls.library.functions
871
.gnutls_openpgp_crt_import(crt, ctypes.byref(datum),
872
gnutls.library.constants
873
.GNUTLS_OPENPGP_FMT_RAW))
874
# Verify the self signature in the key
875
crtverify = ctypes.c_uint()
876
(gnutls.library.functions
877
.gnutls_openpgp_crt_verify_self(crt, 0,
878
ctypes.byref(crtverify)))
879
if crtverify.value != 0:
880
gnutls.library.functions.gnutls_openpgp_crt_deinit(crt)
881
raise (gnutls.errors.CertificateSecurityError
883
# New buffer for the fingerprint
884
buf = ctypes.create_string_buffer(20)
885
buf_len = ctypes.c_size_t()
886
# Get the fingerprint from the certificate into the buffer
887
(gnutls.library.functions
888
.gnutls_openpgp_crt_get_fingerprint(crt, ctypes.byref(buf),
889
ctypes.byref(buf_len)))
890
# Deinit the certificate
891
gnutls.library.functions.gnutls_openpgp_crt_deinit(crt)
892
# Convert the buffer to a Python bytestring
893
fpr = ctypes.string_at(buf, buf_len.value)
894
# Convert the bytestring to hexadecimal notation
895
hex_fpr = u''.join(u"%02X" % ord(char) for char in fpr)
899
class ForkingMixInWithPipe(socketserver.ForkingMixIn, object):
900
"""Like socketserver.ForkingMixIn, but also pass a pipe."""
901
def process_request(self, request, client_address):
902
"""Overrides and wraps the original process_request().
904
This function creates a new pipe in self.pipe
906
self.pipe = os.pipe()
907
super(ForkingMixInWithPipe,
908
self).process_request(request, client_address)
909
os.close(self.pipe[1]) # close write end
910
self.add_pipe(self.pipe[0])
911
def add_pipe(self, pipe):
912
"""Dummy function; override as necessary"""
916
class IPv6_TCPServer(ForkingMixInWithPipe,
917
socketserver.TCPServer, object):
918
"""IPv6-capable TCP server. Accepts 'None' as address and/or port
659
session = (gnutls.connection
660
.ClientSession(self.request,
664
line = self.request.makefile().readline()
665
logger.debug(u"Protocol version: %r", line)
667
if int(line.strip().split()[0]) > 1:
669
except (ValueError, IndexError, RuntimeError), error:
670
logger.error(u"Unknown protocol version: %s", error)
673
# Note: gnutls.connection.X509Credentials is really a generic
674
# GnuTLS certificate credentials object so long as no X.509
675
# keys are added to it. Therefore, we can use it here despite
676
# using OpenPGP certificates.
678
#priority = ':'.join(("NONE", "+VERS-TLS1.1", "+AES-256-CBC",
679
# "+SHA1", "+COMP-NULL", "+CTYPE-OPENPGP",
681
# Use a fallback default, since this MUST be set.
682
priority = self.server.settings.get("priority", "NORMAL")
683
(gnutls.library.functions
684
.gnutls_priority_set_direct(session._c_object,
689
except gnutls.errors.GNUTLSError, error:
690
logger.warning(u"Handshake failed: %s", error)
691
# Do not run session.bye() here: the session is not
692
# established. Just abandon the request.
694
logger.debug(u"Handshake succeeded")
696
fpr = fingerprint(peer_certificate(session))
697
except (TypeError, gnutls.errors.GNUTLSError), error:
698
logger.warning(u"Bad certificate: %s", error)
701
logger.debug(u"Fingerprint: %s", fpr)
703
for c in self.server.clients:
704
if c.fingerprint == fpr:
708
logger.warning(u"Client not found for fingerprint: %s",
712
# Have to check if client.still_valid(), since it is possible
713
# that the client timed out while establishing the GnuTLS
715
if not client.still_valid():
716
logger.warning(u"Client %(name)s is invalid",
720
## This won't work here, since we're in a fork.
721
# client.checked_ok()
723
while sent_size < len(client.secret):
724
sent = session.send(client.secret[sent_size:])
725
logger.debug(u"Sent: %d, remaining: %d",
726
sent, len(client.secret)
727
- (sent_size + sent))
732
class IPv6_TCPServer(SocketServer.ForkingMixIn,
733
SocketServer.TCPServer, object):
734
"""IPv6 TCP server. Accepts 'None' as address and/or port.
736
settings: Server settings
737
clients: Set() of Client objects
921
738
enabled: Boolean; whether this server is activated yet
922
interface: None or a network interface name (string)
923
use_ipv6: Boolean; to use IPv6 or not
925
def __init__(self, server_address, RequestHandlerClass,
926
interface=None, use_ipv6=True):
927
self.interface = interface
929
self.address_family = socket.AF_INET6
930
socketserver.TCPServer.__init__(self, server_address,
740
address_family = socket.AF_INET6
741
def __init__(self, *args, **kwargs):
742
if "settings" in kwargs:
743
self.settings = kwargs["settings"]
744
del kwargs["settings"]
745
if "clients" in kwargs:
746
self.clients = kwargs["clients"]
747
del kwargs["clients"]
749
super(IPv6_TCPServer, self).__init__(*args, **kwargs)
932
750
def server_bind(self):
933
751
"""This overrides the normal server_bind() function
934
752
to bind to an interface if one was specified, and also NOT to
935
753
bind to an address or port if they were not specified."""
936
if self.interface is not None:
937
if SO_BINDTODEVICE is None:
938
logger.error(u"SO_BINDTODEVICE does not exist;"
939
u" cannot bind to interface %s",
943
self.socket.setsockopt(socket.SOL_SOCKET,
947
except socket.error, error:
948
if error[0] == errno.EPERM:
949
logger.error(u"No permission to"
950
u" bind to interface %s",
952
elif error[0] == errno.ENOPROTOOPT:
953
logger.error(u"SO_BINDTODEVICE not available;"
954
u" cannot bind to interface %s",
754
if self.settings["interface"]:
755
# 25 is from /usr/include/asm-i486/socket.h
756
SO_BINDTODEVICE = getattr(socket, "SO_BINDTODEVICE", 25)
758
self.socket.setsockopt(socket.SOL_SOCKET,
760
self.settings["interface"])
761
except socket.error, error:
762
if error[0] == errno.EPERM:
763
logger.error(u"No permission to"
764
u" bind to interface %s",
765
self.settings["interface"])
958
768
# Only bind(2) the socket if we really need to.
959
769
if self.server_address[0] or self.server_address[1]:
960
770
if not self.server_address[0]:
961
if self.address_family == socket.AF_INET6:
962
any_address = u"::" # in6addr_any
964
any_address = socket.INADDR_ANY
965
self.server_address = (any_address,
772
self.server_address = (in6addr_any,
966
773
self.server_address[1])
967
774
elif not self.server_address[1]:
968
775
self.server_address = (self.server_address[0],
777
# if self.settings["interface"]:
971
778
# self.server_address = (self.server_address[0],
976
return socketserver.TCPServer.server_bind(self)
979
class MandosServer(IPv6_TCPServer):
983
clients: set of Client objects
984
gnutls_priority GnuTLS priority string
985
use_dbus: Boolean; to emit D-Bus signals or not
987
Assumes a gobject.MainLoop event loop.
989
def __init__(self, server_address, RequestHandlerClass,
990
interface=None, use_ipv6=True, clients=None,
991
gnutls_priority=None, use_dbus=True):
993
self.clients = clients
994
if self.clients is None:
996
self.use_dbus = use_dbus
997
self.gnutls_priority = gnutls_priority
998
IPv6_TCPServer.__init__(self, server_address,
1000
interface = interface,
1001
use_ipv6 = use_ipv6)
784
return super(IPv6_TCPServer, self).server_bind()
1002
785
def server_activate(self):
1003
786
if self.enabled:
1004
return socketserver.TCPServer.server_activate(self)
787
return super(IPv6_TCPServer, self).server_activate()
1005
788
def enable(self):
1006
789
self.enabled = True
1007
def add_pipe(self, pipe):
1008
# Call "handle_ipc" for both data and EOF events
1009
gobject.io_add_watch(pipe, gobject.IO_IN | gobject.IO_HUP,
1011
def handle_ipc(self, source, condition, file_objects={}):
1013
gobject.IO_IN: u"IN", # There is data to read.
1014
gobject.IO_OUT: u"OUT", # Data can be written (without
1016
gobject.IO_PRI: u"PRI", # There is urgent data to read.
1017
gobject.IO_ERR: u"ERR", # Error condition.
1018
gobject.IO_HUP: u"HUP" # Hung up (the connection has been
1019
# broken, usually for pipes and
1022
conditions_string = ' | '.join(name
1024
condition_names.iteritems()
1025
if cond & condition)
1026
logger.debug(u"Handling IPC: FD = %d, condition = %s", source,
1029
# Turn the pipe file descriptor into a Python file object
1030
if source not in file_objects:
1031
file_objects[source] = os.fdopen(source, u"r", 1)
1033
# Read a line from the file object
1034
cmdline = file_objects[source].readline()
1035
if not cmdline: # Empty line means end of file
1036
# close the IPC pipe
1037
file_objects[source].close()
1038
del file_objects[source]
1040
# Stop calling this function
1043
logger.debug(u"IPC command: %r", cmdline)
1045
# Parse and act on command
1046
cmd, args = cmdline.rstrip(u"\r\n").split(None, 1)
1048
if cmd == u"NOTFOUND":
1049
logger.warning(u"Client not found for fingerprint: %s",
1053
mandos_dbus_service.ClientNotFound(args)
1054
elif cmd == u"INVALID":
1055
for client in self.clients:
1056
if client.name == args:
1057
logger.warning(u"Client %s is invalid", args)
1063
logger.error(u"Unknown client %s is invalid", args)
1064
elif cmd == u"SENDING":
1065
for client in self.clients:
1066
if client.name == args:
1067
logger.info(u"Sending secret to %s", client.name)
1071
client.ReceivedSecret()
1074
logger.error(u"Sending secret to unknown client %s",
1077
logger.error(u"Unknown IPC command: %r", cmdline)
1079
# Keep calling this function
1083
792
def string_to_delta(interval):
1084
793
"""Parse a string and return a datetime.timedelta
1086
>>> string_to_delta(u'7d')
795
>>> string_to_delta('7d')
1087
796
datetime.timedelta(7)
1088
>>> string_to_delta(u'60s')
797
>>> string_to_delta('60s')
1089
798
datetime.timedelta(0, 60)
1090
>>> string_to_delta(u'60m')
799
>>> string_to_delta('60m')
1091
800
datetime.timedelta(0, 3600)
1092
>>> string_to_delta(u'24h')
801
>>> string_to_delta('24h')
1093
802
datetime.timedelta(1)
1094
803
>>> string_to_delta(u'1w')
1095
804
datetime.timedelta(7)
1096
>>> string_to_delta(u'5m 30s')
805
>>> string_to_delta('5m 30s')
1097
806
datetime.timedelta(0, 330)
1099
808
timevalue = datetime.timedelta(0)
1207
932
# Default values for config file for server-global settings
1208
server_defaults = { u"interface": u"",
1213
u"SECURE256:!CTYPE-X.509:+CTYPE-OPENPGP",
1214
u"servicename": u"Mandos",
1215
u"use_dbus": u"True",
1216
u"use_ipv6": u"True",
933
server_defaults = { "interface": "",
938
"SECURE256:!CTYPE-X.509:+CTYPE-OPENPGP",
939
"servicename": "Mandos",
1219
943
# Parse config file for server-global settings
1220
server_config = configparser.SafeConfigParser(server_defaults)
944
server_config = ConfigParser.SafeConfigParser(server_defaults)
1221
945
del server_defaults
1222
server_config.read(os.path.join(options.configdir,
946
server_config.read(os.path.join(options.configdir, "mandos.conf"))
1224
947
# Convert the SafeConfigParser object to a dict
1225
948
server_settings = server_config.defaults()
1226
949
# Use the appropriate methods on the non-string config options
1227
for option in (u"debug", u"use_dbus", u"use_ipv6"):
1228
server_settings[option] = server_config.getboolean(u"DEFAULT",
950
server_settings["debug"] = server_config.getboolean("DEFAULT",
952
server_settings["use_dbus"] = server_config.getboolean("DEFAULT",
1230
954
if server_settings["port"]:
1231
server_settings["port"] = server_config.getint(u"DEFAULT",
955
server_settings["port"] = server_config.getint("DEFAULT",
1233
957
del server_config
1235
959
# Override the settings from the config file with command line
1236
960
# options, if set.
1237
for option in (u"interface", u"address", u"port", u"debug",
1238
u"priority", u"servicename", u"configdir",
1239
u"use_dbus", u"use_ipv6"):
961
for option in ("interface", "address", "port", "debug",
962
"priority", "servicename", "configdir",
1240
964
value = getattr(options, option)
1241
965
if value is not None:
1242
966
server_settings[option] = value
1244
# Force all strings to be unicode
1245
for option in server_settings.keys():
1246
if type(server_settings[option]) is str:
1247
server_settings[option] = unicode(server_settings[option])
1248
968
# Now we have our good server settings in "server_settings"
1250
##################################################################
1252
970
# For convenience
1253
debug = server_settings[u"debug"]
1254
use_dbus = server_settings[u"use_dbus"]
1255
use_ipv6 = server_settings[u"use_ipv6"]
971
debug = server_settings["debug"]
972
use_dbus = server_settings["use_dbus"]
974
def sigsegvhandler(signum, frame):
975
raise RuntimeError('Segmentation fault')
1258
978
syslogger.setLevel(logging.WARNING)
1259
979
console.setLevel(logging.WARNING)
981
signal.signal(signal.SIGSEGV, sigsegvhandler)
1261
if server_settings[u"servicename"] != u"Mandos":
983
if server_settings["servicename"] != "Mandos":
1262
984
syslogger.setFormatter(logging.Formatter
1263
(u'Mandos (%s) [%%(process)d]:'
1264
u' %%(levelname)s: %%(message)s'
1265
% server_settings[u"servicename"]))
985
('Mandos (%s): %%(levelname)s:'
987
% server_settings["servicename"]))
1267
989
# Parse config file with clients
1268
client_defaults = { u"timeout": u"1h",
1270
u"checker": u"fping -q -- %%(host)s",
990
client_defaults = { "timeout": "1h",
992
"checker": "fping -q -- %%(host)s",
1273
client_config = configparser.SafeConfigParser(client_defaults)
1274
client_config.read(os.path.join(server_settings[u"configdir"],
1277
global mandos_dbus_service
1278
mandos_dbus_service = None
1280
tcp_server = MandosServer((server_settings[u"address"],
1281
server_settings[u"port"]),
1283
interface=server_settings[u"interface"],
1286
server_settings[u"priority"],
1288
pidfilename = u"/var/run/mandos.pid"
1290
pidfile = open(pidfilename, u"w")
1292
logger.error(u"Could not open file %r", pidfilename)
1295
uid = pwd.getpwnam(u"_mandos").pw_uid
1296
gid = pwd.getpwnam(u"_mandos").pw_gid
995
client_config = ConfigParser.SafeConfigParser(client_defaults)
996
client_config.read(os.path.join(server_settings["configdir"],
1000
tcp_server = IPv6_TCPServer((server_settings["address"],
1001
server_settings["port"]),
1003
settings=server_settings,
1005
pidfilename = "/var/run/mandos.pid"
1007
pidfile = open(pidfilename, "w")
1008
except IOError, error:
1009
logger.error("Could not open file %r", pidfilename)
1012
uid = pwd.getpwnam("_mandos").pw_uid
1013
gid = pwd.getpwnam("_mandos").pw_gid
1297
1014
except KeyError:
1299
uid = pwd.getpwnam(u"mandos").pw_uid
1300
gid = pwd.getpwnam(u"mandos").pw_gid
1016
uid = pwd.getpwnam("mandos").pw_uid
1017
gid = pwd.getpwnam("mandos").pw_gid
1301
1018
except KeyError:
1303
uid = pwd.getpwnam(u"nobody").pw_uid
1304
gid = pwd.getpwnam(u"nobody").pw_gid
1020
uid = pwd.getpwnam("nobody").pw_uid
1021
gid = pwd.getpwnam("nogroup").pw_gid
1305
1022
except KeyError: