mirror of
https://github.com/chocolate-doom/master-server.git
synced 2024-11-10 07:11:38 +00:00
Include a Message-Type: field so that end messages can only be generated
from start messages. Include millisecond precision in the time fields of the messages for extra accuracy. Log nonce values and demo hashes. Subversion-branch: /master Subversion-revision: 2519
This commit is contained in:
parent
6f54a0d8c1
commit
2cc103e783
2 changed files with 29 additions and 10 deletions
|
@ -322,6 +322,8 @@ class MasterServer:
|
|||
packet = nonce + signature
|
||||
self.send_message(addr, NET_MASTER_PACKET_TYPE_SIGN_START_RESPONSE,
|
||||
packet)
|
||||
self.log_output(addr, "Generated nonce: %s" %
|
||||
secure_demo.bin_to_hex(nonce))
|
||||
|
||||
def sign_end_message(self, data, addr):
|
||||
""" Generate a signed end message and return to the client. """
|
||||
|
@ -336,6 +338,9 @@ class MasterServer:
|
|||
demo_hash = data[0:20]
|
||||
start_message = data[20:]
|
||||
|
||||
self.log_output(addr, "End demo hash: %s" %
|
||||
secure_demo.bin_to_hex(demo_hash))
|
||||
|
||||
# Parse the start message and verify the signature, then use it
|
||||
# to generate an end message along with the hash of the demo.
|
||||
signature = self.signer.sign_end_message(start_message, demo_hash)
|
||||
|
@ -364,7 +369,7 @@ class MasterServer:
|
|||
def rx_packet(self):
|
||||
""" Invoked when a packet is received. """
|
||||
|
||||
data, addr = self.sock.recvfrom(1024)
|
||||
data, addr = self.sock.recvfrom(1400)
|
||||
|
||||
try:
|
||||
self.process_packet(data, addr)
|
||||
|
@ -374,7 +379,7 @@ class MasterServer:
|
|||
def rx_packet_query_sock(self):
|
||||
""" Invoked when a packet is received on the query socket. """
|
||||
|
||||
data, addr = self.query_sock.recvfrom(1024)
|
||||
data, addr = self.query_sock.recvfrom(1400)
|
||||
|
||||
try:
|
||||
self.process_query_response(data, addr)
|
||||
|
|
|
@ -37,9 +37,15 @@ except ImportError:
|
|||
available = False
|
||||
|
||||
def now_string():
|
||||
"""Generate an ISO8601 string for the current time."""
|
||||
"""Generate a string representing the current time.
|
||||
|
||||
The time is roughly ISO8601 UTC format, but also includes
|
||||
milliseconds for additional accuracy.
|
||||
"""
|
||||
now = time.time()
|
||||
return time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime(now))
|
||||
ms = int(now * 1000) % 1000
|
||||
datetime_base = time.strftime('%Y-%m-%dT%H:%M:%S', time.gmtime(now))
|
||||
return "%s.%03iZ" % (datetime_base, ms)
|
||||
|
||||
def bin_to_hex(data):
|
||||
"""Convert a string of binary data into a hex representation."""
|
||||
|
@ -56,6 +62,7 @@ class SecureSigner(object):
|
|||
def _generate_start_message(self, nonce):
|
||||
"""Generate the plaintext used for a start message."""
|
||||
return "\n".join([
|
||||
"Message-Type: Start",
|
||||
"Start-Time: %s" % now_string(),
|
||||
"Nonce: %s" % bin_to_hex(nonce),
|
||||
])
|
||||
|
@ -115,15 +122,22 @@ class SecureSigner(object):
|
|||
if plaintext is None:
|
||||
return None
|
||||
|
||||
# We assume the plaintext message ends with a newline.
|
||||
if plaintext[-1] != "\n":
|
||||
plaintext = plaintext + "\n"
|
||||
# Split plain-text of start message into lines, and verify
|
||||
# message type:
|
||||
plaintext = plaintext.rstrip("\n")
|
||||
plaintext_lines = plaintext.split("\n")
|
||||
|
||||
# Add extra fields to the plaintext, to create the end message.
|
||||
message = plaintext + "\n".join([
|
||||
if plaintext_lines[0] != "Message-Type: Start":
|
||||
return None
|
||||
|
||||
# Construct the end message:
|
||||
message_lines = [ "Message-Type: Signature" ]
|
||||
message_lines += plaintext_lines[1:]
|
||||
message_lines += [
|
||||
"End-Time: %s" % now_string(),
|
||||
"Demo-Checksum: %s" % bin_to_hex(demo_hash),
|
||||
])
|
||||
]
|
||||
message = "\n".join(message_lines)
|
||||
return self._sign_plaintext_message(message)
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
Loading…
Reference in a new issue