diff --git a/minecraft/networking/encryption.py b/minecraft/networking/encryption.py index 01871c6..fd21dbd 100644 --- a/minecraft/networking/encryption.py +++ b/minecraft/networking/encryption.py @@ -41,10 +41,14 @@ def generate_verification_hash(server_id, shared_secret, public_key): verification_hash.update(shared_secret) verification_hash.update(public_key) + return minecraft_sha1_hash_digest(verification_hash) + + +def minecraft_sha1_hash_digest(sha1_hash): # Minecraft first parses the sha1 bytes as a signed number and then spits outs # its hex representation - number = _number_from_bytes(verification_hash.digest(), signed=True) - return format(number, 'x') + number_representation = _number_from_bytes(sha1_hash.digest(), signed=True) + return format(number_representation, 'x') def _number_from_bytes(b, signed=False): diff --git a/minecraft/networking/types.py b/minecraft/networking/types.py index 9c878c3..75607f4 100644 --- a/minecraft/networking/types.py +++ b/minecraft/networking/types.py @@ -80,27 +80,27 @@ class Integer(Type): class VarInt(Type): @staticmethod - def read_socket(s): - d = 0 + def read_socket(socket): + number = 0 for i in range(5): - b = s.recv(1) - if b == "": + byte = socket.recv(1) + if byte == "": raise RuntimeError("Socket disconnected") - b = ord(b) - d |= (b & 0x7F) << 7 * i - if not b & 0x80: + byte = ord(byte) + number |= (byte & 0x7F) << 7 * i + if not byte & 0x80: break - return d + return number @staticmethod def read(file_object): - d = 0 + number = 0 for i in range(5): - b = ord(file_object.read(1)) - d |= (b & 0x7F) << 7 * i - if not b & 0x80: + byte = ord(file_object.read(1)) + number |= (byte & 0x7F) << 7 * i + if not byte & 0x80: break - return d + return number @staticmethod def send(value, socket): @@ -115,12 +115,12 @@ class VarInt(Type): @staticmethod def size(value): - for max_value, size in VarInt_size_table.iteritems(): + for max_value, size in VARINT_SIZE_TABLE.iteritems(): if value < max_value: return size # Maps (maximum integer value -> size of VarInt in bytes) -VarInt_size_table = { +VARINT_SIZE_TABLE = { 2**7: 1, 2**14: 2, 2**21: 3, diff --git a/tests/test_encryption.py b/tests/test_encryption.py new file mode 100644 index 0000000..db6aef2 --- /dev/null +++ b/tests/test_encryption.py @@ -0,0 +1,17 @@ +import unittest +import hashlib +from minecraft.networking.encryption import minecraft_sha1_hash_digest + + +class Hashing(unittest.TestCase): + + test_data = {'Notch': '4ed1f46bbe04bc756bcb17c0c7ce3e4632f06a48', + 'jeb_': '-7c9d5b0044c130109a5d7b5fb5c317c02b4e28c1', + 'simon': '88e16a1019277b15d58faf0541e11910eb756f6'} + + def test_hashing(self): + for input_value in self.test_data.iterkeys(): + sha1_hash = hashlib.sha1() + sha1_hash.update(input_value) + self.assertEquals(minecraft_sha1_hash_digest(sha1_hash), self.test_data[input_value]) + \ No newline at end of file diff --git a/tox.ini b/tox.ini index 93d2e76..6c0efa6 100644 --- a/tox.ini +++ b/tox.ini @@ -12,6 +12,7 @@ commands = nosetests deps = nose requests + cryptography [testenv:py27] deps =