1// Copyright (c) 2010 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// See "SSPI Sample Application" at
6// http://msdn.microsoft.com/en-us/library/aa918273.aspx
7// and "NTLM Security Support Provider" at
8// http://msdn.microsoft.com/en-us/library/aa923611.aspx.
9
10#include "net/http/http_auth_handler_ntlm.h"
11
12#include "base/string_util.h"
13#include "net/base/net_errors.h"
14#include "net/base/net_util.h"
15#include "net/http/http_auth_sspi_win.h"
16#include "net/http/url_security_manager.h"
17
18#pragma comment(lib, "secur32.lib")
19
20namespace net {
21
22HttpAuthHandlerNTLM::HttpAuthHandlerNTLM(
23    SSPILibrary* sspi_library, ULONG max_token_length,
24    URLSecurityManager* url_security_manager)
25    : auth_sspi_(sspi_library, "NTLM", NTLMSP_NAME, max_token_length),
26      url_security_manager_(url_security_manager) {
27}
28
29HttpAuthHandlerNTLM::~HttpAuthHandlerNTLM() {
30}
31
32// Require identity on first pass instead of second.
33bool HttpAuthHandlerNTLM::NeedsIdentity() {
34  return auth_sspi_.NeedsIdentity();
35}
36
37bool HttpAuthHandlerNTLM::AllowsDefaultCredentials() {
38  if (target_ == HttpAuth::AUTH_PROXY)
39    return true;
40  if (!url_security_manager_)
41    return false;
42  return url_security_manager_->CanUseDefaultCredentials(origin_);
43}
44
45HttpAuthHandlerNTLM::Factory::Factory()
46    : max_token_length_(0),
47      first_creation_(true),
48      is_unsupported_(false),
49      sspi_library_(NULL) {
50}
51
52HttpAuthHandlerNTLM::Factory::~Factory() {
53}
54
55int HttpAuthHandlerNTLM::Factory::CreateAuthHandler(
56    HttpAuth::ChallengeTokenizer* challenge,
57    HttpAuth::Target target,
58    const GURL& origin,
59    CreateReason reason,
60    int digest_nonce_count,
61    const BoundNetLog& net_log,
62    scoped_ptr<HttpAuthHandler>* handler) {
63  if (is_unsupported_ || reason == CREATE_PREEMPTIVE)
64    return ERR_UNSUPPORTED_AUTH_SCHEME;
65  if (max_token_length_ == 0) {
66    int rv = DetermineMaxTokenLength(sspi_library_, NTLMSP_NAME,
67                                     &max_token_length_);
68    if (rv == ERR_UNSUPPORTED_AUTH_SCHEME)
69      is_unsupported_ = true;
70    if (rv != OK)
71      return rv;
72  }
73  // TODO(cbentzel): Move towards model of parsing in the factory
74  //                 method and only constructing when valid.
75  scoped_ptr<HttpAuthHandler> tmp_handler(
76      new HttpAuthHandlerNTLM(sspi_library_, max_token_length_,
77                              url_security_manager()));
78  if (!tmp_handler->InitFromChallenge(challenge, target, origin, net_log))
79    return ERR_INVALID_RESPONSE;
80  handler->swap(tmp_handler);
81  return OK;
82}
83
84}  // namespace net
85