Fix far-future date handling
Previously, if a user-provided timestamp was after the largest-possible Swift timestamp, we would raise AccessDenied. However, AWS continues to complain about time skew. Note that we may regret this come 2286, but by then I'll be dead. Change-Id: I88952a28a7e7c42540c61514f82582815fabf611
This commit is contained in:
		
				
					committed by
					
						
						Kota Tsuyuzaki
					
				
			
			
				
	
			
			
			
						parent
						
							710738b548
						
					
				
				
					commit
					136721428f
				
			@@ -138,10 +138,15 @@ class SigV4Mixin(object):
 | 
			
		||||
                raise AccessDenied('AWS authentication requires a valid Date '
 | 
			
		||||
                                   'or x-amz-date header')
 | 
			
		||||
 | 
			
		||||
            if timestamp < 0:
 | 
			
		||||
                raise AccessDenied('AWS authentication requires a valid Date '
 | 
			
		||||
                                   'or x-amz-date header')
 | 
			
		||||
 | 
			
		||||
            try:
 | 
			
		||||
                self._timestamp = S3Timestamp(timestamp)
 | 
			
		||||
            except ValueError:
 | 
			
		||||
                raise AccessDenied()
 | 
			
		||||
                # Must be far-future; blame clock skew
 | 
			
		||||
                raise RequestTimeTooSkewed()
 | 
			
		||||
 | 
			
		||||
        return self._timestamp
 | 
			
		||||
 | 
			
		||||
@@ -422,10 +427,14 @@ class Request(swob.Request):
 | 
			
		||||
                raise AccessDenied('AWS authentication requires a valid Date '
 | 
			
		||||
                                   'or x-amz-date header')
 | 
			
		||||
 | 
			
		||||
            if timestamp < 0:
 | 
			
		||||
                raise AccessDenied('AWS authentication requires a valid Date '
 | 
			
		||||
                                   'or x-amz-date header')
 | 
			
		||||
            try:
 | 
			
		||||
                self._timestamp = S3Timestamp(timestamp)
 | 
			
		||||
            except ValueError:
 | 
			
		||||
                raise AccessDenied()
 | 
			
		||||
                # Must be far-future; blame clock skew
 | 
			
		||||
                raise RequestTimeTooSkewed()
 | 
			
		||||
 | 
			
		||||
        return self._timestamp
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -604,7 +604,7 @@ class RequestTimeout(ErrorResponse):
 | 
			
		||||
 | 
			
		||||
class RequestTimeTooSkewed(ErrorResponse):
 | 
			
		||||
    _status = '403 Forbidden'
 | 
			
		||||
    _msg = 'The difference between the request time and the server\'s time ' \
 | 
			
		||||
    _msg = 'The difference between the request time and the current time ' \
 | 
			
		||||
           'is too large.'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,6 @@ ceph_s3:
 | 
			
		||||
  s3tests.functional.test_headers.test_bucket_create_bad_authorization_none: {status: KNOWN}
 | 
			
		||||
  s3tests.functional.test_headers.test_object_create_bad_authorization_invalid_aws2: {status: KNOWN}
 | 
			
		||||
  s3tests.functional.test_headers.test_object_create_bad_authorization_none: {status: KNOWN}
 | 
			
		||||
  s3tests.functional.test_headers.test_object_create_bad_date_after_end_aws2: {status: KNOWN}
 | 
			
		||||
  s3tests.functional.test_s3.test_100_continue: {status: KNOWN}
 | 
			
		||||
  s3tests.functional.test_s3.test_abort_multipart_upload: {status: KNOWN}
 | 
			
		||||
  s3tests.functional.test_s3.test_abort_multipart_upload_not_found: {status: KNOWN}
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,6 @@ ceph_s3:
 | 
			
		||||
  s3tests.functional.test_headers.test_bucket_create_bad_authorization_none: {status: KNOWN}
 | 
			
		||||
  s3tests.functional.test_headers.test_object_create_bad_authorization_invalid_aws2: {status: KNOWN}
 | 
			
		||||
  s3tests.functional.test_headers.test_object_create_bad_authorization_none: {status: KNOWN}
 | 
			
		||||
  s3tests.functional.test_headers.test_object_create_bad_date_after_end_aws2: {status: KNOWN}
 | 
			
		||||
  s3tests.functional.test_s3.test_100_continue: {status: KNOWN}
 | 
			
		||||
  s3tests.functional.test_s3.test_atomic_conditional_write_1mb: {status: KNOWN}
 | 
			
		||||
  s3tests.functional.test_s3.test_atomic_dual_conditional_write_1mb: {status: KNOWN}
 | 
			
		||||
 
 | 
			
		||||
@@ -27,7 +27,7 @@ from swift3.cfg import CONF
 | 
			
		||||
from swift3.request import Request as S3_Request
 | 
			
		||||
from swift3.request import S3AclRequest, SigV4Request, SIGV4_X_AMZ_DATE_FORMAT
 | 
			
		||||
from swift3.response import InvalidArgument, NoSuchBucket, InternalError, \
 | 
			
		||||
    AccessDenied, SignatureDoesNotMatch
 | 
			
		||||
    AccessDenied, SignatureDoesNotMatch, RequestTimeTooSkewed
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
Fake_ACL_MAP = {
 | 
			
		||||
@@ -439,6 +439,24 @@ class TestRequest(Swift3TestCase):
 | 
			
		||||
            self._test_request_timestamp_sigv4(date_header)
 | 
			
		||||
 | 
			
		||||
        self.assertEqual('403 Forbidden', cm.exception.message)
 | 
			
		||||
        self.assertIn(access_denied_message, cm.exception.body)
 | 
			
		||||
 | 
			
		||||
        # far-past Date header
 | 
			
		||||
        date_header = {'Date': 'Tue, 07 Jul 999 21:53:04 GMT'}
 | 
			
		||||
        with self.assertRaises(AccessDenied) as cm:
 | 
			
		||||
            self._test_request_timestamp_sigv4(date_header)
 | 
			
		||||
 | 
			
		||||
        self.assertEqual('403 Forbidden', cm.exception.message)
 | 
			
		||||
        self.assertIn(access_denied_message, cm.exception.body)
 | 
			
		||||
 | 
			
		||||
        # far-future Date header
 | 
			
		||||
        date_header = {'Date': 'Tue, 07 Jul 9999 21:53:04 GMT'}
 | 
			
		||||
        with self.assertRaises(RequestTimeTooSkewed) as cm:
 | 
			
		||||
            self._test_request_timestamp_sigv4(date_header)
 | 
			
		||||
 | 
			
		||||
        self.assertEqual('403 Forbidden', cm.exception.message)
 | 
			
		||||
        self.assertIn('The difference between the request time and the '
 | 
			
		||||
                      'current time is too large.', cm.exception.body)
 | 
			
		||||
 | 
			
		||||
    def _test_request_timestamp_sigv2(self, date_header):
 | 
			
		||||
        # signature v4 here
 | 
			
		||||
@@ -486,6 +504,31 @@ class TestRequest(Swift3TestCase):
 | 
			
		||||
        self.assertEqual('403 Forbidden', cm.exception.message)
 | 
			
		||||
        self.assertIn(access_denied_message, cm.exception.body)
 | 
			
		||||
 | 
			
		||||
        # Negative timestamp
 | 
			
		||||
        date_header = {'X-Amz-Date': '00160523T054055Z'}
 | 
			
		||||
        with self.assertRaises(AccessDenied) as cm:
 | 
			
		||||
            self._test_request_timestamp_sigv2(date_header)
 | 
			
		||||
 | 
			
		||||
        self.assertEqual('403 Forbidden', cm.exception.message)
 | 
			
		||||
        self.assertIn(access_denied_message, cm.exception.body)
 | 
			
		||||
 | 
			
		||||
        # far-past Date header
 | 
			
		||||
        date_header = {'Date': 'Tue, 07 Jul 999 21:53:04 GMT'}
 | 
			
		||||
        with self.assertRaises(AccessDenied) as cm:
 | 
			
		||||
            self._test_request_timestamp_sigv2(date_header)
 | 
			
		||||
 | 
			
		||||
        self.assertEqual('403 Forbidden', cm.exception.message)
 | 
			
		||||
        self.assertIn(access_denied_message, cm.exception.body)
 | 
			
		||||
 | 
			
		||||
        # far-future Date header
 | 
			
		||||
        date_header = {'Date': 'Tue, 07 Jul 9999 21:53:04 GMT'}
 | 
			
		||||
        with self.assertRaises(RequestTimeTooSkewed) as cm:
 | 
			
		||||
            self._test_request_timestamp_sigv2(date_header)
 | 
			
		||||
 | 
			
		||||
        self.assertEqual('403 Forbidden', cm.exception.message)
 | 
			
		||||
        self.assertIn('The difference between the request time and the '
 | 
			
		||||
                      'current time is too large.', cm.exception.body)
 | 
			
		||||
 | 
			
		||||
    def test_headers_to_sign_sigv4(self):
 | 
			
		||||
        environ = {
 | 
			
		||||
            'REQUEST_METHOD': 'GET'}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user