4
* AUTHOR: Arjan de Vet <Arjan.deVet@adv.iae.nl>
6
* Example authentication program for Squid, based on the original
7
* proxy_auth code from client_side.c, written by
8
* Jon Thackray <jrmt@uk.gdscorp.com>.
10
* Uses a NCSA httpd style password file for authentication with the
11
* following improvements suggested by various people:
13
* - comment lines are possible and should start with a '#';
14
* - empty or blank lines are possible;
15
* - extra fields in the password file are ignored; this makes it
16
* possible to use a Unix password file but I do not recommend that.
18
* MD5 without salt and magic strings - Added by Ramon de Carvalho and Rodrigo Rubira Branco
37
#include <sys/types.h>
48
#include "crypt_md5.h"
50
static hash_table *hash = NULL;
51
static HASHFREE my_free;
53
typedef struct _user_data {
54
/* first two items must be same as hash_link */
56
struct _user_data *next;
70
read_passwd_file(const char *passwdfile)
78
hashFreeItems(hash, my_free);
82
hash = hash_create((HASHCMP *) strcmp, 7921, hash_string);
84
fprintf(stderr, "ncsa_auth: cannot create hash table\n");
87
f = fopen(passwdfile, "r");
89
fprintf(stderr, "%s: %s\n", passwdfile, xstrerror());
92
while (fgets(buf, 8192, f) != NULL) {
93
if ((buf[0] == '#') || (buf[0] == ' ') || (buf[0] == '\t') ||
96
user = strtok(buf, ":\n\r");
97
passwd = strtok(NULL, ":\n\r");
98
if ((strlen(user) > 0) && passwd) {
99
u = xmalloc(sizeof(*u));
100
u->user = xstrdup(user);
101
u->passwd = xstrdup(passwd);
102
hash_join(hash, (hash_link *) u);
109
main(int argc, char **argv)
112
time_t change_time = -1;
114
char *user, *passwd, *p;
116
setbuf(stdout, NULL);
118
fprintf(stderr, "Usage: ncsa_auth <passwordfile>\n");
121
if (stat(argv[1], &sb) != 0) {
122
fprintf(stderr, "cannot stat %s\n", argv[1]);
125
while (fgets(buf, 256, stdin) != NULL) {
126
if ((p = strchr(buf, '\n')) != NULL)
127
*p = '\0'; /* strip \n */
128
if (stat(argv[1], &sb) == 0) {
129
if (sb.st_mtime != change_time) {
130
read_passwd_file(argv[1]);
131
change_time = sb.st_mtime;
134
if ((user = strtok(buf, " ")) == NULL) {
138
if ((passwd = strtok(NULL, "")) == NULL) {
142
rfc1738_unescape(user);
143
rfc1738_unescape(passwd);
144
u = (user_data *) hash_lookup(hash, user);
146
printf("ERR No such user\n");
148
} else if (strlen(passwd) <= 8 && strcmp(u->passwd, (char *) crypt(passwd, u->passwd)) == 0) {
149
// Bug 3107: crypt() DES functionality silently truncates long passwords.
151
} else if (strlen(passwd) > 8 && strcmp(u->passwd, (char *) crypt(passwd, u->passwd)) == 0) {
152
// Bug 3107: crypt() DES functionality silently truncates long passwords.
153
fprintf(stderr, "SECURITY ALERT: NCSA DES algorithm truncating user %s password to 8 bytes. Upgrade to MD5.", user);
154
// Highly Unsafe: permit a transition period for admin to update passwords.
157
} else if (strcmp(u->passwd, (char *) crypt_md5(passwd, u->passwd)) == 0) {
159
} else if (strcmp(u->passwd, (char *) md5sum(passwd)) == 0) {
162
printf("ERR Wrong password\n");
166
hashFreeItems(hash, my_free);
167
hashFreeMemory(hash);