From f23c2df07c78e94d693c074f1583b1fa71dc755a Mon Sep 17 00:00:00 2001 From: Mark Unwin Date: Thu, 23 Nov 2023 08:10:28 +1000 Subject: [PATCH 01/43] Initial commit for Agents. --- app/Config/Agents.php | 34 ++ app/Config/OpenAudit.php | 2 +- app/Config/Routes.php | 4 +- app/Helpers/response_helper.php | 2 +- app/Helpers/utility_helper.php | 23 +- app/Models/AgentsModel.php | 807 ++++++++++++++++++++++++++++++++ app/Views/agentsCollection.php | 72 +++ app/Views/agentsCreateform.php | 290 ++++++++++++ app/Views/agentsRead.php | 510 ++++++++++++++++++++ app/Views/lang/en.inc | 69 +-- app/Views/rolesCreateform.php | 2 +- app/Views/rolesRead.php | 2 +- app/Views/rulesRead.php | 1 + app/Views/shared/header.php | 7 + other/open-audit.sql | 2 +- 15 files changed, 1788 insertions(+), 39 deletions(-) create mode 100644 app/Config/Agents.php create mode 100644 app/Models/AgentsModel.php create mode 100644 app/Views/agentsCollection.php create mode 100644 app/Views/agentsCreateform.php create mode 100644 app/Views/agentsRead.php diff --git a/app/Config/Agents.php b/app/Config/Agents.php new file mode 100644 index 000000000..6fc2506e6 --- /dev/null +++ b/app/Config/Agents.php @@ -0,0 +1,34 @@ + + * @copyright 2023 FirstWave + * @license http://www.gnu.org/licenses/agpl-3.0.html aGPL v3 + * @version GIT: Open-AudIT_5.0.0 + * @link http://www.open-audit.org + */ + +/** + * Base Object Agents + * + * @access public + * @category Object + * @package Open-AudIT\Controller\Agents + * @author Mark Unwin + * @license http://www.gnu.org/licenses/agpl-3.0.html aGPL v3 + * @link http://www.open-audit.org + */ +class Agents extends BaseController +{ + +} diff --git a/app/Config/OpenAudit.php b/app/Config/OpenAudit.php index 3d84870bf..b43670079 100755 --- a/app/Config/OpenAudit.php +++ b/app/Config/OpenAudit.php @@ -183,7 +183,7 @@ public function __construct() $modules[] = (object)array("name" => "opEvents", "url" => (in_array('opEvents', $apps)) ? "/omk/opEvents/" : "https://firstwave.com/opevents-traps-network-event-management/"); $modules[] = (object)array("name" => "opConfig", "url" => (in_array('opConfig', $apps)) ? "/omk/opConfig" : "https://firstwave.com/products/network-configuration-management/"); $modules[] = (object)array("name" => "opHA", "url" => (in_array('opHA', $apps)) ? "/omk/opHA" : "https://firstwave.com/products/distributed-network-management/"); - $modules[] = (object)array("name" => "opReports", "url" => (in_array('opReports', $apps)) ? "/omk/opReports/" : "https => //firstwave.com/products/advanced-analysis-and-reporting/"); + $modules[] = (object)array("name" => "opReports", "url" => (in_array('opReports', $apps)) ? "/omk/opReports/" : "https://firstwave.com/products/advanced-analysis-and-reporting/"); $modules[] = (object)array("name" => "opAddress", "url" => (in_array('opAddress', $apps)) ? "/omk/opAddress/" : "https://firstwave.com/products/ip-address-audit-and-management/"); $modules[] = (object)array("name" => "opLicensing", "url" => (file_exists($opLicense)) ? "/omk/opLicense" : ""); $modules[] = (object)array("name" => "NMIS", "url" => (file_exists($nmis . '/cgi-bin/nmiscgi.pl')) ? "/cgi-nmis9/nmiscgi.pl" : "https://firstwave.com/products/network-management-information-system/"); diff --git a/app/Config/Routes.php b/app/Config/Routes.php index 938773fe7..cd5581110 100755 --- a/app/Config/Routes.php +++ b/app/Config/Routes.php @@ -14,7 +14,7 @@ * -------------------------------------------------------------------- */ -$collections = array('applications','attributes','baselines','baselines_policies','baselines_results','clouds','clusters','collectors', 'components', +$collections = array('agents','applications','attributes','baselines','baselines_policies','baselines_results','clouds','clusters','collectors', 'components', 'configuration','connections','credentials','dashboards','devices','discoveries','discovery_log','discovery_scan_options','errors','fields','files', 'groups','integrations','ldap_servers','licenses','locations','maps','networks','nmis','orgs','queries','queue','racks','rack_devices','reports','roles', 'rules','scripts','summaries','support','tasks','users','widgets'); @@ -24,6 +24,8 @@ # These will match and then take precedence over the below route array +$routes->post('agents/execute', 'Agents::execute', ['as' => 'agentsExecuteAll']); + $routes->get('baselines/(:num)/execute', 'Baselines::executeForm/$1', ['filter' => \App\Filters\Session::class, 'as' => 'baselinesExecuteForm']); $routes->post('baselines/(:num)/execute', 'Baselines::execute/$1', ['filter' => \App\Filters\Session::class, 'as' => 'baselinesExecute']); diff --git a/app/Helpers/response_helper.php b/app/Helpers/response_helper.php index 6faf2cc73..292e7d7b1 100644 --- a/app/Helpers/response_helper.php +++ b/app/Helpers/response_helper.php @@ -1499,7 +1499,7 @@ function response_valid_actions() */ function response_valid_collections() { - return array('applications','attributes','baselines','baselines_policies','baselines_results','chart','clouds','clusters','collectors','components','configuration','connections','credentials','dashboards','database','devices','discoveries','discovery_log','discovery_scan_options','errors','fields','files','groups','help','integrations','integrations_log','integrations_rules','ldap_servers','licenses','locations','logs','maps','networks','nmis','orgs','queries','queue','racks','rack_devices','reports','roles','rules','scripts','search','sessions','summaries','support','tasks','users','widgets'); + return array('agents','applications','attributes','baselines','baselines_policies','baselines_results','chart','clouds','clusters','collectors','components','configuration','connections','credentials','dashboards','database','devices','discoveries','discovery_log','discovery_scan_options','errors','fields','files','groups','help','integrations','integrations_log','integrations_rules','ldap_servers','licenses','locations','logs','maps','networks','nmis','orgs','queries','queue','racks','rack_devices','reports','roles','rules','scripts','search','sessions','summaries','support','tasks','users','widgets'); } } diff --git a/app/Helpers/utility_helper.php b/app/Helpers/utility_helper.php index 4930113e4..54b82b5ac 100644 --- a/app/Helpers/utility_helper.php +++ b/app/Helpers/utility_helper.php @@ -233,6 +233,17 @@ function format_data($result, $type) } } + if ($type === 'agents') { + foreach ($result as $item) { + if (!empty($item->inputs)) { + $item->inputs = json_decode($item->inputs); + } + if (!empty($item->outputs)) { + $item->outputs = json_decode($item->outputs); + } + } + } + if ($type === 'baselines_policies') { foreach ($result as $item) { if (!empty($item->tests)) { @@ -439,8 +450,18 @@ function collections_list() { $collections = new \stdClass(); - $collections->applications = new \StdClass(); # FIX ME + $collections->agents = new \StdClass(); + $collections->agents->icon = 'fa fa-th-list'; + $collections->agents->name = 'Agents'; + $collections->agents->edition = 'Enterprise'; + $collections->agents->orgs = 'd'; + $collections->agents->actions = new \stdClass(); + $collections->agents->actions->enterprise = 'crud'; + $collections->agents->actions->professional = 'r'; + $collections->agents->actions->community = ''; + + $collections->applications = new \StdClass(); $collections->applications->icon = 'fa fa-th-list'; $collections->applications->name = 'Applications'; $collections->applications->edition = 'Enterprise'; diff --git a/app/Models/AgentsModel.php b/app/Models/AgentsModel.php new file mode 100644 index 000000000..37badc0cf --- /dev/null +++ b/app/Models/AgentsModel.php @@ -0,0 +1,807 @@ +db = db_connect(); + $this->builder = $this->db->table('agents'); + # Use the below to execute BaseModel::__construct + # parent::__construct(); + } + + /** + * Read the collection from the database + * + * @param $resp object An object containing the properties, filter, sort and limit as passed by the user + * + * @return array An array of formatted entries + */ + public function collection(object $resp): array + { + $properties = $resp->meta->properties; + $properties[] = "orgs.name as `orgs.name`"; + $properties[] = "orgs.id as `orgs.id`"; + $this->builder->select($properties, false); + $this->builder->join('orgs', $resp->meta->collection . '.org_id = orgs.id', 'left'); + foreach ($resp->meta->filter as $filter) { + if (in_array($filter->operator, ['!=', '>=', '<=', '=', '>', '<'])) { + $this->builder->{$filter->function}($filter->name . ' ' . $filter->operator, $filter->value); + } else { + $this->builder->{$filter->function}($filter->name, $filter->value); + } + } + $this->builder->orderBy($resp->meta->sort); + $this->builder->limit($resp->meta->limit, $resp->meta->offset); + $query = $this->builder->get(); + if ($this->sqlError($this->db->error())) { + return array(); + } + return format_data($query->getResult(), $resp->meta->collection); + } + + /** + * Create an individual item in the database + * + * @param object $data The data attributes + * + * @return int|false The Integer ID of the newly created item, or false + */ + public function create($data = null): ?int + { + if (empty($data)) { + return null; + } + if (is_array($data->inputs) or is_object($data->inputs)) { + $new_inputs = array(); + foreach ($data->inputs as $input) { + $item = new \stdClass(); + foreach ($input as $key => $value) { + $item->{$key} = $value; + } + $new_inputs[] = $item; + } + $data->inputs = json_encode($new_inputs); + } + + if (is_array($data->outputs) or is_object($data->outputs)) { + $new_outputs = array(); + foreach ($data->outputs as $output) { + $item = new \stdClass(); + foreach ($output as $key => $value) { + $item->{$key} = $value; + } + $new_outputs[] = $item; + } + $data->outputs = json_encode($new_outputs); + } + $data = $this->createFieldData('agents', $data); + if (empty($data)) { + return null; + } + $this->builder->insert($data); + if ($error = $this->sqlError($this->db->error())) { + \Config\Services::session()->setFlashdata('error', json_encode($error)); + return null; + } + return (intval($this->db->insertID())); + } + + /** + * Delete an individual item from the database, by ID + * + * @param int $id The ID of the requested item + * + * @return bool true || false depending on success + */ + public function delete($id = null, bool $purge = false): bool + { + $this->builder->delete(['id' => intval($id)]); + if ($this->sqlError($this->db->error())) { + return false; + } + if ($this->db->affectedRows() !== 1) { + return false; + } + return true; + } + + /** + * [execute description] + * @param [type] $parameters MUST contain either a device ID or a device object, SHOULD contain an action, default is to update, SHOULD contain a discovery ID for logging + * @return [type] [description] + */ + public function execute(object $device = null, int $discovery_id = 0, string $action = 'update', int $id = 0) + { + log_message('debug', 'RulesExecute called.'); + $item_start = microtime(true); + helper('macaddress'); + + if (empty($id) && empty($device)) { + log_message('error', 'RulesExecute called, but no device object or id passed.'); + return; + } + + $instance = & get_instance(); + + helper('snmp_model'); + helper('mac_model'); + $discoveryLogModel = new \App\Models\DiscoveryLogModel(); + + $log = new \stdClass(); + $log->message = 'Running rules::execute function.'; + $log->severity = 7; + $log->command_status = 'notice'; + $log->file = 'm_rules'; + $log->function = 'execute'; + $log->command = 'Device Update '; + + $device_sub = array(); + if (!empty($device)) { + $device->where = 'supplied'; + $log->command_output = json_encode($device); + $log->command = 'Device Input '; + } + $log->command .= "($action)."; + + if (!empty($id)) { + // Get our device + $log->command_output = "Device ID supplied: {$id}"; + $log->command = 'Device ID Input '; + $sql = 'SELECT * FROM `devices` WHERE id = ?'; + $result = $this->db->query($sql, [$id])->getResult(); + if (!empty($result[0])) { + $device = $result[0]; + $device->where = 'database'; + // NOTE - Some of these are in the database and default to 0. Empty these. + if ($device->snmp_enterprise_id === 0) { + $device->snmp_enterprise_id = ''; + } + if ($device->os_bit === 0) { + $device->os_bit = ''; + } + if ($device->memory_count === 0) { + $device->memory_count = ''; + } + if ($device->processor_count === 0) { + $device->processor_count = ''; + } + if ($device->storage_count === 0) { + $device->storage_count = ''; + } + if ($device->switch_port === 0) { + $device->switch_port = ''; + } + $device->discovery_id = ''; + } else { + log_message('error', "Could not retrieve data from devices table for ID: $id. Not running Rules function."); + $log->severity = 4; + $log->command_status = 'fail'; + $log->message = "Could not retrieve data from devices table for ID: $id. Not running Rules function."; + $discoveryLogModel->create($log); + return $device; + } + // Get the first MAC Address because there is no mac stored in 'devices' + $sql = "SELECT `mac` FROM `network` WHERE device_id = ? and current = 'y' and `mac` != '' order by `mac` limit 1"; + $result = $this->db->query($sql, [$id])->getResult(); + if (!empty($result[0])) { + $device->mac_address = $result[0]->mac; + } + } + + // Log down here because we may not have been passed a $device + $log->discovery_id = (!empty($discovery_id)) ? $discovery_id : ''; + if (empty($log->discovery_id) and !empty($device->discovery_id)) { + $log->discovery_id = $device->discovery_id; + } + $log->device_id = (!empty($device->id)) ? intval($device->id) : ''; + $log->ip = (!empty($device->ip)) ? ip_address_from_db($device->ip) : ''; + $discoveryLogModel->create($log); + + $id = (!empty($device->id)) ? $device->id : ''; + // Discovery ID for logging + if (empty($discovery_id)) { + if (!empty($device->discovery_id)) { + $discovery_id = $device->discovery_id; + } + } + + // NOTE - don't set the id or last_seen_by here as we test if empty after rules + // have been run and only update if not empty (after adding id and last_seen_by). + $newdevice = new \stdClass(); + + // Details based on SNMP OID + if (!empty($device->snmp_oid)) { + $log_start = microtime(true); + $newdevice = get_details_from_oid($device->snmp_oid); + if (!empty($newdevice->type) or !empty($newdevice->model)) { + $temp = empty($newdevice->model) ? $newdevice->type : $newdevice->model; + $log->message = "Hit on \$device->snmp_oid {$device->snmp_oid} eq {$device->snmp_oid}"; + $log->command = 'Rules Match - SNMP OID for ' . $temp; + $log->command_output = json_encode($newdevice); + $log->command_time_to_execute = (microtime(true) - $log_start); + $discoveryLogModel->create($log); + foreach ($newdevice as $key => $value) { + $device->{$key} = $value; + } + } + } + + // Manufacturer based on MAC Address + if (!empty($device->mac_address) and empty($device->manufacturer)) { + $log_start = microtime(true); + $newdevice->manufacturer = get_manufacturer_from_mac($device->mac_address); + if (!empty($newdevice->manufacturer)) { + $log->message = "Hit on \$device->mac_address {$device->mac_address} st " . substr(strtolower($device->mac_address), 0, 8); + $log->command = 'Rules Match - Mac Address for ' . $newdevice->manufacturer; + $log->command_output = json_encode($newdevice); + $log->command_time_to_execute = (microtime(true) - $log_start); + $discoveryLogModel->create($log); + $device->manufacturer = $newdevice->manufacturer; + } + } + + // Manufacturer based on SNMP Enterprise ID + if (!empty($device->snmp_enterprise_id) && empty($device->manufacturer)) { + $log_start = microtime(true); + $newdevice->manufacturer = get_manufacturer_from_oid($device->snmp_enterprise_id); + if (!empty($newdevice->manufacturer)) { + $log->message = 'Hit on $device->snmp_enterprise_id ' . $device->snmp_enterprise_id . ' eq ' . $device->snmp_enterprise_id; + $log->command = 'Rules Match - SNMP Enterprise Number for ' . $newdevice->manufacturer; + $log->command_output = json_encode($newdevice); + $log->command_time_to_execute = (microtime(true) - $log_start); + $discoveryLogModel->create($log); + $device->manufacturer = $newdevice->manufacturer; + } + } + + // Mac Description based on Manufacturer Code (derived from Serial) + if (!empty($device->manufacturer_code)) { + $log_start = microtime(true); + $newdevice->description = get_description_from_manufacturer_code($device->manufacturer_code); + if (!empty($newdevice->description)) { + $log->message .= " Hit on \$device->manufacturer_code " . $device->manufacturer_code . " eq " . $device->manufacturer_code; + $log->command = 'Rules Match - Mac Model into description'; + $log->command_output = json_encode($newdevice->description); + $log->command_time_to_execute = (microtime(true) - $log_start); + $discoveryLogModel->create($log); + $device->description = $newdevice->description; + } + } + + // TODO - Orgs + $sql = "SELECT * FROM `rules` ORDER BY weight ASC, id"; + $rules = $this->db->query($sql)->getResult(); + + $other_tables = array(); + foreach ($rules as $rule) { + $rule->inputs = json_decode($rule->inputs); + $rule->outputs = json_decode($rule->outputs); + foreach ($rule->inputs as $input) { + if (!$this->db->tableExists($input->table)) { + $l = new \stdClass(); + $l->command_status = 'error'; + $l->discovery_id = $log->discovery_id; + $l->ip = $log->ip; + $l->message = 'Rule ' . $rule->id . ' specified a table that does not exist: ' . $input->table . '.'; + $l->command = json_encode($rule); + $l->command_output = ''; + $discoveryLogModel->create($l); + continue; + } + if ($input->table !== 'devices' and !in_array($input->table, $other_tables)) { + $other_tables[] = $input->table; + } + } + } + + foreach ($other_tables as $table) { + $sql = "SELECT * FROM `{$table}` WHERE device_id = ? AND current = 'y'"; + $result = $this->db->query($sql, [$id])->getResult(); + $device_sub[$table] = $result; + } + unset($other_tables); + + // Special case the MAC as we might have it in the device entry, but not network table yet + if (!empty($device->mac_address) and empty($device_sub['network'])) { + $item = new \stdClass(); + $item->mac = $device->mac_address; + $device_sub['network'] = array($item); + } + + foreach ($rules as $rule) { + if (is_array($rule->inputs)) { + $input_count = count($rule->inputs); + } else { + // Log an error, but continue + $l = new \stdClass(); + $l->command_status = 'error'; + $l->discovery_id = $log->discovery_id; + $l->ip = $log->ip; + $l->message = 'Rule ' . $rule->id . ' inputs is not an array.'; + $l->command = $rule->inputs; + $l->command_output = ''; + $discoveryLogModel->create($l); + continue; + } + $hit = 0; + foreach ($rule->inputs as $input) { + if ($input->table === 'devices') { + switch ($input->operator) { + case 'eq': + if (isset($device->{$input->attribute}) && (string)$device->{$input->attribute} === (string)$input->value) { + if ((string)$input->value !== '') { + $log->message .= " Hit on {$input->attribute} " . $device->{$input->attribute} . ' eq ' . $input->value; + } else { + $log->message .= " Hit on {$input->attribute} is empty"; + } + $hit++; + } + break; + + case 'ne': + if (!isset($device->{$input->attribute}) or (string)$device->{$input->attribute} !== (string)$input->value) { + if ((string)$input->value !== '') { + $log->message .= " Hit on $input->attribute " . @$device->{$input->attribute} . " ne " . $input->value; + } else { + $log->message .= " Hit on $input->attribute is not empty"; + } + $hit++; + } + break; + + case 'gt': + if (isset($device->{$input->attribute}) and (string)$device->{$input->attribute} > (string)$input->value) { + $log->message .= " Hit on $input->attribute " . $device->{$input->attribute} . " gt " . $input->value; + $hit++; + } + break; + + case 'ge': + if (isset($device->{$input->attribute}) and (string)$device->{$input->attribute} >= (string)$input->value) { + $log->message .= " Hit on $input->attribute " . $device->{$input->attribute} . " ge " . $input->value; + $hit++; + } + break; + + case 'lt': + if (isset($device->{$input->attribute}) and (string)$device->{$input->attribute} < (string)$input->value) { + $log->message .= " Hit on $input->attribute " . $device->{$input->attribute} . " lt " . $input->value; + $hit++; + } + break; + + case 'le': + if (isset($device->{$input->attribute}) and (string)$device->{$input->attribute} <= (string)$input->value) { + $log->message .= " Hit on $input->attribute " . $device->{$input->attribute} . " le" . $input->value; + $hit++; + } + break; + + case 'li': + if (isset($device->{$input->attribute}) and stripos((string)$device->{$input->attribute}, $input->value) !== false) { + $log->message .= " Hit on $input->attribute " . $device->{$input->attribute} . " li " . $input->value; + $hit++; + } + break; + + case 'nl': + if (isset($device->{$input->attribute}) and stripos((string)$device->{$input->attribute}, $input->value) === false) { + $log->message .= " Hit on $input->attribute " . $device->{$input->attribute} . " nl " . $input->value; + $hit++; + } + break; + + case 'in': + $values = explode(',', $input->value); + if (isset($device->{$input->attribute}) and in_array((string)$device->{$input->attribute}, $values)) { + $log->message .= " Hit on $input->attribute " . $device->{$input->attribute} . " in " . $input->value; + $hit++; + } + break; + + case 'ni': + $values = explode(',', $input->value); + if (!isset($device->{$input->attribute}) or !in_array((string)$device->{$input->attribute}, $values)) { + $log->message .= " Hit on $input->attribute " . $device->{$input->attribute} . " ni " . $input->value; + $hit++; + } + break; + + case 'st': + if (!empty($device->{$input->attribute}) and stripos((string)$device->{$input->attribute}, $input->value) === 0) { + $log->message .= " Hit on $input->attribute " . $device->{$input->attribute} . " st " . $input->value; + $hit++; + } + break; + + case 're': + if (isset($device->{$input->attribute}) and preg_match($input->value, $device->{$input->attribute})) { + $log->message .= " Hit on $input->attribute " . $device->{$input->attribute} . " re " . $input->value; + $hit++; + } + break; + + default: + if (isset($device->{$input->attribute}) and (string)$device->{$input->attribute} === (string)$input->value) { + $log->message .= " Hit on $input->attribute " . $device->{$input->attribute} . " default " . $input->value; + $hit++; + } + break; + } + } else { + if (!empty($input->table) and !empty($device_sub[$input->table])) { + switch ($input->operator) { + case 'eq': + foreach ($device_sub[$input->table] as $dsub) { + if ((string)$dsub->{$input->attribute} === (string)$input->value) { + if ($input->value != '') { + $log->message .= " Hit on " . $input->table . " " . "$input->attribute " . $dsub->{$input->attribute} . " eq " . $input->value . " for " . $rule->name . "."; + } else { + $log->message .= " Hit on $dsub $input->attribute is empty"; + } + $hit++; + break; + } + } + break; + + case 'ne': + foreach ($device_sub[$input->table] as $dsub) { + if ((string)$dsub->{$input->attribute} !== (string)$input->value) { + if ($input->value != '') { + $log->message .= " Hit on " . $input->table . " $input->attribute " . $dsub->{$input->attribute} . " ne " . $input->value; + } else { + $log->message .= " Hit on " . $input->table . " $input->attribute is empty"; + } + $hit++; + break; + } + } + break; + + case 'gt': + foreach ($device_sub[$input->table] as $dsub) { + if ((string)$dsub->{$input->attribute} > (string)$input->value) { + $log->message .= " Hit on " . $dsub->{$input->attribute} . " gt " . $input->value; + $hit++; + break; + } + } + break; + + case 'ge': + foreach ($device_sub[$input->table] as $dsub) { + if ((string)$dsub->{$input->attribute} >= (string)$input->value) { + $log->message .= " Hit on " . $dsub->{$input->attribute} . " ge " . $input->value; + $hit++; + break; + } + } + break; + + case 'lt': + foreach ($device_sub[$input->table] as $dsub) { + if ((string)$dsub->{$input->attribute} < (string)$input->value) { + $log->message .= " Hit on " . $dsub->{$input->attribute} . " lt " . $input->value; + $hit++; + break; + } + } + break; + + case 'le': + foreach ($device_sub[$input->table] as $dsub) { + if ((string)$dsub->{$input->attribute} <= (string)$input->value) { + $log->message .= " Hit on " . $dsub->{$input->attribute} . " le" . $input->value; + $hit++; + break; + } + } + break; + + case 'li': + foreach ($device_sub[$input->table] as $dsub) { + if (stripos((string)$dsub->{$input->attribute}, $input->value) !== false) { + $log->message .= " Hit on " . $dsub->{$input->attribute} . " li " . $input->value; + $hit++; + break; + } + } + break; + + case 'nl': + foreach ($device_sub[$input->table] as $dsub) { + if (stripos((string)$dsub->{$input->attribute}, $input->value) === false) { + $log->message .= " Hit on " . $dsub->{$input->attribute} . " nl " . $input->value ; + $hit++; + break; + } + } + break; + + case 'in': + $values = explode(',', $input->value); + foreach ($device_sub[$input->table] as $dsub) { + if (in_array((string)$dsub->{$input->attribute}, $values)) { + $log->message .= " Hit on " . $dsub->{$input->attribute} . " in " . $input->value; + $hit++; + break; + } + } + break; + + case 'ni': + $values = explode(',', $input->value); + foreach ($device_sub[$input->table] as $dsub) { + if (!in_array((string)$dsub->{$input->attribute}, $values)) { + $log->message .= " Hit on " . $dsub->{$input->attribute} . " ni " . $input->value; + $hit++; + break; + } + } + break; + + case 'st': + foreach ($device_sub[$input->table] as $dsub) { + if (stripos((string)$dsub->{$input->attribute}, $input->value) === 0) { + $log->message .= " Hit on " . $dsub->{$input->attribute} . " st " . $input->value; + $hit++; + break; + } + } + break; + + case 're': + foreach ($device_sub[$input->table] as $dsub) { + if (preg_match($input->value, (string)$dsub->{$input->attribute})) { + $log->message .= " Hit on " . $dsub->{$input->attribute} . " re " . $input->value; + $hit++; + break; + } + } + break; + + default: + foreach ($device_sub[$input->table] as $dsub) { + if ((string)$dsub->{$input->attribute} == (string)$input->value) { + $log->message .= " Hit on " . $device->{$input->attribute} . " default " . $input->value; + $hit++; + break; + } + } + break; + } + } + } + if ($hit >= $input_count) { + $attributes = new \stdClass(); + foreach ($rule->outputs as $output) { + switch ($output->value_type) { + case 'string': + $newdevice->{$output->attribute} = (string)$output->value; + break; + + case 'integer': + $newdevice->{$output->attribute} = intval($output->value); + break; + + case 'timestamp': + if ($output->value == '') { + $newdevice->{$output->attribute} = $instance->config->timestamp; + } else { + $newdevice->{$output->attribute} = intval($output->value); + } + break; + + default: + $newdevice->{$output->attribute} = (string)$output->value; + break; + } + $attributes->{$output->attribute} = $newdevice->{$output->attribute}; + $device->{$output->attribute} = $newdevice->{$output->attribute}; + } + $log->message = trim($log->message); + $log->command = 'Rules Match - ' . $rule->name . ', ID: ' . $rule->id; + $log->command_output = json_encode($attributes); + $log->command_time_to_execute = (microtime(true) - $item_start); + $discoveryLogModel->create($log); + } + } + $log->message = ''; + } + unset($rules); + + $log->message = 'Completed rules::execute function.'; + $log->command = ''; + $log->command_output = ''; + $log->command_status = 'notice'; + $discoveryLogModel->create($log); + + if (count(get_object_vars($newdevice)) > 0) { + $newdevice->id = @$device->id; + if ($action == 'update') { + $newdevice->last_seen_by = 'rules'; + $devicesModel = new \App\Models\DevicesModel(); + $devicesModel->update($newdevice->id, $newdevice); + return false; + } else { + return $device; + } + } else { + if ($action == 'update') { + return false; + } else { + return $device; + } + } + } + + /** + * Return an array containing arrays of related items to be stored in resp->included + * + * @param int $id The ID of the requested item + * @return array An array of anything needed for screen output + */ + public function includedRead(int $id = 0): array + { + $included = array(); + $locationsModel = new \App\Models\LocationsModel(); + $included['locations'] = $locationsModel->listUser(); + return $included; + } + + /** + * Return an array containing arrays of related items to be stored in resp->included + * + * @param int $id The ID of the requested item + * @return array An array of anything needed for screen output + */ + public function includedCreateForm(int $id = 0): array + { + return array(); + } + + + /** + * Read the entire collection from the database that the user is allowed to read + * + * @return array An array of formatted entries + */ + public function listUser($where = array(), $orgs = array()): array + { + if (empty($orgs)) { + $instance = & get_instance(); + $orgs = array_unique(array_merge($instance->user->orgs, $instance->orgsModel->getUserDescendants($instance->user->orgs, $instance->orgs))); + $orgs = array_unique(array_merge($orgs, $instance->orgsModel->getUserAscendants($instance->user->orgs, $instance->orgs))); + $orgs[] = 1; + $orgs = array_unique($orgs); + } + + $properties = array(); + $properties[] = 'agents.*'; + $properties[] = 'orgs.name as `orgs.name`'; + $this->builder->select($properties, false); + $this->builder->join('orgs', 'agents.org_id = orgs.id', 'left'); + $this->builder->whereIn('orgs.id', $orgs); + $this->builder->where($where); + $query = $this->builder->get(); + if ($this->sqlError($this->db->error())) { + return array(); + } + return format_data($query->getResult(), 'agents'); + } + + /** + * Read the entire collection from the database + * + * @return array An array of all entries + */ + public function listAll(): array + { + $query = $this->builder->get(); + if ($this->sqlError($this->db->error())) { + return array(); + } + return $query->getResult(); + } + + /** + * Read an individual item from the database, by ID + * + * @param int $id The ID of the requested item + * + * @return array The array containing the requested item + */ + public function read(int $id = 0): array + { + $query = $this->builder->getWhere(['id' => intval($id)]); + if ($this->sqlError($this->db->error())) { + return array(); + } + return format_data($query->getResult(), 'agents'); + } + + /** + * Reset a table + * + * @return bool Did it work or not? + */ + public function reset(string $table = ''): bool + { + if ($this->tableReset('agents')) { + return true; + } + return false; + } + + /** + * Update an individual item in the database + * + * @param object $data The data attributes + * + * @return bool true || false depending on success + */ + public function update($id = null, $data = null): bool + { + $data = $this->updateFieldData('agents', $data); + $this->builder->where('id', intval($id)); + $this->builder->update($data); + if ($this->sqlError($this->db->error())) { + return false; + } + return true; + } + + /** + * The dictionary item + * + * @return object The stdClass object containing the dictionary + */ + public function dictionary(): object + { + $instance = & get_instance(); + + $collection = 'agents'; + $dictionary = new stdClass(); + $dictionary->table = $collection; + $dictionary->columns = new stdClass(); + + $dictionary->attributes = new stdClass(); + $dictionary->attributes->collection = array('id', 'name', 'description', 'orgs.name', 'subnet', 'check_minutes', 'weight'); + $dictionary->attributes->create = array('name','org_id'); # We MUST have each of these present and assigned a value + $dictionary->attributes->fields = $this->db->getFieldNames($collection); # All field names for this table + $dictionary->attributes->fieldsMeta = $this->db->getFieldData($collection); # The meta data about all fields - name, type, max_length, primary_key, nullable, default + $dictionary->attributes->update = $this->updateFields($collection); # We MAY update any of these listed fields + $dictionary->sentence = 'Think \'if this, then that\' for devices with an Agent installed.'; + + $dictionary->about = '

Agents let you configure and audit remote PCs.

'; + + $dictionary->notes = '

'; + + $dictionary->product = 'enterprise'; + $dictionary->columns->id = $instance->dictionary->id; + $dictionary->columns->name = $instance->dictionary->name; + $dictionary->columns->org_id = $instance->dictionary->org_id; + $dictionary->columns->description = $instance->dictionary->description; + $dictionary->columns->devices_assigned_to_location = 'Any discovered devices will be assigned to this Location if set. Links to locations.id.'; + $dictionary->columns->devices_assigned_to_org = "Any devices will be assigned to this Org if set. If not set and they are a new device they are assigned to the 'org_id' of this agent. Links to orgs.id."; + $dictionary->columns->check_minutes = 'If this many or more minutes have passed since the device contacted the server, run this rule.'; + $dictionary->columns->weight = 'A lower number means it will be applied before other rules.'; + $dictionary->columns->inputs = 'A JSON object containing an array of attributes to match (normal weight is 100).'; + $dictionary->columns->outputs = 'A JSON object containing an array of attributes to change if the match occurs.'; + $dictionary->columns->subnet = 'If an agent reports in from this subnet, match.'; + $dictionary->columns->edited_by = $instance->dictionary->edited_by; + $dictionary->columns->edited_date = $instance->dictionary->edited_date; + return $dictionary; + } +} diff --git a/app/Views/agentsCollection.php b/app/Views/agentsCollection.php new file mode 100644 index 000000000..20d8ba4f7 --- /dev/null +++ b/app/Views/agentsCollection.php @@ -0,0 +1,72 @@ + +
+
+
+ collection, $meta->icon, $user, '', $meta->query_string) ?> +
+
+
+
+ + + + + data_order as $key) { + if ($key === 'id' or $key === 'orgs.id') { + continue; + } ?> + + + + + permissions[$meta->collection], 'd') !== false) { ?> + + + + + + + + + collection, $item->id) ?> + data_order as $key) { + if ($key === 'id' or $key === 'orgs.id') { + continue; + } + if ($key === 'orgs.name' and !empty($item->attributes->{'orgs.id'})) { + echo "\n"; + } else { + echo "\n"; + } + ?> + + attributes->inputs)) { ?> + + attributes->outputs)) { ?> + + permissions[$meta->collection], 'd') !== false) { ?> + id)) ?> + + + + + +
collection.'Collection') . "?" . $meta->collection . ".org_id=" . $item->attributes->{'orgs.id'} . "\">" . $item->attributes->{$key} . "" . $item->attributes->{$key} . " + attributes->inputs as $input) { ?> + attribute ?> operator ?> value ?>
+ + +
+ attributes->outputs as $output) { ?> + action . ' ' . @$output->value ?>
+ + +
+
+
+
+
diff --git a/app/Views/agentsCreateform.php b/app/Views/agentsCreateform.php new file mode 100644 index 000000000..45550223f --- /dev/null +++ b/app/Views/agentsCreateform.php @@ -0,0 +1,290 @@ + +
+
+
+ collection, $meta->icon, $user); ?> +
+
+
+
+
+ + + attributes->create) ?> + attributes->create) ?> + attributes->create) ?> + attributes->create) ?> + + +
+
+
+
+ + +
+
+
+
+
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+
+
+
+
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+
+
+
+
+
+
+
+ +
+
+
+ + +
+
+ + +
+
+ +
+
+ about)) { + echo "

About


"; + echo html_entity_decode($dictionary->about); + } ?> + notes)) { + echo "

Notes


"; + echo html_entity_decode($dictionary->notes); + } ?> +

Fields


+ columns as $key => $value) { + echo "$key: " . html_entity_decode($value) . "

"; + } ?> +
+
+
+
+
+
+ + + \ No newline at end of file diff --git a/app/Views/agentsRead.php b/app/Views/agentsRead.php new file mode 100644 index 000000000..0b9404596 --- /dev/null +++ b/app/Views/agentsRead.php @@ -0,0 +1,510 @@ + +
+
+
+ collection, $meta->id, $meta->icon, $user, $resource->name) ?> +
+
+
+
+ name, $dictionary->columns->name, $update) ?> + org_id, $dictionary->columns->org_id, $update, __('Organisation'), $orgs) ?> + description, $dictionary->columns->description, $update) ?> + subnet, $dictionary->columns->subnet, $update) ?> + check_minutes, $dictionary->columns->check_minutes, $update) ?> + weight, $dictionary->columns->weight, $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) ?> + edited_date, $dictionary->columns->edited_date, false) ?> + +
+
+
+
+
+ +
+
+ + +
+ + +
+ inputs as $input) { + $input_count += +1; ?> +
+
+ +
+ +
+ +
+ +
+ +
+ + +
+ + + + + + + +
+ +
+ +
+
+
+ +
+
+
+
+
+ +
+
+ + +
+ +
+ + +
+ outputs as $output) { + $output_count += 1; ?> +
+
+ +
+ +
+ value)) { ?> + + +
+ +
+ +
+ + + + + + + + + +
+
+ +
+
+
+
+ + +
+
+
+ about)) { ?> +


+ about ?> + + notes)) { ?> +


+ notes ?> + + columns)) { ?> +


+ columns as $key => $value) { ?> + :

+ + +
+
+
+
+
+
+ + \ No newline at end of file diff --git a/app/Views/lang/en.inc b/app/Views/lang/en.inc index 30e0d919e..28b032ee8 100644 --- a/app/Views/lang/en.inc +++ b/app/Views/lang/en.inc @@ -7,6 +7,7 @@ $GLOBALS["lang"]["=="]="=="; $GLOBALS["lang"][">"]=">"; $GLOBALS["lang"][">="]=">="; $GLOBALS["lang"]["About"]="About"; +$GLOBALS["lang"]["About Agents"]="About Agents"; $GLOBALS["lang"]["About Applications"]="About Applications"; $GLOBALS["lang"]["About Baselines"]="About Baselines"; $GLOBALS["lang"]["About Clouds"]="About Clouds"; @@ -57,11 +58,12 @@ $GLOBALS["lang"]["Add Policies from Device"]="Add Policies from Device"; $GLOBALS["lang"]["Add Policy"]="Add Policy"; $GLOBALS["lang"]["Address"]="Address"; $GLOBALS["lang"]["AD Group"]="AD Group"; -$GLOBALS["lang"]["Admin"]="Admin"; $GLOBALS["lang"]["admin"]="admin"; +$GLOBALS["lang"]["Admin"]="Admin"; $GLOBALS["lang"]["Admin Status"]="Admin Status"; $GLOBALS["lang"]["ADSL Modem"]="ADSL Modem"; $GLOBALS["lang"]["Advanced"]="Advanced"; +$GLOBALS["lang"]["Agents"]="Agents"; $GLOBALS["lang"]["Aggressive"]="Aggressive"; $GLOBALS["lang"]["Airforce"]="Airforce"; $GLOBALS["lang"]["Airport"]="Airport"; @@ -77,12 +79,12 @@ $GLOBALS["lang"]["Android"]="Android"; $GLOBALS["lang"]["Antivirus"]="Antivirus"; $GLOBALS["lang"]["Apache"]="Apache"; $GLOBALS["lang"]["API Result"]="API Result"; -$GLOBALS["lang"]["application"]="application"; $GLOBALS["lang"]["Application"]="Application"; +$GLOBALS["lang"]["application"]="application"; $GLOBALS["lang"]["Application Accelerator"]="Application Accelerator"; $GLOBALS["lang"]["Application Licenses"]="Application Licenses"; -$GLOBALS["lang"]["Applications"]="Applications"; $GLOBALS["lang"]["applications"]="applications"; +$GLOBALS["lang"]["Applications"]="Applications"; $GLOBALS["lang"]["Application Servers"]="Application Servers"; $GLOBALS["lang"]["Application Services"]="Application Services"; $GLOBALS["lang"]["April"]="April"; @@ -112,6 +114,7 @@ $GLOBALS["lang"]["Attachments"]="Attachments"; $GLOBALS["lang"]["Attribute"]="Attribute"; $GLOBALS["lang"]["Attributes"]="Attributes"; $GLOBALS["lang"]["attributes"]="attributes"; +$GLOBALS["lang"]["Audit"]="Audit"; $GLOBALS["lang"]["Audit Class"]="Audit Class"; $GLOBALS["lang"]["Audit Dates"]="Audit Dates"; $GLOBALS["lang"]["Audit Log"]="Audit Log"; @@ -134,8 +137,8 @@ $GLOBALS["lang"]["Bar Code Reader"]="Bar Code Reader"; $GLOBALS["lang"]["Base DN"]="Base DN"; $GLOBALS["lang"]["Based On"]="Based On"; $GLOBALS["lang"]["Baseline"]="Baseline"; -$GLOBALS["lang"]["Baselines"]="Baselines"; $GLOBALS["lang"]["baselines"]="baselines"; +$GLOBALS["lang"]["Baselines"]="Baselines"; $GLOBALS["lang"]["Baselines Policies"]="Baselines Policies"; $GLOBALS["lang"]["Baselines Policy"]="Baselines Policy"; $GLOBALS["lang"]["Baselines Policy Details"]="Baselines Policy Details"; @@ -198,11 +201,12 @@ $GLOBALS["lang"]["change_log"]="change_log"; $GLOBALS["lang"]["chart"]="chart"; $GLOBALS["lang"]["Chassis"]="Chassis"; $GLOBALS["lang"]["Check for SSH on these ports"]="Check for SSH on these ports"; +$GLOBALS["lang"]["Check Minutes"]="Check Minutes"; $GLOBALS["lang"]["Choose"]="Choose"; $GLOBALS["lang"]["Choose a Device"]="Choose a Device"; $GLOBALS["lang"]["Choose a Table"]="Choose a Table"; -$GLOBALS["lang"]["Cidr"]="Cidr"; $GLOBALS["lang"]["CIDR"]="CIDR"; +$GLOBALS["lang"]["Cidr"]="Cidr"; $GLOBALS["lang"]["CIDR Mask"]="CIDR Mask"; $GLOBALS["lang"]["Circuit Count"]="Circuit Count"; $GLOBALS["lang"]["Cisco Module"]="Cisco Module"; @@ -230,11 +234,11 @@ $GLOBALS["lang"]["cluster"]="cluster"; $GLOBALS["lang"]["Cluster"]="Cluster"; $GLOBALS["lang"]["Cluster ID"]="Cluster ID"; $GLOBALS["lang"]["Cluster Name"]="Cluster Name"; -$GLOBALS["lang"]["Clusters"]="Clusters"; $GLOBALS["lang"]["clusters"]="clusters"; +$GLOBALS["lang"]["Clusters"]="Clusters"; $GLOBALS["lang"]["Cluster Type"]="Cluster Type"; -$GLOBALS["lang"]["Collector"]="Collector"; $GLOBALS["lang"]["collector"]="collector"; +$GLOBALS["lang"]["Collector"]="Collector"; $GLOBALS["lang"]["collectors"]="collectors"; $GLOBALS["lang"]["Collectors"]="Collectors"; $GLOBALS["lang"]["Collector Uuid"]="Collector Uuid"; @@ -266,8 +270,8 @@ $GLOBALS["lang"]["Configure"]="Configure"; $GLOBALS["lang"]["Connected To"]="Connected To"; $GLOBALS["lang"]["Connection"]="Connection"; $GLOBALS["lang"]["Connection Options"]="Connection Options"; -$GLOBALS["lang"]["connections"]="connections"; $GLOBALS["lang"]["Connections"]="Connections"; +$GLOBALS["lang"]["connections"]="connections"; $GLOBALS["lang"]["Consider Filtered Ports Open"]="Consider Filtered Ports Open"; $GLOBALS["lang"]["Consider filtered Ports Open"]="Consider filtered Ports Open"; $GLOBALS["lang"]["Consider Open|Filtered Ports Open"]="Consider Open|Filtered Ports Open"; @@ -293,8 +297,8 @@ $GLOBALS["lang"]["Create NMIS Devices from Open-AudIT"]="Create NMIS Devices fro $GLOBALS["lang"]["Create Open-AudIT Devices from "]="Create Open-AudIT Devices from "; $GLOBALS["lang"]["Create Open-AudIT Devices from NMIS"]="Create Open-AudIT Devices from NMIS"; $GLOBALS["lang"]["credential"]="credential"; -$GLOBALS["lang"]["credentials"]="credentials"; $GLOBALS["lang"]["Credentials"]="Credentials"; +$GLOBALS["lang"]["credentials"]="credentials"; $GLOBALS["lang"]["Credentials Key"]="Credentials Key"; $GLOBALS["lang"]["Credentials Secret"]="Credentials Secret"; $GLOBALS["lang"]["CSV"]="CSV"; @@ -305,8 +309,8 @@ $GLOBALS["lang"]["Custom TCP Ports"]="Custom TCP Ports"; $GLOBALS["lang"]["Custom UDP Ports"]="Custom UDP Ports"; $GLOBALS["lang"]["Czech"]="Czech"; $GLOBALS["lang"]["Dallas_Office"]="Dallas_Office"; -$GLOBALS["lang"]["dashboards"]="dashboards"; $GLOBALS["lang"]["Dashboards"]="Dashboards"; +$GLOBALS["lang"]["dashboards"]="dashboards"; $GLOBALS["lang"]["Database"]="Database"; $GLOBALS["lang"]["Database Tables"]="Database Tables"; $GLOBALS["lang"]["Data Center"]="Data Center"; @@ -347,8 +351,8 @@ $GLOBALS["lang"]["Delete from Application"]="Delete from Application"; $GLOBALS["lang"]["Delete from Cluster"]="Delete from Cluster"; $GLOBALS["lang"]["Delete NMIS Devices if not in Open-AudIT"]="Delete NMIS Devices if not in Open-AudIT"; $GLOBALS["lang"]["Depot"]="Depot"; -$GLOBALS["lang"]["Description"]="Description"; $GLOBALS["lang"]["description"]="description"; +$GLOBALS["lang"]["Description"]="Description"; $GLOBALS["lang"]["Desktop"]="Desktop"; $GLOBALS["lang"]["Destination"]="Destination"; $GLOBALS["lang"]["Detail"]="Detail"; @@ -364,8 +368,8 @@ $GLOBALS["lang"]["Device ID B"]="Device ID B"; $GLOBALS["lang"]["Device Name"]="Device Name"; $GLOBALS["lang"]["Device Result"]="Device Result"; $GLOBALS["lang"]["Device Results"]="Device Results"; -$GLOBALS["lang"]["devices"]="devices"; $GLOBALS["lang"]["Devices"]="Devices"; +$GLOBALS["lang"]["devices"]="devices"; $GLOBALS["lang"]["Devices Audited"]="Devices Audited"; $GLOBALS["lang"]["Devices Audited per Day"]="Devices Audited per Day"; $GLOBALS["lang"]["Devices by Class"]="Devices by Class"; @@ -434,8 +438,8 @@ $GLOBALS["lang"]["Disabled"]="Disabled"; $GLOBALS["lang"]["Disaster Recovery"]="Disaster Recovery"; $GLOBALS["lang"]["Discover"]="Discover"; $GLOBALS["lang"]["Discover Clouds"]="Discover Clouds"; -$GLOBALS["lang"]["discoveries"]="discoveries"; $GLOBALS["lang"]["Discoveries"]="Discoveries"; +$GLOBALS["lang"]["discoveries"]="discoveries"; $GLOBALS["lang"]["Discover Networks"]="Discover Networks"; $GLOBALS["lang"]["Discovery"]="Discovery"; $GLOBALS["lang"]["Discovery Change Logs"]="Discovery Change Logs"; @@ -459,8 +463,8 @@ $GLOBALS["lang"]["Display in Menu"]="Display in Menu"; $GLOBALS["lang"]["District"]="District"; $GLOBALS["lang"]["DN Account"]="DN Account"; $GLOBALS["lang"]["DN Password"]="DN Password"; -$GLOBALS["lang"]["dns"]="dns"; $GLOBALS["lang"]["Dns"]="Dns"; +$GLOBALS["lang"]["dns"]="dns"; $GLOBALS["lang"]["DNS Domain"]="DNS Domain"; $GLOBALS["lang"]["DNS Domains"]="DNS Domains"; $GLOBALS["lang"]["Dns Fqdn"]="Dns Fqdn"; @@ -555,17 +559,17 @@ $GLOBALS["lang"]["Features"]="Features"; $GLOBALS["lang"]["February"]="February"; $GLOBALS["lang"]["field"]="field"; $GLOBALS["lang"]["Field Name"]="Field Name"; -$GLOBALS["lang"]["fields"]="fields"; $GLOBALS["lang"]["Fields"]="Fields"; +$GLOBALS["lang"]["fields"]="fields"; $GLOBALS["lang"]["Field Type"]="Field Type"; -$GLOBALS["lang"]["File"]="File"; $GLOBALS["lang"]["file"]="file"; +$GLOBALS["lang"]["File"]="File"; $GLOBALS["lang"]["File Import"]="File Import"; $GLOBALS["lang"]["File Input"]="File Input"; -$GLOBALS["lang"]["Filename"]="Filename"; $GLOBALS["lang"]["File Name"]="File Name"; -$GLOBALS["lang"]["Files"]="Files"; +$GLOBALS["lang"]["Filename"]="Filename"; $GLOBALS["lang"]["files"]="files"; +$GLOBALS["lang"]["Files"]="Files"; $GLOBALS["lang"]["Fire Station"]="Fire Station"; $GLOBALS["lang"]["Firewall"]="Firewall"; $GLOBALS["lang"]["Firmware"]="Firmware"; @@ -616,19 +620,19 @@ $GLOBALS["lang"]["Google JSON Credentials"]="Google JSON Credentials"; $GLOBALS["lang"]["Graceville"]="Graceville"; $GLOBALS["lang"]["graph"]="graph"; $GLOBALS["lang"]["greater or equals"]="greater or equals"; -$GLOBALS["lang"]["greater than"]="greater than"; $GLOBALS["lang"]["Greater Than"]="Greater Than"; +$GLOBALS["lang"]["greater than"]="greater than"; $GLOBALS["lang"]["Group"]="Group"; -$GLOBALS["lang"]["groups"]="groups"; $GLOBALS["lang"]["Groups"]="Groups"; +$GLOBALS["lang"]["groups"]="groups"; $GLOBALS["lang"]["Guard"]="Guard"; $GLOBALS["lang"]["Guests"]="Guests"; $GLOBALS["lang"]["Hard Drive Index"]="Hard Drive Index"; $GLOBALS["lang"]["Hardware"]="Hardware"; $GLOBALS["lang"]["Hardware Additions by Day"]="Hardware Additions by Day"; $GLOBALS["lang"]["Head"]="Head"; -$GLOBALS["lang"]["HeadOffice"]="HeadOffice"; $GLOBALS["lang"]["Head Office"]="Head Office"; +$GLOBALS["lang"]["HeadOffice"]="HeadOffice"; $GLOBALS["lang"]["Height"]="Height"; $GLOBALS["lang"]["Height in RU"]="Height in RU"; $GLOBALS["lang"]["Help"]="Help"; @@ -689,8 +693,8 @@ $GLOBALS["lang"]["Instance Type"]="Instance Type"; $GLOBALS["lang"]["Integer"]="Integer"; $GLOBALS["lang"]["Integration"]="Integration"; $GLOBALS["lang"]["Integration Default for NMIS"]="Integration Default for NMIS"; -$GLOBALS["lang"]["integrations"]="integrations"; $GLOBALS["lang"]["Integrations"]="Integrations"; +$GLOBALS["lang"]["integrations"]="integrations"; $GLOBALS["lang"]["integrations_log"]="integrations_log"; $GLOBALS["lang"]["Interface"]="Interface"; $GLOBALS["lang"]["Interfaces Used or Available"]="Interfaces Used or Available"; @@ -701,9 +705,9 @@ $GLOBALS["lang"]["Internal ID"]="Internal ID"; $GLOBALS["lang"]["Invoice ID"]="Invoice ID"; $GLOBALS["lang"]["IoT Device"]="IoT Device"; $GLOBALS["lang"]["IoT Sensor"]="IoT Sensor"; -$GLOBALS["lang"]["IP"]="IP"; -$GLOBALS["lang"]["Ip"]="Ip"; $GLOBALS["lang"]["ip"]="ip"; +$GLOBALS["lang"]["Ip"]="Ip"; +$GLOBALS["lang"]["IP"]="IP"; $GLOBALS["lang"]["iPad"]="iPad"; $GLOBALS["lang"]["IP Address"]="IP Address"; $GLOBALS["lang"]["IP Addresses"]="IP Addresses"; @@ -822,8 +826,8 @@ $GLOBALS["lang"]["Manufacturer"]="Manufacturer"; $GLOBALS["lang"]["Manufacturer Code"]="Manufacturer Code"; $GLOBALS["lang"]["Manufacturers"]="Manufacturers"; $GLOBALS["lang"]["Map"]="Map"; -$GLOBALS["lang"]["maps"]="maps"; $GLOBALS["lang"]["Maps"]="Maps"; +$GLOBALS["lang"]["maps"]="maps"; $GLOBALS["lang"]["March"]="March"; $GLOBALS["lang"]["MariaDB"]="MariaDB"; $GLOBALS["lang"]["Marina"]="Marina"; @@ -855,8 +859,8 @@ $GLOBALS["lang"]["Mobile Modem"]="Mobile Modem"; $GLOBALS["lang"]["Mobile Phone Tower"]="Mobile Phone Tower"; $GLOBALS["lang"]["Model"]="Model"; $GLOBALS["lang"]["Model Family"]="Model Family"; -$GLOBALS["lang"]["Module"]="Module"; $GLOBALS["lang"]["module"]="module"; +$GLOBALS["lang"]["Module"]="Module"; $GLOBALS["lang"]["Modules"]="Modules"; $GLOBALS["lang"]["Monday"]="Monday"; $GLOBALS["lang"]["MongoDB"]="MongoDB"; @@ -889,8 +893,8 @@ $GLOBALS["lang"]["NAS (Network Attached Storage)"]="NAS (Network Attached Storag $GLOBALS["lang"]["Navy"]="Navy"; $GLOBALS["lang"]["Net Index"]="Net Index"; $GLOBALS["lang"]["Netmask"]="Netmask"; -$GLOBALS["lang"]["Netstat"]="Netstat"; $GLOBALS["lang"]["netstat"]="netstat"; +$GLOBALS["lang"]["Netstat"]="Netstat"; $GLOBALS["lang"]["Netstat Policies"]="Netstat Policies"; $GLOBALS["lang"]["Netstat Ports"]="Netstat Ports"; $GLOBALS["lang"]["Network"]="Network"; @@ -919,10 +923,10 @@ $GLOBALS["lang"]["Nmap"]="Nmap"; $GLOBALS["lang"]["nmap"]="nmap"; $GLOBALS["lang"]["Nmap Duration"]="Nmap Duration"; $GLOBALS["lang"]["NMIS"]="NMIS"; -$GLOBALS["lang"]["Nmis Business Service"]="Nmis Business Service"; $GLOBALS["lang"]["NMIS Business Service"]="NMIS Business Service"; -$GLOBALS["lang"]["Nmis Customer"]="Nmis Customer"; +$GLOBALS["lang"]["Nmis Business Service"]="Nmis Business Service"; $GLOBALS["lang"]["NMIS Customer"]="NMIS Customer"; +$GLOBALS["lang"]["Nmis Customer"]="Nmis Customer"; $GLOBALS["lang"]["NMIS Device Options"]="NMIS Device Options"; $GLOBALS["lang"]["NMIS Device Selection"]="NMIS Device Selection"; $GLOBALS["lang"]["NMIS Field Name"]="NMIS Field Name"; @@ -1134,15 +1138,16 @@ $GLOBALS["lang"]["Queued Items"]="Queued Items"; $GLOBALS["lang"]["Queue Limit"]="Queue Limit"; $GLOBALS["lang"]["Rack"]="Rack"; $GLOBALS["lang"]["Rack Devices"]="Rack Devices"; -$GLOBALS["lang"]["Racks"]="Racks"; $GLOBALS["lang"]["racks"]="racks"; +$GLOBALS["lang"]["Racks"]="Racks"; $GLOBALS["lang"]["rack_devices"]="rack_devices"; -$GLOBALS["lang"]["Radio"]="Radio"; $GLOBALS["lang"]["radio"]="radio"; +$GLOBALS["lang"]["Radio"]="Radio"; $GLOBALS["lang"]["Radio Station"]="Radio Station"; $GLOBALS["lang"]["Read"]="Read"; $GLOBALS["lang"]["Read our online documentation on the Open-AudIT Wiki."]="Read our online documentation on the Open-AudIT Wiki."; $GLOBALS["lang"]["recreateRole"]="recreateRole"; +$GLOBALS["lang"]["regex"]="regex"; $GLOBALS["lang"]["Regional"]="Regional"; $GLOBALS["lang"]["Registered User"]="Registered User"; $GLOBALS["lang"]["Release"]="Release"; @@ -1210,8 +1215,8 @@ $GLOBALS["lang"]["Schedule Reports"]="Schedule Reports"; $GLOBALS["lang"]["School"]="School"; $GLOBALS["lang"]["Scripts"]="Scripts"; $GLOBALS["lang"]["scripts"]="scripts"; -$GLOBALS["lang"]["scsi"]="scsi"; $GLOBALS["lang"]["Scsi"]="Scsi"; +$GLOBALS["lang"]["scsi"]="scsi"; $GLOBALS["lang"]["Scsi Bus"]="Scsi Bus"; $GLOBALS["lang"]["Scsi Logical Unit"]="Scsi Logical Unit"; $GLOBALS["lang"]["Scsi Port"]="Scsi Port"; diff --git a/app/Views/rolesCreateform.php b/app/Views/rolesCreateform.php index cbc64bf7e..55cbb0f4b 100644 --- a/app/Views/rolesCreateform.php +++ b/app/Views/rolesCreateform.php @@ -2,7 +2,7 @@ # Copyright © 2023 FirstWave. All Rights Reserved. # SPDX-License-Identifier: AGPL-3.0-or-later include 'shared/create_functions.php'; -$endpoints = array('applications','attributes','baselines','charts','clouds','clusters','collectors','configuration','connections','credentials','dashboards','database','devices','discoveries','discovery_scan_options','fields','files','groups','integrations','ldap_servers','licenses','locations','networks','orgs','queries','racks','reports','roles','rules','scripts','summaries','tasks','users','widgets'); +$endpoints = array('agents','applications','attributes','baselines','charts','clouds','clusters','collectors','configuration','connections','credentials','dashboards','database','devices','discoveries','discovery_scan_options','fields','files','groups','integrations','ldap_servers','licenses','locations','networks','orgs','queries','racks','reports','roles','rules','scripts','summaries','tasks','users','widgets'); $permissions = array('c', 'r', 'u', 'd'); ?>
diff --git a/app/Views/rolesRead.php b/app/Views/rolesRead.php index 16380ee1f..b0f026830 100644 --- a/app/Views/rolesRead.php +++ b/app/Views/rolesRead.php @@ -3,7 +3,7 @@ # SPDX-License-Identifier: AGPL-3.0-or-later include 'shared/read_functions.php'; $permissions = array('c','r','u','d'); -$endpoints = array('applications','attributes','baselines','clouds','clusters','components','configuration','connections','credentials','dashboards','database','devices','discoveries','discovery_scan_options','fields','files','groups','integrations','ldap_servers','licenses','locations','logs','networks','orgs','queries','racks','rack_devices','roles','rules','scripts','search','summaries','tasks','users','widgets'); +$endpoints = array('agents','applications','attributes','baselines','clouds','clusters','components','configuration','connections','credentials','dashboards','database','devices','discoveries','discovery_scan_options','fields','files','groups','integrations','ldap_servers','licenses','locations','logs','networks','orgs','queries','racks','rack_devices','roles','rules','scripts','search','summaries','tasks','users','widgets'); $item_permissions = $resource->permissions; $style = @$user->toolbar_style; if ($style === 'icontext') { diff --git a/app/Views/rulesRead.php b/app/Views/rulesRead.php index 441494e99..2ed610ffb 100644 --- a/app/Views/rulesRead.php +++ b/app/Views/rulesRead.php @@ -529,6 +529,7 @@ \ \ \ + \ \ \
\ diff --git a/app/Views/shared/header.php b/app/Views/shared/header.php index b2b954de8..e381ce416 100644 --- a/app/Views/shared/header.php +++ b/app/Views/shared/header.php @@ -193,6 +193,13 @@ function my_comparison($asort, $bsort)
\n"; @@ -36,6 +37,7 @@ } if ($key === 'device_id') { $label = 'Device ID'; + $link = ""; } if ($key === 'devices.id' or $key === 'devices.name') { continue; @@ -46,7 +48,7 @@ if ($key === 'command_output') { $resource->{$key} = html_entity_decode($resource->{$key}); } - echo read_field($key, $resource->{$key}, '', false, $label); + echo read_field($key, $resource->{$key}, '', false, $label, $link); } echo "
\n"; } ?> From 8c150123a72aa981485aa5b267dbb5fdacc9cfd8 Mon Sep 17 00:00:00 2001 From: Mark Unwin Date: Tue, 28 Nov 2023 16:06:16 +1000 Subject: [PATCH 03/43] Remove MultiReports from the menu. Fix a duplicate CSS class in tasks in header. Allow all licenses to access Reports. --- app/Views/shared/header.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/Views/shared/header.php b/app/Views/shared/header.php index e381ce416..6d65aa6d3 100644 --- a/app/Views/shared/header.php +++ b/app/Views/shared/header.php @@ -173,7 +173,7 @@ function my_comparison($asort, $bsort) $link = $report->type . 'Execute'; if ($report->{'attributes'}->{'menu_category'} === $category) { if ($report->{'attributes'}->{'menu_category'} === 'Discovery') { - if ($config->license !== 'commercial') { + if (!empty($config->license) and $config->license !== 'commercial' and $config->license !== 'free') { echo "
  • " . $report->{'attributes'}->{'name'} . "
  • \n"; } else { echo "
  • id) . "\">" . $report->{'attributes'}->{'name'} . "
  • \n"; @@ -186,7 +186,7 @@ function my_comparison($asort, $bsort) echo " \n"; } ?> - + @@ -420,7 +420,7 @@ function my_comparison($asort, $bsort) -
  • +
  • \n"; } ?> - - +
  • @@ -664,7 +663,7 @@ function menuItem($collection = '', $permission = '', $user = null, $route = '', if (strpos($instance->collections->{$collection}->actions->{$instance->config->product}, $instance->resp->meta->permission_requested[$instance->resp->meta->action]) === false) { $return = "
  • collections->{$collection}->edition . "\" href=\"#\">" . $title . "
  • \n"; } - // Check if use has permission and a license + // Check if user has permission and a license if (strpos($instance->collections->{$collection}->actions->{$instance->config->product}, $instance->resp->meta->permission_requested[$instance->resp->meta->action]) !== false) { if (get_user_permission($collection, $permission, $user)) { $return = "
  • " . $title . "
  • \n"; From 27d85f3c15d1f369d27c88ea2314d27f4fcf0227 Mon Sep 17 00:00:00 2001 From: Mark Unwin Date: Wed, 29 Nov 2023 16:10:13 +1000 Subject: [PATCH 11/43] Make icons on Summaries URL agnostic. --- app/Views/summariesCollection.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Views/summariesCollection.php b/app/Views/summariesCollection.php index ae657d6fe..06f5eaf39 100644 --- a/app/Views/summariesCollection.php +++ b/app/Views/summariesCollection.php @@ -57,7 +57,7 @@
    - <?= $name ?> + <?= $name ?>
    name) ?> count ?>
    From 8e4d4cc31ee1cab13c045ebe0684acaef39714a4 Mon Sep 17 00:00:00 2001 From: Mark Unwin Date: Wed, 29 Nov 2023 16:11:32 +1000 Subject: [PATCH 12/43] Fix PHP 8.2 warnings. --- app/Controllers/Logon.php | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/app/Controllers/Logon.php b/app/Controllers/Logon.php index 9838a4f42..923d50738 100644 --- a/app/Controllers/Logon.php +++ b/app/Controllers/Logon.php @@ -40,8 +40,8 @@ class Logon extends Controller { public function createForm() { - $this->session = session(); - if (!empty($this->session->get('user_id'))) { + $session = session(); + if (!empty($session->get('user_id'))) { return redirect()->to(site_url('summaries')); } return view('logon', ['config' => new \Config\OpenAudit()]); @@ -49,9 +49,9 @@ public function createForm() public function create() { - $this->session = session(); - $this->logonModel = model('App\Models\LogonModel'); - $this->config = new \Config\OpenAudit(); + $session = session(); + $logonModel = model('App\Models\LogonModel'); + $config = new \Config\OpenAudit(); $username = (!empty($_POST['username'])) ? $_POST['username'] : ''; if (empty($username) && ! empty($_SERVER['HTTP_USERNAME'])) { @@ -67,7 +67,7 @@ public function create() if (empty($username) or empty($password)) { # set flash need creds - $this->session->setFlashdata('flash', '{"level":"danger", "message":"Credentials required"}'); + $session->setFlashdata('flash', '{"level":"danger", "message":"Credentials required"}'); log_message('error', '{"level":"danger", "message":"Credentials required"}'); return redirect()->to(site_url('logon')); } @@ -90,16 +90,16 @@ public function create() $format = 'json'; } - $user = $this->logonModel->logon($username, $password); + $user = $logonModel->logon($username, $password); if ($user) { log_message('info', 'Valid credentials for ' . $username . ' from ' . @$this->request->getIPAddress()); - $this->session->set('user_id', $user->id); + $session->set('user_id', $user->id); if ($format !== 'json') { if (!empty($_POST['url'])) { header('Location: ' . $_POST['url']); exit; } - if ($this->config->device_count === 0) { + if ($config->device_count === 0) { return redirect()->to(url_to('welcome')); } else { return redirect()->to(url_to('home')); @@ -123,8 +123,8 @@ public function create() public function delete() { - $this->session = session(); - $this->session->destroy(); + $session = session(); + $session->destroy(); return redirect()->to(site_url('logon')); } @@ -132,8 +132,8 @@ public function license() { $this->response->setContentType('application/json'); $json = '{"license":"none","product":"free"}'; - $this->config = new \Config\OpenAudit(); - $enterprise_binary = $this->config->enterprise_binary; + $config = new \Config\OpenAudit(); + $enterprise_binary = $config->enterprise_binary; if (!empty($enterprise_binary)) { if (php_uname('s') === 'Windows NT') { $command = "%comspec% /c start /b " . $enterprise_binary . " --license"; From 5f00f89728c8b21833acfdf45d19c2692ba161e2 Mon Sep 17 00:00:00 2001 From: Mark Unwin Date: Thu, 30 Nov 2023 10:48:57 +1000 Subject: [PATCH 13/43] On devicesCollection and discoveriesRead, add a space either side of IPs in the dataTable. Users can now 'search' for 192.168.1.1 and not return 192.168.1.11. --- app/Views/devicesCollection.php | 7 ++++++- app/Views/discoveriesRead.php | 2 +- public/js/open-audit.js | 14 ++++++++++++-- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/app/Views/devicesCollection.php b/app/Views/devicesCollection.php index 13397ba39..3acb1ce55 100644 --- a/app/Views/devicesCollection.php +++ b/app/Views/devicesCollection.php @@ -158,7 +158,7 @@ echo " attributes->icon . ".svg\" style=\"width:40px\" alt=\"" . $item->attributes->icon . "\">\n"; } } else if ($key === 'ip' and !empty($item->attributes->ip_padded)) { - echo " " . $item->attributes->ip_padded . "" . $item->attributes->{$key} . "\n"; + echo " " . $item->attributes->ip_padded . " " . $item->attributes->{$key} . " \n"; } else { echo "  " . $item->attributes->{$key} . "\n"; } @@ -238,6 +238,11 @@ "pagingType": "full", "pageLength": 50, "lengthMenu": [[10, 25, 50, 100, -1], [10, 25, 50, 100, "All"]], + "oSearch": { + "bSmart": false, + "bRegex": true, + "sSearch": "" + }, "columnDefs": [ id) ?> id ?> timestamp ?> - ip_padded ?>ip ?> + ip_padded ?> ip ?> command_status === 'success') { ?> diff --git a/public/js/open-audit.js b/public/js/open-audit.js index f8d73152a..e8c4e4d5b 100644 --- a/public/js/open-audit.js +++ b/public/js/open-audit.js @@ -283,7 +283,12 @@ $(document).ready(function () { "order": [[ 1, 'asc' ]], "info": true, "pageLength": 50, - "autoWidth": false + "autoWidth": false, + "oSearch": { + "bSmart": false, + "bRegex": true, + "sSearch": "" + } }); /* DataTables Init Secondary */ @@ -293,7 +298,12 @@ $(document).ready(function () { "order": [[ 1, 'asc' ]], "info": false, "pageLength": 100, - "autoWidth": false + "autoWidth": false, + "oSearch": { + "bSmart": false, + "bRegex": true, + "sSearch": "" + } }); /* Enable pop-over's */ From a4b51b70bd9a0af57ccd94414643b10a0d895cfa Mon Sep 17 00:00:00 2001 From: Mark Unwin Date: Thu, 30 Nov 2023 10:58:51 +1000 Subject: [PATCH 14/43] On discoveriesRead, in the logs, add DeviceMatch where function = match to more easily use the dataTables search. --- app/Views/discoveriesRead.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/Views/discoveriesRead.php b/app/Views/discoveriesRead.php index 4661e876d..bc2793ade 100644 --- a/app/Views/discoveriesRead.php +++ b/app/Views/discoveriesRead.php @@ -380,6 +380,9 @@ message, 'not responding, ignoring') === false and strpos($log->message, 'responding, adding to device list') === false) { ?> + function === 'match') { + $log->message = 'DeviceMatch - ' . $log->message; + } ?> id) ?> id ?> From 80a2443c546d901ae6581bea2511b78a8955ee3f Mon Sep 17 00:00:00 2001 From: Mark Unwin Date: Mon, 4 Dec 2023 13:05:04 +1000 Subject: [PATCH 15/43] Fix App config to determine the BASEURL even when running from spark. --- app/Config/App.php | 29 ++++++++++++++++++++++++++++- env | 2 -- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/app/Config/App.php b/app/Config/App.php index 25eeed919..88f04a906 100755 --- a/app/Config/App.php +++ b/app/Config/App.php @@ -18,7 +18,8 @@ class App extends BaseConfig * http://example.com/ */ # public string $baseURL = 'http://localhost:8080/'; - public string $baseURL = BASEURL; + # public string $baseURL = BASEURL; + public string $baseURL = ''; /** * Allowed Hostnames in the Site URL other than the hostname in the baseURL. @@ -447,4 +448,30 @@ class App extends BaseConfig * @see http://www.w3.org/TR/CSP/ */ public bool $CSPEnabled = true; + + public function __construct() + { + // Dynamically set our baseURL + $this->baseURL = 'http://'; + if (isset($_SERVER['HTTPS']) && !empty($_SERVER['HTTPS'])) { + $this->baseURL = 'https://'; + } + if (!empty($_SERVER['SERVER_NAME'])) { + $this->baseURL .= $_SERVER['SERVER_NAME']; + } else { + $this->baseURL .= 'localhost'; + } + if (!empty($_SERVER['SERVER_PORT']) and $_SERVER['SERVER_PORT'] != '80' and $_SERVER['SERVER_PORT'] != '443') { + $this->baseURL .= ':' . $_SERVER['SERVER_PORT']; + } + $this->baseURL .= str_replace('index.php', '', $_SERVER['SCRIPT_NAME']); + if (is_cli()) { + $this->baseURL = 'http://localhost/'; + } + + # Set CPSEnabled depending on environment + if (!empty($_SERVER['CI_ENVIRONMENT']) and $_SERVER['CI_ENVIRONMENT'] === 'development') { + $this->CSPEnabled = false; + } + } } diff --git a/env b/env index f480c1514..7184c820f 100755 --- a/env +++ b/env @@ -15,8 +15,6 @@ #-------------------------------------------------------------------- # CI_ENVIRONMENT = development -# app.CSPEnabled = false -# logger.threshold = 9 #-------------------------------------------------------------------- # APP From cd65609a9c34769b0b16af0a62f5c9c660e0c5c9 Mon Sep 17 00:00:00 2001 From: Mark Unwin Date: Mon, 4 Dec 2023 13:06:08 +1000 Subject: [PATCH 16/43] Bump versions to 5.0.2. --- app/Config/OpenAudit.php | 4 ++-- app/Models/DatabaseModel.php | 4 ++++ app/Models/db_upgrades/db_5.0.2.php | 17 +++++++++++++++++ 3 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 app/Models/db_upgrades/db_5.0.2.php diff --git a/app/Config/OpenAudit.php b/app/Config/OpenAudit.php index b43670079..20ae36d21 100755 --- a/app/Config/OpenAudit.php +++ b/app/Config/OpenAudit.php @@ -12,8 +12,8 @@ class OpenAudit extends BaseConfig { public function __construct() { - $this->appVersion = 20230615; - $this->displayVersion = '5.0.0'; + $this->appVersion = 20231130; + $this->displayVersion = '5.0.2'; $this->microtime = microtime(true); $commercial_dir = array(APPPATH . '/../../omk', diff --git a/app/Models/DatabaseModel.php b/app/Models/DatabaseModel.php index ae07a7a37..7c65b1487 100644 --- a/app/Models/DatabaseModel.php +++ b/app/Models/DatabaseModel.php @@ -319,6 +319,10 @@ public function update($id = null, $data = null): bool include "db_upgrades/db_5.0.0.php"; } + if (intval(config('Openaudit')->internal_version) < 20231130) { + include "db_upgrades/db_5.0.2.php"; + } + $instance = & get_instance(); $instance->data = $output; return true; diff --git a/app/Models/db_upgrades/db_5.0.2.php b/app/Models/db_upgrades/db_5.0.2.php new file mode 100644 index 000000000..3586c77cb --- /dev/null +++ b/app/Models/db_upgrades/db_5.0.2.php @@ -0,0 +1,17 @@ +query($sql); +$output .= str_replace("\n", " ", (string)$db->getLastQuery()) . "\n\n"; +log_message('info', (string)$db->getLastQuery()); + +$sql = "UPDATE `configuration` SET `value` = '5.0.2' WHERE `name` = 'display_version'"; +$db->query($sql); +$output .= str_replace("\n", " ", (string)$db->getLastQuery()) . "\n\n"; +log_message('info', (string)$db->getLastQuery()); + +$output .= "Upgrade database to 5.0.2 completed.\n\n"; +config('Openaudit')->internal_version = 20231130; +config('Openaudit')->display_version = '5.0.2'; From ea6a6ab43cb4867ee0f512f4c7cf336b593d7aeb Mon Sep 17 00:00:00 2001 From: Mark Unwin Date: Mon, 4 Dec 2023 13:06:33 +1000 Subject: [PATCH 17/43] Add directory permissions fixes in Cli, but commented out. --- app/Controllers/Cli.php | 49 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 46 insertions(+), 3 deletions(-) diff --git a/app/Controllers/Cli.php b/app/Controllers/Cli.php index ea7f4208c..a421167e3 100644 --- a/app/Controllers/Cli.php +++ b/app/Controllers/Cli.php @@ -91,14 +91,57 @@ public function executeTasks() if (empty($this->config->enterprise_binary)) { return; } + + // # Perform some directory permissions fixing + + // # Lang Files + // chmod(ROOTPATH . 'app/Views/lang/cs.inc', 0666); + // chmod(ROOTPATH . 'app/Views/lang/de.inc', 0666); + // chmod(ROOTPATH . 'app/Views/lang/en.inc', 0666); + // chmod(ROOTPATH . 'app/Views/lang/es.inc', 0666); + // chmod(ROOTPATH . 'app/Views/lang/fr.inc', 0666); + // chmod(ROOTPATH . 'app/Views/lang/pt-br.inc', 0666); + // chmod(ROOTPATH . 'app/Views/lang/zh-tw.inc', 0666); + + // # Other Dir + // chmod(ROOTPATH . 'other', 0777); + + // # Scripts Dir + // chmod(ROOTPATH . 'other/scripts', 0777); + + // # Attachments Dir + // chmod(ROOTPATH . 'app/Attachments', 0777); + + // # Uploads Dir + // chmod(ROOTPATH . 'writable/uploads', 0777); + + // # Cache Dir + // chmod(ROOTPATH . 'writable/cache', 0777); + + // # Logs Dir + // chmod(ROOTPATH . 'writable/logs', 0777); + + // # Session Dir + // chmod(ROOTPATH . 'writable/session', 0777); + + // # DebugBar Dir + // chmod(ROOTPATH . 'writable/debugbar', 0777); + + // # Custom Images Dir + // if (php_uname('s') === 'Linux') { + // chmod(ROOTPATH . 'public/custom_images', 0777); + // } + + // # Custom Images Dir + // if (php_uname('s') === 'Windows NT') { + // chmod(ROOTPATH . '../htdocs/open-audit/custom_images', 0777); + // } + $response = new stdClass(); $response->meta = new stdClass(); $response->meta->collection = 'tasks'; $response->meta->action = 'execute'; $response->meta->uuid = $this->config->uuid; - - # echo json_encode($response) . "\n"; - $db = db_connect() or die("Cannot establish a database connection."); // Insert the entry $sql = "INSERT INTO enterprise VALUES (null, ?, '', NOW(), '')"; From e87660143705c7525c8bc0850f14d636a3c27815 Mon Sep 17 00:00:00 2001 From: Mark Unwin Date: Mon, 4 Dec 2023 13:07:06 +1000 Subject: [PATCH 18/43] Ensure we return a 401 for a failed login for non-HTML requests. --- app/Controllers/Logon.php | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/app/Controllers/Logon.php b/app/Controllers/Logon.php index 923d50738..0e468b951 100644 --- a/app/Controllers/Logon.php +++ b/app/Controllers/Logon.php @@ -65,13 +65,6 @@ public function create() $password = $_SERVER['HTTP_PASSWORD']; } - if (empty($username) or empty($password)) { - # set flash need creds - $session->setFlashdata('flash', '{"level":"danger", "message":"Credentials required"}'); - log_message('error', '{"level":"danger", "message":"Credentials required"}'); - return redirect()->to(site_url('logon')); - } - $http_accept = (!empty($_SERVER['HTTP_ACCEPT'])) ? $_SERVER['HTTP_ACCEPT'] : ''; $format = ''; if (strpos($http_accept, 'application/json') !== false) { @@ -90,6 +83,17 @@ public function create() $format = 'json'; } + if (empty($username) or empty($password)) { + # set flash need creds + $session->setFlashdata('flash', '{"level":"danger", "message":"Credentials required"}'); + log_message('error', '{"level":"danger", "message":"Credentials required"}'); + if ($format === 'html') { + return redirect()->to(site_url('logon')); + } + header('HTTP/1.0 401 Unauthorized'); + echo '{"message":"Credentials required"}'; + } + $user = $logonModel->logon($username, $password); if ($user) { log_message('info', 'Valid credentials for ' . $username . ' from ' . @$this->request->getIPAddress()); @@ -118,7 +122,11 @@ public function create() exit; } log_message('info', 'Invalid credentials for ' . $username . ' from ' . @$this->request->getIPAddress()); - return redirect()->to(site_url('logon')); + if ($format === 'html') { + return redirect()->to(site_url('logon')); + } + header('HTTP/1.0 401 Unauthorized'); + echo '{"message":"Credentials required"}'; } public function delete() From a4ed50602e1f9e5ef8c0e4f5f800a92d0a5bb139 Mon Sep 17 00:00:00 2001 From: Mark Unwin Date: Mon, 4 Dec 2023 13:08:00 +1000 Subject: [PATCH 19/43] When an integration starts a discovery, set last_finished to our standard 2001 date rather than 1 second in the future. --- app/Models/IntegrationsModel.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Models/IntegrationsModel.php b/app/Models/IntegrationsModel.php index da058194f..e6e363713 100644 --- a/app/Models/IntegrationsModel.php +++ b/app/Models/IntegrationsModel.php @@ -523,7 +523,7 @@ public function execute(int $id = 0) $sql = "INSERT INTO integrations_log VALUES (null, ?, null, ?, 'info', ?)"; $this->db->query($sql, [$integration->id, microtime(true), $message]); - $sql = "UPDATE `discoveries` SET `status` = 'running', `ip_all_count` = 0, `ip_responding_count` = 0, `ip_scanned_count` = 0, `ip_discovered_count` = 0, `ip_audited_count` = 0, `last_run` = NOW(), `last_finished` = DATE_ADD(NOW(), interval 1 second) WHERE id = ?"; + $sql = "UPDATE `discoveries` SET `status` = 'running', `ip_all_count` = 0, `ip_responding_count` = 0, `ip_scanned_count` = 0, `ip_discovered_count` = 0, `ip_audited_count` = 0, `last_run` = NOW(), `last_finished` = '2001-01-01 00:00:00' WHERE id = ?"; $this->db->query($sql, [$integration->attributes->discovery_id]); $sql = "DELETE FROM discovery_log WHERE discovery_id = ?"; From 3ff327bca16608a8198219b54a0d046e4becadd7 Mon Sep 17 00:00:00 2001 From: Mark Unwin Date: Mon, 4 Dec 2023 13:08:50 +1000 Subject: [PATCH 20/43] Fix some items for CSS dark mode on devicesRead. --- public/css/open-audit.css | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/public/css/open-audit.css b/public/css/open-audit.css index bc289686a..dbc77967f 100644 --- a/public/css/open-audit.css +++ b/public/css/open-audit.css @@ -545,4 +545,36 @@ table.dataTable > thead .sorting_desc_disabled::after background-color: #333; color: white; } + .section_toggle:hover + { + cursor: pointer; + cursor: hand; + background-color: #444; + } + .mb-2 + { + border-color: #888; + color: white; + background-color: #555; + } + .link_button + { + font-size: 1.2rem; + color: white; + border: var(--bs-border-width) solid var(--bs-border-color); + background-color: #333; + } + .btn-light a + { + font-weight: 300; + background-color: #999; + } + .btn-light a:hover + { + text-decoration: none; + } + .btn-outline-secondary a + { + color: var(--bs-btn-color); + } } From e2bffa47a668c0a3bc029cfc2a10932784813a1c Mon Sep 17 00:00:00 2001 From: Mark Unwin Date: Mon, 4 Dec 2023 13:09:11 +1000 Subject: [PATCH 21/43] Bump to 5.0.2 in open-audit.sql. --- other/open-audit.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/other/open-audit.sql b/other/open-audit.sql index 108d39d83..bbbbdc72c 100644 --- a/other/open-audit.sql +++ b/other/open-audit.sql @@ -908,7 +908,7 @@ INSERT INTO `configuration` VALUES (NULL,'discovery_use_dns','y','bool','y','sys INSERT INTO `configuration` VALUES (NULL,'discovery_use_ipmi','y','bool','y','system','2000-01-01 00:00:00','Should we use ipmitool for discovering management ports if ipmitool is installed.'); INSERT INTO `configuration` VALUES (NULL,'discovery_use_org_id_match','n','bool','y','system','2000-01-01 00:00:00','When matching a device and assign_devices_to_org is set, use that attribute in the relevant match rules.'); INSERT INTO `configuration` VALUES (NULL,'discovery_use_vintage_service','n','bool','y','system','2000-01-01 00:00:00','On Windows, use the old way of running discovery with the Apache service account.'); -INSERT INTO `configuration` VALUES (NULL,'display_version','5.0.0','text','n','system','2000-01-01 00:00:00','The version shown on the web pages.'); +INSERT INTO `configuration` VALUES (NULL,'display_version','5.0.2','text','n','system','2000-01-01 00:00:00','The version shown on the web pages.'); INSERT INTO `configuration` VALUES (NULL,'download_reports','n','bool','y','system','2000-01-01 00:00:00','Tells Open-AudIT to advise the browser to download as a file or display the csv, xml, json reports.'); INSERT INTO `configuration` VALUES (NULL,'mail_domain','','text','y','system','2000-01-01 00:00:00','Email domain to use.'); INSERT INTO `configuration` VALUES (NULL,'mail_from','','text','y','system','2000-01-01 00:00:00','Email address used for as the sender.'); @@ -921,7 +921,7 @@ INSERT INTO `configuration` VALUES (NULL,'firstwave_prompt','2000-01-01','date', INSERT INTO `configuration` VALUES (NULL,'graph_days','30','number','y','system','2000-01-01 00:00:00','The number of days to report on for the Enterprise graphs.'); INSERT INTO `configuration` VALUES (NULL,'gui_trim_characters','25','number','y','system','2000-01-01 00:00:00','When showing a table of information in the web GUI, replace characters greater than this with \"...\".'); INSERT INTO `configuration` VALUES (NULL,'homepage','summaries','text','y','system','2000-01-01 00:00:00','Any links to the default page should be directed to this endpoint.'); -INSERT INTO `configuration` VALUES (NULL,'internal_version','20230615','number','n','system','2000-01-01 00:00:00','The internal numerical version.'); +INSERT INTO `configuration` VALUES (NULL,'internal_version','20231130','number','n','system','2000-01-01 00:00:00','The internal numerical version.'); INSERT INTO `configuration` VALUES (NULL,'maps_api_key','','text','y','system','2000-01-01 00:00:00','Your API key for Google Maps.'); INSERT INTO `configuration` VALUES (NULL,'match_dbus','n','bool','y','system','2000-01-01 00:00:00','Should we match a device based on its dbus id.'); INSERT INTO `configuration` VALUES (NULL,'match_dns_fqdn','n','bool','y','system','2000-01-01 00:00:00','Should we match a device based on its DNS fqdn.'); From 5a90fa92b8257e75bafd4254dcfd008e143ad5c6 Mon Sep 17 00:00:00 2001 From: Mark Unwin Date: Mon, 4 Dec 2023 13:09:26 +1000 Subject: [PATCH 22/43] Lang strings. --- app/Views/lang/en.inc | 57 +++++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/app/Views/lang/en.inc b/app/Views/lang/en.inc index f929a1b4b..880b04338 100644 --- a/app/Views/lang/en.inc +++ b/app/Views/lang/en.inc @@ -64,8 +64,8 @@ $GLOBALS["lang"]["Add Policy"]="Add Policy"; $GLOBALS["lang"]["Address"]="Address"; $GLOBALS["lang"]["Add Then"]="Add Then"; $GLOBALS["lang"]["AD Group"]="AD Group"; -$GLOBALS["lang"]["Admin"]="Admin"; $GLOBALS["lang"]["admin"]="admin"; +$GLOBALS["lang"]["Admin"]="Admin"; $GLOBALS["lang"]["Admin Status"]="Admin Status"; $GLOBALS["lang"]["ADSL Modem"]="ADSL Modem"; $GLOBALS["lang"]["Advanced"]="Advanced"; @@ -85,8 +85,8 @@ $GLOBALS["lang"]["Android"]="Android"; $GLOBALS["lang"]["Antivirus"]="Antivirus"; $GLOBALS["lang"]["Apache"]="Apache"; $GLOBALS["lang"]["API Result"]="API Result"; -$GLOBALS["lang"]["Application"]="Application"; $GLOBALS["lang"]["application"]="application"; +$GLOBALS["lang"]["Application"]="Application"; $GLOBALS["lang"]["Application Accelerator"]="Application Accelerator"; $GLOBALS["lang"]["Application Licenses"]="Application Licenses"; $GLOBALS["lang"]["Applications"]="Applications"; @@ -143,8 +143,8 @@ $GLOBALS["lang"]["Bar Code Reader"]="Bar Code Reader"; $GLOBALS["lang"]["Base DN"]="Base DN"; $GLOBALS["lang"]["Based On"]="Based On"; $GLOBALS["lang"]["Baseline"]="Baseline"; -$GLOBALS["lang"]["baselines"]="baselines"; $GLOBALS["lang"]["Baselines"]="Baselines"; +$GLOBALS["lang"]["baselines"]="baselines"; $GLOBALS["lang"]["Baselines Policies"]="Baselines Policies"; $GLOBALS["lang"]["Baselines Policy"]="Baselines Policy"; $GLOBALS["lang"]["Baselines Policy Details"]="Baselines Policy Details"; @@ -211,8 +211,8 @@ $GLOBALS["lang"]["Check Minutes"]="Check Minutes"; $GLOBALS["lang"]["Choose"]="Choose"; $GLOBALS["lang"]["Choose a Device"]="Choose a Device"; $GLOBALS["lang"]["Choose a Table"]="Choose a Table"; -$GLOBALS["lang"]["CIDR"]="CIDR"; $GLOBALS["lang"]["Cidr"]="Cidr"; +$GLOBALS["lang"]["CIDR"]="CIDR"; $GLOBALS["lang"]["CIDR Mask"]="CIDR Mask"; $GLOBALS["lang"]["Circuit Count"]="Circuit Count"; $GLOBALS["lang"]["Cisco Module"]="Cisco Module"; @@ -232,8 +232,8 @@ $GLOBALS["lang"]["Cloud Discovery"]="Cloud Discovery"; $GLOBALS["lang"]["Cloud ID"]="Cloud ID"; $GLOBALS["lang"]["Cloud Instances by Org and Type"]="Cloud Instances by Org and Type"; $GLOBALS["lang"]["Cloud Region"]="Cloud Region"; -$GLOBALS["lang"]["clouds"]="clouds"; $GLOBALS["lang"]["Clouds"]="Clouds"; +$GLOBALS["lang"]["clouds"]="clouds"; $GLOBALS["lang"]["Cloud Zone"]="Cloud Zone"; $GLOBALS["lang"]["cloud_log"]="cloud_log"; $GLOBALS["lang"]["cluster"]="cluster"; @@ -315,8 +315,8 @@ $GLOBALS["lang"]["Custom TCP Ports"]="Custom TCP Ports"; $GLOBALS["lang"]["Custom UDP Ports"]="Custom UDP Ports"; $GLOBALS["lang"]["Czech"]="Czech"; $GLOBALS["lang"]["Dallas_Office"]="Dallas_Office"; -$GLOBALS["lang"]["dashboards"]="dashboards"; $GLOBALS["lang"]["Dashboards"]="Dashboards"; +$GLOBALS["lang"]["dashboards"]="dashboards"; $GLOBALS["lang"]["Database"]="Database"; $GLOBALS["lang"]["Database Tables"]="Database Tables"; $GLOBALS["lang"]["DataCenter"]="DataCenter"; @@ -374,8 +374,8 @@ $GLOBALS["lang"]["Device ID B"]="Device ID B"; $GLOBALS["lang"]["Device Name"]="Device Name"; $GLOBALS["lang"]["Device Result"]="Device Result"; $GLOBALS["lang"]["Device Results"]="Device Results"; -$GLOBALS["lang"]["Devices"]="Devices"; $GLOBALS["lang"]["devices"]="devices"; +$GLOBALS["lang"]["Devices"]="Devices"; $GLOBALS["lang"]["Devices Audited"]="Devices Audited"; $GLOBALS["lang"]["Devices Audited per Day"]="Devices Audited per Day"; $GLOBALS["lang"]["Devices by Class"]="Devices by Class"; @@ -473,9 +473,9 @@ $GLOBALS["lang"]["Dns"]="Dns"; $GLOBALS["lang"]["dns"]="dns"; $GLOBALS["lang"]["DNS Domain"]="DNS Domain"; $GLOBALS["lang"]["DNS Domains"]="DNS Domains"; -$GLOBALS["lang"]["Dns Fqdn"]="Dns Fqdn"; $GLOBALS["lang"]["DNS Fqdn"]="DNS Fqdn"; $GLOBALS["lang"]["DNS FQDN"]="DNS FQDN"; +$GLOBALS["lang"]["Dns Fqdn"]="Dns Fqdn"; $GLOBALS["lang"]["DNS Hostname"]="DNS Hostname"; $GLOBALS["lang"]["Doctors Office"]="Doctors Office"; $GLOBALS["lang"]["Documentation"]="Documentation"; @@ -491,6 +491,8 @@ $GLOBALS["lang"]["Driver"]="Driver"; $GLOBALS["lang"]["DSLAM"]="DSLAM"; $GLOBALS["lang"]["DSL Modem"]="DSL Modem"; $GLOBALS["lang"]["Duplex"]="Duplex"; +$GLOBALS["lang"]["Duration"]="Duration"; +$GLOBALS["lang"]["Duration (hh:mm:ss)"]="Duration (hh:mm:ss)"; $GLOBALS["lang"]["Edit"]="Edit"; $GLOBALS["lang"]["Edited By"]="Edited By"; $GLOBALS["lang"]["Edited Date"]="Edited Date"; @@ -764,8 +766,8 @@ $GLOBALS["lang"]["ldap_servers"]="ldap_servers"; $GLOBALS["lang"]["Learn About"]="Learn About"; $GLOBALS["lang"]["Lease Expiry Date"]="Lease Expiry Date"; $GLOBALS["lang"]["less or equals"]="less or equals"; -$GLOBALS["lang"]["Less Than"]="Less Than"; $GLOBALS["lang"]["less than"]="less than"; +$GLOBALS["lang"]["Less Than"]="Less Than"; $GLOBALS["lang"]["Level"]="Level"; $GLOBALS["lang"]["Library"]="Library"; $GLOBALS["lang"]["License"]="License"; @@ -797,13 +799,13 @@ $GLOBALS["lang"]["Location Rack"]="Location Rack"; $GLOBALS["lang"]["Location Rack Position"]="Location Rack Position"; $GLOBALS["lang"]["Location Rack Size"]="Location Rack Size"; $GLOBALS["lang"]["Location Room"]="Location Room"; -$GLOBALS["lang"]["locations"]="locations"; $GLOBALS["lang"]["Locations"]="Locations"; +$GLOBALS["lang"]["locations"]="locations"; $GLOBALS["lang"]["Locations ID"]="Locations ID"; $GLOBALS["lang"]["Locations Name"]="Locations Name"; $GLOBALS["lang"]["Location Suite"]="Location Suite"; -$GLOBALS["lang"]["Log"]="Log"; $GLOBALS["lang"]["log"]="log"; +$GLOBALS["lang"]["Log"]="Log"; $GLOBALS["lang"]["Log Files"]="Log Files"; $GLOBALS["lang"]["Log Format"]="Log Format"; $GLOBALS["lang"]["Logical Cores "]="Logical Cores "; @@ -872,12 +874,12 @@ $GLOBALS["lang"]["Module"]="Module"; $GLOBALS["lang"]["Modules"]="Modules"; $GLOBALS["lang"]["Monday"]="Monday"; $GLOBALS["lang"]["MongoDB"]="MongoDB"; -$GLOBALS["lang"]["monitor"]="monitor"; $GLOBALS["lang"]["Monitor"]="Monitor"; +$GLOBALS["lang"]["monitor"]="monitor"; $GLOBALS["lang"]["Month"]="Month"; $GLOBALS["lang"]["Motel"]="Motel"; -$GLOBALS["lang"]["Motherboard"]="Motherboard"; $GLOBALS["lang"]["motherboard"]="motherboard"; +$GLOBALS["lang"]["Motherboard"]="Motherboard"; $GLOBALS["lang"]["Mount Point"]="Mount Point"; $GLOBALS["lang"]["Mount Type"]="Mount Type"; $GLOBALS["lang"]["MS FrontPage"]="MS FrontPage"; @@ -910,8 +912,8 @@ $GLOBALS["lang"]["network"]="network"; $GLOBALS["lang"]["Network Device"]="Network Device"; $GLOBALS["lang"]["Network IDS (Intrusion Detection)"]="Network IDS (Intrusion Detection)"; $GLOBALS["lang"]["Network Printer"]="Network Printer"; -$GLOBALS["lang"]["Networks"]="Networks"; $GLOBALS["lang"]["networks"]="networks"; +$GLOBALS["lang"]["Networks"]="Networks"; $GLOBALS["lang"]["Network Scanner"]="Network Scanner"; $GLOBALS["lang"]["Networks Generated By"]="Networks Generated By"; $GLOBALS["lang"]["Networks using a CIDR Mask of"]="Networks using a CIDR Mask of"; @@ -927,8 +929,8 @@ $GLOBALS["lang"]["Newsagent"]="Newsagent"; $GLOBALS["lang"]["News Feed"]="News Feed"; $GLOBALS["lang"]["New Software Discovered per Day"]="New Software Discovered per Day"; $GLOBALS["lang"]["Next Run"]="Next Run"; -$GLOBALS["lang"]["nmap"]="nmap"; $GLOBALS["lang"]["Nmap"]="Nmap"; +$GLOBALS["lang"]["nmap"]="nmap"; $GLOBALS["lang"]["Nmap Duration"]="Nmap Duration"; $GLOBALS["lang"]["NMIS"]="NMIS"; $GLOBALS["lang"]["Nmis Business Service"]="Nmis Business Service"; @@ -944,11 +946,11 @@ $GLOBALS["lang"]["Nmis Group"]="Nmis Group"; $GLOBALS["lang"]["Nmis Manage"]="Nmis Manage"; $GLOBALS["lang"]["Nmis Name"]="Nmis Name"; $GLOBALS["lang"]["Nmis Notes"]="Nmis Notes"; -$GLOBALS["lang"]["NMIS Poller"]="NMIS Poller"; $GLOBALS["lang"]["Nmis Poller"]="Nmis Poller"; +$GLOBALS["lang"]["NMIS Poller"]="NMIS Poller"; $GLOBALS["lang"]["Nmis Poller Uuid"]="Nmis Poller Uuid"; -$GLOBALS["lang"]["Nmis Role"]="Nmis Role"; $GLOBALS["lang"]["NMIS Role"]="NMIS Role"; +$GLOBALS["lang"]["Nmis Role"]="Nmis Role"; $GLOBALS["lang"]["No"]="No"; $GLOBALS["lang"]["No database upgrade required at this time."]="No database upgrade required at this time."; $GLOBALS["lang"]["No data in License Key"]="No data in License Key"; @@ -983,8 +985,8 @@ $GLOBALS["lang"]["OpenLDAP"]="OpenLDAP"; $GLOBALS["lang"]["Operating System"]="Operating System"; $GLOBALS["lang"]["Operating System Names"]="Operating System Names"; $GLOBALS["lang"]["Operating Systems"]="Operating Systems"; -$GLOBALS["lang"]["optical"]="optical"; $GLOBALS["lang"]["Optical"]="Optical"; +$GLOBALS["lang"]["optical"]="optical"; $GLOBALS["lang"]["Options"]="Options"; $GLOBALS["lang"]["Org"]="Org"; $GLOBALS["lang"]["Organisation"]="Organisation"; @@ -1000,8 +1002,8 @@ $GLOBALS["lang"]["OS"]="OS"; $GLOBALS["lang"]["OS Arch"]="OS Arch"; $GLOBALS["lang"]["OS Bit"]="OS Bit"; $GLOBALS["lang"]["OS Cpe"]="OS Cpe"; -$GLOBALS["lang"]["Os Family"]="Os Family"; $GLOBALS["lang"]["OS Family"]="OS Family"; +$GLOBALS["lang"]["Os Family"]="Os Family"; $GLOBALS["lang"]["OS Group"]="OS Group"; $GLOBALS["lang"]["OS Installation Date"]="OS Installation Date"; $GLOBALS["lang"]["OS Installed On"]="OS Installed On"; @@ -1018,13 +1020,13 @@ $GLOBALS["lang"]["Output"]="Output"; $GLOBALS["lang"]["Outputs"]="Outputs"; $GLOBALS["lang"]["Overwrite"]="Overwrite"; $GLOBALS["lang"]["Owner"]="Owner"; -$GLOBALS["lang"]["pagefile"]="pagefile"; $GLOBALS["lang"]["Pagefile"]="Pagefile"; +$GLOBALS["lang"]["pagefile"]="pagefile"; $GLOBALS["lang"]["Paranoid"]="Paranoid"; $GLOBALS["lang"]["Parent ID"]="Parent ID"; $GLOBALS["lang"]["Parent Name"]="Parent Name"; -$GLOBALS["lang"]["Partition"]="Partition"; $GLOBALS["lang"]["partition"]="partition"; +$GLOBALS["lang"]["Partition"]="Partition"; $GLOBALS["lang"]["Partition Count"]="Partition Count"; $GLOBALS["lang"]["Partition Disk Index"]="Partition Disk Index"; $GLOBALS["lang"]["Partition Free"]="Partition Free"; @@ -1146,8 +1148,8 @@ $GLOBALS["lang"]["Queued Items"]="Queued Items"; $GLOBALS["lang"]["Queue Limit"]="Queue Limit"; $GLOBALS["lang"]["Rack"]="Rack"; $GLOBALS["lang"]["Rack Devices"]="Rack Devices"; -$GLOBALS["lang"]["Racks"]="Racks"; $GLOBALS["lang"]["racks"]="racks"; +$GLOBALS["lang"]["Racks"]="Racks"; $GLOBALS["lang"]["rack_devices"]="rack_devices"; $GLOBALS["lang"]["radio"]="radio"; $GLOBALS["lang"]["Radio"]="Radio"; @@ -1195,8 +1197,8 @@ $GLOBALS["lang"]["Row"]="Row"; $GLOBALS["lang"]["Row Count"]="Row Count"; $GLOBALS["lang"]["Row Position"]="Row Position"; $GLOBALS["lang"]["rows"]="rows"; -$GLOBALS["lang"]["rules"]="rules"; $GLOBALS["lang"]["Rules"]="Rules"; +$GLOBALS["lang"]["rules"]="rules"; $GLOBALS["lang"]["Run Discovery"]="Run Discovery"; $GLOBALS["lang"]["Run Discovery on Devices"]="Run Discovery on Devices"; $GLOBALS["lang"]["Run the default discovery and find out \"What's On Your Network?\"."]="Run the default discovery and find out \"What's On Your Network?\"."; @@ -1221,8 +1223,8 @@ $GLOBALS["lang"]["Scan Options"]="Scan Options"; $GLOBALS["lang"]["Schedule"]="Schedule"; $GLOBALS["lang"]["Schedule Reports"]="Schedule Reports"; $GLOBALS["lang"]["School"]="School"; -$GLOBALS["lang"]["Scripts"]="Scripts"; $GLOBALS["lang"]["scripts"]="scripts"; +$GLOBALS["lang"]["Scripts"]="Scripts"; $GLOBALS["lang"]["Scsi"]="Scsi"; $GLOBALS["lang"]["scsi"]="scsi"; $GLOBALS["lang"]["Scsi Bus"]="Scsi Bus"; @@ -1258,6 +1260,7 @@ $GLOBALS["lang"]["Server :: MariaDB"]="Server :: MariaDB"; $GLOBALS["lang"]["Server :: MongoDB"]="Server :: MongoDB"; $GLOBALS["lang"]["Server :: MySQL"]="Server :: MySQL"; $GLOBALS["lang"]["Server :: NGINX"]="Server :: NGINX"; +$GLOBALS["lang"]["Server :: PostgreSQL"]="Server :: PostgreSQL"; $GLOBALS["lang"]["Server ID"]="Server ID"; $GLOBALS["lang"]["Server Is"]="Server Is"; $GLOBALS["lang"]["Server Item"]="Server Item"; @@ -1306,8 +1309,8 @@ $GLOBALS["lang"]["SNMP OID"]="SNMP OID"; $GLOBALS["lang"]["SNMP v3"]="SNMP v3"; $GLOBALS["lang"]["Snmp Version"]="Snmp Version"; $GLOBALS["lang"]["SNMP Version"]="SNMP Version"; -$GLOBALS["lang"]["software"]="software"; $GLOBALS["lang"]["Software"]="Software"; +$GLOBALS["lang"]["software"]="software"; $GLOBALS["lang"]["Software Additions by Day"]="Software Additions by Day"; $GLOBALS["lang"]["Software Found Last 7 Days"]="Software Found Last 7 Days"; $GLOBALS["lang"]["Software Found Today"]="Software Found Today"; @@ -1319,8 +1322,8 @@ $GLOBALS["lang"]["Software Policies"]="Software Policies"; $GLOBALS["lang"]["Software Version"]="Software Version"; $GLOBALS["lang"]["software_key"]="software_key"; $GLOBALS["lang"]["Solaris"]="Solaris"; -$GLOBALS["lang"]["Sound"]="Sound"; $GLOBALS["lang"]["sound"]="sound"; +$GLOBALS["lang"]["Sound"]="Sound"; $GLOBALS["lang"]["Source"]="Source"; $GLOBALS["lang"]["Spanish"]="Spanish"; $GLOBALS["lang"]["Specialized"]="Specialized"; @@ -1381,8 +1384,8 @@ $GLOBALS["lang"]["Tags :: "]="Tags :: "; $GLOBALS["lang"]["Tape Library"]="Tape Library"; $GLOBALS["lang"]["task"]="task"; $GLOBALS["lang"]["Task"]="Task"; -$GLOBALS["lang"]["Tasks"]="Tasks"; $GLOBALS["lang"]["tasks"]="tasks"; +$GLOBALS["lang"]["Tasks"]="Tasks"; $GLOBALS["lang"]["Telecom Misc"]="Telecom Misc"; $GLOBALS["lang"]["Tenant ID"]="Tenant ID"; $GLOBALS["lang"]["Tennant ID"]="Tennant ID"; From 408c3657e13fb9a079cc6a228aa39b7a73085887 Mon Sep 17 00:00:00 2001 From: Mark Unwin Date: Mon, 4 Dec 2023 13:10:43 +1000 Subject: [PATCH 23/43] improved SupportModel tests. Nmap version, lang files. Comment out no longer required items. --- app/Models/SupportModel.php | 63 +++++++++++++++++++++++-------------- 1 file changed, 40 insertions(+), 23 deletions(-) diff --git a/app/Models/SupportModel.php b/app/Models/SupportModel.php index 12769a051..8f2a3ddf8 100644 --- a/app/Models/SupportModel.php +++ b/app/Models/SupportModel.php @@ -183,7 +183,6 @@ public function collection(object $resp): array exec($command_string, $output, $return_var); $data->logs = new stdClass; $data->logs = $output; - } if (php_uname('s') === 'Windows NT') { @@ -220,19 +219,26 @@ public function collection(object $resp): array $data->php->process_owner = $posix_getpwuid['name']; unset($posix_getpwuid); } + unset($output); $data->prereq->nmap = ''; $command_string = 'nmap --version'; exec($command_string, $output, $return_var); - $data->prereq->nmap = @$output[1]; - unset($output); - $prereqs = array('screen', 'sshpass', 'curl', 'wget', 'zip', 'ipmitool', 'rrdtool', 'logrotate'); - foreach ($prereqs as $prereq) { - $command_string = 'which ' . $prereq . ' 2>/dev/null'; - exec($command_string, $output, $return_var); - $data->prereq->{$prereq} = @$output[0]; - unset($output); - unset($command_string); + if (!empty($output)) { + foreach ($output as $line) { + if (strpos($line, 'ersion') !== false) { + $data->prereq->nmap = $line; + } + } } + unset($output); + // $prereqs = array('screen', 'sshpass', 'curl', 'wget', 'zip', 'ipmitool', 'rrdtool', 'logrotate'); + // foreach ($prereqs as $prereq) { + // $command_string = 'which ' . $prereq . ' 2>/dev/null'; + // exec($command_string, $output, $return_var); + // $data->prereq->{$prereq} = @$output[0]; + // unset($output); + // unset($command_string); + // } // Samba Client $command_string = 'which smbclient 2>/dev/null'; exec($command_string, $output, $return_var); @@ -243,7 +249,7 @@ public function collection(object $resp): array unset($command_string); // winexe version - $command_string = APPPATH . '../other/winexe-static-2 --version 2>&1'; + $command_string = ROOTPATH . 'other/winexe-static-2 --version 2>&1'; exec($command_string, $output, $return_var); if (isset($output[0]) && strpos($output[0], 'winexe') === 0) { $data->prereq->winexe = $output[0]; @@ -300,9 +306,9 @@ public function collection(object $resp): array unset($command_string); } // Scripts perms - should be writable - $data->permissions->scripts = APPPATH . '../other - FAIL'; - if (is_writable(APPPATH . '../other')) { - $data->permissions->scripts = APPPATH . '../other - PASS'; + $data->permissions->scripts = ROOTPATH . 'other - FAIL'; + if (is_writable(ROOTPATH . 'other')) { + $data->permissions->scripts = ROOTPATH . 'other - PASS'; } // Attachments perms - should be writable $data->permissions->attachments = APPPATH . 'Attachments - FAIL'; @@ -310,19 +316,30 @@ public function collection(object $resp): array $data->permissions->attachments = APPPATH . 'Attachments - PASS'; } // Uploads perms - should be writable - $data->permissions->uploads = APPPATH . '../writable/uploads - FAIL'; - if (is_writable(APPPATH . '../writable/uploads')) { - $data->permissions->uploads = APPPATH . '../writable/uploads - PASS'; + $data->permissions->uploads = ROOTPATH . 'writable/uploads - FAIL'; + if (is_writable(ROOTPATH . 'writable/uploads')) { + $data->permissions->uploads = ROOTPATH . 'writable/uploads - PASS'; } // Custom Images perms - should be writable - $data->permissions->custom_images = APPPATH . '../public/custom_images - FAIL'; - if (is_writable(APPPATH . '../public/custom_images')) { - $data->permissions->custom_images = APPPATH . '../public/custom_images - PASS'; + $data->permissions->custom_images = ROOTPATH . 'public/custom_images - FAIL'; + if (is_writable(ROOTPATH . 'public/custom_images')) { + $data->permissions->custom_images = ROOTPATH . 'public/custom_images - PASS'; } // Logs perms - should be writable - $data->permissions->logs = APPPATH . '../writable/logs - FAIL'; - if (is_writable(APPPATH . '../writable/logs')) { - $data->permissions->logs = APPPATH . '../writable/logs - PASS'; + $data->permissions->logs = ROOTPATH . 'writable/logs - FAIL'; + if (is_writable(ROOTPATH . 'writable/logs')) { + $data->permissions->logs = ROOTPATH . 'writable/logs - PASS'; + } + if (!empty($_SERVER['CI_ENVIRONMENT']) and $_SERVER['CI_ENVIRONMENT'] === 'development') { + // Lang Files perms - should be writable + $files = glob(APPPATH . 'Views/lang/*.{inc}', GLOB_BRACE); + foreach ($files as $file) { + $filename = str_replace(APPPATH . 'Views/lang/', '', $file); + $data->permissions->{$filename} = $file . ' - FAIL'; + if (is_writable($file)) { + $data->permissions->{$filename} = $file . ' - PASS'; + } + } } } return array($data); From 3076c6788ba375ef7ff59e0e1272c3fd7b8ed143 Mon Sep 17 00:00:00 2001 From: Mark Unwin Date: Mon, 4 Dec 2023 13:12:15 +1000 Subject: [PATCH 24/43] Improved discovery logging when we cannot build and audit script and add the device IP to the logging for the RulesModel->execute calls. --- app/Helpers/discoveries_helper.php | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/app/Helpers/discoveries_helper.php b/app/Helpers/discoveries_helper.php index f827a102b..01f994f9c 100644 --- a/app/Helpers/discoveries_helper.php +++ b/app/Helpers/discoveries_helper.php @@ -1346,9 +1346,14 @@ function ip_audit($ip_scan = null) if (!empty($credentials_windows) or ! empty($credentials_ssh)) { $temp = $instance->scriptsModel->build(strtolower($device->os_group)); if (empty($temp)) { - $log->message = 'Could not retrieve audit script for ' . strtolower($device->os_group) . ', check system log for details.'; - $log->command_status = 'fail'; + $log->command_output = 'Could not retrieve audit script for ' . strtolower($device->os_group) . ', check ' . ROOTPATH . 'other/scripts is writable.'; + $log->command_status = 'issue'; $log->severity = 4; + if (php_uname('s') === 'Linux') { + $command_string = 'stat ' . ROOTPATH . 'other/scripts'; + exec($command_string, $output, $return_var); + $log->command = $command_string . ' : ' . json_encode($output); + } $discoveryLogModel->create($log); $log->command_status = 'notice'; $log->severity = 7; @@ -1778,11 +1783,12 @@ function ip_audit($ip_scan = null) // Run our rules to update the device attributes if (!empty($audit)) { - log_message('debug', 'rulesModel::execute::return because audit script result exists'); + log_message('debug', 'rulesModel::execute::return because audit script result exists for ' . $device->ip); $instance->rulesModel->execute($audit->system, intval($discovery->id), 'return', intval($audit->system->id)); } else { - log_message('debug', 'rulesModel::execute::update because audit script result does not exist'); - $instance->rulesModel->execute(null, intval($discovery->id), 'update', intval($device->id)); + log_message('debug', 'rulesModel::execute::update because audit script result does not exist for ' . $device->ip); + # $instance->rulesModel->execute(null, intval($discovery->id), 'update', intval($device->id)); + $instance->rulesModel->execute($device, intval($discovery->id), 'update', intval($device->id)); } if (!empty($audit)) { From 02d2d2d3453d7b0507d22b0cd8ce8cbe766d024d Mon Sep 17 00:00:00 2001 From: Mark Unwin Date: Mon, 4 Dec 2023 13:31:33 +1000 Subject: [PATCH 25/43] Improved logging in RulesModel, better determine and use IP. --- app/Models/RulesModel.php | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/app/Models/RulesModel.php b/app/Models/RulesModel.php index 00fc9ea1a..2d8d47b4d 100644 --- a/app/Models/RulesModel.php +++ b/app/Models/RulesModel.php @@ -141,9 +141,9 @@ public function execute(object $device = null, int $discovery_id = 0, string $ac $log->message = 'Running rules::execute function.'; $log->severity = 7; $log->command_status = 'notice'; - $log->file = 'm_rules'; + $log->file = 'RulesModel'; $log->function = 'execute'; - $log->command = 'Device Update '; + $log->command = 'Device Update'; $device_sub = array(); if (!empty($device)) { @@ -153,6 +153,11 @@ public function execute(object $device = null, int $discovery_id = 0, string $ac } $log->command .= "($action)."; + // If we also have a $device AND it's IP is populated, save and use that as we're likley incoming from discovery_helper with no audit result + if (!empty($device->ip)) { + $ip = $device->ip; + } + if (!empty($id)) { // Get our device $log->command_output = "Device ID supplied: {$id}"; @@ -182,6 +187,9 @@ public function execute(object $device = null, int $discovery_id = 0, string $ac $device->switch_port = ''; } $device->discovery_id = ''; + if (empty($ip)) { + $ip = $device->ip; + } } else { log_message('error', "Could not retrieve data from devices table for ID: $id. Not running Rules function."); $log->severity = 4; @@ -204,7 +212,13 @@ public function execute(object $device = null, int $discovery_id = 0, string $ac $log->discovery_id = $device->discovery_id; } $log->device_id = (!empty($device->id)) ? intval($device->id) : ''; - $log->ip = (!empty($device->ip)) ? ip_address_from_db($device->ip) : ''; + if (!empty($ip)) { + $log->ip = ip_address_from_db($ip); + } else if (!empty($device->ip)) { + $log->ip = ip_address_from_db($device->ip); + } else { + $log->ip = ''; + } $discoveryLogModel->create($log); $id = (!empty($device->id)) ? $device->id : ''; From ba51023161abed6b5347896f22cbc958b41f571a Mon Sep 17 00:00:00 2001 From: Mark Unwin Date: Mon, 4 Dec 2023 13:32:12 +1000 Subject: [PATCH 26/43] Improved fail logging in ScriptsModel when running build. Particularly when we cannot write to other/scripts. --- app/Models/ScriptsModel.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/Models/ScriptsModel.php b/app/Models/ScriptsModel.php index 10c35cd7b..1f1b3014c 100644 --- a/app/Models/ScriptsModel.php +++ b/app/Models/ScriptsModel.php @@ -22,6 +22,11 @@ public function __construct() public function build(string $operating_system = ''): array { + // First, make sure we can write to the scripts directory + if (!is_writable(ROOTPATH . 'other/scripts')) { + log_message('error', 'Cannot write to ' . ROOTPATH . 'other/scripts, so we cannot build an audit script. Discoveries will fail.'); + return array(); + } // Get and make the audit script $timestamp = date('y_m_d_H_i_s') . '_' . explode(' ', explode('.', microtime())[1])[0]; $instance = & get_instance(); From 7f2fdce754be2ba37b40830b906b7fe4923ba1fc Mon Sep 17 00:00:00 2001 From: Mark Unwin Date: Mon, 4 Dec 2023 13:33:20 +1000 Subject: [PATCH 27/43] Use IP for improved logging and better detection and handling (and logging) of the case where multiple audit scripts are running on a target simultaneously. --- app/Helpers/ssh_helper.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/app/Helpers/ssh_helper.php b/app/Helpers/ssh_helper.php index ddc3771ce..41f24d732 100644 --- a/app/Helpers/ssh_helper.php +++ b/app/Helpers/ssh_helper.php @@ -459,6 +459,10 @@ function ssh_command($parameters) unset($ssh); for ($i=0; $i < count($result); $i++) { $result[$i] = trim($result[$i]); + # Special Case + if (stripos($result[$i], 'Exiting as other audits are currently running.') !== false) { + return false; + } } $log->command_time_to_execute = (microtime(true) - $item_start); $log->command_output = @json_encode($result); @@ -575,7 +579,7 @@ function ssh_audit($parameters) $ssh = new \phpseclib3\Net\SSH2($ip, $ssh_port); $ssh->setTimeout(10); if ($credential->type === 'ssh_key') { - log_message('debug', 'Testing credentials named: ' . $credential->name); + log_message('debug', 'Testing credentials named: ' . $credential->name . ' on ' . $ip); if (!empty($credential->credentials->password)) { $key = PublicKeyLoader::load($credential->credentials->ssh_key, $credential->credentials->password); } else { @@ -600,7 +604,7 @@ function ssh_audit($parameters) unset($ssh); } } else if ($credential->type === 'ssh') { - log_message('debug', 'Testing credentials named: ' . $credential->name); + log_message('debug', 'Testing credentials named: ' . $credential->name . ' on ' . $ip); if ($ssh->login($credential->credentials->username, $credential->credentials->password)) { $log->message = "Valid credentials named {$credential->name} used to log in to {$ip}."; $log->command_status = 'success'; From e714789ace3096b034137c84d36feb00a9249e5b Mon Sep 17 00:00:00 2001 From: Mark Unwin Date: Mon, 4 Dec 2023 13:34:44 +1000 Subject: [PATCH 28/43] On discoveriesRead, show improved 'duration' times per device. Use a better IP (the discovery_log.ip, not the devices.ip) in the devices log. --- app/Views/discoveriesRead.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/Views/discoveriesRead.php b/app/Views/discoveriesRead.php index bc2793ade..7f6a9242b 100644 --- a/app/Views/discoveriesRead.php +++ b/app/Views/discoveriesRead.php @@ -439,7 +439,7 @@ - + @@ -448,7 +448,7 @@ - {'devices.ip'} ?>{'discovery_log.ip'} ?>
    + {'discovery_log.ip'}) ?>{'discovery_log.ip'} ?>
    {'devices.type'} === 'unknown') { ?> {'devices.type'} ?> {'devices.type'} === 'unclassified') { ?> @@ -463,7 +463,7 @@ {'discovery_log.message'} ?> - {'discovery_log.command_time_to_execute'} . ' ' . __('seconds') ?> + {'discovery_log.command_time_to_execute'} ?> From 8d14f206ae1ea9a90d5eabd59728bb2138c4e066 Mon Sep 17 00:00:00 2001 From: Mark Unwin Date: Mon, 4 Dec 2023 13:36:30 +1000 Subject: [PATCH 29/43] Improve a couple of 'issues' descriptions. --- app/Models/DiscoveriesModel.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/Models/DiscoveriesModel.php b/app/Models/DiscoveriesModel.php index e25885a7a..af991fe03 100644 --- a/app/Models/DiscoveriesModel.php +++ b/app/Models/DiscoveriesModel.php @@ -637,7 +637,7 @@ public function issueMap(object $issue): object $issue->action = 'add credentials'; } else if (strpos($issue->{'output'}, 'ERROR: Failed to open connection - NT_STATUS_CONNECTION_RESET') !== false) { # Windows connection from Linux Open-AudIT server - $issue->description = 'It is likely SMB1 was used in an attept to talk to Windows. SMB1 has been deprecated and now removed from most Windows install by Microsoft. Check here.'; + $issue->description = 'It is likely SMB1 was used in an attempt to talk to Windows. SMB1 has been deprecated and now removed from most Windows install by Microsoft. Check here.'; $issue->action = ''; } else if (strpos($issue->{'output'}, 'ERROR: Failed to save ADMIN$/winexesvc.exe - NT_STATUS_ACCESS_DENIED') !== false) { # Windows connection from Linux Open-AudIT server @@ -720,6 +720,12 @@ public function issueMap(object $issue): object } else if (strpos($issue->{'output'}, 'No credentials array passed to') !== false) { $issue->description = 'Ensure you have credentials for this type.'; $issue->action = 'add credentials'; + } else if (strpos($issue->{'output'}, 'Could not retrieve audit script for') !== false) { + $issue->description = 'The scripts directory at ' . ROOTPATH . 'other/scripts is not writable by the webserver. This must be fixed in order to create audit scripts to push to targets when running discovery.'; + if (php_uname('s') === 'Linux') { + $issue->description .= ' You should likely run chmod 777 ' . ROOTPATH . 'other/scripts.'; + } + $issue->action = ''; } else { $issue->description = 'Unknown'; $issue->action = ''; From 83a5f8d5f660aa92dabf12121fb04519dd6554f5 Mon Sep 17 00:00:00 2001 From: Mark Unwin Date: Mon, 4 Dec 2023 13:37:52 +1000 Subject: [PATCH 30/43] Add and use a 'permissions' function to check file perms and display where required on templates. --- app/Models/DiscoveriesModel.php | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/app/Models/DiscoveriesModel.php b/app/Models/DiscoveriesModel.php index af991fe03..8cc98dae9 100644 --- a/app/Models/DiscoveriesModel.php +++ b/app/Models/DiscoveriesModel.php @@ -46,6 +46,7 @@ public function collection(object $resp): array if ($this->sqlError($this->db->error())) { return array(); } + $this->permissions(); return format_data($query->getResult(), $resp->meta->collection); } @@ -774,6 +775,30 @@ public function listAll(): array return $query->getResult(); } + public function permissions() + { + $warning = ''; + $files = array('other/scripts'); + foreach ($files as $file) { + if (!is_writable(ROOTPATH . $file)) { + $warning .= 'ERROR: ' . ROOTPATH . $file . " is not writable.\n"; + log_message('error', ROOTPATH . $file . " is not writable."); + } + } + if (php_uname('s') !== 'Windows NT') { + $command = 'which nmap 2>/dev/null'; + exec($command, $output, $return_var); + if (!isset($output[0])) { + $warning .= "\ERROR: Cannot find Nmap"; + log_message('error', "Cannot find Nmap."); + } + } + if (!empty($warning)) { + \Config\Services::session()->setFlashdata('warning', $warning); + } + return; + } + /** * [queue description] * @param int $id The ID of the discovery to start @@ -842,6 +867,7 @@ public function read(int $id = 0): array $result[0]->attributes->scan_options->id = $scan_options_id; $result[0]->attributes->scan_options->{'discovery_scan_options.name'} = $dco[0]->name; } + $this->permissions(); return $result; } From 8233fa6c5ad2b160d0359ddd21fd443bbabee6bc Mon Sep 17 00:00:00 2001 From: Mark Unwin Date: Mon, 4 Dec 2023 13:39:24 +1000 Subject: [PATCH 31/43] Improve discoveriesModel::queue to use a last_finished time of the standard 2001 and not 1 second in the future. --- app/Models/DiscoveriesModel.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Models/DiscoveriesModel.php b/app/Models/DiscoveriesModel.php index 8cc98dae9..3a6382da9 100644 --- a/app/Models/DiscoveriesModel.php +++ b/app/Models/DiscoveriesModel.php @@ -815,7 +815,7 @@ public function queue(int $id = 0): bool $sql = 'DELETE from discovery_log WHERE discovery_id = ?'; $this->db->query($sql, [$id]); // Reset attributes - $sql = "UPDATE `discoveries` SET `status` = 'running', `ip_all_count` = 0, `ip_responding_count` = 0, `ip_scanned_count` = 0, `ip_discovered_count` = 0, `ip_audited_count` = 0, `last_run` = NOW(), `last_finished` = DATE_ADD(NOW(), interval 1 second) WHERE id = ?"; + $sql = "UPDATE `discoveries` SET `status` = 'running', `ip_all_count` = 0, `ip_responding_count` = 0, `ip_scanned_count` = 0, `ip_discovered_count` = 0, `ip_audited_count` = 0, `last_run` = NOW(), `last_finished` = '2001-01-01 00:00:00' WHERE id = ?"; $this->db->query($sql, [$id]); // Queue the item $queueModel = new \App\Models\QueueModel(); From 6d5ee1ddfadba0ae23911d22b5276548093cf933 Mon Sep 17 00:00:00 2001 From: Mark Unwin Date: Mon, 4 Dec 2023 13:42:39 +1000 Subject: [PATCH 32/43] Revise query in discoveriesModel to mark as complete and discoveries not logged to for over 30 minutes. --- app/Models/DiscoveriesModel.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/Models/DiscoveriesModel.php b/app/Models/DiscoveriesModel.php index 3a6382da9..ab62e4b7c 100644 --- a/app/Models/DiscoveriesModel.php +++ b/app/Models/DiscoveriesModel.php @@ -519,8 +519,8 @@ public function includedCollection(int $id = 0): array # TODO - Should we delete orphaned logs? # $sql = "DELETE FROM `discovery_log` WHERE `discovery_id` IN (SELECT discovery_log.discovery_id FROM discovery_log LEFT JOIN discoveries ON discovery_log.discovery_id = discoveries.id WHERE discoveries.name IS NULL GROUP BY discovery_log.discovery_id)"; - # TODO - Should we mark as completed any discoveries with status = running and last logged > 30 minutes ago? (yes) - $sql = "SELECT TIMESTAMPDIFF(HOUR, discovery_log.timestamp, now()) AS `diff`, MAX(discovery_log.id), discovery_log.timestamp, discovery_log.discovery_id FROM discovery_log LEFT JOIN `discoveries` ON discovery_log.discovery_id = discoveries.id WHERE discoveries.status = 'running' AND TIMESTAMPDIFF(MINUTE, discovery_log.timestamp, now()) > 30 GROUP BY discovery_log.discovery_id"; + # Mark as completed any discoveries with status = running and last logged > 30 minutes ago + $sql = "SELECT discoveries.status, discovery_id, MAX(discovery_log.id) AS `id`, `timestamp` FROM discovery_log LEFT JOIN discoveries ON discovery_log.discovery_id = discoveries.id WHERE discoveries.status = 'running' AND discovery_id IS NOT NULL AND TIMESTAMPDIFF(MINUTE, discovery_log.timestamp, now()) > 30 GROUP BY discovery_id"; $result = $this->db->query($sql)->getResult(); foreach ($result as $discovery) { $sql = "UPDATE `discoveries` SET `status` = 'killed' WHERE id = ?"; From 17f192139e2da4d4da1c0b5a333bd14ba550907c Mon Sep 17 00:00:00 2001 From: Mark Unwin Date: Mon, 4 Dec 2023 13:56:03 +1000 Subject: [PATCH 33/43] Add the discovery log ID on the devicesRead template to make sorting more intuitive. --- app/Views/devicesRead.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/Views/devicesRead.php b/app/Views/devicesRead.php index 8dfcc98b6..01105efee 100644 --- a/app/Views/devicesRead.php +++ b/app/Views/devicesRead.php @@ -503,6 +503,7 @@ + @@ -515,6 +516,7 @@ foreach ($included['discovery_log'] as $row) { ?> id) ?> + command_status === 'warning') { ?> From 880ef7eff12030e005b70727110634aeb23a3585 Mon Sep 17 00:00:00 2001 From: Mark Unwin Date: Mon, 4 Dec 2023 13:56:34 +1000 Subject: [PATCH 34/43] Improve SQL for device list for DiscoveriesRead template. --- app/Models/DiscoveriesModel.php | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/app/Models/DiscoveriesModel.php b/app/Models/DiscoveriesModel.php index ab62e4b7c..cac97107e 100644 --- a/app/Models/DiscoveriesModel.php +++ b/app/Models/DiscoveriesModel.php @@ -558,10 +558,28 @@ public function includedRead(int $id = 0): array $included['ips'] = $query->getResult(); - $sql = "SELECT discovery_log.ip AS `discovery_log.ip`, discovery_log.message AS `discovery_log.message`, ROUND(discovery_log.command_time_to_execute, 1) AS `discovery_log.command_time_to_execute`, devices.id AS `devices.id`, devices.type AS `devices.type`, devices.name AS `devices.name`, devices.domain AS `devices.domain`, devices.ip AS `devices.ip`, devices.os_family AS `devices.os_family`, devices.serial AS `devices.serial`, devices.status AS `devices.status`, devices.last_seen_by AS `devices.last_seen_by`, devices.last_seen AS `devices.last_seen`, devices.manufacturer AS `devices.manufacturer`, devices.class AS `devices.class`, devices.os_group AS `devices.os_group`, devices.icon AS `devices.icon`, devices.identification AS `devices.identification` FROM discovery_log LEFT JOIN devices ON (discovery_log.device_id = devices.id) WHERE discovery_log.id IN (SELECT MAX(discovery_log.id) FROM discovery_log WHERE discovery_log.message NOT LIKE '%not responding%' AND discovery_log.discovery_id = ? AND discovery_log.ip != '127.0.0.1' GROUP BY discovery_log.ip)"; - $query = $this->db->query($sql, [$id]); - $included['devices'] = $query->getResult(); + #$sql = "SELECT discovery_log.ip AS `discovery_log.ip`, discovery_log.message AS `discovery_log.message`, ROUND(discovery_log.command_time_to_execute, 1) AS `discovery_log.command_time_to_execute`, devices.id AS `devices.id`, devices.type AS `devices.type`, devices.name AS `devices.name`, devices.domain AS `devices.domain`, devices.ip AS `devices.ip`, devices.os_family AS `devices.os_family`, devices.serial AS `devices.serial`, devices.status AS `devices.status`, devices.last_seen_by AS `devices.last_seen_by`, devices.last_seen AS `devices.last_seen`, devices.manufacturer AS `devices.manufacturer`, devices.class AS `devices.class`, devices.os_group AS `devices.os_group`, devices.icon AS `devices.icon`, devices.identification AS `devices.identification` FROM discovery_log LEFT JOIN devices ON (discovery_log.device_id = devices.id) WHERE discovery_log.id IN (SELECT MAX(discovery_log.id) FROM discovery_log WHERE discovery_log.message NOT LIKE '%not responding%' AND discovery_log.discovery_id = ? AND discovery_log.ip != '127.0.0.1' GROUP BY discovery_log.ip)"; + $sql = "SELECT TIMEDIFF(MAX(discovery_log.timestamp), MIN(discovery_log.timestamp)) AS `discovery_log.command_time_to_execute`, discovery_log.ip AS `discovery_log.ip`, devices.id AS `devices.id`, devices.type AS `devices.type`, devices.name AS `devices.name`, devices.domain AS `devices.domain`, devices.ip AS `devices.ip`, devices.os_family AS `devices.os_family`, devices.serial AS `devices.serial`, devices.status AS `devices.status`, devices.last_seen_by AS `devices.last_seen_by`, devices.last_seen AS `devices.last_seen`, devices.manufacturer AS `devices.manufacturer`, devices.class AS `devices.class`, devices.os_group AS `devices.os_group`, devices.icon AS `devices.icon`, devices.identification AS `devices.identification`, '' AS `discovery_log.message` FROM discovery_log LEFT JOIN devices ON (discovery_log.device_id = devices.id) WHERE discovery_log.discovery_id = ? AND discovery_log.ip != '127.0.0.1' AND discovery_log.device_id IS NOT NULL GROUP BY discovery_log.ip"; + $query = $this->db->query($sql, [$id]); + log_message('error', 'SQL: ' . str_replace("\n", " ", (string)$this->db->getLastQuery())); + $devices = $query->getResult(); + $device_ips = array(); + foreach ($devices as $device) { + $device_ips[] = $device->{'discovery_log.ip'}; + } + $sql = "SELECT device_id, ip, message FROM discovery_log WHERE `id` IN (SELECT MAX(t2.id) FROM discovery_log t2 WHERE discovery_id = ? GROUP BY ip) AND discovery_id = ? AND ip IN ( \"" . implode('","', $device_ips) . "\") and ip != '127.0.0.1'"; + $query = $this->db->query($sql, [$id, $id]); + log_message('error', 'SQL: ' . str_replace("\n", " ", (string)$this->db->getLastQuery())); + $messages = $query->getResult(); + foreach ($messages as $message) { + foreach ($devices as $device) { + if ($message->ip === $device->{'discovery_log.ip'}) { + $device->{'discovery_log.message'} = $message->message; + } + } + } + $included['devices'] = $devices; return $included; } From 42f0e1fa90dc818ac4fac5a0609b4f2adbcc689e Mon Sep 17 00:00:00 2001 From: Mark Unwin Date: Mon, 4 Dec 2023 14:00:38 +1000 Subject: [PATCH 35/43] Ensure we have a minimum of 3.0.34 for composer for phpseclib. --- composer.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.lock b/composer.lock index 762491fcc..1427c7208 100755 --- a/composer.lock +++ b/composer.lock @@ -317,7 +317,7 @@ "require-dev": { "guzzlehttp/promises": "^2.0", "kelvinmo/simplejwt": "0.7.1", - "phpseclib/phpseclib": "^3.0", + "phpseclib/phpseclib": "^3.0.34", "phpspec/prophecy-phpunit": "^2.0", "phpunit/phpunit": "^9.0.0", "sebastian/comparator": ">=1.2.3", From c3e3a42769eec245c8aa432cc4806791a87e5234 Mon Sep 17 00:00:00 2001 From: Mark Unwin Date: Mon, 4 Dec 2023 14:03:51 +1000 Subject: [PATCH 36/43] Improve a comment as to why we don't delete discovery logs without a discovery id in DiscoveriesModel. --- app/Models/DiscoveriesModel.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Models/DiscoveriesModel.php b/app/Models/DiscoveriesModel.php index cac97107e..d60c30602 100644 --- a/app/Models/DiscoveriesModel.php +++ b/app/Models/DiscoveriesModel.php @@ -516,7 +516,7 @@ public function includedCollection(int $id = 0): array $sql = 'SELECT `id` FROM `configuration` WHERE `name` = "queue_count"'; $included['queue_id'] = $this->db->query($sql)->getResult()[0]->id; - # TODO - Should we delete orphaned logs? + # TODO - Should we delete orphaned logs? NO - there may be logs from a direct audit result upload # $sql = "DELETE FROM `discovery_log` WHERE `discovery_id` IN (SELECT discovery_log.discovery_id FROM discovery_log LEFT JOIN discoveries ON discovery_log.discovery_id = discoveries.id WHERE discoveries.name IS NULL GROUP BY discovery_log.discovery_id)"; # Mark as completed any discoveries with status = running and last logged > 30 minutes ago From 78dd7c38b74793d392f942ba8d3d7c3213929eef Mon Sep 17 00:00:00 2001 From: Mark Unwin Date: Mon, 4 Dec 2023 14:22:58 +1000 Subject: [PATCH 37/43] Remove a couple of debugging SQL query logs from DiscoveriesModel. --- app/Models/DiscoveriesModel.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/Models/DiscoveriesModel.php b/app/Models/DiscoveriesModel.php index d60c30602..271d67a5a 100644 --- a/app/Models/DiscoveriesModel.php +++ b/app/Models/DiscoveriesModel.php @@ -562,7 +562,6 @@ public function includedRead(int $id = 0): array $sql = "SELECT TIMEDIFF(MAX(discovery_log.timestamp), MIN(discovery_log.timestamp)) AS `discovery_log.command_time_to_execute`, discovery_log.ip AS `discovery_log.ip`, devices.id AS `devices.id`, devices.type AS `devices.type`, devices.name AS `devices.name`, devices.domain AS `devices.domain`, devices.ip AS `devices.ip`, devices.os_family AS `devices.os_family`, devices.serial AS `devices.serial`, devices.status AS `devices.status`, devices.last_seen_by AS `devices.last_seen_by`, devices.last_seen AS `devices.last_seen`, devices.manufacturer AS `devices.manufacturer`, devices.class AS `devices.class`, devices.os_group AS `devices.os_group`, devices.icon AS `devices.icon`, devices.identification AS `devices.identification`, '' AS `discovery_log.message` FROM discovery_log LEFT JOIN devices ON (discovery_log.device_id = devices.id) WHERE discovery_log.discovery_id = ? AND discovery_log.ip != '127.0.0.1' AND discovery_log.device_id IS NOT NULL GROUP BY discovery_log.ip"; $query = $this->db->query($sql, [$id]); - log_message('error', 'SQL: ' . str_replace("\n", " ", (string)$this->db->getLastQuery())); $devices = $query->getResult(); $device_ips = array(); foreach ($devices as $device) { @@ -570,7 +569,6 @@ public function includedRead(int $id = 0): array } $sql = "SELECT device_id, ip, message FROM discovery_log WHERE `id` IN (SELECT MAX(t2.id) FROM discovery_log t2 WHERE discovery_id = ? GROUP BY ip) AND discovery_id = ? AND ip IN ( \"" . implode('","', $device_ips) . "\") and ip != '127.0.0.1'"; $query = $this->db->query($sql, [$id, $id]); - log_message('error', 'SQL: ' . str_replace("\n", " ", (string)$this->db->getLastQuery())); $messages = $query->getResult(); foreach ($messages as $message) { foreach ($devices as $device) { From b308c59a4215ff4af7558b75c2da6d2324f13b6a Mon Sep 17 00:00:00 2001 From: Mark Unwin Date: Mon, 4 Dec 2023 15:54:07 +1000 Subject: [PATCH 38/43] In DiscoveryLogModel, ALWAYS grab a new timestamp from MySQL for each log. This is a change from using the PHP timestamp and removes the need to set 'timezone' in the app code. --- app/Models/DiscoveryLogModel.php | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/app/Models/DiscoveryLogModel.php b/app/Models/DiscoveryLogModel.php index 4b6bf8049..dc52cef81 100644 --- a/app/Models/DiscoveryLogModel.php +++ b/app/Models/DiscoveryLogModel.php @@ -136,14 +136,8 @@ public function create($data = null): ?int $data->command_status = (!empty($data->command_status)) ? $data->command_status : ''; $data->command_time_to_execute = (!empty($data->command_time_to_execute)) ? $data->command_time_to_execute : 0; $data->command_output = (!empty($data->command_output)) ? $data->command_output : ''; - if (empty($data->timestamp)) { - $data->timestamp = date('Y-m-d H:i:s'); - #log_message('debug', 'timetamp is empty, log is: ' . $data->message . ' :: ' . $data->command); - } else { - #log_message('debug', 'timetamp is NOT empty, log is: ' . $data->message . ' :: ' . $data->command); - } - // NOTE - Not using the above as it causes timestamp -> id order issues. May affect Collectors? - $data->timestamp = date('Y-m-d H:i:s'); + $sql = "SELECT NOW() as `timestamp`"; + $data->timestamp = $this->db->query($sql)->getResult()[0]->timestamp; if (!empty($data->message) and stripos($data->message, 'Collector - Starting discovery') !== false and !empty($data->discovery_id)) { // Special clear of local discovery logs if start of a Collector discovery From 6235be59aac1495df30b45937658a74f7f40aa78 Mon Sep 17 00:00:00 2001 From: Mark Unwin Date: Tue, 5 Dec 2023 11:45:14 +1000 Subject: [PATCH 39/43] Fix link to the opEvents FirstWave webpage. --- app/Config/OpenAudit.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Config/OpenAudit.php b/app/Config/OpenAudit.php index 20ae36d21..8d45dabd2 100755 --- a/app/Config/OpenAudit.php +++ b/app/Config/OpenAudit.php @@ -180,7 +180,7 @@ public function __construct() $opLicense = $this->commercial_dir . "/bin/oplicense-cli.pl"; $modules[] = (object)array("name" => "Applications", "url" => (file_exists($this->commercial_dir)) ? "/omk" : ""); $modules[] = (object)array("name" => "opCharts", "url" => (in_array('opCharts', $apps)) ? "/omk/opCharts" : "https://firstwave.com/products/interactive-dashboards-and-charts/"); - $modules[] = (object)array("name" => "opEvents", "url" => (in_array('opEvents', $apps)) ? "/omk/opEvents/" : "https://firstwave.com/opevents-traps-network-event-management/"); + $modules[] = (object)array("name" => "opEvents", "url" => (in_array('opEvents', $apps)) ? "/omk/opEvents/" : "https://firstwave.com/products/centralized-log-and-event-management/"); $modules[] = (object)array("name" => "opConfig", "url" => (in_array('opConfig', $apps)) ? "/omk/opConfig" : "https://firstwave.com/products/network-configuration-management/"); $modules[] = (object)array("name" => "opHA", "url" => (in_array('opHA', $apps)) ? "/omk/opHA" : "https://firstwave.com/products/distributed-network-management/"); $modules[] = (object)array("name" => "opReports", "url" => (in_array('opReports', $apps)) ? "/omk/opReports/" : "https://firstwave.com/products/advanced-analysis-and-reporting/"); From 5f34b20319c8231d4596328e2f511fa443306840 Mon Sep 17 00:00:00 2001 From: Mark Unwin Date: Tue, 5 Dec 2023 11:45:54 +1000 Subject: [PATCH 40/43] SNMP device OID <-> attribute improvements. --- app/Helpers/snmp_10892_helper.php | 15 +++++++++++++++ app/Helpers/snmp_2275_helper.php | 16 ++++++++++++++++ app/Helpers/snmp_23629_helper.php | 18 ++++++++++++++++++ app/Helpers/snmp_2_helper.php | 17 +++++++++++++++++ app/Helpers/snmp_674_helper.php | 15 +++++++++++++++ app/Helpers/snmp_9_helper.php | 25 +++++++++++++++++++++++++ app/Helpers/snmp_helper.php | 12 ++++++++++++ 7 files changed, 118 insertions(+) create mode 100644 app/Helpers/snmp_10892_helper.php create mode 100644 app/Helpers/snmp_2275_helper.php create mode 100644 app/Helpers/snmp_23629_helper.php create mode 100644 app/Helpers/snmp_2_helper.php diff --git a/app/Helpers/snmp_10892_helper.php b/app/Helpers/snmp_10892_helper.php new file mode 100644 index 000000000..ecd0a8928 --- /dev/null +++ b/app/Helpers/snmp_10892_helper.php @@ -0,0 +1,15 @@ +type = 'unknown'; + $details->model = my_snmp_get($ip, $credentials, "1.3.6.1.4.1.10529.300.1.3.1.0"); + $details->serial = my_snmp_get($ip, $credentials, "1.3.6.1.4.1.10529.300.1.3.5.0"); + return($details); +}; diff --git a/app/Helpers/snmp_2275_helper.php b/app/Helpers/snmp_2275_helper.php new file mode 100644 index 000000000..4cb582669 --- /dev/null +++ b/app/Helpers/snmp_2275_helper.php @@ -0,0 +1,16 @@ +model = my_snmp_get($ip, $credentials, "1.3.6.1.4.1.3375.2.1.3.5.2.0"); + $details->serial = my_snmp_get($ip, $credentials, "1.3.6.1.4.1.3375.2.1.3.3.3.0"); + $details->os_version = my_snmp_get($ip, $credentials, "1.3.6.1.4.1.3375.2.1.4.2.0"); + $details->uptime = my_snmp_get($ip, $credentials, "1.3.6.1.2.1.25.1.1"); + return($details); +}; diff --git a/app/Helpers/snmp_23629_helper.php b/app/Helpers/snmp_23629_helper.php new file mode 100644 index 000000000..e6f9bb8da --- /dev/null +++ b/app/Helpers/snmp_23629_helper.php @@ -0,0 +1,18 @@ +type = 'unknown'; + $details->manufacturer = my_snmp_get($ip, $credentials, "1.3.6.1.4.1.674.10892.2.1.1.4.0"); + $details->model = my_snmp_get($ip, $credentials, "1.3.6.1.4.1.674.10892.2.1.1.2.0"); + $details->serial = my_snmp_get($ip, $credentials, "1.3.6.1.4.1.674.10892.2.1.1.6.0"); + $details->os_name = my_snmp_get($ip, $credentials, "1.3.6.1.4.1.674.10892.2.1.1.1.0"); + $details->os_version = my_snmp_get($ip, $credentials, "1.3.6.1.4.1.674.10892.2.1.2.1.0"); + return($details); +}; diff --git a/app/Helpers/snmp_2_helper.php b/app/Helpers/snmp_2_helper.php new file mode 100644 index 000000000..e162801ad --- /dev/null +++ b/app/Helpers/snmp_2_helper.php @@ -0,0 +1,17 @@ +model = my_snmp_get($ip, $credentials, "1.3.6.1.4.1.2.3.51.2.2.21.1.1.2.0"); + $details->serial = my_snmp_get($ip, $credentials, "1.3.6.1.4.1.2.3.51.2.2.21.1.1.3.0"); + $details->os_version = my_snmp_get($ip, $credentials, "1.3.6.1.4.1.2.3.51.2.2.21.3.1.1.3.1"); + $details->os_name = my_snmp_get($ip, $credentials, "1.3.6.1.4.1.2.3.51.2.2.21.3.1.1.2.1"); + + return($details); +}; diff --git a/app/Helpers/snmp_674_helper.php b/app/Helpers/snmp_674_helper.php index 9584cd6e1..89a9998f2 100644 --- a/app/Helpers/snmp_674_helper.php +++ b/app/Helpers/snmp_674_helper.php @@ -9,6 +9,21 @@ $get_oid_details = function ($ip, $credentials, $oid) { $details = new \StdClass(); $details->model = my_snmp_get($ip, $credentials, "1.3.6.1.4.1.674.10892.2.1.1.2.0"); + if (empty($details->model)) { + $details->model = my_snmp_get($ip, $credentials, "1.3.6.1.4.1.674.10892.5.1.3.12.0"); + } $details->serial = my_snmp_get($ip, $credentials, "1.3.6.1.4.1.674.10892.2.1.1.11.0"); + if (empty($details->serial)) { + $details->serial = my_snmp_get($ip, $credentials, "1.3.6.1.4.1.674.10892.5.1.3.2.0"); + } + if (empty($details->serial)) { + $details->serial = my_snmp_get($ip, $credentials, "1.3.6.1.4.1.674.10892.5.1.2.1.0"); + } + $details->os_name = my_snmp_get($ip, $credentials, "1.3.6.1.4.1.674.10892.5.1.3.6.0"); + $details->os_version = my_snmp_get($ip, $credentials, "1.3.6.1.4.1.674.10892.5.1.3.14.0"); + $temp = my_snmp_get($ip, $credentials, "1.3.6.1.4.1.674.10892.5.1.1.4"); + if (!empty($temp)) { + $details->manufacturer = $temp; + } return($details); }; diff --git a/app/Helpers/snmp_9_helper.php b/app/Helpers/snmp_9_helper.php index 6657c886d..a64e15528 100644 --- a/app/Helpers/snmp_9_helper.php +++ b/app/Helpers/snmp_9_helper.php @@ -130,5 +130,30 @@ $details->serial = str_replace('VDH=', '', $details->serial); } + # 3560 + if (empty($details->model)) { + $details->model = my_snmp_get($ip, $credentials, "1.3.6.1.2.1.47.1.1.1.1.2.1001"); + } + + # 3560 + if (empty($details->os_version)) { + $details->os_version = my_snmp_get($ip, $credentials, "1.3.6.1.2.1.47.1.1.1.1.10.1001"); + } + + # 3560 + if (empty($details->serial)) { + $details->serial = $my_snmp_get($ip, $credentials, "1.3.6.1.2.1.47.1.1.1.1.11.1001"); + } + + # ASR + if (empty($details->os_version)) { + $details->os_version = $my_snmp_get($ip, $credentials, "1.3.6.1.2.1.47.1.1.1.1.10.7000"); + } + + # 9300 + if (empty($details->os_name)) { + $details->os_name = $my_snmp_get($ip, $credentials, "1.3.6.1.4.1.9.9.249.1.1.1.1.2"); + } + return($details); }; diff --git a/app/Helpers/snmp_helper.php b/app/Helpers/snmp_helper.php index 5d0e6fc60..d0021f6d6 100644 --- a/app/Helpers/snmp_helper.php +++ b/app/Helpers/snmp_helper.php @@ -792,6 +792,18 @@ function snmp_audit(string $ip = '', object $credentials = null, int $discovery_ $discoveryLogModel->create($log); unset($log->id, $log->command, $log->command_time_to_execute); } + // guess at model using entity mib #3 + if (empty($details->model)) { + $item_start = microtime(true); + $details->model = my_snmp_get($ip, $credentials, '1.3.6.1.2.1.47.1.1.1.1.13.1'); + $log->command_time_to_execute = (microtime(true) - $item_start); + $log->message = 'Model based on Entity MIB retrieval for '.$ip; + $log->command = 'snmpget 1.3.6.1.2.1.47.1.1.1.1.13.1'; + $log->command_output = (string)$details->model; + $log->command_status = 'notice'; + $discoveryLogModel->create($log); + unset($log->id, $log->command, $log->command_time_to_execute); + } // guess at model using host resources mib if (empty($details->model)) { $item_start = microtime(true); From 1d3ab976015b7a5349b569b1b500f644eb278017 Mon Sep 17 00:00:00 2001 From: Mark Unwin Date: Tue, 5 Dec 2023 11:51:36 +1000 Subject: [PATCH 41/43] Add the Samba version to the Support Output. --- app/Helpers/snmp_23629_helper.php | 18 ------------------ app/Models/SupportModel.php | 6 ++++++ 2 files changed, 6 insertions(+), 18 deletions(-) delete mode 100644 app/Helpers/snmp_23629_helper.php diff --git a/app/Helpers/snmp_23629_helper.php b/app/Helpers/snmp_23629_helper.php deleted file mode 100644 index e6f9bb8da..000000000 --- a/app/Helpers/snmp_23629_helper.php +++ /dev/null @@ -1,18 +0,0 @@ -type = 'unknown'; - $details->manufacturer = my_snmp_get($ip, $credentials, "1.3.6.1.4.1.674.10892.2.1.1.4.0"); - $details->model = my_snmp_get($ip, $credentials, "1.3.6.1.4.1.674.10892.2.1.1.2.0"); - $details->serial = my_snmp_get($ip, $credentials, "1.3.6.1.4.1.674.10892.2.1.1.6.0"); - $details->os_name = my_snmp_get($ip, $credentials, "1.3.6.1.4.1.674.10892.2.1.1.1.0"); - $details->os_version = my_snmp_get($ip, $credentials, "1.3.6.1.4.1.674.10892.2.1.2.1.0"); - return($details); -}; diff --git a/app/Models/SupportModel.php b/app/Models/SupportModel.php index 8f2a3ddf8..b82f93fad 100644 --- a/app/Models/SupportModel.php +++ b/app/Models/SupportModel.php @@ -244,6 +244,12 @@ public function collection(object $resp): array exec($command_string, $output, $return_var); if (isset($output[0])) { $data->prereq->sambaclient = $output[0]; + $command_string = 'smbclient --version'; + unset($output); + exec($command_string, $output, $return_var); + if (isset($output[0])) { + $data->prereq->sambaclient = $output[0]; + } } unset($output); unset($command_string); From 88fd462eb17eed1e44f448e66fe811218c27e719 Mon Sep 17 00:00:00 2001 From: Mark Unwin Date: Tue, 5 Dec 2023 13:18:57 +1000 Subject: [PATCH 42/43] Use 'success' button to populate the example devices for colour consistency. --- app/Views/devicesExampleForm.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Views/devicesExampleForm.php b/app/Views/devicesExampleForm.php index 36a1d115c..d5d1a7824 100644 --- a/app/Views/devicesExampleForm.php +++ b/app/Views/devicesExampleForm.php @@ -15,7 +15,7 @@



    - +

    From a2f56386574b938cf7e24fb59271cea76c24c090 Mon Sep 17 00:00:00 2001 From: Mark Unwin Date: Tue, 5 Dec 2023 13:19:17 +1000 Subject: [PATCH 43/43] CollectorsModel disctionary updates. --- app/Models/CollectorsModel.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/app/Models/CollectorsModel.php b/app/Models/CollectorsModel.php index d2bda3ec1..98d83a715 100644 --- a/app/Models/CollectorsModel.php +++ b/app/Models/CollectorsModel.php @@ -230,11 +230,13 @@ public function dictionary(): object $dictionary->columns->ip = 'The IP address of this collector used to communicate with the server.'; $dictionary->columns->network_address = 'The collectors internal IP used when it runs a discovery.'; $dictionary->columns->type = 'A collector is either in Collector or Stand-Alone mode.'; - $dictionary->columns->status = 'Unused.'; - $dictionary->columns->os = 'Unused.'; - $dictionary->columns->options = 'Unused.'; + $dictionary->columns->os = 'Automatically populated based on the Collectors OS.'; + $dictionary->columns->host = 'The URL of your Open-AudIT Server that this Collector will report to (no trailing slash).'; + $dictionary->columns->community = 'The web directory on the host that Open-AudIT is installed (requires a trailing slash).'; $dictionary->columns->user_id = 'The user account this collector uses. Links to users.id.'; $dictionary->columns->uuid = 'This collectors universally unique identifier.'; + $dictionary->columns->options = 'Unused.'; + $dictionary->columns->status = 'Auto populated by the Open-AudIT Server.'; $dictionary->columns->edited_by = $instance->dictionary->edited_by; $dictionary->columns->edited_date = $instance->dictionary->edited_date; return $dictionary;
    {'id'} ?> {'discoveries.name'} ?> timestamp ?>