Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / whidbey / netfxsp / ndp / fx / src / Net / System / Net / _NtlmClient.cs / 2 / _NtlmClient.cs
//------------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//-----------------------------------------------------------------------------
namespace System.Net {
using System.Collections;
using System.Security.Permissions;
using System.Globalization;
internal class NtlmClient : ISessionAuthenticationModule {
internal const string AuthType = "NTLM";
internal static string Signature = AuthType.ToLower(CultureInfo.InvariantCulture);
internal static int SignatureSize = Signature.Length;
//
// RAID#95841
// SSPI crashes without checking max length, so we need to check the sizes ourselves before
// we call into SSPI. values are UNLEN, PWLEN and DNLEN taken from sdk\inc\lmcons.h
// the fix in SSPI will make it to SP4 on win2k.
//
internal const int MaxNtlmCredentialSize = 256 + 256 + 15; // UNLEN + PWLEN + DNLEN
public Authorization Authenticate(string challenge, WebRequest webRequest, ICredentials credentials) {
GlobalLog.Print("NtlmClient::Authenticate() challenge:[" + ValidationHelper.ToString(challenge) + "] webRequest#" + ValidationHelper.HashString(webRequest) + " credentials#" + ValidationHelper.HashString(credentials) + " calling DoAuthenticate()");
return DoAuthenticate(challenge, webRequest, credentials, false);
}
private Authorization DoAuthenticate(string challenge, WebRequest webRequest, ICredentials credentials, bool preAuthenticate) {
GlobalLog.Print("NtlmClient::DoAuthenticate() challenge:[" + ValidationHelper.ToString(challenge) + "] webRequest#" + ValidationHelper.HashString(webRequest) + " credentials#" + ValidationHelper.HashString(credentials) + " preAuthenticate:" + preAuthenticate.ToString());
GlobalLog.Assert(credentials != null, "NtlmClient::DoAuthenticate()|credentials == null");
if (credentials == null) {
return null;
}
HttpWebRequest httpWebRequest = webRequest as HttpWebRequest;
GlobalLog.Assert(httpWebRequest != null, "NtlmClient::DoAuthenticate()|httpWebRequest == null");
GlobalLog.Assert(httpWebRequest.ChallengedUri != null, "NtlmClient::DoAuthenticate()|httpWebRequest.ChallengedUri == null");
NTAuthentication authSession = null;
string incoming = null;
if (!preAuthenticate) {
int index = AuthenticationManager.FindSubstringNotInQuotes(challenge, Signature);
if (index < 0) {
return null;
}
int blobBegin = index + SignatureSize;
//
// there may be multiple challenges. If the next character after the
// package name is not a comma then it is challenge data
//
if (challenge.Length > blobBegin && challenge[blobBegin] != ',') {
++blobBegin;
}
else {
index = -1;
}
if (index >= 0 && challenge.Length > blobBegin)
{
// Strip other modules information in case of multiple challenges
// i.e do not take ", NTLM" as part of the following Negotiate blob
// Negotiate TlRMTVNTUAACAAAADgAOADgAAAA1wo ... MAbwBmAHQALgBjAG8AbQAAAAAA,NTLM
index = challenge.IndexOf(',', blobBegin);
if (index != -1)
incoming = challenge.Substring(blobBegin, index - blobBegin);
else
incoming = challenge.Substring(blobBegin);
}
authSession = httpWebRequest.CurrentAuthenticationState.GetSecurityContext(this);
GlobalLog.Print("NtlmClient::DoAuthenticate() key:" + ValidationHelper.HashString(httpWebRequest.CurrentAuthenticationState) + " retrieved authSession:" + ValidationHelper.HashString(authSession));
}
if (authSession==null) {
NetworkCredential NC = credentials.GetCredential(httpWebRequest.ChallengedUri, Signature);
GlobalLog.Print("NtlmClient::DoAuthenticate() GetCredential() returns:" + ValidationHelper.ToString(NC));
string username = string.Empty;
if (NC == null || (!(NC is SystemNetworkCredential) && (username = NC.InternalGetUserName()).Length == 0))
{
return null;
}
//
// here we cover a hole in the SSPI layer. longer credentials
// might corrupt the process and cause a reboot.
//
if (username.Length + NC.InternalGetPassword().Length + NC.InternalGetDomain().Length>NtlmClient.MaxNtlmCredentialSize) {
//
// rather then throwing an exception here we return null so other packages can be used.
// this is questionable, hence:
// Consider: make this throw a NotSupportedException so it is discoverable
//
return null;
}
ICredentialPolicy policy = AuthenticationManager.CredentialPolicy;
if (policy != null && !policy.ShouldSendCredential(httpWebRequest.ChallengedUri, httpWebRequest, NC, this))
return null;
string spn = httpWebRequest.CurrentAuthenticationState.GetComputeSpn(httpWebRequest);
authSession =
new NTAuthentication(
AuthType,
NC,
spn,
httpWebRequest);
GlobalLog.Print("NtlmClient::DoAuthenticate() setting SecurityContext for:" + ValidationHelper.HashString(httpWebRequest.CurrentAuthenticationState) + " to authSession:" + ValidationHelper.HashString(authSession));
httpWebRequest.CurrentAuthenticationState.SetSecurityContext(authSession, this);
}
string clientResponse = authSession.GetOutgoingBlob(incoming);
if (clientResponse==null) {
return null;
}
bool canShareConnection = httpWebRequest.UnsafeOrProxyAuthenticatedConnectionSharing;
if (canShareConnection) {
httpWebRequest.LockConnection = true;
}
// this is the first leg of an NTLM handshake,
// set the NtlmKeepAlive override *STRICTLY* only in this case.
httpWebRequest.NtlmKeepAlive = incoming==null;
return AuthenticationManager.GetGroupAuthorization(this, AuthType + " " + clientResponse, authSession.IsCompleted, authSession, canShareConnection, false);
}
public bool CanPreAuthenticate {
get {
return true;
}
}
public Authorization PreAuthenticate(WebRequest webRequest, ICredentials credentials) {
GlobalLog.Print("NtlmClient::PreAuthenticate() webRequest#" + ValidationHelper.HashString(webRequest) + " credentials#" + ValidationHelper.HashString(credentials) + " calling DoAuthenticate()");
return DoAuthenticate(null, webRequest, credentials, true);
}
public string AuthenticationType {
get {
return AuthType;
}
}
//
// called when getting the final blob on the 200 OK from the server
//
public bool Update(string challenge, WebRequest webRequest) {
GlobalLog.Print("NtlmClient::Update(): " + challenge);
HttpWebRequest httpWebRequest = webRequest as HttpWebRequest;
GlobalLog.Assert(httpWebRequest != null, "NtlmClient::Update()|httpWebRequest == null");
GlobalLog.Assert(httpWebRequest.ChallengedUri != null, "NtlmClient::Update()|httpWebRequest.ChallengedUri == null");
//
// try to retrieve the state of the ongoing handshake
//
NTAuthentication authSession = httpWebRequest.CurrentAuthenticationState.GetSecurityContext(this);
GlobalLog.Print("NtlmClient::Update() key:" + ValidationHelper.HashString(httpWebRequest.CurrentAuthenticationState) + " retrieved authSession:" + ValidationHelper.HashString(authSession));
if (authSession==null) {
GlobalLog.Print("NtlmClient::Update() null session returning true");
return true;
}
GlobalLog.Print("NtlmClient::Update() authSession.IsCompleted:" + authSession.IsCompleted.ToString());
if (!authSession.IsCompleted && httpWebRequest.CurrentAuthenticationState.StatusCodeMatch==httpWebRequest.ResponseStatusCode) {
GlobalLog.Print("NtlmClient::Update() still handshaking (based on status code) returning false");
return false;
}
ClearSession(httpWebRequest);
// now possibly close the ConnectionGroup after authentication is done.
if (!httpWebRequest.UnsafeOrProxyAuthenticatedConnectionSharing) {
GlobalLog.Print("NtlmClient::Update() releasing ConnectionGroup:" + httpWebRequest.GetConnectionGroupLine());
httpWebRequest.ServicePoint.ReleaseConnectionGroup(httpWebRequest.GetConnectionGroupLine());
}
GlobalLog.Print("NtlmClient::Update() session removed and ConnectionGorup released returning true");
return true;
}
public void ClearSession(WebRequest webRequest) {
HttpWebRequest httpWebRequest = webRequest as HttpWebRequest;
GlobalLog.Assert(httpWebRequest != null, "NtlmClient::ClearSession()|httpWebRequest == null");
httpWebRequest.CurrentAuthenticationState.ClearSession();
}
public bool CanUseDefaultCredentials {
get {
return true;
}
}
}; // class NtlmClient
} // namespace System.Net
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//------------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//-----------------------------------------------------------------------------
namespace System.Net {
using System.Collections;
using System.Security.Permissions;
using System.Globalization;
internal class NtlmClient : ISessionAuthenticationModule {
internal const string AuthType = "NTLM";
internal static string Signature = AuthType.ToLower(CultureInfo.InvariantCulture);
internal static int SignatureSize = Signature.Length;
//
// RAID#95841
// SSPI crashes without checking max length, so we need to check the sizes ourselves before
// we call into SSPI. values are UNLEN, PWLEN and DNLEN taken from sdk\inc\lmcons.h
// the fix in SSPI will make it to SP4 on win2k.
//
internal const int MaxNtlmCredentialSize = 256 + 256 + 15; // UNLEN + PWLEN + DNLEN
public Authorization Authenticate(string challenge, WebRequest webRequest, ICredentials credentials) {
GlobalLog.Print("NtlmClient::Authenticate() challenge:[" + ValidationHelper.ToString(challenge) + "] webRequest#" + ValidationHelper.HashString(webRequest) + " credentials#" + ValidationHelper.HashString(credentials) + " calling DoAuthenticate()");
return DoAuthenticate(challenge, webRequest, credentials, false);
}
private Authorization DoAuthenticate(string challenge, WebRequest webRequest, ICredentials credentials, bool preAuthenticate) {
GlobalLog.Print("NtlmClient::DoAuthenticate() challenge:[" + ValidationHelper.ToString(challenge) + "] webRequest#" + ValidationHelper.HashString(webRequest) + " credentials#" + ValidationHelper.HashString(credentials) + " preAuthenticate:" + preAuthenticate.ToString());
GlobalLog.Assert(credentials != null, "NtlmClient::DoAuthenticate()|credentials == null");
if (credentials == null) {
return null;
}
HttpWebRequest httpWebRequest = webRequest as HttpWebRequest;
GlobalLog.Assert(httpWebRequest != null, "NtlmClient::DoAuthenticate()|httpWebRequest == null");
GlobalLog.Assert(httpWebRequest.ChallengedUri != null, "NtlmClient::DoAuthenticate()|httpWebRequest.ChallengedUri == null");
NTAuthentication authSession = null;
string incoming = null;
if (!preAuthenticate) {
int index = AuthenticationManager.FindSubstringNotInQuotes(challenge, Signature);
if (index < 0) {
return null;
}
int blobBegin = index + SignatureSize;
//
// there may be multiple challenges. If the next character after the
// package name is not a comma then it is challenge data
//
if (challenge.Length > blobBegin && challenge[blobBegin] != ',') {
++blobBegin;
}
else {
index = -1;
}
if (index >= 0 && challenge.Length > blobBegin)
{
// Strip other modules information in case of multiple challenges
// i.e do not take ", NTLM" as part of the following Negotiate blob
// Negotiate TlRMTVNTUAACAAAADgAOADgAAAA1wo ... MAbwBmAHQALgBjAG8AbQAAAAAA,NTLM
index = challenge.IndexOf(',', blobBegin);
if (index != -1)
incoming = challenge.Substring(blobBegin, index - blobBegin);
else
incoming = challenge.Substring(blobBegin);
}
authSession = httpWebRequest.CurrentAuthenticationState.GetSecurityContext(this);
GlobalLog.Print("NtlmClient::DoAuthenticate() key:" + ValidationHelper.HashString(httpWebRequest.CurrentAuthenticationState) + " retrieved authSession:" + ValidationHelper.HashString(authSession));
}
if (authSession==null) {
NetworkCredential NC = credentials.GetCredential(httpWebRequest.ChallengedUri, Signature);
GlobalLog.Print("NtlmClient::DoAuthenticate() GetCredential() returns:" + ValidationHelper.ToString(NC));
string username = string.Empty;
if (NC == null || (!(NC is SystemNetworkCredential) && (username = NC.InternalGetUserName()).Length == 0))
{
return null;
}
//
// here we cover a hole in the SSPI layer. longer credentials
// might corrupt the process and cause a reboot.
//
if (username.Length + NC.InternalGetPassword().Length + NC.InternalGetDomain().Length>NtlmClient.MaxNtlmCredentialSize) {
//
// rather then throwing an exception here we return null so other packages can be used.
// this is questionable, hence:
// Consider: make this throw a NotSupportedException so it is discoverable
//
return null;
}
ICredentialPolicy policy = AuthenticationManager.CredentialPolicy;
if (policy != null && !policy.ShouldSendCredential(httpWebRequest.ChallengedUri, httpWebRequest, NC, this))
return null;
string spn = httpWebRequest.CurrentAuthenticationState.GetComputeSpn(httpWebRequest);
authSession =
new NTAuthentication(
AuthType,
NC,
spn,
httpWebRequest);
GlobalLog.Print("NtlmClient::DoAuthenticate() setting SecurityContext for:" + ValidationHelper.HashString(httpWebRequest.CurrentAuthenticationState) + " to authSession:" + ValidationHelper.HashString(authSession));
httpWebRequest.CurrentAuthenticationState.SetSecurityContext(authSession, this);
}
string clientResponse = authSession.GetOutgoingBlob(incoming);
if (clientResponse==null) {
return null;
}
bool canShareConnection = httpWebRequest.UnsafeOrProxyAuthenticatedConnectionSharing;
if (canShareConnection) {
httpWebRequest.LockConnection = true;
}
// this is the first leg of an NTLM handshake,
// set the NtlmKeepAlive override *STRICTLY* only in this case.
httpWebRequest.NtlmKeepAlive = incoming==null;
return AuthenticationManager.GetGroupAuthorization(this, AuthType + " " + clientResponse, authSession.IsCompleted, authSession, canShareConnection, false);
}
public bool CanPreAuthenticate {
get {
return true;
}
}
public Authorization PreAuthenticate(WebRequest webRequest, ICredentials credentials) {
GlobalLog.Print("NtlmClient::PreAuthenticate() webRequest#" + ValidationHelper.HashString(webRequest) + " credentials#" + ValidationHelper.HashString(credentials) + " calling DoAuthenticate()");
return DoAuthenticate(null, webRequest, credentials, true);
}
public string AuthenticationType {
get {
return AuthType;
}
}
//
// called when getting the final blob on the 200 OK from the server
//
public bool Update(string challenge, WebRequest webRequest) {
GlobalLog.Print("NtlmClient::Update(): " + challenge);
HttpWebRequest httpWebRequest = webRequest as HttpWebRequest;
GlobalLog.Assert(httpWebRequest != null, "NtlmClient::Update()|httpWebRequest == null");
GlobalLog.Assert(httpWebRequest.ChallengedUri != null, "NtlmClient::Update()|httpWebRequest.ChallengedUri == null");
//
// try to retrieve the state of the ongoing handshake
//
NTAuthentication authSession = httpWebRequest.CurrentAuthenticationState.GetSecurityContext(this);
GlobalLog.Print("NtlmClient::Update() key:" + ValidationHelper.HashString(httpWebRequest.CurrentAuthenticationState) + " retrieved authSession:" + ValidationHelper.HashString(authSession));
if (authSession==null) {
GlobalLog.Print("NtlmClient::Update() null session returning true");
return true;
}
GlobalLog.Print("NtlmClient::Update() authSession.IsCompleted:" + authSession.IsCompleted.ToString());
if (!authSession.IsCompleted && httpWebRequest.CurrentAuthenticationState.StatusCodeMatch==httpWebRequest.ResponseStatusCode) {
GlobalLog.Print("NtlmClient::Update() still handshaking (based on status code) returning false");
return false;
}
ClearSession(httpWebRequest);
// now possibly close the ConnectionGroup after authentication is done.
if (!httpWebRequest.UnsafeOrProxyAuthenticatedConnectionSharing) {
GlobalLog.Print("NtlmClient::Update() releasing ConnectionGroup:" + httpWebRequest.GetConnectionGroupLine());
httpWebRequest.ServicePoint.ReleaseConnectionGroup(httpWebRequest.GetConnectionGroupLine());
}
GlobalLog.Print("NtlmClient::Update() session removed and ConnectionGorup released returning true");
return true;
}
public void ClearSession(WebRequest webRequest) {
HttpWebRequest httpWebRequest = webRequest as HttpWebRequest;
GlobalLog.Assert(httpWebRequest != null, "NtlmClient::ClearSession()|httpWebRequest == null");
httpWebRequest.CurrentAuthenticationState.ClearSession();
}
public bool CanUseDefaultCredentials {
get {
return true;
}
}
}; // class NtlmClient
} // namespace System.Net
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- IntPtr.cs
- ExpressionBuilder.cs
- StringValueSerializer.cs
- ByteStream.cs
- NetTcpBinding.cs
- Array.cs
- DataGridViewComboBoxEditingControl.cs
- ChtmlTextWriter.cs
- sqlpipe.cs
- ServiceModelSectionGroup.cs
- ByteStreamGeometryContext.cs
- HierarchicalDataTemplate.cs
- Queue.cs
- ContainerParaClient.cs
- MenuCommand.cs
- Int16.cs
- DataColumnChangeEvent.cs
- DocumentReference.cs
- documentsequencetextpointer.cs
- TemplateDefinition.cs
- DataGridViewSelectedCellCollection.cs
- ServicesUtilities.cs
- DataGridViewButtonCell.cs
- UnsafeNativeMethods.cs
- DateTimePicker.cs
- SmiSettersStream.cs
- SecureConversationSecurityTokenParameters.cs
- AdRotator.cs
- WindowsFormsLinkLabel.cs
- DataGridViewDataErrorEventArgs.cs
- FileAuthorizationModule.cs
- GridViewRowEventArgs.cs
- EditorServiceContext.cs
- WorkingDirectoryEditor.cs
- EntityDataSourceReferenceGroup.cs
- HtmlFormWrapper.cs
- CaseInsensitiveComparer.cs
- DetailsViewInsertedEventArgs.cs
- ClientCredentials.cs
- UnsafeNativeMethods.cs
- XpsSerializationManagerAsync.cs
- FixedSOMTable.cs
- UIElement.cs
- ServiceOperation.cs
- SslStream.cs
- SystemWebExtensionsSectionGroup.cs
- SecurityDocument.cs
- QueueProcessor.cs
- WebBrowsableAttribute.cs
- ArrayItemValue.cs
- ObjectFullSpanRewriter.cs
- PropertyStore.cs
- ResourcesBuildProvider.cs
- ProgressBarBrushConverter.cs
- StrongNamePublicKeyBlob.cs
- securitycriticaldataformultiplegetandset.cs
- ToggleProviderWrapper.cs
- Item.cs
- Delegate.cs
- NamespaceInfo.cs
- IndependentlyAnimatedPropertyMetadata.cs
- XmlDomTextWriter.cs
- XPathNodeInfoAtom.cs
- Axis.cs
- ReflectPropertyDescriptor.cs
- RegexCompilationInfo.cs
- DataTableNewRowEvent.cs
- ValueQuery.cs
- ScriptHandlerFactory.cs
- DataGridViewRowEventArgs.cs
- FactoryGenerator.cs
- WeakHashtable.cs
- InputMethod.cs
- SpotLight.cs
- EntityDataSourceState.cs
- DeclarativeExpressionConditionDeclaration.cs
- DateTimeParse.cs
- SettingsSection.cs
- TreeViewCancelEvent.cs
- AsyncDataRequest.cs
- NavigationPropertyEmitter.cs
- ObjectViewFactory.cs
- DeadCharTextComposition.cs
- HorizontalAlignConverter.cs
- ZipIOModeEnforcingStream.cs
- XComponentModel.cs
- CodeAccessPermission.cs
- InstanceLockQueryResult.cs
- EditorZone.cs
- TypeDescriptorContext.cs
- MenuItemBinding.cs
- ClrProviderManifest.cs
- StringInfo.cs
- DefaultValueAttribute.cs
- CodeExporter.cs
- CodeDelegateCreateExpression.cs
- FrameAutomationPeer.cs
- ConditionChanges.cs
- KeyedCollection.cs
- TextRunCache.cs