<commit_before>#    DWC Network Server Emulator
#    Copyright (C) 2014 polaris-
#    Copyright (C) 2014 ToadKing
#    Copyright (C) 2014 AdmiralCurtiss
#    Copyright (C) 2014 msoucy
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as
#    published by the Free Software Foundation, either version 3 of the
#    License, or (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.

import base64
import json
import logging
import time
import urlparse
import BaseHTTPServer
import SocketServer
import threading
import os
import random
import traceback

import gamespy.gs_database as gs_database
import gamespy.gs_utility as gs_utils
import other.utils as utils

logger_output_to_console = True
logger_output_to_file = True
logger_name = "NasServer"
logger_filename = "nas_server.log"
logger = utils.create_logger(logger_name, logger_filename, -1, logger_output_to_console, logger_output_to_file)

# if a game from this list requests a file listing, the server will return that only one exists and return a random one
# this is used for Mystery Gift distribution on Generation 4 Pokemon games
gamecodes_return_random_file = ['ADAD', 'ADAE', 'ADAF', 'ADAI', 'ADAJ', 'ADAK', 'ADAS', 'CPUD', 'CPUE', 'CPUF', 'CPUI', 'CPUJ', 'CPUK', 'CPUS', 'IPGD', 'IPGE', 'IPGF', 'IPGI', 'IPGJ', 'IPGK', 'IPGS']

#address = ("0.0.0.0", 80)
address = ("127.0.0.1", 9000)

class NasServer(object):
    def start(self):
        httpd = NasHTTPServer((address[0], address[1]), NasHTTPServerHandler)
        t = threading.Thread(target=httpd.serve_forever)
        t.daemon = True
        t.start()
        logger.log(logging.INFO, "Now listening for connections on %s:%d...", address[0], address[1])
        httpd.serve_forever()

class NasHTTPServer(SocketServer.ThreadingMixIn,BaseHTTPServer.HTTPServer):
    def __init__(self, server_address, RequestHandlerClass):
        #self.db = gs_database.GamespyDatabase()
        BaseHTTPServer.HTTPServer.__init__(self, server_address, RequestHandlerClass)

class NasHTTPServerHandler(BaseHTTPServer.BaseHTTPRequestHandler):
    def version_string(self):
        return "Nintendo Wii (http)"

    def do_GET(self):
        self.server = lambda:None
        self.server.db = gs_database.GamespyDatabase()

        try:
            # conntest server
            self.send_response(200)
            self.send_header("Content-type", "text/html")
            self.send_header("X-Organization", "Nintendo")
            self.send_header("Server", "BigIP")
            self.end_headers()
            self.wfile.write("ok")
        except:
            logger.log(logging.ERROR, "Unknown exception: %s" % traceback.format_exc())

    def do_POST(self):
        self.server = lambda:None
        self.server.db = gs_database.GamespyDatabase()

        try:
            length = int(self.headers['content-length'])
            post = self.str_to_dict(self.rfile.read(length))
            if self.client_address[0] == '127.0.0.1':
                client_address = (self.headers.get('x-forwarded-for', self.client_address[0]), self.client_address[1])
            else:
                client_address = self.client_address

            post['ipaddr'] = client_address[0]

            if self.path == "/ac":
                logger.log(logging.DEBUG, "Request to %s from %s", self.path, client_address)
                logger.log(logging.DEBUG, post)
                ret = {
                    "datetime": time.strftime("%Y%m%d%H%M%S"),
                    "retry": "0"
                }
                action = post["action"]
                self.send_response(200)
                self.send_header("Content-type", "text/plain")
                self.send_header("NODE", "wifiappe1")

                if action == "acctcreate":
                    # TODO: test for duplicate accounts
                    if self.server.db.is_banned(post):
                        logger.log(logging.DEBUG, "acctcreate denied for banned user "+str(post))
                        ret = {
                            "datetime": time.strftime("%Y%m%d%H%M%S"),
                            "returncd": "3913",
                            "locator": "gamespy.com",
                            "retry": "1",
                            "reason": "User banned."
                        }
                    else:
                        ret["returncd"] = "002"
                        ret['userid'] = self.server.db.get_next_available_userid()

                        logger.log(logging.DEBUG, "acctcreate response to %s", client_address)
                        logger.log(logging.DEBUG, ret)

                    ret = self.dict_to_str(ret)

                elif action == "login":
                    if self.server.db.is_banned(post):
                        logger.log(logging.DEBUG, "login denied for banned user "+str(post))
                        ret = {
                            "datetime": time.strftime("%Y%m%d%H%M%S"),
                            "returncd": "3914",
                            "locator": "gamespy.com",
                            "retry": "1",
                            "reason": "User banned."
                        }
                    else:
                        challenge = utils.generate_random_str(8)
                        post["challenge"] = challenge
                        
                        if not self.server.db.check_user_exists(post["userid"], post["gsbrcd"]) or self.server.db.check_user_enabled(post["userid"], post["gsbrcd"]):
                            authtoken = self.server.db.generate_authtoken(post["userid"], post)
                            ret.update({
                                "returncd": "001",
                                "locator": "gamespy.com",
                                "challenge": challenge,
                                "token": authtoken,
                            })

                            logger.log(logging.DEBUG, "login response to %s", client_address)
                            logger.log(logging.DEBUG, ret)
                        else:
                            # user is banned
                            ret.update({
                                "returncd": "3912",
                                "locator": "gamespy.com",
                            })
                            logger.log(logging.DEBUG, "login response to %s (user banned)", client_address)
                            logger.log(logging.DEBUG, ret)

                    ret = self.dict_to_str(ret)

                elif action == "SVCLOC" or action == "svcloc": # Get service based on service id number
                    ret["returncd"] = "007"
                    ret["statusdata"] = "Y"
                    authtoken = self.server.db.generate_authtoken(post["userid"], post)

                    if 'svc' in post:
                        if post["svc"] in ("9000", "9001"): # DLC host = 9000
                            ret["svchost"] = self.headers['host'] # in case the client's DNS isn't redirecting dls1.nintendowifi.net

                            # Brawl has 2 host headers which Apache chokes on, so only return the first one or else it won't work
                            ret["svchost"] = ret["svchost"].split(',')[0]
<commit_msg>Revert 798a9238bd5f72d752828068dd5631128377395d since we have a different ban system now.<commit_after>#    DWC Network Server Emulator
#    Copyright (C) 2014 polaris-
#    Copyright (C) 2014 ToadKing
#    Copyright (C) 2014 AdmiralCurtiss
#    Copyright (C) 2014 msoucy
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU Affero General Public License as
#    published by the Free Software Foundation, either version 3 of the
#    License, or (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU Affero General Public License for more details.
#
#    You should have received a copy of the GNU Affero General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.

import base64
import json
import logging
import time
import urlparse
import BaseHTTPServer
import SocketServer
import threading
import os
import random
import traceback

import gamespy.gs_database as gs_database
import gamespy.gs_utility as gs_utils
import other.utils as utils

logger_output_to_console = True
logger_output_to_file = True
logger_name = "NasServer"
logger_filename = "nas_server.log"
logger = utils.create_logger(logger_name, logger_filename, -1, logger_output_to_console, logger_output_to_file)

# if a game from this list requests a file listing, the server will return that only one exists and return a random one
# this is used for Mystery Gift distribution on Generation 4 Pokemon games
gamecodes_return_random_file = ['ADAD', 'ADAE', 'ADAF', 'ADAI', 'ADAJ', 'ADAK', 'ADAS', 'CPUD', 'CPUE', 'CPUF', 'CPUI', 'CPUJ', 'CPUK', 'CPUS', 'IPGD', 'IPGE', 'IPGF', 'IPGI', 'IPGJ', 'IPGK', 'IPGS']

#address = ("0.0.0.0", 80)
address = ("127.0.0.1", 9000)

class NasServer(object):
    def start(self):
        httpd = NasHTTPServer((address[0], address[1]), NasHTTPServerHandler)
        t = threading.Thread(target=httpd.serve_forever)
        t.daemon = True
        t.start()
        logger.log(logging.INFO, "Now listening for connections on %s:%d...", address[0], address[1])
        httpd.serve_forever()

class NasHTTPServer(SocketServer.ThreadingMixIn,BaseHTTPServer.HTTPServer):
    def __init__(self, server_address, RequestHandlerClass):
        #self.db = gs_database.GamespyDatabase()
        BaseHTTPServer.HTTPServer.__init__(self, server_address, RequestHandlerClass)

class NasHTTPServerHandler(BaseHTTPServer.BaseHTTPRequestHandler):
    def version_string(self):
        return "Nintendo Wii (http)"

    def do_GET(self):
        self.server = lambda:None
        self.server.db = gs_database.GamespyDatabase()

        try:
            # conntest server
            self.send_response(200)
            self.send_header("Content-type", "text/html")
            self.send_header("X-Organization", "Nintendo")
            self.send_header("Server", "BigIP")
            self.end_headers()
            self.wfile.write("ok")
        except:
            logger.log(logging.ERROR, "Unknown exception: %s" % traceback.format_exc())

    def do_POST(self):
        self.server = lambda:None
        self.server.db = gs_database.GamespyDatabase()

        try:
            length = int(self.headers['content-length'])
            post = self.str_to_dict(self.rfile.read(length))
            if self.client_address[0] == '127.0.0.1':
                client_address = (self.headers.get('x-forwarded-for', self.client_address[0]), self.client_address[1])
            else:
                client_address = self.client_address

            post['ipaddr'] = client_address[0]

            if self.path == "/ac":
                logger.log(logging.DEBUG, "Request to %s from %s", self.path, client_address)
                logger.log(logging.DEBUG, post)
                ret = {
                    "datetime": time.strftime("%Y%m%d%H%M%S"),
                    "retry": "0"
                }
                action = post["action"]
                self.send_response(200)
                self.send_header("Content-type", "text/plain")
                self.send_header("NODE", "wifiappe1")

                if action == "acctcreate":
                    # TODO: test for duplicate accounts
                    if self.server.db.is_banned(post):
                        logger.log(logging.DEBUG, "acctcreate denied for banned user "+str(post))
                        ret = {
                            "datetime": time.strftime("%Y%m%d%H%M%S"),
                            "returncd": "3913",
                            "locator": "gamespy.com",
                            "retry": "1",
                            "reason": "User banned."
                        }
                    else:
                        ret["returncd"] = "002"
                        ret['userid'] = self.server.db.get_next_available_userid()

                        logger.log(logging.DEBUG, "acctcreate response to %s", client_address)
                        logger.log(logging.DEBUG, ret)

                    ret = self.dict_to_str(ret)

                elif action == "login":
                    if self.server.db.is_banned(post):
                        logger.log(logging.DEBUG, "login denied for banned user "+str(post))
                        ret = {
                            "datetime": time.strftime("%Y%m%d%H%M%S"),
                            "returncd": "3914",
                            "locator": "gamespy.com",
                            "retry": "1",
                            "reason": "User banned."
                        }
                    else:
                        challenge = utils.generate_random_str(8)
                        post["challenge"] = challenge
                        
                        authtoken = self.server.db.generate_authtoken(post["userid"], post)
                        ret.update({
                            "returncd": "001",
                            "locator": "gamespy.com",
                            "challenge": challenge,
                            "token": authtoken,
                        })

                        logger.log(logging.DEBUG, "login response to %s", client_address)
                        logger.log(logging.DEBUG, ret)

                    ret = self.dict_to_str(ret)

                elif action == "SVCLOC" or action == "svcloc": # Get service based on service id number
                    ret["returncd"] = "007"
                    ret["statusdata"] = "Y"
                    authtoken = self.server.db.generate_authtoken(post["userid"], post)

                    if 'svc' in post:
                        if post["svc"] in ("9000", "9001"): # DLC host = 9000
                            ret["svchost"] = self.headers['host'] # in case the client's DNS isn't redirecting dls1.nintendowifi.net

                            # Brawl has 2 host headers which Apache chokes on, so only return the first one or else it won't work
                            ret["svchost"] = ret["svchost"].split(',')[0]

{'fraction_non_alphanumeric': 0.10815888352120236, 'fraction_numerical': 0.015029522275899088, 'mean_word_length': 1.7865021499345672, 'pattern_counts': {'":': 42, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 6, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7078143', 'n_tokens_mistral': 4279, 'n_tokens_neox': 4028, 'n_words': 1049}