Commit 25a20e23 authored by Zentaro Kavanagh's avatar Zentaro Kavanagh Committed by Commit Bot

Make new NTLM implementation live.

- Passes all unit tests of previous implementation with minor exception
- New implementation points empty security buffers at end of header
  rather than 0 to follow the recommendation of the spec.

BUG=chromium:22532

Change-Id: I3e7617f512af70600b5c7e03be2dd8a7936a5bbd
Reviewed-on: https://chromium-review.googlesource.com/598309
Commit-Queue: Zentaro Kavanagh <zentaro@google.com>
Reviewed-by: default avatarAsanka Herath <asanka@chromium.org>
Cr-Commit-Position: refs/heads/master@{#504077}
parent 08f92b3c
......@@ -49,13 +49,6 @@ int HttpAuthHandlerNTLM::GenerateAuthTokenImpl(
LOG(ERROR) << "Username and password are expected to be non-NULL.";
return ERR_MISSING_AUTH_CREDENTIALS;
}
// TODO(wtc): See if we can use char* instead of void* for in_buf and
// out_buf. This change will need to propagate to GetNextToken,
// GenerateType1Msg, and GenerateType3Msg, and perhaps further.
const void* in_buf;
void* out_buf;
uint32_t in_buf_len, out_buf_len;
std::string decoded_auth_data;
// The username may be in the form "DOMAIN\user". Parse it into the two
// components.
......@@ -73,32 +66,33 @@ int HttpAuthHandlerNTLM::GenerateAuthTokenImpl(
domain_ = domain;
credentials_.Set(user, credentials->password());
// Initial challenge.
std::string decoded_auth_data;
if (auth_data_.empty()) {
in_buf_len = 0;
in_buf = NULL;
// There is no |auth_data_| because the client sends the first message.
int rv = InitializeBeforeFirstChallenge();
if (rv != OK)
return rv;
} else {
// When |auth_data_| is present it contains the Challenge message.
if (!base::Base64Decode(auth_data_, &decoded_auth_data)) {
LOG(ERROR) << "Unexpected problem Base64 decoding.";
return ERR_UNEXPECTED;
}
in_buf_len = decoded_auth_data.length();
in_buf = decoded_auth_data.data();
}
int rv = GetNextToken(in_buf, in_buf_len, &out_buf, &out_buf_len);
if (rv != OK)
return rv;
ntlm::Buffer next_token = GetNextToken(
ntlm::Buffer(reinterpret_cast<const uint8_t*>(decoded_auth_data.data()),
decoded_auth_data.size()));
if (next_token.empty())
return ERR_UNEXPECTED;
// Base64 encode data in output buffer and prepend "NTLM ".
std::string encode_input(static_cast<char*>(out_buf), out_buf_len);
std::string encode_output;
base::Base64Encode(encode_input, &encode_output);
// OK, we are done with |out_buf|
free(out_buf);
base::Base64Encode(
base::StringPiece(reinterpret_cast<const char*>(next_token.data()),
next_token.size()),
&encode_output);
*auth_token = std::string("NTLM ") + encode_output;
return OK;
#endif
......
......@@ -23,6 +23,8 @@
#include <windows.h>
#include <security.h>
#include "net/http/http_auth_sspi_win.h"
#elif defined(NTLM_PORTABLE)
#include "net/ntlm/ntlm_client.h"
#endif
#include <string>
......@@ -134,24 +136,23 @@ class NET_EXPORT_PRIVATE HttpAuthHandlerNTLM : public HttpAuthHandler {
// Returns the old function.
static GenerateRandomProc SetGenerateRandomProc(GenerateRandomProc proc);
static HostNameProc SetHostNameProc(HostNameProc proc);
// Given an input token received from the server, generate the next output
// token to be sent to the server.
ntlm::Buffer GetNextToken(const ntlm::Buffer& in_token);
#endif
// Parse the challenge, saving the results into this instance.
HttpAuth::AuthorizationResult ParseChallenge(
HttpAuthChallengeTokenizer* tok, bool initial_challenge);
// Given an input token received from the server, generate the next output
// token to be sent to the server.
int GetNextToken(const void* in_token,
uint32_t in_token_len,
void** out_token,
uint32_t* out_token_len);
// Create an NTLM SPN to identify the |origin| server.
static std::string CreateSPN(const GURL& origin);
#if defined(NTLM_SSPI)
HttpAuthSSPI auth_sspi_;
#elif defined(NTLM_PORTABLE)
ntlm::NtlmClient ntlm_client_;
#endif
#if defined(NTLM_PORTABLE)
......
This diff is collapsed.
......@@ -174,7 +174,7 @@ TEST_F(HttpAuthHandlerNtlmPortableTest, VerifyType1Message) {
// The type 1 message generated is always the same. The only variable
// part of the message is the flags and this implementation always offers
// the same set of flags.
ASSERT_EQ("NTLM TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=", token);
ASSERT_EQ("NTLM TlRMTVNTUAABAAAAB4IIAAAAAAAgAAAAAAAAACAAAAA=", token);
}
TEST_F(HttpAuthHandlerNtlmPortableTest, EmptyTokenFails) {
......
......@@ -21,6 +21,8 @@ constexpr base::char16 kPassword[] = {'P', 'a', 's', 's', 'w',
'o', 'r', 'd', '\0'};
constexpr base::char16 kNtlmDomain[] = {'D', 'o', 'm', 'a', 'i', 'n', '\0'};
constexpr base::char16 kUser[] = {'U', 's', 'e', 'r', '\0'};
constexpr base::char16 kDomainUserCombined[] = {'D', 'o', 'm', 'a', 'i', 'n',
'\\', 'U', 's', 'e', 'r', '\0'};
constexpr base::char16 kHostname[] = {'C', 'O', 'M', 'P', 'U',
'T', 'E', 'R', '\0'};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment