Remove filesystem
authorSangwan Kwon <sangwan.kwon@samsung.com>
Fri, 24 Apr 2020 05:04:26 +0000 (14:04 +0900)
committer권상완/Security 2Lab(SR)/Engineer/삼성전자 <sangwan.kwon@samsung.com>
Tue, 28 Apr 2020 07:13:55 +0000 (16:13 +0900)
Signed-off-by: Sangwan Kwon <sangwan.kwon@samsung.com>
27 files changed:
specs/processes.table [deleted file]
specs/utility/file.table [deleted file]
src/osquery/CMakeLists.txt
src/osquery/core/init.cpp
src/osquery/core/system.cpp
src/osquery/filesystem/CMakeLists.txt [deleted file]
src/osquery/filesystem/fileops.h [deleted file]
src/osquery/filesystem/filesystem.cpp [deleted file]
src/osquery/filesystem/filesystem.h [deleted file]
src/osquery/filesystem/linux/mem.cpp [deleted file]
src/osquery/filesystem/linux/proc.cpp [deleted file]
src/osquery/filesystem/linux/proc.h [deleted file]
src/osquery/filesystem/mock_file_structure.cpp [deleted file]
src/osquery/filesystem/mock_file_structure.h [deleted file]
src/osquery/filesystem/posix/fileops.cpp [deleted file]
src/osquery/filesystem/tests/fileops.cpp [deleted file]
src/osquery/logger/logger.cpp
src/osquery/logger/plugins/filesystem.cpp [deleted file]
src/osquery/logger/plugins/syslog.cpp [deleted file]
src/osquery/main/main.cpp
src/osquery/sql/virtual_sqlite_table.cpp
src/osquery/tables/system/linux/processes.cpp [deleted file]
src/osquery/tables/utility/file.cpp [deleted file]
src/osquery/tests/test_util.h
src/vist/client/schema/processes.hpp [deleted file]
src/vist/client/tests/virtual-table.cpp
src/vist/client/virtual-table.cpp

diff --git a/specs/processes.table b/specs/processes.table
deleted file mode 100644 (file)
index e07c6ac..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-table_name("processes")
-description("All running processes on the host system.")
-schema([
-    Column("pid", BIGINT, "Process (or thread) ID", index=True),
-    Column("name", TEXT, "The process path or shorthand argv[0]"),
-    Column("path", TEXT, "Path to executed binary"),
-    Column("cmdline", TEXT, "Complete argv"),
-    Column("state", TEXT, "Process state"),
-    Column("cwd", TEXT, "Process current working directory"),
-    Column("root", TEXT, "Process virtual root directory"),
-    Column("uid", BIGINT, "Unsigned user ID"),
-    Column("gid", BIGINT, "Unsigned group ID"),
-    Column("euid", BIGINT, "Unsigned effective user ID"),
-    Column("egid", BIGINT, "Unsigned effective group ID"),
-    Column("suid", BIGINT, "Unsigned saved user ID"),
-    Column("sgid", BIGINT, "Unsigned saved group ID"),
-    Column("on_disk", INTEGER,
-        "The process path exists yes=1, no=0, unknown=-1"),
-    Column("wired_size", BIGINT, "Bytes of unpagable memory used by process"),
-    Column("resident_size", BIGINT, "Bytes of private memory used by process"),
-    Column("total_size", BIGINT, "Total virtual memory size",
-        aliases=["phys_footprint"]),
-    Column("user_time", BIGINT, "CPU time in milliseconds spent in user space"),
-    Column("system_time", BIGINT, "CPU time in milliseconds spent in kernel space"),
-    Column("disk_bytes_read", BIGINT, "Bytes read from disk"),
-    Column("disk_bytes_written", BIGINT, "Bytes written to disk"),
-    Column("start_time", BIGINT, "Process start time in seconds since Epoch, in case of error -1"),
-    Column("parent", BIGINT, "Process parent's PID"),
-    Column("pgroup", BIGINT, "Process group"),
-    Column("threads", INTEGER, "Number of threads used by process"),
-    Column("nice", INTEGER, "Process nice level (-20 to 20, default 0)"),
-])
-extended_schema(WINDOWS, [
-    Column("is_elevated_token", INTEGER, "Process uses elevated token yes=1, no=0"),
-    Column("elapsed_time", BIGINT, "Elapsed time in seconds this process has been running."),
-    Column("handle_count", BIGINT, "Total number of handles that the process has open. This number is the sum of the handles currently opened by each thread in the process."),
-    Column("percent_processor_time", BIGINT, "Returns elapsed time that all of the threads of this process used the processor to execute instructions in 100 nanoseconds ticks."),
-])
-extended_schema(DARWIN, [
-    Column("upid", BIGINT, "A 64bit pid that is never reused. Returns -1 if we couldn't gather them from the system."),
-    Column("uppid", BIGINT, "The 64bit parent pid that is never reused. Returns -1 if we couldn't gather them from the system."),
-    Column("cpu_type", INTEGER, "A 64bit pid that is never reused. Returns -1 if we couldn't gather them from the system."),
-    Column("cpu_subtype", INTEGER, "The 64bit parent pid that is never reused. Returns -1 if we couldn't gather them from the system."),
-])
-attributes(cacheable=True, strongly_typed_rows=True)
-implementation("system/processes@genProcesses")
-examples([
-  "select * from processes where pid = 1",
-])
diff --git a/specs/utility/file.table b/specs/utility/file.table
deleted file mode 100644 (file)
index 43047f3..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-table_name("file")
-description("Interactive filesystem attributes and metadata.")
-schema([
-    Column("path", TEXT, "Absolute file path", required=True, index=True),
-    Column("directory", TEXT, "Directory of file(s)", required=True),
-    Column("filename", TEXT, "Name portion of file path"),
-    Column("inode", BIGINT, "Filesystem inode number"),
-    Column("uid", BIGINT, "Owning user ID"),
-    Column("gid", BIGINT, "Owning group ID"),
-    Column("mode", TEXT, "Permission bits"),
-    Column("device", BIGINT, "Device ID (optional)"),
-    Column("size", BIGINT, "Size of file in bytes"),
-    Column("block_size", INTEGER, "Block size of filesystem"),
-    Column("atime", BIGINT, "Last access time"),
-    Column("mtime", BIGINT, "Last modification time"),
-    Column("ctime", BIGINT, "Last status change time"),
-    Column("btime", BIGINT, "(B)irth or (cr)eate time"),
-    Column("hard_links", INTEGER, "Number of hard links"),
-    Column("symlink", INTEGER, "1 if the path is a symlink, otherwise 0"),
-    Column("type", TEXT, "File status"),
-])
-extended_schema(WINDOWS, [
-    Column("attributes", TEXT, "File attrib string. See: https://ss64.com/nt/attrib.html"),
-    Column("volume_serial", TEXT, "Volume serial number"),
-    Column("file_id", TEXT, "file ID"),
-    Column("product_version", TEXT, "File product version"),
-])
-attributes(utility=True)
-implementation("utility/file@genFile")
-examples([
-  "select * from file where path = '/etc/passwd'",
-  "select * from file where directory = '/etc/'",
-  "select * from file where path LIKE '/etc/%'",
-])
index 7fa8209..a7a9008 100644 (file)
@@ -40,8 +40,6 @@ ENDIF(DEFINED GBS_BUILD)
 
 ## osquery v4.0.0
 ADD_SUBDIRECTORY(core)
-ADD_SUBDIRECTORY(filesystem)
-ADD_SUBDIRECTORY(logger)
 ADD_SUBDIRECTORY(registry)
 ADD_SUBDIRECTORY(sql)
 ADD_SUBDIRECTORY(tables)
index afb9f05..a5319ef 100644 (file)
@@ -37,7 +37,6 @@
 #include "osquery/utils/info/platform_type.h"
 #include <osquery/core.h>
 #include <osquery/data_logger.h>
-#include <osquery/filesystem/filesystem.h>
 #include <osquery/registry.h>
 #include <osquery/utils/info/version.h>
 #include <osquery/utils/system/time.h>
@@ -81,10 +80,6 @@ enum {
 
 namespace {
 extern "C" {
-static inline bool hasWorkerVariable() {
-  return ::osquery::getEnvVar("OSQUERY_WORKER").is_initialized();
-}
-
 volatile std::sig_atomic_t kHandledSignal{0};
 
 void signalHandler(int num) {
@@ -174,13 +169,6 @@ Initializer::Initializer(int& argc,
 }
 
 void Initializer::initDaemon() const {
-  if (isWorker() || !isDaemon()) {
-    // The worker process (child) will not daemonize.
-    return;
-  }
-
-  // Print the version to the OS system log.
-  systemLog(binary_ + " started [version=" + kVersion + "]");
 }
 
 void Initializer::initShell() const {
@@ -196,10 +184,6 @@ void Initializer::initWorker(const std::string& name) const {
   }
 }
 
-bool Initializer::isWorker() {
-  return hasWorkerVariable();
-}
-
 void Initializer::initActivePlugin(const std::string& type,
                                    const std::string& name) const {
   auto rs = RegistryFactory::get().setActive(type, name);
@@ -244,7 +228,6 @@ void Initializer::requestShutdown(int retcode) {
 }
 
 void Initializer::requestShutdown(int retcode, const std::string& system_log) {
-  systemLog(system_log);
   requestShutdown(retcode);
 }
 
index 2720675..a6e973a 100644 (file)
@@ -46,7 +46,6 @@
 #include <boost/uuid/uuid_io.hpp>
 
 #include <osquery/core.h>
-#include <osquery/filesystem/filesystem.h>
 #include <osquery/logger.h>
 #include <osquery/sql.h>
 #include <osquery/system.h>
@@ -149,48 +148,7 @@ bool isPlaceholderHardwareUUID(const std::string& uuid) {
 }
 
 std::string generateHostUUID() {
-  std::string hardware_uuid;
-#ifdef __APPLE__
-  // Use the hardware UUID available on OSX to identify this machine
-  uuid_t id;
-  // wait at most 5 seconds for gethostuuid to return
-  const timespec wait = {5, 0};
-  if (gethostuuid(id, &wait) == 0) {
-    char out[128] = {0};
-    uuid_unparse(id, out);
-    hardware_uuid = std::string(out);
-  }
-#elif WIN32
-  const WmiRequest wmiUUIDReq("Select UUID from Win32_ComputerSystemProduct");
-  const std::vector<WmiResultItem>& wmiUUIDResults = wmiUUIDReq.results();
-  if (wmiUUIDResults.size() != 0) {
-    wmiUUIDResults[0].GetString("UUID", hardware_uuid);
-  }
-#else
-  readFile("/sys/class/dmi/id/product_uuid", hardware_uuid);
-#endif
-
-  // We know at least Linux will append a newline.
-  hardware_uuid.erase(
-      std::remove(hardware_uuid.begin(), hardware_uuid.end(), '\n'),
-      hardware_uuid.end());
-  boost::algorithm::trim(hardware_uuid);
-  if (!hardware_uuid.empty()) {
-    // Construct a new string to remove trailing nulls.
-    hardware_uuid = std::string(hardware_uuid.c_str());
-  }
-
-  // Check whether the UUID is valid. If not generate an ephemeral UUID.
-  if (hardware_uuid.empty()) {
-    VLOG(1) << "Failed to read system uuid, returning ephemeral uuid";
-    return generateNewUUID();
-  } else if (isPlaceholderHardwareUUID(hardware_uuid)) {
-    VLOG(1) << "Hardware uuid '" << hardware_uuid
-            << "' is a placeholder, returning ephemeral uuid";
-    return generateNewUUID();
-  } else {
-    return hardware_uuid;
-  }
+  return "Not supported";
 }
 
 Status getInstanceUUID(std::string& ident) {
diff --git a/src/osquery/filesystem/CMakeLists.txt b/src/osquery/filesystem/CMakeLists.txt
deleted file mode 100644 (file)
index 5359404..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-#  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
-
-ADD_OSQUERY_LIBRARY(osquery_filesystem filesystem.cpp
-                                                                          mock_file_structure.cpp
-                                                                          linux/mem.cpp
-                                                                          linux/proc.cpp
-                                                                          posix/fileops.cpp)
-
-FILE(GLOB OSQUERY_FILESYSTEM_TESTS "tests/*.cpp")
-ADD_OSQUERY_TEST(${OSQUERY_FILESYSTEM_TESTS})
diff --git a/src/osquery/filesystem/fileops.h b/src/osquery/filesystem/fileops.h
deleted file mode 100644 (file)
index c7d439d..0000000
+++ /dev/null
@@ -1,427 +0,0 @@
-/**
- *  Copyright (c) 2014-present, Facebook, Inc.
- *  All rights reserved.
- *
- *  This source code is licensed in accordance with the terms specified in
- *  the LICENSE file found in the root directory of this source tree.
- */
-
-#pragma once
-
-#include <fcntl.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#ifdef WIN32
-#include <iomanip>
-#include <map>
-#include <osquery/utils/system/system.h>
-#else
-#include <unistd.h>
-#endif
-
-#include <string>
-#include <vector>
-
-#include <boost/filesystem.hpp>
-#include <boost/noncopyable.hpp>
-#include <boost/optional.hpp>
-
-#include <osquery/utils/status/status.h>
-#include <osquery/utils/system/env.h>
-
-namespace osquery {
-
-#ifdef WIN32
-
-using mode_t = int;
-using ssize_t = SSIZE_T;
-using PlatformHandle = HANDLE;
-using PlatformTimeType = FILETIME;
-
-// Windows do not define these by default
-#define R_OK 4
-#define W_OK 2
-#define X_OK 1
-
-// Windows does not define these constants, and they are neater
-// than using raw octal for platformChmod, etc.
-#define S_IRUSR 0400
-#define S_IWUSR 0200
-#define S_IXUSR 0100
-#define S_IRWXU (S_IRUSR | S_IWUSR | S_IXUSR)
-
-#define S_IRGRP (S_IRUSR >> 3)
-#define S_IWGRP (S_IWUSR >> 3)
-#define S_IXGRP (S_IXUSR >> 3)
-#define S_IRWXG (S_IRWXU >> 3)
-
-#define S_IROTH (S_IRGRP >> 3)
-#define S_IWOTH (S_IWGRP >> 3)
-#define S_IXOTH (S_IXGRP >> 3)
-#define S_IRWXO (S_IRWXG >> 3)
-
-const std::map<std::int32_t, std::string> kDriveLetters{
-    {0, "A:\\"},  {1, "B:\\"},  {2, "C:\\"},  {3, "D:\\"},  {4, "E:\\"},
-    {5, "F:\\"},  {6, "G:\\"},  {7, "H:\\"},  {8, "I:\\"},  {9, "J:\\"},
-    {10, "K:\\"}, {11, "L:\\"}, {12, "M:\\"}, {13, "N:\\"}, {14, "O:\\"},
-    {15, "P:\\"}, {16, "Q:\\"}, {17, "R:\\"}, {18, "S:\\"}, {19, "T:\\"},
-    {20, "U:\\"}, {21, "V:\\"}, {22, "W:\\"}, {23, "X:\\"}, {24, "Y:\\"},
-    {25, "Z:\\"},
-};
-
-typedef struct win_stat {
-  std::string path;
-  std::string filename;
-  int symlink;
-  std::string file_id;
-  LONGLONG inode;
-  unsigned long uid;
-  unsigned long gid;
-  std::string mode;
-  LONGLONG device;
-  LONGLONG size;
-  int block_size;
-  LONGLONG atime;
-  LONGLONG mtime;
-  LONGLONG ctime;
-  LONGLONG btime;
-  int hard_links;
-  std::string type;
-  std::string attributes;
-  std::string volume_serial;
-  std::string product_version;
-
-} WINDOWS_STAT;
-
-#else
-
-using PlatformHandle = int;
-using PlatformTimeType = struct timeval;
-#endif
-
-typedef struct { PlatformTimeType times[2]; } PlatformTime;
-
-/// Constant for an invalid handle.
-const PlatformHandle kInvalidHandle = (PlatformHandle)-1;
-
-std::string lastErrorMessage(unsigned long);
-
-/**
- * @brief File access modes for PlatformFile.
- *
- * A file can be opened for many access modes with a variety of different
- * options on Windows and POSIX. To provide multi-platform support, we need to
- * provide an abstraction that can cover the supported platforms.
- */
-
-#define PF_READ 0x0001
-#define PF_WRITE 0x0002
-
-#define PF_OPTIONS_MASK 0x001c
-#define PF_GET_OPTIONS(x) ((x & PF_OPTIONS_MASK) >> 2)
-// Create new file only if it does not exist, or else fail.
-#define PF_CREATE_NEW (0 << 2)
-// If file exists truncate it, or else create new one.
-#define PF_CREATE_ALWAYS (1 << 2)
-// If file exists open it, or else fail.
-#define PF_OPEN_EXISTING (2 << 2)
-// If file exists open it, or else create new one.
-#define PF_OPEN_ALWAYS (3 << 2)
-#define PF_TRUNCATE (4 << 2)
-
-#define PF_NONBLOCK 0x0020
-#define PF_APPEND 0x0040
-
-/**
- * @brief Modes for seeking through a file.
- *
- * Provides a platform agnostic enumeration for file seek operations. These
- * are translated to the appropriate flags for the underlying platform.
- */
-enum SeekMode { PF_SEEK_BEGIN = 0, PF_SEEK_CURRENT, PF_SEEK_END };
-
-#ifdef WIN32
-/// Takes a Windows FILETIME object and returns seconds since epoch
-LONGLONG filetimeToUnixtime(const FILETIME& ft);
-
-LONGLONG longIntToUnixtime(LARGE_INTEGER& ft);
-
-std::string getFileAttribStr(unsigned long);
-
-Status platformStat(const boost::filesystem::path&, WINDOWS_STAT*);
-
-/**
- * @brief Stores information about the last Windows async request
- *
- * Currently, we have rudimentary support for non-blocking operations on
- * Windows. The implementation attempts to emulate POSIX non-blocking IO
- * semantics using the Windows asynchronous API. As such, there are currently
- * limitations. For example, opening a non-blocking file with read and write
- * privileges may produce some problems. If a write operation does not
- * immediately succeed, we cancel IO instead of waiting on it. As a result,
- * on-going async read operations will get canceled and data might get lost.
- *
- * Windows-only class that deals with simulating POSIX asynchronous IO semantics
- * using Windows API calls
- */
-struct AsyncEvent {
-  AsyncEvent();
-  ~AsyncEvent();
-
-  OVERLAPPED overlapped_{0};
-  std::unique_ptr<char[]> buffer_{nullptr};
-  bool is_active_{false};
-};
-
-/*
- * @brief Converts a Windows short path to a full path
- *
- * This takes an 8.3 format path (i.e. C:\PROGRA~2\1PASSW~1\x64\AGILE1~1.DLL)
- * and converts to a full path
- *
- * @param shortPath the short path
- * @param rLongPath will be populated with the long path
- *
- * @return Success if successful, otherwise failure
- */
-Status windowsShortPathToLongPath(const std::string& shortPath,
-                                  std::string& rLongPath);
-
-/*
- * @brief Get the product version associated with a file
- *
- * @param path: Full path to the file
- * @param rVersion: String representing the product version, e.g. "16.0.8201.0"
- *
- * @return Success if the version could be retrieved, otherwise failure
- */
-Status windowsGetFileVersion(const std::string& path, std::string& rVersion);
-#endif
-
-/**
- * @brief Platform-agnostic file object.
- *
- * PlatformFile is a multi-platform class that offers input/output capabilities
- * for files.
- */
-class PlatformFile : private boost::noncopyable {
- public:
-  explicit PlatformFile(const boost::filesystem::path& path,
-                        int mode,
-                        int perms = -1);
-  explicit PlatformFile(PlatformHandle handle) : handle_(handle) {}
-
-  ~PlatformFile();
-
-  /// Checks to see if the file object is "special file".
-  bool isSpecialFile() const;
-
-  /**
-   * @brief Checks to see if there are any pending IO operations.
-   *
-   * This is mostly used after a read()/write() error in non-blocking mode to
-   * determine the intention of the error. If read()/write() returns an error
-   * and hasPendingIo() is true, this indicates that the read()/write()
-   * operation didn't complete on time.
-   */
-  bool hasPendingIo() const {
-    return has_pending_io_;
-  }
-
-  /// Checks to see if the handle backing the PlatformFile object is valid.
-  bool isValid() const {
-    return (handle_ != kInvalidHandle);
-  }
-
-  /// Returns the platform specific handle.
-  PlatformHandle nativeHandle() const {
-    return handle_;
-  }
-
-  /**
-   * @brief Returns success if owner of the file is root.
-   *
-   * At the moment, we only determine that the owner of the current file is a
-   * member of the Administrators group. We do not count files owned by
-   * TrustedInstaller as owned by root.
-   */
-  Status isOwnerRoot() const;
-
-  /// Returns success if the owner of the file is the current user.
-  Status isOwnerCurrentUser() const;
-
-  /// Determines whether the file has the executable bit set.
-  Status isExecutable() const;
-
-  /**
-   * @brief Determines how immutable the file is to external modifications.
-   *
-   * Currently, this is only implemented on Windows. The Windows version of this
-   * function ensures that writes are explicitly denied for the file AND the
-   * file's parent directory.
-   */
-  Status hasSafePermissions() const;
-
-  /// Return the modified, created, birth, updated, etc times.
-  bool getFileTimes(PlatformTime& times);
-
-  /// Change the file times.
-  bool setFileTimes(const PlatformTime& times);
-
-  /// Read a number of bytes into a buffer.
-  ssize_t read(void* buf, size_t nbyte);
-
-  /// Write a number of bytes from a buffer.
-  ssize_t write(const void* buf, size_t nbyte);
-
-  /// Use the platform-specific seek.
-  off_t seek(off_t offset, SeekMode mode);
-
-  /// Inspect the file size.
-  size_t size() const;
-
- private:
-  boost::filesystem::path fname_;
-
-  /// The internal platform-specific open file handle.
-  PlatformHandle handle_{kInvalidHandle};
-
-  /// Is the file opened in a non-blocking read mode.
-  bool is_nonblock_{false};
-
-  /// Does the file have pending operations.
-  bool has_pending_io_{false};
-
-#ifdef WIN32
-  int cursor_{0};
-
-  AsyncEvent last_read_;
-
-  ssize_t getOverlappedResultForRead(void* buf, size_t requested_size);
-#endif
-};
-
-/**
- * @brief Returns the current user's home directory.
- *
- * This uses multiple methods to find the current user's home directory. It
- * attempts to use environment variables first and on failure, tries to obtain
- * the path using platform specific functions. Returns a boost::none on the
- * failure of both methods.
- */
-boost::optional<std::string> getHomeDirectory();
-
-/**
- * @brief Multi-platform implementation of chmod.
- * @note There are issues with the ACL being ordered "incorrectly". This
- *        incorrect ordering does help with implementing the proper
- *        behaviors
- *
- * This function approximates the functionality of the POSIX chmod function on
- * Windows. While there is the _chmod function on Windows, it does not support
- * the user, group, world permissions model. The Windows version of this
- * function will approximate it by using GetNamedSecurityInfoA to obtain the
- * file's owner and group. World is represented by the Everyone group on
- * Windows. Allowed permissions are represented by an access allowed access
- * control entry and unset permissions are represented by an explicit access
- * denied access control entry. However, the Windows preference for ACL ordering
- * creates some problems. For instance, if a user wishes to protect a file by
- * denying world access to a file, the normal standard for ACL ordering will end
- * up denying everyone, including the user, to the file (because of the deny
- * Everyone access control entry that is first in the ACL). To counter this, we
- * have to be more creative with the ACL order which presents some problems for
- * when attempting to modify permissions via File Explorer (complains of a
- * mis-ordered ACL and offers to rectify the problem).
- */
-bool platformChmod(const std::string& path, mode_t perms);
-
-/**
- * @brief Sets 'safe' permissions for the database backing osquery
- *
- * @note Safe DB perms are equivalent to a chmod 0700 for root on posix
- * so we emulate this by granting Full perms to SYSTEM and Administrators
- * only.
- */
-bool platformSetSafeDbPerms(const std::string& path);
-
-/**
- * @brief Multi-platform implementation of glob.
- * @note glob support is not 100% congruent with Linux glob. There are slight
- *       differences in how GLOB_TILDE and GLOB_BRACE are implemented.
- *
- * This function approximates the functionality of the POSIX glob function on
- * Windows. It has naive support of GLOB_TILDE (doesn't support ~user syntax),
- * GLOB_MARK, and GLOB_BRACE (custom translation of glob expressions to regex).
- */
-std::vector<std::string> platformGlob(const std::string& find_path);
-
-/**
- * @brief Checks to see if the current user has the permissions to perform a
- *        specified operation on a file.
- *
- * This abstracts the POSIX access function across Windows and POSIX. On
- * Windows, this calls the equivalent _access function.
- */
-int platformAccess(const std::string& path, mode_t mode);
-
-/**
- * @brief Checks to see if the provided directory is a temporary folder.
- * @note This just compares the temporary directory path against the given path
- *       on Windows.
- */
-Status platformIsTmpDir(const boost::filesystem::path& dir);
-
-/// Determines the accessibility and existence of the file path.
-Status platformIsFileAccessible(const boost::filesystem::path& path);
-
-/// Determine if the FILE object points to a tty (console, serial port, etc).
-bool platformIsatty(FILE* f);
-
-/// Opens a file and returns boost::none on error
-boost::optional<FILE*> platformFopen(const std::string& filename,
-                                     const std::string& mode);
-
-/**
- * @brief Checks for the existence of a named pipe or UNIX socket.
- *
- * This method is overloaded to perform two actions. If removal is requested
- * the success is determined based on the non-existence or successful removal
- * of the socket path. Otherwise the result is straightforward.
- *
- * The removal action is only used when extensions or the extension manager
- * is first starting.
- *
- * @param path The filesystem path to a UNIX socket or Windows named pipe.
- * @param remove_socket Attempt to remove the socket if it exists.
- *
- * @return Success if the socket exists and removal was not requested. False
- * if the socket exists and removal was requested (and the attempt to remove
- * had failed).
- */
-Status socketExists(const boost::filesystem::path& path,
-                    bool remove_socket = false);
-
-/**
- * @brief Returns the OS root system directory.
- *
- * Some applications store configuration and application data inside of the
- * Windows directory. This function retrieves the path to the current
- * configurations Windows location.
- *
- * On POSIX systems this returns "/".
- *
- * @return boost::filesystem::path containing the OS root location.
- */
-boost::filesystem::path getSystemRoot();
-
-/**
- * @brief Returns the successfully and fills d_stat if lstat was successful.
- *
- *
- * On Windows systems this does not touch the structure.
- *
- * @return osquery::Status
- */
-Status platformLstat(const std::string& path, struct stat& d_stat);
-}
diff --git a/src/osquery/filesystem/filesystem.cpp b/src/osquery/filesystem/filesystem.cpp
deleted file mode 100644 (file)
index 3922c94..0000000
+++ /dev/null
@@ -1,571 +0,0 @@
-/**
- *  Copyright (c) 2014-present, Facebook, Inc.
- *  All rights reserved.
- *
- *  This source code is licensed in accordance with the terms specified in
- *  the LICENSE file found in the root directory of this source tree.
- */
-
-#include <sstream>
-
-#include <fcntl.h>
-#include <sys/stat.h>
-
-#ifndef WIN32
-#include <glob.h>
-#include <pwd.h>
-#include <sys/time.h>
-#endif
-
-#include <boost/algorithm/string.hpp>
-#include <boost/filesystem/fstream.hpp>
-#include <boost/filesystem/operations.hpp>
-#include <boost/property_tree/json_parser.hpp>
-
-#include <osquery/filesystem/filesystem.h>
-#include <osquery/logger.h>
-#include <osquery/sql.h>
-#include <osquery/system.h>
-#include <osquery/utils/system/system.h>
-
-#include <osquery/utils/json/json.h>
-
-namespace pt = boost::property_tree;
-namespace fs = boost::filesystem;
-namespace errc = boost::system::errc;
-
-namespace osquery {
-static const size_t kMaxRecursiveGlobs = 64;
-
-Status writeTextFile(const fs::path& path,
-                     const std::string& content,
-                     int permissions,
-                     int mode) {
-  // Open the file with the request permissions.
-  PlatformFile output_fd(path, mode, permissions);
-  if (!output_fd.isValid()) {
-    return Status(1, "Could not create file: " + path.string());
-  }
-
-  // If the file existed with different permissions before our open
-  // they must be restricted.
-  if (!platformChmod(path.string(), permissions)) {
-    // Could not change the file to the requested permissions.
-    return Status(1, "Failed to change permissions for file: " + path.string());
-  }
-
-  ssize_t bytes = output_fd.write(content.c_str(), content.size());
-  if (static_cast<size_t>(bytes) != content.size()) {
-    return Status(1, "Failed to write contents to file: " + path.string());
-  }
-
-  return Status::success();
-}
-
-struct OpenReadableFile : private boost::noncopyable {
- public:
-  explicit OpenReadableFile(const fs::path& path, bool blocking = false) {
-    int mode = PF_OPEN_EXISTING | PF_READ;
-    if (!blocking) {
-      mode |= PF_NONBLOCK;
-    }
-
-    // Open the file descriptor and allow caller to perform error checking.
-    fd.reset(new PlatformFile(path, mode));
-  }
-
- public:
-  std::unique_ptr<PlatformFile> fd{nullptr};
-};
-
-Status readFile(const fs::path& path,
-                size_t size,
-                size_t block_size,
-                bool dry_run,
-                bool preserve_time,
-                std::function<void(std::string& buffer, size_t size)> predicate,
-                bool blocking) {
-  OpenReadableFile handle(path, blocking);
-  if (handle.fd == nullptr || !handle.fd->isValid()) {
-    return Status(1, "Cannot open file for reading: " + path.string());
-  }
-
-  off_t file_size = static_cast<off_t>(handle.fd->size());
-  if (handle.fd->isSpecialFile() && size > 0) {
-    file_size = static_cast<off_t>(size);
-  }
-
-  // Apply the max byte-read based on file/link target ownership.
-  auto read_max = static_cast<off_t>(2048);
-  if (file_size > read_max) {
-    if (!dry_run) {
-      LOG(WARNING) << "Cannot read file that exceeds size limit: "
-                   << path.string();
-      VLOG(1) << "Cannot read " << path.string()
-              << " size exceeds limit: " << file_size << " > " << read_max;
-    }
-    return Status(1, "File exceeds read limits");
-  }
-
-  if (dry_run) {
-    // The caller is only interested in performing file read checks.
-    boost::system::error_code ec;
-    try {
-      return Status(0, fs::canonical(path, ec).string());
-    } catch (const boost::filesystem::filesystem_error& err) {
-      return Status(1, err.what());
-    }
-  }
-
-  PlatformTime times;
-  handle.fd->getFileTimes(times);
-
-  off_t total_bytes = 0;
-  if (file_size == 0 || block_size > 0) {
-    // Reset block size to a sane minimum.
-    block_size = (block_size < 4096) ? 4096 : block_size;
-    ssize_t part_bytes = 0;
-    bool overflow = false;
-    do {
-      std::string part(block_size, '\0');
-      part_bytes = handle.fd->read(&part[0], block_size);
-      if (part_bytes > 0) {
-        total_bytes += static_cast<off_t>(part_bytes);
-        if (total_bytes >= read_max) {
-          return Status(1, "File exceeds read limits");
-        }
-        if (file_size > 0 && total_bytes > file_size) {
-          overflow = true;
-          part_bytes -= (total_bytes - file_size);
-        }
-        predicate(part, part_bytes);
-      }
-    } while (part_bytes > 0 && !overflow);
-  } else {
-    std::string content(file_size, '\0');
-    do {
-      auto part_bytes =
-          handle.fd->read(&content[total_bytes], file_size - total_bytes);
-      if (part_bytes > 0) {
-        total_bytes += static_cast<off_t>(part_bytes);
-      }
-    } while (handle.fd->hasPendingIo());
-    predicate(content, file_size);
-  }
-
-  return Status::success();
-}
-
-Status readFile(const fs::path& path,
-                std::string& content,
-                size_t size,
-                bool dry_run,
-                bool preserve_time,
-                bool blocking) {
-  return readFile(path,
-                  size,
-                  4096,
-                  dry_run,
-                  preserve_time,
-                  ([&content](std::string& buffer, size_t _size) {
-                    if (buffer.size() == _size) {
-                      content += std::move(buffer);
-                    } else {
-                      content += buffer.substr(0, _size);
-                    }
-                  }),
-                  blocking);
-}
-
-Status readFile(const fs::path& path, bool blocking) {
-  std::string blank;
-  return readFile(path, blank, 0, true, false, blocking);
-}
-
-Status forensicReadFile(const fs::path& path,
-                        std::string& content,
-                        bool blocking) {
-  return readFile(path, content, 0, false, true, blocking);
-}
-
-Status isWritable(const fs::path& path, bool effective) {
-  auto path_exists = pathExists(path);
-  if (!path_exists.ok()) {
-    return path_exists;
-  }
-
-  if (effective) {
-    PlatformFile fd(path, PF_OPEN_EXISTING | PF_WRITE);
-    return Status(fd.isValid() ? 0 : 1);
-  } else if (platformAccess(path.string(), W_OK) == 0) {
-    return Status::success();
-  }
-
-  return Status(1, "Path is not writable: " + path.string());
-}
-
-Status isReadable(const fs::path& path, bool effective) {
-  auto path_exists = pathExists(path);
-  if (!path_exists.ok()) {
-    return path_exists;
-  }
-
-  if (effective) {
-    PlatformFile fd(path, PF_OPEN_EXISTING | PF_READ);
-    return Status(fd.isValid() ? 0 : 1);
-  } else if (platformAccess(path.string(), R_OK) == 0) {
-    return Status::success();
-  }
-
-  return Status(1, "Path is not readable: " + path.string());
-}
-
-Status pathExists(const fs::path& path) {
-  boost::system::error_code ec;
-  if (path.empty()) {
-    return Status(1, "-1");
-  }
-
-  // A tri-state determination of presence
-  if (!fs::exists(path, ec) || ec.value() != errc::success) {
-    return Status(1, ec.message());
-  }
-  return Status::success();
-}
-
-Status movePath(const fs::path& from, const fs::path& to) {
-  boost::system::error_code ec;
-  if (from.empty() || to.empty()) {
-    return Status(1, "Cannot copy empty paths");
-  }
-
-  fs::rename(from, to, ec);
-  if (ec.value() != errc::success) {
-    return Status(1, ec.message());
-  }
-  return Status(0);
-}
-
-Status removePath(const fs::path& path) {
-  boost::system::error_code ec;
-  auto removed_files = fs::remove_all(path, ec);
-  if (ec.value() != errc::success) {
-    return Status(1, ec.message());
-  }
-  return Status(0, std::to_string(removed_files));
-}
-
-static bool checkForLoops(std::set<int>& dsym_inos, std::string path) {
-  if (path.empty() || path.back() != '/') {
-    return false;
-  }
-
-  path.pop_back();
-  struct stat d_stat;
-  // On Windows systems (lstat not implemented) this immiedately returns
-  if (!platformLstat(path, d_stat).ok()) {
-    return false;
-  }
-
-  if ((d_stat.st_mode & 0170000) == 0) {
-    return false;
-  }
-
-  if (dsym_inos.find(d_stat.st_ino) == dsym_inos.end()) {
-    dsym_inos.insert(d_stat.st_ino);
-  } else {
-    LOG(WARNING) << "Symlink loop detected possibly involving: " << path;
-    return true;
-  }
-  return false;
-}
-
-static void genGlobs(std::string path,
-                     std::vector<std::string>& results,
-                     GlobLimits limits) {
-  // Use our helped escape/replace for wildcards.
-  replaceGlobWildcards(path, limits);
-  // inodes of directory symlinks for loop detection
-  std::set<int> dsym_inos;
-
-  // Generate a glob set and recurse for double star.
-  for (size_t glob_index = 0; ++glob_index < kMaxRecursiveGlobs;) {
-    auto glob_results = platformGlob(path);
-
-    for (auto& result_path : glob_results) {
-      results.push_back(result_path);
-
-      if (checkForLoops(dsym_inos, result_path)) {
-        glob_index = kMaxRecursiveGlobs;
-      }
-    }
-
-    // The end state is a non-recursive ending or empty set of matches.
-    size_t wild = path.rfind("**");
-    // Allow a trailing slash after the double wild indicator.
-    if (glob_results.size() == 0 || wild > path.size() ||
-        wild + 3 < path.size()) {
-      break;
-    }
-
-    path += "/**";
-  }
-
-  // Prune results based on settings/requested glob limitations.
-  auto end = std::remove_if(
-      results.begin(), results.end(), [limits](const std::string& found) {
-        return !(((found[found.length() - 1] == '/' ||
-                   found[found.length() - 1] == '\\') &&
-                  limits & GLOB_FOLDERS) ||
-                 ((found[found.length() - 1] != '/' &&
-                   found[found.length() - 1] != '\\') &&
-                  limits & GLOB_FILES));
-      });
-  results.erase(end, results.end());
-}
-
-Status resolveFilePattern(const fs::path& fs_path,
-                          std::vector<std::string>& results) {
-  return resolveFilePattern(fs_path, results, GLOB_ALL);
-}
-
-Status resolveFilePattern(const fs::path& fs_path,
-                          std::vector<std::string>& results,
-                          GlobLimits setting) {
-  genGlobs(fs_path.string(), results, setting);
-  return Status::success();
-}
-
-inline void replaceGlobWildcards(std::string& pattern, GlobLimits limits) {
-  // Replace SQL-wildcard '%' with globbing wildcard '*'.
-  if (pattern.find('%') != std::string::npos) {
-    boost::replace_all(pattern, "%", "*");
-  }
-
-  // Relative paths are a bad idea, but we try to accommodate.
-  if ((pattern.size() == 0 || ((pattern[0] != '/' && pattern[0] != '\\') &&
-                               (pattern.size() > 3 && pattern[1] != ':' &&
-                                pattern[2] != '\\' && pattern[2] != '/'))) &&
-      pattern[0] != '~') {
-    try {
-      boost::system::error_code ec;
-      pattern = (fs::current_path(ec) / pattern).make_preferred().string();
-    } catch (const fs::filesystem_error& /* e */) {
-      // There is a bug in versions of current_path that still throw.
-    }
-  }
-
-  auto base =
-      fs::path(pattern.substr(0, pattern.find('*'))).make_preferred().string();
-
-  if (base.size() > 0) {
-    boost::system::error_code ec;
-    auto canonicalized = ((limits & GLOB_NO_CANON) == 0)
-                             ? fs::canonical(base, ec).make_preferred().string()
-                             : base;
-
-    if (canonicalized.size() > 0 && canonicalized != base) {
-      if (isDirectory(canonicalized)) {
-        // Canonicalized directory paths will not include a trailing '/'.
-        // However, if the wildcards are applied to files within a directory
-        // then the missing '/' changes the wildcard meaning.
-        canonicalized += '/';
-      }
-      // We are unable to canonicalize the meaning of post-wildcard limiters.
-      pattern = fs::path(canonicalized + pattern.substr(base.size()))
-                    .make_preferred()
-                    .string();
-    }
-  }
-}
-
-inline Status listInAbsoluteDirectory(const fs::path& path,
-                                      std::vector<std::string>& results,
-                                      GlobLimits limits) {
-  if (path.filename() == "*" && !pathExists(path.parent_path())) {
-    return Status(1, "Directory not found: " + path.parent_path().string());
-  }
-
-  if (path.filename() == "*" && !isDirectory(path.parent_path())) {
-    return Status(1, "Path not a directory: " + path.parent_path().string());
-  }
-
-  genGlobs(path.string(), results, limits);
-  return Status::success();
-}
-
-Status listFilesInDirectory(const fs::path& path,
-                            std::vector<std::string>& results,
-                            bool recursive) {
-  return listInAbsoluteDirectory(
-      (path / ((recursive) ? "**" : "*")), results, GLOB_FILES);
-}
-
-Status listDirectoriesInDirectory(const fs::path& path,
-                                  std::vector<std::string>& results,
-                                  bool recursive) {
-  return listInAbsoluteDirectory(
-      (path / ((recursive) ? "**" : "*")), results, GLOB_FOLDERS);
-}
-
-Status isDirectory(const fs::path& path) {
-  boost::system::error_code ec;
-  if (fs::is_directory(path, ec)) {
-    return Status::success();
-  }
-
-  // The success error code is returned for as a failure (undefined error)
-  // We need to flip that into an error, a success would have falling through
-  // in the above conditional.
-  if (ec.value() == errc::success) {
-    return Status(1, "Path is not a directory: " + path.string());
-  }
-  return Status(ec.value(), ec.message());
-}
-
-Status createDirectory(const boost::filesystem::path& dir_path,
-                       bool const recursive,
-                       bool const ignore_existence) {
-  auto err = boost::system::error_code{};
-  bool is_created = false;
-  if (recursive) {
-    is_created = boost::filesystem::create_directories(dir_path, err);
-  } else {
-    is_created = boost::filesystem::create_directory(dir_path, err);
-  }
-  if (is_created) {
-    return Status::success();
-  }
-  if (ignore_existence && isDirectory(dir_path).ok()) {
-    return Status::success();
-  }
-  auto msg = std::string{"Could not create directory \""};
-  msg += dir_path.string();
-  msg += '"';
-  if (err) {
-    msg += ": ";
-    msg += err.message();
-  }
-  return Status::failure(msg);
-}
-
-std::set<fs::path> getHomeDirectories() {
-  std::set<fs::path> results;
-
-  auto users = SQL::selectAllFrom("users");
-  for (const auto& user : users) {
-    if (user.at("directory").size() > 0) {
-      results.insert(user.at("directory"));
-    }
-  }
-
-  return results;
-}
-
-bool safePermissions(const fs::path& dir,
-                     const fs::path& path,
-                     bool executable) {
-  if (!platformIsFileAccessible(path).ok()) {
-    // Path was not real, had too may links, or could not be accessed.
-    return false;
-  }
-
-  Status result = platformIsTmpDir(dir);
-  if (!result.ok() && result.getCode() < 0) {
-    // An error has occurred in stat() on dir, most likely because the file path
-    // does not exist
-    return false;
-  } else if (result.ok()) {
-    // Do not load modules from /tmp-like directories.
-    return false;
-  }
-
-  PlatformFile fd(path, PF_OPEN_EXISTING | PF_READ);
-  if (!fd.isValid()) {
-    return false;
-  }
-
-  result = isDirectory(path);
-  if (!result.ok() && result.getCode() < 0) {
-    // Something went wrong when determining the file's directoriness
-    return false;
-  } else if (result.ok()) {
-    // Only load file-like nodes (not directories).
-    return false;
-  }
-
-  if (fd.isOwnerRoot().ok() || fd.isOwnerCurrentUser().ok()) {
-    result = fd.isExecutable();
-
-    // Otherwise, require matching or root file ownership.
-    if (executable && (result.getCode() > 0 || !fd.hasSafePermissions().ok())) {
-      // Require executable, implies by the owner.
-      return false;
-    }
-
-    return true;
-  }
-
-  // Do not load modules not owned by the user.
-  return false;
-}
-
-const std::string& osqueryHomeDirectory() {
-  static std::string homedir;
-
-  if (homedir.size() == 0) {
-    // Try to get the caller's home directory
-    boost::system::error_code ec;
-    auto userdir = getHomeDirectory();
-    if (userdir.is_initialized() && isWritable(*userdir).ok()) {
-      auto osquery_dir = (fs::path(*userdir) / ".osquery");
-      if (isWritable(osquery_dir) ||
-          boost::filesystem::create_directories(osquery_dir, ec)) {
-        homedir = osquery_dir.make_preferred().string();
-        return homedir;
-      }
-    }
-
-    // Fail over to a temporary directory (used for the shell).
-    auto temp =
-        fs::temp_directory_path(ec) /
-        (std::string("osquery-") + std::to_string((rand() % 10000) + 20000));
-    boost::filesystem::create_directories(temp, ec);
-    homedir = temp.make_preferred().string();
-  }
-
-  return homedir;
-}
-
-std::string lsperms(int mode) {
-  static const char rwx[] = {'0', '1', '2', '3', '4', '5', '6', '7'};
-  std::string bits;
-
-  bits += rwx[(mode >> 9) & 7];
-  bits += rwx[(mode >> 6) & 7];
-  bits += rwx[(mode >> 3) & 7];
-  bits += rwx[(mode >> 0) & 7];
-  return bits;
-}
-
-Status parseJSON(const fs::path& path, pt::ptree& tree) {
-  std::string json_data;
-  if (!readFile(path, json_data).ok()) {
-    return Status(1, "Could not read JSON from file");
-  }
-
-  return parseJSONContent(json_data, tree);
-}
-
-Status parseJSONContent(const std::string& content, pt::ptree& tree) {
-  // Read the extensions data into a JSON blob, then property tree.
-  try {
-    std::stringstream json_stream;
-    json_stream << content;
-    pt::read_json(json_stream, tree);
-  } catch (const pt::json_parser::json_parser_error& /* e */) {
-    return Status(1, "Could not parse JSON from file");
-  }
-  return Status::success();
-}
-} // namespace osquery
diff --git a/src/osquery/filesystem/filesystem.h b/src/osquery/filesystem/filesystem.h
deleted file mode 100644 (file)
index 6e68080..0000000
+++ /dev/null
@@ -1,363 +0,0 @@
-/**
- *  Copyright (c) 2014-present, Facebook, Inc.
- *  All rights reserved.
- *
- *  This source code is licensed in accordance with the terms specified in
- *  the LICENSE file found in the root directory of this source tree.
- */
-
-#pragma once
-
-#include <osquery/filesystem/fileops.h>
-
-#include <map>
-#include <set>
-#include <string>
-#include <vector>
-
-#include <boost/filesystem/path.hpp>
-#include <boost/property_tree/ptree.hpp>
-
-namespace osquery {
-
-class Status;
-
-/// Globbing directory traversal function recursive limit.
-enum GlobLimits : size_t {
-  GLOB_FILES = 0x1,
-  GLOB_FOLDERS = 0x2,
-  GLOB_ALL = GLOB_FILES | GLOB_FOLDERS,
-  GLOB_NO_CANON = 0x4,
-};
-
-inline GlobLimits operator|(GlobLimits a, GlobLimits b) {
-  return static_cast<GlobLimits>(static_cast<size_t>(a) |
-                                 static_cast<size_t>(b));
-}
-
-/// Globbing wildcard character.
-const std::string kSQLGlobWildcard{"%"};
-
-/// Globbing wildcard recursive character (double wildcard).
-const std::string kSQLGlobRecursive{kSQLGlobWildcard + kSQLGlobWildcard};
-
-/**
- * @brief Read a file from disk.
- *
- * @param path the path of the file that you would like to read.
- * @param size Number of bytes to read from file.
- * @param content a reference to a string which will be populated with the
- * contents of the path indicated by the path parameter.
- * @param dry_run do not actually read the file content.
- * @param preserve_time Attempt to preserve file mtime and atime.
- * @param blocking Request a blocking read.
- *
- * @return an instance of Status, indicating success or failure.
- */
-Status readFile(const boost::filesystem::path& path,
-                std::string& content,
-                size_t size = 0,
-                bool dry_run = false,
-                bool preserve_time = false,
-                bool blocking = false);
-
-/// Read a file and preserve the atime and mtime.
-Status forensicReadFile(const boost::filesystem::path& path,
-                        std::string& content,
-                        bool blocking = false);
-
-/**
- * @brief Return the status of an attempted file read.
- *
- * @param path the path of the file that you would like to read.
- * @param blocking Request a blocking read.
- *
- * @return success iff the file would have been read. On success the status
- * message is the complete/absolute path.
- */
-Status readFile(const boost::filesystem::path& path, bool blocking = false);
-
-/// Internal representation for predicate-based chunk reading.
-Status readFile(const boost::filesystem::path& path,
-                size_t size,
-                size_t block_size,
-                bool dry_run,
-                bool preserve_time,
-                std::function<void(std::string& buffer, size_t size)> predicate,
-                bool blocking = false);
-
-/**
- * @brief Write text to disk.
- *
- * @param path the path of the file that you would like to write.
- * @param content the text that should be written exactly to disk.
- * @param permissions the filesystem permissions to request when opening.
- * @param mode to open file with
- *
- * @return an instance of Status, indicating success or failure.
- */
-Status writeTextFile(const boost::filesystem::path& path,
-                     const std::string& content,
-                     int permissions = 0660,
-                     int mode = PF_OPEN_ALWAYS | PF_WRITE | PF_APPEND);
-
-/**
- * @brief Check if a path is writable.
- *
- * @param path The path of the file that you would like to write.
- * @param effective If you would like to check using effective UID
- *
- * @return A status returning if it's writable
- */
-Status isWritable(const boost::filesystem::path& path, bool effective = false);
-
-/**
- * @brief Check if a path is readable.
- *
- * @param path The path of the file that you would like to read.
- * @param effective If you would like to check using effective UID
- *
- * @return A status returning if it's readable
- */
-Status isReadable(const boost::filesystem::path& path, bool effective = false);
-
-/**
- * @brief A helper to check if a path exists on disk or not.
- *
- * @param path Target path.
- *
- * @return The code of the Status instance will be -1 if no input was supplied,
- * assuming the caller is not aware of how to check path-getter results.
- * The code will be 0 if the path does not exist on disk and 1 if the path
- * does exist on disk.
- */
-Status pathExists(const boost::filesystem::path& path);
-
-/**
- * @brief List all of the files in a specific directory.
- *
- * @param path the path which you would like to list.
- * @param results a non-const reference to a vector which will be populated
- * with the directory listing of the path param, assuming that all operations
- * completed successfully.
- * @param recursive should the listing descend recursively into the directory.
- *
- * @return an instance of Status, indicating success or failure.
- */
-Status listFilesInDirectory(const boost::filesystem::path& path,
-                            std::vector<std::string>& results,
-                            bool recursive = false);
-
-/**
- * @brief List all of the directories in a specific directory, non-recursively.
- *
- * @param path the path which you would like to list
- * @param results a non-const reference to a vector which will be populated
- * with the directory listing of the path param, assuming that all operations
- * completed successfully.
- * @param recursive should the listing descend recursively into the directory.
- *
- * @return an instance of Status, indicating success or failure.
- */
-Status listDirectoriesInDirectory(const boost::filesystem::path& path,
-                                  std::vector<std::string>& results,
-                                  bool recursive = false);
-
-/**
- * @brief Given a filesystem globbing patten, resolve all matching paths.
- *
- * @code{.cpp}
- *   std::vector<std::string> results;
- *   auto s = resolveFilePattern("/Users/marpaia/Downloads/%", results);
- *   if (s.ok()) {
- *     for (const auto& result : results) {
- *       LOG(INFO) << result;
- *     }
- *   }
- * @endcode
- *
- * @param pattern filesystem globbing pattern.
- * @param results output vector of matching paths.
- *
- * @return an instance of Status, indicating success or failure.
- */
-Status resolveFilePattern(const boost::filesystem::path& pattern,
-                          std::vector<std::string>& results);
-
-/**
- * @brief Given a filesystem globbing patten, resolve all matching paths.
- *
- * See resolveFilePattern, but supply a limitation to request only directories
- * or files that match the path.
- *
- * @param pattern filesystem globbing pattern.
- * @param results output vector of matching paths.
- * @param setting a bit list of match types, e.g., files, folders.
- *
- * @return an instance of Status, indicating success or failure.
- */
-Status resolveFilePattern(const boost::filesystem::path& pattern,
-                          std::vector<std::string>& results,
-                          GlobLimits setting);
-
-/**
- * @brief Transform a path with SQL wildcards to globbing wildcard.
- *
- * SQL uses '%' as a wildcard matching token, and filesystem globbing uses '*'.
- * In osquery-internal methods the filesystem character is used. This helper
- * method will perform the correct preg/escape and replace.
- *
- * This has a side effect of canonicalizing paths up to the first wildcard.
- * For example: /tmp/% becomes /private/tmp/% on OS X systems. And /tmp/%.
- *
- * @param pattern the input and output filesystem glob pattern.
- * @param limits osquery::GlobLimits to apply (currently only recognizes
- * osquery::GLOB_NO_CANON)
- */
-void replaceGlobWildcards(std::string& pattern, GlobLimits limits = GLOB_ALL);
-
-/// Attempt to remove a directory path.
-Status removePath(const boost::filesystem::path& path);
-
-/// Move a file or directory to another path.
-Status movePath(const boost::filesystem::path& from,
-                const boost::filesystem::path& to);
-
-/**
- * @brief Check if an input path is a directory.
- *
- * @param path input path, either a filename or directory.
- *
- * @return If the input path was a directory.
- */
-Status isDirectory(const boost::filesystem::path& path);
-
-/**
- * @brief Create the directory
- *
- * @param path to the intended directory
- * @param recursive - make parent directories as needed
- * @param ignore_existence - no error if directory already exists
- *
- * @return Status of operation
- */
-Status createDirectory(const boost::filesystem::path& path,
-                       bool recursive = false,
-                       bool ignore_existence = false);
-
-/**
- * @brief Return a vector of all home directories on the system.
- *
- * @return a vector of string paths containing all home directories.
- */
-std::set<boost::filesystem::path> getHomeDirectories();
-
-/**
- * @brief Check the permissions of a file and its directory.
- *
- * 'Safe' implies the directory is not a /tmp-like directory in that users
- * cannot control super-user-owner files. The file should be owned by the
- * process's UID or the file should be owned by root.
- *
- * @param dir the directory to check `/tmp` mode.
- * @param path a path to a file to check.
- * @param executable true if the file must also be executable.
- *
- * @return true if the file is 'safe' else false.
- */
-bool safePermissions(const boost::filesystem::path& dir,
-                     const boost::filesystem::path& path,
-                     bool executable = false);
-
-/**
- * @brief osquery may use local storage in a user-protected "home".
- *
- * Return a standard path to an "osquery" home directory. This path may store
- * a protected extensions socket, backing storage database, and debug logs.
- */
-const std::string& osqueryHomeDirectory();
-
-/// Return bit-mask-style permissions.
-std::string lsperms(int mode);
-
-/**
- * @brief Parse a JSON file on disk into a property tree.
- *
- * @param path the path of the JSON file.
- * @param tree output property tree.
- *
- * @return an instance of Status, indicating success or failure if malformed.
- */
-Status parseJSON(const boost::filesystem::path& path,
-                 boost::property_tree::ptree& tree);
-
-/**
- * @brief Parse JSON content into a property tree.
- *
- * @param content JSON string data.
- * @param tree output property tree.
- *
- * @return an instance of Status, indicating success or failure if malformed.
- */
-Status parseJSONContent(const std::string& content,
-                        boost::property_tree::ptree& tree);
-
-#ifdef __linux__
-/**
- * @brief Iterate over `/proc` process, returns a list of pids.
- *
- * @param processes output list of process pids as strings (int paths in proc).
- *
- * @return an instance of Status, indicating success or failure.
- */
-Status procProcesses(std::set<std::string>& processes);
-
-/**
- * @brief Iterate over a `/proc` process's descriptors, return a list of fds.
- *
- * @param process a string pid from proc.
- * @param descriptors output list of descriptor numbers as strings.
- *
- * @return status of iteration, failure if the process path did not exist.
- */
-Status procDescriptors(const std::string& process,
-                       std::map<std::string, std::string>& descriptors);
-
-/**
- * @brief Read a descriptor's virtual path.
- *
- * @param process a string pid from proc.
- * @param descriptor a string descriptor number for a proc.
- * @param result output variable with value of link.
- *
- * @return status of read, failure on permission error or filesystem error.
- */
-Status procReadDescriptor(const std::string& process,
-                          const std::string& descriptor,
-                          std::string& result);
-
-/**
- * @brief Read bytes from Linux's raw memory.
- *
- * Most Linux kernels include a device node /dev/mem that allows privileged
- * users to map or seek/read pages of physical memory.
- * osquery discourages the use of physical memory reads for security and
- * performance reasons and must first try safer methods for data parsing
- * such as /sys and /proc.
- *
- * A platform user may disable physical memory reads:
- *   --disable_memory=true
- * This flag/option will cause readRawMemory to forcefully fail.
- *
- * @param base The absolute memory address to read from. This does not need
- * to be page aligned, readRawMem will take care of alignment and only
- * return the requested start address and size.
- * @param length The length of the buffer with a max of 0x10000.
- * @param buffer The output buffer, caller is responsible for resources if
- * readRawMem returns success.
- * @return status The status of the read.
- */
-Status readRawMem(size_t base, size_t length, void** buffer);
-#endif
-
-} // namespace osquery
diff --git a/src/osquery/filesystem/linux/mem.cpp b/src/osquery/filesystem/linux/mem.cpp
deleted file mode 100644 (file)
index 645b1f2..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-/**
- *  Copyright (c) 2014-present, Facebook, Inc.
- *  All rights reserved.
- *
- *  This source code is licensed in accordance with the terms specified in
- *  the LICENSE file found in the root directory of this source tree.
- */
-
-#include <sys/mman.h>
-#include <sys/types.h>
-
-#include <errno.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-#include <osquery/filesystem/filesystem.h>
-#include <osquery/logger.h>
-
-namespace osquery {
-
-#define kLinuxMaxMemRead 0x10000
-
-const std::string kLinuxMemPath = "/dev/mem";
-
-Status readMem(int fd, size_t base, size_t length, uint8_t* buffer) {
-  if (lseek(fd, base, SEEK_SET) == -1) {
-    return Status(1, "Cannot seek to physical base");
-  }
-
-  // Read from raw memory until an unrecoverable read error or the all of the
-  // requested bytes are read.
-  size_t total_read = 0;
-  ssize_t bytes_read = -1;
-  while (total_read != length && bytes_read != 0) {
-    bytes_read = read(fd, buffer + total_read, length - total_read);
-    if (bytes_read == -1) {
-      if (errno != EINTR) {
-        return Status(1, "Cannot read requested length");
-      }
-    } else {
-      total_read += bytes_read;
-    }
-  }
-
-  // The read call finished without reading the requested number of bytes.
-  if (total_read != length) {
-    return Status(1, "Read incorrect number of bytes");
-  }
-
-  return Status::success();
-}
-
-Status readRawMem(size_t base, size_t length, void** buffer) {
-  *buffer = 0;
-
-  if (length > kLinuxMaxMemRead) {
-    return Status(1, "Cowardly refusing to read a large number of bytes");
-  }
-
-  auto status = isReadable(kLinuxMemPath);
-  if (!status.ok()) {
-    // For non-su users *hopefully* raw memory is not readable.
-    return status;
-  }
-
-  int fd = open(kLinuxMemPath.c_str(), O_RDONLY);
-  if (fd < 0) {
-    return Status(1, std::string("Cannot open ") + kLinuxMemPath);
-  }
-
-  if ((*buffer = malloc(length)) == nullptr) {
-    close(fd);
-    return Status(1, "Cannot allocate memory for read");
-  }
-
-#ifdef _SC_PAGESIZE
-  size_t offset = base % sysconf(_SC_PAGESIZE);
-#else
-  // getpagesize() is more or less deprecated.
-  size_t offset = base % getpagesize();
-#endif
-
-  // Use memmap for maximum portability over read().
-  auto map = mmap(0, offset + length, PROT_READ, MAP_SHARED, fd, base - offset);
-  if (map == MAP_FAILED) {
-    // Could fallback to a lseek/read.
-    if (!readMem(fd, base, length, (uint8_t*)*buffer).ok()) {
-      close(fd);
-      free(*buffer);
-      *buffer = nullptr;
-      return Status(1, "Cannot memory map or seek/read memory");
-    }
-  } else {
-    // Memory map succeeded, copy and unmap.
-    memcpy(*buffer, (uint8_t*)map + offset, length);
-    if (munmap(map, offset + length) == -1) {
-      LOG(WARNING) << "Unable to unmap raw memory";
-    }
-  }
-
-  close(fd);
-  return Status::success();
-}
-}
diff --git a/src/osquery/filesystem/linux/proc.cpp b/src/osquery/filesystem/linux/proc.cpp
deleted file mode 100644 (file)
index 5a10b76..0000000
+++ /dev/null
@@ -1,342 +0,0 @@
-/**
- *  Copyright (c) 2014-present, Facebook, Inc.
- *  All rights reserved.
- *
- *  This source code is licensed in accordance with the terms specified in
- *  the LICENSE file found in the root directory of this source tree.
- */
-
-#include <linux/limits.h>
-#include <unistd.h>
-
-#include <boost/filesystem.hpp>
-
-#include <osquery/logger.h>
-#include <osquery/filesystem/filesystem.h>
-#include <osquery/filesystem/linux/proc.h>
-#include <osquery/utils/conversions/split.h>
-
-
-namespace osquery {
-const std::vector<std::string> kUserNamespaceList = {
-    "cgroup", "ipc", "mnt", "net", "pid", "user", "uts"};
-
-Status procGetNamespaceInode(ino_t& inode,
-                             const std::string& namespace_name,
-                             const std::string& process_namespace_root) {
-  inode = 0;
-
-  auto path = process_namespace_root + "/" + namespace_name;
-
-  char link_destination[PATH_MAX] = {};
-  auto link_dest_length = readlink(path.data(), link_destination, PATH_MAX - 1);
-  if (link_dest_length < 0) {
-    return Status(1, "Failed to retrieve the inode for namespace " + path);
-  }
-
-  // The link destination must be in the following form: namespace:[inode]
-  if (std::strncmp(link_destination,
-                   namespace_name.data(),
-                   namespace_name.size()) != 0 ||
-      std::strncmp(link_destination + namespace_name.size(), ":[", 2) != 0) {
-    return Status(1, "Invalid descriptor for namespace " + path);
-  }
-
-  // Parse the inode part of the string; strtoull should return us a pointer
-  // to the closing square bracket
-  const char* inode_string_ptr = link_destination + namespace_name.size() + 2;
-  char* square_bracket_ptr = nullptr;
-
-  inode = static_cast<ino_t>(
-      std::strtoull(inode_string_ptr, &square_bracket_ptr, 10));
-  if (inode == 0 || square_bracket_ptr == nullptr ||
-      *square_bracket_ptr != ']') {
-    return Status(1, "Invalid inode value in descriptor for namespace " + path);
-  }
-
-  return Status::success();
-}
-
-Status procGetProcessNamespaces(const std::string& process_id,
-                                ProcessNamespaceList& namespace_list,
-                                std::vector<std::string> namespaces) {
-  namespace_list.clear();
-
-  if (namespaces.empty()) {
-    namespaces = kUserNamespaceList;
-  }
-
-  auto process_namespace_root = kLinuxProcPath + "/" + process_id + "/ns";
-
-  for (const auto& namespace_name : namespaces) {
-    ino_t namespace_inode;
-    auto status = procGetNamespaceInode(
-        namespace_inode, namespace_name, process_namespace_root);
-    if (!status.ok()) {
-      continue;
-    }
-
-    namespace_list[namespace_name] = namespace_inode;
-  }
-
-  return Status::success();
-}
-
-std::string procDecodeAddressFromHex(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 std::string(addr_buffer);
-}
-
-unsigned short procDecodePortFromHex(const std::string& encoded_port) {
-  unsigned short decoded = 0;
-  if (encoded_port.length() == 4) {
-    sscanf(encoded_port.c_str(), "%hX", &decoded);
-  }
-  return decoded;
-}
-
-static Status procGetSocketListInet(int family,
-                                    int protocol,
-                                    ino_t net_ns,
-                                    const std::string& path,
-                                    const std::string& content,
-                                    SocketInfoList& result) {
-  // The system's socket information is tokenized by line.
-  bool header = true;
-  for (const auto& line : osquery::split(content, "\n")) {
-    if (header) {
-      if (line.find("sl") != 0 && line.find("sk") != 0) {
-        return Status(1, std::string("Invalid file header for ") + path);
-      }
-      header = false;
-      continue;
-    }
-
-    // The socket information is tokenized by spaces, each a field.
-    auto fields = osquery::split(line, " ");
-    if (fields.size() < 10) {
-      VLOG(1) << "Invalid socket descriptor found: '" << line
-              << "'. Skipping this entry";
-      continue;
-    }
-
-    // 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) {
-      VLOG(1) << "Invalid socket descriptor found: '" << line
-              << "'. Skipping this entry";
-      continue;
-    }
-
-    SocketInfo socket_info = {};
-    socket_info.socket = fields[9];
-    socket_info.net_ns = net_ns;
-    socket_info.family = family;
-    socket_info.protocol = protocol;
-    socket_info.local_address = procDecodeAddressFromHex(locals[0], family);
-    socket_info.local_port = procDecodePortFromHex(locals[1]);
-    socket_info.remote_address = procDecodeAddressFromHex(remotes[0], family);
-    socket_info.remote_port = procDecodePortFromHex(remotes[1]);
-
-    if (protocol == IPPROTO_TCP) {
-      char* null_terminator_ptr = nullptr;
-      auto integer_socket_state =
-          std::strtoull(fields[3].data(), &null_terminator_ptr, 16);
-      if (integer_socket_state == 0 ||
-          integer_socket_state >= tcp_states.size() ||
-          null_terminator_ptr == nullptr || *null_terminator_ptr != 0) {
-        socket_info.state = "UNKNOWN";
-      } else {
-        socket_info.state = tcp_states[integer_socket_state];
-      }
-    }
-
-    result.push_back(std::move(socket_info));
-  }
-
-  return Status(0);
-}
-
-static Status procGetSocketListUnix(ino_t net_ns,
-                                    const std::string& path,
-                                    const std::string& content,
-                                    SocketInfoList& result) {
-  // The system's socket information is tokenized by line.
-  bool header = true;
-  for (const auto& line : osquery::split(content, "\n")) {
-    if (header) {
-      if (line.find("Num") != 0) {
-        return Status(1, std::string("Invalid file header for ") + path);
-      }
-      header = false;
-      continue;
-    }
-
-    // The socket information is tokenized by spaces, each a field.
-    auto fields = osquery::split(line, " ");
-    if (fields.size() < 7) {
-      VLOG(1) << "Invalid UNIX socket descriptor found: '" << line
-              << "'. Skipping this entry";
-      continue;
-    }
-
-    SocketInfo socket_info = {};
-    socket_info.socket = fields[6];
-    socket_info.net_ns = net_ns;
-    socket_info.family = AF_UNIX;
-    socket_info.protocol = std::atoll(fields[2].data());
-    socket_info.unix_socket_path = (fields.size() >= 8) ? fields[7] : "";
-
-    result.push_back(std::move(socket_info));
-  }
-
-  return Status(0);
-}
-
-Status procGetSocketList(int family,
-                         int protocol,
-                         ino_t net_ns,
-                         const std::string& pid,
-                         SocketInfoList& result) {
-  std::string path = kLinuxProcPath + "/" + pid + "/net/";
-
-  switch (family) {
-  case AF_INET:
-    if (kLinuxProtocolNames.count(protocol) == 0) {
-      return Status(1,
-                    "Invalid family " + std::to_string(protocol) +
-                        " for AF_INET familiy");
-    } else {
-      path += kLinuxProtocolNames.at(protocol);
-    }
-    break;
-
-  case AF_INET6:
-    if (kLinuxProtocolNames.count(protocol) == 0) {
-      return Status(1,
-                    "Invalid protocol " + std::to_string(protocol) +
-                        " for AF_INET6 familiy");
-    } else {
-      path += kLinuxProtocolNames.at(protocol) + "6";
-    }
-    break;
-
-  case AF_UNIX:
-    if (protocol != IPPROTO_IP) {
-      return Status(1,
-                    "Invalid protocol " + std::to_string(protocol) +
-                        " for AF_UNIX familiy");
-    } else {
-      path += "unix";
-    }
-
-    break;
-
-  default:
-    return Status(1, "Invalid family " + std::to_string(family));
-  }
-
-  std::string content;
-  if (!osquery::readFile(path, content).ok()) {
-    return Status(1, "Could not open socket information from " + path);
-  }
-
-  Status status(0);
-  switch (family) {
-  case AF_INET:
-  case AF_INET6:
-    status =
-        procGetSocketListInet(family, protocol, net_ns, path, content, result);
-    break;
-
-  case AF_UNIX:
-    status = procGetSocketListUnix(net_ns, path, content, result);
-    break;
-  }
-
-  return status;
-}
-
-Status procGetSocketInodeToProcessInfoMap(const std::string& pid,
-                                          SocketInodeToProcessInfoMap& result) {
-  auto callback = [](const std::string& _pid,
-                     const std::string& fd,
-                     const std::string& link,
-                     SocketInodeToProcessInfoMap& _result) -> bool {
-    /* We only care about sockets. But there will be other descriptors. */
-    if (link.find("socket:[") != 0) {
-      return true;
-    }
-
-    std::string inode = link.substr(8, link.size() - 9);
-    _result[inode] = {_pid, fd};
-    return true;
-  };
-
-  return procEnumerateProcessDescriptors<decltype(result)>(
-      pid, result, callback);
-}
-
-Status procProcesses(std::set<std::string>& processes) {
-  auto callback = [](const std::string& pid,
-                     std::set<std::string>& _processes) -> bool {
-    _processes.insert(pid);
-    return true;
-  };
-
-  return procEnumerateProcesses<decltype(processes)>(processes, callback);
-}
-
-Status procDescriptors(const std::string& process,
-                       std::map<std::string, std::string>& descriptors) {
-  auto callback = [](const std::string& pid,
-                     const std::string& fd,
-                     const std::string& link_name,
-                     std::map<std::string, std::string>& _descriptors) -> bool {
-    _descriptors[fd] = link_name;
-    return true;
-  };
-
-  return procEnumerateProcessDescriptors<decltype(descriptors)>(
-      process, descriptors, callback);
-}
-
-Status procReadDescriptor(const std::string& process,
-                          const std::string& descriptor,
-                          std::string& result) {
-  auto link = kLinuxProcPath + "/" + process + "/fd/" + descriptor;
-
-  char result_path[PATH_MAX] = {0};
-  auto size = readlink(link.c_str(), result_path, sizeof(result_path) - 1);
-  if (size >= 0) {
-    result = std::string(result_path);
-    return Status(0);
-  } else {
-    return Status(1, "Could not read path");
-  }
-}
-
-} // namespace osquery
diff --git a/src/osquery/filesystem/linux/proc.h b/src/osquery/filesystem/linux/proc.h
deleted file mode 100644 (file)
index 7d97750..0000000
+++ /dev/null
@@ -1,220 +0,0 @@
-/**
- *  Copyright (c) 2014-present, Facebook, Inc.
- *  All rights reserved.
- *
- *  This source code is licensed in accordance with the terms specified in
- *  the LICENSE file found in the root directory of this source tree.
- */
-
-#pragma once
-
-#include <unordered_map>
-
-#include <arpa/inet.h>
-#include <linux/limits.h>
-#include <unistd.h>
-
-#include <boost/filesystem.hpp>
-
-#include <osquery/filesystem/filesystem.h>
-#include <osquery/logger.h>
-#include <osquery/utils/conversions/tryto.h>
-
-namespace osquery {
-const std::string kLinuxProcPath = "/proc";
-
-struct SocketInfo final {
-  std::string socket;
-  ino_t net_ns;
-
-  int family{0};
-  int protocol{0};
-
-  std::string local_address;
-  std::uint16_t local_port{0U};
-
-  std::string remote_address;
-  std::uint16_t remote_port{0U};
-
-  std::string unix_socket_path;
-
-  std::string state;
-};
-typedef std::vector<SocketInfo> SocketInfoList;
-
-struct SocketProcessInfo final {
-  std::string pid;
-  std::string fd;
-};
-typedef std::map<std::string, SocketProcessInfo> SocketInodeToProcessInfoMap;
-
-// 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"},
-};
-
-const std::vector<std::string> tcp_states = {"UNKNOWN",
-                                             "ESTABLISHED",
-                                             "SYN_SENT",
-                                             "SYN_RECV",
-                                             "FIN_WAIT1",
-                                             "FIN_WAIT2",
-                                             "TIME_WAIT",
-                                             "CLOSED",
-                                             "CLOSE_WAIT",
-                                             "LAST_ACK",
-                                             "LISTEN",
-                                             "CLOSING"};
-
-using ProcessNamespaceList = std::map<std::string, ino_t>;
-
-Status procGetProcessNamespaces(
-    const std::string& process_id,
-    ProcessNamespaceList& namespace_list,
-    std::vector<std::string> namespaces = std::vector<std::string>());
-
-Status procReadDescriptor(const std::string& process,
-                          const std::string& descriptor,
-                          std::string& result);
-
-/// This function parses the inode value in the destination of a user namespace
-/// symlink; fail if the namespace name is now what we expect
-Status procGetNamespaceInode(ino_t& inode,
-                             const std::string& namespace_name,
-                             const std::string& process_namespace_root);
-
-std::string procDecodeAddressFromHex(const std::string& encoded_address,
-                                     int family);
-
-unsigned short procDecodePortFromHex(const std::string& encoded_port);
-
-/**
- * @brief Construct a map of socket inode number to socket information collected
- * from /proc/<pid>/net for a certain family and protocol under a certain pid.
- *
- * The output parameter result is used as-is, i.e. it IS NOT cleared beforehand,
- * so values will either be added or replace existing ones without check.
- *
- * @param family The socket family. One of AF_INET, AF_INET6 or AF_UNIX.
- * @param protocol The socket protocol. For AF_INET and AF_INET6 one of the keys
- * @param pid Query data for this pid.
- * of kLinuxProtocolNames. For AF_UNIX only IPPROTO_IP is valid.
- * @param result The output parameter.
- */
-Status procGetSocketList(int family,
-                         int protocol,
-                         ino_t net_ns,
-                         const std::string& pid,
-                         SocketInfoList& result);
-
-/**
- * @brief Construct a map of socket inode number to process information for the
- * process that owns the socket by reading entries under /proc/<pid>/fd.
- *
- * The output parameter result is used as-is, i.e. it IS NOT cleared beforehand,
- * so values will either be added or replace existing ones without check.
- *
- * @param pid The process of interests
- * @param result The output parameter.
- */
-Status procGetSocketInodeToProcessInfoMap(const std::string& pid,
-                                          SocketInodeToProcessInfoMap& result);
-
-/**
- * @brief Enumerate all pids in the system by listing pid numbers under /proc
- * and execute a callback for each one of them. The callback will receive the
- * pid and the user_data provided as argument.
- *
- * Notice there isn't any type of locking here so race conditions might occur,
- * e.g. a process is destroyed right before the callback being called.
- *
- * The loop will stop after the first callback failed, i.e. returned false.
- *
- * @param user_data User provided data to be passed to the callback
- * @param callback A pointer to the callback function
- */
-template <typename UserData>
-Status procEnumerateProcesses(UserData& user_data,
-                              bool (*callback)(const std::string&, UserData&)) {
-  boost::filesystem::directory_iterator it(kLinuxProcPath), end;
-
-  try {
-    for (; it != end; ++it) {
-      if (!boost::filesystem::is_directory(it->status())) {
-        continue;
-      }
-
-      // See #792: std::regex is incomplete until GCC 4.9
-      const auto& pid = it->path().leaf().string();
-      if (std::atoll(pid.data()) <= 0) {
-        continue;
-      }
-
-      bool ret = callback(pid, user_data);
-      if (ret == false) {
-        break;
-      }
-    }
-  } catch (const boost::filesystem::filesystem_error& e) {
-    VLOG(1) << "Exception iterating Linux processes: " << e.what();
-    return Status(1, e.what());
-  }
-
-  return Status(0);
-}
-
-/**
- * @brief Enumerate all file descriptors of a certain process identified by its
- * pid by listing files under /proc/<pid>/fd and execute a callback for each one
- * of them. The callback will receive the pid the file descriptor and the real
- * path the file descriptor links to, and the user_data provided as argument.
- *
- * Notice there isn't any type of locking here so race conditions might occur,
- * e.g. a socket is closed right before the callback being called.
- *
- * The loop will stop after the first callback failed, i.e. returned false.
- *
- * @param pid The process id of interest
- * @param user_data User provided data to be passed to the callback
- * @param callback A pointer to the callback function
- */
-template <typename UserData>
-Status procEnumerateProcessDescriptors(const std::string& pid,
-                                       UserData& user_data,
-                                       bool (*callback)(const std::string& pid,
-                                                        const std::string& fd,
-                                                        const std::string& link,
-                                                        UserData& user_data)) {
-  std::string descriptors_path = kLinuxProcPath + "/" + pid + "/fd";
-
-  try {
-    boost::filesystem::directory_iterator it(descriptors_path), end;
-
-    for (; it != end; ++it) {
-      auto fd = it->path().leaf().string();
-
-      std::string link;
-      Status status = procReadDescriptor(pid, fd, link);
-      if (!status.ok()) {
-        VLOG(1) << "Failed to read the link for file descriptor " << fd
-                << " of pid " << pid << ". Data might be incomplete.";
-      }
-
-      bool ret = callback(pid, fd, link, user_data);
-      if (ret == false) {
-        break;
-      }
-    }
-  } catch (boost::filesystem::filesystem_error& e) {
-    VLOG(1) << "Exception iterating process file descriptors: " << e.what();
-    return Status(1, e.what());
-  }
-
-  return Status(0);
-}
-
-} // namespace osquery
diff --git a/src/osquery/filesystem/mock_file_structure.cpp b/src/osquery/filesystem/mock_file_structure.cpp
deleted file mode 100644 (file)
index a4d9ee3..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-/**
- *  Copyright (c) 2014-present, Facebook, Inc.
- *  All rights reserved.
- *
- *  This source code is licensed in accordance with the terms specified in
- *  the LICENSE file found in the root directory of this source tree.
- */
-
-#include <osquery/filesystem/filesystem.h>
-
-#include <boost/filesystem/path.hpp>
-
-namespace osquery {
-
-namespace fs = boost::filesystem;
-
-fs::path createMockFileStructure() {
-  const auto root_dir =
-      fs::temp_directory_path() /
-      fs::unique_path("osquery.tests.%%%%.%%%%");
-  fs::create_directories(root_dir / "toplevel/");
-  fs::create_directories(root_dir / "toplevel/secondlevel1");
-  fs::create_directories(root_dir / "toplevel/secondlevel2");
-  fs::create_directories(root_dir / "toplevel/secondlevel3");
-  fs::create_directories(root_dir / "toplevel/secondlevel3/thirdlevel1");
-  fs::create_directories(root_dir / "deep11/deep2/deep3/");
-  fs::create_directories(root_dir / "deep1/deep2/");
-  writeTextFile(root_dir / "root.txt", "root");
-  writeTextFile(root_dir / "door.txt", "toor", 0550);
-  writeTextFile(root_dir / "roto.txt", "roto");
-  writeTextFile(root_dir / "deep1/level1.txt", "l1");
-  writeTextFile(root_dir / "deep11/not_bash", "l1");
-  writeTextFile(root_dir / "deep1/deep2/level2.txt", "l2");
-
-  writeTextFile(root_dir / "deep11/level1.txt", "l1");
-  writeTextFile(root_dir / "deep11/deep2/level2.txt", "l2");
-  writeTextFile(root_dir / "deep11/deep2/deep3/level3.txt", "l3");
-
-#ifdef WIN32
-  writeTextFile(root_dir / "root2.txt", "l1");
-#else
-  boost::system::error_code ec;
-  fs::create_symlink(
-      root_dir / "root.txt", root_dir / "root2.txt", ec);
-#endif
-  return root_dir;
-}
-
-} // namespace osquery
diff --git a/src/osquery/filesystem/mock_file_structure.h b/src/osquery/filesystem/mock_file_structure.h
deleted file mode 100644 (file)
index 82375d4..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-/**
- *  Copyright (c) 2014-present, Facebook, Inc.
- *  All rights reserved.
- *
- *  This source code is licensed in accordance with the terms specified in
- *  the LICENSE file found in the root directory of this source tree.
- */
-
-#pragma once
-
-#include <boost/filesystem/path.hpp>
-
-namespace osquery {
-
-// generate a small directory structure for testing
-boost::filesystem::path createMockFileStructure();
-
-} // namespace
diff --git a/src/osquery/filesystem/posix/fileops.cpp b/src/osquery/filesystem/posix/fileops.cpp
deleted file mode 100644 (file)
index 0892aa1..0000000
+++ /dev/null
@@ -1,379 +0,0 @@
-/**
- *  Copyright (c) 2014-present, Facebook, Inc.
- *  All rights reserved.
- *
- *  This source code is licensed in accordance with the terms specified in
- *  the LICENSE file found in the root directory of this source tree.
- */
-
-#include <osquery/filesystem/filesystem.h>
-#include <osquery/filesystem/fileops.h>
-
-#include <glob.h>
-#include <pwd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <sys/types.h>
-
-#include <boost/filesystem.hpp>
-#include <boost/optional.hpp>
-
-namespace fs = boost::filesystem;
-namespace errc = boost::system::errc;
-
-namespace osquery {
-
-PlatformFile::PlatformFile(const fs::path& path, int mode, int perms)
-    : fname_(path) {
-  int oflag = 0;
-  bool may_create = false;
-  bool check_existence = false;
-
-  if ((mode & PF_READ) == PF_READ && (mode & PF_WRITE) == PF_WRITE) {
-    oflag = O_RDWR;
-  } else if ((mode & PF_READ) == PF_READ) {
-    oflag = O_RDONLY;
-  } else if ((mode & PF_WRITE) == PF_WRITE) {
-    oflag = O_WRONLY;
-  }
-
-  switch (PF_GET_OPTIONS(mode)) {
-  case PF_GET_OPTIONS(PF_CREATE_ALWAYS):
-    oflag |= O_CREAT | O_TRUNC;
-    may_create = true;
-    break;
-  case PF_GET_OPTIONS(PF_CREATE_NEW):
-    oflag |= O_CREAT | O_EXCL;
-    may_create = true;
-    break;
-  case PF_GET_OPTIONS(PF_OPEN_EXISTING):
-    check_existence = true;
-    break;
-  case PF_GET_OPTIONS(PF_OPEN_ALWAYS):
-    oflag |= O_CREAT;
-    may_create = true;
-    break;
-  case PF_GET_OPTIONS(PF_TRUNCATE):
-    if (mode & PF_WRITE) {
-      oflag |= O_TRUNC;
-    }
-
-    break;
-  default:
-    break;
-  }
-
-  if ((mode & PF_NONBLOCK) == PF_NONBLOCK) {
-    oflag |= O_NONBLOCK;
-    is_nonblock_ = true;
-  }
-
-  if ((mode & PF_APPEND) == PF_APPEND) {
-    oflag |= O_APPEND;
-  }
-
-  if (perms == -1 && may_create) {
-    perms = 0666;
-  }
-
-  boost::system::error_code ec;
-  if (check_existence &&
-      (!fs::exists(fname_, ec) || ec.value() != errc::success)) {
-    handle_ = kInvalidHandle;
-  } else {
-    handle_ = ::open(fname_.c_str(), oflag, perms);
-  }
-}
-
-PlatformFile::~PlatformFile() {
-  if (handle_ != kInvalidHandle) {
-    ::close(handle_);
-    handle_ = kInvalidHandle;
-  }
-}
-
-bool PlatformFile::isSpecialFile() const {
-  return (size() == 0);
-}
-
-static uid_t getFileOwner(PlatformHandle handle) {
-  struct stat file;
-  if (::fstat(handle, &file) < 0) {
-    return -1;
-  }
-  return file.st_uid;
-}
-
-Status PlatformFile::isOwnerRoot() const {
-  if (!isValid()) {
-    return Status(-1, "Invalid handle_");
-  }
-
-  uid_t owner_id = getFileOwner(handle_);
-  if (owner_id == (uid_t)-1) {
-    return Status(-1, "fstat error");
-  }
-
-  if (owner_id == 0) {
-    return Status::success();
-  }
-  return Status(1, "Owner is not root");
-}
-
-Status PlatformFile::isOwnerCurrentUser() const {
-  if (!isValid()) {
-    return Status(-1, "Invalid handle_");
-  }
-
-  uid_t owner_id = getFileOwner(handle_);
-  if (owner_id == (uid_t)-1) {
-    return Status(-1, "fstat error");
-  }
-
-  if (owner_id == ::getuid()) {
-    return Status::success();
-  }
-
-  return Status(1, "Owner is not current user");
-}
-
-Status PlatformFile::isExecutable() const {
-  struct stat file_stat;
-  if (::fstat(handle_, &file_stat) < 0) {
-    return Status(-1, "fstat error");
-  }
-
-  if ((file_stat.st_mode & S_IXUSR) == S_IXUSR) {
-    return Status::success();
-  }
-
-  return Status(1, "Not executable");
-}
-
-Status PlatformFile::hasSafePermissions() const {
-  struct stat file;
-  if (::fstat(handle_, &file) < 0) {
-    return Status(-1, "fstat error");
-  }
-
-  // We allow user write for now, since our main threat is external
-  // modification by other users
-  if ((file.st_mode & S_IWOTH) == 0) {
-    return Status::success();
-  }
-
-  return Status(1, "Writable");
-}
-
-bool PlatformFile::getFileTimes(PlatformTime& times) {
-  if (!isValid()) {
-    return false;
-  }
-
-  struct stat file;
-  if (::fstat(handle_, &file) < 0) {
-    return false;
-  }
-
-#if defined(__linux__)
-  TIMESPEC_TO_TIMEVAL(&times.times[0], &file.st_atim);
-  TIMESPEC_TO_TIMEVAL(&times.times[1], &file.st_mtim);
-#else
-  TIMESPEC_TO_TIMEVAL(&times.times[0], &file.st_atimespec);
-  TIMESPEC_TO_TIMEVAL(&times.times[1], &file.st_mtimespec);
-#endif
-
-  return true;
-}
-
-bool PlatformFile::setFileTimes(const PlatformTime& times) {
-  if (!isValid()) {
-    return false;
-  }
-
-  return (::futimes(handle_, times.times) == 0);
-}
-
-ssize_t PlatformFile::read(void* buf, size_t nbyte) {
-  if (!isValid()) {
-    return -1;
-  }
-
-  has_pending_io_ = false;
-  auto ret = ::read(handle_, buf, nbyte);
-  if (ret < 0 && errno == EAGAIN) {
-    has_pending_io_ = true;
-  } else if (ret > 0 && static_cast<size_t>(ret) < nbyte) {
-    // This handles a (bug?) in Linux where special files are labeled as normal
-    // for example: /sys nodes that must be read in pages.
-    has_pending_io_ = true;
-  }
-
-  return ret;
-}
-
-ssize_t PlatformFile::write(const void* buf, size_t nbyte) {
-  if (!isValid()) {
-    return -1;
-  }
-
-  has_pending_io_ = false;
-  auto ret = ::write(handle_, buf, nbyte);
-  if (ret < 0 && errno == EAGAIN) {
-    has_pending_io_ = true;
-  }
-  return ret;
-}
-
-off_t PlatformFile::seek(off_t offset, SeekMode mode) {
-  if (!isValid()) {
-    return -1;
-  }
-
-  int whence = 0;
-  switch (mode) {
-  case PF_SEEK_BEGIN:
-    whence = SEEK_SET;
-    break;
-  case PF_SEEK_CURRENT:
-    whence = SEEK_CUR;
-    break;
-  case PF_SEEK_END:
-    whence = SEEK_END;
-    break;
-  default:
-    break;
-  }
-  return ::lseek(handle_, offset, whence);
-}
-
-size_t PlatformFile::size() const {
-  struct stat file;
-  if (::fstat(handle_, &file) < 0) {
-    // This is an error case, but the size is not signed.
-    return 0;
-  }
-  return file.st_size;
-}
-
-boost::optional<std::string> getHomeDirectory() {
-  // Try to get the caller's home directory using HOME and getpwuid.
-  auto user = ::getpwuid(getuid());
-  auto homedir = getEnvVar("HOME");
-  if (homedir.is_initialized()) {
-    // Fail over to the users home directory if HOME is not writable.
-    if (isWritable(*homedir)) {
-      return homedir;
-    }
-  }
-
-  if (user != nullptr && user->pw_dir != nullptr) {
-    return std::string(user->pw_dir);
-  } else {
-    return boost::none;
-  }
-}
-
-bool platformSetSafeDbPerms(const std::string& path) {
-  return platformChmod(path, S_IRWXU);
-}
-
-bool platformChmod(const std::string& path, mode_t perms) {
-  return (::chmod(path.c_str(), perms) == 0);
-}
-
-std::vector<std::string> platformGlob(const std::string& find_path) {
-  std::vector<std::string> results;
-
-  glob_t data;
-  ::glob(
-      find_path.c_str(), GLOB_TILDE | GLOB_MARK | GLOB_BRACE, nullptr, &data);
-  size_t count = data.gl_pathc;
-
-  for (size_t index = 0; index < count; index++) {
-    results.push_back(data.gl_pathv[index]);
-  }
-
-  ::globfree(&data);
-  return results;
-}
-
-int platformAccess(const std::string& path, mode_t mode) {
-  return ::access(path.c_str(), mode);
-}
-
-Status platformIsTmpDir(const fs::path& dir) {
-  struct stat dir_stat;
-  if (::stat(dir.c_str(), &dir_stat) < 0) {
-    return Status(-1, "");
-  }
-
-  if (dir_stat.st_mode & (1 << 9)) {
-    return Status::success();
-  }
-
-  return Status(1, "");
-}
-
-// Reduce this to be a lstat check for symlink stuff
-Status platformIsFileAccessible(const fs::path& path) {
-  struct stat link_stat;
-  if (::lstat(path.c_str(), &link_stat) < 0) {
-    return Status(1, "File is not acccessible");
-  }
-  return Status::success();
-}
-
-bool platformIsatty(FILE* f) {
-  return 0 != isatty(fileno(f));
-}
-
-boost::optional<FILE*> platformFopen(const std::string& filename,
-                                     const std::string& mode) {
-  auto fp = ::fopen(filename.c_str(), mode.c_str());
-  if (fp == nullptr) {
-    return boost::none;
-  }
-
-  return fp;
-}
-
-Status socketExists(const fs::path& path, bool remove_socket) {
-  // This implies that the socket is writable.
-  if (pathExists(path).ok()) {
-    if (!isWritable(path).ok()) {
-      return Status(1, "Cannot write extension socket: " + path.string());
-    } else if (remove_socket && !removePath(path).ok()) {
-      return Status(1, "Cannot remove extension socket: " + path.string());
-    }
-  } else {
-    // The path does not exist.
-    if (!pathExists(path.parent_path()).ok()) {
-      return Status(1, "Extension socket directory missing: " + path.string());
-    } else if (!isWritable(path.parent_path()).ok()) {
-      return Status(1, "Cannot create extension socket: " + path.string());
-    }
-
-    // If we are not requesting to remove the socket then this is a failure.
-    if (!remove_socket) {
-      return Status(1, "Socket does not exist");
-    }
-  }
-  return Status(0);
-}
-
-fs::path getSystemRoot() {
-  return fs::path("/");
-}
-
-Status platformLstat(const std::string& path, struct stat& d_stat) {
-  if (::lstat(path.c_str(), &d_stat) < 0) {
-    return Status(1);
-  }
-  return Status(0);
-}
-}
diff --git a/src/osquery/filesystem/tests/fileops.cpp b/src/osquery/filesystem/tests/fileops.cpp
deleted file mode 100644 (file)
index d0fdce0..0000000
+++ /dev/null
@@ -1,770 +0,0 @@
-/**
- *  Copyright (c) 2014-present, Facebook, Inc.
- *  All rights reserved.
- *
- *  This source code is licensed in accordance with the terms specified in
- *  the LICENSE file found in the root directory of this source tree.
- */
-
-#include <osquery/filesystem/fileops.h>
-
-#include <osquery/filesystem/mock_file_structure.h>
-
-#include <osquery/utils/info/platform_type.h>
-#include <osquery/utils/scope_guard.h>
-
-#include <gtest/gtest.h>
-
-#include <boost/filesystem.hpp>
-
-
-namespace fs = boost::filesystem;
-
-namespace osquery {
-
-class FileOpsTests : public testing::Test {
- protected:
-  fs::path fake_directory_;
-
-  void SetUp() override {
-    fake_directory_ = createMockFileStructure();
-  }
-
-  void TearDown() override {
-    fs::remove_all(fake_directory_);
-  }
-
-  bool globResultsMatch(const std::vector<std::string>& results,
-                        const std::vector<fs::path>& expected) {
-    // Sets cannot be the same if they are different sizes
-    if (results.size() != expected.size()) {
-      return false;
-    }
-    // Convert the data structure to a set for better searching
-    std::set<std::string> results_set;
-    for (const auto& res : results) {
-      results_set.insert(res);
-    }
-
-    for (auto res : expected) {
-      const auto loc = results_set.find(res.make_preferred().string());
-      // Unable to find element (something is in expected but not results)
-      if (loc == results_set.end()) {
-        return false;
-      }
-      // Pair found so remove from results
-      results_set.erase(loc);
-    }
-
-    // There are unremoved values so expected is a proper subset of results
-    if (!results_set.empty()) {
-      return false;
-    }
-    return true;
-  }
-};
-
-class TempFile {
- public:
-  TempFile() {
-    do {
-      path_ = generateTempPath();
-    } while (fs::exists(path_));
-  }
-
-  ~TempFile() {
-    if (fs::exists(path_)) {
-      fs::remove(path_);
-    }
-  }
-
-  const std::string& path() const {
-    return path_;
-  }
-
- private:
-  static std::string generateTempPath() {
-    return (fs::temp_directory_path() / fs::unique_path("osquery-%%%%-%%%%"))
-        .make_preferred()
-        .string();
-  }
-
- private:
-  std::string path_;
-};
-
-TEST_F(FileOpsTests, test_openFile) {
-  TempFile tmp_file;
-  std::string path = tmp_file.path();
-
-  {
-    PlatformFile fd(path, PF_OPEN_EXISTING | PF_READ);
-    EXPECT_FALSE(fd.isValid());
-  }
-
-  {
-    PlatformFile fd(path, PF_CREATE_NEW | PF_WRITE);
-    EXPECT_TRUE(fd.isValid());
-  }
-
-  {
-    PlatformFile fd(path, PF_CREATE_NEW | PF_READ);
-    EXPECT_FALSE(fd.isValid());
-  }
-
-  fs::remove(path);
-
-  {
-    PlatformFile fd(path, PF_CREATE_ALWAYS | PF_READ);
-    EXPECT_TRUE(fd.isValid());
-  }
-
-  {
-    PlatformFile fd(path, PF_CREATE_ALWAYS | PF_READ);
-    EXPECT_TRUE(fd.isValid());
-  }
-
-  {
-    PlatformFile fd(path, PF_OPEN_EXISTING | PF_READ);
-    EXPECT_TRUE(fd.isValid());
-  }
-}
-
-/*
- * This is a special function for testing file share operations on Windows. Our
- * PlatformFile as of now will only set FILE_SHARE_READ to play nicely with log
- * reading tools. However, we need to create one with FILE_SHARE_READ and
- * FILE_SHARE_WRITE for testing.
- */
-std::unique_ptr<PlatformFile> openRWSharedFile(const std::string& path,
-                                               int mode) {
-#ifdef WIN32
-  DWORD access_mask = -1;
-  DWORD creation_disposition = -1;
-
-  if (mode == (PF_OPEN_EXISTING | PF_READ)) {
-    access_mask = PF_READ;
-    creation_disposition = OPEN_EXISTING;
-  } else if (mode == (PF_OPEN_ALWAYS | PF_WRITE)) {
-    access_mask = PF_WRITE;
-    creation_disposition = OPEN_ALWAYS;
-  }
-
-  HANDLE handle = ::CreateFileA(path.c_str(),
-                                access_mask,
-                                FILE_SHARE_READ | FILE_SHARE_WRITE,
-                                nullptr,
-                                creation_disposition,
-                                0,
-                                nullptr);
-  return std::unique_ptr<PlatformFile>(new PlatformFile(handle));
-#else
-  return std::unique_ptr<PlatformFile>(new PlatformFile(path, mode));
-#endif
-}
-
-TEST_F(FileOpsTests, test_shareRead) {
-  TempFile tmp_file;
-  std::string path = tmp_file.path();
-
-  const char* test1_data = "AAAABBBB";
-  const ssize_t test1_size = ::strlen(test1_data);
-
-  {
-    PlatformFile fd(path, PF_CREATE_NEW | PF_WRITE);
-    ASSERT_TRUE(fd.isValid());
-    EXPECT_EQ(test1_size, fd.write(test1_data, test1_size));
-  }
-
-  {
-    auto reader_fd = openRWSharedFile(path, PF_OPEN_EXISTING | PF_READ);
-    ASSERT_TRUE(reader_fd->isValid());
-
-    std::vector<char> buf;
-    buf.assign(test1_size, '\0');
-
-    EXPECT_EQ(test1_size, reader_fd->read(buf.data(), test1_size));
-    EXPECT_EQ(static_cast<size_t>(test1_size), buf.size());
-
-    for (ssize_t i = 0; i < test1_size; i++) {
-      EXPECT_EQ(test1_data[i], buf[i]);
-    }
-
-    PlatformFile fd(path, PF_OPEN_ALWAYS | PF_WRITE | PF_APPEND);
-    EXPECT_TRUE(fd.isValid());
-  }
-}
-
-TEST_F(FileOpsTests, test_fileIo) {
-  TempFile tmp_file;
-  std::string path = tmp_file.path();
-
-  const char* expected_read = "AAAABBBBCCCCDDDD";
-  const ssize_t expected_read_len = ::strlen(expected_read);
-  const ssize_t expected_write_len = ::strlen(expected_read);
-  const size_t expected_buf_size = ::strlen(expected_read);
-
-  {
-    PlatformFile fd(path, PF_CREATE_NEW | PF_WRITE);
-    ASSERT_TRUE(fd.isValid());
-    EXPECT_EQ(expected_write_len, fd.write(expected_read, expected_read_len));
-  }
-
-  {
-    std::vector<char> buf(expected_read_len);
-    PlatformFile fd(path, PF_OPEN_EXISTING | PF_READ);
-    ASSERT_TRUE(fd.isValid());
-    ASSERT_FALSE(fd.isSpecialFile());
-    EXPECT_EQ(expected_read_len, fd.read(buf.data(), expected_read_len));
-    EXPECT_EQ(expected_buf_size, buf.size());
-    for (ssize_t i = 0; i < expected_read_len; i++) {
-      EXPECT_EQ(expected_read[i], buf[i]);
-    }
-  }
-}
-
-TEST_F(FileOpsTests, test_append) {
-  TempFile tmp_file;
-  std::string path = tmp_file.path();
-
-  const char* test_data = "AAAABBBBCCCCDDDDD";
-  const ssize_t test_size = ::strlen(test_data);
-  const ssize_t test1_size = 7;
-  const ssize_t test2_size = test_size - test1_size;
-
-  {
-    PlatformFile fd(path, PF_OPEN_ALWAYS | PF_WRITE | PF_APPEND);
-    ASSERT_TRUE(fd.isValid());
-    EXPECT_EQ(test1_size, fd.write(test_data, test1_size));
-  }
-
-  {
-    PlatformFile fd(path, PF_OPEN_ALWAYS | PF_WRITE | PF_APPEND);
-    ASSERT_TRUE(fd.isValid());
-    EXPECT_EQ(test2_size, fd.write(&test_data[7], test2_size));
-  }
-
-  {
-    PlatformFile fd(path, PF_OPEN_EXISTING | PF_READ);
-    ASSERT_TRUE(fd.isValid());
-
-    std::vector<char> buf;
-    buf.assign(test_size, '\0');
-    EXPECT_EQ(test_size, fd.read(buf.data(), test_size));
-    EXPECT_EQ(static_cast<size_t>(test_size), buf.size());
-
-    for (ssize_t i = 0; i < test_size; i++) {
-      EXPECT_EQ(test_data[i], buf[i]);
-    }
-  }
-}
-
-TEST_F(FileOpsTests, test_asyncIo) {
-  TempFile tmp_file;
-  std::string path = tmp_file.path();
-
-  const char* expected = "AAAABBBBCCCCDDDDEEEEFFFFGGGG";
-  const ssize_t expected_len = ::strlen(expected);
-
-  {
-    PlatformFile fd(path, PF_CREATE_NEW | PF_WRITE | PF_NONBLOCK);
-    ASSERT_TRUE(fd.isValid());
-    EXPECT_EQ(expected_len, fd.write(expected, expected_len));
-  }
-
-  {
-    PlatformFile fd(path, PF_OPEN_EXISTING | PF_READ | PF_NONBLOCK);
-    ASSERT_TRUE(fd.isValid());
-    ASSERT_FALSE(fd.isSpecialFile());
-
-    std::vector<char> buf(expected_len);
-    EXPECT_EQ(expected_len, fd.read(buf.data(), expected_len));
-    EXPECT_EQ(0, ::memcmp(expected, buf.data(), expected_len));
-  }
-
-  {
-    PlatformFile fd(path, PF_OPEN_EXISTING | PF_READ | PF_NONBLOCK);
-    ASSERT_TRUE(fd.isValid());
-    ASSERT_FALSE(fd.isSpecialFile());
-
-    std::vector<char> buf(expected_len);
-    char* ptr = buf.data();
-    ssize_t part_bytes = 0;
-    int iterations = 0;
-    do {
-      part_bytes = fd.read(ptr, 4);
-      if (part_bytes > 0) {
-        ptr += part_bytes;
-        iterations++;
-      }
-    } while (part_bytes > 0);
-
-    EXPECT_EQ(7, iterations);
-    EXPECT_EQ(0, ::memcmp(expected, buf.data(), expected_len));
-  }
-}
-
-TEST_F(FileOpsTests, test_seekFile) {
-  TempFile tmp_file;
-  std::string path = tmp_file.path();
-
-  const char* expected = "AABBBBAACCCAAAAADDDDAAAAAAAA";
-  const ssize_t expected_len = ::strlen(expected);
-  ssize_t expected_offs;
-
-  {
-    PlatformFile fd(path, PF_CREATE_ALWAYS | PF_WRITE);
-    ASSERT_TRUE(fd.isValid());
-    EXPECT_EQ(expected_len,
-              fd.write("AAAAAAAAAAAAAAAAAAAAAAAAAAAA", expected_len));
-  }
-
-  // Cast to the proper type, off_t
-  expected_offs = expected_len - 12;
-
-  {
-    PlatformFile fd(path, PF_OPEN_EXISTING | PF_WRITE);
-    ASSERT_TRUE(fd.isValid());
-
-    EXPECT_EQ(expected_offs, fd.seek(-12, PF_SEEK_END));
-    EXPECT_EQ(4, fd.write("DDDD", 4));
-
-    EXPECT_EQ(2, fd.seek(2, PF_SEEK_BEGIN));
-    EXPECT_EQ(4, fd.write("BBBB", 4));
-
-    EXPECT_EQ(8, fd.seek(2, PF_SEEK_CURRENT));
-    EXPECT_EQ(3, fd.write("CCC", 3));
-  }
-
-  {
-    std::vector<char> buffer(expected_len);
-
-    PlatformFile fd(path, PF_OPEN_EXISTING | PF_READ);
-    ASSERT_TRUE(fd.isValid());
-
-    EXPECT_EQ(expected_len, fd.read(buffer.data(), expected_len));
-    EXPECT_EQ(0, ::memcmp(buffer.data(), expected, expected_len));
-  }
-}
-
-TEST_F(FileOpsTests, test_large_read_write) {
-  TempFile tmp_file;
-  std::string path = tmp_file.path();
-
-  const std::string expected(20000000, 'A');
-  const ssize_t expected_len = expected.size();
-  ASSERT_EQ(strnlen(expected.data(), 20000001), 20000000U);
-
-  {
-    PlatformFile fd(path, PF_CREATE_ALWAYS | PF_WRITE);
-    ASSERT_TRUE(fd.isValid());
-    auto write_len = fd.write(expected.c_str(), expected_len);
-    EXPECT_EQ(expected_len, write_len);
-  }
-
-  {
-    std::vector<char> buffer(expected_len);
-    PlatformFile fd(path, PF_OPEN_EXISTING | PF_READ);
-    ASSERT_TRUE(fd.isValid());
-    auto read_len = fd.read(buffer.data(), expected_len);
-    EXPECT_EQ(expected_len, read_len);
-    EXPECT_EQ(expected, std::string(buffer.data(), buffer.size()));
-  }
-}
-
-TEST_F(FileOpsTests, test_chmod_no_exec) {
-  TempFile tmp_file;
-  std::string path = tmp_file.path();
-
-  {
-    PlatformFile fd(path, PF_CREATE_ALWAYS | PF_WRITE);
-    ASSERT_TRUE(fd.isValid());
-    EXPECT_EQ(4, fd.write("TEST", 4));
-  }
-
-  EXPECT_TRUE(platformChmod(path, S_IRUSR | S_IWUSR | S_IROTH | S_IWOTH));
-
-  {
-    PlatformFile fd(path, PF_OPEN_EXISTING | PF_READ);
-    ASSERT_TRUE(fd.isValid());
-
-    auto status = fd.isExecutable();
-    EXPECT_TRUE(!status.ok());
-    EXPECT_EQ(1, status.getCode());
-  }
-
-  EXPECT_TRUE(platformChmod(
-      path, S_IRUSR | S_IWUSR | S_IXUSR | S_IROTH | S_IWOTH | S_IXOTH));
-
-  {
-    PlatformFile fd(path, PF_OPEN_EXISTING | PF_READ);
-    ASSERT_TRUE(fd.isValid());
-
-    EXPECT_TRUE(fd.isExecutable().ok());
-  }
-}
-
-TEST_F(FileOpsTests, test_chmod_no_read) {
-  TempFile tmp_file;
-  std::string path = tmp_file.path();
-
-  {
-    PlatformFile fd(path, PF_CREATE_ALWAYS | PF_WRITE);
-    ASSERT_TRUE(fd.isValid());
-    EXPECT_EQ(4, fd.write("TEST", 4));
-  }
-
-  EXPECT_TRUE(platformChmod(path, S_IWUSR | S_IWOTH));
-
-  {
-    PlatformFile fd(path, PF_OPEN_EXISTING | PF_READ);
-    EXPECT_FALSE(fd.isValid());
-  }
-
-  {
-    PlatformFile fd(path, PF_OPEN_EXISTING | PF_WRITE);
-    EXPECT_TRUE(fd.isValid());
-  }
-}
-
-TEST_F(FileOpsTests, test_chmod_no_write) {
-  TempFile tmp_file;
-  std::string path = tmp_file.path();
-
-  {
-    PlatformFile fd(path, PF_CREATE_ALWAYS | PF_WRITE);
-    ASSERT_TRUE(fd.isValid());
-    EXPECT_EQ(4, fd.write("TEST", 4));
-  }
-
-  EXPECT_TRUE(platformChmod(path, S_IRUSR | S_IROTH));
-
-  {
-    PlatformFile fd(path, PF_OPEN_EXISTING | PF_READ);
-    EXPECT_TRUE(fd.isValid());
-  }
-
-  {
-    PlatformFile fd(path, PF_OPEN_EXISTING | PF_WRITE);
-    EXPECT_FALSE(fd.isValid());
-  }
-}
-
-TEST_F(FileOpsTests, test_access) {
-  const int all_access = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP |
-                         S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH;
-
-  TempFile tmp_file;
-  std::string path = tmp_file.path();
-
-  {
-    PlatformFile fd(path, PF_CREATE_ALWAYS | PF_WRITE);
-    ASSERT_TRUE(fd.isValid());
-    EXPECT_EQ(4, fd.write("TEST", 4));
-  }
-
-  EXPECT_TRUE(platformChmod(path, S_IRUSR | S_IWUSR | S_IXUSR));
-
-  EXPECT_EQ(0, platformAccess(path, R_OK | W_OK | X_OK));
-  EXPECT_EQ(0, platformAccess(path, R_OK | W_OK));
-  EXPECT_EQ(0, platformAccess(path, R_OK | X_OK));
-  EXPECT_EQ(0, platformAccess(path, W_OK | X_OK));
-  EXPECT_EQ(0, platformAccess(path, R_OK));
-  EXPECT_EQ(0, platformAccess(path, W_OK));
-  EXPECT_EQ(0, platformAccess(path, X_OK));
-
-  EXPECT_TRUE(platformChmod(path, S_IRUSR | S_IWUSR));
-
-  EXPECT_EQ(-1, platformAccess(path, R_OK | W_OK | X_OK));
-  EXPECT_EQ(0, platformAccess(path, R_OK | W_OK));
-  EXPECT_EQ(-1, platformAccess(path, R_OK | X_OK));
-  EXPECT_EQ(-1, platformAccess(path, W_OK | X_OK));
-  EXPECT_EQ(0, platformAccess(path, R_OK));
-  EXPECT_EQ(0, platformAccess(path, W_OK));
-  EXPECT_EQ(-1, platformAccess(path, X_OK));
-
-  EXPECT_TRUE(platformChmod(path, S_IRUSR | S_IXUSR));
-
-  EXPECT_EQ(-1, platformAccess(path, R_OK | W_OK | X_OK));
-  EXPECT_EQ(-1, platformAccess(path, R_OK | W_OK));
-  EXPECT_EQ(0, platformAccess(path, R_OK | X_OK));
-  EXPECT_EQ(-1, platformAccess(path, W_OK | X_OK));
-  EXPECT_EQ(0, platformAccess(path, R_OK));
-  EXPECT_EQ(-1, platformAccess(path, W_OK));
-  EXPECT_EQ(0, platformAccess(path, X_OK));
-
-  EXPECT_TRUE(platformChmod(path, S_IWUSR | S_IXUSR));
-
-  EXPECT_EQ(-1, platformAccess(path, R_OK | W_OK | X_OK));
-  EXPECT_EQ(-1, platformAccess(path, R_OK | W_OK));
-  EXPECT_EQ(-1, platformAccess(path, R_OK | X_OK));
-  EXPECT_EQ(0, platformAccess(path, W_OK | X_OK));
-  EXPECT_EQ(-1, platformAccess(path, R_OK));
-  EXPECT_EQ(0, platformAccess(path, W_OK));
-  EXPECT_EQ(0, platformAccess(path, X_OK));
-
-  EXPECT_TRUE(platformChmod(path, S_IRUSR));
-
-  EXPECT_EQ(-1, platformAccess(path, R_OK | W_OK | X_OK));
-  EXPECT_EQ(-1, platformAccess(path, R_OK | W_OK));
-  EXPECT_EQ(-1, platformAccess(path, R_OK | X_OK));
-  EXPECT_EQ(-1, platformAccess(path, W_OK | X_OK));
-  EXPECT_EQ(0, platformAccess(path, R_OK));
-  EXPECT_EQ(-1, platformAccess(path, W_OK));
-  EXPECT_EQ(-1, platformAccess(path, X_OK));
-
-  EXPECT_TRUE(platformChmod(path, S_IWUSR));
-
-  EXPECT_EQ(-1, platformAccess(path, R_OK | W_OK | X_OK));
-  EXPECT_EQ(-1, platformAccess(path, R_OK | W_OK));
-  EXPECT_EQ(-1, platformAccess(path, R_OK | X_OK));
-  EXPECT_EQ(-1, platformAccess(path, W_OK | X_OK));
-  EXPECT_EQ(-1, platformAccess(path, R_OK));
-  EXPECT_EQ(0, platformAccess(path, W_OK));
-  EXPECT_EQ(-1, platformAccess(path, X_OK));
-
-  EXPECT_TRUE(platformChmod(path, S_IXUSR));
-
-  EXPECT_EQ(-1, platformAccess(path, R_OK | W_OK | X_OK));
-  EXPECT_EQ(-1, platformAccess(path, R_OK | W_OK));
-  EXPECT_EQ(-1, platformAccess(path, R_OK | X_OK));
-  EXPECT_EQ(-1, platformAccess(path, W_OK | X_OK));
-  EXPECT_EQ(-1, platformAccess(path, R_OK));
-  EXPECT_EQ(-1, platformAccess(path, W_OK));
-  EXPECT_EQ(0, platformAccess(path, X_OK));
-
-  // Reset permissions
-  EXPECT_TRUE(platformChmod(path, all_access));
-}
-
-TEST_F(FileOpsTests, test_safe_permissions) {
-  const auto root_path = fs::temp_directory_path() /
-                         fs::unique_path("osquery.safe-perms-test.%%%%.%%%%");
-  auto const root_path_manager =
-      scope_guard::create([&root_path]() { fs::remove_all(root_path); });
-
-  const auto temp_file = (root_path / "test").string();
-  const auto root_dir = root_path.string();
-
-  const int all_access = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP |
-                         S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH;
-
-  fs::create_directories(root_dir);
-
-  {
-    PlatformFile fd(temp_file, PF_CREATE_ALWAYS | PF_WRITE);
-    ASSERT_TRUE(fd.isValid());
-
-    EXPECT_TRUE(
-        platformChmod(temp_file, S_IRUSR | S_IWGRP | S_IROTH | S_IWOTH));
-    EXPECT_TRUE(platformChmod(root_dir, S_IRUSR | S_IRGRP | S_IROTH));
-
-    auto status = fd.hasSafePermissions();
-    EXPECT_FALSE(status.ok());
-    EXPECT_EQ(1, status.getCode());
-
-    if (isPlatform(PlatformType::TYPE_POSIX)) {
-      // On POSIX, chmod on a file requires +x on the parent directory
-      EXPECT_TRUE(platformChmod(root_dir, all_access));
-    }
-
-    EXPECT_TRUE(platformChmod(temp_file, S_IRUSR | S_IRGRP | S_IROTH));
-    EXPECT_TRUE(platformChmod(root_dir,
-                              S_IRUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH));
-
-    status = fd.hasSafePermissions();
-
-    if (isPlatform(PlatformType::TYPE_WINDOWS)) {
-      EXPECT_FALSE(status.ok());
-      EXPECT_EQ(1, status.getCode());
-    } else {
-      // On POSIX, we only check to see if temp_file has S_IWOTH
-      EXPECT_TRUE(status.ok());
-    }
-
-    if (isPlatform(PlatformType::TYPE_POSIX)) {
-      // On POSIX, chmod on a file requires +x on the parent directory
-      EXPECT_TRUE(platformChmod(root_dir, all_access));
-    }
-
-    EXPECT_TRUE(platformChmod(temp_file, S_IRUSR | S_IRGRP | S_IROTH));
-    EXPECT_TRUE(platformChmod(root_dir, S_IRUSR | S_IRGRP | S_IWGRP | S_IROTH));
-
-    status = fd.hasSafePermissions();
-
-    if (isPlatform(PlatformType::TYPE_WINDOWS)) {
-      EXPECT_FALSE(status.ok());
-      EXPECT_EQ(1, status.getCode());
-    } else {
-      // On POSIX, we only check to see if temp_file has S_IWOTH
-      EXPECT_TRUE(status.ok());
-    }
-
-    if (isPlatform(PlatformType::TYPE_POSIX)) {
-      // On POSIX, chmod on a file requires +x on the parent directory
-      EXPECT_TRUE(platformChmod(root_dir, all_access));
-    }
-
-    EXPECT_TRUE(platformChmod(temp_file, 0));
-    EXPECT_TRUE(platformChmod(root_dir, 0));
-    EXPECT_TRUE(fd.hasSafePermissions().ok());
-
-    if (isPlatform(PlatformType::TYPE_POSIX)) {
-      // On POSIX, chmod on a file requires +x on the parent directory
-      EXPECT_TRUE(platformChmod(root_dir, all_access));
-    }
-
-    EXPECT_TRUE(platformChmod(temp_file, S_IRUSR | S_IRGRP | S_IROTH));
-    EXPECT_TRUE(platformChmod(root_dir, S_IRUSR | S_IRGRP | S_IROTH));
-    EXPECT_TRUE(fd.hasSafePermissions().ok());
-  }
-
-  EXPECT_TRUE(platformChmod(root_dir, all_access));
-  EXPECT_TRUE(platformChmod(temp_file, all_access));
-}
-
-TEST_F(FileOpsTests, test_safe_db_permissions) {
-  const auto db_path =
-      fs::temp_directory_path() /
-      fs::unique_path("osquery.safe-db-perms-test.%%%%.%%%%.db");
-  auto const db_path_manager =
-      scope_guard::create([&db_path]() { fs::remove_all(db_path); });
-
-  const auto sst_file = (db_path / "1234.sst").string();
-  const auto db = db_path.string();
-
-  fs::create_directories(db);
-
-  // Ensure that 'safe' permissions get applied correctly
-  {
-    EXPECT_TRUE(platformSetSafeDbPerms(db));
-
-    PlatformFile fd(sst_file, PF_CREATE_ALWAYS | PF_WRITE);
-    ASSERT_TRUE(fd.isValid());
-
-    // The 'hasSafePermissions' function ensures no low priv writes can occur
-    auto status = fd.hasSafePermissions();
-
-    EXPECT_TRUE(fd.hasSafePermissions().ok());
-    EXPECT_EQ(0, status.getCode());
-  }
-
-  // Ensure that we still have read and write access to the db
-  {
-    EXPECT_EQ(0, platformAccess(db, R_OK | W_OK));
-    EXPECT_EQ(0, platformAccess(sst_file, R_OK | W_OK));
-  }
-
-  // Tear down our mock DB files
-  const int all_access = S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP |
-                         S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH;
-  EXPECT_TRUE(platformChmod(db, all_access));
-  EXPECT_TRUE(platformChmod(sst_file, all_access));
-}
-
-TEST_F(FileOpsTests, test_glob) {
-  {
-    std::vector<fs::path> expected{fake_directory_ / "door.txt",
-                                   fake_directory_ / "root.txt",
-                                   fake_directory_ / "root2.txt",
-                                   fake_directory_ / "roto.txt"};
-    auto result = platformGlob((fake_directory_ / "*.txt").string());
-    EXPECT_TRUE(globResultsMatch(result, expected));
-  }
-
-  {
-    std::vector<fs::path> expected{fake_directory_ / "deep1/",
-                                   fake_directory_ / "deep11/",
-                                   fake_directory_ / "door.txt",
-                                   fake_directory_ / "root.txt",
-                                   fake_directory_ / "root2.txt",
-                                   fake_directory_ / "roto.txt",
-                                   fake_directory_ / "toplevel/"};
-    auto result = platformGlob((fake_directory_ / "*").string());
-    EXPECT_TRUE(globResultsMatch(result, expected));
-  }
-
-  {
-    std::vector<fs::path> expected{fake_directory_ / "deep1/deep2/",
-                                   fake_directory_ / "deep1/level1.txt",
-                                   fake_directory_ / "deep11/deep2/",
-                                   fake_directory_ / "deep11/level1.txt",
-                                   fake_directory_ / "deep11/not_bash",
-                                   fake_directory_ / "toplevel/secondlevel1/",
-                                   fake_directory_ / "toplevel/secondlevel2/",
-                                   fake_directory_ / "toplevel/secondlevel3/"};
-    auto result = platformGlob((fake_directory_ / "*" / "*").string());
-    EXPECT_TRUE(globResultsMatch(result, expected));
-  }
-
-  {
-    std::vector<fs::path> expected{
-        fake_directory_ / "deep1/deep2/level2.txt",
-        fake_directory_ / "deep11/deep2/deep3/",
-        fake_directory_ / "deep11/deep2/level2.txt",
-        fake_directory_ / "toplevel/secondlevel3/thirdlevel1/",
-    };
-    auto result = platformGlob((fake_directory_ / "*/*/*").string());
-    EXPECT_TRUE(globResultsMatch(result, expected));
-  }
-
-  {
-    std::vector<fs::path> expected{fake_directory_ / "deep11/deep2/deep3/",
-                                   fake_directory_ / "deep11/deep2/level2.txt"};
-    auto result = platformGlob((fake_directory_ / "*11/*/*").string());
-    EXPECT_TRUE(globResultsMatch(result, expected));
-  }
-
-  {
-    std::vector<fs::path> expected{fake_directory_ / "deep1/",
-                                   fake_directory_ / "root.txt"};
-    auto result = platformGlob((fake_directory_ / "{deep,root}{1,.txt}").string());
-    EXPECT_TRUE(globResultsMatch(result, expected));
-  }
-
-  {
-    std::vector<fs::path> expected{fake_directory_ / "deep1/deep2/level2.txt",
-                                   fake_directory_ / "deep11/deep2/deep3/",
-                                   fake_directory_ / "deep11/deep2/level2.txt"};
-    auto result = platformGlob((fake_directory_ / "*/deep2/*").string());
-    EXPECT_TRUE(globResultsMatch(result, expected));
-  }
-
-  {
-    std::vector<fs::path> expected{fake_directory_ / "deep1/deep2/",
-                                   fake_directory_ / "deep1/level1.txt",
-                                   fake_directory_ / "deep11/deep2/",
-                                   fake_directory_ / "deep11/level1.txt",
-                                   fake_directory_ / "deep11/not_bash"};
-    auto result =
-        platformGlob((fake_directory_ / "*/{deep2,level1,not_bash}{,.txt}").string());
-    EXPECT_TRUE(globResultsMatch(result, expected));
-  }
-}
-
-TEST_F(FileOpsTests, test_zero_permissions_file) {
-  TempFile tmp_file;
-  std::string path = tmp_file.path();
-
-  const std::string expected_str = "0_permissions";
-  const ssize_t expected_len = expected_str.size();
-
-  // Setup file for testing
-  PlatformFile fd(path, PF_CREATE_NEW | PF_READ | PF_WRITE);
-  ASSERT_TRUE(fd.isValid());
-  EXPECT_EQ(expected_len, fd.write(expected_str.c_str(), expected_len));
-  EXPECT_TRUE(platformChmod(path, 0));
-
-  // Test file
-  EXPECT_TRUE(!fd.isExecutable().ok());
-
-  std::vector<char> buf(expected_len);
-  EXPECT_EQ(0, fd.read(buf.data(), expected_len));
-
-  auto modes = {R_OK, W_OK, X_OK};
-  for (auto& mode : modes) {
-    EXPECT_EQ(-1, platformAccess(path, mode));
-  }
-  EXPECT_EQ(boost::none, platformFopen(path, "r"));
-}
-} // namespace osquery
index eb4748e..1ab11c6 100644 (file)
@@ -18,7 +18,6 @@
 #include <boost/noncopyable.hpp>
 
 #include <osquery/data_logger.h>
-#include <osquery/filesystem/filesystem.h>
 #include <osquery/plugins/logger.h>
 #include <osquery/registry_factory.h>
 #include <osquery/system.h>
diff --git a/src/osquery/logger/plugins/filesystem.cpp b/src/osquery/logger/plugins/filesystem.cpp
deleted file mode 100644 (file)
index b340575..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- *  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 <exception>
-#include <mutex>
-
-#include <osquery/filesystem.h>
-#include <osquery/logger.h>
-
-namespace pt = boost::property_tree;
-namespace fs = boost::filesystem;
-
-namespace osquery {
-
-const std::string kFilesystemLoggerFilename = "osqueryd.results.log";
-const std::string kFilesystemLoggerSnapshots = "osqueryd.snapshots.log";
-const std::string kFilesystemLoggerHealth = "osqueryd.health.log";
-
-std::mutex filesystemLoggerPluginMutex;
-
-class FilesystemLoggerPlugin : public LoggerPlugin {
- public:
-  Status setUp();
-  Status logString(const std::string& s);
-  Status logStringToFile(const std::string& s, const std::string& filename);
-  Status logSnapshot(const std::string& s);
-  Status logHealth(const std::string& s);
-  Status init(const std::string& name, const std::vector<StatusLogLine>& log);
-  Status logStatus(const std::vector<StatusLogLine>& log);
-
- private:
-  fs::path log_path_;
-};
-
-REGISTER(FilesystemLoggerPlugin, "logger", "filesystem");
-
-Status FilesystemLoggerPlugin::setUp() {
-  return Status(0, "OK");
-}
-
-Status FilesystemLoggerPlugin::logString(const std::string& s) {
-  return logStringToFile(s, kFilesystemLoggerFilename);
-}
-
-Status FilesystemLoggerPlugin::logStringToFile(const std::string& s,
-                                               const std::string& filename) {
-  std::lock_guard<std::mutex> lock(filesystemLoggerPluginMutex);
-  try {
-    // The results log may contain sensitive information if run as root.
-    auto status = writeTextFile((log_path_ / filename).string(), s, 0640, true);
-    if (!status.ok()) {
-      return status;
-    }
-  } catch (const std::exception& e) {
-    return Status(1, e.what());
-  }
-  return Status(0, "OK");
-}
-
-Status FilesystemLoggerPlugin::logStatus(
-    const std::vector<StatusLogLine>& log) {
-  for (const auto& item : log) {
-    // Emit this intermediate log to the Glog filesystem logger.
-    google::LogMessage(item.filename.c_str(),
-                       item.line,
-                       (google::LogSeverity)item.severity).stream()
-        << item.message;
-  }
-
-  return Status(0, "OK");
-}
-
-Status FilesystemLoggerPlugin::logSnapshot(const std::string& s) {
-  // Send the snapshot data to a separate filename.
-  return logStringToFile(s, kFilesystemLoggerSnapshots);
-}
-
-Status FilesystemLoggerPlugin::logHealth(const std::string& s) {
-  return logStringToFile(s, kFilesystemLoggerHealth);
-}
-
-Status FilesystemLoggerPlugin::init(const std::string& name,
-                                    const std::vector<StatusLogLine>& log) {
-  // Stop the internal Glog facilities.
-  google::ShutdownGoogleLogging();
-
-  // Restart the Glog facilities using the name `init` was provided.
-  google::InitGoogleLogging(name.c_str());
-
-  // We may violate Glog global object assumptions. So set names manually.
-  auto basename = (log_path_ / name).string();
-  google::SetLogDestination(google::INFO, (basename + ".INFO.").c_str());
-  google::SetLogDestination(google::WARNING, (basename + ".WARNING.").c_str());
-  google::SetLogDestination(google::ERROR, (basename + ".ERROR.").c_str());
-
-  // Now funnel the intermediate status logs provided to `init`.
-  logStatus(log);
-
-  // The filesystem logger cheats and uses Glog to log to the filesystem so
-  // we can return failure here and stop the custom log sink.
-  return Status(1, "No status logger used for filesystem");
-}
-}
diff --git a/src/osquery/logger/plugins/syslog.cpp b/src/osquery/logger/plugins/syslog.cpp
deleted file mode 100644 (file)
index 04f70d1..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- *  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 <syslog.h>
-
-#include <osquery/logger.h>
-#include <osquery/utils/conversions/split.h>
-
-namespace osquery {
-
-class SyslogLoggerPlugin : public LoggerPlugin {
- public:
-  Status logString(const std::string& s);
-  Status init(const std::string& name, const std::vector<StatusLogLine>& log);
-  Status logStatus(const std::vector<StatusLogLine>& log);
-};
-
-REGISTER(SyslogLoggerPlugin, "logger", "syslog");
-
-Status SyslogLoggerPlugin::logString(const std::string& s) {
-  for (const auto& line : osquery::split(s, "\n")) {
-    syslog(LOG_INFO, "result=%s", line.c_str());
-  }
-  return Status(0, "OK");
-}
-
-Status SyslogLoggerPlugin::logStatus(const std::vector<StatusLogLine>& log) {
-  for (const auto& item : log) {
-    int severity = LOG_NOTICE;
-    if (item.severity == O_INFO) {
-      severity = LOG_NOTICE;
-    } else if (item.severity == O_WARNING) {
-      severity = LOG_WARNING;
-    } else if (item.severity == O_ERROR) {
-      severity = LOG_ERR;
-    } else if (item.severity == O_FATAL) {
-      severity = LOG_CRIT;
-    }
-
-    std::string line = "severity=" + std::to_string(item.severity)
-                    + " location=" + item.filename + ":" + std::to_string(item.line) +
-                      " message=" + item.message;
-
-    syslog(severity, "%s", line.c_str());
-  }
-  return Status(0, "OK");
-}
-
-Status SyslogLoggerPlugin::init(const std::string& name,
-                                const std::vector<StatusLogLine>& log) {
-  closelog();
-
-  // Now funnel the intermediate status logs provided to `init`.
-  return logStatus(log);
-}
-}
index 0a49f65..253b961 100644 (file)
 #include <iostream>
 
 #include <boost/algorithm/string/predicate.hpp>
+#include <boost/filesystem.hpp>
 
 #include <osquery/core.h>
 #include <osquery/devtools/devtools.h>
-#include <osquery/filesystem/fileops.h>
 #include <osquery/logger.h>
 #include <osquery/main/main.h>
 #include <osquery/registry_factory.h>
@@ -32,8 +32,6 @@ namespace osquery {
 int startDaemon(Initializer& runner) {
   runner.start();
 
-//  osquery::events::init_syscall_tracing();
-
   // Finally wait for a signal / interrupt to shutdown.
   runner.waitForShutdown();
   return 0;
index c1979ec..40ba0b8 100644 (file)
@@ -7,7 +7,6 @@
  */
 
 #include <osquery/core.h>
-#include <osquery/filesystem/filesystem.h>
 #include <osquery/logger.h>
 #include <osquery/sql.h>
 
 #include "osquery/sql/dynamic_table_row.h"
 #include "osquery/sql/sqlite_util.h"
 
+#include <boost/filesystem/path.hpp>
+
 namespace fs = boost::filesystem;
+namespace errc = boost::system::errc;
 
 namespace osquery {
 
@@ -73,10 +75,16 @@ Status genTableRowsForSqliteTable(const fs::path& sqlite_db,
                                   TableRows& results,
                                   bool respect_locking) {
   sqlite3* db = nullptr;
-  if (!pathExists(sqlite_db).ok()) {
+  boost::system::error_code ec;
+  if (sqlite_db.empty()) {
     return Status(1, "Database path does not exist");
   }
 
+  // A tri-state determination of presence
+  if (!fs::exists(sqlite_db, ec) || ec.value() != errc::success) {
+    return Status(1, ec.message());
+  }
+
   auto rc = sqlite3_open_v2(
       sqlite_db.string().c_str(),
       &db,
diff --git a/src/osquery/tables/system/linux/processes.cpp b/src/osquery/tables/system/linux/processes.cpp
deleted file mode 100644 (file)
index 6ab8334..0000000
+++ /dev/null
@@ -1,530 +0,0 @@
-/**
- *  Copyright (c) 2014-present, Facebook, Inc.
- *  All rights reserved.
- *
- *  This source code is licensed in accordance with the terms specified in
- *  the LICENSE file found in the root directory of this source tree.
- */
-
-#include <map>
-#include <string>
-
-#include <stdlib.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-#include <boost/algorithm/string/predicate.hpp>
-#include <boost/algorithm/string/trim.hpp>
-#include <boost/noncopyable.hpp>
-#include <boost/regex.hpp>
-
-#include <osquery/core.h>
-#include <osquery/filesystem/filesystem.h>
-#include <osquery/filesystem/linux/proc.h>
-#include <osquery/logger.h>
-#include <osquery/sql/dynamic_table_row.h>
-#include <osquery/tables.h>
-
-#include <osquery/utils/conversions/split.h>
-#include <osquery/utils/system/uptime.h>
-
-#include <ctime>
-
-namespace osquery {
-namespace tables {
-
-const int kMSIn1CLKTCK = (1000 / sysconf(_SC_CLK_TCK));
-
-inline std::string getProcAttr(const std::string& attr,
-                               const std::string& pid) {
-  return "/proc/" + pid + "/" + attr;
-}
-
-inline std::string readProcCMDLine(const std::string& pid) {
-  auto attr = getProcAttr("cmdline", pid);
-
-  std::string content;
-  readFile(attr, content);
-  // Remove \0 delimiters.
-  std::replace_if(content.begin(),
-                  content.end(),
-                  [](const char& c) { return c == 0; },
-                  ' ');
-  // Remove trailing delimiter.
-  boost::algorithm::trim(content);
-  return content;
-}
-
-inline std::string readProcLink(const std::string& attr,
-                                const std::string& pid) {
-  // The exe is a symlink to the binary on-disk.
-  auto attr_path = getProcAttr(attr, pid);
-
-  std::string result = "";
-  struct stat sb;
-  if (lstat(attr_path.c_str(), &sb) != -1) {
-    // Some symlinks may report 'st_size' as zero
-    // Use PATH_MAX as best guess
-    // For cases when 'st_size' is not zero but smaller than
-    // PATH_MAX we will still use PATH_MAX to minimize chance
-    // of output trucation during race condition
-    ssize_t buf_size = sb.st_size < PATH_MAX ? PATH_MAX : sb.st_size;
-    // +1 for \0, since readlink does not append a null
-    char* linkname = static_cast<char*>(malloc(buf_size + 1));
-    ssize_t r = readlink(attr_path.c_str(), linkname, buf_size);
-
-    if (r > 0) { // Success check
-      // r may not be equal to buf_size
-      // if r == buf_size there was race condition
-      // and link is longer than buf_size and because of this
-      // truncated
-      linkname[r] = '\0';
-      result = std::string(linkname);
-    }
-    free(linkname);
-  }
-
-  return result;
-}
-
-// In the case where the linked binary path ends in " (deleted)", and a file
-// actually exists at that path, check whether the inode of that file matches
-// the inode of the mapped file in /proc/%pid/maps
-Status deletedMatchesInode(const std::string& path, const std::string& pid) {
-  const std::string maps_path = getProcAttr("maps", pid);
-  std::string maps_contents;
-  auto s = osquery::readFile(maps_path, maps_contents);
-  if (!s.ok()) {
-    return Status(-1, "Cannot read maps file: " + maps_path);
-  }
-
-  // Extract the expected inode of the binary file from /proc/%pid/maps
-  boost::smatch what;
-  boost::regex expression("([0-9]+)\\h+\\Q" + path + "\\E");
-  if (!boost::regex_search(maps_contents, what, expression)) {
-    return Status(-1, "Could not find binary inode in maps file: " + maps_path);
-  }
-  std::string inode = what[1];
-
-  // stat the file at the expected binary path
-  struct stat st;
-  if (stat(path.c_str(), &st) != 0) {
-    return Status(-1, "Error in stat of binary: " + path);
-  }
-
-  // If the inodes match, the binary name actually ends with " (deleted)"
-  if (std::to_string(st.st_ino) == inode) {
-    return Status::success();
-  } else {
-    return Status(1, "Inodes do not match");
-  }
-}
-
-std::set<std::string> getProcList(const QueryContext& context) {
-  std::set<std::string> pidlist;
-  if (context.constraints.count("pid") > 0 &&
-      context.constraints.at("pid").exists(EQUALS)) {
-    for (const auto& pid : context.constraints.at("pid").getAll(EQUALS)) {
-      if (isDirectory("/proc/" + pid)) {
-        pidlist.insert(pid);
-      }
-    }
-  } else {
-    osquery::procProcesses(pidlist);
-  }
-
-  return pidlist;
-}
-
-void genProcessEnvironment(const std::string& pid, QueryData& results) {
-  auto attr = getProcAttr("environ", pid);
-
-  std::string content;
-  readFile(attr, content);
-  const char* variable = content.c_str();
-
-  // Stop at the end of nul-delimited string content.
-  while (*variable > 0) {
-    auto buf = std::string(variable);
-    size_t idx = buf.find_first_of("=");
-
-    Row r;
-    r["pid"] = pid;
-    r["key"] = buf.substr(0, idx);
-    r["value"] = buf.substr(idx + 1);
-    results.push_back(r);
-    variable += buf.size() + 1;
-  }
-}
-
-void genProcessMap(const std::string& pid, QueryData& results) {
-  auto map = getProcAttr("maps", pid);
-
-  std::string content;
-  readFile(map, content);
-  for (auto& line : osquery::split(content, "\n")) {
-    auto fields = osquery::split(line, " ");
-    // If can't read address, not sure.
-    if (fields.size() < 5) {
-      continue;
-    }
-
-    Row r;
-    r["pid"] = pid;
-    if (!fields[0].empty()) {
-      auto addresses = osquery::split(fields[0], "-");
-      if (addresses.size() >= 2) {
-        r["start"] = "0x" + addresses[0];
-        r["end"] = "0x" + addresses[1];
-      } else {
-        // Problem with the address format.
-        continue;
-      }
-    }
-
-    r["permissions"] = fields[1];
-    auto offset = tryTo<long long>(fields[2], 16);
-    r["offset"] = BIGINT((offset) ? offset.take() : -1);
-    r["device"] = fields[3];
-    r["inode"] = fields[4];
-
-    // Path name must be trimmed.
-    if (fields.size() > 5) {
-      boost::trim(fields[5]);
-      r["path"] = fields[5];
-    }
-
-    // BSS with name in pathname.
-    r["pseudo"] = (fields[4] == "0" && !r["path"].empty()) ? "1" : "0";
-    results.push_back(std::move(r));
-  }
-}
-
-/**
- *  Output from string parsing /proc/<pid>/status.
- */
-struct SimpleProcStat : private boost::noncopyable {
- public:
-  std::string name;
-  std::string real_uid;
-  std::string real_gid;
-  std::string effective_uid;
-  std::string effective_gid;
-  std::string saved_uid;
-  std::string saved_gid;
-  std::string resident_size;
-  std::string total_size;
-  std::string state;
-  std::string parent;
-  std::string group;
-  std::string nice;
-  std::string threads;
-  std::string user_time;
-  std::string system_time;
-  std::string start_time;
-
-  /// For errors processing proc data.
-  Status status;
-
-  explicit SimpleProcStat(const std::string& pid);
-};
-
-SimpleProcStat::SimpleProcStat(const std::string& pid) {
-  std::string content;
-  if (readFile(getProcAttr("stat", pid), content).ok()) {
-    auto start = content.find_last_of(")");
-    // Start parsing stats from ") <MODE>..."
-    if (start == std::string::npos || content.size() <= start + 2) {
-      status = Status(1, "Invalid /proc/stat header");
-      return;
-    }
-
-    auto details = osquery::split(content.substr(start + 2), " ");
-    if (details.size() <= 19) {
-      status = Status(1, "Invalid /proc/stat content");
-      return;
-    }
-
-    this->state = details.at(0);
-    this->parent = details.at(1);
-    this->group = details.at(2);
-    this->user_time = details.at(11);
-    this->system_time = details.at(12);
-    this->nice = details.at(16);
-    this->threads = details.at(17);
-    this->start_time = details.at(19);
-  }
-
-  // /proc/N/status may be not available, or readable by this user.
-  if (!readFile(getProcAttr("status", pid), content).ok()) {
-    status = Status(1, "Cannot read /proc/status");
-    return;
-  }
-
-  for (const auto& line : osquery::split(content, "\n")) {
-    // Status lines are formatted: Key: Value....\n.
-    auto detail = osquery::split(line, ':', 1);
-    if (detail.size() != 2) {
-      continue;
-    }
-
-    // There are specific fields from each detail.
-    if (detail.at(0) == "Name") {
-      this->name = detail.at(1);
-    } else if (detail.at(0) == "VmRSS") {
-      detail[1].erase(detail.at(1).end() - 3, detail.at(1).end());
-      // Memory is reported in kB.
-      this->resident_size = detail.at(1) + "000";
-    } else if (detail.at(0) == "VmSize") {
-      detail[1].erase(detail.at(1).end() - 3, detail.at(1).end());
-      // Memory is reported in kB.
-      this->total_size = detail.at(1) + "000";
-    } else if (detail.at(0) == "Gid") {
-      // Format is: R E - -
-      auto gid_detail = osquery::split(detail.at(1), "\t");
-      if (gid_detail.size() == 4) {
-        this->real_gid = gid_detail.at(0);
-        this->effective_gid = gid_detail.at(1);
-        this->saved_gid = gid_detail.at(2);
-      }
-    } else if (detail.at(0) == "Uid") {
-      auto uid_detail = osquery::split(detail.at(1), "\t");
-      if (uid_detail.size() == 4) {
-        this->real_uid = uid_detail.at(0);
-        this->effective_uid = uid_detail.at(1);
-        this->saved_uid = uid_detail.at(2);
-      }
-    }
-  }
-}
-
-/**
- * Output from string parsing /proc/<pid>/io.
- */
-struct SimpleProcIo : private boost::noncopyable {
- public:
-  std::string read_bytes;
-  std::string write_bytes;
-  std::string cancelled_write_bytes;
-
-  /// For errors processing proc data.
-  Status status;
-
-  explicit SimpleProcIo(const std::string& pid);
-};
-
-SimpleProcIo::SimpleProcIo(const std::string& pid) {
-  std::string content;
-  if (!readFile(getProcAttr("io", pid), content).ok()) {
-    status = Status(
-        1, "Cannot read /proc/" + pid + "/io (is osquery running as root?)");
-    return;
-  }
-
-  for (const auto& line : osquery::split(content, "\n")) {
-    // IO lines are formatted: Key: Value....\n.
-    auto detail = osquery::split(line, ':', 1);
-    if (detail.size() != 2) {
-      continue;
-    }
-
-    // There are specific fields from each detail
-    if (detail.at(0) == "read_bytes") {
-      this->read_bytes = detail.at(1);
-    } else if (detail.at(0) == "write_bytes") {
-      this->write_bytes = detail.at(1);
-    } else if (detail.at(0) == "cancelled_write_bytes") {
-      this->cancelled_write_bytes = detail.at(1);
-    }
-  }
-}
-
-/**
- * @brief Determine if the process path (binary) exists on the filesystem.
- *
- * If the path of the executable that started the process is available and
- * the path exists on disk, set on_disk to 1. If the path is not
- * available, set on_disk to -1. If, and only if, the path of the
- * executable is available and the file does NOT exist on disk, set on_disk
- * to 0.
- *
- * @param pid The string (because we're referencing file path) pid.
- * @param path A mutable string found from /proc/N/exe. If this is found
- *             to contain the (deleted) suffix, it will be removed.
- * @return A tristate -1 error, 1 yes, 0 nope.
- */
-int getOnDisk(const std::string& pid, std::string& path) {
-  if (path.empty()) {
-    return -1;
-  }
-
-  // The string appended to the exe path when the binary is deleted
-  const std::string kDeletedString = " (deleted)";
-  if (!boost::algorithm::ends_with(path, kDeletedString)) {
-    return (osquery::pathExists(path)) ? 1 : 0;
-  }
-
-  if (!osquery::pathExists(path)) {
-    // No file exists with the path including " (deleted)", so we can strip
-    // this from the path and set on_disk = 0
-    path.erase(path.size() - kDeletedString.size());
-    return 0;
-  }
-
-  // Special case in which we have to check the inode to see whether the
-  // process is actually running from a binary file ending with
-  // " (deleted)". See #1607
-  std::string maps_contents;
-  Status deleted = deletedMatchesInode(path, pid);
-  if (deleted.getCode() == -1) {
-    LOG(ERROR) << deleted.getMessage();
-    return -1;
-  } else if (deleted.getCode() == 0) {
-    // The process is actually running from a binary ending with
-    // " (deleted)"
-    return 1;
-  } else {
-    // There is a collision with a file name ending in " (deleted)", but
-    // that file is not the binary for this process
-    path.erase(path.size() - kDeletedString.size());
-    return 0;
-  }
-}
-
-void genProcess(const std::string& pid,
-                long system_boot_time,
-                TableRows& results) {
-  // Parse the process stat and status.
-  SimpleProcStat proc_stat(pid);
-  // Parse the process io
-  SimpleProcIo proc_io(pid);
-
-  if (!proc_stat.status.ok()) {
-    VLOG(1) << proc_stat.status.getMessage() << " for pid " << pid;
-    return;
-  }
-
-  auto r = make_table_row();
-  r["pid"] = pid;
-  r["parent"] = proc_stat.parent;
-  r["path"] = readProcLink("exe", pid);
-  r["name"] = proc_stat.name;
-  r["pgroup"] = proc_stat.group;
-  r["state"] = proc_stat.state;
-  r["nice"] = proc_stat.nice;
-  r["threads"] = proc_stat.threads;
-  // Read/parse cmdline arguments.
-  r["cmdline"] = readProcCMDLine(pid);
-  r["cwd"] = readProcLink("cwd", pid);
-  r["root"] = readProcLink("root", pid);
-  r["uid"] = proc_stat.real_uid;
-  r["euid"] = proc_stat.effective_uid;
-  r["suid"] = proc_stat.saved_uid;
-  r["gid"] = proc_stat.real_gid;
-  r["egid"] = proc_stat.effective_gid;
-  r["sgid"] = proc_stat.saved_gid;
-
-  r["on_disk"] = INTEGER(getOnDisk(pid, r["path"]));
-
-  // size/memory information
-  r["wired_size"] = "0"; // No support for unpagable counters in linux.
-  r["resident_size"] = proc_stat.resident_size;
-  r["total_size"] = proc_stat.total_size;
-
-  // time information
-  auto usr_time = std::strtoull(proc_stat.user_time.data(), nullptr, 10);
-  r["user_time"] = std::to_string(usr_time * kMSIn1CLKTCK);
-  auto sys_time = std::strtoull(proc_stat.system_time.data(), nullptr, 10);
-  r["system_time"] = std::to_string(sys_time * kMSIn1CLKTCK);
-
-  auto proc_start_time_exp = tryTo<long>(proc_stat.start_time);
-  if (proc_start_time_exp.isValue() && system_boot_time > 0) {
-    r["start_time"] = INTEGER(system_boot_time + proc_start_time_exp.take() /
-                                                     sysconf(_SC_CLK_TCK));
-  } else {
-    r["start_time"] = "-1";
-  }
-
-  if (!proc_io.status.ok()) {
-    // /proc/<pid>/io can require root to access, so don't fail if we can't
-    VLOG(1) << proc_io.status.getMessage();
-  } else {
-    r["disk_bytes_read"] = proc_io.read_bytes;
-    long long write_bytes = tryTo<long long>(proc_io.write_bytes).takeOr(0ll);
-    long long cancelled_write_bytes =
-        tryTo<long long>(proc_io.cancelled_write_bytes).takeOr(0ll);
-
-    r["disk_bytes_written"] =
-        std::to_string(write_bytes - cancelled_write_bytes);
-  }
-
-  results.push_back(r);
-}
-
-void genNamespaces(const std::string& pid, QueryData& results) {
-  Row r;
-
-  ProcessNamespaceList proc_ns;
-  Status status = procGetProcessNamespaces(pid, proc_ns);
-  if (!status.ok()) {
-    VLOG(1) << "Namespaces for pid " << pid
-            << " are incomplete: " << status.what();
-  }
-
-  r["pid"] = pid;
-  for (const auto& pair : proc_ns) {
-    r[pair.first + "_namespace"] = std::to_string(pair.second);
-  }
-
-  results.push_back(r);
-}
-
-TableRows genProcesses(QueryContext& context) {
-  TableRows results;
-  auto system_boot_time = getUptime();
-  if (system_boot_time > 0) {
-    system_boot_time = std::time(nullptr) - system_boot_time;
-  }
-
-  auto pidlist = getProcList(context);
-  for (const auto& pid : pidlist) {
-    genProcess(pid, system_boot_time, results);
-  }
-
-  return results;
-}
-
-QueryData genProcessEnvs(QueryContext& context) {
-  QueryData results;
-
-  auto pidlist = getProcList(context);
-  for (const auto& pid : pidlist) {
-    genProcessEnvironment(pid, results);
-  }
-
-  return results;
-}
-
-QueryData genProcessMemoryMap(QueryContext& context) {
-  QueryData results;
-
-  auto pidlist = getProcList(context);
-  for (const auto& pid : pidlist) {
-    genProcessMap(pid, results);
-  }
-
-  return results;
-}
-
-QueryData genProcessNamespaces(QueryContext& context) {
-  QueryData results;
-
-  const auto pidlist = getProcList(context);
-  for (const auto& pid : pidlist) {
-    genNamespaces(pid, results);
-  }
-
-  return results;
-}
-}
-}
diff --git a/src/osquery/tables/utility/file.cpp b/src/osquery/tables/utility/file.cpp
deleted file mode 100644 (file)
index c72ab73..0000000
+++ /dev/null
@@ -1,199 +0,0 @@
-/**
- *  Copyright (c) 2014-present, Facebook, Inc.
- *  All rights reserved.
- *
- *  This source code is licensed in accordance with the terms specified in
- *  the LICENSE file found in the root directory of this source tree.
- */
-
-#if !defined(WIN32)
-#include <sys/stat.h>
-#endif
-
-#include <osquery/filesystem/filesystem.h>
-#include <osquery/logger.h>
-#include <osquery/tables.h>
-#include <osquery/filesystem/fileops.h>
-
-namespace fs = boost::filesystem;
-
-namespace osquery {
-
-namespace tables {
-
-#if !defined(WIN32)
-
-const std::map<fs::file_type, std::string> kTypeNames{
-    {fs::regular_file, "regular"},
-    {fs::directory_file, "directory"},
-    {fs::symlink_file, "symlink"},
-    {fs::block_file, "block"},
-    {fs::character_file, "character"},
-    {fs::fifo_file, "fifo"},
-    {fs::socket_file, "socket"},
-    {fs::type_unknown, "unknown"},
-    {fs::status_error, "error"},
-};
-
-#endif
-
-void genFileInfo(const fs::path& path,
-                 const fs::path& parent,
-                 const std::string& pattern,
-                 QueryData& results) {
-  // Must provide the path, filename, directory separate from boost path->string
-  // helpers to match any explicit (query-parsed) predicate constraints.
-
-  Row r;
-  r["path"] = path.string();
-  r["filename"] = path.filename().string();
-  r["directory"] = parent.string();
-  r["symlink"] = "0";
-
-#if !defined(WIN32)
-
-  struct stat file_stat;
-
-  // On POSIX systems, first check the link state.
-  struct stat link_stat;
-  if (lstat(path.string().c_str(), &link_stat) < 0) {
-    // Path was not real, had too may links, or could not be accessed.
-    return;
-  }
-  if (S_ISLNK(link_stat.st_mode)) {
-    r["symlink"] = "1";
-  }
-
-  if (stat(path.string().c_str(), &file_stat)) {
-    file_stat = link_stat;
-  }
-
-  r["inode"] = BIGINT(file_stat.st_ino);
-  r["uid"] = BIGINT(file_stat.st_uid);
-  r["gid"] = BIGINT(file_stat.st_gid);
-  r["mode"] = lsperms(file_stat.st_mode);
-  r["device"] = BIGINT(file_stat.st_rdev);
-  r["size"] = BIGINT(file_stat.st_size);
-  r["block_size"] = INTEGER(file_stat.st_blksize);
-  r["hard_links"] = INTEGER(file_stat.st_nlink);
-
-  r["atime"] = BIGINT(file_stat.st_atime);
-  r["mtime"] = BIGINT(file_stat.st_mtime);
-  r["ctime"] = BIGINT(file_stat.st_ctime);
-
-#if defined(__linux__)
-  // No 'birth' or create time in Linux or Windows.
-  r["btime"] = "0";
-#else
-  r["btime"] = BIGINT(file_stat.st_birthtimespec.tv_sec);
-#endif
-
-  // Type booleans
-  boost::system::error_code ec;
-  auto status = fs::status(path, ec);
-  if (kTypeNames.count(status.type())) {
-    r["type"] = kTypeNames.at(status.type());
-  } else {
-    r["type"] = "unknown";
-  }
-
-#else
-
-  WINDOWS_STAT file_stat;
-
-  auto rtn = platformStat(path, &file_stat);
-  if (!rtn.ok()) {
-    VLOG(1) << "PlatformStat failed with " << rtn.getMessage();
-    return;
-  }
-
-  r["symlink"] = INTEGER(file_stat.symlink);
-  r["inode"] = BIGINT(file_stat.inode);
-  r["uid"] = BIGINT(file_stat.uid);
-  r["gid"] = BIGINT(file_stat.gid);
-  r["mode"] = TEXT(file_stat.mode);
-  r["device"] = BIGINT(file_stat.device);
-  r["size"] = BIGINT(file_stat.size);
-  r["block_size"] = INTEGER(file_stat.block_size);
-  r["hard_links"] = INTEGER(file_stat.hard_links);
-  r["atime"] = BIGINT(file_stat.atime);
-  r["mtime"] = BIGINT(file_stat.mtime);
-  r["ctime"] = BIGINT(file_stat.ctime);
-  r["btime"] = BIGINT(file_stat.btime);
-  r["type"] = TEXT(file_stat.type);
-  r["attributes"] = TEXT(file_stat.attributes);
-  r["file_id"] = TEXT(file_stat.file_id);
-  r["volume_serial"] = TEXT(file_stat.volume_serial);
-  r["product_version"] = TEXT(file_stat.product_version);
-
-#endif
-
-  results.push_back(r);
-}
-
-QueryData genFile(QueryContext& context) {
-  QueryData results;
-
-  // Resolve file paths for EQUALS and LIKE operations.
-  auto paths = context.constraints["path"].getAll(EQUALS);
-  context.expandConstraints(
-      "path",
-      LIKE,
-      paths,
-      ([&](const std::string& pattern, std::set<std::string>& out) {
-        std::vector<std::string> patterns;
-        auto status =
-            resolveFilePattern(pattern, patterns, GLOB_ALL | GLOB_NO_CANON);
-        if (status.ok()) {
-          for (const auto& resolved : patterns) {
-            out.insert(resolved);
-          }
-        }
-        return status;
-      }));
-
-  // Iterate through each of the resolved/supplied paths.
-  for (const auto& path_string : paths) {
-    fs::path path = path_string;
-    genFileInfo(path, path.parent_path(), "", results);
-  }
-
-  // Resolve directories for EQUALS and LIKE operations.
-  auto directories = context.constraints["directory"].getAll(EQUALS);
-  context.expandConstraints(
-      "directory",
-      LIKE,
-      directories,
-      ([&](const std::string& pattern, std::set<std::string>& out) {
-        std::vector<std::string> patterns;
-        auto status =
-            resolveFilePattern(pattern, patterns, GLOB_FOLDERS | GLOB_NO_CANON);
-        if (status.ok()) {
-          for (const auto& resolved : patterns) {
-            out.insert(resolved);
-          }
-        }
-        return status;
-      }));
-
-  // Now loop through constraints using the directory column constraint.
-  for (const auto& directory_string : directories) {
-    if (!isReadable(directory_string) || !isDirectory(directory_string)) {
-      continue;
-    }
-
-    try {
-      // Iterate over the directory and generate info for each regular file.
-      fs::directory_iterator begin(directory_string), end;
-      for (; begin != end; ++begin) {
-        genFileInfo(begin->path(), directory_string, "", results);
-      }
-    } catch (const fs::filesystem_error& /* e */) {
-      continue;
-    }
-  }
-
-  return results;
-}
-}
-} // namespace osquery
index f02fc03..78e4a4d 100644 (file)
@@ -13,7 +13,6 @@
 #include <vector>
 
 #include <osquery/core.h>
-#include <osquery/filesystem/filesystem.h>
 
 namespace osquery {
 
diff --git a/src/vist/client/schema/processes.hpp b/src/vist/client/schema/processes.hpp
deleted file mode 100644 (file)
index 764cd2d..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- *  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
- */
-
-#pragma once
-
-#include <string>
-
-namespace vist {
-namespace schema {
-
-struct Processes {
-       long long int pid;
-       std::string name;
-       std::string path;
-       std::string cmdline;
-       long long int uid;
-       long long int gid;
-       long long int euid;
-       long long int egid;
-       int on_disk;
-       long long int resident_size;
-       long long int parent;
-};
-
-} // namesapce schema
-} // namesapce vist
index 61dbdcf..27814ff 100644 (file)
@@ -19,7 +19,6 @@
 #include <vist/client/virtual-table.hpp>
 
 #include <vist/client/schema/policy.hpp>
-#include <vist/client/schema/processes.hpp>
 #include <vist/client/schema/time.hpp>
 
 #include <vist/logger.hpp>
@@ -75,39 +74,6 @@ TEST(VirtualTableTests, time_row_arry_op)
        EXPECT_NE(result.seconds, -1);
 }
 
-TEST(VirtualTableTests, processes_table)
-{
-       Processes result;
-       VirtualTable<Processes> processes;
-       EXPECT_TRUE(processes.size() > 0);
-
-       for(auto& p : processes) {
-               EXPECT_TRUE(p.size() > 0);
-               result.pid = p.at(&Processes::pid);
-               result.name = p.at(&Processes::name);
-               result.path = p.at(&Processes::path);
-               result.cmdline = p.at(&Processes::cmdline);
-               result.uid = p.at(&Processes::uid);
-               result.gid = p.at(&Processes::gid);
-               result.euid = p.at(&Processes::euid);
-               result.egid = p.at(&Processes::egid);
-               result.on_disk = p.at(&Processes::on_disk);
-               result.parent = p.at(&Processes::parent);
-
-               INFO(VIST_CLIENT) << "[Test] Processes table:";
-               INFO(VIST_CLIENT) << "\t pid: " << result.pid;
-               INFO(VIST_CLIENT) << "\t name: " << result.name;
-               INFO(VIST_CLIENT) << "\t path: " << result.path;
-               INFO(VIST_CLIENT) << "\t cmdline: " << result.cmdline;
-               INFO(VIST_CLIENT) << "\t uid: " << result.uid;
-               INFO(VIST_CLIENT) << "\t gid: " << result.gid;
-               INFO(VIST_CLIENT) << "\t euid: " << result.euid;
-               INFO(VIST_CLIENT) << "\t egid: " << result.egid;
-               INFO(VIST_CLIENT) << "\t on_disk: " << result.on_disk;
-               INFO(VIST_CLIENT) << "\t parent: " << result.parent;
-       }
-}
-
 TEST(VirtualTableTests, policy_int_table)
 {
        VirtualTable<Policy<int>> table;
index 0423516..2da7c73 100644 (file)
@@ -18,7 +18,6 @@
 
 #include <vist/client/query.hpp>
 #include <vist/client/schema/policy.hpp>
-#include <vist/client/schema/processes.hpp>
 #include <vist/client/schema/time.hpp>
 
 #include <vist/exception.hpp>
@@ -37,24 +36,13 @@ Table time { "time", Column("hour", &Time::hour),
                                         Column("minutes", &Time::minutes),
                                         Column("seconds", &Time::seconds) };
 
-Table processes { "processes", Column("pid", &Processes::pid),
-                                                          Column("name", &Processes::name),
-                                                          Column("path", &Processes::path),
-                                                          Column("cmdline", &Processes::cmdline),
-                                                          Column("uid", &Processes::uid),
-                                                          Column("gid", &Processes::gid),
-                                                          Column("euid", &Processes::euid),
-                                                          Column("egid", &Processes::egid),
-                                                          Column("on_disk", &Processes::on_disk),
-                                                          Column("parent", &Processes::parent) };
-
 Table policyInt { "policy", Column("name", &Policy<int>::name),
                                                        Column("value", &Policy<int>::value) };
 
 Table policyStr { "policy", Column("name", &Policy<std::string>::name),
                                                        Column("value", &Policy<std::string>::value) };
 
-Database metaDB { "db", time, processes, policyInt, policyStr };
+Database metaDB { "db", time, policyInt, policyStr };
 
 } // anonymous namespace
 
@@ -137,15 +125,6 @@ template class VirtualRow<Time>;
 template int VirtualRow<Time>::at(int Time::*) const;
 template int VirtualRow<Time>::operator[](int Time::*) const;
 
-template class VirtualTable<Processes>;
-template class VirtualRow<Processes>;
-template int VirtualRow<Processes>::at(int Processes::*) const;
-template int VirtualRow<Processes>::operator[](int Processes::*) const;
-template long long int VirtualRow<Processes>::at(long long int Processes::*) const;
-template long long int VirtualRow<Processes>::operator[](long long int Processes::*) const;
-template std::string VirtualRow<Processes>::at(std::string Processes::*) const;
-template std::string VirtualRow<Processes>::operator[](std::string Processes::*) const;
-
 template class VirtualTable<Policy<int>>;
 template class VirtualRow<Policy<int>>;
 /// name column