1 |
commit: d8d0c8f39f95af3647f73b5781199899e9b9529d |
2 |
Author: Alexander Bersenev <bay <AT> hackerdom <DOT> ru> |
3 |
AuthorDate: Mon Jun 27 03:41:57 2011 +0000 |
4 |
Commit: Александр Берсенев <bay <AT> hackerdom <DOT> ru> |
5 |
CommitDate: Mon Jun 27 03:41:57 2011 +0000 |
6 |
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/autodep.git;a=commit;h=d8d0c8f3 |
7 |
|
8 |
hooklib approach has been rewritten |
9 |
|
10 |
--- |
11 |
logger/src/autodep/logfs/fstracer.py | 36 ++- |
12 |
logger/src/autodep/logfs/logger_hooklib.py | 1 + |
13 |
logger/src/autodep/logfs/test_fstracer.py | 51 ++-- |
14 |
logger/src/hook_lib/file_hook.c | 354 +++++++++++++++------------- |
15 |
4 files changed, 249 insertions(+), 193 deletions(-) |
16 |
|
17 |
diff --git a/logger/src/autodep/logfs/fstracer.py b/logger/src/autodep/logfs/fstracer.py |
18 |
index a4a5b49..7ceb36e 100644 |
19 |
--- a/logger/src/autodep/logfs/fstracer.py |
20 |
+++ b/logger/src/autodep/logfs/fstracer.py |
21 |
@@ -5,6 +5,7 @@ This module is a bridge between low-level logging services and high level handli |
22 |
|
23 |
import os |
24 |
import sys |
25 |
+import stat |
26 |
import time |
27 |
import tempfile |
28 |
import socket |
29 |
@@ -132,6 +133,10 @@ def getfsevents(prog_name,arguments,approach="hooklib",filterproc=defaultfilter) |
30 |
sock_listen.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) |
31 |
sock_listen.bind(socketname) |
32 |
sock_listen.listen(1024) |
33 |
+ # enable connect a socket for anyone |
34 |
+ os.chmod(tmpdir,stat.S_IRUSR|stat.S_IWUSR|stat.S_IXUSR|stat.S_IROTH|stat.S_IWOTH|stat.S_IXOTH) |
35 |
+ os.chmod(socketname,stat.S_IRUSR|stat.S_IWUSR|stat.S_IROTH|stat.S_IWOTH) |
36 |
+ |
37 |
except socket.error, e: |
38 |
print "Failed to create a socket for exchange data with the logger: %s" % e |
39 |
return [] |
40 |
@@ -161,6 +166,7 @@ def getfsevents(prog_name,arguments,approach="hooklib",filterproc=defaultfilter) |
41 |
connects = 0; |
42 |
clients={} |
43 |
stop=0 |
44 |
+ was_first_connect=False |
45 |
|
46 |
while stop==0: |
47 |
sock_events = epoll.poll(3) |
48 |
@@ -172,21 +178,27 @@ def getfsevents(prog_name,arguments,approach="hooklib",filterproc=defaultfilter) |
49 |
else: |
50 |
(client,addr)=ret |
51 |
connects+=1; # client accepted |
52 |
+ was_first_connect=True |
53 |
epoll.register(client.fileno(), select.EPOLLIN) |
54 |
clients[client.fileno()]=client |
55 |
- elif sock_event & select.EPOLLHUP: |
56 |
- epoll.unregister(fileno) |
57 |
- clients[fileno].close() |
58 |
- del clients[fileno] |
59 |
- connects-=1 |
60 |
+ #elif sock_event & select.EPOLLHUP: |
61 |
+ #epoll.unregister(fileno) |
62 |
+ #clients[fileno].close() |
63 |
+ #del clients[fileno] |
64 |
+ #connects-=1 |
65 |
|
66 |
- if connects==0: |
67 |
- stop=1 |
68 |
- break |
69 |
elif sock_event & select.EPOLLIN: |
70 |
s=clients[fileno] |
71 |
record=s.recv(8192) |
72 |
|
73 |
+ if not record: # if connection was closed |
74 |
+ epoll.unregister(fileno) |
75 |
+ clients[fileno].close() |
76 |
+ del clients[fileno] |
77 |
+ connects-=1 |
78 |
+ #print "closing!!" |
79 |
+ continue |
80 |
+ |
81 |
message=record.split("\0") |
82 |
#print message |
83 |
|
84 |
@@ -194,11 +206,11 @@ def getfsevents(prog_name,arguments,approach="hooklib",filterproc=defaultfilter) |
85 |
if message[4]=="ASKING": |
86 |
if filterproc(message[1],message[2],message[3]): |
87 |
#print "Allowing an access to %s" % message[2] |
88 |
- s.sendall("ALLOW"); # TODO: think about flush here |
89 |
+ s.sendall("ALLOW\0"); # TODO: think about flush here |
90 |
|
91 |
else: |
92 |
print "Blocking an access to %s" % message[2] |
93 |
- s.sendall("DENY"); # TODO: think about flush here |
94 |
+ s.sendall("DENY\0"); # TODO: think about flush here |
95 |
|
96 |
else: |
97 |
eventname,filename,stage,result=message[1:5] |
98 |
@@ -236,7 +248,9 @@ def getfsevents(prog_name,arguments,approach="hooklib",filterproc=defaultfilter) |
99 |
except IndexError: |
100 |
print "IndexError while parsing %s"%record |
101 |
|
102 |
- |
103 |
+ if was_first_connect and connects==0: |
104 |
+ break |
105 |
+ |
106 |
if len(sock_events)==0 and len(clients)==0: |
107 |
# # seems like there is no connect |
108 |
print "It seems like a logger module was unable to start or failed to finish\n" + \ |
109 |
|
110 |
diff --git a/logger/src/autodep/logfs/logger_hooklib.py b/logger/src/autodep/logfs/logger_hooklib.py |
111 |
index cf677f4..cda22b6 100644 |
112 |
--- a/logger/src/autodep/logfs/logger_hooklib.py |
113 |
+++ b/logger/src/autodep/logfs/logger_hooklib.py |
114 |
@@ -1,6 +1,7 @@ |
115 |
#!/usr/bin/env python2 |
116 |
|
117 |
import os |
118 |
+import sys |
119 |
|
120 |
class logger: |
121 |
socketname='' |
122 |
|
123 |
diff --git a/logger/src/autodep/logfs/test_fstracer.py b/logger/src/autodep/logfs/test_fstracer.py |
124 |
index db61486..15d4c27 100644 |
125 |
--- a/logger/src/autodep/logfs/test_fstracer.py |
126 |
+++ b/logger/src/autodep/logfs/test_fstracer.py |
127 |
@@ -16,47 +16,49 @@ def simple_getfsevents(prog,args,approach="hooklib"): |
128 |
|
129 |
class hooklib_simple_tests(unittest.TestCase): |
130 |
def test_open_unexists(self): |
131 |
- self.assertEqual(fstracer.getfsevents('/bin/cat', |
132 |
- ['/bin/cat','f1','f2']), |
133 |
- [['open', 'f1'], ['open', 'f2']]) |
134 |
+ eventslist=simple_getfsevents('/bin/cat', ['/bin/cat','/f1','/f2'],approach="hooklib") |
135 |
+ print eventslist |
136 |
+ self.assertTrue(eventslist.count(['/f1',"fail"])==1) |
137 |
+ self.assertTrue(eventslist.count(['/f2',"fail"])==1) |
138 |
|
139 |
def test_open_exists(self): |
140 |
- self.assertEqual(fstracer.getfsevents('/bin/cat', |
141 |
- ['/bin/cat','/etc/passwd']), |
142 |
- [['open', '/etc/passwd']]) |
143 |
+ eventslist=simple_getfsevents('/bin/cat', ['/bin/cat','/etc/passwd'],approach="hooklib") |
144 |
+ self.assertTrue(eventslist.count(['/etc/passwd','success'])>=1) |
145 |
|
146 |
- |
147 |
def test_open_many(self): |
148 |
filesnum=200 |
149 |
- self.assertEqual(fstracer.getfsevents('/bin/cat', |
150 |
- ['/bin/cat']+map(lambda x: 'file'+str(x),range(0,filesnum))), |
151 |
- map(lambda x: ['open','file'+str(x)],range(0,filesnum))) |
152 |
- |
153 |
+ eventslist=simple_getfsevents('/bin/cat',['/bin/cat']+ |
154 |
+ map(lambda x: '/file'+str(x),range(0,filesnum)), approach="hooklib") |
155 |
+ for f in map(lambda x: ['/file'+str(x),'fail'],range(0,filesnum)): |
156 |
+ self.assertTrue(f in eventslist) |
157 |
|
158 |
def test_parralel(self): |
159 |
- filesnum=200 |
160 |
- procnum=6 |
161 |
+ filesnum=400 |
162 |
+ procnum=8 |
163 |
|
164 |
# create command |
165 |
command="" |
166 |
for p in xrange(0,procnum): |
167 |
command+="/bin/cat " |
168 |
for f in xrange(0,filesnum): |
169 |
- command+="file_%d_%d " % (p,f) |
170 |
+ command+="/file_%d_%d " % (p,f) |
171 |
command+="& " |
172 |
- command+=" >/dev/null 2>&1" |
173 |
- command+=" "+"A"*65536 |
174 |
- |
175 |
+ command+=" 2>/dev/null" |
176 |
+ #command+=" "+"A"*65536 |
177 |
|
178 |
- resultarray=fstracer.getfsevents('/bin/sh', ['/bin/sh','-c',command]) |
179 |
- |
180 |
- self.assertTrue(resultarray.count(['execve', '/bin/cat'])==procnum) |
181 |
- |
182 |
- print resultarray |
183 |
+ resultarray=simple_getfsevents('/bin/sh', ['/bin/sh','-c',command],approach="hooklib") |
184 |
|
185 |
for p in xrange(0,procnum): |
186 |
for f in xrange(0,filesnum): |
187 |
- self.assertTrue(resultarray.count(['open', 'file_%d_%d' % (p,f)])==1) |
188 |
+ self.assertTrue(resultarray.count(['/file_%d_%d' % (p,f),"fail"])==1) |
189 |
+ |
190 |
+ def test_open_very_many(self): |
191 |
+ resultarray=simple_getfsevents('/bin/sh', ['/bin/sh','-c', |
192 |
+ "for i in `seq 1 1000`; do cat /testmany$i;done 2> /dev/null"],approach="hooklib") |
193 |
+ #print resultarray |
194 |
+ for i in range(1,1000): |
195 |
+ self.assertTrue(resultarray.count(['/testmany'+str(i),'fail'])==1) |
196 |
+ |
197 |
|
198 |
class fusefs_simple_tests(unittest.TestCase): |
199 |
def test_open_unexists(self): |
200 |
@@ -105,5 +107,6 @@ class fusefs_simple_tests(unittest.TestCase): |
201 |
|
202 |
if __name__ == '__main__': |
203 |
#unittest.main() |
204 |
- suite = unittest.TestLoader().loadTestsFromTestCase(fusefs_simple_tests) |
205 |
+ #suite = unittest.TestLoader().loadTestsFromTestCase(fusefs_simple_tests) |
206 |
+ suite = unittest.TestLoader().loadTestsFromTestCase(hooklib_simple_tests) |
207 |
unittest.TextTestRunner(verbosity=2).run(suite) |
208 |
\ No newline at end of file |
209 |
|
210 |
diff --git a/logger/src/hook_lib/file_hook.c b/logger/src/hook_lib/file_hook.c |
211 |
index d17becc..7c846e2 100644 |
212 |
--- a/logger/src/hook_lib/file_hook.c |
213 |
+++ b/logger/src/hook_lib/file_hook.c |
214 |
@@ -8,6 +8,7 @@ |
215 |
#include <time.h> |
216 |
|
217 |
#include <dlfcn.h> |
218 |
+#include <pthread.h> |
219 |
|
220 |
#define _FCNTL_H |
221 |
#include <bits/fcntl.h> |
222 |
@@ -16,36 +17,48 @@ |
223 |
#include <sys/socket.h> |
224 |
#include <sys/un.h> |
225 |
|
226 |
-#define MAXPATHLEN 256 |
227 |
+#define MAXPATHLEN 1024 |
228 |
#define MAXSOCKETPATHLEN 108 |
229 |
#define MAXFILEBUFFLEN 2048 |
230 |
|
231 |
+#define MAXSOCKETMSGLEN 8192 |
232 |
+ |
233 |
//extern int errorno; |
234 |
|
235 |
+pthread_mutex_t socketblock = PTHREAD_MUTEX_INITIALIZER; |
236 |
+ |
237 |
int (*_open)(const char * pathname, int flags, ...); |
238 |
int (*_open64)(const char * pathname, int flags, ...); |
239 |
FILE * (*_fopen)(const char *path, const char *mode); |
240 |
FILE * (*_fopen64)(const char *path, const char *mode); |
241 |
int (*_execve)(const char *filename, char *const argv[],char *const envp[]); |
242 |
-pid_t (*_fork)(); |
243 |
+ssize_t (*_read)(int fd, void *buf, size_t count); |
244 |
+ssize_t (*_write)(int fd, const void *buf, size_t count); |
245 |
+size_t (*_fread)(void *ptr, size_t size, size_t nmemb, FILE *stream); |
246 |
+size_t (*_fwrite)(const void *ptr, size_t size, size_t nmemb, FILE *stream); |
247 |
|
248 |
-FILE *log_file; // one of these two vars will be used for logging |
249 |
-int log_socket=-1; |
250 |
+int (*_close)(int fd); // we hooking this, because some programs closes our socket |
251 |
|
252 |
-int is_log_into_socket=0; |
253 |
+int log_socket=-1; |
254 |
|
255 |
void __doinit(){ |
256 |
- //stat(NULL,NULL); |
257 |
_open = (int (*)(const char * pathname, int flags, ...)) dlsym(RTLD_NEXT, "open"); |
258 |
_open64 = (int (*)(const char * pathname, int flags, ...)) dlsym(RTLD_NEXT, "open64"); |
259 |
+ |
260 |
_fopen = (FILE * (*)(const char *path, const char *mode)) dlsym(RTLD_NEXT, "fopen"); |
261 |
_fopen64 = (FILE * (*)(const char *path, const char *mode)) dlsym(RTLD_NEXT, "fopen64"); |
262 |
+ |
263 |
+ _read= (ssize_t (*)(int fd, void *buf, size_t count)) dlsym(RTLD_NEXT, "read"); |
264 |
+ _write= (ssize_t (*)(int fd, const void *buf, size_t count)) dlsym(RTLD_NEXT, "write"); |
265 |
+ |
266 |
_execve = (int (*)(const char *filename, char *const argv[],char *const envp[])) dlsym(RTLD_NEXT, "execve"); |
267 |
- _fork = (pid_t (*)()) dlsym(RTLD_NEXT, "fork"); |
268 |
|
269 |
+ _close= (int (*)(int fd)) dlsym(RTLD_NEXT, "close"); |
270 |
+ |
271 |
+ |
272 |
if(_open==NULL || _open64==NULL || |
273 |
_fopen==NULL || _fopen64==NULL || |
274 |
- execve==NULL || _fork==NULL) { |
275 |
+ execve==NULL || _read==NULL || _write==NULL || close==NULL) { |
276 |
fprintf(stderr,"Failed to load original functions of hook\n"); |
277 |
exit(1); |
278 |
} |
279 |
@@ -53,19 +66,17 @@ void __doinit(){ |
280 |
|
281 |
char *log_socket_name=getenv("LOG_SOCKET"); |
282 |
if(log_socket_name==NULL) { |
283 |
- fprintf(stderr,"Using stderr as output for logs " |
284 |
- "because the LOG_SOCKET environment variable isn't defined.\n"); |
285 |
+ fprintf(stderr,"LOG_SOCKET environment variable isn't defined." |
286 |
+ "Are this library launched by server?\n"); |
287 |
|
288 |
- log_file=stderr; |
289 |
+ exit(1); |
290 |
} else { |
291 |
- is_log_into_socket=1; |
292 |
- |
293 |
if(strlen(log_socket_name)>=MAXSOCKETPATHLEN) { |
294 |
fprintf(stderr,"Unable to create a unix-socket %s: socket name is too long,exiting\n", log_socket_name); |
295 |
exit(1); |
296 |
} |
297 |
|
298 |
- log_socket=socket(AF_UNIX, SOCK_STREAM, 0); |
299 |
+ log_socket=socket(AF_UNIX, SOCK_SEQPACKET, 0); |
300 |
if(log_socket==-1) { |
301 |
fprintf(stderr,"Unable to create a unix-socket %s: %s\n", log_socket_name, strerror(errno)); |
302 |
exit(1); |
303 |
@@ -81,24 +92,11 @@ void __doinit(){ |
304 |
fprintf(stderr,"Unable to connect a unix-socket: %s\n", strerror(errno)); |
305 |
exit(1); |
306 |
} |
307 |
- |
308 |
- log_file=fdopen(log_socket,"r+"); |
309 |
- |
310 |
- if(log_file==NULL) { |
311 |
- fprintf(stderr,"Unable to open a socket for a steam writing: %s\n", strerror(errno)); |
312 |
- exit(1); |
313 |
- } |
314 |
} |
315 |
} |
316 |
|
317 |
void __dofini() { |
318 |
- fflush(log_file); |
319 |
- fclose(log_file); |
320 |
- |
321 |
- if(is_log_into_socket) |
322 |
- close(log_socket); |
323 |
- |
324 |
- //fprintf(stderr,"All sockets closed\n"); |
325 |
+ //close(log_socket); |
326 |
} |
327 |
|
328 |
void _init() { |
329 |
@@ -110,188 +108,228 @@ void _fini() { |
330 |
} |
331 |
|
332 |
/* |
333 |
- * Prints a string escaping spaces and '\' |
334 |
- * Does not check input variables |
335 |
-*/ |
336 |
-void __print_escaped(FILE *fh ,const char *s){ |
337 |
- for(;(*s)!=0; s++) { |
338 |
- if(*s==' ') |
339 |
- fprintf(fh,"\\ "); |
340 |
- else if(*s==',') |
341 |
- fprintf(fh,"\\,"); |
342 |
- else if(*s=='\r') |
343 |
- fprintf(fh,"\\r"); |
344 |
- else if(*s=='\n') |
345 |
- fprintf(fh,"\\n"); |
346 |
- else if(*s=='\\') |
347 |
- fprintf(fh,"\\\\"); |
348 |
- else |
349 |
- fprintf(fh,"%c", *s); |
350 |
- } |
351 |
-} |
352 |
- |
353 |
-/* |
354 |
- * Get a pid of the parent proccess |
355 |
- * Parse the /proc/pid/stat |
356 |
- * We need a first number after last ')' character |
357 |
+ * Format of log string: time event filename stage result/err |
358 |
*/ |
359 |
-pid_t __getparentpid(pid_t pid){ |
360 |
- char filename[MAXPATHLEN]; |
361 |
- snprintf(filename,MAXPATHLEN, "/proc/%d/stat",pid); |
362 |
- FILE *stat_file_handle=fopen(filename,"r"); |
363 |
- if(stat_file_handle==NULL) { |
364 |
- fprintf(log_file,"NULL"); |
365 |
- return 0; |
366 |
- } |
367 |
- |
368 |
- char filedata[MAXFILEBUFFLEN]; |
369 |
- size_t bytes_readed=fread(filedata,sizeof(char),MAXFILEBUFFLEN,stat_file_handle); |
370 |
- if(bytes_readed==0 || bytes_readed>=MAXFILEBUFFLEN) { |
371 |
- fprintf(log_file,"NULL"); |
372 |
- fclose(stat_file_handle); |
373 |
- return 0; |
374 |
- } |
375 |
- |
376 |
- filedata[bytes_readed]=0; |
377 |
- |
378 |
- char *beg_scan_offset=rindex(filedata,')'); |
379 |
- if(beg_scan_offset==NULL) { |
380 |
- fprintf(log_file,"NULL"); |
381 |
- fclose(stat_file_handle); |
382 |
- return 0; |
383 |
+static void __raw_log_event(const char *event_type, const char *filename, char *result,int err, char* stage) { |
384 |
+ //printf("lololo:%s %s %s\n",event_type,filename,stage); |
385 |
+ |
386 |
+ char msg_buff[MAXSOCKETMSGLEN]; |
387 |
+ int bytes_to_send; |
388 |
+ if(strcmp(result,"ERR")==0) { |
389 |
+ bytes_to_send=snprintf(msg_buff,MAXSOCKETMSGLEN,"%lld%c%s%c%s%c%s%c%s/%d", |
390 |
+ (unsigned long long)time(NULL),0,event_type,0,filename,0,stage,0,result,err); |
391 |
+ } else { |
392 |
+ bytes_to_send=snprintf(msg_buff,MAXSOCKETMSGLEN,"%lld%c%s%c%s%c%s%c%s", |
393 |
+ (unsigned long long)time(NULL),0,event_type,0,filename,0,stage,0,result); |
394 |
} |
395 |
|
396 |
- pid_t parent_pid; |
397 |
- int tokens_readed=sscanf(beg_scan_offset,") %*c %d",&parent_pid); |
398 |
- if(tokens_readed!=1) { |
399 |
- fprintf(log_file,"NULL"); |
400 |
- fclose(stat_file_handle); |
401 |
- return 0; |
402 |
+ if(bytes_to_send>=MAXSOCKETMSGLEN) return; |
403 |
+ if(send(log_socket,msg_buff,bytes_to_send,0)==-1) { |
404 |
+ printf("BAYBAY!!!11 %d %d\n",log_socket, getpid()); |
405 |
+ sleep(100500); |
406 |
} |
407 |
- fclose(stat_file_handle); |
408 |
|
409 |
- if(pid==1) |
410 |
- return 0; // set this explicitly. |
411 |
- // I am not sure that ppid of init proccess is always 0 |
412 |
- |
413 |
- return parent_pid; |
414 |
} |
415 |
|
416 |
/* |
417 |
- * Print cmdline of proccess(escaped) |
418 |
+ * Log an event |
419 |
*/ |
420 |
-void __print_cmdline(pid_t pid) { |
421 |
- char filename[MAXPATHLEN]; |
422 |
- snprintf(filename,MAXPATHLEN, "/proc/%d/cmdline",pid); |
423 |
- FILE *cmdline_file_handle=fopen(filename,"r"); |
424 |
- if(cmdline_file_handle==NULL) { |
425 |
- fprintf(log_file,"UNKNOWN"); |
426 |
- return; |
427 |
- } |
428 |
- |
429 |
- char read_buffer[MAXFILEBUFFLEN+1]={0}; |
430 |
- int readed; |
431 |
- do { |
432 |
- readed=fread(read_buffer,sizeof(char),MAXFILEBUFFLEN,cmdline_file_handle); |
433 |
- char *last_printed=read_buffer; |
434 |
- int i; |
435 |
- for(i=0; i<readed; i++) { |
436 |
- if(read_buffer[i]==0) { |
437 |
- __print_escaped(log_file,last_printed); |
438 |
- fprintf(log_file,"\\0"); |
439 |
- last_printed=read_buffer+i+1; |
440 |
- } |
441 |
- } |
442 |
- read_buffer[readed]=0; |
443 |
- if(last_printed<read_buffer+readed) |
444 |
- __print_escaped(log_file,last_printed); // print rest of buffer |
445 |
+static void __log_event(const char *event_type, const char *filename, char *result,int err, char* stage) { |
446 |
+ __raw_log_event(event_type,filename,result,err,stage); |
447 |
+} |
448 |
|
449 |
- } while(readed==MAXFILEBUFFLEN); |
450 |
- fclose(cmdline_file_handle); |
451 |
+/* |
452 |
+ * Get a stage. Stage is from environment |
453 |
+*/ |
454 |
+static char * __get_stage(){ |
455 |
+ char *ret=getenv("EBUILD_PHASE"); |
456 |
+ if(ret==NULL) |
457 |
+ return "unknown"; |
458 |
+ return ret; |
459 |
} |
460 |
|
461 |
/* |
462 |
- * Format of log string: time event file flags result parents |
463 |
+ * Get full path by fd |
464 |
*/ |
465 |
-void __hook_log(const char *event_type, const char *filename, int result, int err) { |
466 |
- |
467 |
- fprintf(log_file,"%lld ",(unsigned long long)time(NULL)); |
468 |
- |
469 |
- __print_escaped(log_file, event_type); |
470 |
- fprintf(log_file," "); |
471 |
- __print_escaped(log_file, filename); |
472 |
- fprintf(log_file," %d %d %d", result, err, getpid()); |
473 |
- // TODO: add a parent processes in output |
474 |
-// pid_t pid; |
475 |
-// __getparentpid(getpid()); |
476 |
-// for(pid=getpid();pid!=0;pid=__getparentpid(pid)){ |
477 |
-// __print_cmdline(pid); |
478 |
-// if(pid!=1) |
479 |
-// fprintf(log_file,","); |
480 |
- |
481 |
-// } |
482 |
+ssize_t __get_path_by_fd(int fd, char *output, int output_len) { |
483 |
+ char path_to_fd_link[MAXPATHLEN]; |
484 |
+ |
485 |
+ snprintf(path_to_fd_link,MAXPATHLEN,"/proc/self/fd/%d",fd); |
486 |
+ ssize_t bytes_num=readlink(path_to_fd_link,output,output_len-1); |
487 |
+ output[bytes_num]=0; // because readlink don't do this |
488 |
+ if(output[0]!='/') return -1; // some odd string like pipe: |
489 |
+ return bytes_num; |
490 |
+} |
491 |
+ |
492 |
+/* |
493 |
+ * Ask for event "alloweness" |
494 |
+*/ |
495 |
+static int __is_event_allowed(const char *event_type,const char *filename, char* stage) { |
496 |
+ char answer[8]; |
497 |
+ int bytes_recieved; |
498 |
+ |
499 |
+ |
500 |
+ pthread_mutex_lock( &socketblock ); |
501 |
+ |
502 |
+ __raw_log_event(event_type,filename,"ASKING",0,stage); |
503 |
+ bytes_recieved=recv(log_socket,answer,8,0); |
504 |
+ |
505 |
+ pthread_mutex_unlock( &socketblock ); |
506 |
|
507 |
- fprintf(log_file,"\n"); |
508 |
- fflush(log_file); |
509 |
+ if(strcmp(answer,"ALLOW")==0) |
510 |
+ return 1; |
511 |
+ else if(strcmp(answer,"DENY")==0) |
512 |
+ return 0; |
513 |
+ else |
514 |
+ fprintf(stderr,"Protocol error, text should be ALLOW or DENY, got: %s",answer); |
515 |
+ return 0; |
516 |
} |
517 |
|
518 |
-int open(const char * pathname, int flags, mode_t mode) { |
519 |
+ |
520 |
+int open(const char * path, int flags, mode_t mode) { |
521 |
int ret; |
522 |
+ char fullpath[MAXPATHLEN]; |
523 |
+ realpath(path,fullpath); |
524 |
+ char *stage=__get_stage(); |
525 |
+ if(! __is_event_allowed("open",fullpath,stage)) { |
526 |
+ errno=2; // not found |
527 |
+ __log_event("open",fullpath,"DENIED",errno,stage); |
528 |
+ return -1; |
529 |
+ } |
530 |
+ |
531 |
+ |
532 |
if(flags & O_CREAT) |
533 |
- ret=_open(pathname, flags, mode); |
534 |
+ ret=_open(path, flags, mode); |
535 |
else |
536 |
- ret=_open(pathname, flags, 0); |
537 |
- |
538 |
- __hook_log("open",pathname,ret,errno); |
539 |
+ ret=_open(path, flags, 0); |
540 |
|
541 |
+ if(ret==-1) |
542 |
+ __log_event("open",fullpath,"ERR",errno,stage); |
543 |
+ else |
544 |
+ __log_event("open",fullpath,"OK",0,stage); |
545 |
+ |
546 |
+ |
547 |
return ret; |
548 |
} |
549 |
|
550 |
-int open64(const char * pathname, int flags, mode_t mode) { |
551 |
+int open64(const char * path, int flags, mode_t mode) { |
552 |
int ret; |
553 |
+ char fullpath[MAXPATHLEN]; |
554 |
+ realpath(path,fullpath); |
555 |
+ char *stage=__get_stage(); |
556 |
+ if(! __is_event_allowed("open",fullpath,stage)) { |
557 |
+ errno=2; // not found |
558 |
+ __log_event("open",path,"DENIED",errno,stage); |
559 |
+ return -1; |
560 |
+ } |
561 |
|
562 |
if(flags & O_CREAT) |
563 |
- ret=_open64(pathname, flags, mode); |
564 |
+ ret=_open64(path, flags, mode); |
565 |
else |
566 |
- ret=_open64(pathname, flags, 0); |
567 |
+ ret=_open64(path, flags, 0); |
568 |
|
569 |
- __hook_log("open",pathname,ret,errno); |
570 |
+ if(ret==-1) |
571 |
+ __log_event("open",fullpath,"ERR",errno,stage); |
572 |
+ else |
573 |
+ __log_event("open",fullpath,"OK",0,stage); |
574 |
|
575 |
return ret; |
576 |
} |
577 |
|
578 |
FILE *fopen(const char *path, const char *mode) { |
579 |
FILE *ret; |
580 |
+ char fullpath[MAXPATHLEN]; |
581 |
+ realpath(path,fullpath); |
582 |
+ |
583 |
+ char *stage=__get_stage(); |
584 |
+ if(! __is_event_allowed("open",fullpath,stage)) { |
585 |
+ errno=2; // not found |
586 |
+ __log_event("open",path,"DENIED",errno,stage); |
587 |
+ return NULL; |
588 |
+ } |
589 |
+ |
590 |
ret=_fopen(path,mode); |
591 |
- __hook_log("open",path,0,errno); |
592 |
+ if(ret==NULL) |
593 |
+ __log_event("open",fullpath,"ERR",errno,stage); |
594 |
+ else |
595 |
+ __log_event("open",fullpath,"OK",0,stage); |
596 |
return ret; |
597 |
} |
598 |
|
599 |
FILE *fopen64(const char *path, const char *mode) { |
600 |
FILE *ret; |
601 |
+ char fullpath[MAXPATHLEN]; |
602 |
+ realpath(path,fullpath); |
603 |
+ |
604 |
+ char *stage=__get_stage(); |
605 |
+ if(! __is_event_allowed("open",fullpath,stage)) { |
606 |
+ errno=2; // not found |
607 |
+ __log_event("open",fullpath,"DENIED",errno,stage); |
608 |
+ return NULL; |
609 |
+ } |
610 |
+ |
611 |
ret=_fopen64(path,mode); |
612 |
- __hook_log("open",path,0,errno); |
613 |
+ |
614 |
+ if(ret==NULL) |
615 |
+ __log_event("open",fullpath,"ERR",errno,stage); |
616 |
+ else |
617 |
+ __log_event("open",fullpath,"OK",0,stage); |
618 |
+ |
619 |
return ret; |
620 |
} |
621 |
|
622 |
+ssize_t read(int fd, void *buf, size_t count){ |
623 |
+ ssize_t ret=_read(fd,buf,count); |
624 |
+ char *stage=__get_stage(); |
625 |
|
626 |
-int execve(const char *filename, char *const argv[], |
627 |
- char *const envp[]) { |
628 |
- __hook_log("execve",filename,0,0); |
629 |
+ char fullpath[MAXPATHLEN]; |
630 |
+ ssize_t path_size=__get_path_by_fd(fd,fullpath,MAXPATHLEN); |
631 |
+ if(path_size==-1) |
632 |
+ return ret; |
633 |
+ |
634 |
+ if(ret==-1) |
635 |
+ __log_event("read",fullpath,"ERR",errno,stage); |
636 |
+ else |
637 |
+ __log_event("read",fullpath,"OK",0,stage); |
638 |
|
639 |
- int ret=_execve(filename, argv, envp); |
640 |
+ return ret; |
641 |
+} |
642 |
+ |
643 |
+ssize_t write(int fd,const void *buf, size_t count){ |
644 |
+ ssize_t ret=_write(fd,buf,count); |
645 |
+ char *stage=__get_stage(); |
646 |
+ char fullpath[MAXPATHLEN]; |
647 |
+ ssize_t path_size=__get_path_by_fd(fd,fullpath,MAXPATHLEN); |
648 |
+ if(path_size==-1) |
649 |
+ return ret; |
650 |
|
651 |
+ if(ret==-1) |
652 |
+ __log_event("write",fullpath,"ERR",errno,stage); |
653 |
+ else |
654 |
+ __log_event("write",fullpath,"OK",0,stage); |
655 |
+ |
656 |
return ret; |
657 |
} |
658 |
|
659 |
-pid_t fork(void) { |
660 |
- int ret=_fork(); |
661 |
- // we must to handle fork for reconnect a socket |
662 |
|
663 |
- if(ret==0) { |
664 |
- __dofini(); // reinit connection for clildren |
665 |
- __doinit(); // because now it is different processes |
666 |
- } |
667 |
+ |
668 |
+int execve(const char *filename, char *const argv[], |
669 |
+ char *const envp[]) { |
670 |
+ if(access(filename, F_OK)!=-1) |
671 |
+ __log_event("open",filename,"OK",0,__get_stage()); |
672 |
+ else |
673 |
+ __log_event("open",filename,"ERR",2,__get_stage()); |
674 |
+ |
675 |
+ |
676 |
+ int ret=_execve(filename, argv, envp); |
677 |
|
678 |
return ret; |
679 |
} |
680 |
+ |
681 |
+int close(int fd) { |
682 |
+ if(fd!=log_socket) { |
683 |
+ return _close(fd); |
684 |
+ } |
685 |
+ return -1; |
686 |
+} |
687 |
+ |