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

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors