diff --git a/admin_page_server.py b/admin_page_server.py index 0579c55..decf0c5 100644 --- a/admin_page_server.py +++ b/admin_page_server.py @@ -82,6 +82,7 @@ class AdminPage(resource.Resource): '' '

' 'All Users | ' + 'Consoles | ' 'Active Bans ' '

' ) @@ -145,6 +146,39 @@ class AdminPage(resource.Resource): referer = "/banhammer" request.setHeader("Location", referer) + request.setResponseCode(303) + return responsedata + def update_consolelist(self, request): + address = request.getClientIP() + dbconn = sqlite3.connect('gpcm.db') + macadr = request.args['macadr'][0].strip() + actiontype = request.args['action'][0] + if not macadr.isalnum(): + request.setResponseCode(500) + logger.log(logging.INFO,address+" Bad data "+macadr+" ") + return "Bad data" + if actiontype == 'add': + dbconn.cursor().execute('insert into pending values(?)',(macadr,)) + dbconn.cursor().execute('insert into registered values(?)',(macadr,)) + responsedata = "Added macadr=%s" % (macadr) + elif actiontype == 'activate': + dbconn.cursor().execute('insert into registered values(?)',(macadr,)) + responsedata = "Activated console belonging to %s" % (macadr) + else: + dbconn.cursor().execute('delete from pending where macadr=?',(macadr,)) + dbconn.cursor().execute('delete from registered where macadr=?',(macadr,)) + responsedata = "Removed macadr=%s" % (macadr) + dbconn.commit() + dbconn.close() + logger.log(logging.INFO,address+" "+responsedata) + request.setHeader("Content-Type", "text/html; charset=utf-8") + request.setHeader("Location", "/consoles") + referer = request.getHeader('referer') + request.setResponseCode(303) + if not referer: + referer = "/banhammer" + request.setHeader("Location", referer) + request.setResponseCode(303) return responsedata @@ -277,6 +311,40 @@ class AdminPage(resource.Resource): request.setResponseCode(303) return responsedata + def render_consolelist(self, request): + address = request.getClientIP() + dbconn = sqlite3.connect('gpcm.db') + active_list = [] + for row in dbconn.cursor().execute("SELECT * FROM REGISTERED"): + active_list.append(str(row[0])) + logger.log(logging.INFO,address+" Viewed console list") + responsedata = ("" + '[CLICK HERE TO LOG OUT]' + "
" + "macadr:\r\n" + "\r\n" + "
\r\n" + "" + "\r\n") + for row in dbconn.cursor().execute("select * from pending"): + macadr = str(row[0]) + if macadr in active_list: + responsedata += ("" + "\r\n") + else: + responsedata += ("" + "\r\n") + responsedata += "
macadr
"+macadr+"
" + "" + "\r\n" + "
"+macadr+"
" + "" + "\r\n" + "
" + dbconn.close() + request.setHeader("Content-Type", "text/html; charset=utf-8") + return responsedata + def render_GET(self, request): if not adminpageconf: self.render_not_available(request) @@ -292,7 +360,9 @@ class AdminPage(resource.Resource): elif request.path == "/banhammer": title = 'AltWfc Users' response = self.render_blacklist(request) - + elif request.path == "/consoles": + title = "AltWfc Console List" + response = self.render_consolelist(request) return self.get_header(title) + response + self.get_footer() def render_POST(self, request): @@ -304,6 +374,8 @@ class AdminPage(resource.Resource): if request.path == "/updatebanlist": return self.update_banlist(request) + if request.path == "/updateconsolelist": + return self.update_consolelist(request) else: return self.get_header() + self.get_footer() diff --git a/gamespy/gs_database.py b/gamespy/gs_database.py index cd59854..46a6ce9 100644 --- a/gamespy/gs_database.py +++ b/gamespy/gs_database.py @@ -118,7 +118,8 @@ class GamespyDatabase(object): tx.nonquery("CREATE TABLE IF NOT EXISTS gameinfo (profileid INT, dindex TEXT, ptype TEXT, data TEXT)") tx.nonquery("CREATE TABLE IF NOT EXISTS nas_logins (userid TEXT, authtoken TEXT, data TEXT)") tx.nonquery("CREATE TABLE IF NOT EXISTS banned (gameid TEXT, ipaddr TEXT)") - + tx.nonquery("CREATE TABLE IF NOT EXISTS pending (macadr TEXT)") + tx.nonquery("CREATE TABLE IF NOT EXISTS registered (macadr TEXT)") # Create some indexes for performance. tx.nonquery("CREATE UNIQUE INDEX IF NOT EXISTS gamestatprofile_triple on gamestat_profile(profileid,dindex,ptype)") tx.nonquery("CREATE UNIQUE INDEX IF NOT EXISTS users_profileid_idx ON users (profileid)") @@ -403,6 +404,14 @@ class GamespyDatabase(object): with Transaction(self.conn) as tx: row = tx.queryone("SELECT COUNT(*) FROM banned WHERE gameid = ? AND ipaddr = ?",(postdata['gamecd'][:-1],postdata['ipaddr'])) return int(row[0]) > 0 + def pending(self,postdata): + with Transaction(self.conn) as tx: + row = tx.queryone("SELECT COUNT(*) FROM pending WHERE macadr = ?",(postdata['macadr'],)) + return int(row[0]) > 0 + def registered(self,postdata): + with Transaction(self.conn) as tx: + row = tx.queryone("SELECT COUNT(*) FROM registered WHERE macadr = ?",(postdata['macadr'],)) + return int(row[0]) > 0 def get_next_available_userid(self): with Transaction(self.conn) as tx: diff --git a/master_server.py b/master_server.py index 81023dc..1d156e1 100644 --- a/master_server.py +++ b/master_server.py @@ -27,6 +27,7 @@ from gamespy_gamestats_server import GameSpyGamestatsServer from nas_server import NasServer from internal_stats_server import InternalStatsServer from admin_page_server import AdminPageServer +from register_page import RegPageServer from storage_server import StorageServer from gamestats_server_http import GameStatsServer @@ -54,6 +55,7 @@ if __name__ == "__main__": NasServer, InternalStatsServer, AdminPageServer, + RegPageServer, StorageServer, GameStatsServer, ] diff --git a/nas_server.py b/nas_server.py index 8d1393c..fdb1809 100644 --- a/nas_server.py +++ b/nas_server.py @@ -135,6 +135,23 @@ class NasHTTPServerHandler(BaseHTTPServer.BaseHTTPRequestHandler): "retry": "1", "reason": "User banned." } + #Un-comment these lines to enable console registration feature + #elif not self.server.db.pending(post): + #logger.log(logging.DEBUG, "Login denied - Unknown console"+str(post)) + #ret = { + #"datetime": time.strftime("%Y%m%d%H%M%S"), + #"returncd": "3921", + #"locator": "gamespy.com", + #"retry": "1", + #} + #elif not self.server.db.registered(post): + #logger.log(logging.DEBUG, "Login denied - console pending"+str(post)) + #ret = { + #"datetime": time.strftime("%Y%m%d%H%M%S"), + #"returncd": "3888", + #"locator": "gamespy.com", + #"retry": "1", + #} else: challenge = utils.generate_random_str(8) post["challenge"] = challenge diff --git a/register_page.py b/register_page.py new file mode 100644 index 0000000..cb52837 --- /dev/null +++ b/register_page.py @@ -0,0 +1,126 @@ +# DWC Network Server Emulator +# Copyright (C) 2014 SMTDDR +# Copyright (C) 2014 kyle95wm +# Copyright (C) 2014 AdmiralCurtiss +# +# 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 . + +from twisted.web import server, resource +from twisted.internet import reactor +from twisted.internet.error import ReactorAlreadyRunning +import base64 +import codecs +import sqlite3 +import collections +import json +import time +import datetime +import other.utils as utils +import gamespy +import gamespy.gs_utility as gs_utils + +class RegPage(resource.Resource): + isLeaf = True + + def __init__(self,regpage): + self.regpage = regpage + + def get_header(self, title = None): + if not title: + title = 'Register a Console' + s = ( + '' + '' + '' + title + '' + '' + '' + '

' + 'Register a Console' + '

' + ) + return s + + def get_footer(self): + s = ( + '' + '' + ) + return s + + def update_maclist(self, request): + address = request.getClientIP() + dbconn = sqlite3.connect('gpcm.db') + macadr = request.args['macadr'][0].strip() + actiontype = request.args['action'][0] + if not macadr.isalnum(): + request.setResponseCode(500) + logger.log(logging.INFO,address+" Bad data "+macadr+" ") + return "Bad data" + if actiontype == 'add': + dbconn.cursor().execute('insert into pending values(?)',(macadr,)) + responsedata = "Added %s to pending list. Your application may take anywhere from 24 to 48 hours." % (macadr) + dbconn.commit() + dbconn.close() + request.setHeader("Content-Type", "text/html; charset=utf-8") + request.setResponseCode(303) + return responsedata + if not referer: + referer = "/register" + request.setHeader("Location", referer) + + request.setResponseCode(303) + return responsedata + + def render_maclist(self, request): + address = request.getClientIP() + dbconn = sqlite3.connect('gpcm.db') + responsedata = ("" + "
" + "macadr (must be in the format of aabbccddeeff):\r\n" + "\r\n" + "
\r\n" + "" + "") + dbconn.close() + request.setHeader("Content-Type", "text/html; charset=utf-8") + return responsedata + + def render_GET(self, request): + title = None + response = '' + if request.path == "/register": + title = 'Register a Console to ALTWFC' + response = self.render_maclist(request) + + return self.get_header(title) + response + self.get_footer() + + def render_POST(self, request): + if request.path == "/updatemaclist": + return self.update_maclist(request) + else: + return self.get_header() + self.get_footer() + +port = 9998 +class RegPageServer(object): + def start(self): + site = server.Site(RegPage(self)) + reactor.listenTCP(port, site) + try: + if reactor.running == False: + reactor.run(installSignalHandlers=0) + except ReactorAlreadyRunning: + pass + +if __name__ == "__main__": + RegPageServer().start()