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

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

Issue 159656: Include SSPI support for NTLM authentication. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: files moved Created 11 years, 4 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_posix.cc ('k') | net/http/http_network_transaction_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Property Changes:
Added: svn:eol-style
+ LF
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 #include "net/http/http_auth_handler_ntlm.h"
6
7 #include "base/logging.h"
8 #include "net/base/net_errors.h"
9
10 #if !defined(NDEBUG)
11 #define CASE_(_x) case _x: return # _x;
12 static const char *MapErrorCode(int rc) {
13 switch (rc) {
14 CASE_(SEC_E_OK)
15 CASE_(SEC_I_CONTINUE_NEEDED)
16 CASE_(SEC_I_COMPLETE_NEEDED)
17 CASE_(SEC_I_COMPLETE_AND_CONTINUE)
18 CASE_(SEC_E_INCOMPLETE_MESSAGE)
19 CASE_(SEC_I_INCOMPLETE_CREDENTIALS)
20 CASE_(SEC_E_INVALID_HANDLE)
21 CASE_(SEC_E_TARGET_UNKNOWN)
22 CASE_(SEC_E_LOGON_DENIED)
23 CASE_(SEC_E_INTERNAL_ERROR)
24 CASE_(SEC_E_NO_CREDENTIALS)
25 CASE_(SEC_E_NO_AUTHENTICATING_AUTHORITY)
26 CASE_(SEC_E_INSUFFICIENT_MEMORY)
27 CASE_(SEC_E_INVALID_TOKEN)
28 }
29 return "<unknown>";
30 }
31 #else
32 #define MapErrorCode(x) (x)
33 #endif
34
35 namespace net {
36
37 HttpAuthHandlerNTLM::HttpAuthHandlerNTLM()
38 : max_token_len_(0) {
39 memset(&cred_, 0, sizeof(cred_));
40 memset(&ctxt_, 0, sizeof(ctxt_));
41 }
42
43 HttpAuthHandlerNTLM::~HttpAuthHandlerNTLM() {
44 ResetSecurityContext();
45 if (cred_.dwLower || cred_.dwUpper) {
46 FreeCredentialHandle(&cred_);
47 memset(&cred_, 0, sizeof(cred_));
48 }
49 ZapString(&password_);
50 }
51
52 int HttpAuthHandlerNTLM::InitializeBeforeFirstChallenge() {
53 DCHECK_EQ("ntlm", scheme_) << "This is not ntlm scheme";
54
55 SEC_WCHAR *package = L"NTLM";
56 PSecPkgInfo pinfo;
57 TimeStamp use_before;
58 SECURITY_STATUS rc;
59
60 // The following API call is required to get the maximum token length
61 // for the scheme.
62 // TODO(arindam): Can we move this (PSecPkgInfo) to a static function ?
63 rc = QuerySecurityPackageInfo(package, &pinfo);
64 if (rc != SEC_E_OK) {
65 LOG(ERROR) << package << " not found";
66 return ERR_UNEXPECTED;
67 }
68 max_token_len_ = pinfo->cbMaxToken;
69 FreeContextBuffer(pinfo);
70
71 SEC_WINNT_AUTH_IDENTITY identity;
72 identity.Domain =
73 reinterpret_cast<USHORT*>(const_cast<wchar_t*>(domain_.data()));
74 identity.DomainLength = domain_.size();
75 identity.User =
76 reinterpret_cast<USHORT*>(const_cast<wchar_t*>(username_.data()));
77 identity.UserLength = username_.size();
78 identity.Password =
79 reinterpret_cast<USHORT*>(const_cast<wchar_t*>(password_.data()));
80 identity.PasswordLength = password_.size();
81 identity.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
82
83 LOG(ERROR) << "Calling Acquire Creds Handle";
84
85 // Pass the username/password to get the credentials.
86 // Note: If params 1 and 5 are NULL, it gets the credentials for the
87 // logged in user which can be used for single sign-on.
88 rc = AcquireCredentialsHandle(const_cast<wchar_t*>(username_.c_str()),
89 package, // pszPackage
90 SECPKG_CRED_OUTBOUND, // fCredentialUse
91 NULL, // pvLogonID
92 &identity, // pAuthData (login information)
93 NULL, // pGetKeyFn (always NULL)
94 NULL, // pvGetKeyArgument (always NULL)
95 &cred_, // phCredential
96 &use_before); // ptsExpiry
97 if (rc != SEC_E_OK)
98 return ERR_UNEXPECTED;
99
100 return OK;
101 }
102
103 int HttpAuthHandlerNTLM::GetNextToken(const void* in_token,
104 uint32 in_token_len,
105 void** out_token,
106 uint32* out_token_len) {
107 SECURITY_STATUS rc;
108 TimeStamp ignored;
109
110 DWORD ctx_attr, ctx_req = 0;
111 CtxtHandle *ctx_in;
112 SecBufferDesc ibd, obd;
113 SecBuffer ib, ob;
114
115 if (in_token) {
116 ib.BufferType = SECBUFFER_TOKEN;
117 ib.cbBuffer = in_token_len;
118 ib.pvBuffer = const_cast<void*>(in_token);
119 ibd.ulVersion = SECBUFFER_VERSION;
120 ibd.cBuffers = 1;
121 ibd.pBuffers = &ib;
122 ctx_in = &ctxt_;
123 } else {
124 // If there is no input token, then we are starting a new
125 // authentication sequence. If we have already initialized our
126 // security context, then we're in trouble because it means that the
127 // first sequence failed. We need to bail or else we might end up in
128 // an infinite loop.
129 if (ctxt_.dwLower || ctxt_.dwUpper) {
130 LOG(ERROR) <<"Cannot restart authentication sequence";
131 return ERR_INVALID_RESPONSE;
132 }
133 ctx_in = NULL;
134 }
135
136 obd.ulVersion = SECBUFFER_VERSION;
137 obd.cBuffers = 1;
138 obd.pBuffers = &ob;
139 ob.BufferType = SECBUFFER_TOKEN;
140 ob.cbBuffer = max_token_len_;
141 ob.pvBuffer = malloc(ob.cbBuffer);
142 if (!ob.pvBuffer)
143 return ERR_UNEXPECTED;
144 memset(ob.pvBuffer, 0, ob.cbBuffer);
145
146 SEC_WCHAR *sn = NULL; // Package is NTLM.
147
148 LOG(ERROR) << "Sending Another Token";
149
150 // This returns a token that is passed to the remote server.
151 rc = InitializeSecurityContext(&cred_, // phCredential
152 ctx_in, // phContext (NULL on first call)
153 sn, // pszTargetName
154 ctx_req, // fContextReq
155 0, // reserved NULL
156 SECURITY_NATIVE_DREP, // TargetDataRep
157 in_token ? &ibd : NULL, // pInput
158 0, // reserved NULl
159 &ctxt_, // phNewContext
160 &obd, // pOutput
161 &ctx_attr, // pfContextAttr
162 &ignored); // ptsExpiry
163 if (rc == SEC_I_CONTINUE_NEEDED || rc == SEC_E_OK) {
164 if (!ob.cbBuffer) {
165 free(ob.pvBuffer);
166 ob.pvBuffer = NULL;
167 }
168 *out_token = ob.pvBuffer;
169 *out_token_len = ob.cbBuffer;
170 return OK;
171 } else {
172 LOG(ERROR) << "InitializeSecurityContext failed " << MapErrorCode(rc);
173 ResetSecurityContext();
174 free(ob.pvBuffer);
175 return ERR_UNEXPECTED;
176 }
177 }
178
179 // Require identity on first pass instead of second.
180 bool HttpAuthHandlerNTLM::NeedsIdentity() {
181 return !auth_data_.empty();
182 }
183
184 void HttpAuthHandlerNTLM::ResetSecurityContext() {
185 if (ctxt_.dwLower || ctxt_.dwUpper) {
186 DeleteSecurityContext(&ctxt_);
187 memset(&ctxt_, 0, sizeof(ctxt_));
188 }
189 }
190
191 } // namespace net
192
OLDNEW
« no previous file with comments | « net/http/http_auth_handler_ntlm_posix.cc ('k') | net/http/http_network_transaction_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698