commit d5b27e5be1711aa6a0c883929d92e11a344153de
parent 6b195437ed191db0cfde67a364280982b47143bf
Author: ghost43 <somber.night@protonmail.com>
Date: Thu, 21 Nov 2019 15:21:17 +0000
Merge pull request #5787 from xaya/http-request-auth
Return 401 from RPC server for missing auth
Diffstat:
1 file changed, 13 insertions(+), 4 deletions(-)
diff --git a/electrum/daemon.py b/electrum/daemon.py
@@ -259,6 +259,12 @@ class PayServer(Logger):
class AuthenticationError(Exception):
pass
+class AuthenticationInvalidOrMissing(AuthenticationError):
+ pass
+
+class AuthenticationCredentialsInvalid(AuthenticationError):
+ pass
+
class Daemon(Logger):
@profiler
@@ -302,23 +308,26 @@ class Daemon(Logger):
return
auth_string = headers.get('Authorization', None)
if auth_string is None:
- raise AuthenticationError('CredentialsMissing')
+ raise AuthenticationInvalidOrMissing('CredentialsMissing')
basic, _, encoded = auth_string.partition(' ')
if basic != 'Basic':
- raise AuthenticationError('UnsupportedType')
+ raise AuthenticationInvalidOrMissing('UnsupportedType')
encoded = to_bytes(encoded, 'utf8')
credentials = to_string(b64decode(encoded), 'utf8')
username, _, password = credentials.partition(':')
if not (constant_time_compare(username, self.rpc_user)
and constant_time_compare(password, self.rpc_password)):
await asyncio.sleep(0.050)
- raise AuthenticationError('Invalid Credentials')
+ raise AuthenticationCredentialsInvalid('Invalid Credentials')
async def handle(self, request):
async with self.auth_lock:
try:
await self.authenticate(request.headers)
- except AuthenticationError:
+ except AuthenticationInvalidOrMissing:
+ return web.Response(headers={"WWW-Authenticate": "Basic realm=Electrum"},
+ text='Unauthorized', status=401)
+ except AuthenticationCredentialsInvalid:
return web.Response(text='Forbidden', status=403)
request = await request.text()
response = await jsonrpcserver.async_dispatch(request, methods=self.methods)