socks: refactor addr parsing.

This commit is contained in:
Christopher Jeffrey 2017-01-25 02:31:40 -08:00
parent 00dccf0d5d
commit 64114460ad
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD

View File

@ -410,7 +410,7 @@ SOCKS.prototype.sendProxy = function sendProxy() {
}; };
SOCKS.prototype.handleProxy = function handleProxy(data) { SOCKS.prototype.handleProxy = function handleProxy(data) {
var br, len, host, port, msg; var addr, msg;
if (data.length < 6) { if (data.length < 6) {
this.error('Bad packet size for SOCKS connect.'); this.error('Bad packet size for SOCKS connect.');
@ -433,45 +433,18 @@ SOCKS.prototype.handleProxy = function handleProxy(data) {
return; return;
} }
br = new BufferReader(data); try {
br.seek(3); addr = parseAddr(data, 3);
} catch (e) {
switch (br.readU8()) { this.error(e);
case 0x01: return;
if (br.left() < 6) {
this.error('Bad packet length for SOCKS connect.');
return;
}
host = IP.toString(br.readBytes(4));
port = br.readU16BE();
break;
case 0x03:
len = br.readU8();
if (br.left() < len + 2) {
this.error('Bad packet length for SOCKS connect.');
return;
}
host = br.readString(len, 'utf8');
port = br.readU16BE();
break;
case 0x04:
if (br.left() < 18) {
this.error('Bad packet length for SOCKS connect.');
return;
}
host = IP.toString(br.readBytes(16));
port = br.readU16BE();
break;
default:
this.error('Unknown SOCKS address type: %d.', data[4]);
return;
} }
this.state = SOCKS.states.PROXY_DONE; this.state = SOCKS.states.PROXY_DONE;
this.stopTimeout(); this.stopTimeout();
this.proxied = true; this.proxied = true;
this.emit('proxied', host, port); this.emit('proxy address', addr);
this.emit('proxy', this.socket); this.emit('proxy', this.socket);
}; };
@ -494,9 +467,9 @@ SOCKS.prototype.sendResolve = function sendResolve() {
}; };
SOCKS.prototype.handleResolve = function handleResolve(data) { SOCKS.prototype.handleResolve = function handleResolve(data) {
var ip, msg; var addr, msg;
if (data.length !== 10) { if (data.length < 6) {
this.error('Bad packet size for tor resolve.'); this.error('Bad packet size for tor resolve.');
return; return;
} }
@ -513,17 +486,12 @@ SOCKS.prototype.handleResolve = function handleResolve(data) {
} }
if (data[2] !== 0x00) { if (data[2] !== 0x00) {
this.error('Unknown tor resolve error: %d.', data[2]);
return;
}
if (data[3] !== 0x01) {
this.error('Tor resolve failed (padding).'); this.error('Tor resolve failed (padding).');
return; return;
} }
try { try {
ip = IP.toString(data.slice(4, 8)); addr = parseAddr(data, 3);
} catch (e) { } catch (e) {
this.error(e); this.error(e);
return; return;
@ -533,7 +501,7 @@ SOCKS.prototype.handleResolve = function handleResolve(data) {
this.destroy(); this.destroy();
this.emit('resolve', [ip]); this.emit('resolve', [addr.host]);
}; };
SOCKS.resolve = function resolve(options) { SOCKS.resolve = function resolve(options) {
@ -690,6 +658,48 @@ function parseProxy(host) {
}; };
} }
function parseAddr(data, offset) {
var br = new BufferReader(data);
var type, len, host, port;
if (br.left() < offset + 2)
throw new Error('Bad SOCKS address length.');
br.seek(offset);
type = br.readU8();
switch (type) {
case 0x01:
if (br.left() < 6)
throw new Error('Bad SOCKS ipv4 length.');
host = IP.toString(br.readBytes(4));
port = br.readU16BE();
break;
case 0x03:
len = br.readU8();
if (br.left() < len + 2)
throw new Error('Bad SOCKS domain length.');
host = br.readString(len, 'utf8');
port = br.readU16BE();
break;
case 0x04:
if (br.left() < 18)
throw new Error('Bad SOCKS ipv6 length.');
host = IP.toString(br.readBytes(16));
port = br.readU16BE();
break;
default:
throw new Error('Unknown SOCKS address type: ' + type + '.');
}
return { host: host, port: port };
}
/* /*
* Expose * Expose
*/ */