... | ... |
@@ -23,8 +23,6 @@ |
23 | 23 |
#include "clamav-config.h" |
24 | 24 |
#endif |
25 | 25 |
|
26 |
-//#define ONAS_DEBUG |
|
27 |
- |
|
28 | 26 |
#include <stdio.h> |
29 | 27 |
#include <stdlib.h> |
30 | 28 |
#include <curl/curl.h> |
... | ... |
@@ -169,64 +167,90 @@ CURLcode onas_curl_init(CURL **curl, const char *ipaddr, int64_t port, int64_t t |
169 | 169 |
return CURLE_FAILED_INIT; |
170 | 170 |
} |
171 | 171 |
|
172 |
- /* setup here, but caller needs to cleanup */ |
|
172 |
+ /* setup here, but caller needs to cleanup */ |
|
173 | 173 |
*curl = curl_easy_init(); |
174 | 174 |
|
175 |
- curlcode = curl_easy_setopt(*curl, CURLOPT_PORT, port); |
|
176 |
- if (CURLE_OK != curlcode) { |
|
177 |
- logg("!ClamClient: could not setup curl with tcp port, %s\n", curl_easy_strerror(curlcode)); |
|
178 |
- curl_easy_cleanup(*curl); |
|
179 |
- return curlcode; |
|
180 |
- } |
|
175 |
+ if (!port) { |
|
176 |
+ |
|
177 |
+ /* "ipaddr" is actually our unix socket path here */ |
|
178 |
+ curlcode = curl_easy_setopt(*curl, CURLOPT_UNIX_SOCKET_PATH, ipaddr); |
|
179 |
+ if (CURLE_OK != curlcode) { |
|
180 |
+ logg("!ClamClient: could not setup curl with local unix socket, %s\n", curl_easy_strerror(curlcode)); |
|
181 |
+ curl_easy_cleanup(*curl); |
|
182 |
+ return curlcode; |
|
183 |
+ } |
|
181 | 184 |
|
182 |
- curlcode = curl_easy_setopt(*curl, CURLOPT_URL, ipaddr); |
|
183 |
- if (CURLE_OK != curlcode) { |
|
184 |
- logg("!ClamClient: could not setup curl with tcp address, %s\n", curl_easy_strerror(curlcode)); |
|
185 |
- curl_easy_cleanup(*curl); |
|
186 |
- return curlcode; |
|
185 |
+ curlcode = curl_easy_setopt(*curl, CURLOPT_URL, "http://localhost/"); |
|
186 |
+ if (CURLE_OK != curlcode) { |
|
187 |
+ logg("!ClamClient: could not setup curl with local address, %s\n", curl_easy_strerror(curlcode)); |
|
188 |
+ curl_easy_cleanup(*curl); |
|
189 |
+ return curlcode; |
|
190 |
+ } |
|
191 |
+ |
|
192 |
+ } else { |
|
193 |
+ |
|
194 |
+ curlcode = curl_easy_setopt(*curl, CURLOPT_PORT, port); |
|
195 |
+ if (CURLE_OK != curlcode) { |
|
196 |
+ logg("!ClamClient: could not setup curl with tcp port, %s\n", curl_easy_strerror(curlcode)); |
|
197 |
+ curl_easy_cleanup(*curl); |
|
198 |
+ return curlcode; |
|
199 |
+ } |
|
200 |
+ |
|
201 |
+ curlcode = curl_easy_setopt(*curl, CURLOPT_URL, ipaddr); |
|
202 |
+ if (CURLE_OK != curlcode) { |
|
203 |
+ logg("!ClamClient: could not setup curl with tcp address, %s\n", curl_easy_strerror(curlcode)); |
|
204 |
+ curl_easy_cleanup(*curl); |
|
205 |
+ return curlcode; |
|
206 |
+ } |
|
187 | 207 |
} |
188 | 208 |
|
189 |
- /* we implement our own transfer protocol via send and recv, so we only need to connect */ |
|
190 |
- curlcode = curl_easy_setopt(*curl, CURLOPT_CONNECT_ONLY, 1L); |
|
191 |
- if (CURLE_OK != curlcode) { |
|
192 |
- logg("!ClamClient: could not setup curl to connect only, %s\n", curl_easy_strerror(curlcode)); |
|
193 |
- curl_easy_cleanup(*curl); |
|
194 |
- return curlcode; |
|
195 |
- } |
|
209 |
+ curlcode = curl_easy_setopt(*curl, CURLOPT_NOSIGNAL, 1L); |
|
210 |
+ if (CURLE_OK != curlcode) { |
|
211 |
+ logg("!ClamClient: could not setup curl to not use signals, %s\n", curl_easy_strerror(curlcode)); |
|
212 |
+ curl_easy_cleanup(*curl); |
|
213 |
+ return curlcode; |
|
214 |
+ } |
|
196 | 215 |
|
197 |
- /* we implement our own transfer protocol via send and recv, so we only need to connect */ |
|
198 |
- curlcode = curl_easy_setopt(*curl, CURLOPT_CONNECTTIMEOUT_MS, (long) timeout); |
|
199 |
- if (CURLE_OK != curlcode) { |
|
200 |
- logg("!ClamClient: could not setup curl with connect timeout, %s\n", curl_easy_strerror(curlcode)); |
|
201 |
- curl_easy_cleanup(*curl); |
|
202 |
- return curlcode; |
|
203 |
- } |
|
216 |
+ curlcode = curl_easy_setopt(*curl, CURLOPT_CONNECTTIMEOUT_MS, (long) timeout); |
|
217 |
+ if (CURLE_OK != curlcode) { |
|
218 |
+ logg("!ClamClient: could not setup curl with connect timeout, %s\n", curl_easy_strerror(curlcode)); |
|
219 |
+ curl_easy_cleanup(*curl); |
|
220 |
+ return curlcode; |
|
221 |
+ } |
|
204 | 222 |
|
223 |
+ /* we implement our own transfer protocol via send and recv, so we only need to connect */ |
|
224 |
+ curlcode = curl_easy_setopt(*curl, CURLOPT_CONNECT_ONLY, 1L); |
|
225 |
+ if (CURLE_OK != curlcode) { |
|
226 |
+ logg("!ClamClient: could not setup curl to connect only, %s\n", curl_easy_strerror(curlcode)); |
|
227 |
+ curl_easy_cleanup(*curl); |
|
228 |
+ return curlcode; |
|
229 |
+ } |
|
205 | 230 |
|
206 | 231 |
|
207 | 232 |
#ifdef ONAS_DEBUG |
208 |
- curlcode = curl_easy_setopt(*curl, CURLOPT_VERBOSE, 1L); |
|
209 |
- if (CURLE_OK != curlcode) { |
|
210 |
- logg("!ClamClient: could not tell curl to be verbose, %s\n", curl_easy_strerror(curlcode)); |
|
211 |
- curl_easy_cleanup(*curl); |
|
212 |
- return curlcode; |
|
213 |
- } |
|
233 |
+ curlcode = curl_easy_setopt(*curl, CURLOPT_VERBOSE, 1L); |
|
234 |
+ if (CURLE_OK != curlcode) { |
|
235 |
+ logg("!ClamClient: could not tell curl to be verbose, %s\n", curl_easy_strerror(curlcode)); |
|
236 |
+ curl_easy_cleanup(*curl); |
|
237 |
+ return curlcode; |
|
238 |
+ } |
|
214 | 239 |
#endif |
215 | 240 |
|
216 |
- /* don't care about the body of the return message */ |
|
217 |
- curlcode = curl_easy_setopt(*curl, CURLOPT_NOBODY, 1L); |
|
218 |
- if (CURLE_OK != curlcode) { |
|
219 |
- logg("!ClamClient: could not setup curl to send HEAD request, %s\n", curl_easy_strerror(curlcode)); |
|
220 |
- curl_easy_cleanup(*curl); |
|
221 |
- return curlcode; |
|
222 |
- } |
|
241 |
+ /* don't care about the body of the return message */ |
|
242 |
+ curlcode = curl_easy_setopt(*curl, CURLOPT_NOBODY, 1L); |
|
243 |
+ if (CURLE_OK != curlcode) { |
|
244 |
+ logg("!ClamClient: could not setup curl to send HEAD request, %s\n", curl_easy_strerror(curlcode)); |
|
245 |
+ curl_easy_cleanup(*curl); |
|
246 |
+ return curlcode; |
|
247 |
+ } |
|
248 |
+ |
|
249 |
+ curlcode = curl_easy_setopt(*curl, CURLOPT_HEADER, 0L); |
|
250 |
+ if (CURLE_OK != curlcode) { |
|
251 |
+ logg("!ClamClient: could not setup curl to not send header, %s\n", curl_easy_strerror(curlcode)); |
|
252 |
+ curl_easy_cleanup(*curl); |
|
253 |
+ return curlcode; |
|
254 |
+ } |
|
223 | 255 |
|
224 |
- curlcode = curl_easy_setopt(*curl, CURLOPT_HEADER, 0L); |
|
225 |
- if (CURLE_OK != curlcode) { |
|
226 |
- logg("!ClamClient: could not setup curl to not send header, %s\n", curl_easy_strerror(curlcode)); |
|
227 |
- curl_easy_cleanup(*curl); |
|
228 |
- return curlcode; |
|
229 |
- } |
|
230 | 256 |
|
231 | 257 |
return curlcode; |
232 | 258 |
} |
... | ... |
@@ -336,13 +360,7 @@ int onas_get_clamd_version(struct onas_context **ctx) |
336 | 336 |
} |
337 | 337 |
|
338 | 338 |
if (!b_remote) { |
339 |
- curl = curl_easy_init(); |
|
340 |
- curlcode = curl_easy_setopt(curl, CURLOPT_UNIX_SOCKET_PATH, optget((*ctx)->clamdopts, "LocalSocket")->strarg); |
|
341 |
- if (CURLE_OK != curlcode) { |
|
342 |
- logg("!ClamClient: could not setup curl with local unix socket, %s\n", curl_easy_strerror(curlcode)); |
|
343 |
- curl_easy_cleanup(curl); |
|
344 |
- return 2; |
|
345 |
- } |
|
339 |
+ curlcode = onas_curl_init(&curl, optget((*ctx)->clamdopts, "LocalSocket")->strarg, (*ctx)->portnum, timeout); |
|
346 | 340 |
} else { |
347 | 341 |
curlcode = onas_curl_init(&curl, optget((*ctx)->clamdopts, "TCPAddr")->strarg, (*ctx)->portnum, timeout); |
348 | 342 |
if (CURLE_OK != curlcode) { |
... | ... |
@@ -329,7 +329,32 @@ int onas_dsresult(CURL *curl, int scantype, uint64_t maxstream, const char *file |
329 | 329 |
if (ret_code) { |
330 | 330 |
*ret_code = CL_ESTAT; |
331 | 331 |
} |
332 |
+ } else if(len > 41 && !memcmp(eol-42, " lstat() failed: Permission denied. ERROR", 41)) { |
|
333 |
+ if(errors) { |
|
334 |
+ (*errors)++; |
|
335 |
+ } |
|
336 |
+ *printok = 0; |
|
337 |
+ |
|
338 |
+ if(filename) { |
|
339 |
+ (scantype >= STREAM) ? logg("*%s%s\n", filename, colon) : logg("*%s\n", bol); |
|
340 |
+ } |
|
341 |
+ |
|
342 |
+ if (ret_code) { |
|
343 |
+ *ret_code = CL_ESTAT; |
|
344 |
+ } |
|
345 |
+ } else if(len > 21 && !memcmp(eol-22, " Access denied. ERROR", 21)) { |
|
346 |
+ if(errors) { |
|
347 |
+ (*errors)++; |
|
348 |
+ } |
|
349 |
+ *printok = 0; |
|
332 | 350 |
|
351 |
+ if(filename) { |
|
352 |
+ (scantype >= STREAM) ? logg("*%s%s\n", filename, colon) : logg("*%s\n", bol); |
|
353 |
+ } |
|
354 |
+ |
|
355 |
+ if (ret_code) { |
|
356 |
+ *ret_code = CL_EACCES; |
|
357 |
+ } |
|
333 | 358 |
} else if(!memcmp(eol-7, " ERROR", 6)) { |
334 | 359 |
if(errors) { |
335 | 360 |
(*errors)++; |
... | ... |
@@ -57,33 +57,38 @@ |
57 | 57 |
|
58 | 58 |
extern pthread_t ddd_pid; |
59 | 59 |
extern pthread_t scque_pid; |
60 |
+static int onas_fan_fd; |
|
60 | 61 |
|
61 |
-/*static void onas_fan_exit(int sig) |
|
62 |
+static void onas_fan_exit(int sig) |
|
62 | 63 |
{ |
63 | 64 |
logg("*ClamFanotif: onas_fan_exit(), signal %d\n", sig); |
64 | 65 |
|
66 |
+ if(onas_fan_fd) { |
|
65 | 67 |
close(onas_fan_fd); |
68 |
+ } |
|
69 |
+ onas_fan_fd = 0; |
|
66 | 70 |
|
67 | 71 |
if (ddd_pid > 0) { |
68 | 72 |
pthread_kill(ddd_pid, SIGUSR1); |
69 | 73 |
pthread_join(ddd_pid, NULL); |
70 | 74 |
} |
75 |
+ ddd_pid = 0; |
|
71 | 76 |
|
72 | 77 |
if (scque_pid > 0) { |
73 |
- pthread_kill(ddd_pid, SIGUSR1); |
|
74 |
- pthread_join(ddd_pid, NULL); |
|
78 |
+ pthread_kill(scque_pid, SIGUSR2); |
|
79 |
+ pthread_join(scque_pid, NULL); |
|
75 | 80 |
} |
81 |
+ scque_pid = 0; |
|
76 | 82 |
|
77 |
- pthread_exit(NULL); |
|
78 | 83 |
logg("ClamFanotif: stopped\n"); |
79 |
-}*/ |
|
84 |
+ pthread_exit(NULL); |
|
85 |
+} |
|
80 | 86 |
|
81 | 87 |
cl_error_t onas_setup_fanotif(struct onas_context **ctx) { |
82 | 88 |
|
83 | 89 |
const struct optstruct *pt; |
84 | 90 |
short int scan; |
85 | 91 |
unsigned int sizelimit = 0, extinfo; |
86 |
- int onas_fan_fd; |
|
87 | 92 |
uint64_t fan_mask = FAN_EVENT_ON_CHILD; |
88 | 93 |
char err[128]; |
89 | 94 |
|
... | ... |
@@ -152,9 +157,9 @@ cl_error_t onas_setup_fanotif(struct onas_context **ctx) { |
152 | 152 |
/* Load other options. */ |
153 | 153 |
(*ctx)->sizelimit = optget((*ctx)->clamdopts, "OnAccessMaxFileSize")->numarg; |
154 | 154 |
if((*ctx)->sizelimit) |
155 |
- logg("*ClamFanotif: Max file size limited to %lu bytes\n", (*ctx)->sizelimit); |
|
155 |
+ logg("*ClamFanotif: max file size limited to %lu bytes\n", (*ctx)->sizelimit); |
|
156 | 156 |
else |
157 |
- logg("*ClamFanotif: File size limit disabled\n"); |
|
157 |
+ logg("*ClamFanotif: file size limit disabled\n"); |
|
158 | 158 |
|
159 | 159 |
extinfo = optget((*ctx)->clamdopts, "ExtendedDetectionInfo")->enabled; |
160 | 160 |
|
... | ... |
@@ -164,6 +169,8 @@ cl_error_t onas_setup_fanotif(struct onas_context **ctx) { |
164 | 164 |
int onas_fan_eloop(struct onas_context **ctx) { |
165 | 165 |
int ret = 0; |
166 | 166 |
int err_cnt = 0; |
167 |
+ sigset_t sigset; |
|
168 |
+ struct sigaction act; |
|
167 | 169 |
short int scan; |
168 | 170 |
STATBUF sb; |
169 | 171 |
fd_set rfds; |
... | ... |
@@ -174,6 +181,26 @@ int onas_fan_eloop(struct onas_context **ctx) { |
174 | 174 |
int len, check, fres; |
175 | 175 |
char err[128]; |
176 | 176 |
|
177 |
+ /* ignore all signals except SIGUSR1 */ |
|
178 |
+ sigfillset(&sigset); |
|
179 |
+ sigdelset(&sigset, SIGUSR1); |
|
180 |
+ /* The behavior of a process is undefined after it ignores a |
|
181 |
+ * SIGFPE, SIGILL, SIGSEGV, or SIGBUS signal */ |
|
182 |
+ sigdelset(&sigset, SIGFPE); |
|
183 |
+ sigdelset(&sigset, SIGILL); |
|
184 |
+ sigdelset(&sigset, SIGSEGV); |
|
185 |
+ sigdelset(&sigset, SIGINT); |
|
186 |
+#ifdef SIGBUS |
|
187 |
+ sigdelset(&sigset, SIGBUS); |
|
188 |
+#endif |
|
189 |
+ pthread_sigmask(SIG_SETMASK, &sigset, NULL); |
|
190 |
+ memset(&act, 0, sizeof(struct sigaction)); |
|
191 |
+ act.sa_handler = onas_fan_exit; |
|
192 |
+ sigfillset(&(act.sa_mask)); |
|
193 |
+ sigaction(SIGUSR1, &act, NULL); |
|
194 |
+ sigaction(SIGSEGV, &act, NULL); |
|
195 |
+ sigaction(SIGINT, &act, NULL); |
|
196 |
+ |
|
177 | 197 |
FD_ZERO(&rfds); |
178 | 198 |
FD_SET((*ctx)->fan_fd, &rfds); |
179 | 199 |
do { |
... | ... |
@@ -278,6 +305,7 @@ int onas_fan_eloop(struct onas_context **ctx) { |
278 | 278 |
logg("!ClamFanotif: error occurred while excluding event\n"); |
279 | 279 |
return 2; |
280 | 280 |
} |
281 |
+ } |
|
281 | 282 |
|
282 | 283 |
if (-1 == close(fmd->fd)) { |
283 | 284 |
logg("!ClamFanotif: error occurred while closing metadata fd, %d\n", fmd->fd); |
... | ... |
@@ -289,7 +317,6 @@ int onas_fan_eloop(struct onas_context **ctx) { |
289 | 289 |
} |
290 | 290 |
} |
291 | 291 |
} |
292 |
- } |
|
293 | 292 |
fmd = FAN_EVENT_NEXT(fmd, bread); |
294 | 293 |
} |
295 | 294 |
do { |
... | ... |
@@ -348,7 +348,8 @@ void *onas_ddd_th(void *arg) { |
348 | 348 |
* SIGFPE, SIGILL, SIGSEGV, or SIGBUS signal */ |
349 | 349 |
sigdelset(&sigset, SIGFPE); |
350 | 350 |
sigdelset(&sigset, SIGILL); |
351 |
- //sigdelset(&sigset, SIGSEGV); |
|
351 |
+ sigdelset(&sigset, SIGSEGV); |
|
352 |
+ sigdelset(&sigset, SIGINT); |
|
352 | 353 |
#ifdef SIGBUS |
353 | 354 |
sigdelset(&sigset, SIGBUS); |
354 | 355 |
#endif |
... | ... |
@@ -359,22 +360,22 @@ void *onas_ddd_th(void *arg) { |
359 | 359 |
sigaction(SIGUSR1, &act, NULL); |
360 | 360 |
sigaction(SIGSEGV, &act, NULL); |
361 | 361 |
|
362 |
- logg("*ClamInotif: Starting inotify event thread\n"); |
|
362 |
+ logg("*ClamInotif: starting inotify event thread\n"); |
|
363 | 363 |
|
364 | 364 |
onas_in_fd = inotify_init1(IN_NONBLOCK); |
365 | 365 |
if (onas_in_fd == -1) { |
366 |
- logg("!ClamInotif: Could not init inotify."); |
|
366 |
+ logg("!ClamInotif: could not init inotify\n"); |
|
367 | 367 |
return NULL; |
368 | 368 |
} |
369 | 369 |
|
370 | 370 |
ret = onas_ddd_init(0, ONAS_DEFAULT_HT_SIZE); |
371 | 371 |
if (ret) { |
372 |
- logg("!ClamInotif: Failed to initialize 3D. \n"); |
|
372 |
+ logg("!ClamInotif: failed to initialize DDD system\n"); |
|
373 | 373 |
return NULL; |
374 | 374 |
} |
375 | 375 |
|
376 | 376 |
|
377 |
- logg("*ClamInotif: Dynamically determining directory hierarchy...\n"); |
|
377 |
+ logg("*ClamInotif: dynamically determining directory hierarchy...\n"); |
|
378 | 378 |
/* Add provided paths recursively. */ |
379 | 379 |
|
380 | 380 |
if (!optget(ctx->opts, "watch-list")->enabled && !optget(ctx->clamdopts, "OnAccessIncludePath")->enabled) { |
... | ... |
@@ -593,7 +594,7 @@ void *onas_ddd_th(void *arg) { |
593 | 593 |
} |
594 | 594 |
} |
595 | 595 |
|
596 |
- logg("*ClamInotif: Exiting inotify event thread\n"); |
|
596 |
+ logg("*ClamInotif: exiting inotify event thread\n"); |
|
597 | 597 |
return NULL; |
598 | 598 |
} |
599 | 599 |
|
... | ... |
@@ -605,7 +606,7 @@ static void onas_ddd_handle_in_delete(struct onas_context *ctx, |
605 | 605 |
if (stat(child_path, &s) == 0 && S_ISREG(s.st_mode)) return; |
606 | 606 |
if (!(event->mask & IN_ISDIR)) return; |
607 | 607 |
|
608 |
- logg("*ClamInotif: DELETE - Removing %s from %s with wd:%d\n", child_path, path, wd); |
|
608 |
+ logg("*ClamInotif: DELETE - removing %s from %s with wd:%d\n", child_path, path, wd); |
|
609 | 609 |
onas_ddd_unwatch(child_path, ctx->fan_fd, onas_in_fd); |
610 | 610 |
onas_ht_rm_hierarchy(ddd_ht, child_path, strlen(child_path), 0); |
611 | 611 |
|
... | ... |
@@ -619,7 +620,7 @@ static void onas_ddd_handle_in_moved_from(struct onas_context *ctx, |
619 | 619 |
if (stat(child_path, &s) == 0 && S_ISREG(s.st_mode)) return; |
620 | 620 |
if (!(event->mask & IN_ISDIR)) return; |
621 | 621 |
|
622 |
- logg("*ClamInotif: MOVED_FROM - Removing %s from %s with wd:%d\n", child_path, path, wd); |
|
622 |
+ logg("*ClamInotif: MOVED_FROM - removing %s from %s with wd:%d\n", child_path, path, wd); |
|
623 | 623 |
onas_ddd_unwatch(child_path, ctx->fan_fd, onas_in_fd); |
624 | 624 |
onas_ht_rm_hierarchy(ddd_ht, child_path, strlen(child_path), 0); |
625 | 625 |
|
... | ... |
@@ -636,7 +637,7 @@ static void onas_ddd_handle_in_create(struct onas_context *ctx, |
636 | 636 |
onas_ddd_handle_extra_scanning(ctx, child_path, ONAS_SCTH_B_FILE); |
637 | 637 |
|
638 | 638 |
} else if(event->mask & IN_ISDIR) { |
639 |
- logg("*ClamInotif: CREATE - Adding %s to %s with wd:%d\n", child_path, path, wd); |
|
639 |
+ logg("*ClamInotif: CREATE - adding %s to %s with wd:%d\n", child_path, path, wd); |
|
640 | 640 |
onas_ddd_handle_extra_scanning(ctx, child_path, ONAS_SCTH_B_DIR); |
641 | 641 |
|
642 | 642 |
onas_ht_add_hierarchy(ddd_ht, child_path); |
... | ... |
@@ -648,7 +649,7 @@ static void onas_ddd_handle_in_create(struct onas_context *ctx, |
648 | 648 |
if (stat(child_path, &s) == 0 && S_ISREG(s.st_mode)) return; |
649 | 649 |
if (!(event->mask & IN_ISDIR)) return; |
650 | 650 |
|
651 |
- logg("*ClamInotif: MOVED_TO - Adding %s to %s with wd:%d\n", child_path, path, wd); |
|
651 |
+ logg("*ClamInotif: MOVED_TO - adding %s to %s with wd:%d\n", child_path, path, wd); |
|
652 | 652 |
onas_ht_add_hierarchy(ddd_ht, child_path); |
653 | 653 |
onas_ddd_watch(child_path, ctx->fan_fd, ctx->fan_mask, onas_in_fd, in_mask); |
654 | 654 |
} |
... | ... |
@@ -665,7 +666,7 @@ static void onas_ddd_handle_in_moved_to(struct onas_context *ctx, |
665 | 665 |
onas_ddd_handle_extra_scanning(ctx, child_path, ONAS_SCTH_B_FILE); |
666 | 666 |
|
667 | 667 |
} else if(event->mask & IN_ISDIR) { |
668 |
- logg("*ClamInotif: MOVED_TO - Adding %s to %s with wd:%d\n", child_path, path, wd); |
|
668 |
+ logg("*ClamInotif: MOVED_TO - adding %s to %s with wd:%d\n", child_path, path, wd); |
|
669 | 669 |
onas_ddd_handle_extra_scanning(ctx, child_path, ONAS_SCTH_B_DIR); |
670 | 670 |
|
671 | 671 |
onas_ht_add_hierarchy(ddd_ht, child_path); |
... | ... |
@@ -676,7 +677,7 @@ static void onas_ddd_handle_in_moved_to(struct onas_context *ctx, |
676 | 676 |
if (stat(child_path, &s) == 0 && S_ISREG(s.st_mode)) return; |
677 | 677 |
if (!(event->mask & IN_ISDIR)) return; |
678 | 678 |
|
679 |
- logg("*ClamInotif: MOVED_TO - Adding %s to %s with wd:%d\n", child_path, path, wd); |
|
679 |
+ logg("*ClamInotif: MOVED_TO - adding %s to %s with wd:%d\n", child_path, path, wd); |
|
680 | 680 |
onas_ht_add_hierarchy(ddd_ht, child_path); |
681 | 681 |
onas_ddd_watch(child_path, ctx->fan_fd, ctx->fan_mask, onas_in_fd, in_mask); |
682 | 682 |
} |
... | ... |
@@ -717,12 +718,22 @@ static void onas_ddd_handle_extra_scanning(struct onas_context *ctx, const char |
717 | 717 |
static void onas_ddd_exit(int sig) { |
718 | 718 |
logg("*ClamInotif: onas_ddd_exit(), signal %d\n", sig); |
719 | 719 |
|
720 |
+ if (onas_in_fd) { |
|
720 | 721 |
close(onas_in_fd); |
722 |
+ } |
|
723 |
+ onas_in_fd = 0; |
|
721 | 724 |
|
725 |
+ if (ddd_ht) { |
|
722 | 726 |
onas_free_ht(ddd_ht); |
727 |
+ } |
|
728 |
+ ddd_ht = NULL; |
|
729 |
+ |
|
730 |
+ if (wdlt) { |
|
723 | 731 |
free(wdlt); |
732 |
+ } |
|
733 |
+ wdlt = NULL; |
|
724 | 734 |
|
725 |
- pthread_exit(NULL); |
|
726 | 735 |
logg("ClamInotif: stopped\n"); |
736 |
+ pthread_exit(NULL); |
|
727 | 737 |
} |
728 | 738 |
#endif |
... | ... |
@@ -148,12 +148,13 @@ void *onas_scanque_th(void *arg) { |
148 | 148 |
|
149 | 149 |
/* ignore all signals except SIGUSR1 */ |
150 | 150 |
sigfillset(&sigset); |
151 |
- sigdelset(&sigset, SIGUSR1); |
|
151 |
+ sigdelset(&sigset, SIGUSR2); |
|
152 | 152 |
/* The behavior of a process is undefined after it ignores a |
153 | 153 |
* SIGFPE, SIGILL, SIGSEGV, or SIGBUS signal */ |
154 | 154 |
sigdelset(&sigset, SIGFPE); |
155 | 155 |
sigdelset(&sigset, SIGILL); |
156 |
- //sigdelset(&sigset, SIGSEGV); |
|
156 |
+ sigdelset(&sigset, SIGSEGV); |
|
157 |
+ sigdelset(&sigset, SIGINT); |
|
157 | 158 |
#ifdef SIGBUS |
158 | 159 |
sigdelset(&sigset, SIGBUS); |
159 | 160 |
#endif |
... | ... |
@@ -161,16 +162,16 @@ void *onas_scanque_th(void *arg) { |
161 | 161 |
memset(&act, 0, sizeof(struct sigaction)); |
162 | 162 |
act.sa_handler = onas_scanque_exit; |
163 | 163 |
sigfillset(&(act.sa_mask)); |
164 |
- sigaction(SIGUSR1, &act, NULL); |
|
164 |
+ sigaction(SIGUSR2, &act, NULL); |
|
165 | 165 |
sigaction(SIGSEGV, &act, NULL); |
166 | 166 |
|
167 |
- logg("*ClamQueue: initializing event queue consumer w/ (%d) threads in thread pool\n", ctx->maxthreads); |
|
167 |
+ logg("*ClamQueue: initializing event queue consumer ... (%d) threads in thread pool\n", ctx->maxthreads); |
|
168 | 168 |
onas_init_event_queue(); |
169 | 169 |
threadpool thpool = thpool_init(ctx->maxthreads); |
170 | 170 |
g_thpool = thpool; |
171 | 171 |
|
172 | 172 |
/* loop w/ onas_consume_event until we die */ |
173 |
- logg("*ClamQueue: waiting to cosume events ...\n"); |
|
173 |
+ logg("*ClamQueue: waiting to consume events ...\n"); |
|
174 | 174 |
do { |
175 | 175 |
/* if there's no event to consume ... */ |
176 | 176 |
if (!onas_consume_event(thpool)) { |
... | ... |
@@ -201,7 +202,10 @@ static int onas_consume_event(threadpool thpool) { |
201 | 201 |
return 1; |
202 | 202 |
} |
203 | 203 |
|
204 |
+#ifdef ONAS_DEBUG |
|
204 | 205 |
logg("*ClamonQueue: consuming event!\n"); |
206 |
+#endif |
|
207 |
+ |
|
205 | 208 |
thpool_add_work(thpool, (void *) onas_scan_worker, (void *) popped_node->data); |
206 | 209 |
|
207 | 210 |
g_onas_event_queue_head->next = g_onas_event_queue_head->next->next; |
... | ... |
@@ -222,7 +226,10 @@ cl_error_t onas_queue_event(struct onas_scan_event *event_data) { |
222 | 222 |
|
223 | 223 |
struct onas_event_queue_node *node = NULL; |
224 | 224 |
|
225 |
+#ifdef ONAS_DEBUG |
|
225 | 226 |
logg("*ClamonQueue: queueing event!\n"); |
227 |
+#endif |
|
228 |
+ |
|
226 | 229 |
if (CL_EMEM == onas_new_event_queue_node(&node)) { |
227 | 230 |
return CL_EMEM; |
228 | 231 |
} |
... | ... |
@@ -273,10 +280,13 @@ static void onas_scanque_exit(int sig) { |
273 | 273 |
logg("*ClamScanque: onas_scanque_exit(), signal %d\n", sig); |
274 | 274 |
|
275 | 275 |
onas_destroy_event_queue(); |
276 |
- thpool_destroy(g_thpool); |
|
276 |
+ if (g_thpool) { |
|
277 |
+ thpool_destroy(g_thpool); |
|
278 |
+ } |
|
279 |
+ g_thpool = NULL; |
|
277 | 280 |
|
278 |
- pthread_exit(NULL); |
|
279 | 281 |
logg("ClamScanque: stopped\n"); |
282 |
+ pthread_exit(NULL); |
|
280 | 283 |
} |
281 | 284 |
|
282 | 285 |
#endif |
... | ... |
@@ -167,8 +167,6 @@ static cl_error_t onas_scth_scanfile(struct onas_scan_event *event_data, const c |
167 | 167 |
res.response = FAN_DENY; |
168 | 168 |
} |
169 | 169 |
} |
170 |
- } else { |
|
171 |
- logg("DEBUG: NOT SCANNING\n"); |
|
172 | 170 |
} |
173 | 171 |
|
174 | 172 |
|
... | ... |
@@ -178,7 +176,7 @@ static cl_error_t onas_scth_scanfile(struct onas_scan_event *event_data, const c |
178 | 178 |
if(ret == -1) { |
179 | 179 |
logg("!ClamWorker: internal error (can't write to fanotify)\n"); |
180 | 180 |
if (errno == ENOENT) { |
181 |
- logg("ClamWorker: permission event has already been written ... recovering ...\n"); |
|
181 |
+ logg("*ClamWorker: permission event has already been written ... recovering ...\n"); |
|
182 | 182 |
} else { |
183 | 183 |
ret = CL_EWRITE; |
184 | 184 |
} |
... | ... |
@@ -187,10 +185,15 @@ static cl_error_t onas_scth_scanfile(struct onas_scan_event *event_data, const c |
187 | 187 |
} |
188 | 188 |
|
189 | 189 |
if (b_fanotify) { |
190 |
+ |
|
191 |
+#ifdef ONAS_DEBUG |
|
192 |
+ logg("*ClamWorker: closing fd, %d)\n", event_data->fmd->fd); |
|
193 |
+#endif |
|
190 | 194 |
if (-1 == close(event_data->fmd->fd) ) { |
195 |
+ |
|
191 | 196 |
logg("!ClamWorker: internal error (can't close fanotify meta fd, %d)\n", event_data->fmd->fd); |
192 | 197 |
if (errno == EBADF) { |
193 |
- logg("ClamWorker: fd already closed ... recovering ...\n"); |
|
198 |
+ logg("*ClamWorker: fd already closed ... recovering ...\n"); |
|
194 | 199 |
} else { |
195 | 200 |
ret = CL_EUNLINK; |
196 | 201 |
} |
... | ... |
@@ -273,11 +276,17 @@ static cl_error_t onas_scth_handle_file(struct onas_scan_event *event_data, cons |
273 | 273 |
} |
274 | 274 |
|
275 | 275 |
ret = onas_scth_scanfile(event_data, pathname, sb, &infected, &err, &ret_code); |
276 |
- // probs need to error check here later, or at least log |
|
277 |
- if (event_data->bool_opts | ONAS_SCTH_B_INOTIFY) { |
|
278 |
- logg(">>>>>>DEBUG: ClamWorker: Inotify Scan Rsults ... ret = %d ; infected = %d ; err = %d ret_code = %d\n", |
|
276 |
+ |
|
277 |
+#ifdef ONAS_DEBUG |
|
278 |
+ /* very noisy, debug only */ |
|
279 |
+ if (event_data->bool_opts & ONAS_SCTH_B_INOTIFY) { |
|
280 |
+ logg("*ClamWorker: Inotify Scan Results ...\n\tret = %d ...\n\tinfected = %d ...\n\terr = %d ...\n\tret_code = %d\n", |
|
279 | 281 |
ret, infected, err, ret_code); |
282 |
+ } else { |
|
283 |
+ logg("*ClamWorker: Fanotify Scan Results ...\n\tret = %d ...\n\tinfected = %d ...\n\terr = %d ...\n\tret_code = %d\n\tfd = %d\n", |
|
284 |
+ ret, infected, err, ret_code, event_data->fmd->fd); |
|
280 | 285 |
} |
286 |
+#endif |
|
281 | 287 |
|
282 | 288 |
return ret; |
283 | 289 |
} |
... | ... |
@@ -365,8 +374,6 @@ cl_error_t onas_map_context_info_to_event_data(struct onas_context *ctx, struct |
365 | 365 |
(*event_data)->scantype = ctx->scantype; |
366 | 366 |
(*event_data)->timeout = ctx->timeout; |
367 | 367 |
(*event_data)->maxstream = ctx->maxstream; |
368 |
- (*event_data)->tcpaddr = optget(ctx->clamdopts, "TCPAddr")->strarg; |
|
369 |
- (*event_data)->portnum = ctx->portnum; |
|
370 | 368 |
(*event_data)->fan_fd = ctx->fan_fd; |
371 | 369 |
(*event_data)->sizelimit = ctx->sizelimit; |
372 | 370 |
(*event_data)->retry_attempts = ctx->retry_attempts; |
... | ... |
@@ -379,6 +386,14 @@ cl_error_t onas_map_context_info_to_event_data(struct onas_context *ctx, struct |
379 | 379 |
(*event_data)->bool_opts |= ONAS_SCTH_B_DENY_ON_E; |
380 | 380 |
} |
381 | 381 |
|
382 |
+ if (ctx->isremote) { |
|
383 |
+ (*event_data)->bool_opts |= ONAS_SCTH_B_REMOTE; |
|
384 |
+ (*event_data)->tcpaddr = optget(ctx->clamdopts, "TCPAddr")->strarg; |
|
385 |
+ (*event_data)->portnum = ctx->portnum; |
|
386 |
+ } else { |
|
387 |
+ (*event_data)->tcpaddr = optget(ctx->clamdopts, "LocalSocket")->strarg; |
|
388 |
+ } |
|
389 |
+ |
|
382 | 390 |
return CL_SUCCESS; |
383 | 391 |
} |
384 | 392 |
#endif |
... | ... |
@@ -33,6 +33,17 @@ |
33 | 33 |
#define ONAS_SCTH_B_SCAN 0x10 |
34 | 34 |
#define ONAS_SCTH_B_RETRY_ON_E 0x20 |
35 | 35 |
#define ONAS_SCTH_B_DENY_ON_E 0x40 |
36 |
+#define ONAS_SCTH_B_REMOTE 0x80 |
|
37 |
+ |
|
38 |
+#ifndef HAVE_ATTRIB_PACKED |
|
39 |
+#define __attribute__(x) |
|
40 |
+#endif |
|
41 |
+#ifdef HAVE_PRAGMA_PACK |
|
42 |
+#pragma pack(1) |
|
43 |
+#endif |
|
44 |
+#ifdef HAVE_PRAGMA_PACK_HPPA |
|
45 |
+#pragma pack 1 |
|
46 |
+#endif |
|
36 | 47 |
|
37 | 48 |
struct onas_scan_event { |
38 | 49 |
const char *tcpaddr; |
... | ... |
@@ -46,7 +57,14 @@ struct onas_scan_event { |
46 | 46 |
int64_t maxstream; |
47 | 47 |
int64_t timeout; |
48 | 48 |
uint8_t bool_opts; |
49 |
-}; |
|
49 |
+} __attribute((packed)); |
|
50 |
+ |
|
51 |
+#ifdef HAVE_PRAGMA_PACK |
|
52 |
+#pragma pack() |
|
53 |
+#endif |
|
54 |
+#ifdef HAVE_PRAGMA_PACK_HPPA |
|
55 |
+#pragma pack |
|
56 |
+#endif |
|
50 | 57 |
|
51 | 58 |
void *onas_scan_th(void *arg); |
52 | 59 |
|