2014-12-18 18:50:47 +00:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2014, Facebook, Inc.
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* This source code is licensed under the BSD-style license found in the
|
2015-05-12 06:31:13 +00:00
|
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
2014-12-18 18:50:47 +00:00
|
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2014-11-29 16:06:34 +00:00
|
|
|
#include <vector>
|
|
|
|
#include <string>
|
|
|
|
|
|
|
|
#include <boost/algorithm/string/join.hpp>
|
|
|
|
#include <boost/algorithm/string/predicate.hpp>
|
|
|
|
|
2014-12-14 21:14:00 +00:00
|
|
|
#include <osquery/core.h>
|
2015-01-21 21:36:55 +00:00
|
|
|
#include <osquery/logger.h>
|
2014-12-14 21:14:00 +00:00
|
|
|
#include <osquery/tables.h>
|
|
|
|
#include <osquery/filesystem.h>
|
2014-11-29 16:06:34 +00:00
|
|
|
|
|
|
|
namespace osquery {
|
|
|
|
namespace tables {
|
|
|
|
|
|
|
|
QueryData parseEtcServicesContent(const std::string& content) {
|
|
|
|
QueryData results;
|
|
|
|
|
|
|
|
for (const auto& line : split(content, "\n")) {
|
|
|
|
// Empty line or comment.
|
|
|
|
if (line.size() == 0 || boost::starts_with(line, "#")) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// [0]: name port/protocol [aliases]
|
2014-12-14 21:14:00 +00:00
|
|
|
// [1]: [comment part1]
|
|
|
|
// [2]: [comment part2]
|
|
|
|
// [n]: [comment partn]
|
2014-11-29 16:06:34 +00:00
|
|
|
auto service_info_comment = split(line, "#");
|
|
|
|
|
|
|
|
// [0]: name
|
|
|
|
// [1]: port/protocol
|
|
|
|
// [2]: [aliases0]
|
|
|
|
// [3]: [aliases1]
|
|
|
|
// [n]: [aliasesn]
|
|
|
|
auto service_info = split(service_info_comment[0]);
|
|
|
|
if (service_info.size() < 2) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// [0]: port [1]: protocol
|
|
|
|
auto service_port_protocol = split(service_info[1], "/");
|
|
|
|
if (service_port_protocol.size() != 2) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2014-12-14 21:14:00 +00:00
|
|
|
Row r;
|
|
|
|
r["name"] = TEXT(service_info[0]);
|
|
|
|
r["port"] = INTEGER(service_port_protocol[0]);
|
|
|
|
r["protocol"] = TEXT(service_port_protocol[1]);
|
2014-11-29 16:06:34 +00:00
|
|
|
|
|
|
|
// Removes the name and the port/protcol elements.
|
|
|
|
service_info.erase(service_info.begin(), service_info.begin() + 2);
|
2014-12-14 21:14:00 +00:00
|
|
|
r["aliases"] = TEXT(boost::algorithm::join(service_info, " "));
|
2014-11-29 16:06:34 +00:00
|
|
|
|
|
|
|
// If there is a comment for the service.
|
2014-12-14 21:14:00 +00:00
|
|
|
if (service_info_comment.size() > 1) {
|
|
|
|
// Removes everything except the comment (parts of the comment).
|
2015-07-24 07:09:06 +00:00
|
|
|
service_info_comment.erase(service_info_comment.begin(),
|
|
|
|
service_info_comment.begin() + 1);
|
2014-12-14 21:14:00 +00:00
|
|
|
r["comment"] = TEXT(boost::algorithm::join(service_info_comment, " # "));
|
2014-11-29 16:06:34 +00:00
|
|
|
}
|
|
|
|
results.push_back(r);
|
|
|
|
}
|
|
|
|
return results;
|
|
|
|
}
|
|
|
|
|
2014-12-14 21:14:00 +00:00
|
|
|
QueryData genEtcServices(QueryContext& context) {
|
2014-11-29 16:06:34 +00:00
|
|
|
std::string content;
|
|
|
|
auto s = osquery::readFile("/etc/services", content);
|
|
|
|
if (s.ok()) {
|
|
|
|
return parseEtcServicesContent(content);
|
|
|
|
} else {
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|