Files
cameradar/cameradar_standalone/src/tasks/parsing.cpp
T
Brendan LE GLAUNEC 201d7e31c6 Initial commit
2016-05-20 16:13:22 +02:00

123 lines
4.6 KiB
C++

// Copyright 2016 Etix Labs
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <tasks/parsing.h>
namespace etix {
namespace cameradar {
static const std::string no_hosts_found_ =
"No hosts were discovered on your network. Please check your internet "
"connexion "
"and verify that the subnetworks you specified in your configuration file "
"were "
"accessible";
//! Avoids segfaults on unknown xml structure
std::string
xml_safe_get(const TiXmlElement* elem, const std::string& attr) {
if (elem == nullptr) return "Closed";
if (elem->Attribute(attr.c_str()) != nullptr) return std::string(elem->Attribute(attr.c_str()));
return "Closed";
}
//! Parse a single host node (generally containing only one camera)
//! Pushes it back to the data structure
void
parsing::parse_camera(TiXmlElement* xml_host, std::vector<stream_model>& data) const {
TiXmlElement* xml_streams = xml_host->FirstChild("ports")->ToElement();
stream_model stream;
for (TiXmlElement* xml_stream = xml_streams->FirstChild("port")->ToElement(); xml_stream;
xml_stream = xml_stream->NextSiblingElement("port")) {
stream.address = xml_safe_get(xml_host->FirstChild("address")->ToElement(), "addr");
stream.protocol = xml_safe_get(xml_stream, "protocol");
stream.port = static_cast<unsigned short>(std::stoi(xml_safe_get(xml_stream, "portid")));
TiXmlElement* state = xml_stream->FirstChild("state")->ToElement();
stream.state = xml_safe_get(state, "state");
TiXmlElement* service;
if (state->NextSibling("service") &&
(service = state->NextSibling("service")->ToElement())) {
stream.service_name = xml_safe_get(service, "name");
stream.product = xml_safe_get(service, "product");
} else {
stream.service_name = "Closed";
stream.product = "Closed";
}
data.push_back(stream);
}
}
//! Prints all detected cameras into the data structure and stops the program if
//! no open RTSP streams were found
bool
parsing::print_detected_cameras(const std::vector<stream_model>& data) const {
int added = 0;
for (const auto& stream : data) {
if (!stream.service_name.compare("rtsp") && !stream.state.compare("open")) {
try {
LOG_INFO_("Generated JSON Result : " + deserialize(stream).toStyledString(),
"print");
added++;
} catch (const std::runtime_error& e) {
LOG_WARN_("Port already scanned : " + std::string(e.what()), "parsing");
added++;
}
}
}
if (!added) {
LOG_WARN_(
"Mapping unsuccessful, no rtsp streams were discovered. You "
"should try other "
"subnetworks",
"parsing");
return false;
}
LOG_INFO_("Mapping successfuly ended, " + std::to_string(added) +
" RTSP streams were discovered.",
"parsing");
(*cache)->set_streams(data);
return true;
}
//! Opens the nmap output file, parses the data of each discovered port
//! Adds the RTSP ports only into the DB
bool
parsing::run() const {
std::vector<stream_model> data;
try {
TiXmlDocument doc(nmap_output.c_str());
doc.LoadFile();
TiXmlHandle docHandle(&doc);
TiXmlElement* nmaprun = docHandle.FirstChild("nmaprun").ToElement();
TiXmlNode* xml_node = nmaprun->FirstChild("host");
if (xml_node == NULL) return false;
TiXmlElement* xml_host;
if ((xml_host = xml_node->ToElement()) && xml_host->Attribute("endtime"))
for (xml_host = xml_node->ToElement(); xml_host;
xml_host = xml_host->NextSiblingElement("host")) {
parse_camera(xml_host, data);
}
else
LOG_WARN_(no_hosts_found_, "parsing");
if (data.size() == 0) { LOG_WARN_("No cameras were discovered", "parsing"); }
return print_detected_cameras(data);
} catch (std::exception& e) {
LOG_ERR_("Error during parsing. brutepath aborted : " + std::string(e.what()), "parsing");
return false;
}
}
}
}