📄 stormwall.c
字号:
/** This file is part of Firestorm NIDS* Copyright (c) 2002 Gianni Tedesco* This program is released under the terms of the GNU GPL version 2** This is the stormwall daemon, it wakes up when firestorm tells it,* and it sends files off to a central server or whatever.*/#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <fcntl.h>#include <sys/stat.h>#include <getopt.h>#include <dirent.h>#include <syslog.h>#include <netdb.h>#include <sys/socket.h>#ifndef _BSD_SOURCE#define _BSD_SOURCE#endif#include <grp.h>#include <strtouint.h>#include <stormwall.h>/* Action flags */#define SWA_ROTATE (1<<0)/* Filename */static char fifo_fn[]="log/.stormwall";static char log_dir[]="log";/* Our current PID */pid_t my_pid;/* Our fifo */int fifo_fd=-1;/* Remote log host */struct sockaddr_in sa;int s=-1;/* Rotate a log file */void rotate_one_file(char *fn){ syslog(LOG_DEBUG, "(todo)rotate: %s", fn);#if 0 /* We are finished with this file now so delete it */ if ( unlink(fn) ) { syslog(LOG_ERR, "%s: unlink(): %m", fn); /* bad shit will happen... */ }#endif}/* Scan the log directory for new files */void rotate_logs(){ DIR *d; struct dirent *f; char fn[1024]; if ( !(d=opendir(log_dir)) ) { syslog(LOG_ERR, "%s: opendir(): %m", log_dir); return; } while( (f=readdir(d)) ) { if ( f->d_name[0]!='@' ) continue; if ( snprintf(fn , sizeof(fn), "%s/%s", log_dir, f->d_name)>0 ) { rotate_one_file(fn); }else{ syslog(LOG_ERR, "%s: path overflow", log_dir); } } closedir(d);}static inline void action_dispatch(unsigned long a){ if ( a & SWA_ROTATE ) rotate_logs();}/* Open the communications pipe, sleep until someone opens it */void open_fifo(void){ /* Sleep waiting for a writer */ if ( (fifo_fd=open(fifo_fn, O_RDONLY))<0 ) { syslog(LOG_ERR, "%s: open(): %m", fifo_fn); }}/* Process fifo messages untill last writer closes */void wait_fifo(void){ unsigned long actions; unsigned char buf[512]; int ret, i; if ( fifo_fd<0 ) { /* Stops us running away with CPU */ usleep(500000); return; }readloop: actions=0; ret=read(fifo_fd, (char *)buf, sizeof(buf)); /* There was an error */ if ( ret<0 ) { syslog(LOG_ERR, "%s: read(): %m", fifo_fn); close(fifo_fd); return; } /* The last writer closed, never mind */ if ( ret==0 ) { syslog(LOG_INFO, "All firestorm daemons are dead"); close(fifo_fd); return; } /* See what we were asked to do */ for(i=0; i<ret; i++) { switch(buf[i]) { case STORMWALL_ROTATE: actions|=SWA_ROTATE; break; default: syslog(LOG_INFO, "unknown code (%u)", buf[i]); break; } } action_dispatch(actions); goto readloop;}void stormwall_background(void){ switch(fork()) { case 0: break; case -1: syslog(LOG_ERR, "fork(): %m"); default: _exit(0); } if (setsid()<0) { syslog(LOG_ERR, "setsid(): %m"); } switch(fork()) { case 0: break; case -1: syslog(LOG_ERR, "fork(): %m"); default: _exit(0); }}int main(int argc, char **argv){ int c,opti; uid_t uid=0; gid_t gid=0; char *root_dir=NULL; struct option opts[]={ {"uid", 1, 0, 'u'}, {"gid", 1, 0, 'g'}, {"root", 1, 0, 'r'}, {NULL, 0, 0, 0} }; /* Open up syslog connection */ openlog("stormwall", LOG_DAEMON, 0); /* Parse the command line arguments */ while( (c=getopt_long(argc,argv,"u:g:r:", (const struct option *)&opts, &opti))!=-1 ) { switch (c) { case 'u': if ( strtouint(optarg,&uid) ) goto err; break; case 'g': if ( strtouint(optarg,&gid) ) goto err; break; case 'r': root_dir=optarg; break; default: goto err; } } if ( !root_dir ) goto err; /* Change in to the root directory */ if ( chdir(root_dir) ) { syslog(LOG_ERR, "%s: chdir(): %m", root_dir); exit(1); } if ( geteuid() ) { syslog(LOG_WARNING, "warning: cannot chroot, im not root"); }else{ /* Chroot */ if ( chroot(".") ) { syslog(LOG_ERR, "%s: chroot(): %m", root_dir); exit(1); } if ( uid==0 || gid==0 ) { syslog(LOG_ERR, "I will NOT run as root you moron!"); exit(1); } /* Drop root privileges */ if ( setgroups(1,&gid)==-1 || setgid(gid)==-1 ) { syslog(LOG_ERR, "unable to drop gid to %u: %m", gid); exit(1); } if ( setuid(uid) == -1 ) { syslog(LOG_ERR, "unable to drop uid to %u: %m", uid); exit(1); } } /* Fork off! */ stormwall_background(); /* Never fails */ my_pid=getpid(); /* Open straight away, don't want firestorm * to wait while we upload the last lot of logs */ open_fifo(); /* Rotate any logs left over from last time */ rotate_logs(); /* Back to the grind */ for(;;) { wait_fifo(); open_fifo(); } /* not reached */ closelog(); exit(0);err: syslog(LOG_ERR, "Bad arguments: %s should not " "be run by hand", argv[0]); exit(1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -