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

Unified 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 side-by-side diff with in-line comments
Download patch
« 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 »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/http/http_auth_handler_ntlm_win.cc
===================================================================
--- net/http/http_auth_handler_ntlm_win.cc (revision 0)
+++ net/http/http_auth_handler_ntlm_win.cc (revision 0)
@@ -0,0 +1,192 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/http/http_auth_handler_ntlm.h"
+
+#include "base/logging.h"
+#include "net/base/net_errors.h"
+
+#if !defined(NDEBUG)
+#define CASE_(_x) case _x: return # _x;
+static const char *MapErrorCode(int rc) {
+ switch (rc) {
+ CASE_(SEC_E_OK)
+ CASE_(SEC_I_CONTINUE_NEEDED)
+ CASE_(SEC_I_COMPLETE_NEEDED)
+ CASE_(SEC_I_COMPLETE_AND_CONTINUE)
+ CASE_(SEC_E_INCOMPLETE_MESSAGE)
+ CASE_(SEC_I_INCOMPLETE_CREDENTIALS)
+ CASE_(SEC_E_INVALID_HANDLE)
+ CASE_(SEC_E_TARGET_UNKNOWN)
+ CASE_(SEC_E_LOGON_DENIED)
+ CASE_(SEC_E_INTERNAL_ERROR)
+ CASE_(SEC_E_NO_CREDENTIALS)
+ CASE_(SEC_E_NO_AUTHENTICATING_AUTHORITY)
+ CASE_(SEC_E_INSUFFICIENT_MEMORY)
+ CASE_(SEC_E_INVALID_TOKEN)
+ }
+ return "<unknown>";
+}
+#else
+#define MapErrorCode(x) (x)
+#endif
+
+namespace net {
+
+HttpAuthHandlerNTLM::HttpAuthHandlerNTLM()
+ : max_token_len_(0) {
+ memset(&cred_, 0, sizeof(cred_));
+ memset(&ctxt_, 0, sizeof(ctxt_));
+}
+
+HttpAuthHandlerNTLM::~HttpAuthHandlerNTLM() {
+ ResetSecurityContext();
+ if (cred_.dwLower || cred_.dwUpper) {
+ FreeCredentialHandle(&cred_);
+ memset(&cred_, 0, sizeof(cred_));
+ }
+ ZapString(&password_);
+}
+
+int HttpAuthHandlerNTLM::InitializeBeforeFirstChallenge() {
+ DCHECK_EQ("ntlm", scheme_) << "This is not ntlm scheme";
+
+ SEC_WCHAR *package = L"NTLM";
+ PSecPkgInfo pinfo;
+ TimeStamp use_before;
+ SECURITY_STATUS rc;
+
+ // The following API call is required to get the maximum token length
+ // for the scheme.
+ // TODO(arindam): Can we move this (PSecPkgInfo) to a static function ?
+ rc = QuerySecurityPackageInfo(package, &pinfo);
+ if (rc != SEC_E_OK) {
+ LOG(ERROR) << package << " not found";
+ return ERR_UNEXPECTED;
+ }
+ max_token_len_ = pinfo->cbMaxToken;
+ FreeContextBuffer(pinfo);
+
+ SEC_WINNT_AUTH_IDENTITY identity;
+ identity.Domain =
+ reinterpret_cast<USHORT*>(const_cast<wchar_t*>(domain_.data()));
+ identity.DomainLength = domain_.size();
+ identity.User =
+ reinterpret_cast<USHORT*>(const_cast<wchar_t*>(username_.data()));
+ identity.UserLength = username_.size();
+ identity.Password =
+ reinterpret_cast<USHORT*>(const_cast<wchar_t*>(password_.data()));
+ identity.PasswordLength = password_.size();
+ identity.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
+
+ LOG(ERROR) << "Calling Acquire Creds Handle";
+
+ // Pass the username/password to get the credentials.
+ // Note: If params 1 and 5 are NULL, it gets the credentials for the
+ // logged in user which can be used for single sign-on.
+ rc = AcquireCredentialsHandle(const_cast<wchar_t*>(username_.c_str()),
+ package, // pszPackage
+ SECPKG_CRED_OUTBOUND, // fCredentialUse
+ NULL, // pvLogonID
+ &identity, // pAuthData (login information)
+ NULL, // pGetKeyFn (always NULL)
+ NULL, // pvGetKeyArgument (always NULL)
+ &cred_, // phCredential
+ &use_before); // ptsExpiry
+ if (rc != SEC_E_OK)
+ return ERR_UNEXPECTED;
+
+ return OK;
+}
+
+int HttpAuthHandlerNTLM::GetNextToken(const void* in_token,
+ uint32 in_token_len,
+ void** out_token,
+ uint32* out_token_len) {
+ SECURITY_STATUS rc;
+ TimeStamp ignored;
+
+ DWORD ctx_attr, ctx_req = 0;
+ CtxtHandle *ctx_in;
+ SecBufferDesc ibd, obd;
+ SecBuffer ib, ob;
+
+ if (in_token) {
+ ib.BufferType = SECBUFFER_TOKEN;
+ ib.cbBuffer = in_token_len;
+ ib.pvBuffer = const_cast<void*>(in_token);
+ ibd.ulVersion = SECBUFFER_VERSION;
+ ibd.cBuffers = 1;
+ ibd.pBuffers = &ib;
+ ctx_in = &ctxt_;
+ } else {
+ // If there is no input token, then we are starting a new
+ // authentication sequence. If we have already initialized our
+ // security context, then we're in trouble because it means that the
+ // first sequence failed. We need to bail or else we might end up in
+ // an infinite loop.
+ if (ctxt_.dwLower || ctxt_.dwUpper) {
+ LOG(ERROR) <<"Cannot restart authentication sequence";
+ return ERR_INVALID_RESPONSE;
+ }
+ ctx_in = NULL;
+ }
+
+ obd.ulVersion = SECBUFFER_VERSION;
+ obd.cBuffers = 1;
+ obd.pBuffers = &ob;
+ ob.BufferType = SECBUFFER_TOKEN;
+ ob.cbBuffer = max_token_len_;
+ ob.pvBuffer = malloc(ob.cbBuffer);
+ if (!ob.pvBuffer)
+ return ERR_UNEXPECTED;
+ memset(ob.pvBuffer, 0, ob.cbBuffer);
+
+ SEC_WCHAR *sn = NULL; // Package is NTLM.
+
+ LOG(ERROR) << "Sending Another Token";
+
+ // This returns a token that is passed to the remote server.
+ rc = InitializeSecurityContext(&cred_, // phCredential
+ ctx_in, // phContext (NULL on first call)
+ sn, // pszTargetName
+ ctx_req, // fContextReq
+ 0, // reserved NULL
+ SECURITY_NATIVE_DREP, // TargetDataRep
+ in_token ? &ibd : NULL, // pInput
+ 0, // reserved NULl
+ &ctxt_, // phNewContext
+ &obd, // pOutput
+ &ctx_attr, // pfContextAttr
+ &ignored); // ptsExpiry
+ if (rc == SEC_I_CONTINUE_NEEDED || rc == SEC_E_OK) {
+ if (!ob.cbBuffer) {
+ free(ob.pvBuffer);
+ ob.pvBuffer = NULL;
+ }
+ *out_token = ob.pvBuffer;
+ *out_token_len = ob.cbBuffer;
+ return OK;
+ } else {
+ LOG(ERROR) << "InitializeSecurityContext failed " << MapErrorCode(rc);
+ ResetSecurityContext();
+ free(ob.pvBuffer);
+ return ERR_UNEXPECTED;
+ }
+}
+
+// Require identity on first pass instead of second.
+bool HttpAuthHandlerNTLM::NeedsIdentity() {
+ return !auth_data_.empty();
+}
+
+void HttpAuthHandlerNTLM::ResetSecurityContext() {
+ if (ctxt_.dwLower || ctxt_.dwUpper) {
+ DeleteSecurityContext(&ctxt_);
+ memset(&ctxt_, 0, sizeof(ctxt_));
+ }
+}
+
+} // namespace net
+
Property changes on: net\http\http_auth_handler_ntlm_win.cc
___________________________________________________________________
Added: svn:eol-style
+ LF
« 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