From 3a0b7d07d3a82bdeca627aa3a0fb8f41047aae94 Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Tue, 24 Jan 2017 05:46:03 -0800 Subject: [PATCH] socks: fix no auth and proxying. --- lib/net/socks.js | 68 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 46 insertions(+), 22 deletions(-) diff --git a/lib/net/socks.js b/lib/net/socks.js index 7b6cbbc1..c7e9553f 100644 --- a/lib/net/socks.js +++ b/lib/net/socks.js @@ -36,6 +36,7 @@ function SOCKS() { this.name = 'localhost'; this.destroyed = false; this.timeout = null; + this.proxied = false; } util.inherits(SOCKS, EventEmitter); @@ -84,7 +85,7 @@ SOCKS.prototype.startTimeout = function startTimeout() { var self = this; this.timeout = setTimeout(function() { self.timeout = null; - self.error('Request timed out.'); + self.error('Request timed out (' + self.state + ').'); }, 5000); }; @@ -105,18 +106,26 @@ SOCKS.prototype.connect = function connect(port, host) { this.socket.connect(port, host); this.socket.on('connect', function() { + if (self.proxied) + return; self.handleConnect(); }); this.socket.on('data', function(data) { + if (self.proxied) + return; self.handleData(data); }); this.socket.on('error', function(err) { + if (self.proxied) + return; self.handleError(err); }); this.socket.on('close', function() { + if (self.proxied) + return; self.handleClose(); }); }; @@ -210,12 +219,20 @@ SOCKS.prototype.handleData = function handleData(data) { }; SOCKS.prototype.sendHandshake = function sendHandshake() { - var packet = new Buffer(4); + var packet; - packet[0] = 0x05; - packet[1] = 0x02; - packet[2] = 0x00; - packet[3] = 0x02; + if (this.username) { + packet = new Buffer(4); + packet[0] = 0x05; + packet[1] = 0x02; + packet[2] = 0x00; + packet[3] = 0x02; + } else { + packet = new Buffer(3); + packet[0] = 0x05; + packet[1] = 0x01; + packet[2] = 0x00; + } this.state = SOCKS.states.HANDSHAKE; this.socket.write(packet); @@ -243,7 +260,7 @@ SOCKS.prototype.handleHandshake = function handleHandshake(data) { break; case 0x00: this.state = SOCKS.states.AUTH; - this.emit('auth'); + this.auth(); break; default: this.error('Handshake error: ' + data[1]); @@ -261,6 +278,11 @@ SOCKS.prototype.sendAuth = function sendAuth() { return; } + if (!pass) { + this.error('No password passed for auth.'); + return; + } + ulen = Buffer.byteLength(user, 'ascii'); plen = Buffer.byteLength(pass, 'ascii'); size = 3 + ulen + plen; @@ -293,6 +315,10 @@ SOCKS.prototype.handleAuth = function handleAuth(data) { return; } + this.auth(); +}; + +SOCKS.prototype.auth = function auth() { this.emit('auth'); switch (this.target) { @@ -328,7 +354,7 @@ SOCKS.prototype.sendProxy = function sendProxy() { break; default: type = 0x03; - name = new Buffer(IP.toString(host), 'ascii'); + name = new Buffer(host, 'ascii'); len = 1 + name.length; break; } @@ -437,10 +463,10 @@ SOCKS.prototype.handleProxy = function handleProxy(data) { } this.state = SOCKS.states.PROXY_DONE; + this.stopTimeout(); + this.proxied = true; - this.destroy(); - - this.emit('proxy', { host: host, port: port }); + this.emit('proxy', this.socket); }; SOCKS.prototype.sendResolve = function sendResolve() { @@ -535,7 +561,7 @@ function Proxy(proxy, user, pass) { EventEmitter.call(this); - this.socket = new net.Socket(); + this.socket = null; this.proxy = IP.fromHostname(proxy); this.username = user; this.password = pass; @@ -549,7 +575,7 @@ util.inherits(Proxy, EventEmitter); Proxy.prototype.connect = co(function* connect(port, host) { var self = this; - var options, addr; + var options, socket; options = { host: this.proxy.host, @@ -561,19 +587,15 @@ Proxy.prototype.connect = co(function* connect(port, host) { }; try { - addr = yield SOCKS.proxy(options); + socket = yield SOCKS.proxy(options); } catch (e) { this.emit('error', e); return; } - this.socket.connect(addr.port, addr.host); - - this.socket.on('connect', function() { - self.remoteAddress = self.socket.remoteAddress; - self.remotePort = self.socket.remotePort; - self.emit('connect'); - }); + this.remoteAddress = host; + this.remotePort = port; + this.socket = socket; this.socket.on('error', function(err) { self.emit('error', err); @@ -585,12 +607,14 @@ Proxy.prototype.connect = co(function* connect(port, host) { this.socket.on('data', function(data) { self.bytesRead += data.length; - self.emit('data'); + self.emit('data', data); }); this.socket.on('drain', function() { self.emit('drain'); }); + + this.emit('connect'); }); Proxy.prototype.write = function write(data, callback) {