]> git.ipfire.org Git - thirdparty/squid.git/blob - src/auth/AclProxyAuth.cc
mempools-nozero part 1: fix ctors of classes declared MEMPROXY_CLASS
[thirdparty/squid.git] / src / auth / AclProxyAuth.cc
1 /*
2 * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
3 *
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.
7 */
8
9 /* DEBUG: section 28 Access Control */
10
11 #include "squid.h"
12 #include "acl/FilledChecklist.h"
13 #include "acl/RegexData.h"
14 #include "acl/UserData.h"
15 #include "auth/Acl.h"
16 #include "auth/AclProxyAuth.h"
17 #include "auth/Gadgets.h"
18 #include "auth/User.h"
19 #include "auth/UserRequest.h"
20 #include "client_side.h"
21 #include "HttpRequest.h"
22
23 ACLProxyAuth::~ACLProxyAuth()
24 {
25 delete data;
26 }
27
28 ACLProxyAuth::ACLProxyAuth(ACLData<char const *> *newData, char const *theType) :
29 data(newData),
30 type_(theType)
31 {}
32
33 ACLProxyAuth::ACLProxyAuth(ACLProxyAuth const &old) :
34 data(old.data->clone()),
35 type_(old.type_)
36 {}
37
38 ACLProxyAuth &
39 ACLProxyAuth::operator=(ACLProxyAuth const &rhs)
40 {
41 data = rhs.data->clone();
42 type_ = rhs.type_;
43 return *this;
44 }
45
46 char const *
47 ACLProxyAuth::typeString() const
48 {
49 return type_;
50 }
51
52 void
53 ACLProxyAuth::parse()
54 {
55 data->parse();
56 }
57
58 int
59 ACLProxyAuth::match(ACLChecklist *checklist)
60 {
61 allow_t answer = AuthenticateAcl(checklist);
62
63 // convert to tri-state ACL match 1,0,-1
64 switch (answer) {
65 case ACCESS_ALLOWED:
66 // check for a match
67 return matchProxyAuth(checklist);
68
69 case ACCESS_DENIED:
70 return 0; // non-match
71
72 case ACCESS_DUNNO:
73 case ACCESS_AUTH_REQUIRED:
74 default:
75 // If the answer is not allowed or denied (matches/not matches) and
76 // async authentication is not in progress, then we are done.
77 if (checklist->keepMatching())
78 checklist->markFinished(answer, "AuthenticateAcl exception");
79 return -1; // other
80 }
81 }
82
83 SBufList
84 ACLProxyAuth::dump() const
85 {
86 return data->dump();
87 }
88
89 bool
90 ACLProxyAuth::empty() const
91 {
92 return data->empty();
93 }
94
95 bool
96 ACLProxyAuth::valid() const
97 {
98 if (authenticateSchemeCount() == 0) {
99 debugs(28, DBG_CRITICAL, "Can't use proxy auth because no authentication schemes were compiled.");
100 return false;
101 }
102
103 if (authenticateActiveSchemeCount() == 0) {
104 debugs(28, DBG_CRITICAL, "Can't use proxy auth because no authentication schemes are fully configured.");
105 return false;
106 }
107
108 return true;
109 }
110
111 ProxyAuthLookup ProxyAuthLookup::instance_;
112
113 ProxyAuthLookup *
114 ProxyAuthLookup::Instance()
115 {
116 return &instance_;
117 }
118
119 void
120 ProxyAuthLookup::checkForAsync(ACLChecklist *cl) const
121 {
122 ACLFilledChecklist *checklist = Filled(cl);
123
124 debugs(28, 3, HERE << "checking password via authenticator");
125
126 /* make sure someone created auth_user_request for us */
127 assert(checklist->auth_user_request != NULL);
128 assert(checklist->auth_user_request->valid());
129 checklist->auth_user_request->start(checklist->request, checklist->al, LookupDone, checklist);
130 }
131
132 void
133 ProxyAuthLookup::LookupDone(void *data)
134 {
135 ACLFilledChecklist *checklist = Filled(static_cast<ACLChecklist*>(data));
136
137 if (checklist->auth_user_request == NULL || !checklist->auth_user_request->valid() || checklist->conn() == NULL) {
138 /* credentials could not be checked either way
139 * restart the whole process */
140 /* OR the connection was closed, there's no way to continue */
141 checklist->auth_user_request = NULL;
142
143 if (checklist->conn() != NULL) {
144 checklist->conn()->setAuth(NULL, "proxy_auth ACL failure");
145 }
146 }
147
148 checklist->resumeNonBlockingCheck(ProxyAuthLookup::Instance());
149 }
150
151 ACL *
152 ACLProxyAuth::clone() const
153 {
154 return new ACLProxyAuth(*this);
155 }
156
157 int
158 ACLProxyAuth::matchForCache(ACLChecklist *cl)
159 {
160 ACLFilledChecklist *checklist = Filled(cl);
161 assert (checklist->auth_user_request != NULL);
162 return data->match(checklist->auth_user_request->username());
163 }
164
165 /* aclMatchProxyAuth can return two exit codes:
166 * 0 : Authorisation for this ACL failed. (Did not match)
167 * 1 : Authorisation OK. (Matched)
168 */
169 int
170 ACLProxyAuth::matchProxyAuth(ACLChecklist *cl)
171 {
172 ACLFilledChecklist *checklist = Filled(cl);
173 if (checklist->request->flags.sslBumped)
174 return 1; // AuthenticateAcl() already handled this bumped request
175 if (!authenticateUserAuthenticated(Filled(checklist)->auth_user_request)) {
176 return 0;
177 }
178 /* check to see if we have matched the user-acl before */
179 int result = cacheMatchAcl(&checklist->auth_user_request->user()->proxy_match_cache, checklist);
180 checklist->auth_user_request = NULL;
181 return result;
182 }
183