]>
Commit | Line | Data |
---|---|---|
48071869 | 1 | /* |
bbc27441 | 2 | * Copyright (C) 1996-2014 The Squid Software Foundation and contributors |
48071869 | 3 | * |
bbc27441 AJ |
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. | |
48071869 | 7 | */ |
8 | ||
bbc27441 AJ |
9 | /* DEBUG: section 28 Access Control */ |
10 | ||
582c2af2 | 11 | #include "squid.h" |
6fc1da74 | 12 | |
ee0927b6 | 13 | #if USE_SQUID_EUI |
6fc1da74 | 14 | |
c0941a6a AR |
15 | #include "acl/Arp.h" |
16 | #include "acl/FilledChecklist.h" | |
06390e4b | 17 | #include "cache_cf.h" |
582c2af2 | 18 | #include "Debug.h" |
ee0927b6 | 19 | #include "eui/Eui48.h" |
9b859d6f | 20 | #include "globals.h" |
96d89ea0 | 21 | #include "ip/Address.h" |
48071869 | 22 | |
a98c2da5 | 23 | static void aclParseArpList(SplayNode<Eui::Eui48 *> **curlist); |
b7ac5457 | 24 | static int aclMatchArp(SplayNode<Eui::Eui48 *> **dataptr, Ip::Address &c); |
a98c2da5 AJ |
25 | static SplayNode<Eui::Eui48 *>::SPLAYCMP aclArpCompare; |
26 | static SplayNode<Eui::Eui48 *>::SPLAYWALKEE aclDumpArpListWalkee; | |
48071869 | 27 | |
48071869 | 28 | ACL * |
29 | ACLARP::clone() const | |
30 | { | |
31 | return new ACLARP(*this); | |
32 | } | |
33 | ||
34 | ACLARP::ACLARP (char const *theClass) : data (NULL), class_ (theClass) | |
35 | {} | |
36 | ||
37 | ACLARP::ACLARP (ACLARP const & old) : data (NULL), class_ (old.class_) | |
38 | { | |
39 | /* we don't have copy constructors for the data yet */ | |
40 | assert (!old.data); | |
41 | } | |
42 | ||
48071869 | 43 | ACLARP::~ACLARP() |
44 | { | |
45 | if (data) | |
a98c2da5 | 46 | data->destroy(SplayNode<Eui::Eui48*>::DefaultFree); |
48071869 | 47 | } |
48 | ||
49 | char const * | |
50 | ACLARP::typeString() const | |
51 | { | |
52 | return class_; | |
53 | } | |
54 | ||
55 | bool | |
4b0f5de8 | 56 | ACLARP::empty () const |
48071869 | 57 | { |
290eb6b9 | 58 | return data->empty(); |
48071869 | 59 | } |
60 | ||
61 | /* ==== BEGIN ARP ACL SUPPORT ============================================= */ | |
62 | ||
63 | /* | |
64 | * From: dale@server.ctam.bitmcnit.bryansk.su (Dale) | |
65 | * To: wessels@nlanr.net | |
66 | * Subject: Another Squid patch... :) | |
67 | * Date: Thu, 04 Dec 1997 19:55:01 +0300 | |
68 | * ============================================================================ | |
26ac0430 | 69 | * |
48071869 | 70 | * Working on setting up a proper firewall for a network containing some |
71 | * Win'95 computers at our Univ, I've discovered that some smart students | |
72 | * avoid the restrictions easily just changing their IP addresses in Win'95 | |
73 | * Contol Panel... It has been getting boring, so I took Squid-1.1.18 | |
74 | * sources and added a new acl type for hard-wired access control: | |
26ac0430 | 75 | * |
48071869 | 76 | * acl <name> arp <Ethernet address> ... |
26ac0430 | 77 | * |
48071869 | 78 | * For example, |
26ac0430 | 79 | * |
48071869 | 80 | * acl students arp 00:00:21:55:ed:22 00:00:21:ff:55:38 |
81 | * | |
82 | * NOTE: Linux code by David Luyer <luyer@ucs.uwa.edu.au>. | |
83 | * Original (BSD-specific) code no longer works. | |
84 | * Solaris code by R. Gancarz <radekg@solaris.elektrownia-lagisza.com.pl> | |
85 | */ | |
86 | ||
a98c2da5 | 87 | Eui::Eui48 * |
48071869 | 88 | aclParseArpData(const char *t) |
89 | { | |
ee0927b6 | 90 | char buf[256]; |
a98c2da5 | 91 | Eui::Eui48 *q = new Eui::Eui48; |
bf8fe701 | 92 | debugs(28, 5, "aclParseArpData: " << t); |
48071869 | 93 | |
ee0927b6 | 94 | if (sscanf(t, "%[0-9a-fA-F:]", buf) != 1) { |
fa84c01d | 95 | debugs(28, DBG_CRITICAL, "aclParseArpData: Bad ethernet address: '" << t << "'"); |
48071869 | 96 | safe_free(q); |
97 | return NULL; | |
98 | } | |
99 | ||
ee0927b6 | 100 | if (!q->decode(buf)) { |
fa84c01d FC |
101 | debugs(28, DBG_CRITICAL, "" << cfg_filename << " line " << config_lineno << ": " << config_input_line); |
102 | debugs(28, DBG_CRITICAL, "aclParseArpData: Ignoring invalid ARP acl entry: can't parse '" << buf << "'"); | |
48071869 | 103 | safe_free(q); |
104 | return NULL; | |
105 | } | |
106 | ||
107 | return q; | |
108 | } | |
109 | ||
48071869 | 110 | /*******************/ |
111 | /* aclParseArpList */ | |
112 | /*******************/ | |
113 | void | |
114 | ACLARP::parse() | |
115 | { | |
ee0927b6 | 116 | aclParseArpList(&data); |
48071869 | 117 | } |
118 | ||
119 | void | |
a98c2da5 | 120 | aclParseArpList(SplayNode<Eui::Eui48 *> **curlist) |
48071869 | 121 | { |
122 | char *t = NULL; | |
a98c2da5 AJ |
123 | SplayNode<Eui::Eui48*> **Top = curlist; |
124 | Eui::Eui48 *q = NULL; | |
48071869 | 125 | |
126 | while ((t = strtokFile())) { | |
127 | if ((q = aclParseArpData(t)) == NULL) | |
128 | continue; | |
129 | ||
130 | *Top = (*Top)->insert(q, aclArpCompare); | |
131 | } | |
132 | } | |
133 | ||
134 | int | |
c0941a6a | 135 | ACLARP::match(ACLChecklist *cl) |
48071869 | 136 | { |
af6a12ee | 137 | ACLFilledChecklist *checklist = Filled(cl); |
c0941a6a | 138 | |
cc192b50 | 139 | /* IPv6 does not do ARP */ |
4dd643d5 | 140 | if (!checklist->src_addr.isIPv4()) { |
cc192b50 | 141 | debugs(14, 3, "ACLARP::match: IPv4 Required for ARP Lookups. Skipping " << checklist->src_addr ); |
142 | return 0; | |
143 | } | |
144 | ||
48071869 | 145 | return aclMatchArp(&data, checklist->src_addr); |
146 | } | |
147 | ||
148 | /***************/ | |
149 | /* aclMatchArp */ | |
150 | /***************/ | |
151 | int | |
b7ac5457 | 152 | aclMatchArp(SplayNode<Eui::Eui48 *> **dataptr, Ip::Address &c) |
48071869 | 153 | { |
a98c2da5 AJ |
154 | Eui::Eui48 result; |
155 | SplayNode<Eui::Eui48 *> **Top = dataptr; | |
cc192b50 | 156 | |
ee0927b6 AJ |
157 | if (result.lookup(c)) { |
158 | /* Do ACL match lookup */ | |
159 | *Top = (*Top)->splay(&result, aclArpCompare); | |
160 | debugs(28, 3, "aclMatchArp: '" << c << "' " << (splayLastResult ? "NOT found" : "found")); | |
48071869 | 161 | return (0 == splayLastResult); |
162 | } | |
163 | ||
48071869 | 164 | /* |
165 | * Address was not found on any interface | |
166 | */ | |
ee0927b6 | 167 | debugs(28, 3, "aclMatchArp: " << c << " NOT found"); |
48071869 | 168 | return 0; |
169 | } | |
170 | ||
171 | static int | |
a98c2da5 | 172 | aclArpCompare(Eui::Eui48 * const &a, Eui::Eui48 * const &b) |
48071869 | 173 | { |
a98c2da5 | 174 | return memcmp(a, b, sizeof(Eui::Eui48)); |
48071869 | 175 | } |
176 | ||
48071869 | 177 | static void |
a98c2da5 | 178 | aclDumpArpListWalkee(Eui::Eui48 * const &node, void *state) |
48071869 | 179 | { |
ee0927b6 AJ |
180 | static char buf[48]; |
181 | node->encode(buf, 48); | |
9b859d6f | 182 | static_cast<SBufList *>(state)->push_back(SBuf(buf)); |
48071869 | 183 | } |
184 | ||
9b859d6f | 185 | SBufList |
48071869 | 186 | ACLARP::dump() const |
187 | { | |
9b859d6f FC |
188 | SBufList sl; |
189 | data->walk(aclDumpArpListWalkee, &sl); | |
190 | return sl; | |
48071869 | 191 | } |
192 | ||
193 | /* ==== END ARP ACL SUPPORT =============================================== */ | |
ee0927b6 AJ |
194 | |
195 | #endif /* USE_SQUID_EUI */ | |
f53969cc | 196 |