URL: https://github.com/freeipa/freeipa/pull/824
Author: frasertweedale
 Title: #824: ca-add: validate Subject DN name attributes
Action: synchronized

To pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/824/head:pr824
git checkout pr824
From 9a9944e1504289ba7e898ac8bf749b6c33133eb1 Mon Sep 17 00:00:00 2001
From: Fraser Tweedale <ftwee...@redhat.com>
Date: Mon, 29 May 2017 00:02:24 +1000
Subject: [PATCH] ca-add: validate Subject DN name attributes

If the Subject DN is syntactically valid but contains unrecognised
name attributes, FreeIPA accepts it but Dogtag rejects it, returning
status 400 and causing the framework to raise RemoteRetrieveError.

Update the ca-add command to perform some additional validation on
the user-supplied Subject DN, making sure that we recognise all the
attributes.

Fixes: https://pagure.io/freeipa/issue/6987
---
 ipapython/dn.py                        |  4 ++--
 ipaserver/plugins/ca.py                | 21 +++++++++++++++++++++
 ipatests/test_xmlrpc/test_ca_plugin.py | 15 +++++++++++++++
 3 files changed, 38 insertions(+), 2 deletions(-)

diff --git a/ipapython/dn.py b/ipapython/dn.py
index a54629e8b9..9499096f45 100644
--- a/ipapython/dn.py
+++ b/ipapython/dn.py
@@ -1131,7 +1131,7 @@ def _rdns_from_value(self, value):
         elif isinstance(value, cryptography.x509.name.Name):
             rdns = list(reversed([
                 [get_ava(
-                    _ATTR_NAME_BY_OID.get(ava.oid, ava.oid.dotted_string),
+                    ATTR_NAME_BY_OID.get(ava.oid, ava.oid.dotted_string),
                     ava.value)]
                 for ava in value
             ]))
@@ -1426,7 +1426,7 @@ def rindex(self, pattern, start=None, end=None):
         return i
 
 
-_ATTR_NAME_BY_OID = {
+ATTR_NAME_BY_OID = {
     cryptography.x509.oid.NameOID.COMMON_NAME: 'CN',
     cryptography.x509.oid.NameOID.COUNTRY_NAME: 'C',
     cryptography.x509.oid.NameOID.LOCALITY_NAME: 'L',
diff --git a/ipaserver/plugins/ca.py b/ipaserver/plugins/ca.py
index 9bb163dffa..8db6ec549f 100644
--- a/ipaserver/plugins/ca.py
+++ b/ipaserver/plugins/ca.py
@@ -4,9 +4,12 @@
 
 import base64
 
+import six
+
 from ipalib import api, errors, output, Bytes, DNParam, Flag, Str
 from ipalib.constants import IPA_CA_CN
 from ipalib.plugable import Registry
+from ipapython.dn import ATTR_NAME_BY_OID
 from ipaserver.plugins.baseldap import (
     LDAPObject, LDAPSearch, LDAPCreate, LDAPDelete,
     LDAPUpdate, LDAPRetrieve, LDAPQuery, pkey_to_value)
@@ -236,6 +239,24 @@ def pre_callback(self, ldap, dn, entry, entry_attrs, *keys, **options):
             raise errors.ACIError(
                 info=_("Insufficient 'add' privilege for entry '%s'.") % dn)
 
+        # check that DN only includes standard naming attributes
+        dn_attrs = {
+            ava.attr.lower()
+            for rdn in options['ipacasubjectdn']
+            for ava in rdn
+        }
+        x509_attrs = {
+            attr.lower()
+            for attr in six.viewvalues(ATTR_NAME_BY_OID)
+        }
+        unknown_attrs = dn_attrs - x509_attrs
+        if len(unknown_attrs) > 0:
+            raise errors.ValidationError(
+                name=_("Subject DN"),
+                error=_("Unrecognized attributes: %(attrs)s")
+                    % dict(attrs=", ".join(unknown_attrs))
+            )
+
         # check for name collision before creating CA in Dogtag
         try:
             api.Object.ca.get_dn_if_exists(keys[-1])
diff --git a/ipatests/test_xmlrpc/test_ca_plugin.py b/ipatests/test_xmlrpc/test_ca_plugin.py
index 1e0e52ff74..28cd94aad0 100644
--- a/ipatests/test_xmlrpc/test_ca_plugin.py
+++ b/ipatests/test_xmlrpc/test_ca_plugin.py
@@ -63,6 +63,16 @@ def subject_conflict_subca(request):
     return tracker
 
 
+@pytest.fixture(scope='class')
+def unrecognised_subject_dn_attrs_subca(request):
+    name = u'crud-subca-3'
+    subject = u'CN=crud subca test,DN=example.com,O=crud testing inc'
+    tracker = CATracker(name, subject)
+
+    # Should not get created, no need to delete
+    return tracker
+
+
 @pytest.mark.tier0
 class TestDefaultCA(XMLRPC_test):
     def test_default_ca_present(self, default_ca):
@@ -173,3 +183,8 @@ def test_create_subca_with_subject_conflict(
 
         with pytest.raises(errors.DuplicateEntry):
             subject_conflict_subca.create()
+
+    def test_create_subca_with_unrecognised_subject_dn_attrs(
+            self, unrecognised_subject_dn_attrs_subca):
+        with pytest.raises(errors.ValidationError):
+            unrecognised_subject_dn_attrs_subca.create()
_______________________________________________
FreeIPA-devel mailing list -- freeipa-devel@lists.fedorahosted.org
To unsubscribe send an email to freeipa-devel-le...@lists.fedorahosted.org

Reply via email to