diff options
author | Matt Thode <prometheanfire@gentoo.org> | 2014-06-01 02:19:39 +0000 |
---|---|---|
committer | Matt Thode <prometheanfire@gentoo.org> | 2014-06-01 02:19:39 +0000 |
commit | 32bd0426ad4e72a152dc9dbd572bb7337e6f4d9c (patch) | |
tree | b53a54efe307e0e515e6cb3581cda6397d8a3873 /sys-auth/keystone | |
parent | delete duplicated entry in deps, observed by Arfrever (diff) | |
download | historical-32bd0426ad4e72a152dc9dbd572bb7337e6f4d9c.tar.gz historical-32bd0426ad4e72a152dc9dbd572bb7337e6f4d9c.tar.bz2 historical-32bd0426ad4e72a152dc9dbd572bb7337e6f4d9c.zip |
fix for CVE-2014-0204 bug 511000
Package-Manager: portage-2.2.8-r1/cvs/Linux x86_64
Manifest-Sign-Key: 0x2471EB3E40AC5AC3
Diffstat (limited to 'sys-auth/keystone')
-rw-r--r-- | sys-auth/keystone/ChangeLog | 9 | ||||
-rw-r--r-- | sys-auth/keystone/Manifest | 22 | ||||
-rw-r--r-- | sys-auth/keystone/files/2014.1-CVE-2014-0204.patch | 522 | ||||
-rw-r--r-- | sys-auth/keystone/keystone-2014.1-r2.ebuild (renamed from sys-auth/keystone/keystone-2014.1-r1.ebuild) | 3 | ||||
-rw-r--r-- | sys-auth/keystone/keystone-2014.1.ebuild | 134 |
5 files changed, 548 insertions, 142 deletions
diff --git a/sys-auth/keystone/ChangeLog b/sys-auth/keystone/ChangeLog index 9b1d986dd530..26cec68e73cf 100644 --- a/sys-auth/keystone/ChangeLog +++ b/sys-auth/keystone/ChangeLog @@ -1,6 +1,13 @@ # ChangeLog for sys-auth/keystone # Copyright 1999-2014 Gentoo Foundation; Distributed under the GPL v2 -# $Header: /var/cvsroot/gentoo-x86/sys-auth/keystone/ChangeLog,v 1.69 2014/05/11 11:17:14 vadimk Exp $ +# $Header: /var/cvsroot/gentoo-x86/sys-auth/keystone/ChangeLog,v 1.70 2014/06/01 02:19:16 prometheanfire Exp $ + +*keystone-2014.1-r2 (01 Jun 2014) + + 01 Jun 2014; Matthew Thode <prometheanfire@gentoo.org> + +files/2014.1-CVE-2014-0204.patch, +keystone-2014.1-r2.ebuild, + -keystone-2014.1-r1.ebuild, -keystone-2014.1.ebuild: + fix for CVE-2014-0204 bug 511000 *keystone-2014.1-r1 (11 May 2014) diff --git a/sys-auth/keystone/Manifest b/sys-auth/keystone/Manifest index 4457577df066..8c21b93ad3ad 100644 --- a/sys-auth/keystone/Manifest +++ b/sys-auth/keystone/Manifest @@ -1,6 +1,7 @@ -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256 +AUX 2014.1-CVE-2014-0204.patch 21197 SHA256 1125298db7d1c7f016cd133bb71a36429475a311cfccd9b2ec9ebc7819299f24 SHA512 b42a6ab40dc99e6e273d60f0e9ed85e7e745a855e11a5b492cc06af433a78b8b5b61cc0b3958f46f5375a033d612d94b8a6c4f86b0dc94c57b9edea02a2a00ae WHIRLPOOL 528734f09658e51e46fb36c95f80b2e564fee4f8f0054f6a982796d1390929eb480222e52bb40e031eef97722b8ff7a97dc08fdc51ca6e2c6a01709199c964fb AUX CVE-2014-2828-2013.2.3.patch 2518 SHA256 25ab1d0d633e087d6b8e9ac0aca3be53011abf59d67cd42dc4781df6f3a16247 SHA512 29d08b69226b2e0130b621991ef37f74ef41b0acdcf09e7ab7b991ebf423d999d906ea4e7be4672fb9786f129f6f015246a57c1de36d7321c90b8a87a96ca4e5 WHIRLPOOL 67d27a94110545c02685b769b2b2f2bd291dd7c6c893bfa010e1e36143f485783a9bea27a56347c256f9ad0b6a693f63c9fb7bade60a6a35efe79dc5bf878f6d AUX keystone.confd 124 SHA256 50daa09c5922190a6663e36a32e9b6e5c512672e5be776fcc9b0805da40b6e8d SHA512 1cf50ddcd55421481f8b34f91f35787299b2f9044bcc0a63c70ffff372d740cb84c399d31e52d708fdacad3455d77867d02b438ec2fb39b35ac2e106a2c9e0ad WHIRLPOOL e6c2b76131846cd0ce86e8d766d3f5bbd0d8cd0643de9100d7946afa44c3f13500719feca3ee4ea49644f6881fa34bdc17c08d65a001841ae8f40fc820d334fc AUX keystone.initd 674 SHA256 fc556365de7198de035ebf083b10f59043aa3266270d3ab708d613311f1a719a SHA512 10066c2197973aeee2444ae1bff0ffc3d2a7360a632b55b9c2f66bf064285491e698721ec1525a22b18c0b74a8a6c5c4b84d2cf73812a0f93b2dbfffba799718 WHIRLPOOL 7969003cec68ca8017de003e6a5cfb4bd239a149b06dd9304c9ba8200b4fedfe8ae7e8d3c443e741d1c19cedc5d67150f1d236eef565685a64aa4a998c1ec509 @@ -9,16 +10,25 @@ DIST keystone-2013.2.3.tar.gz 1093050 SHA256 0d27a32c6c211706f8b13aafe2fd51c7ddb DIST keystone-2014.1.tar.gz 1419245 SHA256 51254ea84afd3d98e2744c0cf4877b765e16053e262c5c668aa291bdfdb93900 SHA512 a33e3a511623cace4baa876366c21a5b866221244aa128fec79ab884e8ad6cbfa36ed72f90304b6ebdb81fa7d810cd3714bf67605511a2fd35085ff7adef9e03 WHIRLPOOL 1048ab3410eac9487241805e1428911c6c78a3a7a7b517526ec378732c451d6e33efafb5d5e37f32ed29a7fc08fae5257d6051455588704a4058fdebd1110590 EBUILD keystone-2013.2.3-r1.ebuild 4764 SHA256 5c128452ba5682b689497505cf3b45875e73d8ad2aa907b902c18f44585edb38 SHA512 dfff973ffb1e28b7565186293c9c0443e7591f204bf87ba4adf921e361bab908195c190d6dd46ec22070f895ab52cf83eb6c273255bec6f9d1653022f5a05219 WHIRLPOOL 84d92d56c22059f993110f50ba130dabae50e461cd8c14c5da51a8677b318603b099f93766feb4af2a589e8fe343599c21ed6de122706cdbe4f06f60aaacb3f0 EBUILD keystone-2013.2.9999.ebuild 4377 SHA256 385e06b8c937d146a17664fbd0ed22b58e9cadaf3d3e412ec83454fdaafb8dbf SHA512 17468c45b38e61d254f45389bc7c88929494a8a943b0a4e800bbd1ef788a50d506fa812eb649797e4f6fa8a8340974efae53bb3b07fea504065962b087e3f04e WHIRLPOOL ceab5a177fc6a8dfd6f074434244ecae19b66bfb754df54310b84b3556d513b136152d169fef53945d4a01d1e037022bc14c3cd7c2524374917283d89541e351 -EBUILD keystone-2014.1-r1.ebuild 4874 SHA256 c93d8944959dbed8724d052cb9693580e3f6b8d8d4c0cbb867a9bd420a9fc77f SHA512 10eeb34b600615951d08631e1d4b91f1cd8d9f8bc2f3e2f6748f6dab886cda45904bc27155f2eab18003669d332d385678fe754a4a4087ccee79ba462107d058 WHIRLPOOL c21afca3d059210227c8d7dcb0e2ebbbc3dcb329296711e66b816315e405f8261b6e8c13b9963d709e31810ca8b45496b93041894a0c4db53564b1ce1e825c87 +EBUILD keystone-2014.1-r2.ebuild 4924 SHA256 1648c0629787be53a6f591e9b8ef6a1805954581ab69aba50307bb67579f4eba SHA512 d9dc36343e65a2509ce50469fcd64c7aadbe6135fcb2cd3b50f6f82d9143ec1c31c4fad437ff4a0964ec53f14b710911fd96754cc6fcf18a54009a6580d36e3c WHIRLPOOL 4bddf48be788fd635a48f917be5cc133c7725121289b8262b8a77d3e7d4ff52ae855f1b5157e7a6170cdb795599cf0c91de4d51cd6787e6c01f6bfef8ea00310 EBUILD keystone-2014.1.9999.ebuild 4989 SHA256 e5e7a9fd8e58df694677871bf35d8153959bd9c1efcdb96275c91be8e8aa3421 SHA512 25093e1707f326037b7a9a870846e22e0ac7f71a303aa6aa655b29cfb1b4100ca1050358c062c230396b9a54f4af70eb81184915b4759d3d637381ff33c86ff4 WHIRLPOOL 8d47446634047d8aaf937d7aa6adc75f5b9ec27c0518b6bed964c9cb73e8dd5ab6793bf2456635650916b85c98ebff4f6d4da64f575196395513ade0389ef31a -EBUILD keystone-2014.1.ebuild 5053 SHA256 41ff5c5253446595bfc195964079a28664538744933a7b8bef6abb0b2923bd11 SHA512 f9cf0e67e6ff84c9825eb72763dd4022120904b534e30e107fe5c50e8851237d017866eba0b1f08af4d27bfa320ea1c92c1dcfc2ff41b780a1224ddb1e82a16b WHIRLPOOL f789fc0b4cb33774932f4d64d409ad4e93f1961c0e69153fe11d3b4b8f76c3037b45d443ca610492ccb57c9b64c1b3d28a3e6974751ebdeef8f4ed5cfe7fc7ba EBUILD keystone-9999.ebuild 4363 SHA256 fe7aaf23f6dd4bced7a44d2092fc3ac2148a79088c792808e099439f92385f0f SHA512 818d48bfe82fe801a11ef6b2f65398b99497a4a943ab1882657d3d69224060204300b11288aa48befb3572079c52963cba2e5f5d1d9165bcb3664b444a201369 WHIRLPOOL 08c4f0f9089c7d166f7155d9fb5d5fbb1e05ab9adb784a9c6274f51d3efe1c73bc25818cc237507803e71c7818728e69c52a6c11dafac2d2c0f0fd585f1b1228 -MISC ChangeLog 14974 SHA256 2d190c96de4f51392d13497a8ddebe695fcac488df55571533818c0afe126bb8 SHA512 522b21debb68ff4f638d46479bf0880c6e66174e08c9e7e0b2dfb822e2ef880e678531741c432e0718cc67c8a37da188379dbf53ba54c53ba648719b5d7a6c7b WHIRLPOOL 8cebccd7f075f97281f33da6d1bdaa6adaa12121d81fedb408a355edc98b25e567ca878687ab5ec27c53f834c2d9520686a56e00990c2f7b7950d695cead5d7c +MISC ChangeLog 15230 SHA256 2df86945e59e8f75dacf8735a4c711c1cdad2f51878d677795f0d91f790e075c SHA512 31eda9ff712b81fca117231a5fb420f8dc4db7d6a24ad66cb781bee9c113959cfec85f5a54c0b0ca406b6b2aa1013dae47c34e5d7f15f646d2f676e53687c0c6 WHIRLPOOL 4f878bfb7ae2179d386d3b5863e4aee56575fef8e42b4ddbd5bcd94a4258a1f78bed37c5e7f3f0d59dd6f94fa1194daed5c700f6556076c648f538d66c3d48a5 MISC metadata.xml 424 SHA256 c89c0232e90df5d811d17941c1594e4c4c45db48c2b6240a3c62b232caad4e84 SHA512 9d7fcca89a6f35a93f1a57790103249cdc25424cbdb374bf26b691e81b27182dc3380a8ff67b77e7aabf4ce944e4a813d619838d4bc97086b4208e5312d76f11 WHIRLPOOL 4ec9d4c5ff5c484c341b06fe77fcac8e6fdd0e0b651dbd58b6f2d5aecd05db5bf70218b94733eb749ced7436f9df5ba5c93496bae06c0ff9a62b91ecb53ab77a -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) -iEYEAREIAAYFAlNvXEoACgkQiLKviuHfItX1fgCeLM3UvFrQEDYstQHGutfBlAfV -OewAoK7XKcghNCF+4ZMBC+wmqoLwg0rb -=8Xpt +iQIcBAEBCAAGBQJTio27AAoJECRx6z5ArFrDk+kQALljCymWFC8F5YmkqbRoFHZT +jpowOUMxf+gMYo2RGYIt0L6q2gOy0jCq3/S1EBflYyJsTuAlPS6wbV9+dGsFH7KF +g2U8u++1qB7JX1fKaQNoJgeLiu5I/I9tdY+rmoBx6jj1aAp/OuaInErEqySO7DK8 +BxX+AU2e0XGDlXNSZOcmxMsjo3hpC3PreSojJWytnMiPTTFE+RSVfyfjK/3X2yyo +n06d8K0bA0xxzZiuybxuAknpUo4O1cINuuCcOtRnPU3pBeAGySodtoWMKmqyw39T +jyKEpssjmw6z3PCwKraZHRoLeyZUn2yNykuxjzyopnfTNYUOj3VysWbB77gPJr6v +D2zZvwdE04CJKjkWuCYZLg7n+GOu7vEJYHhLYS9u228vL5cWXSIRx+PEmcmQKAVu +oSRxwG/U2qOEH3XyVVkuciwCV8s++CVm04s1GTmMTOXlgOB9yZGPvSUnNf835AaM +LXPY1rRNiEdFLA3nREYlX3x8WVipAKtDy3Sbl6Zk5gYhMUaXP1SFAv7QS/ntO14v +8oLQmwH35MB0po2K2ChhW9rdr+ESWSK71A/Q991OxAFVDb4WBbjpP0gl5pTY1i92 +sowDsQ0/bq6Y8FGvNy0mTECRb7j4mORVqBPSaSLHe/FWAX12eA+5IqUQ5kZzuiH/ +e/6h9a0/ztW0aF9zah6X +=vDiW -----END PGP SIGNATURE----- diff --git a/sys-auth/keystone/files/2014.1-CVE-2014-0204.patch b/sys-auth/keystone/files/2014.1-CVE-2014-0204.patch new file mode 100644 index 000000000000..b5fc3ba64cc1 --- /dev/null +++ b/sys-auth/keystone/files/2014.1-CVE-2014-0204.patch @@ -0,0 +1,522 @@ +From 786af9829c5329a982e3451f77afebbfb21850bd Mon Sep 17 00:00:00 2001 +From: Brant Knudson <bknudson@us.ibm.com> +Date: Fri, 18 Apr 2014 11:18:42 -0500 +Subject: [PATCH] SQL and LDAP fixes for get_roles_for_user_and_project + user=group ID + +When there was a role assigned to a group with the same ID as a user, +the SQL and LDAP assignment backends would incorrectly return the +assignment to the group when requesting roles for the user via the +get_roles_for_user_and_project method. + +With this change, assignments to a group with the same ID are not +returned for the user when calling get_roles_for_user_and_project. + +Functions were added to compare DNs more accurately based on the +LDAP RFCs. + +The fakeldap code was changed to normalize the values when +comparing values for checking if the values match the filter. + +Co-Authored By: Nathan Kinder <nkinder@redhat.com> +Co-Authored By: Adam Young <ayoung@redhat.com> + +Change-Id: Id3d6f66c995e65e37d909359420d71ecdde86b69 +Closes-Bug: #1309228 +--- + keystone/assignment/backends/ldap.py | 11 +-- + keystone/assignment/backends/sql.py | 15 +++ + keystone/common/ldap/core.py | 110 +++++++++++++++++++++ + keystone/tests/fakeldap.py | 17 +++- + keystone/tests/test_backend.py | 37 +++++++ + keystone/tests/test_backend_ldap.py | 28 ++++++ + keystone/tests/unit/common/test_ldap.py | 169 ++++++++++++++++++++++++++++++++ + 7 files changed, 378 insertions(+), 9 deletions(-) + create mode 100644 keystone/tests/unit/common/test_ldap.py + +diff --git a/keystone/assignment/backends/ldap.py b/keystone/assignment/backends/ldap.py +index 2afd339..09b0f01 100644 +--- a/keystone/assignment/backends/ldap.py ++++ b/keystone/assignment/backends/ldap.py +@@ -88,24 +88,19 @@ def _get_metadata(self, user_id=None, tenant_id=None, + + def _get_roles_for_just_user_and_project(user_id, tenant_id): + self.get_project(tenant_id) ++ user_dn = self.user._id_to_dn(user_id) + return [self.role._dn_to_id(a.role_dn) + for a in self.role.get_role_assignments + (self.project._id_to_dn(tenant_id)) +- if self.user._dn_to_id(a.user_dn) == user_id] ++ if common_ldap.is_dn_equal(a.user_dn, user_dn)] + + def _get_roles_for_group_and_project(group_id, project_id): + self.get_project(project_id) + group_dn = self.group._id_to_dn(group_id) +- # NOTE(marcos-fermin-lobo): In Active Directory, for functions +- # such as "self.role.get_role_assignments", it returns +- # the key "CN" or "OU" in uppercase. +- # The group_dn var has "CN" and "OU" in lowercase. +- # For this reason, it is necessary to use the "upper()" +- # function so both are consistent. + return [self.role._dn_to_id(a.role_dn) + for a in self.role.get_role_assignments + (self.project._id_to_dn(project_id)) +- if a.user_dn.upper() == group_dn.upper()] ++ if common_ldap.is_dn_equal(a.user_dn, group_dn)] + + if domain_id is not None: + msg = _('Domain metadata not supported by LDAP') +diff --git a/keystone/assignment/backends/sql.py b/keystone/assignment/backends/sql.py +index 1d8c78f..b546a42 100644 +--- a/keystone/assignment/backends/sql.py ++++ b/keystone/assignment/backends/sql.py +@@ -86,6 +86,21 @@ def _get_metadata(self, user_id=None, tenant_id=None, + session = sql.get_session() + + q = session.query(RoleAssignment) ++ ++ def _calc_assignment_type(): ++ # Figure out the assignment type we're checking for from the args. ++ if user_id: ++ if tenant_id: ++ return AssignmentType.USER_PROJECT ++ else: ++ return AssignmentType.USER_DOMAIN ++ else: ++ if tenant_id: ++ return AssignmentType.GROUP_PROJECT ++ else: ++ return AssignmentType.GROUP_DOMAIN ++ ++ q = q.filter_by(type=_calc_assignment_type()) + q = q.filter_by(actor_id=user_id or group_id) + q = q.filter_by(target_id=tenant_id or domain_id) + refs = q.all() +diff --git a/keystone/common/ldap/core.py b/keystone/common/ldap/core.py +index e8d1dc0..9561650 100644 +--- a/keystone/common/ldap/core.py ++++ b/keystone/common/ldap/core.py +@@ -13,6 +13,7 @@ + # under the License. + + import os.path ++import re + + import ldap + import ldap.filter +@@ -101,6 +102,115 @@ def ldap_scope(scope): + 'options': ', '.join(LDAP_SCOPES.keys())}) + + ++def prep_case_insensitive(value): ++ """Prepare a string for case-insensitive comparison. ++ ++ This is defined in RFC4518. For simplicity, all this function does is ++ lowercase all the characters, strip leading and trailing whitespace, ++ and compress sequences of spaces to a single space. ++ """ ++ value = re.sub(r'\s+', ' ', value.strip().lower()) ++ return value ++ ++ ++def is_ava_value_equal(attribute_type, val1, val2): ++ """Returns True if and only if the AVAs are equal. ++ ++ When comparing AVAs, the equality matching rule for the attribute type ++ should be taken into consideration. For simplicity, this implementation ++ does a case-insensitive comparison. ++ ++ Note that this function uses prep_case_insenstive so the limitations of ++ that function apply here. ++ ++ """ ++ ++ return prep_case_insensitive(val1) == prep_case_insensitive(val2) ++ ++ ++def is_rdn_equal(rdn1, rdn2): ++ """Returns True if and only if the RDNs are equal. ++ ++ * RDNs must have the same number of AVAs. ++ * Each AVA of the RDNs must be the equal for the same attribute type. The ++ order isn't significant. Note that an attribute type will only be in one ++ AVA in an RDN, otherwise the DN wouldn't be valid. ++ * Attribute types aren't case sensitive. Note that attribute type ++ comparison is more complicated than implemented. This function only ++ compares case-insentive. The code should handle multiple names for an ++ attribute type (e.g., cn, commonName, and 2.5.4.3 are the same). ++ ++ Note that this function uses is_ava_value_equal to compare AVAs so the ++ limitations of that function apply here. ++ ++ """ ++ ++ if len(rdn1) != len(rdn2): ++ return False ++ ++ for attr_type_1, val1, dummy in rdn1: ++ found = False ++ for attr_type_2, val2, dummy in rdn2: ++ if attr_type_1.lower() != attr_type_2.lower(): ++ continue ++ ++ found = True ++ if not is_ava_value_equal(attr_type_1, val1, val2): ++ return False ++ break ++ if not found: ++ return False ++ ++ return True ++ ++ ++def is_dn_equal(dn1, dn2): ++ """Returns True if and only if the DNs are equal. ++ ++ Two DNs are equal if they've got the same number of RDNs and if the RDNs ++ are the same at each position. See RFC4517. ++ ++ Note that this function uses is_rdn_equal to compare RDNs so the ++ limitations of that function apply here. ++ ++ :param dn1: Either a string DN or a DN parsed by ldap.dn.str2dn. ++ :param dn2: Either a string DN or a DN parsed by ldap.dn.str2dn. ++ ++ """ ++ ++ if not isinstance(dn1, list): ++ dn1 = ldap.dn.str2dn(dn1) ++ if not isinstance(dn2, list): ++ dn2 = ldap.dn.str2dn(dn2) ++ ++ if len(dn1) != len(dn2): ++ return False ++ ++ for rdn1, rdn2 in zip(dn1, dn2): ++ if not is_rdn_equal(rdn1, rdn2): ++ return False ++ return True ++ ++ ++def dn_startswith(descendant_dn, dn): ++ """Returns True if and only if the descendant_dn is under the dn. ++ ++ :param descendant_dn: Either a string DN or a DN parsed by ldap.dn.str2dn. ++ :param dn: Either a string DN or a DN parsed by ldap.dn.str2dn. ++ ++ """ ++ ++ if not isinstance(descendant_dn, list): ++ descendant_dn = ldap.dn.str2dn(descendant_dn) ++ if not isinstance(dn, list): ++ dn = ldap.dn.str2dn(dn) ++ ++ if len(descendant_dn) <= len(dn): ++ return False ++ ++ return is_dn_equal(descendant_dn[len(dn):], dn) ++ ++ + _HANDLERS = {} + + +diff --git a/keystone/tests/fakeldap.py b/keystone/tests/fakeldap.py +index 8347d68..21e1bd3 100644 +--- a/keystone/tests/fakeldap.py ++++ b/keystone/tests/fakeldap.py +@@ -51,6 +51,19 @@ def _process_attr(attr_name, value_or_values): + + def normalize_dn(dn): + # Capitalize the attribute names as an LDAP server might. ++ ++ # NOTE(blk-u): Special case for this tested value, used with ++ # test_user_id_comma. The call to str2dn here isn't always correct ++ # here, because `dn` is escaped for an LDAP filter. str2dn() normally ++ # works only because there's no special characters in `dn`. ++ if dn == 'cn=Doe\\5c, John,ou=Users,cn=example,cn=com': ++ return 'CN=Doe\\, John,OU=Users,CN=example,CN=com' ++ ++ # NOTE(blk-u): Another special case for this tested value. When a ++ # roleOccupant has an escaped comma, it gets converted to \2C. ++ if dn == 'cn=Doe\\, John,ou=Users,cn=example,cn=com': ++ return 'CN=Doe\\2C John,OU=Users,CN=example,CN=com' ++ + dn = ldap.dn.str2dn(dn) + norm = [] + for part in dn: +@@ -118,7 +131,9 @@ def _match(key, value, attrs): + str_sids = [str(x) for x in attrs[key]] + return str(value) in str_sids + if key != 'objectclass': +- return _process_attr(key, value)[0] in attrs[key] ++ check_value = _process_attr(key, value)[0] ++ norm_values = list(_process_attr(key, x)[0] for x in attrs[key]) ++ return check_value in norm_values + # it is an objectclass check, so check subclasses + values = _subs(value) + for v in values: +diff --git a/keystone/tests/test_backend.py b/keystone/tests/test_backend.py +index c8d7341..b42b209 100644 +--- a/keystone/tests/test_backend.py ++++ b/keystone/tests/test_backend.py +@@ -1377,6 +1377,43 @@ def test_multi_group_grants_on_project_domain(self): + self.assertIn(role_list[1]['id'], combined_role_list) + self.assertIn(role_list[2]['id'], combined_role_list) + ++ def test_get_roles_for_user_and_project_user_group_same_id(self): ++ """When a user has the same ID as a group, ++ get_roles_for_user_and_project returns only the roles for the user and ++ not the group. ++ ++ """ ++ ++ # Setup: create user, group with same ID, role, and project; ++ # assign the group the role on the project. ++ ++ user_group_id = uuid.uuid4().hex ++ ++ user1 = {'id': user_group_id, 'name': uuid.uuid4().hex, ++ 'domain_id': DEFAULT_DOMAIN_ID, } ++ self.identity_api.create_user(user_group_id, user1) ++ ++ group1 = {'id': user_group_id, 'name': uuid.uuid4().hex, ++ 'domain_id': DEFAULT_DOMAIN_ID, } ++ self.identity_api.create_group(user_group_id, group1) ++ ++ role1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} ++ self.assignment_api.create_role(role1['id'], role1) ++ ++ project1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex, ++ 'domain_id': DEFAULT_DOMAIN_ID, } ++ self.assignment_api.create_project(project1['id'], project1) ++ ++ self.assignment_api.create_grant(role1['id'], ++ group_id=user_group_id, ++ project_id=project1['id']) ++ ++ # Check the roles, shouldn't be any since the user wasn't granted any. ++ roles = self.assignment_api.get_roles_for_user_and_project( ++ user_group_id, project1['id']) ++ ++ self.assertEqual([], roles, 'role for group is %s' % role1['id']) ++ + def test_delete_role_with_user_and_group_grants(self): + role1 = {'id': uuid.uuid4().hex, 'name': uuid.uuid4().hex} + self.assignment_api.create_role(role1['id'], role1) +diff --git a/keystone/tests/test_backend_ldap.py b/keystone/tests/test_backend_ldap.py +index 310fbbc..9964527 100644 +--- a/keystone/tests/test_backend_ldap.py ++++ b/keystone/tests/test_backend_ldap.py +@@ -546,6 +546,34 @@ def test_new_arbitrary_attributes_are_returned_from_update_user(self): + def test_updated_arbitrary_attributes_are_returned_from_update_user(self): + self.skipTest("Using arbitrary attributes doesn't work under LDAP") + ++ def test_user_id_comma_grants(self): ++ """Even if the user has a , in their ID, can get user and group grants. ++ """ ++ ++ # Create a user with a , in their ID ++ # NOTE(blk-u): the DN for this user is hard-coded in fakeldap! ++ user_id = u'Doe, John' ++ user = { ++ 'id': user_id, ++ 'name': self.getUniqueString(), ++ 'password': self.getUniqueString(), ++ 'domain_id': CONF.identity.default_domain_id, ++ } ++ self.identity_api.create_user(user_id, user) ++ ++ # Grant the user a role on a project. ++ ++ role_id = 'member' ++ project_id = self.tenant_baz['id'] ++ ++ self.assignment_api.create_grant(role_id, user_id=user_id, ++ project_id=project_id) ++ ++ role_ref = self.assignment_api.get_grant(role_id, user_id=user_id, ++ project_id=project_id) ++ ++ self.assertEqual(role_id, role_ref['id']) ++ + + class LDAPIdentity(BaseLDAPIdentity, tests.TestCase): + def setUp(self): +diff --git a/keystone/tests/unit/common/test_ldap.py b/keystone/tests/unit/common/test_ldap.py +new file mode 100644 +index 0000000..220bf1a +--- /dev/null ++++ b/keystone/tests/unit/common/test_ldap.py +@@ -0,0 +1,169 @@ ++# Licensed under the Apache License, Version 2.0 (the "License"); you may ++# not use this file except in compliance with the License. You may obtain ++# a copy of the License at ++# ++# http://www.apache.org/licenses/LICENSE-2.0 ++# ++# Unless required by applicable law or agreed to in writing, software ++# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT ++# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the ++# License for the specific language governing permissions and limitations ++# under the License. ++ ++import ldap.dn ++ ++from keystone.common import ldap as ks_ldap ++from keystone import tests ++ ++ ++class DnCompareTest(tests.BaseTestCase): ++ """Tests for the DN comparison functions in keystone.common.ldap.core.""" ++ ++ def test_prep(self): ++ # prep_case_insensitive returns the string with spaces at the front and ++ # end if it's already lowercase and no insignificant characters. ++ value = 'lowercase value' ++ self.assertEqual(value, ks_ldap.prep_case_insensitive(value)) ++ ++ def test_prep_lowercase(self): ++ # prep_case_insensitive returns the string with spaces at the front and ++ # end and lowercases the value. ++ value = 'UPPERCASE VALUE' ++ exp_value = value.lower() ++ self.assertEqual(exp_value, ks_ldap.prep_case_insensitive(value)) ++ ++ def test_prep_insignificant(self): ++ # prep_case_insensitive remove insignificant spaces. ++ value = 'before after' ++ exp_value = 'before after' ++ self.assertEqual(exp_value, ks_ldap.prep_case_insensitive(value)) ++ ++ def test_prep_insignificant_pre_post(self): ++ # prep_case_insensitive remove insignificant spaces. ++ value = ' value ' ++ exp_value = 'value' ++ self.assertEqual(exp_value, ks_ldap.prep_case_insensitive(value)) ++ ++ def test_ava_equal_same(self): ++ # is_ava_value_equal returns True if the two values are the same. ++ value = 'val1' ++ self.assertTrue(ks_ldap.is_ava_value_equal('cn', value, value)) ++ ++ def test_ava_equal_complex(self): ++ # is_ava_value_equal returns True if the two values are the same using ++ # a value that's got different capitalization and insignificant chars. ++ val1 = 'before after' ++ val2 = ' BEFORE afTer ' ++ self.assertTrue(ks_ldap.is_ava_value_equal('cn', val1, val2)) ++ ++ def test_ava_different(self): ++ # is_ava_value_equal returns False if the values aren't the same. ++ self.assertFalse(ks_ldap.is_ava_value_equal('cn', 'val1', 'val2')) ++ ++ def test_rdn_same(self): ++ # is_rdn_equal returns True if the two values are the same. ++ rdn = ldap.dn.str2dn('cn=val1')[0] ++ self.assertTrue(ks_ldap.is_rdn_equal(rdn, rdn)) ++ ++ def test_rdn_diff_length(self): ++ # is_rdn_equal returns False if the RDNs have a different number of ++ # AVAs. ++ rdn1 = ldap.dn.str2dn('cn=cn1')[0] ++ rdn2 = ldap.dn.str2dn('cn=cn1+ou=ou1')[0] ++ self.assertFalse(ks_ldap.is_rdn_equal(rdn1, rdn2)) ++ ++ def test_rdn_multi_ava_same_order(self): ++ # is_rdn_equal returns True if the RDNs have the same number of AVAs ++ # and the values are the same. ++ rdn1 = ldap.dn.str2dn('cn=cn1+ou=ou1')[0] ++ rdn2 = ldap.dn.str2dn('cn=CN1+ou=OU1')[0] ++ self.assertTrue(ks_ldap.is_rdn_equal(rdn1, rdn2)) ++ ++ def test_rdn_multi_ava_diff_order(self): ++ # is_rdn_equal returns True if the RDNs have the same number of AVAs ++ # and the values are the same, even if in a different order ++ rdn1 = ldap.dn.str2dn('cn=cn1+ou=ou1')[0] ++ rdn2 = ldap.dn.str2dn('ou=OU1+cn=CN1')[0] ++ self.assertTrue(ks_ldap.is_rdn_equal(rdn1, rdn2)) ++ ++ def test_rdn_multi_ava_diff_type(self): ++ # is_rdn_equal returns False if the RDNs have the same number of AVAs ++ # and the attribute types are different. ++ rdn1 = ldap.dn.str2dn('cn=cn1+ou=ou1')[0] ++ rdn2 = ldap.dn.str2dn('cn=cn1+sn=sn1')[0] ++ self.assertFalse(ks_ldap.is_rdn_equal(rdn1, rdn2)) ++ ++ def test_rdn_attr_type_case_diff(self): ++ # is_rdn_equal returns True for same RDNs even when attr type case is ++ # different. ++ rdn1 = ldap.dn.str2dn('cn=cn1')[0] ++ rdn2 = ldap.dn.str2dn('CN=cn1')[0] ++ self.assertTrue(ks_ldap.is_rdn_equal(rdn1, rdn2)) ++ ++ def test_rdn_attr_type_alias(self): ++ # is_rdn_equal returns False for same RDNs even when attr type alias is ++ # used. Note that this is a limitation since an LDAP server should ++ # consider them equal. ++ rdn1 = ldap.dn.str2dn('cn=cn1')[0] ++ rdn2 = ldap.dn.str2dn('2.5.4.3=cn1')[0] ++ self.assertFalse(ks_ldap.is_rdn_equal(rdn1, rdn2)) ++ ++ def test_dn_same(self): ++ # is_dn_equal returns True if the DNs are the same. ++ dn = 'cn=Babs Jansen,ou=OpenStack' ++ self.assertTrue(ks_ldap.is_dn_equal(dn, dn)) ++ ++ def test_dn_diff_length(self): ++ # is_dn_equal returns False if the DNs don't have the same number of ++ # RDNs ++ dn1 = 'cn=Babs Jansen,ou=OpenStack' ++ dn2 = 'cn=Babs Jansen,ou=OpenStack,dc=example.com' ++ self.assertFalse(ks_ldap.is_dn_equal(dn1, dn2)) ++ ++ def test_dn_equal_rdns(self): ++ # is_dn_equal returns True if the DNs have the same number of RDNs ++ # and each RDN is the same. ++ dn1 = 'cn=Babs Jansen,ou=OpenStack+cn=OpenSource' ++ dn2 = 'CN=Babs Jansen,cn=OpenSource+ou=OpenStack' ++ self.assertTrue(ks_ldap.is_dn_equal(dn1, dn2)) ++ ++ def test_dn_parsed_dns(self): ++ # is_dn_equal can also accept parsed DNs. ++ dn_str1 = ldap.dn.str2dn('cn=Babs Jansen,ou=OpenStack+cn=OpenSource') ++ dn_str2 = ldap.dn.str2dn('CN=Babs Jansen,cn=OpenSource+ou=OpenStack') ++ self.assertTrue(ks_ldap.is_dn_equal(dn_str1, dn_str2)) ++ ++ def test_startswith_under_child(self): ++ # dn_startswith returns True if descendant_dn is a child of dn. ++ child = 'cn=Babs Jansen,ou=OpenStack' ++ parent = 'ou=OpenStack' ++ self.assertTrue(ks_ldap.dn_startswith(child, parent)) ++ ++ def test_startswith_parent(self): ++ # dn_startswith returns False if descendant_dn is a parent of dn. ++ child = 'cn=Babs Jansen,ou=OpenStack' ++ parent = 'ou=OpenStack' ++ self.assertFalse(ks_ldap.dn_startswith(parent, child)) ++ ++ def test_startswith_same(self): ++ # dn_startswith returns False if DNs are the same. ++ dn = 'cn=Babs Jansen,ou=OpenStack' ++ self.assertFalse(ks_ldap.dn_startswith(dn, dn)) ++ ++ def test_startswith_not_parent(self): ++ # dn_startswith returns False if descendant_dn is not under the dn ++ child = 'cn=Babs Jansen,ou=OpenStack' ++ parent = 'dc=example.com' ++ self.assertFalse(ks_ldap.dn_startswith(child, parent)) ++ ++ def test_startswith_descendant(self): ++ # dn_startswith returns True if descendant_dn is a descendant of dn. ++ descendant = 'cn=Babs Jansen,ou=Keystone,ou=OpenStack,dc=example.com' ++ dn = 'ou=OpenStack,dc=example.com' ++ self.assertTrue(ks_ldap.dn_startswith(descendant, dn)) ++ ++ def test_startswith_parsed_dns(self): ++ # dn_startswith also accepts parsed DNs. ++ descendant = ldap.dn.str2dn('cn=Babs Jansen,ou=OpenStack') ++ dn = ldap.dn.str2dn('ou=OpenStack') ++ self.assertTrue(ks_ldap.dn_startswith(descendant, dn)) +-- +1.9.3 + diff --git a/sys-auth/keystone/keystone-2014.1-r1.ebuild b/sys-auth/keystone/keystone-2014.1-r2.ebuild index 054ce0ca6888..7d9a842a0d51 100644 --- a/sys-auth/keystone/keystone-2014.1-r1.ebuild +++ b/sys-auth/keystone/keystone-2014.1-r2.ebuild @@ -1,6 +1,6 @@ # Copyright 1999-2014 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 -# $Header: /var/cvsroot/gentoo-x86/sys-auth/keystone/keystone-2014.1-r1.ebuild,v 1.1 2014/05/11 11:17:14 vadimk Exp $ +# $Header: /var/cvsroot/gentoo-x86/sys-auth/keystone/keystone-2014.1-r2.ebuild,v 1.1 2014/06/01 02:19:16 prometheanfire Exp $ EAPI=5 @@ -77,6 +77,7 @@ RDEPEND=">=dev-python/webob-1.2.3-r1[${PYTHON_USEDEP}] ldap? ( dev-python/python-ldap[${PYTHON_USEDEP}] )" PATCHES=( + "${FILESDIR}/2014.1-CVE-2014-0204.patch" ) pkg_setup() { diff --git a/sys-auth/keystone/keystone-2014.1.ebuild b/sys-auth/keystone/keystone-2014.1.ebuild deleted file mode 100644 index 5fb710184d12..000000000000 --- a/sys-auth/keystone/keystone-2014.1.ebuild +++ /dev/null @@ -1,134 +0,0 @@ -# Copyright 1999-2014 Gentoo Foundation -# Distributed under the terms of the GNU General Public License v2 -# $Header: /var/cvsroot/gentoo-x86/sys-auth/keystone/keystone-2014.1.ebuild,v 1.2 2014/04/29 17:33:21 prometheanfire Exp $ - -EAPI=5 - -PYTHON_COMPAT=( python2_7 ) - -inherit distutils-r1 user - -DESCRIPTION="The Openstack authentication, authorization, and service catalog written in Python." -HOMEPAGE="https://launchpad.net/keystone" -SRC_URI="http://launchpad.net/${PN}/icehouse/${PV}/+download/${P}.tar.gz" - -LICENSE="Apache-2.0" -SLOT="0" -KEYWORDS="~amd64 ~x86" -IUSE="+sqlite mysql postgres ldap test" -REQUIRED_USE="|| ( mysql postgres sqlite )" - -#todo, seperate out rdepend via use flags -DEPEND="dev-python/setuptools[${PYTHON_USEDEP}] - >=dev-python/pbr-0.6[${PYTHON_USEDEP}] - <dev-python/pbr-1.0[${PYTHON_USEDEP}] - test? ( ${RDEPEND} - >=dev-python/hacking-0.8[${PYTHON_USEDEP}] - <dev-python/hacking-0.9[${PYTHON_USEDEP}] - dev-lang/python[sqlite] - >=dev-python/python-memcached-1.48[${PYTHON_USEDEP}] - >=dev-python/pymongo-2.4[${PYTHON_USEDEP}] - ldap? ( ~dev-python/python-ldap-2.3.13 ) - >=dev-python/coverage-3.6[${PYTHON_USEDEP}] - >=dev-python/fixtures-0.3.14[${PYTHON_USEDEP}] - >=dev-python/mock-1.0[${PYTHON_USEDEP}] - >=dev-python/mox-0.5.3[${PYTHON_USEDEP}] - >=dev-python/sphinx-1.1.2[${PYTHON_USEDEP}] - <dev-python/sphinx-1.2[${PYTHON_USEDEP}] - >=dev-python/webtest-2.0[${PYTHON_USEDEP}] - >=dev-python/subunit-0.0.18[${PYTHON_USEDEP}] - >=dev-python/testrepository-0.0.18[${PYTHON_USEDEP}] - >=dev-python/testtools-0.9.34[${PYTHON_USEDEP}] - >=dev-python/testscenarios-0.4[${PYTHON_USEDEP}] - >=dev-python/httplib2-0.7.5[${PYTHON_USEDEP}] - >=dev-python/requests-1.1[${PYTHON_USEDEP}] - >=dev-python/keyring-2.1[${PYTHON_USEDEP}] - dev-python/oslo-sphinx[${PYTHON_USEDEP}] - >=dev-python/kombu-2.4.8[${PYTHON_USEDEP}] - >=dev-python/lockfile-0.8[${PYTHON_USEDEP}] - >=dev-python/stevedore-0.14[${PYTHON_USEDEP}] - )" -RDEPEND=">=dev-python/webob-1.2.3-r1[${PYTHON_USEDEP}] - >=dev-python/eventlet-0.13.0[${PYTHON_USEDEP}] - >=dev-python/greenlet-0.3.2[${PYTHON_USEDEP}] - >=dev-python/netaddr-0.7.6[${PYTHON_USEDEP}] - >=dev-python/pastedeploy-1.5.0[${PYTHON_USEDEP}] - dev-python/paste[${PYTHON_USEDEP}] - >=dev-python/routes-1.12.3[${PYTHON_USEDEP}] - >=dev-python/six-1.5.2[${PYTHON_USEDEP}] - sqlite? ( >=dev-python/sqlalchemy-0.7.8[sqlite,${PYTHON_USEDEP}] - <=dev-python/sqlalchemy-0.9.99[sqlite,${PYTHON_USEDEP}] ) - mysql? ( >=dev-python/sqlalchemy-0.7.8[mysql,${PYTHON_USEDEP}] - <=dev-python/sqlalchemy-0.9.99[mysql,${PYTHON_USEDEP}] ) - postgres? ( >=dev-python/sqlalchemy-0.7.8[postgres,${PYTHON_USEDEP}] - <=dev-python/sqlalchemy-0.9.99[postgres,${PYTHON_USEDEP}] ) - >=dev-python/sqlalchemy-migrate-0.9[${PYTHON_USEDEP}] - dev-python/passlib[${PYTHON_USEDEP}] - >=dev-python/lxml-2.3[${PYTHON_USEDEP}] - >=dev-python/iso8601-0.1.9[${PYTHON_USEDEP}] - >=dev-python/python-keystoneclient-0.7.0[${PYTHON_USEDEP}] - >=dev-python/oslo-config-1.2.0[${PYTHON_USEDEP}] - >=dev-python/oslo-messaging-1.3.0[${PYTHON_USEDEP}] - >=dev-python/Babel-1.3[${PYTHON_USEDEP}] - >=dev-python/oauthlib-0.6.0[${PYTHON_USEDEP}] - >=dev-python/dogpile-cache-0.5.0[${PYTHON_USEDEP}] - >=dev-python/jsonschema-2.0.0[${PYTHON_USEDEP}] - <dev-python/jsonschema-3.0.0[${PYTHON_USEDEP}] - >=dev-python/pycadf-0.4.1[${PYTHON_USEDEP}] - ldap? ( dev-python/python-ldap[${PYTHON_USEDEP}] )" - -PATCHES=( -) - -pkg_setup() { - enewgroup keystone - enewuser keystone -1 -1 /var/lib/keystone keystone -} - -python_prepare_all() { - # it's in git, but not in the tarball..... - mkdir -p ${PN}/tests/tmp/ || die - cp etc/keystone-paste.ini ${PN}/tests/tmp/ || die - distutils-r1_python_prepare_all -} - -python_test() { - # Ignore (naughty) test_.py files & 1 test that connect to the network - nosetests -I 'test_keystoneclient*' \ - -e test_import || die "testsuite failed under python2.7" -} - -python_install() { - distutils-r1_python_install - newconfd "${FILESDIR}/keystone.confd" keystone - newinitd "${FILESDIR}/keystone.initd" keystone - - diropts -m 0750 - keepdir /etc/keystone /var/log/keystone - insinto /etc/keystone - doins etc/keystone.conf.sample etc/logging.conf.sample - doins etc/default_catalog.templates etc/policy.json - doins etc/policy.v3cloudsample.json etc/keystone-paste.ini - - fowners keystone:keystone /etc/keystone /var/log/keystone -} - -pkg_postinst() { - elog "You might want to run:" - elog "emerge --config =${CATEGORY}/${PF}" - elog "if this is a new install." - elog "If you have not already configured your openssl installation" - elog "please do it by modifying /etc/ssl/openssl.cnf" - elog "BEFORE issuing the configuration command." - elog "Otherwise default values will be used." -} - -pkg_config() { - if [ ! -d "${ROOT}"/etc/keystone/ssl ] ; then - einfo "Press ENTER to configure the keystone PKI, or Control-C to abort now..." - read - "${ROOT}"/usr/bin/keystone-manage pki_setup --keystone-user keystone --keystone-group keystone - else - einfo "keystone PKI certificates directory already present, skipping configuration" - fi -} |