mirror of
https://github.com/valitydev/osquery-1.git
synced 2024-11-06 17:45:22 +00:00
Added custom path functions (#4265)
This commit is contained in:
parent
584c5ddcbd
commit
6047e7d6f8
@ -8,6 +8,7 @@ set(OSQUERY_SQL_INTERNAL
|
||||
"sqlite_hashing.cpp"
|
||||
"sqlite_encoding.cpp"
|
||||
"virtual_table.cpp"
|
||||
"sqlite_filesystem.cpp"
|
||||
"virtual_sqlite_table.cpp"
|
||||
)
|
||||
|
||||
|
@ -75,7 +75,7 @@ void registerEncodingExtensions(sqlite3* db) {
|
||||
sqlite3_create_function(db,
|
||||
"conditional_to_base64",
|
||||
1,
|
||||
SQLITE_UTF8,
|
||||
SQLITE_UTF8 | SQLITE_DETERMINISTIC,
|
||||
nullptr,
|
||||
sqliteB64ConditionalEncFunc,
|
||||
nullptr,
|
||||
@ -83,7 +83,7 @@ void registerEncodingExtensions(sqlite3* db) {
|
||||
sqlite3_create_function(db,
|
||||
"to_base64",
|
||||
1,
|
||||
SQLITE_UTF8,
|
||||
SQLITE_UTF8 | SQLITE_DETERMINISTIC,
|
||||
nullptr,
|
||||
sqliteB64EncFunc,
|
||||
nullptr,
|
||||
@ -91,10 +91,10 @@ void registerEncodingExtensions(sqlite3* db) {
|
||||
sqlite3_create_function(db,
|
||||
"from_base64",
|
||||
1,
|
||||
SQLITE_UTF8,
|
||||
SQLITE_UTF8 | SQLITE_DETERMINISTIC,
|
||||
nullptr,
|
||||
sqliteB64DecFunc,
|
||||
nullptr,
|
||||
nullptr);
|
||||
}
|
||||
}
|
||||
} // namespace osquery
|
||||
|
164
osquery/sql/sqlite_filesystem.cpp
Normal file
164
osquery/sql/sqlite_filesystem.cpp
Normal file
@ -0,0 +1,164 @@
|
||||
/**
|
||||
* Copyright (c) 2017-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under both the Apache 2.0 license (found in the
|
||||
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
|
||||
* in the COPYING file in the root directory of this source tree).
|
||||
* You may select, at your option, one of the above-listed licenses.
|
||||
*/
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
#include <sqlite3.h>
|
||||
|
||||
namespace osquery {
|
||||
|
||||
static boost::optional<std::string> findExistingProgramPathFromCommand(
|
||||
const char* path, char escape_symbol, bool allow_quoting, bool shortest) {
|
||||
size_t length = strlen(path);
|
||||
std::string result;
|
||||
size_t pos = 0;
|
||||
// Skip spaces
|
||||
for (; pos < length; ++pos) {
|
||||
if (!isspace(path[pos])) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
std::string temp_string;
|
||||
bool is_quoted = false;
|
||||
bool is_escaped = false;
|
||||
for (; pos < length; ++pos) {
|
||||
if (is_escaped) {
|
||||
temp_string += path[pos];
|
||||
is_escaped = false;
|
||||
continue;
|
||||
}
|
||||
if (allow_quoting && path[pos] == '"') {
|
||||
is_quoted = !is_quoted;
|
||||
continue;
|
||||
}
|
||||
if (path[pos] == escape_symbol) {
|
||||
is_escaped = true;
|
||||
continue;
|
||||
}
|
||||
if (!is_quoted && isspace(path[pos])) {
|
||||
// validate temp string
|
||||
boost::filesystem::path test_path = temp_string;
|
||||
auto status = boost::filesystem::status(test_path);
|
||||
if (boost::filesystem::exists(status) &&
|
||||
!boost::filesystem::is_directory(status)) {
|
||||
result = temp_string;
|
||||
if (shortest) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
temp_string += path[pos];
|
||||
}
|
||||
if (result.length() == 0 || !shortest) {
|
||||
boost::filesystem::path test_path = temp_string;
|
||||
auto status = boost::filesystem::status(test_path);
|
||||
if (boost::filesystem::exists(status) &&
|
||||
!boost::filesystem::is_directory(status)) {
|
||||
result = temp_string;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static boost::optional<std::string> findExistingProgramPathFromCommandSqlArgs(
|
||||
int argc, sqlite3_value** argv, bool shortest) {
|
||||
if (argc == 0) {
|
||||
return boost::none;
|
||||
}
|
||||
// NULLs are not allowed
|
||||
for (int i = 0; i < argc; i++) {
|
||||
if (SQLITE_NULL == sqlite3_value_type(argv[i])) {
|
||||
return boost::none;
|
||||
}
|
||||
}
|
||||
const char* path = reinterpret_cast<const char*>(sqlite3_value_text(argv[0]));
|
||||
bool allow_quoting = false;
|
||||
if (argc > 1) {
|
||||
allow_quoting = sqlite3_value_int(argv[1]) != 0 ? true : false;
|
||||
}
|
||||
#ifdef WIN32
|
||||
char escape_symbol = '^';
|
||||
#else
|
||||
char escape_symbol = '\\';
|
||||
#endif
|
||||
if (argc > 2) {
|
||||
const char* escape_symbol_string =
|
||||
reinterpret_cast<const char*>(sqlite3_value_text(argv[2]));
|
||||
if (escape_symbol_string == NULL ||
|
||||
std::strlen(escape_symbol_string) != 1) {
|
||||
return boost::none;
|
||||
}
|
||||
escape_symbol = escape_symbol_string[0];
|
||||
}
|
||||
return findExistingProgramPathFromCommand(
|
||||
path, escape_symbol, allow_quoting, shortest);
|
||||
}
|
||||
|
||||
static void findFilePathInLaunchCommand(sqlite3_context* context,
|
||||
int argc,
|
||||
sqlite3_value** argv) {
|
||||
auto result = findExistingProgramPathFromCommandSqlArgs(argc, argv, true);
|
||||
if (result) {
|
||||
sqlite3_result_text(context,
|
||||
result->c_str(),
|
||||
static_cast<int>(result->size()),
|
||||
SQLITE_TRANSIENT);
|
||||
} else {
|
||||
sqlite3_result_error(
|
||||
context, "Invalid inputs to find_binary_path_from_cmd", -1);
|
||||
}
|
||||
}
|
||||
|
||||
static void isPathDeterministic(sqlite3_context* context,
|
||||
int argc,
|
||||
sqlite3_value** argv) {
|
||||
auto shortest = findExistingProgramPathFromCommandSqlArgs(argc, argv, true);
|
||||
if (shortest) {
|
||||
const char* path = (const char*)sqlite3_value_text(argv[0]);
|
||||
if (shortest->length() == 0 || shortest->length() == strlen(path)) {
|
||||
// There are 2 cases:
|
||||
// 1 - empty string, all parts of path are invalid,
|
||||
// so path is deterministic
|
||||
// 2 - short == full, then there is only 1 valid path
|
||||
sqlite3_result_int(context, 1);
|
||||
return;
|
||||
} else {
|
||||
auto longest =
|
||||
findExistingProgramPathFromCommandSqlArgs(argc, argv, false);
|
||||
if (longest) {
|
||||
sqlite3_result_int(context,
|
||||
shortest->length() == longest->length() ? 1 : 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
sqlite3_result_error(context, "Invalid inputs to is_path_deterministic", -1);
|
||||
}
|
||||
|
||||
void registerFilesystemExtensions(sqlite3* db) {
|
||||
sqlite3_create_function(db,
|
||||
"is_path_deterministic",
|
||||
-1,
|
||||
SQLITE_UTF8 | SQLITE_DETERMINISTIC,
|
||||
nullptr,
|
||||
isPathDeterministic,
|
||||
nullptr,
|
||||
nullptr);
|
||||
sqlite3_create_function(db,
|
||||
"find_file_path_in_cmd",
|
||||
-1,
|
||||
SQLITE_UTF8 | SQLITE_DETERMINISTIC,
|
||||
nullptr,
|
||||
findFilePathInLaunchCommand,
|
||||
nullptr,
|
||||
nullptr);
|
||||
}
|
||||
} // namespace osquery
|
@ -58,17 +58,29 @@ static void sqliteSHA256Func(sqlite3_context* context,
|
||||
}
|
||||
|
||||
void registerHashingExtensions(sqlite3* db) {
|
||||
sqlite3_create_function(
|
||||
db, "md5", 1, SQLITE_UTF8, nullptr, sqliteMD5Func, nullptr, nullptr);
|
||||
sqlite3_create_function(
|
||||
db, "sha1", 1, SQLITE_UTF8, nullptr, sqliteSHA1Func, nullptr, nullptr);
|
||||
sqlite3_create_function(db,
|
||||
"md5",
|
||||
1,
|
||||
SQLITE_UTF8 | SQLITE_DETERMINISTIC,
|
||||
nullptr,
|
||||
sqliteMD5Func,
|
||||
nullptr,
|
||||
nullptr);
|
||||
sqlite3_create_function(db,
|
||||
"sha1",
|
||||
1,
|
||||
SQLITE_UTF8 | SQLITE_DETERMINISTIC,
|
||||
nullptr,
|
||||
sqliteSHA1Func,
|
||||
nullptr,
|
||||
nullptr);
|
||||
sqlite3_create_function(db,
|
||||
"sha256",
|
||||
1,
|
||||
SQLITE_UTF8,
|
||||
SQLITE_UTF8 | SQLITE_DETERMINISTIC,
|
||||
nullptr,
|
||||
sqliteSHA256Func,
|
||||
nullptr,
|
||||
nullptr);
|
||||
}
|
||||
}
|
||||
} // namespace osquery
|
||||
|
@ -52,9 +52,9 @@ using DoubleDoubleFunction = std::function<double(double)>;
|
||||
/**
|
||||
* @brief Call a math function that takes a double and returns a double.
|
||||
*/
|
||||
static void callDoubleFunc(sqlite3_context *context,
|
||||
static void callDoubleFunc(sqlite3_context* context,
|
||||
int argc,
|
||||
sqlite3_value **argv,
|
||||
sqlite3_value** argv,
|
||||
DoubleDoubleFunction f) {
|
||||
double rVal = 0.0, val;
|
||||
assert(argc == 1);
|
||||
@ -75,27 +75,27 @@ static void callDoubleFunc(sqlite3_context *context,
|
||||
}
|
||||
}
|
||||
|
||||
static void sinFunc(sqlite3_context *context, int argc, sqlite3_value **argv) {
|
||||
static void sinFunc(sqlite3_context* context, int argc, sqlite3_value** argv) {
|
||||
callDoubleFunc(context, argc, argv, SIN_FUNC);
|
||||
}
|
||||
|
||||
static void cosFunc(sqlite3_context *context, int argc, sqlite3_value **argv) {
|
||||
static void cosFunc(sqlite3_context* context, int argc, sqlite3_value** argv) {
|
||||
callDoubleFunc(context, argc, argv, COS_FUNC);
|
||||
}
|
||||
|
||||
static void tanFunc(sqlite3_context *context, int argc, sqlite3_value **argv) {
|
||||
static void tanFunc(sqlite3_context* context, int argc, sqlite3_value** argv) {
|
||||
callDoubleFunc(context, argc, argv, TAN_FUNC);
|
||||
}
|
||||
|
||||
static void asinFunc(sqlite3_context *context, int argc, sqlite3_value **argv) {
|
||||
static void asinFunc(sqlite3_context* context, int argc, sqlite3_value** argv) {
|
||||
callDoubleFunc(context, argc, argv, ASIN_FUNC);
|
||||
}
|
||||
|
||||
static void acosFunc(sqlite3_context *context, int argc, sqlite3_value **argv) {
|
||||
static void acosFunc(sqlite3_context* context, int argc, sqlite3_value** argv) {
|
||||
callDoubleFunc(context, argc, argv, ACOS_FUNC);
|
||||
}
|
||||
|
||||
static void atanFunc(sqlite3_context *context, int argc, sqlite3_value **argv) {
|
||||
static void atanFunc(sqlite3_context* context, int argc, sqlite3_value** argv) {
|
||||
callDoubleFunc(context, argc, argv, ATAN_FUNC);
|
||||
}
|
||||
|
||||
@ -103,31 +103,31 @@ static double cot(double x) {
|
||||
return 1.0 / tan(x);
|
||||
}
|
||||
|
||||
static void cotFunc(sqlite3_context *context, int argc, sqlite3_value **argv) {
|
||||
static void cotFunc(sqlite3_context* context, int argc, sqlite3_value** argv) {
|
||||
callDoubleFunc(context, argc, argv, cot);
|
||||
}
|
||||
|
||||
static void logFunc(sqlite3_context *context, int argc, sqlite3_value **argv) {
|
||||
static void logFunc(sqlite3_context* context, int argc, sqlite3_value** argv) {
|
||||
callDoubleFunc(context, argc, argv, LOG_FUNC);
|
||||
}
|
||||
|
||||
static void log10Func(sqlite3_context *context,
|
||||
static void log10Func(sqlite3_context* context,
|
||||
int argc,
|
||||
sqlite3_value **argv) {
|
||||
sqlite3_value** argv) {
|
||||
callDoubleFunc(context, argc, argv, LOG10_FUNC);
|
||||
}
|
||||
|
||||
static void sqrtFunc(sqlite3_context *context, int argc, sqlite3_value **argv) {
|
||||
static void sqrtFunc(sqlite3_context* context, int argc, sqlite3_value** argv) {
|
||||
callDoubleFunc(context, argc, argv, SQRT_FUNC);
|
||||
}
|
||||
|
||||
static void expFunc(sqlite3_context *context, int argc, sqlite3_value **argv) {
|
||||
static void expFunc(sqlite3_context* context, int argc, sqlite3_value** argv) {
|
||||
callDoubleFunc(context, argc, argv, EXP_FUNC);
|
||||
}
|
||||
|
||||
static void powerFunc(sqlite3_context *context,
|
||||
static void powerFunc(sqlite3_context* context,
|
||||
int argc,
|
||||
sqlite3_value **argv) {
|
||||
sqlite3_value** argv) {
|
||||
assert(argc == 2);
|
||||
|
||||
if (sqlite3_value_type(argv[0]) == SQLITE_NULL ||
|
||||
@ -146,9 +146,9 @@ static void powerFunc(sqlite3_context *context,
|
||||
}
|
||||
}
|
||||
|
||||
static void callCastedDoubleFunc(sqlite3_context *context,
|
||||
static void callCastedDoubleFunc(sqlite3_context* context,
|
||||
int argc,
|
||||
sqlite3_value **argv,
|
||||
sqlite3_value** argv,
|
||||
DoubleDoubleFunction f) {
|
||||
double rVal = 0.0;
|
||||
assert(argc == 1);
|
||||
@ -168,13 +168,13 @@ static void callCastedDoubleFunc(sqlite3_context *context,
|
||||
}
|
||||
}
|
||||
|
||||
static void ceilFunc(sqlite3_context *context, int argc, sqlite3_value **argv) {
|
||||
static void ceilFunc(sqlite3_context* context, int argc, sqlite3_value** argv) {
|
||||
callCastedDoubleFunc(context, argc, argv, CEIL_FUNC);
|
||||
}
|
||||
|
||||
static void floorFunc(sqlite3_context *context,
|
||||
static void floorFunc(sqlite3_context* context,
|
||||
int argc,
|
||||
sqlite3_value **argv) {
|
||||
sqlite3_value** argv) {
|
||||
callCastedDoubleFunc(context, argc, argv, FLOOR_FUNC);
|
||||
}
|
||||
|
||||
@ -188,29 +188,29 @@ static double rad2deg(double x) {
|
||||
return 180.0 * x / M_PI;
|
||||
}
|
||||
|
||||
static void rad2degFunc(sqlite3_context *context,
|
||||
static void rad2degFunc(sqlite3_context* context,
|
||||
int argc,
|
||||
sqlite3_value **argv) {
|
||||
sqlite3_value** argv) {
|
||||
callDoubleFunc(context, argc, argv, rad2deg);
|
||||
}
|
||||
|
||||
static void deg2radFunc(sqlite3_context *context,
|
||||
static void deg2radFunc(sqlite3_context* context,
|
||||
int argc,
|
||||
sqlite3_value **argv) {
|
||||
sqlite3_value** argv) {
|
||||
callDoubleFunc(context, argc, argv, deg2rad);
|
||||
}
|
||||
|
||||
static void piFunc(sqlite3_context *context, int argc, sqlite3_value **argv) {
|
||||
static void piFunc(sqlite3_context* context, int argc, sqlite3_value** argv) {
|
||||
sqlite3_result_double(context, M_PI);
|
||||
}
|
||||
|
||||
struct FuncDef {
|
||||
const char *zFunctionName;
|
||||
const char* zFunctionName;
|
||||
int nArg;
|
||||
void (*xFunc)(sqlite3_context *, int, sqlite3_value **);
|
||||
void (*xFunc)(sqlite3_context*, int, sqlite3_value**);
|
||||
};
|
||||
|
||||
void registerMathExtensions(sqlite3 *db) {
|
||||
void registerMathExtensions(sqlite3* db) {
|
||||
// This approach to adding non-standard Math functions was inspired by the
|
||||
// somewhat deprecated/legacy work by Liam Healy from 2010 in the extension
|
||||
// functions contribution.
|
||||
@ -238,11 +238,11 @@ void registerMathExtensions(sqlite3 *db) {
|
||||
sqlite3_create_function(db,
|
||||
aFuncs[i].zFunctionName,
|
||||
aFuncs[i].nArg,
|
||||
SQLITE_UTF8,
|
||||
SQLITE_UTF8 | SQLITE_DETERMINISTIC,
|
||||
nullptr,
|
||||
aFuncs[i].xFunc,
|
||||
nullptr,
|
||||
nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace osquery
|
||||
|
@ -68,4 +68,4 @@ void registerOperationExtensions(sqlite3* db) {
|
||||
addCarveFile,
|
||||
executeCarve);
|
||||
}
|
||||
}
|
||||
} // namespace osquery
|
||||
|
@ -156,7 +156,7 @@ void registerStringExtensions(sqlite3* db) {
|
||||
sqlite3_create_function(db,
|
||||
"split",
|
||||
3,
|
||||
SQLITE_UTF8,
|
||||
SQLITE_UTF8 | SQLITE_DETERMINISTIC,
|
||||
nullptr,
|
||||
tokenStringSplitFunc,
|
||||
nullptr,
|
||||
@ -164,7 +164,7 @@ void registerStringExtensions(sqlite3* db) {
|
||||
sqlite3_create_function(db,
|
||||
"regex_split",
|
||||
3,
|
||||
SQLITE_UTF8,
|
||||
SQLITE_UTF8 | SQLITE_DETERMINISTIC,
|
||||
nullptr,
|
||||
regexStringSplitFunc,
|
||||
nullptr,
|
||||
@ -172,10 +172,10 @@ void registerStringExtensions(sqlite3* db) {
|
||||
sqlite3_create_function(db,
|
||||
"inet_aton",
|
||||
1,
|
||||
SQLITE_UTF8,
|
||||
SQLITE_UTF8 | SQLITE_DETERMINISTIC,
|
||||
nullptr,
|
||||
ip4StringToDecimalFunc,
|
||||
nullptr,
|
||||
nullptr);
|
||||
}
|
||||
}
|
||||
} // namespace osquery
|
||||
|
@ -236,6 +236,7 @@ static inline void openOptimized(sqlite3*& db) {
|
||||
#if !defined(SKIP_CARVER)
|
||||
registerOperationExtensions(db);
|
||||
#endif
|
||||
registerFilesystemExtensions(db);
|
||||
registerHashingExtensions(db);
|
||||
registerEncodingExtensions(db);
|
||||
}
|
||||
@ -549,4 +550,4 @@ Status getQueryColumnsInternal(const std::string& q,
|
||||
|
||||
return status;
|
||||
}
|
||||
}
|
||||
} // namespace osquery
|
||||
|
@ -405,6 +405,11 @@ void registerOperationExtensions(sqlite3* db);
|
||||
*/
|
||||
void registerEncodingExtensions(sqlite3* db);
|
||||
|
||||
/**
|
||||
* @brief Register filesystem-related 'custom' functions.
|
||||
*/
|
||||
void registerFilesystemExtensions(sqlite3* db);
|
||||
|
||||
/**
|
||||
* @brief Generate the data for auto-constructed sqlite tables
|
||||
*
|
||||
@ -419,4 +424,4 @@ void registerEncodingExtensions(sqlite3* db);
|
||||
Status genQueryDataForSqliteTable(const boost::filesystem::path& sqlite_db,
|
||||
const std::string& sqlite_query,
|
||||
QueryData& results);
|
||||
}
|
||||
} // namespace osquery
|
||||
|
Loading…
Reference in New Issue
Block a user