r17878 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r17877‎ | r17878 | r17879 >
Date:04:35, 23 November 2006
Author:river
Status:old
Tags:
Comment:
move acl implementation to libwillow and document it
Modified paths:
  • /trunk/willow/src/include/acl.h (modified) (history)
  • /trunk/willow/src/libwillow/Makefile.in (modified) (history)
  • /trunk/willow/src/libwillow/acl.cc (added) (history)
  • /trunk/willow/src/libwillow/acl.cc (added) (history)
  • /trunk/willow/src/wreadlog/Makefile.in (modified) (history)
  • /trunk/willow/src/wreadlog/acl.cc (deleted) (history)

Diff [purge]

Index: trunk/willow/src/include/acl.h
@@ -71,13 +71,37 @@
7272 #define ACLFL_NONE 0x00000000
7373 #define ACLFL_LOG 0x00000001
7474
 75+/**
 76+ * A prefix in an ACL entry. Stores the address family, address and prefix
 77+ * length. Both IPv4 and IPv6 prefixes are supported.
 78+ *
 79+ * The ACL does not distinguish between IPv4 and IPv6 addresses. To match
 80+ * on both address families, two ACLs should be used.
 81+ *
 82+ * This ACL implementation is O(n) for lookups. For a an unordered, but
 83+ * much faster, access list, see radix.h
 84+ */
7585 struct aclprefix
7686 {
77 - bool match (const sockaddr *) const;
78 - bool match (const aclprefix *) const;
 87+ /**
 88+ * Match the provided socket address against this ACL entry. The prefix
 89+ * length is assumed to be 32 bits (for IPv4) or 128 bits (for IPv6).
 90+ *
 91+ * \param addr address to match
 92+ * \returns true if the address matches, otherwise false
 93+ */
 94+ bool match (const sockaddr *addr) const;
7995
80 - uint8_t family;
81 - uint8_t prefixlen;
 96+ /**
 97+ * Match another ACE against this one.
 98+ *
 99+ * \param pfx prefix to match
 100+ * \returns true if the prefix matches, otherwise false
 101+ */
 102+ bool match (const aclprefix *pfx) const;
 103+
 104+ uint8_t family; /**< Address family, AF_INET or AF_INET6 */
 105+ uint8_t prefixlen; /**< Prefix length of this ACE */
82106 union {
83107 uint8_t val[16];
84108 in_addr prefix4;
@@ -87,20 +111,64 @@
88112 } u;
89113 };
90114
 115+/**
 116+ * One entry (ACE) in an ACL.
 117+ */
91118 struct aclnode {
92 - aclprefix prefix;
93 - uint32_t action;
94 - uint32_t flags;
 119+ aclprefix prefix; /**< This entry's prefix */
 120+ uint32_t action; /**< Action to take, ACL_NONE, ACL_PASS or ACL_BLOCK */
 121+ uint32_t flags; /**< Can be ACLFL_LOG to log this match. */
95122 };
96123
 124+/**
 125+ * An ACL. Call add() to add entries to the ACL, then match() addresses
 126+ * against the list.
 127+ */
97128 struct acl {
98 - acl (int family, string const &name = "");
 129+ /**
 130+ * Create a new ACL with the given address family and name.
 131+ *
 132+ * \param family address family, AF_INET or AF_INET6
 133+ * \param name name of this ACL. The ACL itself never uses this value.
 134+ */
 135+ acl (int family, string const &name = "");
 136+
 137+ /**
 138+ * Return the name of this ACL.
 139+ */
99140 string const & name (void) const;
100 - void name (string const &);
 141+
 142+ /**
 143+ * Rename this ACL.
 144+ * \param newname new name for the ACL
 145+ */
 146+ void name (string const &newname);
 147+
 148+ /**
 149+ * Return this ACL's address family.
 150+ */
101151 int family (void) const;
102 - void family (int);
 152+
 153+ /**
 154+ * Add a new entry to this ACL.
 155+ *
 156+ * \param prefix IP prefix to add, without the mask
 157+ * \param prefixlen length of the prefix to add, in bits
 158+ * \param action action to take on this entry, one of ACL_NONE,
 159+ * ACL_PASS or ACP_BLOCK
 160+ * \param flags flags for this entry, 0 or ACLFL_LOG
 161+ *
 162+ * \return true if the entry was added, false if the prefix could
 163+ * not be parsed.
 164+ */
103165 bool add (const char *prefix, const uint8_t prefixlen,
104166 const uint32_t action, const uint32_t flags);
 167+
 168+ /**
 169+ * Match an IP address against this ACL.
 170+ *
 171+ * \return the matching ACE if any, otherwise NULL.
 172+ */
105173 const aclnode * match (const sockaddr *sa);
106174
107175 uint8_t _family;
@@ -108,4 +176,4 @@
109177 string _name;
110178 };
111179
112 -#endif /* __ACL_H */
 180+#endif /* ACL_H */
Index: trunk/willow/src/libwillow/Makefile.in
@@ -13,6 +13,7 @@
1414 LIB=willow
1515 CPPFLAGS = -I../include
1616 SRCS= \
 17+ acl.cc \
1718 htcp.cc \
1819 libwillow.cc \
1920 mbuffer.cc \
Index: trunk/willow/src/libwillow/acl.cc
@@ -0,0 +1,162 @@
 2+/*
 3+ * Willow: Lightweight HTTP reverse-proxy.
 4+ * acl: ACL definitions.
 5+ * Copyright (C) 2001, 2002 Pim van Pelt <pim@ipng.nl>
 6+ * Copyright 2006 River Tarnell <river@attenuate.org>
 7+ *
 8+ * This is from DAPd package (http://dapd.sourceforge.net). It was
 9+ * released under the GPL and relicensed with permission from
 10+ * Pim van Pelt.
 11+ *
 12+ * Redistribution and use in source and binary forms, with or without
 13+ * modification, are permitted provided that the following conditions
 14+ * are met:
 15+ *
 16+ * * Redistributions of source code must retain the above copyright
 17+ * notice, this list of conditions and the following disclaimer.
 18+ *
 19+ * * Redistributions in binary form must reproduce the above
 20+ * copyright notice, this list of conditions and the following
 21+ * disclaimer in the documentation and/or other materials provided
 22+ * with the distribution.
 23+ *
 24+ * * Neither the name of the authors nor the names of contributors
 25+ * may be used to endorse or promote products derived from this
 26+ * software without specific prior written permission.
 27+ *
 28+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 29+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 30+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 31+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 32+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 33+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 34+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 35+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 36+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 37+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 38+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 39+ * POSSIBILITY OF SUCH DAMAGE.
 40+ */
 41+/* From: Id: acl.c,v 1.10 2004/04/15 07:29:57 pim Exp */
 42+/* $Id$ */
 43+
 44+#include <iostream>
 45+#include <cstring>
 46+using std::memcpy;
 47+
 48+#include "acl.h"
 49+
 50+static uint8_t maskbit[] = {0x00, 0x80, 0xc0, 0xe0, 0xf0,
 51+ 0xf8, 0xfc, 0xfe, 0xff};
 52+#define PNBBY 8
 53+#define MASKBIT(offset) ((0xff << (PNBBY - (offset))) & 0xff)
 54+
 55+bool
 56+aclprefix::match (const aclprefix *p) const
 57+{
 58+int offset;
 59+int shift;
 60+
 61+ uint8_t *np = (uint8_t *)&this->u.val;
 62+ uint8_t *pp = (uint8_t *)&p->u.val;
 63+
 64+ /* If n's prefix is longer than p's one return 0. */
 65+ if (this->prefixlen > p->prefixlen)
 66+ return false;
 67+ offset = this->prefixlen / PNBBY;
 68+ shift = this->prefixlen % PNBBY;
 69+ if (shift)
 70+ if (maskbit[shift] & (np[offset] ^ pp[offset]))
 71+ return false;
 72+ while (offset--)
 73+ if (np[offset] != pp[offset])
 74+ return false;
 75+
 76+ return true;
 77+}
 78+
 79+bool
 80+aclprefix::match (const sockaddr *sa) const
 81+{
 82+aclprefix a;
 83+ switch (sa->sa_family) {
 84+ case AF_INET: {
 85+ sockaddr_in *mysin = (sockaddr_in *) sa;
 86+ a.family = AF_INET;
 87+ a.prefixlen = 32;
 88+ memcpy (&a.u.val, &mysin->sin_addr, sizeof(in_addr));
 89+ break;
 90+ }
 91+#ifdef AF_INET6
 92+ case AF_INET6: {
 93+ sockaddr_in6 *mysin6 = (sockaddr_in6 *) sa;
 94+ a.family = AF_INET6;
 95+ a.prefixlen = 128;
 96+ memcpy (&a.u.val, &mysin6->sin6_addr, sizeof(in6_addr));
 97+ break;
 98+ }
 99+#endif
 100+ default:
 101+ return false;
 102+ }
 103+ if (sa->sa_family != this->family)
 104+ return false;
 105+ return this->match(&a);
 106+}
 107+
 108+acl::acl (int family_, string const &name_)
 109+ : _family(family_)
 110+ , _name(name_)
 111+{
 112+}
 113+
 114+const aclnode *
 115+acl::match (const sockaddr *sa)
 116+{
 117+aclnode *an;
 118+vector<aclnode>::const_iterator it, end;
 119+ if (acllist.empty())
 120+ return NULL;
 121+ if (_family != sa->sa_family)
 122+ return NULL;
 123+
 124+ for (it = acllist.begin(), end = acllist.end(); it != end; ++it) {
 125+ if (it->prefix.match(sa))
 126+ return &*it;
 127+ }
 128+ return NULL;
 129+}
 130+
 131+bool
 132+acl::add (const char *prefix, const uint8_t prefixlen, const uint32_t action, const uint32_t flags)
 133+{
 134+aclnode an;
 135+
 136+ an.prefix.family = _family;
 137+ an.prefix.prefixlen = prefixlen;
 138+ if (inet_pton(an.prefix.family, prefix, (void *)&an.prefix.u.val) <= 0) {
 139+ return false;
 140+ }
 141+ an.action = action;
 142+ an.flags = flags;
 143+ acllist.push_back(an);
 144+ return true;
 145+}
 146+
 147+void
 148+acl::name (string const &name)
 149+{
 150+ _name = name;
 151+}
 152+
 153+string const &
 154+acl::name (void) const
 155+{
 156+ return _name;
 157+}
 158+
 159+int
 160+acl::family(void) const
 161+{
 162+ return _family;
 163+}
Property changes on: trunk/willow/src/libwillow/acl.cc
___________________________________________________________________
Added: svn:keywords
1164 + Id Revision
Index: trunk/willow/src/wreadlog/acl.cc
@@ -1,208 +0,0 @@
2 -/*
3 - * Willow: Lightweight HTTP reverse-proxy.
4 - * acl: ACL definitions.
5 - * Copyright (C) 2001, 2002 Pim van Pelt <pim@ipng.nl>
6 - * Copyright 2006 River Tarnell <river@attenuate.org>
7 - *
8 - * This is from DAPd package (http://dapd.sourceforge.net). It was
9 - * released under the GPL and relicensed with permission from
10 - * Pim van Pelt.
11 - *
12 - * Redistribution and use in source and binary forms, with or without
13 - * modification, are permitted provided that the following conditions
14 - * are met:
15 - *
16 - * * Redistributions of source code must retain the above copyright
17 - * notice, this list of conditions and the following disclaimer.
18 - *
19 - * * Redistributions in binary form must reproduce the above
20 - * copyright notice, this list of conditions and the following
21 - * disclaimer in the documentation and/or other materials provided
22 - * with the distribution.
23 - *
24 - * * Neither the name of the authors nor the names of contributors
25 - * may be used to endorse or promote products derived from this
26 - * software without specific prior written permission.
27 - *
28 - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31 - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32 - * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33 - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34 - * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35 - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36 - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
37 - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38 - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39 - * POSSIBILITY OF SUCH DAMAGE.
40 - */
41 -/* From: Id: acl.c,v 1.10 2004/04/15 07:29:57 pim Exp */
42 -/* $Id$ */
43 -
44 -#include <iostream>
45 -#include <cstring>
46 -using std::memcpy;
47 -
48 -#include "acl.h"
49 -
50 -static uint8_t maskbit[] = {0x00, 0x80, 0xc0, 0xe0, 0xf0,
51 - 0xf8, 0xfc, 0xfe, 0xff};
52 -#define PNBBY 8
53 -#define MASKBIT(offset) ((0xff << (PNBBY - (offset))) & 0xff)
54 -
55 -bool
56 -aclprefix::match (const aclprefix *p) const
57 -{
58 -int offset;
59 -int shift;
60 -
61 - uint8_t *np = (uint8_t *)&this->u.val;
62 - uint8_t *pp = (uint8_t *)&p->u.val;
63 -
64 - /* If n's prefix is longer than p's one return 0. */
65 - if (this->prefixlen > p->prefixlen)
66 - return false;
67 - offset = this->prefixlen / PNBBY;
68 - shift = this->prefixlen % PNBBY;
69 - if (shift)
70 - if (maskbit[shift] & (np[offset] ^ pp[offset]))
71 - return false;
72 - while (offset--)
73 - if (np[offset] != pp[offset])
74 - return false;
75 -
76 - return true;
77 -}
78 -
79 -bool
80 -aclprefix::match (const sockaddr *sa) const
81 -{
82 -aclprefix a;
83 - switch (sa->sa_family) {
84 - case AF_INET: {
85 - sockaddr_in *mysin = (sockaddr_in *) sa;
86 - a.family = AF_INET;
87 - a.prefixlen = 32;
88 - memcpy (&a.u.val, &mysin->sin_addr, sizeof(in_addr));
89 - break;
90 - }
91 -#ifdef AF_INET6
92 - case AF_INET6: {
93 - sockaddr_in6 *mysin6 = (sockaddr_in6 *) sa;
94 - a.family = AF_INET6;
95 - a.prefixlen = 128;
96 - memcpy (&a.u.val, &mysin6->sin6_addr, sizeof(in6_addr));
97 - break;
98 - }
99 -#endif
100 - default:
101 - return false;
102 - }
103 - if (sa->sa_family != this->family)
104 - return false;
105 - return this->match(&a);
106 -}
107 -
108 -acl::acl (int family_, string const &name_)
109 - : _family(family_)
110 - , _name(name_)
111 -{
112 -}
113 -
114 -const aclnode *
115 -acl::match (const sockaddr *sa)
116 -{
117 -aclnode *an;
118 -vector<aclnode>::const_iterator it, end;
119 - if (acllist.empty())
120 - return NULL;
121 - if (_family != sa->sa_family)
122 - return NULL;
123 -
124 - for (it = acllist.begin(), end = acllist.end(); it != end; ++it) {
125 - if (it->prefix.match(sa))
126 - return &*it;
127 - }
128 - return NULL;
129 -}
130 -
131 -bool
132 -acl::add (const char *prefix, const uint8_t prefixlen, const uint32_t action, const uint32_t flags)
133 -{
134 -aclnode an;
135 -
136 - an.prefix.family = _family;
137 - an.prefix.prefixlen = prefixlen;
138 - if (inet_pton(an.prefix.family, prefix, (void *)&an.prefix.u.val) <= 0) {
139 - return false;
140 - }
141 - an.action = action;
142 - an.flags = flags;
143 - acllist.push_back(an);
144 - return true;
145 -}
146 -
147 -void
148 -acl::name (string const &name)
149 -{
150 - _name = name;
151 -}
152 -
153 -string const &
154 -acl::name (void) const
155 -{
156 - return _name;
157 -}
158 -
159 -int
160 -acl::family(void) const
161 -{
162 - return _family;
163 -}
164 -
165 -void
166 -acl::family(int f)
167 -{
168 - _family = f;
169 -}
170 -
171 -#ifdef STANDALONE
172 -int main ()
173 -{
174 - struct acl *acl;
175 - struct aclnode *aclnode;
176 - struct sockaddr_in6 a6;
177 - struct sockaddr_in a;
178 -
179 - acl = new acl;
180 - acl_setfamily (acl, AF_INET);
181 - acl_setname (acl, "dappekepatches");
182 -
183 - acl_node_add (acl, "10.0.0.0", 8, ACL_PASS, ACLFL_NONE);
184 - acl_node_add (acl, "172.16.0.0", 12, ACL_PASS, ACLFL_LOG);
185 - acl_node_add (acl, "192.168.0.0", 16, ACL_PASS, ACLFL_NONE);
186 - acl_node_add (acl, "0.0.0.0", 0, ACL_BLOCK, ACLFL_LOG);
187 -
188 - a.sin_family = AF_INET;
189 - if (inet_pton (AF_INET, "10.0.0.8", (void *)&a.sin_addr) <0) {
190 - printf ("inet_pton failed\n");
191 - return -1;
192 - }
193 - a6.sin6_family = AF_INET6;
194 - if (inet_pton (AF_INET6, "2001:6e0::2", (void *)&a6.sin6_addr) <0) {
195 - printf ("inet_pton failed\n");
196 - return -1;
197 - }
198 - aclnode = acl->match((struct sockaddr *)&a);
199 - if (!aclnode) {
200 - printf ("The address did not match in the ACL.\n");
201 - } else {
202 - printf ("The address matched. Action=%lu, flags=%lu\n", (unsigned long) aclnode->action, (unsigned long) aclnode->flags);
203 - printf ("The name is '%s'\n", acl->name);
204 - }
205 -
206 - acl_destroy (&acl);
207 - return 0;
208 -}
209 -#endif
Index: trunk/willow/src/wreadlog/Makefile.in
@@ -12,7 +12,6 @@
1313 BINDIR = @bindir@
1414 CPPFLAGS = -I../include
1515 BASESRCS = \
16 - acl.cc \
1716 packet_decoder.cc \
1817 topurl_printer.cc \
1918 wreadlog.cc \
@@ -24,7 +23,7 @@
2524
2625 EXTRA_DIST= Makefile.in
2726
28 -LDFLAGS = $(LIBOBJS) -lcurses
 27+LDFLAGS = $(LIBOBJS) -lcurses -L../libwillow -lwillow
2928
3029 .SUFFIXES: .y .l .c .cc .o
3130