/****************************************/
/* 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>
#include <fcntl.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 found2=0;       /* found for target ALL */
    int field;	/* which field in a line we are on	*/
    int linecount;	/* line counter				*/
    char *ptr; 	/* plain ol' char pointer		*/
    char line[128];  /* for reading in a line from a file 	*/
    char tempstring[128]; /* temp char string		*/
    char target[4]="ALL"; /* what we are looking for 	*/
    FILE *fileptr;	/* file pointer for input file(s)	*/

    char *strptr = target;

    const char * tempfile =NULL;
    const char * shellcode=NULL;
    const char * header   =NULL;

    if (verbose >= 0)
    {
        printf(" Running checkhostsfiles module...\n");
    }

    if (verbose > 0)
    {
        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.
    */
    tempfile = "/tmp/lsat1.lsat";
    shellcode = "grep -v \\# /etc/hosts.allow >/tmp/lsat1.lsat";
    if ((dostuff(tempfile, 0, shellcode, 0)) < 0)
    {
	/* something went wrong */
	perror(" Creation of list failed.\n");
	return(-1);
    }
    
    /* there should be no "ALL:ALL" in here! */
    /* check for it...			 */

    /* open the file...			 */
    fileptr = fopen("/tmp/lsat1.lsat", "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(" Dust biting 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 */
		    /* there is an ALL:ALL in hosts.allow */
		    found = 1;
                }
                if (strstr(tempstring, target) != NULL)
                {
                    /* found match, 2nd filed, but not 1st. */
		    /* there is an allow all in hosts.allow */
		    found2 = 1;
                }
            }
            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);

    /* note dostuff will rm the tempfile */
    header = "Lines found in hosts.allow\nMake sure you wish to allow the following:\n";
    if ((dostuff(tempfile, filename, 0, header)) < 0)
    {
	/* something went wrong */
	perror(" Creation of list failed.");
	return(-1);
    }

    if (verbose > 0)
    {
        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.
    */
    shellcode = "grep -v \\# /etc/hosts.deny >/tmp/lsat1.lsat";
    if ((dostuff(tempfile, 0, shellcode, 0)) < 0)
    {
	/* something went wrong */
	perror(" Creation of list failed.");
	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/lsat1.lsat", "r");
    if (fileptr == NULL)
    {
        perror(" Error opening tmp file.\n");
        perror(" Error was in checkhostsfiles module.\n");
        return(-1);
    }

    /* reset flags... */
    found = 0;
    /* 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(" Dust biting 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 = 0, there is _no_ ALL:ALL */
    if (found == 0)
    {
 	header = "*****Did not find ALL:ALL in hosts.deny.\nLines found in hosts.deny:\n";
    }
    if (found == 1)
    {
        header = "*****ALL:ALL present in hosts.deny. Good.\nHere are the lines in hosts.deny:\n";
    }

    if ((dostuff(tempfile, filename, 0, header)) < 0)
    {
	/* something went wrong */
	perror(" Creation of list failed.");
	return(-1);
    }


    if (verbose > 0)
    {
        printf(" Finished module checkhostsfiles.\n");
    }

    return(0);
}
