helpers.js 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.ipToBuffer = exports.int32ToIpv4 = exports.ipv4ToInt32 = exports.validateSocksClientChainOptions = exports.validateSocksClientOptions = void 0;
  4. const util_1 = require("./util");
  5. const constants_1 = require("./constants");
  6. const stream = require("stream");
  7. const ip_address_1 = require("ip-address");
  8. const net = require("net");
  9. /**
  10. * Validates the provided SocksClientOptions
  11. * @param options { SocksClientOptions }
  12. * @param acceptedCommands { string[] } A list of accepted SocksProxy commands.
  13. */
  14. function validateSocksClientOptions(options, acceptedCommands = ['connect', 'bind', 'associate']) {
  15. // Check SOCKs command option.
  16. if (!constants_1.SocksCommand[options.command]) {
  17. throw new util_1.SocksClientError(constants_1.ERRORS.InvalidSocksCommand, options);
  18. }
  19. // Check SocksCommand for acceptable command.
  20. if (acceptedCommands.indexOf(options.command) === -1) {
  21. throw new util_1.SocksClientError(constants_1.ERRORS.InvalidSocksCommandForOperation, options);
  22. }
  23. // Check destination
  24. if (!isValidSocksRemoteHost(options.destination)) {
  25. throw new util_1.SocksClientError(constants_1.ERRORS.InvalidSocksClientOptionsDestination, options);
  26. }
  27. // Check SOCKS proxy to use
  28. if (!isValidSocksProxy(options.proxy)) {
  29. throw new util_1.SocksClientError(constants_1.ERRORS.InvalidSocksClientOptionsProxy, options);
  30. }
  31. // Validate custom auth (if set)
  32. validateCustomProxyAuth(options.proxy, options);
  33. // Check timeout
  34. if (options.timeout && !isValidTimeoutValue(options.timeout)) {
  35. throw new util_1.SocksClientError(constants_1.ERRORS.InvalidSocksClientOptionsTimeout, options);
  36. }
  37. // Check existing_socket (if provided)
  38. if (options.existing_socket &&
  39. !(options.existing_socket instanceof stream.Duplex)) {
  40. throw new util_1.SocksClientError(constants_1.ERRORS.InvalidSocksClientOptionsExistingSocket, options);
  41. }
  42. }
  43. exports.validateSocksClientOptions = validateSocksClientOptions;
  44. /**
  45. * Validates the SocksClientChainOptions
  46. * @param options { SocksClientChainOptions }
  47. */
  48. function validateSocksClientChainOptions(options) {
  49. // Only connect is supported when chaining.
  50. if (options.command !== 'connect') {
  51. throw new util_1.SocksClientError(constants_1.ERRORS.InvalidSocksCommandChain, options);
  52. }
  53. // Check destination
  54. if (!isValidSocksRemoteHost(options.destination)) {
  55. throw new util_1.SocksClientError(constants_1.ERRORS.InvalidSocksClientOptionsDestination, options);
  56. }
  57. // Validate proxies (length)
  58. if (!(options.proxies &&
  59. Array.isArray(options.proxies) &&
  60. options.proxies.length >= 2)) {
  61. throw new util_1.SocksClientError(constants_1.ERRORS.InvalidSocksClientOptionsProxiesLength, options);
  62. }
  63. // Validate proxies
  64. options.proxies.forEach((proxy) => {
  65. if (!isValidSocksProxy(proxy)) {
  66. throw new util_1.SocksClientError(constants_1.ERRORS.InvalidSocksClientOptionsProxy, options);
  67. }
  68. // Validate custom auth (if set)
  69. validateCustomProxyAuth(proxy, options);
  70. });
  71. // Check timeout
  72. if (options.timeout && !isValidTimeoutValue(options.timeout)) {
  73. throw new util_1.SocksClientError(constants_1.ERRORS.InvalidSocksClientOptionsTimeout, options);
  74. }
  75. }
  76. exports.validateSocksClientChainOptions = validateSocksClientChainOptions;
  77. function validateCustomProxyAuth(proxy, options) {
  78. if (proxy.custom_auth_method !== undefined) {
  79. // Invalid auth method range
  80. if (proxy.custom_auth_method < constants_1.SOCKS5_CUSTOM_AUTH_START ||
  81. proxy.custom_auth_method > constants_1.SOCKS5_CUSTOM_AUTH_END) {
  82. throw new util_1.SocksClientError(constants_1.ERRORS.InvalidSocksClientOptionsCustomAuthRange, options);
  83. }
  84. // Missing custom_auth_request_handler
  85. if (proxy.custom_auth_request_handler === undefined ||
  86. typeof proxy.custom_auth_request_handler !== 'function') {
  87. throw new util_1.SocksClientError(constants_1.ERRORS.InvalidSocksClientOptionsCustomAuthOptions, options);
  88. }
  89. // Missing custom_auth_response_size
  90. if (proxy.custom_auth_response_size === undefined) {
  91. throw new util_1.SocksClientError(constants_1.ERRORS.InvalidSocksClientOptionsCustomAuthOptions, options);
  92. }
  93. // Missing/invalid custom_auth_response_handler
  94. if (proxy.custom_auth_response_handler === undefined ||
  95. typeof proxy.custom_auth_response_handler !== 'function') {
  96. throw new util_1.SocksClientError(constants_1.ERRORS.InvalidSocksClientOptionsCustomAuthOptions, options);
  97. }
  98. }
  99. }
  100. /**
  101. * Validates a SocksRemoteHost
  102. * @param remoteHost { SocksRemoteHost }
  103. */
  104. function isValidSocksRemoteHost(remoteHost) {
  105. return (remoteHost &&
  106. typeof remoteHost.host === 'string' &&
  107. typeof remoteHost.port === 'number' &&
  108. remoteHost.port >= 0 &&
  109. remoteHost.port <= 65535);
  110. }
  111. /**
  112. * Validates a SocksProxy
  113. * @param proxy { SocksProxy }
  114. */
  115. function isValidSocksProxy(proxy) {
  116. return (proxy &&
  117. (typeof proxy.host === 'string' || typeof proxy.ipaddress === 'string') &&
  118. typeof proxy.port === 'number' &&
  119. proxy.port >= 0 &&
  120. proxy.port <= 65535 &&
  121. (proxy.type === 4 || proxy.type === 5));
  122. }
  123. /**
  124. * Validates a timeout value.
  125. * @param value { Number }
  126. */
  127. function isValidTimeoutValue(value) {
  128. return typeof value === 'number' && value > 0;
  129. }
  130. function ipv4ToInt32(ip) {
  131. const address = new ip_address_1.Address4(ip);
  132. // Convert the IPv4 address parts to an integer
  133. return address.toArray().reduce((acc, part) => (acc << 8) + part, 0);
  134. }
  135. exports.ipv4ToInt32 = ipv4ToInt32;
  136. function int32ToIpv4(int32) {
  137. // Extract each byte (octet) from the 32-bit integer
  138. const octet1 = (int32 >>> 24) & 0xff;
  139. const octet2 = (int32 >>> 16) & 0xff;
  140. const octet3 = (int32 >>> 8) & 0xff;
  141. const octet4 = int32 & 0xff;
  142. // Combine the octets into a string in IPv4 format
  143. return [octet1, octet2, octet3, octet4].join('.');
  144. }
  145. exports.int32ToIpv4 = int32ToIpv4;
  146. function ipToBuffer(ip) {
  147. if (net.isIPv4(ip)) {
  148. // Handle IPv4 addresses
  149. const address = new ip_address_1.Address4(ip);
  150. return Buffer.from(address.toArray());
  151. }
  152. else if (net.isIPv6(ip)) {
  153. // Handle IPv6 addresses
  154. const address = new ip_address_1.Address6(ip);
  155. return Buffer.from(address.toByteArray());
  156. }
  157. else {
  158. throw new Error('Invalid IP address format');
  159. }
  160. }
  161. exports.ipToBuffer = ipToBuffer;
  162. //# sourceMappingURL=helpers.js.map