Add the token= key for server blobs from Negotiate helpers.
Update HelperReply parser to convert AF responses when received.
result = HelperReply::TT;
p+=2;
} else if (!strncmp(p,"AF ",3)) {
- // NTLM OK response
- result = HelperReply::AF;
- p+=2;
+ // NTLM/Negotate OK response
+ result = HelperReply::OK;
+ p+=3;
+ // followed by an auth token
+ char *token = strwordtok(NULL, &p);
+ authToken.init();
+ authToken.append(token, strlen(token));
+ // ... and an optional username field
+ for(;xisspace(*p);p++); // skip whitespace
+ if (*p) {
+ user.init();
+ user.append(p,strlen(p));
+ p += user.size();
+ }
} else if (!strncmp(p,"NA ",3)) {
// NTLM fail-closed ERR response
result = HelperReply::NA;
found |= parseKeyValue("password=", 9, password);
found |= parseKeyValue("message=", 8, message);
found |= parseKeyValue("log=", 8, log);
+ found |= parseKeyValue("token=", 8, authToken);
} while(found);
if (urlQuoting) {
case HelperReply::TT:
os << "TT";
break;
- case HelperReply::AF:
- os << "AF";
- break;
case HelperReply::NA:
os << "NA";
break;
// some result codes for backward compatibility with NTLM/Negotiate
// TODO: migrate these into variants of the above results with key-pair parameters
TT,
- AF,
NA
} result;
MemBuf password;
MemBuf message;
MemBuf log;
+ MemBuf authToken;
// TODO other (custom) key=pair values. when the callbacks actually use this object.
// for now they retain their own parsing routines handling other()
}
break;
- 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());
}
/* we're finished, release the helper */
- auth_user_request->user()->username(arg);
+ auth_user_request->user()->username(reply.user.content());
auth_user_request->denyMessage("Login successful");
safe_free(lm_request->server_blob);
- lm_request->server_blob = xstrdup(blob);
+ lm_request->server_blob = xstrdup(reply.authToken.content());
lm_request->releaseAuthServer();
/* connection is authenticated */
* 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::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();
- debugs(29, 4, HERE << "Successfully validated user via NTLM. Username '" << blob << "'");
+ debugs(29, 4, HERE << "Successfully validated user via NTLM. Username '" << reply.user << "'");
/* connection is authenticated */
debugs(29, 4, HERE << "authenticated user " << auth_user_request->user()->username());
/* see if this is an existing user with a different proxy_auth
* 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;