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
- Parameter.cs
- LoginCancelEventArgs.cs
- TextBox.cs
- DockAndAnchorLayout.cs
- WebContext.cs
- AxHostDesigner.cs
- DayRenderEvent.cs
- NamedPipeTransportSecurityElement.cs
- TextEditorDragDrop.cs
- ResponseBodyWriter.cs
- XmlAttributes.cs
- _WinHttpWebProxyDataBuilder.cs
- SortAction.cs
- XmlElementAttributes.cs
- InputReportEventArgs.cs
- ToolboxComponentsCreatingEventArgs.cs
- SchemaSetCompiler.cs
- WebServiceReceive.cs
- EventLogEntry.cs
- TemplateAction.cs
- AutoFocusStyle.xaml.cs
- UnauthorizedAccessException.cs
- ContextMenuStripActionList.cs
- PlanCompiler.cs
- HttpResponse.cs
- HashStream.cs
- ThrowHelper.cs
- CompilerCollection.cs
- AssemblyResolver.cs
- SimpleHandlerFactory.cs
- BitmapPalettes.cs
- ExpressionNode.cs
- Transform3DCollection.cs
- ConfigXmlDocument.cs
- Peer.cs
- IndexerNameAttribute.cs
- CompositeTypefaceMetrics.cs
- ImmutableObjectAttribute.cs
- UnmanagedHandle.cs
- SafeThemeHandle.cs
- ValidationResult.cs
- PrintDialogException.cs
- PersistenceContextEnlistment.cs
- SizeFConverter.cs
- TdsParserHelperClasses.cs
- RemoteTokenFactory.cs
- HtmlControlDesigner.cs
- XhtmlBasicObjectListAdapter.cs
- DataBoundControlParameterTarget.cs
- RawKeyboardInputReport.cs
- SqlProviderManifest.cs
- HttpValueCollection.cs
- StringCollectionEditor.cs
- CodeAttributeArgument.cs
- IISUnsafeMethods.cs
- AccessViolationException.cs
- UrlMappingsSection.cs
- EntityParameterCollection.cs
- LinearQuaternionKeyFrame.cs
- XsltQilFactory.cs
- TypeLibConverter.cs
- smtppermission.cs
- ExpressionLink.cs
- WebPartTransformerCollection.cs
- TableSectionStyle.cs
- WebRequest.cs
- ObjectHelper.cs
- unsafenativemethodstextservices.cs
- DependencySource.cs
- JavaScriptObjectDeserializer.cs
- ExtendedPropertyInfo.cs
- SoundPlayerAction.cs
- XmlLinkedNode.cs
- OdbcConnectionOpen.cs
- DiagnosticTrace.cs
- GCHandleCookieTable.cs
- XmlException.cs
- ButtonFlatAdapter.cs
- OutputScope.cs
- SoapEnumAttribute.cs
- XmlNodeReader.cs
- EntityTypeEmitter.cs
- DataGridCheckBoxColumn.cs
- SecurityDescriptor.cs
- DependencyPropertyKind.cs
- IItemContainerGenerator.cs
- ArrayListCollectionBase.cs
- BitmapEffectDrawing.cs
- VarRefManager.cs
- HttpResponse.cs
- WebServiceMethodData.cs
- DoubleAnimation.cs
- DataGridViewButtonCell.cs
- Menu.cs
- SqlFacetAttribute.cs
- ElementMarkupObject.cs
- JobInputBins.cs
- ServerValidateEventArgs.cs
- ConfigurationManagerHelperFactory.cs
- Point3DIndependentAnimationStorage.cs