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#ifndef NET_HTTP_HTTP_AUTH_HANDLER_NTLM_H_
6#define NET_HTTP_HTTP_AUTH_HANDLER_NTLM_H_
7#pragma once
8
9#include "build/build_config.h"
10
11// This contains the portable and the SSPI implementations for NTLM.
12// We use NTLM_SSPI for Windows, and NTLM_PORTABLE for other platforms.
13#if defined(OS_WIN)
14#define NTLM_SSPI
15#else
16#define NTLM_PORTABLE
17#endif
18
19#if defined(NTLM_SSPI)
20#define SECURITY_WIN32 1
21#include <windows.h>
22#include <security.h>
23#include "net/http/http_auth_sspi_win.h"
24#endif
25
26#include <string>
27
28#include "base/basictypes.h"
29#include "base/string16.h"
30#include "net/http/http_auth_handler.h"
31#include "net/http/http_auth_handler_factory.h"
32
33namespace net {
34
35class URLSecurityManager;
36
37// Code for handling HTTP NTLM authentication.
38class HttpAuthHandlerNTLM : public HttpAuthHandler {
39 public:
40  class Factory : public HttpAuthHandlerFactory {
41   public:
42    Factory();
43    virtual ~Factory();
44
45    virtual int CreateAuthHandler(HttpAuth::ChallengeTokenizer* challenge,
46                                  HttpAuth::Target target,
47                                  const GURL& origin,
48                                  CreateReason reason,
49                                  int digest_nonce_count,
50                                  const BoundNetLog& net_log,
51                                  scoped_ptr<HttpAuthHandler>* handler);
52#if defined(NTLM_SSPI)
53    // Set the SSPILibrary to use. Typically the only callers which need to
54    // use this are unit tests which pass in a mocked-out version of the
55    // SSPI library.
56    // The caller is responsible for managing the lifetime of |*sspi_library|,
57    // and the lifetime must exceed that of this Factory object and all
58    // HttpAuthHandler's that this Factory object creates.
59    void set_sspi_library(SSPILibrary* sspi_library) {
60      sspi_library_ = sspi_library;
61    }
62#endif  // defined(NTLM_SSPI)
63   private:
64#if defined(NTLM_SSPI)
65    ULONG max_token_length_;
66    bool first_creation_;
67    bool is_unsupported_;
68    SSPILibrary* sspi_library_;
69#endif  // defined(NTLM_SSPI)
70  };
71
72#if defined(NTLM_PORTABLE)
73  // A function that generates n random bytes in the output buffer.
74  typedef void (*GenerateRandomProc)(uint8* output, size_t n);
75
76  // A function that returns the local host name. Returns an empty string if
77  // the local host name is not available.
78  typedef std::string (*HostNameProc)();
79
80  // For unit tests to override and restore the GenerateRandom and
81  // GetHostName functions.
82  class ScopedProcSetter {
83   public:
84    ScopedProcSetter(GenerateRandomProc random_proc,
85                     HostNameProc host_name_proc) {
86      old_random_proc_ = SetGenerateRandomProc(random_proc);
87      old_host_name_proc_ = SetHostNameProc(host_name_proc);
88    }
89
90    ~ScopedProcSetter() {
91      SetGenerateRandomProc(old_random_proc_);
92      SetHostNameProc(old_host_name_proc_);
93    }
94
95   private:
96    GenerateRandomProc old_random_proc_;
97    HostNameProc old_host_name_proc_;
98  };
99#endif
100
101#if defined(NTLM_PORTABLE)
102  HttpAuthHandlerNTLM();
103#endif
104#if defined(NTLM_SSPI)
105  HttpAuthHandlerNTLM(SSPILibrary* sspi_library, ULONG max_token_length,
106                      URLSecurityManager* url_security_manager);
107#endif
108
109  virtual bool NeedsIdentity();
110
111  virtual bool AllowsDefaultCredentials();
112
113  virtual HttpAuth::AuthorizationResult HandleAnotherChallenge(
114      HttpAuth::ChallengeTokenizer* challenge);
115
116 protected:
117  // This function acquires a credentials handle in the SSPI implementation.
118  // It does nothing in the portable implementation.
119  int InitializeBeforeFirstChallenge();
120
121  virtual bool Init(HttpAuth::ChallengeTokenizer* tok);
122
123  virtual int GenerateAuthTokenImpl(const string16* username,
124                                    const string16* password,
125                                    const HttpRequestInfo* request,
126                                    CompletionCallback* callback,
127                                    std::string* auth_token);
128
129 private:
130  ~HttpAuthHandlerNTLM();
131
132#if defined(NTLM_PORTABLE)
133  // For unit tests to override the GenerateRandom and GetHostName functions.
134  // Returns the old function.
135  static GenerateRandomProc SetGenerateRandomProc(GenerateRandomProc proc);
136  static HostNameProc SetHostNameProc(HostNameProc proc);
137#endif
138
139  // Parse the challenge, saving the results into this instance.
140  HttpAuth::AuthorizationResult ParseChallenge(
141      HttpAuth::ChallengeTokenizer* tok, bool initial_challenge);
142
143  // Given an input token received from the server, generate the next output
144  // token to be sent to the server.
145  int GetNextToken(const void* in_token,
146                   uint32 in_token_len,
147                   void** out_token,
148                   uint32* out_token_len);
149
150  // Create an NTLM SPN to identify the |origin| server.
151  static std::wstring CreateSPN(const GURL& origin);
152
153#if defined(NTLM_SSPI)
154  HttpAuthSSPI auth_sspi_;
155#endif
156
157#if defined(NTLM_PORTABLE)
158  static GenerateRandomProc generate_random_proc_;
159  static HostNameProc get_host_name_proc_;
160#endif
161
162  string16 domain_;
163  string16 username_;
164  string16 password_;
165
166  // The base64-encoded string following "NTLM" in the "WWW-Authenticate" or
167  // "Proxy-Authenticate" response header.
168  std::string auth_data_;
169
170#if defined(NTLM_SSPI)
171  URLSecurityManager* url_security_manager_;
172#endif
173};
174
175}  // namespace net
176
177#endif  // NET_HTTP_HTTP_AUTH_HANDLER_NTLM_H_
178