} else if (!strncmp(p,"TT ",3)) {
// NTLM challenge token
result = HelperReply::TT;
- p+=2;
+ p+=3;
+ // followed by an auth token
+ char *token = strwordtok(NULL, &p);
+ authToken.init();
+ authToken.append(token, strlen(token));
} else if (!strncmp(p,"AF ",3)) {
- // NTLM OK response
- result = HelperReply::AF;
+ // NTLM/Negotate OK response
+ result = HelperReply::OK;
p+=3;
+ // followed by:
+ // an auth token and user field
+ // or, an optional username field
+ char *blob = strwordtok(NULL, &p);
+ char *arg = strwordtok(NULL, &p);
+ if (arg != NULL) {
+ authToken.init();
+ authToken.append(blob, strlen(blob));
+ user.init();
+ user.append(arg,strlen(arg));
+ } else if (blob != NULL) {
+ user.init();
+ user.append(blob, strlen(blob));
+ }
} else if (!strncmp(p,"NA ",3)) {
// NTLM fail-closed ERR response
result = HelperReply::NA;
operator <<(std::ostream &os, const HelperReply &r)
{
os << "{result=";
- switch(r.result)
- {
- switch (r.result) {
++ switch(r.result) {
case HelperReply::Okay:
os << "OK";
break;
public:
// create/parse details from the msg buffer provided
- HelperReply(const char *buf, size_t len);
+ HelperReply(const char *buf, size_t len, bool urlQuoting = false);
- ~HelperReply() {}
const MemBuf &other() const { return other_; }
case HelperReply::TT:
/* we have been given a blob to send to the client */
safe_free(lm_request->server_blob);
- lm_request->request->flags.must_keepalive = 1;
- if (lm_request->request->flags.proxy_keepalive) {
+ lm_request->request->flags.mustKeepalive = 1;
+ if (lm_request->request->flags.proxyKeepalive) {
- lm_request->server_blob = xstrdup(blob);
+ lm_request->server_blob = xstrdup(reply.authToken.content());
auth_user_request->user()->credentials(Auth::Handshake);
auth_user_request->denyMessage("Authentication in progress");
- debugs(29, 4, HERE << "Need to challenge the client with a server blob '" << blob << "'");
+ debugs(29, 4, HERE << "Need to challenge the client with a server token: '" << reply.authToken << "'");
} else {
auth_user_request->user()->credentials(Auth::Failed);
- auth_user_request->denyMessage("NTLM authentication requires a persistent connection");
+ auth_user_request->denyMessage("Negotiate authentication requires a persistent connection");
}
break;
- case HelperReply::Okay:
- {
- case HelperReply::AF:
+ case HelperReply::Okay: {
- if (arg == NULL) {
+ if (!reply.user.hasContent()) {
// XXX: handle a success with no username better
/* protocol error */
fatalf("authenticateNegotiateHandleReply: *** Unsupported helper response ***, '%s'\n", reply.other().content());
* existing user or a new user */
local_auth_user->expiretime = current_time.tv_sec;
auth_user_request->user()->credentials(Auth::Ok);
- debugs(29, 4, HERE << "Successfully validated user via Negotiate. Username '" << arg << "'");
+ debugs(29, 4, HERE << "Successfully validated user via Negotiate. Username '" << reply.user << "'");
}
- break;
+ break;
case HelperReply::NA:
case HelperReply::Error:
case HelperReply::TT:
/* we have been given a blob to send to the client */
safe_free(lm_request->server_blob);
- lm_request->request->flags.must_keepalive = 1;
- if (lm_request->request->flags.proxy_keepalive) {
+ lm_request->request->flags.mustKeepalive = 1;
+ if (lm_request->request->flags.proxyKeepalive) {
- lm_request->server_blob = xstrdup(blob);
+ lm_request->server_blob = xstrdup(reply.authToken.content());
auth_user_request->user()->credentials(Auth::Handshake);
auth_user_request->denyMessage("Authentication in progress");
- debugs(29, 4, HERE << "Need to challenge the client with a server blob '" << blob << "'");
+ debugs(29, 4, HERE << "Need to challenge the client with a server token: '" << reply.authToken << "'");
} else {
auth_user_request->user()->credentials(Auth::Failed);
auth_user_request->denyMessage("NTLM authentication requires a persistent connection");
}
break;
- case HelperReply::Okay:
- {
+ case HelperReply::AF:
+ case HelperReply::Okay: {
/* we're finished, release the helper */
- auth_user_request->user()->username(blob);
+ auth_user_request->user()->username(reply.user.content());
auth_user_request->denyMessage("Login successful");
safe_free(lm_request->server_blob);
lm_request->releaseAuthServer();
* existing user or a new user */
local_auth_user->expiretime = current_time.tv_sec;
auth_user_request->user()->credentials(Auth::Ok);
- debugs(29, 4, HERE << "Successfully validated user via NTLM. Username '" << blob << "'");
+ debugs(29, 4, HERE << "Successfully validated user via NTLM. Username '" << reply.user << "'");
}
- break;
+ break;
case HelperReply::NA:
case HelperReply::Error:
if (squid_curtime - first_warn > 3 * 60)
fatal("SSL servers not responding for 3 minutes");
debugs(34, DBG_IMPORTANT, HERE << "Queue overload, rejecting");
- const char *errMsg = "BH error 45 Temporary network problem, please retry later"; // XXX: upgrade to message=""
+ const char *errMsg = "BH message=\"error 45 Temporary network problem, please retry later\"";
- callback(data, HelperReply(errMsg,strlen(errMsg)));
+ HelperReply failReply(errMsg,strlen(errMsg));
+ callback(data, failReply);
return;
}