wtvsec: use initial key for ticket signing
update: initial work for future ability to update wtv-ticket to client
update: wtv-flashrom: use zefie server only if file does not exist locally (allows both zefie server roms and local roms)
update: wtv-flashrom:/get-lc2-path: experimental 'Cancel Update' button
fix: wtv-tricks:/blastcache: return_to was not unescaped
This commit is contained in:
zefie
2021-07-20 23:44:55 -04:00
parent b07d74d2db
commit 897bf10abb
9 changed files with 92 additions and 47 deletions

View File

@@ -30,7 +30,7 @@ Let us use the URL `wtv-1800:/preregister` as an example. This is what the serve
- Access Asynchronous mode by setting `request_is_async = true;` - 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` - 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. - 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) \] - `./ServiceVault/wtv-1800/preregister.html` \[ [Example](zefie_wtvp_minisrv/ServiceVault/wtv-music/demo/index.html) \]
- HTML match (*HTML mode*) - HTML match (*HTML mode*)
- Like Direct File Mode, but you don't need to append `.html`. - Like Direct File Mode, but you don't need to append `.html`.
- You do not need to do anything special with this format. - You do not need to do anything special with this format.

View File

@@ -1,17 +1,21 @@
if (socket.ssid != null) { if (socket.ssid != null) {
if (ssid_sessions[socket.ssid].get("wtvsec_login")) ssid_sessions[socket.ssid].delete("wtvsec_login"); if (!ssid_sessions[socket.ssid].data_store.wtvsec_login) {
var wtvsec_login = new WTVSec(); ssid_sessions[socket.ssid].data_store.wtvsec_login = new WTVSec();
wtvsec_login.IssueChallenge(); ssid_sessions[socket.ssid].data_store.wtvsec_login.IssueChallenge();
wtvsec_login.set_incarnation(request_headers["wtv-incarnation"]); ssid_sessions[socket.ssid].data_store.wtvsec_login.set_incarnation(request_headers["wtv-incarnation"]);
ssid_sessions[socket.ssid].set("wtvsec_login", wtvsec_login); }
} else {
var errpage = doErrorCode(400);
headers = errpage[0];
data = errpage[1];
} }
if (wtvsec_login) { if (ssid_sessions[socket.ssid].data_store.wtvsec_login) {
var prereg_contype = "text/html"; var prereg_contype = "text/html";
// if relogin, skip tellyscript // if relogin, skip tellyscript
if (request_headers.query.relogin) { // skip tellyscript if (request_headers.query.relogin) { // skip tellyscript
wtvsec_login.ticket_b64 = null; // clear old ticket ssid_sessions[socket.ssid].data_store.wtvsec_login.ticket_b64 = null; // clear old ticket
} }
// if relogin, skip tellyscript // if relogin, skip tellyscript
@@ -34,7 +38,7 @@ if (wtvsec_login) {
headers = `200 OK headers = `200 OK
Connection: Keep-Alive Connection: Keep-Alive
wtv-initial-key: ` + wtvsec_login.challenge_key.toString(CryptoJS.enc.Base64) + ` wtv-initial-key: ` + ssid_sessions[socket.ssid].data_store.wtvsec_login.challenge_key.toString(CryptoJS.enc.Base64) + `
Content-Type: `+ prereg_contype + ` Content-Type: `+ prereg_contype + `
wtv-service: reset wtv-service: reset
` + getServiceString('wtv-1800') + ` ` + getServiceString('wtv-1800') + `

View File

@@ -3,10 +3,31 @@ request_is_async = true;
var request_path = unescape(request_headers.query.path); var request_path = unescape(request_headers.query.path);
headers = "200 OK\n" headers = "200 OK\n"
function doLocalFlashROM(flashrom_file_path) {
// use local flashrom files;
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);
}
}
if (request_headers.query.raw) { if (request_headers.query.raw) {
if ((/\.brom$/).test(request_path)) headers += "Content-Type: binary/x-wtv-bootrom"; // maybe? if ((/\.brom$/).test(request_path)) headers += "Content-Type: binary/x-wtv-bootrom"; // maybe?
else headers += "Content-Type: binary/x-wtv-flashblock"; else headers += "Content-Type: binary/x-wtv-flashblock";
if (minisrv_config.services[service_name].use_zefie_server) { var flashrom_file_path = service_dir + '/' + request_path;
if (minisrv_config.services[service_name].use_zefie_server && !fs.existsSync(flashrom_file_path)) {
// get flashrom files from archive.midnightchannel.net // get flashrom files from archive.midnightchannel.net
var options = { var options = {
host: "archive.midnightchannel.net", host: "archive.midnightchannel.net",
@@ -40,23 +61,7 @@ if (request_headers.query.raw) {
}); });
req.end(); req.end();
} else { } else {
// use local flashrom files); doLocalFlashROM(flashrom_file_path);
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 { } else {
// no support for bf0app yet, but here we send the client to initiate-lc2-download // no support for bf0app yet, but here we send the client to initiate-lc2-download

View File

@@ -4,13 +4,30 @@
// - handle failures // - handle failures
request_is_async = true; request_is_async = true;
function doLocalFlashROM() {
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);
}
});
}
if (!request_headers.query.path) { if (!request_headers.query.path) {
var errpage = doErrorPage(400); var errpage = doErrorPage(400);
headers = errpage[0]; headers = errpage[0];
data = errpage[1]; data = errpage[1];
} else { } else {
var request_path = unescape(request_headers.query.path); var request_path = unescape(request_headers.query.path);
if (minisrv_config.services[service_name].use_zefie_server) { var flashrom_file_path = service_dir + '/' + request_path;
if (minisrv_config.services[service_name].use_zefie_server && !fs.existsSync(flashrom_file_path)) {
// read first 256 bytes of flashrom file from archive.midnightchannel.net // read first 256 bytes of flashrom file from archive.midnightchannel.net
// to get `flashrom_message` and `numparts` if missing // to get `flashrom_message` and `numparts` if missing
var options = { var options = {
@@ -61,20 +78,7 @@ if (!request_headers.query.path) {
req.end(); req.end();
} else { } else {
// use local flashrom files // use local flashrom files
var flashrom_file_path = service_dir + '/' + request_path; doLocalFlashROM(flashrom_file_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);
}
});
} }
} }
@@ -195,7 +199,10 @@ ${flashrom_message}
<tr> <tr>
<td width=104 valign=middle align=center> <td width=104 valign=middle align=center>
<td width=20 valign=middle align=center> <td width=20 valign=middle align=center>
<td colspan=9 width=416 valign=top align=left> <td colspan=9 width=416 valign=top align=right>
<form action="client:gohome">
<input type="submit" value="Cancel Update" text="#CCCCCC" borderimage="file://ROM/Borders/ButtonBorder2.bif">
</form>
<table cellspacing=0 cellpadding=0> <table cellspacing=0 cellpadding=0>
<tr> <tr>
<td width=306 valign=top align=left> <td width=306 valign=top align=left>

View File

@@ -1,6 +1,7 @@
headers =`200 OK headers =`200 OK
Connection: Keep-Alive Connection: Keep-Alive
wtv-expire-all: wtv-home:/splash wtv-expire-all: wtv-home:/splash
wtv-expire-all: wtv-flashrom:
Content-type: text/html` Content-type: text/html`
if (ssid_sessions[socket.ssid].get('box-does-psuedo-encryption')) { if (ssid_sessions[socket.ssid].get('box-does-psuedo-encryption')) {

View File

@@ -6,7 +6,7 @@ Content-type: text/html`
var visit_url = null; var visit_url = null;
if (request_headers.Referer) visit_url = request_headers.Referer; if (request_headers.Referer) visit_url = request_headers.Referer;
else if (request_headers.query.return_to) visit_url = request_headers.query.return_to; else if (request_headers.query.return_to) visit_url = unescape(request_headers.query.return_to);
else visit_url = "client:goback"; else visit_url = "client:goback";
data = `<html> data = `<html>

View File

@@ -453,6 +453,17 @@ async function sendToClient(socket, headers_obj, data) {
headers_obj["Content-Length"] = data.byteLength; headers_obj["Content-Length"] = data.byteLength;
} }
if (ssid_sessions[socket.ssid]) {
if (ssid_sessions[socket.ssid].data_store.wtvsec_login) {
if (ssid_sessions[socket.ssid].data_store.wtvsec_login.ticket_b64) {
if (ssid_sessions[socket.ssid].data_store.update_ticket) {
headers_obj["wtv-ticket"] = ssid_sessions[socket.ssid].data_store.wtvsec_login.ticket_b64;
headers_obj = moveObjectElement("wtv-ticket", "Connection", headers_obj);
ssid_sessions[socket.ssid].data_store.update_ticket = false;
}
}
}
}
// header object to string // header object to string
if (zshowheaders) console.log(" * Outgoing headers on socket ID", socket.id, (await filterSSID(headers_obj))); if (zshowheaders) console.log(" * Outgoing headers on socket ID", socket.id, (await filterSSID(headers_obj)));
@@ -604,6 +615,24 @@ async function processRequest(socket, data_hex, returnHeadersBeforeSecure = fals
}); });
} }
if (ssid_sessions[socket.ssid]) {
if (headers["wtv-ticket"]) {
if (!ssid_sessions[socket.ssid].data_store.wtvsec_login) {
ssid_sessions[socket.ssid].data_store.wtvsec_login = new WTVSec();
ssid_sessions[socket.ssid].data_store.wtvsec_login.IssueChallenge();
ssid_sessions[socket.ssid].data_store.wtvsec_login.set_incarnation(headers["wtv-incarnation"]);
ssid_sessions[socket.ssid].data_store.wtvsec_login.ticket_b64 = headers["wtv-ticket"];
ssid_sessions[socket.ssid].data_store.wtvsec_login.DecodeTicket(ssid_sessions[socket.ssid].data_store.wtvsec_login.ticket_b64);
} else {
if (ssid_sessions[socket.ssid].data_store.wtvsec_login.ticket_b64 != headers["wtv-ticket"]) {
if (zdebug) console.log(" # New ticket from client");
ssid_sessions[socket.ssid].data_store.wtvsec_login.ticket_b64 = headers["wtv-ticket"];
ssid_sessions[socket.ssid].data_store.wtvsec_login.DecodeTicket(ssid_sessions[socket.ssid].data_store.wtvsec_login.ticket_b64);
}
}
}
}
if (returnHeadersBeforeSecure) { if (returnHeadersBeforeSecure) {
headers = await checkForPostData(socket, headers, data, data_hex); headers = await checkForPostData(socket, headers, data, data_hex);
return headers; return headers;

View File

@@ -1,6 +1,6 @@
{ {
"name": "zefie_wtvp_minisrv", "name": "zefie_wtvp_minisrv",
"version": "0.9.1", "version": "0.9.2",
"description": "WebTV Service (WTVP) Emulation Server", "description": "WebTV Service (WTVP) Emulation Server",
"main": "app.js", "main": "app.js",
"homepage": "https://github.com/zefie/zefie_wtvp_minisrv", "homepage": "https://github.com/zefie/zefie_wtvp_minisrv",

View File

@@ -202,7 +202,6 @@
<Content Include="session_data.js"> <Content Include="session_data.js">
<SubType>Code</SubType> <SubType>Code</SubType>
</Content> </Content>
<Content Include="user_config.example.json" />
<Content Include="user_config.json" /> <Content Include="user_config.json" />
<Content Include="wtvsec.js"> <Content Include="wtvsec.js">
<SubType>Code</SubType> <SubType>Code</SubType>