@applitools/eg-socks5-proxy-server
Advanced tools
Comparing version 0.1.6 to 0.1.7-beta
{ | ||
"name": "@applitools/eg-socks5-proxy-server", | ||
"version": "0.1.6", | ||
"version": "0.1.7-beta", | ||
"description": "", | ||
@@ -5,0 +5,0 @@ "main": "src/index.js", |
254
src/index.js
@@ -11,3 +11,6 @@ const { | ||
const {createRequestExecuter} = require('./create-request-executer') | ||
const {handshake} = require('./handshake') | ||
const {authenticate} = require('./authenticate') | ||
const {executeRequest} = require('./execute-request') | ||
const {executeRequestThroughRemoteProxy} = require('./excute-request-through-remote-proxy') | ||
@@ -36,3 +39,2 @@ const binary = require('binary') | ||
ORIGIN_SOCKET_ERROR: 'orgin-socket-error', | ||
@@ -70,64 +72,14 @@ REMOTE_SOCKET_ERROR: 'remote-socket-error', | ||
/** | ||
* +----+------+----------+------+----------+ | ||
* |VER | ULEN | UNAME | PLEN | PASSWD | | ||
* +----+------+----------+------+----------+ | ||
* | 1 | 1 | 1 to 255 | 1 | 1 to 255 | | ||
* +----+------+----------+------+----------+ | ||
* | ||
* | ||
* @param {Buffer} buffer - a buffer | ||
* @returns {undefined} | ||
**/ | ||
function authenticate(buffer) { | ||
let authDomain = domain.create() | ||
binary | ||
.stream(buffer) | ||
.word8('ver') | ||
.word8('ulen') | ||
.buffer('uname', 'ulen') | ||
.word8('plen') | ||
.buffer('passwd', 'plen') | ||
.tap((args) => { | ||
// capture the raw buffer | ||
args.requestBuffer = buffer | ||
// verify version is appropriate | ||
if (args.ver !== RFC_1929_VERSION) { | ||
return end(RFC_1929_REPLIES.GENERAL_FAILURE, args) | ||
} | ||
authDomain.on('error', (err) => { | ||
// emit failed authentication event | ||
self.server.emit(EVENTS.AUTHENTICATION_ERROR, args.uname.toString(), err) | ||
// respond with auth failure | ||
return end(RFC_1929_REPLIES.GENERAL_FAILURE, args) | ||
}) | ||
// perform authentication | ||
self.options.authenticate( | ||
args.uname.toString(), | ||
args.passwd.toString(), | ||
socket, | ||
authDomain.intercept(() => { | ||
// emit successful authentication event | ||
self.server.emit(EVENTS.AUTHENTICATION, args.uname.toString()) | ||
// respond with success... | ||
let responseBuffer = Buffer.allocUnsafe(2) | ||
responseBuffer[0] = RFC_1929_VERSION | ||
responseBuffer[1] = RFC_1929_REPLIES.SUCCEEDED | ||
// respond then listen for cmd and dst info | ||
socket.write(responseBuffer, () => { | ||
// now listen for more details | ||
socket.once('data', connect) | ||
}) | ||
}), | ||
) | ||
}) | ||
function _authenticate(buffer) { | ||
authenticate({ | ||
socket, | ||
buffer, | ||
options: self.options, | ||
connect, | ||
end, | ||
onAuthenticated: (args) => self.server.emit(EVENTS.AUTHENTICATION, args.uname.toString()), | ||
onFailed: (args, err) => | ||
self.server.emit(EVENTS.AUTHENTICATION_ERROR, args.uname.toString(), err), | ||
}) | ||
} | ||
/** | ||
@@ -266,19 +218,7 @@ * +----+-----+-------+------+----------+----------+ | ||
const proxyServer = {...self.options.proxyServer} | ||
let createExecuterAndRegisterToEvents | ||
if (proxyServer){ | ||
proxyServer.onHandShakeCompleted = () => { | ||
self.server.emit(EVENTS.REMOTE_PROXY_HANDSHAKE_COMPLETED, {originInfo, destinationInfo, proxyServer}) | ||
} | ||
let retry = 0 | ||
proxyServer.onHandshakeTimeout = () => { | ||
self.server.emit(EVENTS.REMOTE_PROXY_HANDSHAKE_TIMEOUT, {originInfo, destinationInfo, proxyServer}) | ||
retry++ | ||
if (retry <= 3) createExecuterAndRegisterToEvents() | ||
else end(RFC_1928_REPLIES.NETWORK_UNREACHABLE, args) | ||
} | ||
} | ||
const proxyServer = self.options.proxyServer | ||
? {...self.options.proxyServer} | ||
: undefined | ||
@@ -290,3 +230,6 @@ self.server.emit(EVENTS.ACCEPT_NEW_REQUEST, { | ||
}) | ||
if (proxyServer) { | ||
} | ||
createExecuterAndRegisterToEvents = () => { | ||
@@ -302,3 +245,3 @@ let connectionTimeout = setTimeout( | ||
) | ||
const clearConnectionTimeout = () => { | ||
@@ -308,22 +251,13 @@ connectionTimeout && clearTimeout(connectionTimeout) | ||
} | ||
let destination = createRequestExecuter({ | ||
originalSocket: socket, | ||
clientHandshakeBuffer, | ||
proxyServer, | ||
args, | ||
}) | ||
self.destinationSockets.push(socket) | ||
destination.on('connect', () => { | ||
const onConnect = (destinationSocket) => { | ||
connectionFilterDomain.exit() | ||
clearConnectionTimeout() | ||
// close destination socket when after original socket was closed | ||
socket.on('close', () => { | ||
destination.destroy() | ||
destinationSocket.destroy() | ||
self.destinationSockets.splice(self.destinationSockets.indexOf(socket), 1) | ||
}) | ||
const event = proxyServer | ||
@@ -333,14 +267,8 @@ ? EVENTS.CONNECTED_TO_REMOTE_PROXY | ||
self.server.emit(event, {destinationInfo, originInfo, proxyServer}) | ||
}) | ||
destination.on('error', (err) => { | ||
} | ||
const onError = (err) => { | ||
// exit the connection filter domain | ||
connectionFilterDomain.exit() | ||
clearConnectionTimeout() | ||
// notify of connection error | ||
err.addr = args.dst.addr | ||
err.atyp = args.atyp | ||
err.port = args.dst.port | ||
self.server.emit(EVENTS.REMOTE_SOCKET_ERROR, { | ||
@@ -354,13 +282,47 @@ err, | ||
}) | ||
if (err.code && err.code === 'EADDRNOTAVAIL') { | ||
return end(RFC_1928_REPLIES.HOST_UNREACHABLE, args) | ||
} | ||
let destination | ||
if (!proxyServer) { | ||
destination = executeRequest({ | ||
originalSocket: socket, | ||
args, | ||
end, | ||
onConnect, | ||
onError, | ||
}) | ||
} else { | ||
proxyServer.onHandShakeCompleted = () => { | ||
self.server.emit(EVENTS.REMOTE_PROXY_HANDSHAKE_COMPLETED, { | ||
originInfo, | ||
destinationInfo, | ||
proxyServer, | ||
}) | ||
} | ||
if (err.code && err.code === 'ECONNREFUSED') { | ||
return end(RFC_1928_REPLIES.CONNECTION_REFUSED, args) | ||
let retry = 0 | ||
proxyServer.onHandshakeTimeout = () => { | ||
self.server.emit(EVENTS.REMOTE_PROXY_HANDSHAKE_TIMEOUT, { | ||
originInfo, | ||
destinationInfo, | ||
proxyServer, | ||
}) | ||
retry++ | ||
if (retry <= 3) createExecuterAndRegisterToEvents() | ||
else end(RFC_1928_REPLIES.NETWORK_UNREACHABLE, args) | ||
} | ||
return end(RFC_1928_REPLIES.NETWORK_UNREACHABLE, args) | ||
}) | ||
destination = executeRequestThroughRemoteProxy({ | ||
originalSocket: socket, | ||
clientHandshakeBuffer, | ||
proxyServer, | ||
args, | ||
end, | ||
onConnect, | ||
onError, | ||
}) | ||
} | ||
self.destinationSockets.push(socket) | ||
} | ||
@@ -420,58 +382,22 @@ | ||
**/ | ||
function handshake(buffer) { | ||
function _handshake(buffer) { | ||
clientHandshakeBuffer = buffer | ||
binary | ||
.stream(buffer) | ||
.word8('ver') | ||
.word8('nmethods') | ||
.buffer('methods', 'nmethods') | ||
.tap((args) => { | ||
// verify version is appropriate | ||
if (args.ver !== RFC_1928_VERSION) { | ||
return end(RFC_1928_REPLIES.GENERAL_FAILURE, args) | ||
} | ||
// convert methods buffer to an array | ||
let acceptedMethods = [].slice.call(args.methods).reduce((methods, method) => { | ||
methods[method] = true | ||
return methods | ||
}, {}), | ||
basicAuth = typeof self.options.authenticate === 'function', | ||
next = connect, | ||
noAuth = | ||
!basicAuth && typeof acceptedMethods[0] !== 'undefined' && acceptedMethods[0], | ||
responseBuffer = Buffer.allocUnsafe(2) | ||
const onHandshakeCompleted = (buffer) => { | ||
self.server.emit(EVENTS.HANDSHAKE, socket) | ||
} | ||
// form response Buffer | ||
responseBuffer[0] = RFC_1928_VERSION | ||
responseBuffer[1] = RFC_1928_METHODS.NO_AUTHENTICATION_REQUIRED | ||
// check for basic auth configuration | ||
if (basicAuth) { | ||
responseBuffer[1] = RFC_1928_METHODS.BASIC_AUTHENTICATION | ||
next = authenticate | ||
// if NO AUTHENTICATION REQUIRED and | ||
} else if (!basicAuth && noAuth) { | ||
responseBuffer[1] = RFC_1928_METHODS.NO_AUTHENTICATION_REQUIRED | ||
next = connect | ||
// basic auth callback not provided and no auth is not supported | ||
} else { | ||
return end(RFC_1928_METHODS.NO_ACCEPTABLE_METHODS, args) | ||
} | ||
// respond then listen for cmd and dst info | ||
socket.write(responseBuffer, () => { | ||
// emit handshake event | ||
self.server.emit(EVENTS.HANDSHAKE, socket) | ||
// now listen for more details | ||
socket.once('data', next) | ||
}) | ||
}) | ||
handshake({ | ||
socket, | ||
buffer, | ||
options: self.options, | ||
connect, | ||
authenticate: _authenticate, | ||
onHandshakeCompleted, | ||
end, | ||
}) | ||
} | ||
// capture the client handshake | ||
socket.once('data', handshake) | ||
socket.once('data', _handshake) | ||
@@ -478,0 +404,0 @@ // capture socket closure |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Deprecated
MaintenanceThe maintainer of the package marked it as deprecated. This could indicate that a single version should not be used, or that the package is no longer maintained and any new vulnerabilities will not be fixed.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
24061
7
646
1
3