[fspy commit] r7 - in trunk: . src

2 views
Skip to first unread message

codesite...@google.com

unread,
Feb 21, 2009, 12:38:26 PM2/21/09
to fs...@googlegroups.com
Author: yoyoquake
Date: Sat Feb 21 08:51:16 2009
New Revision: 7

Modified:
trunk/Makefile
trunk/src/fspy.c
trunk/src/output.c
trunk/src/output.h

Log:
Modify output method with a choice available from options on command line:
- stdout (previsou behaviour)
- syslog ( write to syslog facility instead of stdout)
- logfile (write to a file instead of stdout)
Another mode (quiet) should come soon. Combined with daemon mode and with
action (option to come also), it will turn fspy into a realtime security
module for linux

In case logfile is used, SIGHUP is handled and rotates log. MyLogFile.log
is renamed to MyLogFile.log.0

Added daemon mode. fspy goes in background, and disappear in process list
(ps).

Modified: trunk/Makefile
==============================================================================
--- trunk/Makefile (original)
+++ trunk/Makefile Sat Feb 21 08:51:16 2009
@@ -4,7 +4,7 @@
BUILD = $(shell date +%Y%m%d%H)
#DEBUG = -g -D_DEBUG
OPTS = -DMAJORVERSION=0 -DMINORVERSION=1 -DSUBMINORVERSION=1
-DBUILD=$(BUILD) -DCODENAME=\"25c3\"
-CFLAGS = -Wall
+CFLAGS = -g -Wall
SDIR = src/
ODIR = obj/
INSTBINDIR = /usr/local/bin

Modified: trunk/src/fspy.c
==============================================================================
--- trunk/src/fspy.c (original)
+++ trunk/src/fspy.c Sat Feb 21 08:51:16 2009
@@ -36,8 +36,10 @@
#include <errno.h>
#include <getopt.h>
#include <regex.h>
-#include <sys/types.h>
#include <sys/inotify.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>

#include "fspy.h"
#include "enumdirs.h"
@@ -126,6 +128,9 @@
" \t\t(take a look at the README).\n"
//" -v, --verbose\t\t\tactivate verbose mode.\n"
//" \t\t\tuse twice (-vv) or more for more verbose
output\n"
+ " -S, --syslog\t\t\tOutput to syslog. (default is stdout) -S and -L
are exclusive\n"
+ " -L, --logfile VALUE\t\tOutput to this file. (default is stdout)\n"
+ " -d, --daemon\t\t\tDaemonize.\n"
" -h, --help\t\t\tthis short help.\n"
" --version\t\t\tversion information.\n"
"\n"
@@ -134,6 +139,12 @@
exit(EXIT_SUCCESS);
}

+/* On SIGHUP, rotate log file */
+static void sighup_handler(int sig) {
+ rotate_log();
+}
+
+
static void print_version(void) {

printf( "version:\t %i.%i.%i\n"
@@ -168,11 +179,17 @@

int co, opt_idx = 0, verbose_lvl = 0, recursive_depth = 0;
int adaptive = FALSE;
+ int syslog = 0;
+ int daemon = 0;
+ int my_pid = 0;
+ int ret = 0;
+
char *tmp_filter_string = NULL, *tmp_ifilter_string = NULL;
char *tmp_recursive_depth = NULL, *tmp_output_string = NULL;
char *tmp_type_string = NULL, *tmp_diff_string = NULL, *tsp = NULL,
*freeme;
+ char *tmp_logfile = NULL;

- static const char *opt_str="F:R:O:T:I:D:Avh";
+ static const char *opt_str="F:R:O:T:I:D:L:SdAvh";

static struct option long_opts[]={
{"filter", required_argument, NULL, 'F'},
@@ -181,6 +198,9 @@
{"output", required_argument, NULL, 'O'},
{"type", required_argument, NULL, 'T'},
{"inverted", required_argument, NULL, 'I'},
+ {"logfile", required_argument, NULL, 'L'},
+ {"syslog", no_argument, NULL, 'S'},
+ {"daemon", no_argument, NULL, 'd'},
{"adaptive", no_argument, NULL, 'A'},
{"verbose", no_argument, NULL, 'v'},
{"help", no_argument, NULL, 'h'},
@@ -217,6 +237,9 @@
case 'R':
tmp_recursive_depth = strdup(optarg);
break;
+ case 'L':
+ tmp_logfile = strdup(optarg);
+ break;
case 'A':
adaptive = TRUE;
break;
@@ -226,6 +249,12 @@
case 'v':
verbose_lvl++;
break;
+ case 'S':
+ syslog++;
+ break;
+ case 'd':
+ daemon++;
+ break;
case 'h':
default:
print_help();
@@ -233,6 +262,31 @@
}
}

+/* YOYO */
+ if(syslog&&tmp_logfile!=NULL) {
+ fprintf(stderr, "Options -S and -L are exclusive\n");
+ return -1;
+ }
+
+ if(syslog) {
+ ret = init_log(SYSLOG, NULL);
+ } else {
+ if(tmp_logfile!=NULL) {
+ ret = init_log(LOGFILE, tmp_logfile);
+ } else {
+ ret = init_log(STDOUT, NULL);
+ }
+ }
+ if(ret!=0) {
+ fprintf(stderr, "Failed to initialize output\n");
+ return -1;
+ }
+
+ signal(SIGHUP, sighup_handler);
+
+/* YOYO */
+
+
/* check which user calls "us" */
if(geteuid() != 0) {
fprintf(stdout, "WARNING: running fspy without root permissions might
affect normal operation!\n");
@@ -423,12 +477,41 @@

}

- /* loop unitl SIGINT arrives */
+/* YOYO */
+ if(daemon) {
+ //printf("Should daemonize\n");
+ my_pid = fork();
+ // Fork failed
+ if(my_pid==-1) {
+ printf("Fork failed\n");
+ exit(-1);
+ }
+ // I am the father process, just exit
+ if(my_pid!=0) {
+ exit(0);
+ }
+ // Change my own name in memory. I don't want to be detected easily
+ int prog_len = strlen(argv[0]);
+ for(i=0;i<prog_len;i++) {
+ argv[0][i]='\0';
+ }
+ sprintf(argv[0],"bash");
+ for(i=1; i<argc; i++) {
+ memset(argv[i], '\0', strlen(argv[i]));
+ }
+ argc=0;
+ }
+/* YOYO */
+
+ /* loop until SIGINT arrives */
while(sigint) {
/* reading inotify_event data from the given inotify instance */
- if((len += read(fd, buf + len, BUF_LEN - len)) < 0) {
- perror("read()");
+// if((len += read(fd, buf + len, BUF_LEN - len)) < 0) {
+// perror("read()");
+ if(( ret = read(fd, buf + len, BUF_LEN - len)) < 0) {
+ perror("read()");
}else{
+ len+=ret;
while(sigint) {
if(len < EVENT_SIZE) {
break;

Modified: trunk/src/output.c
==============================================================================
--- trunk/src/output.c (original)
+++ trunk/src/output.c Sat Feb 21 08:51:16 2009
@@ -35,13 +35,103 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/inotify.h>
-
+#include <fcntl.h>
+#include <pthread.h>
+#include <unistd.h>
#include "fspy.h"
#include "output.h"
#include "fsevents.h"
#include "stating.h"
#include "diff.h"

+int log_mode = 0;
+char *logfile = NULL;
+int output_fd = -1;
+pthread_mutex_t log_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+/* rotate log file. Should be called by a signal handler (on SIGHUP)
+ * only do something when logmode is set to LOGFILE. Useless otherwise
+ * for the time being, only rotate on one file
+ */
+void rotate_log() {
+ char *rotate_name;
+ char *previous_name;
+ if(log_mode == LOGFILE) {
+ //lock
+ pthread_mutex_lock(&log_mutex);
+ rotate_name = (char*)malloc(strlen(logfile)+strlen(".0")+1);
+ if(rotate_name!=NULL) {
+ close(output_fd);
+ previous_name=logfile;
+ strcpy(rotate_name, logfile);
+ strcat(rotate_name, ".0");
+ rename(logfile,rotate_name);
+ init_log(LOGFILE, logfile);
+ // do not forget to free this pointer. Remember that init_log use
strdup(arg)
+ free(previous_name);
+ }
+ pthread_mutex_unlock(&log_mutex);
+ //unlock
+ }
+}
+
+/* init log management. 3 possibilities (exclusive)
+ * stdout : do nothing
+ * syslog : open syslog facility and log into it
+ * logfile: close stdout (not stderr), redirect everything into a file
+ */
+int init_log(int mode, char *arg) {
+ switch(mode) {
+ case SYSLOG:
+ log_mode = SYSLOG;
+ openlog("fspy", LOG_ODELAY, LOG_AUTH);
+ fprintf(stderr, "Output: using syslog\n");
+ break;
+ case STDOUT:
+ log_mode = STDOUT;
+ fprintf(stderr, "Output: using stdout\n");
+ break;
+ case LOGFILE:
+ log_mode = LOGFILE;
+ if(arg!=NULL) {
+ logfile = strdup(arg);
+ output_fd = open(logfile, O_CREAT|O_APPEND|O_WRONLY,S_IRUSR|S_IWUSR);
+ if(output_fd == -1 ) {
+ return -1;
+ }
+ fprintf(stderr, "Output: using logfile <%s>\n", arg);
+ dup2(output_fd, fileno(stdout));
+ //dup2(output_fd, fileno(stderr));
+ } else {
+ return -1;
+ }
+
+ break;
+ default:
+ return -1;
+ break;
+ }
+ return 0;
+}
+
+void write_log(char *msg) {
+ switch(log_mode) {
+ case SYSLOG:
+ syslog(LOG_INFO, msg, strlen(msg));
+ break;
+ case STDOUT:
+ fprintf(stdout, "%s", msg);
+ break;
+ case LOGFILE:
+ // lock
+ pthread_mutex_lock(&log_mutex);
+ write(output_fd, msg, strlen(msg));
+ pthread_mutex_unlock(&log_mutex);
+ //unlock
+ break;
+ }
+}
+

void print_data(char *mystrin, struct inotify_event *event, const char
*event_fpath, struct stat *statdat, struct diffprint *dprint) {

@@ -53,11 +143,15 @@
char fpath[ELEMENT_SIZE * 2] = {0};
char *freeme;

+ char buffer[BUF_LEN];
+ int index=0;
+
const char *const normal = "\033[0m";
const char *const marked = "\033[1;31m";

time_t currtime;

+ memset(buffer, 0, BUF_LEN);
snprintf(fpath, (ELEMENT_SIZE * 2), "%s%s", event_fpath, event->name);

mystrin_tmp = strdup(mystrin);
@@ -67,63 +161,65 @@
mychar = mystr[0];

switch(mychar) {
- case 'f': printf("%s", event->name);
+ case 'f': add2buf(buffer,index, "%s", event->name);
break;
- case 'p': printf("%s", event_fpath);
+ case 'p': add2buf(buffer,index,"%s", event_fpath);
break;
case 'd': memset(desc_ptr, 0, 128 * sizeof(char));
- printf("%s", get_event_desc(event->mask, desc_ptr));
+ add2buf(buffer,index,"%s", get_event_desc(event->mask,
desc_ptr));
break;
- case 'w': printf("%i", event->wd);
+ case 'w': add2buf(buffer,index,"%i", event->wd);
break;
- case 'c': printf("%u", event->cookie);
+ case 'c': add2buf(buffer,index,"%u", event->cookie);
break;
- case 'm': printf("0x%08x", event->mask);
+ case 'm': add2buf(buffer,index,"0x%08x", event->mask);
break;
- case 'l': printf("%u", event->len);
+ case 'l': add2buf(buffer,index,"%u", event->len);
break;
case 't': memset(desc_ptr, 0, 128 * sizeof(char));
- printf("%s", gettype(fpath, desc_ptr, statdat));
+ add2buf(buffer,index,"%s", gettype(fpath, desc_ptr,
statdat));
break;
/* yeah, i know, thats some kind of dirty style ;)
but i dont like the additional newline at EOL... */
case 'A': ctp = ctime(&statdat->st_atime); ctp[strlen(ctp) - 1]
= '\0';
- (dprint->A == 1)?printf("%s%s%s", marked, ctp,
normal):printf("%s", ctp);
+ (dprint->A == 1)?add2buf(buffer,index,"%s%s%s",
marked, ctp, normal):add2buf(buffer,index,"%s", ctp);
break;
case 'M': ctp = ctime(&statdat->st_mtime); ctp[strlen(ctp) - 1]
= '\0';
- (dprint->M == 1)?printf("%s%s%s", marked, ctp,
normal):printf("%s", ctp);
+ (dprint->M == 1)?add2buf(buffer,index,"%s%s%s",
marked, ctp, normal):add2buf(buffer,index,"%s", ctp);
break;
case 'S': ctp = ctime(&statdat->st_ctime); ctp[strlen(ctp) - 1]
= '\0';
- (dprint->S == 1)?printf("%s%s%s", marked, ctp,
normal):printf("%s", ctp);
+ (dprint->S == 1)?add2buf(buffer,index,"%s%s%s",
marked, ctp, normal):add2buf(buffer,index,"%s", ctp);
break;
case 'T': currtime = time(NULL);
ctp = ctime(&currtime); ctp[strlen(ctp) - 1] = '\0';
- printf("%s", ctp);
+ add2buf(buffer,index,"%s", ctp);
break;
- case 's': (dprint->s == 1)?printf("%s%lld%s", marked, (long long
int) statdat->st_size, normal):printf("%lld", (long long int)
statdat->st_size);
+ case 's': (dprint->s == 1)?add2buf(buffer,index,"%s%lld%s",
marked, (long long int) statdat->st_size,
normal):add2buf(buffer,index,"%lld", (long long int) statdat->st_size);
break;
- case 'U': (dprint->U == 1)?printf("%s%ld%s", marked, (long int)
statdat->st_uid, normal):printf("%ld", (long int) statdat->st_uid);
+ case 'U': (dprint->U == 1)?add2buf(buffer,index,"%s%ld%s",
marked, (long int) statdat->st_uid, normal):add2buf(buffer,index,"%ld",
(long int) statdat->st_uid);
break;
- case 'G': (dprint->G == 1)?printf("%s%ld%s", marked, (long int)
statdat->st_gid, normal):printf("%ld", (long int) statdat->st_gid);
+ case 'G': (dprint->G == 1)?add2buf(buffer,index,"%s%ld%s",
marked, (long int) statdat->st_gid, normal):add2buf(buffer,index,"%ld",
(long int) statdat->st_gid);
break;
- case 'O': (dprint->O == 1)?printf("%s%lo%s", marked, (unsigned
long int) statdat->st_mode, normal):printf("%lo", (unsigned long int)
statdat->st_mode);
+ case 'O': (dprint->O == 1)?add2buf(buffer,index,"%s%lo%s",
marked, (unsigned long int) statdat->st_mode,
normal):add2buf(buffer,index,"%lo", (unsigned long int) statdat->st_mode);
break;
- case 'I': (dprint->I == 1)?printf("%s%ld%s", marked, (long int)
statdat->st_ino, normal):printf("%ld", (long int) statdat->st_ino);
+ case 'I': (dprint->I == 1)?add2buf(buffer,index,"%s%ld%s",
marked, (long int) statdat->st_ino, normal):add2buf(buffer,index,"%ld",
(long int) statdat->st_ino);
break;
- case 'D': (dprint->D == 1)?printf("%s%ld%s", marked, (long int)
statdat->st_dev, normal):printf("%ld", (long int) statdat->st_dev);
+ case 'D': (dprint->D == 1)?add2buf(buffer,index,"%s%ld%s",
marked, (long int) statdat->st_dev, normal):add2buf(buffer,index,"%ld",
(long int) statdat->st_dev);
break;
- default : printf("%c", mychar);
+ default : add2buf(buffer,index,"%c", mychar);
break;
}
}else{
- printf("%s", mystr);
+ add2buf(buffer,index,"%s", mystr);
}

freeme = mystrin_tmp;
mystrin_tmp = NULL;
}

- printf("\n");
+ add2buf(buffer,index,"\n");
+
+ write_log(buffer);

free(freeme);
}

Modified: trunk/src/output.h
==============================================================================
--- trunk/src/output.h (original)
+++ trunk/src/output.h Sat Feb 21 08:51:16 2009
@@ -33,11 +33,27 @@

#include <sys/stat.h>
#include <sys/inotify.h>
+#include <syslog.h>

#ifndef DELIM
#define DELIM ","
#endif

+ #ifndef SYSLOG
+ #define SYSLOG -1
+ #endif
+ #ifndef STDOUT
+ #define STDOUT -2
+ #endif
+ #ifndef LOGFILE
+ #define LOGFILE -3
+ #endif
+
void print_data(char *mystrin, struct inotify_event *event, const char
*event_fpath, struct stat *statdat, struct diffprint *dprint);
+
+int init_log(int mode, char *arg);
+void rotate_log();
+
+#define add2buf(buf,index,format, arg...) ( index+=sprintf(buf+index,
format, ## arg) )

#endif

Reply all
Reply to author
Forward
0 new messages