URL: https://github.com/freeipa/freeipa/pull/329
Author: frasertweedale
 Title: #329: experiment: did pull/177 break ci?
Action: opened

PR body:
"""
This PR reverts the commits from pull/177 to test the hypothesis
that something in these commits broke CI.
"""

To pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/329/head:pr329
git checkout pr329
From 8e13b7c01311e44eb3ec1dc16dac26b8d3287139 Mon Sep 17 00:00:00 2001
From: Fraser Tweedale <ftwee...@redhat.com>
Date: Tue, 13 Dec 2016 10:50:50 +1000
Subject: [PATCH 1/3] Revert "Add options to write lightweight CA cert or chain
 to file"

This reverts commit 32b1743e5fb318b226a602ec8d9a4b6ef2a25c9d.
---
 API.txt                                   |  6 +--
 VERSION.m4                                |  4 +-
 ipaclient/plugins/ca.py                   | 53 -------------------------
 ipaserver/plugins/ca.py                   | 65 +++----------------------------
 ipaserver/plugins/dogtag.py               | 12 ------
 ipatests/test_xmlrpc/tracker/ca_plugin.py | 31 ++++-----------
 ipatests/test_xmlrpc/xmlrpc_test.py       | 17 --------
 7 files changed, 16 insertions(+), 172 deletions(-)
 delete mode 100644 ipaclient/plugins/ca.py

diff --git a/API.txt b/API.txt
index 543cec5..bad3b92 100644
--- a/API.txt
+++ b/API.txt
@@ -445,11 +445,10 @@ option: Str('version?')
 output: Output('count', type=[<type 'int'>])
 output: Output('results', type=[<type 'list'>, <type 'tuple'>])
 command: ca_add/1
-args: 1,8,3
+args: 1,7,3
 arg: Str('cn', cli_name='name')
 option: Str('addattr*', cli_name='addattr')
 option: Flag('all', autofill=True, cli_name='all', default=False)
-option: Flag('chain', autofill=True, default=False)
 option: Str('description?', cli_name='desc')
 option: DNParam('ipacasubjectdn', cli_name='subject')
 option: Flag('raw', autofill=True, cli_name='raw', default=False)
@@ -520,10 +519,9 @@ output: Entry('result')
 output: Output('summary', type=[<type 'unicode'>, <type 'NoneType'>])
 output: PrimaryKey('value')
 command: ca_show/1
-args: 1,5,3
+args: 1,4,3
 arg: Str('cn', cli_name='name')
 option: Flag('all', autofill=True, cli_name='all', default=False)
-option: Flag('chain', autofill=True, default=False)
 option: Flag('raw', autofill=True, cli_name='raw', default=False)
 option: Flag('rights', autofill=True, default=False)
 option: Str('version?')
diff --git a/VERSION.m4 b/VERSION.m4
index 36929ee..7d9e107 100644
--- a/VERSION.m4
+++ b/VERSION.m4
@@ -73,8 +73,8 @@ define(IPA_DATA_VERSION, 20100614120000)
 #                                                      #
 ########################################################
 define(IPA_API_VERSION_MAJOR, 2)
-define(IPA_API_VERSION_MINOR, 217)
-# Last change: Add options to write lightweight CA cert or chain to file
+define(IPA_API_VERSION_MINOR, 216)
+# Last change: DNS: Support URI resource record type
 
 
 ########################################################
diff --git a/ipaclient/plugins/ca.py b/ipaclient/plugins/ca.py
deleted file mode 100644
index fcdf484..0000000
--- a/ipaclient/plugins/ca.py
+++ /dev/null
@@ -1,53 +0,0 @@
-#
-# Copyright (C) 2016  FreeIPA Contributors see COPYING for license
-#
-
-import base64
-from ipaclient.frontend import MethodOverride
-from ipalib import util, x509, Str
-from ipalib.plugable import Registry
-from ipalib.text import _
-
-register = Registry()
-
-
-class WithCertOutArgs(MethodOverride):
-
-    takes_options = (
-        Str(
-            'certificate_out?',
-            doc=_('Write certificate (chain if --chain used) to file'),
-            include='cli',
-            cli_metavar='FILE',
-        ),
-    )
-
-    def forward(self, *keys, **options):
-        filename = None
-        if 'certificate_out' in options:
-            filename = options.pop('certificate_out')
-            util.check_writable_file(filename)
-
-        result = super(WithCertOutArgs, self).forward(*keys, **options)
-        if filename:
-            def to_pem(x):
-                return x509.make_pem(x)
-            if options.get('chain', False):
-                ders = result['result']['certificate_chain']
-                data = '\n'.join(to_pem(base64.b64encode(der)) for der in ders)
-            else:
-                data = to_pem(result['result']['certificate'])
-            with open(filename, 'wb') as f:
-                f.write(data)
-
-        return result
-
-
-@register(override=True, no_fail=True)
-class ca_add(WithCertOutArgs):
-    pass
-
-
-@register(override=True, no_fail=True)
-class ca_show(WithCertOutArgs):
-    pass
diff --git a/ipaserver/plugins/ca.py b/ipaserver/plugins/ca.py
index ef1d68c..d9ae8c8 100644
--- a/ipaserver/plugins/ca.py
+++ b/ipaserver/plugins/ca.py
@@ -2,18 +2,14 @@
 # Copyright (C) 2016  FreeIPA Contributors see COPYING for license
 #
 
-import base64
-
-import six
-
-from ipalib import api, errors, output, Bytes, DNParam, Flag, Str
+from ipalib import api, errors, output, DNParam, Str
 from ipalib.constants import IPA_CA_CN
 from ipalib.plugable import Registry
 from ipaserver.plugins.baseldap import (
     LDAPObject, LDAPSearch, LDAPCreate, LDAPDelete,
     LDAPUpdate, LDAPRetrieve, LDAPQuery, pkey_to_value)
 from ipaserver.plugins.cert import ca_enabled_check
-from ipalib import _, ngettext, x509
+from ipalib import _, ngettext
 
 
 __doc__ = _("""
@@ -104,18 +100,6 @@ class ca(LDAPObject):
             doc=_('Issuer Distinguished Name'),
             flags=['no_create', 'no_update'],
         ),
-        Bytes(
-            'certificate',
-            label=_("Certificate"),
-            doc=_("Base-64 encoded certificate."),
-            flags={'no_create', 'no_update', 'no_search'},
-        ),
-        Bytes(
-            'certificate_chain*',
-            label=_("Certificate chain"),
-            doc=_("X.509 certificate chain"),
-            flags={'no_create', 'no_update', 'no_search'},
-        ),
     )
 
     permission_filter_objectclasses = ['ipaca']
@@ -161,21 +145,6 @@ class ca(LDAPObject):
     }
 
 
-def set_certificate_attrs(entry, options, always_include_cert=True):
-    ca_id = entry['ipacaid'][0]
-    full = options.get('all', False)
-    with api.Backend.ra_lightweight_ca as ca_api:
-        if always_include_cert or full:
-            der = ca_api.read_ca_cert(ca_id)
-            entry['certificate'] = six.text_type(base64.b64encode(der))
-
-        if options.get('chain', False) or full:
-            pkcs7_der = ca_api.read_ca_chain(ca_id)
-            pems = x509.pkcs7_to_pems(pkcs7_der, x509.DER)
-            ders = [x509.normalize_certificate(pem) for pem in pems]
-            entry['certificate_chain'] = ders
-
-
 @register()
 class ca_find(LDAPSearch):
     __doc__ = _("Search for CAs.")
@@ -185,32 +154,16 @@ class ca_find(LDAPSearch):
 
     def execute(self, *keys, **options):
         ca_enabled_check()
-        result = super(ca_find, self).execute(*keys, **options)
-        for entry in result['result']:
-            set_certificate_attrs(entry, options, always_include_cert=False)
-        return result
-
-
-_chain_flag = Flag(
-    'chain',
-    default=False,
-    doc=_('Include certificate chain in output'),
-)
+        return super(ca_find, self).execute(*keys, **options)
 
 
 @register()
 class ca_show(LDAPRetrieve):
     __doc__ = _("Display the properties of a CA.")
 
-    takes_options = LDAPRetrieve.takes_options + (
-        _chain_flag,
-    )
-
-    def execute(self, *keys, **options):
+    def execute(self, *args, **kwargs):
         ca_enabled_check()
-        result = super(ca_show, self).execute(*keys, **options)
-        set_certificate_attrs(result['result'], options)
-        return result
+        return super(ca_show, self).execute(*args, **kwargs)
 
 
 @register()
@@ -218,10 +171,6 @@ class ca_add(LDAPCreate):
     __doc__ = _("Create a CA.")
     msg_summary = _('Created CA "%(value)s"')
 
-    takes_options = LDAPCreate.takes_options + (
-        _chain_flag,
-    )
-
     def pre_callback(self, ldap, dn, entry, entry_attrs, *keys, **options):
         ca_enabled_check()
         if not ldap.can_add(dn[1:]):
@@ -254,10 +203,6 @@ def pre_callback(self, ldap, dn, entry, entry_attrs, *keys, **options):
         entry['ipacasubjectdn'] = [resp['dn']]
         return dn
 
-    def post_callback(self, ldap, dn, entry_attrs, *keys, **options):
-        set_certificate_attrs(entry_attrs, options)
-        return dn
-
 
 @register()
 class ca_del(LDAPDelete):
diff --git a/ipaserver/plugins/dogtag.py b/ipaserver/plugins/dogtag.py
index 73c14ed..3d0838c 100644
--- a/ipaserver/plugins/dogtag.py
+++ b/ipaserver/plugins/dogtag.py
@@ -2127,18 +2127,6 @@ def read_ca(self, ca_id):
         except:
             raise errors.RemoteRetrieveError(reason=_("Response from CA was not valid JSON"))
 
-    def read_ca_cert(self, ca_id):
-        _status, _resp_headers, resp_body = self._ssldo(
-            'GET', '{}/cert'.format(ca_id),
-            headers={'Accept': 'application/pkix-cert'})
-        return resp_body
-
-    def read_ca_chain(self, ca_id):
-        _status, _resp_headers, resp_body = self._ssldo(
-            'GET', '{}/chain'.format(ca_id),
-            headers={'Accept': 'application/pkcs7-mime'})
-        return resp_body
-
     def disable_ca(self, ca_id):
         self._ssldo(
             'POST', ca_id + '/disable',
diff --git a/ipatests/test_xmlrpc/tracker/ca_plugin.py b/ipatests/test_xmlrpc/tracker/ca_plugin.py
index e18b1c1..ec58c28 100644
--- a/ipatests/test_xmlrpc/tracker/ca_plugin.py
+++ b/ipatests/test_xmlrpc/tracker/ca_plugin.py
@@ -8,13 +8,7 @@
 from ipapython.dn import DN
 from ipatests.test_xmlrpc.tracker.base import Tracker
 from ipatests.util import assert_deepequal
-from ipatests.test_xmlrpc.xmlrpc_test import (
-    fuzzy_issuer,
-    fuzzy_caid,
-    fuzzy_base64,
-    fuzzy_sequence_of,
-    fuzzy_bytes,
-)
+from ipatests.test_xmlrpc.xmlrpc_test import fuzzy_issuer, fuzzy_caid
 from ipatests.test_xmlrpc import objectclasses
 
 
@@ -25,21 +19,12 @@
 class CATracker(Tracker):
     """Implementation of a Tracker class for CA plugin."""
 
-    ldap_keys = {
+    retrieve_keys = {
         'dn', 'cn', 'ipacaid', 'ipacasubjectdn', 'ipacaissuerdn', 'description'
     }
-    cert_keys = {
-        'certificate',
-    }
-    cert_all_keys = {
-        'certificate_chain',
-    }
-    find_keys = ldap_keys
-    find_all_keys = {'objectclass'} | ldap_keys
-    retrieve_keys = ldap_keys | cert_keys
-    retrieve_all_keys = {'objectclass'} | retrieve_keys | cert_all_keys
-    create_keys = {'objectclass'} | retrieve_keys
-    update_keys = ldap_keys - {'dn'}
+    retrieve_all_keys = {'objectclass'} | retrieve_keys
+    create_keys = retrieve_all_keys
+    update_keys = retrieve_keys - {'dn'}
 
     def __init__(self, name, subject, desc=u"Test generated CA",
                  default_version=None):
@@ -74,8 +59,6 @@ def track_create(self):
             ipacasubjectdn=[self.ipasubjectdn],
             ipacaissuerdn=[fuzzy_issuer],
             ipacaid=[fuzzy_caid],
-            certificate=fuzzy_base64,
-            certificate_chain=fuzzy_sequence_of(fuzzy_bytes),
             objectclass=objectclasses.ca
         )
         self.exists = True
@@ -119,9 +102,9 @@ def make_find_command(self, *args, **kwargs):
     def check_find(self, result, all=False, raw=False):
         """Check the plugin's `find` command result"""
         if all:
-            expected = self.filter_attrs(self.find_all_keys)
+            expected = self.filter_attrs(self.retrieve_all_keys)
         else:
-            expected = self.filter_attrs(self.find_keys)
+            expected = self.filter_attrs(self.retrieve_keys)
 
         assert_deepequal(dict(
             count=1,
diff --git a/ipatests/test_xmlrpc/xmlrpc_test.py b/ipatests/test_xmlrpc/xmlrpc_test.py
index 67565b0..0ce1245 100644
--- a/ipatests/test_xmlrpc/xmlrpc_test.py
+++ b/ipatests/test_xmlrpc/xmlrpc_test.py
@@ -22,7 +22,6 @@
 """
 from __future__ import print_function
 
-import collections
 import datetime
 import inspect
 
@@ -50,20 +49,6 @@
     '^cn=%s,cn=automember rebuild membership,cn=tasks,cn=config$' % uuid_re
 )
 
-# base64-encoded value
-fuzzy_base64 = Fuzzy('^[0-9A-Za-z/+]+={0,2}$')
-
-
-def fuzzy_sequence_of(fuzzy):
-    """Construct a Fuzzy for a Sequence of values matching the given Fuzzy."""
-    def test(xs):
-        if not isinstance(xs, collections.Sequence):
-            return False
-        else:
-            return all(fuzzy == x for x in xs)
-
-    return Fuzzy(test=test)
-
 # Matches an automember task finish message
 fuzzy_automember_message = Fuzzy(
     '^Automember rebuild task finished\. Processed \(\d+\) entries\.$'
@@ -124,8 +109,6 @@ def test(xs):
 # match any string
 fuzzy_string = Fuzzy(type=six.string_types)
 
-fuzzy_bytes = Fuzzy(type=bytes)
-
 # case insensitive match of sets
 def fuzzy_set_ci(s):
     return Fuzzy(test=lambda other: set(x.lower() for x in other) == set(y.lower() for y in s))

From 102efca0c53a04c071199a057c647ff923287df4 Mon Sep 17 00:00:00 2001
From: Fraser Tweedale <ftwee...@redhat.com>
Date: Tue, 13 Dec 2016 10:50:53 +1000
Subject: [PATCH 2/3] Revert "certdb: accumulate extracted certs as list of
 PEMs"

This reverts commit cc5b88e5d4ac1171374be9ae8e6e60730243dd3d.
---
 ipapython/certdb.py | 15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/ipapython/certdb.py b/ipapython/certdb.py
index 9481326..4fbbbd9 100644
--- a/ipapython/certdb.py
+++ b/ipapython/certdb.py
@@ -203,7 +203,7 @@ def import_files(self, files, db_password_filename, import_keys=False,
         """
         key_file = None
         extracted_key = None
-        extracted_certs = []
+        extracted_certs = ''
 
         for filename in files:
             try:
@@ -234,7 +234,7 @@ def import_files(self, files, db_password_filename, import_keys=False,
                                     filename, line, e)
                                 continue
                         else:
-                            extracted_certs.append(body)
+                            extracted_certs += body + '\n'
                             loaded = True
                             continue
 
@@ -252,7 +252,7 @@ def import_files(self, files, db_password_filename, import_keys=False,
                                     filename, line, e)
                             continue
                         else:
-                            extracted_certs.extend(certs)
+                            extracted_certs += '\n'.join(certs) + '\n'
                             loaded = True
                             continue
 
@@ -302,7 +302,7 @@ def import_files(self, files, db_password_filename, import_keys=False,
                 pass
             else:
                 data = x509.make_pem(base64.b64encode(data))
-                extracted_certs.append(data)
+                extracted_certs += data + '\n'
                 continue
 
             # Try to import the file as PKCS#12 file
@@ -343,15 +343,14 @@ def import_files(self, files, db_password_filename, import_keys=False,
             raise RuntimeError(
                 "No server certificates found in %s" % (', '.join(files)))
 
-        for cert_pem in extracted_certs:
-            cert = x509.load_certificate(cert_pem)
+        certs = x509.load_certificate_list(extracted_certs)
+        for cert in certs:
             nickname = str(DN(cert.subject))
             data = cert.public_bytes(serialization.Encoding.DER)
             self.add_cert(data, nickname, ',,')
 
         if extracted_key:
-            in_file = ipautil.write_tmp_file(
-                    '\n'.join(extracted_certs) + '\n' + extracted_key)
+            in_file = ipautil.write_tmp_file(extracted_certs + extracted_key)
             out_file = tempfile.NamedTemporaryFile()
             out_password = ipautil.ipa_generate_password()
             out_pwdfile = ipautil.write_tmp_file(out_password)

From 8ef08908aa6b22c7ac000037a1f3271b95313501 Mon Sep 17 00:00:00 2001
From: Fraser Tweedale <ftwee...@redhat.com>
Date: Tue, 13 Dec 2016 10:50:54 +1000
Subject: [PATCH 3/3] Revert "Add function for extracting PEM certs from PKCS
 #7"

This reverts commit c7ea56c049ec8ab1a5500852eca6faf750b1479f.
---
 ipalib/x509.py                  | 29 +----------------------
 ipapython/certdb.py             |  9 +++++--
 ipaserver/install/cainstance.py | 52 ++++++++++++++++++++++++++---------------
 3 files changed, 41 insertions(+), 49 deletions(-)

diff --git a/ipalib/x509.py b/ipalib/x509.py
index 851af5a..e1c3867 100644
--- a/ipalib/x509.py
+++ b/ipalib/x509.py
@@ -49,14 +49,6 @@
 from ipalib import util
 from ipalib import errors
 from ipapython.dn import DN
-from ipapython import ipautil
-
-try:
-    from ipaplatform.paths import paths
-except ImportError:
-    OPENSSL = '/usr/bin/openssl'
-else:
-    OPENSSL = paths.OPENSSL
 
 if six.PY3:
     unicode = str
@@ -64,9 +56,7 @@
 PEM = 0
 DER = 1
 
-PEM_REGEX = re.compile(
-    r'-----BEGIN CERTIFICATE-----.*?-----END CERTIFICATE-----',
-    re.DOTALL)
+PEM_REGEX = re.compile(r'(?<=-----BEGIN CERTIFICATE-----).*?(?=-----END CERTIFICATE-----)', re.DOTALL)
 
 EKU_SERVER_AUTH = '1.3.6.1.5.5.7.3.1'
 EKU_CLIENT_AUTH = '1.3.6.1.5.5.7.3.2'
@@ -155,23 +145,6 @@ def load_certificate_list_from_file(filename):
         return load_certificate_list(f.read())
 
 
-def pkcs7_to_pems(data, datatype=PEM):
-    """
-    Extract certificates from a PKCS #7 object.
-
-    Return a ``list`` of X.509 PEM strings.
-
-    May throw ``ipautil.CalledProcessError`` on invalid data.
-
-    """
-    cmd = [
-        OPENSSL, "pkcs7", "-print_certs",
-        "-inform", "PEM" if datatype == PEM else "DER",
-    ]
-    result = ipautil.run(cmd, stdin=data, capture_output=True)
-    return PEM_REGEX.findall(result.output)
-
-
 def is_self_signed(certificate, datatype=PEM):
     cert = load_certificate(certificate, datatype)
     return cert.issuer == cert.subject
diff --git a/ipapython/certdb.py b/ipapython/certdb.py
index 4fbbbd9..4e05b78 100644
--- a/ipapython/certdb.py
+++ b/ipapython/certdb.py
@@ -239,8 +239,13 @@ def import_files(self, files, db_password_filename, import_keys=False,
                             continue
 
                     if label in ('PKCS7', 'PKCS #7 SIGNED DATA', 'CERTIFICATE'):
+                        args = [
+                            OPENSSL, 'pkcs7',
+                            '-print_certs',
+                        ]
                         try:
-                            certs = x509.pkcs7_to_pems(body)
+                            result = ipautil.run(
+                                args, stdin=body, capture_output=True)
                         except ipautil.CalledProcessError as e:
                             if label == 'CERTIFICATE':
                                 root_logger.warning(
@@ -252,7 +257,7 @@ def import_files(self, files, db_password_filename, import_keys=False,
                                     filename, line, e)
                             continue
                         else:
-                            extracted_certs += '\n'.join(certs) + '\n'
+                            extracted_certs += result.output + '\n'
                             loaded = True
                             continue
 
diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
index c7e81f0..dbea519 100644
--- a/ipaserver/install/cainstance.py
+++ b/ipaserver/install/cainstance.py
@@ -749,30 +749,44 @@ def __import_ca_chain(self):
         # makes openssl throw up.
         data = base64.b64decode(chain)
 
-        certlist = x509.pkcs7_to_pems(data, x509.DER)
+        result = ipautil.run(
+            [paths.OPENSSL,
+             "pkcs7",
+             "-inform",
+             "DER",
+             "-print_certs",
+             ], stdin=data, capture_output=True)
+        certlist = result.output
 
         # Ok, now we have all the certificates in certs, walk through it
         # and pull out each certificate and add it to our database
 
+        st = 1
+        en = 0
+        subid = 0
         ca_dn = DN(('CN','Certificate Authority'), self.subject_base)
-        for cert in certlist:
-            try:
-                chain_fd, chain_name = tempfile.mkstemp()
-                os.write(chain_fd, cert)
-                os.close(chain_fd)
-                (_rdn, subject_dn) = certs.get_cert_nickname(cert)
-                if subject_dn == ca_dn:
-                    nick = get_ca_nickname(self.realm)
-                    trust_flags = 'CT,C,C'
-                else:
-                    nick = str(subject_dn)
-                    trust_flags = ',,'
-                self.__run_certutil(
-                    ['-A', '-t', trust_flags, '-n', nick, '-a',
-                     '-i', chain_name]
-                )
-            finally:
-                os.remove(chain_name)
+        while st > 0:
+            st = certlist.find('-----BEGIN', en)
+            en = certlist.find('-----END', en+1)
+            if st > 0:
+                try:
+                    (chain_fd, chain_name) = tempfile.mkstemp()
+                    os.write(chain_fd, certlist[st:en+25])
+                    os.close(chain_fd)
+                    (_rdn, subject_dn) = certs.get_cert_nickname(certlist[st:en+25])
+                    if subject_dn == ca_dn:
+                        nick = get_ca_nickname(self.realm)
+                        trust_flags = 'CT,C,C'
+                    else:
+                        nick = str(subject_dn)
+                        trust_flags = ',,'
+                    self.__run_certutil(
+                        ['-A', '-t', trust_flags, '-n', nick, '-a',
+                         '-i', chain_name]
+                    )
+                finally:
+                    os.remove(chain_name)
+                    subid += 1
 
         # Restore NSS trust flags of all previously existing certificates
         for nick, trust_flags in cert_backup_list:
-- 
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code

Reply via email to