mirror of
https://github.com/valitydev/osquery-1.git
synced 2024-11-08 02:18:53 +00:00
141 lines
4.1 KiB
C++
141 lines
4.1 KiB
C++
// Copyright 2004-present Facebook. All Rights Reserved.
|
|
|
|
#include <boost/algorithm/string/join.hpp>
|
|
#include <boost/filesystem/operations.hpp>
|
|
#include <boost/filesystem/path.hpp>
|
|
#include <boost/lexical_cast.hpp>
|
|
|
|
#include <glog/logging.h>
|
|
|
|
#include "osquery/core.h"
|
|
#include "osquery/database.h"
|
|
#include "osquery/filesystem.h"
|
|
|
|
namespace pt = boost::property_tree;
|
|
|
|
namespace osquery {
|
|
namespace tables {
|
|
|
|
const std::map<std::string, std::string> kAppsInfoPlistTopLevelStringKeys = {
|
|
{"CFBundleExecutable", "bundle_executable"},
|
|
{"CFBundleIdentifier", "bundle_identifier"},
|
|
{"CFBundleName", "bundle_name"},
|
|
{"CFBundleShortVersionString", "bundle_short_version"},
|
|
{"CFBundleVersion", "bundle_version"},
|
|
{"CFBundlePackageType", "bundle_package_type"},
|
|
{"CFBundleDevelopmentRegion", "development_region"},
|
|
{"CFBundleDisplayName", "display_name"},
|
|
{"CFBundleGetInfoString", "info_string"},
|
|
{"DTCompiler", "compiler"},
|
|
{"LSMinimumSystemVersion", "minimum_system_version"},
|
|
{"LSApplicationCategoryType", "category"},
|
|
{"NSAppleScriptEnabled", "applescript_enabled"},
|
|
{"NSHumanReadableCopyright", "copyright"},
|
|
};
|
|
|
|
const std::vector<std::string> kHomeDirSearchPaths = {
|
|
"/Applications", "/Desktops", "/Downloads",
|
|
};
|
|
|
|
std::vector<std::string> getAppInfoPlistPaths() {
|
|
std::vector<std::string> results;
|
|
|
|
std::vector<std::string> slash_applications;
|
|
auto slash_apps_s =
|
|
osquery::listFilesInDirectory("/Applications", slash_applications);
|
|
if (slash_apps_s.ok()) {
|
|
for (const auto& app_path : slash_applications) {
|
|
std::string path = app_path + "/Contents/Info.plist";
|
|
if (boost::filesystem::exists(path)) {
|
|
results.push_back(path);
|
|
}
|
|
}
|
|
} else {
|
|
LOG(ERROR) << "Error listing /Applications: " << slash_apps_s.toString();
|
|
}
|
|
|
|
std::vector<std::string> home_dirs;
|
|
auto home_dirs_s = osquery::listFilesInDirectory("/Users", home_dirs);
|
|
if (home_dirs_s.ok()) {
|
|
for (const auto& home_dir : home_dirs) {
|
|
for (const auto& dir_to_check : kHomeDirSearchPaths) {
|
|
std::string apps_path = home_dir + dir_to_check;
|
|
if (boost::filesystem::is_directory(apps_path)) {
|
|
std::vector<std::string> user_apps;
|
|
auto user_apps_s =
|
|
osquery::listFilesInDirectory(apps_path, user_apps);
|
|
if (!user_apps_s.ok()) {
|
|
VLOG(1) << "Error listing " << apps_path << ": "
|
|
<< user_apps_s.toString();
|
|
continue;
|
|
}
|
|
for (const auto& user_app : user_apps) {
|
|
std::string path = user_app + "/Contents/Info.plist";
|
|
if (boost::filesystem::exists(path)) {
|
|
results.push_back(path);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
LOG(ERROR) << "Error listing /Users: " << home_dirs_s.toString();
|
|
}
|
|
|
|
return results;
|
|
}
|
|
|
|
std::string getNameFromInfoPlistPath(const std::string& path) {
|
|
auto bits = osquery::split(path, "/");
|
|
if (bits.size() >= 4) {
|
|
return bits[bits.size() - 3];
|
|
} else {
|
|
return "";
|
|
}
|
|
}
|
|
|
|
std::string getPathFromInfoPlistPath(const std::string& path) {
|
|
auto bits = osquery::split(path, "/");
|
|
if (bits.size() >= 4) {
|
|
bits.pop_back();
|
|
bits.pop_back();
|
|
return "/" + boost::algorithm::join(bits, "/");
|
|
} else {
|
|
return "";
|
|
}
|
|
}
|
|
|
|
Row parseInfoPlist(const std::string& path, const pt::ptree& tree) {
|
|
Row r;
|
|
r["name"] = getNameFromInfoPlistPath(path);
|
|
r["path"] = getPathFromInfoPlistPath(path);
|
|
for (const auto& it : kAppsInfoPlistTopLevelStringKeys) {
|
|
try {
|
|
r[it.second] = tree.get<std::string>(it.first);
|
|
} catch (const pt::ptree_error& e) {
|
|
VLOG(1) << "Error retrieving " << it.first << " from " << path << ": "
|
|
<< e.what();
|
|
r[it.second] = "";
|
|
}
|
|
}
|
|
return r;
|
|
}
|
|
|
|
QueryData genApps() {
|
|
QueryData results;
|
|
|
|
for (const auto& path : getAppInfoPlistPaths()) {
|
|
pt::ptree tree;
|
|
auto s = osquery::parsePlist(path, tree);
|
|
if (s.ok()) {
|
|
results.push_back(parseInfoPlist(path, tree));
|
|
} else {
|
|
LOG(ERROR) << "Error parsing " << path << ": " << s.toString();
|
|
}
|
|
}
|
|
|
|
return results;
|
|
}
|
|
}
|
|
}
|