crypto: Fix traceback on non-utf8, non-swift paths
fetch_crypto_keys can fail like get_keys(): from callback: 'utf-8' codec can't encode character '\udcc0' in position 1: surrogates not allowed: Traceback (most recent call last): File ".../swift/common/middleware/crypto/crypto_utils.py", line 166, in get_keys keys = fetch_crypto_keys(key_id=key_id) File ".../swift/common/middleware/crypto/keymaster.py", line 148, in fetch_crypto_keys keys['container'] = self.keymaster.create_key( File ".../swift/common/middleware/crypto/keymaster.py", line 322, in create_key path = path.encode('utf-8') UnicodeEncodeError: 'utf-8' codec can't encode character '\udcc0' in position 1: surrogates not allowed This doesn't fix *all* non-utf8 paths, but - it was easy enough to avoid the non-swift ones, which have been seen in prod, and - there's ample precedent in other middlewares for checking API version. Signed-off-by: Tim Burke <tim.burke@gmail.com> Change-Id: I8c342c4751ba3ca682efd152e90e396e9f8eb851
This commit is contained in:
@@ -16,6 +16,7 @@
|
|||||||
import base64
|
import base64
|
||||||
import json
|
import json
|
||||||
|
|
||||||
|
from swift.common.constraints import valid_api_version
|
||||||
from swift.common.header_key_dict import HeaderKeyDict
|
from swift.common.header_key_dict import HeaderKeyDict
|
||||||
from swift.common.http import is_success
|
from swift.common.http import is_success
|
||||||
from swift.common.middleware.crypto.crypto_utils import CryptoWSGIContext, \
|
from swift.common.middleware.crypto.crypto_utils import CryptoWSGIContext, \
|
||||||
@@ -454,8 +455,12 @@ class Decrypter(object):
|
|||||||
is_cont_or_obj_req = True
|
is_cont_or_obj_req = True
|
||||||
except ValueError:
|
except ValueError:
|
||||||
is_cont_or_obj_req = False
|
is_cont_or_obj_req = False
|
||||||
|
|
||||||
if not is_cont_or_obj_req:
|
if not is_cont_or_obj_req:
|
||||||
return self.app(env, start_response)
|
return self.app(env, start_response)
|
||||||
|
if not valid_api_version(parts[0]):
|
||||||
|
# Not a swift request
|
||||||
|
return self.app(env, start_response)
|
||||||
|
|
||||||
if parts[3] and req.method in ('GET', 'HEAD'):
|
if parts[3] and req.method in ('GET', 'HEAD'):
|
||||||
handler = DecrypterObjContext(self, self.logger).handle
|
handler = DecrypterObjContext(self, self.logger).handle
|
||||||
|
@@ -22,7 +22,7 @@ from unittest import mock
|
|||||||
from swift.common.request_helpers import is_object_transient_sysmeta
|
from swift.common.request_helpers import is_object_transient_sysmeta
|
||||||
from swift.common.utils import MD5_OF_EMPTY_STRING
|
from swift.common.utils import MD5_OF_EMPTY_STRING
|
||||||
from swift.common.header_key_dict import HeaderKeyDict
|
from swift.common.header_key_dict import HeaderKeyDict
|
||||||
from swift.common.middleware.crypto import decrypter
|
from swift.common.middleware.crypto import decrypter, keymaster
|
||||||
from swift.common.middleware.crypto.crypto_utils import CRYPTO_KEY_CALLBACK, \
|
from swift.common.middleware.crypto.crypto_utils import CRYPTO_KEY_CALLBACK, \
|
||||||
dump_crypto_meta, Crypto, load_crypto_meta
|
dump_crypto_meta, Crypto, load_crypto_meta
|
||||||
from swift.common.swob import Request, HTTPException, HTTPOk, \
|
from swift.common.swob import Request, HTTPException, HTTPOk, \
|
||||||
@@ -1211,6 +1211,18 @@ class TestDecrypter(unittest.TestCase):
|
|||||||
req.get_response(app)
|
req.get_response(app)
|
||||||
self.assertEqual(FakeAppThatExcepts.MESSAGE, catcher.exception.body)
|
self.assertEqual(FakeAppThatExcepts.MESSAGE, catcher.exception.body)
|
||||||
|
|
||||||
|
def test_non_swift_path(self):
|
||||||
|
path = '/\xC0.\xC0./\xC0.\xC0./\xC0.\xC0./\xC0.\xC0./winnt/win.ini'
|
||||||
|
fake_swift = FakeSwift()
|
||||||
|
fake_swift.register('GET', path, HTTPNotFound, {})
|
||||||
|
app = keymaster.KeyMaster(decrypter.Decrypter(fake_swift, {}), {
|
||||||
|
'encryption_root_secret': 'A' * 80,
|
||||||
|
})
|
||||||
|
app.app.logger = debug_logger()
|
||||||
|
req = Request.blank(path)
|
||||||
|
resp = req.get_response(app)
|
||||||
|
self.assertEqual(resp.status_int, 404)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
Reference in New Issue
Block a user