From 628972cf5954f4e74844442b964790d472430f4d Mon Sep 17 00:00:00 2001 From: phk Date: Sat, 22 Jul 2006 10:41:00 +0000 Subject: [PATCH] Change the acl syntax slightly: the ( ... ) should enclose all of the rule (ie: also ! and /mask if present). Implement matching for IPv4. Acl tests are shmlogged as follows (doc candidate): shmlog tag: VCL_actl "NO_MATCH $acl" client did not match access list $acl "FAIL $acl $rule" getaddrinfo(3) failed on $rule which had a '!' "MATCH $acl $rule" client matched $rule "NEG_MATCH $acl $rule" client matched negated (!) $rule git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@558 d4fa192b-c00b-0410-8231-f00ffab90ce4 --- varnish-cache/bin/varnishd/cache_vrt_acl.c | 79 ++++++++++++++++++++-- varnish-cache/include/shmlog_tags.h | 1 + varnish-cache/include/vcl_returns.h | 2 +- varnish-cache/include/vrt.h | 5 +- varnish-cache/lib/libvcl/vcc_acl.c | 27 ++++++-- varnish-cache/lib/libvcl/vcc_fixed_token.c | 5 +- 6 files changed, 103 insertions(+), 16 deletions(-) diff --git a/varnish-cache/bin/varnishd/cache_vrt_acl.c b/varnish-cache/bin/varnishd/cache_vrt_acl.c index 3a461de6..4674cef2 100644 --- a/varnish-cache/bin/varnishd/cache_vrt_acl.c +++ b/varnish-cache/bin/varnishd/cache_vrt_acl.c @@ -19,14 +19,85 @@ #include #include #include +#include +static unsigned ipv4mask[] = { + [0] = 0xffffffff, +#define M(n) [n] = (0xffffffff << (32 - n)) + M( 1), M( 2), M( 3), M( 4), M( 5), M( 6), M( 7), M( 8), M( 9), M(10), + M(11), M(12), M(13), M(14), M(15), M(16), M(17), M(18), M(19), M(20), + M(21), M(22), M(23), M(24), M(25), M(26), M(27), M(28), M(29), M(30), + M(31), M(32) +}; + +static int +vrt_acl_vsl(struct sess *sp, const char *acl, struct vrt_acl *ap, int r) +{ + + assert(ap != NULL); + if (ap->name == NULL) { + assert(r == 0); + VSL(SLT_VCL_acl, sp->fd, "NO_MATCH %s", acl); + return (r); + } + if (ap->priv == NULL) { + assert(r == 0); + VSL(SLT_VCL_acl, sp->fd, "FAIL %s %s", acl, ap->desc); + return (r); + } + + VSL(SLT_VCL_acl, sp->fd, "%s %s %s", + r ? "MATCH" : "NEG_MATCH", acl, ap->desc); + return (r); +} + int -VRT_acl_match(struct sess *sp, struct vrt_acl *ap) +VRT_acl_match(struct sess *sp, const char *acl, struct vrt_acl *ap) { - (void)sp; - (void)ap; - return (0); + struct addrinfo *a1; + struct sockaddr_in *sin1, *sin2; + + if (sp->sockaddr->sa_family == AF_INET) { + assert(sp->sockaddrlen >= sizeof *sin1); + sin1 = (void*)sp->sockaddr; + } else { + sin1 = NULL; + } + + for ( ; ap->name != NULL; ap++) { + if (ap->priv == NULL && ap->paren) + continue; + if (ap->priv == NULL && ap->not) { + return (vrt_acl_vsl(sp, acl, ap, 0)); + } + if (ap->priv == NULL) + continue; + for (a1 = ap->priv; a1 != NULL; a1 = a1->ai_next) { + + /* only match the right family */ + if (a1->ai_family != sp->sockaddr->sa_family) + continue; + + if (a1->ai_family == AF_INET) { + assert(sin1 != NULL); + assert(a1->ai_addrlen >= sizeof (*sin2)); + sin2 = (void*)a1->ai_addr; + if (0 == (( + htonl(sin1->sin_addr.s_addr) ^ + htonl(sin2->sin_addr.s_addr)) & + ipv4mask[ap->mask > 32 ? 32 : ap->mask])) + return ( + vrt_acl_vsl(sp, acl, ap, !ap->not)); + continue; + } + + /* Not rules for unknown protos match */ + if (ap->not) + return (vrt_acl_vsl(sp, acl, ap, 0)); + } + } + return (vrt_acl_vsl(sp, acl, ap, 0)); } void diff --git a/varnish-cache/include/shmlog_tags.h b/varnish-cache/include/shmlog_tags.h index 78f5a138..176eb364 100644 --- a/varnish-cache/include/shmlog_tags.h +++ b/varnish-cache/include/shmlog_tags.h @@ -33,6 +33,7 @@ SLTM(RxHeader) SLTM(TxHeader) SLTM(LostHeader) SLTM(TTL) +SLTM(VCL_acl) SLTM(VCL_call) SLTM(VCL_trace) SLTM(VCL_return) diff --git a/varnish-cache/include/vcl_returns.h b/varnish-cache/include/vcl_returns.h index 9fa9a14b..ef965c1b 100644 --- a/varnish-cache/include/vcl_returns.h +++ b/varnish-cache/include/vcl_returns.h @@ -1,5 +1,5 @@ /* - * $Id: vcc_gen_fixed_token.tcl 553 2006-07-21 21:57:43Z phk $ + * $Id: vcc_gen_fixed_token.tcl 556 2006-07-22 09:38:09Z phk $ * * NB: This file is machine generated, DO NOT EDIT! * diff --git a/varnish-cache/include/vrt.h b/varnish-cache/include/vrt.h index 9598bb40..73cbcf63 100644 --- a/varnish-cache/include/vrt.h +++ b/varnish-cache/include/vrt.h @@ -20,14 +20,15 @@ struct vrt_ref { struct vrt_acl { unsigned char not; - unsigned char paren; unsigned char mask; + unsigned char paren; const char *name; + const char *desc; void *priv; }; /* ACL related */ -int VRT_acl_match(struct sess *, struct vrt_acl *); +int VRT_acl_match(struct sess *, const char *, struct vrt_acl *); void VRT_acl_init(struct vrt_acl *); void VRT_acl_fini(struct vrt_acl *); diff --git a/varnish-cache/lib/libvcl/vcc_acl.c b/varnish-cache/lib/libvcl/vcc_acl.c index 50b0d548..13ba8fe1 100644 --- a/varnish-cache/lib/libvcl/vcc_acl.c +++ b/varnish-cache/lib/libvcl/vcc_acl.c @@ -33,7 +33,7 @@ vcc_Cond_Ip(struct var *vp, struct tokenlist *tl) vcc_NextToken(tl); ExpectErr(tl, ID); AddRef(tl, tl->t, R_ACL); - Fc(tl, 1, "VRT_acl_match(sp, acl_%T)\n", tl->t); + Fc(tl, 1, "VRT_acl_match(sp, \"%T\", acl_%T)\n", tl->t, tl->t); vcc_NextToken(tl); break; default: @@ -51,6 +51,7 @@ vcc_Acl(struct tokenlist *tl) { unsigned mask, para, not; struct token *t, *an; + char *p; vcc_NextToken(tl); @@ -71,13 +72,13 @@ vcc_Acl(struct tokenlist *tl) not = para = mask = 0; - if (tl->t->tok == '!') { - not = 1; + if (tl->t->tok == '(') { + para = 1; vcc_NextToken(tl); } - if (tl->t->tok == '(') { - para = 1; + if (tl->t->tok == '!') { + not = 1; vcc_NextToken(tl); } @@ -90,7 +91,19 @@ vcc_Acl(struct tokenlist *tl) ExpectErr(tl, CNUM); mask = UintVal(tl); } - Fc(tl, 1, "{ %u, %u, %u, %T },\n", not, mask, para, t); + Fc(tl, 1, "{ %u, %u, %u, %T, \"", not, mask, para, t); + if (para) + Fc(tl, 0, "("); + if (not) + Fc(tl, 0, "!"); + p = EncString(t); + Fc(tl, 0, "%s", p); + free(p); + if (mask) + Fc(tl, 0, "/%u", mask); + if (para) + Fc(tl, 0, ")"); + Fc(tl, 0, "\" },\n"); if (para) { ExpectErr(tl, ')'); @@ -99,7 +112,7 @@ vcc_Acl(struct tokenlist *tl) ExpectErr(tl, ';'); vcc_NextToken(tl); } - Fc(tl, 1, "{ 0, 0, 0, (void*)0}\n", 0, 0); + Fc(tl, 1, "{ 0, 0, 0, (void*)0, ""}\n", 0, 0); tl->indent -= INDENT; Fc(tl, 1, "};\n\n"); diff --git a/varnish-cache/lib/libvcl/vcc_fixed_token.c b/varnish-cache/lib/libvcl/vcc_fixed_token.c index 58bef42c..4d8870c2 100644 --- a/varnish-cache/lib/libvcl/vcc_fixed_token.c +++ b/varnish-cache/lib/libvcl/vcc_fixed_token.c @@ -486,14 +486,15 @@ vcl_output_lang_h(FILE *f) fputs("\n", f); fputs("struct vrt_acl {\n", f); fputs(" unsigned char not;\n", f); - fputs(" unsigned char paren;\n", f); fputs(" unsigned char mask;\n", f); + fputs(" unsigned char paren;\n", f); fputs(" const char *name;\n", f); + fputs(" const char *desc;\n", f); fputs(" void *priv;\n", f); fputs("};\n", f); fputs("\n", f); fputs("/* ACL related */\n", f); - fputs("int VRT_acl_match(struct sess *, struct vrt_acl *);\n", f); + fputs("int VRT_acl_match(struct sess *, const char *, struct vrt_acl *);\n", f); fputs("void VRT_acl_init(struct vrt_acl *);\n", f); fputs("void VRT_acl_fini(struct vrt_acl *);\n", f); fputs("\n", f); -- 2.39.5