This repository has been archived on 2020-01-20. You can view files and clone it, but cannot push or open issues or pull requests.
lilac/autodiscovery/engines/nmap/NmapAutoDiscoveryEngine.php
2011-08-18 14:54:38 +00:00

128 lines
4.2 KiB
PHP
Executable file

<?php
require_once('Net/Traceroute.php');
class NmapAutoDiscoveryEngine extends AutoDiscoveryEngine {
private $xmlFile;
public function init() {
$job = $this->getJob();
$this->xmlFile = "/tmp/" . $job->getId() . "-nmap.xml";
$job->addNotice("Removing potential old job files.");
@unlink($xmlFile);
return true;
}
public function discover() {
$job = $this->getJob();
$job->addNotice("Starting discovery...");
$config = unserialize($job->getConfig());
$targets = $config->getVar("targets");
// Each target is valid
// We have a list of targets
$nmap_flags = "--max-rtt-timeout 100 --max-retries 0 -sS -O -A -v -oX " . $this->xmlFile;
$exec_line = "sudo " . $config->getVar("nmap_binary") . " " . $nmap_flags . " ";
foreach($targets as $target) {
$exec_line .= $target . " ";
}
$job->addNotice("Executing nmap via: " . $exec_line . "\n");
$completed = false;
// Open the process
$handle = popen($exec_line, 'r'); // Only need it for reading
while(!feof($handle)) {
// nmap is running!
$line = fgets($handle);
if(strlen(trim($line))) $job->addNotice("NMAP: " . $line);
if(strpos($line, "Nmap done") === 0 || strpos($line, "Nmap finished") === 0) {
// Nmap is finished
$completed = true;
}
}
if(!$completed) {
$job->addError("Nmap failed to complete successfully. Could be permissions issue (check sudo access). Aborting discovery.");
return false;
}
$job->addNotice("Nmap finished discovery. Now reading in result XML.");
$nmapXML = simplexml_load_file($this->xmlFile);
// Read in hosts
$job->addNotice("Number of hosts: " . count($nmapXML->host));
foreach($nmapXML->host as $host) {
$job->addNotice('Found ' . $host->address[0]['addr'] . ':' . $host->hostnames[0]->hostname[0]['name'] . '.');
$c = new Criteria();
$c1 = $c->getNewCriterion(NagiosHostPeer::ADDRESS, $host->address[0]['addr']);
$c2 = $c->getNewCriterion(NagiosHostPeer::ADDRESS, $host->hostnames[0]->hostname[0]['name']);
$c1->addOr($c2);
$c->add($c1);
$tempHost = NagiosHostPeer::doSelectOne($c);
if($tempHost) {
$job->addNotice("Device appears to already be in configuration under hostname: " . $host->getName() . ". Skipping.");
continue;
}
$device = new AutodiscoveryDevice();
$device->setAutodiscoveryJob($job);
$device->setAddress($host->address[0]['addr']);
if(empty($host->hostnames[0]->hostname[0]['name'])) {
$device->setName($host->address[0]['addr']);
$device->setDescription($host->address[0]['addr']);
}
else {
$device->setName($host->hostnames[0]->hostname[0]['name']);
$device->setDescription($host->hostnames[0]->hostname[0]['name']);
}
$device->setHostname($host->hostnames[0]->hostname[0]['name']);
// Right now, if it exists, we pick the top-level matching os string (since it's the highest scored)
if(!empty($host->os[0]->osclass[0]['osfamily'])) {
// We found os family data
$device->setOsfamily($host->os[0]->osclass[0]['osfamily']);
}
if(!empty($host->os[0]->osclass[0]['osgen'])) {
// We found os family data
$device->setOsgen($host->os[0]->osclass[0]['osgen']);
}
if(!empty($host->os[0]->osclass[0]['vendor'])) {
// We found os family data
$device->setOsvendor($host->os[0]->osclass[0]['vendor']);
}
$device->save();
// Add services
$job->addNotice("Number of ports for this host: " . count($host->ports[0]->port));
foreach($host->ports[0]->port as $port) {
// $port signifies as port / possible service, we'll grab that
$service = new AutodiscoveryDeviceService();
$service->setProtocol($port['protocol']);
$service->setPort($port['portid']);
if(!empty($port->service[0]['name'])) {
$service->setName($port->service[0]['name']);
}
if(!empty($port->service[0]['product'])) {
$service->setProduct($port->service[0]['product']);
}
if(!empty($port->service[0]['version'])) {
$service->setVersion($port->service[0]['version']);
}
if(!empty($port->service[0]['extrainfo'])) {
$service->setExtrainfo($port->service[0]['extrainfo']);
}
$service->setAutodiscoveryDevice($device);
$service->save();
}
}
$job->addNotice("Added devices and services.");
return true;
}
}