EC2 API Auth Failure
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
OpenStack Identity (keystone) |
Won't Fix
|
Undecided
|
Nikita Kalyanov | ||
ec2-api |
New
|
Undecided
|
Unassigned |
Bug Description
When trying to validate user token through Keystone an inconsistent behavior is observed:
The very first request for a given user to Keystone is successful, while the second and subsequent requests for the same user result in a Key Error in Keystone _decrypt_credential method and thus auth failure (See the attached traceback). The problem is observed by merely repeating the same aws-cli commands for the same user 2 or more times.
After inserting some debug log messages in core.py the problem seem to happen in _get_credential method in keystone.
In first request to Keystone:
Aug 15 20:14:13 ubuntu-vm6 <email address hidden>[22678]: #033[00;36mINFO keystone.
In second request to Keystone:
Aug 15 20:14:43 ubuntu-vm6 <email address hidden>[22678]: #033[00;36mINFO keystone.
=> Basically _get_credential method returns normal encrypted credential (encrypted_blob) for the first call, and an unencrypted credential (blob) for the second and subsequent calls by the same credential_id after 30 seconds. After that, the already decrypted credential incorrectly returned by _get_credential is passed to _decrypt_credential which fails because there is no 'encrypted_blob' key in the dictionary. The stack trace for the second and subsequent calls led to a package named 'dogpile' and some cache-related methods inside it.
The problem seem to happen due to in-place modification of the credential dictionary in _decrypt_credential method. During the first request to Keystone the normal encrypted credential dictionary is returned by _get_credential method and the returned result is cached. However, after that the credential dictionary is modified in-place by _decrypt_credential method. For the second and subsequent calls to the _get_credential for the same user it tries to return the result from cache. But the cached result has been modified by _decrypt_
The solution is to modify a copy of the credential dictionary inside _decrypt_credential method, not the original credential in-place (the same approach as in _encrypt_credential where a copy is modified). This way the encrypted value of the credential is cached and it does not gets modified afterwards. So the normal encrypted credential is returned from cache and passed to _decrypt_credential again and again even for the same user which fixes the problem.
Fix proposed to branch: master /review. opendev. org/677239
Review: https:/