~ubuntu-branches/debian/stretch/haproxy/stretch

« back to all changes in this revision

Viewing changes to src/acl.c

  • Committer: Package Import Robot
  • Author(s): Vincent Bernat, Apollon Oikonomopoulos, Vincent Bernat, Prach Pongpanich
  • Date: 2013-05-06 20:02:14 UTC
  • mfrom: (1.1.12)
  • Revision ID: package-import@ubuntu.com-20130506200214-36s6p81fsa5zqybt
Tags: 1.4.23-1
[ Apollon Oikonomopoulos ]
* New upstream version (Closes: #643650, #678953)
   + This fixes CVE-2012-2942 (Closes: #674447)
   + This fixes CVE-2013-1912 (Closes: #704611)
* Ship vim addon as vim-haproxy (Closes: #702893)
* Check for the configuration file after sourcing /etc/default/haproxy
  (Closes: #641762)
* Use /dev/log for logging by default (Closes: #649085)

[ Vincent Bernat ]
* debian/control:
   + add Vcs-* fields
   + switch maintenance to Debian HAProxy team. (Closes: #706890)
   + drop dependency to quilt: 3.0 (quilt) format is in use.
* debian/rules:
   + don't explicitly call dh_installchangelog.
   + use dh_installdirs to install directories.
   + use dh_install to install error and configuration files.
   + switch to `linux2628` Makefile target for Linux.
* debian/postrm:
   + remove haproxy user and group on purge.
* Ship a more minimal haproxy.cfg file: no `listen` blocks but `global`
  and `defaults` block with appropriate configuration to use chroot and
  logging in the expected way.

[ Prach Pongpanich ]
* debian/copyright:
   + add missing copyright holders
   + update years of copyright
* debian/rules:
   + build with -Wl,--as-needed to get rid of unnecessary depends
* Remove useless files in debian/haproxy.{docs,examples}
* Update debian/watch file, thanks to Bart Martens

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 * ACL management functions.
3
3
 *
4
 
 * Copyright 2000-2008 Willy Tarreau <w@1wt.eu>
 
4
 * Copyright 2000-2011 Willy Tarreau <w@1wt.eu>
5
5
 *
6
6
 * This program is free software; you can redistribute it and/or
7
7
 * modify it under the terms of the GNU General Public License
251
251
        return ACL_PAT_FAIL;
252
252
}
253
253
 
 
254
/* Background: Fast way to find a zero byte in a word
 
255
 * http://graphics.stanford.edu/~seander/bithacks.html#ZeroInWord
 
256
 * hasZeroByte = (v - 0x01010101UL) & ~v & 0x80808080UL;
 
257
 *
 
258
 * To look for 4 different byte values, xor the word with those bytes and
 
259
 * then check for zero bytes:
 
260
 *
 
261
 * v = (((unsigned char)c * 0x1010101U) ^ delimiter)
 
262
 * where <delimiter> is the 4 byte values to look for (as an uint)
 
263
 * and <c> is the character that is being tested
 
264
 */
 
265
static inline unsigned int is_delimiter(unsigned char c, unsigned int mask)
 
266
{
 
267
        mask ^= (c * 0x01010101); /* propagate the char to all 4 bytes */
 
268
        return (mask - 0x01010101) & ~mask & 0x80808080U;
 
269
}
 
270
 
 
271
static inline unsigned int make_4delim(unsigned char d1, unsigned char d2, unsigned char d3, unsigned char d4)
 
272
{
 
273
        return d1 << 24 | d2 << 16 | d3 << 8 | d4;
 
274
}
 
275
 
254
276
/* This one is used by other real functions. It checks that the pattern is
255
277
 * included inside the tested string, but enclosed between the specified
256
 
 * delimitor, or a '/' or a '?' or at the beginning or end of the string.
257
 
 * The delimitor is stripped at the beginning or end of the pattern.
 
278
 * delimiters or at the beginning or end of the string. The delimiters are
 
279
 * provided as an unsigned int made by make_4delim() and match up to 4 different
 
280
 * delimiters. Delimiters are stripped at the beginning and end of the pattern.
258
281
 */
259
 
static int match_word(struct acl_test *test, struct acl_pattern *pattern, char delim)
 
282
static int match_word(struct acl_test *test, struct acl_pattern *pattern, unsigned int delimiters)
260
283
{
261
284
        int may_match, icase;
262
285
        char *c, *end;
265
288
 
266
289
        pl = pattern->len;
267
290
        ps = pattern->ptr.str;
268
 
        while (pl > 0 && (*ps == delim || *ps == '/' || *ps == '?')) {
 
291
 
 
292
        while (pl > 0 && is_delimiter(*ps, delimiters)) {
269
293
                pl--;
270
294
                ps++;
271
295
        }
272
296
 
273
 
        while (pl > 0 &&
274
 
               (ps[pl - 1] == delim || ps[pl - 1] == '/' || ps[pl - 1] == '?'))
 
297
        while (pl > 0 && is_delimiter(ps[pl - 1], delimiters))
275
298
                pl--;
276
299
 
277
300
        if (pl > test->len)
281
304
        icase = pattern->flags & ACL_PAT_F_IGNORE_CASE;
282
305
        end = test->ptr + test->len - pl;
283
306
        for (c = test->ptr; c <= end; c++) {
284
 
                if (*c == '/' || *c == delim || *c == '?') {
 
307
                if (is_delimiter(*c, delimiters)) {
285
308
                        may_match = 1;
286
309
                        continue;
287
310
                }
292
315
                if (icase) {
293
316
                        if ((tolower(*c) == tolower(*ps)) &&
294
317
                            (strncasecmp(ps, c, pl) == 0) &&
295
 
                            (c == end || c[pl] == '/' || c[pl] == delim || c[pl] == '?'))
 
318
                            (c == end || is_delimiter(c[pl], delimiters)))
296
319
                                return ACL_PAT_PASS;
297
320
                } else {
298
321
                        if ((*c == *ps) &&
299
322
                            (strncmp(ps, c, pl) == 0) &&
300
 
                            (c == end || c[pl] == '/' || c[pl] == delim || c[pl] == '?'))
 
323
                            (c == end || is_delimiter(c[pl], delimiters)))
301
324
                                return ACL_PAT_PASS;
302
325
                }
303
326
                may_match = 0;
306
329
}
307
330
 
308
331
/* Checks that the pattern is included inside the tested string, but enclosed
309
 
 * between slashes or at the beginning or end of the string. Slashes at the
310
 
 * beginning or end of the pattern are ignored.
 
332
 * between the delimiters '?' or '/' or at the beginning or end of the string.
 
333
 * Delimiters at the beginning or end of the pattern are ignored.
311
334
 */
312
335
int acl_match_dir(struct acl_test *test, struct acl_pattern *pattern)
313
336
{
314
 
        return match_word(test, pattern, '/');
 
337
        return match_word(test, pattern, make_4delim('/', '?', '?', '?'));
315
338
}
316
339
 
317
340
/* Checks that the pattern is included inside the tested string, but enclosed
318
 
 * between dots or at the beginning or end of the string. Dots at the beginning
319
 
 * or end of the pattern are ignored.
 
341
 * between the delmiters '/', '?', '.' or ":" or at the beginning or end of
 
342
 * the string. Delimiters at the beginning or end of the pattern are ignored.
320
343
 */
321
344
int acl_match_dom(struct acl_test *test, struct acl_pattern *pattern)
322
345
{
323
 
        return match_word(test, pattern, '.');
 
346
        return match_word(test, pattern, make_4delim('/', '?', '.', ':'));
324
347
}
325
348
 
326
349
/* Checks that the integer in <test> is included between min and max */
332
355
        return ACL_PAT_FAIL;
333
356
}
334
357
 
 
358
/* Checks that the length of the pattern in <test> is included between min and max */
 
359
int acl_match_len(struct acl_test *test, struct acl_pattern *pattern)
 
360
{
 
361
        if ((!pattern->val.range.min_set || pattern->val.range.min <= test->len) &&
 
362
            (!pattern->val.range.max_set || test->len <= pattern->val.range.max))
 
363
                return ACL_PAT_PASS;
 
364
        return ACL_PAT_FAIL;
 
365
}
 
366
 
335
367
int acl_match_ip(struct acl_test *test, struct acl_pattern *pattern)
336
368
{
337
369
        struct in_addr *s;
776
808
        opaque = 0;
777
809
        pattern = NULL;
778
810
        args[1] = "";
779
 
        while (fgets(trash, sizeof(trash), file) != NULL) {
780
 
 
 
811
        while (fgets(trash, trashlen, file) != NULL) {
781
812
                c = trash;
782
813
 
783
814
                /* ignore lines beginning with a dash */
1199
1230
 
1200
1231
                if (!cur_suite) {
1201
1232
                        cur_suite = (struct acl_term_suite *)calloc(1, sizeof(*cur_suite));
1202
 
                        if (cur_term == NULL)
 
1233
                        if (cur_suite == NULL)
1203
1234
                                goto out_free_term;
1204
1235
                        LIST_INIT(&cur_suite->terms);
1205
1236
                        LIST_ADDQ(&cond->suites, &cur_suite->list);