]> git.ipfire.org Git - thirdparty/squid.git/blob - helpers/basic_auth/NCSA/basic_ncsa_auth.cc
Polish rfc1738 library code. Add cppunit tests.
[thirdparty/squid.git] / helpers / basic_auth / NCSA / basic_ncsa_auth.cc
1 /*
2 * ncsa_auth.c
3 *
4 * AUTHOR: Arjan de Vet <Arjan.deVet@adv.iae.nl>
5 *
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>.
9 *
10 * Uses a NCSA httpd style password file for authentication with the
11 * following improvements suggested by various people:
12 *
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.
17 *
18 */
19
20 #include "config.h"
21 #include "rfc1738.h"
22
23 #if HAVE_STDIO_H
24 #include <stdio.h>
25 #endif
26 #if HAVE_STDLIB_H
27 #include <stdlib.h>
28 #endif
29 #if HAVE_UNISTD_H
30 #include <unistd.h>
31 #endif
32 #if HAVE_STRING_H
33 #include <string.h>
34 #endif
35 #if HAVE_SYS_TYPES_H
36 #include <sys/types.h>
37 #endif
38 #if HAVE_SYS_STAT_H
39 #include <sys/stat.h>
40 #endif
41 #if HAVE_CRYPT_H
42 #include <crypt.h>
43 #endif
44
45 #include "util.h"
46 #include "hash.h"
47 #include "crypt_md5.h"
48
49 static hash_table *hash = NULL;
50 static HASHFREE my_free;
51
52 typedef struct _user_data {
53 /* first two items must be same as hash_link */
54 char *user;
55 struct _user_data *next;
56 char *passwd;
57 } user_data;
58
59 static void
60 my_free(void *p)
61 {
62 user_data *u = static_cast<user_data*>(p);
63 xfree(u->user);
64 xfree(u->passwd);
65 xfree(u);
66 }
67
68 static void
69 read_passwd_file(const char *passwdfile)
70 {
71 FILE *f;
72 char buf[8192];
73 user_data *u;
74 char *user;
75 char *passwd;
76 if (hash != NULL) {
77 hashFreeItems(hash, my_free);
78 hashFreeMemory(hash);
79 }
80 /* initial setup */
81 hash = hash_create((HASHCMP *) strcmp, 7921, hash_string);
82 if (NULL == hash) {
83 fprintf(stderr, "ncsa_auth: cannot create hash table\n");
84 exit(1);
85 }
86 f = fopen(passwdfile, "r");
87 if (NULL == f) {
88 fprintf(stderr, "%s: %s\n", passwdfile, xstrerror());
89 exit(1);
90 }
91 while (fgets(buf, 8192, f) != NULL) {
92 if ((buf[0] == '#') || (buf[0] == ' ') || (buf[0] == '\t') ||
93 (buf[0] == '\n'))
94 continue;
95 user = strtok(buf, ":\n\r");
96 passwd = strtok(NULL, ":\n\r");
97 if ((strlen(user) > 0) && passwd) {
98 u = static_cast<user_data*>(xmalloc(sizeof(*u)));
99 u->user = xstrdup(user);
100 u->passwd = xstrdup(passwd);
101 hash_join(hash, (hash_link *) u);
102 }
103 }
104 fclose(f);
105 }
106
107 int
108 main(int argc, char **argv)
109 {
110 struct stat sb;
111 time_t change_time = -1;
112 char buf[256];
113 char *user, *passwd, *p;
114 user_data *u;
115 setbuf(stdout, NULL);
116 if (argc != 2) {
117 fprintf(stderr, "Usage: ncsa_auth <passwordfile>\n");
118 exit(1);
119 }
120 if (stat(argv[1], &sb) != 0) {
121 fprintf(stderr, "cannot stat %s\n", argv[1]);
122 exit(1);
123 }
124 while (fgets(buf, 256, stdin) != NULL) {
125 if ((p = strchr(buf, '\n')) != NULL)
126 *p = '\0'; /* strip \n */
127 if (stat(argv[1], &sb) == 0) {
128 if (sb.st_mtime != change_time) {
129 read_passwd_file(argv[1]);
130 change_time = sb.st_mtime;
131 }
132 }
133 if ((user = strtok(buf, " ")) == NULL) {
134 printf("ERR\n");
135 continue;
136 }
137 if ((passwd = strtok(NULL, "")) == NULL) {
138 printf("ERR\n");
139 continue;
140 }
141 rfc1738_unescape(user);
142 rfc1738_unescape(passwd);
143 u = (user_data *) hash_lookup(hash, user);
144 if (u == NULL) {
145 printf("ERR No such user\n");
146 #if HAVE_CRYPT
147 } else if (strcmp(u->passwd, (char *) crypt(passwd, u->passwd)) == 0) {
148 printf("OK\n");
149 #endif
150 } else if (strcmp(u->passwd, (char *) crypt_md5(passwd, u->passwd)) == 0) {
151 printf("OK\n");
152 } else if (strcmp(u->passwd, (char *) md5sum(passwd)) == 0) { /* md5 without salt and magic strings - Added by Ramon de Carvalho and Rodrigo Rubira Branco */
153 printf("OK\n");
154 } else {
155 printf("ERR Wrong password\n");
156 }
157 }
158 if (hash != NULL) {
159 hashFreeItems(hash, my_free);
160 hashFreeMemory(hash);
161 }
162 exit(0);
163 }