430
434
if error.errno != errno.ESRCH: # No such process
432
436
self.checker = None
438
self.PropertyChanged(dbus.String(u"checker_running"),
439
dbus.Boolean(False, variant_level=1))
434
441
def still_valid(self):
435
442
"""Has the timeout not yet passed for this client?"""
436
if not getattr(self, u"enabled", False):
443
if not getattr(self, "enabled", False):
438
445
now = datetime.datetime.utcnow()
439
446
if self.last_checked_ok is None:
440
447
return now < (self.created + self.timeout)
442
449
return now < (self.last_checked_ok + self.timeout)
445
class ClientDBus(Client, dbus.service.Object):
446
"""A Client class using D-Bus
449
dbus_object_path: dbus.ObjectPath ; only set if self.use_dbus
451
# dbus.service.Object doesn't use super(), so we can't either.
453
def __init__(self, *args, **kwargs):
454
Client.__init__(self, *args, **kwargs)
455
# Only now, when this client is initialized, can it show up on
457
self.dbus_object_path = (dbus.ObjectPath
459
+ self.name.replace(u".", u"_")))
460
dbus.service.Object.__init__(self, bus,
461
self.dbus_object_path)
463
oldstate = getattr(self, u"enabled", False)
464
r = Client.enable(self)
465
if oldstate != self.enabled:
467
self.PropertyChanged(dbus.String(u"enabled"),
468
dbus.Boolean(True, variant_level=1))
469
self.PropertyChanged(dbus.String(u"last_enabled"),
470
(_datetime_to_dbus(self.last_enabled,
474
def disable(self, signal = True):
475
oldstate = getattr(self, u"enabled", False)
476
r = Client.disable(self)
477
if signal and oldstate != self.enabled:
479
self.PropertyChanged(dbus.String(u"enabled"),
480
dbus.Boolean(False, variant_level=1))
483
def __del__(self, *args, **kwargs):
485
self.remove_from_connection()
488
if hasattr(dbus.service.Object, u"__del__"):
489
dbus.service.Object.__del__(self, *args, **kwargs)
490
Client.__del__(self, *args, **kwargs)
492
def checker_callback(self, pid, condition, command,
494
self.checker_callback_tag = None
497
self.PropertyChanged(dbus.String(u"checker_running"),
498
dbus.Boolean(False, variant_level=1))
499
if os.WIFEXITED(condition):
500
exitstatus = os.WEXITSTATUS(condition)
502
self.CheckerCompleted(dbus.Int16(exitstatus),
503
dbus.Int64(condition),
504
dbus.String(command))
507
self.CheckerCompleted(dbus.Int16(-1),
508
dbus.Int64(condition),
509
dbus.String(command))
511
return Client.checker_callback(self, pid, condition, command,
514
def checked_ok(self, *args, **kwargs):
515
r = Client.checked_ok(self, *args, **kwargs)
517
self.PropertyChanged(
518
dbus.String(u"last_checked_ok"),
519
(_datetime_to_dbus(self.last_checked_ok,
523
def start_checker(self, *args, **kwargs):
524
old_checker = self.checker
525
if self.checker is not None:
526
old_checker_pid = self.checker.pid
528
old_checker_pid = None
529
r = Client.start_checker(self, *args, **kwargs)
530
# Only if new checker process was started
531
if (self.checker is not None
532
and old_checker_pid != self.checker.pid):
534
self.CheckerStarted(self.current_checker_command)
535
self.PropertyChanged(
536
dbus.String(u"checker_running"),
537
dbus.Boolean(True, variant_level=1))
540
def stop_checker(self, *args, **kwargs):
541
old_checker = getattr(self, u"checker", None)
542
r = Client.stop_checker(self, *args, **kwargs)
543
if (old_checker is not None
544
and getattr(self, u"checker", None) is None):
545
self.PropertyChanged(dbus.String(u"checker_running"),
546
dbus.Boolean(False, variant_level=1))
549
451
## D-Bus methods & signals
550
452
_interface = u"se.bsnet.fukt.Mandos.Client"
552
454
# CheckedOK - method
553
@dbus.service.method(_interface)
555
return self.checked_ok()
455
CheckedOK = dbus.service.method(_interface)(checked_ok)
456
CheckedOK.__name__ = "CheckedOK"
557
458
# CheckerCompleted - signal
558
@dbus.service.signal(_interface, signature=u"nxs")
459
@dbus.service.signal(_interface, signature="nxs")
559
460
def CheckerCompleted(self, exitcode, waitstatus, command):
563
464
# CheckerStarted - signal
564
@dbus.service.signal(_interface, signature=u"s")
465
@dbus.service.signal(_interface, signature="s")
565
466
def CheckerStarted(self, command):
569
470
# GetAllProperties - method
570
@dbus.service.method(_interface, out_signature=u"a{sv}")
471
@dbus.service.method(_interface, out_signature="a{sv}")
571
472
def GetAllProperties(self):
573
474
return dbus.Dictionary({
574
dbus.String(u"name"):
575
476
dbus.String(self.name, variant_level=1),
576
dbus.String(u"fingerprint"):
477
dbus.String("fingerprint"):
577
478
dbus.String(self.fingerprint, variant_level=1),
578
dbus.String(u"host"):
579
480
dbus.String(self.host, variant_level=1),
580
dbus.String(u"created"):
481
dbus.String("created"):
581
482
_datetime_to_dbus(self.created, variant_level=1),
582
dbus.String(u"last_enabled"):
483
dbus.String("last_enabled"):
583
484
(_datetime_to_dbus(self.last_enabled,
585
486
if self.last_enabled is not None
586
487
else dbus.Boolean(False, variant_level=1)),
587
dbus.String(u"enabled"):
488
dbus.String("enabled"):
588
489
dbus.Boolean(self.enabled, variant_level=1),
589
dbus.String(u"last_checked_ok"):
490
dbus.String("last_checked_ok"):
590
491
(_datetime_to_dbus(self.last_checked_ok,
592
493
if self.last_checked_ok is not None
593
494
else dbus.Boolean (False, variant_level=1)),
594
dbus.String(u"timeout"):
495
dbus.String("timeout"):
595
496
dbus.UInt64(self.timeout_milliseconds(),
596
497
variant_level=1),
597
dbus.String(u"interval"):
498
dbus.String("interval"):
598
499
dbus.UInt64(self.interval_milliseconds(),
599
500
variant_level=1),
600
dbus.String(u"checker"):
501
dbus.String("checker"):
601
502
dbus.String(self.checker_command,
602
503
variant_level=1),
603
dbus.String(u"checker_running"):
504
dbus.String("checker_running"):
604
505
dbus.Boolean(self.checker is not None,
605
506
variant_level=1),
606
dbus.String(u"object_path"):
507
dbus.String("object_path"):
607
508
dbus.ObjectPath(self.dbus_object_path,
611
512
# IsStillValid - method
612
@dbus.service.method(_interface, out_signature=u"b")
613
def IsStillValid(self):
614
return self.still_valid()
513
IsStillValid = (dbus.service.method(_interface, out_signature="b")
515
IsStillValid.__name__ = "IsStillValid"
616
517
# PropertyChanged - signal
617
@dbus.service.signal(_interface, signature=u"sv")
518
@dbus.service.signal(_interface, signature="sv")
618
519
def PropertyChanged(self, property, value):
622
# ReceivedSecret - signal
623
@dbus.service.signal(_interface)
624
def ReceivedSecret(self):
629
@dbus.service.signal(_interface)
634
523
# SetChecker - method
635
@dbus.service.method(_interface, in_signature=u"s")
524
@dbus.service.method(_interface, in_signature="s")
636
525
def SetChecker(self, checker):
637
526
"D-Bus setter method"
638
527
self.checker_command = checker
696
583
# StopChecker - method
697
@dbus.service.method(_interface)
698
def StopChecker(self):
584
StopChecker = dbus.service.method(_interface)(stop_checker)
585
StopChecker.__name__ = "StopChecker"
704
class ClientHandler(socketserver.BaseRequestHandler, object):
705
"""A class to handle client connections.
707
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.
708
654
Note: This will run in its own forked process."""
710
656
def handle(self):
711
657
logger.info(u"TCP connection from: %s",
712
658
unicode(self.client_address))
713
logger.debug(u"IPC Pipe FD: %d", self.server.pipe[1])
714
# Open IPC pipe to parent process
715
with closing(os.fdopen(self.server.pipe[1], u"w", 1)) as ipc:
716
session = (gnutls.connection
717
.ClientSession(self.request,
721
line = self.request.makefile().readline()
722
logger.debug(u"Protocol version: %r", line)
724
if int(line.strip().split()[0]) > 1:
726
except (ValueError, IndexError, RuntimeError), error:
727
logger.error(u"Unknown protocol version: %s", error)
730
# Note: gnutls.connection.X509Credentials is really a
731
# generic GnuTLS certificate credentials object so long as
732
# no X.509 keys are added to it. Therefore, we can use it
733
# here despite using OpenPGP certificates.
735
#priority = u':'.join((u"NONE", u"+VERS-TLS1.1",
736
# u"+AES-256-CBC", u"+SHA1",
737
# u"+COMP-NULL", u"+CTYPE-OPENPGP",
739
# Use a fallback default, since this MUST be set.
740
priority = self.server.gnutls_priority
743
(gnutls.library.functions
744
.gnutls_priority_set_direct(session._c_object,
749
except gnutls.errors.GNUTLSError, error:
750
logger.warning(u"Handshake failed: %s", error)
751
# Do not run session.bye() here: the session is not
752
# established. Just abandon the request.
754
logger.debug(u"Handshake succeeded")
756
fpr = self.fingerprint(self.peer_certificate(session))
757
except (TypeError, gnutls.errors.GNUTLSError), error:
758
logger.warning(u"Bad certificate: %s", error)
761
logger.debug(u"Fingerprint: %s", fpr)
763
for c in self.server.clients:
764
if c.fingerprint == fpr:
768
ipc.write(u"NOTFOUND %s\n" % fpr)
771
# Have to check if client.still_valid(), since it is
772
# possible that the client timed out while establishing
773
# the GnuTLS session.
774
if not client.still_valid():
775
ipc.write(u"INVALID %s\n" % client.name)
778
ipc.write(u"SENDING %s\n" % client.name)
780
while sent_size < len(client.secret):
781
sent = session.send(client.secret[sent_size:])
782
logger.debug(u"Sent: %d, remaining: %d",
783
sent, len(client.secret)
784
- (sent_size + sent))
789
def peer_certificate(session):
790
"Return the peer's OpenPGP certificate as a bytestring"
791
# If not an OpenPGP certificate...
792
if (gnutls.library.functions
793
.gnutls_certificate_type_get(session._c_object)
794
!= gnutls.library.constants.GNUTLS_CRT_OPENPGP):
795
# ...do the normal thing
796
return session.peer_certificate
797
list_size = ctypes.c_uint(1)
798
cert_list = (gnutls.library.functions
799
.gnutls_certificate_get_peers
800
(session._c_object, ctypes.byref(list_size)))
801
if not bool(cert_list) and list_size.value != 0:
802
raise gnutls.errors.GNUTLSError(u"error getting peer"
804
if list_size.value == 0:
807
return ctypes.string_at(cert.data, cert.size)
810
def fingerprint(openpgp):
811
"Convert an OpenPGP bytestring to a hexdigit fingerprint"
812
# New GnuTLS "datum" with the OpenPGP public key
813
datum = (gnutls.library.types
814
.gnutls_datum_t(ctypes.cast(ctypes.c_char_p(openpgp),
817
ctypes.c_uint(len(openpgp))))
818
# New empty GnuTLS certificate
819
crt = gnutls.library.types.gnutls_openpgp_crt_t()
820
(gnutls.library.functions
821
.gnutls_openpgp_crt_init(ctypes.byref(crt)))
822
# Import the OpenPGP public key into the certificate
823
(gnutls.library.functions
824
.gnutls_openpgp_crt_import(crt, ctypes.byref(datum),
825
gnutls.library.constants
826
.GNUTLS_OPENPGP_FMT_RAW))
827
# Verify the self signature in the key
828
crtverify = ctypes.c_uint()
829
(gnutls.library.functions
830
.gnutls_openpgp_crt_verify_self(crt, 0,
831
ctypes.byref(crtverify)))
832
if crtverify.value != 0:
833
gnutls.library.functions.gnutls_openpgp_crt_deinit(crt)
834
raise (gnutls.errors.CertificateSecurityError
836
# New buffer for the fingerprint
837
buf = ctypes.create_string_buffer(20)
838
buf_len = ctypes.c_size_t()
839
# Get the fingerprint from the certificate into the buffer
840
(gnutls.library.functions
841
.gnutls_openpgp_crt_get_fingerprint(crt, ctypes.byref(buf),
842
ctypes.byref(buf_len)))
843
# Deinit the certificate
844
gnutls.library.functions.gnutls_openpgp_crt_deinit(crt)
845
# Convert the buffer to a Python bytestring
846
fpr = ctypes.string_at(buf, buf_len.value)
847
# Convert the bytestring to hexadecimal notation
848
hex_fpr = u''.join(u"%02X" % ord(char) for char in fpr)
852
class ForkingMixInWithPipe(socketserver.ForkingMixIn, object):
853
"""Like socketserver.ForkingMixIn, but also pass a pipe.
855
Assumes a gobject.MainLoop event loop.
857
def process_request(self, request, client_address):
858
"""Overrides and wraps the original process_request().
860
This function creates a new pipe in self.pipe
862
self.pipe = os.pipe()
863
super(ForkingMixInWithPipe,
864
self).process_request(request, client_address)
865
os.close(self.pipe[1]) # close write end
866
# Call "handle_ipc" for both data and EOF events
867
gobject.io_add_watch(self.pipe[0],
868
gobject.IO_IN | gobject.IO_HUP,
870
def handle_ipc(source, condition):
871
"""Dummy function; override as necessary"""
876
class IPv6_TCPServer(ForkingMixInWithPipe,
877
socketserver.TCPServer, object):
878
"""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)
702
for c in self.server.clients:
703
if c.fingerprint == fpr:
707
logger.warning(u"Client not found for fingerprint: %s",
711
# Have to check if client.still_valid(), since it is possible
712
# that the client timed out while establishing the GnuTLS
714
if not client.still_valid():
715
logger.warning(u"Client %(name)s is invalid",
719
## This won't work here, since we're in a fork.
720
# client.checked_ok()
722
while sent_size < len(client.secret):
723
sent = session.send(client.secret[sent_size:])
724
logger.debug(u"Sent: %d, remaining: %d",
725
sent, len(client.secret)
726
- (sent_size + sent))
731
class IPv6_TCPServer(SocketServer.ForkingMixIn,
732
SocketServer.TCPServer, object):
733
"""IPv6 TCP server. Accepts 'None' as address and/or port.
735
settings: Server settings
736
clients: Set() of Client objects
881
737
enabled: Boolean; whether this server is activated yet
882
interface: None or a network interface name (string)
883
use_ipv6: Boolean; to use IPv6 or not
885
clients: set of Client objects
886
gnutls_priority GnuTLS priority string
887
use_dbus: Boolean; to emit D-Bus signals or not
889
def __init__(self, server_address, RequestHandlerClass,
890
interface=None, use_ipv6=True, clients=None,
891
gnutls_priority=None, use_dbus=True):
739
address_family = socket.AF_INET6
740
def __init__(self, *args, **kwargs):
741
if "settings" in kwargs:
742
self.settings = kwargs["settings"]
743
del kwargs["settings"]
744
if "clients" in kwargs:
745
self.clients = kwargs["clients"]
746
del kwargs["clients"]
892
747
self.enabled = False
893
self.interface = interface
895
self.address_family = socket.AF_INET6
896
self.clients = clients
897
self.use_dbus = use_dbus
898
self.gnutls_priority = gnutls_priority
899
socketserver.TCPServer.__init__(self, server_address,
748
super(IPv6_TCPServer, self).__init__(*args, **kwargs)
901
749
def server_bind(self):
902
750
"""This overrides the normal server_bind() function
903
751
to bind to an interface if one was specified, and also NOT to
904
752
bind to an address or port if they were not specified."""
905
if self.interface is not None:
753
if self.settings["interface"]:
754
# 25 is from /usr/include/asm-i486/socket.h
755
SO_BINDTODEVICE = getattr(socket, "SO_BINDTODEVICE", 25)
907
757
self.socket.setsockopt(socket.SOL_SOCKET,
909
str(self.interface + u'\0'))
759
self.settings["interface"])
910
760
except socket.error, error:
911
761
if error[0] == errno.EPERM:
912
762
logger.error(u"No permission to"
913
763
u" bind to interface %s",
764
self.settings["interface"])
917
767
# Only bind(2) the socket if we really need to.
918
768
if self.server_address[0] or self.server_address[1]:
919
769
if not self.server_address[0]:
920
if self.address_family == socket.AF_INET6:
921
any_address = u"::" # in6addr_any
923
any_address = socket.INADDR_ANY
924
self.server_address = (any_address,
771
self.server_address = (in6addr_any,
925
772
self.server_address[1])
926
773
elif not self.server_address[1]:
927
774
self.server_address = (self.server_address[0],
776
# if self.settings["interface"]:
930
777
# self.server_address = (self.server_address[0],
935
return socketserver.TCPServer.server_bind(self)
783
return super(IPv6_TCPServer, self).server_bind()
936
784
def server_activate(self):
938
return socketserver.TCPServer.server_activate(self)
786
return super(IPv6_TCPServer, self).server_activate()
939
787
def enable(self):
940
788
self.enabled = True
941
def handle_ipc(self, source, condition, file_objects={}):
943
gobject.IO_IN: u"IN", # There is data to read.
944
gobject.IO_OUT: u"OUT", # Data can be written (without
946
gobject.IO_PRI: u"PRI", # There is urgent data to read.
947
gobject.IO_ERR: u"ERR", # Error condition.
948
gobject.IO_HUP: u"HUP" # Hung up (the connection has been
949
# broken, usually for pipes and
952
conditions_string = ' | '.join(name
954
condition_names.iteritems()
956
logger.debug(u"Handling IPC: FD = %d, condition = %s", source,
959
# Turn the pipe file descriptor into a Python file object
960
if source not in file_objects:
961
file_objects[source] = os.fdopen(source, u"r", 1)
963
# Read a line from the file object
964
cmdline = file_objects[source].readline()
965
if not cmdline: # Empty line means end of file
967
file_objects[source].close()
968
del file_objects[source]
970
# Stop calling this function
973
logger.debug(u"IPC command: %r", cmdline)
975
# Parse and act on command
976
cmd, args = cmdline.rstrip(u"\r\n").split(None, 1)
978
if cmd == u"NOTFOUND":
979
logger.warning(u"Client not found for fingerprint: %s",
983
mandos_dbus_service.ClientNotFound(args)
984
elif cmd == u"INVALID":
985
for client in self.clients:
986
if client.name == args:
987
logger.warning(u"Client %s is invalid", args)
993
logger.error(u"Unknown client %s is invalid", args)
994
elif cmd == u"SENDING":
995
for client in self.clients:
996
if client.name == args:
997
logger.info(u"Sending secret to %s", client.name)
1001
client.ReceivedSecret()
1004
logger.error(u"Sending secret to unknown client %s",
1007
logger.error(u"Unknown IPC command: %r", cmdline)
1009
# Keep calling this function
1013
791
def string_to_delta(interval):
1014
792
"""Parse a string and return a datetime.timedelta
1016
>>> string_to_delta(u'7d')
794
>>> string_to_delta('7d')
1017
795
datetime.timedelta(7)
1018
>>> string_to_delta(u'60s')
796
>>> string_to_delta('60s')
1019
797
datetime.timedelta(0, 60)
1020
>>> string_to_delta(u'60m')
798
>>> string_to_delta('60m')
1021
799
datetime.timedelta(0, 3600)
1022
>>> string_to_delta(u'24h')
800
>>> string_to_delta('24h')
1023
801
datetime.timedelta(1)
1024
802
>>> string_to_delta(u'1w')
1025
803
datetime.timedelta(7)
1026
>>> string_to_delta(u'5m 30s')
804
>>> string_to_delta('5m 30s')
1027
805
datetime.timedelta(0, 330)
1029
807
timevalue = datetime.timedelta(0)
1160
931
# Default values for config file for server-global settings
1161
server_defaults = { u"interface": u"",
1166
u"SECURE256:!CTYPE-X.509:+CTYPE-OPENPGP",
1167
u"servicename": u"Mandos",
1168
u"use_dbus": u"True",
1169
u"use_ipv6": u"True",
932
server_defaults = { "interface": "",
937
"SECURE256:!CTYPE-X.509:+CTYPE-OPENPGP",
938
"servicename": "Mandos",
1172
942
# Parse config file for server-global settings
1173
server_config = configparser.SafeConfigParser(server_defaults)
943
server_config = ConfigParser.SafeConfigParser(server_defaults)
1174
944
del server_defaults
1175
server_config.read(os.path.join(options.configdir,
945
server_config.read(os.path.join(options.configdir, "mandos.conf"))
1177
946
# Convert the SafeConfigParser object to a dict
1178
947
server_settings = server_config.defaults()
1179
948
# Use the appropriate methods on the non-string config options
1180
for option in (u"debug", u"use_dbus", u"use_ipv6"):
1181
server_settings[option] = server_config.getboolean(u"DEFAULT",
949
server_settings["debug"] = server_config.getboolean("DEFAULT",
951
server_settings["use_dbus"] = server_config.getboolean("DEFAULT",
1183
953
if server_settings["port"]:
1184
server_settings["port"] = server_config.getint(u"DEFAULT",
954
server_settings["port"] = server_config.getint("DEFAULT",
1186
956
del server_config
1188
958
# Override the settings from the config file with command line
1189
959
# options, if set.
1190
for option in (u"interface", u"address", u"port", u"debug",
1191
u"priority", u"servicename", u"configdir",
1192
u"use_dbus", u"use_ipv6"):
960
for option in ("interface", "address", "port", "debug",
961
"priority", "servicename", "configdir",
1193
963
value = getattr(options, option)
1194
964
if value is not None:
1195
965
server_settings[option] = value
1197
# Force all strings to be unicode
1198
for option in server_settings.keys():
1199
if type(server_settings[option]) is str:
1200
server_settings[option] = unicode(server_settings[option])
1201
967
# Now we have our good server settings in "server_settings"
1203
##################################################################
1205
969
# For convenience
1206
debug = server_settings[u"debug"]
1207
use_dbus = server_settings[u"use_dbus"]
1208
use_ipv6 = server_settings[u"use_ipv6"]
970
debug = server_settings["debug"]
971
use_dbus = server_settings["use_dbus"]
1211
974
syslogger.setLevel(logging.WARNING)
1212
975
console.setLevel(logging.WARNING)
1214
if server_settings[u"servicename"] != u"Mandos":
977
if server_settings["servicename"] != "Mandos":
1215
978
syslogger.setFormatter(logging.Formatter
1216
(u'Mandos (%s) [%%(process)d]:'
1217
u' %%(levelname)s: %%(message)s'
1218
% server_settings[u"servicename"]))
979
('Mandos (%s): %%(levelname)s:'
981
% server_settings["servicename"]))
1220
983
# Parse config file with clients
1221
client_defaults = { u"timeout": u"1h",
1223
u"checker": u"fping -q -- %%(host)s",
984
client_defaults = { "timeout": "1h",
986
"checker": "fping -q -- %%(host)s",
1226
client_config = configparser.SafeConfigParser(client_defaults)
1227
client_config.read(os.path.join(server_settings[u"configdir"],
1230
global mandos_dbus_service
1231
mandos_dbus_service = None
1234
tcp_server = IPv6_TCPServer((server_settings[u"address"],
1235
server_settings[u"port"]),
1238
server_settings[u"interface"],
1242
server_settings[u"priority"],
1244
pidfilename = u"/var/run/mandos.pid"
1246
pidfile = open(pidfilename, u"w")
1248
logger.error(u"Could not open file %r", pidfilename)
1251
uid = pwd.getpwnam(u"_mandos").pw_uid
1252
gid = pwd.getpwnam(u"_mandos").pw_gid
989
client_config = ConfigParser.SafeConfigParser(client_defaults)
990
client_config.read(os.path.join(server_settings["configdir"],
994
tcp_server = IPv6_TCPServer((server_settings["address"],
995
server_settings["port"]),
997
settings=server_settings,
999
pidfilename = "/var/run/mandos.pid"
1001
pidfile = open(pidfilename, "w")
1002
except IOError, error:
1003
logger.error("Could not open file %r", pidfilename)
1006
uid = pwd.getpwnam("_mandos").pw_uid
1007
gid = pwd.getpwnam("_mandos").pw_gid
1253
1008
except KeyError:
1255
uid = pwd.getpwnam(u"mandos").pw_uid
1256
gid = pwd.getpwnam(u"mandos").pw_gid
1010
uid = pwd.getpwnam("mandos").pw_uid
1011
gid = pwd.getpwnam("mandos").pw_gid
1257
1012
except KeyError:
1259
uid = pwd.getpwnam(u"nobody").pw_uid
1260
gid = pwd.getpwnam(u"nobody").pw_gid
1014
uid = pwd.getpwnam("nobody").pw_uid
1015
gid = pwd.getpwnam("nogroup").pw_gid
1261
1016
except KeyError:
1267
1022
except OSError, error:
1268
1023
if error[0] != errno.EPERM:
1271
# Enable all possible GnuTLS debugging
1273
# "Use a log level over 10 to enable all debugging options."
1275
gnutls.library.functions.gnutls_global_set_log_level(11)
1277
@gnutls.library.types.gnutls_log_func
1278
def debug_gnutls(level, string):
1279
logger.debug(u"GnuTLS: %s", string[:-1])
1281
(gnutls.library.functions
1282
.gnutls_global_set_log_function(debug_gnutls))
1285
protocol = avahi.PROTO_INET6 if use_ipv6 else avahi.PROTO_INET
1286
service = AvahiService(name = server_settings[u"servicename"],
1287
servicetype = u"_mandos._tcp",
1288
protocol = protocol)
1027
service = AvahiService(name = server_settings["servicename"],
1028
servicetype = "_mandos._tcp", )
1289
1029
if server_settings["interface"]:
1290
1030
service.interface = (if_nametoindex
1291
(str(server_settings[u"interface"])))
1031
(server_settings["interface"]))
1293
1033
global main_loop