]>
git.ipfire.org Git - thirdparty/squid.git/blob - helpers/basic_auth/NCSA/basic_ncsa_auth.cc
2 * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
10 * AUTHOR: Arjan de Vet <Arjan.deVet@adv.iae.nl>
12 * Example authentication program for Squid, based on the original
13 * proxy_auth code from client_side.c, written by
14 * Jon Thackray <jrmt@uk.gdscorp.com>.
16 * Uses a NCSA httpd style password file for authentication with the
17 * following improvements suggested by various people:
19 * - comment lines are possible and should start with a '#';
20 * - empty or blank lines are possible;
21 * - extra fields in the password file are ignored; this makes it
22 * possible to use a Unix password file but I do not recommend that.
24 * MD5 without salt and magic strings - Added by Ramon de Carvalho and Rodrigo Rubira Branco
28 #include "crypt_md5.h"
30 #include "helpers/defines.h"
46 static hash_table
*hash
= NULL
;
47 static HASHFREE my_free
;
49 typedef struct _user_data
{
50 /* first two items must be same as hash_link */
52 struct _user_data
*next
;
59 user_data
*u
= static_cast<user_data
*>(p
);
66 read_passwd_file(const char *passwdfile
)
69 char buf
[HELPER_INPUT_BUFFER
];
74 hashFreeItems(hash
, my_free
);
78 hash
= hash_create((HASHCMP
*) strcmp
, 7921, hash_string
);
80 fprintf(stderr
, "FATAL: Cannot create hash table\n");
83 f
= fopen(passwdfile
, "r");
85 fprintf(stderr
, "FATAL: %s: %s\n", passwdfile
, xstrerror());
88 unsigned int lineCount
= 0;
89 buf
[HELPER_INPUT_BUFFER
-1] = '\0';
90 while (fgets(buf
, sizeof(buf
)-1, f
) != NULL
) {
92 if ((buf
[0] == '#') || (buf
[0] == ' ') || (buf
[0] == '\t') ||
95 user
= strtok(buf
, ":\n\r");
97 fprintf(stderr
, "ERROR: Missing user name at %s line %d\n", passwdfile
, lineCount
);
100 passwd
= strtok(NULL
, ":\n\r");
101 if ((strlen(user
) > 0) && passwd
) {
102 u
= static_cast<user_data
*>(xmalloc(sizeof(*u
)));
103 u
->user
= xstrdup(user
);
104 u
->passwd
= xstrdup(passwd
);
105 hash_join(hash
, (hash_link
*) u
);
112 main(int argc
, char **argv
)
115 time_t change_time
= -1;
116 char buf
[HELPER_INPUT_BUFFER
];
117 char *user
, *passwd
, *p
;
119 setbuf(stdout
, NULL
);
121 fprintf(stderr
, "Usage: ncsa_auth <passwordfile>\n");
124 if (stat(argv
[1], &sb
) != 0) {
125 fprintf(stderr
, "FATAL: cannot stat %s\n", argv
[1]);
128 while (fgets(buf
, HELPER_INPUT_BUFFER
, stdin
) != NULL
) {
129 if ((p
= strchr(buf
, '\n')) != NULL
)
130 *p
= '\0'; /* strip \n */
131 if (stat(argv
[1], &sb
) == 0) {
132 if (sb
.st_mtime
!= change_time
) {
133 read_passwd_file(argv
[1]);
134 change_time
= sb
.st_mtime
;
137 if ((user
= strtok(buf
, " ")) == NULL
) {
141 if ((passwd
= strtok(NULL
, "")) == NULL
) {
145 rfc1738_unescape(user
);
146 rfc1738_unescape(passwd
);
147 u
= (user_data
*) hash_lookup(hash
, user
);
149 SEND_ERR("No such user");
152 char *crypted
= NULL
;
154 size_t passwordLength
= strlen(passwd
);
155 // Bug 3831: given algorithms more secure than DES crypt() does not truncate, so we can ignore the bug 3107 length checks below
156 // '$1$' = MD5, '$2a$' = Blowfish, '$5$' = SHA256 (Linux), '$6$' = SHA256 (BSD) and SHA512
157 if (passwordLength
> 1 && u
->passwd
[0] == '$' &&
158 (crypted
= crypt(passwd
, u
->passwd
)) && strcmp(u
->passwd
, crypted
) == 0) {
162 // 'other' prefixes indicate DES algorithm.
163 if (passwordLength
<= 8 && (crypted
= crypt(passwd
, u
->passwd
)) && (strcmp(u
->passwd
, crypted
) == 0)) {
167 if (passwordLength
> 8 && (crypted
= crypt(passwd
, u
->passwd
)) && (strcmp(u
->passwd
, crypted
) == 0)) {
168 // Bug 3107: crypt() DES functionality silently truncates long passwords.
169 SEND_ERR("Password too long. Only 8 characters accepted.");
174 if ( (crypted
= crypt_md5(passwd
, u
->passwd
)) && strcmp(u
->passwd
, crypted
) == 0) {
178 if ( (crypted
= md5sum(passwd
)) && strcmp(u
->passwd
, crypted
) == 0) {
182 SEND_ERR("Wrong password");
185 hashFreeItems(hash
, my_free
);
186 hashFreeMemory(hash
);