/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: 2009-04-01 03:37:45 UTC
  • Revision ID: teddy@fukt.bsnet.se-20090401033745-c89k6bij5opdm1rk
* mandos (ClientDBus.__del__): Bug fix: Correct mispasted code, and do
                               not try to call
                               dbus.service.Object.__del__() if it
                               does not exist.
  (ClientDBus.start_checker): Simplify logic.

Show diffs side-by-side

added added

removed removed

Lines of Context:
673
673
    del _interface
674
674
 
675
675
 
 
676
def peer_certificate(session):
 
677
    "Return the peer's OpenPGP certificate as a bytestring"
 
678
    # If not an OpenPGP certificate...
 
679
    if (gnutls.library.functions
 
680
        .gnutls_certificate_type_get(session._c_object)
 
681
        != gnutls.library.constants.GNUTLS_CRT_OPENPGP):
 
682
        # ...do the normal thing
 
683
        return session.peer_certificate
 
684
    list_size = ctypes.c_uint(1)
 
685
    cert_list = (gnutls.library.functions
 
686
                 .gnutls_certificate_get_peers
 
687
                 (session._c_object, ctypes.byref(list_size)))
 
688
    if not bool(cert_list) and list_size.value != 0:
 
689
        raise gnutls.errors.GNUTLSError("error getting peer"
 
690
                                        " certificate")
 
691
    if list_size.value == 0:
 
692
        return None
 
693
    cert = cert_list[0]
 
694
    return ctypes.string_at(cert.data, cert.size)
 
695
 
 
696
 
 
697
def fingerprint(openpgp):
 
698
    "Convert an OpenPGP bytestring to a hexdigit fingerprint string"
 
699
    # New GnuTLS "datum" with the OpenPGP public key
 
700
    datum = (gnutls.library.types
 
701
             .gnutls_datum_t(ctypes.cast(ctypes.c_char_p(openpgp),
 
702
                                         ctypes.POINTER
 
703
                                         (ctypes.c_ubyte)),
 
704
                             ctypes.c_uint(len(openpgp))))
 
705
    # New empty GnuTLS certificate
 
706
    crt = gnutls.library.types.gnutls_openpgp_crt_t()
 
707
    (gnutls.library.functions
 
708
     .gnutls_openpgp_crt_init(ctypes.byref(crt)))
 
709
    # Import the OpenPGP public key into the certificate
 
710
    (gnutls.library.functions
 
711
     .gnutls_openpgp_crt_import(crt, ctypes.byref(datum),
 
712
                                gnutls.library.constants
 
713
                                .GNUTLS_OPENPGP_FMT_RAW))
 
714
    # Verify the self signature in the key
 
715
    crtverify = ctypes.c_uint()
 
716
    (gnutls.library.functions
 
717
     .gnutls_openpgp_crt_verify_self(crt, 0, ctypes.byref(crtverify)))
 
718
    if crtverify.value != 0:
 
719
        gnutls.library.functions.gnutls_openpgp_crt_deinit(crt)
 
720
        raise gnutls.errors.CertificateSecurityError("Verify failed")
 
721
    # New buffer for the fingerprint
 
722
    buf = ctypes.create_string_buffer(20)
 
723
    buf_len = ctypes.c_size_t()
 
724
    # Get the fingerprint from the certificate into the buffer
 
725
    (gnutls.library.functions
 
726
     .gnutls_openpgp_crt_get_fingerprint(crt, ctypes.byref(buf),
 
727
                                         ctypes.byref(buf_len)))
 
728
    # Deinit the certificate
 
729
    gnutls.library.functions.gnutls_openpgp_crt_deinit(crt)
 
730
    # Convert the buffer to a Python bytestring
 
731
    fpr = ctypes.string_at(buf, buf_len.value)
 
732
    # Convert the bytestring to hexadecimal notation
 
733
    hex_fpr = u''.join(u"%02X" % ord(char) for char in fpr)
 
734
    return hex_fpr
 
735
 
 
736
 
676
737
class TCP_handler(SocketServer.BaseRequestHandler, object):
677
738
    """A TCP request handler class.
678
739
    Instantiated by IPv6_TCPServer for each request to handle it.
722
783
                return
723
784
            logger.debug(u"Handshake succeeded")
724
785
            try:
725
 
                fpr = self.fingerprint(self.peer_certificate(session))
 
786
                fpr = fingerprint(peer_certificate(session))
726
787
            except (TypeError, gnutls.errors.GNUTLSError), error:
727
788
                logger.warning(u"Bad certificate: %s", error)
728
789
                session.bye()
734
795
                    client = c
735
796
                    break
736
797
            else:
 
798
                logger.warning(u"Client not found for fingerprint: %s",
 
799
                               fpr)
737
800
                ipc.write("NOTFOUND %s\n" % fpr)
738
801
                session.bye()
739
802
                return
741
804
            # possible that the client timed out while establishing
742
805
            # the GnuTLS session.
743
806
            if not client.still_valid():
 
807
                logger.warning(u"Client %(name)s is invalid",
 
808
                               vars(client))
744
809
                ipc.write("INVALID %s\n" % client.name)
745
810
                session.bye()
746
811
                return
753
818
                             - (sent_size + sent))
754
819
                sent_size += sent
755
820
            session.bye()
756
 
    
757
 
    @staticmethod
758
 
    def peer_certificate(session):
759
 
        "Return the peer's OpenPGP certificate as a bytestring"
760
 
        # If not an OpenPGP certificate...
761
 
        if (gnutls.library.functions
762
 
            .gnutls_certificate_type_get(session._c_object)
763
 
            != gnutls.library.constants.GNUTLS_CRT_OPENPGP):
764
 
            # ...do the normal thing
765
 
            return session.peer_certificate
766
 
        list_size = ctypes.c_uint(1)
767
 
        cert_list = (gnutls.library.functions
768
 
                     .gnutls_certificate_get_peers
769
 
                     (session._c_object, ctypes.byref(list_size)))
770
 
        if not bool(cert_list) and list_size.value != 0:
771
 
            raise gnutls.errors.GNUTLSError("error getting peer"
772
 
                                            " certificate")
773
 
        if list_size.value == 0:
774
 
            return None
775
 
        cert = cert_list[0]
776
 
        return ctypes.string_at(cert.data, cert.size)
777
 
    
778
 
    @staticmethod
779
 
    def fingerprint(openpgp):
780
 
        "Convert an OpenPGP bytestring to a hexdigit fingerprint"
781
 
        # New GnuTLS "datum" with the OpenPGP public key
782
 
        datum = (gnutls.library.types
783
 
                 .gnutls_datum_t(ctypes.cast(ctypes.c_char_p(openpgp),
784
 
                                             ctypes.POINTER
785
 
                                             (ctypes.c_ubyte)),
786
 
                                 ctypes.c_uint(len(openpgp))))
787
 
        # New empty GnuTLS certificate
788
 
        crt = gnutls.library.types.gnutls_openpgp_crt_t()
789
 
        (gnutls.library.functions
790
 
         .gnutls_openpgp_crt_init(ctypes.byref(crt)))
791
 
        # Import the OpenPGP public key into the certificate
792
 
        (gnutls.library.functions
793
 
         .gnutls_openpgp_crt_import(crt, ctypes.byref(datum),
794
 
                                    gnutls.library.constants
795
 
                                    .GNUTLS_OPENPGP_FMT_RAW))
796
 
        # Verify the self signature in the key
797
 
        crtverify = ctypes.c_uint()
798
 
        (gnutls.library.functions
799
 
         .gnutls_openpgp_crt_verify_self(crt, 0,
800
 
                                         ctypes.byref(crtverify)))
801
 
        if crtverify.value != 0:
802
 
            gnutls.library.functions.gnutls_openpgp_crt_deinit(crt)
803
 
            raise (gnutls.errors.CertificateSecurityError
804
 
                   ("Verify failed"))
805
 
        # New buffer for the fingerprint
806
 
        buf = ctypes.create_string_buffer(20)
807
 
        buf_len = ctypes.c_size_t()
808
 
        # Get the fingerprint from the certificate into the buffer
809
 
        (gnutls.library.functions
810
 
         .gnutls_openpgp_crt_get_fingerprint(crt, ctypes.byref(buf),
811
 
                                             ctypes.byref(buf_len)))
812
 
        # Deinit the certificate
813
 
        gnutls.library.functions.gnutls_openpgp_crt_deinit(crt)
814
 
        # Convert the buffer to a Python bytestring
815
 
        fpr = ctypes.string_at(buf, buf_len.value)
816
 
        # Convert the bytestring to hexadecimal notation
817
 
        hex_fpr = u''.join(u"%02X" % ord(char) for char in fpr)
818
 
        return hex_fpr
819
821
 
820
822
 
821
823
class ForkingMixInWithPipe(SocketServer.ForkingMixIn, object):
937
939
            # Stop calling this function
938
940
            return False
939
941
        
940
 
        logger.debug("IPC command: %r", cmdline)
 
942
        logger.debug("IPC command: %r\n" % cmdline)
941
943
        
942
944
        # Parse and act on command
943
 
        cmd, args = cmdline.rstrip("\r\n").split(None, 1)
944
 
        
 
945
        cmd, args = cmdline.split(None, 1)
945
946
        if cmd == "NOTFOUND":
946
 
            logger.warning(u"Client not found for fingerprint: %s",
947
 
                           args)
948
947
            if self.settings["use_dbus"]:
949
948
                # Emit D-Bus signal
950
949
                mandos_dbus_service.ClientNotFound(args)
951
950
        elif cmd == "INVALID":
952
 
            for client in self.clients:
953
 
                if client.name == args:
954
 
                    logger.warning(u"Client %s is invalid", args)
955
 
                    if self.settings["use_dbus"]:
 
951
            if self.settings["use_dbus"]:
 
952
                for client in self.clients:
 
953
                    if client.name == args:
956
954
                        # Emit D-Bus signal
957
955
                        client.Rejected()
958
 
                    break
959
 
            else:
960
 
                logger.error(u"Unknown client %s is invalid", args)
 
956
                        break
961
957
        elif cmd == "SENDING":
962
958
            for client in self.clients:
963
959
                if client.name == args:
964
 
                    logger.info(u"Sending secret to %s", client.name)
965
960
                    client.checked_ok()
966
961
                    if self.settings["use_dbus"]:
967
962
                        # Emit D-Bus signal
968
963
                        client.ReceivedSecret()
969
964
                    break
970
 
            else:
971
 
                logger.error(u"Sending secret to unknown client %s",
972
 
                             args)
973
965
        else:
974
966
            logger.error("Unknown IPC command: %r", cmdline)
975
967