diff --git a/app/Helpers/network_helper.php b/app/Helpers/network_helper.php index a24567229..b50089179 100644 --- a/app/Helpers/network_helper.php +++ b/app/Helpers/network_helper.php @@ -372,6 +372,78 @@ function ip_address_to_db($ip = '') } } +if (! function_exists('subnet_validate')) { + # pass this function the $subnet string and it will check it is valid + function subnet_validate($subnet) + { + $error = new \stdClass(); + $error->level = 'error'; + $error->message = ''; + + if (!preg_match('/^[\d,\.,\/,-]*$/', $subnet)) { + $error->message = 'Invalid Subnet. Received (' . $subnet . ').'; + log_message('error', $error->message); + $GLOBALS['stash'] = $error; + return ''; + } + + if (strpos($subnet, '/') !== false and strpos($subnet, '-') !== false) { + // We cannot have both a range AND a slash + $error->message = 'A subnet cannot contain / and -. Received (' . $subnet . ').'; + log_message('error', $error->message); + $GLOBALS['stash'] = $error; + return ''; + } + + if (substr_count($subnet, '.') !== 3) { + // We MUST have four octets (3x .) + $error->message = 'Subnet must contain four octets. Received (' . $subnet . ').'; + log_message('error', $error->message); + $GLOBALS['stash'] = $error; + return ''; + } + + $net = explode('/', $subnet); + if (!empty($net[1])) { + // Validate the subnet mask + if ($net[1] < 1 or $net[1] > 32) { + $error->message = 'Subnet mask must be between 1 and 32. Received (' . $subnet . ').'; + log_message('error', $error->message); + $GLOBALS['stash'] = $error; + return ''; + } + } + + $temp = explode('.', $net[0]); + for ($i=0; $i < count($temp); $i++) { + if (strpos($temp[$i], '-') !== false) { + $temp2 = explode('-', $temp[$i]); + if ($temp2[0] < 0 or $temp2[0] > 255) { + $error->message = "Subnet octet " . ($i+1) . " has a value of " . $temp[$i] . ' and is out of bounds. Received (' . $subnet . ').'; + log_message('error', $error->message); + $GLOBALS['stash'] = $error; + return ''; + } + if ($temp2[1] < 0 or $temp2[1] > 255) { + $error->message = "Subnet octet " . ($i+1) . " has a value of " . $temp[$i] . ' and is out of bounds. Received (' . $subnet . ').'; + log_message('error', $error->message); + $GLOBALS['stash'] = $error; + return ''; + } + } + if (strpos($temp[$i], '-') === false) { + if ($temp[$i] < 0 or $temp[$i] > 255) { + $error->message = "Subnet octet " . ($i+1) . " has a value of " . $temp[$i] . ' and is out of bounds. Received (' . $subnet . ').'; + log_message('error', $error->message); + $GLOBALS['stash'] = $error; + return ''; + } + } + } + return $subnet; + } +} + if (! function_exists('dns_validate')) { # pass this function the $details object and it will check hostname, domain and fqdn # we need an ip or a hostname and a working DNS to get all details diff --git a/app/Models/DiscoveriesModel.php b/app/Models/DiscoveriesModel.php index 99d524abe..abd18a855 100644 --- a/app/Models/DiscoveriesModel.php +++ b/app/Models/DiscoveriesModel.php @@ -91,14 +91,16 @@ public function create($data = null): ?int if (isset($data->device_id)) { $data->device_id = intval($data->device_id); } - if (! empty($data->discard)) { + if (!empty($data->discard)) { if ($data->discard !== 'n' && $data->discard !== 'y') { unset($data->discard); } } - if (! empty($data->subnet)) { - if (! preg_match('/^[\d,\.,\/,-]*$/', $data->subnet)) { - $data->subnet = ''; + if (!empty($data->subnet)) { + $data->subnet = subnet_validate($data->subnet); + if (empty($data->subnet)) { + \Config\Services::session()->setFlashdata('error', 'Discovery not created. ' . $GLOBALS['stash']->message); + return null; } } if (empty($data->match_options)) { @@ -294,10 +296,15 @@ public function create($data = null): ?int log_message('error', 'Missing or invalid field: seed_ip'); return null; } - if (empty($data->seed_restrict_to_subnet)) { + if (empty($data->subnet)) { + \Config\Services::session()->setFlashdata('error', 'Missing or invalid subnet provided to Discoveries::Create.'); + log_message('error', 'Missing or invalid subnet provided to Discoveries::create.'); + return null; + } + if (empty($data->seed_restrict_to_subnet) or $data->seed_restrict_to_subnet !== 'n') { $data->seed_restrict_to_subnet = 'y'; } - if (empty($data->seed_restrict_to_private)) { + if (empty($data->seed_restrict_to_private) or $data->seed_restrict_to_subnet !== 'n') { $data->seed_restrict_to_private = 'y'; } } else if ($data->type === 'cloud') { @@ -1045,20 +1052,18 @@ public function update($id = null, $data = null): bool $error->level = 'error'; $error->message = ''; - if (!empty($data->subnet)) { - if (!preg_match('/^[\d,\.,\/,-]*$/', $data->subnet)) { - $error->message = 'Discovery could not be updated - invalid Subnet supplied (' . $data->subnet . ').'; - log_message('error', $error->message); - $GLOBALS['stash'] = $error; + $temp = $data->subnet; + $data->subnet = subnet_validate($data->subnet); + if (empty($data->subnet)) { + # \Config\Services::session()->setFlashdata('error', 'Discovery not updated. ' . $GLOBALS['stash']->message); return false; - } else { - $data->description = 'Subnet - ' . $data->subnet; } + # $data->description = 'Subnet - ' . $data->subnet; } if (isset($data->ad_domain) and $data->ad_domain !== '') { - $data->description = 'Active Directory - ' . $data->ad_domain; + # $data->description = 'Active Directory - ' . $data->ad_domain; } if (isset($data->ad_server)) { diff --git a/app/Views/discoveriesCreateform.php b/app/Views/discoveriesCreateform.php index 9db574e57..df9fba353 100644 --- a/app/Views/discoveriesCreateform.php +++ b/app/Views/discoveriesCreateform.php @@ -30,6 +30,10 @@ +
+ attributes->create) ?> +
+ -
- attributes->create) ?> -
- - product === 'enterprise' or $config->product === 'professional') { @@ -153,7 +152,7 @@ } else if ($type == "seed") { $("#ad").css("display", "none"); $("#seed").css("display", "block"); - $("#subnet").css("display", "none"); + $("#subnet").css("display", "block"); } }); diff --git a/app/Views/discoveriesRead.php b/app/Views/discoveriesRead.php index 3cc3b29c6..3d045ad6f 100644 --- a/app/Views/discoveriesRead.php +++ b/app/Views/discoveriesRead.php @@ -129,7 +129,17 @@ org_id, $dictionary->columns->org_id, $update, __('Organisation'), $orgs) ?> description, $dictionary->columns->description, $update) ?> type, $dictionary->columns->type) ?> - subnet, $dictionary->columns->subnet, $update) ?> + type === 'subnet' or $resource->type === 'seed') { ?> + subnet, $dictionary->columns->subnet, $update) ?> + + type === 'seed') { ?> + seed_restrict_to_subnet, $dictionary->columns->seed_restrict_to_subnet, $update, __('Restrict to Subnet'), []) ?> + seed_restrict_to_private, $dictionary->columns->seed_restrict_to_private, $update, __('Restrict to Private'), []) ?> + + type === 'active directory') { ?> + ad_domain, $dictionary->columns->ad_domain, $update) ?> + ad_server, $dictionary->columns->ad_server, $update) ?> + devices_assigned_to_org, $dictionary->columns->devices_assigned_to_org, $update, __('Assign Devices to Organisation'), $orgs) ?> devices_assigned_to_location, $dictionary->columns->devices_assigned_to_location, $update, __('Assign Devices to Location'), $included['locations']) ?> edited_by, $dictionary->columns->edited_by, false) ?> diff --git a/public/js/open-audit.js b/public/js/open-audit.js index 609ca23a3..ffe715d0c 100644 --- a/public/js/open-audit.js +++ b/public/js/open-audit.js @@ -155,7 +155,6 @@ $(document).ready(function () { return new bootstrap.Toast(toastEl) }); toastList.forEach(toast => toast.show()); - console.log(data); $("#"+attribute).val($("#"+attribute).attr("data-original-value")); } @@ -163,7 +162,6 @@ $(document).ready(function () { attribute = attribute.replace(/\|/g, '\\|'); /* for scan_options.open|filtered */ attribute = attribute.replace(/\[/g, '\\['); /* for tasks.minute[] */ attribute = attribute.replace(/\]/g, '\\]'); /* for tasks.minute[] */ - $("#" + attribute.replace(/\./g, '\\.')).attr("data-original-value", value); $("#" + attribute.replace(/\./g, '\\.')).attr("disabled", true); $(".edit[data-attribute='" + attribute.replace(/\./g, '\\.') + "']").show(); $(".submit[data-attribute='" + attribute.replace(/\./g, '\\.') + "']").hide();