From 64114460adde54f8e0606b778ef99d8abcf7e1ae Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Wed, 25 Jan 2017 02:31:40 -0800 Subject: [PATCH] socks: refactor addr parsing. --- lib/net/socks.js | 96 ++++++++++++++++++++++++++---------------------- 1 file changed, 53 insertions(+), 43 deletions(-) diff --git a/lib/net/socks.js b/lib/net/socks.js index 3cb9129a..f1e02008 100644 --- a/lib/net/socks.js +++ b/lib/net/socks.js @@ -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 */