示例#1
0
def test_ssh_success(vo, rest_client):
    """AUTHENTICATION (REST): SSH RSA public key exchange (correct credentials)."""

    root = InternalAccount('root', vo=vo)
    try:
        add_account_identity(PUBLIC_KEY,
                             IdentityType.SSH,
                             root,
                             email='*****@*****.**')
    except Duplicate:
        pass  # might already exist, can skip

    headers_dict = {'X-Rucio-Account': 'root'}
    response = rest_client.get('/auth/ssh_challenge_token',
                               headers=headers(hdrdict(headers_dict),
                                               vohdr(vo)))
    assert response.status_code == 200
    assert 'challenge-' in response.headers.get('X-Rucio-SSH-Challenge-Token')

    signature = ssh_sign(PRIVATE_KEY,
                         response.headers.get('X-Rucio-SSH-Challenge-Token'))

    headers_dict = {
        'X-Rucio-Account': 'root',
        'X-Rucio-SSH-Signature': signature
    }
    response = rest_client.get('/auth/ssh',
                               headers=headers(hdrdict(headers_dict),
                                               vohdr(vo)))
    assert response.status_code == 200
    assert len(response.headers.get('X-Rucio-Auth-Token')) > 32

    del_account_identity(PUBLIC_KEY, IdentityType.SSH, root)
示例#2
0
    def test_get_auth_token_ssh_success(self):
        """AUTHENTICATION (CORE): SSH RSA public key exchange (good signature)."""

        try:
            add_account_identity(PUBLIC_KEY,
                                 IdentityType.SSH,
                                 'root',
                                 email='*****@*****.**')
        except Duplicate:
            pass  # might already exist, can skip

        challenge_token = get_ssh_challenge_token(account='root',
                                                  appid='test',
                                                  ip='127.0.0.1').token

        signature = base64.b64decode(ssh_sign(PRIVATE_KEY, challenge_token))

        result = get_auth_token_ssh(account='root',
                                    signature=signature,
                                    appid='test',
                                    ip='127.0.0.1')

        assert_is_not_none(result)

        del_account_identity(PUBLIC_KEY, IdentityType.SSH, 'root')
示例#3
0
    def test_invalid_padding(self):
        """AUTHENTICATION (CORE): SSH RSA public key exchange (public key with invalid padding)."""

        root = InternalAccount('root', **self.vo)
        try:
            add_account_identity(INVALID_PADDED_PUBLIC_KEY,
                                 IdentityType.SSH,
                                 root,
                                 email='*****@*****.**')
        except Duplicate:
            pass  # might already exist, can skip

        challenge_token = get_ssh_challenge_token(account='root',
                                                  appid='test',
                                                  ip='127.0.0.1',
                                                  **self.vo).get('token')

        ssh_sign_string = ssh_sign(PRIVATE_KEY, challenge_token)
        signature = base64.b64decode(ssh_sign_string)
        result = get_auth_token_ssh(account='root',
                                    signature=signature,
                                    appid='test',
                                    ip='127.0.0.1',
                                    **self.vo)
        assert result is not None

        del_account_identity(INVALID_PADDED_PUBLIC_KEY, IdentityType.SSH, root)
示例#4
0
    def test_ssh_fail(self):
        """AUTHENTICATION (REST): SSH RSA public key exchange (wrong credentials)."""

        root = InternalAccount('root', **self.vo)
        try:
            add_account_identity(PUBLIC_KEY,
                                 IdentityType.SSH,
                                 root,
                                 email='*****@*****.**')
        except Duplicate:
            pass  # might already exist, can skip

        signature = ssh_sign(PRIVATE_KEY, 'sign_something_else')

        options = []
        headers = {
            'X-Rucio-Account': 'root',
            'X-Rucio-SSH-Signature': signature
        }
        headers.update(self.vo_header)
        result = TestApp(APP.wsgifunc(*options)).get('/ssh',
                                                     headers=headers,
                                                     expect_errors=True)
        assert result.status == 401

        del_account_identity(PUBLIC_KEY, IdentityType.SSH, root)
示例#5
0
    def test_ssh_success(self):
        """AUTHENTICATION (REST): SSH RSA public key exchange (correct credentials)."""

        try:
            add_account_identity(PUBLIC_KEY,
                                 IdentityType.SSH,
                                 'root',
                                 email='*****@*****.**')
        except Duplicate:
            pass  # might already exist, can skip

        options = []
        headers = {'X-Rucio-Account': 'root'}
        result = TestApp(APP.wsgifunc(*options)).get('/ssh_challenge_token',
                                                     headers=headers,
                                                     expect_errors=True)
        assert_equal(result.status, 200)
        assert_in('challenge-', result.header('X-Rucio-SSH-Challenge-Token'))

        signature = ssh_sign(PRIVATE_KEY,
                             result.header('X-Rucio-SSH-Challenge-Token'))

        headers = {
            'X-Rucio-Account': 'root',
            'X-Rucio-SSH-Signature': signature
        }
        result = TestApp(APP.wsgifunc(*options)).get('/ssh',
                                                     headers=headers,
                                                     expect_errors=True)
        assert_equal(result.status, 200)
        assert_greater(len(result.header('X-Rucio-Auth-Token')), 32)

        del_account_identity(PUBLIC_KEY, IdentityType.SSH, 'root')
示例#6
0
    def test_auth_ssh(self):
        """ MULTI VO (REST): Test ssh authentication to multiple VOs """
        mw = []

        try:
            add_account_identity(PUBLIC_KEY, 'SSH', 'root', '*****@*****.**', 'root', **self.vo)
            add_account_identity(PUBLIC_KEY, 'SSH', 'root', '*****@*****.**', 'root', **self.new_vo)
        except Duplicate:
            pass  # Might already exist, can skip

        headers_tst = {'X-Rucio-Account': 'root'}
        headers_tst.update(self.vo_header)
        res_tst = TestApp(auth_app.wsgifunc(*mw)).get('/ssh_challenge_token', headers=headers_tst, expect_errors=True)
        assert_equal(res_tst.status, 200)
        challenge_tst = str(res_tst.header('X-Rucio-SSH-Challenge-Token'))
        headers_tst.update({'X-Rucio-SSH-Signature': ssh_sign(PRIVATE_KEY, challenge_tst)})
        res_tst = TestApp(auth_app.wsgifunc(*mw)).get('/ssh', headers=headers_tst, expect_errors=True)
        assert_equal(res_tst.status, 200)
        token_tst = str(res_tst.header('X-Rucio-Auth-Token'))

        headers_new = {'X-Rucio-Account': 'root'}
        headers_new.update(self.new_header)
        res_new = TestApp(auth_app.wsgifunc(*mw)).get('/ssh_challenge_token', headers=headers_new, expect_errors=True)
        assert_equal(res_new.status, 200)
        challenge_tst = str(res_new.header('X-Rucio-SSH-Challenge-Token'))
        headers_new.update({'X-Rucio-SSH-Signature': ssh_sign(PRIVATE_KEY, challenge_tst)})
        res_new = TestApp(auth_app.wsgifunc(*mw)).get('/ssh', headers=headers_new, expect_errors=True)
        assert_equal(res_new.status, 200)
        token_new = str(res_new.header('X-Rucio-Auth-Token'))

        headers_tst = {'X-Rucio-Auth-Token': str(token_tst)}
        res_tst = TestApp(account_app.wsgifunc(*mw)).get('/', headers=headers_tst, expect_errors=True)
        assert_equal(res_tst.status, 200)
        accounts_tst = [parse_response(a)['account'] for a in res_tst.body.decode().split('\n')[:-1]]
        assert_not_equal(len(accounts_tst), 0)
        assert_in(self.account_tst, accounts_tst)
        assert_not_in(self.account_new, accounts_tst)

        headers_new = {'X-Rucio-Auth-Token': str(token_new)}
        res_new = TestApp(account_app.wsgifunc(*mw)).get('/', headers=headers_new, expect_errors=True)
        assert_equal(res_new.status, 200)
        accounts_new = [parse_response(a)['account'] for a in res_new.body.decode().split('\n')[:-1]]
        assert_not_equal(len(accounts_new), 0)
        assert_in(self.account_new, accounts_new)
        assert_not_in(self.account_tst, accounts_new)
示例#7
0
    def __get_token_ssh(self):
        """
        Sends a request to get an auth token from the server and stores it as a class attribute. Uses SSH key exchange authentication.

        :returns: True if the token was successfully received. False otherwise.
        """
        headers = {}

        private_key_path = self.creds['ssh_private_key']
        if not path.exists(private_key_path):
            self.logger.error('given private key (%s) doesn\'t exist' % private_key_path)
            return False
        if private_key_path is not None and not path.exists(private_key_path):
            self.logger.error('given private key (%s) doesn\'t exist' % private_key_path)
            return False

        url = build_url(self.auth_host, path='auth/ssh_challenge_token')

        result = self._send_request(url, get_token=True)

        if not result:
            self.logger.error('cannot get ssh_challenge_token')
            return False

        if result.status_code != codes.ok:   # pylint: disable-msg=E1101
            exc_cls, exc_msg = self._get_exception(headers=result.headers,
                                                   status_code=result.status_code,
                                                   data=result.content)
            raise exc_cls(exc_msg)

        self.ssh_challenge_token = result.headers['x-rucio-ssh-challenge-token']
        self.logger.debug('got new ssh challenge token \'%s\'' % self.ssh_challenge_token)

        # sign the challenge token with the private key
        with open(private_key_path, 'r') as fd_private_key_path:
            private_key = fd_private_key_path.read()
            signature = ssh_sign(private_key, self.ssh_challenge_token)
            headers['X-Rucio-SSH-Signature'] = signature

        url = build_url(self.auth_host, path='auth/ssh')

        result = self._send_request(url, headers=headers, get_token=True)

        if not result:
            self.logger.error('Cannot retrieve authentication token!')
            return False

        if result.status_code != codes.ok:   # pylint: disable-msg=E1101
            exc_cls, exc_msg = self._get_exception(headers=result.headers,
                                                   status_code=result.status_code,
                                                   data=result.content)
            raise exc_cls(exc_msg)

        self.auth_token = result.headers['x-rucio-auth-token']
        return True
示例#8
0
    def test_get_auth_token_ssh_fail(self):
        """AUTHENTICATION (CORE): SSH RSA public key exchange (wrong signature)."""

        root = InternalAccount('root', **self.vo)
        try:
            add_account_identity(PUBLIC_KEY, IdentityType.SSH, root, email='*****@*****.**')
        except Duplicate:
            pass  # might already exist, can skip

        signature = ssh_sign(PRIVATE_KEY, 'sign_something_else')

        result = get_auth_token_ssh(account='root', signature=signature, appid='test', ip='127.0.0.1', **self.vo)

        assert_is_none(result)

        del_account_identity(PUBLIC_KEY, IdentityType.SSH, root)
示例#9
0
def test_ssh_fail(vo, rest_client):
    """AUTHENTICATION (REST): SSH RSA public key exchange (wrong credentials)."""

    root = InternalAccount('root', vo=vo)
    try:
        add_account_identity(PUBLIC_KEY,
                             IdentityType.SSH,
                             root,
                             email='*****@*****.**')
    except Duplicate:
        pass  # might already exist, can skip

    signature = ssh_sign(PRIVATE_KEY, 'sign_something_else')

    headers_dict = {
        'X-Rucio-Account': 'root',
        'X-Rucio-SSH-Signature': signature
    }
    response = rest_client.get('/auth/ssh',
                               headers=headers(hdrdict(headers_dict),
                                               vohdr(vo)))
    assert response.status_code == 401

    del_account_identity(PUBLIC_KEY, IdentityType.SSH, root)
示例#10
0
    def test_ssh_success(self):
        """AUTHENTICATION (REST): SSH RSA public key exchange (correct credentials)."""

        root = InternalAccount('root', **self.vo)
        try:
            add_account_identity(PUBLIC_KEY,
                                 IdentityType.SSH,
                                 root,
                                 email='*****@*****.**')
        except Duplicate:
            pass  # might already exist, can skip

        options = []
        headers = {'X-Rucio-Account': 'root'}
        headers.update(self.vo_header)
        result = TestApp(APP.wsgifunc(*options)).get('/ssh_challenge_token',
                                                     headers=headers,
                                                     expect_errors=True)
        assert result.status == 200
        assert 'challenge-' in result.header('X-Rucio-SSH-Challenge-Token')

        signature = ssh_sign(PRIVATE_KEY,
                             result.header('X-Rucio-SSH-Challenge-Token'))

        headers = {
            'X-Rucio-Account': 'root',
            'X-Rucio-SSH-Signature': signature
        }
        headers.update(self.vo_header)
        result = TestApp(APP.wsgifunc(*options)).get('/ssh',
                                                     headers=headers,
                                                     expect_errors=True)
        assert result.status == 200
        assert len(result.header('X-Rucio-Auth-Token')) > 32

        del_account_identity(PUBLIC_KEY, IdentityType.SSH, root)
示例#11
0
    def __get_token_ssh(self):
        """
        Sends a request to get an auth token from the server and stores it as a class attribute. Uses SSH key exchange authentication.

        :returns: True if the token was successfully received. False otherwise.
        """
        headers = {'X-Rucio-Account': self.account}

        private_key_path = self.creds['ssh_private_key']
        if not path.exists(private_key_path):
            LOG.error('given private key (%s) doesn\'t exist' %
                      private_key_path)
            return False
        if private_key_path is not None and not path.exists(private_key_path):
            LOG.error('given private key (%s) doesn\'t exist' %
                      private_key_path)
            return False

        url = build_url(self.auth_host, path='auth/ssh_challenge_token')

        result = None
        for retry in range(self.AUTH_RETRIES + 1):
            try:
                result = self.session.get(url,
                                          headers=headers,
                                          verify=self.ca_cert)
                break
            except ConnectionError as error:
                if 'alert certificate expired' in str(error):
                    raise CannotAuthenticate(str(error))
                LOG.warning('ConnectionError: ' + str(error))
                self.ca_cert = False
                if retry > self.request_retries:
                    raise

        if not result:
            LOG.error('cannot get ssh_challenge_token')
            return False

        if result.status_code != codes.ok:  # pylint: disable-msg=E1101
            exc_cls, exc_msg = self._get_exception(
                headers=result.headers,
                status_code=result.status_code,
                data=result.content)
            raise exc_cls(exc_msg)

        self.ssh_challenge_token = result.headers[
            'x-rucio-ssh-challenge-token']
        LOG.debug('got new ssh challenge token \'%s\'' %
                  self.ssh_challenge_token)

        # sign the challenge token with the private key
        with open(private_key_path, 'r') as fd_private_key_path:
            private_key = fd_private_key_path.read()
            signature = ssh_sign(private_key, self.ssh_challenge_token)
            headers['X-Rucio-SSH-Signature'] = signature

        url = build_url(self.auth_host, path='auth/ssh')

        result = None
        for retry in range(self.AUTH_RETRIES + 1):
            try:
                result = self.session.get(url,
                                          headers=headers,
                                          verify=self.ca_cert)
                break
            except ConnectionError as error:
                if 'alert certificate expired' in str(error):
                    raise CannotAuthenticate(str(error))
                LOG.warning('ConnectionError: ' + str(error))
                self.ca_cert = False
                if retry > self.request_retries:
                    raise

        if not result:
            LOG.error('cannot get auth_token')
            return False

        if result.status_code != codes.ok:  # pylint: disable-msg=E1101
            exc_cls, exc_msg = self._get_exception(
                headers=result.headers,
                status_code=result.status_code,
                data=result.content)
            raise exc_cls(exc_msg)

        self.auth_token = result.headers['x-rucio-auth-token']
        LOG.debug('got new token')
        return True