Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
Synchronet
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Main
Synchronet
Commits
d2efa548
Commit
d2efa548
authored
9 years ago
by
echicken
Browse files
Options
Downloads
Patches
Plain Diff
Cleanup
parent
662e4c53
Branches
Branches containing commit
Tags
Tags containing commit
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
mods/websocket-proxy.js
+189
-99
189 additions, 99 deletions
mods/websocket-proxy.js
mods/websocket-rlogin-service.js
+5
-3
5 additions, 3 deletions
mods/websocket-rlogin-service.js
with
194 additions
and
102 deletions
mods/websocket-proxy.js
+
189
−
99
View file @
d2efa548
load
(
"
sha1.js
"
);
load
(
'
sha1.js
'
);
var
WebSocketProxy
=
function
(
client
)
{
...
...
@@ -20,10 +20,10 @@ var WebSocketProxy = function(client) {
var
ServerDataBuffer
=
[];
// From server
function
CalculateWebSocketKey
(
InLine
)
{
var
Digits
=
""
;
var
Digits
=
''
;
var
Spaces
=
0
;
for
(
var
i
=
0
;
i
<
InLine
.
length
;
i
++
)
{
if
(
InLine
.
charAt
(
i
)
==
"
"
)
{
if
(
InLine
.
charAt
(
i
)
==
'
'
)
{
Spaces
++
;
}
else
if
(
!
isNaN
(
InLine
.
charAt
(
i
)))
{
Digits
+=
InLine
.
charAt
(
i
);
...
...
@@ -60,7 +60,8 @@ var WebSocketProxy = function(client) {
}
break
;
case
WEBSOCKET_DATA
:
// We're in a data packet, so check for 0xFF, which indicates the data packet is done
// We're in a data packet, so check for 0xFF, which
// indicates the data packet is done
if
(
InByte
==
0xFF
)
{
FWebSocketState
=
WEBSOCKET_NEED_PACKET_START
;
}
else
{
...
...
@@ -72,10 +73,13 @@ var WebSocketProxy = function(client) {
InByte2
=
client
.
socket
.
recvBin
(
1
);
Result
.
push
(((
InByte
&
31
)
<<
6
)
|
(
InByte2
&
63
));
}
else
{
// Handle UTF-8 decode (should never need this, but included anyway)
// Handle UTF-8 decode (should never need this, but
// included anyway)
InByte2
=
client
.
socket
.
recvBin
(
1
);
InByte3
=
client
.
socket
.
recvBin
(
1
);
Result
.
push
(((
InByte
&
15
)
<<
12
)
|
((
InByte2
&
63
)
<<
6
)
|
(
InByte3
&
63
));
Result
.
push
(
((
InByte
&
15
)
<<
12
)
|
((
InByte2
&
63
)
<<
6
)
|
(
InByte3
&
63
)
);
}
}
break
;
...
...
@@ -95,7 +99,8 @@ var WebSocketProxy = function(client) {
// Check what the client packet state is
switch
(
FWebSocketState
)
{
case
WEBSOCKET_NEED_PACKET_START
:
// Next byte will give us the opcode, and also tell is if the message is fragmented
// Next byte will give us the opcode, and also tell is if
// the message is fragmented
FFrameMask
=
[];
FFrameOpCode
=
client
.
socket
.
recvBin
(
1
);
FFramePayloadLength
=
0
;
...
...
@@ -120,21 +125,31 @@ var WebSocketProxy = function(client) {
FWebSocketState
=
WEBSOCKET_DATA
;
break
;
case
WEBSOCKET_DATA
:
InByte
=
(
client
.
socket
.
recvBin
(
1
)
^
FFrameMask
[
FFramePayloadReceived
++
%
4
]);
InByte
=
(
client
.
socket
.
recvBin
(
1
)
^
FFrameMask
[
FFramePayloadReceived
++
%
4
]
);
// Check if the byte needs to be UTF-8 decoded
if
((
InByte
&
0x80
)
===
0
)
{
Result
.
push
(
InByte
);
}
else
if
((
InByte
&
0xE0
)
===
0xC0
)
{
// Handle UTF-8 decode
InByte2
=
(
client
.
socket
.
recvBin
(
1
)
^
FFrameMask
[
FFramePayloadReceived
++
%
4
]);
InByte2
=
(
client
.
socket
.
recvBin
(
1
)
^
FFrameMask
[
FFramePayloadReceived
++
%
4
]
);
Result
.
push
(((
InByte
&
31
)
<<
6
)
|
(
InByte2
&
63
));
}
else
{
log
(
LOG_
ERR
,
"
Byte out of range:
"
+
InByte
);
log
(
LOG_
NOTICE
,
'
Byte out of range:
'
+
InByte
);
}
// Check if we've received the full payload
if
(
FFramePayloadReceived
===
FFramePayloadLength
)
FWebSocketState
=
WEBSOCKET_NEED_PACKET_START
;
if
(
FFramePayloadReceived
===
FFramePayloadLength
)
{
FWebSocketState
=
WEBSOCKET_NEED_PACKET_START
;
}
break
;
}
}
...
...
@@ -168,7 +183,7 @@ var WebSocketProxy = function(client) {
client
.
socket
.
sendBin
((
AData
[
i
]
>>
6
)
|
192
,
1
);
client
.
socket
.
sendBin
((
AData
[
i
]
&
63
)
|
128
,
1
);
}
else
{
log
(
LOG_
ERR
,
"
Byte out of range:
"
+
AData
[
i
]);
log
(
LOG_
NOTICE
,
'
Byte out of range:
'
+
AData
[
i
]);
}
}
...
...
@@ -184,12 +199,14 @@ var WebSocketProxy = function(client) {
// Check if the byte needs to be UTF-8 encoded
if
((
AData
[
i
]
&
0xFF
)
<=
127
)
{
ToSend
.
push
(
AData
[
i
]);
}
else
if
(((
AData
[
i
]
&
0xFF
)
>=
128
)
&&
((
AData
[
i
]
&
0xFF
)
<=
2047
))
{
}
else
if
(
((
AData
[
i
]
&
0xFF
)
>=
128
)
&&
((
AData
[
i
]
&
0xFF
)
<=
2047
)
)
{
// Handle UTF-8 encode
ToSend
.
push
((
AData
[
i
]
>>
6
)
|
192
);
ToSend
.
push
((
AData
[
i
]
&
63
)
|
128
);
}
else
{
log
(
LOG_
ERR
,
"
Byte out of range:
"
+
AData
[
i
]);
log
(
LOG_
NOTICE
,
'
Byte out of range:
'
+
AData
[
i
]);
}
}
...
...
@@ -200,9 +217,10 @@ var WebSocketProxy = function(client) {
client
.
socket
.
sendBin
(
126
,
1
);
client
.
socket
.
sendBin
(
ToSend
.
length
,
2
);
}
else
{
// NOTE: client.socket.sendBin(ToSend.length, 8); didn't work, so this
// modification limits the send to 2^32 bytes (probably not an issue)
// Probably should look into a proper fix at some point though
// NOTE: client.socket.sendBin(ToSend.length, 8); didn't work,
// so this modification limits the send to 2^32 bytes (probably
// not an issue). Probably should look into a proper fix at
// some point though
client
.
socket
.
sendBin
(
127
,
1
);
client
.
socket
.
sendBin
(
0
,
4
);
client
.
socket
.
sendBin
(
ToSend
.
length
,
4
);
...
...
@@ -220,17 +238,20 @@ var WebSocketProxy = function(client) {
try
{
// Keep reading header data until we get all the data we want
while
(
true
)
{
// Read another line,
and
abort if we don't get one
with
in 5 seconds
// Read another line, abort if we don't get one in 5 seconds
var
InLine
=
client
.
socket
.
recvline
(
1024
,
5
);
if
(
InLine
===
null
)
{
log
(
LOG_ERR
,
"
Timeout exceeded while waiting for complete handshake
"
);
log
(
LOG_ERR
,
'
Timeout exceeded while waiting for complete handshake
'
);
return
false
;
}
log
(
LOG_DEBUG
,
"
Handshake Line:
"
+
InLine
);
log
(
LOG_DEBUG
,
'
Handshake Line:
'
+
InLine
);
// Check for blank line (indicates we have most of the header, and only the last 8 bytes remain
if
(
InLine
===
""
)
{
// Check for blank line (indicates we have most of the header,
// and only the last 8 bytes remain
if
(
InLine
===
''
)
{
switch
(
self
.
headers
[
'
Version
'
])
{
case
0
:
return
ShakeHandsDraft0
();
...
...
@@ -239,67 +260,88 @@ var WebSocketProxy = function(client) {
case
13
:
return
ShakeHandsVersion7
();
default
:
// TODO If this version does not
// match a version understood by the server, the server MUST
// abort the websocket handshake described in this section and
// instead send an appropriate HTTP error code (such as 426
// Upgrade Required), and a |Sec-WebSocket-Version| header
// indicating the version(s) the server is capable of
// understanding.
// TODO If this version does not match a version
// understood by the server, the server MUST abort
// the websocket handshake described in this section
// and instead send an appropriate HTTP error code
// (such as 426 Upgrade Required), and a
// |Sec-WebSocket-Version| header indicating the
// version(s) the server is capable of
// understanding.
break
;
}
break
;
}
else
if
(
InLine
.
indexOf
(
"
Connection:
"
)
===
0
)
{
}
else
if
(
InLine
.
indexOf
(
'
Connection:
'
)
===
0
)
{
// Example: "Connection: Upgrade"
self
.
headers
[
'
Connection
'
]
=
InLine
.
replace
(
/Connection:
\s?
/i
,
""
);
}
else
if
(
InLine
.
indexOf
(
"
GET
"
)
===
0
)
{
self
.
headers
[
'
Connection
'
]
=
InLine
.
replace
(
/Connection:
\s?
/i
,
''
);
}
else
if
(
InLine
.
indexOf
(
'
GET
'
)
===
0
)
{
// Example: "GET /demo HTTP/1.1"
var
GET
=
InLine
.
split
(
"
"
);
var
GET
=
InLine
.
split
(
'
'
);
self
.
headers
[
'
Path
'
]
=
GET
[
1
];
}
else
if
(
InLine
.
indexOf
(
"
Host:
"
)
===
0
)
{
}
else
if
(
InLine
.
indexOf
(
'
Host:
'
)
===
0
)
{
// Example: "Host: example.com"
self
.
headers
[
'
Host
'
]
=
InLine
.
replace
(
/Host:
\s?
/i
,
""
);
}
else
if
(
InLine
.
indexOf
(
"
Origin:
"
)
===
0
)
{
self
.
headers
[
'
Host
'
]
=
InLine
.
replace
(
/Host:
\s?
/i
,
''
);
}
else
if
(
InLine
.
indexOf
(
'
Origin:
'
)
===
0
)
{
// Example: "Origin: http://example.com"
self
.
headers
[
'
Origin
'
]
=
InLine
.
replace
(
/Origin:
\s?
/i
,
""
);
}
else
if
(
InLine
.
indexOf
(
"
Sec-WebSocket-Key:
"
)
===
0
)
{
self
.
headers
[
'
Origin
'
]
=
InLine
.
replace
(
/Origin:
\s?
/i
,
''
);
}
else
if
(
InLine
.
indexOf
(
'
Sec-WebSocket-Key:
'
)
===
0
)
{
// Example: "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ=="
self
.
headers
[
'
Key
'
]
=
InLine
.
replace
(
/Sec-WebSocket-Key:
\s?
/i
,
""
);
}
else
if
(
InLine
.
indexOf
(
"
Sec-WebSocket-Key1:
"
)
===
0
)
{
self
.
headers
[
'
Key
'
]
=
InLine
.
replace
(
/Sec-WebSocket-Key:
\s?
/i
,
''
);
}
else
if
(
InLine
.
indexOf
(
'
Sec-WebSocket-Key1:
'
)
===
0
)
{
// Example: "Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5"
self
.
headers
[
'
Key1
'
]
=
CalculateWebSocketKey
(
InLine
.
replace
(
/Sec-WebSocket-Key1:
\s?
/i
,
""
));
}
else
if
(
InLine
.
indexOf
(
"
Sec-WebSocket-Key2:
"
)
===
0
)
{
self
.
headers
[
'
Key1
'
]
=
CalculateWebSocketKey
(
InLine
.
replace
(
/Sec-WebSocket-Key1:
\s?
/i
,
''
)
);
}
else
if
(
InLine
.
indexOf
(
'
Sec-WebSocket-Key2:
'
)
===
0
)
{
// Example: "Sec-WebSocket-Key2: 12998 5 Y3 1 .P00"
self
.
headers
[
'
Key2
'
]
=
CalculateWebSocketKey
(
InLine
.
replace
(
/Sec-WebSocket-Key2:
\s?
/i
,
""
));
}
else
if
(
InLine
.
indexOf
(
"
Sec-WebSocket-Origin:
"
)
===
0
)
{
self
.
headers
[
'
Key2
'
]
=
CalculateWebSocketKey
(
InLine
.
replace
(
/Sec-WebSocket-Key2:
\s?
/i
,
''
)
);
}
else
if
(
InLine
.
indexOf
(
'
Sec-WebSocket-Origin:
'
)
===
0
)
{
// Example: "Sec-WebSocket-Origin: http://example.com"
self
.
headers
[
'
Origin
'
]
=
InLine
.
replace
(
/Sec-WebSocket-Origin:
\s?
/i
,
""
);
}
else
if
(
InLine
.
indexOf
(
"
Sec-WebSocket-Protocol:
"
)
===
0
)
{
self
.
headers
[
'
Origin
'
]
=
InLine
.
replace
(
/Sec-WebSocket-Origin:
\s?
/i
,
''
);
}
else
if
(
InLine
.
indexOf
(
'
Sec-WebSocket-Protocol:
'
)
===
0
)
{
// Example: "Sec-WebSocket-Protocol: sample"
self
.
headers
[
'
SubProtocol
'
]
=
InLine
.
replace
(
/Sec-WebSocket-Protocol:
\s?
/i
,
""
);
}
else
if
(
InLine
.
indexOf
(
"
Sec-WebSocket-Draft
"
)
===
0
)
{
self
.
headers
[
'
SubProtocol
'
]
=
InLine
.
replace
(
/Sec-WebSocket-Protocol:
\s?
/i
,
''
);
}
else
if
(
InLine
.
indexOf
(
'
Sec-WebSocket-Draft
'
)
===
0
)
{
// Example: "Sec-WebSocket-Draft: 2"
try
{
self
.
headers
[
'
Version
'
]
=
parseInt
(
InLine
.
replace
(
/Sec-WebSocket-Draft:
\s?
/i
,
""
));
self
.
headers
[
'
Version
'
]
=
parseInt
(
InLine
.
replace
(
/Sec-WebSocket-Draft:
\s?
/i
,
''
)
);
}
catch
(
err
)
{
self
.
headers
[
'
Version
'
]
=
0
;
}
}
else
if
(
InLine
.
indexOf
(
"
Sec-WebSocket-Version
"
)
===
0
)
{
}
else
if
(
InLine
.
indexOf
(
'
Sec-WebSocket-Version
'
)
===
0
)
{
// Example: "Sec-WebSocket-Version: 8"
try
{
self
.
headers
[
'
Version
'
]
=
parseInt
(
InLine
.
replace
(
/Sec-WebSocket-Version:
\s?
/i
,
""
));
self
.
headers
[
'
Version
'
]
=
parseInt
(
InLine
.
replace
(
/Sec-WebSocket-Version:
\s?
/i
,
''
)
);
}
catch
(
err
)
{
self
.
headers
[
'
Version
'
]
=
0
;
}
}
else
if
(
InLine
.
indexOf
(
"
Upgrade:
"
)
===
0
)
{
}
else
if
(
InLine
.
indexOf
(
'
Upgrade:
'
)
===
0
)
{
// Example: "Upgrade: websocket"
self
.
headers
[
'
Upgrade
'
]
=
InLine
.
replace
(
/Upgrade:
\s?
/i
,
""
);
}
else
if
(
InLine
.
indexOf
(
"
Cookie:
"
)
===
0
)
{
self
.
headers
[
'
Cookie
'
]
=
InLine
.
replace
(
/Cookie:
\s?
/i
,
""
);
self
.
headers
[
'
Upgrade
'
]
=
InLine
.
replace
(
/Upgrade:
\s?
/i
,
''
);
}
else
if
(
InLine
.
indexOf
(
'
Cookie:
'
)
===
0
)
{
self
.
headers
[
'
Cookie
'
]
=
InLine
.
replace
(
/Cookie:
\s?
/i
,
''
);
}
}
}
catch
(
err
)
{
log
(
LOG_ERR
,
"
ShakeHands() error:
"
+
err
.
toString
());
log
(
LOG_ERR
,
'
ShakeHands() error:
'
+
err
.
toString
());
}
return
false
;
...
...
@@ -307,17 +349,39 @@ var WebSocketProxy = function(client) {
function
ShakeHandsDraft0
()
{
// Ensure we have all the data we need
if
((
'
Key1
'
in
self
.
headers
)
&&
(
'
Key2
'
in
self
.
headers
)
&&
(
'
Host
'
in
self
.
headers
)
&&
(
'
Origin
'
in
self
.
headers
!==
""
)
&&
(
'
Path
'
in
self
.
headers
))
{
// Combine Key1, Key2, and the last 8 bytes into a string that we will later hash
var
ToHash
=
""
ToHash
+=
String
.
fromCharCode
((
self
.
headers
[
'
Key1
'
]
&
0xFF000000
)
>>
24
);
ToHash
+=
String
.
fromCharCode
((
self
.
headers
[
'
Key1
'
]
&
0x00FF0000
)
>>
16
);
ToHash
+=
String
.
fromCharCode
((
self
.
headers
[
'
Key1
'
]
&
0x0000FF00
)
>>
8
);
ToHash
+=
String
.
fromCharCode
((
self
.
headers
[
'
Key1
'
]
&
0x000000FF
)
>>
0
);
ToHash
+=
String
.
fromCharCode
((
self
.
headers
[
'
Key2
'
]
&
0xFF000000
)
>>
24
);
ToHash
+=
String
.
fromCharCode
((
self
.
headers
[
'
Key2
'
]
&
0x00FF0000
)
>>
16
);
ToHash
+=
String
.
fromCharCode
((
self
.
headers
[
'
Key2
'
]
&
0x0000FF00
)
>>
8
);
ToHash
+=
String
.
fromCharCode
((
self
.
headers
[
'
Key2
'
]
&
0x000000FF
)
>>
0
);
if
((
'
Key1
'
in
self
.
headers
)
&&
(
'
Key2
'
in
self
.
headers
)
&&
(
'
Host
'
in
self
.
headers
)
&&
(
'
Origin
'
in
self
.
headers
!==
''
)
&&
(
'
Path
'
in
self
.
headers
)
)
{
// Combine Key1, Key2, and the last 8 bytes into a string that we
// will later hash
var
ToHash
=
''
ToHash
+=
String
.
fromCharCode
(
(
self
.
headers
[
'
Key1
'
]
&
0xFF000000
)
>>
24
);
ToHash
+=
String
.
fromCharCode
(
(
self
.
headers
[
'
Key1
'
]
&
0x00FF0000
)
>>
16
);
ToHash
+=
String
.
fromCharCode
(
(
self
.
headers
[
'
Key1
'
]
&
0x0000FF00
)
>>
8
);
ToHash
+=
String
.
fromCharCode
(
(
self
.
headers
[
'
Key1
'
]
&
0x000000FF
)
>>
0
);
ToHash
+=
String
.
fromCharCode
(
(
self
.
headers
[
'
Key2
'
]
&
0xFF000000
)
>>
24
);
ToHash
+=
String
.
fromCharCode
(
(
self
.
headers
[
'
Key2
'
]
&
0x00FF0000
)
>>
16
);
ToHash
+=
String
.
fromCharCode
(
(
self
.
headers
[
'
Key2
'
]
&
0x0000FF00
)
>>
8
);
ToHash
+=
String
.
fromCharCode
(
(
self
.
headers
[
'
Key2
'
]
&
0x000000FF
)
>>
0
);
for
(
var
i
=
0
;
i
<
8
;
i
++
)
{
ToHash
+=
String
.
fromCharCode
(
client
.
socket
.
recvBin
(
1
));
}
...
...
@@ -326,17 +390,29 @@ var WebSocketProxy = function(client) {
var
Hashed
=
md5_calc
(
ToHash
,
true
);
// Setup the handshake response
var
Response
=
"
HTTP/1.1 101 Web Socket Protocol Handshake
\r\n
"
+
"
Upgrade: WebSocket
\r\n
"
+
"
Connection: Upgrade
\r\n
"
+
"
Sec-WebSocket-Origin:
"
+
self
.
headers
[
'
Origin
'
]
+
"
\r\n
"
+
"
Sec-WebSocket-Location: ws://
"
+
self
.
headers
[
'
Host
'
]
+
self
.
headers
[
'
Path
'
]
+
"
\r\n
"
;
if
(
'
SubProtocol
'
in
self
.
headers
)
Response
+=
"
Sec-WebSocket-Protocol:
"
+
self
.
headers
[
'
SubProtocol
'
]
+
"
\r\n
"
;
Response
+=
"
\r\n
"
;
var
Response
=
'
HTTP/1.1 101 Web Socket Protocol Handshake
\r\n
'
+
'
Upgrade: WebSocket
\r\n
'
+
'
Connection: Upgrade
\r\n
'
+
'
Sec-WebSocket-Origin:
'
+
self
.
headers
[
'
Origin
'
]
+
'
\r\n
'
+
'
Sec-WebSocket-Location: ws://
'
+
self
.
headers
[
'
Host
'
]
+
self
.
headers
[
'
Path
'
]
+
'
\r\n
'
;
if
(
'
SubProtocol
'
in
self
.
headers
)
{
Response
+=
'
Sec-WebSocket-Protocol:
'
+
self
.
headers
[
'
SubProtocol
'
]
+
'
\r\n
'
;
}
Response
+=
'
\r\n
'
;
// Loop through the hash string (which is hex encoded) and append the individual bytes to the response
// Loop through the hash string (which is hex encoded) and append
// the individual bytes to the response
for
(
var
i
=
0
;
i
<
Hashed
.
length
;
i
+=
2
)
{
Response
+=
String
.
fromCharCode
(
parseInt
(
Hashed
.
charAt
(
i
)
+
Hashed
.
charAt
(
i
+
1
),
16
));
Response
+=
String
.
fromCharCode
(
parseInt
(
Hashed
.
charAt
(
i
)
+
Hashed
.
charAt
(
i
+
1
),
16
)
);
}
// Send the response and return
...
...
@@ -344,9 +420,11 @@ var WebSocketProxy = function(client) {
return
true
;
}
else
{
// We're missing some pice of data, log what we do have
log
(
LOG_ERR
,
"
Missing some piece of handshake data. Here's what we have:
"
);
log
(
LOG_ERR
,
'
Missing some piece of handshake data. Here
\'
s what we have:
'
);
for
(
var
x
in
self
.
headers
)
{
log
(
LOG_ERR
,
x
+
"
=>
"
+
self
.
headers
[
x
]);
log
(
LOG_ERR
,
x
+
'
=>
'
+
self
.
headers
[
x
]);
}
return
false
;
}
...
...
@@ -354,8 +432,12 @@ var WebSocketProxy = function(client) {
function
ShakeHandsVersion7
()
{
// Ensure we have all the data we need
if
((
'
Key
'
in
self
.
headers
)
&&
(
'
Host
'
in
self
.
headers
)
&&
(
'
Origin
'
in
self
.
headers
!==
""
)
&&
(
'
Path
'
in
self
.
headers
))
{
var
AcceptGUID
=
"
258EAFA5-E914-47DA-95CA-C5AB0DC85B11
"
;
if
((
'
Key
'
in
self
.
headers
)
&&
(
'
Host
'
in
self
.
headers
)
&&
(
'
Origin
'
in
self
.
headers
!==
''
)
&&
(
'
Path
'
in
self
.
headers
)
)
{
var
AcceptGUID
=
'
258EAFA5-E914-47DA-95CA-C5AB0DC85B11
'
;
// Combine Key and GUID
var
ToHash
=
self
.
headers
[
'
Key
'
]
+
AcceptGUID
;
...
...
@@ -366,42 +448,48 @@ var WebSocketProxy = function(client) {
// Encode the hash
var
ToEncode
=
''
;
for
(
var
i
=
0
;
i
<=
38
;
i
+=
2
)
{
ToEncode
+=
String
.
fromCharCode
(
parseInt
(
Hashed
.
substr
(
i
,
2
),
16
));
ToEncode
+=
String
.
fromCharCode
(
parseInt
(
Hashed
.
substr
(
i
,
2
),
16
)
);
}
var
Encoded
=
base64_encode
(
ToEncode
);
// Setup the handshake response
var
Response
=
"
HTTP/1.1 101 Switching Protocols
\r\n
"
+
"
Upgrade: websocket
\r\n
"
+
"
Connection: Upgrade
\r\n
"
+
"
Sec-WebSocket-Accept:
"
+
Encoded
+
"
\r\n
"
;
if
(
'
SubProtocol
'
in
self
.
headers
)
Response
+=
"
Sec-WebSocket-Protocol: plain
\r\n
"
;
// Only sub-protocol we support
Response
+=
"
\r\n
"
;
var
Response
=
'
HTTP/1.1 101 Switching Protocols
\r\n
'
+
'
Upgrade: websocket
\r\n
'
+
'
Connection: Upgrade
\r\n
'
+
'
Sec-WebSocket-Accept:
'
+
Encoded
+
'
\r\n
'
;
if
(
'
SubProtocol
'
in
self
.
headers
)
{
// Only sub-protocol we support
Response
+=
'
Sec-WebSocket-Protocol: plain
\r\n
'
;
}
Response
+=
'
\r\n
'
;
// Send the response and return
client
.
socket
.
send
(
Response
);
return
true
;
}
else
{
// We're missing some pice of data, log what we do have
log
(
LOG_ERR
,
"
Missing some piece of handshake data. Here's what we have:
"
);
log
(
LOG_ERR
,
'
Missing some piece of handshake data. Here
\'
s what we have:
'
);
for
(
var
x
in
self
.
headers
)
{
log
(
LOG_ERR
,
x
+
"
=>
"
+
self
.
headers
[
x
]);
log
(
LOG_ERR
,
x
+
'
=>
'
+
self
.
headers
[
x
]);
}
return
false
;
}
}
this
.
__defineGetter__
(
"
data_waiting
"
,
'
data_waiting
'
,
function
()
{
return
(
ClientDataBuffer
.
length
>
0
);
}
);
this
.
send
=
function
(
data
)
{
if
(
typeof
data
==
"
string
"
)
{
data
=
data
.
split
(
""
).
map
(
function
(
d
)
{
if
(
typeof
data
==
=
'
string
'
)
{
data
=
data
.
split
(
''
).
map
(
function
(
d
)
{
return
ascii
(
d
);
}
);
...
...
@@ -410,15 +498,18 @@ var WebSocketProxy = function(client) {
}
this
.
receive
=
function
()
{
var
data
=
""
;
while
(
ClientDataBuffer
.
length
>
0
)
{
var
data
=
''
;
while
(
ClientDataBuffer
.
length
>
0
)
{
data
+=
ascii
(
ClientDataBuffer
.
shift
());
}
return
data
;
}
this
.
receiveArray
=
function
(
len
)
{
return
ClientDataBuffer
.
splice
(
0
,
(
typeof
len
==
"
number
"
?
len
:
ClientDataBuffer
.
length
));
return
ClientDataBuffer
.
splice
(
0
,
(
typeof
len
===
'
number
'
?
len
:
ClientDataBuffer
.
length
)
);
}
this
.
cycle
=
function
()
{
...
...
@@ -426,7 +517,6 @@ var WebSocketProxy = function(client) {
SendToWebSocketClient
(
ServerDataBuffer
.
splice
(
0
,
4096
));
}
if
(
!
ShakeHands
())
throw
"
ShakeHands() failed
"
;
if
(
!
ShakeHands
())
throw
'
ShakeHands() failed
'
;
}
\ No newline at end of file
This diff is collapsed.
Click to expand it.
mods/websocket-rlogin-service.js
+
5
−
3
View file @
d2efa548
...
...
@@ -17,8 +17,9 @@ function getSession(un) {
return
session
;
}
// Obfuscated lazy port of an unfinished node.js rlogin client I made quite some time ago.
// It does what it needs to do. Unless it doesn't - in which case, replace it with something better.
// Obfuscated lazy port of an unfinished rlogin client I made quite some time
// ago. It does what it needs to do. Unless it doesn't - in which case,
// replace it with something better.
var
RLogin
=
function
(
e
){
var
n
=
this
;
const
t
=
24
,
i
=
13
,
s
=
17
,
o
=
19
,
c
=
10
;
var
r
=
[],
p
=
[],
u
=
{
connected
:
!
1
,
cooked
:
!
0
,
suspendInput
:
!
1
,
suspendOutput
:
!
1
,
watchForClientEscape
:
!
0
,
clientHasEscaped
:
!
1
},
d
=
{
rows
:
24
,
columns
:
80
,
pixelsX
:
640
,
pixelsY
:
480
,
clientEscape
:
"
~
"
},
f
=
{
DOT
:
n
.
disconnect
,
EOT
:
n
.
disconnect
,
SUB
:
function
(){
u
.
suspendInput
=
u
.
suspendInput
?
!
1
:
!
0
,
u
.
suspendOutput
=
u
.
suspendInput
},
EOM
:
function
(){
u
.
suspendInput
=
u
.
suspendInput
?
!
1
:
!
0
,
u
.
suspendOutput
=!
1
}};
this
.
__defineGetter__
(
"
connected
"
,
function
(){
return
u
.
connected
}),
this
.
__defineSetter__
(
"
connected
"
,
function
(
e
){
"
boolean
"
!=
typeof
e
||
e
||
n
.
disconnect
()}),
this
.
__defineGetter__
(
"
rows
"
,
function
(){
return
d
.
rows
}),
this
.
__defineSetter__
(
"
rows
"
,
function
(
e
){
if
(
!
(
"
number
"
==
typeof
e
&&
e
>
0
))
throw
"
RLogin: Invalid 'rows' setting
"
+
e
;
d
.
rows
=
e
}),
this
.
__defineGetter__
(
"
columns
"
,
function
(){
return
d
.
columns
}),
this
.
__defineSetter__
(
"
columns
"
,
function
(
e
){
if
(
!
(
"
number
"
==
typeof
e
&&
e
>
0
))
throw
"
RLogin: Invalid 'columns' setting
"
+
e
;
d
.
columns
=
e
}),
this
.
__defineGetter__
(
"
pixelsX
"
,
function
(){
return
d
.
pixelsX
}),
this
.
__defineSetter__
(
"
pixelsX
"
,
function
(
e
){
if
(
!
(
"
number
"
==
typeof
e
&&
e
>
0
))
throw
"
RLogin: Invalid 'pixelsX' setting
"
+
e
;
d
.
pixelsX
=
e
}),
this
.
__defineGetter__
(
"
pixelsY
"
,
function
(){
return
d
.
pixelsY
}),
this
.
__defineSetter__
(
"
pixelsY
"
,
function
(
e
){
if
(
!
(
"
number
"
==
typeof
e
&&
e
>
0
))
throw
"
RLogin: Invalid 'pixelsY' setting
"
+
e
;
d
.
pixelsY
=
e
}),
this
.
__defineGetter__
(
"
clientEscape
"
,
function
(){
return
d
.
clientEscape
}),
this
.
__defineSetter__
(
"
clientEscape
"
,
function
(
e
){
if
(
"
string
"
!=
typeof
e
||
1
!=
e
.
length
)
throw
"
RLogin: Invalid 'clientEscape' setting
"
+
e
;
d
.
clientEscape
=
e
});
var
a
=
new
Socket
,
l
=
function
(){
if
(
!
(
a
.
nread
<
1
)){
for
(
var
e
=
[];
a
.
nread
>
0
;)
e
.
push
(
a
.
recvBin
(
1
));
if
(
!
u
.
connected
)
if
(
0
==
e
[
0
]){
if
(
u
.
connected
=!
0
,
!
(
e
.
length
>
1
))
return
;
e
=
e
.
slice
(
1
)}
else
n
.
disconnect
();
u
.
suspendOutput
||
(
r
=
r
.
concat
(
e
))}};
this
.
send
=
function
(
e
){
if
(
!
u
.
connected
)
throw
"
RLogin.send: not connected.
"
;
if
(
u
.
suspendInput
)
throw
"
RLogin.send: input has been suspended.
"
;
"
string
"
==
typeof
e
&&
(
e
=
e
.
split
(
""
).
map
(
function
(
e
){
return
ascii
(
e
)}));
for
(
var
n
=
[],
r
=
0
;
r
<
e
.
length
;
r
++
)
u
.
watchForClientEscape
&&
e
[
r
]
==
d
.
clientEscape
.
charCodeAt
(
0
)?(
u
.
watchForClientEscape
=!
1
,
u
.
clientHasEscaped
=!
0
):
u
.
clientHasEscaped
?(
u
.
clientHasEscaped
=!
1
,
"
undefined
"
!=
typeof
f
[
e
[
r
]]
&&
f
[
e
[
r
]]()):
!
u
.
cooked
||
e
[
r
]
!=
s
&&
e
[
r
]
!=
o
?((
r
>
0
&&
e
[
r
-
1
]
==
i
&&
e
[
r
]
==
c
||
e
[
r
]
==
t
)
&&
(
u
.
watchForClientEscape
=!
0
),
n
.
push
(
e
[
r
])):
u
.
suspendOutput
==
(
e
[
r
]
==
o
);
p
=
p
.
concat
(
n
)},
this
.
receive
=
function
(){
return
r
.
splice
(
0
,
r
.
length
)},
this
.
addClientEscape
=
function
(
e
,
n
){
if
(
"
string
"
!=
typeof
e
&&
"
number
"
!=
typeof
e
||
"
string
"
==
typeof
e
&&
e
.
length
>
1
||
"
function
"
!=
typeof
n
)
throw
"
RLogin.addClientEscape: invalid arguments.
"
;
f
[
e
.
charCodeAt
(
0
)]
=
n
},
this
.
connect
=
function
(){
if
(
"
number
"
!=
typeof
e
.
port
||
"
string
"
!=
typeof
e
.
host
)
throw
"
RLogin: invalid host or port argument.
"
;
if
(
"
string
"
!=
typeof
e
.
clientUsername
)
throw
"
RLogin: invalid clientUsername argument.
"
;
if
(
"
string
"
!=
typeof
e
.
serverUsername
)
throw
"
RLogin: invalid serverUsername argument.
"
;
if
(
"
string
"
!=
typeof
e
.
terminalType
)
throw
"
RLogin: invalid terminalType argument.
"
;
if
(
"
number
"
!=
typeof
e
.
terminalSpeed
)
throw
"
RLogin: invalid terminalSpeed argument.
"
;
if
(
!
a
.
connect
(
e
.
host
,
e
.
port
))
throw
"
RLogin: Unable to connect to server.
"
;
for
(
a
.
sendBin
(
0
,
1
),
a
.
send
(
e
.
clientUsername
),
a
.
sendBin
(
0
,
1
),
a
.
send
(
e
.
serverUsername
),
a
.
sendBin
(
0
,
1
),
a
.
send
(
e
.
terminalType
+
"
/
"
+
e
.
terminalSpeed
),
a
.
sendBin
(
0
,
1
);
a
.
is_connected
&&
a
.
nread
<
1
;)
mswait
(
5
);
l
()},
this
.
cycle
=
function
(){
if
(
l
(),
!
(
u
.
suspendInput
||
p
.
length
<
1
))
for
(;
p
.
length
>
0
;)
a
.
sendBin
(
p
.
shift
(),
1
)},
this
.
disconnect
=
function
(){
a
.
close
(),
u
.
connected
=!
1
}};
try
{
...
...
@@ -29,8 +30,9 @@ try {
err
(
'
No cookie from WebSocket client.
'
);
}
// Should probably search for the right cookie instead of assuming
var
cookie
=
wss
.
headers
[
'
Cookie
'
].
split
(
'
=
'
);
if
(
cookie
[
0
]
!==
"
synchronet
"
||
cookie
.
length
<
2
)
{
if
(
cookie
[
0
]
!==
'
synchronet
'
||
cookie
.
length
<
2
)
{
err
(
'
Invalid cookie from WebSocket client.
'
);
}
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment