From e3999c4906348dadcc85eec1df9a48e776deccd5 Mon Sep 17 00:00:00 2001 From: "Kali Kaneko (leap communications)" Date: Thu, 23 Feb 2017 00:35:33 +0100 Subject: [feature] require authentication token for api implements a global auth token for the app. this token is written to .config/leap/authtoken, and passed to the anchor part of the landing URI when opening the index resource by the browser. - Resolves: #8765 --- src/leap/bitmask/core/web/_auth.py | 7 ++++--- src/leap/bitmask/core/web/api.py | 11 ++++++++++- src/leap/bitmask/core/web/service.py | 20 ++++++-------------- 3 files changed, 20 insertions(+), 18 deletions(-) (limited to 'src/leap/bitmask/core/web') diff --git a/src/leap/bitmask/core/web/_auth.py b/src/leap/bitmask/core/web/_auth.py index 2747fae8..aa6aeb9b 100644 --- a/src/leap/bitmask/core/web/_auth.py +++ b/src/leap/bitmask/core/web/_auth.py @@ -6,6 +6,7 @@ from twisted.web.guard import HTTPAuthSessionWrapper, BasicCredentialFactory from twisted.web.resource import IResource +# Deprecate if the user-session tokens are finally not used. class TokenCredentialFactory(BasicCredentialFactory): scheme = 'token' @@ -37,11 +38,11 @@ class WhitelistHTTPAuthSessionWrapper(HTTPAuthSessionWrapper): return HTTPAuthSessionWrapper.render(self, request) -def protectedResourceFactory(resource, session_tokens, whitelist): +def protectedResourceFactory(resource, tokens, whitelist): realm = HttpPasswordRealm(resource) - checker = TokenDictChecker(session_tokens) - resource_portal = portal.Portal(realm, [checker]) + checker = TokenDictChecker(tokens) credentialFactory = TokenCredentialFactory('localhost') + resource_portal = portal.Portal(realm, [checker]) protected_resource = WhitelistHTTPAuthSessionWrapper( resource_portal, [credentialFactory], whitelist=whitelist) diff --git a/src/leap/bitmask/core/web/api.py b/src/leap/bitmask/core/web/api.py index d31afa50..01c65bae 100644 --- a/src/leap/bitmask/core/web/api.py +++ b/src/leap/bitmask/core/web/api.py @@ -11,11 +11,20 @@ class Api(Resource): isLeaf = True - def __init__(self, dispatcher): + def __init__(self, dispatcher, global_tokens): Resource.__init__(self) self.dispatcher = dispatcher + self.global_tokens = global_tokens def render_POST(self, request): + token = request.getHeader('x-bitmask-auth') + if not token: + request.setResponseCode(401) + return 'unauthorized: no app token' + elif token.strip() not in self.global_tokens: + request.setResponseCode(401) + return 'unauthorized: bad app token' + command = request.uri.split('/')[2:] params = request.content.getvalue() if params: diff --git a/src/leap/bitmask/core/web/service.py b/src/leap/bitmask/core/web/service.py index c1d839e8..2b8a7343 100644 --- a/src/leap/bitmask/core/web/service.py +++ b/src/leap/bitmask/core/web/service.py @@ -61,11 +61,6 @@ class HTTPDispatcherService(service.Service): API_WHITELIST = ( '/API/core/version', '/API/core/stats', - '/API/bonafide/user/create', - '/API/bonafide/user/authenticate', - '/API/bonafide/provider/list', - '/API/bonafide/provider/create', - '/API/bonafide/provider/read', ) def __init__(self, core, port=7070, debug=False, onion=False): @@ -76,7 +71,6 @@ class HTTPDispatcherService(service.Service): self.uri = '' def startService(self): - # TODO refactor this, too long---------------------------------------- if HAS_WEB_UI: webdir = os.path.abspath( pkg_resources.resource_filename('leap.bitmask_js', 'public')) @@ -91,18 +85,16 @@ class HTTPDispatcherService(service.Service): 'ui', 'app', 'lib', 'bitmask.js') jsapi = File(os.path.abspath(jspath)) - api = Api(CommandDispatcher(self._core)) - # protected_api = protectedResourceFactory( - # api, self._core.tokens, self.API_WHITELIST) + api = Api(CommandDispatcher(self._core), self._core.global_tokens) root = File(webdir) + root.putChild(u'API', api) - # FIXME -- switching off the protected api, due to - # https://0xacab.org/leap/bitmask-dev/issues/9 + # XXX remove it we don't bring session tokens again + # protected_api = protectedResourceFactory( + # api, self._core.global_tokens, self.API_WHITELIST) # root.putChild(u'API', protected_api) - # ------------------------------------------------- - root.putChild(u'API', api) if not HAS_WEB_UI: root.putChild('bitmask.js', jsapi) @@ -110,7 +102,7 @@ class HTTPDispatcherService(service.Service): self.site = factory if self.onion and _has_txtorcon(): - self._start_onion_service(factory) + self._start_onion_service(factory) else: interface = '127.0.0.1' endpoint = endpoints.TCP4ServerEndpoint( -- cgit v1.2.3