From 3d38f21281237e9cccbba26afc1ab641947c5dc0 Mon Sep 17 00:00:00 2001 From: ArtemBaskal Date: Wed, 27 May 2020 17:09:08 +0300 Subject: [PATCH] Add ipv6 cidr support --- client/package-lock.json | 3 +-- client/package.json | 1 + client/src/helpers/helpers.js | 48 +++++++++++++++++++++-------------- 3 files changed, 31 insertions(+), 21 deletions(-) diff --git a/client/package-lock.json b/client/package-lock.json index fe5e2b15aee..080ffad63ea 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -6350,8 +6350,7 @@ "ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "dev": true + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" }, "is-absolute-url": { "version": "3.0.3", diff --git a/client/package.json b/client/package.json index e59d72db517..7dea31a1dad 100644 --- a/client/package.json +++ b/client/package.json @@ -15,6 +15,7 @@ "date-fns": "^1.29.0", "i18next": "^19.4.4", "i18next-browser-languagedetector": "^4.2.0", + "ipaddr.js": "^1.9.1", "lodash": "^4.17.15", "nanoid": "^3.1.9", "prop-types": "^15.7.2", diff --git a/client/src/helpers/helpers.js b/client/src/helpers/helpers.js index e6bcc12c6f1..0fdaf9ba78b 100644 --- a/client/src/helpers/helpers.js +++ b/client/src/helpers/helpers.js @@ -11,6 +11,7 @@ import round from 'lodash/round'; import axios from 'axios'; import i18n from 'i18next'; import uniqBy from 'lodash/uniqBy'; +import ipaddr from 'ipaddr.js'; import versionCompare from './versionCompare'; import { @@ -494,22 +495,27 @@ export const normalizeMultiline = (multiline) => `${normalizeTextarea(multiline) .map((line) => line.trim()) .join('\n')}\n`; -/** - * @param ip {string} - * @returns {number} - */ -export const ipToInt = (ip) => ip.split('.') - .reduce((int, oct) => (int << 8) + parseInt(oct, 10), 0) >>> 0; /** - * @param cidr {string} * @param ip {string} + * @param cidr {string} * @returns {boolean} */ -export const isIpInCidr = (cidr, ip) => { - const [range, bits = 32] = cidr.split('/'); - const mask = ~((2 ** (32 - bits)) - 1); - return (ipToInt(ip) & mask) === (ipToInt(range) & mask); +export const isIpInCidr = (ip, cidr) => { + try { + const [cidrIp] = cidr.split('/'); + const cidrIpVersion = ipaddr.parse(cidrIp) + .kind(); + + const parsedIp = ipaddr.parse(ip); + const ipVersion = parsedIp.kind(); + + const parsedCidr = ipaddr.parseCIDR(cidr); + + return ipVersion === cidrIpVersion && parsedIp.match(parsedCidr); + } catch (e) { + return false; + } }; /** @@ -518,15 +524,19 @@ export const isIpInCidr = (cidr, ip) => { * @returns {boolean | 'CIDR' | 'IP'} */ export const isClientInIpsOrCidrs = (rawClients, currentClient) => rawClients.split('\n') - .reduce((acc, curr) => { - if (acc) { - return acc; - } - if (curr.includes('/') && isIpInCidr(curr, currentClient)) { - return BLOCKED_CLIENT.CIDR; + .reduce((isClientInList, rawClient) => { + if (isClientInList) { + return isClientInList; } - if (curr === currentClient) { + + if (rawClient === currentClient) { return BLOCKED_CLIENT.IP; } + + if (rawClient.includes('/') && isIpInCidr(currentClient, rawClient)) { + return BLOCKED_CLIENT.CIDR; + } + return false; - }, false); + }, + false);