--- /dev/null
+# Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License
+
+SET(OSQUERY_CODEGEN_PATH "${CMAKE_SOURCE_DIR}/tools/codegen")
+SET(OSQUERY_TABLES_PATH "${CMAKE_SOURCE_DIR}")
+SET(OSQUERY_GENERATED_PATH "${CMAKE_BINARY_DIR}/generated")
+
+SET(GENERATED_TABLES "")
+
+FILE(GLOB TABLE_FILES "${CMAKE_SOURCE_DIR}/specs/*.table")
+FILE(GLOB TABLE_FILES_LINUX "${CMAKE_SOURCE_DIR}/specs/linux/*.table")
+FILE(GLOB TABLE_FILES_UTILITY "${CMAKE_SOURCE_DIR}/specs/utility/*.table")
+LIST(APPEND TABLE_FILES ${TABLE_FILES_LINUX})
+LIST(APPEND TABLE_FILES ${TABLE_FILES_UTILITY})
+
+IF(DEFINED GBS_BUILD)
+ FILE(GLOB TABLE_FILES_TIZEN "${CMAKE_SOURCE_DIR}/specs/tizen/*.table")
+ LIST(APPEND TABLE_FILES ${TABLE_FILES_TIZEN})
+ENDIF(DEFINED GBS_BUILD)
+
+FILE(GLOB TABLE_FILES_TEMPLATES "${CMAKE_SOURCE_DIR}/tools/codegen/templates/*.in")
+SET(GENERATION_DEPENDENCIES "${OSQUERY_CODEGEN_PATH}/gentable.py"
+ "${OSQUERY_CODEGEN_PATH}/amalgamate.py"
+ "${OSQUERY_TABLES_PATH}/specs/blacklist")
+
+LIST(APPEND GENERATION_DEPENDENCIES ${TABLE_FILES_TEMPLATES})
+
+FOREACH(TABLE_FILE ${TABLE_FILES})
+ SET(TABLE_FILE_GEN ${TABLE_FILE})
+ STRING(REPLACE "${OSQUERY_TABLES_PATH}/specs"
+ "${OSQUERY_GENERATED_PATH}/tables"
+ TABLE_FILE_GEN
+ ${TABLE_FILE_GEN})
+ STRING(REPLACE "linux/" "" TABLE_FILE_GEN ${TABLE_FILE_GEN})
+ STRING(REPLACE "" "" TABLE_FILE_GEN ${TABLE_FILE_GEN})
+ STRING(REPLACE ".table" ".cpp" TABLE_FILE_GEN ${TABLE_FILE_GEN})
+ ADD_CUSTOM_COMMAND(
+ OUTPUT ${TABLE_FILE_GEN}
+ COMMAND
+ python "${OSQUERY_CODEGEN_PATH}/gentable.py" "${TABLE_FILE}" "${TABLE_FILE_GEN}" "$ENV{DISABLE_BLACKLIST}"
+ DEPENDS
+ ${TABLE_FILE} ${GENERATION_DEPENDENCIES}
+
+ WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}")
+ LIST(APPEND GENERATED_TABLES ${TABLE_FILE_GEN})
+ENDFOREACH()
+
+SET(AMALGAMATION_FILE_GEN "${OSQUERY_GENERATED_PATH}/amalgamation.cpp")
+ADD_CUSTOM_COMMAND(
+ OUTPUT ${AMALGAMATION_FILE_GEN}
+ COMMAND
+ python "${OSQUERY_CODEGEN_PATH}/amalgamate.py" "${OSQUERY_CODEGEN_PATH}" "${OSQUERY_GENERATED_PATH}"
+ DEPENDS
+ ${GENERATED_TABLES}
+ WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}")
+
+ADD_LIBRARY(osquery_generated_tables OBJECT "${AMALGAMATION_FILE_GEN}")
+++ /dev/null
-table_name("acpi_tables")
-description("Firmware ACPI functional table common metadata and content.")
-schema([
- Column("name", TEXT, "ACPI table name"),
- Column("size", INTEGER, "Size of compiled table data"),
- Column("md5", TEXT, "MD5 hash of table content"),
-])
-implementation("system/acpi_tables@genACPITables")
+++ /dev/null
-table_name("arp_cache")
-description("Address resolution cache, both static and dynamic (from ARP, NDP).")
-schema([
- Column("address", TEXT, "IPv4 address target"),
- Column("mac", TEXT, "MAC address of broadcasted address"),
- Column("interface", TEXT, "Interface of the network for the MAC"),
- Column("permanent", TEXT, "1 for true, 0 for false"),
-])
-implementation("linux/arp_cache,darwin/routes@genArpCache")
+++ /dev/null
-table_name("crontab")
-description("Line parsed values from system and user cron/tab.")
-schema([
- Column("event", TEXT, "The job @event name (rare)"),
- Column("minute", TEXT, "The exact minute for the job"),
- Column("hour", TEXT, "The hour of the day for the job"),
- Column("day_of_month", TEXT, "The day of the month for the job"),
- Column("month", TEXT, "The month of the year for the job"),
- Column("day_of_week", TEXT, "The day of the week for the job"),
- Column("command", TEXT, "Raw command string"),
- Column("path", TEXT, "File parsed"),
-])
-implementation("crontab@genCronTab")
+++ /dev/null
-table_name("etc_protocols")
-description("Line-parsed /etc/protocols.")
-schema([
- Column("name", TEXT, "Protocol name"),
- Column("number", INTEGER, "Protocol number"),
- Column("alias", TEXT, "Protocol alias"),
- Column("comment", TEXT, "Comment with protocol description"),
-])
-implementation("etc_protocols@genEtcProtocols")
-
+++ /dev/null
-table_name("etc_services")
-description("Line-parsed /etc/services.")
-schema([
- Column("name", TEXT, "Service name"),
- Column("port", INTEGER, "Service port number"),
- Column("protocol", TEXT, "Transport protocol (TCP/UDP)"),
- Column("aliases", TEXT, "Optional space separated list of other names for a service"),
- Column("comment", TEXT, "Optional comment for a service."),
-])
-implementation("etc_services@genEtcServices")
+++ /dev/null
-table_name("hardware_events")
-description("Hardware (PCI/USB/HID) events from UDEV or IOKit.")
-schema([
- Column("action", TEXT, "Remove, insert, change properties, etc"),
- Column("path", TEXT, "Local device path assigned (optional)"),
- Column("type", TEXT, "Type of hardware and hardware event"),
- Column("driver", TEXT, "Driver claiming the device"),
- Column("model", TEXT, "Hardware device model"),
- Column("model_id", INTEGER, "Hardware model identifier"),
- Column("vendor", TEXT, "Hardware device vendor"),
- Column("vendor_id", INTEGER, "Hardware vendor identifier"),
- Column("serial", TEXT, "Device serial (optional)"),
- Column("revision", INTEGER, "Device revision (optional)"),
- Column("time", BIGINT, "Time of hardware event"),
-])
-attributes(event_subscriber=True)
-implementation("events/hardware_events@hardware_events::genTable")
+++ /dev/null
-table_name("kernel_info")
-description("Basic active kernel information.")
-schema([
- Column("version", TEXT, "Kernel version"),
- Column("arguments", TEXT, "Kernel arguments"),
- Column("path", TEXT, "Kernel path"),
- Column("device", TEXT, "Kernel device identifier"),
- Column("md5", TEXT, "MD5 hash of Kernel"),
-])
-implementation("system/kernel_info@genKernelInfo")
+++ /dev/null
-table_name("last")
-description("System logins and logouts.")
-schema([
- Column("username", TEXT, "Entry username"),
- Column("tty", TEXT, "Entry terminal"),
- Column("pid", INTEGER, "Process (or thread) ID"),
- Column("type", INTEGER, "Entry type, according to ut_type types (utmp.h)"),
- Column("time", INTEGER, "Entry timestamp"),
- Column("host", TEXT, "Entry hostname"),
-])
-implementation("last@genLastAccess")
+++ /dev/null
-table_name("kernel_modules")
-description("Linux kernel modules both loaded and within the load search path.")
-schema([
- Column("name", TEXT, "Module name"),
- Column("size", TEXT, "Size of module content"),
- Column("used_by", TEXT, "Module reverse dependencies"),
- Column("status", TEXT, "Kernel module status"),
- Column("address", TEXT, "Kernel module address"),
-])
-implementation("kernel_modules@genKernelModules")
+++ /dev/null
-table_name("memory_map")
-description("OS memory region map.")
-schema([
- Column("region", INTEGER, "Region index"),
- Column("type", TEXT, "Textual description"),
- Column("start", TEXT, "Start address of memory region"),
- Column("end", TEXT, "End address of memory region"),
-])
-implementation("memory_map@genMemoryMap")
+++ /dev/null
-table_name("msr")
-description("Various pieces of data stored in the model specific register per "
- "processor. NOTE: the msr kernel module must be enabled, and "
- "osquery must be run as root.")
-schema([
- Column("processor_number", BIGINT,
- "The processor number as reported in /proc/cpuinfo"),
- Column("turbo_disabled", BIGINT, "Whether the turbo feature is disabled."),
- Column("turbo_ratio_limit", BIGINT, "The turbo feature ratio limit."),
- Column("platform_info", BIGINT, "Platform information."),
- Column("perf_ctl", BIGINT, "Performance setting for the processor."),
- Column("perf_status", BIGINT, "Performance status for the processor."),
- Column("feature_control", BIGINT, "Bitfield controling enabled features."),
- Column("rapl_power_limit", BIGINT,
- "Run Time Average Power Limiting power limit."),
- Column("rapl_energy_status", BIGINT,
- "Run Time Average Power Limiting energy status."),
- Column("rapl_power_units", BIGINT,
- "Run Time Average Power Limiting power units.")
-])
-implementation("model_specific_register@genModelSpecificRegister")
+++ /dev/null
-table_name("shared_memory")
-description("OS shared memory regions.")
-schema([
- Column("shmid", INTEGER, "Shared memory segment ID"),
- Column("owner_uid", BIGINT, "User ID of owning process"),
- Column("creator_uid", BIGINT, "User ID of creator process"),
- Column("pid", BIGINT, "Process ID to last use the segment"),
- Column("creator_pid", BIGINT, "Process ID that created the segment"),
- Column("atime", BIGINT, "Attached time"),
- Column("dtime", BIGINT, "Detached time"),
- Column("ctime", BIGINT, "Changed time"),
- Column("permissions", TEXT, "Memory segment permissions"),
- Column("size", BIGINT, "Size in bytes"),
- Column("attached", INTEGER, "Number of attached processes"),
- Column("status", TEXT, "Destination/attach status"),
- Column("locked", INTEGER, "1 if segment is locked else 0"),
-])
-implementation("shared_memory@genSharedMemory")
+++ /dev/null
-table_name("logged_in_users")
-description("Users with an active shell on the system.")
-schema([
- Column("user", TEXT, "User login name"),
- Column("tty", TEXT, "Device name"),
- Column("host", TEXT, "Remote hostname"),
- Column("time", INTEGER, "Time entry was made"),
- Column("pid", INTEGER, "Process (or thread) ID"),
-])
-implementation("logged_in_users@genLoggedInUsers")
+++ /dev/null
-table_name("mounts")
-description("System mounted devices and filesystems (not process specific).")
-schema([
- Column("device", TEXT, "Mounted device"),
- Column("device_alias", TEXT, "Mounted device alias"),
- Column("path", TEXT, "Mounted device path"),
- Column("type", TEXT, "Mounted device type"),
- Column("blocks_size", BIGINT, "Block size in bytes"),
- Column("blocks", BIGINT, "Mounted device used blocks"),
- Column("blocks_free", BIGINT, "Mounted device free blocks"),
- Column("blocks_available", BIGINT, "Mounted device available blocks"),
- Column("inodes", BIGINT, "Mounted device used inodes"),
- Column("inodes_free", BIGINT, "Mounted device free inodes"),
- Column("flags", TEXT, "Mounted device flags"),
-])
-implementation("mounts@genMounts")
+++ /dev/null
-table_name("os_version")
-description("A single row containing the operating system name and version.")
-schema([
- Column("name", TEXT, "Distribution or product name"),
- Column("major", INTEGER, "Major release version"),
- Column("minor", INTEGER, "Minor release version"),
- Column("patch", INTEGER, "Optional patch release"),
- Column("build", TEXT, "Optional build-specific or variant string"),
-])
-implementation("system/os_version@genOSVersion")
+++ /dev/null
-table_name("passwd_changes")
-description("Track time, action changes to /etc/passwd.")
-schema([
- Column("target_path", TEXT, "The path changed"),
- Column("action", TEXT, "Change action (UPDATE, REMOVE, etc)"),
- Column("transaction_id", BIGINT, "ID used during bulk update"),
- Column("time", BIGINT, "Time of the change"),
-])
-attributes(event_subscriber=True)
-implementation("passwd_changes@passwd_changes::genTable")
+++ /dev/null
-table_name("pci_devices")
-description("PCI devices active on the host system.")
-schema([
- Column("pci_slot", TEXT, "PCI Device used slot"),
- Column("pci_class", TEXT, "PCI Device class"),
- Column("driver", TEXT, "PCI Device used driver"),
- Column("vendor", TEXT, "PCI Device vendor"),
- Column("vendor_id", TEXT, "PCI Device vendor identifier"),
- Column("model", TEXT, "PCI Device model"),
- Column("model_id", TEXT, "PCI Device model identifier"),
-
- # Optional columns
- #Column("subsystem", TEXT, "PCI Device subsystem"),
- #Column("express", INTEGER, "1 If PCI device is express else 0"),
- #Column("thunderbolt", INTEGER, "1 If PCI device is thunderbolt else 0"),
- #Column("removable", INTEGER, "1 If PCI device is removable else 0"),
-])
-implementation("pci_devices@genPCIDevices")
+++ /dev/null
-table_name("process_open_files")
-description("File descriptors for each process.")
-schema([
- Column("pid", BIGINT, "Process (or thread) ID", index=True),
- Column("fd", BIGINT, "Process-specific file descriptor number"),
- Column("path", TEXT, "Filesystem path of descriptor"),
-])
-implementation("system/process_open_files@genOpenFiles")
-examples([
- "select * from process_open_files where pid = 1",
-])
+++ /dev/null
-table_name("process_open_sockets")
-description("Processes which have open network sockets on the system.")
-schema([
- Column("pid", INTEGER, "Process (or thread) ID", index=True),
- Column("socket", INTEGER, "Socket descriptor number"),
- Column("family", INTEGER, "Network protocol (IPv4, IPv6)"),
- Column("protocol", INTEGER, "Transport protocol (TCP/UDP)"),
- Column("local_address", TEXT, "Socket local address"),
- Column("remote_address", TEXT, "Socket remote address"),
- Column("local_port", INTEGER, "Socket local port"),
- Column("remote_port", INTEGER, "Socket remote port"),
- Column("path", TEXT, "For UNIX sockets (family=AF_UNIX), the domain path"),
-])
-implementation("system/process_open_sockets@genOpenSockets")
-examples([
- "select * from process_open_sockets where pid = 1",
-])
+++ /dev/null
-table_name("shell_history")
-description("A line-delimited (command) table of per-user .*_history data.")
-schema([
- Column("username", TEXT, "Shell history owner",
- additional=True),
- Column("command", TEXT, "Unparsed date/line/command history line"),
- Column("history_file", TEXT, "Path to the .*_history for this user"),
- ForeignKey(column="username", table="users"),
-])
-implementation("shell_history@genShellHistory")
+++ /dev/null
-table_name("smbios_tables")
-description("BIOS (DMI) structure common details and content.")
-schema([
- Column("number", INTEGER, "Table entry number"),
- Column("type", INTEGER, "Table entry type"),
- Column("description", TEXT, "Table entry description"),
- Column("handle", INTEGER, "Table entry handle"),
- Column("header_size", INTEGER, "Header size in bytes"),
- Column("size", INTEGER, "Table entry size in bytes"),
- Column("md5", TEXT, "MD5 hash of table entry"),
-])
-implementation("system/smbios_tables@genSMBIOSTables")
+++ /dev/null
-table_name("suid_bin")
-description("suid binaries in common locations.")
-schema([
- Column("path", TEXT, "Binary path"),
- Column("username", TEXT, "Binary owner username"),
- Column("groupname", TEXT, "Binary owner group"),
- Column("permissions", TEXT, "Binary permissions"),
-])
-implementation("suid_bin@genSuidBin")
+++ /dev/null
-table_name("system_controls")
-description("sysctl names, values, and settings information.")
-schema([
- Column("name", TEXT, "Full sysctl MIB name"),
- Column("oid", TEXT, "Control MIB"),
- Column("subsystem", TEXT, "Subsystem ID, control type"),
- Column("current_value", TEXT, "Value of setting"),
- Column("config_value", TEXT, "The MIB value set in /etc/sysctl.conf"),
- Column("type", TEXT, "Data type"),
-])
-implementation("system_controls@genSystemControls")
+++ /dev/null
-table_name("uptime")
-description("Track time passed since last boot.")
-schema([
- Column("days", INTEGER, "Days of uptime"),
- Column("hours", INTEGER, "Hours of uptime"),
- Column("minutes", INTEGER, "Minutes of uptime"),
- Column("seconds", INTEGER, "Seconds of uptime"),
- Column("total_seconds", BIGINT, "Total uptime seconds"),
-])
-implementation("system/uptime@genUptime")
+++ /dev/null
-table_name("usb_devices")
-description("USB devices that are actively plugged into the host system.")
-schema([
- Column("usb_address", INTEGER, "USB Device used address"),
- Column("usb_port", INTEGER, "USB Device used port"),
- Column("vendor", TEXT, "USB Device vendor string"),
- Column("vendor_id", TEXT, "USB Device vendor identifier"),
- Column("model", TEXT, "USB Device model string"),
- Column("model_id", TEXT, "USB Device model identifier"),
- Column("serial", TEXT, "USB Device serial connection"),
- Column("removable", INTEGER, "1 If USB device is removable else 0"),
-])
-implementation("usb_devices@genUSBDevices")
+++ /dev/null
-/*
- * Copyright (c) 2014, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
- *
- */
-
-#include <vector>
-#include <string>
-
-#include <osquery/core.h>
-#include <osquery/logger.h>
-#include <osquery/tables.h>
-
-#include "osquery/events/linux/udev.h"
-
-namespace osquery {
-
-/**
- * @brief Track udev events in Linux
- */
-class HardwareEventSubscriber : public EventSubscriber<UdevEventPublisher> {
- public:
- Status init();
-
- Status Callback(const UdevEventContextRef& ec, const void* user_data);
-};
-
-REGISTER(HardwareEventSubscriber, "event_subscriber", "hardware_events");
-
-Status HardwareEventSubscriber::init() {
- auto subscription = createSubscriptionContext();
- subscription->action = UDEV_EVENT_ACTION_ALL;
-
- subscribe(&HardwareEventSubscriber::Callback, subscription, nullptr);
- return Status(0, "OK");
-}
-
-Status HardwareEventSubscriber::Callback(const UdevEventContextRef& ec,
- const void* user_data) {
- Row r;
-
- if (ec->devtype.empty()) {
- // Superfluous hardware event.
- return Status(0, "Missing type.");
- } else if (ec->devnode.empty() && ec->driver.empty()) {
- return Status(0, "Missing node and driver.");
- }
-
- struct udev_device *device = ec->device;
- r["action"] = ec->action_string;
- r["path"] = ec->devnode;
- r["type"] = ec->devtype;
- r["driver"] = ec->driver;
-
- // UDEV properties.
- r["model"] = UdevEventPublisher::getValue(device, "ID_MODEL_FROM_DATABASE");
- if (r["path"].empty() && r["model"].empty()) {
- // Don't emit mising path/model combos.
- return Status(0, "Missing path and model.");
- }
-
- r["model_id"] = INTEGER(UdevEventPublisher::getValue(device, "ID_MODEL_ID"));
- r["vendor"] = UdevEventPublisher::getValue(device, "ID_VENDOR_FROM_DATABASE");
- r["vendor_id"] =
- INTEGER(UdevEventPublisher::getValue(device, "ID_VENDOR_ID"));
- r["serial"] =
- INTEGER(UdevEventPublisher::getValue(device, "ID_SERIAL_SHORT"));
- r["revision"] = INTEGER(UdevEventPublisher::getValue(device, "ID_REVISION"));
- add(r, ec->time);
- return Status(0, "OK");
-}
-}
+++ /dev/null
-/*
- * Copyright (c) 2014, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
- *
- */
-
-#include <vector>
-#include <string>
-
-#include <osquery/core.h>
-#include <osquery/logger.h>
-#include <osquery/tables.h>
-
-#include "osquery/events/linux/inotify.h"
-
-namespace osquery {
-
-/**
- * @brief Track time, action changes to /etc/passwd
- *
- * This is mostly an example EventSubscriber implementation.
- */
-class PasswdChangesEventSubscriber
- : public EventSubscriber<INotifyEventPublisher> {
- public:
- Status init();
-
- /**
- * @brief This exports a single Callback for INotifyEventPublisher events.
- *
- * @param ec The EventCallback type receives an EventContextRef substruct
- * for the INotifyEventPublisher declared in this EventSubscriber subclass.
- *
- * @return Was the callback successful.
- */
- Status Callback(const INotifyEventContextRef& ec, const void* user_data);
-};
-
-/**
- * @brief Each EventSubscriber must register itself so the init method is
- *called.
- *
- * This registers PasswdChangesEventSubscriber into the osquery EventSubscriber
- * pseudo-plugin registry.
- */
-REGISTER(PasswdChangesEventSubscriber, "event_subscriber", "passwd_changes");
-
-Status PasswdChangesEventSubscriber::init() {
- auto mc = createSubscriptionContext();
- mc->path = "/etc/passwd";
- mc->mask = IN_ATTRIB | IN_MODIFY | IN_DELETE | IN_CREATE;
- subscribe(&PasswdChangesEventSubscriber::Callback, mc, nullptr);
- return Status(0, "OK");
-}
-
-Status PasswdChangesEventSubscriber::Callback(const INotifyEventContextRef& ec,
- const void* user_data) {
- Row r;
- r["action"] = ec->action;
- r["target_path"] = ec->path;
- r["transaction_id"] = INTEGER(ec->event->cookie);
- if (ec->action != "" && ec->action != "OPENED") {
- // A callback is somewhat useless unless it changes the EventSubscriber
- // state
- // or calls `add` to store a marked up event.
- add(r, ec->time);
- }
- return Status(0, "OK");
-}
-}
+++ /dev/null
-/*
- * Copyright (c) 2014, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
- *
- */
-
-#include <vector>
-#include <string>
-
-#include <boost/algorithm/string/join.hpp>
-#include <boost/algorithm/string/predicate.hpp>
-
-#include <osquery/core.h>
-#include <osquery/logger.h>
-#include <osquery/tables.h>
-#include <osquery/filesystem.h>
-
-namespace osquery {
-namespace tables {
-
-QueryData parseEtcProtocolsContent(const std::string& content) {
- QueryData results;
-
- for (const auto& line : split(content, "\n")) {
- // Empty line or comment.
- if (line.size() == 0 || boost::starts_with(line, "#")) {
- continue;
- }
-
- // [0]: name protocol_number alias
- // [1]: [comment part1]
- // [2]: [comment part2]
- // [n]: [comment partn]
- auto protocol_comment = split(line, "#");
-
- // [0]: name
- // [1]: protocol_number
- // [2]: alias
- auto protocol_fields = split(protocol_comment[0]);
- if (protocol_fields.size() < 2) {
- continue;
- }
-
- Row r;
- r["name"] = TEXT(protocol_fields[0]);
- r["number"] = INTEGER(protocol_fields[1]);
- if (protocol_fields.size() > 2) {
- r["alias"] = TEXT(protocol_fields[2]);
- }
-
- // If there is a comment for the service.
- if (protocol_comment.size() > 1) {
- // Removes everything except the comment (parts of the comment).
- protocol_comment.erase(protocol_comment.begin(), protocol_comment.begin() + 1);
- r["comment"] = TEXT(boost::algorithm::join(protocol_comment, " # "));
- }
- results.push_back(r);
- }
- return results;
-}
-
-QueryData genEtcProtocols(QueryContext& context) {
- std::string content;
- auto s = osquery::readFile("/etc/protocols", content);
- if (s.ok()) {
- return parseEtcProtocolsContent(content);
- } else {
- TLOG << "Error reading /etc/protocols: " << s.toString();
- return {};
- }
-}
-}
-}
+++ /dev/null
-/*
- * Copyright (c) 2014, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
- *
- */
-
-#include <vector>
-#include <string>
-
-#include <boost/algorithm/string/join.hpp>
-#include <boost/algorithm/string/predicate.hpp>
-
-#include <osquery/core.h>
-#include <osquery/logger.h>
-#include <osquery/tables.h>
-#include <osquery/filesystem.h>
-
-namespace osquery {
-namespace tables {
-
-QueryData parseEtcServicesContent(const std::string& content) {
- QueryData results;
-
- for (const auto& line : split(content, "\n")) {
- // Empty line or comment.
- if (line.size() == 0 || boost::starts_with(line, "#")) {
- continue;
- }
-
- // [0]: name port/protocol [aliases]
- // [1]: [comment part1]
- // [2]: [comment part2]
- // [n]: [comment partn]
- auto service_info_comment = split(line, "#");
-
- // [0]: name
- // [1]: port/protocol
- // [2]: [aliases0]
- // [3]: [aliases1]
- // [n]: [aliasesn]
- auto service_info = split(service_info_comment[0]);
- if (service_info.size() < 2) {
- LOG(WARNING) << "Line of /etc/services wasn't properly formatted. "
- << "Expected at least 2, got " << service_info.size();
- continue;
- }
-
- // [0]: port [1]: protocol
- auto service_port_protocol = split(service_info[1], "/");
- if (service_port_protocol.size() != 2) {
- LOG(WARNING) << "Line of /etc/services wasn't properly formatted. "
- << "Expected 2, got " << service_port_protocol.size();
- continue;
- }
-
- Row r;
- r["name"] = TEXT(service_info[0]);
- r["port"] = INTEGER(service_port_protocol[0]);
- r["protocol"] = TEXT(service_port_protocol[1]);
-
- // Removes the name and the port/protcol elements.
- service_info.erase(service_info.begin(), service_info.begin() + 2);
- r["aliases"] = TEXT(boost::algorithm::join(service_info, " "));
-
- // If there is a comment for the service.
- if (service_info_comment.size() > 1) {
- // Removes everything except the comment (parts of the comment).
- service_info_comment.erase(service_info_comment.begin(), service_info_comment.begin() + 1);
- r["comment"] = TEXT(boost::algorithm::join(service_info_comment, " # "));
- }
- results.push_back(r);
- }
- return results;
-}
-
-QueryData genEtcServices(QueryContext& context) {
- std::string content;
- auto s = osquery::readFile("/etc/services", content);
- if (s.ok()) {
- return parseEtcServicesContent(content);
- } else {
- LOG(ERROR) << "Error reading /etc/services: " << s.toString();
- return {};
- }
-}
-}
-}
+++ /dev/null
-/*
- * Copyright (c) 2014, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
- *
- */
-
-#include <fstream>
-
-#include <boost/algorithm/string/split.hpp>
-#include <boost/algorithm/string/trim.hpp>
-
-#include <osquery/tables.h>
-#include <osquery/filesystem.h>
-#include <osquery/logger.h>
-
-namespace osquery {
-namespace tables {
-
-const std::string kLinuxArpTable = "/proc/net/arp";
-
-QueryData genArpCache(QueryContext& context) {
- QueryData results;
-
- boost::filesystem::path arp_path = kLinuxArpTable;
- if (!osquery::isReadable(arp_path).ok()) {
- VLOG(1) << "Cannot read arp table.";
- return results;
- }
-
- std::ifstream fd(arp_path.string(), std::ios::in | std::ios::binary);
- std::string line;
-
- if (fd.fail() || fd.eof()) {
- VLOG(1) << "Empty or failed arp table.";
- return results;
- }
-
- // Read the header line.
- std::getline(fd, line, '\n');
- while (!(fd.fail() || fd.eof())) {
- std::getline(fd, line, '\n');
-
- // IP address, HW type, Flags, HW address, Mask Device
- std::vector<std::string> fields;
- boost::split(fields, line, boost::is_any_of(" "), boost::token_compress_on);
- for (auto& f : fields) {
- // Inline trim each split.
- boost::trim(f);
- }
-
- if (fields.size() != 6) {
- // An unhandled error case.
- continue;
- }
-
- Row r;
- r["address"] = fields[0];
- r["mac"] = fields[3];
- r["interface"] = fields[5];
-
- // Note: it's also possible to detect publish entries (ATF_PUB).
- if (fields[2] == "0x6") {
- // The string representation of ATF_COM | ATF_PERM.
- r["permanent"] = "1";
- } else {
- r["permanent"] = "0";
- }
-
- results.push_back(r);
- }
-
- return results;
-}
-}
-}
+++ /dev/null
-/*
- * Copyright (c) 2014, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
- *
- */
-
-#include <arpa/inet.h>
-
-#include <boost/algorithm/string/split.hpp>
-
-#include <osquery/core.h>
-#include <osquery/filesystem.h>
-#include <osquery/logger.h>
-#include <osquery/tables.h>
-
-namespace osquery {
-namespace tables {
-
-// Linux proc protocol define to net stats file name.
-const std::map<int, std::string> kLinuxProtocolNames = {
- {IPPROTO_ICMP, "icmp"},
- {IPPROTO_TCP, "tcp"},
- {IPPROTO_UDP, "udp"},
- {IPPROTO_UDPLITE, "udplite"},
- {IPPROTO_RAW, "raw"},
-};
-
-std::string addressFromHex(const std::string &encoded_address, int family) {
- char addr_buffer[INET6_ADDRSTRLEN] = {0};
- if (family == AF_INET) {
- struct in_addr decoded;
- if (encoded_address.length() == 8) {
- sscanf(encoded_address.c_str(), "%X", &(decoded.s_addr));
- inet_ntop(AF_INET, &decoded, addr_buffer, INET_ADDRSTRLEN);
- }
- } else if (family == AF_INET6) {
- struct in6_addr decoded;
- if (encoded_address.length() == 32) {
- sscanf(encoded_address.c_str(),
- "%8x%8x%8x%8x",
- (unsigned int *)&(decoded.s6_addr[0]),
- (unsigned int *)&(decoded.s6_addr[4]),
- (unsigned int *)&(decoded.s6_addr[8]),
- (unsigned int *)&(decoded.s6_addr[12]));
- inet_ntop(AF_INET6, &decoded, addr_buffer, INET6_ADDRSTRLEN);
- }
- }
-
- return TEXT(addr_buffer);
-}
-
-unsigned short portFromHex(const std::string &encoded_port) {
- unsigned short decoded = 0;
- if (encoded_port.length() == 4) {
- sscanf(encoded_port.c_str(), "%hX", &decoded);
- }
- return decoded;
-}
-
-void genSocketsFromProc(const std::map<std::string, std::string> &inodes,
- int protocol,
- int family,
- QueryData &results) {
- std::string path = "/proc/net/";
- if (family == AF_UNIX) {
- path += "unix";
- } else {
- path += kLinuxProtocolNames.at(protocol);
- path += (family == AF_INET6) ? "6" : "";
- }
-
- std::string content;
- if (!osquery::readFile(path, content).ok()) {
- // Could not open socket information from /proc.
- return;
- }
-
- // The system's socket information is tokenized by line.
- size_t index = 0;
- for (const auto &line : osquery::split(content, "\n")) {
- if (++index == 1) {
- // The first line is a textual header and will be ignored.
- if (line.find("sl") != 0 && line.find("sk") != 0 &&
- line.find("Num") != 0) {
- // Header fields are unknown, stop parsing.
- break;
- }
- continue;
- }
-
- // The socket information is tokenized by spaces, each a field.
- auto fields = osquery::split(line, " ");
- // UNIX socket reporting has a smaller number of fields.
- size_t min_fields = (family == AF_UNIX) ? 7 : 10;
- if (fields.size() < min_fields) {
- // Unknown/malformed socket information.
- continue;
- }
-
-
- Row r;
- if (family == AF_UNIX) {
- r["socket"] = fields[6];
- r["family"] = "0";
- r["protocol"] = fields[2];
- r["local_address"] = "";
- r["local_port"] = "0";
- r["remote_address"] = "";
- r["remote_port"] = "0";
- r["path"] = (fields.size() >= 8) ? fields[7] : "";
- } else {
- // Two of the fields are the local/remote address/port pairs.
- auto locals = osquery::split(fields[1], ":");
- auto remotes = osquery::split(fields[2], ":");
- if (locals.size() != 2 || remotes.size() != 2) {
- // Unknown/malformed socket information.
- continue;
- }
-
- r["socket"] = fields[9];
- r["family"] = INTEGER(family);
- r["protocol"] = INTEGER(protocol);
- r["local_address"] = addressFromHex(locals[0], family);
- r["local_port"] = INTEGER(portFromHex(locals[1]));
- r["remote_address"] = addressFromHex(remotes[0], family);
- r["remote_port"] = INTEGER(portFromHex(remotes[1]));
- // Path is only used for UNIX domain sockets.
- r["path"] = "";
- }
-
- if (inodes.count(r["socket"]) > 0) {
- r["pid"] = inodes.at(r["socket"]);
- } else {
- r["pid"] = "-1";
- }
-
- results.push_back(r);
- }
-}
-
-QueryData genOpenSockets(QueryContext &context) {
- QueryData results;
-
- // If a pid is given then set that as the only item in processes.
- std::set<std::string> pids;
- if (context.constraints["pid"].exists(EQUALS)) {
- pids = context.constraints["pid"].getAll(EQUALS);
- } else {
- osquery::procProcesses(pids);
- }
-
- // Generate a map of socket inode to process tid.
- std::map<std::string, std::string> socket_inodes;
- for (const auto &process : pids) {
- std::map<std::string, std::string> descriptors;
- if (osquery::procDescriptors(process, descriptors).ok()) {
- for (const auto& fd : descriptors) {
- if (fd.second.find("socket:[") == 0) {
- // See #792: std::regex is incomplete until GCC 4.9 (skip 8 chars)
- auto inode = fd.second.substr(8);
- socket_inodes[inode.substr(0, inode.size() - 1)] = process;
- }
- }
- }
- }
-
- // This used to use netlink (Ref: #1094) to request socket information.
- // Use proc messages to query socket information.
- for (const auto &protocol : kLinuxProtocolNames) {
- genSocketsFromProc(socket_inodes, protocol.first, AF_INET, results);
- genSocketsFromProc(socket_inodes, protocol.first, AF_INET6, results);
- }
-
- genSocketsFromProc(socket_inodes, IPPROTO_IP, AF_UNIX, results);
- return results;
-}
-}
-}
+++ /dev/null
-/*
- * Copyright (c) 2014, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
- *
- */
-
-#include <sys/socket.h>
-#include <linux/netlink.h>
-#include <linux/rtnetlink.h>
-#include <net/if.h>
-
-#include <boost/algorithm/string/trim.hpp>
-
-#include <osquery/core.h>
-#include <osquery/logger.h>
-#include <osquery/tables.h>
-
-#include "osquery/tables/networking/utils.h"
-
-namespace osquery {
-namespace tables {
-
-#define MAX_NETLINK_SIZE 8192
-#define MAX_NETLINK_LATENCY 2000
-
-std::string getNetlinkIP(int family, const char* buffer) {
- char dst[INET6_ADDRSTRLEN];
- memset(dst, 0, INET6_ADDRSTRLEN);
-
- inet_ntop(family, buffer, dst, INET6_ADDRSTRLEN);
- std::string address(dst);
- boost::trim(address);
-
- return address;
-}
-
-Status readNetlink(int socket_fd, int seq, char* output, size_t* size) {
- struct nlmsghdr* nl_hdr = nullptr;
-
- size_t message_size = 0;
- do {
- int latency = 0;
- int bytes = 0;
- while (bytes == 0) {
- bytes = recv(socket_fd, output, MAX_NETLINK_SIZE - message_size, 0);
- if (bytes < 0) {
- return Status(1, "Could not read from NETLINK");
- } else if (latency >= MAX_NETLINK_LATENCY) {
- return Status(1, "Netlink timeout");
- } else if (bytes == 0) {
- ::usleep(20);
- latency += 20;
- }
- }
-
- // Assure valid header response, and not an error type.
- nl_hdr = (struct nlmsghdr*)output;
- if (NLMSG_OK(nl_hdr, bytes) == 0 || nl_hdr->nlmsg_type == NLMSG_ERROR) {
- return Status(1, "Read invalid NETLINK message");
- }
-
- if (nl_hdr->nlmsg_type == NLMSG_DONE) {
- break;
- }
-
- // Move the buffer pointer
- output += bytes;
- message_size += bytes;
- if ((nl_hdr->nlmsg_flags & NLM_F_MULTI) == 0) {
- break;
- }
- } while (nl_hdr->nlmsg_seq != seq || nl_hdr->nlmsg_pid != getpid());
-
- *size = message_size;
- return Status(0, "OK");
-}
-
-void genNetlinkRoutes(const struct nlmsghdr* netlink_msg, QueryData& results) {
- std::string address;
- int mask = 0;
- char interface[IF_NAMESIZE];
-
- struct rtmsg* message = (struct rtmsg*)NLMSG_DATA(netlink_msg);
- struct rtattr* attr = (struct rtattr*)RTM_RTA(message);
- int attr_size = RTM_PAYLOAD(netlink_msg);
-
- Row r;
-
- // Iterate over each route in the netlink message
- bool has_destination = false;
- r["metric"] = "0";
- while (RTA_OK(attr, attr_size)) {
- switch (attr->rta_type) {
- case RTA_OIF:
- if_indextoname(*(int*)RTA_DATA(attr), interface);
- r["interface"] = std::string(interface);
- break;
- case RTA_GATEWAY:
- address = getNetlinkIP(message->rtm_family, (char*)RTA_DATA(attr));
- r["gateway"] = address;
- break;
- case RTA_PREFSRC:
- address = getNetlinkIP(message->rtm_family, (char*)RTA_DATA(attr));
- r["source"] = address;
- break;
- case RTA_DST:
- if (message->rtm_dst_len != 32 && message->rtm_dst_len != 128) {
- mask = (int)message->rtm_dst_len;
- }
- address = getNetlinkIP(message->rtm_family, (char*)RTA_DATA(attr));
- r["destination"] = address;
- has_destination = true;
- break;
- case RTA_PRIORITY:
- r["metric"] = INTEGER(*(int*)RTA_DATA(attr));
- break;
- }
- attr = RTA_NEXT(attr, attr_size);
- }
-
- if (!has_destination) {
- r["destination"] = "0.0.0.0";
- if (message->rtm_dst_len) {
- mask = (int)message->rtm_dst_len;
- }
- }
-
- // Route type determination
- if (message->rtm_type == RTN_UNICAST) {
- r["type"] = "gateway";
- } else if (message->rtm_type == RTN_LOCAL) {
- r["type"] = "local";
- } else if (message->rtm_type == RTN_BROADCAST) {
- r["type"] = "broadcast";
- } else if (message->rtm_type == RTN_ANYCAST) {
- r["type"] = "anycast";
- } else {
- r["type"] = "other";
- }
-
- r["flags"] = INTEGER(message->rtm_flags);
-
- // This is the cidr-formatted mask
- r["netmask"] = INTEGER(mask);
-
- // Fields not supported by Linux routes:
- r["mtu"] = "0";
- results.push_back(r);
-}
-
-QueryData genRoutes(QueryContext& context) {
- QueryData results;
-
- int socket_fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
- if (socket_fd < 0) {
- VLOG(1) << "Cannot open NETLINK socket";
- return {};
- }
-
- // Create netlink message header
- auto netlink_buffer = (void*)malloc(MAX_NETLINK_SIZE);
- if (netlink_buffer == nullptr) {
- close(socket_fd);
- return {};
- }
-
- auto netlink_msg = (struct nlmsghdr*)netlink_buffer;
- netlink_msg->nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
- netlink_msg->nlmsg_type = RTM_GETROUTE; // routes from kernel routing table
- netlink_msg->nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST;
- netlink_msg->nlmsg_seq = 0;
- netlink_msg->nlmsg_pid = getpid();
-
- // Send the netlink request to the kernel
- if (send(socket_fd, netlink_msg, netlink_msg->nlmsg_len, 0) < 0) {
- TLOG << "Cannot write NETLINK request header to socket";
- close(socket_fd);
- free(netlink_buffer);
- return {};
- }
-
- // Wrap the read socket to support multi-netlink messages
- size_t size = 0;
- if (!readNetlink(socket_fd, 1, (char*)netlink_msg, &size).ok()) {
- TLOG << "Cannot read NETLINK response from socket";
- close(socket_fd);
- free(netlink_buffer);
- return {};
- }
-
- // Treat the netlink response as route information
- while (NLMSG_OK(netlink_msg, size)) {
- genNetlinkRoutes(netlink_msg, results);
- netlink_msg = NLMSG_NEXT(netlink_msg, size);
- }
-
- close(socket_fd);
- free(netlink_buffer);
- return results;
-}
-}
-}
+++ /dev/null
-/*
- * Copyright (c) 2014, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
- *
- */
-
-#include <gtest/gtest.h>
-
-#include <osquery/logger.h>
-
-#include "osquery/core/test_util.h"
-
-namespace osquery {
-namespace tables {
-
-osquery::QueryData parseEtcProtocolsContent(const std::string& content);
-
-class EtcProtocolsTests : public testing::Test {};
-
-TEST_F(EtcProtocolsTests, test_parse_etc_protocols_content) {
- EXPECT_EQ(parseEtcProtocolsContent(getEtcProtocolsContent()),
- getEtcProtocolsExpectedResults());
-}
-}
-}
+++ /dev/null
-/*
- * Copyright (c) 2014, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
- *
- */
-
-#include <vector>
-
-#include <boost/algorithm/string/trim.hpp>
-
-#include <osquery/core.h>
-#include <osquery/tables.h>
-#include <osquery/filesystem.h>
-#include <osquery/logger.h>
-
-namespace osquery {
-namespace tables {
-
-const std::string kSystemCron = "/etc/crontab";
-
-const std::vector<std::string> kUserCronPaths = {
- "/var/at/tabs/", "/var/spool/cron/", "/var/spool/cron/crontabs/",
-};
-
-std::vector<std::string> cronFromFile(const std::string& path) {
- std::string content;
- std::vector<std::string> cron_lines;
- if (!isReadable(path).ok()) {
- return cron_lines;
- }
-
- if (!readFile(path, content).ok()) {
- return cron_lines;
- }
-
- auto lines = split(content, "\n");
-
- // Only populate the lines that are not comments or blank.
- for (auto& line : lines) {
- // Cheat and use a non-const iteration, to inline trim.
- boost::trim(line);
- if (line.size() > 0 && line.at(0) != '#') {
- cron_lines.push_back(line);
- }
- }
-
- return cron_lines;
-}
-
-void genCronLine(const std::string& path,
- const std::string& line,
- QueryData& results) {
- Row r;
-
- r["path"] = path;
- auto columns = split(line, " \t");
-
- size_t index = 0;
- auto iterator = columns.begin();
- for (; iterator != columns.end(); ++iterator) {
- if (index == 0) {
- if ((*iterator).at(0) == '@') {
- // If the first value is an 'at' then skip to the command.
- r["event"] = *iterator;
- index = 5;
- continue;
- }
- r["minute"] = *iterator;
- } else if (index == 1) {
- r["hour"] = *iterator;
- } else if (index == 2) {
- r["day_of_month"] = *iterator;
- } else if (index == 3) {
- r["month"] = *iterator;
- } else if (index == 4) {
- r["day_of_week"] = *iterator;
- } else if (index == 5) {
- r["command"] = *iterator;
- } else {
- // Long if switch to handle command breaks from space delim.
- r["command"] += " " + *iterator;
- }
- index++;
- }
-
- if (r["command"].size() == 0) {
- // The line was not well-formed, perhaps it was a variable?
- return;
- }
-
- results.push_back(r);
-}
-
-QueryData genCronTab(QueryContext& context) {
- QueryData results;
-
- auto system_lines = cronFromFile(kSystemCron);
- for (const auto& line : system_lines) {
- genCronLine(kSystemCron, line, results);
- }
-
- std::vector<std::string> user_crons;
- for (const auto cron_path : kUserCronPaths) {
- osquery::listFilesInDirectory(cron_path, user_crons);
- }
-
- // The user-based crons are identified by their path.
- for (const auto& user_path : user_crons) {
- auto user_lines = cronFromFile(user_path);
- for (const auto& line : user_lines) {
- genCronLine(user_path, line, results);
- }
- }
-
- return results;
-}
-}
-}
+++ /dev/null
-/*
- * Copyright (c) 2014, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
- *
- */
-
-#include <vector>
-#include <string>
-
-#include <utmpx.h>
-
-#include <osquery/core.h>
-#include <osquery/tables.h>
-
-namespace osquery {
-namespace tables {
-
-QueryData genLastAccess(QueryContext& context) {
- QueryData results;
- struct utmpx *ut;
-#ifdef __APPLE__
- setutxent_wtmp(0); // 0 = reverse chronological order
-
- while ((ut = getutxent_wtmp()) != nullptr) {
-#else
-
- utmpxname("/var/log/wtmpx");
- setutxent();
-
- while ((ut = getutxent()) != nullptr) {
-#endif
-
- Row r;
- r["username"] = std::string(ut->ut_user);
- r["tty"] = std::string(ut->ut_line);
- r["pid"] = boost::lexical_cast<std::string>(ut->ut_pid);
- r["type"] = boost::lexical_cast<std::string>(ut->ut_type);
- r["time"] = boost::lexical_cast<std::string>(ut->ut_tv.tv_sec);
- r["host"] = std::string(ut->ut_host);
-
- results.push_back(r);
- }
-
-#ifdef __APPLE__
- endutxent_wtmp();
-#else
- endutxent();
-#endif
-
- return results;
-}
-}
-}
+++ /dev/null
-/*
- * Copyright (c) 2014, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
- *
- */
-
-#include <boost/filesystem.hpp>
-
-#include <osquery/core.h>
-#include <osquery/filesystem.h>
-#include <osquery/hash.h>
-#include <osquery/tables.h>
-
-namespace fs = boost::filesystem;
-
-namespace osquery {
-namespace tables {
-
-const std::string kLinuxACPIPath = "/sys/firmware/acpi/tables";
-
-void genACPITable(const std::string& table, QueryData& results) {
- fs::path table_path = table;
-
- // There may be "categories" of tables in the form of directories.
- Status status;
- if (!fs::is_regular_file(table_path)) {
- std::vector<std::string> child_tables;
- status = osquery::listFilesInDirectory(table_path, child_tables);
- if (status.ok()) {
- for (const auto& child_table : child_tables) {
- genACPITable(child_table, results);
- }
- }
-
- return;
- }
-
- Row r;
- r["name"] = table_path.filename().string();
-
- std::string table_content;
- status = osquery::readFile(table_path, table_content);
- if (!status.ok()) {
- r["size"] = INTEGER(-1);
- } else {
- r["size"] = INTEGER(table_content.size());
- r["md5"] = osquery::hashFromBuffer(
- HASH_TYPE_MD5, table_content.c_str(), table_content.length());
- }
-
- results.push_back(r);
-}
-
-QueryData genACPITables(QueryContext& context) {
- QueryData results;
-
- // In Linux, hopefully the ACPI tables are parsed and exposed as nodes.
- std::vector<std::string> tables;
- auto status = osquery::listFilesInDirectory(kLinuxACPIPath, tables);
- if (!status.ok()) {
- // We could not read the tables path or the nodes are not exposed.
- return {};
- }
-
- for (const auto& table : tables) {
- genACPITable(table, results);
- }
-
- return results;
-}
-}
-}
+++ /dev/null
-/*
- * Copyright (c) 2014, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
- *
- */
-
-#include <boost/algorithm/string/split.hpp>
-
-#include <osquery/core.h>
-#include <osquery/filesystem.h>
-#include <osquery/hash.h>
-#include <osquery/logger.h>
-#include <osquery/tables.h>
-
-namespace osquery {
-namespace tables {
-
-const std::string kKernelArgumentsPath = "/proc/cmdline";
-const std::string kKernelSignaturePath = "/proc/version";
-
-QueryData genKernelInfo(QueryContext& context) {
- QueryData results;
- Row r;
-
- if (pathExists(kKernelArgumentsPath).ok()) {
- std::string arguments_line;
- // Grab the whole arguments string from proc.
- if (readFile(kKernelArgumentsPath, arguments_line).ok()) {
- auto arguments = split(arguments_line, " ");
- std::string additional_arguments;
-
- // Iterate over each space-tokenized argument.
- for (const auto& argument : arguments) {
- if (argument.substr(0, 11) == "BOOT_IMAGE=") {
- r["path"] = argument.substr(11);
- } else if (argument.substr(0, 5) == "root=") {
- r["device"] = argument.substr(5);
- } else {
- if (additional_arguments.size() > 0) {
- additional_arguments += " ";
- }
- additional_arguments += argument;
- }
- }
- r["arguments"] = additional_arguments;
- }
- } else {
- VLOG(1) << "Cannot find kernel arguments file: " << kKernelArgumentsPath;
- }
-
- if (pathExists(kKernelSignaturePath).ok()) {
- std::string signature;
-
- // The signature includes the kernel version, build data, buildhost,
- // GCC version used, and possibly build date.
- if (readFile(kKernelSignaturePath, signature).ok()) {
- auto details = split(signature, " ");
- if (details.size() > 2 && details[1] == "version") {
- r["version"] = details[2];
- }
- }
- } else {
- VLOG(1) << "Cannot find kernel signature file: " << kKernelSignaturePath;
- }
-
- // Using the path of the boot image, attempt to calculate a hash.
- if (r.count("path") > 0) {
- r["md5"] = hashFromFile(HASH_TYPE_MD5, r.at("path"));
- }
-
- results.push_back(r);
- return results;
-}
-}
-}
+++ /dev/null
-/*
- * Copyright (c) 2014, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
- *
- */
-
-#include <fstream>
-
-#include <boost/algorithm/string/split.hpp>
-#include <boost/algorithm/string/trim.hpp>
-
-#include <osquery/core.h>
-#include <osquery/filesystem.h>
-#include <osquery/logger.h>
-#include <osquery/tables.h>
-
-namespace osquery {
-namespace tables {
-
-const std::string kKernelModulePath = "/proc/modules";
-
-QueryData genKernelModules(QueryContext& context) {
- QueryData results;
-
- if (!pathExists(kKernelModulePath).ok()) {
- VLOG(1) << "Cannot find kernel modules proc file: " << kKernelModulePath;
- return {};
- }
-
- // Cannot seek to the end of procfs.
- std::ifstream fd(kKernelModulePath, std::ios::in);
- if (!fd) {
- VLOG(1) << "Cannot read kernel modules from: " << kKernelModulePath;
- return {};
- }
-
- auto module_info = std::string(std::istreambuf_iterator<char>(fd),
- std::istreambuf_iterator<char>());
-
- for (const auto& module : split(module_info, "\n")) {
- Row r;
- auto module_info = split(module, " ");
- if (module_info.size() < 6) {
- // Interesting error case, this module line is not well formed.
- continue;
- }
-
- for (auto& detail : module_info) {
- // Clean up the delimiters
- boost::trim(detail);
- if (detail.back() == ',') {
- detail.pop_back();
- }
- }
-
- r["name"] = module_info[0];
- r["size"] = module_info[1];
- r["used_by"] = module_info[3];
- r["status"] = module_info[4];
- r["address"] = module_info[5];
- results.push_back(r);
- }
-
- return results;
-}
-}
-}
+++ /dev/null
-/*
- * Copyright (c) 2014, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
- *
- */
-
-#include <boost/algorithm/string.hpp>
-
-#include <osquery/core.h>
-#include <osquery/filesystem.h>
-#include <osquery/logger.h>
-#include <osquery/tables.h>
-
-namespace fs = boost::filesystem;
-
-namespace osquery {
-namespace tables {
-
-const std::string kMemoryMapLocation = "/sys/firmware/memmap";
-
-QueryData genMemoryMap(QueryContext& context) {
- QueryData results;
-
- // Linux memory map is exposed in /sys.
- std::vector<std::string> regions;
- auto status = listDirectoriesInDirectory(kMemoryMapLocation, regions);
- if (!status.ok()) {
- return {};
- }
-
- for (const auto& index : regions) {
- fs::path index_path(index);
- Row r;
- r["region"] = index_path.filename().string();
-
- // The type is a textual description
- std::string content;
- readFile(index_path / "type", content);
- boost::trim(content);
- r["type"] = content;
-
- // Keep these in 0xFFFF (hex) form.
- readFile(index_path / "start", content);
- boost::trim(content);
- r["start"] = content;
-
- readFile(index_path / "end", content);
- boost::trim(content);
- r["end"] = content;
-
- results.push_back(r);
- }
-
- return results;
-}
-}
-}
+++ /dev/null
-/*
- * Copyright (c) 2014, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
- *
- */
-
-#include <dirent.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <unistd.h>
-
-#include <osquery/core.h>
-#include <osquery/filesystem.h>
-#include <osquery/logger.h>
-#include <osquery/tables.h>
-
-#define MSR_FILENAME_BUFFER_SIZE 32
-
-#define NO_MASK 0xFFFFFFFFFFFFFFFFULL
-
-// Defines taken from uapi/asm/msr-index.h from the linux kernel.
-#define MSR_PLATFORM_INFO 0x000000ce
-
-#define MSR_IA32_FEATURE_CONTROL 0x0000003a
-
-#define MSR_IA32_PERF_STATUS 0x00000198
-#define MSR_IA32_PERF_CTL 0x00000199
-#define INTEL_PERF_CTL_MASK 0xffff
-
-#define MSR_IA32_MISC_ENABLE 0x000001a0
-
-#define MSR_TURBO_RATIO_LIMIT 0x000001ad
-
-#define MSR_IA32_MISC_ENABLE_TURBO_DISABLE_BIT 38
-#define MSR_IA32_MISC_ENABLE_TURBO_DISABLE \
- (1ULL << MSR_IA32_MISC_ENABLE_TURBO_DISABLE_BIT)
-
-// Run Time Average Power Limiting (RAPL).
-#define MSR_RAPL_POWER_UNIT 0x00000606
-#define MSR_PKG_ENERGY_STATUS 0x00000611
-#define MSR_PKG_POWER_LIMIT 0x00000610
-
-namespace osquery {
-namespace tables {
-
-// These are the entries to retrieve from the model specific register
-struct msr_record_t {
- const char *name;
- const off_t offset;
- const uint64_t mask;
- const int is_flag;
-};
-const static msr_record_t fields[] = {
- {.name = "turbo_disabled",
- .offset = MSR_IA32_MISC_ENABLE,
- .mask = MSR_IA32_MISC_ENABLE_TURBO_DISABLE,
- .is_flag = true},
- {.name = "turbo_ratio_limit",
- .offset = MSR_TURBO_RATIO_LIMIT,
- .mask = NO_MASK,
- .is_flag = false},
- {.name = "platform_info",
- .offset = MSR_PLATFORM_INFO,
- .mask = NO_MASK,
- .is_flag = false},
- {.name = "perf_status",
- .offset = MSR_IA32_PERF_STATUS,
- .mask = NO_MASK,
- .is_flag = false},
- {.name = "perf_ctl",
- .offset = MSR_IA32_PERF_CTL,
- .mask = INTEL_PERF_CTL_MASK,
- .is_flag = false},
- {.name = "feature_control",
- .offset = MSR_IA32_FEATURE_CONTROL,
- .mask = NO_MASK,
- .is_flag = false},
- {.name = "rapl_power_limit",
- .offset = MSR_PKG_POWER_LIMIT,
- .mask = NO_MASK,
- .is_flag = false},
- {.name = "rapl_energy_status",
- .offset = MSR_PKG_ENERGY_STATUS,
- .mask = NO_MASK,
- .is_flag = false},
- {.name = "rapl_power_units",
- .offset = MSR_RAPL_POWER_UNIT,
- .mask = NO_MASK,
- .is_flag = false}};
-
-void getModelSpecificRegisterData(QueryData &results, int cpu_number) {
- auto msr_filename =
- std::string("/dev/cpu/") + std::to_string(cpu_number) + "/msr";
-
- int fd = open(msr_filename.c_str(), O_RDONLY);
- if (fd < 0) {
- int err = errno;
- TLOG << "Could not open msr file " << msr_filename
- << " check the msr kernel module is enabled.";
- if (err == EACCES) {
- LOG(WARNING) << "Could not access msr device. Run osquery as root.";
- }
- return;
- }
-
- Row r;
- r["processor_number"] = BIGINT(cpu_number);
- for (const msr_record_t &field : fields) {
- uint64_t output;
- ssize_t size = pread(fd, &output, sizeof(uint64_t), field.offset);
- if (size != sizeof(uint64_t)) {
- // Processor does not have a record of this type.
- continue;
- }
- if (field.is_flag) {
- r[field.name] = BIGINT((output & field.mask) ? 1 : 0);
- } else {
- r[field.name] = BIGINT(output & field.mask);
- }
- }
- results.push_back(r);
- close(fd);
-
- return;
-}
-
-// Filter only for filenames starting with a digit.
-int msrScandirFilter(const struct dirent *entry) {
- if (isdigit(entry->d_name[0])) {
- return 1;
- } else {
- return 0;
- }
-}
-
-QueryData genModelSpecificRegister(QueryContext &context) {
- QueryData results;
-
- struct dirent **entries = nullptr;
- int num_entries = scandir("/dev/cpu", &entries, msrScandirFilter, 0);
- if (num_entries < 1) {
- LOG(WARNING) << "No msr information check msr kernel module is enabled.";
- return results;
- }
- while (num_entries--) {
- getModelSpecificRegisterData(results, atoi(entries[num_entries]->d_name));
- free(entries[num_entries]);
- }
- free(entries);
-
- return results;
-}
-}
-}
+++ /dev/null
-/*
- * Copyright (c) 2014, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
- *
- */
-
-#include <mntent.h>
-#include <sys/vfs.h>
-
-#include <osquery/core.h>
-#include <osquery/filesystem.h>
-#include <osquery/tables.h>
-
-namespace osquery {
-namespace tables {
-
-QueryData genMounts(QueryContext &context) {
- QueryData results;
- FILE *mounts;
- struct mntent *ent;
- char real_path[PATH_MAX];
- struct statfs st;
-
- if ((mounts = setmntent("/proc/mounts", "r"))) {
- while ((ent = getmntent(mounts))) {
- Row r;
-
- r["device"] = std::string(ent->mnt_fsname);
- r["device_alias"] = std::string(
- realpath(ent->mnt_fsname, real_path) ? real_path : ent->mnt_fsname);
- r["path"] = std::string(ent->mnt_dir);
- r["type"] = std::string(ent->mnt_type);
- r["flags"] = std::string(ent->mnt_opts);
- if (!statfs(ent->mnt_dir, &st)) {
- r["blocks_size"] = BIGINT(st.f_bsize);
- r["blocks"] = BIGINT(st.f_blocks);
- r["blocks_free"] = BIGINT(st.f_bfree);
- r["blocks_available"] = BIGINT(st.f_bavail);
- r["inodes"] = BIGINT(st.f_files);
- r["inodes_free"] = BIGINT(st.f_ffree);
- }
-
- results.push_back(r);
- }
- endmntent(mounts);
- }
-
- return results;
-}
-}
-}
+++ /dev/null
-/*
- * Copyright (c) 2014, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
- *
- */
-
-#include <string>
-
-#include <boost/regex.hpp>
-#include <boost/xpressive/xpressive.hpp>
-
-#include <osquery/filesystem.h>
-#include <osquery/sql.h>
-#include <osquery/tables.h>
-
-namespace xp = boost::xpressive;
-
-namespace osquery {
-namespace tables {
-
-const std::string kLinuxOSRelease = "/etc/redhat-release";
-const std::string kLinuxOSRegex =
- "(?P<name>\\w+) .* "
- "(?P<major>[0-9]+)\\.(?P<minor>[0-9]+)[\\.]{0,1}(?P<patch>[0-9]+).*";
-
-QueryData genOSVersion(QueryContext& context) {
- std::string content;
- if (!readFile(kLinuxOSRelease, content).ok()) {
- return {};
- }
-
- Row r;
- auto rx = xp::sregex::compile(kLinuxOSRegex);
- xp::smatch matches;
- for (const auto& line : osquery::split(content, "\n")) {
- if (xp::regex_search(line, matches, rx)) {
- r["major"] = INTEGER(matches["major"]);
- r["minor"] = INTEGER(matches["minor"]);
- r["patch"] =
- (matches["patch"].length() > 0) ? INTEGER(matches["patch"]) : "0";
- r["name"] = matches["name"];
- break;
- }
- }
-
- // No build name.
- r["build"] = "";
- return {r};
-}
-}
-}
+++ /dev/null
-/*
- * Copyright (c) 2014, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
- *
- */
-
-#include <boost/algorithm/string/split.hpp>
-#include <boost/algorithm/string/trim.hpp>
-
-#include <osquery/core.h>
-#include <osquery/logger.h>
-#include <osquery/tables.h>
-
-#include "osquery/events/linux/udev.h"
-
-namespace osquery {
-namespace tables {
-
-const std::string kPCIKeySlot = "PCI_SLOT_NAME";
-const std::string kPCIKeyClass = "ID_PCI_CLASS_FROM_DATABASE";
-const std::string kPCIKeyVendor = "ID_VENDOR_FROM_DATABASE";
-const std::string kPCIKeyModel = "ID_MODEL_FROM_DATABASE";
-const std::string kPCIKeyID = "PCI_ID";
-const std::string kPCIKeyDriver = "DRIVER";
-
-QueryData genPCIDevices(QueryContext &context) {
- QueryData results;
-
- auto udev_handle = udev_new();
- if (udev_handle == nullptr) {
- VLOG(1) << "Could not get udev handle.";
- return results;
- }
-
- // Perform enumeration/search.
- auto enumerate = udev_enumerate_new(udev_handle);
- udev_enumerate_add_match_subsystem(enumerate, "pci");
- udev_enumerate_scan_devices(enumerate);
-
- // Get list entries and iterate over entries.
- struct udev_list_entry *device_entries, *entry;
- device_entries = udev_enumerate_get_list_entry(enumerate);
-
- udev_list_entry_foreach(entry, device_entries) {
- const char *path = udev_list_entry_get_name(entry);
- auto device = udev_device_new_from_syspath(udev_handle, path);
-
- Row r;
- r["pci_slot"] = UdevEventPublisher::getValue(device, kPCIKeySlot);
- r["pci_class"] = UdevEventPublisher::getValue(device, kPCIKeyClass);
- r["driver"] = UdevEventPublisher::getValue(device, kPCIKeyDriver);
- r["vendor"] = UdevEventPublisher::getValue(device, kPCIKeyVendor);
- r["model"] = UdevEventPublisher::getValue(device, kPCIKeyModel);
-
- // VENDOR:MODEL ID is in the form of HHHH:HHHH.
- std::vector<std::string> ids;
- auto device_id = UdevEventPublisher::getValue(device, kPCIKeyID);
- boost::split(ids, device_id, boost::is_any_of(":"));
- if (ids.size() == 2) {
- r["vendor_id"] = ids[0];
- r["model_id"] = ids[1];
- }
-
- // Set invalid vendor/model IDs to 0.
- if (r["vendor_id"].size() == 0) {
- r["vendor_id"] = "0";
- }
-
- if (r["model_id"].size() == 0) {
- r["model_id"] = "0";
- }
-
- results.push_back(r);
- udev_device_unref(device);
- }
-
- // Drop references to udev structs.
- udev_enumerate_unref(enumerate);
- udev_unref(udev_handle);
-
- return results;
-}
-}
-}
+++ /dev/null
-/*
- * Copyright (c) 2014, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
- *
- */
-
-#include <osquery/core.h>
-#include <osquery/logger.h>
-#include <osquery/tables.h>
-#include <osquery/filesystem.h>
-
-namespace osquery {
-namespace tables {
-
-void genDescriptors(const std::string& process,
- const std::map<std::string, std::string>& descriptors,
- QueryData& results) {
- for (const auto& fd : descriptors) {
- if (fd.second.find("socket:") != std::string::npos ||
- fd.second.find("anon_inode:") != std::string::npos ||
- fd.second.find("pipe:") != std::string::npos) {
- // This is NOT a vnode/file descriptor.
- continue;
- }
-
- Row r;
- r["pid"] = process;
- r["fd"] = fd.first;
- r["path"] = fd.second;
- results.push_back(r);
- }
-
- return;
-}
-
-QueryData genOpenFiles(QueryContext& context) {
- QueryData results;
-
- std::set<std::string> pids;
- if (context.constraints["pid"].exists(EQUALS)) {
- pids = context.constraints["pid"].getAll(EQUALS);
- } else {
- osquery::procProcesses(pids);
- }
-
- for (const auto& process : pids) {
- std::map<std::string, std::string> descriptors;
- if (osquery::procDescriptors(process, descriptors).ok()) {
- genDescriptors(process, descriptors, results);
- }
- }
-
- return results;
-}
-}
-}
+++ /dev/null
-/*
- * Copyright (c) 2014, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
- *
- */
-
-#include <sys/shm.h>
-#include <pwd.h>
-
-#include <osquery/core.h>
-#include <osquery/filesystem.h>
-#include <osquery/logger.h>
-#include <osquery/tables.h>
-
-namespace osquery {
-namespace tables {
-
-struct shm_info {
- int used_ids;
- unsigned long shm_tot;
- unsigned long shm_rss;
- unsigned long shm_swp;
- unsigned long swap_attempts;
- unsigned long swap_successes;
-} __attribute__((unused));
-
-QueryData genSharedMemory(QueryContext &context) {
- QueryData results;
-
- // Use shared memory control (shmctl) to get the max SHMID.
- struct shm_info shm_info;
- int maxid = shmctl(0, SHM_INFO, (struct shmid_ds *)(void *)&shm_info);
- if (maxid < 0) {
- VLOG(1) << "Linux kernel not configured for shared memory";
- return {};
- }
-
- // Use a static pointer to access IPC permissions structure.
- struct shmid_ds shmseg;
- struct ipc_perm *ipcp = &shmseg.shm_perm;
-
- // Then iterate each shared memory ID up to the max.
- for (int id = 0; id <= maxid; id++) {
- int shmid = shmctl(id, SHM_STAT, &shmseg);
- if (shmid < 0) {
- continue;
- }
-
- Row r;
- r["shmid"] = INTEGER(shmid);
-
- struct passwd *pw = getpwuid(shmseg.shm_perm.uid);
- if (pw != nullptr) {
- r["owner_uid"] = BIGINT(pw->pw_uid);
- }
-
- pw = getpwuid(shmseg.shm_perm.cuid);
- if (pw != nullptr) {
- r["creator_uid"] = BIGINT(pw->pw_uid);
- }
-
- // Accessor, creator pids.
- r["pid"] = BIGINT(shmseg.shm_lpid);
- r["creator_pid"] = BIGINT(shmseg.shm_cpid);
-
- // Access, detached, creator times
- r["atime"] = BIGINT(shmseg.shm_atime);
- r["dtime"] = BIGINT(shmseg.shm_dtime);
- r["ctime"] = BIGINT(shmseg.shm_ctime);
-
- r["permissions"] = lsperms(ipcp->mode);
- r["size"] = BIGINT(shmseg.shm_segsz);
- r["attached"] = INTEGER(shmseg.shm_nattch);
- r["status"] = (ipcp->mode & SHM_DEST) ? "dest" : "";
- r["locked"] = (ipcp->mode & SHM_LOCKED) ? "1" : "0";
-
- results.push_back(r);
- }
-
- return results;
-}
-}
-}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright (c) 2014, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
- *
- */
-
-#include <osquery/core.h>
-#include <osquery/filesystem.h>
-#include <osquery/logger.h>
-#include <osquery/tables.h>
-
-#include "osquery/tables/system/smbios_utils.h"
-
-namespace osquery {
-namespace tables {
-
-#define kLinuxSMBIOSRawAddress_ 0xF0000
-#define kLinuxSMBIOSRawLength_ 0x10000
-
-const std::string kLinuxEFISystabPath = "/sys/firmware/efi/systab";
-const std::string kLinuxLegacyEFISystabPath = "/proc/efi/systab";
-
-void genSMBIOSFromDMI(size_t base, size_t length, QueryData& results) {
- // Linux will expose the SMBIOS/DMI entry point structures, which contain
- // a member variable with the DMI tables start address and size.
- // This applies to both the EFI-variable and physical memory search.
- uint8_t* data;
- auto status = osquery::readRawMem(base, length, (void**)&data);
- if (!status.ok()) {
- VLOG(1) << "Could not read DMI tables memory";
- return;
- }
-
- // Attempt to parse tables from allocated data.
- genSMBIOSTables(data, length, results);
- free(data);
-}
-
-void genEFISystabTables(QueryData& results) {
- // Not yet supported.
- return;
-}
-
-void genRawSMBIOSTables(QueryData& results) {
- uint8_t* data;
- auto status = osquery::readRawMem(
- kLinuxSMBIOSRawAddress_, kLinuxSMBIOSRawLength_, (void**)&data);
- if (!status.ok()) {
- VLOG(1) << "Could not read SMBIOS memory";
- return;
- }
-
- // Search for the SMBIOS/DMI tables magic header string.
- size_t offset;
- for (offset = 0; offset <= 0xFFF0; offset += 16) {
- // Could look for "_SM_" for the SMBIOS header, but the DMI header exists
- // in both SMBIOS and the legacy DMI spec.
- if (memcmp(data + offset, "_DMI_", 5) == 0) {
- auto dmi_data = (DMIEntryPoint*)(data + offset);
- genSMBIOSFromDMI(dmi_data->tableAddress, dmi_data->tableLength, results);
- }
- }
-
- free(data);
-}
-
-QueryData genSMBIOSTables(QueryContext& context) {
- QueryData results;
-
- if (osquery::isReadable(kLinuxEFISystabPath).ok() ||
- osquery::isReadable(kLinuxLegacyEFISystabPath).ok()) {
- genEFISystabTables(results);
- } else {
- genRawSMBIOSTables(results);
- }
-
- return results;
-}
-}
-}
+++ /dev/null
-/*
- * Copyright (c) 2014, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
- *
- */
-
-#include <sys/sysctl.h>
-
-#include <boost/algorithm/string/trim.hpp>
-
-#include <osquery/filesystem.h>
-#include <osquery/tables.h>
-
-#include "osquery/tables/system/sysctl_utils.h"
-
-namespace fs = boost::filesystem;
-
-namespace osquery {
-namespace tables {
-
-const std::string kSystemControlPath = "/proc/sys/";
-
-void genControlInfo(const std::string& mib_path, QueryData& results,
- const std::map<std::string, std::string>& config) {
- if (isDirectory(mib_path).ok()) {
- // Iterate through the subitems and items.
- std::vector<std::string> items;
- if (listDirectoriesInDirectory(mib_path, items).ok()) {
- for (const auto& item : items) {
- genControlInfo(item, results, config);
- }
- }
-
- if (listFilesInDirectory(mib_path, items).ok()) {
- for (const auto& item : items) {
- genControlInfo(item, results, config);
- }
- }
- return;
- }
-
- // This is a file (leaf-control).
- Row r;
- r["name"] = mib_path.substr(kSystemControlPath.size());
-
- std::replace(r["name"].begin(), r["name"].end(), '/', '.');
- // No known way to convert name MIB to int array.
- r["subsystem"] = osquery::split(r.at("name"), ".")[0];
-
- if (isReadable(mib_path).ok()) {
- std::string content;
- readFile(mib_path, content);
- boost::trim(content);
- r["current_value"] = content;
- }
-
- if (config.count(r.at("name")) > 0) {
- r["config_value"] = config.at(r.at("name"));
- }
- r["type"] = "string";
- results.push_back(r);
-}
-
-void genControlInfo(int* oid,
- size_t oid_size,
- QueryData& results,
- const std::map<std::string, std::string>& config) {
- // Get control size
- size_t response_size = CTL_MAX_VALUE;
- char response[CTL_MAX_VALUE + 1] = {0};
- if (sysctl(oid, oid_size, response, &response_size, 0, 0) != 0) {
- // Cannot request MIB data.
- return;
- }
-
- // Data is output, but no way to determine type (long, int, string, struct).
- Row r;
- r["oid"] = stringFromMIB(oid, oid_size);
- r["current_value"] = std::string(response);
- r["type"] = "string";
- results.push_back(r);
-}
-
-void genAllControls(QueryData& results,
- const std::map<std::string, std::string>& config,
- const std::string& subsystem) {
- // Linux sysctl subsystems are directories in /proc
- std::vector<std::string> subsystems;
- if (!listDirectoriesInDirectory("/proc/sys", subsystems).ok()) {
- return;
- }
-
- for (const auto& sub : subsystems) {
- if (subsystem.size() != 0 &&
- fs::path(sub).filename().string() != subsystem) {
- // Request is limiting subsystem.
- continue;
- }
- genControlInfo(sub, results, config);
- }
-}
-
-void genControlInfoFromName(const std::string& name, QueryData& results,
- const std::map<std::string, std::string>& config) {
- // Convert '.'-tokenized name to path.
- std::string name_path = name;
- std::replace(name_path.begin(), name_path.end(), '.', '/');
- auto mib_path = fs::path(kSystemControlPath) / name_path;
-
- genControlInfo(mib_path.string(), results, config);
-}
-}
-}
+++ /dev/null
-/*
- * Copyright (c) 2014, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
- *
- */
-
-#include <osquery/core.h>
-#include <osquery/logger.h>
-#include <osquery/tables.h>
-
-#include "osquery/events/linux/udev.h"
-
-namespace osquery {
-namespace tables {
-
-const std::string kUSBKeyVendorID = "ID_VENDOR_ID";
-const std::string kUSBKeyVendor = "ID_VENDOR_FROM_DATABASE";
-const std::string kUSBKeyModelID = "ID_MODEL_ID";
-const std::string kUSBKeyModel = "ID_MODEL_FROM_DATABASE";
-const std::string kUSBKeyDriver = "ID_USB_DRIVER";
-const std::string kUSBKeySubsystem = "SUBSYSTEM";
-const std::string kUSBKeySerial = "ID_SERIAL_SHORT";
-const std::string kUSBKeyAddress = "BUSNUM";
-const std::string kUSBKeyPort = "DEVNUM";
-
-QueryData genUSBDevices(QueryContext &context) {
- QueryData results;
-
- auto udev_handle = udev_new();
- if (udev_handle == nullptr) {
- VLOG(1) << "Could not get udev handle.";
- return results;
- }
-
- // Perform enumeration/search.
- auto enumerate = udev_enumerate_new(udev_handle);
- udev_enumerate_add_match_subsystem(enumerate, "usb");
- udev_enumerate_scan_devices(enumerate);
-
- // Get list entries and iterate over entries.
- struct udev_list_entry *device_entries, *entry;
- device_entries = udev_enumerate_get_list_entry(enumerate);
-
- udev_list_entry_foreach(entry, device_entries) {
- const char *path = udev_list_entry_get_name(entry);
- auto device = udev_device_new_from_syspath(udev_handle, path);
-
- Row r;
- // r["driver"] = UdevEventPublisher::getValue(device, kUSBKeyDriver);
- r["vendor"] = UdevEventPublisher::getValue(device, kUSBKeyVendor);
- r["model"] = UdevEventPublisher::getValue(device, kUSBKeyModel);
-
- // USB-specific vendor/model ID properties.
- r["model_id"] = UdevEventPublisher::getValue(device, kUSBKeyModelID);
- r["vendor_id"] = UdevEventPublisher::getValue(device, kUSBKeyVendorID);
- r["serial"] = UdevEventPublisher::getValue(device, kUSBKeySerial);
-
- // Address/port accessors.
- r["usb_address"] = UdevEventPublisher::getValue(device, kUSBKeyAddress);
- r["usb_port"] = UdevEventPublisher::getValue(device, kUSBKeyPort);
-
- // Removable detection.
- auto removable = UdevEventPublisher::getAttr(device, "removable");
- if (removable == "unknown") {
- r["removable"] = "-1";
- } else {
- r["removable"] = "1";
- }
-
- if (r["usb_address"].size() > 0 && r["usb_port"].size() > 0) {
- results.push_back(r);
- }
- udev_device_unref(device);
- }
-
- // Drop references to udev structs.
- udev_enumerate_unref(enumerate);
- udev_unref(udev_handle);
-
- return results;
-}
-}
-}
+++ /dev/null
-/*
- * Copyright (c) 2014, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
- *
- */
-
-#include <mutex>
-
-#include <osquery/core.h>
-#include <osquery/tables.h>
-
-#include <utmpx.h>
-
-namespace osquery {
-namespace tables {
-
-std::mutex utmpxEnumerationMutex;
-
-QueryData genLoggedInUsers(QueryContext& context) {
- std::lock_guard<std::mutex> lock(utmpxEnumerationMutex);
- QueryData results;
- struct utmpx *entry = nullptr;
-
- while ((entry = getutxent()) != nullptr) {
- if (entry->ut_pid == 1) {
- continue;
- }
- Row r;
- r["user"] = TEXT(entry->ut_user);
- r["tty"] = TEXT(entry->ut_line);
- r["host"] = TEXT(entry->ut_host);
- r["time"] = INTEGER(entry->ut_tv.tv_sec);
- r["pid"] = INTEGER(entry->ut_pid);
- results.push_back(r);
- }
- endutxent();
-
- return results;
-}
-}
-}
+++ /dev/null
-/*
- * Copyright (c) 2014, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
- *
- */
-
-#include <string>
-#include <vector>
-
-#include <pwd.h>
-
-#include <osquery/core.h>
-#include <osquery/tables.h>
-#include <osquery/filesystem.h>
-#include <osquery/logger.h>
-#include <osquery/sql.h>
-
-namespace osquery {
-namespace tables {
-
-const std::vector<std::string> kShellHistoryFiles = {
- ".bash_history", ".zsh_history", ".zhistory", ".history",
-};
-
-void genShellHistoryForUser(const std::string& username,
- const std::string& directory,
- QueryData& results) {
- for (const auto& hfile : kShellHistoryFiles) {
- boost::filesystem::path history_file = directory;
- history_file /= hfile;
-
- std::string history_content;
- if (!readFile(history_file, history_content).ok()) {
- // Cannot read a specific history file.
- continue;
- }
-
- for (const auto& line : split(history_content, "\n")) {
- Row r;
- r["username"] = username;
- r["command"] = line;
- r["history_file"] = history_file.string();
- results.push_back(r);
- }
- }
-}
-
-QueryData genShellHistory(QueryContext& context) {
- QueryData results;
-
- // Select only the home directory for this user.
- QueryData users;
- if (!context.constraints["username"].exists(EQUALS)) {
- users =
- SQL::selectAllFrom("users", "uid", EQUALS, std::to_string(getuid()));
- } else {
- auto usernames = context.constraints["username"].getAll(EQUALS);
- for (const auto& username : usernames) {
- // Use a predicated select all for each user.
- auto user = SQL::selectAllFrom("users", "username", EQUALS, username);
- users.insert(users.end(), user.begin(), user.end());
- }
- }
-
- // Iterate over each user
- for (const auto& row : users) {
- if (row.count("username") > 0 && row.count("directory") > 0) {
- genShellHistoryForUser(row.at("username"), row.at("directory"), results);
- }
- }
-
- return results;
-}
-}
-}
+++ /dev/null
-/*
- * Copyright (c) 2014, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
- *
- */
-
-#include <osquery/hash.h>
-
-#include "osquery/tables/system/smbios_utils.h"
-
-namespace osquery {
-namespace tables {
-
-const std::map<int, std::string> kSMBIOSTypeDescriptions = {
- {0, "BIOS Information"},
- {1, "System Information"},
- {2, "Base Board or Module Information"},
- {3, "System Enclosure or Chassis"},
- {4, "Processor Information"},
- {5, "Memory Controller Information"},
- {6, "Memory Module Information"},
- {7, "Cache Information"},
- {8, "Port Connector Information"},
- {9, "System Slots"},
- {10, "On Board Devices Information"},
- {11, "OEM Strings"},
- {12, "System Configuration Options"},
- {13, "BIOS Language Information"},
- {14, "Group Associations"},
- {15, "System Event Log"},
- {16, "Physical Memory Array"},
- {17, "Memory Device"},
- {18, "32-bit Memory Error Information"},
- {19, "Memory Array Mapped Address"},
- {20, "Memory Device Mapped Address"},
- {21, "Built-in Pointing Device"},
- {22, "Portable Battery"},
- {23, "System Reset"},
- {24, "Hardware Security"},
- {25, "System Power Controls"},
- {26, "Voltage Probe"},
- {27, "Cooling Device"},
- {28, "Temperature Probe"},
- {29, "Electrical Current Probe"},
- {30, "Out-of-Band Remote Access"},
- {31, "Boot Integrity Services"},
- {32, "System Boot Information"},
- {33, "64-bit Memory Error Information"},
- {34, "Management Device"},
- {35, "Management Device Component"},
- {36, "Management Device Threshold Data"},
- {37, "Memory Channel"},
- {38, "IPMI Device Information"},
- {39, "System Power Supply"},
- {40, "Additional Information"},
- {41, "Onboard Devices Extended Info"},
- {126, "Inactive"},
- {127, "End-of-Table"},
- {130, "Memory SPD Data"},
- {131, "OEM Processor Type"},
- {132, "OEM Processor Bus Speed"},
-};
-
-void genSMBIOSTables(const uint8_t* tables, size_t length, QueryData& results) {
- // Keep a pointer to the end of the SMBIOS data for comparison.
- auto tables_end = tables + length;
- auto table = tables;
-
- // Iterate through table structures within SMBIOS data range.
- size_t index = 0;
- while (table + sizeof(SMBStructHeader) <= tables_end) {
- auto header = (const SMBStructHeader*)table;
- if (table + header->length > tables_end) {
- // Invalid header, length must be within SMBIOS data range.
- break;
- }
-
- Row r;
- // The index is a supliment that keeps track of table order.
- r["number"] = INTEGER(index++);
- r["type"] = INTEGER((unsigned short)header->type);
- if (kSMBIOSTypeDescriptions.count(header->type) > 0) {
- r["description"] = kSMBIOSTypeDescriptions.at(header->type);
- }
-
- r["handle"] = BIGINT((unsigned long long)header->handle);
- r["header_size"] = INTEGER((unsigned short)header->length);
-
- // The SMBIOS structure may have unformatted, double-NULL delimited trailing
- // data, which are usually strings.
- auto next_table = table + header->length;
- for (; next_table + sizeof(SMBStructHeader) <= tables_end; next_table++) {
- if (next_table[0] == 0 && next_table[1] == 0) {
- next_table += 2;
- break;
- }
- }
-
- auto table_length = next_table - table;
- r["size"] = INTEGER(table_length);
- r["md5"] = hashFromBuffer(HASH_TYPE_MD5, table, table_length);
-
- table = next_table;
- results.push_back(r);
- }
-}
-}
-}
+++ /dev/null
-/*
- * Copyright (c) 2014, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
- *
- */
-
-#include <osquery/tables.h>
-
-namespace osquery {
-namespace tables {
-
-typedef struct SMBStructHeader {
- uint8_t type;
- uint8_t length;
- uint16_t handle;
-} __attribute__((packed)) SMBStructHeader;
-
-typedef struct DMIEntryPoint {
- uint8_t anchor[5];
- uint8_t checksum;
- uint16_t tableLength;
- uint32_t tableAddress;
- uint16_t structureCount;
- uint8_t bcdRevision;
-} __attribute__((packed)) DMIEntryPoint;
-
-extern const std::map<int, std::string> kSMBIOSTypeDescriptions;
-
-void genSMBIOSTables(const uint8_t* tables, size_t length, QueryData& results);
-}
-}
+++ /dev/null
-/*
- * Copyright (c) 2014, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
- *
- */
-
-#include <pwd.h>
-#include <grp.h>
-#include <sys/stat.h>
-
-#include <boost/filesystem.hpp>
-
-#include <osquery/filesystem.h>
-#include <osquery/logger.h>
-#include <osquery/tables.h>
-
-namespace fs = boost::filesystem;
-
-namespace osquery {
-namespace tables {
-
-std::vector<std::string> kBinarySearchPaths = {
- "/bin",
- "/sbin",
- "/usr/bin",
- "/usr/sbin",
- "/usr/local/bin",
- "/usr/local/sbin",
- "/tmp",
-};
-
-Status genBin(const fs::path& path, int perms, QueryData& results) {
- struct stat info;
- // store user and group
- if (stat(path.c_str(), &info) != 0) {
- return Status(1, "stat failed");
- }
-
- // store path
- Row r;
- r["path"] = path.string();
- struct passwd *pw = getpwuid(info.st_uid);
- struct group *gr = getgrgid(info.st_gid);
-
- // get user name + group
- std::string user;
- if (pw != nullptr) {
- user = std::string(pw->pw_name);
- } else {
- user = boost::lexical_cast<std::string>(info.st_uid);
- }
-
- std::string group;
- if (gr != nullptr) {
- group = std::string(gr->gr_name);
- } else {
- group = boost::lexical_cast<std::string>(info.st_gid);
- }
-
- r["username"] = user;
- r["groupname"] = group;
-
- r["permissions"] = "";
- if ((perms & 04000) == 04000) {
- r["permissions"] += "S";
- }
-
- if ((perms & 02000) == 02000) {
- r["permissions"] += "G";
- }
-
- results.push_back(r);
- return Status(0, "OK");
-}
-
-bool isSuidBin(const fs::path& path, int perms) {
- if (!fs::is_regular_file(path)) {
- return false;
- }
-
- if ((perms & 04000) == 04000 || (perms & 02000) == 02000) {
- return true;
- }
- return false;
-}
-
-void genSuidBinsFromPath(const std::string& path, QueryData& results) {
- if (!pathExists(path).ok()) {
- // Creating an iterator on a missing path will except.
- return;
- }
-
- auto it = fs::recursive_directory_iterator(fs::path(path));
- fs::recursive_directory_iterator end;
- while (it != end) {
- fs::path path = *it;
- try {
- // Do not traverse symlinked directories.
- if (fs::is_directory(path) && fs::is_symlink(path)) {
- it.no_push();
- }
-
- int perms = it.status().permissions();
- if (isSuidBin(path, perms)) {
- // Only emit suid bins.
- genBin(path, perms, results);
- }
-
- ++it;
- } catch (fs::filesystem_error& e) {
- VLOG(1) << "Cannot read binary from " << path;
- it.no_push();
- // Try to recover, otherwise break.
- try { ++it; } catch(fs::filesystem_error& e) { break; }
- }
- }
-}
-
-QueryData genSuidBin(QueryContext& context) {
- QueryData results;
-
- // Todo: add hidden column to select on that triggers non-std path searches.
- for (const auto& path : kBinarySearchPaths) {
- genSuidBinsFromPath(path, results);
- }
-
- return results;
-}
-}
-}
+++ /dev/null
-/*
- * Copyright (c) 2014, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
- *
- */
-
-#include <sys/sysctl.h>
-
-#include <osquery/tables.h>
-
-namespace osquery {
-namespace tables {
-
-#define CTL_MAX_VALUE 128
-
-#ifndef CTL_DEBUG_MAXID
-#define CTL_DEBUG_MAXID (CTL_MAXNAME * 2)
-#endif
-
-std::string stringFromMIB(const int* oid, size_t oid_size);
-
-/// Must be implemented by the platform.
-void genAllControls(QueryData& results,
- const std::map<std::string, std::string>& config,
- const std::string& subsystem);
-
-/// Must be implemented by the platform.
-void genControlInfo(int* oid,
- size_t oid_size,
- QueryData& results,
- const std::map<std::string, std::string>& config);
-
-/// Must be implemented by the platform.
-void genControlInfoFromName(const std::string& name, QueryData& results,
- const std::map<std::string, std::string>& config);
-}
-}
+++ /dev/null
-/*
- * Copyright (c) 2014, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
- *
- */
-
-#include <boost/algorithm/string/trim.hpp>
-
-#include <osquery/filesystem.h>
-#include <osquery/tables.h>
-
-#include "osquery/tables/system/sysctl_utils.h"
-
-namespace osquery {
-namespace tables {
-
-const std::vector<std::string> kControlSettingsFiles = {"/etc/sysctl.conf"};
-
-const std::vector<std::string> kControlSettingsDirs = {
- "/run/sysctl.d/%.conf",
- "/etc/sysctl.d/%.conf",
- "/usr/local/lib/sysctl.d/%.conf",
- "/usr/lib/sysctl.d/%.conf",
- "/lib/sysctl.d/%.conf",
-};
-
-std::string stringFromMIB(const int* oid, size_t oid_size) {
- std::string result;
- for (size_t i = 0; i < oid_size; ++i) {
- // Walk an int-encoded MIB and return the string representation, '.'.
- if (result.size() > 0) {
- result += ".";
- }
- result += std::to_string(oid[i]);
- }
- return result;
-}
-
-void genControlInfoFromOIDString(
- const std::string& oid_string,
- QueryData& results,
- const std::map<std::string, std::string>& config) {
- int request[CTL_DEBUG_MAXID + 2] = {0};
- auto tokens = osquery::split(oid_string, ".");
- if (tokens.size() > CTL_DEBUG_MAXID) {
- // OID input string was too large.
- return;
- }
-
- // Convert the string into an int array.
- for (size_t i = 0; i < tokens.size(); ++i) {
- request[i] = atol(tokens.at(i).c_str());
- }
- genControlInfo((int*)request, tokens.size(), results, config);
-}
-
-void genControlConfigFromPath(const std::string& path,
- std::map<std::string, std::string>& config) {
- std::string content;
- if (!osquery::readFile(path, content).ok()) {
- return;
- }
-
- for (auto& line : split(content, "\n")) {
- boost::trim(line);
- if (line[0] == '#' || line[0] == ';') {
- continue;
- }
-
- // Try to tokenize the config line using '='.
- auto detail = split(line, "=");
- if (detail.size() == 2) {
- boost::trim(detail[0]);
- boost::trim(detail[1]);
- config[detail[0]] = detail[1];
- }
- }
-}
-
-QueryData genSystemControls(QueryContext& context) {
- QueryData results;
-
- // Read the sysctl.conf values.
- std::map<std::string, std::string> config;
- for (const auto& path : kControlSettingsFiles) {
- genControlConfigFromPath(path, config);
- }
-
- for (const auto& dirs : kControlSettingsDirs) {
- std::vector<std::string> configs;
- if (resolveFilePattern(dirs, configs).ok()) {
- for (const auto& path : configs) {
- genControlConfigFromPath(path, config);
- }
- }
- }
-
- // Iterate through the sysctl-defined macro of control types.
- 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(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(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) {
- genAllControls(results, config, subsystem);
- }
- } else {
- genAllControls(results, config, "");
- }
-
- return results;
-}
-}
-}
+++ /dev/null
-/*
- * Copyright (c) 2014, Facebook, Inc.
- * All rights reserved.
- *
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
- *
- */
-
-#include <osquery/tables.h>
-
-#if defined(__APPLE__)
- #include <time.h>
- #include <errno.h>
- #include <sys/sysctl.h>
-#elif defined(__linux__)
- #include <sys/sysinfo.h>
-#endif
-
-namespace osquery {
-namespace tables {
-
-long getUptime() {
- #if defined(__APPLE__)
- struct timeval boot_time;
- size_t len = sizeof(boot_time);
- int mib[2] = {
- CTL_KERN,
- KERN_BOOTTIME
- };
-
- if (sysctl(mib, 2, &boot_time, &len, NULL, 0) < 0) {
- return -1;
- }
-
- time_t seconds_since_boot = boot_time.tv_sec;
- time_t current_seconds = time(NULL);
-
- return long(difftime(current_seconds, seconds_since_boot));
- #elif defined(__linux__)
- struct sysinfo sys_info;
-
- if (sysinfo(&sys_info) != 0) {
- return -1;
- }
-
- return sys_info.uptime;
- #endif
-}
-
-QueryData genUptime(QueryContext& context) {
- Row r;
- QueryData results;
- long uptime_in_seconds = getUptime();
-
- if (uptime_in_seconds >= 0) {
- r["days"] = INTEGER(uptime_in_seconds / 60 / 60 / 24);
- r["hours"] = INTEGER((uptime_in_seconds / 60 / 60) % 24);
- r["minutes"] = INTEGER((uptime_in_seconds / 60) % 60);
- r["seconds"] = INTEGER(uptime_in_seconds % 60);
- r["total_seconds"] = BIGINT(uptime_in_seconds);
- results.push_back(r);
- }
-
- return results;
-}
-}
-}
--- /dev/null
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+/*
+ * @file bluetooth_policy.cpp
+ * @author Sangwan Kwon (sangwan.kwon@samsung.com)
+ * @brief Implementation of bluetooth_policy table
+ */
+
+#include <string>
+#include <memory>
+#include <stdexcept>
+
+#include <osquery/sql.h>
+#include <osquery/logger.h>
+#include <osquery/tables.h>
+
+#include <dpm/device-policy-manager.h>
+#include <dpm/pil/policy-client.h>
+
+namespace osquery {
+namespace tables {
+
+QueryData genBluetoothPolicy(QueryContext& context) try {
+ std::shared_ptr<void> handle(dpm_manager_create(), dpm_manager_destroy);
+ if (handle == nullptr)
+ throw std::runtime_error("Cannot create dpm-client handle.");
+
+ /// This status is defined at DPM
+ ::Status<bool> status { true };
+ Row r;
+
+ DevicePolicyClient &client = GetDevicePolicyClient(handle.get());
+ status = client.methodCall<bool>("Bluetooth::getModeChangeState");
+ r["mode_change_state"] = INTEGER(status.get());
+
+ status = client.methodCall<bool>("Bluetooth::getDesktopConnectivityState");
+ r["desktop_connectivity_state"] = INTEGER(status.get());
+
+ status = client.methodCall<bool>("Bluetooth::getTetheringState");
+ r["tethering_state"] = INTEGER(status.get());
+
+ status = client.methodCall<bool>("Bluetooth::getPairingState");
+ r["paring_state"] = INTEGER(status.get());
+
+ return { r };
+} catch (...) {
+// TODO(Sangwan): Resolve duplicated "ERROR" macro with DPM
+// LOG(ERROR) << "Exception occured";
+ Row r;
+ return { r };
+}
+
+} // namespace tables
+} // namespace osquery
--- /dev/null
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+#include <gtest/gtest.h>
+
+#include <osquery/sql.h>
+#include <osquery/logger.h>
+
+#include <dpm/device-policy-manager.h>
+#include <dpm/pil/policy-client.h>
+
+class PolicyTests : public testing::Test {};
+
+using namespace osquery;
+
+TEST_F(PolicyTests, Bluetooth) {
+ std::shared_ptr<void> handle(dpm_manager_create(), dpm_manager_destroy);
+ if (handle == nullptr)
+ throw std::runtime_error("Cannot create dpm-client handle.");
+
+ ::Status<bool> status { true };
+
+ DevicePolicyClient &client = GetDevicePolicyClient(handle.get());
+ status = client.methodCall<bool>("Bluetooth::getModeChangeState");
+ EXPECT_EQ(true, status.get());
+
+ status = client.methodCall<bool>("Bluetooth::getDesktopConnectivityState");
+ EXPECT_EQ(true, status.get());
+
+ status = client.methodCall<bool>("Bluetooth::getTetheringState");
+ EXPECT_EQ(true, status.get());
+
+ status = client.methodCall<bool>("Bluetooth::getPairingState");
+ EXPECT_EQ(true, status.get());
+}
+
+TEST_F(PolicyTests, Wifi) {
+ std::shared_ptr<void> handle(dpm_manager_create(), dpm_manager_destroy);
+ if (handle == nullptr)
+ throw std::runtime_error("Cannot create dpm-client handle.");
+
+ ::Status<bool> status { true };
+
+ DevicePolicyClient &client = GetDevicePolicyClient(handle.get());
+ status = client.methodCall<bool>("Wifi::getState");
+ EXPECT_EQ(true, status.get());
+
+ status = client.methodCall<bool>("Wifi::isProfileChangeRestricted");
+ EXPECT_EQ(true, status.get());
+
+ status = client.methodCall<bool>("Wifi::getHotspotState");
+ EXPECT_EQ(true, status.get());
+}
+
+TEST_F(PolicyTests, Usb) {
+ std::shared_ptr<void> handle(dpm_manager_create(), dpm_manager_destroy);
+ if (handle == nullptr)
+ throw std::runtime_error("Cannot create dpm-client handle.");
+
+ ::Status<bool> status { true };
+
+ DevicePolicyClient &client = GetDevicePolicyClient(handle.get());
+ status = client.methodCall<bool>("Usb::getDebuggingState");
+ EXPECT_EQ(true, status.get());
+
+ status = client.methodCall<bool>("Usb::getTetheringState");
+ EXPECT_EQ(true, status.get());
+
+ status = client.methodCall<bool>("Usb::getClientState");
+ EXPECT_EQ(true, status.get());
+}
--- /dev/null
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+/*
+ * @file usb_policy.cpp
+ * @author Sangwan Kwon (sangwan.kwon@samsung.com)
+ * @brief Implementation of usb_policy table
+ */
+
+#include <string>
+#include <memory>
+#include <stdexcept>
+
+#include <osquery/sql.h>
+#include <osquery/logger.h>
+#include <osquery/tables.h>
+
+#include <dpm/device-policy-manager.h>
+#include <dpm/pil/policy-client.h>
+
+namespace osquery {
+namespace tables {
+
+QueryData genUsbPolicy(QueryContext& context) try {
+ std::shared_ptr<void> handle(dpm_manager_create(), dpm_manager_destroy);
+ if (handle == nullptr)
+ throw std::runtime_error("Cannot create dpm-client handle.");
+
+ /// This status is defined at DPM
+ ::Status<bool> status { true };
+ Row r;
+
+ DevicePolicyClient &client = GetDevicePolicyClient(handle.get());
+ status = client.methodCall<bool>("Usb::getDebuggingState");
+ r["usb_debugging"] = INTEGER(status.get());
+
+ status = client.methodCall<bool>("Usb::getTetheringState");
+ r["usb_tethering"] = INTEGER(status.get());
+
+ status = client.methodCall<bool>("Usb::getClientState");
+ r["usb_client"] = INTEGER(status.get());
+
+ return { r };
+} catch (...) {
+// TODO(Sangwan): Resolve duplicated "ERROR" macro with DPM
+ Row r;
+ return { r };
+}
+
+} // namespace tables
+} // namespace osquery
--- /dev/null
+/*
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+/*
+ * @file wifi_policy.cpp
+ * @author Sangwan Kwon (sangwan.kwon@samsung.com)
+ * @brief Implementation of wifi_policy table
+ */
+
+#include <string>
+#include <memory>
+#include <stdexcept>
+
+#include <osquery/sql.h>
+#include <osquery/logger.h>
+#include <osquery/tables.h>
+
+#include <dpm/device-policy-manager.h>
+#include <dpm/pil/policy-client.h>
+
+namespace osquery {
+namespace tables {
+
+QueryData genWifiPolicy(QueryContext& context) try {
+ std::shared_ptr<void> handle(dpm_manager_create(), dpm_manager_destroy);
+ if (handle == nullptr)
+ throw std::runtime_error("Cannot create dpm-client handle.");
+
+ /// This status is defined at DPM
+ ::Status<bool> status { true };
+ Row r;
+
+ DevicePolicyClient &client = GetDevicePolicyClient(handle.get());
+ status = client.methodCall<bool>("Wifi::getState");
+ r["wifi"] = INTEGER(status.get());
+
+ status = client.methodCall<bool>("Wifi::isProfileChangeRestricted");
+ r["wifi_profile_change"] = INTEGER(status.get());
+
+ status = client.methodCall<bool>("Wifi::getHotspotState");
+ r["wifi_hotspot"] = INTEGER(status.get());
+
+ return { r };
+} catch (...) {
+// TODO(Sangwan): Resolve duplicated "ERROR" macro with DPM
+ Row r;
+ return { r };
+}
+
+} // namespace tables
+} // namespace osquery