]> git.ipfire.org Git - thirdparty/squid.git/blob - helpers/external_acl/kerberos_ldap_group/support_group.cc
Renamed squid.h to squid-old.h and config.h to squid.h
[thirdparty/squid.git] / helpers / external_acl / kerberos_ldap_group / support_group.cc
1
2 /*
3 * -----------------------------------------------------------------------------
4 *
5 * Author: Markus Moeller (markus_moeller at compuserve.com)
6 *
7 * Copyright (C) 2007 Markus Moeller. All rights reserved.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
22 *
23 * -----------------------------------------------------------------------------
24 */
25
26 #include "squid.h"
27 #include "util.h"
28
29 #ifdef HAVE_LDAP
30
31 #include "support.h"
32
33 struct gdstruct *init_gd(void);
34
35 struct gdstruct *
36 init_gd(void) {
37 struct gdstruct *gdsp;
38 gdsp = (struct gdstruct *) xmalloc(sizeof(struct gdstruct));
39 gdsp->group = NULL;
40 gdsp->domain = NULL;
41 gdsp->next = NULL;
42 return gdsp;
43 }
44
45 char *utf8dup(struct main_args *margs);
46
47 char *
48 utf8dup(struct main_args *margs)
49 {
50 int c = 0, s;
51 size_t n;
52 char *src;
53 unsigned char *p, *dupp;
54
55 src = margs->glist;
56 if (!src)
57 return NULL;
58 for (n = 0; n < strlen(src); n++)
59 if ((unsigned char) src[n] > 127)
60 c++;
61 if (c != 0) {
62 p = (unsigned char *) xmalloc(strlen(src) + c);
63 dupp = p;
64 for (n = 0; n < strlen(src); n++) {
65 s = (unsigned char) src[n];
66 if (s > 127 && s < 192) {
67 *p = 194;
68 p++;
69 *p = s;
70 } else if (s > 191 && s < 256) {
71 *p = 195;
72 p++;
73 *p = s - 64;
74 } else
75 *p = s;
76 p++;
77 }
78 *p = '\0';
79 debug((char *) "%s| %s: INFO: Group %s as UTF-8: %s\n", LogTime(), PROGRAM, src, dupp);
80 return (char *) dupp;
81 } else
82 return xstrdup(src);
83 }
84
85 char *hex_utf_char(struct main_args *margs, int flag);
86 /*
87 * UTF8 = UTF1 / UTFMB
88 * UTFMB = UTF2 / UTF3 / UTF4
89 *
90 * UTF0 = %x80-BF
91 * UTF1 = %x00-7F
92 * UTF2 = %xC2-DF UTF0
93 * UTF3 = %xE0 %xA0-BF UTF0 / %xE1-EC 2(UTF0) /
94 * %xED %x80-9F UTF0 / %xEE-EF 2(UTF0)
95 * UTF4 = %xF0 %x90-BF 2(UTF0) / %xF1-F3 3(UTF0) /
96 * %xF4 %x80-8F 2(UTF0)
97 *
98 * http://www.utf8-chartable.de/unicode-utf8-table.pl
99 */
100
101 char *
102 hex_utf_char(struct main_args *margs, int flag)
103 {
104 char *up;
105 char *upd;
106 char *ul;
107 int a, n, nl, ival, ichar;
108 int iUTF2, iUTF3, iUTF4;
109
110 if (flag) {
111 up = margs->ulist;
112 } else {
113 up = margs->tlist;
114 }
115
116 if (!up)
117 return NULL;
118
119 upd = strrchr(up, '@');
120 if (upd)
121 a = upd - up;
122 else
123 a = strlen(up);
124
125 ul = (char *) xmalloc(strlen(up));
126 n = 0;
127 nl = 0;
128 iUTF2 = 0;
129 iUTF3 = 0;
130 iUTF4 = 0;
131
132 while (n < (int) strlen(up)) {
133 if (flag && n == a)
134 break;
135 if (up[n] == '@') {
136 ul[nl] = '@';
137 nl++;
138 n++;
139 continue;
140 }
141 ival = up[n];
142 if (ival > 64 && ival < 71)
143 ichar = (ival - 55) * 16;
144 else if (ival > 96 && ival < 103)
145 ichar = (ival - 87) * 16;
146 else if (ival > 47 && ival < 58)
147 ichar = (ival - 48) * 16;
148 else {
149 debug((char *) "%s| %s: WARNING: Invalid Hex value %c\n", LogTime(), PROGRAM, ival);
150 if (ul)
151 xfree(ul);
152 return NULL;
153 }
154
155
156 if (n == a - 1) {
157 debug((char *) "%s| %s: WARNING: Invalid Hex UTF-8 string %s\n", LogTime(), PROGRAM, up);
158 if (ul)
159 xfree(ul);
160 return NULL;
161 }
162 n++;
163 ival = up[n];
164 if (ival > 64 && ival < 71)
165 ichar = ichar + ival - 55;
166 else if (ival > 96 && ival < 103)
167 ichar = ichar + ival - 87;
168 else if (ival > 47 && ival < 58)
169 ichar = ichar + ival - 48;
170 else {
171 debug((char *) "%s| %s: WARNING: Invalid Hex value %c\n", LogTime(), PROGRAM, ival);
172 if (ul)
173 xfree(ul);
174 return NULL;
175 }
176
177 if (iUTF2) {
178 if (iUTF2 == 0xC2 && ichar > 0x7F && ichar < 0xC0) {
179 iUTF2 = 0;
180 ul[nl - 1] = ichar;
181 } else if (iUTF2 == 0xC3 && ichar > 0x7F && ichar < 0xC0) {
182 iUTF2 = 0;
183 ul[nl - 1] = ichar + 64;
184 } else if (iUTF2 > 0xC3 && iUTF2 < 0xE0 && ichar > 0x7F && ichar < 0xC0) {
185 iUTF2 = 0;
186 ul[nl] = ichar;
187 nl++;
188 } else {
189 iUTF2 = 0;
190 ul[nl] = ichar;
191 ul[nl + 1] = '\0';
192 debug((char *) "%s| %s: WARNING: Invalid UTF-8 sequence for Unicode %s\n", LogTime(), PROGRAM, ul);
193 if (ul)
194 xfree(ul);
195 return NULL;
196 }
197 } else if (iUTF3) {
198 if (iUTF3 == 0xE0 && ichar > 0x9F && ichar < 0xC0) {
199 iUTF3 = 1;
200 ul[nl] = ichar;
201 nl++;
202 } else if (iUTF3 > 0xE0 && iUTF3 < 0xED && ichar > 0x7F && ichar < 0xC0) {
203 iUTF3 = 2;
204 ul[nl] = ichar;
205 nl++;
206 } else if (iUTF3 == 0xED && ichar > 0x7F && ichar < 0xA0) {
207 iUTF3 = 3;
208 ul[nl] = ichar;
209 nl++;
210 } else if (iUTF3 > 0xED && iUTF3 < 0xF0 && ichar > 0x7F && ichar < 0xC0) {
211 iUTF3 = 4;
212 ul[nl] = ichar;
213 nl++;
214 } else if (iUTF3 > 0 && iUTF3 < 5 && ichar > 0x7F && ichar < 0xC0) {
215 iUTF3 = 0;
216 ul[nl] = ichar;
217 nl++;
218 } else {
219 iUTF3 = 0;
220 ul[nl] = ichar;
221 ul[nl + 1] = '\0';
222 debug((char *) "%s| %s: WARNING: Invalid UTF-8 sequence for Unicode %s\n", LogTime(), PROGRAM, ul);
223 if (ul)
224 xfree(ul);
225 return NULL;
226 }
227 } else if (iUTF4) {
228 if (iUTF4 == 0xF0 && ichar > 0x8F && ichar < 0xC0) {
229 iUTF4 = 1;
230 ul[nl] = ichar;
231 nl++;
232 } else if (iUTF4 > 0xF0 && iUTF3 < 0xF4 && ichar > 0x7F && ichar < 0xC0) {
233 iUTF4 = 2;
234 ul[nl] = ichar;
235 nl++;
236 } else if (iUTF4 == 0xF4 && ichar > 0x7F && ichar < 0x90) {
237 iUTF4 = 3;
238 ul[nl] = ichar;
239 nl++;
240 } else if (iUTF4 > 0 && iUTF4 < 5 && ichar > 0x7F && ichar < 0xC0) {
241 if (iUTF4 == 4)
242 iUTF4 = 0;
243 else
244 iUTF4 = 4;
245 ul[nl] = ichar;
246 nl++;
247 } else {
248 iUTF4 = 0;
249 ul[nl] = ichar;
250 ul[nl + 1] = '\0';
251 debug((char *) "%s| %s: WARNING: Invalid UTF-8 sequence for Unicode %s\n", LogTime(), PROGRAM, ul);
252 if (ul)
253 xfree(ul);
254 return NULL;
255 }
256 } else if (ichar < 0x80) {
257 /* UTF1 */
258 ul[nl] = ichar;
259 nl++;
260 } else if (ichar > 0xC1 && ichar < 0xE0) {
261 /* UTF2 (Latin) */
262 iUTF2 = ichar;
263 ul[nl] = ichar;
264 nl++;
265 } else if (ichar > 0xDF && ichar < 0xF0) {
266 /* UTF3 */
267 iUTF3 = ichar;
268 ul[nl] = ichar;
269 nl++;
270 } else if (ichar > 0xEF && ichar < 0xF5) {
271 /* UTF4 */
272 iUTF4 = ichar;
273 ul[nl] = ichar;
274 nl++;
275 } else {
276 ul[nl] = ichar;
277 ul[nl + 1] = '\0';
278 debug((char *) "%s| %s: WARNING: Invalid UTF-8 sequence for Unicode %s\n", LogTime(), PROGRAM, ul);
279 if (ul)
280 xfree(ul);
281 return NULL;
282 }
283 n++;
284 }
285
286 ul[nl] = '\0';
287 if (iUTF2 || iUTF3 || iUTF4) {
288 debug((char *) "%s| %s: INFO: iUTF2: %d iUTF3: %d iUTF4: %d\n", LogTime(), PROGRAM, iUTF2, iUTF3, iUTF4);
289 debug((char *) "%s| %s: WARNING: Invalid UTF-8 sequence for Unicode %s\n", LogTime(), PROGRAM, ul);
290 if (ul)
291 xfree(ul);
292 return NULL;
293 }
294 if (flag && upd)
295 ul = strcat(ul, upd);
296 return ul;
297 }
298
299
300 int
301 create_gd(struct main_args *margs)
302 {
303 char *gp, *dp;
304 char *hp1, *hp2, *up;
305 char *p;
306 struct gdstruct *gdsp = NULL, *gdspn = NULL;
307 /*
308 * Group list format:
309 *
310 * glist=Pattern1[:Pattern2]
311 *
312 * Pattern=Group Group for all domains(including non Kerberos domains using ldap url options) if no
313 * other group definition for domain exists or users without
314 * domain information.
315 * gdstruct.domain=NULL, gdstruct.group=Group
316 *
317 * or Pattern=Group@ Group for all Kerberos domains if no other group definition
318 * exists
319 * gdstruct.domain="", gdstruct.group=Group
320 *
321 * or Pattern=Group@Domain Group for a specific Kerberos domain
322 * gdstruct.domain=Domain, gdstruct.group=Group
323 *
324 *
325 */
326 hp1 = hex_utf_char(margs, 0);
327 hp2 = hex_utf_char(margs, 1);
328 up = utf8dup(margs);
329 p = up;
330 if (hp1) {
331 if (hp2) {
332 if (up) {
333 p = (char *) xmalloc(strlen(up) + strlen(hp1) + strlen(hp2) + 2);
334 strcpy(p, up);
335 strcat(p, ":");
336 strcat(p, hp1);
337 strcat(p, ":");
338 strcat(p, hp2);
339 } else {
340 p = (char *) xmalloc(strlen(hp1) + strlen(hp2) + 1);
341 strcpy(p, hp1);
342 strcat(p, ":");
343 strcat(p, hp2);
344 }
345 } else {
346 if (up) {
347 p = (char *) xmalloc(strlen(up) + strlen(hp1) + 1);
348 strcpy(p, up);
349 strcat(p, ":");
350 strcat(p, hp1);
351 } else
352 p = hp1;
353 }
354 } else {
355 if (hp2) {
356 if (up) {
357 p = (char *) xmalloc(strlen(up) + strlen(hp2) + 1);
358 strcpy(p, up);
359 strcat(p, ":");
360 strcat(p, hp2);
361 } else
362 p = hp2;
363 } else
364 p = up;
365 }
366 gp = p;
367 debug((char *) "%s| %s: INFO: Group list %s\n", LogTime(), PROGRAM, p ? p : "NULL");
368 dp = NULL;
369
370 if (!p) {
371 debug((char *) "%s| %s: ERROR: No groups defined.\n", LogTime(), PROGRAM);
372 return (1);
373 }
374 while (*p) { /* loop over group list */
375 if (*p == '\n' || *p == '\r') { /* Ignore CR and LF if exist */
376 p++;
377 continue;
378 }
379 if (*p == '@') { /* end of group name - start of domain name */
380 if (p == gp) { /* empty group name not allowed */
381 debug((char *) "%s| %s: ERROR: No group defined for domain %s\n", LogTime(), PROGRAM, p);
382 return (1);
383 }
384 *p = '\0';
385 p++;
386 gdsp = init_gd();
387 gdsp->group = gp;
388 if (gdspn) /* Have already an existing structure */
389 gdsp->next = gdspn;
390 dp = p; /* after @ starts new domain name */
391 } else if (*p == ':') { /* end of group name or end of domain name */
392 if (p == gp) { /* empty group name not allowed */
393 debug((char *) "%s| %s: ERROR: No group defined for domain %s\n", LogTime(), PROGRAM, p);
394 return (1);
395 }
396 *p = '\0';
397 p++;
398 if (dp) { /* end of domain name */
399 gdsp->domain = xstrdup(dp);
400 dp = NULL;
401 } else { /* end of group name and no domain name */
402 gdsp = init_gd();
403 gdsp->group = gp;
404 if (gdspn) /* Have already an existing structure */
405 gdsp->next = gdspn;
406 }
407 gdspn = gdsp;
408 gp = p; /* after : starts new group name */
409 debug((char *) "%s| %s: INFO: Group %s Domain %s\n", LogTime(), PROGRAM, gdsp->group, gdsp->domain ? gdsp->domain : "NULL");
410 } else
411 p++;
412 }
413 if (p == gp) { /* empty group name not allowed */
414 debug((char *) "%s| %s: ERROR: No group defined for domain %s\n", LogTime(), PROGRAM, p);
415 return (1);
416 }
417 if (dp) { /* end of domain name */
418 gdsp->domain = xstrdup(dp);
419 } else { /* end of group name and no domain name */
420 gdsp = init_gd();
421 gdsp->group = gp;
422 if (gdspn) /* Have already an existing structure */
423 gdsp->next = gdspn;
424 }
425 debug((char *) "%s| %s: INFO: Group %s Domain %s\n", LogTime(), PROGRAM, gdsp->group, gdsp->domain ? gdsp->domain : "NULL");
426
427 margs->groups = gdsp;
428 return (0);
429 }
430 #endif