/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-02-11 06:14:29 UTC
  • Revision ID: teddy@recompile.se-20190211061429-n6n5zk29iatshlb3
Fix Debian package dependencies

* debian/control (Build-Depends): Changed GnuTLS dependencies to
                                  "libgnutls30 (>= 3.3.0),
                                  libgnutls28-dev (>= 3.6.6) |
                                  libgnutls28-dev (<< 3.6.0)".  (We
                                  can't depend on the virtual package
                                  "gnutls-dev", since we need the
                                  version restrictions.)
  (Package: mandos/Depends): Remove dependency on libgnutls28-dev
                             package.
  (Package: mandos/Suggests): New; set to "libc6-dev,
                              c-compiler". (Used to find value of
                              "SO_BINDTODEVICE").
  (Package: mandos-client/Depends): Don't depend on openssl anymore;
                                    instead depend on either a
                                    gnutls-bin (>= 3.6.6) (in which
                                    case TLS key generation will
                                    work), or on libgnutls30 (<<
                                    3.6.0) (in which case TLS key
                                    generation will not be needed).

Show diffs side-by-side

added added

removed removed

Lines of Context:
115
115
if sys.version_info.major == 2:
116
116
    str = unicode
117
117
 
118
 
version = "1.8.4"
 
118
version = "1.8.2"
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."""
 
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."""
280
281
    IF_UNSPEC = -1               # avahi-common/address.h
281
282
    PROTO_UNSPEC = -1            # avahi-common/address.h
282
283
    PROTO_INET = 0               # avahi-common/address.h
286
287
    DBUS_INTERFACE_SERVER = DBUS_NAME + ".Server"
287
288
    DBUS_PATH_SERVER = "/"
288
289
 
289
 
    @staticmethod
290
 
    def string_array_to_txt_array(t):
 
290
    def string_array_to_txt_array(self, 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()
301
302
 
302
303
 
303
304
class AvahiError(Exception):
503
504
 
504
505
 
505
506
# Pretend that we have a GnuTLS module
506
 
class gnutls(object):
507
 
    """This isn't so much a class as it is a module-like namespace."""
 
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."""
508
510
 
509
511
    library = ctypes.util.find_library("gnutls")
510
512
    if library is None:
511
513
        library = ctypes.util.find_library("gnutls-deb0")
512
514
    _library = ctypes.cdll.LoadLibrary(library)
513
515
    del library
 
516
    _need_version = b"3.3.0"
 
517
    _tls_rawpk_version = b"3.6.6"
 
518
 
 
519
    def __init__(self):
 
520
        # Need to use "self" here, since this method is called before
 
521
        # the assignment to the "gnutls" global variable happens.
 
522
        if self.check_version(self._need_version) is None:
 
523
            raise self.Error("Needs GnuTLS {} or later"
 
524
                             .format(self._need_version))
514
525
 
515
526
    # Unless otherwise indicated, the constants and types below are
516
527
    # all from the gnutls/gnutls.h C header file.
558
569
 
559
570
    # Exceptions
560
571
    class Error(Exception):
 
572
        # We need to use the class name "GnuTLS" here, since this
 
573
        # exception might be raised from within GnuTLS.__init__,
 
574
        # which is called before the assignment to the "gnutls"
 
575
        # global variable has happened.
561
576
        def __init__(self, message=None, code=None, args=()):
562
577
            # Default usage is by a message string, but if a return
563
578
            # code is passed, convert it to a string with
564
579
            # gnutls.strerror()
565
580
            self.code = code
566
581
            if message is None and code is not None:
567
 
                message = gnutls.strerror(code)
568
 
            return super(gnutls.Error, self).__init__(
 
582
                message = GnuTLS.strerror(code)
 
583
            return super(GnuTLS.Error, self).__init__(
569
584
                message, *args)
570
585
 
571
586
    class CertificateSecurityError(Error):
586
601
        def __init__(self, socket, credentials=None):
587
602
            self._c_object = gnutls.session_t()
588
603
            gnutls_flags = gnutls.CLIENT
589
 
            if gnutls.check_version(b"3.5.6"):
 
604
            if gnutls.check_version("3.5.6"):
590
605
                gnutls_flags |= gnutls.NO_TICKETS
591
606
            if gnutls.has_rawpk:
592
607
                gnutls_flags |= gnutls.ENABLE_RAWPK
729
744
    check_version.argtypes = [ctypes.c_char_p]
730
745
    check_version.restype = ctypes.c_char_p
731
746
 
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
747
    has_rawpk = bool(check_version(_tls_rawpk_version))
739
748
 
740
749
    if has_rawpk:
794
803
                                                    ctypes.c_size_t)]
795
804
        openpgp_crt_get_fingerprint.restype = _error_code
796
805
 
797
 
    if check_version(b"3.6.4"):
 
806
    if check_version("3.6.4"):
798
807
        certificate_type_get2 = _library.gnutls_certificate_type_get2
799
808
        certificate_type_get2.argtypes = [session_t, ctypes.c_int]
800
809
        certificate_type_get2.restype = _error_code
801
810
 
802
811
    # Remove non-public functions
803
812
    del _error_code, _retry_on_error
 
813
# Create the global "gnutls" object, simulating a module
 
814
gnutls = GnuTLS()
804
815
 
805
816
 
806
817
def call_pipe(connection,       # : multiprocessing.Connection
821
832
    approved:   bool(); 'None' if not yet approved/disapproved
822
833
    approval_delay: datetime.timedelta(); Time to wait for approval
823
834
    approval_duration: datetime.timedelta(); Duration of one approval
824
 
    checker: multiprocessing.Process(); a running checker process used
825
 
             to see if the client lives. 'None' if no process is
826
 
             running.
 
835
    checker:    subprocess.Popen(); a running checker process used
 
836
                                    to see if the client lives.
 
837
                                    'None' if no process is running.
827
838
    checker_callback_tag: a GLib event source tag, or None
828
839
    checker_command: string; External command which is run to check
829
840
                     if client lives.  %() expansions are done at
1036
1047
    def checker_callback(self, source, condition, connection,
1037
1048
                         command):
1038
1049
        """The checker has completed, so take appropriate actions."""
 
1050
        self.checker_callback_tag = None
 
1051
        self.checker = None
1039
1052
        # Read return code from connection (see call_pipe)
1040
1053
        returncode = connection.recv()
1041
1054
        connection.close()
1042
 
        self.checker.join()
1043
 
        self.checker_callback_tag = None
1044
 
        self.checker = None
1045
1055
 
1046
1056
        if returncode >= 0:
1047
1057
            self.last_checker_status = returncode
2288
2298
            approval_required = False
2289
2299
            try:
2290
2300
                if gnutls.has_rawpk:
2291
 
                    fpr = b""
 
2301
                    fpr = ""
2292
2302
                    try:
2293
2303
                        key_id = self.key_id(
2294
2304
                            self.peer_certificate(session))
2298
2308
                    logger.debug("Key ID: %s", key_id)
2299
2309
 
2300
2310
                else:
2301
 
                    key_id = b""
 
2311
                    key_id = ""
2302
2312
                    try:
2303
2313
                        fpr = self.fingerprint(
2304
2314
                            self.peer_certificate(session))
2606
2616
                    raise
2607
2617
        # Only bind(2) the socket if we really need to.
2608
2618
        if self.server_address[0] or self.server_address[1]:
2609
 
            if self.server_address[1]:
2610
 
                self.allow_reuse_address = True
2611
2619
            if not self.server_address[0]:
2612
2620
                if self.address_family == socket.AF_INET6:
2613
2621
                    any_address = "::"  # in6addr_any
3245
3253
                        for k in ("name", "host"):
3246
3254
                            if isinstance(value[k], bytes):
3247
3255
                                value[k] = value[k].decode("utf-8")
3248
 
                        if "key_id" not in value:
 
3256
                        if not value.has_key("key_id"):
3249
3257
                            value["key_id"] = ""
3250
 
                        elif "fingerprint" not in value:
 
3258
                        elif not value.has_key("fingerprint"):
3251
3259
                            value["fingerprint"] = ""
3252
3260
                    #  old_client_settings
3253
3261
                    # .keys()