From bce6a59040360a75fa98b2456d3ad75fd42a0ae6 Mon Sep 17 00:00:00 2001 From: Mark Unwin Date: Mon, 18 Mar 2024 11:02:28 +1000 Subject: [PATCH 01/26] Change schema change_log.user_id -> change_log.ack_by. --- app/Models/db_upgrades/db_5.2.0.php | 14 ++++++++++++++ other/open-audit.sql | 2 +- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/app/Models/db_upgrades/db_5.2.0.php b/app/Models/db_upgrades/db_5.2.0.php index 9ad67403a..0c7cdfd01 100644 --- a/app/Models/db_upgrades/db_5.2.0.php +++ b/app/Models/db_upgrades/db_5.2.0.php @@ -1,6 +1,20 @@ fieldExists('user_id', 'change_log')) { + $sql = "ALTER TABLE `change_log` DROP `user_id`"; + $db->query($sql); + $output .= str_replace("\n", " ", (string)$db->getLastQuery()) . "\n\n"; + log_message('info', (string)$db->getLastQuery()); +} + +if (!$db->fieldExists('ack_by', 'change_log')) { + $sql = "ALTER TABLE `change_log` ADD `ack_by` varchar(200) NOT NULL DEFAULT ''"; + $db->query($sql); + $output .= str_replace("\n", " ", (string)$db->getLastQuery()) . "\n\n"; + log_message('info', (string)$db->getLastQuery()); +} + $sql = "DELETE FROM `configuration` WHERE `name` IN ('product', 'oae_product')"; $db->query($sql); $output .= str_replace("\n", " ", (string)$db->getLastQuery()) . "\n\n"; diff --git a/other/open-audit.sql b/other/open-audit.sql index c1b8491a7..9c1a810c7 100644 --- a/other/open-audit.sql +++ b/other/open-audit.sql @@ -557,7 +557,7 @@ CREATE TABLE `change_log` ( `db_row` int(10) unsigned NOT NULL DEFAULT '0', `db_action` enum('','create','update','delete') NOT NULL DEFAULT '', `details` text NOT NULL, - `user_id` int(10) unsigned DEFAULT NULL, + `ack_by` varchar(200) NOT NULL DEFAULT '', `ack_time` datetime NOT NULL DEFAULT '2000-01-01 00:00:00', `external_link` varchar(200) NOT NULL DEFAULT '', `external_ident` varchar(200) NOT NULL DEFAULT '', From 8676183921e3e48a55a9fab9dd40906dca2da8f3 Mon Sep 17 00:00:00 2001 From: Mark Unwin Date: Mon, 18 Mar 2024 11:51:10 +1000 Subject: [PATCH 02/26] Provide a link from the change log to the component on componentsRead. --- app/Views/componentsRead.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/Views/componentsRead.php b/app/Views/componentsRead.php index b17e083f5..2b376a4fe 100644 --- a/app/Views/componentsRead.php +++ b/app/Views/componentsRead.php @@ -30,6 +30,9 @@ } else if ($data[0]->type === 'policy' and $key === 'options') { $resource->{$key} = html_entity_decode($resource->{$key}); echo read_text_box($key, $resource->{$key}); + } else if ($data[0]->type === 'change_log' and $key === 'db_row') { + $link = ""; + echo read_field($key, $resource->{$key}, '', false, $label, $link); } else { $label = ''; if ($key === 'id') { From 471ef06fc1b28e5ec1358698dc1f98c8e79ae9ce Mon Sep 17 00:00:00 2001 From: Mark Unwin Date: Mon, 18 Mar 2024 12:04:40 +1000 Subject: [PATCH 03/26] Change schema. change_log.note -> change_log.notes. Varchar to text, as per other notes columns. --- app/Models/ComponentsModel.php | 4 ++-- app/Models/db_upgrades/db_5.2.0.php | 9 ++++++++- other/open-audit.sql | 2 +- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/app/Models/ComponentsModel.php b/app/Models/ComponentsModel.php index 1ae642417..f53855c76 100644 --- a/app/Models/ComponentsModel.php +++ b/app/Models/ComponentsModel.php @@ -1277,7 +1277,7 @@ public function upsert(string $table = '', object $device = null, array $data = } $alert_details = substr($alert_details, 0, -2); $alert_details = "Item added to {$table} - {$alert_details}"; - $sql = 'INSERT INTO change_log (device_id, db_table, db_row, db_action, details, `timestamp`) VALUES (?, ?, ?, ?, ?, ?)'; + $sql = 'INSERT INTO change_log (device_id, db_table, db_row, db_action, details, `timestamp`, `notes`) VALUES (?, ?, ?, ?, ?, ?, "")'; $query = $this->db->query($sql, [intval($device->id), "{$table}", intval($id), 'create', "{$alert_details}", "{$device->last_seen}"]); // add a count to our chart table $sql = "INSERT INTO chart (`when`, `what`, `org_id`, `count`) VALUES (DATE(NOW()), '{$table}_create', " . intval($device->org_id) . ', 1) ON DUPLICATE KEY UPDATE `count` = `count` + 1'; @@ -1384,7 +1384,7 @@ public function upsert(string $table = '', object $device = null, array $data = } $alert_details = substr($alert_details, 0, -2); $alert_details = "Item removed from {$table} - {$alert_details}"; - $sql = 'INSERT INTO change_log (device_id, db_table, db_row, db_action, details, `timestamp`) VALUES (?, ?, ?, ?, ?, ?)'; + $sql = 'INSERT INTO change_log (device_id, db_table, db_row, db_action, details, `timestamp`, `notes`) VALUES (?, ?, ?, ?, ?, ?, "")'; $query = $this->db->query($sql, [intval($device->id), "{$table}", intval($db_item->id), 'delete', "{$alert_details}", "{$device->last_seen}"]); // add a count to our chart table $sql = "INSERT INTO chart (`when`, `what`, `org_id`, `count`) VALUES (DATE(NOW()), '{$table}_delete', " . intval($device->org_id) . ', 1) ON DUPLICATE KEY UPDATE `count` = `count` + 1'; diff --git a/app/Models/db_upgrades/db_5.2.0.php b/app/Models/db_upgrades/db_5.2.0.php index 0c7cdfd01..b49754219 100644 --- a/app/Models/db_upgrades/db_5.2.0.php +++ b/app/Models/db_upgrades/db_5.2.0.php @@ -9,7 +9,14 @@ } if (!$db->fieldExists('ack_by', 'change_log')) { - $sql = "ALTER TABLE `change_log` ADD `ack_by` varchar(200) NOT NULL DEFAULT ''"; + $sql = "ALTER TABLE `change_log` ADD `ack_by` varchar(200) NOT NULL DEFAULT '' AFTER `details`"; + $db->query($sql); + $output .= str_replace("\n", " ", (string)$db->getLastQuery()) . "\n\n"; + log_message('info', (string)$db->getLastQuery()); +} + +if (!$db->fieldExists('notes', 'change_log') and $db->fieldExists('note', 'change_log')) { + $sql = "ALTER TABLE `change_log` CHANGE `note` `notes` TEXT NOT NULL"; $db->query($sql); $output .= str_replace("\n", " ", (string)$db->getLastQuery()) . "\n\n"; log_message('info', (string)$db->getLastQuery()); diff --git a/other/open-audit.sql b/other/open-audit.sql index 9c1a810c7..1ab313144 100644 --- a/other/open-audit.sql +++ b/other/open-audit.sql @@ -561,7 +561,7 @@ CREATE TABLE `change_log` ( `ack_time` datetime NOT NULL DEFAULT '2000-01-01 00:00:00', `external_link` varchar(200) NOT NULL DEFAULT '', `external_ident` varchar(200) NOT NULL DEFAULT '', - `note` varchar(200) NOT NULL DEFAULT '', + `notes` text NOT NULL, `change_id` int(10) unsigned DEFAULT NULL, `change_type` enum('','standard','normal','emergency','unauthorised') NOT NULL DEFAULT '', `timestamp` datetime NOT NULL DEFAULT '2000-01-01 00:00:00', From 99f72f30a5cbb2a13fda3029898d196e0ce37a15 Mon Sep 17 00:00:00 2001 From: Mark Unwin Date: Mon, 18 Mar 2024 17:29:54 +1000 Subject: [PATCH 04/26] Initial new feature - executables for Linux. --- app/Config/OpenAudit.php | 3 +- app/Config/Routes.php | 2 +- app/Helpers/components_helper.php | 3 + app/Helpers/response_helper.php | 6 +- app/Helpers/utility_helper.php | 11 ++ app/Models/ComponentsModel.php | 4 +- app/Models/DevicesModel.php | 4 +- app/Models/ExecutablesModel.php | 252 ++++++++++++++++++++++++++++ app/Models/ScriptsModel.php | 24 +++ app/Models/db_upgrades/db_5.2.0.php | 72 ++++++++ app/Views/devicesRead.php | 41 ++++- app/Views/executablesCollection.php | 52 ++++++ app/Views/executablesCreateform.php | 62 +++++++ app/Views/executablesRead.php | 73 ++++++++ app/Views/lang/en.inc | 2 + app/Views/shared/header.php | 9 + other/audit_linux.sh | 63 +++++++ other/open-audit.sql | 84 +++++++++- public/icons/executable.svg | 63 +++++++ 19 files changed, 817 insertions(+), 13 deletions(-) create mode 100644 app/Models/ExecutablesModel.php create mode 100644 app/Views/executablesCollection.php create mode 100644 app/Views/executablesCreateform.php create mode 100644 app/Views/executablesRead.php mode change 100755 => 100644 app/Views/lang/en.inc create mode 100755 public/icons/executable.svg diff --git a/app/Config/OpenAudit.php b/app/Config/OpenAudit.php index d900fc032..f063105a6 100755 --- a/app/Config/OpenAudit.php +++ b/app/Config/OpenAudit.php @@ -14,7 +14,7 @@ class OpenAudit extends BaseConfig public string $displayVersion = '5.1.0'; public int $appVersion = 20240104; - public array $enterprise_collections = array('applications' => 'cud', 'baselines' => 'crud', 'baselines_policies' => 'crud', 'baselines_results' => 'crud', 'clouds' => 'crud', 'collectors' => 'crud', 'dashboards' => 'cud', 'discovery_scan_options' => 'cud', 'files' => 'crud', 'integrations' => 'crud', 'racks' => 'crud', 'roles' => 'cu'); + public array $enterprise_collections = array('applications' => 'cud', 'baselines' => 'crud', 'baselines_policies' => 'crud', 'baselines_results' => 'crud', 'clouds' => 'crud', 'collectors' => 'crud', 'dashboards' => 'cud', 'discovery_scan_options' => 'cud', 'files' => 'crud', 'executables' => 'crud', 'integrations' => 'crud', 'racks' => 'crud', 'roles' => 'cu'); public array $professional_collections = array('applications' => 'r', 'clusters' => 'crud', 'dashboards' => 'r', 'discovery_scan_options' => 'r', 'maps' => 'crud', 'rules' => 'crud', 'tasks' => 'crud', 'widgets' => 'crud'); public float $microtime = 0; public int $collector_connect_timeout = 10; @@ -32,6 +32,7 @@ class OpenAudit extends BaseConfig public string $server_os = ''; public string $server_platform = ''; public bool $advanced_queries = true; + public bool $executables = false; public function __set($key, $value) { diff --git a/app/Config/Routes.php b/app/Config/Routes.php index 0439793ee..fa2a1f888 100755 --- a/app/Config/Routes.php +++ b/app/Config/Routes.php @@ -15,7 +15,7 @@ */ $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', +'configuration','connections','credentials','dashboards','devices','discoveries','discovery_log','discovery_scan_options','errors','executables','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'); diff --git a/app/Helpers/components_helper.php b/app/Helpers/components_helper.php index a3ae20540..4cf0ae68f 100644 --- a/app/Helpers/components_helper.php +++ b/app/Helpers/components_helper.php @@ -19,6 +19,9 @@ function match_columns($table) if ($table === 'dns') { $match_columns = array('ip', 'name', 'fqdn'); } + if ($table === 'executable') { + $match_columns = array('full_name', 'hash', 'inode', 'last_changed'); + } if ($table === 'file') { $match_columns = array('full_name', 'hash', 'inode', 'last_changed'); } diff --git a/app/Helpers/response_helper.php b/app/Helpers/response_helper.php index e67c76ab7..02b23894a 100644 --- a/app/Helpers/response_helper.php +++ b/app/Helpers/response_helper.php @@ -1498,7 +1498,7 @@ function response_valid_actions() */ function response_valid_collections() { - 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'); + 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','executables','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'); } } @@ -1532,7 +1532,7 @@ function response_valid_formats() */ function response_valid_includes() { - return array('application', 'attachment', 'audit_log', 'bios', 'certificate', 'change_log', 'cluster', 'credential', 'discovery_log', 'disk', 'dns', 'edit_log', 'field', 'file', 'image', 'ip', 'location', 'log', 'memory', 'module', 'monitor', 'motherboard', 'netstat', 'network', 'nmap', 'optical', 'pagefile', 'partition', 'policy', 'print_queue', 'processor', 'purchase', 'rack_devices', 'radio', 'route', 'san', 'scsi', 'server', 'server_item', 'service', 'share', 'software', 'software_key', 'sound', 'task', 'usb', 'user', 'user_group', 'variable', 'video', 'vm', 'windows'); + return array('application', 'attachment', 'audit_log', 'bios', 'certificate', 'change_log', 'cluster', 'credential', 'discovery_log', 'disk', 'dns', 'edit_log', 'executable', 'field', 'file', 'image', 'ip', 'location', 'log', 'memory', 'module', 'monitor', 'motherboard', 'netstat', 'network', 'nmap', 'optical', 'pagefile', 'partition', 'policy', 'print_queue', 'processor', 'purchase', 'rack_devices', 'radio', 'route', 'san', 'scsi', 'server', 'server_item', 'service', 'share', 'software', 'software_key', 'sound', 'task', 'usb', 'user', 'user_group', 'variable', 'video', 'vm', 'windows'); } } @@ -1588,7 +1588,7 @@ function response_valid_permissions($collection) */ function response_valid_sub_resources() { - return array('application', 'attachment', 'audit_log', 'bios', 'certificate', 'change_log', 'cluster', 'credential', 'discovery', 'discovery_log', 'disk', 'dns', 'edit_log', 'field', 'image', 'ip', 'log', 'memory', 'module', 'monitor', 'motherboard', 'netstat', 'network', 'nmap', 'optical', 'pagefile', 'partition', 'partition_graph', 'policy', 'print_queue', 'processor', 'radio', 'route', 'scsi', 'server', 'server_item', 'service', 'share', 'software', 'software_key', 'sound', 'task', 'usb', 'user', 'user_group', 'variable', 'video', 'vm', 'windows', 'report', 'query', 'group'); + return array('application', 'attachment', 'audit_log', 'bios', 'certificate', 'change_log', 'cluster', 'credential', 'discovery', 'discovery_log', 'disk', 'dns', 'edit_log', 'executable', 'field', 'image', 'ip', 'log', 'memory', 'module', 'monitor', 'motherboard', 'netstat', 'network', 'nmap', 'optical', 'pagefile', 'partition', 'partition_graph', 'policy', 'print_queue', 'processor', 'radio', 'route', 'scsi', 'server', 'server_item', 'service', 'share', 'software', 'software_key', 'sound', 'task', 'usb', 'user', 'user_group', 'variable', 'video', 'vm', 'windows', 'report', 'query', 'group'); } } diff --git a/app/Helpers/utility_helper.php b/app/Helpers/utility_helper.php index 436fbcd23..fc38493d4 100644 --- a/app/Helpers/utility_helper.php +++ b/app/Helpers/utility_helper.php @@ -643,6 +643,17 @@ function collections_list() $collections->discovery_scan_options->actions->professional = 'r'; $collections->discovery_scan_options->actions->community = 'r'; + + $collections->executables = new \StdClass(); + $collections->executables->icon = 'fa fa-file-code-o'; + $collections->executables->name = 'Executables'; + $collections->executables->edition = 'Enterprise'; + $collections->executables->orgs = 'b'; + $collections->executables->actions = new \stdClass(); + $collections->executables->actions->enterprise = 'crud'; + $collections->executables->actions->professional = ''; + $collections->executables->actions->community = ''; + $collections->fields = new \StdClass(); $collections->fields->icon = 'fa fa-comments-o'; $collections->fields->name = 'Fields'; diff --git a/app/Models/ComponentsModel.php b/app/Models/ComponentsModel.php index f53855c76..89ca746c9 100644 --- a/app/Models/ComponentsModel.php +++ b/app/Models/ComponentsModel.php @@ -47,7 +47,7 @@ public function collection(object $resp): array } if ($table === '') { // No components.type requested, return all the below - $tables = array('bios', 'certificate', 'disk', 'dns', 'file', 'ip', 'log', 'memory', 'module', 'monitor', 'motherboard', 'netstat', 'network', 'nmap', 'optical', 'pagefile', 'partition', 'policy', 'print_queue', 'processor', 'radio', 'route', 'san', 'scsi', 'server', 'server_item', 'service', 'share', 'software', 'software_key', 'sound', 'task', 'usb', 'user', 'user_group', 'variable', 'video', 'vm', 'windows'); + $tables = array('bios', 'certificate', 'disk', 'dns', 'executable', 'file', 'ip', 'log', 'memory', 'module', 'monitor', 'motherboard', 'netstat', 'network', 'nmap', 'optical', 'pagefile', 'partition', 'policy', 'print_queue', 'processor', 'radio', 'route', 'san', 'scsi', 'server', 'server_item', 'service', 'share', 'software', 'software_key', 'sound', 'task', 'usb', 'user', 'user_group', 'variable', 'video', 'vm', 'windows'); } $orgs = array(); $count = count($resp->meta->filter); @@ -67,7 +67,7 @@ public function collection(object $resp): array } } if (empty($tables)) { - if (!in_array($table, ['audit_log', 'bios', 'certificate', 'change_log', 'discovery_log', 'disk', 'dns', 'edit_log', 'file', 'ip', 'log', 'memory', 'module', 'monitor', 'motherboard', 'netstat', 'network', 'nmap', 'optical', 'pagefile', 'partition', 'policy', 'print_queue', 'processor', 'radio', 'route', 'san', 'scsi', 'server', 'server_item', 'service', 'share', 'software', 'software_key', 'sound', 'task', 'usb', 'user', 'user_group', 'variable', 'video', 'vm', 'windows'])) { + if (!in_array($table, ['audit_log', 'bios', 'certificate', 'change_log', 'discovery_log', 'disk', 'dns', 'edit_log', 'executable', 'file', 'ip', 'log', 'memory', 'module', 'monitor', 'motherboard', 'netstat', 'network', 'nmap', 'optical', 'pagefile', 'partition', 'policy', 'print_queue', 'processor', 'radio', 'route', 'san', 'scsi', 'server', 'server_item', 'service', 'share', 'software', 'software_key', 'sound', 'task', 'usb', 'user', 'user_group', 'variable', 'video', 'vm', 'windows'])) { # Invalid table log_message('error', 'Invalid table provided to ComponentsModel::collection, ' . $table); $_SESSION['error'] = 'Invalid table provided to ComponentsModel::collection, ' . htmlentities($table); diff --git a/app/Models/DevicesModel.php b/app/Models/DevicesModel.php index 61d89a752..6cfc961c3 100644 --- a/app/Models/DevicesModel.php +++ b/app/Models/DevicesModel.php @@ -356,7 +356,7 @@ public function includedCollection(): array $orgs = array_unique(array_merge($instance->user->orgs, $instance->orgsModel->getUserDescendants($instance->user->orgs, $instance->orgs))); $included = array(); - // No file, radio, san, scsi, usb + // No executable, file, radio, san, scsi, usb $current = array('audit_log', 'bios', 'change_log', 'disk', 'dns', 'edit_log', 'ip', 'log', 'memory', 'module', 'monitor', 'motherboard', 'netstat', 'network', 'nmap', 'optical', 'pagefile', 'partition', 'policy', 'print_queue', 'processor', 'route', 'server', 'server_item', 'service', 'share', 'software', 'software_key', 'sound', 'task', 'user', 'user_group', 'variable', 'video', 'vm', 'windows'); foreach ($current as $table) { @@ -387,7 +387,7 @@ public function includedRead(int $id = 0): array } $include = array(); - $current = array('bios', 'certificate', 'disk', 'dns', 'file', 'ip', 'log', 'memory', 'module', 'monitor', 'motherboard', 'netstat', 'network', 'nmap', 'optical', 'pagefile', 'partition', 'policy', 'print_queue', 'processor', 'radio', 'route', 'san', 'scsi', 'server_item', 'service', 'share', 'software', 'software_key', 'sound', 'task', 'usb', 'user', 'user_group', 'variable', 'video', 'vm', 'windows'); + $current = array('bios', 'certificate', 'disk', 'dns', 'executable', 'file', 'ip', 'log', 'memory', 'module', 'monitor', 'motherboard', 'netstat', 'network', 'nmap', 'optical', 'pagefile', 'partition', 'policy', 'print_queue', 'processor', 'radio', 'route', 'san', 'scsi', 'server_item', 'service', 'share', 'software', 'software_key', 'sound', 'task', 'usb', 'user', 'user_group', 'variable', 'video', 'vm', 'windows'); foreach ($current as $table) { if (empty($resp_include) or in_array($table, $resp_include)) { $sql = "SELECT * FROM `$table` WHERE device_id = ? and current = 'y'"; diff --git a/app/Models/ExecutablesModel.php b/app/Models/ExecutablesModel.php new file mode 100644 index 000000000..cb62b4e2e --- /dev/null +++ b/app/Models/ExecutablesModel.php @@ -0,0 +1,252 @@ +db = db_connect(); + $this->builder = $this->db->table('executables'); + # 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; + } + $data->path = str_replace("'", '', $data->path); + $data->path = str_replace('"', '', $data->path); + $data->path = str_replace(';', '', $data->path); + $data->path = str_replace("\n", '', $data->path); + $data = $this->createFieldData('executables', $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; + } + + /** + * 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 + { + return array(); + } + + /** + * 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[] = 'executables.*'; + $properties[] = 'orgs.name as `orgs.name`'; + $this->builder->select($properties, false); + $this->builder->join('orgs', 'executables.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(), 'executables'); + } + + /** + * 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(), 'executables'); + } + + /** + * Reset a table + * + * @return bool Did it work or not? + */ + public function reset(string $table = ''): bool + { + if ($this->tableReset('executables')) { + 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('executables', $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 = 'executables'; + $dictionary = new stdClass(); + $dictionary->table = $collection; + $dictionary->columns = new stdClass(); + + $dictionary->attributes = new stdClass(); + $dictionary->attributes->collection = array('id', 'name', 'description', 'path', 'exclude', 'orgs.name'); + $dictionary->attributes->create = array('name','org_id','path','exclude'); + $dictionary->attributes->fields = $this->db->getFieldNames($collection); + $dictionary->attributes->fieldsMeta = $this->db->getFieldData($collection); + $dictionary->attributes->update = $this->updateFields($collection); + + $dictionary->sentence = 'Open-AudIT Enterprise includes Executables, which detects executable files not know by the package manager. This feature is for Linux targets only.'; + + $dictionary->about = '

Open-AudIT can retrieve details about a file, ask the native package manager if they are known to it and monitor these files for changes as per other attributes in the Open-AudIT database.

Supported clients are Linux only.

' . $instance->dictionary->link . '

'; + + $dictionary->notes = '

Supported clients are Linux only.

'; + + + $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->path = 'The path to the file or directory.'; + $dictionary->columns->os_family = 'Unused as at 5.2.0.'; + $dictionary->columns->exclude = 'Should this file (or pattern) be used to exclude files from being reported.'; + $dictionary->columns->edited_by = $instance->dictionary->edited_by; + $dictionary->columns->edited_date = $instance->dictionary->edited_date; + return $dictionary; + } +} diff --git a/app/Models/ScriptsModel.php b/app/Models/ScriptsModel.php index 86faaf2a6..549692010 100644 --- a/app/Models/ScriptsModel.php +++ b/app/Models/ScriptsModel.php @@ -405,6 +405,30 @@ public function download(int $id = 0): ?string } } + if (!empty($instance->config->executables) and $instance->config->executables) { + $sql = "SELECT * FROM executables"; + $result = $this->db->query($sql)->getResult(); + $exclusions = array(); + if (!empty($result)) { + foreach ($result as $item) { + $path = str_replace('\\', '\\\\', $item->path); + if ($item->exclude === 'n') { + $replace = $find . "\nexecutables[" . ($item->id + 1) . ']="' . $path . '"'; + $file = str_replace($find, $replace, $file); + } + if ($item->exclude === 'y') { + #$replace = $find . "\nexclusions[" . ($item->id + 1) . ']="' . $path . '"'; + #$file = str_replace($find, $replace, $file); + $exclusions[] = $path; + } + } + } + if (!empty($exclusions)) { + $replace = $find . "\nexclusions=\"" . implode('|', $exclusions) . "\""; + $file = str_replace($find, $replace, $file); + } + } + // Force all line endings to be Unix style // Windows audit scripts with Unix line endings work // Unix audit scripts with Windows line endings do not work (bash for one, chokes) diff --git a/app/Models/db_upgrades/db_5.2.0.php b/app/Models/db_upgrades/db_5.2.0.php index b49754219..45638f9c8 100644 --- a/app/Models/db_upgrades/db_5.2.0.php +++ b/app/Models/db_upgrades/db_5.2.0.php @@ -22,6 +22,78 @@ log_message('info', (string)$db->getLastQuery()); } +if (!$db->tableExists('executables')) { + $sql = "CREATE TABLE `executables` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `name` varchar(200) NOT NULL DEFAULT '', + `org_id` int(10) unsigned NOT NULL DEFAULT '1', + `path` text NOT NULL, + `description` text NOT NULL, + `os_family` varchar(50) NOT NULL DEFAULT '', + `exclude` enum('y', 'n') NOT NULL DEFAULT 'n', + `edited_by` varchar(200) NOT NULL DEFAULT '', + `edited_date` datetime NOT NULL DEFAULT '2000-01-01 00:00:00', + PRIMARY KEY (`id`) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci;"; + $db->query($sql); + $output .= str_replace("\n", " ", (string)$db->getLastQuery()) . "\n\n"; + log_message('info', (string)$db->getLastQuery()); +} + +if (!$db->tableExists('executable')) { + $sql = " CREATE TABLE `executable` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `device_id` int(10) unsigned DEFAULT NULL, + `current` enum('y','n') NOT NULL DEFAULT 'y', + `first_seen` datetime NOT NULL DEFAULT '2000-01-01 00:00:00', + `last_seen` datetime NOT NULL DEFAULT '2000-01-01 00:00:00', + `executable_id` int(10) unsigned DEFAULT NULL, + `name` varchar(200) NOT NULL DEFAULT '', + `full_name` text NOT NULL, + `description` varchar(1000) NOT NULL, + `package` varchar(1000) NOT NULL, + `size` int(10) unsigned NOT NULL DEFAULT '0', + `directory` text NOT NULL, + `hash` varchar(250) NOT NULL DEFAULT '', + `last_changed` varchar(100) NOT NULL DEFAULT '', + `meta_last_changed` varchar(100) NOT NULL DEFAULT '', + `permission` varchar(250) NOT NULL DEFAULT '', + `owner` varchar(100) NOT NULL DEFAULT '', + `group` varchar(100) NOT NULL DEFAULT '', + `type` varchar(100) NOT NULL DEFAULT '', + `version` varchar(100) NOT NULL DEFAULT '', + `inode` bigint(20) unsigned NOT NULL DEFAULT '0', + `ack_by` varchar(200) NOT NULL DEFAULT '', + `ack_date` datetime NOT NULL DEFAULT '2000-01-01 00:00:00', + `notes` text NOT NULL, + PRIMARY KEY (`id`), + KEY `system_id` (`device_id`), + KEY `name` (`name`), + CONSTRAINT `executable_system_id` FOREIGN KEY (`device_id`) REFERENCES `devices` (`id`) ON DELETE CASCADE + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci"; + $db->query($sql); + $output .= str_replace("\n", " ", (string)$db->getLastQuery()) . "\n\n"; + log_message('info', (string)$db->getLastQuery()); +} + +$sql = "SELECT * FROM `roles`"; +$roles = $db->query($sql)->getResult(); +$output .= str_replace("\n", " ", (string)$db->getLastQuery()) . "\n\n"; +log_message('info', (string)$db->getLastQuery()); + +foreach ($roles as $role) { + if ($role->name === 'org_admin' or $role->name === 'user') { + $permissions = json_decode($role->permissions); + if ($role->name === 'org_admin') { + $permissions->executables = 'crud'; + } + if ($role->name === 'user') { + $permissions->executable = 'r'; + } + $this->rolesModel->update(intval($role->id), $permissions); + } +} + $sql = "DELETE FROM `configuration` WHERE `name` IN ('product', 'oae_product')"; $db->query($sql); $output .= str_replace("\n", " ", (string)$db->getLastQuery()) . "\n\n"; diff --git a/app/Views/devicesRead.php b/app/Views/devicesRead.php index c5ad4e4ec..7a263cb16 100644 --- a/app/Views/devicesRead.php +++ b/app/Views/devicesRead.php @@ -126,7 +126,7 @@ + +
-
#
+  #
+
NOTE - You are accessing this URL from the local Open-AudIT server. The downloaded script will not be able to submit when run on any other machine.
If you need to audit other machines, please download the script from a remote machine, not the Open-AudIT server itself.'); + } ?> -
  From 2822836393d45ebf702b3722e3ab742324f850ad Mon Sep 17 00:00:00 2001 From: Mark Unwin Date: Thu, 21 Mar 2024 11:25:06 +1000 Subject: [PATCH 11/26] Lang strings. --- app/Views/lang/en.inc | 1 + 1 file changed, 1 insertion(+) diff --git a/app/Views/lang/en.inc b/app/Views/lang/en.inc index bec014fbd..970e8d3ce 100644 --- a/app/Views/lang/en.inc +++ b/app/Views/lang/en.inc @@ -7,6 +7,7 @@ $GLOBALS["lang"]["3"]="3"; $GLOBALS["lang"]["4"]="4"; $GLOBALS["lang"]["5"]="5"; $GLOBALS["lang"]["<"]="<"; +$GLOBALS["lang"]["

NOTE - You are accessing this URL from the local Open-AudIT server. The downloaded script will not be able to submit when run on any other machine.
If you need to audit other machines, please download the script from a remote machine, not the Open-AudIT server itself."]="

NOTE - You are accessing this URL from the local Open-AudIT server. The downloaded script will not be able to submit when run on any other machine.
If you need to audit other machines, please download the script from a remote machine, not the Open-AudIT server itself."; $GLOBALS["lang"]["=<"]="=<"; $GLOBALS["lang"]["=="]="=="; $GLOBALS["lang"][">"]=">"; From be26fbdf1ed5ef6a9b9069d2c2426e28c5cf3355 Mon Sep 17 00:00:00 2001 From: Mark Unwin Date: Thu, 21 Mar 2024 17:37:59 +1000 Subject: [PATCH 12/26] When using SNMP against ESX, get the VMGuestOS and use to guess at an icon. --- app/Helpers/snmp_6876_2_helper.php | 1 + app/Models/ComponentsModel.php | 20 ++++++++++++++++++++ app/Views/devicesRead.php | 4 ++-- 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/app/Helpers/snmp_6876_2_helper.php b/app/Helpers/snmp_6876_2_helper.php index e608d252f..7fbdf2532 100644 --- a/app/Helpers/snmp_6876_2_helper.php +++ b/app/Helpers/snmp_6876_2_helper.php @@ -41,6 +41,7 @@ $guest->cpu = my_snmp_get($ip, $credentials, "1.3.6.1.4.1.6876.2.1.1.9.".$guest->vm_ident); $guest->status = my_snmp_get($ip, $credentials, "1.3.6.1.4.1.6876.2.1.1.6.".$guest->vm_ident); $guest->config_file = my_snmp_get($ip, $credentials, "1.3.6.1.4.1.6876.2.1.1.3.".$guest->vm_ident); + $guest->os = my_snmp_get($ip, $credentials, "1.3.6.1.4.1.6876.2.1.1.4.".$guest->vm_ident); $guest->vm_group = ''; $guest->type = 'esx'; $guests[] = $guest; diff --git a/app/Models/ComponentsModel.php b/app/Models/ComponentsModel.php index 89ca746c9..4d28d6a52 100644 --- a/app/Models/ComponentsModel.php +++ b/app/Models/ComponentsModel.php @@ -1109,6 +1109,26 @@ public function upsert(string $table = '', object $device = null, array $data = } } } + if (empty($virtual_machine->icon) and !empty($virtual_machine->os)) { + if (stripos($virtual_machine->os, 'red hat') !== false) { + $virtual_machine->icon = 'redhat'; + } + if (stripos($virtual_machine->os, 'debian') !== false) { + $virtual_machine->icon = 'debian'; + } + if (stripos($virtual_machine->os, 'centos') !== false) { + $virtual_machine->icon = 'centos'; + } + if (stripos($virtual_machine->os, 'ubuntu') !== false) { + $virtual_machine->icon = 'ubuntu'; + } + if (stripos($virtual_machine->os, 'windows') !== false) { + $virtual_machine->icon = 'windows'; + } + if (empty($virtual_machine->icon) and stripos($virtual_machine->os, 'linux') !== false) { + $virtual_machine->icon = 'linux'; + } + } } } diff --git a/app/Views/devicesRead.php b/app/Views/devicesRead.php index 7a263cb16..4851e9afe 100644 --- a/app/Views/devicesRead.php +++ b/app/Views/devicesRead.php @@ -2416,7 +2416,7 @@ - + @@ -2434,7 +2434,7 @@ } ?> id) ?> - icon ?> + icon ?> name ?> type ?> memory_count ?> From ce880381efb02926db3ba38dba37b9168274b649 Mon Sep 17 00:00:00 2001 From: Mark Unwin Date: Thu, 21 Mar 2024 17:38:40 +1000 Subject: [PATCH 13/26] When adding a device, set change_log.ack_by to an empty string, not null. --- app/Models/DevicesModel.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Models/DevicesModel.php b/app/Models/DevicesModel.php index 6cfc961c3..610903c5c 100644 --- a/app/Models/DevicesModel.php +++ b/app/Models/DevicesModel.php @@ -213,7 +213,7 @@ public function create($data = null): ?int // Set the device icon reset_icons($id); - $sql = "INSERT INTO change_log VALUES (null, ?, 'devices', ?, 'create', 'Item added to devices', null, '2000-01-01 00:00:00', '', '', '', null, '', NOW())"; + $sql = "INSERT INTO change_log VALUES (null, ?, 'devices', ?, 'create', 'Item added to devices', '', '2000-01-01 00:00:00', '', '', '', null, '', NOW())"; $this->db->query($sql, [$id, $id]); $weight = weight($data->last_seen_by); From b071158d355337f047257805c799a6d8af23b835 Mon Sep 17 00:00:00 2001 From: Mark Unwin Date: Thu, 21 Mar 2024 17:39:12 +1000 Subject: [PATCH 14/26] Improve scripts::download. --- app/Models/ScriptsModel.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/Models/ScriptsModel.php b/app/Models/ScriptsModel.php index 1ebb60296..3e3cbf4cd 100644 --- a/app/Models/ScriptsModel.php +++ b/app/Models/ScriptsModel.php @@ -410,7 +410,7 @@ public function download(int $id = 0): ?string } } - if (!empty($instance->config->executables) and $instance->config->executables) { + if (!empty($instance->config->executables) and $instance->config->executables and $instance->config->product === 'enterprise') { if ($data->based_on === 'audit_linux.sh') { $sql = "SELECT * FROM executables"; $result = $this->db->query($sql)->getResult(); @@ -423,8 +423,6 @@ public function download(int $id = 0): ?string $file = str_replace($find, $replace, $file); } if ($item->exclude === 'y') { - #$replace = $find . "\nexclusions[" . ($item->id + 1) . ']="' . $path . '"'; - #$file = str_replace($find, $replace, $file); $exclusions[] = $path; } } From 3b0bf773e84b7baa0865cbd66d8d8b3037facd78 Mon Sep 17 00:00:00 2001 From: Mark Unwin Date: Thu, 21 Mar 2024 17:39:43 +1000 Subject: [PATCH 15/26] Update the default Windows icon and add a specific Windows 2019 icon. --- public/device_images/windows.svg | 382 ++++---------------------- public/device_images/windows_2019.svg | 74 +++++ 2 files changed, 123 insertions(+), 333 deletions(-) create mode 100644 public/device_images/windows_2019.svg diff --git a/public/device_images/windows.svg b/public/device_images/windows.svg index 0406abc37..e33635a52 100644 --- a/public/device_images/windows.svg +++ b/public/device_images/windows.svg @@ -1,358 +1,74 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + id="svg9233" + inkscape:version="0.48.4 r9939" + sodipodi:docname="windows_new.svg"> + id="metadata9268"> image/svg+xml - + + - - - - - - - - - - - - - - + id="g9284" + transform="matrix(0.73993803,0,0,0.73993803,7.569537,7.1494765)"> + + + + diff --git a/public/device_images/windows_2019.svg b/public/device_images/windows_2019.svg new file mode 100644 index 000000000..e33635a52 --- /dev/null +++ b/public/device_images/windows_2019.svg @@ -0,0 +1,74 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + From b58b353b3036c638163d6f19567edd4483ef5c72 Mon Sep 17 00:00:00 2001 From: Mark Unwin Date: Thu, 21 Mar 2024 17:40:14 +1000 Subject: [PATCH 16/26] Fix trying to count an integer bug. --- app/Helpers/snmp_helper.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/Helpers/snmp_helper.php b/app/Helpers/snmp_helper.php index 0ca0e6833..0108e7b87 100644 --- a/app/Helpers/snmp_helper.php +++ b/app/Helpers/snmp_helper.php @@ -1634,8 +1634,7 @@ function snmp_audit(string $ip = '', object $credentials = null, int $discovery_ $log->command_time_to_execute = (microtime(true) - $item_start); $log->message = 'Route count retrieval for '.$ip; $log->command = 'snmpwalk 1.3.6.1.2.1.4.24.3.0'; - $temp = (!empty($route_count)) ? count($route_count) : 0; - $log->command_output = "Count is $temp"; + $log->command_output = "Count is $route_count"; $log->command_status = 'notice'; if (!empty($route_count) && $route_count < $config_value) { $retrieve_routes = 1; From a626581d0bb9c9eb13160c36c43f06c9fc6739cd Mon Sep 17 00:00:00 2001 From: Mark Unwin Date: Tue, 26 Mar 2024 15:24:58 +1000 Subject: [PATCH 17/26] Add a Fping scan (commented out) in discoveries_helper::responding_ip_list for Linux. --- app/Helpers/discoveries_helper.php | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/app/Helpers/discoveries_helper.php b/app/Helpers/discoveries_helper.php index 7f2460b50..86ad20704 100644 --- a/app/Helpers/discoveries_helper.php +++ b/app/Helpers/discoveries_helper.php @@ -66,7 +66,7 @@ function all_ip_list($discovery = null) function responding_ip_list($discovery = null) { if (is_null($discovery)) { - return false; + return array(); } $discoveryLogModel = new \App\Models\DiscoveryLogModel(); @@ -90,6 +90,13 @@ function responding_ip_list($discovery = null) $command = 'nmap -n -oG - -sP --exclude ' . $discovery->scan_options->exclude_ip . ' ' . $discovery->subnet; } else { $command = 'nmap -n -oG - -sP ' . $discovery->subnet; + // NOTE - below is for Linux only and only in specific circumstances + // - Fping doesn't have an exclude option + // - Fping doesn't accept the same host formatting as Nmap, except for 1.2.3.4/5 + // if (filter_var($discovery->subnet, FILTER_VALIDATE_IP)) { + // $discovery->subnet = $discovery->subnet . '/32'; + // } + // $command = 'fping -A -a -q -g -r 2 ' . $discovery->subnet . ' 2>&1'; } if (php_uname('s') === 'Darwin') { $command = '/usr/local/bin/' . $command; @@ -103,13 +110,19 @@ function responding_ip_list($discovery = null) $ip_addresses[] = $temp[1]; } } + // Caters to a single responding IP on each line, for fping or Nmap with piping to cut, et al + // foreach ($output as $line) { + // if (filter_var($line, FILTER_VALIDATE_IP)) { + // $ip_addresses[] = $line; + // } + // } } else { if (php_uname('s') === 'Windows NT' and empty($output)) { log_message('error', 'No response from Nmap. Is the Apache Service running as a normal user?'); } $log->command_output = json_encode($output); $discoveryLogModel->create($log); - return false; + return array(); } } else { if (!empty($discovery->scan_options->exclude_ip)) { @@ -131,7 +144,7 @@ function responding_ip_list($discovery = null) } } else { $discoveryLogModel->create($log); - return false; + return array(); } } $log->command_output = 'Responding IPs: ' . @count($ip_addresses); From 06ec7f50e5aedc278cea72d7a9e105e277c6a7f7 Mon Sep 17 00:00:00 2001 From: Mark Unwin Date: Tue, 26 Mar 2024 15:25:59 +1000 Subject: [PATCH 18/26] Avoid halting on an error in ssh_helper. --- app/Helpers/ssh_helper.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/Helpers/ssh_helper.php b/app/Helpers/ssh_helper.php index fe7d269cd..b435c3881 100644 --- a/app/Helpers/ssh_helper.php +++ b/app/Helpers/ssh_helper.php @@ -605,7 +605,9 @@ function ssh_audit($parameters) } } else if ($credential->type === 'ssh') { log_message('debug', 'Testing credentials named: ' . $credential->name . ' on ' . $ip); - if ($ssh->login($credential->credentials->username, $credential->credentials->password)) { + // NOTE - Use @ below because some devices cause "Error reading from socket" and halt this process + // TODO - change to try / catch + 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'; $discoveryLogModel->create($log); From 89224d4140d39db9f7606b08349659f56a2acb84 Mon Sep 17 00:00:00 2001 From: Mark Unwin Date: Tue, 26 Mar 2024 15:27:58 +1000 Subject: [PATCH 19/26] 5.2.0 config changes. --- app/Models/db_upgrades/db_5.2.0.php | 40 ++++++++++++++++++----------- other/db_5.2.0.php | 27 ------------------- 2 files changed, 25 insertions(+), 42 deletions(-) delete mode 100644 other/db_5.2.0.php diff --git a/app/Models/db_upgrades/db_5.2.0.php b/app/Models/db_upgrades/db_5.2.0.php index 45638f9c8..89f621399 100644 --- a/app/Models/db_upgrades/db_5.2.0.php +++ b/app/Models/db_upgrades/db_5.2.0.php @@ -1,6 +1,11 @@ query($sql); +$output .= str_replace("\n", " ", (string)$db->getLastQuery()) . "\n\n"; +log_message('info', (string)$db->getLastQuery()); + if ($db->fieldExists('user_id', 'change_log')) { $sql = "ALTER TABLE `change_log` DROP `user_id`"; $db->query($sql); @@ -22,6 +27,21 @@ log_message('info', (string)$db->getLastQuery()); } +$sql = "DELETE FROM `configuration` WHERE `name` IN ('product', 'oae_product')"; +$db->query($sql); +$output .= str_replace("\n", " ", (string)$db->getLastQuery()) . "\n\n"; +log_message('info', (string)$db->getLastQuery()); + +$sql = "UPDATE `configuration` SET `value` = 'n' WHERE `name` = 'create_change_log_ip'"; +$db->query($sql); +$output .= str_replace("\n", " ", (string)$db->getLastQuery()) . "\n\n"; +log_message('info', (string)$db->getLastQuery()); + +$sql = "UPDATE `configuration` SET `value` = 'y' WHERE `name` = 'delete_noncurrent_ip'"; +$db->query($sql); +$output .= str_replace("\n", " ", (string)$db->getLastQuery()) . "\n\n"; +log_message('info', (string)$db->getLastQuery()); + if (!$db->tableExists('executables')) { $sql = "CREATE TABLE `executables` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, @@ -76,6 +96,11 @@ log_message('info', (string)$db->getLastQuery()); } +$sql = "ALTER TABLE `partition` CHANGE `mount_point` `mount_point` VARCHAR(200) NOT NULL DEFAULT ''"; +$db->query($sql); +$output .= str_replace("\n", " ", (string)$db->getLastQuery()) . "\n\n"; +log_message('info', (string)$db->getLastQuery()); + $sql = "SELECT * FROM `roles`"; $roles = $db->query($sql)->getResult(); $output .= str_replace("\n", " ", (string)$db->getLastQuery()) . "\n\n"; @@ -94,21 +119,6 @@ } } -$sql = "DELETE FROM `configuration` WHERE `name` IN ('product', 'oae_product')"; -$db->query($sql); -$output .= str_replace("\n", " ", (string)$db->getLastQuery()) . "\n\n"; -log_message('info', (string)$db->getLastQuery()); - -$sql = "UPDATE `configuration` SET `value` = 'n' WHERE `name` = 'create_change_log_ip'"; -$db->query($sql); -$output .= str_replace("\n", " ", (string)$db->getLastQuery()) . "\n\n"; -log_message('info', (string)$db->getLastQuery()); - -$sql = "UPDATE `configuration` SET `value` = 'y' WHERE `name` = 'delete_noncurrent_ip'"; -$db->query($sql); -$output .= str_replace("\n", " ", (string)$db->getLastQuery()) . "\n\n"; -log_message('info', (string)$db->getLastQuery()); - // set our versions $sql = "UPDATE `configuration` SET `value` = '20240512' WHERE `name` = 'internal_version'"; $db->query($sql); diff --git a/other/db_5.2.0.php b/other/db_5.2.0.php deleted file mode 100644 index 7279807b2..000000000 --- a/other/db_5.2.0.php +++ /dev/null @@ -1,27 +0,0 @@ -query($sql); -$output .= str_replace("\n", " ", (string)$db->getLastQuery()) . "\n\n"; -log_message('info', (string)$db->getLastQuery()); - -$sql = "ALTER TABLE `bios` CHANGE `serial` `serial` VARCHAR(200) NOT NULL DEFAULT ''"; -$db->query($sql); -$output .= str_replace("\n", " ", (string)$db->getLastQuery()) . "\n\n"; -log_message('info', (string)$db->getLastQuery()); - -// set our versions -$sql = "UPDATE `configuration` SET `value` = '20240512' WHERE `name` = 'internal_version'"; -$db->query($sql); -$output .= str_replace("\n", " ", (string)$db->getLastQuery()) . "\n\n"; -log_message('info', (string)$db->getLastQuery()); - -$sql = "UPDATE `configuration` SET `value` = '5.2.0' 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.2.0 completed.\n\n"; -config('Openaudit')->internal_version = 20240512; -config('Openaudit')->display_version = '5.2.0'; From 22f2fd8719eb27057f0275ac2eac57b3086df02e Mon Sep 17 00:00:00 2001 From: Mark Unwin Date: Wed, 27 Mar 2024 11:04:14 +1000 Subject: [PATCH 20/26] Apply dataTables to licensesRead template. --- app/Views/licensesRead.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Views/licensesRead.php b/app/Views/licensesRead.php index 30de972ad..26a73c759 100644 --- a/app/Views/licensesRead.php +++ b/app/Views/licensesRead.php @@ -106,7 +106,7 @@
- +
From 0d23c7300e03232bc6a951979530cfb6e4604070 Mon Sep 17 00:00:00 2001 From: Mark Unwin Date: Wed, 27 Mar 2024 11:04:40 +1000 Subject: [PATCH 21/26] HTML entity decode the value on configurationRead template. --- app/Views/configurationRead.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Views/configurationRead.php b/app/Views/configurationRead.php index 74d29fcff..a11280bb3 100644 --- a/app/Views/configurationRead.php +++ b/app/Views/configurationRead.php @@ -19,7 +19,7 @@ editable, $dictionary->columns->editable, false) ?> type, $dictionary->columns->type, false) ?> type !== 'bool') { ?> - value, $dictionary->columns->value, $update, '', '', '', $resource->type) ?> + value), $dictionary->columns->value, $update, '', '', '', $resource->type) ?> type === 'bool') { ?> value, $dictionary->columns->value, $update, '', array()) ?> From 01738c98a45df2959b45f8d6fae9b9bdf0504efd Mon Sep 17 00:00:00 2001 From: Mark Unwin Date: Wed, 27 Mar 2024 11:05:24 +1000 Subject: [PATCH 22/26] Sync the SQL definition file and 5.2.0 upgrade. --- app/Models/db_upgrades/db_5.2.0.php | 10 +++++ other/open-audit.sql | 66 ++++++++++++++--------------- 2 files changed, 43 insertions(+), 33 deletions(-) diff --git a/app/Models/db_upgrades/db_5.2.0.php b/app/Models/db_upgrades/db_5.2.0.php index 89f621399..0325e7b11 100644 --- a/app/Models/db_upgrades/db_5.2.0.php +++ b/app/Models/db_upgrades/db_5.2.0.php @@ -42,6 +42,16 @@ $output .= str_replace("\n", " ", (string)$db->getLastQuery()) . "\n\n"; log_message('info', (string)$db->getLastQuery()); +$sql = "ALTER TABLE `discovery_log` CHANGE `timestamp` `timestamp` datetime DEFAULT current_timestamp()"; +$db->query($sql); +$output .= str_replace("\n", " ", (string)$db->getLastQuery()) . "\n\n"; +log_message('info', (string)$db->getLastQuery()); + +$sql = "ALTER TABLE `enterprise` CHANGE `response` `response` mediumtext NOT NULL DEFAULT ''"; +$db->query($sql); +$output .= str_replace("\n", " ", (string)$db->getLastQuery()) . "\n\n"; +log_message('info', (string)$db->getLastQuery()); + if (!$db->tableExists('executables')) { $sql = "CREATE TABLE `executables` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, diff --git a/other/open-audit.sql b/other/open-audit.sql index 2fd1ade8e..f3b10abbe 100644 --- a/other/open-audit.sql +++ b/other/open-audit.sql @@ -1328,7 +1328,7 @@ CREATE TABLE `discovery_log` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `discovery_id` int(10) unsigned DEFAULT NULL, `device_id` int(10) unsigned DEFAULT NULL, - `timestamp` datetime NOT NULL DEFAULT '2000-01-01 00:00:00', + `timestamp` datetime DEFAULT current_timestamp(), `severity` int(1) unsigned NOT NULL DEFAULT '5', `severity_text` enum('debug','info','notice','warning','error','critical','alert','emergency') NOT NULL DEFAULT 'notice', `pid` int(10) unsigned NOT NULL DEFAULT '0', @@ -1534,7 +1534,7 @@ DROP TABLE IF EXISTS `enterprise`; CREATE TABLE `enterprise` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `request` text NOT NULL, - `response` longtext NOT NULL, + `response` mediumtext NOT NULL DEFAULT '', `timestamp` datetime NOT NULL DEFAULT current_timestamp(), `output` mediumtext NOT NULL DEFAULT '', PRIMARY KEY (`id`) @@ -1557,36 +1557,36 @@ UNLOCK TABLES; DROP TABLE IF EXISTS `executable`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8 */; - CREATE TABLE `executable` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, - `device_id` int(10) unsigned DEFAULT NULL, - `current` enum('y','n') NOT NULL DEFAULT 'y', - `first_seen` datetime NOT NULL DEFAULT '2000-01-01 00:00:00', - `last_seen` datetime NOT NULL DEFAULT '2000-01-01 00:00:00', - `executable_id` int(10) unsigned DEFAULT NULL, - `name` varchar(200) NOT NULL DEFAULT '', - `full_name` text NOT NULL, - `description` varchar(1000) NOT NULL, - `package` varchar(1000) NOT NULL, - `size` int(10) unsigned NOT NULL DEFAULT '0', - `directory` text NOT NULL, - `hash` varchar(250) NOT NULL DEFAULT '', - `last_changed` varchar(100) NOT NULL DEFAULT '', - `meta_last_changed` varchar(100) NOT NULL DEFAULT '', - `permission` varchar(250) NOT NULL DEFAULT '', - `owner` varchar(100) NOT NULL DEFAULT '', - `group` varchar(100) NOT NULL DEFAULT '', - `type` varchar(100) NOT NULL DEFAULT '', - `version` varchar(100) NOT NULL DEFAULT '', - `inode` bigint(20) unsigned NOT NULL DEFAULT '0', - `ack_by` varchar(200) NOT NULL DEFAULT '', - `ack_date` datetime NOT NULL DEFAULT '2000-01-01 00:00:00', - `notes` text NOT NULL, - PRIMARY KEY (`id`), - KEY `system_id` (`device_id`), - KEY `name` (`name`), - CONSTRAINT `executable_system_id` FOREIGN KEY (`device_id`) REFERENCES `devices` (`id`) ON DELETE CASCADE - ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci; +CREATE TABLE `executable` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `device_id` int(10) unsigned DEFAULT NULL, + `current` enum('y','n') NOT NULL DEFAULT 'y', + `first_seen` datetime NOT NULL DEFAULT '2000-01-01 00:00:00', + `last_seen` datetime NOT NULL DEFAULT '2000-01-01 00:00:00', + `executable_id` int(10) unsigned DEFAULT NULL, + `name` varchar(200) NOT NULL DEFAULT '', + `full_name` text NOT NULL, + `description` varchar(1000) NOT NULL, + `package` varchar(1000) NOT NULL, + `size` int(10) unsigned NOT NULL DEFAULT '0', + `directory` text NOT NULL, + `hash` varchar(250) NOT NULL DEFAULT '', + `last_changed` varchar(100) NOT NULL DEFAULT '', + `meta_last_changed` varchar(100) NOT NULL DEFAULT '', + `permission` varchar(250) NOT NULL DEFAULT '', + `owner` varchar(100) NOT NULL DEFAULT '', + `group` varchar(100) NOT NULL DEFAULT '', + `type` varchar(100) NOT NULL DEFAULT '', + `version` varchar(100) NOT NULL DEFAULT '', + `inode` bigint(20) unsigned NOT NULL DEFAULT '0', + `ack_by` varchar(200) NOT NULL DEFAULT '', + `ack_date` datetime NOT NULL DEFAULT '2000-01-01 00:00:00', + `notes` text NOT NULL, + PRIMARY KEY (`id`), + KEY `system_id` (`device_id`), + KEY `name` (`name`), + CONSTRAINT `executable_system_id` FOREIGN KEY (`device_id`) REFERENCES `devices` (`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -1612,7 +1612,7 @@ CREATE TABLE `executables` ( `path` text NOT NULL, `description` text NOT NULL, `os_family` varchar(50) NOT NULL DEFAULT '', - `exclude` enum('y', 'n') NOT NULL DEFAULT 'n', + `exclude` enum('y','n') NOT NULL DEFAULT 'n', `edited_by` varchar(200) NOT NULL DEFAULT '', `edited_date` datetime NOT NULL DEFAULT '2000-01-01 00:00:00', PRIMARY KEY (`id`) From 6b7e6fbe77d8525a7d2a1b5f5fa10d7b1331012a Mon Sep 17 00:00:00 2001 From: Mark Unwin Date: Wed, 3 Apr 2024 14:04:39 +1000 Subject: [PATCH 23/26] Ensure system->discovery_id exists. --- app/Controllers/Input.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Controllers/Input.php b/app/Controllers/Input.php index 35453e352..d86f58b62 100644 --- a/app/Controllers/Input.php +++ b/app/Controllers/Input.php @@ -50,7 +50,7 @@ public function devices() include "include_process_device.php"; $discoveryLogModel = new \App\Models\DiscoveryLogModel(); $log = new \stdClass(); - $log->discovery_id = null; + $log->discovery_id = (!empty($device->system->discovery_id)) ? intval($device->system->discovery_id) : null; $log->device_id = $device->system->id; $log->timestamp = null; $log->severity = 7; From 9abdfa99b3deaa5114644a5b9fe3f9fad0a02575 Mon Sep 17 00:00:00 2001 From: Mark Unwin Date: Wed, 3 Apr 2024 14:04:55 +1000 Subject: [PATCH 24/26] Ensure system->discovery_id exists. --- app/Controllers/include_process_device.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Controllers/include_process_device.php b/app/Controllers/include_process_device.php index 7318202a8..3ccdb5059 100644 --- a/app/Controllers/include_process_device.php +++ b/app/Controllers/include_process_device.php @@ -16,7 +16,7 @@ helper('utility'); $log = new \stdClass(); -$log->discovery_id = null; +$log->discovery_id = (!empty($device->system->discovery_id)) ? intval($device->system->discovery_id) : null; $log->device_id = null; $log->timestamp = null; $log->severity = 7; From c9ca6ff5b4f98a9782121f64504697bd4393115e Mon Sep 17 00:00:00 2001 From: Mark Unwin Date: Wed, 3 Apr 2024 14:06:33 +1000 Subject: [PATCH 25/26] Remove comment. --- app/Helpers/discoveries_helper.php | 11 ++++++++++- app/Models/DiscoveryLogModel.php | 1 - 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/app/Helpers/discoveries_helper.php b/app/Helpers/discoveries_helper.php index 86ad20704..935b7f0d3 100644 --- a/app/Helpers/discoveries_helper.php +++ b/app/Helpers/discoveries_helper.php @@ -88,8 +88,13 @@ function responding_ip_list($discovery = null) if ($discovery->scan_options->ping === 'y') { if (!empty($discovery->scan_options->exclude_ip)) { $command = 'nmap -n -oG - -sP --exclude ' . $discovery->scan_options->exclude_ip . ' ' . $discovery->subnet; + // NOTE - Below should be faster than 'normal' Nmap + // $command = 'nmap -n -oG - -sP -T5 --min-parallelism 100 --max-parallelism 256 --exclude ' . $discovery->scan_options->exclude_ip . ' ' . $discovery->subnet; } else { $command = 'nmap -n -oG - -sP ' . $discovery->subnet; + // NOTE - Below should be faster than 'normal' Nmap + // $command = 'nmap -n -oG - -sP -T5 --min-parallelism 100 --max-parallelism 256 ' . $discovery->subnet; + // // NOTE - below is for Linux only and only in specific circumstances // - Fping doesn't have an exclude option // - Fping doesn't accept the same host formatting as Nmap, except for 1.2.3.4/5 @@ -1820,7 +1825,7 @@ function ip_audit($ip_scan = null) $log->message = 'Matching device from audit result'; $discoveryLogModel->create($log); $audit_device = deviceMatch($audit->system, intval($discovery->id), $discovery->match_options); - #$audit->system->discovery_id = $discovery->id; + $audit->system->discovery_id = $discovery->id; if (!empty($audit->system->id)) { $log->device_id = $audit->system->id; } @@ -1986,6 +1991,7 @@ function ip_audit($ip_scan = null) unset($device_json->system->original_last_seen); unset($device_json->system->id); unset($device_json->system->first_seen); + $device_json->system->discovery_id = $discovery->id; $device_json = json_encode($device_json); $url = $server->host . $server->community . '/index.php/input/devices'; @@ -2008,6 +2014,7 @@ function ip_audit($ip_scan = null) // error $log->severity = 4; $log->message = 'Could not send result to ' . $url . ' - please check with your server administrator.'; + $log->device_id = $device->id; $discoveryLogModel->create($log); $log->severity = 7; log_message('error', 'Could not send result to ' . $url); @@ -2015,6 +2022,7 @@ function ip_audit($ip_scan = null) // success $log->severity = 7; $log->message = 'Result sent to ' . $server->host . '.'; + $log->device_id = $device->id; $discoveryLogModel->create($log); log_message('debug', 'Result sent to ' . $server->host . '.'); } @@ -2034,6 +2042,7 @@ function ip_audit($ip_scan = null) $log->command_status = 'device complete'; $log->command_time_to_execute = microtime(true) - $start; $log->message = 'IP Audit finish on device ' . ip_address_from_db($device->ip); + $log->device_id = $device->id; $log->ip = ip_address_from_db($device->ip); $discoveryLogModel->create($log); diff --git a/app/Models/DiscoveryLogModel.php b/app/Models/DiscoveryLogModel.php index 27bbac954..be1e34828 100644 --- a/app/Models/DiscoveryLogModel.php +++ b/app/Models/DiscoveryLogModel.php @@ -158,7 +158,6 @@ public function create($data = null): ?int $this->builder->insert($newdata); $id = intval($this->db->insertID()); - // TODO - enable // If we are a collector, forward the log if (!empty($instance->config->servers) and !empty($instance->config->servers->type) and $instance->config->servers->type === 'collector') { $log = $newdata; From 9d866a4aa1abf78bba8cd2a8c54d996e7b979ca4 Mon Sep 17 00:00:00 2001 From: Mark Unwin Date: Wed, 3 Apr 2024 14:06:51 +1000 Subject: [PATCH 26/26] Fix tasksModel. --- app/Models/TasksModel.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/app/Models/TasksModel.php b/app/Models/TasksModel.php index c1b82268d..478778b59 100644 --- a/app/Models/TasksModel.php +++ b/app/Models/TasksModel.php @@ -90,6 +90,15 @@ public function create($data = null): ?int if (empty($data)) { return null; } + $data->minute = implode(',', $data->minute); + $data->hour = implode(',', $data->hour); + $data->month = implode(',', $data->month); + $data->day_of_month = implode(',', $data->day_of_month); + $data->day_of_week = implode(',', $data->day_of_week); + if (empty($data->uuid)) { + $instance = & get_instance(); + $data->uuid = $instance->config->uuid; + } $data = $this->createFieldData('tasks', $data); if (empty($data)) { return null;