]>
git.ipfire.org Git - thirdparty/squid.git/blob - helpers/basic_auth/NCSA/basic_ncsa_auth.cc
2 * AUTHOR: Arjan de Vet <Arjan.deVet@adv.iae.nl>
4 * Example authentication program for Squid, based on the original
5 * proxy_auth code from client_side.c, written by
6 * Jon Thackray <jrmt@uk.gdscorp.com>.
8 * Uses a NCSA httpd style password file for authentication with the
9 * following improvements suggested by various people:
11 * - comment lines are possible and should start with a '#';
12 * - empty or blank lines are possible;
13 * - extra fields in the password file are ignored; this makes it
14 * possible to use a Unix password file but I do not recommend that.
16 * MD5 without salt and magic strings - Added by Ramon de Carvalho and Rodrigo Rubira Branco
20 #include "crypt_md5.h"
22 #include "helpers/defines.h"
45 static hash_table
*hash
= NULL
;
46 static HASHFREE my_free
;
48 typedef struct _user_data
{
49 /* first two items must be same as hash_link */
51 struct _user_data
*next
;
58 user_data
*u
= static_cast<user_data
*>(p
);
65 read_passwd_file(const char *passwdfile
)
73 hashFreeItems(hash
, my_free
);
77 hash
= hash_create((HASHCMP
*) strcmp
, 7921, hash_string
);
79 fprintf(stderr
, "FATAL: Cannot create hash table\n");
82 f
= fopen(passwdfile
, "r");
84 fprintf(stderr
, "FATAL: %s: %s\n", passwdfile
, xstrerror());
87 while (fgets(buf
, 8192, f
) != NULL
) {
88 if ((buf
[0] == '#') || (buf
[0] == ' ') || (buf
[0] == '\t') ||
91 user
= strtok(buf
, ":\n\r");
92 passwd
= strtok(NULL
, ":\n\r");
93 if ((strlen(user
) > 0) && passwd
) {
94 u
= static_cast<user_data
*>(xmalloc(sizeof(*u
)));
95 u
->user
= xstrdup(user
);
96 u
->passwd
= xstrdup(passwd
);
97 hash_join(hash
, (hash_link
*) u
);
104 main(int argc
, char **argv
)
107 time_t change_time
= -1;
108 char buf
[HELPER_INPUT_BUFFER
];
109 char *user
, *passwd
, *p
;
111 setbuf(stdout
, NULL
);
113 fprintf(stderr
, "Usage: ncsa_auth <passwordfile>\n");
116 if (stat(argv
[1], &sb
) != 0) {
117 fprintf(stderr
, "FATAL: cannot stat %s\n", argv
[1]);
120 while (fgets(buf
, HELPER_INPUT_BUFFER
, stdin
) != NULL
) {
121 if ((p
= strchr(buf
, '\n')) != NULL
)
122 *p
= '\0'; /* strip \n */
123 if (stat(argv
[1], &sb
) == 0) {
124 if (sb
.st_mtime
!= change_time
) {
125 read_passwd_file(argv
[1]);
126 change_time
= sb
.st_mtime
;
129 if ((user
= strtok(buf
, " ")) == NULL
) {
133 if ((passwd
= strtok(NULL
, "")) == NULL
) {
137 rfc1738_unescape(user
);
138 rfc1738_unescape(passwd
);
139 u
= (user_data
*) hash_lookup(hash
, user
);
141 SEND_ERR("No such user");
143 } else if (strlen(passwd
) <= 8 && strcmp(u
->passwd
, (char *) crypt(passwd
, u
->passwd
)) == 0) {
144 // Bug 3107: crypt() DES functionality silently truncates long passwords.
146 } else if (strlen(passwd
) > 8 && strcmp(u
->passwd
, (char *) crypt(passwd
, u
->passwd
)) == 0) {
147 // Bug 3107: crypt() DES functionality silently truncates long passwords.
148 SEND_ERR("Password too long. Only 8 characters accepted.");
150 } else if (strcmp(u
->passwd
, (char *) crypt_md5(passwd
, u
->passwd
)) == 0) {
152 } else if (strcmp(u
->passwd
, (char *) md5sum(passwd
)) == 0) {
155 SEND_ERR("Wrong password");
159 hashFreeItems(hash
, my_free
);
160 hashFreeMemory(hash
);