456
430
if error.errno != errno.ESRCH: # No such process
458
432
self.checker = None
460
self.PropertyChanged(dbus.String(u"checker_running"),
461
dbus.Boolean(False, variant_level=1))
463
434
def still_valid(self):
464
435
"""Has the timeout not yet passed for this client?"""
465
if not getattr(self, "enabled", False):
436
if not getattr(self, u"enabled", False):
467
438
now = datetime.datetime.utcnow()
468
439
if self.last_checked_ok is None:
469
440
return now < (self.created + self.timeout)
471
442
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))
473
549
## D-Bus methods & signals
474
550
_interface = u"se.bsnet.fukt.Mandos.Client"
476
552
# CheckedOK - method
477
CheckedOK = dbus.service.method(_interface)(checked_ok)
478
CheckedOK.__name__ = "CheckedOK"
553
@dbus.service.method(_interface)
555
return self.checked_ok()
480
557
# CheckerCompleted - signal
481
@dbus.service.signal(_interface, signature="nxs")
558
@dbus.service.signal(_interface, signature=u"nxs")
482
559
def CheckerCompleted(self, exitcode, waitstatus, command):
486
563
# CheckerStarted - signal
487
@dbus.service.signal(_interface, signature="s")
564
@dbus.service.signal(_interface, signature=u"s")
488
565
def CheckerStarted(self, command):
492
569
# GetAllProperties - method
493
@dbus.service.method(_interface, out_signature="a{sv}")
570
@dbus.service.method(_interface, out_signature=u"a{sv}")
494
571
def GetAllProperties(self):
496
573
return dbus.Dictionary({
574
dbus.String(u"name"):
498
575
dbus.String(self.name, variant_level=1),
499
dbus.String("fingerprint"):
576
dbus.String(u"fingerprint"):
500
577
dbus.String(self.fingerprint, variant_level=1),
578
dbus.String(u"host"):
502
579
dbus.String(self.host, variant_level=1),
503
dbus.String("created"):
580
dbus.String(u"created"):
504
581
_datetime_to_dbus(self.created, variant_level=1),
505
dbus.String("last_enabled"):
582
dbus.String(u"last_enabled"):
506
583
(_datetime_to_dbus(self.last_enabled,
508
585
if self.last_enabled is not None
509
586
else dbus.Boolean(False, variant_level=1)),
510
dbus.String("enabled"):
587
dbus.String(u"enabled"):
511
588
dbus.Boolean(self.enabled, variant_level=1),
512
dbus.String("last_checked_ok"):
589
dbus.String(u"last_checked_ok"):
513
590
(_datetime_to_dbus(self.last_checked_ok,
515
592
if self.last_checked_ok is not None
516
593
else dbus.Boolean (False, variant_level=1)),
517
dbus.String("timeout"):
594
dbus.String(u"timeout"):
518
595
dbus.UInt64(self.timeout_milliseconds(),
519
596
variant_level=1),
520
dbus.String("interval"):
597
dbus.String(u"interval"):
521
598
dbus.UInt64(self.interval_milliseconds(),
522
599
variant_level=1),
523
dbus.String("checker"):
600
dbus.String(u"checker"):
524
601
dbus.String(self.checker_command,
525
602
variant_level=1),
526
dbus.String("checker_running"):
603
dbus.String(u"checker_running"):
527
604
dbus.Boolean(self.checker is not None,
528
605
variant_level=1),
529
dbus.String("object_path"):
606
dbus.String(u"object_path"):
530
607
dbus.ObjectPath(self.dbus_object_path,
534
611
# IsStillValid - method
535
IsStillValid = (dbus.service.method(_interface, out_signature="b")
537
IsStillValid.__name__ = "IsStillValid"
612
@dbus.service.method(_interface, out_signature=u"b")
613
def IsStillValid(self):
614
return self.still_valid()
539
616
# PropertyChanged - signal
540
@dbus.service.signal(_interface, signature="sv")
617
@dbus.service.signal(_interface, signature=u"sv")
541
618
def PropertyChanged(self, property, value):
622
# ReceivedSecret - signal
623
@dbus.service.signal(_interface)
624
def ReceivedSecret(self):
629
@dbus.service.signal(_interface)
545
634
# SetChecker - method
546
@dbus.service.method(_interface, in_signature="s")
635
@dbus.service.method(_interface, in_signature=u"s")
547
636
def SetChecker(self, checker):
548
637
"D-Bus setter method"
549
638
self.checker_command = checker
605
696
# StopChecker - method
606
StopChecker = dbus.service.method(_interface)(stop_checker)
607
StopChecker.__name__ = "StopChecker"
697
@dbus.service.method(_interface)
698
def StopChecker(self):
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.
704
class ClientHandler(socketserver.BaseRequestHandler, object):
705
"""A class to handle client connections.
707
Instantiated once for each connection to handle it.
676
708
Note: This will run in its own forked process."""
678
710
def handle(self):
679
711
logger.info(u"TCP connection from: %s",
680
712
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):
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):
756
878
"""IPv6-capable TCP server. Accepts 'None' as address and/or port
758
settings: Server settings
759
clients: Set() of Client objects
760
881
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
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"]
889
def __init__(self, server_address, RequestHandlerClass,
890
interface=None, use_ipv6=True, clients=None,
891
gnutls_priority=None, use_dbus=True):
774
892
self.enabled = False
775
super(IPv6_TCPServer, self).__init__(*args, **kwargs)
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,
776
901
def server_bind(self):
777
902
"""This overrides the normal server_bind() function
778
903
to bind to an interface if one was specified, and also NOT to
779
904
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)
905
if self.interface is not None:
784
907
self.socket.setsockopt(socket.SOL_SOCKET,
786
self.settings["interface"])
909
str(self.interface + u'\0'))
787
910
except socket.error, error:
788
911
if error[0] == errno.EPERM:
789
912
logger.error(u"No permission to"
790
913
u" bind to interface %s",
791
self.settings["interface"])
794
917
# Only bind(2) the socket if we really need to.
795
918
if self.server_address[0] or self.server_address[1]:
796
919
if not self.server_address[0]:
797
920
if self.address_family == socket.AF_INET6:
798
any_address = "::" # in6addr_any
921
any_address = u"::" # in6addr_any
800
923
any_address = socket.INADDR_ANY
801
924
self.server_address = (any_address,
803
926
elif not self.server_address[1]:
804
927
self.server_address = (self.server_address[0],
806
# if self.settings["interface"]:
807
930
# self.server_address = (self.server_address[0],
813
return super(IPv6_TCPServer, self).server_bind()
935
return socketserver.TCPServer.server_bind(self)
814
936
def server_activate(self):
816
return super(IPv6_TCPServer, self).server_activate()
938
return socketserver.TCPServer.server_activate(self)
817
939
def enable(self):
818
940
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
821
1013
def string_to_delta(interval):
822
1014
"""Parse a string and return a datetime.timedelta
824
>>> string_to_delta('7d')
1016
>>> string_to_delta(u'7d')
825
1017
datetime.timedelta(7)
826
>>> string_to_delta('60s')
1018
>>> string_to_delta(u'60s')
827
1019
datetime.timedelta(0, 60)
828
>>> string_to_delta('60m')
1020
>>> string_to_delta(u'60m')
829
1021
datetime.timedelta(0, 3600)
830
>>> string_to_delta('24h')
1022
>>> string_to_delta(u'24h')
831
1023
datetime.timedelta(1)
832
1024
>>> string_to_delta(u'1w')
833
1025
datetime.timedelta(7)
834
>>> string_to_delta('5m 30s')
1026
>>> string_to_delta(u'5m 30s')
835
1027
datetime.timedelta(0, 330)
837
1029
timevalue = datetime.timedelta(0)
1125
######################################################################
1126
# Parsing of options, both command line and config file
930
1128
parser = optparse.OptionParser(version = "%%prog %s" % version)
931
parser.add_option("-i", "--interface", type="string",
932
metavar="IF", help="Bind to interface IF")
933
parser.add_option("-a", "--address", type="string",
934
help="Address to listen for requests on")
935
parser.add_option("-p", "--port", type="int",
936
help="Port number to receive requests on")
937
parser.add_option("--check", action="store_true",
938
help="Run self-test")
939
parser.add_option("--debug", action="store_true",
940
help="Debug mode; run in foreground and log to"
942
parser.add_option("--priority", type="string", help="GnuTLS"
943
" priority string (see GnuTLS documentation)")
944
parser.add_option("--servicename", type="string", metavar="NAME",
945
help="Zeroconf service name")
946
parser.add_option("--configdir", type="string",
947
default="/etc/mandos", metavar="DIR",
948
help="Directory to search for configuration"
950
parser.add_option("--no-dbus", action="store_false",
952
help="Do not provide D-Bus system bus"
954
parser.add_option("--no-ipv6", action="store_false",
955
dest="use_ipv6", help="Do not use IPv6")
1129
parser.add_option("-i", u"--interface", type=u"string",
1130
metavar="IF", help=u"Bind to interface IF")
1131
parser.add_option("-a", u"--address", type=u"string",
1132
help=u"Address to listen for requests on")
1133
parser.add_option("-p", u"--port", type=u"int",
1134
help=u"Port number to receive requests on")
1135
parser.add_option("--check", action=u"store_true",
1136
help=u"Run self-test")
1137
parser.add_option("--debug", action=u"store_true",
1138
help=u"Debug mode; run in foreground and log to"
1140
parser.add_option("--priority", type=u"string", help=u"GnuTLS"
1141
u" priority string (see GnuTLS documentation)")
1142
parser.add_option("--servicename", type=u"string",
1143
metavar=u"NAME", help=u"Zeroconf service name")
1144
parser.add_option("--configdir", type=u"string",
1145
default=u"/etc/mandos", metavar=u"DIR",
1146
help=u"Directory to search for configuration"
1148
parser.add_option("--no-dbus", action=u"store_false",
1149
dest=u"use_dbus", help=u"Do not provide D-Bus"
1150
u" system bus interface")
1151
parser.add_option("--no-ipv6", action=u"store_false",
1152
dest=u"use_ipv6", help=u"Do not use IPv6")
956
1153
options = parser.parse_args()[0]
958
1155
if options.check:
963
1160
# Default values for config file for server-global settings
964
server_defaults = { "interface": "",
969
"SECURE256:!CTYPE-X.509:+CTYPE-OPENPGP",
970
"servicename": "Mandos",
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",
975
1172
# Parse config file for server-global settings
976
server_config = ConfigParser.SafeConfigParser(server_defaults)
1173
server_config = configparser.SafeConfigParser(server_defaults)
977
1174
del server_defaults
978
server_config.read(os.path.join(options.configdir, "mandos.conf"))
1175
server_config.read(os.path.join(options.configdir,
979
1177
# Convert the SafeConfigParser object to a dict
980
1178
server_settings = server_config.defaults()
981
1179
# Use the appropriate methods on the non-string config options
982
server_settings["debug"] = server_config.getboolean("DEFAULT",
984
server_settings["use_dbus"] = server_config.getboolean("DEFAULT",
986
server_settings["use_ipv6"] = server_config.getboolean("DEFAULT",
1180
for option in (u"debug", u"use_dbus", u"use_ipv6"):
1181
server_settings[option] = server_config.getboolean(u"DEFAULT",
988
1183
if server_settings["port"]:
989
server_settings["port"] = server_config.getint("DEFAULT",
1184
server_settings["port"] = server_config.getint(u"DEFAULT",
991
1186
del server_config
993
1188
# Override the settings from the config file with command line
994
1189
# options, if set.
995
for option in ("interface", "address", "port", "debug",
996
"priority", "servicename", "configdir",
997
"use_dbus", "use_ipv6"):
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"):
998
1193
value = getattr(options, option)
999
1194
if value is not None:
1000
1195
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])
1002
1201
# Now we have our good server settings in "server_settings"
1203
##################################################################
1004
1205
# For convenience
1005
debug = server_settings["debug"]
1006
use_dbus = server_settings["use_dbus"]
1007
use_ipv6 = server_settings["use_ipv6"]
1206
debug = server_settings[u"debug"]
1207
use_dbus = server_settings[u"use_dbus"]
1208
use_ipv6 = server_settings[u"use_ipv6"]
1010
1211
syslogger.setLevel(logging.WARNING)
1011
1212
console.setLevel(logging.WARNING)
1013
if server_settings["servicename"] != "Mandos":
1214
if server_settings[u"servicename"] != u"Mandos":
1014
1215
syslogger.setFormatter(logging.Formatter
1015
('Mandos (%s): %%(levelname)s:'
1017
% server_settings["servicename"]))
1216
(u'Mandos (%s) [%%(process)d]:'
1217
u' %%(levelname)s: %%(message)s'
1218
% server_settings[u"servicename"]))
1019
1220
# Parse config file with clients
1020
client_defaults = { "timeout": "1h",
1022
"checker": "fping -q -- %%(host)s",
1221
client_defaults = { u"timeout": u"1h",
1223
u"checker": u"fping -q -- %%(host)s",
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"
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"
1037
pidfile = open(pidfilename, "w")
1246
pidfile = open(pidfilename, u"w")
1038
1247
except IOError:
1039
logger.error("Could not open file %r", pidfilename)
1248
logger.error(u"Could not open file %r", pidfilename)
1042
uid = pwd.getpwnam("_mandos").pw_uid
1043
gid = pwd.getpwnam("_mandos").pw_gid
1251
uid = pwd.getpwnam(u"_mandos").pw_uid
1252
gid = pwd.getpwnam(u"_mandos").pw_gid
1044
1253
except KeyError:
1046
uid = pwd.getpwnam("mandos").pw_uid
1047
gid = pwd.getpwnam("mandos").pw_gid
1255
uid = pwd.getpwnam(u"mandos").pw_uid
1256
gid = pwd.getpwnam(u"mandos").pw_gid
1048
1257
except KeyError:
1050
uid = pwd.getpwnam("nobody").pw_uid
1051
gid = pwd.getpwnam("nogroup").pw_gid
1259
uid = pwd.getpwnam(u"nobody").pw_uid
1260
gid = pwd.getpwnam(u"nobody").pw_gid
1052
1261
except KeyError: