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) {
var br, len, host, port, msg;
var addr, msg;
if (data.length < 6) {
this.error('Bad packet size for SOCKS connect.');
@ -433,45 +433,18 @@ SOCKS.prototype.handleProxy = function handleProxy(data) {
return;
}
br = new BufferReader(data);
br.seek(3);
switch (br.readU8()) {
case 0x01:
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;
try {
addr = parseAddr(data, 3);
} catch (e) {
this.error(e);
return;
}
this.state = SOCKS.states.PROXY_DONE;
this.stopTimeout();
this.proxied = true;
this.emit('proxied', host, port);
this.emit('proxy address', addr);
this.emit('proxy', this.socket);
};
@ -494,9 +467,9 @@ SOCKS.prototype.sendResolve = function sendResolve() {
};
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.');
return;
}
@ -513,17 +486,12 @@ SOCKS.prototype.handleResolve = function handleResolve(data) {
}
if (data[2] !== 0x00) {
this.error('Unknown tor resolve error: %d.', data[2]);
return;
}
if (data[3] !== 0x01) {
this.error('Tor resolve failed (padding).');
return;
}
try {
ip = IP.toString(data.slice(4, 8));
addr = parseAddr(data, 3);
} catch (e) {
this.error(e);
return;
@ -533,7 +501,7 @@ SOCKS.prototype.handleResolve = function handleResolve(data) {
this.destroy();
this.emit('resolve', [ip]);
this.emit('resolve', [addr.host]);
};
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
*/