socks: fix no auth and proxying.

This commit is contained in:
Christopher Jeffrey 2017-01-24 05:46:03 -08:00
parent a87484f2e8
commit 3a0b7d07d3
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD

View File

@ -36,6 +36,7 @@ function SOCKS() {
this.name = 'localhost'; this.name = 'localhost';
this.destroyed = false; this.destroyed = false;
this.timeout = null; this.timeout = null;
this.proxied = false;
} }
util.inherits(SOCKS, EventEmitter); util.inherits(SOCKS, EventEmitter);
@ -84,7 +85,7 @@ SOCKS.prototype.startTimeout = function startTimeout() {
var self = this; var self = this;
this.timeout = setTimeout(function() { this.timeout = setTimeout(function() {
self.timeout = null; self.timeout = null;
self.error('Request timed out.'); self.error('Request timed out (' + self.state + ').');
}, 5000); }, 5000);
}; };
@ -105,18 +106,26 @@ SOCKS.prototype.connect = function connect(port, host) {
this.socket.connect(port, host); this.socket.connect(port, host);
this.socket.on('connect', function() { this.socket.on('connect', function() {
if (self.proxied)
return;
self.handleConnect(); self.handleConnect();
}); });
this.socket.on('data', function(data) { this.socket.on('data', function(data) {
if (self.proxied)
return;
self.handleData(data); self.handleData(data);
}); });
this.socket.on('error', function(err) { this.socket.on('error', function(err) {
if (self.proxied)
return;
self.handleError(err); self.handleError(err);
}); });
this.socket.on('close', function() { this.socket.on('close', function() {
if (self.proxied)
return;
self.handleClose(); self.handleClose();
}); });
}; };
@ -210,12 +219,20 @@ SOCKS.prototype.handleData = function handleData(data) {
}; };
SOCKS.prototype.sendHandshake = function sendHandshake() { SOCKS.prototype.sendHandshake = function sendHandshake() {
var packet = new Buffer(4); var packet;
packet[0] = 0x05; if (this.username) {
packet[1] = 0x02; packet = new Buffer(4);
packet[2] = 0x00; packet[0] = 0x05;
packet[3] = 0x02; 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.state = SOCKS.states.HANDSHAKE;
this.socket.write(packet); this.socket.write(packet);
@ -243,7 +260,7 @@ SOCKS.prototype.handleHandshake = function handleHandshake(data) {
break; break;
case 0x00: case 0x00:
this.state = SOCKS.states.AUTH; this.state = SOCKS.states.AUTH;
this.emit('auth'); this.auth();
break; break;
default: default:
this.error('Handshake error: ' + data[1]); this.error('Handshake error: ' + data[1]);
@ -261,6 +278,11 @@ SOCKS.prototype.sendAuth = function sendAuth() {
return; return;
} }
if (!pass) {
this.error('No password passed for auth.');
return;
}
ulen = Buffer.byteLength(user, 'ascii'); ulen = Buffer.byteLength(user, 'ascii');
plen = Buffer.byteLength(pass, 'ascii'); plen = Buffer.byteLength(pass, 'ascii');
size = 3 + ulen + plen; size = 3 + ulen + plen;
@ -293,6 +315,10 @@ SOCKS.prototype.handleAuth = function handleAuth(data) {
return; return;
} }
this.auth();
};
SOCKS.prototype.auth = function auth() {
this.emit('auth'); this.emit('auth');
switch (this.target) { switch (this.target) {
@ -328,7 +354,7 @@ SOCKS.prototype.sendProxy = function sendProxy() {
break; break;
default: default:
type = 0x03; type = 0x03;
name = new Buffer(IP.toString(host), 'ascii'); name = new Buffer(host, 'ascii');
len = 1 + name.length; len = 1 + name.length;
break; break;
} }
@ -437,10 +463,10 @@ SOCKS.prototype.handleProxy = function handleProxy(data) {
} }
this.state = SOCKS.states.PROXY_DONE; this.state = SOCKS.states.PROXY_DONE;
this.stopTimeout();
this.proxied = true;
this.destroy(); this.emit('proxy', this.socket);
this.emit('proxy', { host: host, port: port });
}; };
SOCKS.prototype.sendResolve = function sendResolve() { SOCKS.prototype.sendResolve = function sendResolve() {
@ -535,7 +561,7 @@ function Proxy(proxy, user, pass) {
EventEmitter.call(this); EventEmitter.call(this);
this.socket = new net.Socket(); this.socket = null;
this.proxy = IP.fromHostname(proxy); this.proxy = IP.fromHostname(proxy);
this.username = user; this.username = user;
this.password = pass; this.password = pass;
@ -549,7 +575,7 @@ util.inherits(Proxy, EventEmitter);
Proxy.prototype.connect = co(function* connect(port, host) { Proxy.prototype.connect = co(function* connect(port, host) {
var self = this; var self = this;
var options, addr; var options, socket;
options = { options = {
host: this.proxy.host, host: this.proxy.host,
@ -561,19 +587,15 @@ Proxy.prototype.connect = co(function* connect(port, host) {
}; };
try { try {
addr = yield SOCKS.proxy(options); socket = yield SOCKS.proxy(options);
} catch (e) { } catch (e) {
this.emit('error', e); this.emit('error', e);
return; return;
} }
this.socket.connect(addr.port, addr.host); this.remoteAddress = host;
this.remotePort = port;
this.socket.on('connect', function() { this.socket = socket;
self.remoteAddress = self.socket.remoteAddress;
self.remotePort = self.socket.remotePort;
self.emit('connect');
});
this.socket.on('error', function(err) { this.socket.on('error', function(err) {
self.emit('error', err); self.emit('error', err);
@ -585,12 +607,14 @@ Proxy.prototype.connect = co(function* connect(port, host) {
this.socket.on('data', function(data) { this.socket.on('data', function(data) {
self.bytesRead += data.length; self.bytesRead += data.length;
self.emit('data'); self.emit('data', data);
}); });
this.socket.on('drain', function() { this.socket.on('drain', function() {
self.emit('drain'); self.emit('drain');
}); });
this.emit('connect');
}); });
Proxy.prototype.write = function write(data, callback) { Proxy.prototype.write = function write(data, callback) {