summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatt Thode <prometheanfire@gentoo.org>2014-06-01 02:19:39 +0000
committerMatt Thode <prometheanfire@gentoo.org>2014-06-01 02:19:39 +0000
commit32bd0426ad4e72a152dc9dbd572bb7337e6f4d9c (patch)
treeb53a54efe307e0e515e6cb3581cda6397d8a3873 /sys-auth/keystone
parentdelete duplicated entry in deps, observed by Arfrever (diff)
downloadhistorical-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/ChangeLog9
-rw-r--r--sys-auth/keystone/Manifest22
-rw-r--r--sys-auth/keystone/files/2014.1-CVE-2014-0204.patch522
-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.ebuild134
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
-}