/***************************************************************************/ /* Module: $Id: readconfig.c,v 1.3 1999/05/07 04:15:26 maf Exp $ /* Description: readconfiguration file. /* Author: maf /* Notes: /***************************************************************************/ /* $Log: */ /* # KarlBridge remote authentication configuration file. # lines with the first non white space character a # are ignored # \ can be used as a continuation character. # \H can be used to represent the client host in the src IP or dst IP fields # authorization record format: # lrange, hrange, src IP, dst IP, dst IP mask, timeout, bridge IP, \ # bridge community, service name # # example: # # Hagerty Hall Public Labs (KarlBridge @ 128.146.109.252) # 128.146.81.2,128.146.81.250, \H, 0.0.0.0, 0.0.0.0, 30, 128.146.109.252, \ # public, Off Campus Access # # Osu Campus Only CD-ROM server (128.146.4.99) (KarlBridge @ 128.146.4.252) # 128.146.0.0,128.146.255.255, 128.146.4.99, \H, 255.255.255.255, 30, \ # 128.146.4.252, public, Current Publications CD-ROM Database # */ #include #include "kbauth.h" #include #include #include #include #include ReadConfigFile(db, fname) struct KbRemAuthDatabase *db; char *fname; { FILE *FP; char buf[MAXCONFIGLINE], tmpBuf[MAXCONFIGLINE]; char *p, *bufPtr; int err, recNo, lineNo, eolFlag, contFlag, longLineFlag, x; err = 0; FP = NULL; recNo = 0; contFlag = 0; lineNo = 0; if (!(FP = fopen(fname, "r"))) { perror(fname); err = 1; goto ReadConfigFileout; } while (!feof(FP)) { if (contFlag) { if (!fgets(tmpBuf, MAXCONFIGLINE, FP)) goto cont1; /* \ on prev line, this line was blank */ bufPtr = tmpBuf; } else { if (!fgets(buf, MAXCONFIGLINE, FP)) continue; /* implicit exit from loop */ bufPtr = buf; ++lineNo; } /* make sure this line ended in eol */ eolFlag = 0; for (p = bufPtr; *p; ++p) if ((*p == '\n') || (*p == '\r')) { *p = 0; eolFlag = 1; break; } /* ignore all leading white space, note this is after the eol check so it will work */ for (; isspace((int)*bufPtr); ++bufPtr); /* short circuit for blank lines */ if (eolFlag && (!contFlag) && (!bufPtr[0])) continue; /* if this is a continuation line, add it on the end */ if (contFlag) { if ((strlen(buf) + strlen(bufPtr) + 1) > MAXCONFIGLINE) longLineFlag = 1; else { strcat(buf, tmpBuf); longLineFlag = 0; } } /* check for lines too long */ if ((!eolFlag && !feof(FP)) || (contFlag && longLineFlag)) { fprintf(stderr, "%s, line %d too long\n", fname, lineNo); err = 1; goto ReadConfigFileout; } /* ignore comment lines (note, must be after too long check) */ if (buf[0] == '#') continue; cont1: /* lines that end with a \ need to be joined with the next line */ x = strlen(buf); if (!x) x = 1; --x; if (buf[x] == '\\') { contFlag = 1; buf[x] = 0; continue; } else contFlag = 0; /* final check for blank line */ if (!buf[0]) continue; /* Parse the line */ p = buf; /* make sure there are records left to be filled */ if (recNo >= MAXAUTHRECORDS) { fprintf(stderr, "Maximum authentication records (%d) exceeded.\n", (int)MAXAUTHRECORDS); err = 1; goto ReadConfigFileout; } /* lrange */ if (GetField(&p, tmpBuf, "lrange", lineNo)) { err = 1; goto ReadConfigFileout; } db[recNo].ipLow = htonl((u_long)inet_addr(tmpBuf)); /* hrange */ if (GetField(&p, tmpBuf, "hrange", lineNo)) { err = 1; goto ReadConfigFileout; } db[recNo].ipHigh = htonl((u_long)inet_addr(tmpBuf)); /* srcIP */ if (GetField(&p, tmpBuf, "srcIP", lineNo)) { err = 1; goto ReadConfigFileout; } if (!strcmp(tmpBuf, "\\H")) db[recNo].srcIP = 0xFFFFFFFF; else db[recNo].srcIP = htonl((u_long)inet_addr(tmpBuf)); /* dstIP */ if (GetField(&p, tmpBuf, "dstIP", lineNo)) { err = 1; goto ReadConfigFileout; } if (!strcmp(tmpBuf, "\\H")) db[recNo].dstIP = 0xFFFFFFFF; else db[recNo].dstIP = htonl((u_long)inet_addr(tmpBuf)); /* dstIPMask */ if (GetField(&p, tmpBuf, "dstIPMask", lineNo)) { err = 1; goto ReadConfigFileout; } db[recNo].dstIPMask = htonl((u_long)inet_addr(tmpBuf)); /* timeout */ if (GetField(&p, tmpBuf, "timeout", lineNo)) { err = 1; goto ReadConfigFileout; } db[recNo].timeOut = (u_long)atol(tmpBuf); /* bridgeIP */ if (GetField(&p, tmpBuf, "bridgeIP", lineNo)) { err = 1; goto ReadConfigFileout; } db[recNo].bridgeIP = htonl((u_long)inet_addr(tmpBuf)); /* bridgeCommunity */ if (GetField(&p, tmpBuf, "bridgeCommunity", lineNo)) { err = 1; goto ReadConfigFileout; } if (strlen(tmpBuf) > MAXCOMMUNITYNAME) { fprintf(stderr, "Community name (line %d) is too long\n", lineNo); err = 1; goto ReadConfigFileout; } strcpy(db[recNo].bridgeCommunity, tmpBuf); /* serviceName is rest of line */ for (; isspace((int)*p); ++p); if (strlen(p) > MAXSERVICENAME) { fprintf(stderr, "Field serviceName (line %d) is too long\n", lineNo); err = 1; goto ReadConfigFileout; } strcpy(db[recNo].serviceName, p); ++recNo; } /* while !feof() */ err = 0; /* good */ ReadConfigFileout: if (FP) fclose(FP); if (err) return err; else { db[recNo].ipLow = 0xFFFFFFFF; /* mark end */ return 0; /* good */ } } int GetField(c, buf, msg, lineNo) char **c, *buf, *msg; int lineNo; { char *p; int x; p = (char*)*c; /* easy deref */ buf[0] = 0; /* skip whitespace */ for (; isspace((int)*p); ++p); for (x = 0; *p && (*p != ','); ++x, ++p) buf[x] = *p; if (!buf[0]) { fprintf(stderr, "Field %s (line %d) is missing\n", msg, lineNo); return 1; } buf[x] = 0; *c = ++p; return 0; } /* GetField */