Config.cc
Go to the documentation of this file.
1/*
2 * Copyright (C) 1996-2023 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 NTLM 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"
17#include "auth/ntlm/Config.h"
18#include "auth/ntlm/Scheme.h"
19#include "auth/ntlm/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
33/* NTLM Scheme */
35
37static int authntlm_initialised = 0;
38
39static hash_table *proxy_auth_cache = nullptr;
40
41void
42Auth::Ntlm::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
52/* free any allocated configuration details */
53void
54Auth::Ntlm::Config::done()
55{
57
59
62 }
63
64 if (!shutting_down)
65 return;
66
67 ntlmauthenticators = nullptr;
68
69 if (authenticateProgram)
70 wordlistDestroy(&authenticateProgram);
71
72 debugs(29, DBG_IMPORTANT, "Reconfigure: NTLM authentication configuration cleared.");
73}
74
75const char *
76Auth::Ntlm::Config::type() const
77{
78 return Auth::Ntlm::Scheme::GetInstance()->type();
79}
80
81/* Initialize helpers and the like for this auth scheme. Called AFTER parsing the
82 * config file */
83void
84Auth::Ntlm::Config::init(Auth::SchemeConfig *)
85{
86 if (authenticateProgram) {
87
89
90 if (ntlmauthenticators == nullptr)
91 ntlmauthenticators = statefulhelper::Make("ntlmauthenticator");
92
95
97
98 ntlmauthenticators->cmdline = authenticateProgram;
99
100 ntlmauthenticators->childs.updateLimits(authenticateChildren);
101
103
105 }
106}
107
108void
109Auth::Ntlm::Config::registerWithCacheManager(void)
110{
111 Mgr::RegisterAction("ntlmauthenticator",
112 "NTLM User Authenticator Stats",
114}
115
116bool
117Auth::Ntlm::Config::active() const
118{
119 return authntlm_initialised == 1;
120}
121
122bool
123Auth::Ntlm::Config::configured() const
124{
125 if ((authenticateProgram != nullptr) && (authenticateChildren.n_max != 0)) {
126 debugs(29, 9, "returning configured");
127 return true;
128 }
129
130 debugs(29, 9, "returning unconfigured");
131 return false;
132}
133
134/* NTLM Scheme */
135
136void
137Auth::Ntlm::Config::fixHeader(Auth::UserRequest::Pointer auth_user_request, HttpReply *rep, Http::HdrType hdrType, 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:" << hdrType << " header: 'NTLM'");
149 httpHeaderPutStrf(&rep->header, hdrType, "NTLM");
150
151 if (!keep_alive) {
152 /* drop the connection */
153 request->flags.proxyKeepalive = false;
154 }
155 } else {
156 Auth::Ntlm::UserRequest *ntlm_request = dynamic_cast<Auth::Ntlm::UserRequest *>(auth_user_request.getRaw());
157 assert(ntlm_request != nullptr);
158
159 switch (ntlm_request->user()->credentials()) {
160
161 case Auth::Failed:
162 /* here it makes sense to drop the connection, as auth is
163 * tied to it, even if MAYBE the client could handle it - Kinkie */
164 request->flags.proxyKeepalive = false;
165 [[fallthrough]];
166
167 case Auth::Ok:
168 /* Special case: authentication finished OK but disallowed by ACL.
169 * Need to start over to give the client another chance.
170 */
171 [[fallthrough]];
172
173 case Auth::Unchecked:
174 /* semantic change: do not drop the connection.
175 * 2.5 implementation used to keep it open - Kinkie */
176 debugs(29, 9, "Sending type:" << hdrType << " header: 'NTLM'");
177 httpHeaderPutStrf(&rep->header, hdrType, "NTLM");
178 break;
179
180 case Auth::Handshake:
181 /* we're waiting for a response from the client. Pass it the blob */
182 debugs(29, 9, "Sending type:" << hdrType << " header: 'NTLM " << ntlm_request->server_blob << "'");
183 httpHeaderPutStrf(&rep->header, hdrType, "NTLM %s", ntlm_request->server_blob);
184 safe_free(ntlm_request->server_blob);
185 break;
186
187 default:
188 debugs(29, DBG_CRITICAL, "NTLM Auth fixHeader: state " << ntlm_request->user()->credentials() << ".");
189 fatal("unexpected state in AuthenticateNTLMFixErrorHeader.\n");
190 }
191 }
192}
193
194static void
196{
198 ntlmauthenticators->packStatsInto(sentry, "NTLM Authenticator Statistics");
199}
200
201/*
202 * Decode a NTLM [Proxy-]Auth string, placing the results in the passed
203 * Auth_user structure.
204 */
206Auth::Ntlm::Config::decode(char const *proxy_auth, const HttpRequest *, const char *aRequestRealm)
207{
208 Auth::Ntlm::User *newUser = new Auth::Ntlm::User(Auth::SchemeConfig::Find("ntlm"), aRequestRealm);
209 Auth::UserRequest::Pointer auth_user_request = new Auth::Ntlm::UserRequest();
210 assert(auth_user_request->user() == nullptr);
211
212 auth_user_request->user(newUser);
213 auth_user_request->user()->auth_type = Auth::AUTH_NTLM;
214
215 auth_user_request->user()->BuildUserKey(proxy_auth, aRequestRealm);
216
217 /* all we have to do is identify that it's NTLM - the helper does the rest */
218 debugs(29, 9, "decode: NTLM authentication");
219 return auth_user_request;
220}
221
void httpHeaderPutStrf(HttpHeader *hdr, Http::HdrType id, const char *fmt,...)
#define assert(EX)
Definition: assert.h:17
void AUTHSSTATS(StoreEntry *)
Definition: Gadgets.h:21
static AUTHSSTATS authenticateNTLMStats
Definition: Config.cc:34
Helper::StatefulClientPointer ntlmauthenticators
Definition: Config.cc:36
static hash_table * proxy_auth_cache
Definition: Config.cc:39
static int authntlm_initialised
Definition: Config.cc:37
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
void packStatsInto(Packable *p, const char *label=nullptr) const
Dump some stats about the helper state to a Packable object.
Definition: helper.cc:696
ChildConfig childs
Configuration settings for number running.
Definition: helper.h:118
wordlist * cmdline
Definition: helper.h:114
int ipc_type
Definition: helper.h:119
RequestFlags flags
Definition: HttpRequest.h:141
HttpHeader header
Definition: Message.h:74
C * getRaw() const
Definition: RefCount.h:89
bool mustKeepalive
Definition: RequestFlags.h:83
bool proxyKeepalive
Definition: RequestFlags.h:42
static Pointer Make(const char *name)
Definition: helper.cc:765
void openSessions() override
Definition: helper.cc:329
#define DBG_IMPORTANT
Definition: Stream.h:38
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Stream.h:194
#define DBG_CRITICAL
Definition: Stream.h:37
#define IPC_STREAM
Definition: defines.h:106
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 helperStatefulShutdown(const statefulhelper::Pointer &hlp)
Definition: helper.cc:807
@ AUTH_NTLM
Definition: Type.h:20
void RegisterAction(char const *action, char const *desc, OBJH *handler, int pw_req_flag, int atomic)
Definition: Registration.cc:16
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