]>
Commit | Line | Data |
---|---|---|
8000a965 | 1 | /* |
bf95c10a | 2 | * Copyright (C) 1996-2022 The Squid Software Foundation and contributors |
8000a965 | 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. | |
8000a965 | 7 | */ |
8 | ||
bbc27441 AJ |
9 | /* DEBUG: section 28 Access Control */ |
10 | ||
582c2af2 | 11 | #include "squid.h" |
c0941a6a | 12 | #include "acl/FilledChecklist.h" |
c0941a6a | 13 | #include "acl/RegexData.h" |
602d9612 | 14 | #include "acl/UserData.h" |
c0941a6a | 15 | #include "auth/Acl.h" |
602d9612 A |
16 | #include "auth/AclProxyAuth.h" |
17 | #include "auth/Gadgets.h" | |
2d2b0bb7 AR |
18 | #include "auth/User.h" |
19 | #include "auth/UserRequest.h" | |
602d9612 | 20 | #include "client_side.h" |
d3dddfb5 | 21 | #include "http/Stream.h" |
602d9612 | 22 | #include "HttpRequest.h" |
8000a965 | 23 | |
8000a965 | 24 | ACLProxyAuth::~ACLProxyAuth() |
25 | { | |
00d77d6b | 26 | delete data; |
225b7b10 | 27 | } |
28 | ||
d59e4742 FC |
29 | ACLProxyAuth::ACLProxyAuth(ACLData<char const *> *newData, char const *theType) : |
30 | data(newData), | |
31 | type_(theType) | |
32 | {} | |
62e76326 | 33 | |
8000a965 | 34 | char const * |
35 | ACLProxyAuth::typeString() const | |
36 | { | |
3841dd46 | 37 | return type_; |
8000a965 | 38 | } |
39 | ||
8d76389c EB |
40 | const Acl::Options & |
41 | ACLProxyAuth::lineOptions() | |
4eac3407 | 42 | { |
8d76389c | 43 | return data->lineOptions(); |
4eac3407 CT |
44 | } |
45 | ||
8000a965 | 46 | void |
47 | ACLProxyAuth::parse() | |
48 | { | |
225b7b10 | 49 | data->parse(); |
8000a965 | 50 | } |
51 | ||
8000a965 | 52 | int |
53 | ACLProxyAuth::match(ACLChecklist *checklist) | |
54 | { | |
329c128c | 55 | auto answer = AuthenticateAcl(checklist); |
62e76326 | 56 | |
ccec22f9 | 57 | // convert to tri-state ACL match 1,0,-1 |
9b831d57 | 58 | switch (answer) { |
ccec22f9 | 59 | case ACCESS_ALLOWED: |
ccec22f9 AJ |
60 | // check for a match |
61 | return matchProxyAuth(checklist); | |
62e76326 | 62 | |
ccec22f9 | 63 | case ACCESS_DENIED: |
ccec22f9 | 64 | return 0; // non-match |
62e76326 | 65 | |
ccec22f9 AJ |
66 | case ACCESS_DUNNO: |
67 | case ACCESS_AUTH_REQUIRED: | |
68 | default: | |
e0f7153c | 69 | // If the answer is not allowed or denied (matches/not matches) and |
6f58d7d7 AR |
70 | // async authentication is not in progress, then we are done. |
71 | if (checklist->keepMatching()) | |
e0f7153c | 72 | checklist->markFinished(answer, "AuthenticateAcl exception"); |
ccec22f9 AJ |
73 | return -1; // other |
74 | } | |
8000a965 | 75 | } |
76 | ||
8966008b | 77 | SBufList |
8000a965 | 78 | ACLProxyAuth::dump() const |
79 | { | |
80 | return data->dump(); | |
81 | } | |
82 | ||
83 | bool | |
d6d0eb11 | 84 | ACLProxyAuth::empty() const |
8000a965 | 85 | { |
079170d4 | 86 | return data->empty(); |
8000a965 | 87 | } |
225b7b10 | 88 | |
4b0f5de8 | 89 | bool |
d6d0eb11 | 90 | ACLProxyAuth::valid() const |
4b0f5de8 | 91 | { |
92 | if (authenticateSchemeCount() == 0) { | |
d816f28d | 93 | debugs(28, DBG_CRITICAL, "ERROR: Cannot use proxy auth because no authentication schemes were compiled."); |
4b0f5de8 | 94 | return false; |
95 | } | |
96 | ||
97 | if (authenticateActiveSchemeCount() == 0) { | |
d816f28d | 98 | debugs(28, DBG_CRITICAL, "ERROR: Cannot use proxy auth because no authentication schemes are fully configured."); |
4b0f5de8 | 99 | return false; |
100 | } | |
101 | ||
102 | return true; | |
103 | } | |
104 | ||
225b7b10 | 105 | ProxyAuthLookup ProxyAuthLookup::instance_; |
106 | ||
107 | ProxyAuthLookup * | |
108 | ProxyAuthLookup::Instance() | |
109 | { | |
110 | return &instance_; | |
111 | } | |
112 | ||
113 | void | |
e26fd173 | 114 | ProxyAuthLookup::checkForAsync(ACLChecklist *cl) const |
225b7b10 | 115 | { |
c0941a6a AR |
116 | ACLFilledChecklist *checklist = Filled(cl); |
117 | ||
bf95c10a | 118 | debugs(28, 3, "checking password via authenticator"); |
225b7b10 | 119 | |
225b7b10 | 120 | /* make sure someone created auth_user_request for us */ |
aee3523a | 121 | assert(checklist->auth_user_request != nullptr); |
2e39494f | 122 | assert(checklist->auth_user_request->valid()); |
d4806c91 | 123 | checklist->auth_user_request->start(checklist->request, checklist->al, LookupDone, checklist); |
225b7b10 | 124 | } |
125 | ||
126 | void | |
4c535e87 | 127 | ProxyAuthLookup::LookupDone(void *data) |
225b7b10 | 128 | { |
c0941a6a AR |
129 | ACLFilledChecklist *checklist = Filled(static_cast<ACLChecklist*>(data)); |
130 | ||
aee3523a | 131 | if (checklist->auth_user_request == nullptr || !checklist->auth_user_request->valid() || checklist->conn() == nullptr) { |
62e76326 | 132 | /* credentials could not be checked either way |
133 | * restart the whole process */ | |
134 | /* OR the connection was closed, there's no way to continue */ | |
aee3523a | 135 | checklist->auth_user_request = nullptr; |
62e76326 | 136 | |
aee3523a AR |
137 | if (checklist->conn() != nullptr) { |
138 | checklist->conn()->setAuth(nullptr, "proxy_auth ACL failure"); | |
62e76326 | 139 | } |
225b7b10 | 140 | } |
62e76326 | 141 | |
6f58d7d7 | 142 | checklist->resumeNonBlockingCheck(ProxyAuthLookup::Instance()); |
225b7b10 | 143 | } |
144 | ||
225b7b10 | 145 | int |
c0941a6a | 146 | ACLProxyAuth::matchForCache(ACLChecklist *cl) |
225b7b10 | 147 | { |
c0941a6a | 148 | ACLFilledChecklist *checklist = Filled(cl); |
aee3523a | 149 | assert (checklist->auth_user_request != nullptr); |
f5691f9c | 150 | return data->match(checklist->auth_user_request->username()); |
225b7b10 | 151 | } |
152 | ||
153 | /* aclMatchProxyAuth can return two exit codes: | |
154 | * 0 : Authorisation for this ACL failed. (Did not match) | |
155 | * 1 : Authorisation OK. (Matched) | |
156 | */ | |
157 | int | |
c0941a6a | 158 | ACLProxyAuth::matchProxyAuth(ACLChecklist *cl) |
225b7b10 | 159 | { |
c0941a6a | 160 | ACLFilledChecklist *checklist = Filled(cl); |
82b0fff6 VA |
161 | if (!checklist->request->flags.sslBumped) { |
162 | if (!authenticateUserAuthenticated(checklist->auth_user_request)) { | |
163 | return 0; | |
164 | } | |
d232141d | 165 | } |
225b7b10 | 166 | /* check to see if we have matched the user-acl before */ |
a33a428a | 167 | int result = cacheMatchAcl(&checklist->auth_user_request->user()->proxy_match_cache, checklist); |
aee3523a | 168 | checklist->auth_user_request = nullptr; |
225b7b10 | 169 | return result; |
170 | } | |
f53969cc | 171 |