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"
20 #include "auth/ntlm/UserRequest.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 
37 static int authntlm_initialised = 0;
38 
39 static hash_table *proxy_auth_cache = nullptr;
40 
41 void
42 Auth::Ntlm::Config::rotateHelpers()
43 {
44  /* schedule closure of existing helpers */
45  if (ntlmauthenticators) {
47  }
48 
49  /* NP: dynamic helper restart will ensure they start up again as needed. */
50 }
51 
52 /* free any allocated configuration details */
53 void
54 Auth::Ntlm::Config::done()
55 {
57 
59 
60  if (ntlmauthenticators) {
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 
75 const char *
76 Auth::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 */
83 void
84 Auth::Ntlm::Config::init(Auth::SchemeConfig *)
85 {
86  if (authenticateProgram) {
87 
89 
90  if (ntlmauthenticators == nullptr)
91  ntlmauthenticators = statefulhelper::Make("ntlmauthenticator");
92 
93  if (!proxy_auth_cache)
94  proxy_auth_cache = hash_create((HASHCMP *) strcmp, 7921, hash_string);
95 
97 
98  ntlmauthenticators->cmdline = authenticateProgram;
99 
100  ntlmauthenticators->childs.updateLimits(authenticateChildren);
101 
103 
105  }
106 }
107 
108 void
109 Auth::Ntlm::Config::registerWithCacheManager(void)
110 {
111  Mgr::RegisterAction("ntlmauthenticator",
112  "NTLM User Authenticator Stats",
113  authenticateNTLMStats, 0, 1);
114 }
115 
116 bool
117 Auth::Ntlm::Config::active() const
118 {
119  return authntlm_initialised == 1;
120 }
121 
122 bool
123 Auth::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 
136 void
137 Auth::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 
194 static void
196 {
197  if (ntlmauthenticators)
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  */
206 Auth::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 fatal(const char *message)
Definition: fatal.cc:28
void wordlistDestroy(wordlist **list)
destroy a wordlist
Definition: wordlist.cc:16
void openSessions() override
Definition: helper.cc:327
Helper::StatefulClientPointer ntlmauthenticators
Definition: Config.cc:36
#define DBG_CRITICAL
Definition: Stream.h:37
@ AUTH_NTLM
Definition: Type.h:20
HttpHeader header
Definition: Message.h:74
int ipc_type
Definition: helper.h:120
RequestFlags flags
Definition: HttpRequest.h:141
static Pointer Make(const char *name)
Definition: helper.cc:763
HASHHASH hash_string
Definition: hash.h:45
static int authntlm_initialised
Definition: Config.cc:37
void packStatsInto(Packable *p, const char *label=nullptr) const
Dump some stats about the helper state to a Packable object.
Definition: helper.cc:694
C * getRaw() const
Definition: RefCount.h:89
int HASHCMP(const void *, const void *)
Definition: hash.h:13
ChildConfig & updateLimits(const ChildConfig &rhs)
Definition: ChildConfig.cc:45
virtual User::Pointer user()
Definition: UserRequest.h:143
void httpHeaderPutStrf(HttpHeader *hdr, Http::HdrType id, const char *fmt,...)
static SchemeConfig * Find(const char *proxy_auth)
Definition: SchemeConfig.cc:59
static hash_table * proxy_auth_cache
Definition: Config.cc:39
void helperStatefulShutdown(const statefulhelper::Pointer &hlp)
Definition: helper.cc:808
static AUTHSSTATS authenticateNTLMStats
Definition: Config.cc:34
ChildConfig childs
Configuration settings for number running.
Definition: helper.h:119
#define safe_free(x)
Definition: xalloc.h:73
#define assert(EX)
Definition: assert.h:17
wordlist * cmdline
Definition: helper.h:115
void AUTHSSTATS(StoreEntry *)
Definition: Gadgets.h:21
bool mustKeepalive
Definition: RequestFlags.h:83
bool proxyKeepalive
Definition: RequestFlags.h:42
hash_table * hash_create(HASHCMP *, int, HASHHASH *)
Definition: hash.cc:108
void RegisterAction(char const *action, char const *desc, OBJH *handler, Protected, Atomic, Format)
Definition: Registration.cc:54
#define DBG_IMPORTANT
Definition: Stream.h:38
virtual void done()
int shutting_down
#define IPC_STREAM
Definition: defines.h:104
#define debugs(SECTION, LEVEL, CONTENT)
Definition: Stream.h:192

 

Introduction

Documentation

Support

Miscellaneous