/mandos/trunk

To get this branch, use:
bzr branch http://bzr.recompile.se/loggerhead/mandos/trunk

« back to all changes in this revision

Viewing changes to mandos

  • Committer: Teddy Hogeborn
  • Date: 2019-08-02 22:16:53 UTC
  • Revision ID: teddy@recompile.se-20190802221653-ic1iko9hbefzwsk7
Fix bug in server Debian package: Fails to start on first install

There has been a very long-standing bug where installation of the
server (the "mandos" Debian package) would fail to start the server
properly right after installation.  It would work on manual (re)start
after installation, or after reboot, and even after package purge and
reinstall, it would then work the first time.  The problem, it turns
out, is when the new "_mandos" user (and corresponding group) is
created, the D-Bus server is not reloaded, and is therefore not aware
of that user, and does not recognize the user and group name in the
/etc/dbus-1/system.d/mandos.conf file.  The Mandos server, when it
tries to start and access the D-Bus, is then not permitted to connect
to its D-Bus bus name, and disables D-Bus use as a fallback measure;
i.e. the server works, but it is not controllable via D-Bus commands
(via mandos-ctl or mandos-monitor).  The next time the D-Bus daemon is
reloaded for any reason, the new user & group would become visible to
the D-Bus daemon and after that, any restart of the Mandos server
would succeed and it would bind to its D-Bus name properly, and
thereby be visible and controllable by mandos-ctl & mandos-monitor.
This was mostly invisible when using sysvinit, but systemd makes the
problem visible since the systemd service file for the Mandos server
is configured to not consider the Mandos server "started" until the
D-Bus name has been bound; this makes the starting of the service wait
for 90 seconds and then fail with a timeout error.

Fixing this should also make the Debian CI autopkgtest tests work.

* debian/mandos.postinst (configure): After creating (or renaming)
                                      user & group, reload D-Bus
                                      daemon (if present).

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
# "AvahiService" class, and some lines in "main".
12
12
#
13
13
# Everything else is
14
 
# Copyright © 2008-2018 Teddy Hogeborn
15
 
# Copyright © 2008-2018 Björn Påhlsson
 
14
# Copyright © 2008-2019 Teddy Hogeborn
 
15
# Copyright © 2008-2019 Björn Påhlsson
16
16
#
17
17
# This file is part of Mandos.
18
18
#
115
115
if sys.version_info.major == 2:
116
116
    str = unicode
117
117
 
118
 
version = "1.7.18"
 
118
version = "1.8.5"
119
119
stored_state_file = "clients.pickle"
120
120
 
121
121
logger = logging.getLogger()
275
275
 
276
276
 
277
277
# Pretend that we have an Avahi module
278
 
class Avahi(object):
279
 
    """This isn't so much a class as it is a module-like namespace.
280
 
    It is instantiated once, and simulates having an Avahi module."""
 
278
class avahi(object):
 
279
    """This isn't so much a class as it is a module-like namespace."""
281
280
    IF_UNSPEC = -1               # avahi-common/address.h
282
281
    PROTO_UNSPEC = -1            # avahi-common/address.h
283
282
    PROTO_INET = 0               # avahi-common/address.h
287
286
    DBUS_INTERFACE_SERVER = DBUS_NAME + ".Server"
288
287
    DBUS_PATH_SERVER = "/"
289
288
 
290
 
    def string_array_to_txt_array(self, t):
 
289
    @staticmethod
 
290
    def string_array_to_txt_array(t):
291
291
        return dbus.Array((dbus.ByteArray(s.encode("utf-8"))
292
292
                           for s in t), signature="ay")
293
293
    ENTRY_GROUP_ESTABLISHED = 2  # avahi-common/defs.h
298
298
    SERVER_RUNNING = 2           # avahi-common/defs.h
299
299
    SERVER_COLLISION = 3         # avahi-common/defs.h
300
300
    SERVER_FAILURE = 4           # avahi-common/defs.h
301
 
avahi = Avahi()
302
301
 
303
302
 
304
303
class AvahiError(Exception):
504
503
 
505
504
 
506
505
# Pretend that we have a GnuTLS module
507
 
class GnuTLS(object):
508
 
    """This isn't so much a class as it is a module-like namespace.
509
 
    It is instantiated once, and simulates having a GnuTLS module."""
 
506
class gnutls(object):
 
507
    """This isn't so much a class as it is a module-like namespace."""
510
508
 
511
509
    library = ctypes.util.find_library("gnutls")
512
510
    if library is None:
513
511
        library = ctypes.util.find_library("gnutls-deb0")
514
512
    _library = ctypes.cdll.LoadLibrary(library)
515
513
    del library
516
 
    _need_version = b"3.3.0"
517
 
 
518
 
    def __init__(self):
519
 
        # Need to use "self" here, since this method is called before
520
 
        # the assignment to the "gnutls" global variable happens.
521
 
        if self.check_version(self._need_version) is None:
522
 
            raise self.Error("Needs GnuTLS {} or later"
523
 
                             .format(self._need_version))
524
514
 
525
515
    # Unless otherwise indicated, the constants and types below are
526
516
    # all from the gnutls/gnutls.h C header file.
530
520
    E_INTERRUPTED = -52
531
521
    E_AGAIN = -28
532
522
    CRT_OPENPGP = 2
 
523
    CRT_RAWPK = 3
533
524
    CLIENT = 2
534
525
    SHUT_RDWR = 0
535
526
    CRD_CERTIFICATE = 1
536
527
    E_NO_CERTIFICATE_FOUND = -49
 
528
    X509_FMT_DER = 0
 
529
    NO_TICKETS = 1<<10
 
530
    ENABLE_RAWPK = 1<<18
 
531
    CTYPE_PEERS = 3
 
532
    KEYID_USE_SHA256 = 1        # gnutls/x509.h
537
533
    OPENPGP_FMT_RAW = 0         # gnutls/openpgp.h
538
534
 
539
535
    # Types
562
558
 
563
559
    # Exceptions
564
560
    class Error(Exception):
565
 
        # We need to use the class name "GnuTLS" here, since this
566
 
        # exception might be raised from within GnuTLS.__init__,
567
 
        # which is called before the assignment to the "gnutls"
568
 
        # global variable has happened.
569
561
        def __init__(self, message=None, code=None, args=()):
570
562
            # Default usage is by a message string, but if a return
571
563
            # code is passed, convert it to a string with
572
564
            # gnutls.strerror()
573
565
            self.code = code
574
566
            if message is None and code is not None:
575
 
                message = GnuTLS.strerror(code)
576
 
            return super(GnuTLS.Error, self).__init__(
 
567
                message = gnutls.strerror(code)
 
568
            return super(gnutls.Error, self).__init__(
577
569
                message, *args)
578
570
 
579
571
    class CertificateSecurityError(Error):
593
585
    class ClientSession(object):
594
586
        def __init__(self, socket, credentials=None):
595
587
            self._c_object = gnutls.session_t()
596
 
            gnutls.init(ctypes.byref(self._c_object), gnutls.CLIENT)
 
588
            gnutls_flags = gnutls.CLIENT
 
589
            if gnutls.check_version(b"3.5.6"):
 
590
                gnutls_flags |= gnutls.NO_TICKETS
 
591
            if gnutls.has_rawpk:
 
592
                gnutls_flags |= gnutls.ENABLE_RAWPK
 
593
            gnutls.init(ctypes.byref(self._c_object), gnutls_flags)
 
594
            del gnutls_flags
597
595
            gnutls.set_default_priority(self._c_object)
598
596
            gnutls.transport_set_ptr(self._c_object, socket.fileno())
599
597
            gnutls.handshake_set_private_extensions(self._c_object,
731
729
    check_version.argtypes = [ctypes.c_char_p]
732
730
    check_version.restype = ctypes.c_char_p
733
731
 
734
 
    # All the function declarations below are from gnutls/openpgp.h
735
 
 
736
 
    openpgp_crt_init = _library.gnutls_openpgp_crt_init
737
 
    openpgp_crt_init.argtypes = [ctypes.POINTER(openpgp_crt_t)]
738
 
    openpgp_crt_init.restype = _error_code
739
 
 
740
 
    openpgp_crt_import = _library.gnutls_openpgp_crt_import
741
 
    openpgp_crt_import.argtypes = [openpgp_crt_t,
742
 
                                   ctypes.POINTER(datum_t),
743
 
                                   openpgp_crt_fmt_t]
744
 
    openpgp_crt_import.restype = _error_code
745
 
 
746
 
    openpgp_crt_verify_self = _library.gnutls_openpgp_crt_verify_self
747
 
    openpgp_crt_verify_self.argtypes = [openpgp_crt_t, ctypes.c_uint,
748
 
                                        ctypes.POINTER(ctypes.c_uint)]
749
 
    openpgp_crt_verify_self.restype = _error_code
750
 
 
751
 
    openpgp_crt_deinit = _library.gnutls_openpgp_crt_deinit
752
 
    openpgp_crt_deinit.argtypes = [openpgp_crt_t]
753
 
    openpgp_crt_deinit.restype = None
754
 
 
755
 
    openpgp_crt_get_fingerprint = (
756
 
        _library.gnutls_openpgp_crt_get_fingerprint)
757
 
    openpgp_crt_get_fingerprint.argtypes = [openpgp_crt_t,
758
 
                                            ctypes.c_void_p,
759
 
                                            ctypes.POINTER(
760
 
                                                ctypes.c_size_t)]
761
 
    openpgp_crt_get_fingerprint.restype = _error_code
 
732
    _need_version = b"3.3.0"
 
733
    if check_version(_need_version) is None:
 
734
        raise self.Error("Needs GnuTLS {} or later"
 
735
                         .format(_need_version))
 
736
 
 
737
    _tls_rawpk_version = b"3.6.6"
 
738
    has_rawpk = bool(check_version(_tls_rawpk_version))
 
739
 
 
740
    if has_rawpk:
 
741
        # Types
 
742
        class pubkey_st(ctypes.Structure):
 
743
            _fields = []
 
744
        pubkey_t = ctypes.POINTER(pubkey_st)
 
745
 
 
746
        x509_crt_fmt_t = ctypes.c_int
 
747
 
 
748
        # All the function declarations below are from gnutls/abstract.h
 
749
        pubkey_init = _library.gnutls_pubkey_init
 
750
        pubkey_init.argtypes = [ctypes.POINTER(pubkey_t)]
 
751
        pubkey_init.restype = _error_code
 
752
 
 
753
        pubkey_import = _library.gnutls_pubkey_import
 
754
        pubkey_import.argtypes = [pubkey_t, ctypes.POINTER(datum_t),
 
755
                                  x509_crt_fmt_t]
 
756
        pubkey_import.restype = _error_code
 
757
 
 
758
        pubkey_get_key_id = _library.gnutls_pubkey_get_key_id
 
759
        pubkey_get_key_id.argtypes = [pubkey_t, ctypes.c_int,
 
760
                                      ctypes.POINTER(ctypes.c_ubyte),
 
761
                                      ctypes.POINTER(ctypes.c_size_t)]
 
762
        pubkey_get_key_id.restype = _error_code
 
763
 
 
764
        pubkey_deinit = _library.gnutls_pubkey_deinit
 
765
        pubkey_deinit.argtypes = [pubkey_t]
 
766
        pubkey_deinit.restype = None
 
767
    else:
 
768
        # All the function declarations below are from gnutls/openpgp.h
 
769
 
 
770
        openpgp_crt_init = _library.gnutls_openpgp_crt_init
 
771
        openpgp_crt_init.argtypes = [ctypes.POINTER(openpgp_crt_t)]
 
772
        openpgp_crt_init.restype = _error_code
 
773
 
 
774
        openpgp_crt_import = _library.gnutls_openpgp_crt_import
 
775
        openpgp_crt_import.argtypes = [openpgp_crt_t,
 
776
                                       ctypes.POINTER(datum_t),
 
777
                                       openpgp_crt_fmt_t]
 
778
        openpgp_crt_import.restype = _error_code
 
779
 
 
780
        openpgp_crt_verify_self = _library.gnutls_openpgp_crt_verify_self
 
781
        openpgp_crt_verify_self.argtypes = [openpgp_crt_t, ctypes.c_uint,
 
782
                                            ctypes.POINTER(ctypes.c_uint)]
 
783
        openpgp_crt_verify_self.restype = _error_code
 
784
 
 
785
        openpgp_crt_deinit = _library.gnutls_openpgp_crt_deinit
 
786
        openpgp_crt_deinit.argtypes = [openpgp_crt_t]
 
787
        openpgp_crt_deinit.restype = None
 
788
 
 
789
        openpgp_crt_get_fingerprint = (
 
790
            _library.gnutls_openpgp_crt_get_fingerprint)
 
791
        openpgp_crt_get_fingerprint.argtypes = [openpgp_crt_t,
 
792
                                                ctypes.c_void_p,
 
793
                                                ctypes.POINTER(
 
794
                                                    ctypes.c_size_t)]
 
795
        openpgp_crt_get_fingerprint.restype = _error_code
 
796
 
 
797
    if check_version(b"3.6.4"):
 
798
        certificate_type_get2 = _library.gnutls_certificate_type_get2
 
799
        certificate_type_get2.argtypes = [session_t, ctypes.c_int]
 
800
        certificate_type_get2.restype = _error_code
762
801
 
763
802
    # Remove non-public functions
764
803
    del _error_code, _retry_on_error
765
 
# Create the global "gnutls" object, simulating a module
766
 
gnutls = GnuTLS()
767
804
 
768
805
 
769
806
def call_pipe(connection,       # : multiprocessing.Connection
784
821
    approved:   bool(); 'None' if not yet approved/disapproved
785
822
    approval_delay: datetime.timedelta(); Time to wait for approval
786
823
    approval_duration: datetime.timedelta(); Duration of one approval
787
 
    checker:    subprocess.Popen(); a running checker process used
788
 
                                    to see if the client lives.
789
 
                                    'None' if no process is running.
 
824
    checker: multiprocessing.Process(); a running checker process used
 
825
             to see if the client lives. 'None' if no process is
 
826
             running.
790
827
    checker_callback_tag: a GLib event source tag, or None
791
828
    checker_command: string; External command which is run to check
792
829
                     if client lives.  %() expansions are done at
800
837
    disable_initiator_tag: a GLib event source tag, or None
801
838
    enabled:    bool()
802
839
    fingerprint: string (40 or 32 hexadecimal digits); used to
803
 
                 uniquely identify the client
 
840
                 uniquely identify an OpenPGP client
 
841
    key_id: string (64 hexadecimal digits); used to uniquely identify
 
842
            a client using raw public keys
804
843
    host:       string; available for use by the checker command
805
844
    interval:   datetime.timedelta(); How often to start a new checker
806
845
    last_approval_request: datetime.datetime(); (UTC) or None
824
863
    """
825
864
 
826
865
    runtime_expansions = ("approval_delay", "approval_duration",
827
 
                          "created", "enabled", "expires",
 
866
                          "created", "enabled", "expires", "key_id",
828
867
                          "fingerprint", "host", "interval",
829
868
                          "last_approval_request", "last_checked_ok",
830
869
                          "last_enabled", "name", "timeout")
860
899
            client["enabled"] = config.getboolean(client_name,
861
900
                                                  "enabled")
862
901
 
863
 
            # Uppercase and remove spaces from fingerprint for later
864
 
            # comparison purposes with return value from the
865
 
            # fingerprint() function
 
902
            # Uppercase and remove spaces from key_id and fingerprint
 
903
            # for later comparison purposes with return value from the
 
904
            # key_id() and fingerprint() functions
 
905
            client["key_id"] = (section.get("key_id", "").upper()
 
906
                                .replace(" ", ""))
866
907
            client["fingerprint"] = (section["fingerprint"].upper()
867
908
                                     .replace(" ", ""))
868
909
            if "secret" in section:
912
953
            self.expires = None
913
954
 
914
955
        logger.debug("Creating client %r", self.name)
 
956
        logger.debug("  Key ID: %s", self.key_id)
915
957
        logger.debug("  Fingerprint: %s", self.fingerprint)
916
958
        self.created = settings.get("created",
917
959
                                    datetime.datetime.utcnow())
994
1036
    def checker_callback(self, source, condition, connection,
995
1037
                         command):
996
1038
        """The checker has completed, so take appropriate actions."""
997
 
        self.checker_callback_tag = None
998
 
        self.checker = None
999
1039
        # Read return code from connection (see call_pipe)
1000
1040
        returncode = connection.recv()
1001
1041
        connection.close()
 
1042
        self.checker.join()
 
1043
        self.checker_callback_tag = None
 
1044
        self.checker = None
1002
1045
 
1003
1046
        if returncode >= 0:
1004
1047
            self.last_checker_status = returncode
1999
2042
    def Name_dbus_property(self):
2000
2043
        return dbus.String(self.name)
2001
2044
 
 
2045
    # KeyID - property
 
2046
    @dbus_annotations(
 
2047
        {"org.freedesktop.DBus.Property.EmitsChangedSignal": "const"})
 
2048
    @dbus_service_property(_interface, signature="s", access="read")
 
2049
    def KeyID_dbus_property(self):
 
2050
        return dbus.String(self.key_id)
 
2051
 
2002
2052
    # Fingerprint - property
2003
2053
    @dbus_annotations(
2004
2054
        {"org.freedesktop.DBus.Property.EmitsChangedSignal": "const"})
2160
2210
 
2161
2211
 
2162
2212
class ProxyClient(object):
2163
 
    def __init__(self, child_pipe, fpr, address):
 
2213
    def __init__(self, child_pipe, key_id, fpr, address):
2164
2214
        self._pipe = child_pipe
2165
 
        self._pipe.send(('init', fpr, address))
 
2215
        self._pipe.send(('init', key_id, fpr, address))
2166
2216
        if not self._pipe.recv():
2167
 
            raise KeyError(fpr)
 
2217
            raise KeyError(key_id or fpr)
2168
2218
 
2169
2219
    def __getattribute__(self, name):
2170
2220
        if name == '_pipe':
2237
2287
 
2238
2288
            approval_required = False
2239
2289
            try:
2240
 
                try:
2241
 
                    fpr = self.fingerprint(
2242
 
                        self.peer_certificate(session))
2243
 
                except (TypeError, gnutls.Error) as error:
2244
 
                    logger.warning("Bad certificate: %s", error)
2245
 
                    return
2246
 
                logger.debug("Fingerprint: %s", fpr)
2247
 
 
2248
 
                try:
2249
 
                    client = ProxyClient(child_pipe, fpr,
 
2290
                if gnutls.has_rawpk:
 
2291
                    fpr = b""
 
2292
                    try:
 
2293
                        key_id = self.key_id(
 
2294
                            self.peer_certificate(session))
 
2295
                    except (TypeError, gnutls.Error) as error:
 
2296
                        logger.warning("Bad certificate: %s", error)
 
2297
                        return
 
2298
                    logger.debug("Key ID: %s", key_id)
 
2299
 
 
2300
                else:
 
2301
                    key_id = b""
 
2302
                    try:
 
2303
                        fpr = self.fingerprint(
 
2304
                            self.peer_certificate(session))
 
2305
                    except (TypeError, gnutls.Error) as error:
 
2306
                        logger.warning("Bad certificate: %s", error)
 
2307
                        return
 
2308
                    logger.debug("Fingerprint: %s", fpr)
 
2309
 
 
2310
                try:
 
2311
                    client = ProxyClient(child_pipe, key_id, fpr,
2250
2312
                                         self.client_address)
2251
2313
                except KeyError:
2252
2314
                    return
2329
2391
 
2330
2392
    @staticmethod
2331
2393
    def peer_certificate(session):
2332
 
        "Return the peer's OpenPGP certificate as a bytestring"
2333
 
        # If not an OpenPGP certificate...
2334
 
        if (gnutls.certificate_type_get(session._c_object)
2335
 
            != gnutls.CRT_OPENPGP):
 
2394
        "Return the peer's certificate as a bytestring"
 
2395
        try:
 
2396
            cert_type = gnutls.certificate_type_get2(session._c_object,
 
2397
                                                     gnutls.CTYPE_PEERS)
 
2398
        except AttributeError:
 
2399
            cert_type = gnutls.certificate_type_get(session._c_object)
 
2400
        if gnutls.has_rawpk:
 
2401
            valid_cert_types = frozenset((gnutls.CRT_RAWPK,))
 
2402
        else:
 
2403
            valid_cert_types = frozenset((gnutls.CRT_OPENPGP,))
 
2404
        # If not a valid certificate type...
 
2405
        if cert_type not in valid_cert_types:
 
2406
            logger.info("Cert type %r not in %r", cert_type,
 
2407
                        valid_cert_types)
2336
2408
            # ...return invalid data
2337
2409
            return b""
2338
2410
        list_size = ctypes.c_uint(1)
2346
2418
        return ctypes.string_at(cert.data, cert.size)
2347
2419
 
2348
2420
    @staticmethod
 
2421
    def key_id(certificate):
 
2422
        "Convert a certificate bytestring to a hexdigit key ID"
 
2423
        # New GnuTLS "datum" with the public key
 
2424
        datum = gnutls.datum_t(
 
2425
            ctypes.cast(ctypes.c_char_p(certificate),
 
2426
                        ctypes.POINTER(ctypes.c_ubyte)),
 
2427
            ctypes.c_uint(len(certificate)))
 
2428
        # XXX all these need to be created in the gnutls "module"
 
2429
        # New empty GnuTLS certificate
 
2430
        pubkey = gnutls.pubkey_t()
 
2431
        gnutls.pubkey_init(ctypes.byref(pubkey))
 
2432
        # Import the raw public key into the certificate
 
2433
        gnutls.pubkey_import(pubkey,
 
2434
                             ctypes.byref(datum),
 
2435
                             gnutls.X509_FMT_DER)
 
2436
        # New buffer for the key ID
 
2437
        buf = ctypes.create_string_buffer(32)
 
2438
        buf_len = ctypes.c_size_t(len(buf))
 
2439
        # Get the key ID from the raw public key into the buffer
 
2440
        gnutls.pubkey_get_key_id(pubkey,
 
2441
                                 gnutls.KEYID_USE_SHA256,
 
2442
                                 ctypes.cast(ctypes.byref(buf),
 
2443
                                             ctypes.POINTER(ctypes.c_ubyte)),
 
2444
                                 ctypes.byref(buf_len))
 
2445
        # Deinit the certificate
 
2446
        gnutls.pubkey_deinit(pubkey)
 
2447
 
 
2448
        # Convert the buffer to a Python bytestring
 
2449
        key_id = ctypes.string_at(buf, buf_len.value)
 
2450
        # Convert the bytestring to hexadecimal notation
 
2451
        hex_key_id = binascii.hexlify(key_id).upper()
 
2452
        return hex_key_id
 
2453
 
 
2454
    @staticmethod
2349
2455
    def fingerprint(openpgp):
2350
2456
        "Convert an OpenPGP bytestring to a hexdigit fingerprint"
2351
2457
        # New GnuTLS "datum" with the OpenPGP public key
2365
2471
                                       ctypes.byref(crtverify))
2366
2472
        if crtverify.value != 0:
2367
2473
            gnutls.openpgp_crt_deinit(crt)
2368
 
            raise gnutls.CertificateSecurityError("Verify failed")
 
2474
            raise gnutls.CertificateSecurityError(code
 
2475
                                                  =crtverify.value)
2369
2476
        # New buffer for the fingerprint
2370
2477
        buf = ctypes.create_string_buffer(20)
2371
2478
        buf_len = ctypes.c_size_t()
2499
2606
                    raise
2500
2607
        # Only bind(2) the socket if we really need to.
2501
2608
        if self.server_address[0] or self.server_address[1]:
 
2609
            if self.server_address[1]:
 
2610
                self.allow_reuse_address = True
2502
2611
            if not self.server_address[0]:
2503
2612
                if self.address_family == socket.AF_INET6:
2504
2613
                    any_address = "::"  # in6addr_any
2578
2687
        command = request[0]
2579
2688
 
2580
2689
        if command == 'init':
2581
 
            fpr = request[1].decode("ascii")
2582
 
            address = request[2]
 
2690
            key_id = request[1].decode("ascii")
 
2691
            fpr = request[2].decode("ascii")
 
2692
            address = request[3]
2583
2693
 
2584
2694
            for c in self.clients.values():
2585
 
                if c.fingerprint == fpr:
 
2695
                if key_id == "E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855":
 
2696
                    continue
 
2697
                if key_id and c.key_id == key_id:
 
2698
                    client = c
 
2699
                    break
 
2700
                if fpr and c.fingerprint == fpr:
2586
2701
                    client = c
2587
2702
                    break
2588
2703
            else:
2589
 
                logger.info("Client not found for fingerprint: %s, ad"
2590
 
                            "dress: %s", fpr, address)
 
2704
                logger.info("Client not found for key ID: %s, address"
 
2705
                            ": %s", key_id or fpr, address)
2591
2706
                if self.use_dbus:
2592
2707
                    # Emit D-Bus signal
2593
 
                    mandos_dbus_service.ClientNotFound(fpr,
 
2708
                    mandos_dbus_service.ClientNotFound(key_id or fpr,
2594
2709
                                                       address[0])
2595
2710
                parent_pipe.send(False)
2596
2711
                return False
2859
2974
        sys.exit(os.EX_OK if fail_count == 0 else 1)
2860
2975
 
2861
2976
    # Default values for config file for server-global settings
 
2977
    if gnutls.has_rawpk:
 
2978
        priority = ("SECURE128:!CTYPE-X.509:+CTYPE-RAWPK:!RSA"
 
2979
                    ":!VERS-ALL:+VERS-TLS1.3:%PROFILE_ULTRA")
 
2980
    else:
 
2981
        priority = ("SECURE256:!CTYPE-X.509:+CTYPE-OPENPGP:!RSA"
 
2982
                    ":+SIGN-DSA-SHA256")
2862
2983
    server_defaults = {"interface": "",
2863
2984
                       "address": "",
2864
2985
                       "port": "",
2865
2986
                       "debug": "False",
2866
 
                       "priority":
2867
 
                       "SECURE256:!CTYPE-X.509:+CTYPE-OPENPGP:!RSA"
2868
 
                       ":+SIGN-DSA-SHA256",
 
2987
                       "priority": priority,
2869
2988
                       "servicename": "Mandos",
2870
2989
                       "use_dbus": "True",
2871
2990
                       "use_ipv6": "True",
2876
2995
                       "foreground": "False",
2877
2996
                       "zeroconf": "True",
2878
2997
                       }
 
2998
    del priority
2879
2999
 
2880
3000
    # Parse config file for server-global settings
2881
3001
    server_config = configparser.SafeConfigParser(server_defaults)
3125
3245
                        for k in ("name", "host"):
3126
3246
                            if isinstance(value[k], bytes):
3127
3247
                                value[k] = value[k].decode("utf-8")
 
3248
                        if "key_id" not in value:
 
3249
                            value["key_id"] = ""
 
3250
                        elif "fingerprint" not in value:
 
3251
                            value["fingerprint"] = ""
3128
3252
                    #  old_client_settings
3129
3253
                    # .keys()
3130
3254
                    old_client_settings = {
3267
3391
                pass
3268
3392
 
3269
3393
            @dbus.service.signal(_interface, signature="ss")
3270
 
            def ClientNotFound(self, fingerprint, address):
 
3394
            def ClientNotFound(self, key_id, address):
3271
3395
                "D-Bus signal"
3272
3396
                pass
3273
3397