Config.cc
Go to the documentation of this file.
1/*
2 * Copyright (C) 1996-2022 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 29 Negotiate Authenticator */
10
11/* The functions in this file handle authentication.
12 * They DO NOT perform access control or auditing.
13 * See acl.c for access control and client_side.c for auditing */
14
15#include "squid.h"
16#include "auth/Gadgets.h"
19#include "auth/negotiate/User.h"
21#include "auth/State.h"
22#include "cache_cf.h"
23#include "client_side.h"
24#include "helper.h"
25#include "http/Stream.h"
26#include "HttpHeaderTools.h"
27#include "HttpReply.h"
28#include "HttpRequest.h"
29#include "mgr/Registration.h"
30#include "Store.h"
31#include "wordlist.h"
32
34
36
38
39static hash_table *proxy_auth_cache = nullptr;
40
41void
42Auth::Negotiate::Config::rotateHelpers()
43{
44 /* schedule closure of existing helpers */
47 }
48
49 /* NP: dynamic helper restart will ensure they start up again as needed. */
50}
51
52void
53Auth::Negotiate::Config::done()
54{
56
58
61 }
62
63 if (!shutting_down)
64 return;
65
68
69 if (authenticateProgram)
70 wordlistDestroy(&authenticateProgram);
71
72 debugs(29, DBG_IMPORTANT, "Reconfigure: Negotiate authentication configuration cleared.");
73}
74
75const char *
77{
78 return Auth::Negotiate::Scheme::GetInstance()->type();
79}
80
85void
86Auth::Negotiate::Config::init(Auth::SchemeConfig *)
87{
88 if (authenticateProgram) {
89
91
92 if (negotiateauthenticators == nullptr)
93 negotiateauthenticators = new statefulhelper("negotiateauthenticator");
94
97
99
100 negotiateauthenticators->cmdline = authenticateProgram;
101
102 negotiateauthenticators->childs.updateLimits(authenticateChildren);
103
105
107 }
108}
109
110void
111Auth::Negotiate::Config::registerWithCacheManager(void)
112{
113 Mgr::RegisterAction("negotiateauthenticator",
114 "Negotiate User Authenticator Stats",
116}
117
118bool
119Auth::Negotiate::Config::active() const
120{
121 return authnegotiate_initialised == 1;
122}
123
124bool
125Auth::Negotiate::Config::configured() const
126{
127 if (authenticateProgram && (authenticateChildren.n_max != 0)) {
128 debugs(29, 9, "returning configured");
129 return true;
130 }
131
132 debugs(29, 9, "returning unconfigured");
133 return false;
134}
135
136void
137Auth::Negotiate::Config::fixHeader(Auth::UserRequest::Pointer auth_user_request, HttpReply *rep, Http::HdrType reqType, HttpRequest * request)
138{
139 if (!authenticateProgram)
140 return;
141
142 /* Need keep-alive */
143 if (!request->flags.proxyKeepalive && request->flags.mustKeepalive)
144 return;
145
146 /* New request, no user details */
147 if (auth_user_request == nullptr) {
148 debugs(29, 9, "Sending type:" << reqType << " header: 'Negotiate'");
149 httpHeaderPutStrf(&rep->header, reqType, "Negotiate");
150
151 if (!keep_alive) {
152 /* drop the connection */
153 rep->header.delByName("keep-alive");
154 request->flags.proxyKeepalive = false;
155 }
156 } else {
157 Auth::Negotiate::UserRequest *negotiate_request = dynamic_cast<Auth::Negotiate::UserRequest *>(auth_user_request.getRaw());
158 assert(negotiate_request != nullptr);
159
160 switch (negotiate_request->user()->credentials()) {
161
162 case Auth::Failed:
163 /* here it makes sense to drop the connection, as auth is
164 * tied to it, even if MAYBE the client could handle it - Kinkie */
165 rep->header.delByName("keep-alive");
166 request->flags.proxyKeepalive = false;
167 /* [[fallthrough]] */
168
169 case Auth::Ok:
170 /* Special case: authentication finished OK but disallowed by ACL.
171 * Need to start over to give the client another chance.
172 */
173 if (negotiate_request->server_blob) {
174 debugs(29, 9, "Sending type:" << reqType << " header: 'Negotiate " << negotiate_request->server_blob << "'");
175 httpHeaderPutStrf(&rep->header, reqType, "Negotiate %s", negotiate_request->server_blob);
176 safe_free(negotiate_request->server_blob);
177 } else {
178 debugs(29, 9, "Connection authenticated");
179 httpHeaderPutStrf(&rep->header, reqType, "Negotiate");
180 }
181 break;
182
183 case Auth::Unchecked:
184 /* semantic change: do not drop the connection.
185 * 2.5 implementation used to keep it open - Kinkie */
186 debugs(29, 9, "Sending type:" << reqType << " header: 'Negotiate'");
187 httpHeaderPutStrf(&rep->header, reqType, "Negotiate");
188 break;
189
190 case Auth::Handshake:
191 /* we're waiting for a response from the client. Pass it the blob */
192 debugs(29, 9, "Sending type:" << reqType << " header: 'Negotiate " << negotiate_request->server_blob << "'");
193 httpHeaderPutStrf(&rep->header, reqType, "Negotiate %s", negotiate_request->server_blob);
194 safe_free(negotiate_request->server_blob);
195 break;
196
197 default:
198 debugs(29, DBG_CRITICAL, "ERROR: Negotiate auth fixHeader: state " << negotiate_request->user()->credentials() << ".");
199 fatal("unexpected state in AuthenticateNegotiateFixErrorHeader.\n");
200 }
201 }
202}
203
204static void
206{
208 negotiateauthenticators->packStatsInto(sentry, "Negotiate Authenticator Statistics");
209}
210
211/*
212 * Decode a Negotiate [Proxy-]Auth string, placing the results in the passed
213 * Auth_user structure.
214 */
216Auth::Negotiate::Config::decode(char const *proxy_auth, const HttpRequest *, const char *aRequestRealm)
217{
218 Auth::Negotiate::User *newUser = new Auth::Negotiate::User(Auth::SchemeConfig::Find("negotiate"), aRequestRealm);
219 Auth::UserRequest *auth_user_request = new Auth::Negotiate::UserRequest();
220 assert(auth_user_request->user() == nullptr);
221
222 auth_user_request->user(newUser);
223 auth_user_request->user()->auth_type = Auth::AUTH_NEGOTIATE;
224
225 auth_user_request->user()->BuildUserKey(proxy_auth, aRequestRealm);
226
227 /* all we have to do is identify that it's Negotiate - the helper does the rest */
228 debugs(29, 9, "decode Negotiate authentication");
229 return auth_user_request;
230}
231
void httpHeaderPutStrf(HttpHeader *hdr, Http::HdrType id, const char *fmt,...)
#define assert(EX)
Definition: assert.h:19
void AUTHSSTATS(StoreEntry *)
Definition: Gadgets.h:21
static AUTHSSTATS authenticateNegotiateStats
Definition: Config.cc:33
static int authnegotiate_initialised
Definition: Config.cc:37
static hash_table * proxy_auth_cache
Definition: Config.cc:39
statefulhelper * negotiateauthenticators
Definition: Config.cc:35
virtual void done()
static SchemeConfig * Find(const char *proxy_auth)
Definition: SchemeConfig.cc:59
virtual User::Pointer user()
Definition: UserRequest.h:143
ChildConfig & updateLimits(const ChildConfig &rhs)
Definition: ChildConfig.cc:44
int delByName(const SBuf &name)
Definition: HttpHeader.cc:652
HttpHeader header
Definition: Message.h:74
C * getRaw() const
Definition: RefCount.h:80
void packStatsInto(Packable *p, const char *label=nullptr) const
Dump some stats about the helper state to a Packable object.
Definition: helper.cc:677
wordlist * cmdline
Definition: helper.h:107
Helper::ChildConfig childs
Configuration settings for number running.
Definition: helper.h:111
int ipc_type
Definition: helper.h:112
#define DBG_IMPORTANT
Definition: Stream.h:41
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Stream.h:196
#define DBG_CRITICAL
Definition: Stream.h:40
#define IPC_STREAM
Definition: defines.h:106
int type
Definition: errorpage.cc:152
void fatal(const char *message)
Definition: fatal.cc:28
int shutting_down
SQUIDCEXTERN hash_table * hash_create(HASHCMP *, int, HASHHASH *)
Definition: hash.cc:108
int HASHCMP(const void *, const void *)
Definition: hash.h:13
SQUIDCEXTERN HASHHASH hash_string
Definition: hash.h:45
void helperStatefulOpenServers(statefulhelper *hlp)
Definition: helper.cc:332
void helperStatefulShutdown(statefulhelper *hlp)
Definition: helper.cc:777
@ AUTH_NEGOTIATE
Definition: Type.h:22
void RegisterAction(char const *action, char const *desc, OBJH *handler, int pw_req_flag, int atomic)
Definition: Registration.cc:16
struct _request * request(char *urlin)
Definition: tcp-banger2.c:291
void wordlistDestroy(wordlist **list)
destroy a wordlist
Definition: wordlist.cc:16
#define safe_free(x)
Definition: xalloc.h:73

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors