barneygale / quarry

Python library that implements the Minecraft network protocol and data types
Other
527 stars 75 forks source link

Error when trying to login with Microsoft on 1.19 #164

Closed Lilyp3892 closed 2 years ago

Lilyp3892 commented 2 years ago

Using this method to login (which works on 1.18.2) and is now giving me this error on 1.19: Unhandled Error Traceback (most recent call last): File "C:\Users\USER\AppData\Local\Programs\Python\Python38-32\lib\site-packages\twisted\python\log.py", line 96, in callWithLogger return callWithContext({"system": lp}, func, *args, **kw) File "C:\Users\USER\AppData\Local\Programs\Python\Python38-32\lib\site-packages\twisted\python\log.py", line 80, in callWithContext return context.call({ILogContext: newCtx}, func, *args, **kw) File "C:\Users\USER\AppData\Local\Programs\Python\Python38-32\lib\site-packages\twisted\python\context.py", line 117, in callWithContext return self.currentContext().callWithContext(ctx, func, *args, **kw) File "C:\Users\USER\AppData\Local\Programs\Python\Python38-32\lib\site-packages\twisted\python\context.py", line 82, in callWithContext return func(*args, **kw) --- <exception caught here> --- File "C:\Users\USER\AppData\Local\Programs\Python\Python38-32\lib\site-packages\twisted\internet\selectreactor.py", line 148, in _doReadOrWrite why = getattr(selectable, method)() File "C:\Users\USER\AppData\Local\Programs\Python\Python38-32\lib\site-packages\twisted\internet\tcp.py", line 248, in doRead return self._dataReceived(data) File "C:\Users\USER\AppData\Local\Programs\Python\Python38-32\lib\site-packages\twisted\internet\tcp.py", line 253, in _dataReceived rval = self.protocol.dataReceived(data) File "C:\Users\USER\AppData\Local\Programs\Python\Python38-32\lib\site-packages\quarry\net\protocol.py", line 84, in dataReceived return self.data_received(data) File "C:\Users\USER\AppData\Local\Programs\Python\Python38-32\lib\site-packages\quarry\net\protocol.py", line 245, in data_received self.packet_received(buff, name) File "C:\Users\USER\AppData\Local\Programs\Python\Python38-32\lib\site-packages\quarry\net\protocol.py", line 267, in packet_received dispatched = self.dispatch((name,), buff) File "C:\Users\USER\AppData\Local\Programs\Python\Python38-32\lib\site-packages\quarry\net\protocol.py", line 26, in dispatch handler(buff) File "nbt_view_proxy.py", line 86, in packet_login_encryption_response verify_token = crypto.decrypt_secret( File "C:\Users\USER\AppData\Local\Programs\Python\Python38-32\lib\site-packages\quarry\net\crypto.py", line 102, in decrypt_secret return keypair.decrypt( File "C:\Users\USER\AppData\Local\Programs\Python\Python38-32\lib\site-packages\cryptography\hazmat\backends\openssl\rsa.py", line 422, in decrypt raise ValueError("Ciphertext length must be equal to key size.") builtins.ValueError: Ciphertext length must be equal to key size.

and this is the code I'm using

class MyUpstream(Upstream): def packet_login_encryption_request(self, buff): p_server_id = buff.unpack_string()

    # 1.7.x
    if self.protocol_version <= 5:
        def unpack_array(b): return b.read(b.unpack('h'))
    # 1.8.x
    else:
        def unpack_array(b): return b.read(b.unpack_varint(max_bits=16))

    p_public_key = unpack_array(buff)
    p_verify_token = unpack_array(buff)

    if not self.factory.profile.online:
        raise ProtocolError("Can't log into online-mode server while using"
                            " offline profile")

    self.shared_secret = crypto.make_shared_secret()
    self.public_key = crypto.import_public_key(p_public_key)
    self.verify_token = p_verify_token

    # make digest
    digest = crypto.make_digest(
        p_server_id.encode('ascii'),
        self.shared_secret,
        p_public_key)

    # do auth
    # deferred = self.factory.profile.join(digest)
    # deferred.addCallbacks(self.auth_ok, self.auth_failed)

    url = "https://sessionserver.mojang.com/session/minecraft/join"

    payload = json.dumps({
        "accessToken": self.factory.profile.access_token,
        "selectedProfile": self.factory.profile.uuid.to_hex(False),
        "serverId": digest
    })
    headers = {
        'Content-Type': 'application/json'
    }

    r = requests.request(
        "POST", "https://sessionserver.mojang.com/session/minecraft/join", headers=headers, data=payload)

    if r.status_code == 204:
        self.auth_ok(r.text)
    else:
        self.auth_failed(failure.Failure(
            auth.AuthException('unverified', 'unverified username')))

class MyDownstream(Downstream): def packet_login_encryption_response(self, buff): if self.login_expecting != 1: raise ProtocolError("Out-of-order login")

    # 1.7.x
    if self.protocol_version <= 5:
        def unpack_array(b): return b.read(b.unpack('h'))
    # 1.8.x
    else:
        def unpack_array(b): return b.read(b.unpack_varint(max_bits=16))

    p_shared_secret = unpack_array(buff)
    p_verify_token = unpack_array(buff)

    shared_secret = crypto.decrypt_secret(
        self.factory.keypair,
        p_shared_secret)

    verify_token = crypto.decrypt_secret(
        self.factory.keypair,
        p_verify_token)

    self.login_expecting = None

    if verify_token != self.verify_token:
        raise ProtocolError("Verify token incorrect")

    # enable encryption
    self.cipher.enable(shared_secret)
    self.logger.debug("Encryption enabled")

    # make digest
    digest = crypto.make_digest(
        self.server_id.encode('ascii'),
        shared_secret,
        self.factory.public_key)

    # do auth
    remote_host = None
    if self.factory.prevent_proxy_connections:
        remote_host = self.remote_addr.host

    # deferred = auth.has_joined(
    #     self.factory.auth_timeout,
    #     digest,
    #     self.display_name,
    #     remote_host)
    # deferred.addCallbacks(self.auth_ok, self.auth_failed)

    r = requests.get('https://sessionserver.mojang.com/session/minecraft/hasJoined',
                     params={'username': self.display_name, 'serverId': digest, 'ip': remote_host})

    if r.status_code == 200:
        self.auth_ok(r.json())
    else:
        self.auth_failed(failure.Failure(
            auth.AuthException('invalid', 'invalid session'))

Sorry that wouldn't format for some reason, but the code fails at:

verify_token = crypto.decrypt_secret( self.factory.keypair, p_verify_token)

The code runs but it only fails after I try to join a 1.19 server. If I try to join a 1.18.2 server however it works fine. And I have updated Quarry with the 1.19 additions

If anyone can help me out here it would be much appreciated, sorry if I'm just being dumb

Edit: anything not in bold is code

Lilyp3892 commented 2 years ago

Solved in #135