Пример #1
0
TEST_F(QueryTests, test_is_query_name_in_database) {
  auto query = getOsqueryScheduledQuery();
  auto cf = Query("foobar", query);
  auto encoded_qd = getSerializedQueryDataJSON();
  auto status = db_->Put(kQueries, "foobar", encoded_qd.first);
  EXPECT_TRUE(status.ok());
  // Now test that the query name exists.
  EXPECT_TRUE(cf.isQueryNameInDatabase(db_));
}
Пример #2
0
TEST_F(QueryTests, test_is_query_name_in_database) {
  auto query = getOsqueryScheduledQuery();
  auto cf = Query(query);
  auto hQR = getSerializedHistoricalQueryResultsJSON();
  auto put_status = db->Put(kQueries, query.name, hQR.first);
  EXPECT_TRUE(put_status.ok());
  EXPECT_EQ(put_status.toString(), "OK");
  EXPECT_TRUE(cf.isQueryNameInDatabase(db));
}
Пример #3
0
Status Query::getPreviousQueryResults(QueryData& results, DBHandleRef db) {
    if (!isQueryNameInDatabase()) {
        return Status(0, "Query name not found in database");
    }

    std::string raw;
    auto status = db->Get(kQueries, name_, raw);
    if (!status.ok()) {
        return status;
    }

    status = deserializeQueryDataJSON(raw, results);
    if (!status.ok()) {
        return status;
    }
    return Status(0, "OK");
}
Пример #4
0
Status Query::getHistoricalQueryResults(HistoricalQueryResults& hQR,
                                        std::shared_ptr<DBHandle> db) {
  if (isQueryNameInDatabase()) {
    std::string raw;
    auto get_status = db->Get(kQueries, query_.name, raw);
    if (get_status.ok()) {
      auto deserialize_status = deserializeHistoricalQueryResultsJSON(raw, hQR);
      if (!deserialize_status.ok()) {
        return deserialize_status;
      }
    } else {
      return get_status;
    }
  } else {
    return Status(1, kQueryNameNotFoundError);
  }
  return Status(0, "OK");
}
Пример #5
0
bool Query::isQueryNameInDatabase() {
    return isQueryNameInDatabase(DBHandle::getInstance());
}
Пример #6
0
Status Query::addNewResults(QueryData current_qd,
                            const uint64_t current_epoch,
                            uint64_t& counter,
                            DiffResults& dr,
                            bool calculate_diff) const {
  // The current results are 'fresh' when not calculating a differential.
  bool fresh_results = !calculate_diff;
  bool new_query = false;
  if (!isQueryNameInDatabase()) {
    // This is the first encounter of the scheduled query.
    fresh_results = true;
    LOG(INFO) << "Storing initial results for new scheduled query: " << name_;
    saveQuery(name_, query_);
  } else if (getPreviousEpoch() != current_epoch) {
    fresh_results = true;
    LOG(INFO) << "New Epoch " << current_epoch << " for scheduled query "
              << name_;
  } else if (isNewQuery()) {
    // This query is 'new' in that the previous results may be invalid.
    new_query = true;
    LOG(INFO) << "Scheduled query has been updated: " + name_;
    saveQuery(name_, query_);
  }

  // Use a 'target' avoid copying the query data when serializing and saving.
  // If a differential is requested and needed the target remains the original
  // query data, otherwise the content is moved to the differential's added set.
  const auto* target_gd = &current_qd;
  bool update_db = true;
  if (!fresh_results && calculate_diff) {
    // Get the rows from the last run of this query name.
    QueryDataSet previous_qd;
    auto status = getPreviousQueryResults(previous_qd);
    if (!status.ok()) {
      return status;
    }

    // Calculate the differential between previous and current query results.
    dr = diff(previous_qd, current_qd);

    update_db = (!dr.added.empty() || !dr.removed.empty());
  } else {
    dr.added = std::move(current_qd);
    target_gd = &dr.added;
  }

  counter = getQueryCounter(fresh_results || new_query);
  auto status =
      setDatabaseValue(kQueries, name_ + "counter", std::to_string(counter));
  if (!status.ok()) {
    return status;
  }

  if (update_db) {
    // Replace the "previous" query data with the current.
    std::string json;
    status = serializeQueryDataJSON(*target_gd, json);
    if (!status.ok()) {
      return status;
    }

    status = setDatabaseValue(kQueries, name_, json);
    if (!status.ok()) {
      return status;
    }

    status = setDatabaseValue(
        kQueries, name_ + "epoch", std::to_string(current_epoch));
    if (!status.ok()) {
      return status;
    }
  }
  return Status(0, "OK");
}