예제 #1
0
 def test_parse_server_string(self):
     result = utils.parse_server_string('::1')
     self.assertEqual(('::1', ''), result)
     result = utils.parse_server_string('[::1]:8773')
     self.assertEqual(('::1', '8773'), result)
     result = utils.parse_server_string('2001:db8::192.168.1.1')
     self.assertEqual(('2001:db8::192.168.1.1', ''), result)
     result = utils.parse_server_string('[2001:db8::192.168.1.1]:8773')
     self.assertEqual(('2001:db8::192.168.1.1', '8773'), result)
     result = utils.parse_server_string('192.168.1.1')
     self.assertEqual(('192.168.1.1', ''), result)
     result = utils.parse_server_string('192.168.1.2:8773')
     self.assertEqual(('192.168.1.2', '8773'), result)
     result = utils.parse_server_string('192.168.1.3')
     self.assertEqual(('192.168.1.3', ''), result)
     result = utils.parse_server_string('www.example.com:8443')
     self.assertEqual(('www.example.com', '8443'), result)
     result = utils.parse_server_string('www.example.com')
     self.assertEqual(('www.example.com', ''), result)
     # error case
     result = utils.parse_server_string('www.exa:mple.com:8443')
     self.assertEqual(('', ''), result)
예제 #2
0
 def test_parse_server_string(self):
     result = utils.parse_server_string('::1')
     self.assertEqual(('::1', ''), result)
     result = utils.parse_server_string('[::1]:8773')
     self.assertEqual(('::1', '8773'), result)
     result = utils.parse_server_string('2001:db8::192.168.1.1')
     self.assertEqual(('2001:db8::192.168.1.1', ''), result)
     result = utils.parse_server_string('[2001:db8::192.168.1.1]:8773')
     self.assertEqual(('2001:db8::192.168.1.1', '8773'), result)
     result = utils.parse_server_string('192.168.1.1')
     self.assertEqual(('192.168.1.1', ''), result)
     result = utils.parse_server_string('192.168.1.2:8773')
     self.assertEqual(('192.168.1.2', '8773'), result)
     result = utils.parse_server_string('192.168.1.3')
     self.assertEqual(('192.168.1.3', ''), result)
     result = utils.parse_server_string('www.example.com:8443')
     self.assertEqual(('www.example.com', '8443'), result)
     result = utils.parse_server_string('www.example.com')
     self.assertEqual(('www.example.com', ''), result)
     # error case
     result = utils.parse_server_string('www.exa:mple.com:8443')
     self.assertEqual(('', ''), result)
예제 #3
0
    def authenticate(self, access, signature, params, verb='GET',
                     server_string='127.0.0.1:8773', path='/',
                     check_type='ec2', headers=None):
        """Authenticates AWS request using access key and signature

        If the project is not specified, attempts to authenticate to
        a project with the same name as the user. This way, older tools
        that have no project knowledge will still work.

        @type access: str
        @param access: Access key for user in the form "access:project".

        @type signature: str
        @param signature: Signature of the request.

        @type params: list of str
        @param params: Web paramaters used for the signature.

        @type verb: str
        @param verb: Web request verb ('GET' or 'POST').

        @type server_string: str
        @param server_string: Web request server string.

        @type path: str
        @param path: Web request path.

        @type check_type: str
        @param check_type: Type of signature to check. 'ec2' for EC2, 's3' for
                           S3. Any other value will cause signature not to be
                           checked.

        @type headers: list
        @param headers: HTTP headers passed with the request (only needed for
                        s3 signature checks)

        @rtype: tuple (User, Project)
        @return: User and project that the request represents.
        """
        # TODO(vish): check for valid timestamp
        (access_key, _sep, project_id) = access.partition(':')

        LOG.debug(_('Looking up user: %r'), access_key)
        user = self.get_user_from_access_key(access_key)
        LOG.debug('user: %r', user)
        if user is None:
            LOG.audit(_("Failed authorization for access key %s"), access_key)
            raise exception.AccessKeyNotFound(access_key=access_key)

        # NOTE(vish): if we stop using project name as id we need better
        #             logic to find a default project for user
        if project_id == '':
            LOG.debug(_("Using project name = user name (%s)"), user.name)
            project_id = user.name

        project = self.get_project(project_id)
        if project is None:
            pjid = project_id
            uname = user.name
            LOG.audit(_("failed authorization: no project named %(pjid)s"
                    " (user=%(uname)s)") % locals())
            raise exception.ProjectNotFound(project_id=project_id)
        if not self.is_admin(user) and not self.is_project_member(user,
                                                                  project):
            uname = user.name
            uid = user.id
            pjname = project.name
            pjid = project.id
            LOG.audit(_("Failed authorization: user %(uname)s not admin"
                    " and not member of project %(pjname)s") % locals())
            raise exception.ProjectMembershipNotFound(project_id=pjid,
                                                      user_id=uid)
        if check_type == 's3':
            sign = signer.Signer(user.secret.encode())
            expected_signature = sign.s3_authorization(headers, verb, path)
            LOG.debug(_('user.secret: %s'), user.secret)
            LOG.debug(_('expected_signature: %s'), expected_signature)
            LOG.debug(_('signature: %s'), signature)
            if signature != expected_signature:
                LOG.audit(_("Invalid signature for user %s"), user.name)
                raise exception.InvalidSignature(signature=signature,
                                                 user=user)
        elif check_type == 'ec2':
            # NOTE(vish): hmac can't handle unicode, so encode ensures that
            #             secret isn't unicode
            expected_signature = signer.Signer(user.secret.encode()).generate(
                    params, verb, server_string, path)
            LOG.debug(_('user.secret: %s'), user.secret)
            LOG.debug(_('expected_signature: %s'), expected_signature)
            LOG.debug(_('signature: %s'), signature)
            if signature != expected_signature:
                (addr_str, port_str) = utils.parse_server_string(server_string)
                # If the given server_string contains port num, try without it.
                if port_str != '':
                    host_only_signature = signer.Signer(
                        user.secret.encode()).generate(params, verb,
                                                       addr_str, path)
                    LOG.debug(_('host_only_signature: %s'),
                              host_only_signature)
                    if signature == host_only_signature:
                        return (user, project)
                LOG.audit(_("Invalid signature for user %s"), user.name)
                raise exception.InvalidSignature(signature=signature,
                                                 user=user)
        return (user, project)