mirror of
https://github.com/valitydev/osquery-1.git
synced 2024-11-07 01:55:20 +00:00
Publisher and Table for Event Tap Capture (KeyDown) (#3829)
This commit is contained in:
parent
869ac6fe5e
commit
cd88cecc9a
89
osquery/events/darwin/event_taps.cpp
Normal file
89
osquery/events/darwin/event_taps.cpp
Normal file
@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (c) 2014-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <osquery/flags.h>
|
||||
|
||||
#include "osquery/events/darwin/event_taps.h"
|
||||
|
||||
namespace osquery {
|
||||
|
||||
/// Flag that turns the eventing system for event taps on or off
|
||||
FLAG(bool,
|
||||
enable_keyboard_events,
|
||||
false,
|
||||
"Enable listening for keyboard events");
|
||||
|
||||
REGISTER(EventTappingEventPublisher, "event_publisher", "event_tapping");
|
||||
|
||||
CGEventRef EventTappingEventPublisher::eventCallback(CGEventTapProxy proxy,
|
||||
CGEventType type,
|
||||
CGEventRef event,
|
||||
void* refcon) {
|
||||
auto ec = createEventContext();
|
||||
EventFactory::fire<EventTappingEventPublisher>(ec);
|
||||
return event;
|
||||
}
|
||||
|
||||
Status EventTappingEventPublisher::setUp() {
|
||||
if (!FLAGS_enable_keyboard_events) {
|
||||
return Status(1, "Publisher disabled via configuration");
|
||||
}
|
||||
return Status(0);
|
||||
}
|
||||
|
||||
void EventTappingEventPublisher::tearDown() {
|
||||
stop();
|
||||
}
|
||||
|
||||
void EventTappingEventPublisher::stop() {
|
||||
WriteLock lock(run_loop_mutex_);
|
||||
|
||||
if (run_loop_source_ != nullptr) {
|
||||
CFRunLoopRemoveSource(run_loop_, run_loop_source_, kCFRunLoopCommonModes);
|
||||
CFRelease(run_loop_source_);
|
||||
run_loop_source_ = nullptr;
|
||||
}
|
||||
if (run_loop_ != nullptr) {
|
||||
CFRunLoopStop(run_loop_);
|
||||
run_loop_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void EventTappingEventPublisher::restart() {
|
||||
stop();
|
||||
WriteLock lock(run_loop_mutex_);
|
||||
|
||||
run_loop_ = CFRunLoopGetCurrent();
|
||||
CGEventMask eventMask = (1 << kCGEventKeyDown);
|
||||
CFMachPortRef eventTap = CGEventTapCreate(kCGSessionEventTap,
|
||||
kCGHeadInsertEventTap,
|
||||
kCGEventTapOptionListenOnly,
|
||||
eventMask,
|
||||
eventCallback,
|
||||
NULL);
|
||||
run_loop_source_ =
|
||||
CFMachPortCreateRunLoopSource(kCFAllocatorDefault, eventTap, 0);
|
||||
CFRunLoopAddSource(run_loop_, run_loop_source_, kCFRunLoopCommonModes);
|
||||
CGEventTapEnable(eventTap, true);
|
||||
CFRelease(eventTap);
|
||||
}
|
||||
|
||||
Status EventTappingEventPublisher::run() {
|
||||
restart();
|
||||
CFRunLoopRun();
|
||||
return Status(0);
|
||||
}
|
||||
|
||||
bool EventTappingEventPublisher::shouldFire(
|
||||
const EventTappingSubscriptionContextRef& mc,
|
||||
const EventTappingEventContextRef& ec) const {
|
||||
return true;
|
||||
}
|
||||
}
|
68
osquery/events/darwin/event_taps.h
Normal file
68
osquery/events/darwin/event_taps.h
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (c) 2014-present, 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
|
||||
#include <osquery/events.h>
|
||||
|
||||
namespace osquery {
|
||||
|
||||
struct EventTappingSubscriptionContext : public SubscriptionContext {};
|
||||
struct EventTappingEventContext : public EventContext {};
|
||||
|
||||
using EventTappingEventContextRef = std::shared_ptr<EventTappingEventContext>;
|
||||
using EventTappingSubscriptionContextRef =
|
||||
std::shared_ptr<EventTappingSubscriptionContext>;
|
||||
|
||||
/// This is a dispatched service that handles published EventTapping events.
|
||||
class EventTappingConsumerRunner;
|
||||
|
||||
class EventTappingEventPublisher
|
||||
: public EventPublisher<EventTappingSubscriptionContext,
|
||||
EventTappingEventContext> {
|
||||
DECLARE_PUBLISHER("event_tapping");
|
||||
|
||||
public:
|
||||
Status setUp() override;
|
||||
|
||||
void tearDown() override;
|
||||
|
||||
void stop() override;
|
||||
|
||||
void restart();
|
||||
|
||||
Status run() override;
|
||||
|
||||
EventTappingEventPublisher() : EventPublisher() {}
|
||||
|
||||
virtual ~EventTappingEventPublisher() {
|
||||
tearDown();
|
||||
}
|
||||
|
||||
private:
|
||||
/// Apply normal subscription to event matching logic.
|
||||
bool shouldFire(const EventTappingSubscriptionContextRef& mc,
|
||||
const EventTappingEventContextRef& ec) const override;
|
||||
|
||||
static CGEventRef eventCallback(CGEventTapProxy proxy,
|
||||
CGEventType type,
|
||||
CGEventRef event,
|
||||
void* refcon);
|
||||
|
||||
/// This publisher thread's runloop.
|
||||
CFRunLoopSourceRef run_loop_source_{nullptr};
|
||||
CFRunLoopRef run_loop_{nullptr};
|
||||
|
||||
/// Storage/container operations protection mutex.
|
||||
mutable Mutex run_loop_mutex_;
|
||||
};
|
||||
} // namespace osquery
|
42
osquery/tables/events/darwin/key_events.cpp
Normal file
42
osquery/tables/events/darwin/key_events.cpp
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2014-present, Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD-style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "osquery/events/darwin/event_taps.h"
|
||||
|
||||
namespace osquery {
|
||||
|
||||
class EventTapsKeySubscriber
|
||||
: public EventSubscriber<EventTappingEventPublisher> {
|
||||
public:
|
||||
Status init() override {
|
||||
return Status(0);
|
||||
}
|
||||
|
||||
void configure() override;
|
||||
|
||||
Status Callback(const EventTappingEventContextRef& ec,
|
||||
const EventTappingSubscriptionContextRef& sc);
|
||||
};
|
||||
|
||||
REGISTER(EventTapsKeySubscriber, "event_subscriber", "key_events");
|
||||
|
||||
void EventTapsKeySubscriber::configure() {
|
||||
auto sc = createSubscriptionContext();
|
||||
subscribe(&EventTapsKeySubscriber::Callback, sc);
|
||||
}
|
||||
|
||||
Status EventTapsKeySubscriber::Callback(
|
||||
const EventTappingEventContextRef& ec,
|
||||
const EventTappingSubscriptionContextRef& sc) {
|
||||
Row r;
|
||||
add(r);
|
||||
return Status(0);
|
||||
}
|
||||
} // namespace osquery
|
7
specs/darwin/key_events.table
Normal file
7
specs/darwin/key_events.table
Normal file
@ -0,0 +1,7 @@
|
||||
table_name("key_events")
|
||||
description("Track key events.")
|
||||
schema([
|
||||
Column("time", BIGINT, "Time")
|
||||
])
|
||||
attributes(event_subscriber=True)
|
||||
implementation("events/darwin/key_events@key_events::genTable")
|
Loading…
Reference in New Issue
Block a user