예제 #1
0
파일: packs.cpp 프로젝트: Ramsey16/osquery
size_t restoreSplayedValue(const std::string& name, size_t interval) {
  // Attempt to restore a previously-calculated splay.
  std::string content;
  getDatabaseValue(kPersistentSettings, "interval." + name, content);
  if (!content.empty()) {
    // This query name existed before, check the last requested interval.
    auto details = osquery::split(content, ":");
    if (details.size() == 2) {
      long last_interval, last_splay;
      if (safeStrtol(details[0], 10, last_interval) &&
          safeStrtol(details[1], 10, last_splay)) {
        if (last_interval == static_cast<long>(interval) && last_splay > 0) {
          // This is a matching interval, use the previous splay.
          return static_cast<size_t>(last_splay);
        }
      }
    }
  }

  // If the splayed interval was not restored from the database.
  auto splay = splayValue(interval, FLAGS_schedule_splay_percent);
  content = std::to_string(interval) + ":" + std::to_string(splay);
  setDatabaseValue(kPersistentSettings, "interval." + name, content);
  return splay;
}
예제 #2
0
bool DropPrivileges::dropTo(const std::string& user) {
  auto result = SQL::selectAllFrom("users", "username", EQUALS, user);
  if (result.size() == 0) {
    return false;
  }

  long uid = 0;
  long gid = 0;
  if (!safeStrtol(result[0].at("uid"), 10, uid) ||
      !safeStrtol(result[0].at("gid"), 10, gid)) {
    return false;
  }
  return dropTo(static_cast<uid_t>(uid), static_cast<gid_t>(gid));
}
예제 #3
0
bool parseSockAddr(const std::string& saddr, AuditFields& r) {
  // The protocol is not included in the audit message.
  if (saddr[0] == '0' && saddr[1] == '2') {
    // IPv4
    r["family"] = '2';
    long result{0};
    safeStrtol(saddr.substr(4, 4), 16, result);
    r["remote_port"] = INTEGER(result);
    r["remote_address"] = ip4FromSaddr(saddr, 8);
  } else if (saddr[0] == '0' && saddr[1] == 'A') {
    // IPv6
    r["family"] = "11";
    long result{0};
    safeStrtol(saddr.substr(4, 4), 16, result);
    r["remote_port"] = INTEGER(result);
    std::string address;
    for (size_t i = 0; i < 8; ++i) {
      address += saddr.substr(16 + (i * 4), 4);
      if (i == 0 || i % 7 != 0) {
        address += ':';
      }
    }
    boost::algorithm::to_lower(address);
    r["remote_address"] = std::move(address);
  } else if (saddr[0] == '0' && saddr[1] == '1' && saddr.size() > 6) {
    // Unix domain socket.
    if (!FLAGS_audit_allow_unix) {
      return false;
    }

    r["family"] = '1';
    r["local_port"] = '0';
    r["remote_port"] = '0';
    off_t begin = (saddr[4] == '0' && saddr[5] == '0') ? 6 : 4;
    auto end = saddr.substr(begin).find("00");
    end = (end == std::string::npos) ? saddr.size() : end + 4;
    try {
      r["socket"] = boost::algorithm::unhex(saddr.substr(begin, end - begin));
    } catch (const boost::algorithm::hex_decode_error& e) {
      r["socket"] = "unknown";
    }
  } else {
    // No idea!
    return false;
  }
  return true;
}
예제 #4
0
int xColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int col) {
  BaseCursor *pCur = (BaseCursor *)cur;
  const auto *pVtab = (VirtualTable *)cur->pVtab;
  if (col >= static_cast<int>(pVtab->content->columns.size())) {
    // Requested column index greater than column set size.
    return SQLITE_ERROR;
  }

  const auto &column_name = pVtab->content->columns[col].first;
  const auto &type = pVtab->content->columns[col].second;
  if (pCur->row >= pCur->data.size()) {
    // Request row index greater than row set size.
    return SQLITE_ERROR;
  }

  // Attempt to cast each xFilter-populated row/column to the SQLite type.
  const auto &value = pCur->data[pCur->row][column_name];
  if (pCur->data[pCur->row].count(column_name) == 0) {
    // Missing content.
    VLOG(1) << "Error " << column_name << " is empty";
    sqlite3_result_null(ctx);
  } else if (type == TEXT_TYPE) {
    sqlite3_result_text(ctx, value.c_str(), value.size(), SQLITE_STATIC);
  } else if (type == INTEGER_TYPE) {
    long afinite;
    if (!safeStrtol(value, 10, afinite) || afinite < INT_MIN ||
        afinite > INT_MAX) {
      VLOG(1) << "Error casting " << column_name << " (" << value
              << ") to INTEGER";
      sqlite3_result_null(ctx);
    } else {
      sqlite3_result_int(ctx, (int)afinite);
    }
  } else if (type == BIGINT_TYPE || type == UNSIGNED_BIGINT_TYPE) {
    long long afinite;
    if (!safeStrtoll(value, 10, afinite)) {
      VLOG(1) << "Error casting " << column_name << " (" << value
              << ") to BIGINT";
      sqlite3_result_null(ctx);
    } else {
      sqlite3_result_int64(ctx, afinite);
    }
  } else if (type == DOUBLE_TYPE) {
    char *end = nullptr;
    double afinite = strtod(value.c_str(), &end);
    if (end == nullptr || end == value.c_str() || *end != '\0') {
      afinite = 0;
      VLOG(1) << "Error casting " << column_name << " (" << value
              << ") to DOUBLE";
      sqlite3_result_null(ctx);
    } else {
      sqlite3_result_double(ctx, afinite);
    }
  } else {
    LOG(ERROR) << "Error unknown column type " << column_name;
  }

  return SQLITE_OK;
}
예제 #5
0
파일: iokit.hpp 프로젝트: theopolis/osquery
inline void idToHex(std::string& id) {
  long base = 0;
  if (safeStrtol(id, 10, base)) {
    std::stringstream hex_id;
    hex_id << std::hex << std::setw(4) << std::setfill('0') << (base & 0xFFFF);
    id = hex_id.str();
  }
}
예제 #6
0
size_t getMachineShard(const std::string& hostname = "", bool force = false) {
    static size_t shard = 0;
    if (shard > 0 && !force) {
        return shard;
    }

    // An optional input hostname may override hostname detection for testing.
    auto hn = (hostname.empty()) ? getHostname() : hostname;
    auto hn_hash = hashFromBuffer(HASH_TYPE_MD5, hn.c_str(), hn.size());
    if (hn_hash.size() >= 2) {
        long hn_char;
        if (safeStrtol(hn_hash.substr(0, 2), 16, hn_char)) {
            shard = (hn_char * 100) / 255;
        }
    }
    return shard;
}
예제 #7
0
QueryData genIPv4ArpCache(QueryContext& context) {
  QueryData results;
  QueryData interfaces = genInterfaceDetails(context);
  WmiRequest wmiSystemReq("select * from MSFT_NetNeighbor",
                          (BSTR)L"ROOT\\StandardCimv2");
  std::vector<WmiResultItem>& wmiResults = wmiSystemReq.results();
  std::map<long, std::string> mapOfInterfaces = {
      {1, ""}, // loopback
  };
  unsigned short usiPlaceHolder;
  unsigned char cPlaceHolder;
  unsigned int uiPlaceHolder;
  std::string strPlaceHolder;

  for (const auto& iface : interfaces) {
    long interfaceIndex;
    if (iface.count("interface") > 0) {
      safeStrtol(iface.at("interface"), 10, interfaceIndex);
      std::string macAddress = iface.at("mac");

      mapOfInterfaces.insert(std::make_pair(interfaceIndex, macAddress));
    }
  }
  for (const auto& item : wmiResults) {
    Row r;
    item.GetUnsignedShort("AddressFamily", usiPlaceHolder);
    r["address_family"] = SQL_TEXT(kMapOfAddressFamily.at(usiPlaceHolder));
    item.GetUChar("Store", cPlaceHolder);
    r["store"] = SQL_TEXT(kMapOfStore.at(cPlaceHolder));
    item.GetUChar("State", cPlaceHolder);
    r["state"] = SQL_TEXT(kMapOfState.at(cPlaceHolder));
    item.GetUnsignedInt32("InterfaceIndex", uiPlaceHolder);
    r["interface"] = SQL_TEXT(mapOfInterfaces.at(uiPlaceHolder));
    item.GetString("IPAddress", r["ip_address"]);
    item.GetString("InterfaceAlias", r["interface_alias"]);
    item.GetString("LinkLayerAddress", strPlaceHolder);
    r["link_layer_address"] =
        SQL_TEXT(boost::replace_all_copy(strPlaceHolder, "-", ":"));

    results.push_back(r);
  }

  return results;
}
예제 #8
0
파일: users.cpp 프로젝트: tburgin/osquery
QueryData genUsers(QueryContext& context) {
  QueryData results;
  struct passwd *pwd = nullptr;

  if (context.constraints["uid"].exists(EQUALS)) {
    std::set<std::string> uids = context.constraints["uid"].getAll(EQUALS);
    for (const auto& uid : uids) {
      long auid{0};
      if (safeStrtol(uid, 10, auid) && (pwd = getpwuid(auid)) != nullptr) {
        genUser(pwd, results);
      }
    }
  } else {
    std::lock_guard<std::mutex> lock(pwdEnumerationMutex);
    while ((pwd = getpwent()) != nullptr) {
      genUser(pwd, results);
    }
    endpwent();
  }

  return results;
}
예제 #9
0
void MD::parseMDStat(const std::vector<std::string>& lines, MDStat& result) {
  // Will be used to determine starting point of lines to work on.
  size_t n = 0;

  if (lines.empty()) {
    return;
  }

  // This should always evaluate to true, but just in case we check.
  if (lines[0].find("Personalities :") != std::string::npos) {
    std::string pline(lines[0].substr(sizeof("Personalities :") - 1));
    parseMDPersonalities(pline, result.personalities);

    n = 1;

  } else {
    LOG(WARNING) << "mdstat Personalites not found at line 0: " << lines[0];
  }

  while (n < lines.size()) {
    if (lines[n].find_first_not_of("\t\r\v ") == std::string::npos) {
      n += 1;
      continue;
    }
    // Work off of first 2 character instead of just the first to be safe.
    std::string firstTwo = lines[n].substr(0, 2);
    if (firstTwo == "md") {
      auto mdline(split(lines[n], ":", 1));
      if (mdline.size() < 2) {
        LOG(WARNING) << "Unexpected md device line structure: " << lines[n];
        n += 1;
        continue;
      }

      MDDevice mdd;
      mdd.name = std::move(mdline[0]);
      boost::algorithm::trim(mdd.name);

      auto settings(split(mdline[1], " "));
      trimStrs(settings);
      // First 2 of settings are always status and RAID level
      if (settings.size() >= 2) {
        mdd.status = std::move(settings[0]);
        mdd.raidLevel = std::move(settings[1]);

        for (size_t i = 2; i < settings.size(); i++) {
          mdd.drives.push_back(parseMDDrive(settings[i]));
        }
      }

      /* Next line is device config and settings.  We handle here instead of
       * later b/c pieces are need for both md_drives and md_devices table.  For
       * safety, we check if we at the end of the file. */
      if (n >= lines.size() - 1) {
        continue;
        n += 1;
      }
      auto configline(split(lines[n + 1]));

      if (configline.size() < 4) {
        LOG(WARNING) << "Unexpected md device config: " << lines[n + 1];

      } else {
        trimStrs(configline);

        if (configline[1] == "blocks") {
          Status status = safeStrtol(configline[0], 10, mdd.usableSize);
          if (!status.ok()) {
            LOG(WARNING) << "Could not parse usable size of " << mdd.name;
          }

        } else {
          LOG(WARNING) << "Did not find size in mdstat for " << mdd.name;
        }

        mdd.healthyDrives = configline[configline.size() - 2];
        mdd.driveStatuses = configline[configline.size() - 1];

        if (configline.size() > 4) {
          for (size_t i = 2; i < configline.size() - 2; i++) {
            mdd.other += (" " + configline[i]);
            boost::algorithm::trim(mdd.other);
          }
        }
      }
      // Skip config line for next iteration
      n += 1;

      // Handle potential bitmap, recovery, and resync lines
      while (n < lines.size() - 1) {
        if (handleMDStatuses(
                lines, n, "recovery =", [&mdd](const std::string& line) {
                  parseMDAction(line, mdd.recovery);
                })) {
          continue;
        }

        if (handleMDStatuses(
                lines, n, "resync =", [&mdd](const std::string& line) {
                  parseMDAction(line, mdd.resync);
                })) {
          continue;
        }

        // If in this format, it's generally signaling a progress delay
        if (handleMDStatuses(
                lines, n, "resync=", [&mdd](const std::string& line) {
                  mdd.resync.progress = line;
                })) {
          continue;
        }

        if (handleMDStatuses(
                lines, n, "reshape =", [&mdd](const std::string& line) {
                  parseMDAction(line, mdd.reshape);
                })) {
          continue;
        }

        if (handleMDStatuses(
                lines, n, "check =", [&mdd](const std::string& line) {
                  parseMDAction(line, mdd.checkArray);
                })) {
          continue;
        }

        if (handleMDStatuses(
                lines, n, "bitmap:", [&mdd](const std::string& line) {
                  parseMDBitmap(line, mdd.bitmap);
                })) {
          continue;
        }

        // If none of above, then we can break out of loop
        break;
      }

      result.devices.push_back(mdd);

      // Assume unused
    } else if (firstTwo == "un") {
      result.unused = lines[n].substr(sizeof("unused devices:") - 1);
      boost::algorithm::trim(result.unused);
      // Unexpected mdstat line, log a warning...
    } else {
      LOG(WARNING) << "Unexpected mdstat line: " << lines[n];
    }

    n += 1;
  }
}