15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2011 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// See "SSPI Sample Application" at
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://msdn.microsoft.com/en-us/library/aa918273.aspx
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and "NTLM Security Support Provider" at
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://msdn.microsoft.com/en-us/library/aa923611.aspx.
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_auth_handler_ntlm.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/strings/string_util.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_errors.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_util.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_auth_sspi_win.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/url_security_manager.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#pragma comment(lib, "secur32.lib")
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net {
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HttpAuthHandlerNTLM::HttpAuthHandlerNTLM(
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SSPILibrary* sspi_library, ULONG max_token_length,
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    URLSecurityManager* url_security_manager)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : auth_sspi_(sspi_library, "NTLM", NTLMSP_NAME, max_token_length),
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      url_security_manager_(url_security_manager) {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HttpAuthHandlerNTLM::~HttpAuthHandlerNTLM() {
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Require identity on first pass instead of second.
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HttpAuthHandlerNTLM::NeedsIdentity() {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return auth_sspi_.NeedsIdentity();
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HttpAuthHandlerNTLM::AllowsDefaultCredentials() {
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (target_ == HttpAuth::AUTH_PROXY)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!url_security_manager_)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return url_security_manager_->CanUseDefaultCredentials(origin_);
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HttpAuthHandlerNTLM::Factory::Factory()
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : max_token_length_(0),
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      first_creation_(true),
487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      is_unsupported_(false) {
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HttpAuthHandlerNTLM::Factory::~Factory() {
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int HttpAuthHandlerNTLM::Factory::CreateAuthHandler(
55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    HttpAuthChallengeTokenizer* challenge,
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    HttpAuth::Target target,
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& origin,
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateReason reason,
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int digest_nonce_count,
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const BoundNetLog& net_log,
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    scoped_ptr<HttpAuthHandler>* handler) {
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (is_unsupported_ || reason == CREATE_PREEMPTIVE)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ERR_UNSUPPORTED_AUTH_SCHEME;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (max_token_length_ == 0) {
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int rv = DetermineMaxTokenLength(sspi_library_.get(), NTLMSP_NAME,
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     &max_token_length_);
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv == ERR_UNSUPPORTED_AUTH_SCHEME)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      is_unsupported_ = true;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rv != OK)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return rv;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(cbentzel): Move towards model of parsing in the factory
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //                 method and only constructing when valid.
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<HttpAuthHandler> tmp_handler(
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new HttpAuthHandlerNTLM(sspi_library_.get(), max_token_length_,
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              url_security_manager()));
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!tmp_handler->InitFromChallenge(challenge, target, origin, net_log))
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ERR_INVALID_RESPONSE;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  handler->swap(tmp_handler);
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return OK;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace net
84