Commit 87ffa18d authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

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: http://www.varnish-cache.org/svn/trunk/varnish-cache@558 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent 5f67fbdb
...@@ -19,14 +19,85 @@ ...@@ -19,14 +19,85 @@
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <netdb.h> #include <netdb.h>
#include <netinet/in.h>
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 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; struct addrinfo *a1;
(void)ap; struct sockaddr_in *sin1, *sin2;
return (0);
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 void
......
...@@ -33,6 +33,7 @@ SLTM(RxHeader) ...@@ -33,6 +33,7 @@ SLTM(RxHeader)
SLTM(TxHeader) SLTM(TxHeader)
SLTM(LostHeader) SLTM(LostHeader)
SLTM(TTL) SLTM(TTL)
SLTM(VCL_acl)
SLTM(VCL_call) SLTM(VCL_call)
SLTM(VCL_trace) SLTM(VCL_trace)
SLTM(VCL_return) SLTM(VCL_return)
......
/* /*
* $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! * NB: This file is machine generated, DO NOT EDIT!
* *
......
...@@ -20,14 +20,15 @@ struct vrt_ref { ...@@ -20,14 +20,15 @@ struct vrt_ref {
struct vrt_acl { struct vrt_acl {
unsigned char not; unsigned char not;
unsigned char paren;
unsigned char mask; unsigned char mask;
unsigned char paren;
const char *name; const char *name;
const char *desc;
void *priv; void *priv;
}; };
/* ACL related */ /* 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_init(struct vrt_acl *);
void VRT_acl_fini(struct vrt_acl *); void VRT_acl_fini(struct vrt_acl *);
......
...@@ -33,7 +33,7 @@ vcc_Cond_Ip(struct var *vp, struct tokenlist *tl) ...@@ -33,7 +33,7 @@ vcc_Cond_Ip(struct var *vp, struct tokenlist *tl)
vcc_NextToken(tl); vcc_NextToken(tl);
ExpectErr(tl, ID); ExpectErr(tl, ID);
AddRef(tl, tl->t, R_ACL); 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); vcc_NextToken(tl);
break; break;
default: default:
...@@ -51,6 +51,7 @@ vcc_Acl(struct tokenlist *tl) ...@@ -51,6 +51,7 @@ vcc_Acl(struct tokenlist *tl)
{ {
unsigned mask, para, not; unsigned mask, para, not;
struct token *t, *an; struct token *t, *an;
char *p;
vcc_NextToken(tl); vcc_NextToken(tl);
...@@ -71,13 +72,13 @@ vcc_Acl(struct tokenlist *tl) ...@@ -71,13 +72,13 @@ vcc_Acl(struct tokenlist *tl)
not = para = mask = 0; not = para = mask = 0;
if (tl->t->tok == '!') { if (tl->t->tok == '(') {
not = 1; para = 1;
vcc_NextToken(tl); vcc_NextToken(tl);
} }
if (tl->t->tok == '(') { if (tl->t->tok == '!') {
para = 1; not = 1;
vcc_NextToken(tl); vcc_NextToken(tl);
} }
...@@ -90,7 +91,19 @@ vcc_Acl(struct tokenlist *tl) ...@@ -90,7 +91,19 @@ vcc_Acl(struct tokenlist *tl)
ExpectErr(tl, CNUM); ExpectErr(tl, CNUM);
mask = UintVal(tl); 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) { if (para) {
ExpectErr(tl, ')'); ExpectErr(tl, ')');
...@@ -99,7 +112,7 @@ vcc_Acl(struct tokenlist *tl) ...@@ -99,7 +112,7 @@ vcc_Acl(struct tokenlist *tl)
ExpectErr(tl, ';'); ExpectErr(tl, ';');
vcc_NextToken(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; tl->indent -= INDENT;
Fc(tl, 1, "};\n\n"); Fc(tl, 1, "};\n\n");
......
...@@ -486,14 +486,15 @@ vcl_output_lang_h(FILE *f) ...@@ -486,14 +486,15 @@ vcl_output_lang_h(FILE *f)
fputs("\n", f); fputs("\n", f);
fputs("struct vrt_acl {\n", f); fputs("struct vrt_acl {\n", f);
fputs(" unsigned char not;\n", f); fputs(" unsigned char not;\n", f);
fputs(" unsigned char paren;\n", f);
fputs(" unsigned char mask;\n", f); fputs(" unsigned char mask;\n", f);
fputs(" unsigned char paren;\n", f);
fputs(" const char *name;\n", f); fputs(" const char *name;\n", f);
fputs(" const char *desc;\n", f);
fputs(" void *priv;\n", f); fputs(" void *priv;\n", f);
fputs("};\n", f); fputs("};\n", f);
fputs("\n", f); fputs("\n", f);
fputs("/* ACL related */\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_init(struct vrt_acl *);\n", f);
fputs("void VRT_acl_fini(struct vrt_acl *);\n", f); fputs("void VRT_acl_fini(struct vrt_acl *);\n", f);
fputs("\n", f); fputs("\n", f);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment