Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / whidbey / NetFXspW7 / 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.Authentication.ExtendedProtection; 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); GlobalLog.Print("NtlmClient::Authenticate() ChallengedSpn:" + ValidationHelper.ToString(spn)); ChannelBinding binding = null; if (httpWebRequest.CurrentAuthenticationState.TransportContext != null) { binding = httpWebRequest.CurrentAuthenticationState.TransportContext.GetChannelBinding(ChannelBindingKind.Endpoint); } authSession = new NTAuthentication( AuthType, NC, spn, httpWebRequest, binding); 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()); } // Extract the CBT we used and cache it for future requests that want to do preauth httpWebRequest.ServicePoint.SetCachedChannelBinding(httpWebRequest.ChallengedUri, authSession.ChannelBinding); 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.Authentication.ExtendedProtection; 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); GlobalLog.Print("NtlmClient::Authenticate() ChallengedSpn:" + ValidationHelper.ToString(spn)); ChannelBinding binding = null; if (httpWebRequest.CurrentAuthenticationState.TransportContext != null) { binding = httpWebRequest.CurrentAuthenticationState.TransportContext.GetChannelBinding(ChannelBindingKind.Endpoint); } authSession = new NTAuthentication( AuthType, NC, spn, httpWebRequest, binding); 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()); } // Extract the CBT we used and cache it for future requests that want to do preauth httpWebRequest.ServicePoint.SetCachedChannelBinding(httpWebRequest.ChallengedUri, authSession.ChannelBinding); 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
- AlternationConverter.cs
- FormViewUpdateEventArgs.cs
- returneventsaver.cs
- CollectionTypeElement.cs
- AutomationProperties.cs
- WasEndpointConfigContainer.cs
- MemberMaps.cs
- DetailsViewUpdatedEventArgs.cs
- OleDbReferenceCollection.cs
- Delegate.cs
- SqlClientWrapperSmiStream.cs
- ProviderConnectionPointCollection.cs
- XsdValidatingReader.cs
- NextPreviousPagerField.cs
- AttachmentCollection.cs
- XmlSchemaAttributeGroupRef.cs
- UnauthorizedAccessException.cs
- DrawTreeNodeEventArgs.cs
- HtmlInputRadioButton.cs
- FactoryRecord.cs
- DataSourceViewSchemaConverter.cs
- Comparer.cs
- EditorPartCollection.cs
- StrongNameUtility.cs
- ConfigXmlComment.cs
- ResourceCategoryAttribute.cs
- ListGeneralPage.cs
- RuleSettings.cs
- PolicyStatement.cs
- BackgroundFormatInfo.cs
- HealthMonitoringSectionHelper.cs
- PropertyBuilder.cs
- LicenseContext.cs
- EndpointAddress.cs
- SchemaElementDecl.cs
- ElementHostAutomationPeer.cs
- EllipseGeometry.cs
- MultipartContentParser.cs
- FileSystemWatcher.cs
- PropertyEntry.cs
- QilNode.cs
- DiagnosticsConfigurationHandler.cs
- CryptoConfig.cs
- HistoryEventArgs.cs
- EdmToObjectNamespaceMap.cs
- BitmapCodecInfoInternal.cs
- FileInfo.cs
- Types.cs
- MembershipValidatePasswordEventArgs.cs
- TriggerCollection.cs
- ToolBarOverflowPanel.cs
- WebRequestModuleElement.cs
- UIntPtr.cs
- AttachedPropertyBrowsableAttribute.cs
- HighContrastHelper.cs
- TypeExtensionSerializer.cs
- FormsAuthenticationModule.cs
- ScrollViewerAutomationPeer.cs
- XamlSerializer.cs
- WorkflowDurableInstance.cs
- SoapServerProtocol.cs
- PrimitiveXmlSerializers.cs
- XmlQueryType.cs
- BindingMemberInfo.cs
- TypeDefinition.cs
- AspNetSynchronizationContext.cs
- ResourceLoader.cs
- MemberNameValidator.cs
- Dictionary.cs
- ITextView.cs
- Matrix.cs
- DomainLiteralReader.cs
- ConnectionInterfaceCollection.cs
- ArglessEventHandlerProxy.cs
- TransactionState.cs
- BlurBitmapEffect.cs
- DataControlImageButton.cs
- AudioLevelUpdatedEventArgs.cs
- BitmapMetadataBlob.cs
- SqlDataSourceConfigureSortForm.cs
- TranslateTransform.cs
- _UriSyntax.cs
- DataServiceHostWrapper.cs
- ScriptMethodAttribute.cs
- ObjectPersistData.cs
- ContainerParaClient.cs
- PKCS1MaskGenerationMethod.cs
- mediaeventargs.cs
- StickyNoteAnnotations.cs
- GetPageCompletedEventArgs.cs
- ToolStripOverflow.cs
- Rect3DValueSerializer.cs
- EnvironmentPermission.cs
- CultureInfo.cs
- OneOfElement.cs
- SmiConnection.cs
- FormsAuthenticationUserCollection.cs
- StringTraceRecord.cs
- IInstanceTable.cs
- CodeDOMUtility.cs