mirror of
https://github.com/valitydev/osquery-1.git
synced 2024-11-07 09:58:54 +00:00
Constraint existence now check for constraints using specific operator types.
This change allows QueryContext constraints to be checked for based on operator type. This makes checks for the existence of an equality operator allow enumeration. Example: if (context.constraints["pid"].exists(EQUALS)) { pids = context.constraints["pid"].getAll(EQUALS); } else { osquery::procProcesses(pids); }
This commit is contained in:
parent
ce3ac8a7e3
commit
77aa36fa0b
@ -81,7 +81,7 @@ typedef std::map<std::string, std::vector<std::string> > TableData;
|
||||
* If the query contains a join or where clause with a constraint operator and
|
||||
* expression the table generator may limit the data appropriately.
|
||||
*/
|
||||
enum ConstraintOperator {
|
||||
enum ConstraintOperator : unsigned char {
|
||||
EQUALS = 2,
|
||||
GREATER_THAN = 4,
|
||||
LESS_THAN_OR_EQUALS = 8,
|
||||
@ -89,6 +89,11 @@ enum ConstraintOperator {
|
||||
GREATER_THAN_OR_EQUALS = 32
|
||||
};
|
||||
|
||||
/// Type for flags for what constraint operators are admissable.
|
||||
typedef unsigned char ConstraintOperatorFlag;
|
||||
/// Flag for any operator type.
|
||||
#define ANY_OP 0xFFU
|
||||
|
||||
/**
|
||||
* @brief A Constraint is an operator and expression.
|
||||
*
|
||||
@ -150,15 +155,28 @@ struct ConstraintList {
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check and return if there are any constraints on this column.
|
||||
* @brief Check and return if there are constraints on this column.
|
||||
*
|
||||
* A ConstraintList is used in a ConstraintMap with a column name as the
|
||||
* map index. Tables that act on optional constraints should check if any
|
||||
* constraint was provided.
|
||||
* constraint was provided. The ops parameter serves to specify which
|
||||
* operators we want to check existence for.
|
||||
*
|
||||
* @param ops (Optional: default ANY_OP) The operators types to look for.
|
||||
* @return true if any constraint exists.
|
||||
*/
|
||||
bool exists() const { return (constraints_.size() > 0); }
|
||||
bool exists(const ConstraintOperatorFlag ops = ANY_OP) const {
|
||||
if (ops == ANY_OP) {
|
||||
return (constraints_.size() > 0);
|
||||
} else {
|
||||
for (const struct Constraint &c : constraints_) {
|
||||
if (c.op & ops) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if a constraint exist AND matches the type expression.
|
||||
|
@ -51,13 +51,19 @@ TEST_F(TablesTests, test_constraint_matching) {
|
||||
struct ConstraintList cl;
|
||||
// An empty constraint list has expectations.
|
||||
EXPECT_FALSE(cl.exists());
|
||||
EXPECT_FALSE(cl.exists(GREATER_THAN));
|
||||
EXPECT_TRUE(cl.notExistsOrMatches("some"));
|
||||
|
||||
auto constraint = Constraint(EQUALS);
|
||||
constraint.expr = "some";
|
||||
cl.add(constraint);
|
||||
|
||||
// Test existence checks based on flags.
|
||||
EXPECT_TRUE(cl.exists());
|
||||
EXPECT_TRUE(cl.exists(EQUALS));
|
||||
EXPECT_TRUE(cl.exists(EQUALS | LESS_THAN));
|
||||
EXPECT_FALSE(cl.exists(LESS_THAN));
|
||||
|
||||
EXPECT_TRUE(cl.notExistsOrMatches("some"));
|
||||
EXPECT_TRUE(cl.matches("some"));
|
||||
EXPECT_FALSE(cl.notExistsOrMatches("not_some"));
|
||||
|
@ -127,7 +127,7 @@ QueryData genOpenSockets(QueryContext &context) {
|
||||
|
||||
// If a pid is given then set that as the only item in processes.
|
||||
std::set<std::string> pids;
|
||||
if (context.constraints["pid"].exists()) {
|
||||
if (context.constraints["pid"].exists(EQUALS)) {
|
||||
pids = context.constraints["pid"].getAll(EQUALS);
|
||||
} else {
|
||||
osquery::procProcesses(pids);
|
||||
|
@ -76,7 +76,7 @@ QueryData genRpmPackages(QueryContext& context) {
|
||||
|
||||
rpmts ts = rpmtsCreate();
|
||||
rpmdbMatchIterator matches;
|
||||
if (context.constraints["name"].exists()) {
|
||||
if (context.constraints["name"].exists(EQUALS)) {
|
||||
auto name = (*context.constraints["name"].getAll(EQUALS).begin());
|
||||
matches = rpmtsInitIterator(ts, RPMTAG_NAME, name.c_str(), name.size());
|
||||
} else {
|
||||
@ -116,7 +116,7 @@ QueryData genRpmPackageFiles(QueryContext& context) {
|
||||
|
||||
rpmts ts = rpmtsCreate();
|
||||
rpmdbMatchIterator matches;
|
||||
if (context.constraints["package"].exists()) {
|
||||
if (context.constraints["package"].exists(EQUALS)) {
|
||||
auto name = (*context.constraints["package"].getAll(EQUALS).begin());
|
||||
matches = rpmtsInitIterator(ts, RPMTAG_NAME, name.c_str(), name.size());
|
||||
} else {
|
||||
|
@ -63,7 +63,7 @@ QueryData genCerts(QueryContext &context) {
|
||||
|
||||
// Allow the caller to set an explicit certificate (keychain) search path.
|
||||
std::set<std::string> keychain_paths;
|
||||
if (context.constraints["path"].exists()) {
|
||||
if (context.constraints["path"].exists(EQUALS)) {
|
||||
keychain_paths = context.constraints["path"].getAll(EQUALS);
|
||||
} else {
|
||||
for (const auto& path : kSystemKeychainPaths) {
|
||||
|
@ -88,7 +88,7 @@ QueryData genKeychainItems(QueryContext& context) {
|
||||
|
||||
// Allow the caller to set an explicit certificate (keychain) search path.
|
||||
std::set<std::string> keychain_paths;
|
||||
if (context.constraints["path"].exists()) {
|
||||
if (context.constraints["path"].exists(EQUALS)) {
|
||||
keychain_paths = context.constraints["path"].getAll(EQUALS);
|
||||
} else {
|
||||
// Otherwise limit ONLY to system keychains.
|
||||
|
@ -238,7 +238,7 @@ void genPackageBOM(const std::string& path, QueryData& results) {
|
||||
|
||||
QueryData genPackageBOM(QueryContext& context) {
|
||||
QueryData results;
|
||||
if (context.constraints["path"].exists()) {
|
||||
if (context.constraints["path"].exists(EQUALS)) {
|
||||
// If an explicit path was given, generate and return.
|
||||
auto paths = context.constraints["path"].getAll(EQUALS);
|
||||
for (const auto& path : paths) {
|
||||
@ -268,7 +268,7 @@ void genPackageReceipt(const std::string& path, QueryData& results) {
|
||||
|
||||
QueryData genPackageReceipts(QueryContext& context) {
|
||||
QueryData results;
|
||||
if (context.constraints["path"].exists()) {
|
||||
if (context.constraints["path"].exists(EQUALS)) {
|
||||
// If an explicit path was given, generate and return.
|
||||
auto paths = context.constraints["path"].getAll(EQUALS);
|
||||
for (const auto& path : paths) {
|
||||
|
@ -158,7 +158,7 @@ void genOSXDomainPrefs(const CFStringRef& domain, QueryData& results) {
|
||||
void genOSXDefaultPreferences(QueryContext& context, QueryData& results) {
|
||||
CFArrayRef app_map;
|
||||
|
||||
if (context.constraints["domain"].exists()) {
|
||||
if (context.constraints["domain"].exists(EQUALS)) {
|
||||
// If a specific domain is requested, speed up the set of type conversions.
|
||||
auto domains = context.constraints["domain"].getAll(EQUALS);
|
||||
app_map = (CFArrayRef)CFArrayCreateMutable(
|
||||
@ -243,7 +243,7 @@ void genOSXPlistPreferences(const std::string& path, QueryData& results) {
|
||||
QueryData genOSXPreferences(QueryContext& context) {
|
||||
QueryData results;
|
||||
|
||||
if (context.constraints["path"].exists()) {
|
||||
if (context.constraints["path"].exists(EQUALS)) {
|
||||
// Read preferences from a plist at path.
|
||||
auto paths = context.constraints["path"].getAll(EQUALS);
|
||||
for (const auto& path : paths) {
|
||||
|
@ -34,7 +34,7 @@ namespace tables {
|
||||
std::set<int> getProcList(const QueryContext &context) {
|
||||
std::set<int> pidlist;
|
||||
if (context.constraints.count("pid") > 0 &&
|
||||
context.constraints.at("pid").exists()) {
|
||||
context.constraints.at("pid").exists(EQUALS)) {
|
||||
pidlist = context.constraints.at("pid").getAll<int>(EQUALS);
|
||||
}
|
||||
|
||||
|
@ -20,8 +20,7 @@ QueryData genUserGroups(QueryContext &context) {
|
||||
QueryData results;
|
||||
struct passwd *pwd = nullptr;
|
||||
|
||||
// TODO(1160): Add exists uid EQUALS constraint
|
||||
if (context.constraints["uid"].exists()) {
|
||||
if (context.constraints["uid"].exists(EQUALS)) {
|
||||
std::set<std::string> uids = context.constraints["uid"].getAll(EQUALS);
|
||||
for (const auto &uid : uids) {
|
||||
pwd = getpwuid(std::strtol(uid.c_str(), NULL, 10));
|
||||
|
@ -41,7 +41,7 @@ QueryData genOpenFiles(QueryContext& context) {
|
||||
QueryData results;
|
||||
|
||||
std::set<std::string> pids;
|
||||
if (context.constraints["pid"].exists()) {
|
||||
if (context.constraints["pid"].exists(EQUALS)) {
|
||||
pids = context.constraints["pid"].getAll(EQUALS);
|
||||
} else {
|
||||
osquery::procProcesses(pids);
|
||||
|
@ -225,7 +225,7 @@ QueryData genProcesses(QueryContext& context) {
|
||||
QueryData results;
|
||||
|
||||
std::set<std::string> pids;
|
||||
if (context.constraints["pid"].exists()) {
|
||||
if (context.constraints["pid"].exists(EQUALS)) {
|
||||
pids = context.constraints["pid"].getAll(EQUALS);
|
||||
} else {
|
||||
osquery::procProcesses(pids);
|
||||
@ -245,7 +245,7 @@ QueryData genProcessEnvs(QueryContext& context) {
|
||||
QueryData results;
|
||||
|
||||
std::set<std::string> pids;
|
||||
if (context.constraints["pid"].exists()) {
|
||||
if (context.constraints["pid"].exists(EQUALS)) {
|
||||
pids = context.constraints["pid"].getAll(EQUALS);
|
||||
} else {
|
||||
osquery::procProcesses(pids);
|
||||
@ -262,7 +262,7 @@ QueryData genProcessMemoryMap(QueryContext& context) {
|
||||
QueryData results;
|
||||
|
||||
std::set<std::string> pids;
|
||||
if (context.constraints["pid"].exists()) {
|
||||
if (context.constraints["pid"].exists(EQUALS)) {
|
||||
pids = context.constraints["pid"].getAll(EQUALS);
|
||||
} else {
|
||||
osquery::procProcesses(pids);
|
||||
|
@ -19,8 +19,7 @@ QueryData genUserGroups(QueryContext &context) {
|
||||
QueryData results;
|
||||
struct passwd *pwd = nullptr;
|
||||
|
||||
// TODO(1160): Add exists uid EQUALS constraint
|
||||
if (context.constraints["uid"].exists()) {
|
||||
if (context.constraints["uid"].exists(EQUALS)) {
|
||||
std::set<std::string> uids = context.constraints["uid"].getAll(EQUALS);
|
||||
for (const auto &uid : uids) {
|
||||
pwd = getpwuid(std::strtol(uid.c_str(), NULL, 10));
|
||||
|
@ -100,19 +100,19 @@ QueryData genSystemControls(QueryContext& context) {
|
||||
}
|
||||
|
||||
// Iterate through the sysctl-defined macro of control types.
|
||||
if (context.constraints["name"].exists()) {
|
||||
if (context.constraints["name"].exists(EQUALS)) {
|
||||
// Request MIB information by the description (name).
|
||||
auto names = context.constraints["name"].getAll(EQUALS);
|
||||
for (const auto& name : names) {
|
||||
genControlInfoFromName(name, results, config);
|
||||
}
|
||||
} else if (context.constraints["oid"].exists()) {
|
||||
} else if (context.constraints["oid"].exists(EQUALS)) {
|
||||
// Request MIB by OID as a string, parse into set of INTs.
|
||||
auto oids = context.constraints["oid"].getAll(EQUALS);
|
||||
for (const auto& oid_string : oids) {
|
||||
genControlInfoFromOIDString(oid_string, results, config);
|
||||
}
|
||||
} else if (context.constraints["subsystem"].exists()) {
|
||||
} else if (context.constraints["subsystem"].exists(EQUALS)) {
|
||||
// Limit the MIB search to a subsystem name (first find the INT).
|
||||
auto subsystems = context.constraints["subsystem"].getAll(EQUALS);
|
||||
for (const auto& subsystem : subsystems) {
|
||||
|
Loading…
Reference in New Issue
Block a user