- feature: add SSID whitelist/blacklist as well as IP based SSID auth
- Add user_config_README.md
- Update user_config.example.json
- Update README.md
- update: wtv-1800:/finish-prereg: send tellyscript on relogin if tellyscripts are enabled, and wtv-script-id == 0 (no tellyscript)
- Allow definition of custom ServiceVault paths
- feature: app.js: add `bind_ip` option to specify an IP to bind to, instead of `0.0.0.0`
- feature: custom service logos and better wtv-home:/splash
This commit is contained in:
zefie
2021-07-22 00:45:19 -04:00
parent 45bbcecb72
commit cf00851798
24 changed files with 336 additions and 97 deletions

View File

@@ -16,7 +16,7 @@ This open source server is in alpha status. Use at your own risk.
- wtv-update:/sync for Download-o-Rama style file downloading
### Current issues:
- Occasionally, in certain circumstances, a specific SSID may be unable to reconnect to the server until the server is restarted
- ~~Occasionally, in certain circumstances, a specific SSID may be unable to reconnect to the server until the server is restarted~~ *Hopefully fixed in [v0.9.3](https://github.com/zefie/zefie_wtvp_minisrv/releases/tag/v0.9.3)*
- Mis-configuring wtv-update:/sync DiskMaps may cause units to delete contents of partitions (need more info)
### Won't fix:
@@ -24,25 +24,23 @@ This open source server is in alpha status. Use at your own risk.
- No intentions to support user accounts, registration, or any form of database system
### 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)~~ ***Done***
- ~~Implement HTTP proxy (needs to be able to defluff most of the web, think retro WAP converter)~~ ***Done [v0.7.1](https://github.com/zefie/zefie_wtvp_minisrv/releases/tag/v0.7.1)***
- ~~Flashrom flashing functionality (at least for LC2 and higher)~~ ***Done [v0.8.0](https://github.com/zefie/zefie_wtvp_minisrv/releases/tag/v0.8.0)***
- ~~SSID/IP black/whitelisting (including tying SSID to an IP or multiple IPs)~~ ***Done [v0.9.4](https://github.com/zefie/zefie_wtvp_minisrv/releases/tag/v0.9.4)***
- Flashrom flashing for bf0app old classic (need donor unit)
- SSID/IP black/whitelisting (including tying SSID to an IP or multiple IPs)
- wtv-lzpf support
- (maybe) Proper wtv-star (generic service outage page) support (maybe useful for allowing a unit to multiple sub-minisrvs).
- (maybe) wtvchat stuff
- (probably not) url tokenizer (eg wtv-token-blabla, was mostly to secure service URLs from unintended access, which this server does not aim to do)
### How To Use:
- Install [node.js](https://nodejs.org/en/download/). Be sure to say `Yes` when asked about `Chocolatey`.
- If you have trouble running it on Windows, try a Linux machine, Windows may need a full development enviroment or extra steps.
- Download a snapshot (either of master, or of any commit/branch/relase/tag etc)
- Extract zip somewhere and enter that directory with a command prompt
- Enter `zefie_wtvp_minisrv` subdirectory
- Verify you are in the same directory as `app.js`, then run `npm install`
- Check any configuration, and modify to your liking. Especally `service_ip` (config can be found in `services.json`)
- Check any configuration. Create your override `user_config.json`. Especally `service_ip`. See [user_config_README.md](user_config_README.md) and [user_config.example.json](zefie_wtvp_minisrv/user_config.example.json) for more information.
- **Note:** The intended use is for all custom config to be in `user_config.json` and any custom service files to go in `UserServiceVault`. If you do not care about potential issues with future `git pull`, and will manually add new upstream `config.json` entries, you could use the standard `ServiceVault` and `config.json`
- Run `node app.js`
- If you have trouble running it on Windows, try a Linux machine, Windows may need a full development enviroment or extra steps.
- Test with a WebTV Viewer or connect with a real box
- To connect with a real box, you will need to open ports in your firewall and have a way to connect your WebTV (and preferably reroute 10.0.0.1 to the server)
- See [ServiceVault.md](ServiceVault.md) for a brief introduction to how the service files work

View File

@@ -1,14 +1,17 @@
## Brief ServiceVault Explanation
In `user_config.json`, or `config.json`, under the `config` section:
```
"ServiceVaults": [
"UserServiceVault",
"ServiceVault"
],
```
The `ServiceVaults` entry is an array of Service Vaults to check, in order of priority (topmost = check first). If the path is not absolute, the the server will look in the current directory (of `app.js`). An absolute path can be specified in Linux (`/home/zefie/ServiceVault`) or Windows (`C:\\Users\\zefie\\ServiceVault` or `C:/Users/zefie/ServiceVault`) format.
The server will scan configured ServiceVaults in order of priority and look for files within them.
Currently only 2 Service Vaults are supported, the `User Server Vault` and the `Service Vault`.
The paths to the Service Vaults are user configurable in `user_config.json` or `config.json`
The `User Service Vault` has priority, and files found in that Service Vault will be loaded, even if the
file exists in the `Service Vault`.
Within the Service Vaults, the server 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.

85
user_config_README.md Normal file
View File

@@ -0,0 +1,85 @@
# user_config.json Quick Guide
`user_config.json` is an override file, you do not need to redefine everything that is in `config.json`, just override the values you wish to. You must use the same structure as `config.json`, but can override any value.
---
### `config` section
Some values are available that are not defined in `config.json` by default. I will attempt to cover them here.
```
"service_logo": "WebTVLogoJewel.gif",
"service_splash_logo": "file://ROM/images/SplashLogo1.gif"
```
You can set the image to be loaded in the top left in place of the WebTV or MSN logo, as well as the main Splash image shown on login.
If an absolute path (`wtv-url:/`, `file://` url, or `http(s)://` url) is not passed, the server will search for the specified filename in `wtv-star/images` of any Service Vault. You'll want to keep the filesizes low.
```
"ssid_block_list": [
"8100000000000000",
"8100000000000010"
]
```
This would ban the SSIDs `8100000000000000` and `8100000000000010` from the service, but allow all other SSIDs to connect.
```
"ssid_ip_allow_list": {
"8100000000000000": [
"192.168.1.0/24",
"127.0.0.1"
]
}
```
This would allow `8100000000000000` to connect, despite being on the block list, if it was connecting from the 192.168.1.0/24 Subnet, or from 127.0.0.1.
```
"ssid_allow_list": [
"8100000000000020",
"8100000000000030"
]
```
This would allow only the SSIDs `8100000000000020` and `8100000000000030` to use the service, and block all other SSIDs. Note that if you add an SSID/IP combo to the `ssid_ip_allow_list`, it will allow the SSID even if it is not in the whitelist. This is useful to allow a leaked SSID but only from trusted hosts.
---
### `service` section
```
"wtv-1800" {
"send_tellyscripts": true,
"send_tellyscript_ssid_whitelist": [
"8100000000000000"
]
}
```
This override would enable sending of tellyscripts, but only to the box with SSID `8100000000000000`. The `send_tellyscript_ssid_whitelist` parameter is optional, and if not defined while `send_tellyscripts` is true, the server will simply send tellyscripts to all clients.
```
"wtv-log": {
"write_logs_to_disk": true
}
```
By default the wtv-log:/log service discards any submitted data from the WebTV units. You can override this by setting `write_logs_to_disk` to true, then it will save to the directory named `ServiceLogPost` in the same directory as `app.js`.
```
"wtv-some-custom-service": {
"port": 1609,
"connections": 1
}
```
You can easily define a custom service in your `user_config.json`
```
"wtv-tricks": {
"service_ip": "192.168.1.8",
"port": 1702,
"nobind": true
}
```
The `wtv-tricks` example above shows how you could point a service to another minisrv.
```
"wtv-1800": {
"port": 1715
}
```
The `wtv-1800` example above shows how you could override the default port for a service.
```
"wtv-music": {
"disabled": true
}
```
The `wtv-music` example above shows how you could disable a default service without modifying `config.json`

View File

@@ -14,21 +14,29 @@ if (socket.ssid != null) {
if (ssid_sessions[socket.ssid].data_store.wtvsec_login) {
var prereg_contype = "text/html";
// if relogin, skip tellyscript
if (request_headers.query.relogin) { // skip tellyscript
if (request_headers.query.relogin) { // relogin
ssid_sessions[socket.ssid].data_store.wtvsec_login.ticket_b64 = null; // clear old ticket
}
// if relogin, skip tellyscript
// if relogin and wtv-script-id != 0, skip tellyscript
var romtype, file_path = null;
if (!request_headers.query.relogin && minisrv_config.config.send_tellyscripts) {
var romtype = ssid_sessions[socket.ssid].get("wtv-client-rom-type");
var send_tellyscript = true;
var wtv_script_id = parseInt(ssid_sessions[socket.ssid].get("wtv-script-id"));
if (request_headers.query.relogin && wtv_script_id != 0) send_tellyscript = false;
if (send_tellyscript && minisrv_config.services[service_name].send_tellyscripts) {
if (minisrv_config.services[service_name].send_tellyscript_ssid_whitelist) {
var send_telly_to_ssid = (minisrv_config.services[service_name].send_tellyscript_ssid_whitelist.findIndex(element => element == socket.ssid) != -1)
if (send_telly_to_ssid) romtype = ssid_sessions[socket.ssid].get("wtv-client-rom-type");
} else {
romtype = ssid_sessions[socket.ssid].get("wtv-client-rom-type");
}
}
switch (romtype) {
case "US-LC2-disk-0MB-8MB":
prereg_contype = "text/tellyscript";
if (ssid_sessions[socket.ssid].get("wtv-open-access")) var file_path = __dirname + "/ServiceDeps/premade_tellyscripts/LC2/LC2_OISP_5555732_56k.tok";
// if wtv-open-access: true then client expects OpenISP
if (ssid_sessions[socket.ssid].get("wtv-open-access") == "true") var file_path = __dirname + "/ServiceDeps/premade_tellyscripts/LC2/LC2_OISP_5555732_56k.tok";
else var file_path = __dirname + "/ServiceDeps/premade_tellyscripts/LC2/LC2_WTV_18006138199_56k.tok";
break;

View File

@@ -29,7 +29,7 @@ if (request_headers.query.raw) {
var flashrom_file_path = null;
Object.keys(service_vaults).forEach(function (g) {
if (flashrom_file_path != null) return;
flashrom_file_path = service_vaults[g].path + "/" + service_name + "/" + request_path;
flashrom_file_path = service_vaults[g] + "/" + service_name + "/" + request_path;
if (!fs.existsSync(flashrom_file_path)) flashrom_file_path = null;
});
if (minisrv_config.services[service_name].use_zefie_server && !flashrom_file_path) {

View File

@@ -29,7 +29,7 @@ if (!request_headers.query.path) {
var flashrom_file_path = null;
Object.keys(service_vaults).forEach(function (g) {
if (flashrom_file_path != null) return;
flashrom_file_path = service_vaults[g].path + "/" + service_name + "/" + request_path;
flashrom_file_path = service_vaults[g] + "/" + service_name + "/" + request_path;
if (!fs.existsSync(flashrom_file_path)) flashrom_file_path = null;
});
@@ -123,7 +123,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/HackTVLogoJewel.gif" width=87 height=67>
<img src="`+ minisrv_config.config.service_logo +`" 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

@@ -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/HackTVLogoJewel.gif" width=87 height=67>
<img src="`+ minisrv_config.config.service_logo +`" 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

@@ -51,7 +51,7 @@ data = `<html>
<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>
<img src="`+ minisrv_config.config.service_logo +`" 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

@@ -50,9 +50,9 @@ Content-type: text/html`;
}
else {
var namerand = Math.floor(Math.random() * 100000);
var nickname = 'HackTVUsr_' + namerand;
var nickname = minisrv_config.config.service_name+'_Usr_' + 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);
var offline_user_list = CryptoJS.enc.Latin1.parse("<user-list>\n\t<user userid=\"" + userid + " user-name=\"" + nickname + "\" first-name=\"" + minisrv_config.config.service_name + "User \" last-name=\\" + namerand + "\" password=\"\" mail-enabled=\"true\" />\n</user-list>").toString(CryptoJS.enc.Base64);
data = '';
headers = `200 OK
Connection: Keep-Alive

View File

@@ -44,6 +44,6 @@ data += `width=250 height=10 bgcolor=#444444 text=#ffdd33 cursor=#cc9933 select
</form></li>
</ul>`
if (fs.existsSync(service_vaults[0].path + "/" + service_name + "/home.zefie.html")) {
data += fs.readFileSync(service_vaults[0].path + "/" + service_name + "/home.zefie.html", { 'encoding': 'utf8' });
if (fs.existsSync(service_vaults[0] + "/" + service_name + "/home.zefie.html")) {
data += fs.readFileSync(service_vaults[0] + "/" + service_name + "/home.zefie.html", { 'encoding': 'utf8' });
}

View File

@@ -0,0 +1,36 @@
headers = `200 OK
Connection: Keep-Alive
wtv-expire-all: wtv-
wtv-expire-all: http
Content-type: text/html`
data = `<html>
<head>
<display hideoptions nostatus showwhencomplete skipback clearback fontsize=medium>
<title>Engaging zefie...</title>
<meta http-equiv=Refresh content="5; url=wtv-home:/home?">
</head>
<body bgcolor="#000000" text="#449944">
<bgsound src="file://ROM/Sounds/Splash.mid">
<center>
<spacer type=block height=88 width=21>
<img src="file://ROM/Images/spacer.gif" height=4><br>
<img src="`+ minisrv_config.config.service_splash_logo + `">
<br><br><br>
<p><br>
<p><br>
<table border>
<tr><td width=150>
Mini service
<tr><td>
zefie minisrv v`+ minisrv_config.version;
if (getGitRevision()) {
data += ` (git ` + getGitRevision().substring(0,8) + `)`;
}
data += `
<tr><td>&rate;
</table>
</center>
</body>
</html>
`;

View File

@@ -1,26 +0,0 @@
200 OK
Connection: Keep-Alive
wtv-expire-all: wtv-
wtv-expire-all: http
Content-type: text/html
<html>
<title>Engaging zefie...</title>
<head>
<display nooptions showwhencomplete nostatus skipback clearback fontsize=medium>
<meta
http-equiv=refresh
content="5; url=wtv-home:/home?"
>
</head>
<body bgcolor="#000000" text="#449944">
<bgsound src="file://ROM/Sounds/Splash.mid">
<center>
<img src="wtv-star:/images/HackTVLogo.gif">
<br>
<spacer type=block height=98 width=21>
<br>
</center>
</body>
</html>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

View File

@@ -1,4 +1,7 @@
<html>
headers = `200 OK
Content-Type: text/html`
data = `<html>
<head>
<meta
http-equiv=refresh
@@ -11,7 +14,7 @@
<table cellspacing=0 cellpadding=0>
<tr>
<td width=104 height=74 valign=middle align=center bgcolor=3B3A4D>
<img src="wtv-star:/images/WebTVLogoJewel.gif" width=86 height=64>
<img src="`+minisrv_config.config.service_logo+`" width=86 height=64>
<td width=20 valign=top align=left bgcolor=3B3A4D>
<spacer>
<td colspan=2 width=436 valign=middle align=left bgcolor=3B3A4D>
@@ -45,4 +48,4 @@
</font>
</table>
</body>
</html>
</html>`

View File

@@ -103,7 +103,7 @@ function processGroup(diskmap_primary_group, diskmap_group_data, diskmap_subgrou
var post_match_file = null;
Object.keys(service_vaults).forEach(function (g) {
if (post_match_file != null) return;
post_match_file = service_vaults[g].path + "/" + service_name + "/" + diskmap_group_data.files[k].location;
post_match_file = service_vaults[g] + "/" + service_name + "/" + diskmap_group_data.files[k].location;
if (!fs.existsSync(post_match_file)) post_match_file = null;
});
@@ -136,7 +136,7 @@ if (request_headers.query.diskmap && request_headers.query.group && request_head
var diskmap_json_file = null;
Object.keys(service_vaults).forEach(function (g) {
if (diskmap_json_file != null) return;
diskmap_json_file = service_vaults[g].path + "/" + service_name + "/" + diskmap_dir + request_headers.query.diskmap + ".json";
diskmap_json_file = service_vaults[g] + "/" + service_name + "/" + diskmap_dir + request_headers.query.diskmap + ".json";
if (!fs.existsSync(diskmap_json_file)) diskmap_json_file = null;
});

View File

@@ -89,14 +89,14 @@ async function processPath(socket, service_vault_file_path, request_headers = ne
try {
service_vaults.forEach(function (service_vault_dir) {
if (service_vault_found) return;
service_vault_file_path = service_vault_dir.path + "/" + service_path.replace(/\\/g, "/");
service_vault_file_path = service_vault_dir + "/" + service_path.replace(/\\/g, "/");
if (fs.existsSync(service_vault_file_path)) {
// file exists, read it and return it
service_vault_found = true;
request_is_async = true;
if (!zquiet) console.log(" * Found " + service_vault_file_path + " in " + service_vault_dir.name +" to handle request (Direct File Mode) [Socket " + socket.id + "]");
if (!zquiet) console.log(" * Found " + service_vault_file_path + " to handle request (Direct File Mode) [Socket " + socket.id + "]");
var contype = getConType(service_vault_file_path);
headers = "200 OK\n"
headers += "Content-Type: " + contype;
@@ -106,7 +106,7 @@ async function processPath(socket, service_vault_file_path, request_headers = ne
} else if (fs.existsSync(service_vault_file_path + ".txt")) {
// raw text format, entire payload expected (headers and content)
service_vault_found = true;
if (!zquiet) console.log(" * Found " + service_vault_file_path + ".txt in " + service_vault_dir.name +" to handle request (Raw TXT Mode) [Socket " + socket.id + "]");
if (!zquiet) console.log(" * Found " + service_vault_file_path + ".txt to handle request (Raw TXT Mode) [Socket " + socket.id + "]");
request_is_async = true;
fs.readFile(service_vault_file_path + ".txt", 'Utf-8', function (err, file_raw) {
if (file_raw.indexOf("\n\n") > 0) {
@@ -137,9 +137,9 @@ async function processPath(socket, service_vault_file_path, request_headers = ne
// In Asynchronous mode, you are expected to call sendToClient(socket,headers,data) by the end of your script
// `socket` is already defined and should be passed-through.
service_vault_found = true;
if (!zquiet) console.log(" * Found " + service_vault_file_path + ".js in " + service_vault_dir.name + " to handle request (JS Interpreter mode) [Socket " + socket.id + "]");
if (!zquiet) console.log(" * Found " + service_vault_file_path + ".js to handle request (JS Interpreter mode) [Socket " + socket.id + "]");
// expose var service_dir for script path to the root of the wtv-service
var service_dir = service_vault_dir.path.replace(/\\/g, "/") + "/" + service_name;
var service_dir = service_vault_dir.replace(/\\/g, "/") + "/" + service_name;
socket_sessions[socket.id].starttime = Math.floor(new Date().getTime() / 1000);
var jscript_eval = fs.readFileSync(service_vault_file_path + ".js").toString();
eval(jscript_eval);
@@ -148,7 +148,7 @@ async function processPath(socket, service_vault_file_path, request_headers = ne
else if (fs.existsSync(service_vault_file_path + ".html")) {
// Standard HTML with no headers, WTV Style
service_vault_found = true;
if (!zquiet) console.log(" * Found " + service_vault_file_path + ".html in " + service_vault_dir.name +" to handle request (HTML Mode) [Socket " + socket.id + "]");
if (!zquiet) console.log(" * Found " + service_vault_file_path + ".html to handle request (HTML Mode) [Socket " + socket.id + "]");
request_is_async = true;
headers = "200 OK\n"
headers += "Content-Type: text/html"
@@ -186,7 +186,7 @@ async function processPath(socket, service_vault_file_path, request_headers = ne
}
function filterSSID(obj) {
if (minisrv_config.config.hide_ssid_in_logs) {
if (minisrv_config.config.hide_ssid_in_logs === true) {
if (typeof (obj) == "string") {
if (obj.substr(0, 8) == "MSTVSIMU") {
return obj.substr(0, 10) + ('*').repeat(10) + obj.substr(20);
@@ -598,7 +598,86 @@ async function processRequest(socket, data_hex, returnHeadersBeforeSecure = fals
ssid_sessions[socket.ssid] = new ClientSessionData();
}
if (!ssid_sessions[socket.ssid].data_store.sockets) ssid_sessions[socket.ssid].data_store.sockets = new Array();
ssid_sessions[socket.ssid].data_store.sockets.push(socket.id);
ssid_sessions[socket.ssid].data_store.sockets.push(socket.id);
}
var ip2long = function (ip) {
var components;
if (components = ip.match(/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/)) {
var iplong = 0;
var power = 1;
for (var i = 4; i >= 1; i -= 1) {
iplong += power * parseInt(components[i]);
power *= 256;
}
return iplong;
}
else return -1;
};
var isInSubnet = function (ip, subnet) {
var mask, base_ip, long_ip = ip2long(ip);
if ((mask = subnet.match(/^(.*?)\/(\d{1,2})$/)) && ((base_ip = ip2long(mask[1])) >= 0)) {
var freedom = Math.pow(2, 32 - parseInt(mask[2]));
return (long_ip > base_ip) && (long_ip < base_ip + freedom - 1);
}
else return false;
};
var rejectSSIDConnection = function (ssid, blacklist) {
if (blacklist) console.log(" * Request from SSID", filterSSID(ssid), "(" + socket.remoteAddr + "), but that SSID is in the blacklist, rejecting.");
else console.log(" * Request from SSID", filterSSID(socket.ssid), "(" + socket.remoteAddress + "), but that SSID is not in the whitelist, rejecting.");
var errpage = doErrorPage(401, "Access to this service is denied.");
headers = errpage[0];
data = errpage[1];
socket_sessions[socket.id].close_me = true;
}
var checkSSIDIPWhitelist = function (ssid, blacklist) {
var ssid_access_list_ip_override = false;
if (minisrv_config.config.ssid_ip_allow_list) {
if (minisrv_config.config.ssid_ip_allow_list[socket.ssid]) {
Object.keys(minisrv_config.config.ssid_ip_allow_list[socket.ssid]).forEach(function (k) {
if (minisrv_config.config.ssid_ip_allow_list[socket.ssid][k].indexOf('/') > 0) {
if (isInSubnet(socket.remoteAddress, minisrv_config.config.ssid_ip_allow_list[socket.ssid][k])) {
// remoteAddr is in allowed subnet
ssid_access_list_ip_override = true;
}
} else {
if (socket.remoteAddress == minisrv_config.config.ssid_ip_allow_list[socket.ssid][k]) {
// remoteAddr directly matches IP
ssid_access_list_ip_override = true;
}
}
});
if (!ssid_access_list_ip_override) rejectSSIDConnection(socket.ssid, blacklist);
} else {
rejectSSIDConnection(socket.ssid, blacklist);
}
} else {
rejectSSIDConnection(socket.ssid, blacklist);
}
if (ssid_access_list_ip_override && zdebug) console.log(" * Request from disallowed SSID", filterSSID(ssid), "was allowed due to IP address whitelist");
}
// process whitelist first
if (socket.ssid && minisrv_config.config.ssid_allow_list) {
var ssid_is_in_whitelist = minisrv_config.config.ssid_allow_list.findIndex(element => element == socket.ssid);
if (ssid_is_in_whitelist == -1) {
// no whitelist match, but lets see if the remoteAddress is allowed
checkSSIDIPWhitelist(socket.ssid, false);
}
}
// now check blacklist
if (socket.ssid && minisrv_config.config.ssid_block_list) {
var ssid_is_in_blacklist = minisrv_config.config.ssid_block_list.findIndex(element => element == socket.ssid);
if (ssid_is_in_blacklist != -1) {
// blacklist match, but lets see if the remoteAddress is allowed
checkSSIDIPWhitelist(socket.ssid, true);
}
}
@@ -756,7 +835,7 @@ async function cleanupSocket(socket) {
delete socket_sessions[socket.id];
}
if (socket.ssid) {
var socket_array_index = ssid_sessions[socket.ssid].data_store.sockets.findIndex(element => element = socket.id);
var socket_array_index = ssid_sessions[socket.ssid].data_store.sockets.findIndex(element => element == socket.id);
if (socket_array_index != -1) {
ssid_sessions[socket.ssid].data_store.sockets.splice(socket_array_index,1);
}
@@ -849,6 +928,19 @@ function returnAbsolsutePath(path) {
}
function getGitRevision() {
try {
const rev = fs.readFileSync(__dirname.replace(/\\/g, "/") + '/../.git/HEAD').toString().trim();
if (rev.indexOf(':') === -1) {
return rev;
} else {
return fs.readFileSync(__dirname.replace(/\\/g, "/") + '/../.git/' + rev.substring(5)).toString().trim();
}
} catch (e) {
return null;
}
}
// SERVER START
var z_title = "zefie's wtv minisrv v" + require('./package.json').version;
@@ -886,11 +978,15 @@ if (throw_me) {
throw ("An error has occured while reading the configuration files.");
}
if (minisrv_config.config.UserServiceVault) service_vaults.push({ "path": returnAbsolsutePath(minisrv_config.config.UserServiceVault), "name": "User Service Vault" });
service_vaults.push({ "path": returnAbsolsutePath(minisrv_config.config.ServiceVault), "name": "Service Vault" });
Object.keys(service_vaults).forEach(function (k) {
console.log(" * Using", service_vaults[k].name, "at", service_vaults[k].path);
});
if (minisrv_config.config.ServiceVaults) {
Object.keys(minisrv_config.config.ServiceVaults).forEach(function (k) {
var service_vault = returnAbsolsutePath(minisrv_config.config.ServiceVaults[k]);
service_vaults.push(service_vault);
console.log(" * Configured Service Vault at", service_vault, "with priority",(parseInt(k)+1));
})
} else {
throw ("ERROR: No Service Vaults defined!");
}
var service_ip = minisrv_config.config.service_ip;
Object.keys(minisrv_config.services).forEach(function (k) {
@@ -917,7 +1013,13 @@ Object.keys(minisrv_config.services).forEach(function (k) {
}
console.log(" * Configured Service", k, "on Port", minisrv_config.services[k].port, "- Host", minisrv_config.services[k].host, "- Bind Port:", !minisrv_config.services[k].nobind);
})
if (minisrv_config.config.hide_ssid_in_logs) console.log(" * Masking SSIDs in the console for security");
if (minisrv_config.config.hide_ssid_in_logs) console.log(" * Masking SSIDs in console logs for security");
else console.log(" * Full SSIDs will be shown in console logs");
if (minisrv_config.config.service_logo.indexOf(':') == -1) minisrv_config.config.service_logo = "wtv-star:/images/" + minisrv_config.config.service_logo;
if (minisrv_config.config.service_splash_logo.indexOf(':') == -1) minisrv_config.config.service_splash_logo = "wtv-star:/images/" + minisrv_config.config.service_splash_logo;
minisrv_config.version = require('./package.json').version;
// defaults
var zdebug = false;
@@ -964,17 +1066,19 @@ ports.sort();
// de-duplicate ports in case user configured multiple services on same port
const bind_ports = [...new Set(ports)]
if (!minisrv_config.config.bind_ip) minisrv_config.config.bind_ip = "0.0.0.0";
bind_ports.forEach(function (v) {
try {
var server = net.createServer(handleSocket);
server.listen(v, '0.0.0.0');
server.listen(v, minisrv_config.config.bind_ip);
initstring += v + ", ";
} catch (e) {
throw ("Could not bind to port", v, e.toString());
throw ("Could not bind to port", v, "on", minisrv_config.config.bind_ip, e.toString());
}
});
initstring = initstring.substring(0, initstring.length - 2);
console.log(" * Started server on ports " + initstring + "... Service IP is " + service_ip);
console.log(" * Started server on ports " + initstring + "...")
var listening_ip_string = (minisrv_config.config.bind_ip != "0.0.0.0") ? "IP: " + minisrv_config.config.bind_ip : "all interfaces";
console.log(" * Listening on", listening_ip_string,"~","Service IP:", service_ip);

View File

@@ -1,19 +1,22 @@
{
"config": {
"service_ip": "0.0.0.0",
"ServiceVault": "ServiceVault",
"UserServiceVault": "UserServiceVault",
"service_name": "HackTV",
"send_tellyscripts": false,
"ServiceVaults": [
"UserServiceVault",
"ServiceVault"
],
"service_name": "MSNTV",
"service_logo": "MSNLogo.gif",
"service_splash_logo": "splash_logo_msn.gif",
"hide_ssid_in_logs": true,
"socket_timeout": 350,
"socket_timeout": 350,
"verbosity": 2
},
"services": {
"wtv-1800": {
"host": null,
"port": 1615,
"connections": 1
"connections": 1,
"send_tellyscripts": false
},
"wtv-star": {
"port": 1603,

View File

@@ -1,6 +1,6 @@
{
"name": "zefie_wtvp_minisrv",
"version": "0.9.1",
"version": "0.9.4",
"lockfileVersion": 1,
"requires": true,
"dependencies": {

View File

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

View File

@@ -1,12 +1,36 @@
{
"config": {
"service_ip": "192.168.11.8",
"service_name": "MyWebTV",
"send_tellyscripts": true,
"service_ip": "192.168.1.8",
"service_name": "WebTV",
"service_logo": "WebTVLogoJewel.gif",
"service_splash_logo": "file://ROM/images/SplashLogo1.gif",
"ServiceVaults": [
"UserServiceVault",
"ServiceVault",
"C:\\users\\zefie\\webtv\\ServiceVault",
"C:/Users/zefie/webtv/ServiceVault2",
"/home/zefie/webtv/ServiceVault"
],
"ssid_block_list": [
"8100000000000000",
"8100000000000010"
],
"ssid_ip_allow_list": {
"8100000000000000": [
"192.168.1.0/24",
"127.0.0.1"
]
},
"hide_ssid_in_logs": true,
"verbosity": 0
"verbosity": 2
},
"services": {
"wtv-1800": {
"send_tellyscripts": true,
"send_tellyscript_ssid_whitelist": [
"8100000000000000"
]
},
"wtv-log": {
"write_logs_to_disk": true
},
@@ -15,7 +39,7 @@
"connections": 1
},
"wtv-tricks": {
"service_ip": "192.168.11.8",
"service_ip": "192.168.1.8",
"port": 1702,
"nobind": true
},

View File

@@ -189,7 +189,7 @@
<Content Include="ServiceVault\wtv-update\sync.js">
<SubType>Code</SubType>
</Content>
<Content Include="ServiceVault\wtv-update\DealerDemo.html" />
<Content Include="ServiceVault\wtv-update\DealerDemo.js" />
<Content Include="ServiceVault\wtv-home\home.js" />
<Content Include="ServiceVault\wtv-update\updatesuccess.txt" />
<Content Include="ServiceVault\wtv-1800\finish-prereg.js" />
@@ -197,11 +197,12 @@
<Content Include="ServiceVault\wtv-head-waiter\finalize-security.js" />
<Content Include="ServiceVault\wtv-head-waiter\login-stage-two.js" />
<Content Include="ServiceVault\wtv-head-waiter\login.js" />
<Content Include="ServiceVault\wtv-home\splash.txt" />
<Content Include="ServiceVault\wtv-home\splash.js" />
<Content Include="ServiceVault\wtv-log\log.js" />
<Content Include="session_data.js">
<SubType>Code</SubType>
</Content>
<Content Include="user_config.example.json" />
<Content Include="user_config.json" />
<Content Include="wtvsec.js">
<SubType>Code</SubType>