@@ -10,18 +10,55 @@ var net = require('net'),
1010 WebSocket = require ( 'ws' ) ,
1111 proxyAgent = require ( 'https-proxy-agent' ) ,
1212 os = require ( 'os' ) ,
13- crypto = require ( 'crypto' ) ;
13+ crypto = require ( 'crypto' ) ,
14+ version = require ( './package.json' ) . version ;
1415
1516function pad ( n , width , z ) {
1617 z = z || '0' ;
1718 n = n + '' ;
1819 return n . length >= width ? n : new Array ( width - n . length + 1 ) . join ( z ) + n ;
1920}
2021
22+ function padHeaderLength ( lengthNumber ) {
23+ while ( lengthNumber . length < 4 ) {
24+ lengthNumber = '0' + lengthNumber ;
25+ }
26+
27+ return lengthNumber ;
28+ }
29+
30+ // takes an header object and packs it alongside binary blob
31+ function packData ( obj , dataReceived ) {
32+ var binaryObject = Buffer . from ( JSON . stringify ( obj ) ) ;
33+ var paddedLength = padHeaderLength ( String ( binaryObject . byteLength ) ) ;
34+ var objectLength = Buffer . from ( paddedLength ) ;
35+ if ( ! dataReceived ) {
36+ return Buffer . concat ( [ objectLength , binaryObject ] ) ;
37+ }
38+
39+ return Buffer . concat ( [ objectLength , binaryObject , dataReceived ] ) ;
40+ }
41+
42+ function unpackData ( binaryData ) {
43+ // look at first three bytes to get the length of the header
44+ var length = binaryData . slice ( 0 , 4 ) ;
45+ length = parseInt ( length ) ;
46+ var headerData = binaryData . slice ( 4 , length + 4 ) ;
47+
48+ headerData = JSON . parse ( headerData ) ;
49+ if ( length + 4 == binaryData . byteLength ) {
50+ headerData . data = null ;
51+ } else {
52+ headerData . data = binaryData . slice ( length + 4 , binaryData . byteLength ) ;
53+ }
54+ return headerData ;
55+ }
56+
2157function cbtSocket ( api , params ) {
2258 var inbound ;
2359 var outbound ;
2460 var self = this ;
61+
2562 var killLever = utils . killLever ( self ) ;
2663 params . context = self ;
2764
@@ -68,23 +105,34 @@ function cbtSocket(api, params) {
68105
69106 var tType = self . tType = params . tType ;
70107 self . auth_header = ( Buffer . from ( params . username + ':' + params . authkey ) ) . toString ( 'base64' ) ;
108+
109+ // not used elsewhere
71110 self . t = params . t ;
72111 self . userId = params . userId ;
73112 self . authkey = params . authkey ;
74113 self . qPort = ( params . bytecode ? pad ( ( params . tcpPort - 11000 ) , 3 ) : pad ( ( params . tcpPort - 11000 ) , 3 ) ) ;
75114 self . wsPort = params . tcpPort + 1000 ;
115+
76116 self . cbtServer = 'https://' + params . cbtServer ;
77117 self . cbtApp = 'https://' + params . urls . node ;
78118 self . path = '/wsstunnel' + self . qPort + '/socket.io' ;
79119 self . query = 'userid=' + self . userId + '&authkey=' + self . authkey ;
120+
80121 self . wsPath = self . cbtServer + self . path + '?' + self . query ;
122+
123+ if ( global . isLocal ) {
124+ self . wsPath = params . wssUrl ;
125+ global . logger . info ( `change wsPath to ${ self . path } ` ) ;
126+ }
127+
81128 self . tunnelapi = params . urls . node + '/api/v3/tunnels/' + params . tid ;
82129 var proxyAuthString = self . proxyAuthString = '' ;
83130 self . nokill = params . nokill ;
84131 if ( ! ! params . proxyUser && ! ! params . proxyPass ) {
85132 proxyAuthString = self . proxyAuthString = 'Proxy-Authorization: Basic ' + ( Buffer . from ( params . proxyUser + ':' + params . proxyPass ) ) . toString ( 'base64' ) ;
86133 }
87134 self . ready = params . ready ;
135+
88136 switch ( tType ) {
89137 case 'simple' :
90138 break ;
@@ -104,8 +152,9 @@ function cbtSocket(api, params) {
104152 var agent = makeProxyAgent ( ) ;
105153 conn = self . conn = new WebSocket ( self . wsPath , { agent : agent } ) ;
106154 } else {
107- conn = self . conn = new WebSocket ( self . wsPath , { } ) ;
155+ conn = self . conn = new WebSocket ( self . wsPath , { perMessageDeflate : false } ) ;
108156 }
157+ self . conn . bufferType = "arraybuffer" ;
109158 if ( ! params . rejectUnauthorized ) {
110159 conn . rejectUnauthorized = false ;
111160 }
@@ -115,7 +164,8 @@ function cbtSocket(api, params) {
115164 event :'clientLog' ,
116165 client_verbose_log : log
117166 }
118- conn . send ( JSON . stringify ( dataToServer ) ) ;
167+ var payload = packData ( dataToServer , Buffer . from ( [ ] ) )
168+ conn . send ( payload ) ;
119169 }
120170
121171 self . start = function ( cb ) {
@@ -134,7 +184,17 @@ function cbtSocket(api, params) {
134184 global . logger . debug ( 'Started connection attempt!' ) ;
135185 conn . on ( 'message' , function ( message ) {
136186 try {
137- msg = JSON . parse ( message ) ;
187+ /*
188+ the first hello we get will be a string,
189+ we'll respond with a buffer, and from that
190+ point forward, we'll be talking buffers.
191+ */
192+ if ( _ . isString ( message ) ) {
193+ global . logger . debug ( "Incoming message is string" ) ;
194+ msg = JSON . parse ( message ) ;
195+ } else {
196+ msg = unpackData ( message )
197+ }
138198 self . handleMessage ( msg ) ;
139199 } catch ( e ) {
140200 warn ( e . message ) ;
@@ -206,9 +266,11 @@ function cbtSocket(api, params) {
206266 case 'hello' :
207267 var dataToServer = {
208268 event : 'established' ,
209- wsid : wsid
269+ wsid : wsid ,
210270 }
211- conn . send ( JSON . stringify ( dataToServer ) ) ;
271+ // versions of cbt_tunnels > 1.0.0 send their version to server.js on hello. - CC
272+ var payload = packData ( dataToServer , Buffer . from ( version ) ) ;
273+ conn . send ( payload ) ;
212274 break ;
213275 case 'versions' :
214276 var checkResult = utils . checkVersion ( msg , params ) ;
@@ -228,10 +290,10 @@ function cbtSocket(api, params) {
228290 var data = err ;
229291 var dataToServer = {
230292 event : 'checkrecv' ,
231- data : data ,
232293 wsid : wsid
233294 }
234- conn . send ( JSON . stringify ( dataToServer ) ) ;
295+ var payload = packData ( dataToServer , data )
296+ conn . send ( payload ) ;
235297 } else {
236298 try {
237299 global . logger . debug ( 'IP appears to CBT as: ' + resp . ip ) ;
@@ -240,15 +302,17 @@ function cbtSocket(api, params) {
240302 ip : resp . ip ,
241303 wsid : wsid
242304 }
243- conn . send ( JSON . stringify ( dataToServer ) ) ;
305+ var payload = packData ( dataToServer , Buffer . from ( [ ] ) )
306+ conn . send ( payload ) ;
244307 } catch ( e ) {
245308 warn ( 'Parsing response failed: ' + e ) ;
246309 var dataToServer = {
247310 event : 'checkrecv' ,
248311 error : e ,
249312 wsid : wsid
250313 }
251- conn . send ( JSON . stringify ( dataToServer ) ) ;
314+ var payload = packData ( dataToServer , Buffer . from ( [ ] ) )
315+ conn . send ( payload ) ;
252316 }
253317 }
254318 } ) ;
@@ -270,6 +334,7 @@ function cbtSocket(api, params) {
270334
271335 self . handleData = function ( msg ) {
272336 var data = msg ;
337+
273338 var id = msg . id ;
274339 var wsid = msg . wsid ;
275340
@@ -320,11 +385,11 @@ function cbtSocket(api, params) {
320385 var dataToServer = {
321386 event : 'ack ack ack' ,
322387 id : id ,
323- data : null ,
324388 finished : false ,
325389 wsid : wsid
326390 }
327- conn . send ( JSON . stringify ( dataToServer ) ) ;
391+ var payload = packData ( dataToServer , Buffer . from ( [ ] ) )
392+ conn . send ( payload ) ;
328393 global . logger . debug ( 'Created TCP socket: ' + data . _type + ' ' + host + ' ' + port + ' ' + id ) ;
329394 sendLog ( 'Created TCP socket: ' + data . _type + ' ' + host + ' ' + port + ' ' + id ) ;
330395 } ) ;
@@ -336,11 +401,11 @@ function cbtSocket(api, params) {
336401 var dataToServer = {
337402 event : 'htmlrecv' ,
338403 id : id ,
339- data : null ,
340404 finished : true ,
341405 wsid : wsid
342406 }
343- conn . send ( JSON . stringify ( dataToServer ) ) ;
407+ var payload = packData ( dataToServer , Buffer . from ( [ ] ) )
408+ conn . send ( payload ) ;
344409 connection_list [ id ] . established = false ;
345410 client . end ( ) ;
346411 connection_list [ id ] . ended = true ;
@@ -349,21 +414,22 @@ function cbtSocket(api, params) {
349414 client . on ( 'data' , function ( dataRcvd ) {
350415 if ( socketExists ( id ) ) {
351416 global . logger . debug ( 'TCP socket ' + id + ' received data: Port:' + port + ' Host:' + host ) ;
352- sendLog ( 'TCP socket ' + id + ' received data: Port:' + port + ' Host:' + host ) ;
417+
353418 var dataToServer = {
354419 event : 'htmlrecv' ,
355420 id : id ,
356- data : dataRcvd ,
357- finished : true ,
421+ finished : false ,
358422 wsid : wsid
359423 }
424+
425+ var payload = packData ( dataToServer , dataRcvd )
426+
360427 self . isConnected ( dataRcvd , id , function ( err , connected ) {
361428 if ( err ) {
362429 throw err ;
363430 } else if ( ! err && ! connected ) {
364- conn . send ( JSON . stringify ( dataToServer ) ) ;
431+ conn . send ( payload ) ;
365432 global . logger . debug ( 'TCP socket ' + id + ' internet data emitted to server.js!' ) ;
366- sendLog ( 'TCP socket ' + id + ' internet data emitted to server.js!' ) ;
367433 } else if ( connected ) {
368434 connection_list [ id ] . connected = true ;
369435 }
@@ -379,11 +445,11 @@ function cbtSocket(api, params) {
379445 var dataToServer = {
380446 event : 'htmlrecv' ,
381447 id : id ,
382- data : null ,
383448 finished : true ,
384449 wsid : wsid
385450 }
386- conn . send ( JSON . stringify ( dataToServer ) ) ;
451+ var payload = packData ( dataToServer , Buffer . from ( [ ] ) )
452+ conn . send ( payload ) ;
387453 client . write ( 'end' ) ;
388454 client . end ( ) ;
389455 client . destroy ( ) ;
@@ -401,11 +467,11 @@ function cbtSocket(api, params) {
401467 var dataToServer = {
402468 event : 'htmlrecv' ,
403469 id : id ,
404- data : null ,
405470 finished : true ,
406471 wsid : wsid
407472 }
408- conn . send ( JSON . stringify ( dataToServer ) ) ;
473+ var payload = packData ( dataToServer , Buffer . from ( [ ] ) )
474+ conn . send ( payload ) ;
409475 connection_list [ id ] . established = false ;
410476 client . write ( 'end' ) ;
411477 client . end ( ) ;
@@ -424,11 +490,11 @@ function cbtSocket(api, params) {
424490 var dataToServer = {
425491 event : 'htmlrecv' ,
426492 id : id ,
427- data : null ,
428493 finished : true ,
429494 wsid : wsid
430495 }
431- conn . send ( JSON . stringify ( dataToServer ) ) ;
496+ var payload = packData ( dataToServer , Buffer . from ( [ ] ) )
497+ conn . send ( payload ) ;
432498 connection_list [ id ] . established = false ;
433499 client . write ( 'end' ) ;
434500 client . end ( ) ;
@@ -450,12 +516,9 @@ function cbtSocket(api, params) {
450516 }
451517 self . isTLSHello ( connection_list [ id ] , data . data , id , function ( err ) {
452518 if ( ! err ) {
453- var bufferToSend = Buffer . from ( data . data ) ;
519+ var bufferToSend = Buffer . from ( data . data . toJSON ( ) ) ;
454520 client . write ( bufferToSend , function ( err ) {
455521 if ( err ) {
456- global . logger . debug ( 'Error writing data to: ' ) ;
457- global . logger . debug ( util . inspect ( client ) ) ;
458- global . logger . debug ( util . inspect ( err ) ) ;
459522 sendLog ( 'Error writing data to: ' + util . inspect ( client ) + ' ' + util . inspect ( err ) ) ;
460523 var dataToServer = {
461524 event : 'htmlrecv' ,
@@ -471,7 +534,6 @@ function cbtSocket(api, params) {
471534 }
472535 outbound += 1 ;
473536 global . logger . debug ( 'Wrote to TCP socket ' + id ) ;
474- sendLog ( 'Wrote to TCP socket ' + id ) ;
475537 } ) ;
476538 } else {
477539 global . logger . debug ( 'TLS error:' ) ;
@@ -568,7 +630,7 @@ function cbtSocket(api, params) {
568630
569631 self . isTLSHello = function ( connection , packet , id , cb ) {
570632 //&&(packet[4]===0x7C||packet[4]===0x7C)
571- if ( ( packet [ 0 ] === 0x16 && packet [ 5 ] === 0x01 ) && connection_list [ id ] . manipulateHeaders ) {
633+ if ( ( packet [ 0 ] === 22 && packet [ 5 ] === 191 && connection_list [ id ] . manipulateHeaders ) ) {
572634 var client = connection . client ;
573635 global . logger . debug ( id + ' This is a TLS HELLO! Sending CONNECT...' ) ;
574636 sendLog ( 'Client found TLS hello on: ' + id ) ;
@@ -594,7 +656,6 @@ function cbtSocket(api, params) {
594656 }
595657 outbound += 1 ;
596658 global . logger . debug ( 'Wrote to TCP socket ' + id ) ;
597- sendLog ( 'Wrote to TCP socket ' + id ) ;
598659 var connectedInterval = setInterval ( function ( ) {
599660 if ( connection_list [ id ] . connected ) {
600661 if ( params . verbose ) {
0 commit comments