00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #ifdef HAVE_CONFIG_H
00017 #include "config.h"
00018 #endif
00019 #include <stdio.h>
00020 #include <stdlib.h>
00021 #include <time.h>
00022 #include <string.h>
00023 #include <unistd.h>
00024 #include <sys/types.h>
00025 #include <sys/stat.h>
00026 #include <errno.h>
00027 #include "log.h"
00028 #include "strutil.h"
00029 #include "tail.h"
00030 #include "configfile.h"
00031
00032 typedef struct _ipinfo {
00033 char ip[32];
00034 int hitcount;
00035 int isdropped;
00036 time_t timein;
00037 } ipinfo_t;
00038
00039
00040 ipinfo_t *iplist = NULL;
00041 int ipcnt = 0;
00042 int ipDeleteFlag = 0;
00043
00047 int loadIpList(void) {
00048 struct stat _st, *s = &_st;
00049 int cnt;
00050 char * filename = NULL;
00051 FILE *f;
00052 if(filename == NULL)
00053 filename = confVarPath("iplist",&cnt);
00054 if(stat(filename,s) != 0) {
00055 writeLog("Cannot stat %s: %m",filename);
00056 return -1;
00057 }
00058 cnt = s->st_size / sizeof(ipinfo_t);
00059 if((iplist = malloc(s->st_size)) == NULL) {
00060 fprintf(stderr,"Cannot allocate space for iplist: %m\n");
00061 exit(-1);
00062 }
00063 if((f = fopen(filename,"r")) == NULL) {
00064 fprintf(stderr,"Cannot open iplist: %m\n");
00065 exit(-1);
00066 }
00067 fread(iplist,sizeof(ipinfo_t),cnt,f);
00068 fclose(f);
00069 ipcnt = cnt;
00070 return 0;
00071 }
00075 int writeIpList(void) {
00076 FILE *f;
00077 char *filename = NULL;
00078 int i;
00079 if(filename == NULL)
00080 filename = confVarPath("iplist",&i);
00081 if((f = fopen(filename,"w")) == NULL) {
00082 fprintf(stderr,"Cannot open iplist: %m\n");
00083 exit(-1);
00084 }
00085 fwrite(iplist,sizeof(ipinfo_t),ipcnt,f);
00086 fclose(f);
00087 return 0;
00088 }
00092 int deleteIp(char *ip) {
00093 int i;
00094 if((i = ipEntry(ip)) != -1) {
00095 bzero(iplist[i].ip,sizeof(iplist[i].ip));
00096 iplist[i].timein = (time_t)-1;
00097 ipDeleteFlag = 1;
00098 return 0;
00099 }
00100 return -1;
00101 }
00105 int compactIpList() {
00106 ipinfo_t *nlist;
00107 int i, ncnt = 0;
00108 if((nlist = calloc(sizeof(ipinfo_t),ipcnt)) == NULL) {
00109 writeLog("Cannot allocate space for compaction %m");
00110 return -1;
00111 }
00112 for(i = 0; i < ipcnt; i++)
00113 if(iplist[i].timein != -1)
00114 nlist[ncnt++] = iplist[i];
00115 if((nlist = realloc(nlist,(sizeof(ipinfo_t)*ncnt))) == NULL) {
00116 writeLog("Cannot allocate space for compaction %m");
00117 return -1;
00118 }
00119 free(iplist);
00120 iplist = nlist;
00121 ipDeleteFlag = 0;
00122 }
00126 int ipadd(char *ip) {
00127 ipinfo_t ipi;
00128 int ipn;
00129 strcpy(ipi.ip,ip);
00130 time(&ipi.timein);
00131 ipi.hitcount = 1;
00132 ipi.isdropped = 0;
00133 ipn = ipcnt++;
00134 if((iplist = realloc(iplist,(sizeof(ipinfo_t)*ipcnt))) == NULL) {
00135 writeLog("Cannot allocate ip member");
00136 return -1;
00137 }
00138 iplist[ipn] = ipi;
00139 writeIpList();
00140 return 0;
00141 }
00144 int ipEntry(char *ip) {
00145 int i;
00146 for(i = 0; i < ipcnt; i++)
00147 if(strcmp(iplist[i].ip,ip) == 0)
00148 return i;
00149 errno = ENOENT;
00150 return -1;
00151 }
00155 void incrementHitCount(char *ip) {
00156 int i;
00157 if((i = ipEntry(ip)) != -1)
00158 iplist[i].hitcount ++;
00159 else
00160 ipadd(ip);
00161 time(&iplist[i].timein);
00162 writeIpList();
00163 }
00168 void ipManage(void) {
00169 int i;
00170 time_t now;
00171 static int maxatt = -1;
00172 static int maxsecs = -1;
00173
00174 if(maxatt == -1)
00175 maxatt=confVarInt("maxatt",&i);
00176 if(maxsecs == -1)
00177 maxsecs = confVarInt("maxage",&i) * 60;
00178 time(&now);
00179 for(i = 0; i < ipcnt; i++) {
00180 if(iplist[i].isdropped == 0 && iplist[i].hitcount >= maxatt)
00181 dropIp(i);
00182 else if((now - iplist[i].timein) >= maxsecs)
00183 undropIp(i);
00184 }
00185 if(ipDeleteFlag)
00186 compactIpList();
00187 writeIpList();
00188 }
00193 char * replaceIp(char *buf, char *ip) {
00194 char *tmp, *p;
00195 int i;
00196 tmp = alloca(strlen(buf)+strlen(ip)+2);
00197 if((i = strpos(buf,"$i")) == -1)
00198 return NULL;
00199 p = &buf[i];
00200 p+= 2;
00201 strncpy(tmp,buf,i);
00202 strcat(tmp,ip);
00203 strcat(tmp,p);
00204 return strdup(tmp);
00205 }
00209 int dropIp(int ind) {
00210 ipinfo_t *ip = &iplist[ind];
00211 char * s;
00212 char ** dropRules = NULL;
00213 int i, x;
00214
00215 if(dropRules == NULL)
00216 dropRules = confVarFlist("fwreject",&i);
00217
00218 for(i = 0; i < count(dropRules); i++) {
00219 s = replaceIp(confVarText(dropRules[i],&x),ip->ip);
00220 system(s);
00221 free(s);
00222 }
00223 ip->isdropped = 1;
00224 time(&ip->timein);
00225 writeIpList();
00226 inform("secwatch dropped IP %s",ip->ip);
00227 return 0;
00228 }
00233 int undropIp(int ind) {
00234 ipinfo_t *ip = &iplist[ind];
00235 char * s;
00236 char ** allowRules = NULL;
00237 int i, x;
00238 if(allowRules == NULL)
00239 allowRules = confVarFlist("fwallow",&i);
00240 if(ip->isdropped) {
00241 for(i = 0; i < count(allowRules); i++) {
00242 s = replaceIp(confVarText(allowRules[i],&x),ip->ip);
00243 system(s);
00244 free(s);
00245 }
00246 ip->isdropped = 0;
00247 inform("secwatch undropped IP %s",ip->ip);
00248 time(&ip->timein);
00249 } else
00250 deleteIp(ip->ip);
00251 writeIpList();
00252 return 0;
00253 }