Skip to content

Commit

Permalink
Merge branch 'master' into query-benchmark/linux
Browse files Browse the repository at this point in the history
  • Loading branch information
guliashvili committed Sep 13, 2018
2 parents 4cf9765 + 9b3e147 commit 2358efe
Show file tree
Hide file tree
Showing 34 changed files with 700 additions and 115 deletions.
13 changes: 12 additions & 1 deletion Vagrantfile
Expand Up @@ -134,7 +134,18 @@ Vagrant.configure("2") do |config|
v.memory = 4096
end
end

config.vm.provider "vmware_desktop" do |v|
if ENV['OSQUERY_BUILD_CPUS']
v.cpus = ENV['OSQUERY_BUILD_CPUS'].to_i
else
v.cpus = 2
end
if ENV['OSQUERY_BUILD_MEMORY']
v.memory = ENV['OSQUERY_BUILD_MEMORY'].to_i
else
v.memory = 4096
end
end
config.vm.provider :aws do |aws, override|
# Required. Credentials for AWS API.
aws.access_key_id = ENV['AWS_ACCESS_KEY_ID']
Expand Down
6 changes: 4 additions & 2 deletions include/osquery/expected.h
Expand Up @@ -185,8 +185,10 @@ class Expected final {
}

template <typename ValueTypeUniversal = ValueType>
typename std::enable_if<std::is_same<ValueTypeUniversal, ValueType>::value,
ValueType>::type
typename std::enable_if<
std::is_same<typename std::decay<ValueTypeUniversal>::type,
ValueType>::value,
ValueType>::type
takeOr(ValueTypeUniversal&& defaultValue) {
if (isError()) {
return std::forward<ValueTypeUniversal>(defaultValue);
Expand Down
13 changes: 13 additions & 0 deletions include/osquery/filesystem.h
Expand Up @@ -234,6 +234,19 @@ Status movePath(const boost::filesystem::path& from,
*/
Status isDirectory(const boost::filesystem::path& path);

/**
* @brief Create the directory
*
* @param path to the intended directory
* @param recursive - make parent directories as needed
* @param ignore_existence - no error if directory already exists
*
* @return Status of operation
*/
Status createDirectory(const boost::filesystem::path& path,
bool recursive = false,
bool ignore_existence = false);

/**
* @brief Return a vector of all home directories on the system.
*
Expand Down
25 changes: 0 additions & 25 deletions osquery/core/conversions.h
Expand Up @@ -76,31 +76,6 @@ inline std::string join(const SequenceType& s, const std::string& tok) {
*/
bool isPrintable(const std::string& check);

/// Safely convert a std::wstring to an integer
inline int safeWstrToInt(std::wstring str) {
// std::stoi can throw, and std::stol doesn't support std::wstring
try {
return std::stoi(str);
} catch (const std::out_of_range&) {
return 0;
} catch (const std::invalid_argument&) {
return 0;
}
}

/// Safely convert a string representation of an integer base.
inline Status safeStrtoul(const std::string& rep,
size_t base,
unsigned long int& out) {
char* end{nullptr};
out = strtoul(rep.c_str(), &end, static_cast<int>(base));
if (end == nullptr || end == rep.c_str() || *end != '\0' || errno == ERANGE) {
out = 0;
return Status(1);
}
return Status(0);
}

/**
* @brief In-line helper function for use with utf8StringSize
*/
Expand Down
16 changes: 16 additions & 0 deletions osquery/core/tests/exptected_tests.cpp
Expand Up @@ -300,4 +300,20 @@ GTEST_TEST(ExpectedTest, error__takeOr_with_user_defined_class) {
"427 BC - 347 BC");
}

GTEST_TEST(ExpectedTest, value_takeOr_with_rvalue_as_an_argument) {
auto value = int{312};
auto callable = []() -> Expected<int, TestError> { return 306; };
value = callable().takeOr(value);
EXPECT_EQ(value, 306);
}

GTEST_TEST(ExpectedTest, error_takeOr_with_rvalue_as_an_argument) {
auto value = int{312};
auto callable = []() -> Expected<int, TestError> {
return createError(TestError::Logical, "error message");
};
value = callable().takeOr(value);
EXPECT_EQ(value, 312);
}

} // namespace osquery
19 changes: 10 additions & 9 deletions osquery/core/windows/process_ops.cpp
Expand Up @@ -24,31 +24,32 @@ std::string psidToString(PSID sid) {
}

int getUidFromSid(PSID sid) {
unsigned long uid = -1;
unsigned long const uid_default = -1;
LPTSTR sidString;
if (ConvertSidToStringSid(sid, &sidString) == 0) {
VLOG(1) << "getUidFromSid failed ConvertSidToStringSid error " +
std::to_string(GetLastError());
LocalFree(sidString);
return uid;
return uid_default;
}
auto toks = osquery::split(sidString, "-");

if (toks.size() < 1) {
LocalFree(sidString);
return uid;
return uid_default;
}

auto ret = safeStrtoul(toks.at(toks.size() - 1), 10, uid);
auto uid_exp = tryTo<unsigned long int>(toks.at(toks.size() - 1), 10);

if (!ret.ok()) {
if (uid_exp.isError()) {
LocalFree(sidString);
VLOG(1) << "getUidFromSid failed with safeStrtoul failed to parse PSID";
return uid;
VLOG(1) << "failed to parse PSID "
<< uid_exp.getError().getFullMessageRecursive();
return uid_default;
}

LocalFree(sidString);
return uid;
return uid_exp.take();
}

int getGidFromSid(PSID sid) {
Expand Down Expand Up @@ -82,7 +83,7 @@ int getGidFromSid(PSID sid) {
LPTSTR sidString;
ConvertSidToStringSid(sid, &sidString);
auto toks = osquery::split(sidString, "-");
safeStrtoul(toks.at(toks.size() - 1), 10, gid);
gid = tryTo<unsigned long int>(toks.at(toks.size() - 1), 10).takeOr(gid);
LocalFree(sidString);

} else if (ret == NERR_Success) {
Expand Down
51 changes: 51 additions & 0 deletions osquery/core/windows/wmi.cpp
Expand Up @@ -87,6 +87,57 @@ Status WmiResultItem::GetBool(const std::string& name, bool& ret) const {
return Status(0);
}

Status WmiResultItem::GetDateTime(const std::string& name,
bool is_local,
FILETIME& ft) const {
std::wstring property_name = stringToWstring(name);

VARIANT value;
HRESULT hr = result_->Get(property_name.c_str(), 0, &value, nullptr, nullptr);
if (hr != S_OK) {
return Status(-1, "Error retrieving datetime from WMI query result.");
}

if (value.vt != VT_BSTR) {
VariantClear(&value);
return Status(-1, "Expected VT_BSTR, got something else.");
}

ISWbemDateTime* dt = nullptr;
hr = CoCreateInstance(
CLSID_SWbemDateTime, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&dt));
if (!SUCCEEDED(hr)) {
VariantClear(&value);
return Status(-1, "Failed to create SWbemDateTime object.");
}

hr = dt->put_Value(value.bstrVal);
VariantClear(&value);

if (!SUCCEEDED(hr)) {
dt->Release();
return Status(-1, "Failed to set SWbemDateTime value.");
}

BSTR filetime_str = {0};
hr = dt->GetFileTime(is_local ? VARIANT_TRUE : VARIANT_FALSE, &filetime_str);
if (!SUCCEEDED(hr)) {
dt->Release();
return Status(-1, "GetFileTime failed.");
}

ULARGE_INTEGER ui = {};

ui.QuadPart = _wtoi64(filetime_str);
ft.dwLowDateTime = ui.LowPart;
ft.dwHighDateTime = ui.HighPart;

SysFreeString(filetime_str);
dt->Release();

return Status(0);
}

Status WmiResultItem::GetUChar(const std::string& name,
unsigned char& ret) const {
std::wstring property_name = stringToWstring(name);
Expand Down
10 changes: 10 additions & 0 deletions osquery/core/windows/wmi.h
Expand Up @@ -93,6 +93,16 @@ class WmiResultItem {
*/
Status GetBool(const std::string& name, bool& ret) const;

/**
* @brief Windows WMI Helper function to retrieve a local/non-local FILETIME
* from WMI query.
*
* @returns Status indiciating the success of the query
*/
Status GetDateTime(const std::string& name,
bool is_local,
FILETIME& ft) const;

/**
* @brief Windows WMI Helper function to retrieve an unsigned Char from WMI
* query
Expand Down
8 changes: 4 additions & 4 deletions osquery/dispatcher/distributed_runner.cpp
Expand Up @@ -41,10 +41,10 @@ void DistributedRunner::start() {
std::string str_acu = "0";
Status database = getDatabaseValue(
kPersistentSettings, "distributed_accelerate_checkins_expire", str_acu);
unsigned long accelerate_checkins_expire;
Status conversion = safeStrtoul(str_acu, 10, accelerate_checkins_expire);
if (!database.ok() || !conversion.ok() ||
getUnixTime() > accelerate_checkins_expire) {
auto const accelerate_checkins_expire_exp =
tryTo<unsigned long int>(str_acu, 10);
if (!database.ok() || accelerate_checkins_expire_exp.isError() ||
getUnixTime() > accelerate_checkins_expire_exp.get()) {
pause(std::chrono::seconds(FLAGS_distributed_interval));
} else {
pause(std::chrono::seconds(kDistributedAccelerationInterval));
Expand Down
11 changes: 6 additions & 5 deletions osquery/events/events.cpp
Expand Up @@ -327,8 +327,9 @@ void EventSubscriberPlugin::expireCheck() {
unsigned long min_key_value = 0;
unsigned long max_key_value = 0;
for (const auto& key : keys) {
unsigned long key_value = 0;
safeStrtoul(key.substr(key.rfind('.') + 1), 10, key_value);
auto const key_value =
tryTo<unsigned long int>(key.substr(key.rfind('.') + 1), 10)
.takeOr(0ul);

if (key_value < static_cast<unsigned long>(threshold_key)) {
min_key_value = (min_key_value == 0 || key_value < min_key_value)
Expand Down Expand Up @@ -524,9 +525,9 @@ void EventSubscriberPlugin::get(RowYield& yield,

if (FLAGS_events_optimize && !records.empty()) {
// If records were returned save the ordered-last as the optimization EID.
unsigned long int eidr = 0;
if (safeStrtoul(records.back().first, 10, eidr)) {
optimize_eid_ = static_cast<size_t>(eidr);
auto const eidr_exp = tryTo<unsigned long int>(records.back().first, 10);
if (eidr_exp.isValue()) {
optimize_eid_ = static_cast<size_t>(eidr_exp.get());
}
}

Expand Down
4 changes: 3 additions & 1 deletion osquery/events/linux/auditdnetlink.cpp
Expand Up @@ -762,7 +762,9 @@ bool AuditdNetlinkParser::ParseAuditReply(
return false;
}

safeStrtoul(message_view.substr(6, 10).to_string(), 10, event_record.time);
event_record.time =
tryTo<unsigned long int>(message_view.substr(6, 10).to_string(), 10)
.takeOr(event_record.time);
event_record.audit_id = message_view.substr(6, preamble_end - 6).to_string();

// SELinux doesn't output valid audit records; just save them as they are
Expand Down
8 changes: 4 additions & 4 deletions osquery/examples/example_writable_table.cpp
Expand Up @@ -159,15 +159,15 @@ class WritableTable : public TablePlugin {
row["rowid"] = std::to_string(new_rowid);

} else {
unsigned long long int existing_rowid;
status = safeStrtoull(request.at("id"), 10, existing_rowid);
if (!status.ok()) {
auto const existing_rowid_exp =
tryTo<unsigned long long>(request.at("id"), 10);
if (existing_rowid_exp.isError()) {
return {
{std::make_pair("status", "failure"),
std::make_pair("message", "Invalid rowid defined by osquery")}};
}

row["rowid"] = std::to_string(existing_rowid);
row["rowid"] = std::to_string(existing_rowid_exp.get());
}

// Finally, save the row; also pass the primary key we calculated so that
Expand Down
26 changes: 26 additions & 0 deletions osquery/filesystem/filesystem.cpp
Expand Up @@ -438,6 +438,32 @@ Status isDirectory(const fs::path& path) {
return Status(ec.value(), ec.message());
}

Status createDirectory(const boost::filesystem::path& dir_path,
bool const recursive,
bool const ignore_existence) {
auto err = boost::system::error_code{};
bool is_created = false;
if (recursive) {
is_created = boost::filesystem::create_directories(dir_path, err);
} else {
is_created = boost::filesystem::create_directory(dir_path, err);
}
if (is_created) {
return Status::success();
}
if (ignore_existence && isDirectory(dir_path).ok()) {
return Status::success();
}
auto msg = std::string{"Could not create directory \""};
msg += dir_path.string();
msg += '"';
if (err) {
msg += ": ";
msg += err.message();
}
return Status::failure(msg);
}

std::set<fs::path> getHomeDirectories() {
std::set<fs::path> results;

Expand Down

0 comments on commit 2358efe

Please sign in to comment.