diff -urwN squid-1.2.beta23pl3-0730/src/acl.c squid-1.2.beta23pl3/src/acl.c --- squid-1.2.beta23pl3-0730/src/acl.c Sat Aug 1 14:09:18 1998 +++ squid-1.2.beta23pl3/src/acl.c Mon Aug 3 00:02:08 1998 @@ -672,7 +672,7 @@ /* First time around, 7921 should be big enough */ if ((p->hash = hash_create((HASHCMP *) strcmp, 7921, hash_string)) < 0) { - debug(28, 0) ("aclParseProxyAuth: can't create hash table, turning auth off\n"); + debug(28, 0) ("aclParseProxyAuth: cannot create hash table, turning proxy_auth off\n"); *q = NULL; return; } @@ -1141,16 +1141,16 @@ strtok(sent_auth, "\n"); cleartext = uudecode(sent_auth); xfree(sent_auth); - debug(28, 3) ("aclMatchProxyAuth: cleartext = '%s'\n", cleartext); + debug(28, 6) ("aclMatchProxyAuth: cleartext = '%s'\n", cleartext); xstrncpy(sent_user, cleartext, USER_IDENT_SZ); xfree(cleartext); if ((passwd = strchr(sent_user, ':')) != NULL) *passwd++ = '\0'; if (passwd == NULL) { - debug(28, 3) ("aclMatchProxyAuth: No passwd in auth blob\n"); + debug(28, 1) ("aclMatchProxyAuth: no passwd in proxy authorization header\n"); return 0; } - debug(28, 5) ("aclMatchProxyAuth: checking user %s\n", sent_user); + debug(28, 5) ("aclMatchProxyAuth: checking user '%s'\n", sent_user); /* copy username to checklist for logging on client-side */ xstrncpy(checklist->request->user_ident, sent_user, USER_IDENT_SZ); @@ -1158,17 +1158,17 @@ u = hash_lookup(p->hash, sent_user); if (NULL == u) { /* user not yet known, ask external authenticator */ - debug(28, 4) ("aclMatchProxyAuth: user %s not yet known\n", sent_user); + debug(28, 4) ("aclMatchProxyAuth: user '%s' not yet known\n", sent_user); } else { /* user already known, check password with the cached one */ if ((0 == strcmp(u->passwd, passwd)) && (u->expiretime > current_time.tv_sec)) { - debug(28, 5) ("aclMatchProxyAuth: user %s previously validated\n", + debug(28, 5) ("aclMatchProxyAuth: user '%s' previously validated\n", sent_user); return 1; } /* password mismatch/timeout */ - debug(28, 4) ("aclMatchProxyAuth: user %s: passwords mismatch/timeout\n", + debug(28, 4) ("aclMatchProxyAuth: user '%s' password mismatch/timeout\n", sent_user); /* remove this user from the hash, making him unknown */ hash_remove_link(p->hash, (hash_link *) u); @@ -1176,7 +1176,6 @@ } /* we've got an unknown user now */ - if (checklist->auth_user == NULL) { /* we must still check this user's password */ u = memAllocate(MEM_ACL_PROXY_AUTH_USER); @@ -1185,20 +1184,20 @@ u->passwd_ok = 0; u->expiretime = 0; checklist->auth_user = u; - debug(28, 4) ("aclMatchProxyAuth: going to ask external authenticator\n"); + debug(28, 4) ("aclMatchProxyAuth: going to ask authenticator\n"); return -1; } /* checklist->auth_user has just been checked, check result */ if (checklist->auth_user->passwd_ok == -1) { /* password was checked but did not match */ - debug(28, 4) ("aclMatchProxyAuth: authentication failed for user %s\n", + debug(28, 4) ("aclMatchProxyAuth: authentication failed for user '%s'\n", sent_user); return 0; } /* checklist->auth_user->passwd_ok == 1, passwd check OK */ - debug(28, 5) ("aclMatchProxyAuth: user %s validated OK\n", sent_user); + debug(28, 4) ("aclMatchProxyAuth: user '%s' validated OK\n", sent_user); /* store validated user in hash, after filling in expiretime */ checklist->auth_user->expiretime = current_time.tv_sec + p->timeout; hash_join(p->hash, (hash_link *) checklist->auth_user); @@ -1379,7 +1378,7 @@ } else if (k == -1) { /* register that we need to check the password */ checklist->state[ACL_PROXY_AUTH] = ACL_PROXY_AUTH_CHECK; - return 0; /* XXX */ + return 0; } /* NOTREACHED */ case ACL_SNMP_COMM: @@ -1517,7 +1516,7 @@ aclCheckCallback(checklist, allow); return; } - /* XXX: checklist->state[ACL_PROXY_AUTH] == ACL_PROXY_AUTH_USED */ + /* checklist->state[ACL_PROXY_AUTH] == ACL_PROXY_AUTH_USED */ if (match) { debug(28, 3) ("aclCheck: match found, returning %d\n", allow); aclCheckCallback(checklist, allow); @@ -1599,7 +1598,7 @@ aclCheck_t *checklist = data; checklist->state[ACL_PROXY_AUTH] = ACL_LOOKUP_DONE; debug(28, 4) ("aclProxyAuthDone: result = %s\n", result); - if (result && strcmp(result, "OK") == 0) + if (result && (strncasecmp(result, "OK", 2) == 0)) checklist->auth_user->passwd_ok = 1; else checklist->auth_user->passwd_ok = -1; @@ -1614,7 +1613,7 @@ const char *ident) { int i; - aclCheck_t *checklist = xcalloc(1, sizeof(aclCheck_t)); /* XXX: freed? */ + aclCheck_t *checklist = xcalloc(1, sizeof(aclCheck_t)); cbdataAdd(checklist, MEM_NONE); checklist->access_list = A; /* diff -urwN squid-1.2.beta23pl3-0730/src/authenticate.c squid-1.2.beta23pl3/src/authenticate.c --- squid-1.2.beta23pl3-0730/src/authenticate.c Sat Aug 1 14:09:18 1998 +++ squid-1.2.beta23pl3/src/authenticate.c Sat Aug 1 14:18:30 1998 @@ -317,7 +317,9 @@ args[i++] = auth_opts->key; auth_opts = auth_opts->next; } - /* XXX: warn if too many arguments */ + if (auth_opts != NULL) { + debug(29, 0) ("WARNING: too many authenticate_options\n"); + } args[i] = NULL; x = ipcCreate(IPC_TCP_SOCKET, prg, @@ -353,7 +355,7 @@ first_time++; memset(&AuthenticateStats, '\0', sizeof(AuthenticateStats)); cachemgrRegister("authenticator", - "External Authenticator Stats", + "Authenticator Stats", authenticateStats, 0, 1); } safe_free(short_prg); @@ -378,12 +380,12 @@ authenticate = *(authenticate_child_table + k); if (!EBIT_TEST(authenticate->flags, HELPER_ALIVE)) continue; + if (EBIT_TEST(authenticate->flags, HELPER_CLOSING)) + continue; if (EBIT_TEST(authenticate->flags, HELPER_BUSY)) { na++; continue; } - if (EBIT_TEST(authenticate->flags, HELPER_CLOSING)) - continue; debug(29, 3) ("authenticateShutdownServers: closing authenticator #%d, FD %d\n", authenticate->index + 1, authenticate->fd); comm_close(authenticate->fd); @@ -411,10 +413,6 @@ continue; if (r->data != data) continue; -#if 0 - if (strcmp(r->orig_url, url)) - continue; -#endif debug(29, 3) ("authenticateUnregister: Found match\n"); r->handler = NULL; n++; @@ -424,10 +422,6 @@ continue; if (r->data != data) continue; -#if 0 - if (strcmp(r->orig_url, url)) - continue; -#endif debug(29, 3) ("authenticateUnregister: Found match.\n"); r->handler = NULL; n++; @@ -440,7 +434,7 @@ authenticateStats(StoreEntry * sentry) { int k; - storeAppendPrintf(sentry, "External Authenticator Statistics:\n"); + storeAppendPrintf(sentry, "Authenticator Statistics:\n"); storeAppendPrintf(sentry, "requests: %d\n", AuthenticateStats.requests); storeAppendPrintf(sentry, "replies: %d\n", @@ -453,7 +447,7 @@ NAuthenticators); storeAppendPrintf(sentry, "use histogram:\n"); for (k = 0; k < NAuthenticators; k++) { - storeAppendPrintf(sentry, " authenticator #%d: %d (%d rewrites)\n", + storeAppendPrintf(sentry, " authenticator #%d: %d (%d requests)\n", k + 1, AuthenticateStats.use_hist[k], AuthenticateStats.rewrites[k]); diff -urwN squid-1.2.beta23pl3-0730/src/cf.data.pre squid-1.2.beta23pl3/src/cf.data.pre --- squid-1.2.beta23pl3-0730/src/cf.data.pre Sat Aug 1 14:09:18 1998 +++ squid-1.2.beta23pl3/src/cf.data.pre Mon Aug 3 00:07:52 1998 @@ -949,7 +949,11 @@ DEFAULT: 5 LOC: Config.authenticateChildren DOC_START - The number of authenticate programs to spawn. + The number of authenticator processes to spawn (default 5). If you + start too few Squid will have to wait for them to process a backlog + of usercode/password verifications, slowing it down. When password + verifications are done via a (slow) network you are likely to need + lots of authenticator processes. authenticate_children 5 DOC_END @@ -1321,11 +1325,13 @@ # cache_peer_acl mycache_mydomain.net !all acl aclname proxy_auth [ refresh ] - # Use an EXTERNAL authenticate program to check username/password + # Use an EXTERNAL authentication program to check username/password # combinations (see authenticate_program). # # 'timeout' is the time a checked username/password combination - # remains cached (default = 3600 secs). + # remains cached (default = 3600 secs). If a wrong password + # is given for a cached user, the user gets removed from the + # username/password cache forcing a revalidation. # # When using a proxy_auth ACL in an http_access rule, make sure # it is the *last* in the list and the only proxy_auth ACL in diff -urwN squid-1.2.beta23pl3-0730/src/ncsa_auth.c squid-1.2.beta23pl3/src/ncsa_auth.c --- squid-1.2.beta23pl3-0730/src/ncsa_auth.c Sat Aug 1 14:09:18 1998 +++ squid-1.2.beta23pl3/src/ncsa_auth.c Sun Aug 2 21:05:51 1998 @@ -7,33 +7,30 @@ * proxy_auth code from client_side.c, written by * Jon Thackray . * - * Uses a NCSA httpd style password file for authentication. + * Uses a NCSA httpd style password file for authentication with the + * following improvements suggested by various people: + * + * - comment lines are possible and should start with a '#'; + * - empty or blank lines are possible; + * - extra fields in the password file are ignored; this makes it + * possible to use a Unix password file but I do not recommend that. * */ #include "squid.h" -#define CHECK_INTERVAL 10 - static hash_table *hash = NULL; -static time_t last_time = 0; -static time_t change_time = 0; static void read_passwd_file(const char *passwdfile) { - struct stat buf; FILE *f; hash_link *hashr; + char buf[8192]; acl_proxy_auth_user *u; - static char *passwords = NULL; char *user; char *passwd; - if (stat(passwdfile, &buf) == 0) { - if (buf.st_mtime != change_time) { - /* file has changed */ - change_time = buf.st_mtime; if (hash != NULL) { /* clear hash first */ hash_first(hash); @@ -49,31 +46,21 @@ exit(1); } } - passwords = xmalloc((size_t) buf.st_size + 2); f = fopen(passwdfile, "r"); - fread(passwords, (size_t) buf.st_size, 1, f); - *(passwords + buf.st_size) = '\0'; - strcat(passwords, "\n"); - fclose(f); - - user = strtok(passwords, ":"); - passwd = strtok(NULL, "\n"); - while (user != NULL) { - if (strlen(user) > 0 && passwd && strlen(passwd) > 0) { + while (fgets(buf, 8192, f) != NULL) { + if ((buf[0] == '#') || (buf[0] == ' ') || (buf[0] == '\t') || + (buf[0] == '\n')) + continue; + user = strtok(buf, ":\n"); + passwd = strtok(NULL, ":\n"); + if ((strlen(user) > 0) && passwd) { u = xmalloc(sizeof(acl_proxy_auth_user)); u->user = xstrdup(user); u->passwd = xstrdup(passwd); hash_join(hash, (hash_link *) u); } - user = strtok(NULL, ":"); - passwd = strtok(NULL, "\n"); - } - xfree(passwords); - } - } else { - fprintf(stderr, "ncsa_auth: cannot stat %s\n", passwdfile); - exit(1); } + fclose(f); } /* this is only needed for hash.c */ @@ -87,26 +74,37 @@ int main(int argc, char **argv) { + struct stat sb; + time_t change_time = 0; char buf[256]; - time_t now = 0; - char *user, *passwd; + char *user, *passwd, *p; acl_proxy_auth_user *u; if (argc != 2) { fprintf(stderr, "Usage: ncsa_auth \n"); exit(1); } - read_passwd_file(argv[1]); - last_time = time(NULL); + if (stat(argv[1], &sb) != 0) { + fprintf(stderr, "cannot stat %s\n", argv[1]); + exit(1); + } while (fgets(buf, 256, stdin) != NULL) { - now = time(NULL); - if ((now - last_time) >= CHECK_INTERVAL) { - last_time = now; + if (stat(argv[1], &sb) == 0) { + if (sb.st_mtime != change_time) { read_passwd_file(argv[1]); + change_time = sb.st_mtime; + } } - user = strtok(buf, " "); - passwd = strtok(NULL, " \n"); + user = buf; + if ((passwd = strchr(buf, ' ')) == NULL) { + printf("ERR\n"); + fflush(stdout); + continue; + } + *passwd++ = '\0'; + if ((p = strchr(passwd, '\n')) != NULL) + *p = '\0'; /* strip \n */ u = hash_lookup(hash, user); if (u && strcmp(u->passwd, (char *) crypt(passwd, u->passwd)) == 0) { diff -urwN squid-1.2.beta23pl3-0730/src/structs.h squid-1.2.beta23pl3/src/structs.h --- squid-1.2.beta23pl3-0730/src/structs.h Sat Aug 1 14:09:18 1998 +++ squid-1.2.beta23pl3/src/structs.h Sat Aug 1 14:40:05 1998 @@ -65,7 +65,7 @@ /* first two items must be same as hash_link */ char *user; acl_proxy_auth_user *next; - /* extra fields */ + /* extra fields for proxy_auth */ char *passwd; int passwd_ok; /* 1 = passwd checked OK */ long expiretime; @@ -170,7 +170,7 @@ request_t *request; char ident[USER_IDENT_SZ]; char browser[BROWSERNAMELEN]; - acl_proxy_auth_user *auth_user; /* XXX */ + acl_proxy_auth_user *auth_user; acl_lookup_state state[ACL_ENUM_MAX]; PF *callback; void *callback_data; @@ -764,7 +764,6 @@ struct timeval start; float http_ver; int redirect_state; - int authenticate_state; /* XXX: needed? */ aclCheck_t *acl_checklist; /* need ptr back so we can unreg if needed */ clientHttpRequest *next; AccessLogEntry al;