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
- TextEditorTyping.cs
- RowType.cs
- PreloadHost.cs
- XamlFilter.cs
- SQLBinaryStorage.cs
- Repeater.cs
- NetStream.cs
- SqlBulkCopy.cs
- Substitution.cs
- TemplateParser.cs
- StrongName.cs
- GenericRootAutomationPeer.cs
- CodeDomConfigurationHandler.cs
- DictionaryManager.cs
- ToolBarButton.cs
- _Connection.cs
- DrawingGroup.cs
- Unit.cs
- WorkflowRuntimeServiceElementCollection.cs
- CodeTypeMemberCollection.cs
- _UriTypeConverter.cs
- Fonts.cs
- LinqDataSourceHelper.cs
- DocumentXmlWriter.cs
- XmlSchemaSimpleContentRestriction.cs
- PagesSection.cs
- SQLInt32.cs
- SafeThemeHandle.cs
- TemplateInstanceAttribute.cs
- BamlTreeNode.cs
- FileSystemInfo.cs
- StrongNamePublicKeyBlob.cs
- ResXBuildProvider.cs
- UsernameTokenFactoryCredential.cs
- ObjectDataSourceStatusEventArgs.cs
- ReadWriteObjectLock.cs
- WebServiceData.cs
- SqlCommandBuilder.cs
- PrefixQName.cs
- ObjectContextServiceProvider.cs
- Exception.cs
- Compiler.cs
- DocumentPageHost.cs
- DataGridViewLinkColumn.cs
- EditorPartCollection.cs
- SubclassTypeValidatorAttribute.cs
- HttpDictionary.cs
- SByte.cs
- UpDownBase.cs
- HtmlTableRowCollection.cs
- ChildDocumentBlock.cs
- DataReaderContainer.cs
- CodeSubDirectoriesCollection.cs
- RuntimeArgument.cs
- BitmapCodecInfoInternal.cs
- XsltArgumentList.cs
- ToolStripScrollButton.cs
- Vector.cs
- DecoderExceptionFallback.cs
- AssemblyInfo.cs
- HttpCacheParams.cs
- Variant.cs
- RegexCapture.cs
- NamespaceDecl.cs
- coordinatorscratchpad.cs
- Message.cs
- CollectionConverter.cs
- SerializationException.cs
- MetadataUtil.cs
- ToolStripMenuItem.cs
- IIS7UserPrincipal.cs
- ProxyGenerationError.cs
- LinqDataSourceHelper.cs
- ProcessModuleCollection.cs
- InputQueue.cs
- AssertFilter.cs
- NamespaceQuery.cs
- FontCacheLogic.cs
- TimersDescriptionAttribute.cs
- DockProviderWrapper.cs
- WebPart.cs
- Rectangle.cs
- EncodingNLS.cs
- DoubleCollectionConverter.cs
- ParagraphResult.cs
- GetPageCompletedEventArgs.cs
- SingleStorage.cs
- AccessDataSourceView.cs
- CompositeFontParser.cs
- WindowsIPAddress.cs
- FieldBuilder.cs
- DetailsViewDeletedEventArgs.cs
- ZipIOZip64EndOfCentralDirectoryBlock.cs
- WizardPanel.cs
- EllipticalNodeOperations.cs
- CrossContextChannel.cs
- RoleServiceManager.cs
- GridPatternIdentifiers.cs
- PenThread.cs
- OracleDateTime.cs