Пример #1
0
class certmap(Object):
    """
    virtual object for certmatch_map API
    """
    takes_params = (
        DNSNameParam(
            'domain',
            label=_('Domain'),
            flags={'no_search'},
        ),
        Str(
            'uid*',
            label=_('User logins'),
            flags={'no_search'},
        ),
    )
Пример #2
0
class BaseCertObject(Object):
    takes_params = (
        Str(
            'cacn?',
            cli_name='ca',
            default=IPA_CA_CN,
            autofill=True,
            label=_('Issuing CA'),
            doc=_('Name of issuing CA'),
            flags={'no_create', 'no_update', 'no_search'},
        ),
        Bytes(
            'certificate',
            validate_certificate,
            label=_("Certificate"),
            doc=_("Base-64 encoded certificate."),
            normalizer=x509.normalize_certificate,
            flags={'no_create', 'no_update', 'no_search'},
        ),
        DNParam(
            'subject',
            label=_('Subject'),
            flags={'no_create', 'no_update', 'no_search'},
        ),
        Str(
            'san_rfc822name*',
            label=_('Subject email address'),
            flags={'no_create', 'no_update', 'no_search'},
        ),
        DNSNameParam(
            'san_dnsname*',
            label=_('Subject DNS name'),
            flags={'no_create', 'no_update', 'no_search'},
        ),
        Str(
            'san_x400address*',
            label=_('Subject X.400 address'),
            flags={'no_create', 'no_update', 'no_search'},
        ),
        DNParam(
            'san_directoryname*',
            label=_('Subject directory name'),
            flags={'no_create', 'no_update', 'no_search'},
        ),
        Str(
            'san_edipartyname*',
            label=_('Subject EDI Party name'),
            flags={'no_create', 'no_update', 'no_search'},
        ),
        Str(
            'san_uri*',
            label=_('Subject URI'),
            flags={'no_create', 'no_update', 'no_search'},
        ),
        Str(
            'san_ipaddress*',
            label=_('Subject IP Address'),
            flags={'no_create', 'no_update', 'no_search'},
        ),
        Str(
            'san_oid*',
            label=_('Subject OID'),
            flags={'no_create', 'no_update', 'no_search'},
        ),
        Principal(
            'san_other_upn*',
            label=_('Subject UPN'),
            flags={'no_create', 'no_update', 'no_search'},
        ),
        Principal(
            'san_other_kpn*',
            label=_('Subject Kerberos principal name'),
            flags={'no_create', 'no_update', 'no_search'},
        ),
        Str(
            'san_other*',
            label=_('Subject Other Name'),
            flags={'no_create', 'no_update', 'no_search'},
        ),
        DNParam(
            'issuer',
            label=_('Issuer'),
            doc=_('Issuer DN'),
            flags={'no_create', 'no_update', 'no_search'},
        ),
        DateTime(
            'valid_not_before',
            label=_('Not Before'),
            flags={'no_create', 'no_update', 'no_search'},
        ),
        DateTime(
            'valid_not_after',
            label=_('Not After'),
            flags={'no_create', 'no_update', 'no_search'},
        ),
        Str(
            'md5_fingerprint',
            label=_('Fingerprint (MD5)'),
            flags={'no_create', 'no_update', 'no_search'},
        ),
        Str(
            'sha1_fingerprint',
            label=_('Fingerprint (SHA1)'),
            flags={'no_create', 'no_update', 'no_search'},
        ),
        Int(
            'serial_number',
            label=_('Serial number'),
            doc=_(
                'Serial number in decimal or if prefixed with 0x in hexadecimal'
            ),
            normalizer=normalize_serial_number,
            flags={'no_create', 'no_update', 'no_search'},
        ),
        Str(
            'serial_number_hex',
            label=_('Serial number (hex)'),
            flags={'no_create', 'no_update', 'no_search'},
        ),
    )

    def _parse(self, obj, full=True):
        """Extract certificate-specific data into a result object.

        ``obj``
            Result object containing certificate, into which extracted
            data will be inserted.
        ``full``
            Whether to include all fields, or only the ones we guess
            people want to see most of the time.  Also add
            recognised otherNames to the generic ``san_other``
            attribute when ``True`` in addition to the specialised
            attribute.

        """
        cert = obj.get('certificate')
        if cert is not None:
            cert = x509.load_certificate(cert)
            obj['subject'] = DN(unicode(cert.subject))
            obj['issuer'] = DN(unicode(cert.issuer))
            obj['serial_number'] = cert.serial_number
            if full:
                obj['valid_not_before'] = unicode(cert.valid_not_before_str)
                obj['valid_not_after'] = unicode(cert.valid_not_after_str)
                obj['md5_fingerprint'] = unicode(
                    nss.data_to_hex(nss.md5_digest(cert.der_data), 64)[0])
                obj['sha1_fingerprint'] = unicode(
                    nss.data_to_hex(nss.sha1_digest(cert.der_data), 64)[0])

            try:
                ext_san = cert.get_extension(nss.SEC_OID_X509_SUBJECT_ALT_NAME)
                general_names = x509.decode_generalnames(ext_san.value)
            except KeyError:
                general_names = []

            for name_type, _desc, name, der_name in general_names:
                try:
                    self._add_san_attribute(obj, full, name_type, name,
                                            der_name)
                except Exception:
                    # Invalid GeneralName (i.e. not a valid X.509 cert);
                    # don't fail but log something about it
                    root_logger.warning(
                        "Encountered bad GeneralName; skipping", exc_info=True)

        serial_number = obj.get('serial_number')
        if serial_number is not None:
            obj['serial_number_hex'] = u'0x%X' % serial_number

    def _add_san_attribute(self, obj, full, name_type, name, der_name):
        name_type_map = {
            nss.certRFC822Name: 'san_rfc822name',
            nss.certDNSName: 'san_dnsname',
            nss.certX400Address: 'san_x400address',
            nss.certDirectoryName: 'san_directoryname',
            nss.certEDIPartyName: 'san_edipartyname',
            nss.certURI: 'san_uri',
            nss.certIPAddress: 'san_ipaddress',
            nss.certRegisterID: 'san_oid',
            (nss.certOtherName, x509.SAN_UPN): 'san_other_upn',
            (nss.certOtherName, x509.SAN_KRB5PRINCIPALNAME): 'san_other_kpn',
        }
        default_attrs = {
            'san_rfc822name',
            'san_dnsname',
            'san_other_upn',
            'san_other_kpn',
        }

        attr_name = name_type_map.get(name_type, 'san_other')

        if full or attr_name in default_attrs:
            if attr_name != 'san_other':
                name_formatted = name
            else:
                # display as "OID : b64(DER)"
                name_formatted = u'{}:{}'.format(name_type[1],
                                                 base64.b64encode(der_name))
            attr_value = self.params[attr_name].type(name_formatted)
            obj.setdefault(attr_name, []).append(attr_value)

        if full and attr_name.startswith('san_other_'):
            # also include known otherName in generic otherName attribute
            name_formatted = u'{}:{}'.format(name_type[1],
                                             base64.b64encode(der_name))
            attr_value = self.params['san_other'].type(name_formatted)
            obj.setdefault('san_other', []).append(attr_value)
Пример #3
0
class BaseCertObject(Object):
    takes_params = (
        Str(
            'cacn?',
            cli_name='ca',
            default=IPA_CA_CN,
            autofill=True,
            label=_('Issuing CA'),
            doc=_('Name of issuing CA'),
            flags={'no_create', 'no_update', 'no_search'},
        ),
        Bytes(
            'certificate',
            validate_certificate,
            label=_("Certificate"),
            doc=_("Base-64 encoded certificate."),
            normalizer=x509.normalize_certificate,
            flags={'no_create', 'no_update', 'no_search'},
        ),
        DNParam(
            'subject',
            label=_('Subject'),
            flags={'no_create', 'no_update', 'no_search'},
        ),
        Str(
            'san_rfc822name*',
            label=_('Subject email address'),
            flags={'no_create', 'no_update', 'no_search'},
        ),
        DNSNameParam(
            'san_dnsname*',
            label=_('Subject DNS name'),
            flags={'no_create', 'no_update', 'no_search'},
        ),
        Str(
            'san_x400address*',
            label=_('Subject X.400 address'),
            flags={'no_create', 'no_update', 'no_search'},
        ),
        DNParam(
            'san_directoryname*',
            label=_('Subject directory name'),
            flags={'no_create', 'no_update', 'no_search'},
        ),
        Str(
            'san_edipartyname*',
            label=_('Subject EDI Party name'),
            flags={'no_create', 'no_update', 'no_search'},
        ),
        Str(
            'san_uri*',
            label=_('Subject URI'),
            flags={'no_create', 'no_update', 'no_search'},
        ),
        Str(
            'san_ipaddress*',
            label=_('Subject IP Address'),
            flags={'no_create', 'no_update', 'no_search'},
        ),
        Str(
            'san_oid*',
            label=_('Subject OID'),
            flags={'no_create', 'no_update', 'no_search'},
        ),
        Principal(
            'san_other_upn*',
            label=_('Subject UPN'),
            flags={'no_create', 'no_update', 'no_search'},
        ),
        Principal(
            'san_other_kpn*',
            label=_('Subject Kerberos principal name'),
            flags={'no_create', 'no_update', 'no_search'},
        ),
        Str(
            'san_other*',
            label=_('Subject Other Name'),
            flags={'no_create', 'no_update', 'no_search'},
        ),
        DNParam(
            'issuer',
            label=_('Issuer'),
            doc=_('Issuer DN'),
            flags={'no_create', 'no_update', 'no_search'},
        ),
        DateTime(
            'valid_not_before',
            label=_('Not Before'),
            flags={'no_create', 'no_update', 'no_search'},
        ),
        DateTime(
            'valid_not_after',
            label=_('Not After'),
            flags={'no_create', 'no_update', 'no_search'},
        ),
        Str(
            'md5_fingerprint',
            label=_('Fingerprint (MD5)'),
            flags={'no_create', 'no_update', 'no_search'},
        ),
        Str(
            'sha1_fingerprint',
            label=_('Fingerprint (SHA1)'),
            flags={'no_create', 'no_update', 'no_search'},
        ),
        Int(
            'serial_number',
            label=_('Serial number'),
            doc=_(
                'Serial number in decimal or if prefixed with 0x in hexadecimal'
            ),
            normalizer=normalize_serial_number,
            flags={'no_create', 'no_update', 'no_search'},
        ),
        Str(
            'serial_number_hex',
            label=_('Serial number (hex)'),
            flags={'no_create', 'no_update', 'no_search'},
        ),
    )

    def _parse(self, obj, full=True):
        """Extract certificate-specific data into a result object.

        ``obj``
            Result object containing certificate, into which extracted
            data will be inserted.
        ``full``
            Whether to include all fields, or only the ones we guess
            people want to see most of the time.  Also add
            recognised otherNames to the generic ``san_other``
            attribute when ``True`` in addition to the specialised
            attribute.

        """
        if 'certificate' in obj:
            cert = x509.load_certificate(obj['certificate'])
            obj['subject'] = DN(cert.subject)
            obj['issuer'] = DN(cert.issuer)
            obj['serial_number'] = cert.serial
            obj['valid_not_before'] = x509.format_datetime(
                cert.not_valid_before)
            obj['valid_not_after'] = x509.format_datetime(cert.not_valid_after)
            if full:
                obj['md5_fingerprint'] = x509.to_hex_with_colons(
                    cert.fingerprint(hashes.MD5()))
                obj['sha1_fingerprint'] = x509.to_hex_with_colons(
                    cert.fingerprint(hashes.SHA1()))

            general_names = x509.process_othernames(
                x509.get_san_general_names(cert))

            for gn in general_names:
                try:
                    self._add_san_attribute(obj, full, gn)
                except Exception:
                    # Invalid GeneralName (i.e. not a valid X.509 cert);
                    # don't fail but log something about it
                    root_logger.warning(
                        "Encountered bad GeneralName; skipping", exc_info=True)

        serial_number = obj.get('serial_number')
        if serial_number is not None:
            obj['serial_number_hex'] = u'0x%X' % serial_number

    def _add_san_attribute(self, obj, full, gn):
        name_type_map = {
            cryptography.x509.RFC822Name:
            ('san_rfc822name', attrgetter('value')),
            cryptography.x509.DNSName: ('san_dnsname', attrgetter('value')),
            # cryptography.x509.???: 'san_x400address',
            cryptography.x509.DirectoryName:
            ('san_directoryname', lambda x: DN(x.value)),
            # cryptography.x509.???: 'san_edipartyname',
            cryptography.x509.UniformResourceIdentifier: ('san_uri',
                                                          attrgetter('value')),
            cryptography.x509.IPAddress:
            ('san_ipaddress', attrgetter('value')),
            cryptography.x509.RegisteredID:
            ('san_oid', attrgetter('value.dotted_string')),
            cryptography.x509.OtherName: ('san_other', _format_othername),
            x509.UPN: ('san_other_upn', attrgetter('name')),
            x509.KRB5PrincipalName: ('san_other_kpn', attrgetter('name')),
        }
        default_attrs = {
            'san_rfc822name',
            'san_dnsname',
            'san_other_upn',
            'san_other_kpn',
        }

        if type(gn) not in name_type_map:
            return

        attr_name, format_name = name_type_map[type(gn)]

        if full or attr_name in default_attrs:
            attr_value = self.params[attr_name].type(format_name(gn))
            obj.setdefault(attr_name, []).append(attr_value)

        if full and attr_name.startswith('san_other_'):
            # also include known otherName in generic otherName attribute
            attr_value = self.params['san_other'].type(_format_othername(gn))
            obj.setdefault('san_other', []).append(attr_value)
Пример #4
0
class certmaprule(LDAPObject):
    """
    Certificate Identity Mapping Rules
    """

    label = _('Certificate Identity Mapping Rules')
    label_singular = _('Certificate Identity Mapping Rule')

    object_name = _('Certificate Identity Mapping Rule')
    object_name_plural = _('Certificate Identity Mapping Rules')
    object_class = ['ipacertmaprule']

    container_dn = api.env.container_certmaprules
    default_attributes = [
        'cn', 'description', 'ipacertmapmaprule', 'ipacertmapmatchrule',
        'associateddomain', 'ipacertmappriority', 'ipaenabledflag'
    ]
    search_attributes = [
        'cn', 'description', 'ipacertmapmaprule', 'ipacertmapmatchrule',
        'associateddomain', 'ipacertmappriority', 'ipaenabledflag'
    ]

    takes_params = (
        Str(
            'cn',
            cli_name='rulename',
            primary_key=True,
            label=_('Rule name'),
            doc=_('Certificate Identity Mapping Rule name'),
        ),
        Str(
            'description?',
            cli_name='desc',
            label=_('Description'),
            doc=_('Certificate Identity Mapping Rule description'),
        ),
        Str(
            'ipacertmapmaprule?',
            cli_name='maprule',
            label=_('Mapping rule'),
            doc=_('Rule used to map the certificate with a user entry'),
        ),
        Str(
            'ipacertmapmatchrule?',
            cli_name='matchrule',
            label=_('Matching rule'),
            doc=_('Rule used to check if a certificate can be used for'
                  ' authentication'),
        ),
        DNSNameParam(
            'associateddomain*',
            cli_name='domain',
            label=_('Domain name'),
            doc=_('Domain where the user entry will be searched'),
        ),
        Int(
            'ipacertmappriority?',
            cli_name='priority',
            label=_('Priority'),
            doc=_('Priority of the rule (higher number means lower priority'),
            minvalue=0,
        ),
        Flag('ipaenabledflag?',
             label=_('Enabled'),
             flags=['no_option'],
             default=True),
    )

    permission_filter_objectclasses = ['ipacertmaprule']
    managed_permissions = {
        'System: Add Certmap Rules': {
            'replaces_global_anonymous_aci': True,
            'ipapermright': {'add'},
            'default_privileges':
            {'Certificate Identity Mapping Administrators'},
        },
        'System: Read Certmap Rules': {
            'replaces_global_anonymous_aci': True,
            'ipapermbindruletype': 'all',
            'ipapermright': {'read', 'search', 'compare'},
            'ipapermdefaultattr': {
                'objectclass',
                'cn',
                'description',
                'ipacertmapmaprule',
                'ipacertmapmatchrule',
                'associateddomain',
                'ipacertmappriority',
                'ipaenabledflag',
            },
        },
        'System: Delete Certmap Rules': {
            'replaces_global_anonymous_aci': True,
            'ipapermright': {'delete'},
            'default_privileges':
            {'Certificate Identity Mapping Administrators'},
        },
        'System: Modify Certmap Rules': {
            'replaces_global_anonymous_aci': True,
            'ipapermright': {'write'},
            'ipapermdefaultattr': {
                'objectclass',
                'cn',
                'description',
                'ipacertmapmaprule',
                'ipacertmapmatchrule',
                'associateddomain',
                'ipacertmappriority',
                'ipaenabledflag',
            },
            'default_privileges':
            {'Certificate Identity Mapping Administrators'},
        },
    }