/****************************************/
/* This is the checkhostsfiles.c module */
/* for the lsat program. This module    */
/* reads the /etc/hosts.allow and       */
/* /etc/hosts.deny files.		*/
/* It checks for the existance of a 	*/
/* ALL:ALL line in deny, since we think */
/* that a good security policy would be */
/* only admit services we want and deny */
/* all others.				*/
/*					*/
/* See lsatmain.c for more details	*/
/****************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int checkhostsfiles(filename, verbose)
const char *const filename;
int verbose;
{

	int firstall=0; /* counter for target matches		*/
	int found=0;	/* found for target ALL:ALL		*/
	int field;	/* which field in a line we are on	*/
	int linecount;	/* line counter				*/
	char *ptr; 	/* plain ol' char pointer		*/
	char line[80];  /* for reading in a line from a file 	*/
	char tempstring[20]; /* temp char string		*/
	char target[4]="ALL"; /* what we are looking for 	*/
	FILE *outfile; /* file pointer for output file		*/
	FILE *fileptr;	/* file pointer for input file(s)	*/

	char *strptr = target;

	if (verbose == 1)
	{
		printf("In checkhostsfiles module...\n");
	}

	/* open the outfile for append	*/
	outfile = fopen(filename, "a");
	if (outfile == NULL)
	{
		perror("Error opening outfile!\n");
		perror("Check perms or something...\n");
		return(-1);
	}

	/* write a header for the outfile	*/
	fprintf(outfile, "\n");
	fprintf(outfile, "****************************************\n");

	if (verbose == 1)
	{
		printf("Checking list of entries in hosts.allow\n");
	}


	/* first off, get the entries in /etc/hosts.allow 	*/
	/* that are not comments...				*/
	/* note: grep returns
	*  0 on match
	*  1 on no match
	*  2 on system/file/read/other failure
	*  HOWEVER, -v inverts the sense of 0,1.
	*/
	if (system("grep -v \\# /etc/hosts.allow >> /tmp/greplist.txt") == 2)
	{
		perror("Problem executing grep in checkinetd\n");
		return(-1);
	}

	/* there should be no "ALL:ALL" in here! */
	/* check for it...			 */
	
	/* open the file...			 */
	fileptr = fopen("/tmp/greplist.txt", "r");
	if (fileptr == NULL)
	{
		perror("Error opening tmp file.\n");
		perror("Error was in checkhostsfiles module.\n");
		return(-1);
	}
	
	/* start getting lines from it		 */
	while (fgets(line, sizeof(line), fileptr) != NULL)
	{
		field=0;
		firstall=0;
		ptr = strtok(line, ", :\n");
		while (ptr != NULL)
		{
			/* note we want to check for:	*/
			/* a) any lines at all		*/
			/* b) ALL:ALL			*/
			/* c) <anything>:ALL		*/

			if (sscanf(ptr, "%s", &tempstring) < 1)
			{
				perror("sscanf bit the dust.\n");
				perror("Error was in checkhostsfiles.\n");
				return(-1);
			}
			/* check for now */
			printf("%s\n", tempstring);
			if (field == 0)
			{
				if ((strstr(tempstring, strptr)) != NULL)
				{
					/* found match, 1st field */
					firstall = 1;
				}
			}
			if (field == 1)
			{
				if (((strstr(tempstring, strptr)) != NULL) &&  (firstall ==1)) 
				{
					/* found match, 2nd filed */
					fprintf(outfile, "ALL:ALL found in hosts.allow.\n");
					fprintf(outfile, "Please delete that line!\n");
					fprintf(outfile, "This is a major security risk!\n");
					fprintf(outfile, "\n");
				}
				if (strstr(tempstring, target) != NULL)
                       		{
                                	/* found match, 2nd filed, but not 1st. */
                                	fprintf(outfile, "Found line in hosts.allow that is allowing ALL!\n");
                                	fprintf(outfile, "Please delete that line.\n");
                                	fprintf(outfile, "This is a major security risk!\n");
					fprintf(outfile, "\n");
                        	}
			}
			ptr = strtok(NULL, ", :\n");
			if (ptr == NULL)
			{	
				/* freak out */
				break;
			}
			field++;
		} /* end while(ptr!=NULL) */
	} /* end while(fgets...) */

	/* we have checked hosts.allow. Close open files */
	fclose(fileptr);
	/* rm the tempfile we were using		 */
	if ((system("rm -f /tmp/greplist.txt")) < 0)
	{
		/* rhut-rho... problems.. */
		perror("Can't rm tempfile...\n");
		perror("Permissions problem??\n");
		return(-1);
	}

	if (verbose == 1)
	{
		printf("Checking entries in hosts.deny\n");
	}

	/* now then, get the entries in /etc/hosts.deny         */
        /* that are not comments...                             */
        /* note: grep returns
        *  0 on match
        *  1 on no match
        *  2 on system/file/read/other failure
        *  HOWEVER, -v inverts the sense of 0,1.
        */
        if (system("grep -v \\# /etc/hosts.deny >> /tmp/greplist.txt") == 2)
        {
                perror("Problem executing grep in checkinetd\n");
                return(-1);
        }

	/* two things to check for:		*/
	/* a) this file should not be empty	*/
	/* b) it should contain ALL:ALL		*/
	
	/* open the tempfile...			*/
	fileptr = fopen("/tmp/greplist.txt", "r");
        if (fileptr == NULL)
        {
                perror("Error opening tmp file.\n");
                perror("Error was in checkhostsfiles module.\n");
                return(-1);
        }

	/* start getting lines from this file	*/
	linecount=0;
        while (fgets(line, sizeof(line), fileptr) != NULL)
        {
		ptr = strtok(line, ", \n");
                while (ptr != NULL)
                {
			if (sscanf(line, "%s", &tempstring) < 1)
			{
				perror("sscanf bit the dust.\n");
                                perror("Error was in checkhostsfiles.\n");
                                return(-1);
                        }
			if ((strstr(tempstring, "ALL:ALL")) != NULL)
			{
				/* found match, good */
				found = 1;
			}
			ptr = strtok(NULL, ", \n");
			if (ptr == NULL)
			{
				break;
			}
		} /* end while (ptr != NULL) */	
		linecount++;
	} /* end while(fgets...) */

	/* if found = 1, there is ALL:ALL */
	if (found == 1)
	{
		fprintf(outfile, "Found ALL:ALL in /etc/hosts.deny. Good.\n");
		fprintf(outfile, "\n");
	}
	if (found == 0)
	{
		fprintf(outfile, "Did not find a ALL:ALL line in /etc/hosts.deny.\n");
		fprintf(outfile, "Please place a line with the following in hosts.deny:\n");
		fprintf(outfile, "ALL:ALL\n");
		fprintf(outfile, "\nIf you need to allow services/hosts \n");
		fprintf(outfile, "do it in hosts.allow for each service/host.\n");
		fprintf(outfile, "\n");
	}
	/* print footer info into outfile... */
	fprintf(outfile, "****************************************\n");
	
	/* clean up */
	/* rm the tempfile we were using                 */
        if ((system("rm -f /tmp/greplist.txt")) < 0)
        {
                /* rhut-rho... problems.. */
                perror("Can't rm tempfile...\n");
                perror("Permissions problem??\n");
                return(-1);
        }
	fclose(outfile);

	if (verbose == 1)
	{
	 	printf("Finished module checkhostsfiles.\n");
	}

	return(0);
}
