summaryrefslogtreecommitdiff
path: root/keystone/api/_shared/EC2_S3_Resource.py
diff options
context:
space:
mode:
Diffstat (limited to 'keystone/api/_shared/EC2_S3_Resource.py')
-rw-r--r--keystone/api/_shared/EC2_S3_Resource.py31
1 files changed, 31 insertions, 0 deletions
diff --git a/keystone/api/_shared/EC2_S3_Resource.py b/keystone/api/_shared/EC2_S3_Resource.py
index 021cf4ad5..803254816 100644
--- a/keystone/api/_shared/EC2_S3_Resource.py
+++ b/keystone/api/_shared/EC2_S3_Resource.py
@@ -12,15 +12,20 @@
# Common base resource for EC2 and S3 Authentication
+import datetime
+
from oslo_serialization import jsonutils
+from oslo_utils import timeutils
from werkzeug import exceptions
from keystone.common import provider_api
from keystone.common import utils
+import keystone.conf
from keystone import exception as ks_exceptions
from keystone.i18n import _
from keystone.server import flask as ks_flask
+CONF = keystone.conf.CONF
PROVIDERS = provider_api.ProviderAPIs
CRED_TYPE_EC2 = 'ec2'
@@ -36,6 +41,31 @@ class ResourceBase(ks_flask.ResourceBase):
# the ABC module.
raise NotImplementedError()
+ @staticmethod
+ def _check_timestamp(credentials):
+ timestamp = (
+ # AWS Signature v1/v2
+ credentials.get('params', {}).get('Timestamp') or
+ # AWS Signature v4
+ credentials.get('headers', {}).get('X-Amz-Date') or
+ credentials.get('params', {}).get('X-Amz-Date')
+ )
+ if not timestamp:
+ # If the signed payload doesn't include a timestamp then the signer
+ # must have intentionally left it off
+ return
+ try:
+ timestamp = timeutils.parse_isotime(timestamp)
+ timestamp = timeutils.normalize_time(timestamp)
+ except Exception as e:
+ raise ks_exceptions.Unauthorized(
+ _('Credential timestamp is invalid: %s') % e)
+ auth_ttl = datetime.timedelta(minutes=CONF.credential.auth_ttl)
+ current_time = timeutils.normalize_time(timeutils.utcnow())
+ if current_time > timestamp + auth_ttl:
+ raise ks_exceptions.Unauthorized(
+ _('Credential is expired'))
+
def handle_authenticate(self):
# TODO(morgan): convert this dirty check to JSON Schema validation
# this mirrors the previous behavior of the webob system where an
@@ -101,6 +131,7 @@ class ResourceBase(ks_flask.ResourceBase):
except AssertionError as e:
raise ks_exceptions.Unauthorized from e
+ self._check_timestamp(credentials)
roles = PROVIDERS.assignment_api.get_roles_for_user_and_project(
user_ref['id'], project_ref['id'])