diff options
author | Matt Thode <prometheanfire@gentoo.org> | 2013-05-10 02:30:27 +0000 |
---|---|---|
committer | Matt Thode <prometheanfire@gentoo.org> | 2013-05-10 02:30:27 +0000 |
commit | 6f2573725bd653935648eb84e6d220a1efa132b8 (patch) | |
tree | 764df78f0755d73e3cb33bfd9d6e017525e61d95 /sys-cluster | |
parent | Version bump, bug #469168 (diff) | |
download | historical-6f2573725bd653935648eb84e6d220a1efa132b8.tar.gz historical-6f2573725bd653935648eb84e6d220a1efa132b8.tar.bz2 historical-6f2573725bd653935648eb84e6d220a1efa132b8.zip |
updating openstack nova, should squash at least one sec bug hopefully
2012.2.4 and 2013.1.1
Package-Manager: portage-2.1.11.55/cvs/Linux x86_64
Manifest-Sign-Key: 0x2471EB3E40AC5AC3
Diffstat (limited to 'sys-cluster')
-rw-r--r-- | sys-cluster/nova/ChangeLog | 13 | ||||
-rw-r--r-- | sys-cluster/nova/Manifest | 39 | ||||
-rw-r--r-- | sys-cluster/nova/files/nova-folsom-3-CVE-2013-0335.patch | 410 | ||||
-rw-r--r-- | sys-cluster/nova/files/nova-folsom-3-CVE-2013-1838.patch | 507 | ||||
-rw-r--r-- | sys-cluster/nova/files/nova-folsom-CVE-2013-1664.patch | 396 | ||||
-rw-r--r-- | sys-cluster/nova/nova-2012.2.4.ebuild (renamed from sys-cluster/nova/nova-2012.2.3-r3.ebuild) | 5 | ||||
-rw-r--r-- | sys-cluster/nova/nova-2013.1.1.ebuild (renamed from sys-cluster/nova/nova-2013.1.ebuild) | 2 |
7 files changed, 32 insertions, 1340 deletions
diff --git a/sys-cluster/nova/ChangeLog b/sys-cluster/nova/ChangeLog index 1cf9f27466b9..b8db0de47176 100644 --- a/sys-cluster/nova/ChangeLog +++ b/sys-cluster/nova/ChangeLog @@ -1,6 +1,17 @@ # ChangeLog for sys-cluster/nova # Copyright 1999-2013 Gentoo Foundation; Distributed under the GPL v2 -# $Header: /var/cvsroot/gentoo-x86/sys-cluster/nova/ChangeLog,v 1.9 2013/04/11 07:34:27 prometheanfire Exp $ +# $Header: /var/cvsroot/gentoo-x86/sys-cluster/nova/ChangeLog,v 1.10 2013/05/10 02:30:19 prometheanfire Exp $ + +*nova-2013.1.1 (10 May 2013) +*nova-2012.2.4 (10 May 2013) + + 10 May 2013; Matthew Thode <prometheanfire@gentoo.org> +nova-2012.2.4.ebuild, + +nova-2013.1.1.ebuild, -files/nova-folsom-3-CVE-2013-0335.patch, + -files/nova-folsom-3-CVE-2013-1838.patch, + -files/nova-folsom-CVE-2013-1664.patch, -nova-2012.2.3-r3.ebuild, + -nova-2013.1.ebuild: + updating openstack nova, should squash at least one sec bug hopefully 2012.2.4 + and 2013.1.1 *nova-9999 (11 Apr 2013) diff --git a/sys-cluster/nova/Manifest b/sys-cluster/nova/Manifest index 3f9a603e0dea..24573211e18d 100644 --- a/sys-cluster/nova/Manifest +++ b/sys-cluster/nova/Manifest @@ -1,30 +1,27 @@ -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256 -AUX nova-folsom-3-CVE-2013-0335.patch 18147 SHA256 be947b94ea5b41c13e0c945f428c426cddbfa127ab2a166adc7d49965e4060da SHA512 ba687fe8c557d4c03eaa189f7c611255e1b1902d31e4f95847abf3649cdba2eaa90d1f4e6813ec0c8c9065f10f5d38c77716a02ac2d103310edaf40de0a4070c WHIRLPOOL e02563ff87b2bbc966a02ab026f5a718a6cfd3a7d6aeb5854d67c348e16d324e45a1859d3c6c52d655e7b0a8b0cac637aee3aca30bcde9d2c7d005e341c4f58e -AUX nova-folsom-3-CVE-2013-1838.patch 22534 SHA256 e3faa721a3595edc346997c4553aa9cb92927bab41b4869b258038ff5cf119da SHA512 65fee6cc38bac0775fa2ea4f37632f6eaa7ac92ec4c61dbaf4f56c4a5e4796b0a6039e2b94a243703fd8d471e37e57d7151c2ed74185e36a5a4c56f6d150a55a WHIRLPOOL a78274b5cd5df2c23c0a772e45cf9f49c779026e08d7a71978cc38263049bf393e9e1558f154cf185a20ddab8e56723b44d3cb43a6c3e578b7d92faeacdf787a -AUX nova-folsom-CVE-2013-1664.patch 14249 SHA256 5eb9827905a51a96e86e582a6fb06585f6f4aec29232b06b17294c9745dd7582 SHA512 4ad9a6e5919ab7eb7c7c592b4ec6dfd9b448f836dd6329c58df876b0cdb1a0f92c90c8307450d85fa9ce2cef6ed90906c64e0fabfa848b8f804e044d5d451b87 WHIRLPOOL 8c25ae9c76c0a48524f8b00ceaeadded64615be50114ab371e444f75bedf1962537d23cda989f169422e7ec6ed5e92d7010405251105d2f8863db0c7fef81459 -DIST nova-2012.2.3.tar.gz 6260067 SHA256 e9640d89e84d3feaa537b1faa3945c708beb2cffd8a114ff83484ea151406994 SHA512 bbbbb140ff09d508a44d6b5dc9817b4d6e277ddc45ae1b70b45915c3e8c6873cffaf670a2a745381bbf63b4d5869fab6a524c7d2816fafe0aa4fe73a6ffca15d WHIRLPOOL da4cc6033426fb5268bff67a18574c8d2de4dbbc528df6982e2b87e8b3a92f2df999c8d6bf0b6fb3de1397feccdd906e064b78e3f7bab7fee679eee2437e3185 -DIST nova-2013.1.tar.gz 5713369 SHA256 db7f5259d848358bf14105d5833869ec145f643312e6bc0adef0050120fe3e07 SHA512 d23c121ad2f041bab823d231d6708b991d80db18e9529eb9a06b7854204069a398ac9ce3bd7e83aa872db877ffcd9934422b76ca3a4d176c6728b3c8fda50e0a WHIRLPOOL c4225b29e20c377aecb14454725344ce5458e009f05387b3c4d1c0695c54997cb58dcc0218a6722f9ca78658485055c5140b052535aa676d9eb280477a6aaceb -EBUILD nova-2012.2.3-r3.ebuild 2334 SHA256 57efe68fe80fc13350805791151584f382cd7cf5fad07bf088a495a103c1747d SHA512 4225b7b6fe6a098ac8295a2d86cf749024cdf1c1921c24c0596f48f3ac8b7509ae02d095ce2657f4999fc24de8ec265715cc4f5a79d6397ea5e506ddcccbee44 WHIRLPOOL aa0fdda629ee20fcdef026b23408c36d4f93781ce853164b0437504040f4832f0d37ecc0ae31327927162652d367c00e542c8cfa01eca81aef2eeb5580274689 -EBUILD nova-2013.1.ebuild 2569 SHA256 1152daf7959c1797527e2e080abb2f3239c287170309809b265a1b4e21f935a2 SHA512 6a8e8f325de86a115b28fa4d9e83dd4e231b54c7f23736abc3894010c265f9c71dac5f0a9988f4e41d9258d717446256671aace9d1e67515b966ab1daac5035e WHIRLPOOL b902af76f17bbb62f683302a042fad64df275edc92d8bf19a114b0e38bf17fcd13c8ea24254ead547380a892477edc23147e5d2805524cd62f96b5f17d6b5ad2 +DIST nova-2012.2.4.tar.gz 6286004 SHA256 883a44282514b484a1187c07875834b9c4648555bf20002aceb1d6731ebd0252 SHA512 c05705c7802035232921e7ca9cdcea05571f4771dae573f9364b740553e470d8e4b4e832bf04120c089bad48a75b8493921eefeb28383f70620495a935ad6ec3 WHIRLPOOL 9e8c56b1a66f15f5f6218413e1cd518a0e73f371baea774023a11ad38abccae3e172ec0894fd77f59848685d1993451499916b94c62289d16f57470005e7c123 +DIST nova-2013.1.1.tar.gz 5739118 SHA256 a6bde22f911af202d65a94ee167db567220855e397afac3aeff797f2b225c51c SHA512 b1e65493ed7ea4843dbde1d6afd829fccec0e30c91a996d18c7846aa53fcb663264d4aa4a207f9cce5c7bdb1b342e40928b4f9cbae0467a95d5b515c61655e9e WHIRLPOOL cf032d26a4111336e251755d79f088601032205cd2e63ebd0667fc7b1826f7e6ff664346806434ce01a0a5b4cd44d00d41f98bb45aede5704911fa65f870bac5 +EBUILD nova-2012.2.4.ebuild 2180 SHA256 19ed13f04a9db51dff34e66a84554c210edc406037820df580573e2c7615f387 SHA512 45db4a3c0bc964e14394a6b5a29e343f10101cb69669455cc1fcc547ee4388bd3edc84565fc6476b368e6a37641567e6577985d414ea7e02b25775f1df6e45d1 WHIRLPOOL a9f1dd352aec0ff7210ca9dc9b1908c573b19c9dba48d29b3b9351919873588e079969db30660fc8e93e3dbe28c79ff0f53464233660691aca763922a4a013b7 +EBUILD nova-2013.1.1.ebuild 2571 SHA256 65d2d531335928de13df64aff02fef3a03bf1f569ea455fd99f26ac567da7168 SHA512 4d0473117a5ff93af782c50a0d589cb83cd82856cb28d54f188ad07b8f14b37e0e9e4d784571ca917355bb83fe8c1f7311691327b9a1fefbbe482bcce176fcca WHIRLPOOL 7b2958e4952ffc49d2ed0f5e49c70a1911f79b64da8362193d8c744ca0731466fa4e004282ca8a413e33e264feaf16ad12f864520af11eafdf6f3c8fc5a5405b EBUILD nova-9999.ebuild 2543 SHA256 fba439b8bc02341f3ca6bb827f89cd001b4b60fd913d097dcacc2c2af7e434e9 SHA512 4d50e966b8e092c12634a15c734b38bd83a5552fdb30eeb55d4b8875bac2b3b0c0a03fcc4f122660fe47e49d29827b486e499a0f9fd55b663951980c6be4e150 WHIRLPOOL 5a6239b221ee07ca51f57938f627e290d232c088e13842fb87fab5c596ff88ee3f79a055185c1806a4583df80ffa75c61dc9d98db474ca9dc67e448de83a40c3 -MISC ChangeLog 1910 SHA256 649a1d7f470e525a4e70cd24131a42f778f69482ec92c46088294b29c08baf14 SHA512 1158ea9c2443725bba534bd44fbda6e0dc66cd50676359d93336f33cca99972d1af40c09c834ce3ae8ac0c4759512da37b016101c4c7fe8275273725acc639c7 WHIRLPOOL 82f6a3014f3f867473fb66150c2da896786c930be0277d3a14bc2e6c49e9c400e4928c7603b29a3feb6ac09046cf051dc3b8125518c4e01c0dab550f9fb699f7 +MISC ChangeLog 2349 SHA256 1800281815558e4dc8cb3a447f4084146f4b8418e564ac82c36f8b53010665be SHA512 a79cd218c8ccd3af4c0daa9a3e745a16d0d6a645515467489d6b1bdaefb562233c31ff1fe02402b409644f9afd7e34292a6ea3fd9e4cb4b552dc774795207ebe WHIRLPOOL 9338df3240b13ac487be9c4922460ee758057861351ebb07695181064bde3a9bec2661a501b389bae195dff9eba9d060488f64038fb31951b0f9e3488c057d66 MISC metadata.xml 407 SHA256 87ac581ad3af018ee16b2c5a8dbc98553ad93fc48bf5cfd62a6f929353049e77 SHA512 4ae00a6fc5411c1795249864317143787b31cb068fb1508f8a1455fd6194254961cca80256e0b437dc131560126cdf5a59d98a5a5064ac49c6e43c1651718a4a WHIRLPOOL 52b178c072593baea26fa3d7e9c06aac003d1a828ffa98de712306f60eeddba92271bc6061d7224a76ac35fa3c1da33213983e998160acf92a6d7027b284bcc0 -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.19 (GNU/Linux) -iQIcBAEBCAAGBQJRZmenAAoJECRx6z5ArFrDI38P/3tPLawZgIOldXtxz9sWsYBm -+3/8ZsMzqz1DZ7HCV7JkVpltG4yBmvaHYi/HYt6yk+Qch98UMNyzk/JOjaZZNv+P -pjJfCHizEKqAsthUGVCFncEJAc+OtEwC8sIhM/F7Yi3HSWLXVZhGjDChcolkrQe1 -+QVrzryb6afCVV/QwyQC+l0DdKF4kNUcMdJ7Dy+1h325+eAB2+Ixa7hbpey43Jzj -8ISmLM7gGyjXn7Ikwj44/4O64v4m9AmD10OSM/3oCqUtZ4KR+gIsPv2OQ24t+35g -WDz/QLov26PTY8mSeWFN5xGC9ydw0p7ISbm2wP1r/kfuqNCuu7UiAxItglQe0vGX -fVAEl1OBO7m/kllTRxsCtW43Mtg1U8CJcdcnugHuWzexcQmcd+2AyEFAVENtTgel -e57aY7yrcln/oWkKYLYfqFQge7wOKSP6e+EQk3aFEP9tix+6aNF0UVKQ5us3WeIu -cGDFZ8EbrizYafJmSnGLxbUJMNmKbf0xTWttYLnMNwL11dTkXAvBynsf0E4EeECl -7kiTSk4OeK6V3c5qkeSuNCSOTdNAQ5k8fS8xokKgWqqGQmNxN6kRfwL1p2MNmmMQ -k1JNmKxO3Z8ScuNq+EBPDtLag4y4/qNCKyWAabmUIfh9EPP/jnYyGOnT4s0phKn/ -2d+sJ5sCtqgmYAkJYRie -=66BA +iQIcBAEBCAAGBQJRjFv2AAoJECRx6z5ArFrDXHMQAIFLl32xGg22yp9NHOBGyF0S +UMDee2uG0zZc0P01nKoeV77MnjyV4cTqWTrxpPcQi+xkAfyw6Cr6O9walpo9NOQ0 +JzSNstguzhXjfzb6DYSVEZt6BiA8X3nBhKUW0YM/6/GSgzJvLT0yDbQx95caXzaH +DpfO9eb/M79idHMbePPdtJTdwH5k9DVscKAvMDOOTHgauSp3hvzrPDCyPViSdSA4 +pwH6UkYpkQsVG6Y/oIj5YVjijsI3tX5VOmWvF+iuZwx+GS8ofNLBgg1bQiYsbBt9 +2jLmcQtt8iP9E+qTCuGTgXxAUOX966LIZ8nne/Ip5Ebpv+N+7TgU0EPoNtz+bulO +GVk4hzGy0ZTxdIZ17sPbeDc9jxVVVKCzuz8A5R3+p1fe1RglwvrnumPUo288W8cD ++EpNTNrL287tAZJR+zLamwFx5ivCY6Zk2gZHXDD/vsKiFqumgBIvfWBaKfkJETxt +swTP3fskPiZNw1wL0YeVCetCAStnpufYgTQzTAHgGn7B7xR0OcSqoU1ZApblbSHd ++t4iiGCtLcjdQvWK8I3klaTdsOoS18snYFnfSX3BHK+CWbES1aOphNXgSjRJ6TqQ +IblnUT1CbO6zd5cIcj4dOVNPLV64nPOFpimoKq4xF3T06eoNNp9dwo64JBhLySwO +4/DwWcIsKgfeDM4Hj1fw +=xkhS -----END PGP SIGNATURE----- diff --git a/sys-cluster/nova/files/nova-folsom-3-CVE-2013-0335.patch b/sys-cluster/nova/files/nova-folsom-3-CVE-2013-0335.patch deleted file mode 100644 index 813fd3e2ba03..000000000000 --- a/sys-cluster/nova/files/nova-folsom-3-CVE-2013-0335.patch +++ /dev/null @@ -1,410 +0,0 @@ -From 05a3374992bc8ba53ddc9c491b51c4b59eed0a72 Mon Sep 17 00:00:00 2001 -From: John Herndon <john.herndon@hp.com> -Date: Fri, 22 Feb 2013 20:43:58 +0000 -Subject: [PATCH] VNC Token Validation - -Force console auth service to flush all tokens -associated with an instance when it is deleted. -This will fix a bug where the console for the -wrong instance can be connected to via the console -if the correct circumstances occur. This change also -makes a call to veriry vnc console tokens when a -user attempts to connect to a console. This ensures -the user is connecting to the correct console. - -bug 1125378 -Change-Id: I0d83ec6c4dbfef1af912a200ee15f8052f72da96 ---- - nova/common/memorycache.py | 5 +++ - nova/compute/api.py | 3 +- - nova/compute/manager.py | 12 ++++++ - nova/compute/rpcapi.py | 7 ++++ - nova/consoleauth/manager.py | 41 +++++++++++++++++- - nova/consoleauth/rpcapi.py | 10 ++++- - nova/tests/compute/test_compute.py | 52 ++++++++++++++++++++++- - nova/tests/compute/test_rpcapi.py | 5 +++ - nova/tests/consoleauth/test_consoleauth.py | 67 +++++++++++++++++++++++++++++- - nova/tests/consoleauth/test_rpcapi.py | 6 ++- - 10 files changed, 200 insertions(+), 8 deletions(-) - -diff --git a/nova/common/memorycache.py b/nova/common/memorycache.py -index 502f833..3a1935e 100644 ---- a/nova/common/memorycache.py -+++ b/nova/common/memorycache.py -@@ -62,3 +62,8 @@ class Client(object): - new_value = int(value) + delta - self.cache[key] = (self.cache[key][0], str(new_value)) - return new_value -+ -+ def delete(self, key, time=0): -+ """Deletes the value associated with a key.""" -+ if key in self.cache: -+ del self.cache[key] -diff --git a/nova/compute/api.py b/nova/compute/api.py -index df7b215..3860226 100644 ---- a/nova/compute/api.py -+++ b/nova/compute/api.py -@@ -1853,7 +1853,8 @@ class API(base.Base): - - self.consoleauth_rpcapi.authorize_console(context, - connect_info['token'], console_type, connect_info['host'], -- connect_info['port'], connect_info['internal_access_path']) -+ connect_info['port'], connect_info['internal_access_path'], -+ instance["uuid"]) - - return {'url': connect_info['access_url']} - -diff --git a/nova/compute/manager.py b/nova/compute/manager.py -index 90de5a4..5b0d1ea 100644 ---- a/nova/compute/manager.py -+++ b/nova/compute/manager.py -@@ -52,6 +52,7 @@ from nova.compute import rpcapi as compute_rpcapi - from nova.compute import task_states - from nova.compute import utils as compute_utils - from nova.compute import vm_states -+from nova import consoleauth - import nova.context - from nova import exception - from nova import flags -@@ -235,6 +236,7 @@ class ComputeManager(manager.SchedulerDependentManager): - self.compute_api = compute.API() - self.compute_rpcapi = compute_rpcapi.ComputeAPI() - self.scheduler_rpcapi = scheduler_rpcapi.SchedulerAPI() -+ self.consoleauth_rpcapi = consoleauth.rpcapi.ConsoleAuthAPI() - - super(ComputeManager, self).__init__(service_name="compute", - *args, **kwargs) -@@ -926,6 +928,10 @@ class ComputeManager(manager.SchedulerDependentManager): - self._notify_about_instance_usage(context, instance, "delete.end", - system_metadata=system_meta) - -+ if FLAGS.vnc_enabled: -+ self.consoleauth_rpcapi.delete_tokens_for_instance(context, -+ instance["uuid"]) -+ - @exception.wrap_exception(notifier=notifier, publisher_id=publisher_id()) - @wrap_instance_fault - def terminate_instance(self, context, instance): -@@ -1989,6 +1995,12 @@ class ComputeManager(manager.SchedulerDependentManager): - return connection_info - - @exception.wrap_exception(notifier=notifier, publisher_id=publisher_id()) -+ @wrap_instance_fault -+ def validate_console_port(self, ctxt, instance, port, console_type): -+ console_info = self.driver.get_vnc_console(instance) -+ return console_info['port'] == port -+ -+ @exception.wrap_exception(notifier=notifier, publisher_id=publisher_id()) - @reverts_task_state - @wrap_instance_fault - def reserve_block_device_name(self, context, instance, device): -diff --git a/nova/compute/rpcapi.py b/nova/compute/rpcapi.py -index 2e3873c..afec290 100644 ---- a/nova/compute/rpcapi.py -+++ b/nova/compute/rpcapi.py -@@ -259,6 +259,13 @@ class ComputeAPI(nova.openstack.common.rpc.proxy.RpcProxy): - instance=instance_p, console_type=console_type), - topic=_compute_topic(self.topic, ctxt, None, instance)) - -+ def validate_console_port(self, ctxt, instance, port, console_type): -+ instance_p = jsonutils.to_primitive(instance) -+ return self.call(ctxt, self.make_msg('validate_console_port', -+ instance=instance_p, port=port, console_type=console_type), -+ topic=_compute_topic(self.topic, ctxt, -+ None, instance)) -+ - def host_maintenance_mode(self, ctxt, host_param, mode, host): - '''Set host maintenance mode - -diff --git a/nova/consoleauth/manager.py b/nova/consoleauth/manager.py -index 61efdd0..e715f98 100644 ---- a/nova/consoleauth/manager.py -+++ b/nova/consoleauth/manager.py -@@ -20,6 +20,8 @@ - - import time - -+from nova.compute import rpcapi as compute_rpcapi -+from nova.db import api as db - from nova import flags - from nova import manager - from nova.openstack.common import cfg -@@ -56,10 +58,21 @@ class ConsoleAuthManager(manager.Manager): - from nova.common import memorycache as memcache - self.mc = memcache.Client(FLAGS.memcached_servers, - debug=0) -+ self.compute_rpcapi = compute_rpcapi.ComputeAPI() -+ -+ def _get_tokens_for_instance(self, instance_uuid): -+ tokens_str = self.mc.get(instance_uuid.encode('UTF-8')) -+ if not tokens_str: -+ tokens = [] -+ else: -+ tokens = jsonutils.loads(tokens_str) -+ return tokens - - def authorize_console(self, context, token, console_type, host, port, -- internal_access_path): -+ internal_access_path, instance_uuid=None): -+ - token_dict = {'token': token, -+ 'instance_uuid': instance_uuid, - 'console_type': console_type, - 'host': host, - 'port': port, -@@ -67,11 +80,35 @@ class ConsoleAuthManager(manager.Manager): - 'last_activity_at': time.time()} - data = jsonutils.dumps(token_dict) - self.mc.set(token.encode('UTF-8'), data, FLAGS.console_token_ttl) -+ if instance_uuid is not None: -+ tokens = self._get_tokens_for_instance(instance_uuid) -+ tokens.append(token) -+ self.mc.set(instance_uuid.encode('UTF-8'), -+ jsonutils.dumps(tokens)) -+ - LOG.audit(_("Received Token: %(token)s, %(token_dict)s)"), locals()) - -+ def _validate_token(self, context, token): -+ instance_uuid = token['instance_uuid'] -+ if instance_uuid is None: -+ return False -+ instance = db.instance_get_by_uuid(context, instance_uuid) -+ return self.compute_rpcapi.validate_console_port(context, -+ instance, -+ token['port'], -+ token['console_type']) -+ - def check_token(self, context, token): - token_str = self.mc.get(token.encode('UTF-8')) - token_valid = (token_str is not None) - LOG.audit(_("Checking Token: %(token)s, %(token_valid)s)"), locals()) - if token_valid: -- return jsonutils.loads(token_str) -+ token = jsonutils.loads(token_str) -+ if self._validate_token(context, token): -+ return token -+ -+ def delete_tokens_for_instance(self, context, instance_uuid): -+ tokens = self._get_tokens_for_instance(instance_uuid) -+ for token in tokens: -+ self.mc.delete(token) -+ self.mc.delete(instance_uuid.encode('UTF-8')) -diff --git a/nova/consoleauth/rpcapi.py b/nova/consoleauth/rpcapi.py -index 2fafe3f..b3b34c1 100644 ---- a/nova/consoleauth/rpcapi.py -+++ b/nova/consoleauth/rpcapi.py -@@ -49,14 +49,20 @@ class ConsoleAuthAPI(nova.openstack.common.rpc.proxy.RpcProxy): - default_version=self.BASE_RPC_API_VERSION) - - def authorize_console(self, ctxt, token, console_type, host, port, -- internal_access_path): -+ internal_access_path, instance_uuid=None): - # The remote side doesn't return anything, but we want to block - # until it completes. - return self.call(ctxt, - self.make_msg('authorize_console', - token=token, console_type=console_type, - host=host, port=port, -- internal_access_path=internal_access_path)) -+ internal_access_path=internal_access_path, -+ instance_uuid=instance_uuid)) - - def check_token(self, ctxt, token): - return self.call(ctxt, self.make_msg('check_token', token=token)) -+ -+ def delete_tokens_for_instance(self, ctxt, instance_uuid): -+ return self.call(ctxt, -+ self.make_msg('delete_tokens_for_instance', -+ instance_uuid=instance_uuid)) -diff --git a/nova/tests/compute/test_compute.py b/nova/tests/compute/test_compute.py -index 10b89fd..b745798 100644 ---- a/nova/tests/compute/test_compute.py -+++ b/nova/tests/compute/test_compute.py -@@ -1372,6 +1372,24 @@ class ComputeTestCase(BaseTestCase): - self.compute._delete_instance(self.context, - instance=jsonutils.to_primitive(instance)) - -+ def test_delete_instance_deletes_console_auth_tokens(self): -+ instance = self._create_fake_instance() -+ self.flags(vnc_enabled=True) -+ -+ self.tokens_deleted = False -+ -+ def fake_delete_tokens(*args, **kwargs): -+ self.tokens_deleted = True -+ -+ cauth_rpcapi = self.compute.consoleauth_rpcapi -+ self.stubs.Set(cauth_rpcapi, 'delete_tokens_for_instance', -+ fake_delete_tokens) -+ -+ self.compute._delete_instance(self.context, -+ instance=jsonutils.to_primitive(instance)) -+ -+ self.assertTrue(self.tokens_deleted) -+ - def test_instance_termination_exception_sets_error(self): - """Test that we handle InstanceTerminationFailure - which is propagated up from the underlying driver. -@@ -4505,7 +4523,9 @@ class ComputeAPITestCase(BaseTestCase): - 'console_type': fake_console_type, - 'host': 'fake_console_host', - 'port': 'fake_console_port', -- 'internal_access_path': 'fake_access_path'} -+ 'internal_access_path': 'fake_access_path', -+ 'instance_uuid': fake_instance["uuid"]} -+ - fake_connect_info2 = copy.deepcopy(fake_connect_info) - fake_connect_info2['access_url'] = 'fake_console_url' - -@@ -4539,6 +4559,36 @@ class ComputeAPITestCase(BaseTestCase): - - db.instance_destroy(self.context, instance['uuid']) - -+ def test_validate_console_port(self): -+ self.flags(vnc_enabled=True) -+ instance = jsonutils.to_primitive(self._create_fake_instance()) -+ -+ def fake_driver_get_console(*args, **kwargs): -+ return {'host': "fake_host", 'port': "5900", -+ 'internal_access_path': None} -+ self.stubs.Set(self.compute.driver, "get_vnc_console", -+ fake_driver_get_console) -+ -+ self.assertTrue(self.compute.validate_console_port(self.context, -+ instance, -+ "5900", -+ "novnc")) -+ -+ def test_validate_console_port_wrong_port(self): -+ self.flags(vnc_enabled=True) -+ instance = jsonutils.to_primitive(self._create_fake_instance()) -+ -+ def fake_driver_get_console(*args, **kwargs): -+ return {'host': "fake_host", 'port': "5900", -+ 'internal_access_path': None} -+ self.stubs.Set(self.compute.driver, "get_vnc_console", -+ fake_driver_get_console) -+ -+ self.assertFalse(self.compute.validate_console_port(self.context, -+ instance, -+ "wrongport", -+ "novnc")) -+ - def test_console_output(self): - fake_instance = {'uuid': 'fake_uuid', - 'host': 'fake_compute_host'} -diff --git a/nova/tests/compute/test_rpcapi.py b/nova/tests/compute/test_rpcapi.py -index 559a56a..c42047b 100644 ---- a/nova/tests/compute/test_rpcapi.py -+++ b/nova/tests/compute/test_rpcapi.py -@@ -168,6 +168,11 @@ class ComputeRpcAPITestCase(test.TestCase): - self._test_compute_api('get_vnc_console', 'call', - instance=self.fake_instance, console_type='type') - -+ def test_validate_console_port(self): -+ self._test_compute_api('validate_console_port', 'call', -+ instance=self.fake_instance, port="5900", -+ console_type="novnc") -+ - def test_host_maintenance_mode(self): - self._test_compute_api('host_maintenance_mode', 'call', - host_param='param', mode='mode', host='host') -diff --git a/nova/tests/consoleauth/test_consoleauth.py b/nova/tests/consoleauth/test_consoleauth.py -index da50eb8..4bea85a 100644 ---- a/nova/tests/consoleauth/test_consoleauth.py -+++ b/nova/tests/consoleauth/test_consoleauth.py -@@ -45,8 +45,73 @@ class ConsoleauthTestCase(test.TestCase): - """Test that tokens expire correctly.""" - token = 'mytok' - self.flags(console_token_ttl=1) -+ -+ def fake_validate_token(*args, **kwargs): -+ return True -+ self.stubs.Set(self.manager, -+ "_validate_token", -+ fake_validate_token) -+ - self.manager.authorize_console(self.context, token, 'novnc', -- '127.0.0.1', 'host', '') -+ '127.0.0.1', '8080', 'host', "1234") - self.assertTrue(self.manager.check_token(self.context, token)) - time.sleep(1.1) - self.assertFalse(self.manager.check_token(self.context, token)) -+ -+ def test_multiple_tokens_for_instance(self): -+ tokens = ["token" + str(i) for i in xrange(10)] -+ instance = "12345" -+ -+ def fake_validate_token(*args, **kwargs): -+ return True -+ -+ self.stubs.Set(self.manager, "_validate_token", -+ fake_validate_token) -+ for token in tokens: -+ self.manager.authorize_console(self.context, token, 'novnc', -+ '127.0.0.1', '8080', 'host', -+ instance) -+ -+ for token in tokens: -+ self.assertTrue(self.manager.check_token(self.context, token)) -+ -+ def test_delete_tokens_for_instance(self): -+ instance = "12345" -+ tokens = ["token" + str(i) for i in xrange(10)] -+ -+ def fake_validate_token(*args, **kwargs): -+ return True -+ self.stubs.Set(self.manager, "_validate_token", -+ fake_validate_token) -+ -+ for token in tokens: -+ self.manager.authorize_console(self.context, token, 'novnc', -+ '127.0.0.1', '8080', 'host', -+ instance) -+ self.manager.delete_tokens_for_instance(self.context, instance) -+ stored_tokens = self.manager._get_tokens_for_instance(instance) -+ -+ self.assertEqual(len(stored_tokens), 0) -+ -+ for token in tokens: -+ self.assertFalse(self.manager.check_token(self.context, token)) -+ -+ def test_wrong_token_has_port(self): -+ token = 'mytok' -+ -+ def fake_validate_token(*args, **kwargs): -+ return False -+ -+ self.stubs.Set(self.manager, "_validate_token", -+ fake_validate_token) -+ -+ self.manager.authorize_console(self.context, token, 'novnc', -+ '127.0.0.1', '8080', 'host', -+ instance_uuid='instance') -+ self.assertFalse(self.manager.check_token(self.context, token)) -+ -+ def test_console_no_instance_uuid(self): -+ self.manager.authorize_console(self.context, "token", 'novnc', -+ '127.0.0.1', '8080', 'host', -+ instance_uuid=None) -+ self.assertFalse(self.manager.check_token(self.context, "token")) -diff --git a/nova/tests/consoleauth/test_rpcapi.py b/nova/tests/consoleauth/test_rpcapi.py -index 10484c7..c1e7a46 100644 ---- a/nova/tests/consoleauth/test_rpcapi.py -+++ b/nova/tests/consoleauth/test_rpcapi.py -@@ -68,7 +68,11 @@ class ConsoleAuthRpcAPITestCase(test.TestCase): - def test_authorize_console(self): - self._test_consoleauth_api('authorize_console', token='token', - console_type='ctype', host='h', port='p', -- internal_access_path='iap') -+ internal_access_path='iap', instance_uuid="1234") - - def test_check_token(self): - self._test_consoleauth_api('check_token', token='t') -+ -+ def test_delete_tokens_for_instnace(self): -+ self._test_consoleauth_api('delete_tokens_for_instance', -+ instance_uuid="instance") --- -1.7.12.4 - diff --git a/sys-cluster/nova/files/nova-folsom-3-CVE-2013-1838.patch b/sys-cluster/nova/files/nova-folsom-3-CVE-2013-1838.patch deleted file mode 100644 index 18ae387b2525..000000000000 --- a/sys-cluster/nova/files/nova-folsom-3-CVE-2013-1838.patch +++ /dev/null @@ -1,507 +0,0 @@ -From 9561484166f245d0e4602a36351d6cac72dd9426 Mon Sep 17 00:00:00 2001 -From: Michael Still <mikal@stillhq.com> -Date: Wed, 13 Mar 2013 04:44:14 +1100 -Subject: [PATCH] Add quotas for fixed ips. - -DocImpact: there is now a default quota of 10 fixed ips per tenant. -This will need to be adjusted by deployers if that number does not -meet their needs. - -Resolves bug 1125468 for folsom. - -Change-Id: I970d540cfa6a61b7e903703f845a6453ff55f225 ---- - nova/db/api.py | 6 ++ - nova/db/sqlalchemy/api.py | 21 +++++ - nova/exception.py | 4 + - nova/network/manager.py | 89 ++++++++++++++-------- - nova/quota.py | 10 +++ - .../compute/contrib/test_quota_classes.py | 14 ++-- - .../api/openstack/compute/contrib/test_quotas.py | 16 ++-- - nova/tests/network/test_manager.py | 15 ++++ - nova/tests/test_quota.py | 24 ++++++ - 9 files changed, 157 insertions(+), 42 deletions(-) - -diff --git a/nova/db/api.py b/nova/db/api.py -index bb69558..9f2ff73 100644 ---- a/nova/db/api.py -+++ b/nova/db/api.py -@@ -507,6 +507,12 @@ def fixed_ip_update(context, address, values): - """Create a fixed ip from the values dictionary.""" - return IMPL.fixed_ip_update(context, address, values) - -+ -+def fixed_ip_count_by_project(context, project_id, session=None): -+ """Count fixed ips used by project.""" -+ return IMPL.fixed_ip_count_by_project(context, project_id, -+ session=session) -+ - #################### - - -diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py -index 4bdab49..013ff69 100644 ---- a/nova/db/sqlalchemy/api.py -+++ b/nova/db/sqlalchemy/api.py -@@ -1273,6 +1273,27 @@ def fixed_ip_update(context, address, values): - fixed_ip_ref.save(session=session) - - -+@require_context -+def fixed_ip_count_by_project(context, project_id, session=None): -+ authorize_project_context(context, project_id) -+ -+ # NOTE(mikal): Yes I know this is horrible, but I couldn't -+ # get a query using a join working, mainly because of a failure -+ # to be able to express the where clause sensibly. Patches -+ # welcome. -+ session = get_session() -+ with session.begin(): -+ instance_uuid_query = model_query(context, models.Instance.uuid, -+ read_deleted="no", session=session).\ -+ filter(models.Instance.project_id == \ -+ project_id) -+ uuid_filter = models.FixedIp.instance_uuid.in_(instance_uuid_query) -+ return model_query(context, models.FixedIp, read_deleted="no", -+ session=session).\ -+ filter(uuid_filter).\ -+ count() -+ -+ - ################### - - -diff --git a/nova/exception.py b/nova/exception.py -index 64d31a1..fe80ca2 100644 ---- a/nova/exception.py -+++ b/nova/exception.py -@@ -998,6 +998,10 @@ class FloatingIpLimitExceeded(QuotaError): - message = _("Maximum number of floating ips exceeded") - - -+class FixedIpLimitExceeded(QuotaError): -+ message = _("Maximum number of fixed ips exceeded") -+ -+ - class MetadataLimitExceeded(QuotaError): - message = _("Maximum number of metadata items exceeds %(allowed)d") - -diff --git a/nova/network/manager.py b/nova/network/manager.py -index 00a6e58..df4493b 100644 ---- a/nova/network/manager.py -+++ b/nova/network/manager.py -@@ -1294,37 +1294,53 @@ class NetworkManager(manager.SchedulerDependentManager): - address = None - instance_ref = self.db.instance_get(context, instance_id) - -- if network['cidr']: -- address = kwargs.get('address', None) -- if address: -- address = self.db.fixed_ip_associate(context, -- address, -- instance_ref['uuid'], -- network['id']) -- else: -- address = self.db.fixed_ip_associate_pool(context.elevated(), -- network['id'], -- instance_ref['uuid']) -- self._do_trigger_security_group_members_refresh_for_instance( -- instance_id) -- get_vif = self.db.virtual_interface_get_by_instance_and_network -- vif = get_vif(context, instance_ref['uuid'], network['id']) -- values = {'allocated': True, -- 'virtual_interface_id': vif['id']} -- self.db.fixed_ip_update(context, address, values) -- -- name = instance_ref['display_name'] -- -- if self._validate_instance_zone_for_dns_domain(context, instance_ref): -- uuid = instance_ref['uuid'] -- self.instance_dns_manager.create_entry(name, address, -- "A", -- self.instance_dns_domain) -- self.instance_dns_manager.create_entry(uuid, address, -- "A", -- self.instance_dns_domain) -- self._setup_network_on_host(context, network) -- return address -+ # Check the quota; can't put this in the API because we get -+ # called into from other places -+ try: -+ reservations = QUOTAS.reserve(context, fixed_ips=1) -+ except exception.OverQuota: -+ pid = context.project_id -+ LOG.warn(_("Quota exceeded for %(pid)s, tried to allocate " -+ "fixed IP") % locals()) -+ raise exception.FixedIpLimitExceeded() -+ -+ try: -+ if network['cidr']: -+ address = kwargs.get('address', None) -+ if address: -+ address = self.db.fixed_ip_associate(context, -+ address, -+ instance_ref['uuid'], -+ network['id']) -+ else: -+ address = self.db.fixed_ip_associate_pool( -+ context.elevated(), network['id'], -+ instance_ref['uuid']) -+ self._do_trigger_security_group_members_refresh_for_instance( -+ instance_id) -+ get_vif = self.db.virtual_interface_get_by_instance_and_network -+ vif = get_vif(context, instance_ref['uuid'], network['id']) -+ values = {'allocated': True, -+ 'virtual_interface_id': vif['id']} -+ self.db.fixed_ip_update(context, address, values) -+ -+ name = instance_ref['display_name'] -+ -+ if self._validate_instance_zone_for_dns_domain(context, -+ instance_ref): -+ uuid = instance_ref['uuid'] -+ self.instance_dns_manager.create_entry( -+ name, address, "A", self.instance_dns_domain) -+ self.instance_dns_manager.create_entry( -+ uuid, address, "A", self.instance_dns_domain) -+ self._setup_network_on_host(context, network) -+ -+ QUOTAS.commit(context, reservations) -+ return address -+ -+ except Exception: -+ with excutils.save_and_reraise_exception(): -+ QUOTAS.rollback(context, reservations) - - def deallocate_fixed_ip(self, context, address, host=None, teardown=True): - """Returns a fixed ip to the pool.""" -@@ -1334,6 +1350,13 @@ class NetworkManager(manager.SchedulerDependentManager): - context.elevated(read_deleted='yes'), - fixed_ip_ref['instance_uuid']) - -+ try: -+ reservations = QUOTAS.reserve(context, fixed_ips=-1) -+ except Exception: -+ reservations = None -+ LOG.exception(_("Failed to update usages deallocating " -+ "fixed IP")) -+ - self._do_trigger_security_group_members_refresh_for_instance( - instance['uuid']) - -@@ -1373,6 +1396,10 @@ class NetworkManager(manager.SchedulerDependentManager): - # callback will get called by nova-dhcpbridge. - self.driver.release_dhcp(dev, address, vif['address']) - -+ # Commit the reservations -+ if reservations: -+ QUOTAS.commit(context, reservations) -+ - def lease_fixed_ip(self, context, address): - """Called by dhcp-bridge when ip is leased.""" - LOG.debug(_('Leased IP |%(address)s|'), locals(), context=context) -diff --git a/nova/quota.py b/nova/quota.py -index d3ba0aa..31e2794 100644 ---- a/nova/quota.py -+++ b/nova/quota.py -@@ -50,6 +50,10 @@ quota_opts = [ - cfg.IntOpt('quota_floating_ips', - default=10, - help='number of floating ips allowed per project'), -+ cfg.IntOpt('quota_fixed_ips', -+ default=10, -+ help=('number of fixed ips allowed per project (this should be ' -+ 'at least the number of instances allowed)')), - cfg.IntOpt('quota_metadata_items', - default=128, - help='number of metadata items allowed per instance'), -@@ -778,6 +782,11 @@ def _sync_floating_ips(context, project_id, session): - context, project_id, session=session)) - - -+def _sync_fixed_ips(context, project_id, session): -+ return dict(fixed_ips=db.fixed_ip_count_by_project( -+ context, project_id, session=session)) -+ -+ - def _sync_security_groups(context, project_id, session): - return dict(security_groups=db.security_group_count_by_project( - context, project_id, session=session)) -@@ -794,6 +803,7 @@ resources = [ - ReservableResource('gigabytes', _sync_volumes, 'quota_gigabytes'), - ReservableResource('floating_ips', _sync_floating_ips, - 'quota_floating_ips'), -+ ReservableResource('fixed_ips', _sync_fixed_ips, 'quota_fixed_ips'), - AbsoluteResource('metadata_items', 'quota_metadata_items'), - AbsoluteResource('injected_files', 'quota_injected_files'), - AbsoluteResource('injected_file_content_bytes', -diff --git a/nova/tests/api/openstack/compute/contrib/test_quota_classes.py b/nova/tests/api/openstack/compute/contrib/test_quota_classes.py -index b732f88..5bee208 100644 ---- a/nova/tests/api/openstack/compute/contrib/test_quota_classes.py -+++ b/nova/tests/api/openstack/compute/contrib/test_quota_classes.py -@@ -25,10 +25,11 @@ from nova.tests.api.openstack import fakes - def quota_set(class_name): - return {'quota_class_set': {'id': class_name, 'metadata_items': 128, - 'volumes': 10, 'gigabytes': 1000, 'ram': 51200, -- 'floating_ips': 10, 'instances': 10, 'injected_files': 5, -- 'cores': 20, 'injected_file_content_bytes': 10240, -- 'security_groups': 10, 'security_group_rules': 20, -- 'key_pairs': 100, 'injected_file_path_bytes': 255}} -+ 'floating_ips': 10, 'fixed_ips': 10, 'instances': 10, -+ 'injected_files': 5, 'cores': 20, -+ 'injected_file_content_bytes': 10240, 'security_groups': 10, -+ 'security_group_rules': 20, 'key_pairs': 100, -+ 'injected_file_path_bytes': 255}} - - - class QuotaClassSetsTest(test.TestCase): -@@ -44,6 +45,7 @@ class QuotaClassSetsTest(test.TestCase): - 'ram': 51200, - 'volumes': 10, - 'floating_ips': 10, -+ 'fixed_ips': 10, - 'metadata_items': 128, - 'gigabytes': 1000, - 'injected_files': 5, -@@ -91,7 +93,8 @@ class QuotaClassSetsTest(test.TestCase): - body = {'quota_class_set': {'instances': 50, 'cores': 50, - 'ram': 51200, 'volumes': 10, - 'gigabytes': 1000, 'floating_ips': 10, -- 'metadata_items': 128, 'injected_files': 5, -+ 'fixed_ips': 10, 'metadata_items': 128, -+ 'injected_files': 5, - 'injected_file_content_bytes': 10240, - 'injected_file_path_bytes': 255, - 'security_groups': 10, -@@ -139,6 +142,7 @@ class QuotaTemplateXMLSerializerTest(test.TestCase): - gigabytes=40, - ram=50, - floating_ips=60, -+ fixed_ips=10, - instances=70, - injected_files=80, - security_groups=10, -diff --git a/nova/tests/api/openstack/compute/contrib/test_quotas.py b/nova/tests/api/openstack/compute/contrib/test_quotas.py -index f628535..adfe129 100644 ---- a/nova/tests/api/openstack/compute/contrib/test_quotas.py -+++ b/nova/tests/api/openstack/compute/contrib/test_quotas.py -@@ -26,11 +26,12 @@ from nova.tests.api.openstack import fakes - - def quota_set(id): - return {'quota_set': {'id': id, 'metadata_items': 128, 'volumes': 10, -- 'gigabytes': 1000, 'ram': 51200, 'floating_ips': 10, -- 'instances': 10, 'injected_files': 5, 'cores': 20, -- 'injected_file_content_bytes': 10240, -- 'security_groups': 10, 'security_group_rules': 20, -- 'key_pairs': 100, 'injected_file_path_bytes': 255}} -+ 'gigabytes': 1000, 'ram': 51200, 'floating_ips': 10, -+ 'fixed_ips': 10, 'instances': 10, -+ 'injected_files': 5, 'cores': 20, -+ 'injected_file_content_bytes': 10240, -+ 'security_groups': 10, 'security_group_rules': 20, -+ 'key_pairs': 100, 'injected_file_path_bytes': 255}} - - - class QuotaSetsTest(test.TestCase): -@@ -46,6 +47,7 @@ class QuotaSetsTest(test.TestCase): - 'ram': 51200, - 'volumes': 10, - 'floating_ips': 10, -+ 'fixed_ips': 10, - 'metadata_items': 128, - 'gigabytes': 1000, - 'injected_files': 5, -@@ -88,6 +90,7 @@ class QuotaSetsTest(test.TestCase): - 'volumes': 10, - 'gigabytes': 1000, - 'floating_ips': 10, -+ 'fixed_ips': 10, - 'metadata_items': 128, - 'injected_files': 5, - 'injected_file_path_bytes': 255, -@@ -120,7 +123,7 @@ class QuotaSetsTest(test.TestCase): - 'injected_file_path_bytes': 255, - 'security_groups': 10, - 'security_group_rules': 20, -- 'key_pairs': 100}} -+ 'key_pairs': 100, 'fixed_ips': 10}} - - req = fakes.HTTPRequest.blank('/v2/fake4/os-quota-sets/update_me', - use_admin_context=True) -@@ -171,6 +174,7 @@ class QuotaXMLSerializerTest(test.TestCase): - gigabytes=40, - ram=50, - floating_ips=60, -+ fixed_ips=10, - instances=70, - injected_files=80, - security_groups=10, -diff --git a/nova/tests/network/test_manager.py b/nova/tests/network/test_manager.py -index e983ad6..f27a176 100644 ---- a/nova/tests/network/test_manager.py -+++ b/nova/tests/network/test_manager.py -@@ -30,6 +30,7 @@ from nova.openstack.common import importutils - from nova.openstack.common import log as logging - from nova.openstack.common import rpc - import nova.policy -+from nova import quota - from nova import test - from nova.tests import fake_network - from nova import utils -@@ -278,6 +279,7 @@ class FlatNetworkTestCase(test.TestCase): - self.mox.StubOutWithMock(db, - 'virtual_interface_get_by_instance_and_network') - self.mox.StubOutWithMock(db, 'fixed_ip_update') -+ self.mox.StubOutWithMock(quota.QUOTAS, 'reserve') - - db.fixed_ip_update(mox.IgnoreArg(), - mox.IgnoreArg(), -@@ -291,6 +293,10 @@ class FlatNetworkTestCase(test.TestCase): - db.instance_get(mox.IgnoreArg(), - mox.IgnoreArg()).AndReturn({'security_groups': - [{'id': 0}]}) -+ -+ quota.QUOTAS.reserve(mox.IgnoreArg(), -+ fixed_ips=mox.IgnoreArg()).AndReturn(None) -+ - db.fixed_ip_associate_pool(mox.IgnoreArg(), - mox.IgnoreArg(), - mox.IgnoreArg()).AndReturn('192.168.0.101') -@@ -310,6 +316,7 @@ class FlatNetworkTestCase(test.TestCase): - self.mox.StubOutWithMock(db, - 'virtual_interface_get_by_instance_and_network') - self.mox.StubOutWithMock(db, 'fixed_ip_update') -+ self.mox.StubOutWithMock(quota.QUOTAS, 'reserve') - - db.fixed_ip_update(mox.IgnoreArg(), - mox.IgnoreArg(), -@@ -323,6 +330,10 @@ class FlatNetworkTestCase(test.TestCase): - db.instance_get(mox.IgnoreArg(), - mox.IgnoreArg()).AndReturn({'security_groups': - [{'id': 0}]}) -+ -+ quota.QUOTAS.reserve(mox.IgnoreArg(), -+ fixed_ips=mox.IgnoreArg()).AndReturn(None) -+ - db.fixed_ip_associate_pool(mox.IgnoreArg(), - mox.IgnoreArg(), - mox.IgnoreArg()).AndReturn('192.168.0.101') -@@ -376,6 +387,7 @@ class FlatNetworkTestCase(test.TestCase): - self.mox.StubOutWithMock(db, - 'virtual_interface_get_by_instance_and_network') - self.mox.StubOutWithMock(db, 'fixed_ip_update') -+ self.mox.StubOutWithMock(quota.QUOTAS, 'reserve') - - db.fixed_ip_update(mox.IgnoreArg(), - mox.IgnoreArg(), -@@ -390,6 +402,9 @@ class FlatNetworkTestCase(test.TestCase): - mox.IgnoreArg()).AndReturn({'security_groups': - [{'id': 0}]}) - -+ quota.QUOTAS.reserve(mox.IgnoreArg(), -+ fixed_ips=mox.IgnoreArg()).AndReturn(None) -+ - db.fixed_ip_associate_pool(mox.IgnoreArg(), - mox.IgnoreArg(), - mox.IgnoreArg()).AndReturn(fixedip) -diff --git a/nova/tests/test_quota.py b/nova/tests/test_quota.py -index dd86c7c..5baf966 100644 ---- a/nova/tests/test_quota.py -+++ b/nova/tests/test_quota.py -@@ -723,6 +723,7 @@ class DbQuotaDriverTestCase(test.TestCase): - quota_volumes=10, - quota_gigabytes=1000, - quota_floating_ips=10, -+ quota_fixed_ips=10, - quota_metadata_items=128, - quota_injected_files=5, - quota_injected_file_content_bytes=10 * 1024, -@@ -755,6 +756,7 @@ class DbQuotaDriverTestCase(test.TestCase): - volumes=10, - gigabytes=1000, - floating_ips=10, -+ fixed_ips=10, - metadata_items=128, - injected_files=5, - injected_file_content_bytes=10 * 1024, -@@ -791,6 +793,7 @@ class DbQuotaDriverTestCase(test.TestCase): - volumes=10, - gigabytes=500, - floating_ips=10, -+ fixed_ips=10, - metadata_items=64, - injected_files=5, - injected_file_content_bytes=5 * 1024, -@@ -847,6 +850,7 @@ class DbQuotaDriverTestCase(test.TestCase): - self._stub_quota_class_get_all_by_name() - - def test_get_project_quotas(self): -+ self.maxDiff = None - self._stub_get_by_project() - result = self.driver.get_project_quotas( - FakeContext('test_project', 'test_class'), -@@ -888,6 +892,11 @@ class DbQuotaDriverTestCase(test.TestCase): - in_use=2, - reserved=0, - ), -+ fixed_ips=dict( -+ limit=10, -+ in_use=0, -+ reserved=0, -+ ), - metadata_items=dict( - limit=64, - in_use=0, -@@ -926,6 +935,7 @@ class DbQuotaDriverTestCase(test.TestCase): - )) - - def test_get_project_quotas_alt_context_no_class(self): -+ self.maxDiff = None - self._stub_get_by_project() - result = self.driver.get_project_quotas( - FakeContext('other_project', 'other_class'), -@@ -966,6 +976,11 @@ class DbQuotaDriverTestCase(test.TestCase): - in_use=2, - reserved=0, - ), -+ fixed_ips=dict( -+ limit=10, -+ in_use=0, -+ reserved=0, -+ ), - metadata_items=dict( - limit=128, - in_use=0, -@@ -1004,6 +1019,7 @@ class DbQuotaDriverTestCase(test.TestCase): - )) - - def test_get_project_quotas_alt_context_with_class(self): -+ self.maxDiff = None - self._stub_get_by_project() - result = self.driver.get_project_quotas( - FakeContext('other_project', 'other_class'), -@@ -1045,6 +1061,11 @@ class DbQuotaDriverTestCase(test.TestCase): - in_use=2, - reserved=0, - ), -+ fixed_ips=dict( -+ limit=10, -+ in_use=0, -+ reserved=0, -+ ), - metadata_items=dict( - limit=64, - in_use=0, -@@ -1145,6 +1166,9 @@ class DbQuotaDriverTestCase(test.TestCase): - floating_ips=dict( - limit=10, - ), -+ fixed_ips=dict( -+ limit=10, -+ ), - metadata_items=dict( - limit=64, - ), --- -1.8.1.5 - diff --git a/sys-cluster/nova/files/nova-folsom-CVE-2013-1664.patch b/sys-cluster/nova/files/nova-folsom-CVE-2013-1664.patch deleted file mode 100644 index 9da049326d7a..000000000000 --- a/sys-cluster/nova/files/nova-folsom-CVE-2013-1664.patch +++ /dev/null @@ -1,396 +0,0 @@ -From: Dan Prince <dprince@redhat.com> -Date: Sat, 2 Feb 2013 16:34:25 +0000 (-0500) -Subject: Add a safe_minidom_parse_string function. -X-Git-Url: https://review.openstack.org/gitweb?p=openstack%2Fnova.git;a=commitdiff_plain;h=2ae74f8222058e475350458ca0c820adb910582c - -Add a safe_minidom_parse_string function. - -Adds a new utils.safe_minidom_parse_string function and -updates external API facing Nova modules to use it. -This ensures we have safe defaults on our incoming API XML parsing. - -Internally safe_minidom_parse_string uses a ProtectedExpatParser -class to disable DTDs and entities from being parsed when using -minidom. - -Fixes LP Bug #1100282 for Folsom. - -Change-Id: I6a4051b5e66f3ce5a330b2589c42e6e9e5b9268e ---- - -diff --git a/nova/api/openstack/common.py b/nova/api/openstack/common.py -index ccc70cd..7fe3a50 100644 ---- a/nova/api/openstack/common.py -+++ b/nova/api/openstack/common.py -@@ -21,7 +21,6 @@ import re - import urlparse - - import webob --from xml.dom import minidom - - from nova.api.openstack import wsgi - from nova.api.openstack import xmlutil -@@ -32,6 +31,7 @@ from nova import exception - from nova import flags - from nova.openstack.common import log as logging - from nova import quota -+from nova import utils - - - LOG = logging.getLogger(__name__) -@@ -341,7 +341,7 @@ def raise_http_conflict_for_instance_invalid_state(exc, action): - - class MetadataDeserializer(wsgi.MetadataXMLDeserializer): - def deserialize(self, text): -- dom = minidom.parseString(text) -+ dom = utils.safe_minidom_parse_string(text) - metadata_node = self.find_first_child_named(dom, "metadata") - metadata = self.extract_metadata(metadata_node) - return {'body': {'metadata': metadata}} -@@ -349,7 +349,7 @@ class MetadataDeserializer(wsgi.MetadataXMLDeserializer): - - class MetaItemDeserializer(wsgi.MetadataXMLDeserializer): - def deserialize(self, text): -- dom = minidom.parseString(text) -+ dom = utils.safe_minidom_parse_string(text) - metadata_item = self.extract_metadata(dom) - return {'body': {'meta': metadata_item}} - -@@ -367,7 +367,7 @@ class MetadataXMLDeserializer(wsgi.XMLDeserializer): - return metadata - - def _extract_metadata_container(self, datastring): -- dom = minidom.parseString(datastring) -+ dom = utils.safe_minidom_parse_string(datastring) - metadata_node = self.find_first_child_named(dom, "metadata") - metadata = self.extract_metadata(metadata_node) - return {'body': {'metadata': metadata}} -@@ -379,7 +379,7 @@ class MetadataXMLDeserializer(wsgi.XMLDeserializer): - return self._extract_metadata_container(datastring) - - def update(self, datastring): -- dom = minidom.parseString(datastring) -+ dom = utils.safe_minidom_parse_string(datastring) - metadata_item = self.extract_metadata(dom) - return {'body': {'meta': metadata_item}} - -diff --git a/nova/api/openstack/compute/contrib/hosts.py b/nova/api/openstack/compute/contrib/hosts.py -index 95a80f3..fa3c961 100644 ---- a/nova/api/openstack/compute/contrib/hosts.py -+++ b/nova/api/openstack/compute/contrib/hosts.py -@@ -16,7 +16,6 @@ - """The hosts admin extension.""" - - import webob.exc --from xml.dom import minidom - from xml.parsers import expat - - from nova.api.openstack import extensions -@@ -27,6 +26,7 @@ from nova import db - from nova import exception - from nova import flags - from nova.openstack.common import log as logging -+from nova import utils - - - LOG = logging.getLogger(__name__) -@@ -80,7 +80,7 @@ class HostShowTemplate(xmlutil.TemplateBuilder): - class HostDeserializer(wsgi.XMLDeserializer): - def default(self, string): - try: -- node = minidom.parseString(string) -+ node = utils.safe_minidom_parse_string(string) - except expat.ExpatError: - msg = _("cannot understand XML") - raise exception.MalformedRequestBody(reason=msg) -diff --git a/nova/api/openstack/compute/contrib/security_groups.py b/nova/api/openstack/compute/contrib/security_groups.py -index e5b1797..4a6be1e 100644 ---- a/nova/api/openstack/compute/contrib/security_groups.py -+++ b/nova/api/openstack/compute/contrib/security_groups.py -@@ -16,8 +16,6 @@ - - """The security groups extension.""" - --from xml.dom import minidom -- - import webob - from webob import exc - -@@ -30,6 +28,7 @@ from nova import db - from nova import exception - from nova import flags - from nova.openstack.common import log as logging -+from nova import utils - - - LOG = logging.getLogger(__name__) -@@ -110,7 +109,7 @@ class SecurityGroupXMLDeserializer(wsgi.MetadataXMLDeserializer): - """ - def default(self, string): - """Deserialize an xml-formatted security group create request""" -- dom = minidom.parseString(string) -+ dom = utils.safe_minidom_parse_string(string) - security_group = {} - sg_node = self.find_first_child_named(dom, - 'security_group') -@@ -131,7 +130,7 @@ class SecurityGroupRulesXMLDeserializer(wsgi.MetadataXMLDeserializer): - - def default(self, string): - """Deserialize an xml-formatted security group create request""" -- dom = minidom.parseString(string) -+ dom = utils.safe_minidom_parse_string(string) - security_group_rule = self._extract_security_group_rule(dom) - return {'body': {'security_group_rule': security_group_rule}} - -diff --git a/nova/api/openstack/compute/contrib/volumes.py b/nova/api/openstack/compute/contrib/volumes.py -index 9940e30..9f1fa62 100644 ---- a/nova/api/openstack/compute/contrib/volumes.py -+++ b/nova/api/openstack/compute/contrib/volumes.py -@@ -17,7 +17,6 @@ - - import webob - from webob import exc --from xml.dom import minidom - - from nova.api.openstack import common - from nova.api.openstack import extensions -@@ -155,7 +154,7 @@ class CreateDeserializer(CommonDeserializer): - - def default(self, string): - """Deserialize an xml-formatted volume create request.""" -- dom = minidom.parseString(string) -+ dom = utils.safe_minidom_parse_string(string) - volume = self._extract_volume(dom) - return {'body': {'volume': volume}} - -diff --git a/nova/api/openstack/compute/servers.py b/nova/api/openstack/compute/servers.py -index 3a14b4f..a093266 100644 ---- a/nova/api/openstack/compute/servers.py -+++ b/nova/api/openstack/compute/servers.py -@@ -21,7 +21,6 @@ import socket - - import webob - from webob import exc --from xml.dom import minidom - - from nova.api.openstack import common - from nova.api.openstack.compute import ips -@@ -297,7 +296,7 @@ class ActionDeserializer(CommonDeserializer): - """ - - def default(self, string): -- dom = minidom.parseString(string) -+ dom = utils.safe_minidom_parse_string(string) - action_node = dom.childNodes[0] - action_name = action_node.tagName - -@@ -404,7 +403,7 @@ class CreateDeserializer(CommonDeserializer): - - def default(self, string): - """Deserialize an xml-formatted server create request.""" -- dom = minidom.parseString(string) -+ dom = utils.safe_minidom_parse_string(string) - server = self._extract_server(dom) - return {'body': {'server': server}} - -diff --git a/nova/api/openstack/volume/contrib/volume_actions.py b/nova/api/openstack/volume/contrib/volume_actions.py -index 8a453bf..7e47065 100644 ---- a/nova/api/openstack/volume/contrib/volume_actions.py -+++ b/nova/api/openstack/volume/contrib/volume_actions.py -@@ -13,7 +13,6 @@ - # under the License. - - import webob --from xml.dom import minidom - - from nova.api.openstack import extensions - from nova.api.openstack import wsgi -@@ -22,6 +21,7 @@ from nova import exception - from nova import flags - from nova.openstack.common import log as logging - from nova.openstack.common.rpc import common as rpc_common -+from nova import utils - from nova import volume - - -@@ -54,7 +54,7 @@ class VolumeToImageSerializer(xmlutil.TemplateBuilder): - class VolumeToImageDeserializer(wsgi.XMLDeserializer): - """Deserializer to handle xml-formatted requests""" - def default(self, string): -- dom = minidom.parseString(string) -+ dom = utils.safe_minidom_parse_string(string) - action_node = dom.childNodes[0] - action_name = action_node.tagName - -diff --git a/nova/api/openstack/volume/volumes.py b/nova/api/openstack/volume/volumes.py -index 6cc4af8..ef33f92 100644 ---- a/nova/api/openstack/volume/volumes.py -+++ b/nova/api/openstack/volume/volumes.py -@@ -17,7 +17,6 @@ - - import webob - from webob import exc --from xml.dom import minidom - - from nova.api.openstack import common - from nova.api.openstack import wsgi -@@ -191,7 +190,7 @@ class CreateDeserializer(CommonDeserializer): - - def default(self, string): - """Deserialize an xml-formatted volume create request.""" -- dom = minidom.parseString(string) -+ dom = utils.safe_minidom_parse_string(string) - volume = self._extract_volume(dom) - return {'body': {'volume': volume}} - -diff --git a/nova/api/openstack/wsgi.py b/nova/api/openstack/wsgi.py -index 1ff7745..6ab4f63 100644 ---- a/nova/api/openstack/wsgi.py -+++ b/nova/api/openstack/wsgi.py -@@ -27,6 +27,7 @@ import webob - from nova import exception - from nova.openstack.common import jsonutils - from nova.openstack.common import log as logging -+from nova import utils - from nova import wsgi - - -@@ -217,7 +218,7 @@ class XMLDeserializer(TextDeserializer): - plurals = set(self.metadata.get('plurals', {})) - - try: -- node = minidom.parseString(datastring).childNodes[0] -+ node = utils.safe_minidom_parse_string(datastring).childNodes[0] - return {node.nodeName: self._from_xml_node(node, plurals)} - except expat.ExpatError: - msg = _("cannot understand XML") -@@ -268,11 +269,11 @@ class XMLDeserializer(TextDeserializer): - - def extract_text(self, node): - """Get the text field contained by the given node""" -- if len(node.childNodes) == 1: -- child = node.childNodes[0] -+ ret_val = "" -+ for child in node.childNodes: - if child.nodeType == child.TEXT_NODE: -- return child.nodeValue -- return "" -+ ret_val += child.nodeValue -+ return ret_val - - def extract_elements(self, node): - """Get only Element type childs from node""" -@@ -631,7 +632,7 @@ def action_peek_json(body): - def action_peek_xml(body): - """Determine action to invoke.""" - -- dom = minidom.parseString(body) -+ dom = utils.safe_minidom_parse_string(body) - action_node = dom.childNodes[0] - - return action_node.tagName -diff --git a/nova/tests/test_utils.py b/nova/tests/test_utils.py -index adc62d8..46e4f14 100644 ---- a/nova/tests/test_utils.py -+++ b/nova/tests/test_utils.py -@@ -457,6 +457,39 @@ class GenericUtilsTestCase(test.TestCase): - result = utils.service_is_up(service) - self.assertFalse(result) - -+ def test_safe_parse_xml(self): -+ -+ normal_body = (""" -+ <?xml version="1.0" ?><foo> -+ <bar> -+ <v1>hey</v1> -+ <v2>there</v2> -+ </bar> -+ </foo>""").strip() -+ -+ def killer_body(): -+ return (("""<!DOCTYPE x [ -+ <!ENTITY a "%(a)s"> -+ <!ENTITY b "%(b)s"> -+ <!ENTITY c "%(c)s">]> -+ <foo> -+ <bar> -+ <v1>%(d)s</v1> -+ </bar> -+ </foo>""") % { -+ 'a': 'A' * 10, -+ 'b': '&a;' * 10, -+ 'c': '&b;' * 10, -+ 'd': '&c;' * 9999, -+ }).strip() -+ -+ dom = utils.safe_minidom_parse_string(normal_body) -+ self.assertEqual(normal_body, str(dom.toxml())) -+ -+ self.assertRaises(ValueError, -+ utils.safe_minidom_parse_string, -+ killer_body()) -+ - def test_xhtml_escape(self): - self.assertEqual('"foo"', utils.xhtml_escape('"foo"')) - self.assertEqual(''foo'', utils.xhtml_escape("'foo'")) -diff --git a/nova/utils.py b/nova/utils.py -index 5722cf5..4a605cb 100644 ---- a/nova/utils.py -+++ b/nova/utils.py -@@ -39,6 +39,10 @@ import tempfile - import time - import uuid - import weakref -+from xml.dom import minidom -+from xml.parsers import expat -+from xml import sax -+from xml.sax import expatreader - from xml.sax import saxutils - - from eventlet import event -@@ -567,6 +571,46 @@ class LoopingCall(object): - return self.done.wait() - - -+class ProtectedExpatParser(expatreader.ExpatParser): -+ """An expat parser which disables DTD's and entities by default.""" -+ -+ def __init__(self, forbid_dtd=True, forbid_entities=True, -+ *args, **kwargs): -+ # Python 2.x old style class -+ expatreader.ExpatParser.__init__(self, *args, **kwargs) -+ self.forbid_dtd = forbid_dtd -+ self.forbid_entities = forbid_entities -+ -+ def start_doctype_decl(self, name, sysid, pubid, has_internal_subset): -+ raise ValueError("Inline DTD forbidden") -+ -+ def entity_decl(self, entityName, is_parameter_entity, value, base, -+ systemId, publicId, notationName): -+ raise ValueError("<!ENTITY> forbidden") -+ -+ def unparsed_entity_decl(self, name, base, sysid, pubid, notation_name): -+ # expat 1.2 -+ raise ValueError("<!ENTITY> forbidden") -+ -+ def reset(self): -+ expatreader.ExpatParser.reset(self) -+ if self.forbid_dtd: -+ self._parser.StartDoctypeDeclHandler = self.start_doctype_decl -+ if self.forbid_entities: -+ self._parser.EntityDeclHandler = self.entity_decl -+ self._parser.UnparsedEntityDeclHandler = self.unparsed_entity_decl -+ -+ -+def safe_minidom_parse_string(xml_string): -+ """Parse an XML string using minidom safely. -+ -+ """ -+ try: -+ return minidom.parseString(xml_string, parser=ProtectedExpatParser()) -+ except sax.SAXParseException as se: -+ raise expat.ExpatError() -+ -+ - def xhtml_escape(value): - """Escapes a string so it is valid within XML or XHTML. diff --git a/sys-cluster/nova/nova-2012.2.3-r3.ebuild b/sys-cluster/nova/nova-2012.2.4.ebuild index 2b70c99c2095..e3b0eadb543c 100644 --- a/sys-cluster/nova/nova-2012.2.3-r3.ebuild +++ b/sys-cluster/nova/nova-2012.2.4.ebuild @@ -1,6 +1,6 @@ # Copyright 1999-2013 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 -# $Header: /var/cvsroot/gentoo-x86/sys-cluster/nova/nova-2012.2.3-r3.ebuild,v 1.2 2013/03/26 04:41:39 prometheanfire Exp $ +# $Header: /var/cvsroot/gentoo-x86/sys-cluster/nova/nova-2012.2.4.ebuild,v 1.1 2013/05/10 02:30:19 prometheanfire Exp $ EAPI=5 PYTHON_COMPAT=( python2_7 ) @@ -44,9 +44,6 @@ RDEPEND="=dev-python/amqplib-0.6.1 >=dev-python/python-quantumclient-2.1[${PYTHON_USEDEP}]" PATCHES=( - "${FILESDIR}/nova-folsom-CVE-2013-1664.patch" - "${FILESDIR}/nova-folsom-3-CVE-2013-0335.patch" - "${FILESDIR}/nova-folsom-3-CVE-2013-1838.patch" ) python_install() { diff --git a/sys-cluster/nova/nova-2013.1.ebuild b/sys-cluster/nova/nova-2013.1.1.ebuild index 5d1773450de3..311b34572e3a 100644 --- a/sys-cluster/nova/nova-2013.1.ebuild +++ b/sys-cluster/nova/nova-2013.1.1.ebuild @@ -1,6 +1,6 @@ # Copyright 1999-2013 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 -# $Header: /var/cvsroot/gentoo-x86/sys-cluster/nova/nova-2013.1.ebuild,v 1.1 2013/04/10 17:34:19 prometheanfire Exp $ +# $Header: /var/cvsroot/gentoo-x86/sys-cluster/nova/nova-2013.1.1.ebuild,v 1.1 2013/05/10 02:30:19 prometheanfire Exp $ EAPI=5 PYTHON_COMPAT=( python2_7 ) |