2017-12-19 00:04:06 +00:00
|
|
|
/**
|
2016-02-11 19:48:58 +00:00
|
|
|
* Copyright (c) 2014-present, Facebook, Inc.
|
2015-11-16 06:37:28 +00:00
|
|
|
* All rights reserved.
|
|
|
|
*
|
2017-12-19 00:04:06 +00:00
|
|
|
* This source code is licensed under both the Apache 2.0 license (found in the
|
|
|
|
* LICENSE file in the root directory of this source tree) and the GPLv2 (found
|
|
|
|
* in the COPYING file in the root directory of this source tree).
|
|
|
|
* You may select, at your option, one of the above-listed licenses.
|
2015-11-16 06:37:28 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
2016-03-18 23:14:15 +00:00
|
|
|
#include <atomic>
|
2016-08-10 03:49:56 +00:00
|
|
|
#include <iomanip>
|
2016-03-18 23:14:15 +00:00
|
|
|
|
2015-11-16 06:37:28 +00:00
|
|
|
#include <CoreServices/CoreServices.h>
|
2016-03-15 16:43:11 +00:00
|
|
|
#include <IOKit/IOKitLib.h>
|
2015-11-16 06:37:28 +00:00
|
|
|
|
2018-02-09 17:07:53 +00:00
|
|
|
#include <osquery/events.h>
|
|
|
|
#include <osquery/status.h>
|
|
|
|
|
2016-08-10 03:49:56 +00:00
|
|
|
#include "osquery/core/conversions.h"
|
2018-02-09 17:07:53 +00:00
|
|
|
#include "osquery/core/darwin/iokit.hpp"
|
2016-08-10 03:49:56 +00:00
|
|
|
|
2015-11-16 06:37:28 +00:00
|
|
|
namespace osquery {
|
|
|
|
|
|
|
|
struct IOKitSubscriptionContext : public SubscriptionContext {
|
|
|
|
std::string model_id;
|
|
|
|
std::string vendor_id;
|
|
|
|
|
|
|
|
/// Bus type, e.g., USB.
|
|
|
|
std::string type;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct IOKitEventContext : public EventContext {
|
|
|
|
enum Action {
|
|
|
|
DEVICE_ATTACH = 0,
|
|
|
|
DEVICE_DETACH,
|
|
|
|
};
|
|
|
|
|
|
|
|
Action action;
|
|
|
|
std::string type;
|
|
|
|
std::string vendor;
|
|
|
|
std::string model;
|
|
|
|
std::string vendor_id;
|
|
|
|
std::string model_id;
|
|
|
|
std::string path;
|
|
|
|
std::string driver;
|
|
|
|
std::string version;
|
|
|
|
std::string serial;
|
|
|
|
};
|
|
|
|
|
2015-12-08 01:15:30 +00:00
|
|
|
using IOKitEventContextRef = std::shared_ptr<IOKitEventContext>;
|
|
|
|
using IOKitSubscriptionContextRef = std::shared_ptr<IOKitSubscriptionContext>;
|
2015-11-16 06:37:28 +00:00
|
|
|
|
|
|
|
struct DeviceTracker;
|
|
|
|
|
|
|
|
class IOKitEventPublisher
|
|
|
|
: public EventPublisher<IOKitSubscriptionContext, IOKitEventContext> {
|
|
|
|
DECLARE_PUBLISHER("iokit");
|
|
|
|
|
|
|
|
public:
|
2018-07-23 18:13:43 +00:00
|
|
|
IOKitEventPublisher(const std::string& name = "IOKitEventPublisher")
|
|
|
|
: EventPublisher() {
|
|
|
|
runnable_name_ = name;
|
|
|
|
}
|
|
|
|
|
2015-12-08 01:15:30 +00:00
|
|
|
void tearDown() override;
|
2015-11-16 06:37:28 +00:00
|
|
|
|
2015-12-08 01:15:30 +00:00
|
|
|
Status run() override;
|
2015-11-16 06:37:28 +00:00
|
|
|
|
|
|
|
bool shouldFire(const IOKitSubscriptionContextRef& sc,
|
2015-12-08 01:15:30 +00:00
|
|
|
const IOKitEventContextRef& ec) const override;
|
2015-11-16 06:37:28 +00:00
|
|
|
|
|
|
|
public:
|
|
|
|
// Callbacks
|
|
|
|
static void deviceAttach(void* refcon, io_iterator_t iterator);
|
|
|
|
static void deviceDetach(void* refcon,
|
|
|
|
io_service_t device,
|
|
|
|
natural_t type,
|
|
|
|
void*);
|
|
|
|
|
|
|
|
void newEvent(const io_service_t& device, IOKitEventContext::Action action);
|
|
|
|
|
|
|
|
private:
|
|
|
|
void restart();
|
2016-03-12 09:23:09 +00:00
|
|
|
void stop() override;
|
2015-11-16 06:37:28 +00:00
|
|
|
|
|
|
|
private:
|
2016-03-18 23:14:15 +00:00
|
|
|
/// The publisher state machine will start, restart, and stop the run loop.
|
2015-12-08 01:15:30 +00:00
|
|
|
CFRunLoopRef run_loop_{nullptr};
|
2015-11-16 06:37:28 +00:00
|
|
|
|
2016-03-18 23:14:15 +00:00
|
|
|
/// Notification port, should close.
|
2015-12-08 01:15:30 +00:00
|
|
|
IONotificationPortRef port_{nullptr};
|
2015-11-16 06:37:28 +00:00
|
|
|
|
2016-03-18 23:14:15 +00:00
|
|
|
/// Device attach iterator.
|
2015-11-16 06:37:28 +00:00
|
|
|
io_iterator_t iterator_;
|
|
|
|
|
2016-03-18 23:14:15 +00:00
|
|
|
/// Device detach notification.
|
|
|
|
std::vector<std::shared_ptr<struct DeviceTracker>> devices_;
|
2015-11-16 06:37:28 +00:00
|
|
|
|
2016-03-18 23:14:15 +00:00
|
|
|
/// Device notification and container access protection mutex.
|
|
|
|
mutable Mutex mutex_;
|
2015-11-16 06:37:28 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Should events be emitted by the callback.
|
|
|
|
*
|
|
|
|
* The callback registration initially returns all matches, these must be
|
|
|
|
* consumed by an iterator walk. Do not emit events for this initial seed.
|
|
|
|
* The publisher started boolean is set after a successful restart.
|
|
|
|
*/
|
2016-03-18 23:14:15 +00:00
|
|
|
std::atomic<bool> publisher_started_{false};
|
2015-11-16 06:37:28 +00:00
|
|
|
};
|
|
|
|
}
|