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

 

Introduction

Documentation

Support

Miscellaneous

Web Site Translations

Mirrors