diff --git a/server/package-lock.json b/server/package-lock.json
index a34f914..91f4ab7 100755
--- a/server/package-lock.json
+++ b/server/package-lock.json
@@ -20,6 +20,7 @@
"date-fns": "^2.16.1",
"dotenv": "^8.2.0",
"graphql": "^14.6.0",
+ "ip": "^1.1.5",
"jsonwebtoken": "^8.5.1",
"ldapjs": "^2.2.1",
"node-cron": "^2.0.3",
@@ -5857,6 +5858,11 @@
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
"integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw=="
},
+ "node_modules/ip": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz",
+ "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo="
+ },
"node_modules/ipaddr.js": {
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
@@ -13822,6 +13828,11 @@
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
"integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw=="
},
+ "ip": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz",
+ "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo="
+ },
"ipaddr.js": {
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
diff --git a/server/package.json b/server/package.json
index 3e24b7d..b6635df 100755
--- a/server/package.json
+++ b/server/package.json
@@ -46,6 +46,7 @@
"date-fns": "^2.16.1",
"dotenv": "^8.2.0",
"graphql": "^14.6.0",
+ "ip": "^1.1.5",
"jsonwebtoken": "^8.5.1",
"ldapjs": "^2.2.1",
"node-cron": "^2.0.3",
diff --git a/server/prisma/migrations/20210114134149_add_panos/migration.sql b/server/prisma/migrations/20210114134149_add_panos/migration.sql
index 9c50585..3cb7636 100644
--- a/server/prisma/migrations/20210114134149_add_panos/migration.sql
+++ b/server/prisma/migrations/20210114134149_add_panos/migration.sql
@@ -1,8 +1,8 @@
-- CreateTable
-CREATE TABLE "PanOS" (
+CREATE TABLE "PAHost" (
"id" SERIAL,
+ "cidr" TEXT NOT NULL,
"description" TEXT NOT NULL,
- "ip" TEXT NOT NULL,
"encryptedKey" TEXT NOT NULL,
"note" TEXT,
"user" TEXT NOT NULL,
diff --git a/server/prisma/schema.prisma b/server/prisma/schema.prisma
index 1cd36a3..c47719d 100644
--- a/server/prisma/schema.prisma
+++ b/server/prisma/schema.prisma
@@ -123,11 +123,11 @@ model Statistic {
onlineWifiDevices Int
}
-model PanOS {
+model PAHost {
id Int @id @default(autoincrement())
user String
description String
- ip String @unique
+ cidr String @unique
encryptedKey String
note String?
createdAt DateTime @default(now())
diff --git a/server/src/lib/paloalto.js b/server/src/lib/paloalto.js
index c9f3c22..b69d13f 100644
--- a/server/src/lib/paloalto.js
+++ b/server/src/lib/paloalto.js
@@ -1,14 +1,18 @@
// Ref.: https://docs.paloaltonetworks.com/pan-os/9-1/pan-os-panorama-api/pan-os-xml-api-request-types/apply-user-id-mapping-and-populate-dynamic-address-groups-api.html
import axios from 'axios'
-import prisma from '../prisma'
import https from 'https'
-import { subMinutes } from 'date-fns'
+import { isIPv4 } from 'net'
import qs from 'qs'
+import { add, subMinutes } from 'date-fns'
import { logError, logSuccess } from './logger'
import { AES, enc } from 'crypto-js'
+import ip from 'ip'
+
+import prisma from '../prisma'
const TIMEOUT_IN_MINUTES = '3'
+const CIDR_RE = /^([0-9]{1,3}\.){3}[0-9]{1,3}(\/([0-9]|[1-2][0-9]|3[0-2]))?$/
const httpsAgent = new https.Agent({
rejectUnauthorized: false
@@ -92,49 +96,67 @@ async function updateUserIdMappings() {
}
}
-async function getUserKey({ ip, user, password }) {
- const result = await axios({
- url: `https://${ip}/api/`,
- method: 'POST',
- params: { type: 'keygen', user, password },
- httpsAgent
- })
+async function getUserKey({ ipAddr, user, password }) {
+ try {
+ const result = await axios({
+ url: `https://${ipAddr}/api/`,
+ method: 'POST',
+ params: { type: 'keygen', user, password },
+ httpsAgent
+ })
- return result.data.split('')[1].split('')[0]
+ return result.data.split('')[1].split('')[0]
+ } catch (e) {
+ throw new Error(e.message)
+ }
}
-async function addHost({ ip, user, password, description, note }) {
+function encryptKey(key) {
+ return AES.encrypt(key, process.env.CRYPT_SECRET).toString()
+}
+
+function decryptKey(encryptedKey) {
+ return AES.decrypt(encryptedKey, process.env.CRYPT_SECRET).toString(enc.Utf8)
+}
+
+async function addHost({ cidr, user, password, description, note }) {
try {
- const key = await getUserKey({ ip, user, password })
+ if (!CIDR_RE.test(cidr)) throw new Error('Este não é um CIDR válido')
- const encryptedKey = AES.encrypt(key, process.env.CRYPT_SECRET).toString()
+ const ipAddr = cidr.split('/')[0]
- // const decryptedKey = AES.decrypt(
- // encryptedKey,
- // process.env.CRYPT_SECRET
- // ).toString(enc.Utf8)
+ if (!isIPv4(ipAddr)) throw new Error('Este não é um IPv4 válido')
- const host = await prisma.panOS.create({
- data: {
- ip,
- encryptedKey,
- user,
- description,
- note
- }
+ const net = ip.cidrSubnet(cidr)
+
+ if (net.subnetMaskLength > 32 || net.networkAddress == '0.0.0.0')
+ throw new Error('Esta não é uma combinação de IP/máscara IPv4 válida')
+
+ const key = await getUserKey({ ipAddr, user, password })
+
+ const encryptedKey = encryptKey(key)
+
+ const pAHost = {
+ cidr,
+ encryptedKey,
+ user,
+ description,
+ note
+ }
+
+ const host = await prisma.pAHost.upsert({
+ where: { cidr: cidr },
+ create: pAHost,
+ update: pAHost
})
return {
...host,
- key: `${key.slice(
- 0,
- 8
- )}************************************************************************************************`
+ key: `${key.slice(0, 5)}`
}
} catch (e) {
logError({
- message: `Não foi possível adicionar o host ${ip}.`,
- data: e.message,
+ message: `Não foi possível adicionar o host ${cidr}. ${e?.message}`,
tags: ['paloalto']
})
throw new Error(e.message)
diff --git a/server/src/resolvers/Mutation/index.js b/server/src/resolvers/Mutation/index.js
index 6d12197..8356555 100644
--- a/server/src/resolvers/Mutation/index.js
+++ b/server/src/resolvers/Mutation/index.js
@@ -46,8 +46,8 @@ const Mutation = {
return updateUserIdMappings()
},
- async addPAHost(_, { data: { ip, user, password, description, note } }) {
- return addHost({ ip, user, password, description, note })
+ async addPAHost(_, { data: { cidr, user, password, description, note } }) {
+ return addHost({ cidr, user, password, description, note })
}
}
diff --git a/server/src/typeDefs.js b/server/src/typeDefs.js
index 1f0dc82..36e50f4 100644
--- a/server/src/typeDefs.js
+++ b/server/src/typeDefs.js
@@ -260,7 +260,7 @@ const typeDefs = gql`
type PAHost {
id: ID!
description: String
- ip: String
+ cidr: String
key: String
note: String
createdAt: String
@@ -303,7 +303,7 @@ const typeDefs = gql`
}
input AddPAHostInput {
- ip: String!
+ cidr: String!
user: String!
password: String!
description: String!