- FlashROM Support for LC2 and newer.
 - FlashROM system can handle local files, or proxy from server (default). No need to have a local FlashROM collection!
 - Added 'verbosity' configuration option
 - Update HTML Mode to async fileRead
 - Config option for sending tellyscripts or not
 - Config option to mask SSIDs in console log
 - Update wtv-home:/home and wtv-home:/zefie
 - Update .gitignore
 - Add wtv-music:/demo/index courtesy of MattMan69
 - Update HTML Mode to async fileRead
 - Update Raw TXT Mode to async fileRead
 - Replaced .async.js feature with defining `request_is_async` in standard .js script
 - Cleaned up code a bit
 - Moved global var 'query' to 'request_headers.query'
 - Tidied ServiceDeps
 - Upgraded wtv-log:/log to async, now also logs query arguments, saves to .txt for easier reading.
This commit is contained in:
zefie
2021-07-17 19:15:43 -04:00
parent ccc7951e34
commit 23d014a334
160 changed files with 1413 additions and 378 deletions

View File

@@ -11,12 +11,13 @@ This open source server is in alpha status. Use at your own risk.
- Suports `.async.js` service files with asynchronous requests
- Supports multiple simultaneous users
- WebTV-compatible HTTP Proxy (via minisrv, or using an external proxy for enhanced features (such as [WebOne](https://github.com/atauenis/webone))
- wtv-flashrom for LC2 and newer boxes (bf0app unsupported, need test unit)
- Can flash anything on [Ultra Willies](https://wtv.zefie.com/willie.php) with optional `use_zefie_server` flag set on `wtv-flashrom` service.
### Current issues:
- May not run on non-development Windows machines (VS2019 with nodejs and python)
- Power cycling box and re-connecting via ConnectSetup may invalidate encryption until server is restarted
- wtv-update:/update does not yet function as intended
- wtv-flashrom features do not yet function as intended
- HTTPS Proxying untested, likely needs SSL spoofing with self-signed solution
### Won't fix:
@@ -26,7 +27,8 @@ This open source server is in alpha status. Use at your own risk.
### Feature Todo:
- ~~(maybe) implement HTTP proxy (needs to be able to defluff most of the web, think retro WAP converter)~~ ***Done***
- ~~(maybe) enable "internet mode" (let user outside of minisrv)~~ ***Done***
- Flashrom flashing functionality (at least for LC2 and higher)
- ~~Flashrom flashing functionality (at least for LC2 and higher)~~ ***Done***
- Flashrom flashing for bf0app old classic (need donor unit)
- SSID/IP black/whitelisting (including tying SSID to an IP or multiple IPs)
- (maybe) Proper wtv-star (generic service outage page) support (maybe useful for allowing a unit to multiple sub-minisrvs).
- (maybe) wtvchat stuff

33
ServiceVault.md Normal file
View File

@@ -0,0 +1,33 @@
## Brief ServiceVault Explanation
The server will look for a subdirectory under the running directory, called `ServiceVault` (might be user-configurable in the future).
Within that directory, it looks for a subdirectory named after the wtv-service URL requested.
The server will then look for files in sequential order when requesting a URL, stopping at the first match.
Let us use the URL `wtv-1800:/preregister` as an example. This is what the server would look for (in order):
- `./ServiceVault/wtv-1800/preregister` \[ [Example](zefie_wtvp_minisrv/ServiceVault/wtv-star/images/HackTVLogo.gif) \]
- Exact file name match (*Direct File Mode*)
- Server sends the raw file, with its content-type. No parsing is done on the file.
- You do not need to do anything special with this format.
- `./ServiceVault/wtv-1800/preregister.txt` \[ [Example](zefie_wtvp_minisrv/ServiceVault/wtv-home/splash.txt) \]
- TXT file match (*Raw TXT Mode*)
- Service parses and sends AS-IS.
- You are expected to define headers
- `./ServiceVault/wtv-1800/preregister.js` \[ [Example](zefie_wtvp_minisrv/ServiceVault/wtv-home/home.js) \]
- Synchronous JS match (*JS Interpreter mode*)
- Executes the JavaScript in synchronous mode.
- You are expected to define `headers` and `data` before the end of your script.
- Access Asynchronous mode by setting `request_is_async = true;`
- Client request headers are available as an Array in variable `request_headers`, query arguments are also an Array, in `request_headers.query`
- In Asynchronous mode, you are expected to call `sendToClient(socket,headers,data)` yourself, `socket` is already defined by the time your script runs, so you can just pass it through.
- `./ServiceVault/wtv-1800/preregister.html` \[ [Example](zefie_wtvp_minisrv/ServiceVault/wtv-home/zefie.html) \]
- HTML match (*HTML mode*)
- Like Direct File Mode, but you don't need to append `.html`.
- You do not need to do anything special with this format.
The server will stop at the first result it finds using the order above.
So if you have `preregister.txt` and `preregister.js`, it will use `preregister.txt`, but not `preregister.js`.

View File

@@ -9,6 +9,7 @@ ServiceLogPost/*_*
# Large files not pertaining to the service code
ServiceVault/wtv-flashrom/content/*
ServiceVault/wtv-music/content/*
ServiceVault/wtv-music/midi/*
# User-specific files
*.rsuser

View File

@@ -1,26 +1,40 @@
if (socket_session_data[socket.id].ssid != null && !getSessionData(socket_session_data[socket.id].ssid, 'wtvsec_login')) {
var wtvsec_login = new WTVSec();
wtvsec_login.IssueChallenge();
wtvsec_login.set_incarnation(request_headers['wtv-incarnation']);
wtvsec_login.set_incarnation(request_headers["wtv-incarnation"]);
setSessionData(socket_session_data[socket.id].ssid, 'wtvsec_login', wtvsec_login)
} else {
var wtvsec_login = getSessionData(socket_session_data[socket.id].ssid, 'wtvsec_login')
}
var contype = "text/tellyscript";
var skip_tellyscript = false;
var prereg_contype = "text/html";
// if relogin, skip tellyscript
if (query['relogin']) {
contype = "text/html"; // skip tellyscript
if (request_headers.query.relogin) { // skip tellyscript
wtvsec_login.ticket_b64 = null; // clear old ticket
}
// if relogin, skip tellyscript
var romtype, file_path = null;
if (!request_headers.query.relogin && services_configured.config.send_tellyscripts) {
var romtype = getSessionData(socket_session_data[socket.id].ssid, 'wtv-client-rom-type');
}
switch (romtype) {
case "US-LC2-disk-0MB-8MB":
prereg_contype = "text/tellyscript";
var file_path = __dirname + "/ServiceDeps/premade_tellyscripts/LC2/LC2_OISP_5555732_56k.tok";
break;
default:
data = '';
break;
}
headers = `200 OK
Connection: Keep-Alive
wtv-initial-key: ` + wtvsec_login.challenge_key.toString(CryptoJS.enc.Base64) + `
Content-Type: `+ contype + `
Content-Type: `+ prereg_contype + `
wtv-service: reset
` + getServiceString('wtv-1800') + `
` + getServiceString('wtv-star') + `
@@ -30,20 +44,16 @@ wtv-boot-url: wtv-1800:/preregister?relogin=true
wtv-visit: wtv-head-waiter:/login?
wtv-client-time-zone: GMT -0000
wtv-client-time-dst-rule: GMT
wtv-client-date: `+strftime("%a, %d %b %Y %H:%M:%S", new Date(new Date().toUTCString()))+` GMT`;
wtv-client-date: `+ strftime("%a, %d %b %Y %H:%M:%S", new Date(new Date().toUTCString())) + ` GMT`;
// if relogin, skip tellyscript
var romtype = null;
if (!query['relogin'] && skip_tellyscript == false) {
var romtype = getSessionData(socket_session_data[socket.id].ssid, 'wtv-client-rom-type');
}
switch (romtype) {
case "US-LC2-disk-0MB-8MB":
data = getFile("LC2/LC2_OISP_5555732_56k.tok", true);
break;
default:
data = '';
break;
if (file_path) {
request_is_async = true;
fs.readFile(file_path, null, function (err, file_read_data) {
if (err) {
var errmsg = doErrorCode(400);
headers = errmsg[0];
file_read_data = errmsg[1] + "\n" + err.toString();
}
sendToClient(socket, headers, file_read_data);
});
}

View File

@@ -1,8 +1,8 @@
var gourl = "wtv-1800:/finish-prereg?";
if (query['relogin']) gourl += "relogin=true";
if (request_headers.query.relogin) gourl += "relogin=true";
if (request_headers['wtv-ticket']) {
if (request_headers["wtv-ticket"]) {
gourl = "wtv-head-waiter:/login-stage-two?";
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

View File

@@ -0,0 +1,74 @@
request_is_async = true;
var request_path = unescape(request_headers.query.path);
headers = "200 OK\n"
if (request_headers.query.raw) {
if ((/\.brom$/).test(request_path)) headers += "Content-Type: binary/x-wtv-bootrom"; // maybe?
else headers += "Content-Type: binary/x-wtv-flashblock";
if (services_configured.services[service_name].use_zefie_server) {
// get flashrom files from archive.midnightchannel.net
var options = {
host: "archive.midnightchannel.net",
path: "/zefie/files/wtv-flashrom/" + request_path,
timeout: 5000,
method: 'GET'
}
const req = https.request(options, function (res) {
var data_hex = '';
res.setEncoding('hex');
res.on('data', d => {
data_hex += d;
})
res.on('end', function () {
if (!zquiet) console.log(` * Zefie's FlashROM Server HTTP Status: ${res.statusCode} ${res.statusMessage}`)
if (res.statusCode == 200) {
data = Buffer.from(data_hex, 'hex');
} else if (res.statusCode == 404) {
var errpage = doErrorPage(404, "The service could not find the requested ROM on zefie's server.")
headers = errpage[0];
data = errpage[1];
} else {
var errpage = doErrorPage(400)
headers = errpage[0];
data = errpage[1];
}
sendToClient(socket, headers, data);
});
});
req.end();
} else {
// use local flashrom files);
var flashrom_file_path = service_dir + '/' + request_path;
try {
fs.readFile(flashrom_file_path, null, function (err, data) {
if (err) {
errpage = doErrorPage(400)
headers = errpage[0];
data = err.toString();
}
sendToClient(socket, headers, data);
});
} catch (e) {
var errpage = doErrorPage(404, "The service could not find the requested ROM.")
headers = errpage[0];
data = errpage[1];
sendToClient(socket, headers, data);
}
}
} else {
// no support for bf0app yet, but here we send the client to initiate-lc2-download
// to get the rom image
if (request_headers.query.path) {
headers += "Content-type: text/html\n"
headers += "wtv-visit: wtv-flashrom:/initiate-lc2-download?path=" + request_headers.query.path;
data = '';
} else {
var errpage = doErrorPage(404)
headers = errpage[0];
data = errpage[1];
}
sendToClient(socket, headers, data);
}

View File

@@ -2,11 +2,106 @@
// - ready query param to get flashrom path, check for its existance
// - handle last part to redirect to lc2-download-complete
// - handle failures
request_is_async = true;
headers = `200 OK
if (!request_headers.query.path) {
var errpage = doErrorPage(400);
headers = errpage[0];
data = errpage[1];
} else {
var request_path = unescape(request_headers.query.path);
if (services_configured.services[service_name].use_zefie_server) {
// read first 256 bytes of flashrom file from archive.midnightchannel.net
// to get `flashrom_message` and `numparts` if missing
var options = {
host: "archive.midnightchannel.net",
path: "/zefie/files/wtv-flashrom/" + request_path,
method: 'GET',
timeout: 5000,
headers: {
'Range': 'bytes=0-256'
}
}
var chunk;
const req = https.request(options, function (res) {
var data = '';
res.setEncoding('hex');
res.on('data', function (d) {
data += d;
});
res.on('error', function (e) {
console.log(" * Upstream FlashROM Error:", e);
var errpage = doErrorPage(400)
headers = errpage[0];
data = errpage[1];
sendToClient(socket, headers, data);
});
res.on('end', function () {
if (res.statusCode == 206) {
var flashrom_message = new Buffer.from(data.substring(36 * 2, 68 * 2), 'hex').toString('ascii').replace(/[^0-9a-z\ \.\-]/gi, "");
processLC2DownloadPage(request_headers.query.path, flashrom_message, (request_headers.query.numparts || null));
return;
} else if (res.statusCode == 404) {
var errpage = doErrorPage(404, "The service could not find the requested ROM on zefie's server.")
headers = errpage[0];
data = errpage[1];
} else {
var errpage = doErrorPage(400)
headers = errpage[0];
data = errpage[1];
}
sendToClient(socket, headers, data);
});
});
req.end();
} else {
// use local flashrom files
var flashrom_file_path = service_dir + '/' + request_path;
fs.readFile(flashrom_file_path, null, function (err, data) {
try {
var data_128 = new Buffer.alloc(128);
data.copy(data_128, 0, 0, 128);
var flashrom_message = new Buffer.from(data_128.toString('hex').substring(36 * 2, 68 * 2), 'hex').toString('ascii').replace(/[^0-9a-z\ \.\-]/gi, "");
processLC2DownloadPage(request_headers.query.path, flashrom_message, (request_headers.query.numparts || null));
} catch (e) {
var errpage = doErrorPage(404, "The service could not find the requested ROM.")
headers = errpage[0];
data = errpage[1];
sendToClient(socket, headers, data);
}
});
}
}
async function processLC2DownloadPage(path, flashrom_message, numparts = null) {
if (numparts != null) var flashrom_numparts = parseInt(numparts);
if (!flashrom_numparts) flashrom_numparts = flashrom_message.substring(flashrom_message.length - 4).replace(/\D/g, '');
var ind = new Array();
ind[0] = (path.indexOf("part") + 4);
ind[1] = (path.indexOf(".", ind[0]) + 1);
var flashrom_part_num = path.substr(ind[0], (path.length - ind[1]));
var flashrom_lastpart = (flashrom_numparts == (parseInt(flashrom_part_num) + 1)) ? true : false;
var flashrom_rompath = 'wtv-flashrom:/get-by-path?path=' + path + '&raw=true';
var flashrom_isboot = (/\.brom$/).test(path);
if (flashrom_lastpart) {
flashrom_next_rompath = "wtv-flashrom:/lc2-download-complete?";
} else {
var flashrom_next_part_num = (parseInt(flashrom_part_num) + 1);
if (flashrom_next_part_num < 10) flashrom_next_part_num = "00" + flashrom_next_part_num; // 1s
else if (flashrom_next_part_num >= 10 && flashrom_next_part_num < 100) flashrom_next_part_num = "0" + flashrom_next_part_num; // 10s
var flashrom_next_rompath = flashrom_rompath.replace("part"+flashrom_part_num, "part"+flashrom_next_part_num).replace('get-by-path', 'get-lc2-page').replace("&raw=true", "&numparts=" + parseInt(flashrom_numparts));
}
if (!flashrom_part_num || !flashrom_lastpart || !flashrom_rompath || !flashrom_next_rompath || !flashrom_isboot) {
headers = `200 OK
Content-type: text/html`
data = `<html>
data = `<html>
<head>
<title>
Updating
@@ -18,18 +113,22 @@ hspace=0 vspace=0 fontsize="large">
<table cellspacing=0 cellpadding=0>
<tr>
<td width=104 height=74 valign=middle align=center bgcolor="3B3A4D">
<img src="wtv-flashrom:/ROMCache/HackTVLogoJewel.gif" width=87 height=67>
<td width=20 valign=top align=left bgcolor="3B3A4D">
<img src="wtv-flashrom:/ROMCache/Spacer.gif" width=1 height=1>
<td colspan=10 width=436 valign=middle align=left bgcolor="3B3A4D">
<font color="D6DFD0" size="+2">
<blackface>
<shadow>
<img src="wtv-flashrom:/ROMCache/Spacer.gif" width=1 height=4>
<br>
Updating now...
Updating now
</shadow>
</blackface>
</font>
<tr>
<td colspan=12 width=560 height=10 valign=top align=left>
<img src="wtv-flashrom:/ROMCache/S40H1.gif" width=560 height=6>
<tr>
<td width=104 height=10 valign=top align=left>
<td width=20 valign=top align=left>
@@ -49,38 +148,37 @@ Updating now...
<td width=20 valign=middle align=center>
<td colspan=9 width=100 height=258 valign=top align=left>
<font size=+1>
Your Internet Receiver is being<br>updated automatically.
Your WebTV Unit is being<br>updated automatically.
<p> <font size=+1>
This will take a while, and then<br> your unit will reboot.<br><br>
This will take a while, and<br>then you can use your WebTV again.
`;
if (flashrom_isboot && flashrom_part == 16) {
data += `<p>
if (flashrom_isboot && parseInt(flashrom_part_num) == 16) {
data += `<p>
The system will pause for about 30 seconds at the end of this
update. Please <strong>do not</strong> interrupt the system
during this time.
`
}
data += `</font>
</table>
<table width="100%">
<tr>
<td align="left"><font size="-1" color="#D6DFD0"><small>&nbsp; &nbsp; Receiving part ${flashrom_part} of ${flashrom_total_parts}</small></font></td>
<td align="right"><font size="-1" color="#D6DFD0"><small>v${flashrom_version} (${flashrom_type}) &nbsp; &nbsp;</small></font></td>
</tr>
</table>
<center>
<upgradeblock width=520 height=15
${nextrompath}
errorurl="wtv-flashrom:/lc2-download-failed"
blockurl="wtv-flashrom:/${flashrom_rompath}
lastblock=${flashrom_lastpart}
curblock="${flashrom_part}"
totalblocks="${flashrom_total_parts}"></center>
}
data += `
</font>
<br><br><br><br><br>
<upgradeblock width=280 height=15
nexturl="${flashrom_next_rompath}"
errorurl="wtv-flashrom:/lc2-download-failed?"
blockurl="${flashrom_rompath}"
lastblock="${flashrom_lastpart}"
curblock="` + (parseInt(flashrom_part_num) + 1) + `"
totalblocks="${flashrom_numparts}">
<font size="-1" color="#D6DFD0">
<br>
<img src="wtv-flashrom:/ROMCache/Spacer.gif" width=2 height=10><br>
${flashrom_message}
<br><br>
<tr>
<td width=104 valign=middle align=center>
<td width=20 valign=middle align=center>
<td colspan=10 height=2 valign=middle align=center bgcolor="#191919">
<img src="wtv-flashrom:/ROMCache/Spacer.gif" width=436 height=1>
<tr>
<td width=104 valign=middle align=center>
<td width=20 valign=middle align=center>
@@ -89,6 +187,7 @@ totalblocks="${flashrom_total_parts}"></center>
<td width=104 valign=middle align=center>
<td width=20 valign=middle align=center>
<td colspan=10 height=2 valign=top align=left bgcolor="#191919">
<img src="wtv-flashrom:/ROMCache/Spacer.gif" width=436 height=1>
<tr>
<td width=104 valign=middle align=center>
<td width=20 valign=middle align=center>
@@ -109,4 +208,11 @@ totalblocks="${flashrom_total_parts}"></center>
<td width=20 valign=middle align=center>
</table>
</body>
</html>`
</html>`;
} else {
var errpage = doErrorPage(400)
headers = errpage[0];
data = errpage[1];
}
sendToClient(socket, headers, data);
}

View File

@@ -0,0 +1,11 @@
if (request_headers.query.path) {
headers = "300 OK\n";
headers += "wtv-visit: wtv-flashrom:/get-lc2-page?path=" + request_headers.query.path + "\n";
headers += "Location: wtv-flashrom:/get-lc2-page?path=" + request_headers.query.path + "\n";
headers += "Content-type: text/html";
data = '';
} else {
var errpage = doErrorPage(400)
headers = errpage[0];
data = errpage[1];
}

View File

@@ -23,7 +23,7 @@ hspace=0 vspace=0 fontsize="large">
<table cellspacing=0 cellpadding=0>
<tr>
<td width=104 height=74 valign=middle align=center bgcolor="3B3A4D">
<img src="wtv-flashrom:/ROMCache/MSNLogo.gif" width=87 height=67>
<img src="wtv-flashrom:/ROMCache/HackTVLogoJewel.gif" width=87 height=67>
<td width=20 valign=top align=left bgcolor="3B3A4D">
<img src="wtv-flashrom:/ROMCache/Spacer.gif" width=1 height=1>
<td colspan=10 width=436 valign=middle align=left bgcolor="3B3A4D">

View File

@@ -1,50 +0,0 @@
<html>
<head>
<title>
Updating failed
</title>
<display switchtowebmode transition=none nostatus nooptions skipback clearback>
</head>
<body noscroll bgcolor="#191919" text="#42CC55" link="36d5ff"
hspace=0 vspace=0 fontsize="large">
<table cellspacing=0 cellpadding=0>
<tr>
<td width=104 height=74 valign=middle align=center bgcolor="3B3A4D">
<img src="wtv-flashrom:/ROMCache/MSNLogo.gif" width=87 height=67>
<td width=20 valign=top align=left bgcolor="3B3A4D">
<img src="wtv-flashrom:/ROMCache/Spacer.gif" width=1 height=1>
<td colspan=10 width=436 valign=middle align=left bgcolor="3B3A4D">
<font color="D6DFD0" size="+2">
<blackface>
<shadow>
<img src="wtv-flashrom:/ROMCache/Spacer.gif" width=1 height=4>
<br>
Updated failed
</shadow>
</blackface>
</font>
<tr>
<td colspan=12 width=560 height=10 valign=top align=left>
<img src="wtv-flashrom:/ROMCache/S40H1.gif" width=560 height=6>
<tr>
<td width=104 height=10 valign=top align=left>
<td width=20 valign=top align=left>
<td width=67 valign=top align=left>
<td width=20 valign=top align=left>
<td width=67 valign=top align=left>
<td width=20 valign=top align=left>
<td width=67 valign=top align=left>
<td width=20 valign=top align=left>
<td width=67 valign=top align=left>
<td width=20 valign=top align=left>
<td width=68 valign=top align=left>
<td width=20 valign=top align=left>
<form action="client:poweroff">
<tr>
<td width=104 valign=middle align=center>
<td width=20 valign=middle align=center>
<td colspan=9 width=100 height=258 valign=top align=left>
<font size=+1>
Update failed, gomennasai.
</body>
</html>

View File

@@ -0,0 +1,140 @@
var error = '';
if (request_headers.query.error) {
switch (request_headers.query.error) {
case "1":
error = "uncompression failed";
break;
case "2":
error = "upgrade write failed";
break;
case "3":
error = "signature verification failed";
break;
case "4":
error = "cannot upgrade bootstrap";
break;
case "5":
error = "out of memory";
break;
case "-7":
error = "response error";
break;
case "-20":
error = "timed out";
break;
case "99":
error = "test code";
break;
default:
error = "unknown error";
break;
}
}
var try_again_url = 'wtv-flashrom:/willie';
var try_again_url_path = ''
var try_again_url_start_time = parseInt(new Date().toUTCString()) / 1000;
headers = `200 OK
Content-type: text/html`
data = `<html>
<head>
<display switchtowebmode nooptions nostatus skipback clearback>
<title>Update failed</title>
</head>
<body noscroll bgcolor="#191919" text="#42CC55" link="36d5ff"
hspace=0 vspace=0 transition=none fontsize="large">
<table cellspacing=0 cellpadding=0>
<tr>
<td width=104 height=74 valign=middle align=center bgcolor="3B3A4D">
<img src="wtv-flashrom:/ROMCache/HackTVLogoJewel.gif" width=87 height=67>
<td width=20 valign=top align=left bgcolor="3B3A4D">
<img src="wtv-flashrom:/ROMCache/Spacer.gif" width=1 height=1>
<td colspan=10 width=436 valign=middle align=left bgcolor="3B3A4D">
<font color="D6DFD0" size="+2">
<blackface>
<shadow>
<img src="wtv-flashrom:/ROMCache/Spacer.gif" width=1 height=4>
<br>
Updating failed
</shadow>
</blackface>
</font>
<tr>
<td colspan=12 width=560 height=10 valign=top align=left>
<img src="wtv-flashrom:/ROMCache/S40H1.gif" width=560 height=6>
<tr>
<td width=104 height=10 valign=top align=left>
<td width=20 valign=top align=left>
<td width=67 valign=top align=left>
<td width=20 valign=top align=left>
<td width=67 valign=top align=left>
<td width=20 valign=top align=left>
<td width=67 valign=top align=left>
<td width=20 valign=top align=left>
<td width=67 valign=top align=left>
<td width=20 valign=top align=left>
<td width=68 valign=top align=left>
<td width=20 valign=top align=left>
<form action="${try_again_url}">
<input type="hidden" name="clear_cache" value="true">
<tr>
<td width=104 valign=middle align=center>
<td width=20 valign=middle align=center>
<td colspan=9 width=100 height=258 valign=top align=left>
<font size=+1>
We ran into a technical problem while updating
your unit. (Error: ${error})
Choose <b>Try Again</b> to try again now.
<p><font size=+1>Press the <b>power</b> button to switch off your unit.
<tr>
<td width=104 valign=middle align=center>
<td width=20 valign=middle align=center>
<td colspan=10 height=2 valign=middle align=center bgcolor="2B2B2B">
<img src="wtv-flashrom:/ROMCache/Spacer.gif" width=436 height=1>
<tr>
<td width=104 valign=middle align=center>
<td width=20 valign=middle align=center>
<td colspan=9 height=1 valign=top align=left>
<tr>
<td width=104 valign=middle align=center>
<td width=20 valign=middle align=center>
<td colspan=10 height=2 valign=top align=left bgcolor="0D0D0D">
<img src="wtv-flashrom:/ROMCache/Spacer.gif" width=436 height=1>
<tr>
<td width=104 valign=middle align=center>
<td width=20 valign=middle align=center>
<td colspan=9 height=4 valign=top align=left>
<tr>
<td width=104 valign=middle align=center>
<td width=20 valign=middle align=center>
<td colspan=9 width=416 valign=top align=left>
<table cellspacing=0 cellpadding=0>
<tr>
<td width=306 valign=top align=left>
<font size="-1">
<i>
</i>
</font>
<td width=112 valign=top align=right>
<font size="-1" color="#E7CE4A">
<shadow>
<input selected
name="Try Again"
value="Try Again"
type=submit Value=TryAgain name="Try Again"
borderimage="file://ROM/Borders/ButtonBorder2.bif" usestyle width=110>
</shadow>
</font>
</form>
</table>
<td width=20 valign=middle align=center>
</table>
</body>
</html>`;

View File

@@ -1,35 +0,0 @@
// willie is just a graphical frontend to a list of ROMs
// the rest of the scripts should work if you manually link to a ROM, and actually have it.
var proxy_query = '';
if (query['flash']) delete query['flash'];
if (query['vflash']) delete query['vflash'];
for (const [key, value] of Object.entries(query)) {
proxy_query += "&" + key + "=" + value;
}
console.log(proxy_query);
var options = {
host: "wtv.zefie.com",
path: "/willie.php?pflash=" + getSessionData(socket_session_data[socket.id].ssid, 'wtv-client-rom-type') + proxy_query,
method: 'GET'
}
headers = "200 OK\nContent-type: text/html";
const req = http.request(options, function (res) {
data = '';
console.log(` * Upstream HTTP StatusCode: ${res.statusCode}`)
res.on('data', d => {
data += d;
})
res.on('end', function () {
sendToClient(socket, headers, data);
});
});
req.end();

View File

@@ -0,0 +1,50 @@
// willie is just a graphical frontend to a list of ROMs
// the rest of the scripts should work if you manually link to a ROM, and actually have it.
request_is_async = true;
var proxy_query = '';
if (request_headers.query.flash) delete request_headers.query.flash;
if (request_headers.query.vflash) delete request_headers.query.vflash;
if (request_headers.query.pflash) delete request_headers.query.pflash;
for (const [key, value] of Object.entries(request_headers.query)) {
proxy_query += "&" + key + "=" + value;
}
if (!services_configured.services[service_name].use_zefie_server) {
proxy_query += "&minisrv_local_mode=true";
}
var options = {
host: "wtv.zefie.com",
path: "/willie.php?minisrv=true&pflash=" + getSessionData(socket_session_data[socket.id].ssid, 'wtv-client-rom-type') + proxy_query,
timeout: 5000,
method: 'GET'
}
headers = "200 OK\nContent-type: text/html";
const req = https.request(options, function (res) {
data = '';
res.on('data', d => {
data += d;
});
res.on('error', function (e) {
if (!zquiet) console.log(" * Upstream Ultra Willies HTTP Error:", e);
var errpage = doErrorPage(400)
headers = errpage[0];
data = errpage[1];
sendToClient(socket, headers, data);
});
res.on('end', function () {
if (!zquiet) console.log(" * Upstream Ultra Willies HTTP Response:", res.statusCode, res.statusMessage);
if (request_headers.query.clear_cache) {
headers += "\nwtv-expire-all: wtv-flashrom";
}
sendToClient(socket, headers, data);
});
});
req.end();

View File

@@ -2,10 +2,10 @@ var challenge_response, challenge_header = '';
var gourl;
if (socket_session_data[socket.id].ssid !== null) {
if (request_headers['wtv-ticket']) {
if (request_headers['wtv-ticket'].length > 8) {
DecodeTicket(request_headers['wtv-ticket']);
socket_session_data[socket.id].wtvsec.ticket_b64 = request_headers['wtv-ticket'];
if (request_headers["wtv-ticket"]) {
if (request_headers["wtv-ticket"].length > 8) {
DecodeTicket(request_headers["wtv-ticket"]);
socket_session_data[socket.id].wtvsec.ticket_b64 = request_headers["wtv-ticket"];
//socket_session_data[socket.id].secure == true;
}
} else if (socket_session_data[socket.id].wtvsec.ticket_b64 == null) {

View File

@@ -2,10 +2,9 @@ var challenge_response, challenge_header = '';
var gourl;
if (socket_session_data[socket.id].ssid != null && !getSessionData(socket_session_data[socket.id].ssid, 'wtvsec_login')) {
var wtvsec_login = new WTVSec();
wtvsec_login = new WTVSec();
var wtvsec_login = new WTVSec(1,zdebug);
wtvsec_login.IssueChallenge();
wtvsec_login.set_incarnation(request_headers['wtv-incarnation']);
wtvsec_login.set_incarnation(request_headers["wtv-incarnation"]);
setSessionData(socket_session_data[socket.id].ssid, 'wtvsec_login', wtvsec_login)
} else {
var wtvsec_login = getSessionData(socket_session_data[socket.id].ssid, 'wtvsec_login')
@@ -13,23 +12,23 @@ if (socket_session_data[socket.id].ssid != null && !getSessionData(socket_sessio
if (socket_session_data[socket.id].ssid !== null) {
if (wtvsec_login.ticket_b64 == null) {
if (request_headers['wtv-ticket']) {
if (request_headers['wtv-ticket'].length > 8) {
wtvsec_login.DecodeTicket(request_headers['wtv-ticket']);
wtvsec_login.ticket_b64 = request_headers['wtv-ticket'];
if (request_headers["wtv-ticket"]) {
if (request_headers["wtv-ticket"].length > 8) {
wtvsec_login.DecodeTicket(request_headers["wtv-ticket"]);
wtvsec_login.ticket_b64 = request_headers["wtv-ticket"];
//socket_session_data[socket.id].secure = true;
}
} else {
challenge_response = wtvsec_login.challenge_response;
var client_challenge_response = request_headers['wtv-challenge-response'] || null;
var client_challenge_response = request_headers["wtv-challenge-response"] || null;
if (challenge_response && client_challenge_response) {
//if (challenge_response.toString(CryptoJS.enc.Base64).substring(0,85) == client_challenge_response.substring(0,85)) {
if (challenge_response.toString(CryptoJS.enc.Base64) == client_challenge_response) {
console.log(" * wtv-challenge-response success for "+socket_session_data[socket.id].ssid);
console.log(" * wtv-challenge-response success for " + processSSID(socket_session_data[socket.id].ssid));
wtvsec_login.PrepareTicket();
//socket_session_data[socket.id].secure = true;
} else {
console.log(" * wtv-challenge-response FAILED for " + socket_session_data[socket.id].ssid);
console.log(" * wtv-challenge-response FAILED for " + processSSID(socket_session_data[socket.id].ssid));
if (zdebug) console.log("Response Expected:", challenge_response.toString(CryptoJS.enc.Base64));
if (zdebug) console.log("Response Received:", client_challenge_response)
gourl = "wtv-head-waiter:/login?reissue_challenge=true";
@@ -54,7 +53,7 @@ else {
var nickname = 'HackTVUsr_' + namerand;
var userid = '1'+ Math.floor(Math.random() * 1000000000000000000);
var offline_user_list = CryptoJS.enc.Latin1.parse("<user-list>\n\t<user userid=\"" + userid + " user-name=\"" + nickname + "\" first-name=\"HackTV\" last-name=\"User \"" + namerand + "\" password=\"\" mail-enabled=\"true\" />\n</user-list>").toString(CryptoJS.enc.Base64);
data = '';
headers = `200 OK
Connection: Keep-Alive
wtv-encrypted: true
@@ -80,10 +79,10 @@ wtv-messenger-enable: 0
wtv-noback-all: wtv-
wtv-service: reset
`+ getServiceString('all') + `
wtv-boot-url: wtv-1800:/preregister?relogin=true
wtv-ssl-certs-download-url: wtv-head-waiter:/ssl-cert.der
wtv-ssl-certs-checksum: 473926DC1B11F635A6B920953FDCDE6A
wtv-user-name: `+ nickname + `
wtv-boot-url: wtv-1800:/preregister?relogin=true`
//wtv-ssl-certs-download-url: wtv-head-waiter:/ssl-cert.der
//wtv-ssl-certs-checksum: 473926DC1B11F635A6B920953FDCDE6A
headers += `wtv-user-name: `+ nickname + `
wtv-human-name: `+ nickname + `
wtv-irc-nick: `+ nickname + `
wtv-home-url: wtv-home:/home?

View File

@@ -2,17 +2,17 @@ var challenge_response, challenge_header = '';
if (socket_session_data[socket.id].ssid !== null) {
var wtvsec_login = getSessionData(socket_session_data[socket.id].ssid, 'wtvsec_login');
if (request_headers['wtv-ticket']) {
if (request_headers["wtv-ticket"]) {
if (wtvsec_login.ticket_b64 == null) {
if (request_headers['wtv-ticket'].length > 8) {
wtvsec_login.DecodeTicket(request_headers['wtv-ticket']);
wtvsec_login.ticket_b64 = request_headers['wtv-ticket'];
if (request_headers["wtv-ticket"].length > 8) {
wtvsec_login.DecodeTicket(request_headers["wtv-ticket"]);
wtvsec_login.ticket_b64 = request_headers["wtv-ticket"];
}
}
} else {
if (wtvsec_login) {
challenge_response = wtvsec_login.challenge_response;
var client_challenge_response = request_headers['wtv-challenge-response'] || null;
var client_challenge_response = request_headers["wtv-challenge-response"] || null;
if (challenge_response && client_challenge_response) {
if (challenge_response.toString(CryptoJS.enc.Base64).substring(0, 85) == client_challenge_response.substring(0, 85)) {
console.log(" * wtv-challenge-response success for " + socket_session_data[socket.id].ssid);

View File

@@ -13,7 +13,7 @@ if (getSessionData(socket_session_data[socket.id].ssid, 'box-does-psuedo-encrypt
data =`<html>
<head>
<title>Home for minisrv</title>
<DISPLAY showwhencomplete options showoptions noscroll>
<DISPLAY NoLogo NoStatus hideoptions noscroll>
</head>
<body bgcolor="black" link="gold" vlink="gold" alink="gold" text="gold">
<script>
@@ -24,26 +24,26 @@ function go() {
<h2>Welcome to `+ z_title + `</h2>
<h3>Encryption Status: `+cryptstatus+`</h3>`
data += `<h4>Working stuff</h4>
<a href="client:relog">client:relog (direct)</a><br>
<a href="wtv-tricks:/blastcache?return_to=wtv-home:/home">Clear Cache</a><br>
<form name=access onsubmit="go()">
<input name=url `;
<ul>
<li><a href="client:relog">client:relog (direct)</a></li>
<li><a href="wtv-tricks:/blastcache?return_to=wtv-home:/home">Clear Cache</a></li>
<li><a href="wtv-flashrom:/willie" selected>Ultra Willies</a></li>
<li><a href="wtv-music:/demo/index">MIDI Music Demo</a></li>
<li><a href="http://duckduckgo.com/lite/">DuckDuckGo Lite</a></li>
<li><input name=url `;
if (query['url']) {
data += "value='"+unescape(query['url'])+"'";
if (request_headers.query.url) {
data += "value='" + unescape(request_headers.query.url)+"'";
}
data += `width=250 bgcolor=#444444 text=#ffdd33 cursor=#cc9933 selected>
<input type=submit value="Access URL" borderstyle="ButtonBorder2.bif">
</form>
<input type=submit value="Access URL">
</form></li>
</ul>
<h4>zefie's server only</h4>
<h4>Developer Playground</h4>
<a href="wtv-home:/zefie">zefie's stuff and things</a>
<h4>Test Stuff (probably broken)</h4>
<a href="wtv-update:/update?">HackTV Updater Test</a><br>
<a href="wtv-flashrom:/willie">Ultra Willies</a><br>
<a href="client:showalert?message=If%20you%20choose%20to%20disconnect%20and%20return%20to%20HackTV%20home%2C%20you%20may%20not%20be%20able%20to%20reconnect%20to%20the%20update%20server%20until%20you%20power%20cycle%20your%20box.%3Cbr%3E%3Cbr%3EAre%20you%20sure%20you%20would%20like%20to%20go%20offline%3F&buttonlabel1=No&buttonaction1=client:donothing&buttonlabel2=Yes&buttonaction2=wtv-tricks%3A%2Fgo-offline%3Ftitle%3DHackTV%2520Home">Disconnect and go to HackTV Home</a><br>
</body>
</html>`

View File

@@ -1,6 +1,7 @@
200 OK
Connection: Keep-Alive
wtv-expire-all: wtv-
wtv-expire-all: http
Content-type: text/html
<html>

View File

@@ -5,14 +5,20 @@
</head>
<body bgcolor="black" link="gold" vlink="gold" alink="gold" text="gold">
<h3>zefie's playgrounf</h3>
<h3>Dev playground</h3>
Moved these off the main page to clean it up :)<br>
The stuff on this page is probably useless to you so why not move it off the main page.
The stuff on this page is probably useless to you so why not move it off the main page.<br /><br />
Content here is either not pushed to git (Not Found error), or not fully functional yet (Other errors).
<h4>Just for fun</h4>
<ul>
<li><a href="wtv-music:/content/index.html">Music Collection</a></li>
<li><a href="wtv-music:/midi/index.html">Matt Test</a></li>
<ul>
</ul>
<h4>Test Stuff (probably broken)</h4>
<a href="wtv-update:/update?">HackTV Updater Test</a><br>
<a href="client:showalert?message=If%20you%20choose%20to%20disconnect%20and%20return%20to%20HackTV%20home%2C%20you%20may%20not%20be%20able%20to%20reconnect%20to%20the%20update%20server%20until%20you%20power%20cycle%20your%20box.%3Cbr%3E%3Cbr%3EAre%20you%20sure%20you%20would%20like%20to%20go%20offline%3F&buttonlabel1=No&buttonaction1=client:donothing&buttonlabel2=Yes&buttonaction2=wtv-tricks%3A%2Fgo-offline%3Ftitle%3DHackTV%2520Home">Disconnect and go to HackTV Home</a<br>
</body>
</html>

View File

@@ -1,18 +1,53 @@
// write posted log data to disk. should be decrypted by this point (if it was encrypted) if the crypto stream didn't break
if (request_headers['post_data']) {
var fullpath = __dirname + "/ServiceLogPost/" + Math.floor(new Date().getTime() / 1000) + "_" + query['type'];
if (socket_session_data[socket.id].ssid) fullpath += "_" + socket_session_data[socket.id].ssid;
fullpath = fullpath.replace(/\\/g, "/");
fs.writeFileSync(fullpath, request_headers['post_data'].toString(CryptoJS.enc.Hex), "Hex");
console.log("Wrote POST log data from", socket_session_data[socket.id].ssid, "to", fullpath, "on", socket.id);
}
request_is_async = true;
headers = `200 OK
if (request_headers.post_data) {
headers = `200 OK
Connection: Keep-Alive
Content-length: 0`;
data = '';
data = '';
var fullpath = __dirname + "/ServiceLogPost/" + Math.floor(new Date().getTime() / 1000) + "_" + request_headers.query.type;
if (socket_session_data[socket.id].ssid) fullpath += "_" + socket_session_data[socket.id].ssid;
fullpath += ".txt";
fullpath = fullpath.replace(/\\/g, "/");
var logdata_outstring = '';
Object.keys(request_headers.query).forEach(function (k) {
logdata_outstring += k + "=" + unescape(request_headers.query[k].toString()) + "\r\n";
});
logdata_outstring += "\r\n";
var logdata_outstring_hex = Buffer.from(logdata_outstring, 'utf8').toString('hex');
logdata_outstring_hex += request_headers.post_data.toString(CryptoJS.enc.Hex);
if (services_configured.services[service_name].write_logs_to_disk) {
fs.writeFile(fullpath, logdata_outstring_hex, "Hex", function () {
if (!zquiet) console.log(" * Wrote POST log data from", processSSID(socket_session_data[socket.id].ssid), "for", socket.id);
sendToClient(socket, headers, data);
});
} else {
sendToClient(socket, headers, data);
}
} else {
headers = `200 OK
Connection: Keep-Alive
Content-length: 0`;
data = '';
var logdata_outstring = '';
Object.keys(request_headers.query).forEach(function (k) {
logdata_outstring += k + "=" + unescape(request_headers.query[k].toString()) + "\r\n";
});
var logdata_outstring_hex = Buffer.from(logdata_outstring, 'utf8').toString('hex');
if (services_configured.services[service_name].write_logs_to_disk) {
fs.writeFile(fullpath, logdata_outstring_hex, "Hex", function () {
if (!zquiet) console.log(" * Wrote GET log data from", processSSID(socket_session_data[socket.id].ssid), "for", socket.id);
sendToClient(socket, headers, data);
});
} else {
sendToClient(socket, headers, data);
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -0,0 +1,156 @@
<html>
<head>
<title>
WebTV Music Index
</title>
<display switchtowebmode transition=none>
</head>
<body bgcolor="#171726" text="#82A9D9" link="#9DEFFF" vlink="#597DAA" alink="#9DEFFF" hspace=0 vspace=0 fontsize="small" logo="webtv.gif" address="WebTV Music Index">
<sidebar width="115" border="0">
<table border=0 cellspacing=0 cellpadding=0>
<tr>
<td width=120 height=75 valign=middle align=center bgcolor="3B3A4D" colspan=3>
<a href="wtv-home:/home">
<img src="hacktv4.gif" border="0">
</a>
<tr>
<td width=5>
<tr>
<td bgcolor=#4A525A height=2 width=104 colspan=3>
<tr>
<td width=10 height=26>
<td width=105 valign=middle>
<table cellspacing=0 cellpadding=0 href="client:showalert?message=%3Cfont%20size%3D%22small%22%3EPlease%20download%20HackTV%20from%3Cbr%3E%3Cbr%3E%3Ccenter%3Ehttp%3A%2F%2Fturdinc.kicks-ass.net%2FMsntv%2F%3C%2Fcenter%3E%3Cbr%3E%3Cbr%3Efor%20the%20complete%20WebTV%20Music%20Experience%21%3C%2Ffont%3E&image=wtv-star:/images/HackTVLogoJewel.gif&buttonlabel1=Okay&buttonaction1=client:donothing">
<tr>
<td height=1>
<tr>
<td><shadow><strike><font sizerange=medium color=#E6CD4A>Karaoke</font></strike></shadow>
</table>
<tr>
<td width=5>
<tr>
<td bgcolor=#4A525A height=2 width=104 colspan=3>
<tr>
<td width=10 height=26>
<td width=105 valign=middle>
<table cellspacing=0 cellpadding=0 href="client:showalert?message=%3Cfont%20size%3D%22small%22%3EPlease%20download%20HackTV%20from%3Cbr%3E%3Cbr%3E%3Ccenter%3Ehttp%3A%2F%2Fturdinc.kicks-ass.net%2FMsntv%2F%3C%2Fcenter%3E%3Cbr%3E%3Cbr%3Efor%20the%20complete%20WebTV%20Music%20Experience%21%3C%2Ffont%3E&image=wtv-star:/images/HackTVLogoJewel.gif&buttonlabel1=Okay&buttonaction1=client:donothing">
<tr>
<td height=1>
<tr>
<td><shadow><strike><font sizerange=medium color=#E6CD4A>BG Music</font></strike></shadow>
</table>
<tr>
<td width=5>
<tr>
<td bgcolor=#4A525A height=2 width=104 colspan=3>
<tr>
<td width=10 height=26>
<td width=105 valign=middle>
<table cellspacing=0 cellpadding=0 href="client:showalert?message=%3Cfont%20size%3D%22small%22%3EPlease%20download%20HackTV%20from%3Cbr%3E%3Cbr%3E%3Ccenter%3Ehttp%3A%2F%2Fturdinc.kicks-ass.net%2FMsntv%2F%3C%2Fcenter%3E%3Cbr%3E%3Cbr%3Efor%20the%20complete%20WebTV%20Music%20Experience%21%3C%2Ffont%3E&image=wtv-star:/images/HackTVLogoJewel.gif&buttonlabel1=Okay&buttonaction1=client:donothing">
<tr>
<td height=1>
<tr>
<td><shadow><strike><font sizerange=medium color=#E6CD4A>Orig Classic</font></strike></shadow>
</table>
<tr>
<td width=5>
<tr>
<td bgcolor=#4A525A height=2 width=104 colspan=3>
<tr>
<td width=10 height=26>
<td width=105 valign=middle>
<table cellspacing=0 cellpadding=0 href="wtv-music:/demo/midi/index">
<tr>
<td height=1>
<tr>
<td><shadow><font sizerange=medium color=#E6CD4A>Midi</font></shadow>
</table>
<tr>
<td width=5>
<tr>
<td bgcolor=#4A525A height=2 width=104 colspan=3>
<tr>
<td width=10 height=26>
<td width=105 valign=middle>
<table cellspacing=0 cellpadding=0 href="client:showalert?message=%3Cfont%20size%3D%22small%22%3EPlease%20download%20HackTV%20from%3Cbr%3E%3Cbr%3E%3Ccenter%3Ehttp%3A%2F%2Fturdinc.kicks-ass.net%2FMsntv%2F%3C%2Fcenter%3E%3Cbr%3E%3Cbr%3Efor%20the%20complete%20WebTV%20Music%20Experience%21%3C%2Ffont%3E&image=wtv-star:/images/HackTVLogoJewel.gif&buttonlabel1=Okay&buttonaction1=client:donothing">
<tr>
<td height=1>
<tr>
<td><shadow><strike><font sizerange=medium color=#E6CD4A>RMF</font></strike></shadow>
</table>
<tr>
<td width=5>
<tr>
<td bgcolor=#4A525A height=2 width=104 colspan=3>
<tr>
<td width=10 height=26>
<td width=105 valign=middle>
<table cellspacing=0 cellpadding=0 href="client:showalert?message=%3Cfont%20size%3D%22small%22%3EPlease%20download%20HackTV%20from%3Cbr%3E%3Cbr%3E%3Ccenter%3Ehttp%3A%2F%2Fturdinc.kicks-ass.net%2FMsntv%2F%3C%2Fcenter%3E%3Cbr%3E%3Cbr%3Efor%20the%20complete%20WebTV%20Music%20Experience%21%3C%2Ffont%3E&image=wtv-star:/images/HackTVLogoJewel.gif&buttonlabel1=Okay&buttonaction1=client:donothing">
<tr>
<td height=1>
<tr>
<td><shadow><strike><font sizerange=medium color=#E6CD4A>Mod</font></strike></shadow>
</table>
<tr>
<td width=5>
<tr>
<td bgcolor=#4A525A height=2 width=104 colspan=3>
</td>
</tr>
</table>
</sidebar>
<table cellspacing=0 cellpadding=0 border=0>
<tr>
<td width=444 height=75 valign=middle align=left bgcolor="3B3A4D" colspan="2">
<font color="D6DFD0" size="+3">
<blackface>
<shadow>
<br>
&nbsp; WebTV Music Index
</shadow>
</blackface>
</font>
</td>
</tr>
<tr>
<td height=2 bgcolor=#4A525A colspan="2"></td>
</tr>
<tr>
<td width=2 bgcolor=#4A525A></td>
<td width=442 valign=top align=left>
<table cellpadding="3">
<tr>
<td>
<table cellspacing=0 cellpadding=0>
<tr>
<td align=center absheight=80>
<font size="+2" color="E7CE4A"><blackface><shadow>
&nbsp;&nbsp;&nbsp&nbsp;&nbsp;&nbsp&nbsp;&nbsp;&nbsp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Select your poison!
<tr>
<td height=4>
</table>
<tr>
<td align=center width=480>
<img src="music.jpg"width="260" height="193"border="2" name="r1" alt="wtv" />
</font>
</td>
</tr>
</table>
</body>
</html>

Some files were not shown because too many files have changed in this diff Show More