From 23776c1b189791ac6fb7b5d300cef41fc2d9cd9e Mon Sep 17 00:00:00 2001 From: Toad King Date: Sat, 3 May 2014 14:04:19 -0400 Subject: [PATCH] cleanup nintendo_nas_server and implement stub /pr handling --- gamespy/gs_database.py | 4 +++- gamespy/gs_utility.py | 12 ++-------- nintendo_nas_server.py | 50 +++++++++++++++++++++++------------------- 3 files changed, 32 insertions(+), 34 deletions(-) diff --git a/gamespy/gs_database.py b/gamespy/gs_database.py index efe60b7..2762c8f 100644 --- a/gamespy/gs_database.py +++ b/gamespy/gs_database.py @@ -1,6 +1,7 @@ import sqlite3 import hashlib import itertools +import json import time import logging @@ -381,7 +382,7 @@ class GamespyDatabase(object): if r == None: return None else: - return r["data"] + return json.loads(r["data"]) def generate_authtoken(self, userid, data): # Since the auth token passed back to the game will be random, we can make it small enough that there @@ -403,6 +404,7 @@ class GamespyDatabase(object): c.execute(q, [userid]) r = self.get_dict(c.fetchone()) + data = json.dumps(data) if r == None: # no row, add it q = "INSERT INTO nas_logins VALUES (?, ?, ?)" diff --git a/gamespy/gs_utility.py b/gamespy/gs_utility.py index 19eb5c8..11f3f08 100644 --- a/gamespy/gs_utility.py +++ b/gamespy/gs_utility.py @@ -1,6 +1,5 @@ import base64 import hashlib -import json import time import other.utils as utils @@ -67,14 +66,7 @@ def prepare_rc4_base64(_key, _data): # get the login data from nas.nintendowifi.net/ac from an authtoken def parse_authtoken(authtoken, db): - messages = {} - nas_data = db.get_nas_login(authtoken) - - if nas_data == None: - return None - - return json.loads(nas_data) - + return db.get_nas_login(authtoken) def generate_response(challenge, ac_challenge, secretkey, authtoken): md5 = hashlib.md5() @@ -378,4 +370,4 @@ class EncTypeX: encxkey[260] = c encxkey[259] = d - return c \ No newline at end of file + return c diff --git a/nintendo_nas_server.py b/nintendo_nas_server.py index d20dde7..fa320a8 100644 --- a/nintendo_nas_server.py +++ b/nintendo_nas_server.py @@ -2,7 +2,6 @@ import base64 import json import logging import time -import urllib import urlparse import BaseHTTPServer import os @@ -35,10 +34,7 @@ class NintendoNasHTTPServerHandler(BaseHTTPServer.BaseHTTPRequestHandler): def do_POST(self): if self.path == "/ac": length = int(self.headers['content-length']) - post = urlparse.parse_qs(self.rfile.read(length)) - - for k, v in post.iteritems(): - post[k] = self.base64_dec(v[0]) + post = self.str_to_dict(self.rfile.read(length)) logger.log(logging.DEBUG, "Request to %s from %s", self.path, self.client_address) logger.log(logging.DEBUG, post) @@ -59,10 +55,7 @@ class NintendoNasHTTPServerHandler(BaseHTTPServer.BaseHTTPRequestHandler): logger.log(logging.DEBUG, "acctcreate response to %s", self.client_address) logger.log(logging.DEBUG, ret) - for k, v in ret.iteritems(): - ret[k] = self.base64_enc(v) - - self.wfile.write(urllib.urlencode(ret).replace("%2A", "*")) + self.wfile.write(self.dict_to_str(ret)) elif action == "login": ret["returncd"] = "001" @@ -70,26 +63,28 @@ class NintendoNasHTTPServerHandler(BaseHTTPServer.BaseHTTPRequestHandler): challenge = utils.generate_random_str(8) ret["challenge"] = challenge post["challenge"] = challenge - authtoken = self.server.db.generate_authtoken(post["userid"], json.dumps(post)) + authtoken = self.server.db.generate_authtoken(post["userid"], post) ret["token"] = authtoken logger.log(logging.DEBUG, "login response to %s", self.client_address) logger.log(logging.DEBUG, ret) - for k, v in ret.iteritems(): - ret[k] = self.base64_enc(v) + self.wfile.write(self.dict_to_str(ret)) - self.wfile.write(urllib.urlencode(ret).replace("%2A", "*")) + elif self.path == "/pr": + length = int(self.headers['content-length']) + post = self.str_to_dict(self.rfile.read(length)) - #elif self.path == "/pr": - # TODO + logger.log(logging.DEBUG, "Request to %s from %s", self.path, self.client_address) + logger.log(logging.DEBUG, post) + + # TODO?: implement bad word detection + + self.wfile.write("0") elif self.path == "/download": length = int(self.headers['content-length']) - post = urlparse.parse_qs(self.rfile.read(length)) - - for k, v in post.iteritems(): - post[k] = self.base64_dec(v[0]) + post = self.str_to_dict(self.rfile.read(length)) logger.log(logging.DEBUG, "Request to %s from %s", self.path, self.client_address) logger.log(logging.DEBUG, post) @@ -147,11 +142,20 @@ class NintendoNasHTTPServerHandler(BaseHTTPServer.BaseHTTPRequestHandler): self.wfile.write(ret) - def base64_dec(self, data): - return base64.b64decode(data.replace("*", "=")) + def str_to_dict(self, str): + ret = urlparse.parse_qs(str) - def base64_enc(self, data): - return base64.b64encode(data).replace("=", "*") + for k, v in ret.iteritems(): + ret[k] = base64.b64decode(v[0].replace("*", "=")) + + return ret + + def dict_to_str(self, dict): + for k, v in dict.iteritems(): + dict[k] = base64.b64encode(v).replace("=", "*") + + # nas(wii).nintendowifi.net has a URL query-like format but does not use encoding for special characters + return "&".join("{!s}={!s}".format(k, v) for k, v in dict.items()) if __name__ == "__main__": nas = NintendoNasServer()