Code:
/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / ServiceModel / System / ServiceModel / Security / WindowsSspiNegotiation.cs / 2 / WindowsSspiNegotiation.cs
//------------------------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------------------------- namespace System.ServiceModel.Security { using System.Runtime.InteropServices; using System.ServiceModel.Channels; using System.ServiceModel; using System.ServiceModel.Diagnostics; using System.Diagnostics; using System.Text; using System.Threading; using System.Globalization; using System.ComponentModel; using System.Security.Principal; using System.IdentityModel.Tokens; using System.Net; using System.IdentityModel; using DiagnosticUtility = System.ServiceModel.DiagnosticUtility; using SR = System.ServiceModel.SR; internal sealed class WindowsSspiNegotiation : ISspiNegotiation { SspiContextFlags contextFlags; SafeFreeCredentials credentialsHandle; bool disposed = false; bool doMutualAuth; TokenImpersonationLevel impersonationLevel; bool isCompleted; bool isServer; LifeSpan lifespan; string protocolName; SafeDeleteContext securityContext; string servicePrincipalName; SecSizes sizes; Object syncObject = new Object(); int tokenSize; ////// Client side ctor /// internal WindowsSspiNegotiation(string package, SafeFreeCredentials credentialsHandle, TokenImpersonationLevel impersonationLevel, string servicePrincipalName, bool doMutualAuth) : this(false, package, credentialsHandle, impersonationLevel, servicePrincipalName, doMutualAuth) { } ////// Server side ctor /// internal WindowsSspiNegotiation(string package, SafeFreeCredentials credentialsHandle) : this(true, package, credentialsHandle, TokenImpersonationLevel.Delegation, null, false) { } WindowsSspiNegotiation(bool isServer, string package, SafeFreeCredentials credentialsHandle, TokenImpersonationLevel impersonationLevel, string servicePrincipalName, bool doMutualAuth) { this.tokenSize = SspiWrapper.GetVerifyPackageInfo(package).MaxToken; this.isServer = isServer; this.servicePrincipalName = servicePrincipalName; this.securityContext = null; if (isServer) { this.impersonationLevel = TokenImpersonationLevel.Delegation; this.doMutualAuth = false; } else { this.impersonationLevel = impersonationLevel; this.doMutualAuth = doMutualAuth; } this.credentialsHandle = credentialsHandle; } public DateTime ExpirationTimeUtc { get { ThrowIfDisposed(); if (this.LifeSpan == null) { return SecurityUtils.MaxUtcDateTime; } else { return this.LifeSpan.ExpiryTimeUtc; } } } public bool IsCompleted { get { ThrowIfDisposed(); return this.isCompleted; } } public bool IsDelegationFlag { get { ThrowIfDisposed(); return (this.contextFlags & SspiContextFlags.Delegate) != 0; } } public bool IsIdentifyFlag { get { ThrowIfDisposed(); return (this.contextFlags & (this.isServer ? SspiContextFlags.AcceptIdentify : SspiContextFlags.InitIdentify)) != 0; } } public bool IsMutualAuthFlag { get { ThrowIfDisposed(); return (this.contextFlags & SspiContextFlags.MutualAuth) != 0; } } public bool IsValidContext { get { return (this.securityContext != null && this.securityContext.IsInvalid == false); } } public string KeyEncryptionAlgorithm { get { return SecurityAlgorithms.WindowsSspiKeyWrap; } } public LifeSpan LifeSpan { get { ThrowIfDisposed(); if (this.lifespan == null) { LifeSpan tmpLifeSpan = (LifeSpan) SspiWrapper.QueryContextAttributes(this.securityContext, ContextAttribute.Lifespan); if (IsCompleted) { // cache it only when it's completed this.lifespan = tmpLifeSpan; } return tmpLifeSpan; } return this.lifespan; } } public string ProtocolName { get { ThrowIfDisposed(); if (this.protocolName == null) { NegotiationInfoClass negotiationInfo = SspiWrapper.QueryContextAttributes(this.securityContext, ContextAttribute.NegotiationInfo) as NegotiationInfoClass; if (IsCompleted) { // cache it only when it's completed this.protocolName = negotiationInfo.AuthenticationPackage; } return negotiationInfo.AuthenticationPackage; } return this.protocolName; } } public string ServicePrincipalName { get { ThrowIfDisposed(); return this.servicePrincipalName; } } SecSizes SecuritySizes { get { ThrowIfDisposed(); if (this.sizes == null) { SecSizes tmpSizes = (SecSizes) SspiWrapper.QueryContextAttributes(this.securityContext, ContextAttribute.Sizes); if (IsCompleted) { // cache it only when it's completed this.sizes = tmpSizes; } return tmpSizes; } return this.sizes; } } public string GetRemoteIdentityName() { if (!this.isServer) { return this.servicePrincipalName; } if (IsValidContext) { using (SafeCloseHandle contextToken = GetContextToken()) { using (WindowsIdentity windowsIdentity = new WindowsIdentity(contextToken.DangerousGetHandle())) { return windowsIdentity.Name; } } } return String.Empty; } public byte[] Decrypt(byte[] encryptedContent) { if (encryptedContent == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("encryptedContent"); ThrowIfDisposed(); SecurityBuffer[] securityBuffer = new SecurityBuffer[2]; securityBuffer[0] = new SecurityBuffer(encryptedContent, 0, encryptedContent.Length, BufferType.Stream); securityBuffer[1] = new SecurityBuffer(0, BufferType.Data); int errorCode = SspiWrapper.DecryptMessage(this.securityContext, securityBuffer, 0, true); if (errorCode != 0) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(errorCode)); } for (int i = 0; i < securityBuffer.Length; ++i) { if (securityBuffer[i].type == BufferType.Data) { return securityBuffer[i].token; } } OnBadData(); return null; } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } public byte[] Encrypt(byte[] input) { if (input == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("input"); ThrowIfDisposed(); SecurityBuffer[] securityBuffer = new SecurityBuffer[3]; byte[] tokenBuffer = DiagnosticUtility.Utility.AllocateByteArray(SecuritySizes.SecurityTrailer); securityBuffer[0] = new SecurityBuffer(tokenBuffer, 0, tokenBuffer.Length, BufferType.Token); byte[] dataBuffer = DiagnosticUtility.Utility.AllocateByteArray(input.Length); Buffer.BlockCopy(input, 0, dataBuffer, 0, input.Length); securityBuffer[1] = new SecurityBuffer(dataBuffer, 0, dataBuffer.Length, BufferType.Data); byte[] paddingBuffer = DiagnosticUtility.Utility.AllocateByteArray(SecuritySizes.BlockSize); securityBuffer[2] = new SecurityBuffer(paddingBuffer, 0, paddingBuffer.Length, BufferType.Padding); int errorCode = SspiWrapper.EncryptMessage(this.securityContext, securityBuffer, 0); if (errorCode != 0) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(errorCode)); } int tokenLen = 0; int paddingLen = 0; for (int i = 0; i < securityBuffer.Length; ++i) { if (securityBuffer[i].type == BufferType.Token) tokenLen = securityBuffer[i].size; else if (securityBuffer[i].type == BufferType.Padding) paddingLen = securityBuffer[i].size; } byte[] encryptedData = DiagnosticUtility.Utility.AllocateByteArray(checked(tokenLen + dataBuffer.Length + paddingLen)); Buffer.BlockCopy(tokenBuffer, 0, encryptedData, 0, tokenLen); Buffer.BlockCopy(dataBuffer, 0, encryptedData, tokenLen, dataBuffer.Length); Buffer.BlockCopy(paddingBuffer, 0, encryptedData, tokenLen + dataBuffer.Length, paddingLen); return encryptedData; } public byte[] GetOutgoingBlob(byte[] incomingBlob) { ThrowIfDisposed(); SspiContextFlags requestedFlags = SspiContextFlags.Zero; if (this.doMutualAuth) { requestedFlags |= SspiContextFlags.MutualAuth; } if (this.impersonationLevel == TokenImpersonationLevel.Delegation) { requestedFlags |= SspiContextFlags.Delegate; } else if (this.isServer == false && this.impersonationLevel == TokenImpersonationLevel.Identification) { requestedFlags |= SspiContextFlags.InitIdentify; } else if (this.isServer == false && this.impersonationLevel == TokenImpersonationLevel.Anonymous) { requestedFlags |= SspiContextFlags.InitAnonymous; } // use the confidentiality option to ensure we can encrypt messages requestedFlags |= SspiContextFlags.Confidentiality; requestedFlags |= SspiContextFlags.ReplayDetect; requestedFlags |= SspiContextFlags.SequenceDetect; requestedFlags |= SspiContextFlags.ReplayDetect; requestedFlags |= SspiContextFlags.SequenceDetect; SecurityBuffer inSecurityBuffer = null; int statusCode; if (incomingBlob != null) { inSecurityBuffer = new SecurityBuffer(incomingBlob, BufferType.Token); } SecurityBuffer outSecurityBuffer = new SecurityBuffer(this.tokenSize, BufferType.Token); if (!this.isServer) { // client side statusCode = SspiWrapper.InitializeSecurityContext(this.credentialsHandle, ref this.securityContext, this.servicePrincipalName, requestedFlags, Endianness.Network, inSecurityBuffer, outSecurityBuffer, ref this.contextFlags); } else { // server session statusCode = SspiWrapper.AcceptSecurityContext(this.credentialsHandle, ref this.securityContext, requestedFlags, Endianness.Network, inSecurityBuffer, outSecurityBuffer, ref this.contextFlags); } if ((statusCode & unchecked((int) 0x80000000)) != 0) { CloseContext(); this.isCompleted = true; if (!this.isServer && (statusCode == (int) SecurityStatus.NoCredentials || statusCode == (int) SecurityStatus.TargetUnknown || statusCode == (int) SecurityStatus.WrongPrincipal)) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(statusCode, SR.GetString(SR.IncorrectSpnOrUpnSpecified, this.servicePrincipalName))); } else { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(statusCode, SR.GetString(SR.InvalidSspiNegotiation))); } } if (statusCode ==(int) SecurityStatus.OK) { // we're done this.isCompleted = true; //this.contextFlags = (SspiContextFlags) SspiWrapper.QueryContextAttributes(this.securityContext, ContextAttribute.Flags); } else { // we need to continue } return outSecurityBuffer.token; } public void ImpersonateContext() { ThrowIfDisposed(); if (!IsValidContext) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception((int) SecurityStatus.InvalidHandle)); } SspiWrapper.ImpersonateSecurityContext(this.securityContext); } internal void CloseContext() { ThrowIfDisposed(); try { if (this.securityContext != null) { this.securityContext.Close(); } } finally { this.securityContext = null; } } private void Dispose(bool disposing) { lock (this.syncObject) { if (this.disposed == false) { if (disposing) { this.CloseContext(); } // set to null any references that aren't finalizable this.protocolName = null; this.servicePrincipalName = null; this.sizes = null; this.disposed = true; } } } internal SafeCloseHandle GetContextToken() { if (!IsValidContext) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception((int) SecurityStatus.InvalidHandle)); } SafeCloseHandle token; SecurityStatus status = (SecurityStatus) SspiWrapper.QuerySecurityContextToken(this.securityContext, out token); if (status != SecurityStatus.OK) { Utility.CloseInvalidOutSafeHandle(token); throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception((int) status)); } return token; } void OnBadData() { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new MessageSecurityException(SR.GetString(SR.BadData))); } void ThrowIfDisposed() { lock (this.syncObject) { if (this.disposed) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ObjectDisposedException(null)); } } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- QuaternionKeyFrameCollection.cs
- ExtensionSimplifierMarkupObject.cs
- PageRanges.cs
- TabRenderer.cs
- NotifyCollectionChangedEventArgs.cs
- HostingEnvironmentSection.cs
- DefaultPropertiesToSend.cs
- FtpCachePolicyElement.cs
- MouseBinding.cs
- DigestTraceRecordHelper.cs
- SystemColorTracker.cs
- HttpCookieCollection.cs
- SrgsSemanticInterpretationTag.cs
- XmlBaseWriter.cs
- COM2Properties.cs
- GridViewRowCollection.cs
- RoleService.cs
- ImageIndexEditor.cs
- ImageSourceConverter.cs
- XmlTextEncoder.cs
- StringSorter.cs
- AuthenticationSection.cs
- TextBoxAutomationPeer.cs
- AbsoluteQuery.cs
- VectorCollectionValueSerializer.cs
- ToggleButtonAutomationPeer.cs
- AttachmentService.cs
- DbModificationClause.cs
- TaskbarItemInfo.cs
- TiffBitmapDecoder.cs
- FormatVersion.cs
- TreeNodeClickEventArgs.cs
- InternalResources.cs
- ExcludeFromCodeCoverageAttribute.cs
- InheritanceContextChangedEventManager.cs
- SpellerStatusTable.cs
- Int64.cs
- NameSpaceExtractor.cs
- DesignerTransactionCloseEvent.cs
- TCPListener.cs
- SerializationAttributes.cs
- GACIdentityPermission.cs
- DataViewSetting.cs
- OdbcError.cs
- SystemColors.cs
- Ray3DHitTestResult.cs
- WsrmFault.cs
- ObjectCloneHelper.cs
- HttpWebRequestElement.cs
- CompositeKey.cs
- CapabilitiesRule.cs
- SiblingIterators.cs
- ZipIOZip64EndOfCentralDirectoryBlock.cs
- RotateTransform3D.cs
- CatalogPart.cs
- ScopeCompiler.cs
- Help.cs
- TimeoutValidationAttribute.cs
- LineUtil.cs
- TraceContextEventArgs.cs
- CodeVariableDeclarationStatement.cs
- RequestCacheValidator.cs
- Hash.cs
- UrlMappingsSection.cs
- BrowserCapabilitiesFactory.cs
- DirectoryObjectSecurity.cs
- InvokeProviderWrapper.cs
- WindowVisualStateTracker.cs
- DateTimeConverter.cs
- ArrangedElement.cs
- IisTraceWebEventProvider.cs
- GridItemPattern.cs
- AlgoModule.cs
- Membership.cs
- SerialErrors.cs
- DataGridViewColumnDesignTimeVisibleAttribute.cs
- DelayedRegex.cs
- DataServiceProcessingPipelineEventArgs.cs
- ObjectStateEntryOriginalDbUpdatableDataRecord.cs
- AutoGeneratedField.cs
- AnimationClockResource.cs
- LineUtil.cs
- SecurityDocument.cs
- SerializationFieldInfo.cs
- InlineUIContainer.cs
- WebResourceAttribute.cs
- ValueChangedEventManager.cs
- DataServiceQueryOfT.cs
- TextSegment.cs
- ToolStripDropDownMenu.cs
- TextServicesDisplayAttribute.cs
- CallbackHandler.cs
- SparseMemoryStream.cs
- EventMappingSettingsCollection.cs
- AnnotationResourceCollection.cs
- ProxyWebPartManager.cs
- DbConnectionInternal.cs
- CodeMemberProperty.cs
- RijndaelManaged.cs
- UrlMapping.cs