]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Some rewriting inspired by suggestions of overflow bugs and other problems
authorwessels <>
Thu, 20 Jun 2002 04:54:14 +0000 (04:54 +0000)
committerwessels <>
Thu, 20 Jun 2002 04:54:14 +0000 (04:54 +0000)
with this code.

denyusers.c and allowusers.c have a fair amount of nearly identical code.
I moved these functions to a new file, called usersfile.[ch].  I didn't
really want to add another source file, but....

helpers/basic_auth/MSNT/usersfile.c [new file with mode: 0644]
helpers/basic_auth/MSNT/usersfile.h [new file with mode: 0644]

diff --git a/helpers/basic_auth/MSNT/usersfile.c b/helpers/basic_auth/MSNT/usersfile.c
new file mode 100644 (file)
index 0000000..1964129
--- /dev/null
@@ -0,0 +1,193 @@
+
+/*
+ * usersfile.c
+ * (C) 2000 Antonino Iannella, Stellar-X Pty Ltd
+ * Released under GPL, see COPYING-2.0 for details.
+ * 
+ * These routines are to allow users attempting to use the proxy which
+ * have been explicitly allowed by the system administrator.
+ * The code originated from denyusers.c.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <time.h>
+#include <ctype.h>
+#include <sys/param.h>
+#include <fcntl.h>
+
+#include "usersfile.h"
+
+#define NAMELEN     50         /* Maximum username length */
+
+static int
+name_cmp(const void *a, const void *b)
+{
+    const char *A = a;
+    const char *B = b;
+    return strcasecmp(A, B);
+}
+
+static void
+free_names(usersfile * uf)
+{
+    int i;
+    for (i = 0; i < uf->Inuse; i++) {
+       if (uf->names[i])
+           free(uf->names[i]);
+       uf->names[i] = NULL;
+    }
+    uf->Inuse = 0;
+}
+
+/*
+ * Reads a file of usernames and stuffs them into an array
+ * of strings.
+ * Returns 0 if the user list was successfully loaded,
+ * and 1 in case of error.
+ */
+
+int
+Read_usersfile(const char *path, usersfile * uf)
+{
+    FILE *fp;
+    struct stat FileBuf;
+    char buf[1024];
+
+    free_names(uf);
+
+    if (NULL == path) {
+       path = uf->path;
+    } else {
+       if (uf->path)
+           free(uf->path);
+       uf->path = strdup(path);
+    }
+
+    /* Open the users file. Report any errors. */
+    fp = fopen(path, "r");
+    if (NULL == fp) {
+       uf->LMT = 0;
+       if (errno == ENOENT)
+           return 0;
+       syslog(LOG_ERR, "%s: %s", path, strerror(errno));
+       return 1;
+    }
+    /* Stat the file. If it does not exist, save the size as zero.
+     * Clear the allowed user string. Return. */
+    if (fstat(fileno(fp), &FileBuf) < 0) {
+       syslog(LOG_ERR, "%s: %s", path, strerror(errno));
+       return 1;
+    }
+    /* If it exists, save the modification time and size */
+    uf->LMT = FileBuf.st_mtime;
+
+    /* Handle the special case of a zero length file */
+    if (FileBuf.st_size == 0)
+       return 0;
+
+    /*
+     * Read the file into memory
+     * XXX assumes one username per input line
+     */
+    while (fgets(buf, 1024, fp) != NULL) {
+       /* ensure no names longer than our limit */
+       buf[NAMELEN] = '\0';
+       /* skip bad input lines */
+       if (NULL == strtok(buf, "\r\n"))
+           continue;
+       /* grow the list if necessary */
+       if (0 == uf->Alloc) {
+           uf->Alloc = 256;
+           uf->names = calloc(uf->Alloc, sizeof(*uf->names));
+       } else if (uf->Inuse == uf->Alloc) {
+           uf->Alloc = uf->Alloc << 1;
+           uf->names = realloc(uf->names, uf->Alloc);
+           /* zero out the newly allocated memory */
+           memset(uf->names[uf->Alloc >> 1],
+               '\0',
+               (uf->Alloc >> 1) * sizeof(*uf->names));
+       }
+       uf->names[uf->Inuse] = strdup(buf);
+       uf->Inuse++;
+    }
+    fclose(fp);
+    fp = NULL;
+
+    /* sort the names for searching */
+    qsort(uf->names, uf->Inuse, sizeof(*uf->names), name_cmp);
+
+    return 0;
+}
+
+/*
+ * Check to see if the username provided by Squid appears in the
+ * user list. Returns 0 if the user was not found, and 1 if they were.
+ */
+
+int
+Check_userlist(usersfile * uf, char *User)
+{
+    void *p;
+
+    /* Empty users are always in the list */
+    if (User[0] == '\0')
+       return 1;
+
+    /* If allowed user list is empty, allow all users.
+     * If no users are supposed to be using the proxy, stop squid instead. */
+    if (0 == uf->Inuse)
+       return 1;
+
+    /* Check if username string is found in the allowed user list.
+     * If so, allow. If not, deny. Reconstruct the username
+     * to have whitespace, to avoid finding wrong string subsets. */
+
+    p = bsearch(User,
+       uf->names,
+       uf->Inuse,
+       sizeof(*uf->names),
+       name_cmp);
+    if (NULL == p) {
+       syslog(LOG_DEBUG, "User %s not found", User);
+       return 0;
+    }
+    syslog(LOG_DEBUG, "User %s found", User);
+    return 1;
+}
+
+/*
+ * Checks if there has been a change in a users file.
+ * If the modification time has changed, then reload the user list.
+ */
+void
+Check_forfilechange(usersfile * uf)
+{
+    struct stat ChkBuf;                /* Stat data buffer */
+
+    /* Stat the allowed users file. If it cannot be accessed, return. */
+
+    if (stat(uf->path, &ChkBuf) < 0) {
+       if (errno == ENOENT) {
+           uf->LMT = 0;
+           free_names(uf);
+       } else {                /* Report error when accessing file */
+           syslog(LOG_ERR, "%s: %s", uf->path, strerror(errno));
+       }
+       return;
+    }
+    /* return if no change */
+    if (ChkBuf.st_mtime == uf->LMT)
+       return;
+
+    /*
+     * The file changed, so re-read it.
+     */
+    syslog(LOG_INFO, "Check_forchange: Reloading user list.");
+    Read_usersfile(NULL, uf);
+}
diff --git a/helpers/basic_auth/MSNT/usersfile.h b/helpers/basic_auth/MSNT/usersfile.h
new file mode 100644 (file)
index 0000000..7413a65
--- /dev/null
@@ -0,0 +1,15 @@
+
+
+typedef struct {
+    char *path;
+    char **names;
+    int Alloc;
+    int Inuse;
+    time_t LMT;
+} usersfile;
+
+
+
+int Read_usersfile(const char *path, usersfile * uf);
+int Check_userlist(usersfile * uf, char *User);
+void Check_forfilechange(usersfile * uf);