|
|
403b09 |
From be32fd1d727fc8398dd51fa0fd3f404ef451281a Mon Sep 17 00:00:00 2001
|
|
|
403b09 |
From: Jan Cholasta <jcholast@redhat.com>
|
|
|
403b09 |
Date: Mon, 1 Aug 2016 09:53:39 +0200
|
|
|
403b09 |
Subject: [PATCH] cert: speed up cert-find
|
|
|
403b09 |
|
|
|
403b09 |
Use issuer+serial rather than raw DER blob to identify certificates in
|
|
|
403b09 |
cert-find's intermediate result.
|
|
|
403b09 |
|
|
|
403b09 |
Restructure the code to make it (hopefully) easier to follow.
|
|
|
403b09 |
|
|
|
403b09 |
https://fedorahosted.org/freeipa/ticket/6098
|
|
|
403b09 |
|
|
|
403b09 |
Reviewed-By: Martin Basti <mbasti@redhat.com>
|
|
|
403b09 |
Reviewed-By: Pavel Vomacka <pvomacka@redhat.com>
|
|
|
403b09 |
---
|
|
|
403b09 |
ipaserver/plugins/cert.py | 398 +++++++++++++++++++++++++---------------------
|
|
|
403b09 |
1 file changed, 216 insertions(+), 182 deletions(-)
|
|
|
403b09 |
|
|
|
403b09 |
diff --git a/ipaserver/plugins/cert.py b/ipaserver/plugins/cert.py
|
|
|
403b09 |
index 06041d3083565e8d093b610473d6083111d406d2..47dccf15a4010f2766642aedd2cc16e0a1eb1dd4 100644
|
|
|
403b09 |
--- a/ipaserver/plugins/cert.py
|
|
|
403b09 |
+++ b/ipaserver/plugins/cert.py
|
|
|
403b09 |
@@ -21,6 +21,7 @@
|
|
|
403b09 |
|
|
|
403b09 |
import base64
|
|
|
403b09 |
import binascii
|
|
|
403b09 |
+import collections
|
|
|
403b09 |
import datetime
|
|
|
403b09 |
import os
|
|
|
403b09 |
|
|
|
403b09 |
@@ -295,18 +296,24 @@ class BaseCertObject(Object):
|
|
|
403b09 |
),
|
|
|
403b09 |
)
|
|
|
403b09 |
|
|
|
403b09 |
- def _parse(self, obj):
|
|
|
403b09 |
- cert = x509.load_certificate(obj['certificate'])
|
|
|
403b09 |
- obj['subject'] = DN(unicode(cert.subject))
|
|
|
403b09 |
- obj['issuer'] = DN(unicode(cert.issuer))
|
|
|
403b09 |
- obj['valid_not_before'] = unicode(cert.valid_not_before_str)
|
|
|
403b09 |
- obj['valid_not_after'] = unicode(cert.valid_not_after_str)
|
|
|
403b09 |
- obj['md5_fingerprint'] = unicode(
|
|
|
403b09 |
- nss.data_to_hex(nss.md5_digest(cert.der_data), 64)[0])
|
|
|
403b09 |
- obj['sha1_fingerprint'] = unicode(
|
|
|
403b09 |
- nss.data_to_hex(nss.sha1_digest(cert.der_data), 64)[0])
|
|
|
403b09 |
- obj['serial_number'] = cert.serial_number
|
|
|
403b09 |
- obj['serial_number_hex'] = u'0x%X' % cert.serial_number
|
|
|
403b09 |
+ def _parse(self, obj, full=True):
|
|
|
403b09 |
+ cert = obj.get('certificate')
|
|
|
403b09 |
+ if cert is not None:
|
|
|
403b09 |
+ cert = x509.load_certificate(cert)
|
|
|
403b09 |
+ obj['subject'] = DN(unicode(cert.subject))
|
|
|
403b09 |
+ obj['issuer'] = DN(unicode(cert.issuer))
|
|
|
403b09 |
+ obj['serial_number'] = cert.serial_number
|
|
|
403b09 |
+ if full:
|
|
|
403b09 |
+ obj['valid_not_before'] = unicode(cert.valid_not_before_str)
|
|
|
403b09 |
+ obj['valid_not_after'] = unicode(cert.valid_not_after_str)
|
|
|
403b09 |
+ obj['md5_fingerprint'] = unicode(
|
|
|
403b09 |
+ nss.data_to_hex(nss.md5_digest(cert.der_data), 64)[0])
|
|
|
403b09 |
+ obj['sha1_fingerprint'] = unicode(
|
|
|
403b09 |
+ nss.data_to_hex(nss.sha1_digest(cert.der_data), 64)[0])
|
|
|
403b09 |
+
|
|
|
403b09 |
+ serial_number = obj.get('serial_number')
|
|
|
403b09 |
+ if serial_number is not None:
|
|
|
403b09 |
+ obj['serial_number_hex'] = u'0x%X' % serial_number
|
|
|
403b09 |
|
|
|
403b09 |
|
|
|
403b09 |
class BaseCertMethod(Method):
|
|
|
403b09 |
@@ -691,10 +698,14 @@ class cert(BaseCertObject):
|
|
|
403b09 |
yield self.api.Object[name]
|
|
|
403b09 |
|
|
|
403b09 |
def _fill_owners(self, obj):
|
|
|
403b09 |
+ dns = obj.pop('owner', None)
|
|
|
403b09 |
+ if dns is None:
|
|
|
403b09 |
+ return
|
|
|
403b09 |
+
|
|
|
403b09 |
for owner in self._owners():
|
|
|
403b09 |
container_dn = DN(owner.container_dn, self.api.env.basedn)
|
|
|
403b09 |
name = 'owner_' + owner.name
|
|
|
403b09 |
- for dn in obj['owner']:
|
|
|
403b09 |
+ for dn in dns:
|
|
|
403b09 |
if dn.endswith(container_dn, 1):
|
|
|
403b09 |
value = owner.get_primary_key_from_dn(dn)
|
|
|
403b09 |
obj.setdefault(name, []).append(value)
|
|
|
403b09 |
@@ -776,9 +787,7 @@ class cert_show(Retrieve, CertMethod, VirtualCommand):
|
|
|
403b09 |
result['certificate'] = result['certificate'].replace('\r\n', '')
|
|
|
403b09 |
self.obj._parse(result)
|
|
|
403b09 |
result['revoked'] = ('revocation_reason' in result)
|
|
|
403b09 |
- if 'owner' in result:
|
|
|
403b09 |
- self.obj._fill_owners(result)
|
|
|
403b09 |
- del result['owner']
|
|
|
403b09 |
+ self.obj._fill_owners(result)
|
|
|
403b09 |
|
|
|
403b09 |
if hostname:
|
|
|
403b09 |
# If we have a hostname we want to verify that the subject
|
|
|
403b09 |
@@ -984,36 +993,171 @@ class cert_find(Search, CertMethod):
|
|
|
403b09 |
label=owner.object_name,
|
|
|
403b09 |
)
|
|
|
403b09 |
|
|
|
403b09 |
- def execute(self, criteria=None, all=False, raw=False, pkey_only=False,
|
|
|
403b09 |
- no_members=True, timelimit=None, sizelimit=None, **options):
|
|
|
403b09 |
- ca_options = {'cacn',
|
|
|
403b09 |
- 'revocation_reason',
|
|
|
403b09 |
- 'issuer',
|
|
|
403b09 |
- 'subject',
|
|
|
403b09 |
- 'min_serial_number', 'max_serial_number',
|
|
|
403b09 |
- 'exactly',
|
|
|
403b09 |
- 'validnotafter_from', 'validnotafter_to',
|
|
|
403b09 |
- 'validnotbefore_from', 'validnotbefore_to',
|
|
|
403b09 |
- 'issuedon_from', 'issuedon_to',
|
|
|
403b09 |
- 'revokedon_from', 'revokedon_to'}
|
|
|
403b09 |
- ldap_options = {prefix + owner.name
|
|
|
403b09 |
- for owner in self.obj._owners()
|
|
|
403b09 |
- for prefix in ('', 'no_')}
|
|
|
403b09 |
- has_ca_options = (
|
|
|
403b09 |
- any(name in options for name in ca_options - {'exactly'}) or
|
|
|
403b09 |
- options['exactly'])
|
|
|
403b09 |
- has_ldap_options = any(name in options for name in ldap_options)
|
|
|
403b09 |
- has_cert_option = 'certificate' in options
|
|
|
403b09 |
+ def _get_cert_key(self, cert):
|
|
|
403b09 |
+ nss_cert = x509.load_certificate(cert, x509.DER)
|
|
|
403b09 |
+
|
|
|
403b09 |
+ return (DN(unicode(nss_cert.issuer)), nss_cert.serial_number)
|
|
|
403b09 |
+
|
|
|
403b09 |
+ def _get_cert_obj(self, cert, all, raw, pkey_only):
|
|
|
403b09 |
+ obj = {'certificate': unicode(base64.b64encode(cert))}
|
|
|
403b09 |
+
|
|
|
403b09 |
+ full = not pkey_only and all
|
|
|
403b09 |
+ if not raw:
|
|
|
403b09 |
+ self.obj._parse(obj, full)
|
|
|
403b09 |
+ if not full:
|
|
|
403b09 |
+ del obj['certificate']
|
|
|
403b09 |
+
|
|
|
403b09 |
+ return obj
|
|
|
403b09 |
+
|
|
|
403b09 |
+ def _cert_search(self, all, raw, pkey_only, **options):
|
|
|
403b09 |
+ result = collections.OrderedDict()
|
|
|
403b09 |
+
|
|
|
403b09 |
+ try:
|
|
|
403b09 |
+ cert = options['certificate']
|
|
|
403b09 |
+ except KeyError:
|
|
|
403b09 |
+ return result, False, False
|
|
|
403b09 |
+
|
|
|
403b09 |
+ key = self._get_cert_key(cert)
|
|
|
403b09 |
+
|
|
|
403b09 |
+ result[key] = self._get_cert_obj(cert, all, raw, pkey_only)
|
|
|
403b09 |
+
|
|
|
403b09 |
+ return result, False, True
|
|
|
403b09 |
+
|
|
|
403b09 |
+ def _ca_search(self, all, raw, pkey_only, sizelimit, exactly, **options):
|
|
|
403b09 |
+ ra_options = {}
|
|
|
403b09 |
+ for name in ('revocation_reason',
|
|
|
403b09 |
+ 'issuer',
|
|
|
403b09 |
+ 'subject',
|
|
|
403b09 |
+ 'min_serial_number', 'max_serial_number',
|
|
|
403b09 |
+ 'validnotafter_from', 'validnotafter_to',
|
|
|
403b09 |
+ 'validnotbefore_from', 'validnotbefore_to',
|
|
|
403b09 |
+ 'issuedon_from', 'issuedon_to',
|
|
|
403b09 |
+ 'revokedon_from', 'revokedon_to'):
|
|
|
403b09 |
+ try:
|
|
|
403b09 |
+ value = options[name]
|
|
|
403b09 |
+ except KeyError:
|
|
|
403b09 |
+ continue
|
|
|
403b09 |
+ if isinstance(value, datetime.datetime):
|
|
|
403b09 |
+ value = value.strftime(PKIDATE_FORMAT)
|
|
|
403b09 |
+ elif isinstance(value, DN):
|
|
|
403b09 |
+ value = unicode(value)
|
|
|
403b09 |
+ ra_options[name] = value
|
|
|
403b09 |
+ if sizelimit:
|
|
|
403b09 |
+ ra_options['sizelimit'] = sizelimit
|
|
|
403b09 |
+ if exactly:
|
|
|
403b09 |
+ ra_options['exactly'] = True
|
|
|
403b09 |
+
|
|
|
403b09 |
+ result = collections.OrderedDict()
|
|
|
403b09 |
+ complete = bool(ra_options)
|
|
|
403b09 |
|
|
|
403b09 |
try:
|
|
|
403b09 |
ca_enabled_check()
|
|
|
403b09 |
except errors.NotFound:
|
|
|
403b09 |
- if has_ca_options:
|
|
|
403b09 |
+ if ra_options:
|
|
|
403b09 |
raise
|
|
|
403b09 |
- ca_enabled = False
|
|
|
403b09 |
+ return result, False, complete
|
|
|
403b09 |
+
|
|
|
403b09 |
+ ra = self.api.Backend.ra
|
|
|
403b09 |
+ for ra_obj in ra.find(ra_options):
|
|
|
403b09 |
+ issuer = DN(ra_obj['issuer'])
|
|
|
403b09 |
+ serial_number = ra_obj['serial_number']
|
|
|
403b09 |
+
|
|
|
403b09 |
+ if pkey_only:
|
|
|
403b09 |
+ obj = {'serial_number': serial_number}
|
|
|
403b09 |
+ else:
|
|
|
403b09 |
+ obj = ra_obj
|
|
|
403b09 |
+ obj['issuer'] = issuer
|
|
|
403b09 |
+ obj['subject'] = DN(ra_obj['subject'])
|
|
|
403b09 |
+ del obj['serial_number_hex']
|
|
|
403b09 |
+
|
|
|
403b09 |
+ if all:
|
|
|
403b09 |
+ ra_obj = ra.get_certificate(str(serial_number))
|
|
|
403b09 |
+ if not raw:
|
|
|
403b09 |
+ obj['certificate'] = (
|
|
|
403b09 |
+ ra_obj['certificate'].replace('\r\n', ''))
|
|
|
403b09 |
+ self.obj._parse(obj)
|
|
|
403b09 |
+
|
|
|
403b09 |
+ result[issuer, serial_number] = obj
|
|
|
403b09 |
+
|
|
|
403b09 |
+ return result, False, complete
|
|
|
403b09 |
+
|
|
|
403b09 |
+ def _ldap_search(self, all, raw, pkey_only, no_members, timelimit,
|
|
|
403b09 |
+ sizelimit, **options):
|
|
|
403b09 |
+ ldap = self.api.Backend.ldap2
|
|
|
403b09 |
+
|
|
|
403b09 |
+ filters = []
|
|
|
403b09 |
+ for owner in self.obj._owners():
|
|
|
403b09 |
+ for prefix, rule in (('', ldap.MATCH_ALL),
|
|
|
403b09 |
+ ('no_', ldap.MATCH_NONE)):
|
|
|
403b09 |
+ try:
|
|
|
403b09 |
+ value = options[prefix + owner.name]
|
|
|
403b09 |
+ except KeyError:
|
|
|
403b09 |
+ continue
|
|
|
403b09 |
+
|
|
|
403b09 |
+ filter = ldap.make_filter_from_attr(
|
|
|
403b09 |
+ 'objectclass',
|
|
|
403b09 |
+ owner.object_class,
|
|
|
403b09 |
+ ldap.MATCH_ALL)
|
|
|
403b09 |
+ if filter not in filters:
|
|
|
403b09 |
+ filters.append(filter)
|
|
|
403b09 |
+
|
|
|
403b09 |
+ filter = ldap.make_filter_from_attr(
|
|
|
403b09 |
+ owner.primary_key.name,
|
|
|
403b09 |
+ value,
|
|
|
403b09 |
+ rule)
|
|
|
403b09 |
+ filters.append(filter)
|
|
|
403b09 |
+
|
|
|
403b09 |
+ cert = options.get('certificate')
|
|
|
403b09 |
+ if cert is not None:
|
|
|
403b09 |
+ filter = ldap.make_filter_from_attr('usercertificate', cert)
|
|
|
403b09 |
+ filters.append(filter)
|
|
|
403b09 |
+
|
|
|
403b09 |
+ result = collections.OrderedDict()
|
|
|
403b09 |
+ complete = bool(filters)
|
|
|
403b09 |
+
|
|
|
403b09 |
+ if cert is None:
|
|
|
403b09 |
+ filter = '(usercertificate=*)'
|
|
|
403b09 |
+ filters.append(filter)
|
|
|
403b09 |
+
|
|
|
403b09 |
+ filter = ldap.combine_filters(filters, ldap.MATCH_ALL)
|
|
|
403b09 |
+ try:
|
|
|
403b09 |
+ entries, truncated = ldap.find_entries(
|
|
|
403b09 |
+ base_dn=self.api.env.basedn,
|
|
|
403b09 |
+ filter=filter,
|
|
|
403b09 |
+ attrs_list=['usercertificate'],
|
|
|
403b09 |
+ time_limit=timelimit,
|
|
|
403b09 |
+ size_limit=sizelimit,
|
|
|
403b09 |
+ )
|
|
|
403b09 |
+ except errors.EmptyResult:
|
|
|
403b09 |
+ entries = []
|
|
|
403b09 |
+ truncated = False
|
|
|
403b09 |
else:
|
|
|
403b09 |
- ca_enabled = True
|
|
|
403b09 |
+ truncated = bool(truncated)
|
|
|
403b09 |
+
|
|
|
403b09 |
+ for entry in entries:
|
|
|
403b09 |
+ for attr in ('usercertificate', 'usercertificate;binary'):
|
|
|
403b09 |
+ for cert in entry.get(attr, []):
|
|
|
403b09 |
+ key = self._get_cert_key(cert)
|
|
|
403b09 |
+
|
|
|
403b09 |
+ try:
|
|
|
403b09 |
+ obj = result[key]
|
|
|
403b09 |
+ except KeyError:
|
|
|
403b09 |
+ obj = self._get_cert_obj(cert, all, raw, pkey_only)
|
|
|
403b09 |
+ result[key] = obj
|
|
|
403b09 |
|
|
|
403b09 |
+ if not pkey_only and (all or not no_members):
|
|
|
403b09 |
+ owners = obj.setdefault('owner', [])
|
|
|
403b09 |
+ if entry.dn not in owners:
|
|
|
403b09 |
+ owners.append(entry.dn)
|
|
|
403b09 |
+
|
|
|
403b09 |
+ if not raw:
|
|
|
403b09 |
+ for obj in six.itervalues(result):
|
|
|
403b09 |
+ self.obj._fill_owners(obj)
|
|
|
403b09 |
+
|
|
|
403b09 |
+ return result, truncated, complete
|
|
|
403b09 |
+
|
|
|
403b09 |
+ def execute(self, criteria=None, all=False, raw=False, pkey_only=False,
|
|
|
403b09 |
+ no_members=True, timelimit=None, sizelimit=None, **options):
|
|
|
403b09 |
if 'cacn' in options:
|
|
|
403b09 |
ca_obj = api.Command.ca_show(options['cacn'])['result']
|
|
|
403b09 |
ca_sdn = unicode(ca_obj['ipacasubjectdn'][0])
|
|
|
403b09 |
@@ -1028,153 +1172,43 @@ class cert_find(Search, CertMethod):
|
|
|
403b09 |
if criteria is not None:
|
|
|
403b09 |
return dict(result=[], count=0, truncated=False)
|
|
|
403b09 |
|
|
|
403b09 |
- obj_seq = []
|
|
|
403b09 |
- obj_dict = {}
|
|
|
403b09 |
+ result = collections.OrderedDict()
|
|
|
403b09 |
truncated = False
|
|
|
403b09 |
-
|
|
|
403b09 |
- if has_cert_option:
|
|
|
403b09 |
- cert = options['certificate']
|
|
|
403b09 |
- obj = {'certificate': unicode(base64.b64encode(cert))}
|
|
|
403b09 |
- obj_seq.append(obj)
|
|
|
403b09 |
- obj_dict[cert] = obj
|
|
|
403b09 |
-
|
|
|
403b09 |
- if ca_enabled:
|
|
|
403b09 |
- ra_options = {}
|
|
|
403b09 |
- for name, value in options.items():
|
|
|
403b09 |
- if name not in ca_options:
|
|
|
403b09 |
- continue
|
|
|
403b09 |
- if isinstance(value, datetime.datetime):
|
|
|
403b09 |
- value = value.strftime(PKIDATE_FORMAT)
|
|
|
403b09 |
- elif isinstance(value, DN):
|
|
|
403b09 |
- value = unicode(value)
|
|
|
403b09 |
- ra_options[name] = value
|
|
|
403b09 |
- if sizelimit is not None:
|
|
|
403b09 |
- if sizelimit != 0:
|
|
|
403b09 |
- ra_options['sizelimit'] = sizelimit
|
|
|
403b09 |
- sizelimit = 0
|
|
|
403b09 |
- has_ca_options = True
|
|
|
403b09 |
-
|
|
|
403b09 |
- for ra_obj in self.Backend.ra.find(ra_options):
|
|
|
403b09 |
- obj = {}
|
|
|
403b09 |
- if ((not pkey_only and all) or
|
|
|
403b09 |
- not no_members or
|
|
|
403b09 |
- not has_ca_options or
|
|
|
403b09 |
- has_ldap_options or
|
|
|
403b09 |
- has_cert_option):
|
|
|
403b09 |
- ra_obj.update(
|
|
|
403b09 |
- self.Backend.ra.get_certificate(
|
|
|
403b09 |
- str(ra_obj['serial_number'])))
|
|
|
403b09 |
- cert = base64.b64decode(ra_obj['certificate'])
|
|
|
403b09 |
- try:
|
|
|
403b09 |
- obj = obj_dict[cert]
|
|
|
403b09 |
- except KeyError:
|
|
|
403b09 |
- if has_cert_option:
|
|
|
403b09 |
- continue
|
|
|
403b09 |
- obj = {}
|
|
|
403b09 |
- obj_seq.append(obj)
|
|
|
403b09 |
- obj_dict[cert] = obj
|
|
|
403b09 |
+ complete = False
|
|
|
403b09 |
+
|
|
|
403b09 |
+ for sub_search in (self._cert_search,
|
|
|
403b09 |
+ self._ca_search,
|
|
|
403b09 |
+ self._ldap_search):
|
|
|
403b09 |
+ sub_result, sub_truncated, sub_complete = sub_search(
|
|
|
403b09 |
+ all=all,
|
|
|
403b09 |
+ raw=raw,
|
|
|
403b09 |
+ pkey_only=pkey_only,
|
|
|
403b09 |
+ no_members=no_members,
|
|
|
403b09 |
+ timelimit=timelimit,
|
|
|
403b09 |
+ sizelimit=sizelimit,
|
|
|
403b09 |
+ **options)
|
|
|
403b09 |
+
|
|
|
403b09 |
+ if sub_complete:
|
|
|
403b09 |
+ sizelimit = None
|
|
|
403b09 |
+
|
|
|
403b09 |
+ for key in tuple(result):
|
|
|
403b09 |
+ if key not in sub_result:
|
|
|
403b09 |
+ del result[key]
|
|
|
403b09 |
+
|
|
|
403b09 |
+ for key, sub_obj in six.iteritems(sub_result):
|
|
|
403b09 |
+ try:
|
|
|
403b09 |
+ obj = result[key]
|
|
|
403b09 |
+ except KeyError:
|
|
|
403b09 |
+ if complete:
|
|
|
403b09 |
+ continue
|
|
|
403b09 |
+ result[key] = sub_obj
|
|
|
403b09 |
else:
|
|
|
403b09 |
- obj_seq.append(obj)
|
|
|
403b09 |
- obj.update(ra_obj)
|
|
|
403b09 |
-
|
|
|
403b09 |
- if ((not pkey_only and all) or
|
|
|
403b09 |
- not no_members or
|
|
|
403b09 |
- not has_ca_options or
|
|
|
403b09 |
- has_ldap_options or
|
|
|
403b09 |
- has_cert_option):
|
|
|
403b09 |
- ldap = self.api.Backend.ldap2
|
|
|
403b09 |
+ obj.update(sub_obj)
|
|
|
403b09 |
|
|
|
403b09 |
- filters = []
|
|
|
403b09 |
- if 'certificate' in options:
|
|
|
403b09 |
- cert_filter = ldap.make_filter_from_attr(
|
|
|
403b09 |
- 'usercertificate', options['certificate'])
|
|
|
403b09 |
- else:
|
|
|
403b09 |
- cert_filter = '(usercertificate=*)'
|
|
|
403b09 |
- filters.append(cert_filter)
|
|
|
403b09 |
- for owner in self.obj._owners():
|
|
|
403b09 |
- oc_filter = ldap.make_filter_from_attr(
|
|
|
403b09 |
- 'objectclass', owner.object_class, ldap.MATCH_ALL)
|
|
|
403b09 |
- for prefix, rule in (('', ldap.MATCH_ALL),
|
|
|
403b09 |
- ('no_', ldap.MATCH_NONE)):
|
|
|
403b09 |
- value = options.get(prefix + owner.name)
|
|
|
403b09 |
- if value is None:
|
|
|
403b09 |
- continue
|
|
|
403b09 |
- pkey_filter = ldap.make_filter_from_attr(
|
|
|
403b09 |
- owner.primary_key.name, value, rule)
|
|
|
403b09 |
- filters.append(oc_filter)
|
|
|
403b09 |
- filters.append(pkey_filter)
|
|
|
403b09 |
- filter = ldap.combine_filters(filters, ldap.MATCH_ALL)
|
|
|
403b09 |
+ truncated = truncated or sub_truncated
|
|
|
403b09 |
+ complete = complete or sub_complete
|
|
|
403b09 |
|
|
|
403b09 |
- try:
|
|
|
403b09 |
- entries, truncated = ldap.find_entries(
|
|
|
403b09 |
- base_dn=self.api.env.basedn,
|
|
|
403b09 |
- filter=filter,
|
|
|
403b09 |
- attrs_list=['usercertificate'],
|
|
|
403b09 |
- time_limit=timelimit,
|
|
|
403b09 |
- size_limit=sizelimit,
|
|
|
403b09 |
- )
|
|
|
403b09 |
- except errors.EmptyResult:
|
|
|
403b09 |
- entries, truncated = [], False
|
|
|
403b09 |
- for entry in entries:
|
|
|
403b09 |
- seen = set()
|
|
|
403b09 |
- for attr in ('usercertificate', 'usercertificate;binary'):
|
|
|
403b09 |
- for cert in entry.get(attr, []):
|
|
|
403b09 |
- if cert in seen:
|
|
|
403b09 |
- continue
|
|
|
403b09 |
- seen.add(cert)
|
|
|
403b09 |
- try:
|
|
|
403b09 |
- obj = obj_dict[cert]
|
|
|
403b09 |
- except KeyError:
|
|
|
403b09 |
- if has_ca_options or has_cert_option:
|
|
|
403b09 |
- continue
|
|
|
403b09 |
- obj = {
|
|
|
403b09 |
- 'certificate': unicode(base64.b64encode(cert))}
|
|
|
403b09 |
- obj_seq.append(obj)
|
|
|
403b09 |
- obj_dict[cert] = obj
|
|
|
403b09 |
- obj.setdefault('owner', []).append(entry.dn)
|
|
|
403b09 |
-
|
|
|
403b09 |
- result = []
|
|
|
403b09 |
- for obj in obj_seq:
|
|
|
403b09 |
- if has_ldap_options and 'owner' not in obj:
|
|
|
403b09 |
- continue
|
|
|
403b09 |
- if not pkey_only:
|
|
|
403b09 |
- if not raw:
|
|
|
403b09 |
- if 'certificate' in obj:
|
|
|
403b09 |
- obj['certificate'] = (
|
|
|
403b09 |
- obj['certificate'].replace('\r\n', ''))
|
|
|
403b09 |
- self.obj._parse(obj)
|
|
|
403b09 |
- if not all:
|
|
|
403b09 |
- del obj['certificate']
|
|
|
403b09 |
- del obj['valid_not_before']
|
|
|
403b09 |
- del obj['valid_not_after']
|
|
|
403b09 |
- del obj['md5_fingerprint']
|
|
|
403b09 |
- del obj['sha1_fingerprint']
|
|
|
403b09 |
- if 'subject' in obj:
|
|
|
403b09 |
- obj['subject'] = DN(obj['subject'])
|
|
|
403b09 |
- if 'issuer' in obj:
|
|
|
403b09 |
- obj['issuer'] = DN(obj['issuer'])
|
|
|
403b09 |
- if 'status' in obj:
|
|
|
403b09 |
- obj['revoked'] = (
|
|
|
403b09 |
- obj['status'] in (u'REVOKED', u'REVOKED_EXPIRED'))
|
|
|
403b09 |
- if 'owner' in obj:
|
|
|
403b09 |
- if all or not no_members:
|
|
|
403b09 |
- self.obj._fill_owners(obj)
|
|
|
403b09 |
- del obj['owner']
|
|
|
403b09 |
- else:
|
|
|
403b09 |
- if 'certificate' in obj:
|
|
|
403b09 |
- if not all:
|
|
|
403b09 |
- del obj['certificate']
|
|
|
403b09 |
- if 'owner' in obj:
|
|
|
403b09 |
- if not all and no_members:
|
|
|
403b09 |
- del obj['owner']
|
|
|
403b09 |
- else:
|
|
|
403b09 |
- if 'serial_number' in obj:
|
|
|
403b09 |
- serial_number = obj['serial_number']
|
|
|
403b09 |
- obj.clear()
|
|
|
403b09 |
- obj['serial_number'] = serial_number
|
|
|
403b09 |
- else:
|
|
|
403b09 |
- obj.clear()
|
|
|
403b09 |
- result.append(obj)
|
|
|
403b09 |
+ result = list(six.itervalues(result))
|
|
|
403b09 |
|
|
|
403b09 |
ret = dict(
|
|
|
403b09 |
result=result
|
|
|
403b09 |
--
|
|
|
403b09 |
2.7.4
|
|
|
403b09 |
|