diff --git a/example/cks5-hostname b/example/cks5-hostname
new file mode 100644
index 0000000..3e6a4ef
--- /dev/null
+++ b/example/cks5-hostname
@@ -0,0 +1,6 @@
+
+301 Moved
+301 Moved
+The document has moved
+here.
+
diff --git a/example/index.js b/example/index.js
index 01c542b..3fb6d29 100644
--- a/example/index.js
+++ b/example/index.js
@@ -1,30 +1,29 @@
-const socks5Stream = require("../src/index");
-const net = require("net");
-// Server mock
+const socks5Stream = require('../src/index');
+const net = require('net');
+// Server mock
var server = net.createServer((socket) => {
// Create a new socks5 stream without Authentication
var sockStream = new socks5Stream(socket);
- //Create a new socks5 stream with Type as "username" and Auth details as Username and Password
-
+ //Create a new socks5 stream with Username and Password Authentication
var sockStreamAuth = new socks5Stream(socket, {
- authType:"username",
- username:"username",
- password:"password"
+ username: "username",
+ password: "password",
+ authType: "username"
});
//Piping the data to sock5 stream
- socket.pipe(sockStream).once("data", (data) => {
- console.log(", ==> " + data.toString());
+ socket.pipe(sockStream).once('data', (data) => {
+ console.log(', ==> ' + data.toString());
sockStream.acceptConnection(true);
- sockStream.on("data", (chunk) => {
- console.log(chunk.toString());
- });
- });
+ sockStream.on('data', (chunk) => {
+ // console.log(chunk.toString());
+ })
+ })
});
server.listen(8124, () => {
- console.log("server bound");
+ console.log('server bound');
});
diff --git a/package.json b/package.json
index 3eb9173..a137ea1 100644
--- a/package.json
+++ b/package.json
@@ -21,4 +21,4 @@
"url": "https://github.com/nimit95/socks5-stream/issues"
},
"homepage": "https://github.com/nimit95/socks5-stream#readme"
-}
+}
\ No newline at end of file
diff --git a/src/constants.js b/src/constants.js
index 76205b3..1694c00 100644
--- a/src/constants.js
+++ b/src/constants.js
@@ -3,28 +3,19 @@
module.exports.socksVersion = 0x05;
module.exports.states = {
- NO_CONNECTION:0,
- CONNECTING:1,
+ NO_CONNECTION: 0,
+ CONNECTING: 1,
CONNECTED: 3,
DISCONNECTED: 4,
AUTHENTICATION: 5
-};
+}
module.exports.authTypes = {
- username:1
-};
+ username: 1
+}
module.exports.SOCKS_ADDRESS = {
IPV4: 0x01,
HOSTNAME: 0x03,
IPV6: 0x04
-};
-
-module.exports.SOCKET_ERRORS = {
- NOT_DEFINED : "Socket is not defined or valid",
- WRONG_AUTH : "Wrong Authentication Details givem",
- INITIAL_HANSHAKE : "Got Wrong initial Handshake(not 5,0,x)",
- INVALID_AUTH_PACKET: "Invalid Authentication Packet received",
- INVALID_CONNECT: "Got Wrong Handshake(not 5,1,x,x,x...)",
- NO_CONNECTION : "Connection not established yet"
-};
+}
diff --git a/src/index.js b/src/index.js
index 3f11abe..77c7b57 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,25 +1,25 @@
-const { Transform } = require("stream");
-const util = require("util");
-const constants = require("./constants");
-const socksUtils = require("./socksUtils");
-const utils = require("./utils");
+const { Transform } = require('stream');
+const util = require('util');
+const constants = require('./constants');
+const socksUtils = require('./socksUtils');
+const utils = require('./utils')
/**
- * @param {net.Socket} socket
+ * @param {net.Socket} socket
* Socket from which the Socks stream is comming.
* @param {Object} authDetails
* Optional for authorization if any, Defaults to undefined
* {
- * //In case of username and password
+ * //In case of username and password
* authType:"username",
* username:,
* password:
- *
- *
+ *
+ *
* }
*/
-const socks5Stream = function(socket, authDetails) {
+const socks5Stream = function (socket, authDetails) {
this.authDetails = authDetails || false;
this._socket = socket;
@@ -28,87 +28,89 @@ const socks5Stream = function(socket, authDetails) {
this.state = constants.states.NO_CONNECTION;
- if(this.authDetails) {
- this.authType = constants.authTypes[this.authDetails.authType];
+ if (this.authDetails) {
+ this.authType = constants.authTypes[this.authDetails.authType]
} else {
this.authType = false;
}
-};
+
+}
util.inherits(socks5Stream, Transform);
-socks5Stream.prototype._transform = function(chunk, encoding, callback) {
+socks5Stream.prototype._transform = function (chunk, encoding, callback) {
- if(!utils.isSocketObjValid(this._socket)) {
- return callback(new Error(constants.SOCKET_ERRORS.NOT_DEFINED));
+ if (!utils.isSocketObjValid(this._socket)) {
+ return callback(new Error("Socket is not defined or valid"));
}
- if(this.authDetails && !utils.validateAuth(this.authDetails)) {
- return callback(new Error(constants.SOCKET_ERRORS.WRONG_AUTH));
+ if (this.authDetails && !utils.validateAuth(this.authDetails)) {
+ return callback(new Error("Wrong Authentication Details"));
}
// console.log(chunk);
- if(this.state === constants.states.NO_CONNECTION) {
-
- if(!socksUtils.checkIntialSocksChunk(chunk)) {
- return callback(new Error(constants.SOCKET_ERRORS.INITIAL_HANSHAKE));
+ if (this.state === constants.states.NO_CONNECTION) {
+
+ if (!socksUtils.checkIntialSocksChunk(chunk)) {
+ return callback(new Error("Got Wrong initial Handshake(not 5,0,x)"));
}
- //We need to conect
+ //We need to conect
this._socket.write(socksUtils.generateInitialHandshakeResponse(this.authType), () => {
-
- this.state = this.authDetails? constants.states.AUTHENTICATION : constants.states.CONNECTING;
+
+ this.state = this.authDetails ? constants.states.AUTHENTICATION : constants.states.CONNECTING;
callback(null);
});
+
}
- if(this.state === constants.states.AUTHENTICATION) {
- if(!socksUtils.checkAuthRequest(chunk, this.authType)) {
- return callback(new Error(constants.SOCKET_ERRORS.INVALID_AUTH_PACKET));
+ if (this.state === constants.states.AUTHENTICATION) {
+ if (!socksUtils.checkAuthRequest(chunk, this.authType)) {
+ return callback(new Error("Wrong Authentication Details"));
}
var authDetailRequest = socksUtils.getUsernamePassFromRequest(chunk, this.authType);
- if(this.authDetails.username == authDetailRequest.username && this.authDetails.password == authDetailRequest.password) {
+ if (this.authDetails.username == authDetailRequest.username && this.authDetails.password == authDetailRequest.password) {
this._socket.write(socksUtils.generateSuccessSocksAuthResponse(), () => {
this.state = constants.states.CONNECTING;
- });
+ })
callback(null);
} else {
this._socket.write(socksUtils.generateFailSocksAuthResponse(), () => {
this.state = constants.states.DISCONNECTED;
- });
+ })
//Closing the connection in case of wrong username/password
this._socket.end();
}
}
- if(this.state === constants.states.CONNECTING) {
- if(!socksUtils.checkConnectResponse(chunk)) {
- return callback(new Error(constants.SOCKET_ERRORS.INVALID_CONNECT));
+ if (this.state === constants.states.CONNECTING) {
+ if (!socksUtils.checkConnectResponse(chunk)) {
+ return callback(new Error("Got Wrong Handshake(not 5,1,x,x,x...)"));
}
let hostnamePortObj = socksUtils.getHostnamePort(chunk);
- return callback(null, `${hostnamePortObj.hostname}, ${hostnamePortObj.port}`);
+ return callback(null, `${hostnamePortObj.hostname},${hostnamePortObj.port}`);
}
- if(this.state === constants.states.CONNECTED) {
+ if (this.state === constants.states.CONNECTED) {
// console.log('connected', chunk.toString());
callback(null, chunk);
}
- if(this.state === constants.states.DISCONNECTED) {
+ if (this.state === constants.states.DISCONNECTED) {
callback(null);
}
- this.acceptConnection = function(flag) {
- if(this.state === constants.states.NO_CONNECTION) {
- return callback(new Error(constants.SOCKET_ERRORS.NO_CONNECTION));
+ this.acceptConnection = function (flag) {
+ if (this.state === constants.states.NO_CONNECTION) {
+ return callback(new Error("Connection not established yet."));
}
- if(flag) {
+ if (flag) {
this._socket.write(socksUtils.connectionSuccessfulResponse(), () => {
this.state = constants.states.CONNECTED;
});
@@ -119,15 +121,15 @@ socks5Stream.prototype._transform = function(chunk, encoding, callback) {
//return callback(null);
});
}
- };
+ }
- this._socket.on("close", () => {
+ this._socket.on('close', () => {
this.state = constants.states.DISCONNECTED;
});
- this._socket.on("error", () => {
+ this._socket.on('error', () => {
this.state = constants.states.DISCONNECTED;
});
-
-};
+
+}
module.exports = socks5Stream;
diff --git a/src/socksUtils.js b/src/socksUtils.js
index 43028b0..4d5f5c0 100644
--- a/src/socksUtils.js
+++ b/src/socksUtils.js
@@ -1,143 +1,135 @@
-const constants = require("./constants");
-var checkIntialSocksChunk = function(chunk) {
- if(chunk.length < 3 || chunk[0]!=constants.socksVersion || chunk[1] == 0x00 || chunk.length !== parseInt(chunk[1]) + 2)
- return false;
- return true;
-};
+const constants = require('./constants');
+var checkIntialSocksChunk = function (chunk) {
+ if (chunk.length < 3 || chunk[0] != constants.socksVersion || chunk[1] == 0x00 || chunk.length !== parseInt(chunk[1]) + 2)
+ return false
+ return true
+}
-var checkConnectResponse = function(chunk) {
- if(chunk.length < 4 || chunk[0]!== constants.socksVersion || chunk[2] !== 0x00) return false;
+var checkConnectResponse = function (chunk) {
+ if (chunk.length < 4 || chunk[0] !== constants.socksVersion || chunk[2] !== 0x00) return false;
- if(chunk[3] === constants.SOCKS_ADDRESS.IPV4) {
+ if (chunk[3] === constants.SOCKS_ADDRESS.IPV4) {
return chunk.length === 10;
- } else if(chunk[3] === constants.SOCKS_ADDRESS.IPV6) {
+ } else if (chunk[3] === constants.SOCKS_ADDRESS.IPV6) {
return chunk.length === 22;
- } else if(chunk[3] === constants.SOCKS_ADDRESS.HOSTNAME){
+ } else if (chunk[3] === constants.SOCKS_ADDRESS.HOSTNAME) {
return chunk.length > 3 && chunk.length === 7 + parseInt(chunk[4]);
} else {
return false;
}
-};
+}
-var generateInitialHandshakeResponse = function(authType) {
- var buf = new Buffer.alloc(2,0x00, "hex");
+var generateInitialHandshakeResponse = function (authType) {
+ var buf = new Buffer.alloc(2, 0x00, 'hex');
buf[0] = constants.socksVersion;
- if(authType == constants.authTypes.username) {
+ if (authType == constants.authTypes.username) {
buf[1] = 0x02;
} else {
buf[1] = 0x00;
}
return buf;
-};
+}
-var connectionSuccessfulResponse = function() {
- var buf = new Buffer.alloc(4 + this.buf.length, 0x00, "hex");
+var connectionSuccessfulResponse = function () {
+ var buf = new Buffer.alloc(4 + this.buf.length, 0x00, 'hex');
buf[0] = constants.socksVersion;
buf[1] = 0x00;
buf[2] = 0x00;
buf[3] = 0x01;
this.buf.copy(buf, 4, 0);
return buf;
-};
+}
-var connectionUnsuccessfulResponse = function() {
- var buf = new Buffer.alloc(4 + this.buf.length, 0x00, "hex");
+var connectionUnsuccessfulResponse = function () {
+ var buf = new Buffer.alloc(4 + this.buf.length, 0x00, 'hex');
buf[0] = constants.socksVersion;
buf[1] = 0x00;
buf[2] = 0x00;
buf[3] = 0x01;
this.buf.copy(buf, 4, 0);
return buf;
-};
+}
-var getHostnamePort = function(chunk) {
+var getHostnamePort = function (chunk) {
+ console.log(chunk);
this.addressType = chunk[3];
- if(chunk[3] === constants.SOCKS_ADDRESS.IPV4) {
- let hostname = "", port = "";
+ if (chunk[3] === constants.SOCKS_ADDRESS.IPV4) {
+ let hostname = "", port = parseInt(chunk.slice(8).toString("hex"), 16);
this.buf = chunk.slice(4);
chunk.slice(4, 8).forEach(value => {
- hostname += parseInt(value) + ".";
- });
- chunk.slice(8).forEach(value => {
- port += parseInt(value);
+ hostname += parseInt(value) + '.';
});
return {
hostname: hostname.slice(0, -1),
port: port
};
- }
- if(chunk[3] === constants.SOCKS_ADDRESS.IPV6) {
- let hostname = "", port = "";
+ }
+ if (chunk[3] === constants.SOCKS_ADDRESS.IPV6) {
+ let hostname = "", port = parseInt(chunk.slice(chunk.length - 2).toString("hex"), 16);
this.buf = chunk.slice(4);
- chunk.toString("hex", 4, chunk.length - 2).split("").forEach((value, idx) => {
-
+ chunk.toString('hex', 4, chunk.length - 2).split('').forEach((value, idx) => {
+
hostname += value;
-
- if(idx%4 === 3){
+
+ if (idx % 4 === 3) {
// console.log(idx);
- hostname = hostname + ".";
+ hostname = hostname + '.'
}
});
- chunk.slice(chunk.length - 2).forEach(value => {
- port += parseInt(value);
- });
return {
hostname: hostname.slice(0, -1),
port: port
};
- }
- if(chunk[3] === constants.SOCKS_ADDRESS.HOSTNAME){
- let port = "";
+ }
+ if (chunk[3] === constants.SOCKS_ADDRESS.HOSTNAME) {
+ let hostname = "", port = parseInt(chunk.slice(chunk.length - 2).toString("hex"), 16);
this.buf = chunk.slice(4);
- chunk.slice(chunk.length - 2).forEach(value => {
- port += parseInt(value);
- });
return {
- hostname: chunk.toString("ascii", 5, 5 + parseInt(chunk[4])),
+ hostname: chunk.toString('ascii', 5, 5 + parseInt(chunk[4])),
port: port
};
}
return null;
-};
+}
-var checkAuthRequest = function(chunk, authType) {
- if(authType == constants.authTypes.username) {
- return chunk.length > 3 && parseInt(chunk[1]) > 0 && chunk.length == 3 + parseInt(chunk[1]) + parseInt(chunk[parseInt(chunk[1]) + 2]);
+var checkAuthRequest = function (chunk, authType) {
+ if (authType == constants.authTypes.username) {
+ return chunk.length > 3 && parseInt(chunk[1]) > 0 && chunk.length == 3 + parseInt(chunk[1]) + parseInt(chunk[parseInt(chunk[1]) + 2])
}
-};
+}
-var getUsernamePassFromRequest = function(chunk, authType) {
- if(authType == constants.authTypes.username) {
- var uName = chunk.toString("ascii", 2, parseInt(chunk[1])+2);
- var pass = chunk.toString("ascii", 3 + parseInt(chunk[1]));
+var getUsernamePassFromRequest = function (chunk, authType) {
+ if (authType == constants.authTypes.username) {
+ var uName = chunk.toString('ascii', 2, parseInt(chunk[1]) + 2);
+ var pass = chunk.toString('ascii', 3 + parseInt(chunk[1]));
console.log(uName, pass);
return {
username: uName,
password: pass
- };
+ }
}
-};
+}
-var generateSuccessSocksAuthResponse = function() {
- var buf = new Buffer.alloc(2, 0x00, "hex");
+var generateSuccessSocksAuthResponse = function () {
+ var buf = new Buffer.alloc(2, 0x00, 'hex');
buf[0] = constants.socksVersion;
buf[1] = 0x00;
return buf;
-};
+}
-var generateFailSocksAuthResponse = function() {
- var buf = new Buffer.alloc(2, 0x00, "hex");
+var generateFailSocksAuthResponse = function () {
+ var buf = new Buffer.alloc(2, 0x00, 'hex');
buf[0] = constants.socksVersion;
buf[1] = 0x01;
return buf;
-};
+}
module.exports.checkIntialSocksChunk = checkIntialSocksChunk;
module.exports.checkConnectResponse = checkConnectResponse;
diff --git a/src/utils.js b/src/utils.js
index 72b3414..4b6b112 100644
--- a/src/utils.js
+++ b/src/utils.js
@@ -1,19 +1,19 @@
-const constants = require("./constants");
+const constants = require('./constants');
const utils = {
- isSocketObjValid: function(socket) {
- return socket && typeof socket == "object";
+ isSocketObjValid: function (socket) {
+ return socket && typeof socket == 'object'
},
- validateAuth: function(authDetails) {
- if(typeof authDetails != "object"){
+ validateAuth: function (authDetails) {
+ if (typeof authDetails != 'object') {
return false;
}
- if(constants.authTypes[authDetails.authType] === constants.authTypes["username"]) {
- return typeof authDetails.username == "string" && typeof authDetails.password == "string"
- && authDetails.username.length > 0;
+ if (constants.authTypes[authDetails.authType] === constants.authTypes["username"]) {
+ return typeof authDetails.username == 'string' && typeof authDetails.password == 'string'
+ && authDetails.username.length > 0;
}
}
-};
+}
module.exports = utils;
\ No newline at end of file