* Purpose: Contain all search/filtering functionality within Sagacity
* Created: May 24, 2017
*
* Copyright 2017: Cyber Perspective, LLC, All rights reserved
* Released under the Apache v2.0 License
*
* See license.txt for details
*
* Change Log:
* - May 24, 2017 - File created
* - May 26, 2017 - Couple bug fixes
* - Jul 13, 2017 - Fixed a couple minor display bugs
* - Dec 27, 2017 - Syntax updates
* - May 10, 2018 - Fixed bug #405, probably other bugs with other types
* - May 31, 2018 - Bug fixes
*/
include_once 'config.inc';
include_once 'helper.inc';
include_once 'database.inc';
$db = new db();
$type = filter_input(INPUT_POST, 'type', FILTER_SANITIZE_STRING, FILTER_NULL_ON_FAILURE);
$q = filter_input(INPUT_POST, 'q', FILTER_SANITIZE_STRING, FILTER_NULL_ON_FAILURE);
$start = filter_input(INPUT_POST, 'start', FILTER_VALIDATE_INT, FILTER_NULL_ON_FAILURE);
$len = filter_input(INPUT_POST, 'length', FILTER_VALIDATE_INT, FILTER_NULL_ON_FAILURE);
$draw = filter_input(INPUT_POST, 'draw', FILTER_VALIDATE_INT, FILTER_NULL_ON_FAILURE);
$filter = filter_input(INPUT_POST, 'search', FILTER_SANITIZE_STRING, FILTER_REQUIRE_ARRAY);
$where = [];
$op = '=';
$field = null;
$ret = null;
if (empty($q)) {
print header(JSON) . json_encode(null);
die;
}
if (strpos($q, "%") !== false) {
$op = LIKE;
$q = "'$q'";
}
if ($type == 'stig' || $type == 'vms' || $type == 'ia' || $type == 'nessus') {
if ($type == 'stig') {
$field = '`STIG_ID`';
}
elseif ($type == 'vms') {
$field = '`VMS_ID`';
}
elseif ($type == 'ia') {
$field = '`IA_Controls`';
}
elseif ($type == 'nessus') {
$field = '`Nessus_ID`';
}
if (!is_null($field)) {
$where[] = [
'field' => $field,
'op' => $op,
'value' => $q
];
}
if (!empty($filter['value'])) {
$where[] = [
'field' => 'pdi.STIG_ID',
'op' => LIKE,
'value' => "'%{$filter['value']}%'",
'open-paren' => true,
'sql_op' => 'AND'
];
$where[] = [
'field' => 'pdi.VMS_ID',
'op' => LIKE,
'value' => "'%{$filter['value']}%'",
'sql_op' => 'OR'
];
$where[] = [
'field' => 'pdi.IA_Controls',
'op' => LIKE,
'value' => "'%{$filter['value']}%'",
'sql_op' => 'OR'
];
$where[] = [
'field' => 'pdi.Short_Title',
'op' => LIKE,
'value' => "'%{$filter['value']}%'",
'sql_op' => 'OR'
];
$where[] = [
'field' => 'pdi.Description',
'op' => LIKE,
'value' => "'%{$filter['value']}%'",
'sql_op' => 'OR'
];
$where[] = [
'field' => 'lu.check_contents',
'op' => LIKE,
'value' => "'%{$filter['value']}%'",
'sql_op' => 'OR',
'close-paren' => true
];
}
$db->help->select_count("sagacity.pdi", $where, [
'table_joins' => [
"LEFT JOIN sagacity.pdi_checklist_lookup lu ON pdi.pdi_id = lu.pdi_id",
"LEFT JOIN sagacity.checklist chk ON chk.id = lu.checklist_id"
]
]);
$count = $db->help->execute();
$ret = [
'columns' => [
['title' => 'STIG ID', 'data' => 'stig_id'],
['title' => 'VMS ID', 'data' => 'vms_id'],
['title' => 'Checklist Name', 'data' => 'name'],
['title' => 'Type', 'data' => 'type'],
['title' => 'PDI', 'data' => 'pdi_id'],
['title' => 'File Name', 'data' => 'file']
],
'draw' => $draw,
'recordsTotal' => $count,
'recordsFiltered' => $count,
'data' => []
];
$db->help->select("sagacity.pdi", null, $where, [
'table_joins' => [
"LEFT JOIN sagacity.pdi_checklist_lookup lu ON pdi.pdi_id = lu.pdi_id",
"LEFT JOIN sagacity.checklist chk ON chk.id = lu.checklist_id"
],
'limit' => $len,
'start' => $start
]);
$rows = $db->help->execute();
if (is_array($rows) && count($rows) && isset($rows['STIG_ID'])) {
$rows = [0 => $rows];
}
if (is_array($rows) && count($rows) && isset($rows[0])) {
foreach ($rows as $row) {
$ret['data'][] = [
'stig_id' => $row['STIG_ID'],
'vms_id' => $row['VMS_ID'],
'name' => $row['name'],
'type' => $row['type'],
'pdi_id' => $row['pdi_id'],
'file' => $row['file_name']
];
}
}
}
elseif ($type == 'cve') {
$where[] = [
'field' => 'db.cve_id',
'op' => $op,
'value' => $q
];
if (!empty($filter['value'])) {
$where[] = [
'field' => 'status',
'op' => LIKE,
'value' => "'%{$filter['value']}%'",
'sql_op' => 'AND',
'open-paren' => true
];
$where[] = [
'field' => 'desc',
'op' => LIKE,
'value' => "'%{$filter['value']}%'",
'sql_op' => 'OR',
'close-paren' => true
];
}
$db->help->select_count("sagacity.cve_db db", $where, [
'table_joins' => [
"LEFT JOIN sagacity.cve ON db.cve_id = cve.cve_id"
]
]);
$count = $db->help->execute();
$ret = [
'columns' => [
['title' => 'PDI ID', 'data' => 'pdi_id'],
['title' => 'CVE ID', 'data' => 'cve_id'],
['title' => 'Description', 'data' => 'desc'],
['title' => 'Status', 'data' => 'status'],
['title' => 'References', 'data' => 'ref']
],
'draw' => $draw,
'recordsTotal' => $count,
'recordsFiltered' => $count,
'data' => []
];
$db->help->select("sagacity.cve_db db", ['db.cve_id', 'cve.pdi_id', 'db.seq', 'db.status', 'db.desc'], $where, [
'table_joins' => [
"LEFT JOIN sagacity.cve ON db.cve_id = cve.cve_id"
],
'limit' => $len,
'start' => $start
]);
$rows = $db->help->execute();
if (is_array($rows) && count($rows) && isset($rows['cve_id'])) {
$rows = [0 => $rows];
}
if (is_array($rows) && count($rows) && isset($rows[0])) {
foreach ($rows as $row) {
$references = null;
$db->help->select("sagacity.cve_references", ['source', 'url'], [
[
'field' => 'cve_seq',
'op' => '=',
'value' => $row['cve_id']
],
[
'field' => 'url',
'op' => '!=',
'value' => '',
'sql_op' => 'AND'
]
], [
'group' => 'source'
]);
$refs = $db->help->execute();
if (is_array($refs) && count($refs) && isset($refs['source'])) {
$refs = [0 => $refs];
}
if (is_array($refs) && count($refs) && isset($refs[0])) {
foreach ($refs as $ref) {
$references .= "{$ref['source']} ";
}
}
$ret['data'][] = [
'pdi_id' => "{$row['pdi_id']}",
'cve_id' => $row['cve_id'],
'desc' => $row['desc'],
'status' => $row['status'],
'ref' => $references
];
}
}
}
elseif ($type == 'cpe') {
$where[] = [
'field' => 'cpe',
'op' => $op,
'value' => $q
];
if (!empty($filter['search'])) {
$where[] = [
'field' => 'cpe',
'op' => LIKE,
'value' => $filter['search'],
'sql_op' => 'OR'
];
}
$db->help->select_count("sagacity.software", $where);
$count = $db->help->execute();
$ret = [
'columns' => [
['title' => 'Man', 'data' => 'man'],
['title' => 'Name', 'data' => 'name'],
['title' => 'Ver', 'data' => 'ver'],
['title' => 'CPE', 'data' => 'cpe'],
['title' => 'String', 'data' => 'sw_string']
],
'draw' => $draw,
'recordsTotal' => $count,
'recordsFiltered' => $count,
'data' => []
];
$db->help->select("sagacity.software", null, $where);
$rows = $db->help->execute();
if (is_array($rows) && count($rows) && isset($rows['cpe'])) {
$rows = [0 => $rows];
}
if (is_array($rows) && count($rows) && isset($rows[0])) {
foreach ($rows as $row) {
list($cpe, $type, $man, $name, $ver) = explode(":", $row['cpe']);
$ret['data'][] = [
'man' => ucwords($man),
'name' => ucwords($name),
'ver' => $ver,
'cpe' => $row['cpe'],
'sw_string' => $row['sw_string']
];
}
}
}
elseif ($type == 'iavm') {
$where[] = [
'field' => 'iavmNoticeNumber',
'op' => $op,
'value' => $q
];
$db->help->select_count("sagacity.iavm_notices", $where);
$count = $db->help->execute();
$ret = [
'columns' => [
['title' => 'PDI ID', 'data' => 'pdi_id'],
['title' => 'IAVM Notice', 'data' => 'iavm'],
['title' => 'Title', 'data' => 'title'],
['title' => 'Category', 'data' => 'cat'],
['title' => 'Link', 'data' => 'link']
],
'draw' => $draw,
'recordsTotal' => $count,
'recordsFiltered' => $count,
'data' => []
];
$db->help->select("sagacity.iavm_notices", null, $where, [
'order' => 'iavmNoticeNumber'
]);
$rows = $db->help->execute();
if (is_array($rows) && count($rows) && isset($rows['iavmNoticeNumber'])) {
$rows = [0 => $rows];
}
if (is_array($rows) && count($rows) && isset($rows[0])) {
foreach ($rows as $row) {
$cat = implode("", array_fill(0, $row['stigFindingSeverity'], "I"));
$ret['data'][] = [
'pdi_id' => "{$row['pdi_id']}",
'iavm' => $row['iavmNoticeNumber'],
'title' => $row['title'],
'cat' => $cat,
'link' => "XML"
];
}
}
}
else {
if (strpos($q, "%") === false) {
$q = "'%{$q}%'";
}
$where = [
[
'field' => 'pcl.short_title',
'op' => LIKE,
'value' => $q
],
[
'field' => 's.description',
'op' => LIKE,
'value' => $q,
'sql_op' => 'OR'
],
[
'field' => 'pcl.check_contents',
'op' => LIKE,
'value' => $q,
'sql_op' => 'OR'
]
];
if (!empty($filter['value'])) {
$where[] = [
'field' => 's.stig_id',
'op' => LIKE,
'value' => "'%{$filter['value']}%'",
'sql_op' => 'AND',
'open-paren' => true
];
$where[] = [
'field' => 'gd.vms_id',
'op' => LIKE,
'value' => "'%{$filter['value']}%'",
'sql_op' => 'OR',
'close-paren' => true
];
}
$db->help->select_count("sagacity.pdi_catalog pdi", $where, [
'table_joins' => [
"LEFT JOIN sagacity.stigs s ON s.pdi_id=pdi.id",
"LEFT JOIN sagacity.golddisk gd ON gd.pdi_id=pdi.id",
"LEFT JOIN sagacity.pdi_checklist_lookup pcl ON pdi.id=pcl.pdi_id",
"LEFT JOIN sagacity.checklist c ON c.id=pcl.checklist_id"
]
]);
$count = $db->help->execute();
$ret = [
'columns' => [
['title' => 'STIG ID', 'data' => 'stig_id'],
['title' => 'VMS ID', 'data' => 'vms_id'],
['title' => 'Checklist Name', 'data' => 'name'],
['title' => 'Type', 'data' => 'type'],
['title' => 'PDI', 'data' => 'pdi_id'],
['title' => 'File Name', 'data' => 'file']
],
'draw' => $draw,
'recordsTotal' => $count,
'recordsFiltered' => $count,
'data' => []
];
$db->help->select("sagacity.pdi_catalog pdi", [
"pdi.id AS 'pdi_id'", "pdi.short_title AS 'Short_Title'",
"s.stig_id AS 'STIG_ID'", "gd.vms_id AS 'VMS_ID'",
"c.id AS 'chk_id'", "c.`name` AS 'chk_name'", "c.file_name", "c.`type`", "c.`release`", "c.`ver`"
], $where, [
'table_joins' => [
"LEFT JOIN sagacity.stigs s ON s.pdi_id=pdi.id",
"LEFT JOIN sagacity.golddisk gd ON gd.pdi_id=pdi.id",
"LEFT JOIN sagacity.pdi_checklist_lookup pcl ON pdi.id=pcl.pdi_id",
"LEFT JOIN sagacity.checklist c ON c.id=pcl.checklist_id"
],
'start' => $start,
'limit' => $len
]);
$rows = $db->help->execute();
if (is_array($rows) && count($rows) && isset($rows['pdi_id'])) {
$rows = [0 => $rows];
}
if (is_array($rows) && count($rows) && isset($rows[0])) {
foreach ($rows as $row) {
$name = str_replace("Security Technical Implementation Guide", "STIG", $row['chk_name']);
$title = "{$row['Short_Title']} (from $name)";
$file_name = basename($row['file_name']);
$ret['data'][] = [
'stig_id' => $row['STIG_ID'],
'vms_id' => $row['VMS_ID'],
'name' => "{$row['chk_name']} V{$row['ver']}R{$row['release']}",
'type' => $row['type'],
'pdi_id' => "PDI",
'file' => ""
];
}
}
}
print header(JSON) . json_encode($ret);