]> git.ipfire.org Git - thirdparty/squid.git/blame - helpers/external_acl/kerberos_ldap_group/support_group.cc
SourceFormat Enforcement
[thirdparty/squid.git] / helpers / external_acl / kerberos_ldap_group / support_group.cc
CommitLineData
b1218840
AJ
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
f7f3304a 26#include "squid.h"
b1218840
AJ
27#include "util.h"
28
29#ifdef HAVE_LDAP
30
31#include "support.h"
32
33struct gdstruct *init_gd(void);
34
35struct gdstruct *
2e881a6f 36init_gd(void) {
b1218840
AJ
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
45char *utf8dup(struct main_args *margs);
46
47char *
48utf8dup(struct main_args *margs)
49{
50 int c = 0, s;
51 size_t n;
52 char *src;
af920dee 53 unsigned char *p, *dupp;
b1218840
AJ
54
55 src = margs->glist;
56 if (!src)
2e881a6f 57 return NULL;
a2f5277a 58 for (n = 0; n < strlen(src); ++n)
2e881a6f 59 if ((unsigned char) src[n] > 127)
755494da 60 ++c;
b1218840 61 if (c != 0) {
2e881a6f 62 p = (unsigned char *) xmalloc(strlen(src) + c);
af920dee 63 dupp = p;
a2f5277a 64 for (n = 0; n < strlen(src); ++n) {
2e881a6f
A
65 s = (unsigned char) src[n];
66 if (s > 127 && s < 192) {
67 *p = 194;
755494da 68 ++p;
2e881a6f
A
69 *p = s;
70 } else if (s > 191 && s < 256) {
71 *p = 195;
755494da 72 ++p;
2e881a6f
A
73 *p = s - 64;
74 } else
75 *p = s;
755494da 76 ++p;
2e881a6f
A
77 }
78 *p = '\0';
af920dee
AJ
79 debug((char *) "%s| %s: INFO: Group %s as UTF-8: %s\n", LogTime(), PROGRAM, src, dupp);
80 return (char *) dupp;
b1218840 81 } else
2e881a6f 82 return xstrdup(src);
b1218840
AJ
83}
84
85char *hex_utf_char(struct main_args *margs, int flag);
86/*
87 * UTF8 = UTF1 / UTFMB
88 * UTFMB = UTF2 / UTF3 / UTF4
2e881a6f 89 *
b1218840
AJ
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)
2e881a6f 97 *
b1218840
AJ
98 * http://www.utf8-chartable.de/unicode-utf8-table.pl
99 */
100
101char *
102hex_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) {
2e881a6f 111 up = margs->ulist;
b1218840 112 } else {
2e881a6f 113 up = margs->tlist;
b1218840
AJ
114 }
115
116 if (!up)
2e881a6f 117 return NULL;
b1218840
AJ
118
119 upd = strrchr(up, '@');
120 if (upd)
2e881a6f 121 a = upd - up;
b1218840 122 else
2e881a6f 123 a = strlen(up);
b1218840
AJ
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)) {
2e881a6f
A
133 if (flag && n == a)
134 break;
135 if (up[n] == '@') {
136 ul[nl] = '@';
755494da
FC
137 ++nl;
138 ++n;
2e881a6f
A
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 }
b1218840 154
2e881a6f
A
155 if (n == a - 1) {
156 debug((char *) "%s| %s: WARNING: Invalid Hex UTF-8 string %s\n", LogTime(), PROGRAM, up);
157 if (ul)
158 xfree(ul);
159 return NULL;
160 }
755494da 161 ++n;
2e881a6f
A
162 ival = up[n];
163 if (ival > 64 && ival < 71)
164 ichar = ichar + ival - 55;
165 else if (ival > 96 && ival < 103)
166 ichar = ichar + ival - 87;
167 else if (ival > 47 && ival < 58)
168 ichar = ichar + ival - 48;
169 else {
170 debug((char *) "%s| %s: WARNING: Invalid Hex value %c\n", LogTime(), PROGRAM, ival);
171 if (ul)
172 xfree(ul);
173 return NULL;
174 }
b1218840 175
2e881a6f
A
176 if (iUTF2) {
177 if (iUTF2 == 0xC2 && ichar > 0x7F && ichar < 0xC0) {
178 iUTF2 = 0;
179 ul[nl - 1] = ichar;
180 } else if (iUTF2 == 0xC3 && ichar > 0x7F && ichar < 0xC0) {
181 iUTF2 = 0;
182 ul[nl - 1] = ichar + 64;
183 } else if (iUTF2 > 0xC3 && iUTF2 < 0xE0 && ichar > 0x7F && ichar < 0xC0) {
184 iUTF2 = 0;
185 ul[nl] = ichar;
755494da 186 ++nl;
2e881a6f
A
187 } else {
188 iUTF2 = 0;
189 ul[nl] = ichar;
190 ul[nl + 1] = '\0';
191 debug((char *) "%s| %s: WARNING: Invalid UTF-8 sequence for Unicode %s\n", LogTime(), PROGRAM, ul);
192 if (ul)
193 xfree(ul);
194 return NULL;
195 }
196 } else if (iUTF3) {
197 if (iUTF3 == 0xE0 && ichar > 0x9F && ichar < 0xC0) {
198 iUTF3 = 1;
199 ul[nl] = ichar;
755494da 200 ++nl;
2e881a6f
A
201 } else if (iUTF3 > 0xE0 && iUTF3 < 0xED && ichar > 0x7F && ichar < 0xC0) {
202 iUTF3 = 2;
203 ul[nl] = ichar;
755494da 204 ++nl;
2e881a6f
A
205 } else if (iUTF3 == 0xED && ichar > 0x7F && ichar < 0xA0) {
206 iUTF3 = 3;
207 ul[nl] = ichar;
755494da 208 ++nl;
2e881a6f
A
209 } else if (iUTF3 > 0xED && iUTF3 < 0xF0 && ichar > 0x7F && ichar < 0xC0) {
210 iUTF3 = 4;
211 ul[nl] = ichar;
755494da 212 ++nl;
2e881a6f
A
213 } else if (iUTF3 > 0 && iUTF3 < 5 && ichar > 0x7F && ichar < 0xC0) {
214 iUTF3 = 0;
215 ul[nl] = ichar;
755494da 216 ++nl;
2e881a6f
A
217 } else {
218 iUTF3 = 0;
219 ul[nl] = ichar;
220 ul[nl + 1] = '\0';
221 debug((char *) "%s| %s: WARNING: Invalid UTF-8 sequence for Unicode %s\n", LogTime(), PROGRAM, ul);
222 if (ul)
223 xfree(ul);
224 return NULL;
225 }
226 } else if (iUTF4) {
227 if (iUTF4 == 0xF0 && ichar > 0x8F && ichar < 0xC0) {
228 iUTF4 = 1;
229 ul[nl] = ichar;
755494da 230 ++nl;
2e881a6f
A
231 } else if (iUTF4 > 0xF0 && iUTF3 < 0xF4 && ichar > 0x7F && ichar < 0xC0) {
232 iUTF4 = 2;
233 ul[nl] = ichar;
755494da 234 ++nl;
2e881a6f
A
235 } else if (iUTF4 == 0xF4 && ichar > 0x7F && ichar < 0x90) {
236 iUTF4 = 3;
237 ul[nl] = ichar;
755494da 238 ++nl;
2e881a6f
A
239 } else if (iUTF4 > 0 && iUTF4 < 5 && ichar > 0x7F && ichar < 0xC0) {
240 if (iUTF4 == 4)
241 iUTF4 = 0;
242 else
243 iUTF4 = 4;
244 ul[nl] = ichar;
755494da 245 ++nl;
2e881a6f
A
246 } else {
247 iUTF4 = 0;
248 ul[nl] = ichar;
249 ul[nl + 1] = '\0';
250 debug((char *) "%s| %s: WARNING: Invalid UTF-8 sequence for Unicode %s\n", LogTime(), PROGRAM, ul);
251 if (ul)
252 xfree(ul);
253 return NULL;
254 }
255 } else if (ichar < 0x80) {
256 /* UTF1 */
257 ul[nl] = ichar;
755494da 258 ++nl;
2e881a6f
A
259 } else if (ichar > 0xC1 && ichar < 0xE0) {
260 /* UTF2 (Latin) */
261 iUTF2 = ichar;
262 ul[nl] = ichar;
755494da 263 ++nl;
2e881a6f
A
264 } else if (ichar > 0xDF && ichar < 0xF0) {
265 /* UTF3 */
266 iUTF3 = ichar;
267 ul[nl] = ichar;
755494da 268 ++nl;
2e881a6f
A
269 } else if (ichar > 0xEF && ichar < 0xF5) {
270 /* UTF4 */
271 iUTF4 = ichar;
272 ul[nl] = ichar;
755494da 273 ++nl;
2e881a6f
A
274 } else {
275 ul[nl] = ichar;
276 ul[nl + 1] = '\0';
277 debug((char *) "%s| %s: WARNING: Invalid UTF-8 sequence for Unicode %s\n", LogTime(), PROGRAM, ul);
278 if (ul)
279 xfree(ul);
280 return NULL;
281 }
755494da 282 ++n;
b1218840
AJ
283 }
284
285 ul[nl] = '\0';
286 if (iUTF2 || iUTF3 || iUTF4) {
2e881a6f
A
287 debug((char *) "%s| %s: INFO: iUTF2: %d iUTF3: %d iUTF4: %d\n", LogTime(), PROGRAM, iUTF2, iUTF3, iUTF4);
288 debug((char *) "%s| %s: WARNING: Invalid UTF-8 sequence for Unicode %s\n", LogTime(), PROGRAM, ul);
289 if (ul)
290 xfree(ul);
291 return NULL;
b1218840
AJ
292 }
293 if (flag && upd)
2e881a6f 294 ul = strcat(ul, upd);
b1218840
AJ
295 return ul;
296}
297
b1218840
AJ
298int
299create_gd(struct main_args *margs)
300{
301 char *gp, *dp;
302 char *hp1, *hp2, *up;
303 char *p;
304 struct gdstruct *gdsp = NULL, *gdspn = NULL;
305 /*
306 * Group list format:
307 *
308 * glist=Pattern1[:Pattern2]
309 *
2e881a6f
A
310 * Pattern=Group Group for all domains(including non Kerberos domains using ldap url options) if no
311 * other group definition for domain exists or users without
b1218840
AJ
312 * domain information.
313 * gdstruct.domain=NULL, gdstruct.group=Group
2e881a6f 314 *
b1218840 315 * or Pattern=Group@ Group for all Kerberos domains if no other group definition
2e881a6f 316 * exists
b1218840
AJ
317 * gdstruct.domain="", gdstruct.group=Group
318 *
319 * or Pattern=Group@Domain Group for a specific Kerberos domain
320 * gdstruct.domain=Domain, gdstruct.group=Group
321 *
322 *
323 */
324 hp1 = hex_utf_char(margs, 0);
325 hp2 = hex_utf_char(margs, 1);
326 up = utf8dup(margs);
327 p = up;
328 if (hp1) {
2e881a6f
A
329 if (hp2) {
330 if (up) {
331 p = (char *) xmalloc(strlen(up) + strlen(hp1) + strlen(hp2) + 2);
332 strcpy(p, up);
333 strcat(p, ":");
334 strcat(p, hp1);
335 strcat(p, ":");
336 strcat(p, hp2);
337 } else {
338 p = (char *) xmalloc(strlen(hp1) + strlen(hp2) + 1);
339 strcpy(p, hp1);
340 strcat(p, ":");
341 strcat(p, hp2);
342 }
343 } else {
344 if (up) {
345 p = (char *) xmalloc(strlen(up) + strlen(hp1) + 1);
346 strcpy(p, up);
347 strcat(p, ":");
348 strcat(p, hp1);
349 } else
350 p = hp1;
351 }
b1218840 352 } else {
2e881a6f
A
353 if (hp2) {
354 if (up) {
355 p = (char *) xmalloc(strlen(up) + strlen(hp2) + 1);
356 strcpy(p, up);
357 strcat(p, ":");
358 strcat(p, hp2);
359 } else
360 p = hp2;
361 } else
362 p = up;
b1218840
AJ
363 }
364 gp = p;
365 debug((char *) "%s| %s: INFO: Group list %s\n", LogTime(), PROGRAM, p ? p : "NULL");
366 dp = NULL;
367
368 if (!p) {
2e881a6f
A
369 debug((char *) "%s| %s: ERROR: No groups defined.\n", LogTime(), PROGRAM);
370 return (1);
b1218840
AJ
371 }
372 while (*p) { /* loop over group list */
2e881a6f 373 if (*p == '\n' || *p == '\r') { /* Ignore CR and LF if exist */
755494da 374 ++p;
2e881a6f
A
375 continue;
376 }
377 if (*p == '@') { /* end of group name - start of domain name */
378 if (p == gp) { /* empty group name not allowed */
379 debug((char *) "%s| %s: ERROR: No group defined for domain %s\n", LogTime(), PROGRAM, p);
380 return (1);
381 }
382 *p = '\0';
755494da 383 ++p;
2e881a6f
A
384 gdsp = init_gd();
385 gdsp->group = gp;
386 if (gdspn) /* Have already an existing structure */
387 gdsp->next = gdspn;
388 dp = p; /* after @ starts new domain name */
389 } else if (*p == ':') { /* end of group name or end of domain name */
390 if (p == gp) { /* empty group name not allowed */
391 debug((char *) "%s| %s: ERROR: No group defined for domain %s\n", LogTime(), PROGRAM, p);
392 return (1);
393 }
394 *p = '\0';
755494da 395 ++p;
2e881a6f
A
396 if (dp) { /* end of domain name */
397 gdsp->domain = xstrdup(dp);
398 dp = NULL;
399 } else { /* end of group name and no domain name */
400 gdsp = init_gd();
401 gdsp->group = gp;
402 if (gdspn) /* Have already an existing structure */
403 gdsp->next = gdspn;
404 }
405 gdspn = gdsp;
406 gp = p; /* after : starts new group name */
407 debug((char *) "%s| %s: INFO: Group %s Domain %s\n", LogTime(), PROGRAM, gdsp->group, gdsp->domain ? gdsp->domain : "NULL");
408 } else
755494da 409 ++p;
b1218840
AJ
410 }
411 if (p == gp) { /* empty group name not allowed */
2e881a6f
A
412 debug((char *) "%s| %s: ERROR: No group defined for domain %s\n", LogTime(), PROGRAM, p);
413 return (1);
b1218840
AJ
414 }
415 if (dp) { /* end of domain name */
2e881a6f 416 gdsp->domain = xstrdup(dp);
b1218840 417 } else { /* end of group name and no domain name */
2e881a6f
A
418 gdsp = init_gd();
419 gdsp->group = gp;
420 if (gdspn) /* Have already an existing structure */
421 gdsp->next = gdspn;
b1218840
AJ
422 }
423 debug((char *) "%s| %s: INFO: Group %s Domain %s\n", LogTime(), PROGRAM, gdsp->group, gdsp->domain ? gdsp->domain : "NULL");
424
425 margs->groups = gdsp;
426 return (0);
427}
428#endif