diff --git a/altwfc.cfg b/altwfc.cfg
index 326948f..4a6cdfc 100755
--- a/altwfc.cfg
+++ b/altwfc.cfg
@@ -16,6 +16,7 @@ LoggerOutputFile = ON
[NasServer]
IP = 127.0.0.1
Port = 9000
+SvcHost = dls1.nintendowifi.net
LoggerName = NasServer
LoggerFilename = nas_server.log
LoggerLevel = -1
@@ -40,6 +41,15 @@ LoggerLevel = -1
LoggerOutputConsole = ON
LoggerOutputFile = ON
+[Dls1Server]
+IP = 127.0.0.1
+Port = 9003
+LoggerName = Dls1Server
+LoggerFilename = dls1_server.log
+LoggerLevel = -1
+LoggerOutputConsole = ON
+LoggerOutputFile = ON
+
[AdminPage]
IP = 127.0.0.1
Port = 9009
diff --git a/altwfc_nas.cfg b/altwfc_nas.cfg
index 5995a09..d4996c2 100644
--- a/altwfc_nas.cfg
+++ b/altwfc_nas.cfg
@@ -12,6 +12,7 @@ LoggerOutputFile = ON
[NasServer]
IP = 127.0.0.1
Port = 80
+SvcHost = dls1.nintendowifi.net
LoggerName = NasServer
LoggerFilename = nas_server.log
LoggerLevel = -1
@@ -36,6 +37,15 @@ LoggerLevel = -1
LoggerOutputConsole = ON
LoggerOutputFile = ON
+[Dls1Server]
+IP = 127.0.0.1
+Port = 9003
+LoggerName = Dls1Server
+LoggerFilename = dls1_server.log
+LoggerLevel = -1
+LoggerOutputConsole = ON
+LoggerOutputFile = ON
+
[AdminPage]
IP = 127.0.0.1
Port = 9009
diff --git a/dls1_server.py b/dls1_server.py
new file mode 100644
index 0000000..4539c54
--- /dev/null
+++ b/dls1_server.py
@@ -0,0 +1,161 @@
+"""DWC Network Server Emulator
+
+ Copyright (C) 2014 polaris-
+ Copyright (C) 2014 ToadKing
+ Copyright (C) 2014 AdmiralCurtiss
+ Copyright (C) 2014 msoucy
+ Copyright (C) 2015 Sepalani
+
+ 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 .
+"""
+
+import logging
+import BaseHTTPServer
+import SocketServer
+import os
+import traceback
+
+from other import dlc, utils
+import dwc_config
+
+logger = dwc_config.get_logger('Dls1Server')
+
+
+def handle_post(handler, addr, post):
+ """Handle unknown path."""
+ logger.log(logging.WARNING, "Unknown path request %s from %s:%d!",
+ handler.path, *addr)
+ handler.send_response(404)
+ return None
+
+
+def handle_download_action(handler, dlc_path, post):
+ """Handle unknown download action request."""
+ logger.log(logging.WARNING, "Unknown download action: %s", handler.path)
+ handler.send_response(200)
+ return None
+
+
+def handle_download_count(handler, dlc_path, post):
+ """Handle download count request."""
+ ret = dlc.download_count(dlc_path, post)
+ handler.send_response(200)
+ handler.send_header("Content-type", "text/plain")
+ handler.send_header("X-DLS-Host", "http://127.0.0.1/")
+ return ret
+
+
+def handle_download_list(handler, dlc_path, post):
+ """Handle download list request."""
+ ret = dlc.download_list(dlc_path, post)
+ handler.send_response(200)
+ handler.send_header("Content-type", "text/plain")
+ handler.send_header("X-DLS-Host", "http://127.0.0.1/")
+ return ret
+
+
+def handle_download_contents(handler, dlc_path, post):
+ """Handle download contents request."""
+ ret = dlc.download_contents(dlc_path, post)
+
+ if ret is None:
+ handler.send_response(404)
+ else:
+ handler.send_response(200)
+ handler.send_header("Content-type", "application/x-dsdl")
+ handler.send_header("Content-Disposition",
+ 'attachment; filename="%s"' % post["contents"])
+ handler.send_header("X-DLS-Host", "http://127.0.0.1/")
+ return ret
+
+
+def handle_download(handler, addr, post):
+ """Handle download POST request."""
+ logger.log(logging.DEBUG, "Download request to %s from %s:%d",
+ handler.path, *addr)
+ logger.log(logging.DEBUG, "%s", post)
+
+ action = str(post["action"]).lower()
+ dlc_dir = os.path.abspath("dlc")
+ dlc_path = os.path.abspath(os.path.join("dlc", post["gamecd"]))
+
+ if os.path.commonprefix([dlc_dir, dlc_path]) != dlc_dir:
+ logging.log(logging.WARNING,
+ 'Attempted directory traversal attack "%s",'
+ ' cancelling.', dlc_path)
+ handler.send_response(403)
+ return
+
+ command = handler.download_actions.get(action, handle_download_action)
+ ret = command(handler, dlc_path, post)
+
+ logger.log(logging.DEBUG, "Download response to %s:%d", *addr)
+ return ret
+
+
+class Dls1HTTPServerHandler(BaseHTTPServer.BaseHTTPRequestHandler):
+ """Nintendo Dls1 server handler."""
+
+ post_paths = {
+ "/download": handle_download
+ }
+
+ download_actions = {
+ "count": handle_download_count,
+ "list": handle_download_list,
+ "contents": handle_download_contents,
+ }
+
+ def version_string(self):
+ return "Nintendo Wii (http)"
+
+ def do_POST(self):
+ try:
+ length = int(self.headers['content-length'])
+ post = utils.qs_to_dict(self.rfile.read(length))
+ client_address = (
+ self.headers.get('x-forwarded-for', self.client_address[0]),
+ self.client_address[1]
+ )
+ post['ipaddr'] = client_address[0]
+
+ command = self.post_paths.get(self.path, handle_post)
+ ret = command(self, client_address, post)
+
+ if ret is not None:
+ self.send_header("Content-Length", str(len(ret)))
+ self.end_headers()
+ self.wfile.write(ret)
+ except:
+ logger.log(logging.ERROR, "Exception occurred on POST request!")
+ logger.log(logging.ERROR, "%s", traceback.format_exc())
+
+
+class Dls1HTTPServer(SocketServer.ThreadingMixIn, BaseHTTPServer.HTTPServer):
+ """Threading HTTP server."""
+ pass
+
+
+class Dls1Server(object):
+ def start(self):
+ address = dwc_config.get_ip_port('Dls1Server')
+ httpd = Dls1HTTPServer(address, Dls1HTTPServerHandler)
+ logger.log(logging.INFO, "Now listening for connections on %s:%d...",
+ *address)
+ httpd.serve_forever()
+
+
+if __name__ == "__main__":
+ dls1 = Dls1Server()
+ dls1.start()
diff --git a/dwc_config.py b/dwc_config.py
index dddc956..75ff139 100755
--- a/dwc_config.py
+++ b/dwc_config.py
@@ -75,3 +75,10 @@ def get_logger(section, filename='altwfc.cfg'):
config.getboolean(section, 'LoggerOutputConsole'),
config.getboolean(section, 'LoggerOutputFile')
)
+
+
+def get_svchost(section, filename='altwfc.cfg'):
+ """Return the svchost of the corresponding section."""
+ config = ConfigParser.RawConfigParser(allow_no_value=True)
+ config.read(get_config_filename(filename))
+ return config.get(section, 'SvcHost')
diff --git a/dwc_network_server_emulator.pyproj b/dwc_network_server_emulator.pyproj
index 89b2580..a703b96 100644
--- a/dwc_network_server_emulator.pyproj
+++ b/dwc_network_server_emulator.pyproj
@@ -42,6 +42,7 @@
+
diff --git a/master_server.py b/master_server.py
index 954c123..f2d336b 100644
--- a/master_server.py
+++ b/master_server.py
@@ -28,6 +28,7 @@ from gamespy_qr_server import GameSpyQRServer
from gamespy_server_browser_server import GameSpyServerBrowserServer
from gamespy_gamestats_server import GameSpyGamestatsServer
from nas_server import NasServer
+from dls1_server import Dls1Server
from internal_stats_server import InternalStatsServer
from admin_page_server import AdminPageServer
from storage_server import StorageServer
@@ -59,6 +60,7 @@ if __name__ == "__main__":
# GameSpyServerBrowserServer,
GameSpyNatNegServer,
NasServer,
+ Dls1Server,
InternalStatsServer,
AdminPageServer,
RegPageServer,
diff --git a/nas_server.py b/nas_server.py
index fa5ca30..dd43837 100644
--- a/nas_server.py
+++ b/nas_server.py
@@ -22,14 +22,12 @@
import logging
import time
-import urlparse
import BaseHTTPServer
import SocketServer
-import os
import traceback
from gamespy import gs_database
-from other import dlc, utils
+from other import utils
import dwc_config
logger = dwc_config.get_logger('NasServer')
@@ -134,7 +132,9 @@ def handle_ac_svcloc(handler, db, addr, post):
# DLC host = 9000
# In case the client's DNS isn't redirecting to
# dls1.nintendowifi.net
- ret["svchost"] = handler.headers['host']
+ # NB: NAS config overrides this if set
+ svchost = dwc_config.get_svchost('NasServer')
+ ret["svchost"] = svchost if svchost else handler.headers['host']
# Brawl has 2 host headers which Apache chokes
# on, so only return the first one or else it
@@ -205,77 +205,12 @@ def handle_pr(handler, addr, post):
return utils.dict_to_qs(ret)
-def handle_download_action(handler, dlc_path, post):
- """Handle unknown download action request."""
- logger.log(logging.WARNING, "Unknown download action: %s", handler.path)
- handler.send_response(200)
- return None
-
-
-def handle_download_count(handler, dlc_path, post):
- """Handle download count request."""
- ret = dlc.download_count(dlc_path, post)
- handler.send_response(200)
- handler.send_header("Content-type", "text/plain")
- handler.send_header("X-DLS-Host", "http://127.0.0.1/")
- return ret
-
-
-def handle_download_list(handler, dlc_path, post):
- """Handle download list request."""
- ret = dlc.download_list(dlc_path, post)
- handler.send_response(200)
- handler.send_header("Content-type", "text/plain")
- handler.send_header("X-DLS-Host", "http://127.0.0.1/")
- return ret
-
-
-def handle_download_contents(handler, dlc_path, post):
- """Handle download contents request."""
- ret = dlc.download_contents(dlc_path, post)
-
- if ret is None:
- handler.send_response(404)
- else:
- handler.send_response(200)
- handler.send_header("Content-type", "application/x-dsdl")
- handler.send_header("Content-Disposition",
- 'attachment; filename="%s"' % post["contents"])
- handler.send_header("X-DLS-Host", "http://127.0.0.1/")
- return ret
-
-
-def handle_download(handler, addr, post):
- """Handle download POST request."""
- logger.log(logging.DEBUG, "Download request to %s from %s:%d",
- handler.path, *addr)
- logger.log(logging.DEBUG, "%s", post)
-
- action = str(post["action"]).lower()
- dlc_dir = os.path.abspath("dlc")
- dlc_path = os.path.abspath(os.path.join("dlc", post["gamecd"]))
-
- if os.path.commonprefix([dlc_dir, dlc_path]) != dlc_dir:
- logging.log(logging.WARNING,
- 'Attempted directory traversal attack "%s",'
- ' cancelling.', dlc_path)
- handler.send_response(403)
- return
-
- command = handler.download_actions.get(action, handle_download_action)
- ret = command(handler, dlc_path, post)
-
- logger.log(logging.DEBUG, "Download response to %s:%d", *addr)
- return ret
-
-
class NasHTTPServerHandler(BaseHTTPServer.BaseHTTPRequestHandler):
"""Nintendo NAS server handler."""
post_paths = {
"/ac": handle_ac,
"/pr": handle_pr,
- "/download": handle_download
}
ac_actions = {
@@ -284,12 +219,6 @@ class NasHTTPServerHandler(BaseHTTPServer.BaseHTTPRequestHandler):
"svcloc": handle_ac_svcloc,
}
- download_actions = {
- "count": handle_download_count,
- "list": handle_download_list,
- "contents": handle_download_contents,
- }
-
def version_string(self):
return "Nintendo Wii (http)"
diff --git a/tools/apache-hosts/dls1.nintendowifi.net.conf b/tools/apache-hosts/dls1.nintendowifi.net.conf
new file mode 100644
index 0000000..fda65ea
--- /dev/null
+++ b/tools/apache-hosts/dls1.nintendowifi.net.conf
@@ -0,0 +1,9 @@
+
+ ServerAdmin webmaster@localhost
+ ServerName dls1.nintendowifi.net
+ ServerAlias "dls1.nintendowifi.net"
+ ServerAlias "dls1.nintendowifi.net, dls1.nintendowifi.net"
+ ProxyPreserveHost On
+ ProxyPass / http://127.0.0.1:9003/
+ ProxyPassReverse / http://127.0.0.1:9003/
+
diff --git a/tools/apache-hosts/nas-naswii-dls1-conntest.nintendowifi.net.conf b/tools/apache-hosts/nas-naswii-conntest.nintendowifi.net.conf
similarity index 82%
rename from tools/apache-hosts/nas-naswii-dls1-conntest.nintendowifi.net.conf
rename to tools/apache-hosts/nas-naswii-conntest.nintendowifi.net.conf
index f7f5537..94da24c 100644
--- a/tools/apache-hosts/nas-naswii-dls1-conntest.nintendowifi.net.conf
+++ b/tools/apache-hosts/nas-naswii-conntest.nintendowifi.net.conf
@@ -4,8 +4,6 @@
ServerAlias "naswii.nintendowifi.net, naswii.nintendowifi.net"
ServerAlias "nas.nintendowifi.net"
ServerAlias "nas.nintendowifi.net, nas.nintendowifi.net"
- ServerAlias "dls1.nintendowifi.net"
- ServerAlias "dls1.nintendowifi.net, dls1.nintendowifi.net"
ServerAlias "conntest.nintendowifi.net"
ServerAlias "conntest.nintendowifi.net, conntest.nintendowifi.net"
ProxyPreserveHost On