quarry
quarry copied to clipboard
how do i set up my quarry proxy for online mode servers?
there dosn't seems to any support for microsoft accounts and require a mojang account. consider looking at #123
damn, alr then, thanks man
I got a work around solution. It fixed #132, #123, and https://github.com/LiveOverflow/minecraft-hacked/issues/1.
The reason why online mode is not supported is because of the Auth failed
issue and the Microsoft Login
issue. And here's the explanation:
About the Auth failed
issue
The error message should look like this: Auth failed: [<twisted.python.failure.Failure OpenSSL.SSL.Error: [('SSL routines', 'tls_process_server_certificate', 'certificate verify failed')]>]
Here is a discussion on Stackoverflow: https://stackoverflow.com/questions/33602478/how-to-handle-openssl-ssl-error-while-using-twisted-web-client-agent-on-facebook.
It is a problem related to Twisted, OpenSSL and trust roots configuration 10 years ago. This is one of the reasons why it only works on Linux. To fix this, all you have to do is run the python file via the command SSL_CERT_FILE="$(python -m certifi)" python xxx.py
on Git Bash. You don't need to install WSL if you're using Windows.
About the Microsoft Login
issue
Microsoft made the login process too complicated. I don't think it is possible to login to the account in command line enviroment.
However, you don't have to login or provide your user name and password in the command line. I first go to minecraft.net, then press F12
key to open my developer console. Type JavaScript to get my Minecraft bearer token. Finally paste the token in the code so I can get access to the account. You can follow the instructions on https://kqzz.github.io/mc-bearer-token/
Here is a full example. Oh, btw my example also fixed the Auth failed
issue by using requests
library. That's mean you don't even have to use Git Bash. Enjoy! :)
import json
from xmlrpc.client import ProtocolError
import requests
from twisted.python import failure
from twisted.internet import reactor
from quarry.types.uuid import UUID
from quarry.net.proxy import UpstreamFactory, Upstream, DownstreamFactory, Downstream, Bridge
from quarry.net import auth, crypto
from twisted.internet import reactor
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')))
class MyUpstreamFactory(UpstreamFactory):
protocol = MyUpstream
connection_timeout = 10
class MyBridge(Bridge):
upstream_factory_class = MyUpstreamFactory
def make_profile(self):
"""
Support online mode
"""
# follow: https://kqzz.github.io/mc-bearer-token/
accessToken = '<YOUR TOKEN>'
url = "https://api.minecraftservices.com/minecraft/profile"
headers = {'Authorization': 'Bearer ' + accessToken}
response = requests.request("GET", url, headers=headers)
result = response.json()
myUuid = UUID.from_hex(result['id'])
myUsername = result['name']
return auth.Profile('(skip)', accessToken, myUsername, myUuid)
class MyDownstreamFactory(DownstreamFactory):
protocol = MyDownstream
bridge_class = MyBridge
motd = "Proxy Server"
def main(argv):
# Parse options
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("-a1", "--listen-host1", default="",
help="address to listen on")
parser.add_argument("-p1", "--listen-port1", default=25566,
type=int, help="port to listen on")
parser.add_argument("-b", "--connect-host",
default="127.0.0.1", help="address to connect to")
parser.add_argument("-q", "--connect-port", default=25565,
type=int, help="port to connect to")
args = parser.parse_args(argv)
# Create factory
factory = MyDownstreamFactory()
factory.connect_host = args.connect_host
factory.connect_port = args.connect_port
# Listen
factory.listen(args.listen_host1, args.listen_port1)
reactor.run()
if __name__ == "__main__":
import sys
main(sys.argv[1:])
the code works amazingly, thanks for the help @Jerrylum
It doesn't work for some reason.. it just says connection refused
and yes.. i did paste in my token
Same here, I'm getting connection timed out
Also, if I use the 1st method, using linux.. it just says: Auth failed: [<twisted.python.failure.Failure twisted.internet._sslverify.SimpleVerificationError: 'mojang.com'!='sessionserver.mojang.com'>]
Also, if I use the 1st method, using linux.. it just says: Auth failed: [<twisted.python.failure.Failure twisted.internet._sslverify.SimpleVerificationError: 'mojang.com'!='sessionserver.mojang.com'>]
You'll need to set up your trust root certificates (Usually they're certificates issued by trusted entities that are preinstalled on systems that verify other certificates). For example, I'm on macOS and the Twisted library isn't able to read the system trust root certs. So for me to patch it, I extracted the location of the trust root certificates offered by the python package certifi and set an environment variable so that Twisted can find it. My command to run the proxy server looks like this:
SSL_CERT_FILE="/Users/MY_USERNAME/homebrew/lib/python3.9/site-packages/certifi/cacert.pem" python3 ./src/proxy.py -b 2b2t.org
Also, if I use the 1st method, using linux.. it just says: Auth failed: [<twisted.python.failure.Failure twisted.internet._sslverify.SimpleVerificationError: 'mojang.com'!='sessionserver.mojang.com'>]
You'll need to set up your trust root certificates (Usually they're certificates issued by trusted entities that are preinstalled on systems that verify other certificates). For example, I'm on macOS and the Twisted library isn't able to read the system trust root certs. So for me to patch it, I extracted the location of the trust root certificates offered by the python package certifi and set an environment variable so that Twisted can find it. My command to run the proxy server looks like this:
SSL_CERT_FILE="/Users/MY_USERNAME/homebrew/lib/python3.9/site-packages/certifi/cacert.pem" python3 ./src/proxy.py -b 2b2t.org
Yes I've done SSL_CERT_FILE="$(python -m certifi)" but it still says the same error.. the cert if offered by certifi
Also, if I use the 1st method, using linux.. it just says: Auth failed: [<twisted.python.failure.Failure twisted.internet._sslverify.SimpleVerificationError: 'mojang.com'!='sessionserver.mojang.com'>]
You'll need to set up your trust root certificates (Usually they're certificates issued by trusted entities that are preinstalled on systems that verify other certificates). For example, I'm on macOS and the Twisted library isn't able to read the system trust root certs. So for me to patch it, I extracted the location of the trust root certificates offered by the python package certifi and set an environment variable so that Twisted can find it. My command to run the proxy server looks like this:
SSL_CERT_FILE="/Users/MY_USERNAME/homebrew/lib/python3.9/site-packages/certifi/cacert.pem" python3 ./src/proxy.py -b 2b2t.org
Yes I've done SSL_CERT_FILE="$(python -m certifi)" but it still says the same error.. the cert if offered by certifi
Hmmm, I'd have no idea then
That's really interesting. I ran my code on my MacBook and PC and it was complety fine.
About the first method you tried before @3arthquake3, I understand the situation. In this case, I think my code is the only workaround right now since the SSL problem is too complicated.
Also, you said It doesn't work for some reason.
I would like to know what doesn't work? Why it is connection refused? Would you please execute my code without any modification and tell me what you got?
About the connection timed out problem @robigan, I don't quite understand what's going on. So maybe you can give us more details.
@Jerrylum See the issue I just mentioned over at https://github.com/LiveOverflow/minecraft-hacked/issues/6 for more details on the logs of my connection. But basically I am stuck in the Log In phase as shown in the MC client. Also, if you don't mind, could you explain in a bit more detail how you patch connecting to online servers via the proxy?
That's really interesting. I ran my code on my MacBook and PC and it was complety fine.
About the first method you tried before @3arthquake3, I understand the situation. In this case, I think my code is the only workaround right now since the SSL problem is too complicated.
Also, you said
It doesn't work for some reason.
I would like to know what doesn't work? Why it is connection refused? Would you please execute my code without any modification and tell me what you got?About the connection timed out problem @robigan, I don't quite understand what's going on. So maybe you can give us more details.
When I ran the code exactly, and connect to the proxy, it just says connection refused.. and if I try the first method, when i join, it just shows: encrypting then joining then it just freezes and eventually it would say connection time out
That's really interesting. I ran my code on my MacBook and PC and it was complety fine. About the first method you tried before @3arthquake3, I understand the situation. In this case, I think my code is the only workaround right now since the SSL problem is too complicated. Also, you said
It doesn't work for some reason.
I would like to know what doesn't work? Why it is connection refused? Would you please execute my code without any modification and tell me what you got? About the connection timed out problem @robigan, I don't quite understand what's going on. So maybe you can give us more details.When I ran the code exactly, and connect to the proxy, it just says connection refused.. and if I try the first method, when i join, it just shows: encrypting then joining then it just freezes and eventually it would say connection time out
Are you sure you have properly setup trust roots for your executable? Also, the timeout is caused because you're connecting to the wrong URL. Minecraft internally does some magic to via alternate methods to find the IP to connect to, I would recommend reading up on what Jerry had written on SRV records over at https://github.com/LiveOverflow/minecraft-hacked/issues/6
In my case despite setting the connection URL to 2b2t.org, the actual server is resolved to connect.2b2t.org via the use of SRV records, most likely what you're trying to connect to have the same setup.
That's really interesting. I ran my code on my MacBook and PC and it was complety fine. About the first method you tried before @3arthquake3, I understand the situation. In this case, I think my code is the only workaround right now since the SSL problem is too complicated. Also, you said
It doesn't work for some reason.
I would like to know what doesn't work? Why it is connection refused? Would you please execute my code without any modification and tell me what you got? About the connection timed out problem @robigan, I don't quite understand what's going on. So maybe you can give us more details.When I ran the code exactly, and connect to the proxy, it just says connection refused.. and if I try the first method, when i join, it just shows: encrypting then joining then it just freezes and eventually it would say connection time out
Are you sure you have properly setup trust roots for your executable? Also, the timeout is caused because you're connecting to the wrong URL. Minecraft internally does some magic to via alternate methods to find the IP to connect to, I would recommend reading up on what Jerry had written on SRV records over at LiveOverflow/minecraft-hacked#6
In my case despite setting the connection URL to 2b2t.org, the actual server is resolved to connect.2b2t.org via the use of SRV records, most likely what you're trying to connect to have the same setup.
Yes I took a look at it and tried it, it did fix the timeout problem but now it's saying I can't connect to an online server with an offline profile.. do you have any idea what it says that?
I got a work around solution. It fixed #132, #123, and LiveOverflow/minecraft-hacked#1.
The reason why online mode is not supported is because of the
Auth failed
issue and theMicrosoft Login
issue. And here's the explanation:About the
Auth failed
issueThe error message should look like this:
Auth failed: [<twisted.python.failure.Failure OpenSSL.SSL.Error: [('SSL routines', 'tls_process_server_certificate', 'certificate verify failed')]>]
Here is a discussion on Stackoverflow: https://stackoverflow.com/questions/33602478/how-to-handle-openssl-ssl-error-while-using-twisted-web-client-agent-on-facebook.
It is a problem related to Twisted, OpenSSL and trust roots configuration 10 years ago. This is one of the reasons why it only works on Linux. To fix this, all you have to do is run the python file via the command
SSL_CERT_FILE="$(python -m certifi)" python xxx.py
on Git Bash. You don't need to install WSL if you're using Windows.About the
Microsoft Login
issueMicrosoft made the login process too complicated. I don't think it is possible to login to the account in command line enviroment.
However, you don't have to login or provide your user name and password in the command line. I first go to minecraft.net, then press
F12
key to open my developer console. Type JavaScript to get my Minecraft bearer token. Finally paste the token in the code so I can get access to the account. You can follow the instructions on https://kqzz.github.io/mc-bearer-token/Here is a full example. Oh, btw my example also fixed the
Auth failed
issue by usingrequests
library. That's mean you don't even have to use Git Bash. Enjoy! :)import json from xmlrpc.client import ProtocolError import requests from twisted.python import failure from twisted.internet import reactor from quarry.types.uuid import UUID from quarry.net.proxy import UpstreamFactory, Upstream, DownstreamFactory, Downstream, Bridge from quarry.net import auth, crypto from twisted.internet import reactor 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'))) class MyUpstreamFactory(UpstreamFactory): protocol = MyUpstream connection_timeout = 10 class MyBridge(Bridge): upstream_factory_class = MyUpstreamFactory def make_profile(self): """ Support online mode """ # follow: https://kqzz.github.io/mc-bearer-token/ accessToken = '<YOUR TOKEN>' url = "https://api.minecraftservices.com/minecraft/profile" headers = {'Authorization': 'Bearer ' + accessToken} response = requests.request("GET", url, headers=headers) result = response.json() myUuid = UUID.from_hex(result['id']) myUsername = result['name'] return auth.Profile('(skip)', accessToken, myUsername, myUuid) class MyDownstreamFactory(DownstreamFactory): protocol = MyDownstream bridge_class = MyBridge motd = "Proxy Server" def main(argv): # Parse options import argparse parser = argparse.ArgumentParser() parser.add_argument("-a1", "--listen-host1", default="", help="address to listen on") parser.add_argument("-p1", "--listen-port1", default=25566, type=int, help="port to listen on") parser.add_argument("-b", "--connect-host", default="127.0.0.1", help="address to connect to") parser.add_argument("-q", "--connect-port", default=25565, type=int, help="port to connect to") args = parser.parse_args(argv) # Create factory factory = MyDownstreamFactory() factory.connect_host = args.connect_host factory.connect_port = args.connect_port # Listen factory.listen(args.listen_host1, args.listen_port1) reactor.run() if __name__ == "__main__": import sys main(sys.argv[1:])
This code seems to break in 1.19 #164 @Jerrylum are you able to reproduce this issue?
Edit: Something to note: If you add print(p_verify_token)
just before line 85 (the line where it fails) you will see that with a 1.19 client it prints out b'' or a blank byte, which it does not do in 1.18.2, it instead in 1.18.2 it prints out a long byte like you would expect, so the problem seems to be with getting p_verify_token
I solved this. For anyone curious here's the code
import json
from xmlrpc.client import ProtocolError
import requests
from twisted.python import failure
from twisted.internet import reactor
from quarry.types.uuid import UUID
from quarry.net.proxy import UpstreamFactory, Upstream, DownstreamFactory, Downstream, Bridge
from quarry.net import auth, crypto
from twisted.internet import reactor
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)
buff.read()
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')))
class MyUpstreamFactory(UpstreamFactory):
protocol = MyUpstream
connection_timeout = 10
class MyBridge(Bridge):
upstream_factory_class = MyUpstreamFactory
def make_profile(self):
"""
Support online mode
"""
# follow: https://kqzz.github.io/mc-bearer-token/
accessToken = '<YOUR TOKEN>'
url = "https://api.minecraftservices.com/minecraft/profile"
headers = {'Authorization': 'Bearer ' + accessToken}
response = requests.request("GET", url, headers=headers)
result = response.json()
myUuid = UUID.from_hex(result['id'])
myUsername = result['name']
return auth.Profile('(skip)', accessToken, myUsername, myUuid)
class MyDownstreamFactory(DownstreamFactory):
protocol = MyDownstream
bridge_class = MyBridge
motd = "Proxy Server"
def main(argv):
# Parse options
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("-a", "--listen-host", default="0.0.0.0",
help="address to listen on")
parser.add_argument("-p", "--listen-port", default=25565,
type=int, help="port to listen on")
parser.add_argument("-b", "--connect-host",
default="127.0.0.1", help="address to connect to")
parser.add_argument("-q", "--connect-port", default=25565,
type=int, help="port to connect to")
args = parser.parse_args(argv)
# Create factory
factory = MyDownstreamFactory()
factory.connect_host = args.connect_host
factory.connect_port = args.connect_port
# Listen
factory.listen(args.listen_host, args.listen_port)
reactor.run()
if __name__ == "__main__":
import sys
main(sys.argv[1:])
I got a work around solution. It fixed #132, #123, and LiveOverflow/minecraft-hacked#1.
The reason why online mode is not supported is because of the
Auth failed
issue and theMicrosoft Login
issue. And here's the explanation:About the
Auth failed
issueThe error message should look like this:
Auth failed: [<twisted.python.failure.Failure OpenSSL.SSL.Error: [('SSL routines', 'tls_process_server_certificate', 'certificate verify failed')]>]
Here is a discussion on Stackoverflow: https://stackoverflow.com/questions/33602478/how-to-handle-openssl-ssl-error-while-using-twisted-web-client-agent-on-facebook.
It is a problem related to Twisted, OpenSSL and trust roots configuration 10 years ago. This is one of the reasons why it only works on Linux. To fix this, all you have to do is run the python file via the command
SSL_CERT_FILE="$(python -m certifi)" python xxx.py
on Git Bash. You don't need to install WSL if you're using Windows.About the
Microsoft Login
issueMicrosoft made the login process too complicated. I don't think it is possible to login to the account in command line enviroment.
However, you don't have to login or provide your user name and password in the command line. I first go to minecraft.net, then press
F12
key to open my developer console. Type JavaScript to get my Minecraft bearer token. Finally paste the token in the code so I can get access to the account. You can follow the instructions on https://kqzz.github.io/mc-bearer-token/Here is a full example. Oh, btw my example also fixed the
Auth failed
issue by usingrequests
library. That's mean you don't even have to use Git Bash. Enjoy! :)import json from xmlrpc.client import ProtocolError import requests from twisted.python import failure from twisted.internet import reactor from quarry.types.uuid import UUID from quarry.net.proxy import UpstreamFactory, Upstream, DownstreamFactory, Downstream, Bridge from quarry.net import auth, crypto from twisted.internet import reactor 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'))) class MyUpstreamFactory(UpstreamFactory): protocol = MyUpstream connection_timeout = 10 class MyBridge(Bridge): upstream_factory_class = MyUpstreamFactory def make_profile(self): """ Support online mode """ # follow: https://kqzz.github.io/mc-bearer-token/ accessToken = '<YOUR TOKEN>' url = "https://api.minecraftservices.com/minecraft/profile" headers = {'Authorization': 'Bearer ' + accessToken} response = requests.request("GET", url, headers=headers) result = response.json() myUuid = UUID.from_hex(result['id']) myUsername = result['name'] return auth.Profile('(skip)', accessToken, myUsername, myUuid) class MyDownstreamFactory(DownstreamFactory): protocol = MyDownstream bridge_class = MyBridge motd = "Proxy Server" def main(argv): # Parse options import argparse parser = argparse.ArgumentParser() parser.add_argument("-a1", "--listen-host1", default="", help="address to listen on") parser.add_argument("-p1", "--listen-port1", default=25566, type=int, help="port to listen on") parser.add_argument("-b", "--connect-host", default="127.0.0.1", help="address to connect to") parser.add_argument("-q", "--connect-port", default=25565, type=int, help="port to connect to") args = parser.parse_args(argv) # Create factory factory = MyDownstreamFactory() factory.connect_host = args.connect_host factory.connect_port = args.connect_port # Listen factory.listen(args.listen_host1, args.listen_port1) reactor.run() if __name__ == "__main__": import sys main(sys.argv[1:])
It gets stuck on "Joining world..." and then eventually times out for me.
I solved this. For anyone curious here's the code ...
This works, but is missing profile public key, so can't connect to servers requiring secure profiles (default)
I don't know if that would ever be supported by Quarry
you can do it your self, with modifications or just with moding the lib
i get this "builtins.ValueError: Ciphertext length must be equal to key size. " error when i try run this code
How would you do the version @Jerrylum posted without using quarry as a proxy, directly connecting to the server?
I solved this. For anyone curious here's the code
import json from xmlrpc.client import ProtocolError import requests from twisted.python import failure from twisted.internet import reactor from quarry.types.uuid import UUID from quarry.net.proxy import UpstreamFactory, Upstream, DownstreamFactory, Downstream, Bridge from quarry.net import auth, crypto from twisted.internet import reactor 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) buff.read() 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'))) class MyUpstreamFactory(UpstreamFactory): protocol = MyUpstream connection_timeout = 10 class MyBridge(Bridge): upstream_factory_class = MyUpstreamFactory def make_profile(self): """ Support online mode """ # follow: https://kqzz.github.io/mc-bearer-token/ accessToken = '<YOUR TOKEN>' url = "https://api.minecraftservices.com/minecraft/profile" headers = {'Authorization': 'Bearer ' + accessToken} response = requests.request("GET", url, headers=headers) result = response.json() myUuid = UUID.from_hex(result['id']) myUsername = result['name'] return auth.Profile('(skip)', accessToken, myUsername, myUuid) class MyDownstreamFactory(DownstreamFactory): protocol = MyDownstream bridge_class = MyBridge motd = "Proxy Server" def main(argv): # Parse options import argparse parser = argparse.ArgumentParser() parser.add_argument("-a", "--listen-host", default="0.0.0.0", help="address to listen on") parser.add_argument("-p", "--listen-port", default=25565, type=int, help="port to listen on") parser.add_argument("-b", "--connect-host", default="127.0.0.1", help="address to connect to") parser.add_argument("-q", "--connect-port", default=25565, type=int, help="port to connect to") args = parser.parse_args(argv) # Create factory factory = MyDownstreamFactory() factory.connect_host = args.connect_host factory.connect_port = args.connect_port # Listen factory.listen(args.listen_host, args.listen_port) reactor.run() if __name__ == "__main__": import sys main(sys.argv[1:])
This code was working for me for a min but has since stopped working for some reason
I got a work around solution. It fixed #132, #123, and LiveOverflow/minecraft-hacked#1.
The reason why online mode is not supported is because of the
Auth failed
issue and theMicrosoft Login
issue. And here's the explanation:About the
Auth failed
issueThe error message should look like this:
Auth failed: [<twisted.python.failure.Failure OpenSSL.SSL.Error: [('SSL routines', 'tls_process_server_certificate', 'certificate verify failed')]>]
Here is a discussion on Stackoverflow: https://stackoverflow.com/questions/33602478/how-to-handle-openssl-ssl-error-while-using-twisted-web-client-agent-on-facebook.
It is a problem related to Twisted, OpenSSL and trust roots configuration 10 years ago. This is one of the reasons why it only works on Linux. To fix this, all you have to do is run the python file via the command
SSL_CERT_FILE="$(python -m certifi)" python xxx.py
on Git Bash. You don't need to install WSL if you're using Windows.About the
Microsoft Login
issueMicrosoft made the login process too complicated. I don't think it is possible to login to the account in command line enviroment.
However, you don't have to login or provide your user name and password in the command line. I first go to minecraft.net, then press
F12
key to open my developer console. Type JavaScript to get my Minecraft bearer token. Finally paste the token in the code so I can get access to the account. You can follow the instructions on https://kqzz.github.io/mc-bearer-token/Here is a full example. Oh, btw my example also fixed the
Auth failed
issue by usingrequests
library. That's mean you don't even have to use Git Bash. Enjoy! :)import json from xmlrpc.client import ProtocolError import requests from twisted.python import failure from twisted.internet import reactor from quarry.types.uuid import UUID from quarry.net.proxy import UpstreamFactory, Upstream, DownstreamFactory, Downstream, Bridge from quarry.net import auth, crypto from twisted.internet import reactor 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'))) class MyUpstreamFactory(UpstreamFactory): protocol = MyUpstream connection_timeout = 10 class MyBridge(Bridge): upstream_factory_class = MyUpstreamFactory def make_profile(self): """ Support online mode """ # follow: https://kqzz.github.io/mc-bearer-token/ accessToken = '<YOUR TOKEN>' url = "https://api.minecraftservices.com/minecraft/profile" headers = {'Authorization': 'Bearer ' + accessToken} response = requests.request("GET", url, headers=headers) result = response.json() myUuid = UUID.from_hex(result['id']) myUsername = result['name'] return auth.Profile('(skip)', accessToken, myUsername, myUuid) class MyDownstreamFactory(DownstreamFactory): protocol = MyDownstream bridge_class = MyBridge motd = "Proxy Server" def main(argv): # Parse options import argparse parser = argparse.ArgumentParser() parser.add_argument("-a1", "--listen-host1", default="", help="address to listen on") parser.add_argument("-p1", "--listen-port1", default=25566, type=int, help="port to listen on") parser.add_argument("-b", "--connect-host", default="127.0.0.1", help="address to connect to") parser.add_argument("-q", "--connect-port", default=25565, type=int, help="port to connect to") args = parser.parse_args(argv) # Create factory factory = MyDownstreamFactory() factory.connect_host = args.connect_host factory.connect_port = args.connect_port # Listen factory.listen(args.listen_host1, args.listen_port1) reactor.run() if __name__ == "__main__": import sys main(sys.argv[1:])
I got an error when i joined saying invalid session with my token. To fix this, replace this
with this
i mean technically 204 OK isnt 200 OK but computers will be computers
the only thing needed from the hasJoined
endpoint is the uuid, just provide it seperately!
i was finally able to join hypixel
(the whole reason why im doing this is so i can disable online mode on the proxy listener but log in as me on hypixel, the endpoints needed for join online mode server are blocked by school blocker 😁)