"Fossies" - the Fresh Open Source Software Archive

Member "osquery-4.0.0/osquery/tables/system/tests/darwin/asl_tests.cpp" (28 Jun 2019, 6748 Bytes) of package /linux/misc/osquery-4.0.0.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 /**
    2  *  Copyright (c) 2014-present, Facebook, Inc.
    3  *  All rights reserved.
    4  *
    5  *  This source code is licensed in accordance with the terms specified in
    6  *  the LICENSE file found in the root directory of this source tree.
    7  */
    8 
    9 #include <chrono>
   10 #include <cstdlib>
   11 #include <ctime>
   12 #include <string>
   13 #include <thread>
   14 
   15 #include <gtest/gtest.h>
   16 
   17 #include <osquery/registry_factory.h>
   18 #include <osquery/sql.h>
   19 #include <osquery/tables/system/darwin/asl_utils.h>
   20 #include <osquery/utils/conversions/tryto.h>
   21 
   22 namespace osquery {
   23 namespace tables {
   24 
   25 class AslTests : public testing::Test {
   26  protected:
   27   void SetUp() override {
   28     registryAndPluginInit();
   29   }
   30 };
   31 
   32 // macOS ASL is deprecated in 10.12
   33 _Pragma("clang diagnostic push");
   34 _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"");
   35 
   36 #ifndef OLD_ASL_API
   37 TEST_F(AslTests, test_add_query_op) {
   38   aslmsg query = asl_new(ASL_TYPE_QUERY);
   39   ASSERT_EQ((uint32_t)ASL_TYPE_QUERY, asl_get_type(query));
   40   ASSERT_EQ((size_t)0, asl_count(query));
   41 
   42   const char *key, *val;
   43   uint32_t op;
   44 
   45   addQueryOp(query, "sender", "bar", EQUALS, TEXT_TYPE);
   46   ASSERT_EQ((size_t)1, asl_count(query));
   47 
   48   ASSERT_EQ(0, asl_fetch_key_val_op(query, 0, &key, &val, &op));
   49   ASSERT_STREQ("Sender", key);
   50   ASSERT_STREQ("bar", val);
   51   ASSERT_EQ((uint32_t)ASL_QUERY_OP_EQUAL, op);
   52 
   53   addQueryOp(query, "level", "1", GREATER_THAN, INTEGER_TYPE);
   54   ASSERT_EQ((size_t)2, asl_count(query));
   55   ASSERT_EQ(0, asl_fetch_key_val_op(query, 1, &key, &val, &op));
   56   ASSERT_STREQ("Level", key);
   57   ASSERT_STREQ("1", val);
   58   ASSERT_EQ((uint32_t)(ASL_QUERY_OP_GREATER | ASL_QUERY_OP_NUMERIC), op);
   59 
   60   addQueryOp(query, "gid", "999", LESS_THAN, BIGINT_TYPE);
   61   ASSERT_EQ((size_t)3, asl_count(query));
   62   ASSERT_EQ(0, asl_fetch_key_val_op(query, 2, &key, &val, &op));
   63   ASSERT_STREQ("GID", key);
   64   ASSERT_STREQ("999", val);
   65   ASSERT_EQ((uint32_t)(ASL_QUERY_OP_LESS | ASL_QUERY_OP_NUMERIC), op);
   66 
   67   addQueryOp(query, "facility", "hoo", GREATER_THAN_OR_EQUALS, TEXT_TYPE);
   68   ASSERT_EQ((size_t)4, asl_count(query));
   69   ASSERT_EQ(0, asl_fetch_key_val_op(query, 3, &key, &val, &op));
   70   ASSERT_STREQ("Facility", key);
   71   ASSERT_STREQ("hoo", val);
   72   ASSERT_EQ((uint32_t)ASL_QUERY_OP_GREATER_EQUAL, op);
   73 
   74   addQueryOp(query, "pid", "30", LESS_THAN_OR_EQUALS, INTEGER_TYPE);
   75   ASSERT_EQ((size_t)5, asl_count(query));
   76   ASSERT_EQ(0, asl_fetch_key_val_op(query, 4, &key, &val, &op));
   77   ASSERT_STREQ("PID", key);
   78   ASSERT_STREQ("30", val);
   79   ASSERT_EQ((uint32_t)(ASL_QUERY_OP_LESS_EQUAL | ASL_QUERY_OP_NUMERIC), op);
   80 
   81   addQueryOp(query, "ref_proc", "%tom%", LIKE, TEXT_TYPE);
   82   ASSERT_EQ((size_t)6, asl_count(query));
   83   ASSERT_EQ(0, asl_fetch_key_val_op(query, 5, &key, &val, &op));
   84   ASSERT_STREQ("RefProc", key);
   85   ASSERT_STREQ(".*tom.*", val);
   86   ASSERT_EQ((uint32_t)(ASL_QUERY_OP_EQUAL | ASL_QUERY_OP_REGEX |
   87                        ASL_QUERY_OP_CASEFOLD),
   88             op);
   89 
   90   // Queries against the extra column should not be sent to ASL
   91   addQueryOp(query, "extra", "tom", EQUALS, TEXT_TYPE);
   92   ASSERT_EQ((size_t)6, asl_count(query));
   93 
   94   // Queries with unsupported operators should not be sent to ASL
   95   addQueryOp(query, "host", "tom", GLOB, TEXT_TYPE);
   96   ASSERT_EQ((size_t)6, asl_count(query));
   97 
   98   asl_release(query);
   99 }
  100 
  101 TEST_F(AslTests, test_create_asl_query) {
  102   QueryContext ctx;
  103   ctx.constraints["sender"].add(Constraint(EQUALS, "bar"));
  104   ctx.constraints["sender"].add(Constraint(LIKE, "%a%"));
  105   ctx.constraints["message"].affinity = INTEGER_TYPE;
  106   ctx.constraints["message"].add(Constraint(LESS_THAN, "10"));
  107 
  108   aslmsg query = createAslQuery(ctx);
  109 
  110   ASSERT_EQ((uint32_t)ASL_TYPE_QUERY, asl_get_type(query));
  111   ASSERT_EQ((size_t)3, asl_count(query));
  112 
  113   const char *key, *val;
  114   uint32_t op;
  115 
  116   // Ordering doesn't really matter here, only that we only ended up with
  117   // (message, baz, LESS) and (sender, bar, EQUAL)
  118   ASSERT_EQ(0, asl_fetch_key_val_op(query, 0, &key, &val, &op));
  119   ASSERT_STREQ("Message", key);
  120   ASSERT_STREQ("10", val);
  121   ASSERT_EQ((uint32_t)(ASL_QUERY_OP_LESS | ASL_QUERY_OP_NUMERIC), op);
  122 
  123   ASSERT_EQ(0, asl_fetch_key_val_op(query, 1, &key, &val, &op));
  124   ASSERT_STREQ("Sender", key);
  125   ASSERT_STREQ("bar", val);
  126   ASSERT_EQ((uint32_t)ASL_QUERY_OP_EQUAL, op);
  127 
  128   ASSERT_EQ(0, asl_fetch_key_val_op(query, 2, &key, &val, &op));
  129   ASSERT_STREQ("Sender", key);
  130   ASSERT_STREQ(".*a.*", val);
  131   ASSERT_EQ((uint32_t)(ASL_QUERY_OP_EQUAL | ASL_QUERY_OP_REGEX |
  132                        ASL_QUERY_OP_CASEFOLD),
  133             op);
  134 
  135   asl_release(query);
  136 }
  137 #endif
  138 
  139 TEST_F(AslTests, test_read_asl_row) {
  140   aslmsg row = asl_new(ASL_TYPE_MSG);
  141   ASSERT_EQ(0, asl_set(row, "Sender", "foo"));
  142   ASSERT_EQ(0, asl_set(row, "Level", "1"));
  143   ASSERT_EQ(0, asl_set(row, "Message", "bar"));
  144   ASSERT_EQ(0, asl_set(row, "Bang", "bang_val"));
  145 
  146   Row r;
  147   readAslRow(row, r);
  148 
  149   ASSERT_EQ((size_t)4, r.size());
  150 
  151   ASSERT_EQ("foo", r["sender"]);
  152   ASSERT_EQ("1", r["level"]);
  153   ASSERT_EQ("bar", r["message"]);
  154   ASSERT_EQ((size_t)0, r.count("bang"));
  155   ASSERT_EQ("{\"Bang\":\"bang_val\"}\n", r["extra"]);
  156 
  157   asl_release(row);
  158 }
  159 
  160 TEST_F(AslTests, test_convert_like_regex) {
  161   EXPECT_EQ(".*", convertLikeRegex("%"));
  162   EXPECT_EQ("foo.*", convertLikeRegex("foo%"));
  163   EXPECT_EQ(".*foo.*", convertLikeRegex("%foo%"));
  164   EXPECT_EQ(".*.*", convertLikeRegex("%%"));
  165   EXPECT_EQ(".*.*", convertLikeRegex("%%"));
  166   EXPECT_EQ(".", convertLikeRegex("_"));
  167   EXPECT_EQ("foo.", convertLikeRegex("foo_"));
  168   EXPECT_EQ(".foo", convertLikeRegex("_foo"));
  169   EXPECT_EQ(".foo.", convertLikeRegex("_foo_"));
  170   EXPECT_EQ("..*", convertLikeRegex("_%"));
  171   EXPECT_EQ(".*foo..*", convertLikeRegex("%foo_%"));
  172 }
  173 
  174 TEST_F(AslTests, test_actual_query) {
  175   auto version = SQL::selectAllFrom("os_version");
  176   auto minor_version_exp = tryTo<unsigned long int>(version[0]["minor"], 10);
  177   ASSERT_TRUE(minor_version_exp.isValue());
  178   if (minor_version_exp.get() >= 12) {
  179     // macOS Sierra and above do not support ASL.
  180     return;
  181   }
  182 
  183   // An integration test, this test writes to ASL, and then verifies that we
  184   // can query for the written log
  185   std::string time_str = std::to_string(std::time(nullptr));
  186   std::string command =
  187       "logger -p user.notice -t osquery_test 'osquery_test: "
  188       "test_actual_query " +
  189       time_str + "'";
  190   std::system(command.c_str());
  191   std::this_thread::sleep_for(std::chrono::seconds(1));
  192 
  193   // Check for our written log
  194   auto results =
  195       SQL("select * from asl where facility = 'user' and level = 5 and sender "
  196           "= 'osquery_test' and message like '%" +
  197           time_str + "' and time >= " + time_str);
  198   ASSERT_GT(results.rows().size(), (size_t)0);
  199   ASSERT_EQ("osquery_test", results.rows()[0].at("sender"));
  200   ASSERT_EQ("user", results.rows()[0].at("facility"));
  201 }
  202 
  203 _Pragma("clang diagnostic pop");
  204 }
  205 }