]> git.ipfire.org Git - thirdparty/squid.git/blob - src/auth/AclProxyAuth.cc
SourceFormat Enforcement
[thirdparty/squid.git] / src / auth / AclProxyAuth.cc
1 /*
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.
21 *
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.
26 *
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
35 #include "squid.h"
36 #include "acl/FilledChecklist.h"
37 #include "acl/RegexData.h"
38 #include "acl/UserData.h"
39 #include "auth/Acl.h"
40 #include "auth/AclProxyAuth.h"
41 #include "auth/Gadgets.h"
42 #include "auth/User.h"
43 #include "auth/UserRequest.h"
44 #include "client_side.h"
45 #include "HttpRequest.h"
46
47 ACLProxyAuth::~ACLProxyAuth()
48 {
49 delete data;
50 }
51
52 ACLProxyAuth::ACLProxyAuth(ACLData<char const *> *newData, char const *theType) : data (newData), type_(theType) {}
53
54 ACLProxyAuth::ACLProxyAuth (ACLProxyAuth const &old) : data (old.data->clone()), type_(old.type_)
55 {}
56
57 ACLProxyAuth &
58 ACLProxyAuth::operator= (ACLProxyAuth const &rhs)
59 {
60 data = rhs.data->clone();
61 type_ = rhs.type_;
62 return *this;
63 }
64
65 char const *
66 ACLProxyAuth::typeString() const
67 {
68 return type_;
69 }
70
71 void
72 ACLProxyAuth::parse()
73 {
74 data->parse();
75 }
76
77 int
78 ACLProxyAuth::match(ACLChecklist *checklist)
79 {
80 allow_t answer = AuthenticateAcl(checklist);
81
82 // convert to tri-state ACL match 1,0,-1
83 switch (answer) {
84 case ACCESS_ALLOWED:
85 // check for a match
86 return matchProxyAuth(checklist);
87
88 case ACCESS_DENIED:
89 return 0; // non-match
90
91 case ACCESS_DUNNO:
92 case ACCESS_AUTH_REQUIRED:
93 default:
94 // If the answer is not allowed or denied (matches/not matches) and
95 // async authentication is not in progress, then we are done.
96 if (checklist->keepMatching())
97 checklist->markFinished(answer, "AuthenticateAcl exception");
98 return -1; // other
99 }
100 }
101
102 wordlist *
103 ACLProxyAuth::dump() const
104 {
105 return data->dump();
106 }
107
108 bool
109 ACLProxyAuth::empty () const
110 {
111 return data->empty();
112 }
113
114 bool
115 ACLProxyAuth::valid () const
116 {
117 if (authenticateSchemeCount() == 0) {
118 debugs(28, DBG_CRITICAL, "Can't use proxy auth because no authentication schemes were compiled.");
119 return false;
120 }
121
122 if (authenticateActiveSchemeCount() == 0) {
123 debugs(28, DBG_CRITICAL, "Can't use proxy auth because no authentication schemes are fully configured.");
124 return false;
125 }
126
127 return true;
128 }
129
130 ProxyAuthLookup ProxyAuthLookup::instance_;
131
132 ProxyAuthLookup *
133 ProxyAuthLookup::Instance()
134 {
135 return &instance_;
136 }
137
138 void
139 ProxyAuthLookup::checkForAsync(ACLChecklist *cl) const
140 {
141 ACLFilledChecklist *checklist = Filled(cl);
142
143 debugs(28, 3, HERE << "checking password via authenticator");
144
145 /* make sure someone created auth_user_request for us */
146 assert(checklist->auth_user_request != NULL);
147 assert(checklist->auth_user_request->valid());
148 checklist->auth_user_request->start(LookupDone, checklist);
149 }
150
151 void
152 ProxyAuthLookup::LookupDone(void *data)
153 {
154 ACLFilledChecklist *checklist = Filled(static_cast<ACLChecklist*>(data));
155
156 if (checklist->auth_user_request == NULL || !checklist->auth_user_request->valid() || checklist->conn() == NULL) {
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 */
160 checklist->auth_user_request = NULL;
161
162 if (checklist->conn() != NULL) {
163 checklist->conn()->setAuth(NULL, "proxy_auth ACL failure");
164 }
165 }
166
167 checklist->resumeNonBlockingCheck(ProxyAuthLookup::Instance());
168 }
169
170 ACL *
171 ACLProxyAuth::clone() const
172 {
173 return new ACLProxyAuth(*this);
174 }
175
176 int
177 ACLProxyAuth::matchForCache(ACLChecklist *cl)
178 {
179 ACLFilledChecklist *checklist = Filled(cl);
180 assert (checklist->auth_user_request != NULL);
181 return data->match(checklist->auth_user_request->username());
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
189 ACLProxyAuth::matchProxyAuth(ACLChecklist *cl)
190 {
191 ACLFilledChecklist *checklist = Filled(cl);
192 if (!authenticateUserAuthenticated(Filled(checklist)->auth_user_request)) {
193 return 0;
194 }
195 /* check to see if we have matched the user-acl before */
196 int result = cacheMatchAcl(&checklist->auth_user_request->user()->proxy_match_cache, checklist);
197 checklist->auth_user_request = NULL;
198 return result;
199 }