463 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			463 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| /**
 | |
|  * File: search.php
 | |
|  * Author: Ryan Prather <ryan.prather@cyberperspectives.com>
 | |
|  * 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 .= "<a href='{$ref['url']}' target='_blank'>{$ref['source']}</a> ";
 | |
|                 }
 | |
|             }
 | |
| 
 | |
|             $ret['data'][] = [
 | |
|                 'pdi_id' => "<a href='#' onclick='javascript:open_pdi(\"{$row['pdi_id']}\");'>{$row['pdi_id']}</a>",
 | |
|                 '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' => "<a href='#' onclick='javascript:open_pdi(\"{$row['pdi_id']}\");'>{$row['pdi_id']}</a>",
 | |
|                 'iavm'   => $row['iavmNoticeNumber'],
 | |
|                 'title'  => $row['title'],
 | |
|                 'cat'    => $cat,
 | |
|                 'link'   => "<a href='/reference/iavms/{$row['file_name']}' target='_blank'>XML</a>"
 | |
|             ];
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 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']} (<span style = 'font-style:italic;'>from $name</span>)";
 | |
| 
 | |
|             $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'  => "<a href='#' onclick='javascript:open_stig(\"$file_name\", \"{$row['VMS_ID']}\");'>PDI</a>",
 | |
|                 'file'    => "<a href='/reference/stigs/$file_name' target='_blank'><img src='/img/file.png' style='width:25px;' title='$file_name' /></a>"
 | |
|             ];
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| print header(JSON) . json_encode($ret);
 |