]>
Commit | Line | Data |
---|---|---|
8000a965 | 1 | /* |
8000a965 | 2 | * DEBUG: section 28 Access Control |
3 | * AUTHOR: Duane Wessels | |
4 | * | |
5 | * SQUID Web Proxy Cache http://www.squid-cache.org/ | |
6 | * ---------------------------------------------------------- | |
7 | * | |
8 | * Squid is the result of efforts by numerous individuals from | |
9 | * the Internet community; see the CONTRIBUTORS file for full | |
10 | * details. Many organizations have provided support for Squid's | |
11 | * development; see the SPONSORS file for full details. Squid is | |
12 | * Copyrighted (C) 2001 by the Regents of the University of | |
13 | * California; see the COPYRIGHT file for full details. Squid | |
14 | * incorporates software developed and/or copyrighted by other | |
15 | * sources; see the CREDITS file for full details. | |
16 | * | |
17 | * This program is free software; you can redistribute it and/or modify | |
18 | * it under the terms of the GNU General Public License as published by | |
19 | * the Free Software Foundation; either version 2 of the License, or | |
20 | * (at your option) any later version. | |
26ac0430 | 21 | * |
8000a965 | 22 | * This program is distributed in the hope that it will be useful, |
23 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
24 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
25 | * GNU General Public License for more details. | |
26ac0430 | 26 | * |
8000a965 | 27 | * You should have received a copy of the GNU General Public License |
28 | * along with this program; if not, write to the Free Software | |
29 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. | |
30 | * | |
31 | * | |
32 | * Copyright (c) 2003, Robert Collins <robertc@squid-cache.org> | |
33 | */ | |
34 | ||
582c2af2 | 35 | #include "squid.h" |
c0941a6a AR |
36 | #include "auth/AclProxyAuth.h" |
37 | #include "auth/Gadgets.h" | |
38 | #include "acl/FilledChecklist.h" | |
39 | #include "acl/UserData.h" | |
40 | #include "acl/RegexData.h" | |
a46d2c0e | 41 | #include "client_side.h" |
a2ac85d9 | 42 | #include "HttpRequest.h" |
c0941a6a | 43 | #include "auth/Acl.h" |
2d2b0bb7 AR |
44 | #include "auth/User.h" |
45 | #include "auth/UserRequest.h" | |
8000a965 | 46 | |
8000a965 | 47 | ACLProxyAuth::~ACLProxyAuth() |
48 | { | |
00d77d6b | 49 | delete data; |
225b7b10 | 50 | } |
51 | ||
5dee515e | 52 | ACLProxyAuth::ACLProxyAuth(ACLData<char const *> *newData, char const *theType) : data (newData), type_(theType) {} |
62e76326 | 53 | |
3841dd46 | 54 | ACLProxyAuth::ACLProxyAuth (ACLProxyAuth const &old) : data (old.data->clone()), type_(old.type_) |
62e76326 | 55 | {} |
56 | ||
225b7b10 | 57 | ACLProxyAuth & |
58 | ACLProxyAuth::operator= (ACLProxyAuth const &rhs) | |
59 | { | |
60 | data = rhs.data->clone(); | |
3841dd46 | 61 | type_ = rhs.type_; |
225b7b10 | 62 | return *this; |
8000a965 | 63 | } |
64 | ||
65 | char const * | |
66 | ACLProxyAuth::typeString() const | |
67 | { | |
3841dd46 | 68 | return type_; |
8000a965 | 69 | } |
70 | ||
71 | void | |
72 | ACLProxyAuth::parse() | |
73 | { | |
225b7b10 | 74 | data->parse(); |
8000a965 | 75 | } |
76 | ||
8000a965 | 77 | int |
78 | ACLProxyAuth::match(ACLChecklist *checklist) | |
79 | { | |
ccec22f9 | 80 | allow_t answer = AuthenticateAcl(checklist); |
62e76326 | 81 | |
ccec22f9 | 82 | // convert to tri-state ACL match 1,0,-1 |
9b831d57 | 83 | switch (answer) { |
ccec22f9 | 84 | case ACCESS_ALLOWED: |
ccec22f9 AJ |
85 | // check for a match |
86 | return matchProxyAuth(checklist); | |
62e76326 | 87 | |
ccec22f9 | 88 | case ACCESS_DENIED: |
ccec22f9 | 89 | return 0; // non-match |
62e76326 | 90 | |
ccec22f9 AJ |
91 | case ACCESS_DUNNO: |
92 | case ACCESS_AUTH_REQUIRED: | |
93 | default: | |
e0f7153c | 94 | // If the answer is not allowed or denied (matches/not matches) and |
6f58d7d7 AR |
95 | // async authentication is not in progress, then we are done. |
96 | if (checklist->keepMatching()) | |
e0f7153c | 97 | checklist->markFinished(answer, "AuthenticateAcl exception"); |
ccec22f9 AJ |
98 | return -1; // other |
99 | } | |
8000a965 | 100 | } |
101 | ||
102 | wordlist * | |
103 | ACLProxyAuth::dump() const | |
104 | { | |
105 | return data->dump(); | |
106 | } | |
107 | ||
108 | bool | |
4b0f5de8 | 109 | ACLProxyAuth::empty () const |
8000a965 | 110 | { |
079170d4 | 111 | return data->empty(); |
8000a965 | 112 | } |
225b7b10 | 113 | |
4b0f5de8 | 114 | bool |
115 | ACLProxyAuth::valid () const | |
116 | { | |
117 | if (authenticateSchemeCount() == 0) { | |
fa84c01d | 118 | debugs(28, DBG_CRITICAL, "Can't use proxy auth because no authentication schemes were compiled."); |
4b0f5de8 | 119 | return false; |
120 | } | |
121 | ||
122 | if (authenticateActiveSchemeCount() == 0) { | |
fa84c01d | 123 | debugs(28, DBG_CRITICAL, "Can't use proxy auth because no authentication schemes are fully configured."); |
4b0f5de8 | 124 | return false; |
125 | } | |
126 | ||
127 | return true; | |
128 | } | |
129 | ||
225b7b10 | 130 | ProxyAuthLookup ProxyAuthLookup::instance_; |
131 | ||
132 | ProxyAuthLookup * | |
133 | ProxyAuthLookup::Instance() | |
134 | { | |
135 | return &instance_; | |
136 | } | |
137 | ||
138 | void | |
c0941a6a | 139 | ProxyAuthLookup::checkForAsync(ACLChecklist *cl)const |
225b7b10 | 140 | { |
c0941a6a AR |
141 | ACLFilledChecklist *checklist = Filled(cl); |
142 | ||
2e39494f | 143 | debugs(28, 3, HERE << "checking password via authenticator"); |
225b7b10 | 144 | |
225b7b10 | 145 | /* make sure someone created auth_user_request for us */ |
0a608df9 | 146 | assert(checklist->auth_user_request != NULL); |
2e39494f AJ |
147 | assert(checklist->auth_user_request->valid()); |
148 | checklist->auth_user_request->start(LookupDone, checklist); | |
225b7b10 | 149 | } |
150 | ||
151 | void | |
4c535e87 | 152 | ProxyAuthLookup::LookupDone(void *data) |
225b7b10 | 153 | { |
c0941a6a AR |
154 | ACLFilledChecklist *checklist = Filled(static_cast<ACLChecklist*>(data)); |
155 | ||
0a608df9 | 156 | if (checklist->auth_user_request == NULL || !checklist->auth_user_request->valid() || checklist->conn() == NULL) { |
62e76326 | 157 | /* credentials could not be checked either way |
158 | * restart the whole process */ | |
159 | /* OR the connection was closed, there's no way to continue */ | |
a33a428a | 160 | checklist->auth_user_request = NULL; |
62e76326 | 161 | |
4d3a24ca | 162 | if (checklist->conn() != NULL) { |
cc1e110a | 163 | checklist->conn()->setAuth(NULL, "proxy_auth ACL failure"); |
62e76326 | 164 | } |
225b7b10 | 165 | } |
62e76326 | 166 | |
6f58d7d7 | 167 | checklist->resumeNonBlockingCheck(ProxyAuthLookup::Instance()); |
225b7b10 | 168 | } |
169 | ||
225b7b10 | 170 | ACL * |
171 | ACLProxyAuth::clone() const | |
172 | { | |
173 | return new ACLProxyAuth(*this); | |
174 | } | |
175 | ||
176 | int | |
c0941a6a | 177 | ACLProxyAuth::matchForCache(ACLChecklist *cl) |
225b7b10 | 178 | { |
c0941a6a | 179 | ACLFilledChecklist *checklist = Filled(cl); |
a33a428a | 180 | assert (checklist->auth_user_request != NULL); |
f5691f9c | 181 | return data->match(checklist->auth_user_request->username()); |
225b7b10 | 182 | } |
183 | ||
184 | /* aclMatchProxyAuth can return two exit codes: | |
185 | * 0 : Authorisation for this ACL failed. (Did not match) | |
186 | * 1 : Authorisation OK. (Matched) | |
187 | */ | |
188 | int | |
c0941a6a | 189 | ACLProxyAuth::matchProxyAuth(ACLChecklist *cl) |
225b7b10 | 190 | { |
c0941a6a | 191 | ACLFilledChecklist *checklist = Filled(cl); |
d232141d | 192 | if (!authenticateUserAuthenticated(Filled(checklist)->auth_user_request)) { |
7d20e140 | 193 | return 0; |
d232141d | 194 | } |
225b7b10 | 195 | /* check to see if we have matched the user-acl before */ |
a33a428a AJ |
196 | int result = cacheMatchAcl(&checklist->auth_user_request->user()->proxy_match_cache, checklist); |
197 | checklist->auth_user_request = NULL; | |
225b7b10 | 198 | return result; |
199 | } |