URI: 
       tMerge pull request #5787 from xaya/http-request-auth - electrum - Electrum Bitcoin wallet
  HTML git clone https://git.parazyd.org/electrum
   DIR Log
   DIR Files
   DIR Refs
   DIR Submodules
       ---
   DIR commit d5b27e5be1711aa6a0c883929d92e11a344153de
   DIR parent 6b195437ed191db0cfde67a364280982b47143bf
  HTML 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:
         M electrum/daemon.py                  |      17 +++++++++++++----
       
       1 file changed, 13 insertions(+), 4 deletions(-)
       ---
   DIR diff --git a/electrum/daemon.py b/electrum/daemon.py
       t@@ -259,6 +259,12 @@ class PayServer(Logger):
        class AuthenticationError(Exception):
            pass
        
       +class AuthenticationInvalidOrMissing(AuthenticationError):
       +    pass
       +
       +class AuthenticationCredentialsInvalid(AuthenticationError):
       +    pass
       +
        class Daemon(Logger):
        
            @profiler
       t@@ -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)