/******************************************************************** * $Author: jgoerzen $ * $Revision: 1.2 $ * $Date: 2000/12/20 01:19:20 $ * $Source: /var/cvs/gopher/gopherd/site.c,v $ * $State: Exp $ * * Paul Lindner, University of Minnesota CIS. * * Copyright 1991, 1992 by the Regents of the University of Minnesota * see the file "Copyright" in the distribution for conditions of use. ********************************************************************* * MODULE: site.c * Routines to build up a table of hostnames and access levels ********************************************************************* * Revision History: * $Log: site.c,v $ * Revision 1.2 2000/12/20 01:19:20 jgoerzen * Added patches from David Allen * * Revision 1.1.1.1 2000/08/19 00:28:56 jgoerzen * Import from UMN Gopher 2.3.1 after GPLization * * Revision 3.12 1995/09/25 05:02:39 lindner * Convert to ANSI C * * Revision 3.11 1995/02/17 23:15:30 lindner * Fix for access: lines * * Revision 3.10 1995/02/02 17:13:55 lindner * Fix memory leaks * * Revision 3.9 1994/07/22 22:56:20 lindner * More NO_AUTH stuff.. * * Revision 3.8 1994/07/22 22:25:51 lindner * NO_AUTHENTICATION mods * * Revision 3.7 1994/07/19 20:24:12 lindner * Use local Locale.h * * Revision 3.6 1994/05/02 07:41:15 lindner * Mods to use setlocale() * * Revision 3.5 1994/03/17 21:18:24 lindner * Massive reworking of access limits * * Revision 3.4 1994/03/17 04:27:49 lindner * Additions for maxsessions * * Revision 3.3 1993/08/20 18:03:14 lindner * Mods to allow gopherd.conf files control ftp gateway access * * Revision 3.2 1993/07/27 05:27:57 lindner * Mondo Debug overhaul from Mitra * * Revision 3.1.1.1 1993/02/11 18:02:53 lindner * Gopher+1.2beta release * * Revision 1.2 1993/02/09 22:29:23 lindner * added util.h to includes * * Revision 1.1 1992/12/10 23:13:27 lindner * gopher 1.1 release * * *********************************************************************/ #ifndef NO_AUTHENTICATION #include "site.h" #include "Malloc.h" #include "Locale.h" #include #include "util.h" #include "Debug.h" static Site * SiteNew() { Site *temp; temp = (Site *) malloc(sizeof(Site)); if (temp == NULL) return(NULL); temp->domain = STRnew(); STRinit(temp->domain); SITEsetLevel(temp, ACC_FULL); SITEsetisnum(temp, FALSE); SITEsetmaxsessions(temp, -1); return(temp); } static void SiteDestroy(Site *site) { STRdestroy(site->domain); free(site); } static void Sitecpy(Site *site1, Site *site2) { STRcpy(site1->domain, site2->domain); site1->Level = site2->Level; site1->isnum = site2->isnum; site1->maxsessions = site2->maxsessions; } static void SiteSet(Site *site, char *dom, Accesslevel access, int maxsess) { STRset(site->domain, dom); site->Level = access; if (isdigit(*dom)) site->isnum = TRUE; else site->isnum = FALSE; site->maxsessions = maxsess; } /******************************************************/ SiteArray * SiteArrayNew() { SiteArray *temp; temp = DAnew(20, SiteNew, NULL, SiteDestroy, Sitecpy); return(temp); } static void SiteArrayAdd(SiteArray *sitearr, char *name, Accesslevel Level, int sessions) { Site *temp; temp = SiteNew(); SiteSet(temp, name, Level, sessions); SiteArrPush(sitearr, temp); SiteDestroy(temp); return; } /* * Find the default access level */ Accesslevel SiteDefAccess(SiteArray *sitearr) { int i; Site *temp; for (i=0; i< DAgetTop(sitearr); i++) { temp = SiteArrgetEntry(sitearr, i); if (strcmp(SITEgetDomain(temp), "default") == 0) return(SITEgetLevel(temp)); } return(ACC_UNKNOWN); } /* * Tries to find a match in sitearr for "hostname" or ipnum, then tests the * accesslevel against "mask". * * If it finds it, it returns the result of the search * * If it doesn't it tests agains the "default" item * */ AccessResult SiteAccess( SiteArray *sitearr, char *hostname, char *ipnum, Accesslevel mask, int sessions) { int i; Site *temp=(Site *)NULL; Accesslevel defaccess = ACC_FULL, level; int defmaxsess = -1; int maxsess; if (hostname == NULL && ipnum == NULL) /*** ??? We need to compare *something* ***/ return(SITE_UNDEF); for (i=0; i< DAgetTop(sitearr); i++) { temp = SiteArrgetEntry(sitearr, i); Debug("Testing for %s\n", STRget(temp->domain)); if (strcmp(SITEgetDomain(temp), "default") == 0) { defaccess = SITEgetLevel(temp); defmaxsess = SITEmaxsessions(temp); } else if (SITEisnum(temp) == TRUE) { /*** Check for a match with the domain name from the beginning ***/ int iplen, domainlen; iplen = strlen(ipnum); domainlen = strlen(STRget(temp->domain)); if (iplen >domainlen) iplen = domainlen; if (strncmp(ipnum, SITEgetDomain(temp), iplen) == 0) { break; } } else { /*** Check for a match from the end ***/ /*** It's a domain name, not an ip number ***/ int namelen, domainlen; namelen = strlen(hostname); domainlen = strlen(SITEgetDomain(temp)); /*** don't compare if incoming name is shorter than domain ***/ if (domainlen <= namelen) if (strcasecmp((hostname+namelen-domainlen), SITEgetDomain(temp))==0) break; } } if (i == DAgetTop(sitearr)) { /*** Hmmm, didn't find a match, return "default" val ***/ level = defaccess; maxsess = defmaxsess; } else { /** Otherwise we found a match.. **/ level = SITEgetLevel(temp); maxsess = SITEmaxsessions(temp); } if (sessions > 0) { if (maxsess < sessions && maxsess > 0) return(SITE_TOOBUSY); } if ((level & mask) == mask) return(SITE_OK); else return(SITE_NOACCESS); } /* * process a site description line. */ boolean SiteProcessLine(SiteArray *sitearr, char *inputline, Accesslevel defaccess) { char name[256]; char *namep = name; Accesslevel level = defaccess; int maxsess = 0; /*** the first word is the domain/ip# ***/ while (*inputline == ' ' || *inputline == '\t') inputline++; while (*inputline != ' ' && *inputline != '\t') { *namep = *inputline; namep++; inputline++; } *namep = '\0'; /*** Terminate it ***/ if (namep == name) return(FALSE); /*** bad line ***/ while (*inputline != '\0') { if (*inputline == ' ' || *inputline == '\t' || *inputline == ',') { inputline++; if (*inputline == '!') inputline++; switch (*inputline) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': /** Maxsessions **/ while (*inputline <= '9' && '0' <= *inputline) { maxsess = maxsess * 10 + (*inputline - '0'); inputline++; } break; case 'b': /** Browse **/ if (*(inputline -1) == '!') level &= (ACC_SEARCH | ACC_READ | ACC_FTP); else level |= ACC_BROWSE; break; case 'r': /*** Read ***/ if (*(inputline -1) == '!') level &= (ACC_BROWSE | ACC_SEARCH | ACC_FTP); else level |= ACC_READ; break; case 's': /*** Search ***/ if (*(inputline -1) == '!') level &= (ACC_BROWSE | ACC_READ | ACC_FTP); else level |= ACC_SEARCH; break; case 'f': /*** FTP ***/ if (*(inputline -1) == '!') level &= (ACC_BROWSE | ACC_READ | ACC_SEARCH); else level |= ACC_FTP; break; } } else inputline++; } SiteArrayAdd(sitearr, name, level, maxsess); return(TRUE); } #else #endif