diff options
Diffstat (limited to 'connector/proc_collector_linux.cpp')
-rwxr-xr-x | connector/proc_collector_linux.cpp | 618 |
1 files changed, 618 insertions, 0 deletions
diff --git a/connector/proc_collector_linux.cpp b/connector/proc_collector_linux.cpp new file mode 100755 index 0000000..478ac2b --- /dev/null +++ b/connector/proc_collector_linux.cpp | |||
@@ -0,0 +1,618 @@ | |||
1 | #ifndef WIN32 | ||
2 | #include <sys/socket.h> | ||
3 | #include <linux/netlink.h> | ||
4 | #include <linux/connector.h> | ||
5 | #include <linux/cn_proc.h> | ||
6 | #include <errno.h> | ||
7 | #include <sys/select.h> | ||
8 | #include <sys/types.h> | ||
9 | #include <sys/time.h> | ||
10 | #include <unistd.h> | ||
11 | |||
12 | #include "os_crypto/md5/md5_op.h" | ||
13 | #include "external/procps/readproc.h" | ||
14 | #include "proc_collector.h" | ||
15 | |||
16 | static struct | ||
17 | { | ||
18 | int queue_fd; | ||
19 | int proc_fd; | ||
20 | } proc_monitor = | ||
21 | { | ||
22 | .queue_fd = -1, | ||
23 | .proc_fd = -1 | ||
24 | }; | ||
25 | |||
26 | typedef struct __attribute__((aligned(NLMSG_ALIGNTO))) | ||
27 | { | ||
28 | struct nlmsghdr nl_hdr; | ||
29 | struct __attribute__((__packed__)) | ||
30 | { | ||
31 | struct cn_msg cn_msg; | ||
32 | enum proc_cn_mcast_op cn_mcast; | ||
33 | }; | ||
34 | } register_msg_t; | ||
35 | |||
36 | typedef struct __attribute__((aligned(NLMSG_ALIGNTO))) | ||
37 | { | ||
38 | struct nlmsghdr nl_hdr; | ||
39 | struct __attribute__((__packed__)) | ||
40 | { | ||
41 | struct cn_msg cn_msg; | ||
42 | struct proc_event proc_ev; | ||
43 | }; | ||
44 | } event_msg_t; | ||
45 | |||
46 | #define MAX_TEMP_PROCESS 5000 | ||
47 | #define TEMP_WAIT_TIME 1 | ||
48 | #define PROCESS_SLOT_EMPTY 0 | ||
49 | #define MAX_PATH_NAME 4096 | ||
50 | #define MAX_PIPE_WAIT_USECOND 100 | ||
51 | |||
52 | |||
53 | typedef struct | ||
54 | { | ||
55 | pid_t pid; | ||
56 | pid_t ppid; | ||
57 | time_t fork_time; | ||
58 | int status; | ||
59 | char path[MAX_PATH_NAME]; | ||
60 | os_md5 md5; | ||
61 | char parent_path[MAX_PATH_NAME]; | ||
62 | os_md5 parent_md5; | ||
63 | } process_parent_child_pair_t; | ||
64 | static process_parent_child_pair_t temp_processes[ MAX_TEMP_PROCESS ]; | ||
65 | |||
66 | |||
67 | /* | ||
68 | typedef struct | ||
69 | { | ||
70 | pid_t pid; // process id | ||
71 | char *name; // process name | ||
72 | char *state; //program running state | ||
73 | pid_t ppid; // parent process id | ||
74 | char *pname; // parent process name | ||
75 | ulong utime; // process time in user mode | ||
76 | ulong stime; // process time in kernel mode | ||
77 | char **cmd_line; // command line | ||
78 | char *real_user; // | ||
79 | char *effective_user; | ||
80 | char *saved_user; | ||
81 | char *fs_user; | ||
82 | char *real_group; | ||
83 | char *effective_group; | ||
84 | char *saved_group; | ||
85 | char *fs_group; | ||
86 | int priority; // process priority | ||
87 | int nice; // nice value | ||
88 | long size; // the toal memory | ||
89 | long vm_size; // virtual memory | ||
90 | long resident; // occupied physical memory | ||
91 | long share; // shared memory | ||
92 | time_t start_time; // process startup time | ||
93 | int pgrp; /// process group | ||
94 | int session; // session id | ||
95 | long nlwp; // number of thread | ||
96 | int tgid; // task group id | ||
97 | int tty; // control terminal | ||
98 | int processor; // cpu number last executed on | ||
99 | } proc_info_t; | ||
100 | */ | ||
101 | |||
102 | |||
103 | static void wm_proc_cleanup() | ||
104 | { | ||
105 | if ( proc_monitor.proc_fd > 0 ) | ||
106 | { | ||
107 | close( proc_monitor.proc_fd ); | ||
108 | proc_monitor.proc_fd = -1; | ||
109 | } | ||
110 | |||
111 | if ( proc_monitor.queue_fd > 0 ) | ||
112 | { | ||
113 | close( proc_monitor.queue_fd ); | ||
114 | proc_monitor.queue_fd = -1; | ||
115 | } | ||
116 | } | ||
117 | |||
118 | |||
119 | static int wm_setup_netlink( ) | ||
120 | { | ||
121 | int rc; | ||
122 | int nl_sock; | ||
123 | struct sockaddr_nl sa_nl; | ||
124 | register_msg_t nlcn_msg; | ||
125 | |||
126 | nl_sock = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR); | ||
127 | if (nl_sock == -1) | ||
128 | { | ||
129 | mterror( WM_PROC_LOGTAG, "Can't open netlink socket"); | ||
130 | return -1; | ||
131 | } | ||
132 | |||
133 | sa_nl.nl_family = AF_NETLINK; | ||
134 | sa_nl.nl_groups = CN_IDX_PROC; | ||
135 | sa_nl.nl_pid = getpid(); // 向内核注册 | ||
136 | |||
137 | rc = bind(nl_sock, (struct sockaddr *)&sa_nl, sizeof(sa_nl)); | ||
138 | if (rc == -1) | ||
139 | { | ||
140 | mterror( WM_PROC_LOGTAG, "Can't bind netlink socket"); | ||
141 | close(nl_sock); | ||
142 | return -1; | ||
143 | } | ||
144 | |||
145 | // create listener | ||
146 | memset(&nlcn_msg, 0, sizeof(nlcn_msg)); | ||
147 | nlcn_msg.nl_hdr.nlmsg_len = sizeof(nlcn_msg); | ||
148 | nlcn_msg.nl_hdr.nlmsg_pid = getpid(); | ||
149 | nlcn_msg.nl_hdr.nlmsg_type = NLMSG_DONE; | ||
150 | |||
151 | nlcn_msg.cn_msg.id.idx = CN_IDX_PROC; | ||
152 | nlcn_msg.cn_msg.id.val = CN_VAL_PROC; | ||
153 | nlcn_msg.cn_msg.len = sizeof(enum proc_cn_mcast_op); | ||
154 | |||
155 | nlcn_msg.cn_mcast = PROC_CN_MCAST_LISTEN ; | ||
156 | |||
157 | rc = send(nl_sock, &nlcn_msg, sizeof(nlcn_msg), 0); | ||
158 | if (rc == -1) | ||
159 | { | ||
160 | mterror(WM_PROC_LOGTAG, "can't register to netlink"); | ||
161 | close( nl_sock ); | ||
162 | return -1; | ||
163 | } | ||
164 | |||
165 | proc_monitor.proc_fd = nl_sock; | ||
166 | return 0; | ||
167 | } | ||
168 | |||
169 | static int wm_setup_mq( wm_proc_t *proc ) | ||
170 | { | ||
171 | unsigned int indx; | ||
172 | // Connect to socket | ||
173 | for (indx = 0; indx < WM_MAX_ATTEMPTS; indx++) | ||
174 | { | ||
175 | proc_monitor.queue_fd = StartMQ(DEFAULTQPATH, WRITE); | ||
176 | if ( proc_monitor.queue_fd > 0 ) | ||
177 | { | ||
178 | break; | ||
179 | } | ||
180 | wm_delay(1000 * WM_MAX_WAIT); | ||
181 | } | ||
182 | |||
183 | if (indx == WM_MAX_ATTEMPTS) | ||
184 | { | ||
185 | mterror(WM_PROC_LOGTAG, "Can't connect to queue."); | ||
186 | pthread_exit(NULL); | ||
187 | } | ||
188 | |||
189 | // Cleanup exiting | ||
190 | atexit(wm_proc_cleanup); | ||
191 | |||
192 | return 0; | ||
193 | } | ||
194 | |||
195 | int wm_proc_linux_setup( wm_proc_t *proc ) | ||
196 | { | ||
197 | memset( temp_processes, 0, sizeof( temp_processes ) ); | ||
198 | if ( wm_setup_netlink() < 0 ) | ||
199 | { | ||
200 | return -1; | ||
201 | } | ||
202 | return wm_setup_mq(proc); | ||
203 | } | ||
204 | |||
205 | static void get_path_and_md5( pid_t pid, char *path, char *md5 ) | ||
206 | { | ||
207 | char pid_path[MAX_PATH_NAME]; | ||
208 | struct stat dir_stat; | ||
209 | |||
210 | memset( pid_path, 0, MAX_PATH_NAME); | ||
211 | snprintf( pid_path, MAX_PATH_NAME-1, "/proc/%d", pid ); | ||
212 | if ( stat( pid_path, &dir_stat ) < 0 ) | ||
213 | { | ||
214 | //mterror(WM_PROC_LOGTAG, "failed to open directory %s, errno=(%d:%m)", pid_path, errno ); | ||
215 | return; | ||
216 | } | ||
217 | |||
218 | memset( pid_path, 0, MAX_PATH_NAME); | ||
219 | snprintf( pid_path, MAX_PATH_NAME-1, "/proc/%d/exe", pid ); | ||
220 | memset( path, 0, MAX_PATH_NAME ); | ||
221 | memset( md5, 0, sizeof(os_md5)); | ||
222 | if ( readlink( pid_path, path, MAX_PATH_NAME ) < 0 ) | ||
223 | { | ||
224 | memset(pid_path, 0, MAX_PATH_NAME); | ||
225 | snprintf(pid_path, MAX_PATH_NAME - 1, "/proc/%d/comm", pid); | ||
226 | memset(path, 0, MAX_PATH_NAME); | ||
227 | FILE* fp = fopen(pid_path, "rb"); | ||
228 | if ( NULL == fp ) | ||
229 | { | ||
230 | return; | ||
231 | } | ||
232 | fread( path, MAX_PATH_NAME, 1, fp ); | ||
233 | if ( strlen( path ) > 0 ) | ||
234 | { | ||
235 | path[strlen(path)-1] = '\0'; | ||
236 | } | ||
237 | fclose( fp ); | ||
238 | return; | ||
239 | } | ||
240 | |||
241 | OS_MD5_File(path, md5, OS_BINARY); | ||
242 | |||
243 | return; | ||
244 | } | ||
245 | |||
246 | |||
247 | |||
248 | static void get_process_baseinfo( const process_parent_child_pair_t *pair, const char *location ) | ||
249 | { | ||
250 | proc_t curr_proc; | ||
251 | |||
252 | memset( &curr_proc, 0, sizeof( proc_t )); | ||
253 | |||
254 | cJSON *process = cJSON_CreateObject(); | ||
255 | if( NULL == process) | ||
256 | { | ||
257 | return; | ||
258 | } | ||
259 | cJSON_AddStringToObject(process, "type", "new process"); | ||
260 | cJSON_AddNumberToObject(process, "pid", pair->pid); | ||
261 | cJSON_AddNumberToObject(process, "eventTime", pair->fork_time); | ||
262 | cJSON_AddNumberToObject(process, "ppid", pair->ppid); | ||
263 | if (strlen(pair->path) > 0) | ||
264 | { | ||
265 | cJSON_AddStringToObject(process, "exe", pair->path); | ||
266 | } | ||
267 | if (strlen(pair->md5) > 0) | ||
268 | { | ||
269 | cJSON_AddStringToObject(process, "md5", pair->md5); | ||
270 | } | ||
271 | if (strlen(pair->parent_path) > 0) | ||
272 | { | ||
273 | cJSON_AddStringToObject(process, "parent_exe", pair->parent_path); | ||
274 | } | ||
275 | if (strlen(pair->parent_md5) > 0) | ||
276 | { | ||
277 | cJSON_AddStringToObject(process, "parent_md5", pair->parent_md5); | ||
278 | } | ||
279 | |||
280 | // get process information | ||
281 | if (NULL != get_proc_stats(pair->pid, &curr_proc)) | ||
282 | { | ||
283 | cJSON_AddStringToObject(process, "state", &curr_proc.state); | ||
284 | cJSON_AddNumberToObject(process, "utime", curr_proc.utime); | ||
285 | cJSON_AddNumberToObject(process, "stime", curr_proc.stime); | ||
286 | if (curr_proc.cmdline && curr_proc.cmdline[0]) | ||
287 | { | ||
288 | cJSON *argvs = cJSON_CreateArray(); | ||
289 | cJSON_AddStringToObject(process, "cmd", curr_proc.cmdline[0]); | ||
290 | for (int i = 1; curr_proc.cmdline[i]; i++) | ||
291 | { | ||
292 | if (!strlen(curr_proc.cmdline[i]) == 0) | ||
293 | { | ||
294 | cJSON_AddItemToArray(argvs, cJSON_CreateString(curr_proc.cmdline[i])); | ||
295 | } | ||
296 | } | ||
297 | if (cJSON_GetArraySize(argvs) > 0) | ||
298 | { | ||
299 | cJSON_AddItemToObject(process, "argvs", argvs); | ||
300 | } | ||
301 | else | ||
302 | { | ||
303 | cJSON_Delete(argvs); | ||
304 | } | ||
305 | } | ||
306 | cJSON_AddStringToObject(process, "euser", curr_proc.euser); | ||
307 | cJSON_AddStringToObject(process, "egroup", curr_proc.egroup); | ||
308 | cJSON_AddNumberToObject(process, "resident", curr_proc.resident); | ||
309 | cJSON_AddNumberToObject(process, "nlwp", curr_proc.nlwp); | ||
310 | cJSON_AddNumberToObject(process, "tty", curr_proc.tty); | ||
311 | cJSON_AddNumberToObject(process, "processor", curr_proc.processor); | ||
312 | /* | ||
313 | cJSON_AddStringToObject(process, "ruser", curr_proc.ruser); | ||
314 | cJSON_AddStringToObject(process, "suser", curr_proc.suser); | ||
315 | cJSON_AddStringToObject(process, "rgroup", curr_proc.rgroup); | ||
316 | cJSON_AddStringToObject(process, "sgroup", curr_proc.sgroup); | ||
317 | cJSON_AddStringToObject(process, "fgroup", curr_proc.fgroup); | ||
318 | cJSON_AddNumberToObject(process, "priority", curr_proc.priority); | ||
319 | cJSON_AddNumberToObject(process, "nice", curr_proc.nice); | ||
320 | cJSON_AddNumberToObject(process, "size", curr_proc.size); | ||
321 | cJSON_AddNumberToObject(process, "vm_size", curr_proc.vm_size); | ||
322 | cJSON_AddNumberToObject(process, "share", curr_proc.share); | ||
323 | cJSON_AddNumberToObject(process, "pgrp", curr_proc.pgrp); | ||
324 | cJSON_AddNumberToObject(process, "session", curr_proc.session); | ||
325 | cJSON_AddNumberToObject(process, "tgid", curr_proc.tgid); | ||
326 | */ | ||
327 | } | ||
328 | |||
329 | char *msg = cJSON_PrintUnformatted(process); | ||
330 | wm_sendmsg( MAX_PIPE_WAIT_USECOND, proc_monitor.queue_fd, msg, location, PROC_COLLECTOR_MQ ); | ||
331 | free(msg); | ||
332 | cJSON_Delete( process ); | ||
333 | |||
334 | return; | ||
335 | } | ||
336 | |||
337 | static void get_process_info( const process_parent_child_pair_t *pair, const char *location ) | ||
338 | { | ||
339 | // get process base info | ||
340 | get_process_baseinfo( pair, location ); | ||
341 | |||
342 | // get process library info | ||
343 | |||
344 | // find rootkit in user mode | ||
345 | |||
346 | // check process is a malware | ||
347 | } | ||
348 | |||
349 | static void handle_temp_process( const char *location ) | ||
350 | { | ||
351 | int i = 0; | ||
352 | for ( i = 0; i < MAX_TEMP_PROCESS; i++ ) | ||
353 | { | ||
354 | if ( ( temp_processes[i].status != PROCESS_SLOT_EMPTY ) && ( temp_processes[i].ppid != 0 ) ) | ||
355 | { | ||
356 | mtdebug1(WM_PROC_LOGTAG, "handle process: %d, parent process:%d", temp_processes[i].pid, temp_processes[i].ppid ); | ||
357 | get_process_info( &temp_processes[i], location ); | ||
358 | temp_processes[i].status = PROCESS_SLOT_EMPTY; | ||
359 | } | ||
360 | } | ||
361 | } | ||
362 | |||
363 | static void handle_process_fork( const event_msg_t *proc_msg ) | ||
364 | { | ||
365 | int i = 0; | ||
366 | for ( i = 0; i < MAX_TEMP_PROCESS; i++ ) | ||
367 | { | ||
368 | if ( temp_processes[i].status == PROCESS_SLOT_EMPTY ) | ||
369 | { | ||
370 | get_path_and_md5( proc_msg->proc_ev.event_data.fork.child_pid, temp_processes[i].path, temp_processes[i].md5 ); | ||
371 | get_path_and_md5( proc_msg->proc_ev.event_data.fork.parent_pid, temp_processes[i].parent_path, temp_processes[i].parent_md5); | ||
372 | temp_processes[i].pid = proc_msg->proc_ev.event_data.fork.child_pid; | ||
373 | temp_processes[i].ppid = proc_msg->proc_ev.event_data.fork.parent_pid; | ||
374 | temp_processes[i].fork_time = time(0); | ||
375 | temp_processes[i].status = !PROCESS_SLOT_EMPTY; | ||
376 | mtdebug1(WM_PROC_LOGTAG, "fork process: %d, parent process:%d", temp_processes[i].pid, temp_processes[i].ppid ); | ||
377 | break; | ||
378 | } | ||
379 | } | ||
380 | } | ||
381 | |||
382 | static void handle_process_exec( const event_msg_t *proc_msg, const char *location ) | ||
383 | { | ||
384 | int i = 0; | ||
385 | for ( i = 0; i < MAX_TEMP_PROCESS; i++ ) | ||
386 | { | ||
387 | if (temp_processes[i].pid == proc_msg->proc_ev.event_data.exec.process_pid | ||
388 | && temp_processes[i].status != PROCESS_SLOT_EMPTY) | ||
389 | { | ||
390 | get_path_and_md5( proc_msg->proc_ev.event_data.exec.process_pid, temp_processes[i].path, temp_processes[i].md5 ); | ||
391 | mtdebug1(WM_PROC_LOGTAG, "exec process: %d, parent process:%d", temp_processes[i].pid, temp_processes[i].ppid ); | ||
392 | get_process_info( &temp_processes[i], location ); | ||
393 | temp_processes[i].status = PROCESS_SLOT_EMPTY; | ||
394 | break; | ||
395 | } | ||
396 | } | ||
397 | } | ||
398 | |||
399 | static void handle_process_exit( const event_msg_t *proc_msg, const char* location ) | ||
400 | { | ||
401 | int i = 0; | ||
402 | for ( i = 0; i < MAX_TEMP_PROCESS; i++ ) | ||
403 | { | ||
404 | if ( ( temp_processes[i].status != PROCESS_SLOT_EMPTY ) | ||
405 | && ( proc_msg->proc_ev.event_data.exit.process_pid == temp_processes[i].pid ) | ||
406 | && ( temp_processes[i].ppid == 0 ) ) | ||
407 | { | ||
408 | temp_processes[i].status = PROCESS_SLOT_EMPTY; | ||
409 | return; | ||
410 | } | ||
411 | } | ||
412 | |||
413 | cJSON *process = cJSON_CreateObject(); | ||
414 | cJSON_AddStringToObject(process, "type", "exit"); | ||
415 | cJSON_AddNumberToObject( process, "pid", proc_msg->proc_ev.event_data.exit.process_pid ); | ||
416 | cJSON_AddNumberToObject( process, "eventTime", time(0) ); | ||
417 | cJSON_AddNumberToObject(process, "exitCode", proc_msg->proc_ev.event_data.exit.exit_code); | ||
418 | cJSON_AddNumberToObject(process, "exitSignal", (int)proc_msg->proc_ev.event_data.exit.exit_signal); | ||
419 | |||
420 | char *exit_msg = cJSON_PrintUnformatted( process ); | ||
421 | wm_sendmsg( MAX_PIPE_WAIT_USECOND, proc_monitor.queue_fd, exit_msg, location, PROC_COLLECTOR_MQ ); | ||
422 | free( exit_msg ); | ||
423 | cJSON_Delete( process ); | ||
424 | } | ||
425 | |||
426 | static time_t get_process_start_time( pid_t pid ) | ||
427 | { | ||
428 | char path[MAX_PATH_NAME]; | ||
429 | memset( path, 0, MAX_PATH_NAME); | ||
430 | |||
431 | snprintf( path, MAX_PATH_NAME-1, "/proc/%d", pid ); | ||
432 | |||
433 | struct stat dir_stat; | ||
434 | |||
435 | if ( stat( path, &dir_stat) < 0 ) | ||
436 | { | ||
437 | return 0; | ||
438 | } | ||
439 | |||
440 | return dir_stat.st_mtime; | ||
441 | } | ||
442 | |||
443 | static void get_inventory_processes(const char *location) | ||
444 | { | ||
445 | DIR *proc_dir = opendir( "/proc" ); | ||
446 | if ( NULL == proc_dir ) | ||
447 | { | ||
448 | mterror( WM_PROC_LOGTAG, "failed to open /proc, errno=(%d:%m)", errno ); | ||
449 | return; | ||
450 | } | ||
451 | |||
452 | struct dirent *entry = NULL; | ||
453 | while ( NULL != ( entry = readdir( proc_dir ))) | ||
454 | { | ||
455 | if ( !strcmp( entry->d_name, "." ) || !strcmp( entry->d_name, ".." ) ) | ||
456 | { | ||
457 | continue; | ||
458 | } | ||
459 | int pid = atoi( entry->d_name ); | ||
460 | if ( 0 == pid ) | ||
461 | { | ||
462 | continue; | ||
463 | } | ||
464 | |||
465 | char pid_path[MAX_PATH_NAME]; | ||
466 | os_md5 md5; | ||
467 | memset( pid_path, 0, sizeof( MAX_PATH_NAME)); | ||
468 | memset( md5, 0, sizeof( os_md5 ) ); | ||
469 | get_path_and_md5( pid, pid_path, md5 ); | ||
470 | |||
471 | cJSON *process = cJSON_CreateObject(); | ||
472 | cJSON_AddStringToObject(process, "type", "new process"); | ||
473 | cJSON_AddNumberToObject(process, "eventTime", time(0)); | ||
474 | cJSON_AddNumberToObject(process, "pid", pid); | ||
475 | cJSON_AddNumberToObject(process, "startTime", get_process_start_time(pid)); | ||
476 | if (strlen(pid_path) > 0) | ||
477 | { | ||
478 | cJSON_AddStringToObject(process, "exe", pid_path); | ||
479 | } | ||
480 | if (strlen(md5) > 0) | ||
481 | { | ||
482 | cJSON_AddStringToObject(process, "md5", md5); | ||
483 | } | ||
484 | |||
485 | proc_t curr_proc; | ||
486 | memset( &curr_proc, 0, sizeof( proc_t )); | ||
487 | if ( NULL != get_proc_stats(pid, &curr_proc )) | ||
488 | { | ||
489 | cJSON_AddStringToObject(process, "state", &curr_proc.state); | ||
490 | cJSON_AddNumberToObject(process, "utime", curr_proc.utime); | ||
491 | cJSON_AddNumberToObject(process, "stime", curr_proc.stime); | ||
492 | cJSON_AddStringToObject(process, "euser", curr_proc.euser); | ||
493 | cJSON_AddStringToObject(process, "egroup", curr_proc.egroup); | ||
494 | cJSON_AddNumberToObject(process, "resident", curr_proc.resident); | ||
495 | cJSON_AddNumberToObject(process, "nlwp", curr_proc.nlwp); | ||
496 | cJSON_AddNumberToObject(process, "tty", curr_proc.tty); | ||
497 | cJSON_AddNumberToObject(process, "processor", curr_proc.processor); | ||
498 | /* | ||
499 | cJSON_AddStringToObject(process, "ruser", curr_proc.ruser); | ||
500 | cJSON_AddStringToObject(process, "suser", curr_proc.suser); | ||
501 | cJSON_AddStringToObject(process, "rgroup", curr_proc.rgroup); | ||
502 | cJSON_AddStringToObject(process, "sgroup", curr_proc.sgroup); | ||
503 | cJSON_AddStringToObject(process, "fgroup", curr_proc.fgroup); | ||
504 | |||
505 | cJSON_AddNumberToObject(process, "priority", curr_proc.priority); | ||
506 | cJSON_AddNumberToObject(process, "nice", curr_proc.nice); | ||
507 | cJSON_AddNumberToObject(process, "size", curr_proc.size); | ||
508 | cJSON_AddNumberToObject(process, "vm_size", curr_proc.vm_size); | ||
509 | cJSON_AddNumberToObject(process, "share", curr_proc.share); | ||
510 | cJSON_AddNumberToObject(process, "pgrp", curr_proc.pgrp); | ||
511 | cJSON_AddNumberToObject(process, "session", curr_proc.session); | ||
512 | cJSON_AddNumberToObject(process, "tgid", curr_proc.tgid); | ||
513 | */ | ||
514 | |||
515 | memset(pid_path, 0, sizeof(MAX_PATH_NAME)); | ||
516 | memset(md5, 0, sizeof(os_md5)); | ||
517 | get_path_and_md5(curr_proc.ppid, pid_path, md5); | ||
518 | if (strlen(pid_path) > 0) | ||
519 | { | ||
520 | cJSON_AddStringToObject(process, "parent_exe", pid_path); | ||
521 | } | ||
522 | if (strlen(md5) > 0) | ||
523 | { | ||
524 | cJSON_AddStringToObject(process, "parent_md5", md5); | ||
525 | } | ||
526 | } | ||
527 | |||
528 | char *msg = cJSON_PrintUnformatted(process); | ||
529 | wm_sendmsg(MAX_PIPE_WAIT_USECOND, proc_monitor.queue_fd, msg, location, PROC_COLLECTOR_MQ); | ||
530 | free(msg); | ||
531 | cJSON_Delete(process); | ||
532 | } | ||
533 | |||
534 | closedir( proc_dir); | ||
535 | } | ||
536 | |||
537 | int wm_proc_linux_process(wm_proc_t *proc, const char *location) | ||
538 | { | ||
539 | int rc; | ||
540 | event_msg_t proc_msg; | ||
541 | fd_set readfds; | ||
542 | int max_fd = proc_monitor.proc_fd + 1; | ||
543 | struct timeval tv; | ||
544 | |||
545 | if (proc->flags.enabled == 0) | ||
546 | { | ||
547 | return 0; | ||
548 | merror("process collector disabled, let us rest."); | ||
549 | } | ||
550 | |||
551 | |||
552 | merror("process collector enabled, let us work."); | ||
553 | |||
554 | get_inventory_processes(location); | ||
555 | |||
556 | tv.tv_sec = 5; | ||
557 | tv.tv_usec = 0; | ||
558 | |||
559 | while (1) | ||
560 | { | ||
561 | FD_ZERO(&readfds); | ||
562 | FD_SET(proc_monitor.proc_fd, &readfds); | ||
563 | |||
564 | rc = select(max_fd, &readfds, NULL, NULL, &tv); | ||
565 | if (0 == rc) | ||
566 | { | ||
567 | handle_temp_process(location); | ||
568 | tv.tv_sec = 5; | ||
569 | tv.tv_usec = 0; | ||
570 | continue; | ||
571 | } | ||
572 | if (-1 == rc) | ||
573 | { | ||
574 | if (errno == EINTR) | ||
575 | { | ||
576 | continue; | ||
577 | } | ||
578 | mterror(WM_PROC_LOGTAG, "failed to listen to netlink socket, errno=(%d:%m)", errno); | ||
579 | return rc; | ||
580 | } | ||
581 | if (FD_ISSET(proc_monitor.proc_fd, &readfds)) | ||
582 | { | ||
583 | rc = recv(proc_monitor.proc_fd, &proc_msg, sizeof(proc_msg), 0); | ||
584 | if (rc > 0) | ||
585 | { | ||
586 | switch (proc_msg.proc_ev.what) | ||
587 | { | ||
588 | case proc_event::PROC_EVENT_FORK: | ||
589 | handle_process_fork(&proc_msg); | ||
590 | tv.tv_sec = 1; | ||
591 | tv.tv_usec = 1000; | ||
592 | break; | ||
593 | case proc_event::PROC_EVENT_EXEC: | ||
594 | handle_process_exec(&proc_msg, location); | ||
595 | break; | ||
596 | case proc_event::PROC_EVENT_COMM: | ||
597 | break; | ||
598 | case proc_event::PROC_EVENT_EXIT: | ||
599 | handle_process_exit(&proc_msg, location); | ||
600 | break; | ||
601 | default: | ||
602 | break; | ||
603 | } | ||
604 | } | ||
605 | else if (rc == -1) | ||
606 | { | ||
607 | if (errno == EINTR) | ||
608 | { | ||
609 | continue; | ||
610 | } | ||
611 | mterror(WM_PROC_LOGTAG, "failed to received from netlink socket, errno=(%d:%m)", errno); | ||
612 | } | ||
613 | } | ||
614 | } | ||
615 | |||
616 | return 0; | ||
617 | } | ||
618 | #endif \ No newline at end of file | ||