- update wtv-home:/home: "Ultra Willies" no longer selected by default
- update: allow socket timeout definition via config
- fix: fixed reading of POST DATA from SECURE ON request
- experiment with OISP and WNI tellyscripts
- enhancement: Support UserServiceVault
- update: enable Download-o-Rama style updates. MSNTV DealerDemo included as a demo
This commit is contained in:
zefie
2021-07-19 06:08:47 -04:00
parent 857e3639cc
commit b0ab508d0f
38 changed files with 560 additions and 525 deletions

2
.gitignore vendored
View File

@@ -365,3 +365,5 @@ FodyWeavers.xsd
/hacktv_updsrv/ServiceVault/wtv-music/midi /hacktv_updsrv/ServiceVault/wtv-music/midi
/zefie_wtvp_minisrv/ServiceVault/wtv-home/6969.html /zefie_wtvp_minisrv/ServiceVault/wtv-home/6969.html
/zefie_wtvp_minisrv/user_config.json /zefie_wtvp_minisrv/user_config.json
/zefie_wtvp_minisrv/ServiceVault/wtv-home/home.zefie.html
/zefie_wtvp_minisrv/UserServiceVault/wtv-update

View File

@@ -7,6 +7,7 @@
ServiceLogPost/*_* ServiceLogPost/*_*
# Large files not pertaining to the service code # Large files not pertaining to the service code
UserServiceVault/*-*
ServiceVault/wtv-flashrom/content/* ServiceVault/wtv-flashrom/content/*
ServiceVault/wtv-music/content/* ServiceVault/wtv-music/content/*
ServiceVault/wtv-music/midi/* ServiceVault/wtv-music/midi/*
@@ -368,4 +369,4 @@ MigrationBackup/
# Fody - auto-generated XML schema # Fody - auto-generated XML schema
FodyWeavers.xsd FodyWeavers.xsd
/hacktv_updsrv/ServiceLogPost/1626307222_warning_812bf30600b002bb

View File

@@ -24,7 +24,8 @@ if (wtvsec_login) {
switch (romtype) { switch (romtype) {
case "US-LC2-disk-0MB-8MB": case "US-LC2-disk-0MB-8MB":
prereg_contype = "text/tellyscript"; prereg_contype = "text/tellyscript";
var file_path = __dirname + "/ServiceDeps/premade_tellyscripts/LC2/LC2_OISP_5555732_56k.tok"; if (ssid_sessions[socket.ssid].get("wtv-open-access")) 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; break;
default: default:

View File

@@ -28,8 +28,9 @@ data += `<h4>Working stuff</h4>
<ul> <ul>
<li><a href="client:relog">client:relog (direct)</a></li> <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-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-flashrom:/willie">Ultra Willies</a></li>
<li><a href="wtv-music:/demo/index">MIDI Music Demo</a></li> <li><a href="wtv-music:/demo/index">MIDI Music Demo</a></li>
<li><a href="wtv-update:/DealerDemo">Download old MSNTV DealerDemo</a></li>
<li><a href="http://duckduckgo.com/lite/">DuckDuckGo Lite</a></li> <li><a href="http://duckduckgo.com/lite/">DuckDuckGo Lite</a></li>
<li><input name=url `; <li><input name=url `;
@@ -37,13 +38,16 @@ if (request_headers.query.url) {
data += "value='" + unescape(request_headers.query.url)+"'"; data += "value='" + unescape(request_headers.query.url)+"'";
} }
data += `width=250 bgcolor=#444444 text=#ffdd33 cursor=#cc9933 selected> data += `width=250 height=10 bgcolor=#444444 text=#ffdd33 cursor=#cc9933 selected>
<input type=submit value="Access URL"> <input type=submit value="Access URL">
</form></li> </form></li>
</ul> </ul>`
<h4>Developer Playground</h4> try {
<a href="wtv-home:/zefie">zefie's stuff and things</a> if (fs.lstatSync(service_dir + "/home.zefie.html")) {
data += fs.readFileSync(service_dir + "/home.zefie.html", { 'encoding': 'utf8' });
</body> }
</html>` } catch (e) {
// silent
}
data += "</body>\n</html>";

View File

@@ -1,24 +0,0 @@
<html>
<head>
<title>zefie's playground</title>
<DISPLAY showwhencomplete options showoptions noscroll>
</head>
<body bgcolor="black" link="gold" vlink="gold" alink="gold" text="gold">
<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.<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>
</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

@@ -5,7 +5,7 @@ WebTV Music Index
</title> </title>
<display switchtowebmode transition=none> <display switchtowebmode transition=none>
</head> </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"> <body bgcolor="#171726" text="#82A9D9" link="#9DEFFF" vlink="#597DAA" alink="#9DEFFF" hspace=0 vspace=0 fontsize="small" logo="midi/webtv.gif" address="WebTV Music Index">
<sidebar width="115" border="0"> <sidebar width="115" border="0">

View File

@@ -2,23 +2,23 @@
<head> <head>
<meta <meta
http-equiv=refresh http-equiv=refresh
content="0;url=client:Fetch?group=Browser&source=wtv-update:/sync%3Fdiskmap%3Dhtvupdate&message=Downloading%20updates..." content="0;url=client:Fetch?group=DealerDemo&source=wtv-update:/sync%3Fdiskmap%3DDealerDemo&message=Retrieving%20Files..."
> >
<display downloadsuccess="client:ShowAlert?message=HackTV%20Update%20was%20successful%21&buttonlabel2=Go%20to%20HackTV&action2=wtv-tricks:/go-offline%3Ftitle%3DHackTV%20Home&buttonlabel1=Okay&buttonaction1=client:goback&image=file://disk/browser/Games/hacktv2.gif&noback=true" downloadfail="client:ShowAlert?message=HackTV%20Update%20failed...&buttonlabel1=Okay...&buttonaction1=client:goback&image=file://disk/browser/Games/hacktv2.gif&noback=true"> <display downloadsuccess="client:goback" downloadfail="client:ShowAlert?message=Download%20failed...&buttonlabel1=Okay...&buttonaction1=client:goback&noback=true">
<title>HackTV Updater</title> <title>Retrieving Files</title>
</head> </head>
<body bgcolor=#0 text=#42CC55 fontsize=large hspace=0 vspace=0> <body bgcolor=#0 text=#42CC55 fontsize=large hspace=0 vspace=0>
<table cellspacing=0 cellpadding=0> <table cellspacing=0 cellpadding=0>
<tr> <tr>
<td width=104 height=74 valign=middle align=center bgcolor=3B3A4D> <td width=104 height=74 valign=middle align=center bgcolor=3B3A4D>
<img src="file://Disk/Browser/Games/hacktv4.gif" width=86 height=64> <img src="wtv-star:/images/WebTVLogoJewel.gif" width=86 height=64>
<td width=20 valign=top align=left bgcolor=3B3A4D> <td width=20 valign=top align=left bgcolor=3B3A4D>
<spacer> <spacer>
<td colspan=2 width=436 valign=middle align=left bgcolor=3B3A4D> <td colspan=2 width=436 valign=middle align=left bgcolor=3B3A4D>
<font color=D6DFD0 size=+2><blackface><shadow> <font color=D6DFD0 size=+2><blackface><shadow>
<spacer type=block width=1 height=4> <spacer type=block width=1 height=4>
<br> <br>
Download HackTV Updates Retrieving Files
</shadow> </shadow>
</blackface> </blackface>
</font> </font>
@@ -30,17 +30,17 @@
<tr> <tr>
<td colspan=2> <td colspan=2>
<td> <td>
<font size=+1> <font size=+1>
Your HackTV Unit is downloading updates. Your Internet terminal is retrieving some files.
<p>This may take a while. <p>This may take a while.
</font> </font>
<tr> <tr>
<td colspan=2> <td colspan=2>
<td> <td>
<br><br> <br><br>
<font color=white> <font color=white>
<progressindicator name="downloadprogress" <progressindicator name="downloadprogress"
message="Preparing..." message="Retrieving Files..."
height=40 width=250> height=40 width=250>
</font> </font>
</table> </table>

View File

@@ -0,0 +1,15 @@
<HTML>
<HEAD>
<TITLE>Shockwave</TITLE>
<DISPLAY noscroll nologo nooptions noreconnectalert></HEAD>
<BODY bgcolor="#333333" background="allyouneed.swf">
<table width="100%" border="0" height="100%">
<tr align="center" valign="middle">
<td>
<!-- URL's used in the movie-->
<a href=mainmenu.html><img src="images/spacer.gif" width="560" height="420" border="0"></a>
</td>
</tr>
</table>
</BODY>
</HTML>

View File

@@ -0,0 +1,15 @@
<HTML>
<HEAD>
<TITLE>Shockwave</TITLE>
<DISPLAY noscroll nologo nooptions noreconnectalert></HEAD>
<BODY bgcolor="#333333" background="communicate.swf">
<table width="100%" border="0" height="100%">
<tr align="center" valign="middle">
<td>
<!-- URL's used in the movie-->
<a href=mainmenu.html><img src="images/spacer.gif" width="560" height="420" border="0"></a>
</td>
</tr>
</table>
</BODY>
</HTML>

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 B

View File

@@ -0,0 +1,15 @@
<HTML>
<HEAD>
<TITLE>Shockwave</TITLE>
<DISPLAY noscroll nologo nooptions noreconnectalert></HEAD>
<BODY bgcolor="#333333" background="attractloop.swf">
<table width="100%" border="0" height="100%">
<tr align="center" valign="middle">
<td>
<!-- URL's used in the movie-->
<a href=mainmenu.html><img src="images/spacer.gif" width="560" height="420" border="0"></a>
</td>
</tr>
</table>
</BODY>
</HTML>

View File

@@ -0,0 +1,15 @@
<HTML>
<HEAD>
<TITLE>Shockwave</TITLE>
<DISPLAY noscroll nologo nooptions noreconnectalert></HEAD>
<BODY bgcolor="#333333" background="interactive.swf">
<table width="100%" border="0" height="100%">
<tr align="center" valign="middle">
<td>
<!-- URL's used in the movie-->
<a href=mainmenu.html><img src="images/spacer.gif" width="560" height="420" border="0"></a>
</td>
</tr>
</table>
</BODY>
</HTML>

View File

@@ -0,0 +1,15 @@
<HTML>
<HEAD>
<TITLE>Shockwave</TITLE>
<DISPLAY noscroll nologo nooptions noreconnectalert></HEAD>
<BODY bgcolor="#333333" background="internet.swf">
<table width="100%" border="0" height="100%">
<tr align="center" valign="middle">
<td>
<!-- URL's used in the movie-->
<a href=mainmenu.html><img src="images/spacer.gif" width="560" height="420" border="0"></a>
</td>
</tr>
</table>
</BODY>
</HTML>

View File

@@ -0,0 +1,61 @@
<HTML>
<HEAD>
<TITLE>Shockwave</TITLE>
<DISPLAY noscroll nologo nooptions noreconnectalert></HEAD>
<BODY BGCOLOR="#333333" background="mainmenu.swf">
<table width=560 border=0 cellpadding=0 cellspacing=0>
<tr>
<td> <img src="images/spacer.gif" width=269 height=1></td>
<td> <img src="images/spacer.gif" width=9 height=1></td>
<td> <img src="images/spacer.gif" width=11 height=1></td>
<td> <img src="images/spacer.gif" width=15 height=1></td>
<td> <img src="images/spacer.gif" width=154 height=1></td>
<td> <img src="images/spacer.gif" width=9 height=1></td>
<td> <img src="images/spacer.gif" width=12 height=1></td>
<td> <img src="images/spacer.gif" width=49 height=1></td>
<td> <img src="images/spacer.gif" width=32 height=1></td>
</tr>
<tr>
<td colspan=9> <img src="images/spacer.gif" width=560 height=94></td>
</tr>
<tr>
<td rowspan=10> <img src="images/spacer.gif" width=269 height=326></td>
<td colspan=4> <a href="interactive.html"><img src="images/buttonsplus_interactive.gif" width=189 height=33 border="0"></a></td>
<td colspan=4 rowspan=4> <img src="images/spacer.gif" width=102 height=88></td>
</tr>
<tr>
<td colspan=4> <img src="images/spacer.gif" width=189 height=11></td>
</tr>
<tr>
<td colspan=4> <a href="internet.html"><img src="images/buttonsplus_internet.gif" width=189 height=33 border="0"></a></td>
</tr>
<tr>
<td colspan=4> <img src="images/spacer.gif" width=189 height=11></td>
</tr>
<tr>
<td rowspan=6> <img src="images/spacer.gif" width=9 height=238></td>
<td colspan=4> <a href="communicate.html"><img src="images/buttonsplus_comm.gif" width=189 height=33 border="0"></a></td>
<td colspan=3 rowspan=2> <img src="images/spacer.gif" width=93 height=44></td>
</tr>
<tr>
<td colspan=4> <img src="images/spacer.gif" width=189 height=11></td>
</tr>
<tr>
<td rowspan=4> <img src="images/spacer.gif" width=11 height=194></td>
<td colspan=4> <a href="allyouneed.html"><img src="images/buttonsplus_all.gif" width=190 height=33 border="0"></a></td>
<td colspan=2 rowspan=2> <img src="images/spacer.gif" width=81 height=44></td>
</tr>
<tr>
<td colspan=4> <img src="images/spacer.gif" width=190 height=11></td>
</tr>
<tr>
<td rowspan=2> <img src="images/spacer.gif" width=15 height=150></td>
<td colspan=4> <a href="client:begindialing?failurl=trymsntv.html"><img src="images/buttonsplus_try.gif" width=224 height=33 border="0"></a></td>
<td rowspan=2> <img src="images/spacer.gif" width=32 height=150></td>
</tr>
<tr>
<td colspan=4> <img src="images/spacer.gif" width=224 height=117></td>
</tr>
</table>
</BODY>
</HTML>

View File

@@ -0,0 +1,15 @@
<HTML>
<HEAD>
<TITLE>Shockwave</TITLE>
<DISPLAY noscroll nologo nooptions noreconnectalert></HEAD>
<BODY bgcolor="#333333" background="trymsntv.swf">
<table width="100%" border="0" height="100%">
<tr align="center" valign="middle">
<td>
<!-- URL's used in the movie-->
<a href=mainmenu.html><img src="images/spacer.gif" width="560" height="420" border="0"></a>
</td>
</tr>
</table>
</BODY>
</HTML>

View File

@@ -0,0 +1,70 @@
{
"DealerDemo": {
"display": "Updating the retail demo",
"base": "file://Disk/Demo/",
"location": "content/DealerDemo/",
"partition_size": 54525952,
"files": [
{
"file": "file://Disk/Demo/allyouneed.html"
},
{
"file": "file://Disk/Demo/allyouneed.swf"
},
{
"file": "file://Disk/Demo/attractloop.swf"
},
{
"file": "file://Disk/Demo/communicate.html"
},
{
"file": "file://Disk/Demo/communicate.swf"
},
{
"file": "file://Disk/Demo/images/buttonsplus_all.gif"
},
{
"file": "file://Disk/Demo/images/buttonsplus_comm.gif"
},
{
"file": "file://Disk/Demo/images/buttonsplus_interactive.gif"
},
{
"file": "file://Disk/Demo/images/buttonsplus_internet.gif"
},
{
"file": "file://Disk/Demo/images/buttonsplus_try.gif"
},
{
"file": "file://Disk/Demo/images/spacer.gif"
},
{
"file": "file://Disk/Demo/index.html"
},
{
"file": "file://Disk/Demo/interactive.html"
},
{
"file": "file://Disk/Demo/interactive.swf"
},
{
"file": "file://Disk/Demo/internet.html"
},
{
"file": "file://Disk/Demo/internet.swf"
},
{
"file": "file://Disk/Demo/mainmenu.html"
},
{
"file": "file://Disk/Demo/mainmenu.swf"
},
{
"file": "file://Disk/Demo/trymsntv.html"
},
{
"file": "file://Disk/Demo/trymsntv.swf"
}
]
}
}

View File

@@ -1,10 +0,0 @@
GROUP name=Browser version=!VERS! root=file://Disk/Browser/Games/
display Updating HackTV Files...
sync Games.html content/htvupdate/Games/Games.html
sync cSetup.html content/htvupdate/Games/cSetup.html
END-GROUP
GROUP name=Browser version=!VERS! root=file://Disk/Browser/MattMan/
display Updating HackTV Files...
sync Tricks/tricks.html content/htvupdate/MattMan/Tricks/tricks.html
END-GROUP

View File

@@ -1,122 +0,0 @@
<html>
<head>
<title>HackTV Home</title>
<DISPLAY notvaudio allowoffline options hideoptions switchtowebmode>
<script>
if (document.images) {
pic1 = new Image();
pic1.src = 'mame.jpg';
pic2 = new Image();
pic2.src = 'doom.jpg';
pic3 = new Image();
pic3.src = 'checkers.jpg';
pic4 = new Image();
pic4.src = 'music.jpg';
pic5 = new Image();
pic5.src = 'file1.jpg';
pic6 = new Image();
pic6.src = 'tricks.jpg';
pic7 = new Image();
pic7.src = 'wtvcity2.gif';
pic8 = new Image();
pic8.src = 'tic.jpg';
pic9 = new Image();
pic9.src = 'html.jpg';
pic10 = new Image();
pic10.src = 'cSetup.jpg';
pic11 = new Image();
pic11.src = 'msn.jpg';
pic12 = new Image();
pic12.src = 'wtvcity.gif';
pic13 = new Image();
pic13.src = 'tvh.jpg';
pic14 = new Image();
pic14.src = 'cross.jpg';
pic15 = new Image();
pic15.src = 'ydkj.jpg';
} else {
pic1 = pic2 = pic3 = pic4 = pic5 = pic6 = pic7 = pic8 = pic9 = pic10 = pic11 = pic12 = pic13 = pic14 = document.r1 = "";
}
</script>
</head>
<body bgcolor="#281f26" background="Pattern_Games.gif" text="#cbcbcb" alink="#4489a8" vlink="#4489a8" link="#4489a8" hspace="0" vspace="0" fontsize="large">
<table cellspacing="0" cellpadding="0" cellborder="0">
<tr>
<td background="GamesShadowLogo.gif" width="104" height="80" valign="top" align="left"><spacer type="block" WIDTH="11" HEIGHT="11"><br>
<spacer type="block" WIDTH="10" HEIGHT="1"> <a href="client:showalert?message=Credits:<br><br>eMac<br>MattMan69<br>Outa<br><br>Oct.%202014" onmouseover="document.r1.src=pic7.src;"><img src="file://disk/browser/Games/hacktv4.gif" width="90" height="69"></a></td>
<td width="456" height="80" valign="top" align="center"><img src="GamesBanner.gif" width="456" height="50"><br>
<img src="file://rom/tvimages/Shadow_Horizontal.gif" width="456" height="6"></td></tr></table>
<table cellspacing="0" cellpadding="0">
<tr>
<td colspan="3" height="6"></td>
</tr>
<tr>
<td abswidth="40">&nbsp;</td>
<td>
<table>
<td abswidth="200"><font size="1" color="#ffcf69"><shadow>Play Games</shadow></font></td>
<tr>
<td width="150" height="40" valign="top" align="left"><font size="1" color="#989898">
<li><a href="file://disk/browser/Games/mame.html" onmouseover="document.r1.src=pic1.src;">M.A.M.E.</a>
<li><a href="file://disk/browser/Games/doom.html" onmouseover="document.r1.src=pic2.src;">Doom</a>
<!--li><a href="client:boota?partition=JackROM&size=5242880&source=file://disk/Doom/jackWebTVplus.o">YDKJ</a-->
<li><a href="file://disk/browser/Games/Checkers/index.html" onmouseover="document.r1.src=pic3.src;">Checkers</a>
<li><a href="file://disk/browser/Games/crossword/general/index.html" onmouseover="document.r1.src=pic14.src;">Crosswords</a>
<li><a href="file://disk/browser/Games/tictac/index.html" onmouseover="document.r1.src=pic8.src;">TicTacToe</a></td></tr>
<tr>
<td><font size="1" color="#ffcf69"><shadow>Play Music</shadow></font></td>
<tr>
<td width="200" height="35" valign="top" align="left"><font size="1" color="#989898">
<li><a href="file://disk/Music/index.html" onmouseover="document.r1.src=pic4.src;">WebTV Music</a>
<li><a href="file://disk/Music/Rock/index.html" onmouseover="document.r1.src=pic4.src;">Rock Music</a></td></tr>
<tr>
<td><font size="1" color="#ffcf69"><shadow>Tech Area</shadow></font></td>
<tr>
<td width="150" height="60" valign="top" align="left"><font size="1" color="#989898">
<li><a href="file://disk/Browser/MattMan/techinfo.html" onmouseover="document.r1.src=pic5.src;">Tech Info</a>
<li><a href="file://disk/Browser/MattMan/html/index.html" onmouseover="document.r1.src=pic9.src;">HTML Viewer</a>
<li><a href="file://disk/Browser/MattMan/Tricks/tricks.html" onmouseover="document.r1.src=pic6.src;">HackTV Tricks</a>
<li><a href="file://disk/Browser/Games/cSetup.html" onmouseover="document.r1.src=pic10.src;">Connect Setup</a>
<li><font size="-1"><sup>NEW!</sup</font><a href="client:ConfirmConnectSetup?machine=192.168.11.8&port=1615&ServiceType=custom&useEncryption=true&useDirectConnection=true&Connect=Connect"> Check for Updates</a>
<!--li>Boot <a href="client:boota?NA" onmouseover="document.r1.src=pic11.src;">2.9</a> - <a href="client:boota?NA" onmouseover="document.r1.src=pic12.src;" onmouseout="document.r1.src=pic13.src;">2.1</a-->
</td></tr>
</table>
</td>
<td valign="top">
<table>
<td valign="top">
<center><font size="2" color="#ffcf69"><shadow>
<a href="file://rom/InternalOnly/SetClock.html" onmouseover="document.r1.src=pic7.src;">&date;</a></shadow></font></center><br>
<img src="wtvcity2.gif"
width="260" height="193"
border="2" name="r1"
alt="wtv" />
</td></tr>
</td>
</tr>
</table>
<table>
<tr>
<td align="right" width="252">
<FORM action="client:gototvhome">
<FONT COLOR="#E7CE4A" SIZE=-1><SHADOW>
<INPUT TYPE=BUTTON onclick="location.href='client:activ'" BORDERIMAGE="file://ROM/tvimages/TVButtonBorder.bif" VALUE="Connect" USESTYLE WIDTH=120 onmouseover="document.r1.src=pic7.src;">
</SHADOW></FONT>
<FONT COLOR="#E7CE4A" SIZE=-1><SHADOW>
<INPUT TYPE=SUBMIT BORDERIMAGE="file://ROM/tvimages/TVButtonBorder.bif" VALUE="TV Home" USESTYLE onmouseover="document.r1.src=pic13.src;" WIDTH=120>
</SHADOW></FONT></FORM>
</span>
</td>
</tr>
</table>
</td>
</table>
</body>
</html>

View File

@@ -1,143 +0,0 @@
<html>
<head>
<title>Connect Setup v2.1</title>
<DISPLAY noscroll allowoffline hideoptions notvaudio switchtowebmode>
</head>
<body bgcolor="#281f26" background="Pattern_Games.gif" text="#ffcf69" link="#4489a8"
hspace="0" vspace="0" fontsize="large" noscroll hideoptions>
<table cellspacing="0" cellpadding="0" cellborder="0">
<tr>
<td background="cSetupShadowLogo.gif" width="104" height="80" valign="top" align="left"><spacer type="block" WIDTH="11" HEIGHT="11"><br>
<spacer type="block" WIDTH="10" HEIGHT="1"> <a href="file://disk/Browser/Games/Games.html"><img src="hacktv4.gif" width="87"
height="67"></a> </td>
<td width="456" height="80" valign="top" align="center"><img src="cSetup.GIF"
width="456" height="50"><br>
<img src="file://rom/tvimages/Shadow_Horizontal.gif" width="456" height="6"> </td>
</tr>
</table>
<h2>
&nbsp;Connection Setup v2.1
<hr>
</h2>
<script>
function updateService() {
srv = document.connect.preset[document.connect.preset.selectedIndex].value;
switch (srv) {
case "hacktv":
document.connect.machine.value="192.168.1.3"
break;
case "wni-prod":
document.forms[0].machine.value="10.0.0.1"
break;
case "wni-int":
document.forms[0].machine.value="10.0.128.1"
break;
case "zefie":
document.forms[0].machine.value="home.zef.pw"
break;
case "mattman":
document.forms[0].machine.value="turdinc.kicks-ass.net"
break;
}
}
</script>
<form name="connect" action="client:ConfirmConnectSetup">
<table width=100% cellspacing=1 cellpadding=0>
<tr>
<td colspan=3>
&nbsp;<font color=#4489a8>Presets:</font>
</td>
<td>
<select name="preset" onchange="updateService()" selected>
<option value="hacktv">HackTV Default</option>
<option value="wni-prod">WNI ANI Production Default</option>
<option value="wni-int">WNI ANI Internal Default</option>
<option value="zefie">zefie's Server</option>
<option value="mattman">MattMan's Server</option>
</select>
<tr>
<td colspan=3>
&nbsp;<font color=#4489a8>Service:</font>
<tr>
<td width=15></td>
<td height=2>
<tr>
<td height=2>
<tr>
<td>
<td>
<input name=serviceType type=radio bgcolor=#444444 value=custom checked>
<td>
&nbsp;Custom:&nbsp;&nbsp;&nbsp;
<td>
Address:
<input size=16 ASCIIONLY name=machine bgcolor=#444444 text=#4489a8 cursor=#cc9933 value="192.168.1.3">
&nbsp;&nbsp;&nbsp;Port:
<input size=5 ASCIIONLY NUMBERS name=port bgcolor=#444444 text=#4489a8 cursor=#cc9933 value="1615">
</table>
<table cellspacing=1 cellpadding=0>
<tr>
<td height=6>
<tr>
<td colspan=3>
&nbsp;<font color=#4489a8>Service options:</font><br><br>
<tr>
<td width=15>
<td>
<input type=checkbox name=forceSignup value=true>
<td>
&nbsp;Force signup
<td width=390 align=right>
<form action="client:GoToPhoneSetup">
<font color="#E7CE4A" size=-2><shadow>&nbsp;
<input
type=submit
borderimage="file://ROM/tvimages/TVButtonBorder.bif"
value="Phone Settings"
name="Phone Settings"
usestyle
width=170> &nbsp;
</shadow></font>
</form>
<tr>
<td height=2>
<tr>
<td width=15>
<td>
<input type=checkbox name=useEncryption value=true checked>
<td>
&nbsp;Use encryption
<tr>
<td height=2>
<tr>
<td width=15>
<td>
<input type=checkbox name=useDirectConnection value=true>
<td width=300>
&nbsp;Use direct connection
<td width=390 align=right>
<font color="#E7CE4A" size=-2><shadow>&nbsp;
<input
type=submit
borderimage="file://ROM/tvimages/TVButtonBorder.bif"
value="Connect"
name="Connect"
usestyle
width=170> &nbsp;
</shadow></font>
</table>
<br><br>
<table width=100%>
<tr>
<td align=left width=100% height=70>
<td align=right width=100% height=70>
</table>
</form>
</body>
</html>

View File

@@ -1,52 +0,0 @@
<html>
<head>
<title>HackTV Tricks</title>
<SCRIPT language="JavaScript">
function checkWord(e) {
//e.preventDefault();
var readersEntry = document.pform.pword.value;
if (readersEntry.toLowerCase() == "seqret1") {
window.location.href="file://disk/Browser/MattMan/Tricks/tricks2.html" ;
} else {
document.pform.pword.value="";
alert ("Bad password, access denied!!!");
}
return false;
}
</SCRIPT>
</head>
<body bgcolor="#191919" text="#44cc55" link="36d5ff" vlink="36d5ff" vspace=0>
<sidebar width=20%>
<img src="tricksside.jpg">
</sidebar>
<br>
<br>
<br>
<h1>HackTV Tricks</h1>
<br>
<br>
Hello, citizen! You have reached the "tricks" page. This is meant
for use by 1337 hackers of WebTV networks. If you remember the
right "tricks" you know the password and may enter the access password now.
Otherwise hit the "back" button on your keyboard / remote now!
<p>
Pages beyond this area could cause bodily harm or may render your WebTV useless!
<p>
Remember, the computer is your friend.
<p>
<FORM name="pform" onsubmit="checkWord(e);">
<input name="pword" id="password" bgcolor=#444444 text=#ffdd33 cursor=#cc9933 type="password" size="16">&nbsp;
<input name="button1" value="Enter" onclick="checkWord()" type="button">
</FORM>
</body>
</html>

View File

@@ -1,41 +1,176 @@
// todo: async (and make this work anyway) // todo: async
var content_dir = service_dir + '/content/'; var path = require("path");
var diskmap_dir = content_dir + '/diskmaps/';
if (request_headers.post_data) { var content_dir = "content/"
console.log(request_headers.post_data.toString('CryptoJS.enc.Latin1')) var diskmap_dir = content_dir + "diskmaps/";
function generateDownloadList(diskmap_group_data, update_list, diskmap_data) {
// create WebTV Download List
var newest_file_epoch = 0;
var download_list = '';
if (diskmap_data.partition_size) {
download_list += "CREATE " + diskmap_data.base + "\n";
download_list += "partition-size: " + diskmap_data.partition_size + "\n\n";
}
download_list += "CREATE-GROUP " + diskmap_group_data + "-UPDATE\n";
download_list += "state: invalid\n";
download_list += "base: " + diskmap_data.base + ".GROUP-UPDATE/\n\n";
Object.keys(update_list).forEach(function (k) {
if (parseInt(update_list[k]["Last-modified"]) > newest_file_epoch) newest_file_epoch = parseInt(update_list[k]["Last-modified"]);
download_list += "DISPLAY " + update_list[k].display + "\n\n";
download_list += "GET " + update_list[k].file.replace(diskmap_data.base, "") + "\n";
download_list += "group: " + diskmap_group_data + "-UPDATE\n";
download_list += "location: " + service_name + ":/" + update_list[k].location + "\n";
download_list += "file-permission: r\n"
download_list += "wtv-checksum: " + update_list[k]["wtv-checksum"] + "\n";
download_list += "service-source-location: /webtv/content/" + service_name.replace("wtv-","") + "d/" + update_list[k].location + "\n";
download_list += "client-dest-location: " + update_list[k].file + "\n\n";
});
download_list += "CREATE-GROUP " + diskmap_group_data + "\n";
download_list += "state: invalid\n";
download_list += "service-owned: " + (diskmap_data.service_owned || false) + "\n";
download_list += "base: " + diskmap_data.base + "\n\n";
Object.keys(update_list).forEach(function (k) {
download_list += "DELETE " + update_list[k].file.replace(diskmap_data.base, "") + "\n";
download_list += "group: " + diskmap_group_data + "\n\n";
});
Object.keys(update_list).forEach(function (k) {
download_list += "RENAME " + update_list[k].file.replace(diskmap_data.base, "") + "\n";
download_list += "group: " + diskmap_group_data + "-UPDATE\n";
download_list += "destination-group: " + diskmap_group_data + "\n";
download_list += "location: " + update_list[k].file.replace(diskmap_data.base, "") + "\n\n";
});
download_list += "DELETE-GROUP " + diskmap_group_data + "-UPDATE\n\n";
download_list += "SET-GROUP " + diskmap_group_data + "\n";
download_list += "state: ok\n";
download_list += "version: " + newest_file_epoch + "\n";
download_list += "last-checkup-time: " + new Date().toUTCString().replace("GMT", "+0000") + "\n\n";
return download_list;
} }
if (request_headers.query.diskmap) { function processGroup(diskmap_primary_group, diskmap_group_data, diskmap_subgroup = null) {
if (fs.lstatSync(diskmap_dir + request_headers.query.diskmap + ".txt")) { // parse webtv post
var diskmap_data = fs.readFileSync(diskmap_dir + request_headers.query.diskmap + ".txt").toString(); var output_data = '';
// try to parse diskmap and get an accurate timestamp for webtv versioning var post_data = request_headers.post_data.toString(CryptoJS.enc.Latin1).split("\n");
// check all files in the diskmap and return the timestamp of the most recently modified var post_data_current_directory = '';
var post_data_current_file = '';
var post_data_fileinfo = new Array();
var post_data_filecount = -1;
data = ''; Object.keys(post_data).forEach(function (k) {
var latest_file_ts = 0; if (post_data[k] == "") return;
diskmap_data.split("\n").forEach(function (v) { if (post_data[k].substring(0, 7) == "file://") {
if (v.indexOf(" sync ") != -1) { post_data_current_directory = post_data[k];
v = v.trim(); post_data_current_file = post_data[k];
var vcon = v.substring(v.indexOf("content/")); }
vcon = vcon.replace("content/", content_dir) if (post_data[k].indexOf(":") > 0) {
var vconstat = Math.floor(fs.lstatSync(vcon).mtimeMs / 1000); var post_data_line = post_data[k].split(":")
if (vconstat > latest_file_ts) { var post_data_line_name = post_data_line[0];
latest_file_ts = vconstat post_data_line.shift();
} var post_data_line_data = post_data_line.join(":");
// todo read client post and only give whats needed
// instead of all that is available if (!post_data_fileinfo[post_data_filecount]) post_data_fileinfo[post_data_filecount] = new Array();
// vconstat has the mtime of each file, we need to parse the post_data
data += v + "\n"; if (post_data_line_name == "Last-modified") {
} else { post_data_fileinfo[post_data_filecount][post_data_line_name] = (Date.parse(post_data_line_data) / 1000);
data += v + "\n"; } else if (post_data_line_name == "Content-length") {
post_data_fileinfo[post_data_filecount][post_data_line_name] = parseInt(post_data_line_data);
} }
else {
post_data_fileinfo[post_data_filecount][post_data_line_name] = post_data_line_data;
}
} else {
post_data_filecount++;
post_data_current_file = post_data_current_directory + post_data[k];
post_data_fileinfo[post_data_filecount] = new Array();
post_data_fileinfo[post_data_filecount].file = post_data_current_file
}
});
var wtv_download_list = new Array();
Object.keys(diskmap_group_data.files).forEach(function (k) {
if (!diskmap_group_data.files[k].location) diskmap_group_data.files[k].location = diskmap_group_data.location + diskmap_group_data.files[k].file.replace(diskmap_group_data.base, "");
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;
if (!fs.existsSync(post_match_file)) post_match_file = null;
}); });
//data = diskmap_data.replace("!VERS!", latest_file_ts); var post_match_file_lstat = fs.lstatSync(post_match_file);
var post_match_result = post_data_fileinfo.find(el => el["file"] === diskmap_group_data.files[k].file) || false;
var post_match_file_data = new Buffer.from(fs.readFileSync(post_match_file, {
encoding: null,
flags: 'r'
}));
diskmap_group_data.files[k]["Last-modified"] = (post_match_file_lstat.mtime / 1000);
diskmap_group_data.files[k]["Content-length"] = post_match_file_lstat.size;
diskmap_group_data.files[k]["wtv-checksum"] = CryptoJS.MD5(CryptoJS.lib.WordArray.create(post_match_file_data)).toString(CryptoJS.enc.Hex).toLowerCase();
if (!diskmap_group_data.files[k].display) diskmap_group_data.files[k].display = diskmap_group_data.display;
if (post_match_result) {
// md5s match, so client doesn't need file
if (diskmap_group_data.files[k]['wtv-checksum'] == post_match_result["wtv-checksum"]) return;
else wtv_download_list.push(diskmap_group_data.files[k]);
} else {
wtv_download_list.push(diskmap_group_data.files[k]);
}
var diskmap_group_name = (diskmap_subgroup == null) ? diskmap_primary_group : diskmap_primary_group + "-" + diskmap_subgroup;
output_data = generateDownloadList(diskmap_group_name, wtv_download_list, diskmap_group_data)
});
return output_data;
}
if (request_headers.query.diskmap && request_headers.query.group && request_headers.post_data) {
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";
if (!fs.existsSync(diskmap_json_file)) diskmap_json_file = null;
});
if (diskmap_json_file != null) {
if (fs.lstatSync(diskmap_json_file)) {
try {
// read diskmap
var diskmap_data = JSON.parse(fs.readFileSync(diskmap_json_file).toString());
if (!diskmap_data[request_headers.query.group]) {
throw ("Invalid diskmap data (group does not match)");
}
data = '';
diskmap_data = diskmap_data[request_headers.query.group];
/*if (!diskmap_data.display) {
Object.keys(diskmap_data).forEach(function (k) {
if (diskmap_data[k]) data += processGroup(request_headers.query.group,diskmap_data[k],k);
});
} else { */
data = processGroup(request_headers.query.group, diskmap_data);
//}
headers = "200 OK\nContent-Type: wtv/download-list";
} catch (e) {
var errpage = doErrorPage(400);
headers = errpage[0];
data = errpage[1];
console.log("wtv-update:/sync error", e);
}
}
} else {
var errpage = doErrorPage(404,"The requested DiskMap does not exist.");
headers = errpage[0];
data = errpage[1];
console.log("wtv-update:/sync error", "could not find diskmap");
} }
} }
headers = `200 OK
Content-type: text/download-list`

View File

@@ -13,8 +13,6 @@ var ClientSessionData = require('./session_data.js');
var ports = []; var ports = [];
var service_vault_dir = __dirname + "/ServiceVault";
String.prototype.reverse = function () { String.prototype.reverse = function () {
var splitString = this.split(""); var splitString = this.split("");
var reverseArray = splitString.reverse(); var reverseArray = splitString.reverse();
@@ -87,92 +85,77 @@ async function processPath(socket, path, request_headers = new Array(), service_
var headers, data = null; var headers, data = null;
var request_is_direct_file = false; var request_is_direct_file = false;
var request_is_async = false; var request_is_async = false;
path = path.replace(/\\/g, "/"); var service_vault_found = false;
var service_path = path;
try { try {
try { service_vaults.forEach(function (service_vault_dir) {
// try to see if the exact request exists if (service_vault_found) return;
if (fs.lstatSync(path).isFile()) { path = service_vault_dir.path + "/" + service_path.replace(/\\/g, "/");
request_is_direct_file = true;
if (fs.existsSync(path)) {
// file exists, read it and return it
service_vault_found = true;
request_is_async = true;
if (!zquiet) console.log(" * Found " + path + " in " + service_vault_dir.name +" to handle request (Direct File Mode) [Socket " + socket.id + "]");
var contype = getConType(path);
headers = "200 OK\n"
headers += "Content-Type: " + contype;
fs.readFile(path, null, function (err, data) {
sendToClient(socket, headers, data);
});
} else if (fs.existsSync(path + ".txt")) {
service_vault_found = true;
// raw text format, entire payload expected (headers and content)
if (!zquiet) console.log(" * Found " + path + ".txt in " + service_vault_dir.name +" to handle request (Raw TXT Mode) [Socket " + socket.id + "]");
request_is_async = true;
fs.readFile(path + ".txt", 'Utf-8', function (err, file_raw) {
if (file_raw.indexOf("\n\n") > 0) {
// split headers and data by newline (unix format)
var file_raw_split = file_raw.split("\n\n");
headers = file_raw_split[0];
file_raw_split.shift();
data = file_raw_split.join("\n");
} else if (file_raw.indexOf("\r\n\r\n") > 0) {
// split headers and data by carrage return + newline (windows format)
var file_raw_split = file_raw.split("\r\n\r\n");
headers = file_raw_split[0].replace(/\r/g, "");
file_raw_split.shift();
data = file_raw_split.join("\r\n");
} else {
// couldn't find two line breaks, assume entire file is just headers
headers = file_raw;
data = '';
}
sendToClient(socket, headers, data);
});
} else if (fs.existsSync(path + ".js")) {
service_vault_found = true;
// synchronous js scripting, process with vars, must set 'headers' and 'data' appropriately.
// loaded script will have r/w access to any JavaScript vars this function does.
// request headers are in an array named `request_headers`.
// Query arguments in `request_headers.query`
if (!zquiet) console.log(" * Found " + path + ".js in " + service_vault_dir.name + " 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;
socket_sessions[socket.id].starttime = Math.floor(new Date().getTime() / 1000);
var jscript_eval = fs.readFileSync(path + ".js").toString();
eval(jscript_eval);
if (request_is_async && !zquiet) console.log(" * Script requested Asynchronous mode");
} }
} catch (e) { else if (fs.existsSync(path + ".html")) {
// do nothing its fine service_vault_found = true;
} // Standard HTML with no headers, WTV Style
if (!zquiet) console.log(" * Found " + path + ".html in " + service_vault_dir.name +" to handle request (HTML Mode) [Socket " + socket.id + "]");
if (request_is_direct_file) { request_is_async = true;
// file exists, read it and return it headers = "200 OK\n"
if (!zquiet) console.log(" * Found " + path + " to handle request (Direct File Mode) [Socket " + socket.id +"]"); headers += "Content-Type: text/html"
var contype = getConType(path); fs.readFile(path + ".html", null, function (err, data) {
request_is_async = true; sendToClient(socket, headers, data);
headers = "200 OK\n" });
headers += "Content-Type: " + contype; }
fs.readFile(path, null, function (err, data) { // 'headers' and 'data' should both be set with content by this point!
sendToClient(socket, headers, data); });
});
} else if (fs.existsSync(path + ".txt")) {
// raw text format, entire payload expected (headers and content)
if (!zquiet) console.log(" * Found " + path + ".txt to handle request (Raw TXT Mode) [Socket " + socket.id + "]");
request_is_async = true;
fs.readFile(path + ".txt", 'Utf-8', function (err, file_raw) {
if (file_raw.indexOf("\n\n") > 0) {
// split headers and data by newline (unix format)
var file_raw_split = file_raw.split("\n\n");
headers = file_raw_split[0];
file_raw_split.shift();
data = file_raw_split.join("\n");
} else if (file_raw.indexOf("\r\n\r\n") > 0) {
// split headers and data by carrage return + newline (windows format)
var file_raw_split = file_raw.split("\r\n\r\n");
headers = file_raw_split[0].replace(/\r/g, "");
file_raw_split.shift();
data = file_raw_split.join("\r\n");
} else {
// couldn't find two line breaks, assume entire file is just headers
headers = file_raw;
data = '';
}
sendToClient(socket, headers, data);
});
} else if (fs.existsSync(path + ".js")) {
// synchronous js scripting, process with vars, must set 'headers' and 'data' appropriately.
// loaded script will have r/w access to any JavaScript vars this function does.
// request headers are in an array named `request_headers`.
// Query arguments in `request_headers.query`
if (!zquiet) console.log(" * Found " + 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.replace(/\\/g, "/") + "/" + service_name;
socket_sessions[socket.id].starttime = Math.floor(new Date().getTime() / 1000);
var jscript_eval = fs.readFileSync(path + ".js").toString();
eval(jscript_eval);
if (request_is_async && !zquiet) console.log(" * Script requested Asynchronous mode");
}
else if (fs.existsSync(path + ".html")) {
// Standard HTML with no headers, WTV Style
if (!zquiet) console.log(" * Found " + path + ".html to handle request (HTML Mode) [Socket " + socket.id +"]");
request_is_async = true;
headers = "200 OK\n"
headers += "Content-Type: text/html"
fs.readFile(path + ".html", null, function (err, data) {
sendToClient(socket, headers, data);
});
} else {
var errpage = doErrorPage(404);
headers = errpage[0];
data = errpage[1];
}
// 'headers' and 'data' should both be set with content by this point!
if (headers == null && !request_is_async) {
var errpage = doErrorPage(400);
headers = errpage[0];
data = errpage[1];
console.log(" * Scripting or Data error: Headers were not defined. (headers,data) as follows:")
console.log(socket.id,headers,data)
}
if (data === null) {
data = '';
}
} catch (e) { } catch (e) {
var errpage = doErrorPage(400); var errpage = doErrorPage(400);
headers = errpage[0]; headers = errpage[0];
@@ -180,6 +163,22 @@ async function processPath(socket, path, request_headers = new Array(), service_
console.log(" * Scripting error:",e); console.log(" * Scripting error:",e);
} }
if (!request_is_async) { if (!request_is_async) {
if (!service_vault_found) {
console.log(" * Could not find a Service Vault for", service_path);
var errpage = doErrorPage(404);
headers = errpage[0];
data = errpage[1];
}
if (headers == null && !request_is_async) {
var errpage = doErrorPage(400);
headers = errpage[0];
data = errpage[1];
console.log(" * Scripting or Data error: Headers were not defined. (headers,data) as follows:")
console.log(socket.id, headers, data)
}
if (data === null) {
data = '';
}
sendToClient(socket, headers, data); sendToClient(socket, headers, data);
} }
} }
@@ -250,7 +249,7 @@ async function processURL(socket, request_headers) {
} }
// assume webtv since there is a :/ in the GET // assume webtv since there is a :/ in the GET
var service_name = shortURL.split(':/')[0]; var service_name = shortURL.split(':/')[0];
var urlToPath = service_vault_dir.replace(/\\/g, "/") + "/" + service_name + "/" + shortURL.split(':/')[1]; var urlToPath = service_name + "/" + shortURL.split(':/')[1];
if (zshowheaders) console.log(" * Incoming headers on socket ID", socket.id, (await processSSID(request_headers))); if (zshowheaders) console.log(" * Incoming headers on socket ID", socket.id, (await processSSID(request_headers)));
processPath(socket, urlToPath, request_headers, service_name); processPath(socket, urlToPath, request_headers, service_name);
} else if (shortURL.indexOf('http://') >= 0 || shortURL.indexOf('https://') >= 0) { } else if (shortURL.indexOf('http://') >= 0 || shortURL.indexOf('https://') >= 0) {
@@ -530,7 +529,7 @@ function headersAreStandard(string, verbose = false) {
async function processRequest(socket, data_hex, returnHeadersBeforeSecure = false, encryptedRequest = false) { async function processRequest(socket, data_hex, returnHeadersBeforeSecure = false, encryptedRequest = false) {
var url = ""; var url = "";
var data = CryptoJS.enc.Latin1.stringify(CryptoJS.enc.Hex.parse(data_hex)); var data = Buffer.from(data_hex,'hex').toString('ascii');
var headers = new Array(); var headers = new Array();
if (typeof data === "string") { if (typeof data === "string") {
@@ -556,6 +555,14 @@ async function processRequest(socket, data_hex, returnHeadersBeforeSecure = fals
} }
var enc_data = CryptoJS.enc.Hex.parse(data_hex.substring(header_length * 2)); var enc_data = CryptoJS.enc.Hex.parse(data_hex.substring(header_length * 2));
if (enc_data.sigBytes > 0) { if (enc_data.sigBytes > 0) {
if (!socket_sessions[socket.id].wtvsec) {
var errpage = doErrorPage(400);
headers = errpage[0];
headers += "wtv-visit: client:relog\n";
data = errpage[1];
sendToClient(socket, headers, data);
return;
}
var dec_data = CryptoJS.lib.WordArray.create(socket_sessions[socket.id].wtvsec.Decrypt(0, enc_data)); var dec_data = CryptoJS.lib.WordArray.create(socket_sessions[socket.id].wtvsec.Decrypt(0, enc_data));
var secure_headers = await processRequest(socket, dec_data.toString(CryptoJS.enc.Hex), true, true); var secure_headers = await processRequest(socket, dec_data.toString(CryptoJS.enc.Hex), true, true);
headers.encrypted = true; headers.encrypted = true;
@@ -570,6 +577,8 @@ async function processRequest(socket, data_hex, returnHeadersBeforeSecure = fals
socket.ssid = headers["wtv-client-serial-number"]; socket.ssid = headers["wtv-client-serial-number"];
if (!ssid_sessions[socket.ssid]) { if (!ssid_sessions[socket.ssid]) {
ssid_sessions[socket.ssid] = new ClientSessionData(); ssid_sessions[socket.ssid] = new ClientSessionData();
ssid_sessions[socket.ssid].sockets = new Array();
ssid_sessions[socket.ssid].sockets.push(socket.id);
} }
} }
@@ -592,7 +601,7 @@ async function processRequest(socket, data_hex, returnHeadersBeforeSecure = fals
return headers; return headers;
} }
if (headers.secure === true) { if (headers.secure === true || headers.encrypted === true) {
if (!socket_sessions[socket.id].wtvsec) { if (!socket_sessions[socket.id].wtvsec) {
if (!zquiet) console.log(" * Starting new WTVSec instance on socket", socket.id); if (!zquiet) console.log(" * Starting new WTVSec instance on socket", socket.id);
if (ssid_sessions[socket.ssid].get("wtv-incarnation")) { if (ssid_sessions[socket.ssid].get("wtv-incarnation")) {
@@ -636,7 +645,7 @@ async function processRequest(socket, data_hex, returnHeadersBeforeSecure = fals
if (zdebug) console.log(" # Encrypted Request (SECURE ON)", "on", socket.id, secure_headers); if (zdebug) console.log(" # Encrypted Request (SECURE ON)", "on", socket.id, secure_headers);
if (!secure_headers.request) { if (!secure_headers.request) {
socket_sessions[socket.id].secure = false; socket_sessions[socket.id].secure = false;
var errpage = doErrorPage(499, "Security Stream Busted"); var errpage = doErrorPage(400);
headers = errpage[0]; headers = errpage[0];
data = errpage[1]; data = errpage[1];
sendToClient(socket, headers, data); sendToClient(socket, headers, data);
@@ -649,8 +658,9 @@ async function processRequest(socket, data_hex, returnHeadersBeforeSecure = fals
}); });
} }
} }
} else {
headers = await checkForPostData(socket, headers, data, data_hex);
} }
headers = await checkForPostData(socket, headers, data, data_hex);
if (!headers.request_url) { if (!headers.request_url) {
// still no url, likely lost encryption stream, tell client to relog // still no url, likely lost encryption stream, tell client to relog
/* /*
@@ -688,28 +698,13 @@ async function checkForPostData(socket, headers, data, data_hex) {
// \n\n // \n\n
var header_length = data.length + 2; var header_length = data.length + 2;
} }
var post_data = CryptoJS.enc.Hex.parse(data_hex.substring(header_length * 2));
if (socket_sessions[socket.id].secure == true) { if (socket_sessions[socket.id].secure == true) {
var enc_data = CryptoJS.enc.Hex.parse(socket_sessions[socket.id].buffer.toString(CryptoJS.enc.Hex).substring(header_length * 2)); if (zdebug) console.log(" # Encrypted POST Content (SECURE ON)", "on", socket.id, "[", post_data.sigBytes, "bytes ]");
if (enc_data.sigBytes > 0) {
if (headersAreStandard(enc_data.toString(CryptoJS.enc.Latin1))) {
// some builds (like our targeted 3833), send SECURE ON but then unencrypted headers
if (zdebug) console.log(" # Psuedo-encrypted POST Content (SECURE ON)", "on", socket.id);
// don't actually encrypt output
headers.psuedo_encryption = true;
ssid_sessions[socket.ssid].set("box-does-psuedo-encryption", true);
socket_sessions[socket.id].secure = false;
headers.post_data = await processRequest(socket, enc_data.toString(CryptoJS.enc.Hex), true);
} else {
// SECURE ON and detected encrypted data
ssid_sessions[socket.ssid].set("box-does-psuedo-encryption", false);
headers.post_data = CryptoJS.lib.WordArray.create(socket_sessions[socket.id].wtvsec.Decrypt(0, enc_data))
if (zdebug) console.log(" # Encrypted POST Content (SECURE ON)", "on", socket.id);
}
}
} else { } else {
if (zdebug) console.log(" # Unencrypted POST Content", "on", socket.id); if (zdebug) console.log(" # Unencrypted POST Content", "on", socket.id);
headers.post_data = CryptoJS.enc.Hex.parse(socket_sessions[socket.id].buffer.toString(CryptoJS.enc.Hex).substring(header_length * 2));
} }
headers.post_data = post_data;
} }
} }
return headers; return headers;
@@ -719,9 +714,20 @@ async function cleanupSocket(socket) {
try { try {
if (!zquiet) console.log(" * Destroying old WTVSec instance on disconnected socket", socket.id); if (!zquiet) console.log(" * Destroying old WTVSec instance on disconnected socket", socket.id);
delete socket_sessions[socket.id].buffer; delete socket_sessions[socket.id].buffer;
delete socket_sessions[socket.id].wtvsec; delete socket_sessions[socket.id].wtvsec;
delete socket_sessions[socket.id]; delete socket_sessions[socket.id];
if (socket.ssid) {
if (ssid_sessions[socket.ssid].sockets.findIndex(element => element = socket.id) != -1) {
ssid_sessions[socket.ssid].sockets.splice(ssid_sessions[socket.ssid].sockets.findIndex(element => element = socket.id));
}
var fuckyou = ssid_sessions[socket.ssid].sockets;
if (ssid_sessions[socket.ssid].sockets.length === 0 && ssid_sessions[socket.ssid].get("wtvsec_login")) {
// if last socket for SSID disconnected, destroy login session
if (!zquiet) console.log(" * Last socket from WebTV SSID", processSSID(socket.ssid),"disconnected, destroying initial WTVSec instance");
ssid_sessions[socket.ssid].delete("wtvsec_login");
}
}
;
socket.end(); socket.end();
} catch (e) { } catch (e) {
console.log(" # Could not clean up socket data for socket ID", socket.id, e); console.log(" # Could not clean up socket data for socket ID", socket.id, e);
@@ -736,7 +742,7 @@ async function handleSocket(socket) {
socket_sessions[socket.id] = []; socket_sessions[socket.id] = [];
socket.setEncoding('hex'); //set data encoding (either 'ascii', 'utf8', or 'base64') socket.setEncoding('hex'); //set data encoding (either 'ascii', 'utf8', or 'base64')
socket.on('data', function (data_hex) { socket.on('data', function (data_hex) {
socket.setTimeout(300); socket.setTimeout(minisrv_config.config.socket_timeout);
if (socket_sessions[socket.id].buffer) { if (socket_sessions[socket.id].buffer) {
socket_sessions[socket.id].buffer.concat(CryptoJS.enc.Hex.parse(data_hex)); socket_sessions[socket.id].buffer.concat(CryptoJS.enc.Hex.parse(data_hex));
} else { } else {
@@ -776,6 +782,17 @@ function integrateConfig(main, user) {
return main; return main;
} }
function returnAbsolsutePath(path) {
if (path.substring(0, 1) != "/" && path.substring(1, 1) != ":") {
// non-absolute path, so use current directory as base
path = (__dirname + "/" + path).replace(/\\/g, "/");
} else {
// already absolute path
path = path.replace(/\\/g, "/");
}
return path;
}
var z_title = "zefie's wtv minisrv v" + require('./package.json').version; var z_title = "zefie's wtv minisrv v" + require('./package.json').version;
console.log("**** Welcome to " + z_title + " ****"); console.log("**** Welcome to " + z_title + " ****");
console.log(" *** Reading global configuration..."); console.log(" *** Reading global configuration...");
@@ -784,6 +801,8 @@ try {
} catch (e) { } catch (e) {
throw ("ERROR: Could not read config.json", e); throw ("ERROR: Could not read config.json", e);
} }
var service_vaults = new Array();
try { try {
if (fs.lstatSync(__dirname + "/user_config.json")) { if (fs.lstatSync(__dirname + "/user_config.json")) {
console.log(" *** Reading user configuration..."); console.log(" *** Reading user configuration...");
@@ -809,6 +828,12 @@ if (throw_me) {
throw ("An error has occured while reading the configuration files."); 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);
});
var service_ip = minisrv_config.config.service_ip; var service_ip = minisrv_config.config.service_ip;
Object.keys(minisrv_config.services).forEach(function (k) { Object.keys(minisrv_config.services).forEach(function (k) {
if (minisrv_config.services[k].disabled) return; if (minisrv_config.services[k].disabled) return;

View File

@@ -1,9 +1,12 @@
{ {
"config": { "config": {
"service_ip": "0.0.0.0", "service_ip": "0.0.0.0",
"ServiceVault": "ServiceVault",
"UserServiceVault": "UserServiceVault",
"service_name": "HackTV", "service_name": "HackTV",
"send_tellyscripts": false, "send_tellyscripts": false,
"hide_ssid_in_logs": true, "hide_ssid_in_logs": true,
"socket_timeout": 350,
"verbosity": 2 "verbosity": 2
}, },
"services": { "services": {

View File

@@ -1,6 +1,6 @@
{ {
"name": "zefie_wtvp_minisrv", "name": "zefie_wtvp_minisrv",
"version": "0.8.1", "version": "0.9.0",
"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

@@ -49,7 +49,6 @@
<Content Include="ServiceVault\wtv-flashrom\ROMCache\up-arrows.swf" /> <Content Include="ServiceVault\wtv-flashrom\ROMCache\up-arrows.swf" />
<Content Include="ServiceVault\wtv-flashrom\ROMCache\WebTVLogoJewel.gif" /> <Content Include="ServiceVault\wtv-flashrom\ROMCache\WebTVLogoJewel.gif" />
<Content Include="ServiceVault\wtv-flashrom\willie.js" /> <Content Include="ServiceVault\wtv-flashrom\willie.js" />
<Content Include="ServiceVault\wtv-home\zefie.html" />
<Content Include="ServiceVault\wtv-music\demo\hacktv4.gif" /> <Content Include="ServiceVault\wtv-music\demo\hacktv4.gif" />
<Content Include="ServiceVault\wtv-music\demo\index.html" /> <Content Include="ServiceVault\wtv-music\demo\index.html" />
<Content Include="ServiceVault\wtv-music\demo\midi\acey.mid" /> <Content Include="ServiceVault\wtv-music\demo\midi\acey.mid" />
@@ -184,14 +183,13 @@
<Content Include="ServiceVault\wtv-tricks\info.js"> <Content Include="ServiceVault\wtv-tricks\info.js">
<SubType>Code</SubType> <SubType>Code</SubType>
</Content> </Content>
<Content Include="ServiceVault\wtv-update\content\diskmaps\htvupdate.txt" /> <Content Include="ServiceVault\wtv-update\content\diskmaps\DealerDemo.json">
<Content Include="ServiceVault\wtv-update\content\htvupdate\Games\cSetup.html" /> <SubType>Code</SubType>
<Content Include="ServiceVault\wtv-update\content\htvupdate\Games\Games.html" /> </Content>
<Content Include="ServiceVault\wtv-update\content\htvupdate\MattMan\Tricks\tricks.html" />
<Content Include="ServiceVault\wtv-update\sync.js"> <Content Include="ServiceVault\wtv-update\sync.js">
<SubType>Code</SubType> <SubType>Code</SubType>
</Content> </Content>
<Content Include="ServiceVault\wtv-update\update.html" /> <Content Include="ServiceVault\wtv-update\DealerDemo.html" />
<Content Include="ServiceVault\wtv-home\home.js" /> <Content Include="ServiceVault\wtv-home\home.js" />
<Content Include="ServiceVault\wtv-update\updatesuccess.txt" /> <Content Include="ServiceVault\wtv-update\updatesuccess.txt" />
<Content Include="ServiceVault\wtv-1800\finish-prereg.js" /> <Content Include="ServiceVault\wtv-1800\finish-prereg.js" />
@@ -228,10 +226,6 @@
<Folder Include="ServiceVault\wtv-log\" /> <Folder Include="ServiceVault\wtv-log\" />
<Folder Include="ServiceVault\wtv-update\content\" /> <Folder Include="ServiceVault\wtv-update\content\" />
<Folder Include="ServiceVault\wtv-update\content\diskmaps\" /> <Folder Include="ServiceVault\wtv-update\content\diskmaps\" />
<Folder Include="ServiceVault\wtv-update\content\htvupdate\" />
<Folder Include="ServiceVault\wtv-update\content\htvupdate\Games\" />
<Folder Include="ServiceVault\wtv-update\content\htvupdate\MattMan\" />
<Folder Include="ServiceVault\wtv-update\content\htvupdate\MattMan\Tricks\" />
</ItemGroup> </ItemGroup>
<Import Project="$(VSToolsPath)\Node.js Tools\Microsoft.NodejsToolsV2.targets" /> <Import Project="$(VSToolsPath)\Node.js Tools\Microsoft.NodejsToolsV2.targets" />
</Project> </Project>