From c43e6cf14f902140da81f995170430dfe05f7d13 Mon Sep 17 00:00:00 2001 From: Zachary Boyd Date: Mon, 10 Sep 2018 13:03:02 -0400 Subject: [PATCH] Finishes proxying through a specific instance --- CHANGELOG.md | 2 + package-lock.json | 429 ------------------------------------------ package.json | 3 +- src/DNSServer.js | 5 +- src/HTTPServer.js | 16 +- src/SOCKSServer.js | 26 +-- src/TorPool.js | 2 +- src/launch.js | 2 +- test/ControlServer.js | 2 +- test/DNSServer.js | 5 + test/HTTPServer.js | 230 ++++++++++++++++++++-- test/SOCKSServer.js | 145 ++++++++++++-- test/TorPool.js | 2 +- test/TorProcess.js | 2 +- 14 files changed, 379 insertions(+), 492 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f51fb0e..1d75556 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## [4.0.0] - 2018-09-09 ### Added +- You can now proxy through a specific instance using the username field when connecting to a proxy. Setting `--proxyByName` or `-n` to false will disable this feature. For example to connect to an instance named `instance-1` via http use `http://instance-1:@localhost:9080`. - The control server will accept WebSocket connections if the `--websocketControlHost` or `-w` argument is set. If the argument is used without a hostname it will default to 9078 on all interfaces. - All servers (DNS, HTTP, SOCKS and Control) all have a `listen` method which takes a port and optionally, a host returns a Promise that will resolve when the server is listening. @@ -12,6 +13,7 @@ - The `logger` argument to the constructor of all classes is now optional - The `Config` property of instance definitions will now inherit from `TorPool.default_tor_config`. - The mocha test has been split into individual files all under `test/` +- DNS shows the source/destination hostname/port in logs instead of what the query was resolved to ### Removes - The `new_ips` and `new_ip_at` TorPool and `new_ip` TorProcess have been removed. Use `new_identites`, `new_identity_at` and `new_identity` instead. diff --git a/package-lock.json b/package-lock.json index fc04e57..5ed2a50 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,15 +15,6 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-10.0.6.tgz", "integrity": "sha512-2whhQUfDHRBiZ3L54Ulyl1X+fZWbWabxPYRDAsibgOAtE6adwusD15Xv0Bw/D7cPah35Z/wKTdW3iAKsevw1uw==" }, - "agent-base": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.1.tgz", - "integrity": "sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==", - "dev": true, - "requires": { - "es6-promisify": "^5.0.0" - } - }, "ajv": { "version": "5.5.2", "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", @@ -71,12 +62,6 @@ "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", "dev": true }, - "ast-types": { - "version": "0.11.5", - "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.11.5.tgz", - "integrity": "sha512-oJjo+5e7/vEc2FBK8gUalV0pba4L3VdBIs2EKhOLHLcOd2FgQIVQN9xb0eZ9IjEWyAL7vq6fGJxOvVvdCHNyMw==", - "dev": true - }, "async": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", @@ -165,12 +150,6 @@ "verror": "^1.4.0" } }, - "bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", - "dev": true - }, "camelcase": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", @@ -413,12 +392,6 @@ "assert-plus": "^1.0.0" } }, - "data-uri-to-buffer": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-1.2.0.tgz", - "integrity": "sha512-vKQ9DTQPN1FLYiiEEOQ6IBGFqvjCa5rSK3cWMy/Nespm5d/x3dGFT9UBZnkLxCwua/IXBi2TYnwTEpsOvhC4UQ==", - "dev": true - }, "debug": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", @@ -442,23 +415,6 @@ "type-detect": "^4.0.0" } }, - "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true - }, - "degenerator": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-1.0.4.tgz", - "integrity": "sha1-/PSQo37OJmRk2cxDGrmMWBnO0JU=", - "dev": true, - "requires": { - "ast-types": "0.x.x", - "escodegen": "1.x.x", - "esprima": "3.x.x" - } - }, "del": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/del/-/del-3.0.0.tgz", @@ -478,12 +434,6 @@ "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", "dev": true }, - "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", - "dev": true - }, "diagnostics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/diagnostics/-/diagnostics-1.1.0.tgz", @@ -566,58 +516,12 @@ "resolved": "https://registry.npmjs.org/env-variable/-/env-variable-0.0.4.tgz", "integrity": "sha512-+jpGxSWG4vr6gVxUHOc4p+ilPnql7NzZxOZBxNldsKGjCF+97df3CbuX7XMaDa5oAVkKQj4rKp38rYdC4VcpDg==" }, - "es6-promise": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.4.tgz", - "integrity": "sha512-/NdNZVJg+uZgtm9eS3O6lrOLYmQag2DjdEXuPaHlZ6RuVqgqaVZfgYCepEIKsLqwdQArOPtC3XzRLqGGfT8KQQ==", - "dev": true - }, - "es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", - "dev": true, - "requires": { - "es6-promise": "^4.0.3" - } - }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", "dev": true }, - "escodegen": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.11.0.tgz", - "integrity": "sha512-IeMV45ReixHS53K/OmfKAIztN/igDHzTJUhZM3k1jMhIZWjk45SMwAtBsEXiJp3vSPmTcu6CXn7mDvFHRN66fw==", - "dev": true, - "requires": { - "esprima": "^3.1.3", - "estraverse": "^4.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1", - "source-map": "~0.6.1" - } - }, - "esprima": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", - "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=", - "dev": true - }, - "estraverse": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", - "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", - "dev": true - }, - "esutils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", - "dev": true - }, "eventemitter3": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.0.tgz", @@ -665,23 +569,11 @@ "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", "dev": true }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, "fecha": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fecha/-/fecha-2.3.3.tgz", "integrity": "sha512-lUGBnIamTAwk4znq5BcqsDaxSmZ9nDVJaij6NvRt/Tg4R69gERA+otPKbS86ROw9nxVMw2/mp1fnaiWqbs6Sdg==" }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true - }, "find-up": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", @@ -730,42 +622,6 @@ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, - "ftp": { - "version": "0.3.10", - "resolved": "https://registry.npmjs.org/ftp/-/ftp-0.3.10.tgz", - "integrity": "sha1-kZfYYa2BQvPmPVqDv+TFn3MwiF0=", - "dev": true, - "requires": { - "readable-stream": "1.1.x", - "xregexp": "2.0.0" - }, - "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "readable-stream": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - } - } - }, "get-caller-file": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz", @@ -790,31 +646,6 @@ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=" }, - "get-uri": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-2.0.2.tgz", - "integrity": "sha512-ZD325dMZOgerGqF/rF6vZXyFGTAay62svjQIT+X/oU2PtxYpFxvSkbsdi+oxIrsNxlZVd4y8wUDqkaExWTI/Cw==", - "dev": true, - "requires": { - "data-uri-to-buffer": "1", - "debug": "2", - "extend": "3", - "file-uri-to-path": "1", - "ftp": "~0.3.10", - "readable-stream": "2" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } - } - }, "getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", @@ -939,28 +770,6 @@ "readable-stream": "^2.0.2" } }, - "http-errors": { - "version": "1.6.3", - "resolved": "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", - "dev": true, - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" - } - }, - "http-proxy-agent": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", - "dev": true, - "requires": { - "agent-base": "4", - "debug": "3.1.0" - } - }, "http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", @@ -972,25 +781,6 @@ "sshpk": "^1.7.0" } }, - "https-proxy-agent": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz", - "integrity": "sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==", - "dev": true, - "requires": { - "agent-base": "^4.1.0", - "debug": "^3.1.0" - } - }, - "iconv-lite": { - "version": "0.4.23", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", - "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -1020,12 +810,6 @@ "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=" }, - "ip": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", - "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", - "dev": true - }, "ipaddr.js": { "version": "0.1.9", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-0.1.9.tgz", @@ -1176,16 +960,6 @@ "invert-kv": "^1.0.0" } }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - } - }, "locate-path": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", @@ -1433,12 +1207,6 @@ "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=", "optional": true }, - "netmask": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/netmask/-/netmask-1.0.6.tgz", - "integrity": "sha1-ICl+idhvb2QA8lDZ9Pa0wZRfzTU=", - "dev": true - }, "npm-run-path": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", @@ -1484,20 +1252,6 @@ "resolved": "https://registry.npmjs.org/one-time/-/one-time-0.0.4.tgz", "integrity": "sha1-+M33eISCb+Tf+T46nMN7HkSAdC4=" }, - "optionator": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", - "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", - "dev": true, - "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.4", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "wordwrap": "~1.0.0" - } - }, "os-locale": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", @@ -1544,47 +1298,6 @@ "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=" }, - "pac-proxy-agent": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-2.0.2.tgz", - "integrity": "sha512-cDNAN1Ehjbf5EHkNY5qnRhGPUCp6SnpyVof5fRzN800QV1Y2OkzbH9rmjZkbBRa8igof903yOnjIl6z0SlAhxA==", - "dev": true, - "requires": { - "agent-base": "^4.2.0", - "debug": "^3.1.0", - "get-uri": "^2.0.0", - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.1", - "pac-resolver": "^3.0.0", - "raw-body": "^2.2.0", - "socks-proxy-agent": "^3.0.0" - }, - "dependencies": { - "socks-proxy-agent": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-3.0.1.tgz", - "integrity": "sha512-ZwEDymm204mTzvdqyUqOdovVr2YRd2NYskrYrF2LXyZ9qDiMAoFESGK8CRphiO7rtbo2Y757k2Nia3x2hGtalA==", - "dev": true, - "requires": { - "agent-base": "^4.1.0", - "socks": "^1.1.10" - } - } - } - }, - "pac-resolver": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-3.0.0.tgz", - "integrity": "sha512-tcc38bsjuE3XZ5+4vP96OfhOugrX+JcnpUbhfuc4LuXBLQhoTthOstZeoQJBDnQUDYzYmdImKsbz0xSl1/9qeA==", - "dev": true, - "requires": { - "co": "^4.6.0", - "degenerator": "^1.0.4", - "ip": "^1.1.5", - "netmask": "^1.0.6", - "thunkify": "^2.1.2" - } - }, "parse5": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/parse5/-/parse5-3.0.3.tgz", @@ -1653,39 +1366,11 @@ "resolved": "https://registry.npmjs.org/pkginfo/-/pkginfo-0.3.1.tgz", "integrity": "sha1-Wyn2qB9wcXFC4J52W76rl7T4HiE=" }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true - }, "process-nextick-args": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" }, - "proxy-agent": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-3.0.1.tgz", - "integrity": "sha512-mAZexaz9ZxQhYPWfAjzlrloEjW+JHiBFryE4AJXFDTnaXfmH/FKqC1swTRKuEPbHWz02flQNXFOyDUF7zfEG6A==", - "dev": true, - "requires": { - "agent-base": "^4.2.0", - "debug": "^3.1.0", - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.1", - "lru-cache": "^4.1.2", - "pac-proxy-agent": "^2.0.1", - "proxy-from-env": "^1.0.0", - "socks-proxy-agent": "^4.0.1" - } - }, - "proxy-from-env": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.0.0.tgz", - "integrity": "sha1-M8UDmPcOp+uW0h97gXYwpVeRx+4=", - "dev": true - }, "pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", @@ -1703,18 +1388,6 @@ "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", "dev": true }, - "raw-body": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz", - "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==", - "dev": true, - "requires": { - "bytes": "3.0.0", - "http-errors": "1.6.3", - "iconv-lite": "0.4.23", - "unpipe": "1.0.0" - } - }, "readable-stream": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", @@ -1816,12 +1489,6 @@ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, "secure-keys": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/secure-keys/-/secure-keys-1.0.0.tgz", @@ -1837,12 +1504,6 @@ "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" }, - "setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", - "dev": true - }, "shebang-command": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", @@ -1871,12 +1532,6 @@ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" }, - "smart-buffer": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-1.1.15.tgz", - "integrity": "sha1-fxFLW2X6s+KjWqd1uxLw0cZJvxY=", - "dev": true - }, "sntp": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz", @@ -1886,44 +1541,6 @@ "hoek": "4.x.x" } }, - "socks": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/socks/-/socks-1.1.10.tgz", - "integrity": "sha1-W4t/x8jzQcU+0FbpKbe/Tei6e1o=", - "dev": true, - "requires": { - "ip": "^1.1.4", - "smart-buffer": "^1.0.13" - } - }, - "socks-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-4.0.1.tgz", - "integrity": "sha512-Kezx6/VBguXOsEe5oU3lXYyKMi4+gva72TwJ7pQY5JfqUx2nMk7NXA6z/mpNqIlfQjWYVfeuNvQjexiTaTn6Nw==", - "dev": true, - "requires": { - "agent-base": "~4.2.0", - "socks": "~2.2.0" - }, - "dependencies": { - "smart-buffer": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.0.1.tgz", - "integrity": "sha512-RFqinRVJVcCAL9Uh1oVqE6FZkqsyLiVOYEZ20TqIOjuX7iFVJ+zsbs4RIghnw/pTs7mZvt8ZHhvm1ZUrR4fykg==", - "dev": true - }, - "socks": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.2.1.tgz", - "integrity": "sha512-0GabKw7n9mI46vcNrVfs0o6XzWzjVa3h6GaSo2UPxtWAROXUWavfJWh1M4PR5tnE0dcnQXZIDFP4yrAysLze/w==", - "dev": true, - "requires": { - "ip": "^1.1.5", - "smart-buffer": "^4.0.1" - } - } - } - }, "socksv5": { "version": "git+https://github.com/znetstar/socksv5.git#431e541390314adbbe765650d8d810ec1df38d8a", "from": "git+https://github.com/znetstar/socksv5.git#431e541390314adbbe765650d8d810ec1df38d8a", @@ -1948,13 +1565,6 @@ } } }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "optional": true - }, "sshpk": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.1.tgz", @@ -1976,12 +1586,6 @@ "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=" }, - "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", - "dev": true - }, "stealthy-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", @@ -2047,12 +1651,6 @@ "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-0.0.0.tgz", "integrity": "sha1-V4+8haapJjbkLdF7QdAhjM6esrM=" }, - "thunkify": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/thunkify/-/thunkify-2.1.2.tgz", - "integrity": "sha1-+qDp0jDFGsyVyhOjYawFyn4EVT0=", - "dev": true - }, "tough-cookie": { "version": "2.3.4", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", @@ -2083,27 +1681,12 @@ "dev": true, "optional": true }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2" - } - }, "type-detect": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", - "dev": true - }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -2163,12 +1746,6 @@ "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-3.2.1.tgz", "integrity": "sha512-WPqbdAmMK/kfWCWKM2bA1o997wWPZ0jg5NpO8JPqoaDZgCiZnFpIEddcf7Ur4UZV2sYRUdySVBWKx0+gQQ/jrg==" }, - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", - "dev": true - }, "wrap-ansi": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", @@ -2224,12 +1801,6 @@ "async-limiter": "~1.0.0" } }, - "xregexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-2.0.0.tgz", - "integrity": "sha1-UqY+VsoLhKfzpfPWGHLxJq16WUM=", - "dev": true - }, "xtend": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", diff --git a/package.json b/package.json index b28ef9e..1a3dd7b 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,6 @@ "socksv5": "git+https://github.com/znetstar/socksv5.git#431e541390314adbbe765650d8d810ec1df38d8a", "temp": "^0.8.3", "winston": "^3.0.0-rc5", - "yargs": "^11.0.0", - "proxy-agent": "^3.0.1" + "yargs": "^11.0.0" } } diff --git a/src/DNSServer.js b/src/DNSServer.js index 18a4c07..10d5472 100644 --- a/src/DNSServer.js +++ b/src/DNSServer.js @@ -31,6 +31,8 @@ class DNSServer extends UDPServer { const handle_dns_request = (req, res) => { let connect = (tor_instance) => { + let source = { hostname: req.address.address, port: req.address.port, proto: 'dns' }; + this.emit('instance-connection', tor_instance, source); for (let question of req.question) { let dns_port = (tor_instance.dns_port); let outbound_req = dns.Request({ @@ -39,11 +41,12 @@ class DNSServer extends UDPServer { timeout: dns_timeout }); + this.logger.verbose(`[dns]: ${source.hostname}:${source.port} → 127.0.0.1:${dns_port}${tor_instance.definition.Name ? ' ('+tor_instance.definition.Name+')' : '' }`); + outbound_req.on('message', (err, answer) => { if (!err && answer) { for (let a of answer.answer){ res.answer.push(a); - this.logger.verbose(`[dns]: ${question.name} type ${dns.consts.QTYPE_TO_NAME[question.type]} → 127.0.0.1:${dns_port}${tor_instance.definition.Name ? ' ('+tor_instance.definition.Name+')' : '' } → ${a.address}`) } } }); diff --git a/src/HTTPServer.js b/src/HTTPServer.js index 2ad6a64..0af9826 100644 --- a/src/HTTPServer.js +++ b/src/HTTPServer.js @@ -4,7 +4,6 @@ const { Server } = http; const Promise = require('bluebird'); const socks = require('socksv5'); -const ProxyAgent = require('proxy-agent'); const TOR_ROUTER_PROXY_AGENT = 'tor-router'; @@ -92,8 +91,10 @@ class HTTPServer extends Server { }); let connect = (tor_instance) => { + let source = { hostname: req.connection.remoteAddress, port: req.connection.remotePort, proto: 'http', by_name: Boolean(instance) }; + this.emit('instance-connection', tor_instance, source); let socks_port = tor_instance.socks_port; - this.logger.verbose(`[http-proxy]: ${req.connection.remoteAddress}:${req.connection.remotePort} → 127.0.0.1:${socks_port} → ${url.hostname}:${url.port}`); + this.logger.verbose(`[http-proxy]: ${source.hostname}:${source.port} → 127.0.0.1:${socks_port}${tor_instance.definition.Name ? ' ('+tor_instance.definition.Name+')' : '' } → ${url.hostname}:${url.port}`); let proxy_req = http.request({ method: req.method, @@ -101,7 +102,12 @@ class HTTPServer extends Server { port: url.port, path: url.path, headers: req.headers, - agent: new ProxyAgent(`socks://127.0.0.1:${socks_port}`) + agent: socks.HttpAgent({ + proxyHost: '127.0.0.1', + proxyPort: socks_port, + auths: [ socks.auth.None() ], + localDNS: false + }) }, (proxy_res) => { proxy_res.on('data', (chunk) => { res.write(chunk); @@ -160,8 +166,10 @@ class HTTPServer extends Server { let port = Number(req.url.split(':').pop()); let connect = (tor_instance) => { + let source = { hostname: req.connection.remoteAddress, port: req.connection.remotePort, proto: 'http-connect', by_name: Boolean(instance) }; + this.emit('instance-connection', tor_instance, source); let socks_port = tor_instance.socks_port; - this.logger && this.logger.verbose(`[http-connect]: ${req.connection.remoteAddress}:${req.connection.remotePort} → 127.0.0.1:${socks_port}${tor_instance.definition.Name ? ' ('+tor_instance.definition.Name+')' : '' } → ${hostname}:${port}`) + this.logger && this.logger.verbose(`[http-connect]: ${source.hostname}:${source.port} → 127.0.0.1:${socks_port}${tor_instance.definition.Name ? ' ('+tor_instance.definition.Name+')' : '' } → ${hostname}:${port}`) var outbound_socket; let onClose = (error) => { diff --git a/src/SOCKSServer.js b/src/SOCKSServer.js index ebc7aa8..c201a9e 100644 --- a/src/SOCKSServer.js +++ b/src/SOCKSServer.js @@ -16,7 +16,7 @@ class SOCKSServer extends Server{ } authenticate_user(username, password, callback) { - let deny_un = this.proxy_by_name.deny_unidentifed_users; + let deny_un = this.proxy_by_name.deny_unidentified_users; // No username and deny unindentifed then deny if (!username && deny_un) callback(false); @@ -32,7 +32,7 @@ class SOCKSServer extends Server{ return callback(false); // Otherwise allow - callback(true, instance); + callback(true, true); } constructor(tor_pool, logger, proxy_by_name) { @@ -41,7 +41,7 @@ class SOCKSServer extends Server{ let instance; if (inbound_socket.user) - instance = inbound_socket.user; + instance = this.tor_pool.instance_by_name(inbound_socket.user); let outbound_socket; let buffer = []; @@ -65,8 +65,10 @@ class SOCKSServer extends Server{ inbound_socket.on('error', onClose); let connect = (tor_instance) => { + let source = { hostname: info.srcAddr, port: info.srcPort, proto: 'socks', by_name: Boolean(instance) }; let socks_port = tor_instance.socks_port; - this.logger.verbose(`[socks]: ${info.srcAddr}:${info.srcPort} → 127.0.0.1:${socks_port}${tor_instance.definition.Name ? ' ('+tor_instance.definition.Name+')' : '' } → ${info.dstAddr}:${info.dstPort}`) + this.emit('instance-connection', tor_instance, source); + this.logger.verbose(`[socks]: ${source.hostname}:${source.port} → 127.0.0.1:${socks_port}${tor_instance.definition.Name ? ' ('+tor_instance.definition.Name+')' : '' } → ${info.dstAddr}:${info.dstPort}`) socks.connect({ host: info.dstAddr, @@ -115,20 +117,18 @@ class SOCKSServer extends Server{ super(handleConnection); - this.logger = logger || require('./winston-silent-logger'); - this.tor_pool = tor_pool; - this.proxy_by_name = proxy_by_name; - let auth = socks.auth.None(); - if (!proxy_by_name) { - this.logger.debug(`[socks]: connecting to a specific instance by name has ben turned off`); - } else { - this.logger.debug(`[socks]: connecting to a specific instance by name has ben turned on`); - auth = socks.auth.UserPassword(this.authenticate_user); + if (proxy_by_name) { + auth = socks.auth.UserPassword(this.authenticate_user.bind(this)); } this.useAuth(auth); + + this.logger = logger || require('./winston-silent-logger'); + this.tor_pool = tor_pool; + this.proxy_by_name = proxy_by_name; + this.logger.debug(`[socks]: connecting to a specific instance by name has ben turned ${proxy_by_name ? 'on' : 'off'}`); } }; diff --git a/src/TorPool.js b/src/TorPool.js index e7de4b3..0cecc92 100644 --- a/src/TorPool.js +++ b/src/TorPool.js @@ -109,7 +109,7 @@ class TorPool extends EventEmitter { } async add(instance_definitions) { - return await Promise.all(instance_definitions.map((instance_definition) => this.create_instance(instance_definition))); + return await Promise.all([].concat(instance_definitions).map((instance_definition) => this.create_instance(instance_definition))); } async create(instances) { diff --git a/src/launch.js b/src/launch.js index a42521e..8b9846a 100644 --- a/src/launch.js +++ b/src/launch.js @@ -204,7 +204,7 @@ let logger = winston.createLogger({ level: logLevel, format: winston.format.simple(), silent: (logLevel === 'null'), - transports: new (winston.transports.Console)({ level: (logLevel !== 'null' ? logLevel : void(0)), silent: (logLevel === 'null') }) + transports: [ new (winston.transports.Console)({ level: (logLevel !== 'null' ? logLevel : void(0)), silent: (logLevel === 'null') }) ] }); module.exports = { main, nconf, logger }; \ No newline at end of file diff --git a/test/ControlServer.js b/test/ControlServer.js index 81c7826..72de214 100644 --- a/test/ControlServer.js +++ b/test/ControlServer.js @@ -1,6 +1,6 @@ const _ = require('lodash'); -const assert = require('chai').assert; +const { assert } = require('chai'); const nconf = require('nconf'); const getPort = require('get-port'); diff --git a/test/DNSServer.js b/test/DNSServer.js index 5beadf3..0993601 100644 --- a/test/DNSServer.js +++ b/test/DNSServer.js @@ -50,7 +50,12 @@ describe('DNSServer', function () { }); }); + after('shutdown server', function () { + dnsServer.close(); + }); + after('shutdown tor pool', async function () { + dnsServer.close(); await dnsServerTorPool.exit(); }); }); \ No newline at end of file diff --git a/test/HTTPServer.js b/test/HTTPServer.js index 32370a6..eec96d8 100644 --- a/test/HTTPServer.js +++ b/test/HTTPServer.js @@ -1,7 +1,7 @@ const nconf = require('nconf'); const request = require('request-promise'); const getPort = require('get-port'); -const ProxyAgent = require('proxy-agent'); +const { assert } = require('chai'); const { TorPool, HTTPServer } = require('../'); const { WAIT_FOR_CREATE, PAGE_LOAD_TIME } = require('./constants'); @@ -10,44 +10,234 @@ nconf.use('memory'); require(`${__dirname}/../src/nconf_load_env.js`)(nconf); nconf.defaults(require(`${__dirname}/../src/default_config.js`)); -let httpServerTorPool; -let httpServer; + describe('HTTPServer', function () { - httpServerTorPool = new TorPool(nconf.get('torPath'), {}, nconf.get('parentDataDirectory'), 'round_robin', null); - httpServer = new HTTPServer(httpServerTorPool); - let httpPort; - before('start up server', async function (){ - this.timeout(WAIT_FOR_CREATE); - - await httpServerTorPool.create(1); - httpPort = await getPort(); - - await httpServer.listen(httpPort); - }); - describe('#handle_http_connections(req, res)', function () { + let httpServerTorPool; + let httpServer; + let httpPort; + + before('start up server', async function (){ + httpServerTorPool = new TorPool(nconf.get('torPath'), {}, nconf.get('parentDataDirectory'), 'round_robin', null); + httpServer = new HTTPServer(httpServerTorPool, null, false); + + this.timeout(WAIT_FOR_CREATE); + + await httpServerTorPool.create(1); + httpPort = await getPort(); + + await httpServer.listen(httpPort); + }); + it('should service a request for example.com', async function () { this.timeout(PAGE_LOAD_TIME); await request({ url: 'http://example.com', - agent: new ProxyAgent(`http://127.0.0.1:${httpPort}`) + proxy: `http://127.0.0.1:${httpPort}` }); }); + + after('shutdown server', function () { + httpServer.close(); + }); + + after('shutdown tor pool', async function () { + await httpServerTorPool.exit(); + }); + }); describe('#handle_connect_connections(req, inbound_socket, head)', function () { + let httpServerTorPool; + let httpServer; + let httpPort; + + before('start up server', async function (){ + httpServerTorPool = new TorPool(nconf.get('torPath'), {}, nconf.get('parentDataDirectory'), 'round_robin', null); + httpServer = new HTTPServer(httpServerTorPool, null, false); + + this.timeout(WAIT_FOR_CREATE); + + await httpServerTorPool.create(1); + httpPort = await getPort(); + + await httpServer.listen(httpPort); + }); + it('should service a request for example.com', async function () { this.timeout(PAGE_LOAD_TIME); await request({ - url: 'https://example.com', - agent: new ProxyAgent(`http://127.0.0.1:${httpPort}`) + url: 'http://example.com', + proxy: `http://127.0.0.1:${httpPort}` }); }); + + after('shutdown server', function () { + httpServer.close(); + }); + + after('shutdown tor pool', async function () { + await httpServerTorPool.exit(); + }); }); - after('shutdown tor pool', async function () { - await httpServerTorPool.exit(); + describe('#authenticate_user_http(req, res)', function () { + let httpServerTorPool; + let httpServer; + let httpPort; + + let instance_def = { + Name: 'instance-3' + }; + + before('start up server', async function (){ + httpServerTorPool = new TorPool(nconf.get('torPath'), {}, nconf.get('parentDataDirectory'), 'round_robin', null); + httpServer = new HTTPServer(httpServerTorPool, null, { deny_unidentified_users: true }); + + this.timeout(WAIT_FOR_CREATE * 3); + + await httpServerTorPool.create(2); + await httpServerTorPool.add(instance_def); + httpPort = await getPort(); + + await httpServer.listen(httpPort); + }); + + it(`should service a request for example.com through ${instance_def.Name}`, function (done) { + this.timeout(PAGE_LOAD_TIME); + + let req; + + httpServer.on('instance-connection', (instance, source) => { + assert.equal(instance.instance_name, instance_def.Name); + assert.isTrue(source.by_name); + req.cancel(); + done(); + }); + + req = request({ + url: 'http://example.com', + proxy: `http://${instance_def.Name}:@127.0.0.1:${httpPort}` + }) + .catch(done) + }); + + it(`shouldn't be able to send a request without a username`, async function() { + let f = () => {}; + try { + await request({ + url: 'http://example.com', + proxy: `https://127.0.0.1:${httpPort}`, + timeout: PAGE_LOAD_TIME + }); + } catch (error) { + f = () => { throw error }; + } finally { + assert.throws(f, "407", "Did not return 407 status code"); + } + }); + + it(`shouldn't be able to send a request with an incorrect username`, async function() { + let f = () => {}; + try { + await request({ + url: 'http://example.com', + proxy: `http://blah-blah-blah:@127.0.0.1:${httpPort}`, + timeout: PAGE_LOAD_TIME + }); + } catch (error) { + f = () => { throw error }; + } finally { + assert.throws(f, "407", "Did not return 407 status code"); + } + }); + + after('shutdown server', function () { + httpServer.close(); + }); + + after('shutdown tor pool', async function () { + await httpServerTorPool.exit(); + }); + }); + + describe('#authenticate_user_connect(req, socket)', function () { + let httpServerTorPool; + let httpServer; + let httpPort; + + let instance_def = { + Name: 'instance-3' + }; + + before('start up server', async function (){ + httpServerTorPool = new TorPool(nconf.get('torPath'), {}, nconf.get('parentDataDirectory'), 'round_robin', null); + httpServer = new HTTPServer(httpServerTorPool, null, { deny_unidentified_users: true }); + + this.timeout(WAIT_FOR_CREATE * 3); + + await httpServerTorPool.create(2); + await httpServerTorPool.add(instance_def); + httpPort = await getPort(); + + await httpServer.listen(httpPort); + }); + + it(`should service a request for example.com through ${instance_def.Name}`, function (done) { + this.timeout(PAGE_LOAD_TIME); + let req; + httpServer.on('instance-connection', (instance, source) => { + assert.equal(instance.instance_name, instance_def.Name); + assert.isTrue(source.by_name); + req.cancel(); + done(); + }); + + req = request({ + url: 'https://example.com', + proxy: `http://${instance_def.Name}:@127.0.0.1:${httpPort}`, + }) + .catch(done); + }); + + it(`shouldn't be able to send a request without a username`, async function() { + let f = () => {}; + try { + await request({ + url: 'https://example.com', + proxy: `http://127.0.0.1:${httpPort}`, + timeout: PAGE_LOAD_TIME + }); + } catch (error) { + f = () => { throw error }; + } finally { + assert.throws(f, "socket hang up", "Did not hang up"); + } + }); + + it(`shouldn't be able to send a request with an incorrect username`, async function() { + let f = () => {}; + try { + await request({ + url: 'https://example.com', + proxy: `http://blah-blah-blah:@127.0.0.1:${httpPort}`, + timeout: PAGE_LOAD_TIME + }); + } catch (error) { + f = () => { throw error }; + } finally { + assert.throws(f, "socket hang up", "Did not hang up"); + } + }); + + after('shutdown server', function () { + httpServer.close(); + }); + + after('shutdown tor pool', async function () { + await httpServerTorPool.exit(); + }); }); }); diff --git a/test/SOCKSServer.js b/test/SOCKSServer.js index e26aff3..d04a413 100644 --- a/test/SOCKSServer.js +++ b/test/SOCKSServer.js @@ -1,7 +1,8 @@ const nconf = require('nconf'); const request = require('request-promise'); const getPort = require('get-port'); -const ProxyAgent = require('proxy-agent'); +const { HttpAgent, auth } = require('socksv5'); +const { assert } = require('chai'); const { TorPool, SOCKSServer } = require('../'); const { WAIT_FOR_CREATE, PAGE_LOAD_TIME } = require('./constants'); @@ -10,33 +11,141 @@ nconf.use('memory'); require(`${__dirname}/../src/nconf_load_env.js`)(nconf); nconf.defaults(require(`${__dirname}/../src/default_config.js`)); -let socksServerTorPool; -let socksServer; describe('SOCKSServer', function () { - socksServerTorPool = new TorPool(nconf.get('torPath'), {}, nconf.get('parentDataDirectory'), 'round_robin', null); - socksServer = new SOCKSServer(socksServerTorPool); - let socksPort; - before('start up server', async function (){ - this.timeout(WAIT_FOR_CREATE); - - await socksServerTorPool.create(1); - socksPort = await getPort(); - - await socksServer.listen(socksPort); - }); - describe('#handleConnection(socket)', function () { + let socksPort; + let socksServerTorPool; + let socksServer; + + before('start up server', async function (){ + socksServerTorPool = new TorPool(nconf.get('torPath'), {}, nconf.get('parentDataDirectory'), 'round_robin', null); + socksServer = new SOCKSServer(socksServerTorPool, null, false); + + this.timeout(WAIT_FOR_CREATE); + + await socksServerTorPool.create(1); + socksPort = await getPort(); + + await socksServer.listen(socksPort); + }); + it('should service a request for example.com', async function () { this.timeout(PAGE_LOAD_TIME); await request({ url: 'http://example.com', - agent: new ProxyAgent(`socks://127.0.0.1:${socksPort}`) + agent: new HttpAgent({ + proxyHost: '127.0.0.1', + proxyPort: socksPort, + localDNS: false, + auths: [ auth.None() ] + }) }); }); + + after('shutdown server', function () { + socksServer.close(); + }); + + after('shutdown tor pool', async function () { + socksServer.close(); + await socksServerTorPool.exit(); + }); }); - after('shutdown tor pool', async function () { - await socksServerTorPool.exit(); + describe('#authenticate_user(username, password) - proxy by name', function () { + let socksPort; + let socksServerTorPool; + let socksServer; + let instance_def = { + Name: 'instance-3' + }; + + before('start up server', async function (){ + socksServerTorPool = new TorPool(nconf.get('torPath'), {}, nconf.get('parentDataDirectory'), 'round_robin', null); + socksServer = new SOCKSServer(socksServerTorPool, null, { deny_unidentified_users: true }); + + this.timeout(WAIT_FOR_CREATE * 3); + + await socksServerTorPool.create(2); + await socksServerTorPool.add(instance_def); + + socksPort = await getPort(); + + await socksServer.listen(socksPort); + }); + + it(`should service a request for example.com through ${instance_def.Name}`, function (done) { + this.timeout(PAGE_LOAD_TIME); + + let req; + + socksServer.on('instance-connection', (instance, source) => { + assert.equal(instance.instance_name, instance_def.Name); + assert.isTrue(source.by_name); + req.cancel(); + done(); + }); + + req = request({ + url: 'http://example.com', + agent: new HttpAgent({ + proxyHost: '127.0.0.1', + proxyPort: socksPort, + localDNS: false, + auths: [ auth.UserPassword(instance_def.Name, "doesn't mater") ] + }) + }) + .catch(done); + }); + + // it(`shouldn't be able to send a request without a username`, async function() { + // let f = () => {}; + // try { + // await request({ + // url: 'http://example.com', + // agent: new HttpAgent({ + // proxyHost: '127.0.0.1', + // proxyPort: socksPort, + // localDNS: false, + // auths: [ auth.None() ] + // }), + // timeout: PAGE_LOAD_TIME + // }); + // } catch (error) { + // f = () => { throw error }; + // } finally { + // assert.throws(f); + // } + // }); + + // it(`shouldn't be able to send a request with an incorrect username`, async function() { + // let f = () => {}; + // try { + // await request({ + // url: 'http://example.com', + // agent: new HttpAgent({ + // proxyHost: '127.0.0.1', + // proxyPort: socksPort, + // localDNS: false, + // auths: [ auth.UserPassword("foo", "bar") ] + // }), + // timeout: PAGE_LOAD_TIME + // }); + // } catch (error) { + // f = () => { throw error }; + // } finally { + // assert.throws(f); + // } + // }); + + after('shutdown server', function () { + socksServer.close(); + }); + + after('shutdown tor pool', async function () { + await socksServerTorPool.exit(); + }); }); + }); \ No newline at end of file diff --git a/test/TorPool.js b/test/TorPool.js index e7d5e8e..41860a5 100644 --- a/test/TorPool.js +++ b/test/TorPool.js @@ -1,5 +1,5 @@ const nconf = require('nconf'); -const assert = require('chai').assert; +const { assert } = require('chai'); const Promise = require('bluebird'); const _ = require('lodash'); diff --git a/test/TorProcess.js b/test/TorProcess.js index 3e43e35..a5d2cb3 100644 --- a/test/TorProcess.js +++ b/test/TorProcess.js @@ -1,5 +1,5 @@ const nconf = require('nconf'); -const assert = require('chai').assert; +const { assert } = require('chai'); const { TorProcess } = require('../'); const { WAIT_FOR_CREATE } = require('./constants');