示例#1
0
 def do_fetch():
   # client_secret is not really a secret in that case. So an attacker can
   # impersonate service's identity in OAuth2 flow. But that's generally
   # fine as long as a list of allowed redirect_uri's associated with client_id
   # is limited to 'localhost' or 'urn:ietf:wg:oauth:2.0:oob'. In that case
   # attacker needs some process running on user's machine to successfully
   # complete the flow and grab access_token. When you have malicious code
   # running on your machine you're screwed anyway.
   response = requests.get(
       '%s/auth/api/v1/server/oauth_config' % urlhost.rstrip('/'),
       verify=tools.get_cacerts_bundle())
   if response.status_code == 200:
     try:
       config = response.json()
       if not isinstance(config, dict):
         raise ValueError()
       return _ServiceConfig(
           config['client_id'],
           config['client_not_so_secret'],
           config.get('primary_url'))
     except (KeyError, ValueError) as err:
       logging.error('Invalid response from the service: %s', err)
   else:
     logging.warning(
         'Error when fetching oauth_config, HTTP status code %d',
         response.status_code)
   return None
示例#2
0
    def test_http_level_errors(self):
        def token_gen(_account_id, _scopes):
            self.fail('must not be called')

        with local_auth_server(token_gen, 'acc_1'):
            # Wrong URL.
            ctx = luci_context.read('local_auth')
            r = requests.post(
                url=
                'http://127.0.0.1:%d/blah/LuciLocalAuthService.GetOAuthToken' %
                ctx['rpc_port'],
                data=json.dumps({
                    'account_id': 'acc_1',
                    'scopes': ['A', 'B', 'C'],
                    'secret': ctx['secret'],
                }),
                headers={'Content-Type': 'application/json'})
            self.assertEqual(404, r.status_code)

            # Wrong HTTP method.
            r = requests.get(
                url='http://127.0.0.1:%d/rpc/LuciLocalAuthService.GetOAuthToken'
                % ctx['rpc_port'],
                data=json.dumps({
                    'account_id': 'acc_1',
                    'scopes': ['A', 'B', 'C'],
                    'secret': ctx['secret'],
                }),
                headers={'Content-Type': 'application/json'})
            self.assertEqual(501, r.status_code)

            # Wrong content type.
            r = requests.post(
                url='http://127.0.0.1:%d/rpc/LuciLocalAuthService.GetOAuthToken'
                % ctx['rpc_port'],
                data=json.dumps({
                    'account_id': 'acc_1',
                    'scopes': ['A', 'B', 'C'],
                    'secret': ctx['secret'],
                }),
                headers={'Content-Type': 'application/xml'})
            self.assertEqual(400, r.status_code)

            # Bad JSON.
            r = requests.post(
                url='http://127.0.0.1:%d/rpc/LuciLocalAuthService.GetOAuthToken'
                % ctx['rpc_port'],
                data='not a json',
                headers={'Content-Type': 'application/json'})
            self.assertEqual(400, r.status_code)
示例#3
0
def _fetch_oauth_client_id(urlhost):
    """Ask service to for client_id and client_secret to use."""
    # client_secret is not really a secret in that case. So an attacker can
    # impersonate service's identity in OAuth2 flow. But that's generally
    # fine as long as a list of allowed redirect_uri's associated with client_id
    # is limited to 'localhost' or 'urn:ietf:wg:oauth:2.0:oob'. In that case
    # attacker needs some process running on user's machine to successfully
    # complete the flow and grab access_token. When you have malicious code
    # running on your machine your screwed anyway.
    response = requests.get("%s/auth/api/v1/server/oauth_config" % urlhost.rstrip("/"))
    if response.status_code == 200:
        try:
            config = response.json()
            if not isinstance(config, dict):
                raise ValueError()
            return config["client_id"], config["client_not_so_secret"]
        except (KeyError, ValueError) as err:
            logging.error("Invalid response from the service: %s", err)
    else:
        logging.error("Error when fetching oauth_config, HTTP status code %d", response.status_code)
    return None, None