endpoint_security 0.1.0-universal-darwin
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.rubocop.yml +44 -0
- data/LICENSE.txt +21 -0
- data/README.md +114 -0
- data/Rakefile +170 -0
- data/codegen/ast.rb +67 -0
- data/codegen/emit_c.rb +68 -0
- data/codegen/emit_ruby.rb +128 -0
- data/codegen/ir.rb +193 -0
- data/codegen/overlay/availability.yml +158 -0
- data/codegen/overlay/version_map.yml +92 -0
- data/codegen/run.rb +80 -0
- data/codegen/snapshots/26.5.json +5828 -0
- data/examples/eslogger_clone.rb +5 -0
- data/examples/execblock.rb +16 -0
- data/examples/filemon.rb +10 -0
- data/examples/procmon.rb +13 -0
- data/ext/endpoint_security/client.c +795 -0
- data/ext/endpoint_security/client.h +88 -0
- data/ext/endpoint_security/endpoint_security.c +17 -0
- data/ext/endpoint_security/extconf.rb +37 -0
- data/ext/endpoint_security/field.c +719 -0
- data/ext/endpoint_security/field.h +42 -0
- data/ext/endpoint_security/generated/es_schema.c +1233 -0
- data/ext/endpoint_security/message.c +426 -0
- data/ext/endpoint_security/message.h +13 -0
- data/ext/endpoint_security/mute.c +291 -0
- data/ext/endpoint_security/mute.h +8 -0
- data/ext/endpoint_security/queue.c +124 -0
- data/ext/endpoint_security/queue.h +46 -0
- data/ext/endpoint_security/watchdog.c +243 -0
- data/lib/endpoint_security/availability.rb +30 -0
- data/lib/endpoint_security/client.rb +280 -0
- data/lib/endpoint_security/diagnostics.rb +26 -0
- data/lib/endpoint_security/doctor.rb +35 -0
- data/lib/endpoint_security/errors.rb +42 -0
- data/lib/endpoint_security/generated/availability.rb +169 -0
- data/lib/endpoint_security/generated/enums.rb +409 -0
- data/lib/endpoint_security/generated/event_types.rb +520 -0
- data/lib/endpoint_security/message.rb +29 -0
- data/lib/endpoint_security/object_model.rb +170 -0
- data/lib/endpoint_security/recorder.rb +26 -0
- data/lib/endpoint_security/version.rb +6 -0
- data/lib/endpoint_security.rb +38 -0
- data/support/entitlements.plist +8 -0
- data/support/esmock/esmock.c +482 -0
- data/support/esmock/esmock.h +21 -0
- data/support/sign_ruby.sh +13 -0
- metadata +90 -0
|
@@ -0,0 +1,482 @@
|
|
|
1
|
+
/* esmock.c
|
|
2
|
+
* Calling threads: tests invoke injection; the copied ES handler may enqueue without the GVL.
|
|
3
|
+
*/
|
|
4
|
+
#include "esmock.h"
|
|
5
|
+
|
|
6
|
+
#include <Block.h>
|
|
7
|
+
#include <mach/mach_time.h>
|
|
8
|
+
#include <pthread.h>
|
|
9
|
+
#include <stdatomic.h>
|
|
10
|
+
#include <stddef.h>
|
|
11
|
+
#include <stdlib.h>
|
|
12
|
+
#include <string.h>
|
|
13
|
+
#include <time.h>
|
|
14
|
+
|
|
15
|
+
struct es_client_s {
|
|
16
|
+
es_handler_block_t handler;
|
|
17
|
+
pthread_t creator;
|
|
18
|
+
bool subscriptions[ES_EVENT_TYPE_LAST];
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
typedef struct {
|
|
22
|
+
_Atomic size_t references;
|
|
23
|
+
es_process_t process;
|
|
24
|
+
es_process_t target;
|
|
25
|
+
es_file_t executable;
|
|
26
|
+
es_file_t target_executable;
|
|
27
|
+
struct statfs statfs;
|
|
28
|
+
es_sha256_t sha256;
|
|
29
|
+
void *event_data;
|
|
30
|
+
es_message_t message;
|
|
31
|
+
} mock_message_t;
|
|
32
|
+
|
|
33
|
+
static _Atomic size_t responses;
|
|
34
|
+
static _Atomic uint32_t last_response;
|
|
35
|
+
static _Atomic bool inverted[3];
|
|
36
|
+
static _Atomic int next_new_client_result;
|
|
37
|
+
static _Atomic int next_respond_result;
|
|
38
|
+
static _Atomic int next_delete_result;
|
|
39
|
+
static _Atomic size_t clients;
|
|
40
|
+
static _Atomic bool delete_on_creator_thread;
|
|
41
|
+
|
|
42
|
+
static mock_message_t *
|
|
43
|
+
mock_from_message(const es_message_t *message)
|
|
44
|
+
{
|
|
45
|
+
return (mock_message_t *)((char *)message - offsetof(mock_message_t, message));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
es_new_client_result_t
|
|
49
|
+
es_new_client(es_client_t **client, es_handler_block_t handler)
|
|
50
|
+
{
|
|
51
|
+
es_new_client_result_t result = atomic_exchange_explicit(
|
|
52
|
+
&next_new_client_result, ES_NEW_CLIENT_RESULT_SUCCESS, memory_order_relaxed);
|
|
53
|
+
if (result != ES_NEW_CLIENT_RESULT_SUCCESS) {
|
|
54
|
+
*client = NULL;
|
|
55
|
+
return result;
|
|
56
|
+
}
|
|
57
|
+
*client = calloc(1, sizeof(**client));
|
|
58
|
+
if (*client == NULL) {
|
|
59
|
+
return ES_NEW_CLIENT_RESULT_ERR_INTERNAL;
|
|
60
|
+
}
|
|
61
|
+
(*client)->creator = pthread_self();
|
|
62
|
+
(*client)->handler = Block_copy(handler);
|
|
63
|
+
atomic_fetch_add_explicit(&clients, 1, memory_order_relaxed);
|
|
64
|
+
return ES_NEW_CLIENT_RESULT_SUCCESS;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
es_return_t
|
|
68
|
+
es_delete_client(es_client_t *client)
|
|
69
|
+
{
|
|
70
|
+
if (client == NULL) {
|
|
71
|
+
return ES_RETURN_ERROR;
|
|
72
|
+
}
|
|
73
|
+
atomic_store_explicit(
|
|
74
|
+
&delete_on_creator_thread, pthread_equal(client->creator, pthread_self()), memory_order_relaxed);
|
|
75
|
+
Block_release(client->handler);
|
|
76
|
+
atomic_fetch_sub_explicit(&clients, 1, memory_order_relaxed);
|
|
77
|
+
free(client);
|
|
78
|
+
return atomic_exchange_explicit(&next_delete_result, ES_RETURN_SUCCESS, memory_order_relaxed);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
es_return_t
|
|
82
|
+
es_subscribe(es_client_t *client, const es_event_type_t *events, uint32_t event_count)
|
|
83
|
+
{
|
|
84
|
+
if (client == NULL || events == NULL || event_count == 0) {
|
|
85
|
+
return ES_RETURN_ERROR;
|
|
86
|
+
}
|
|
87
|
+
for (uint32_t index = 0; index < event_count; index++) {
|
|
88
|
+
if (events[index] < 0 || events[index] >= ES_EVENT_TYPE_LAST || events[index] == ES_EVENT_TYPE_RESERVED_0) {
|
|
89
|
+
return ES_RETURN_ERROR;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
for (uint32_t index = 0; index < event_count; index++) {
|
|
93
|
+
client->subscriptions[events[index]] = true;
|
|
94
|
+
}
|
|
95
|
+
return ES_RETURN_SUCCESS;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
es_return_t
|
|
99
|
+
es_unsubscribe(es_client_t *client, const es_event_type_t *events, uint32_t event_count)
|
|
100
|
+
{
|
|
101
|
+
if (client == NULL || events == NULL || event_count == 0) {
|
|
102
|
+
return ES_RETURN_ERROR;
|
|
103
|
+
}
|
|
104
|
+
for (uint32_t index = 0; index < event_count; index++) {
|
|
105
|
+
if (events[index] < 0 || events[index] >= ES_EVENT_TYPE_LAST) {
|
|
106
|
+
return ES_RETURN_ERROR;
|
|
107
|
+
}
|
|
108
|
+
client->subscriptions[events[index]] = false;
|
|
109
|
+
}
|
|
110
|
+
return ES_RETURN_SUCCESS;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
es_return_t
|
|
114
|
+
es_unsubscribe_all(es_client_t *client)
|
|
115
|
+
{
|
|
116
|
+
if (client == NULL) {
|
|
117
|
+
return ES_RETURN_ERROR;
|
|
118
|
+
}
|
|
119
|
+
memset(client->subscriptions, 0, sizeof(client->subscriptions));
|
|
120
|
+
return ES_RETURN_SUCCESS;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
es_return_t
|
|
124
|
+
es_subscriptions(es_client_t *client, size_t *count, es_event_type_t **subscriptions)
|
|
125
|
+
{
|
|
126
|
+
if (client == NULL || count == NULL || subscriptions == NULL) {
|
|
127
|
+
return ES_RETURN_ERROR;
|
|
128
|
+
}
|
|
129
|
+
*count = 0;
|
|
130
|
+
for (size_t index = 0; index < ES_EVENT_TYPE_LAST; index++) {
|
|
131
|
+
*count += client->subscriptions[index] ? 1 : 0;
|
|
132
|
+
}
|
|
133
|
+
*subscriptions = *count == 0 ? NULL : malloc(*count * sizeof(**subscriptions));
|
|
134
|
+
if (*count > 0 && *subscriptions == NULL) {
|
|
135
|
+
return ES_RETURN_ERROR;
|
|
136
|
+
}
|
|
137
|
+
size_t output = 0;
|
|
138
|
+
for (size_t index = 0; index < ES_EVENT_TYPE_LAST; index++) {
|
|
139
|
+
if (client->subscriptions[index]) {
|
|
140
|
+
(*subscriptions)[output++] = (es_event_type_t)index;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return ES_RETURN_SUCCESS;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
es_return_t
|
|
147
|
+
es_mute_process(es_client_t *client, const audit_token_t *token)
|
|
148
|
+
{
|
|
149
|
+
return client != NULL && token != NULL ? ES_RETURN_SUCCESS : ES_RETURN_ERROR;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
es_return_t
|
|
153
|
+
es_unmute_process(es_client_t *client, const audit_token_t *token)
|
|
154
|
+
{
|
|
155
|
+
return es_mute_process(client, token);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
es_return_t
|
|
159
|
+
es_mute_process_events(es_client_t *client, const audit_token_t *token, const es_event_type_t *events, size_t count)
|
|
160
|
+
{
|
|
161
|
+
return client != NULL && token != NULL && events != NULL && count > 0 ? ES_RETURN_SUCCESS : ES_RETURN_ERROR;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
es_return_t
|
|
165
|
+
es_unmute_process_events(es_client_t *client, const audit_token_t *token, const es_event_type_t *events, size_t count)
|
|
166
|
+
{
|
|
167
|
+
return es_mute_process_events(client, token, events, count);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
es_return_t
|
|
171
|
+
es_mute_path(es_client_t *client, const char *path, es_mute_path_type_t type)
|
|
172
|
+
{
|
|
173
|
+
(void)type;
|
|
174
|
+
return client != NULL && path != NULL ? ES_RETURN_SUCCESS : ES_RETURN_ERROR;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
es_return_t
|
|
178
|
+
es_unmute_path(es_client_t *client, const char *path, es_mute_path_type_t type)
|
|
179
|
+
{
|
|
180
|
+
return es_mute_path(client, path, type);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
es_return_t
|
|
184
|
+
es_mute_path_events(
|
|
185
|
+
es_client_t *client, const char *path, es_mute_path_type_t type, const es_event_type_t *events, size_t count)
|
|
186
|
+
{
|
|
187
|
+
(void)type;
|
|
188
|
+
return client != NULL && path != NULL && events != NULL && count > 0 ? ES_RETURN_SUCCESS : ES_RETURN_ERROR;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
es_return_t
|
|
192
|
+
es_unmute_path_events(
|
|
193
|
+
es_client_t *client, const char *path, es_mute_path_type_t type, const es_event_type_t *events, size_t count)
|
|
194
|
+
{
|
|
195
|
+
return es_mute_path_events(client, path, type, events, count);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
es_return_t
|
|
199
|
+
es_unmute_all_paths(es_client_t *client)
|
|
200
|
+
{
|
|
201
|
+
return client == NULL ? ES_RETURN_ERROR : ES_RETURN_SUCCESS;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
es_return_t
|
|
205
|
+
es_unmute_all_target_paths(es_client_t *client)
|
|
206
|
+
{
|
|
207
|
+
return es_unmute_all_paths(client);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
es_return_t
|
|
211
|
+
es_invert_muting(es_client_t *client, es_mute_inversion_type_t type)
|
|
212
|
+
{
|
|
213
|
+
if (client == NULL || type < 0 || type >= ES_MUTE_INVERSION_TYPE_LAST) {
|
|
214
|
+
return ES_RETURN_ERROR;
|
|
215
|
+
}
|
|
216
|
+
atomic_fetch_xor_explicit(&inverted[type], true, memory_order_relaxed);
|
|
217
|
+
return ES_RETURN_SUCCESS;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
es_mute_inverted_return_t
|
|
221
|
+
es_muting_inverted(es_client_t *client, es_mute_inversion_type_t type)
|
|
222
|
+
{
|
|
223
|
+
if (client == NULL || type < 0 || type >= ES_MUTE_INVERSION_TYPE_LAST) {
|
|
224
|
+
return ES_MUTE_INVERTED_ERROR;
|
|
225
|
+
}
|
|
226
|
+
return atomic_load_explicit(&inverted[type], memory_order_relaxed) ? ES_MUTE_INVERTED : ES_MUTE_NOT_INVERTED;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
es_clear_cache_result_t
|
|
230
|
+
es_clear_cache(es_client_t *client)
|
|
231
|
+
{
|
|
232
|
+
return client == NULL ? ES_CLEAR_CACHE_RESULT_ERR_INTERNAL : ES_CLEAR_CACHE_RESULT_SUCCESS;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
es_return_t
|
|
236
|
+
es_muted_paths_events(es_client_t *client, es_muted_paths_t **paths)
|
|
237
|
+
{
|
|
238
|
+
if (client == NULL || paths == NULL) {
|
|
239
|
+
return ES_RETURN_ERROR;
|
|
240
|
+
}
|
|
241
|
+
*paths = calloc(1, sizeof(**paths));
|
|
242
|
+
return *paths == NULL ? ES_RETURN_ERROR : ES_RETURN_SUCCESS;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
void
|
|
246
|
+
es_release_muted_paths(es_muted_paths_t *paths)
|
|
247
|
+
{
|
|
248
|
+
free(paths);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
es_return_t
|
|
252
|
+
es_muted_processes_events(es_client_t *client, es_muted_processes_t **processes)
|
|
253
|
+
{
|
|
254
|
+
if (client == NULL || processes == NULL) {
|
|
255
|
+
return ES_RETURN_ERROR;
|
|
256
|
+
}
|
|
257
|
+
*processes = calloc(1, sizeof(**processes));
|
|
258
|
+
return *processes == NULL ? ES_RETURN_ERROR : ES_RETURN_SUCCESS;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
void
|
|
262
|
+
es_release_muted_processes(es_muted_processes_t *processes)
|
|
263
|
+
{
|
|
264
|
+
free(processes);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
es_respond_result_t
|
|
268
|
+
es_respond_auth_result(es_client_t *client, const es_message_t *message, es_auth_result_t result, bool cache)
|
|
269
|
+
{
|
|
270
|
+
(void)cache;
|
|
271
|
+
if (client == NULL || message == NULL) {
|
|
272
|
+
return ES_RESPOND_RESULT_ERR_INVALID_ARGUMENT;
|
|
273
|
+
}
|
|
274
|
+
es_respond_result_t response = atomic_exchange_explicit(
|
|
275
|
+
&next_respond_result, ES_RESPOND_RESULT_SUCCESS, memory_order_relaxed);
|
|
276
|
+
if (response != ES_RESPOND_RESULT_SUCCESS) {
|
|
277
|
+
return response;
|
|
278
|
+
}
|
|
279
|
+
atomic_store_explicit(&last_response, (uint32_t)result, memory_order_relaxed);
|
|
280
|
+
atomic_fetch_add_explicit(&responses, 1, memory_order_relaxed);
|
|
281
|
+
return ES_RESPOND_RESULT_SUCCESS;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
es_respond_result_t
|
|
285
|
+
es_respond_flags_result(es_client_t *client, const es_message_t *message, uint32_t flags, bool cache)
|
|
286
|
+
{
|
|
287
|
+
(void)cache;
|
|
288
|
+
if (client == NULL || message == NULL) {
|
|
289
|
+
return ES_RESPOND_RESULT_ERR_INVALID_ARGUMENT;
|
|
290
|
+
}
|
|
291
|
+
es_respond_result_t response = atomic_exchange_explicit(
|
|
292
|
+
&next_respond_result, ES_RESPOND_RESULT_SUCCESS, memory_order_relaxed);
|
|
293
|
+
if (response != ES_RESPOND_RESULT_SUCCESS) {
|
|
294
|
+
return response;
|
|
295
|
+
}
|
|
296
|
+
atomic_store_explicit(&last_response, flags, memory_order_relaxed);
|
|
297
|
+
atomic_fetch_add_explicit(&responses, 1, memory_order_relaxed);
|
|
298
|
+
return ES_RESPOND_RESULT_SUCCESS;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
void
|
|
302
|
+
es_retain_message(const es_message_t *message)
|
|
303
|
+
{
|
|
304
|
+
atomic_fetch_add_explicit(&mock_from_message(message)->references, 1, memory_order_relaxed);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
void
|
|
308
|
+
es_release_message(const es_message_t *message)
|
|
309
|
+
{
|
|
310
|
+
mock_message_t *mock = mock_from_message(message);
|
|
311
|
+
if (atomic_fetch_sub_explicit(&mock->references, 1, memory_order_acq_rel) == 1) {
|
|
312
|
+
free(mock->event_data);
|
|
313
|
+
free(mock);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
void
|
|
318
|
+
esmock_inject(
|
|
319
|
+
es_client_t *client, es_event_type_t event_type, es_action_type_t action_type, uint64_t deadline, uint32_t version,
|
|
320
|
+
size_t event_size, es_result_type_t result_type, uint32_t result, bool source_es_client)
|
|
321
|
+
{
|
|
322
|
+
mock_message_t *mock = calloc(1, sizeof(*mock));
|
|
323
|
+
atomic_init(&mock->references, 1);
|
|
324
|
+
mock->message.version = version;
|
|
325
|
+
clock_gettime(CLOCK_REALTIME, &mock->message.time);
|
|
326
|
+
mock->message.mach_time = mach_absolute_time();
|
|
327
|
+
mock->message.deadline = deadline;
|
|
328
|
+
static const char executable_path[] = "/usr/bin/mock-source";
|
|
329
|
+
static const char target_path[] = "/usr/bin/mock-target";
|
|
330
|
+
mock->executable.path.data = executable_path;
|
|
331
|
+
mock->executable.path.length = sizeof(executable_path) - 1;
|
|
332
|
+
mock->executable.path_truncated = true;
|
|
333
|
+
mock->target_executable.path.data = target_path;
|
|
334
|
+
mock->target_executable.path.length = sizeof(target_path) - 1;
|
|
335
|
+
mock->target_executable.path_truncated = true;
|
|
336
|
+
mock->process.executable = &mock->executable;
|
|
337
|
+
mock->target.executable = &mock->target_executable;
|
|
338
|
+
mock->process.cdhash[0] = 0xff;
|
|
339
|
+
mock->process.is_es_client = source_es_client;
|
|
340
|
+
mock->target.cdhash[0] = 0xff;
|
|
341
|
+
mock->message.process = &mock->process;
|
|
342
|
+
mock->message.event_type = event_type;
|
|
343
|
+
mock->message.action_type = action_type;
|
|
344
|
+
if (action_type == ES_ACTION_TYPE_NOTIFY) {
|
|
345
|
+
mock->message.action.notify.result_type = result_type;
|
|
346
|
+
if (result_type == ES_RESULT_TYPE_FLAGS) {
|
|
347
|
+
mock->message.action.notify.result.flags = result;
|
|
348
|
+
} else {
|
|
349
|
+
mock->message.action.notify.result.auth = (es_auth_result_t)result;
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
if (event_size > 0) {
|
|
353
|
+
mock->event_data = calloc(1, event_size);
|
|
354
|
+
if (mock->event_data == NULL) {
|
|
355
|
+
es_release_message(&mock->message);
|
|
356
|
+
return;
|
|
357
|
+
}
|
|
358
|
+
memcpy(&mock->message.event, &mock->event_data, sizeof(mock->event_data));
|
|
359
|
+
}
|
|
360
|
+
if (event_type == ES_EVENT_TYPE_AUTH_EXEC || event_type == ES_EVENT_TYPE_NOTIFY_EXEC) {
|
|
361
|
+
mock->message.event.exec.target = &mock->target;
|
|
362
|
+
}
|
|
363
|
+
if (event_type == ES_EVENT_TYPE_NOTIFY_MOUNT) {
|
|
364
|
+
mock->statfs.f_bsize = 4096;
|
|
365
|
+
memcpy(mock->statfs.f_fstypename, "mockfs", sizeof("mockfs"));
|
|
366
|
+
mock->message.event.mount.statfs = &mock->statfs;
|
|
367
|
+
}
|
|
368
|
+
if (event_type == ES_EVENT_TYPE_NOTIFY_GETATTRLIST) {
|
|
369
|
+
mock->message.event.getattrlist.attrlist.bitmapcount = ATTR_BIT_MAP_COUNT;
|
|
370
|
+
mock->message.event.getattrlist.attrlist.commonattr = 1;
|
|
371
|
+
}
|
|
372
|
+
if (event_type == ES_EVENT_TYPE_NOTIFY_GATEKEEPER_USER_OVERRIDE) {
|
|
373
|
+
es_event_gatekeeper_user_override_t *gatekeeper = mock->event_data;
|
|
374
|
+
mock->sha256[0] = 0xff;
|
|
375
|
+
gatekeeper->sha256 = &mock->sha256;
|
|
376
|
+
}
|
|
377
|
+
client->handler(client, &mock->message);
|
|
378
|
+
es_release_message(&mock->message);
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
size_t
|
|
382
|
+
esmock_response_count(void)
|
|
383
|
+
{
|
|
384
|
+
return atomic_load_explicit(&responses, memory_order_relaxed);
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
uint32_t
|
|
388
|
+
esmock_last_response(void)
|
|
389
|
+
{
|
|
390
|
+
return atomic_load_explicit(&last_response, memory_order_relaxed);
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
size_t
|
|
394
|
+
esmock_client_count(void)
|
|
395
|
+
{
|
|
396
|
+
return atomic_load_explicit(&clients, memory_order_relaxed);
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
bool
|
|
400
|
+
esmock_delete_on_creator_thread(void)
|
|
401
|
+
{
|
|
402
|
+
return atomic_load_explicit(&delete_on_creator_thread, memory_order_relaxed);
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
void
|
|
406
|
+
esmock_set_new_client_result(es_new_client_result_t result)
|
|
407
|
+
{
|
|
408
|
+
atomic_store_explicit(&next_new_client_result, result, memory_order_relaxed);
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
void
|
|
412
|
+
esmock_set_respond_result(es_respond_result_t result)
|
|
413
|
+
{
|
|
414
|
+
atomic_store_explicit(&next_respond_result, result, memory_order_relaxed);
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
void
|
|
418
|
+
esmock_set_delete_result(es_return_t result)
|
|
419
|
+
{
|
|
420
|
+
atomic_store_explicit(&next_delete_result, result, memory_order_relaxed);
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
void
|
|
424
|
+
esmock_reset(void)
|
|
425
|
+
{
|
|
426
|
+
atomic_store_explicit(&responses, 0, memory_order_relaxed);
|
|
427
|
+
atomic_store_explicit(&last_response, 0, memory_order_relaxed);
|
|
428
|
+
atomic_store_explicit(&next_new_client_result, ES_NEW_CLIENT_RESULT_SUCCESS, memory_order_relaxed);
|
|
429
|
+
atomic_store_explicit(&next_respond_result, ES_RESPOND_RESULT_SUCCESS, memory_order_relaxed);
|
|
430
|
+
atomic_store_explicit(&next_delete_result, ES_RETURN_SUCCESS, memory_order_relaxed);
|
|
431
|
+
atomic_store_explicit(&clients, 0, memory_order_relaxed);
|
|
432
|
+
atomic_store_explicit(&delete_on_creator_thread, true, memory_order_relaxed);
|
|
433
|
+
for (size_t index = 0; index < 3; index++) {
|
|
434
|
+
atomic_store_explicit(&inverted[index], false, memory_order_relaxed);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
uint32_t
|
|
439
|
+
es_exec_arg_count(const es_event_exec_t *event)
|
|
440
|
+
{
|
|
441
|
+
(void)event;
|
|
442
|
+
return 0;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
uint32_t
|
|
446
|
+
es_exec_env_count(const es_event_exec_t *event)
|
|
447
|
+
{
|
|
448
|
+
(void)event;
|
|
449
|
+
return 0;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
uint32_t
|
|
453
|
+
es_exec_fd_count(const es_event_exec_t *event)
|
|
454
|
+
{
|
|
455
|
+
(void)event;
|
|
456
|
+
return 0;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
es_string_token_t
|
|
460
|
+
es_exec_arg(const es_event_exec_t *event, uint32_t index)
|
|
461
|
+
{
|
|
462
|
+
(void)event;
|
|
463
|
+
(void)index;
|
|
464
|
+
return (es_string_token_t){0};
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
es_string_token_t
|
|
468
|
+
es_exec_env(const es_event_exec_t *event, uint32_t index)
|
|
469
|
+
{
|
|
470
|
+
(void)event;
|
|
471
|
+
(void)index;
|
|
472
|
+
return (es_string_token_t){0};
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
const es_fd_t *
|
|
476
|
+
es_exec_fd(const es_event_exec_t *event, uint32_t index)
|
|
477
|
+
{
|
|
478
|
+
static const es_fd_t empty = {0};
|
|
479
|
+
(void)event;
|
|
480
|
+
(void)index;
|
|
481
|
+
return ∅
|
|
482
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#ifndef ESMOCK_H
|
|
2
|
+
#define ESMOCK_H
|
|
3
|
+
|
|
4
|
+
#include <EndpointSecurity/EndpointSecurity.h>
|
|
5
|
+
#include <stdbool.h>
|
|
6
|
+
#include <stddef.h>
|
|
7
|
+
#include <stdint.h>
|
|
8
|
+
|
|
9
|
+
void esmock_inject(
|
|
10
|
+
es_client_t *client, es_event_type_t event_type, es_action_type_t action_type, uint64_t deadline, uint32_t version,
|
|
11
|
+
size_t event_size, es_result_type_t result_type, uint32_t result, bool source_es_client);
|
|
12
|
+
size_t esmock_response_count(void);
|
|
13
|
+
uint32_t esmock_last_response(void);
|
|
14
|
+
size_t esmock_client_count(void);
|
|
15
|
+
bool esmock_delete_on_creator_thread(void);
|
|
16
|
+
void esmock_set_new_client_result(es_new_client_result_t result);
|
|
17
|
+
void esmock_set_respond_result(es_respond_result_t result);
|
|
18
|
+
void esmock_set_delete_result(es_return_t result);
|
|
19
|
+
void esmock_reset(void);
|
|
20
|
+
|
|
21
|
+
#endif
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
set -eu
|
|
3
|
+
|
|
4
|
+
source_ruby=${1:?ruby executable is required}
|
|
5
|
+
identity=${2:--}
|
|
6
|
+
project_root=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)
|
|
7
|
+
destination="$project_root/build/es-ruby"
|
|
8
|
+
|
|
9
|
+
mkdir -p "$project_root/build"
|
|
10
|
+
cp "$source_ruby" "$destination"
|
|
11
|
+
codesign --force --options runtime --entitlements "$project_root/support/entitlements.plist" --sign "$identity" "$destination"
|
|
12
|
+
codesign --verify --strict --verbose=2 "$destination"
|
|
13
|
+
codesign -d --entitlements - "$destination"
|
metadata
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: endpoint_security
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: universal-darwin
|
|
6
|
+
authors:
|
|
7
|
+
- Yudai Takada
|
|
8
|
+
bindir: exe
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies: []
|
|
12
|
+
description: A native Ruby interface to macOS EndpointSecurity.
|
|
13
|
+
email:
|
|
14
|
+
- t.yudai92@gmail.com
|
|
15
|
+
executables: []
|
|
16
|
+
extensions:
|
|
17
|
+
- ext/endpoint_security/extconf.rb
|
|
18
|
+
extra_rdoc_files: []
|
|
19
|
+
files:
|
|
20
|
+
- ".rubocop.yml"
|
|
21
|
+
- LICENSE.txt
|
|
22
|
+
- README.md
|
|
23
|
+
- Rakefile
|
|
24
|
+
- codegen/ast.rb
|
|
25
|
+
- codegen/emit_c.rb
|
|
26
|
+
- codegen/emit_ruby.rb
|
|
27
|
+
- codegen/ir.rb
|
|
28
|
+
- codegen/overlay/availability.yml
|
|
29
|
+
- codegen/overlay/version_map.yml
|
|
30
|
+
- codegen/run.rb
|
|
31
|
+
- codegen/snapshots/26.5.json
|
|
32
|
+
- examples/eslogger_clone.rb
|
|
33
|
+
- examples/execblock.rb
|
|
34
|
+
- examples/filemon.rb
|
|
35
|
+
- examples/procmon.rb
|
|
36
|
+
- ext/endpoint_security/client.c
|
|
37
|
+
- ext/endpoint_security/client.h
|
|
38
|
+
- ext/endpoint_security/endpoint_security.c
|
|
39
|
+
- ext/endpoint_security/extconf.rb
|
|
40
|
+
- ext/endpoint_security/field.c
|
|
41
|
+
- ext/endpoint_security/field.h
|
|
42
|
+
- ext/endpoint_security/generated/es_schema.c
|
|
43
|
+
- ext/endpoint_security/message.c
|
|
44
|
+
- ext/endpoint_security/message.h
|
|
45
|
+
- ext/endpoint_security/mute.c
|
|
46
|
+
- ext/endpoint_security/mute.h
|
|
47
|
+
- ext/endpoint_security/queue.c
|
|
48
|
+
- ext/endpoint_security/queue.h
|
|
49
|
+
- ext/endpoint_security/watchdog.c
|
|
50
|
+
- lib/endpoint_security.rb
|
|
51
|
+
- lib/endpoint_security/availability.rb
|
|
52
|
+
- lib/endpoint_security/client.rb
|
|
53
|
+
- lib/endpoint_security/diagnostics.rb
|
|
54
|
+
- lib/endpoint_security/doctor.rb
|
|
55
|
+
- lib/endpoint_security/errors.rb
|
|
56
|
+
- lib/endpoint_security/generated/availability.rb
|
|
57
|
+
- lib/endpoint_security/generated/enums.rb
|
|
58
|
+
- lib/endpoint_security/generated/event_types.rb
|
|
59
|
+
- lib/endpoint_security/message.rb
|
|
60
|
+
- lib/endpoint_security/object_model.rb
|
|
61
|
+
- lib/endpoint_security/recorder.rb
|
|
62
|
+
- lib/endpoint_security/version.rb
|
|
63
|
+
- support/entitlements.plist
|
|
64
|
+
- support/esmock/esmock.c
|
|
65
|
+
- support/esmock/esmock.h
|
|
66
|
+
- support/sign_ruby.sh
|
|
67
|
+
homepage: https://github.com/YudaiTakada/endpoint_security
|
|
68
|
+
licenses:
|
|
69
|
+
- MIT
|
|
70
|
+
metadata:
|
|
71
|
+
homepage_uri: https://github.com/YudaiTakada/endpoint_security
|
|
72
|
+
rubygems_mfa_required: 'true'
|
|
73
|
+
rdoc_options: []
|
|
74
|
+
require_paths:
|
|
75
|
+
- lib
|
|
76
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
77
|
+
requirements:
|
|
78
|
+
- - ">="
|
|
79
|
+
- !ruby/object:Gem::Version
|
|
80
|
+
version: 3.2.0
|
|
81
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
82
|
+
requirements:
|
|
83
|
+
- - ">="
|
|
84
|
+
- !ruby/object:Gem::Version
|
|
85
|
+
version: '0'
|
|
86
|
+
requirements: []
|
|
87
|
+
rubygems_version: 4.0.19
|
|
88
|
+
specification_version: 4
|
|
89
|
+
summary: Ruby bindings for Apple's EndpointSecurity framework
|
|
90
|
+
test_files: []
|