@applitools/eg-socks5-proxy-server
Advanced tools
Comparing version 0.2.0-debug to 0.2.0-debug-10
{ | ||
"name": "@applitools/eg-socks5-proxy-server", | ||
"version": "0.2.0-debug", | ||
"version": "0.2.0-debug-10", | ||
"description": "", | ||
@@ -5,0 +5,0 @@ "main": "src/index.js", |
const binary = require('binary') | ||
const domain = require('domain') | ||
const { | ||
RFC_1928_ATYP, | ||
RFC_1928_COMMANDS, | ||
RFC_1928_METHODS, | ||
RFC_1928_REPLIES, | ||
RFC_1928_VERSION, | ||
RFC_1929_REPLIES, | ||
RFC_1929_VERSION, | ||
} = require('./constants') | ||
const {RFC_1929_REPLIES, RFC_1929_VERSION} = require('./constants') | ||
module.exports = {authenticate} | ||
/** | ||
* +----+------+----------+------+----------+ | ||
* |VER | ULEN | UNAME | PLEN | PASSWD | | ||
* +----+------+----------+------+----------+ | ||
* | 1 | 1 | 1 to 255 | 1 | 1 to 255 | | ||
* +----+------+----------+------+----------+ | ||
* | ||
* | ||
* @param {Buffer} buffer - a buffer | ||
* @returns {undefined} | ||
**/ | ||
function authenticate({socket, buffer, options, connect, end, onAuthenticated, onFailed}) { | ||
let authDomain = domain.create() | ||
* +----+------+----------+------+----------+ | ||
* |VER | ULEN | UNAME | PLEN | PASSWD | | ||
* +----+------+----------+------+----------+ | ||
* | 1 | 1 | 1 to 255 | 1 | 1 to 255 | | ||
* +----+------+----------+------+----------+ | ||
* | ||
* | ||
* @param {Buffer} buffer - a buffer | ||
* @returns {undefined} | ||
**/ | ||
function authenticate({socket, buffer, options, connect, end, onAuthenticated, onFailed}) { | ||
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 | ||
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) | ||
} | ||
// 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 | ||
onFailed(args, err) | ||
authDomain.on('error', (err) => { | ||
// emit failed authentication event | ||
onFailed(args, err) | ||
// respond with auth failure | ||
return end(RFC_1929_REPLIES.GENERAL_FAILURE, args) | ||
}) | ||
// respond with auth failure | ||
return end(RFC_1929_REPLIES.GENERAL_FAILURE, args) | ||
}) | ||
// perform authentication | ||
options.authenticate( | ||
args.uname.toString(), | ||
args.passwd.toString(), | ||
socket, | ||
authDomain.intercept(() => { | ||
// emit successful authentication event | ||
onAuthenticated(args) | ||
// perform authentication | ||
options.authenticate( | ||
args.uname.toString(), | ||
args.passwd.toString(), | ||
socket, | ||
authDomain.intercept(() => { | ||
// emit successful authentication event | ||
onAuthenticated(args) | ||
// respond with success... | ||
let responseBuffer = Buffer.allocUnsafe(2) | ||
responseBuffer[0] = RFC_1929_VERSION | ||
responseBuffer[1] = RFC_1929_REPLIES.SUCCEEDED | ||
// 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) | ||
}) | ||
}), | ||
) | ||
}) | ||
} | ||
// respond then listen for cmd and dst info | ||
socket.write(responseBuffer, () => { | ||
// now listen for more details | ||
socket.once('data', connect) | ||
}) | ||
}), | ||
) | ||
}) | ||
} |
@@ -17,3 +17,3 @@ module.exports = { | ||
REMOTE_PROXY_HANDSHAKE_TIMEOUT: 'remote-proxy-handshake-timeout', | ||
REMOTE_PROXY_DATA_TIMEOUT: 'remote-proxy-data-timeout', | ||
REMOTE_PROXY_RFC_1928_REPLY_TIMEOUT: 'remote-proxy-rpc-1928-reply-timeout', | ||
@@ -20,0 +20,0 @@ ORIGIN_SOCKET_ERROR: 'orgin-socket-error', |
@@ -19,3 +19,3 @@ const net = require('net') | ||
let handshakeTimeout | ||
let timeoutId | ||
@@ -29,6 +29,6 @@ const destination = net.createConnection(port, address, () => { | ||
destination.write(clientHandshakeBuffer, () => { | ||
let isTimeoutCalled = false | ||
let wasHandshakeTimeoutCalled = false | ||
handshakeTimeout = setTimeout(() => { | ||
isTimeoutCalled = true | ||
timeoutId = setTimeout(() => { | ||
wasHandshakeTimeoutCalled = true | ||
destination.destroy() | ||
@@ -39,4 +39,4 @@ proxyServer.onHandshakeTimeout() | ||
destination.once('data', () => { | ||
clearTimeout(handshakeTimeout) | ||
if (isTimeoutCalled) { | ||
clearTimeout(timeoutId) | ||
if (wasHandshakeTimeoutCalled) { | ||
destination.destroy() | ||
@@ -46,8 +46,24 @@ return | ||
const dataTimeoutId = setTimeout(() => proxyServer.onDataTimeout(), 5000) | ||
destination.once('data', () => clearTimeout(dataTimeoutId)) | ||
const writeAcknowledgementToClient = (data) => | ||
originalSocket.write(data, () => { | ||
destination.pipe(originalSocket) | ||
originalSocket.pipe(destination) | ||
}) | ||
let wasRpcReplyTimeoutCalled = false | ||
timeoutId = setTimeout(() => { | ||
wasRpcReplyTimeoutCalled = true | ||
destination.destroy() | ||
proxyServer.onRpc1928ReplyTimeout() | ||
}, 5000) | ||
// first buffer after handshake | ||
destination.write(args.requestBuffer, () => { | ||
destination.pipe(originalSocket) | ||
originalSocket.pipe(destination) | ||
destination.once('data', (data) => { | ||
if (wasRpcReplyTimeoutCalled) return | ||
clearTimeout(timeoutId) | ||
writeAcknowledgementToClient(data) | ||
}) | ||
}) | ||
@@ -69,3 +85,3 @@ | ||
destination.on('error', (err) => { | ||
handshakeTimeout && clearTimeout(handshakeTimeout) | ||
timeoutId && clearTimeout(timeoutId) | ||
@@ -72,0 +88,0 @@ // notify of connection error |
const binary = require('binary') | ||
const { | ||
RFC_1928_METHODS, | ||
RFC_1928_REPLIES, | ||
RFC_1928_VERSION, | ||
} = require('./constants') | ||
const {RFC_1928_METHODS, RFC_1928_REPLIES, RFC_1928_VERSION} = require('./constants') | ||
module.exports = {handshake} | ||
module.exports = {handshake} | ||
@@ -20,62 +16,61 @@ /** | ||
* @param {Buffer} buffer - a buffer | ||
* @param {any} options | ||
* @param {Function} connet | ||
* @param {any} options | ||
* @param {Function} connet | ||
* @param {Function} authenticate | ||
* @param {Function} end | ||
* @param {Function} end | ||
* @param {Function} onHandShakeCompleted | ||
* | ||
* | ||
* @returns {undefined} | ||
**/ | ||
**/ | ||
function handshake({socket, buffer, options, connect, authenticate, end, onHandshakeCompleted}) { | ||
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) | ||
} | ||
const 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 options.authenticate === 'function', | ||
next = connect, | ||
noAuth = | ||
!basicAuth && typeof acceptedMethods[0] !== 'undefined' && acceptedMethods[0], | ||
responseBuffer = Buffer.allocUnsafe(2) | ||
// convert methods buffer to an array | ||
let acceptedMethods = [].slice.call(args.methods).reduce((methods, method) => { | ||
methods[method] = true | ||
return methods | ||
}, {}), | ||
basicAuth = typeof options.authenticate === 'function', | ||
next = connect, | ||
noAuth = !basicAuth && typeof acceptedMethods[0] !== 'undefined' && acceptedMethods[0], | ||
responseBuffer = Buffer.allocUnsafe(2) | ||
// form response Buffer | ||
responseBuffer[0] = RFC_1928_VERSION | ||
responseBuffer[1] = RFC_1928_METHODS.NO_AUTHENTICATION_REQUIRED | ||
// 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 | ||
// 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 | ||
// 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) | ||
} | ||
// 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 | ||
socket.once('data', next) | ||
onHandshakeCompleted && onHandshakeCompleted(clientHandshakeBuffer) | ||
// now listen for more details | ||
}) | ||
// respond then listen for cmd and dst info | ||
socket.write(responseBuffer, () => { | ||
// emit handshake event | ||
socket.once('data', next) | ||
onHandshakeCompleted && onHandshakeCompleted(clientHandshakeBuffer) | ||
// now listen for more details | ||
}) | ||
} | ||
}) | ||
} |
@@ -289,3 +289,3 @@ const { | ||
let retry = 0 | ||
let handshakeRetry = 0 | ||
proxyServer.onHandshakeTimeout = () => { | ||
@@ -297,9 +297,10 @@ self.server.emit(EVENTS.REMOTE_PROXY_HANDSHAKE_TIMEOUT, { | ||
}) | ||
retry++ | ||
if (retry <= 3) createExecuterAndRegisterToEvents() | ||
handshakeRetry++ | ||
if (handshakeRetry <= 3) createExecuterAndRegisterToEvents() | ||
else end(RFC_1928_REPLIES.NETWORK_UNREACHABLE, args) | ||
} | ||
proxyServer.onDataTimeout = () => { | ||
self.server.emit(EVENTS.REMOTE_PROXY_DATA_TIMEOUT, { | ||
let rpcReplyRetry = 0 | ||
proxyServer.onRpc1928ReplyTimeout = () => { | ||
self.server.emit(EVENTS.REMOTE_PROXY_RFC_1928_REPLY_TIMEOUT, { | ||
originInfo, | ||
@@ -309,4 +310,8 @@ destinationInfo, | ||
}) | ||
rpcReplyRetry++ | ||
if (rpcReplyRetry <= 3) createExecuterAndRegisterToEvents() | ||
else end(RFC_1928_REPLIES.NETWORK_UNREACHABLE, args) | ||
} | ||
destination = executeRequestThroughRemoteProxy({ | ||
@@ -313,0 +318,0 @@ originalSocket: socket, |
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
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
25261
666
0