Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(338)

Side by Side Diff: net/http/http_auth_handler_ntlm_win.cc

Issue 242135: Merge r25564 and r26588 from the trunk.... (Closed) Base URL: svn://chrome-svn/chrome/branches/195/src/
Patch Set: Undo an extraneous comment change Created 11 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/http/http_auth_handler_ntlm_portable.cc ('k') | net/http/http_auth_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2009 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/logging.h"
13 #include "base/string_util.h"
14 #include "net/base/net_errors.h"
15 #include "net/base/net_util.h"
16
17 #pragma comment(lib, "secur32.lib")
18
19 namespace {
20
21 void ZapString(string16* s) {
22 memset(&(*s)[0], 0, s->length() * 2);
23 }
24
25 } // namespace
26
27 namespace net {
28
29 HttpAuthHandlerNTLM::HttpAuthHandlerNTLM() : max_token_len_(0) {
30 SecInvalidateHandle(&cred_);
31 SecInvalidateHandle(&ctxt_);
32 }
33
34 HttpAuthHandlerNTLM::~HttpAuthHandlerNTLM() {
35 ResetSecurityContext();
36 if (SecIsValidHandle(&cred_)) {
37 FreeCredentialsHandle(&cred_);
38 SecInvalidateHandle(&cred_);
39 }
40 ZapString(&password_);
41 }
42
43 int HttpAuthHandlerNTLM::InitializeBeforeFirstChallenge() {
44 DCHECK_EQ("ntlm", scheme_) << "This is not ntlm scheme";
45
46 SEC_WCHAR* package = NTLMSP_NAME;
47 PSecPkgInfo pkg_info;
48 SECURITY_STATUS status;
49
50 // The following API call is required to get the maximum token length
51 // for the scheme.
52 // TODO(arindam): Move this (PSecPkgInfo) to a static function.
53 status = QuerySecurityPackageInfo(package, &pkg_info);
54 if (status != SEC_E_OK) {
55 LOG(ERROR) << "Security package " << package << " not found";
56 return ERR_UNEXPECTED;
57 }
58 max_token_len_ = pkg_info->cbMaxToken;
59 FreeContextBuffer(pkg_info);
60
61 SEC_WINNT_AUTH_IDENTITY identity;
62 identity.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
63 identity.User =
64 reinterpret_cast<USHORT*>(const_cast<wchar_t*>(username_.c_str()));
65 identity.UserLength = username_.size();
66 identity.Domain =
67 reinterpret_cast<USHORT*>(const_cast<wchar_t*>(domain_.c_str()));
68 identity.DomainLength = domain_.size();
69 identity.Password =
70 reinterpret_cast<USHORT*>(const_cast<wchar_t*>(password_.c_str()));
71 identity.PasswordLength = password_.size();
72
73 TimeStamp expiry; // Since the credentials handle doesn't expire, ignore
74 // the expiration time.
75
76 // Pass the username/password to get the credentials handle.
77 // Note: If the 5th argument is NULL, it uses the default cached credentials
78 // for the logged in user, which can be used for single sign-on.
79 status = AcquireCredentialsHandle(NULL, // pszPrincipal
80 package, // pszPackage
81 SECPKG_CRED_OUTBOUND, // fCredentialUse
82 NULL, // pvLogonID
83 &identity, // pAuthData
84 NULL, // pGetKeyFn (not used)
85 NULL, // pvGetKeyArgument (not used)
86 &cred_, // phCredential
87 &expiry); // ptsExpiry
88 if (status != SEC_E_OK)
89 return ERR_UNEXPECTED;
90
91 return OK;
92 }
93
94 int HttpAuthHandlerNTLM::GetNextToken(const void* in_token,
95 uint32 in_token_len,
96 void** out_token,
97 uint32* out_token_len) {
98 SECURITY_STATUS status;
99 TimeStamp expiry;
100
101 DWORD ctxt_attr;
102 CtxtHandle* ctxt_ptr;
103 SecBufferDesc in_buffer_desc, out_buffer_desc;
104 SecBufferDesc* in_buffer_desc_ptr;
105 SecBuffer in_buffer, out_buffer;
106
107 if (in_token) {
108 // Prepare input buffer.
109 in_buffer_desc.ulVersion = SECBUFFER_VERSION;
110 in_buffer_desc.cBuffers = 1;
111 in_buffer_desc.pBuffers = &in_buffer;
112 in_buffer.BufferType = SECBUFFER_TOKEN;
113 in_buffer.cbBuffer = in_token_len;
114 in_buffer.pvBuffer = const_cast<void*>(in_token);
115 ctxt_ptr = &ctxt_;
116 in_buffer_desc_ptr = &in_buffer_desc;
117 } else {
118 // If there is no input token, then we are starting a new authentication
119 // sequence. If we have already initialized our security context, then
120 // we're incorrectly reusing the auth handler for a new sequence.
121 if (SecIsValidHandle(&ctxt_)) {
122 LOG(ERROR) << "Cannot restart authentication sequence";
123 return ERR_UNEXPECTED;
124 }
125 ctxt_ptr = NULL;
126 in_buffer_desc_ptr = NULL;
127 }
128
129 // Prepare output buffer.
130 out_buffer_desc.ulVersion = SECBUFFER_VERSION;
131 out_buffer_desc.cBuffers = 1;
132 out_buffer_desc.pBuffers = &out_buffer;
133 out_buffer.BufferType = SECBUFFER_TOKEN;
134 out_buffer.cbBuffer = max_token_len_;
135 out_buffer.pvBuffer = malloc(out_buffer.cbBuffer);
136 if (!out_buffer.pvBuffer)
137 return ERR_OUT_OF_MEMORY;
138
139 // The service principal name of the destination server. See
140 // http://msdn.microsoft.com/en-us/library/ms677949%28VS.85%29.aspx
141 std::wstring target(L"HTTP/");
142 target.append(ASCIIToWide(GetHostAndPort(origin_)));
143 wchar_t* target_name = const_cast<wchar_t*>(target.c_str());
144
145 // This returns a token that is passed to the remote server.
146 status = InitializeSecurityContext(&cred_, // phCredential
147 ctxt_ptr, // phContext
148 target_name, // pszTargetName
149 0, // fContextReq
150 0, // Reserved1 (must be 0)
151 SECURITY_NATIVE_DREP, // TargetDataRep
152 in_buffer_desc_ptr, // pInput
153 0, // Reserved2 (must be 0)
154 &ctxt_, // phNewContext
155 &out_buffer_desc, // pOutput
156 &ctxt_attr, // pfContextAttr
157 &expiry); // ptsExpiry
158 // On success, the function returns SEC_I_CONTINUE_NEEDED on the first call
159 // and SEC_E_OK on the second call. On failure, the function returns an
160 // error code.
161 if (status != SEC_I_CONTINUE_NEEDED && status != SEC_E_OK) {
162 LOG(ERROR) << "InitializeSecurityContext failed: " << status;
163 ResetSecurityContext();
164 free(out_buffer.pvBuffer);
165 return ERR_UNEXPECTED; // TODO(wtc): map error code.
166 }
167 if (!out_buffer.cbBuffer) {
168 free(out_buffer.pvBuffer);
169 out_buffer.pvBuffer = NULL;
170 }
171 *out_token = out_buffer.pvBuffer;
172 *out_token_len = out_buffer.cbBuffer;
173 return OK;
174 }
175
176 // Require identity on first pass instead of second.
177 bool HttpAuthHandlerNTLM::NeedsIdentity() {
178 return auth_data_.empty();
179 }
180
181 bool HttpAuthHandlerNTLM::IsFinalRound() {
182 return !auth_data_.empty();
183 }
184
185 void HttpAuthHandlerNTLM::ResetSecurityContext() {
186 if (SecIsValidHandle(&ctxt_)) {
187 DeleteSecurityContext(&ctxt_);
188 SecInvalidateHandle(&ctxt_);
189 }
190 }
191
192 } // namespace net
193
OLDNEW
« no previous file with comments | « net/http/http_auth_handler_ntlm_portable.cc ('k') | net/http/http_auth_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698