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)#ifndef NET_HTTP_HTTP_AUTH_HANDLER_NTLM_H_ 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NET_HTTP_HTTP_AUTH_HANDLER_NTLM_H_ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "build/build_config.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This contains the portable and the SSPI implementations for NTLM. 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We use NTLM_SSPI for Windows, and NTLM_PORTABLE for other platforms. 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NTLM_SSPI 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NTLM_PORTABLE 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(NTLM_SSPI) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SECURITY_WIN32 1 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <windows.h> 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <security.h> 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_auth_sspi_win.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/strings/string16.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_auth_handler.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_auth_handler_factory.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net { 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class URLSecurityManager; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Code for handling HTTP NTLM authentication. 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class NET_EXPORT_PRIVATE HttpAuthHandlerNTLM : public HttpAuthHandler { 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class Factory : public HttpAuthHandlerFactory { 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Factory(); 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~Factory(); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual int CreateAuthHandler( 45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) HttpAuthChallengeTokenizer* challenge, 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpAuth::Target target, 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& origin, 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateReason reason, 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int digest_nonce_count, 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BoundNetLog& net_log, 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<HttpAuthHandler>* handler) OVERRIDE; 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(NTLM_SSPI) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set the SSPILibrary to use. Typically the only callers which need to use 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // this are unit tests which pass in a mocked-out version of the SSPI 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // library. After the call |sspi_library| will be owned by this Factory and 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // will be destroyed when the Factory is destroyed. 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void set_sspi_library(SSPILibrary* sspi_library) { 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sspi_library_.reset(sspi_library); 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // defined(NTLM_SSPI) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(NTLM_SSPI) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ULONG max_token_length_; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool first_creation_; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_unsupported_; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<SSPILibrary> sspi_library_; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // defined(NTLM_SSPI) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(NTLM_PORTABLE) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A function that generates n random bytes in the output buffer. 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef void (*GenerateRandomProc)(uint8* output, size_t n); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A function that returns the local host name. Returns an empty string if 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the local host name is not available. 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::string (*HostNameProc)(); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For unit tests to override and restore the GenerateRandom and 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // GetHostName functions. 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class ScopedProcSetter { 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedProcSetter(GenerateRandomProc random_proc, 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HostNameProc host_name_proc) { 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) old_random_proc_ = SetGenerateRandomProc(random_proc); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) old_host_name_proc_ = SetHostNameProc(host_name_proc); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~ScopedProcSetter() { 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetGenerateRandomProc(old_random_proc_); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetHostNameProc(old_host_name_proc_); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GenerateRandomProc old_random_proc_; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HostNameProc old_host_name_proc_; 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(NTLM_PORTABLE) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpAuthHandlerNTLM(); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(NTLM_SSPI) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpAuthHandlerNTLM(SSPILibrary* sspi_library, ULONG max_token_length, 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLSecurityManager* url_security_manager); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool NeedsIdentity() OVERRIDE; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool AllowsDefaultCredentials() OVERRIDE; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual HttpAuth::AuthorizationResult HandleAnotherChallenge( 112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) HttpAuthChallengeTokenizer* challenge) OVERRIDE; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This function acquires a credentials handle in the SSPI implementation. 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // It does nothing in the portable implementation. 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int InitializeBeforeFirstChallenge(); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) virtual bool Init(HttpAuthChallengeTokenizer* tok) OVERRIDE; 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual int GenerateAuthTokenImpl(const AuthCredentials* credentials, 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HttpRequestInfo* request, 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const CompletionCallback& callback, 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* auth_token) OVERRIDE; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~HttpAuthHandlerNTLM(); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(NTLM_PORTABLE) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For unit tests to override the GenerateRandom and GetHostName functions. 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the old function. 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static GenerateRandomProc SetGenerateRandomProc(GenerateRandomProc proc); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static HostNameProc SetHostNameProc(HostNameProc proc); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Parse the challenge, saving the results into this instance. 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpAuth::AuthorizationResult ParseChallenge( 138a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) HttpAuthChallengeTokenizer* tok, bool initial_challenge); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Given an input token received from the server, generate the next output 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // token to be sent to the server. 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int GetNextToken(const void* in_token, 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 in_token_len, 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void** out_token, 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32* out_token_len); 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create an NTLM SPN to identify the |origin| server. 148a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) static std::string CreateSPN(const GURL& origin); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(NTLM_SSPI) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpAuthSSPI auth_sspi_; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(NTLM_PORTABLE) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static GenerateRandomProc generate_random_proc_; 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static HostNameProc get_host_name_proc_; 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::string16 domain_; 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AuthCredentials credentials_; 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The base64-encoded string following "NTLM" in the "WWW-Authenticate" or 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // "Proxy-Authenticate" response header. 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string auth_data_; 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(NTLM_SSPI) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URLSecurityManager* url_security_manager_; 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace net 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // NET_HTTP_HTTP_AUTH_HANDLER_NTLM_H_ 174