diff options
| author | Vishvananda Ishaya <vishvananda@gmail.com> | 2013-01-02 13:10:01 -0800 |
|---|---|---|
| committer | Vishvananda Ishaya <vishvananda@gmail.com> | 2013-01-04 09:18:23 -0800 |
| commit | aa2dea35c6e1cfc913e85834b9b98eda4155bd06 (patch) | |
| tree | 3e1740683b45094735477794f8f158b0ab360a2a /nova | |
| parent | 4690b501b58bc499029bc4586ff4b7c0917d2395 (diff) | |
Allow larger encrypted password posts to metadata
System Metadata only supports values up to 255 characters, but
passwords encrypted with an rsa key are generally much longer than
that, so we support longer passwords by chunking into four fields.
Change-Id: Iceae6cbc7609ec3bdf1b3814aec5b73f19613349
Diffstat (limited to 'nova')
| -rw-r--r-- | nova/api/metadata/base.py | 7 | ||||
| -rw-r--r-- | nova/api/metadata/password.py | 34 | ||||
| -rw-r--r-- | nova/tests/test_metadata.py | 3 |
3 files changed, 32 insertions, 12 deletions
diff --git a/nova/api/metadata/base.py b/nova/api/metadata/base.py index 2377da7b7..34d412268 100644 --- a/nova/api/metadata/base.py +++ b/nova/api/metadata/base.py @@ -136,12 +136,7 @@ class InstanceMetadata(): for item in instance.get('metadata', []): self.launch_metadata[item['key']] = item['value'] - self.password = '' - # get password if set - for item in instance.get('system_metadata', []): - if item['key'] == 'password': - self.password = item['value'] or '' - break + self.password = password.extract_password(instance) self.uuid = instance.get('uuid') diff --git a/nova/api/metadata/password.py b/nova/api/metadata/password.py index 3cda67eee..b2bb83b15 100644 --- a/nova/api/metadata/password.py +++ b/nova/api/metadata/password.py @@ -19,7 +19,34 @@ from nova import context from nova import db -MAX_SIZE = 256 +CHUNKS = 4 +CHUNK_LENGTH = 255 +MAX_SIZE = CHUNKS * CHUNK_LENGTH + + +def extract_password(instance): + result = '' + for datum in sorted(instance.get('system_metadata', []), + key=lambda x: x['key']): + if datum['key'].startswith('password_'): + result += datum['value'] + return result or None + + +def set_password(context, instance_uuid, password): + """Stores password as system_metadata items. + + Password is stored with the keys 'password_0' -> 'password_3'. + """ + password = password or '' + meta = {} + for i in xrange(CHUNKS): + meta['password_%d' % i] = password[:CHUNK_LENGTH] + password = password[CHUNK_LENGTH:] + db.instance_system_metadata_update(context, + instance_uuid, + meta, + False) def handle_password(req, meta_data): @@ -36,9 +63,6 @@ def handle_password(req, meta_data): if (req.content_length > MAX_SIZE or len(req.body) > MAX_SIZE): msg = _("Request is too large.") raise exc.HTTPBadRequest(explanation=msg) - db.instance_system_metadata_update(ctxt, - meta_data.uuid, - {'password': req.body}, - False) + set_password(ctxt, meta_data.uuid, req.body) else: raise exc.HTTPBadRequest() diff --git a/nova/tests/test_metadata.py b/nova/tests/test_metadata.py index 1f2ea4bc5..25c26ca9c 100644 --- a/nova/tests/test_metadata.py +++ b/nova/tests/test_metadata.py @@ -550,4 +550,5 @@ class MetadataPasswordTestCase(test.TestCase): def test_too_large(self): self.mdinst.password = '' self.assertRaises(webob.exc.HTTPBadRequest, - self._try_set_password, 'a' * 257) + self._try_set_password, + 'a' * (password.MAX_SIZE + 1)) |
