Exemple #1
0
    def _validate_shared_secret(self, requestor_id, signature,
                                requestor_address):
        expected_signature = hmac.new(
            CONF.neutron.metadata_proxy_shared_secret,
            requestor_id, hashlib.sha256).hexdigest()

        if not utils.constant_time_compare(expected_signature, signature):
            if requestor_id:
                LOG.warning(_LW('X-Instance-ID-Signature: %(signature)s does '
                                'not match the expected value: '
                                '%(expected_signature)s for id: '
                                '%(requestor_id)s. Request From: '
                                '%(requestor_address)s'),
                            {'signature': signature,
                             'expected_signature': expected_signature,
                             'requestor_id': requestor_id,
                             'requestor_address': requestor_address})

            msg = _('Invalid proxy request signature.')
            raise webob.exc.HTTPForbidden(explanation=msg)
Exemple #2
0
    def _validate_shared_secret(self, requestor_id, signature,
                                requestor_address):
        expected_signature = hmac.new(
            CONF.neutron.metadata_proxy_shared_secret,
            requestor_id, hashlib.sha256).hexdigest()

        if not utils.constant_time_compare(expected_signature, signature):
            if requestor_id:
                LOG.warning(_LW('X-Instance-ID-Signature: %(signature)s does '
                                'not match the expected value: '
                                '%(expected_signature)s for id: '
                                '%(requestor_id)s. Request From: '
                                '%(requestor_address)s'),
                            {'signature': signature,
                             'expected_signature': expected_signature,
                             'requestor_id': requestor_id,
                             'requestor_address': requestor_address})

            msg = _('Invalid proxy request signature.')
            raise webob.exc.HTTPForbidden(explanation=msg)
Exemple #3
0
 def test_constant_time_compare(self):
     self.assertTrue(utils.constant_time_compare("abcd1234", "abcd1234"))
     self.assertFalse(utils.constant_time_compare("abcd1234", "a"))
     self.assertFalse(utils.constant_time_compare("abcd1234", "ABCD234"))
Exemple #4
0
 def test_constant_time_compare(self):
     self.assertTrue(utils.constant_time_compare("abcd1234", "abcd1234"))
     self.assertFalse(utils.constant_time_compare("abcd1234", "a"))
     self.assertFalse(utils.constant_time_compare("abcd1234", "ABCD234"))
Exemple #5
0
    def _handle_instance_id_request(self, req):
        instance_id = req.headers.get('X-Instance-ID')
        tenant_id = req.headers.get('X-Tenant-ID')
        signature = req.headers.get('X-Instance-ID-Signature')
        remote_address = req.headers.get('X-Forwarded-For')

        # Ensure that only one header was passed

        if instance_id is None:
            msg = _('X-Instance-ID header is missing from request.')
        elif signature is None:
            msg = _('X-Instance-ID-Signature header is missing from request.')
        elif tenant_id is None:
            msg = _('X-Tenant-ID header is missing from request.')
        elif not isinstance(instance_id, six.string_types):
            msg = _('Multiple X-Instance-ID headers found within request.')
        elif not isinstance(tenant_id, six.string_types):
            msg = _('Multiple X-Tenant-ID headers found within request.')
        else:
            msg = None

        if msg:
            raise webob.exc.HTTPBadRequest(explanation=msg)

        expected_signature = hmac.new(
            CONF.neutron.metadata_proxy_shared_secret,
            instance_id,
            hashlib.sha256).hexdigest()

        if not utils.constant_time_compare(expected_signature, signature):
            if instance_id:
                LOG.warning(_LW('X-Instance-ID-Signature: %(signature)s does '
                                'not match the expected value: '
                                '%(expected_signature)s for id: '
                                '%(instance_id)s. Request From: '
                                '%(remote_address)s'),
                            {'signature': signature,
                             'expected_signature': expected_signature,
                             'instance_id': instance_id,
                             'remote_address': remote_address})

            msg = _('Invalid proxy request signature.')
            raise webob.exc.HTTPForbidden(explanation=msg)

        try:
            meta_data = self.get_metadata_by_instance_id(instance_id,
                                                         remote_address)
        except Exception:
            LOG.exception(_LE('Failed to get metadata for instance id: %s'),
                          instance_id)
            msg = _('An unknown error has occurred. '
                    'Please try your request again.')
            raise webob.exc.HTTPInternalServerError(
                                               explanation=six.text_type(msg))

        if meta_data is None:
            LOG.error(_LE('Failed to get metadata for instance id: %s'),
                      instance_id)
        elif meta_data.instance.project_id != tenant_id:
            LOG.warning(_LW("Tenant_id %(tenant_id)s does not match tenant_id "
                            "of instance %(instance_id)s."),
                        {'tenant_id': tenant_id, 'instance_id': instance_id})
            # causes a 404 to be raised
            meta_data = None

        return meta_data
Exemple #6
0
    def _handle_instance_id_request(self, req):
        instance_id = req.headers.get('X-Instance-ID')
        tenant_id = req.headers.get('X-Tenant-ID')
        signature = req.headers.get('X-Instance-ID-Signature')
        remote_address = req.headers.get('X-Forwarded-For')

        # Ensure that only one header was passed

        if instance_id is None:
            msg = _('X-Instance-ID header is missing from request.')
        elif tenant_id is None:
            msg = _('X-Tenant-ID header is missing from request.')
        elif not isinstance(instance_id, six.string_types):
            msg = _('Multiple X-Instance-ID headers found within request.')
        elif not isinstance(tenant_id, six.string_types):
            msg = _('Multiple X-Tenant-ID headers found within request.')
        else:
            msg = None

        if msg:
            raise webob.exc.HTTPBadRequest(explanation=msg)

        expected_signature = hmac.new(
            CONF.neutron.metadata_proxy_shared_secret, instance_id,
            hashlib.sha256).hexdigest()

        if not utils.constant_time_compare(expected_signature, signature):
            if instance_id:
                LOG.warn(
                    _LW('X-Instance-ID-Signature: %(signature)s does '
                        'not match the expected value: '
                        '%(expected_signature)s for id: %(instance_id)s.'
                        '  Request From: %(remote_address)s'), {
                            'signature': signature,
                            'expected_signature': expected_signature,
                            'instance_id': instance_id,
                            'remote_address': remote_address
                        })

            msg = _('Invalid proxy request signature.')
            raise webob.exc.HTTPForbidden(explanation=msg)

        try:
            meta_data = self.get_metadata_by_instance_id(
                instance_id, remote_address)
        except Exception:
            LOG.exception(_('Failed to get metadata for instance id: %s'),
                          instance_id)
            msg = _('An unknown error has occurred. '
                    'Please try your request again.')
            raise webob.exc.HTTPInternalServerError(
                explanation=six.text_type(msg))

        if meta_data is None:
            LOG.error(_LE('Failed to get metadata for instance id: %s'),
                      instance_id)
        elif meta_data.instance['project_id'] != tenant_id:
            LOG.warn(
                _LW("Tenant_id %(tenant_id)s does not match tenant_id "
                    "of instance %(instance_id)s."), {
                        'tenant_id': tenant_id,
                        'instance_id': instance_id
                    })
            # causes a 404 to be raised
            meta_data = None

        return meta_data