Code:
/ WCF / WCF / 3.5.30729.1 / untmp / Orcas / SP / ndp / cdf / src / WCF / ServiceModel / System / ServiceModel / Channels / PeerSecurityManager.cs / 1 / PeerSecurityManager.cs
//------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------- namespace System.ServiceModel.Channels { using System.Collections.Generic; using System.ServiceModel; using System.ServiceModel.Description; using System.Collections.ObjectModel; using System.Diagnostics; using System.Globalization; using System.Net; using System.Net.Security; using System.Runtime.Serialization; using System.ServiceModel.Diagnostics; using System.Xml; using System.Security; using System.IdentityModel.Claims; using System.IdentityModel.Policy; using System.IdentityModel.Selectors; using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; using System.ServiceModel.Security; using System.ServiceModel.Security.Tokens; using System.IdentityModel.Tokens; using System.Text; using System.Threading; using System.ServiceModel.Dispatcher; class PeerSecurityManager { PeerAuthenticationMode authenticationMode; bool enableSigning; internal string password; DuplexSecurityProtocolFactory securityProtocolFactory; byte[] authenticatorHash; object thisLock; //public EventHandler OnNeighborOpened; public EventHandler OnNeighborAuthenticated; string meshId = String.Empty; ChannelProtectionRequirements protection; PeerSecurityCredentialsManager credManager; SecurityTokenManager tokenManager; SelfSignedCertificate ssc; XmlDictionaryReaderQuotas readerQuotas; // Audit ServiceSecurityAuditBehavior auditBehavior; PeerSecurityManager(PeerAuthenticationMode authMode, bool signing) { this.authenticationMode = authMode; this.enableSigning = signing; thisLock = new object(); } public PeerAuthenticationMode AuthenticationMode { get { return authenticationMode; } } public string Password { get { return password; } } public X509Certificate2 SelfCert { get { return credManager.Certificate; } } public bool MessageAuthentication { get { return this.enableSigning; } } internal string MeshId { get { return this.meshId; } set { this.meshId = value; } } internal SelfSignedCertificate GetCertificate() { if (this.ssc == null) { lock (ThisLock) { if (ssc == null) ssc = SelfSignedCertificate.Create("CN=" + Guid.NewGuid().ToString(), this.Password); } } return ssc; } object ThisLock { get { return thisLock; } } static PeerSecurityCredentialsManager GetCredentialsManager(PeerAuthenticationMode mode, bool signing, BindingContext context) { if (mode == PeerAuthenticationMode.None && !signing) return null; ClientCredentials clientCredentials = context.BindingParameters.Find(); if (clientCredentials != null) { return new PeerSecurityCredentialsManager(clientCredentials.Peer, mode, signing); } ServiceCredentials serviceCredentials = context.BindingParameters.Find (); if (serviceCredentials != null) { return new PeerSecurityCredentialsManager(serviceCredentials.Peer, mode, signing); } SecurityCredentialsManager credman = context.BindingParameters.Find (); if(credman == null) { PeerExceptionHelper.ThrowArgument_InsufficientCredentials(PeerPropertyNames.Credentials); } return new PeerSecurityCredentialsManager(credman.CreateSecurityTokenManager(), mode, signing); } static void Convert(PeerSecuritySettings security, out PeerAuthenticationMode authMode, out bool signing) { authMode = PeerAuthenticationMode.None; signing = false; if(security.Mode == SecurityMode.Transport || security.Mode == SecurityMode.TransportWithMessageCredential) { switch(security.Transport.CredentialType) { case PeerTransportCredentialType.Password: authMode = PeerAuthenticationMode.Password; break; case PeerTransportCredentialType.Certificate: authMode = PeerAuthenticationMode.MutualCertificate; break; } } if( security.Mode == SecurityMode.Message || security.Mode == SecurityMode.TransportWithMessageCredential) { signing = true; } } static public PeerSecurityManager Create(PeerSecuritySettings security, BindingContext context, XmlDictionaryReaderQuotas readerQuotas) { PeerAuthenticationMode authMode = PeerAuthenticationMode.None; bool signing = false; Convert(security, out authMode, out signing); return Create(authMode,signing,context, readerQuotas); } static public PeerSecurityManager Create(PeerAuthenticationMode authenticationMode, bool signMessages, BindingContext context, XmlDictionaryReaderQuotas readerQuotas) { if (authenticationMode == PeerAuthenticationMode.None && !signMessages) return CreateDummy(); // test FIPS mode if (authenticationMode == PeerAuthenticationMode.Password) { try { using(HMACSHA256 algo = new HMACSHA256()) { using(SHA256Managed sha = new SHA256Managed()) {} } } catch (InvalidOperationException e) { DiagnosticUtility.ExceptionUtility.TraceHandledException(e, TraceEventType.Information); PeerExceptionHelper.ThrowInvalidOperation_InsufficientCryptoSupport(e); } } ChannelProtectionRequirements reqs = context.BindingParameters.Find (); PeerSecurityCredentialsManager credman = GetCredentialsManager(authenticationMode,signMessages, context); if(credman.Credential != null) { //for compatibility with existing code: ValidateCredentialSettings(authenticationMode, signMessages, credman.Credential); } PeerSecurityManager manager = Create(authenticationMode, signMessages, credman, reqs, readerQuotas); credman.Parent = manager; manager.ApplyAuditBehaviorSettings(context); return manager; } static void ValidateCredentialSettings(PeerAuthenticationMode authenticationMode, bool signMessages, PeerCredential credential) { X509CertificateValidator validator; if(authenticationMode == PeerAuthenticationMode.None && !signMessages) return; switch (authenticationMode) { case PeerAuthenticationMode.Password: { if(String.IsNullOrEmpty(credential.MeshPassword)) PeerExceptionHelper.ThrowArgument_InsufficientCredentials(PeerPropertyNames.Password); } break; case PeerAuthenticationMode.MutualCertificate: { if (credential.Certificate == null) { PeerExceptionHelper.ThrowArgument_InsufficientCredentials(PeerPropertyNames.Certificate); } if(!credential.PeerAuthentication.TryGetCertificateValidator(out validator)) { PeerExceptionHelper.ThrowArgument_InsufficientCredentials(PeerPropertyNames.PeerAuthentication); } } break; } if (signMessages) { if (!credential.MessageSenderAuthentication.TryGetCertificateValidator(out validator)) { PeerExceptionHelper.ThrowArgument_InsufficientCredentials(PeerPropertyNames.MessageSenderAuthentication); } } } void ApplyAuditBehaviorSettings(BindingContext context) { ServiceSecurityAuditBehavior auditBehavior = context.BindingParameters.Find (); if (auditBehavior != null) { this.auditBehavior = auditBehavior.Clone(); } else { this.auditBehavior = new ServiceSecurityAuditBehavior(); } } public void ApplyServiceSecurity(ServiceDescription description) { if (this.AuthenticationMode == PeerAuthenticationMode.None) return; description.Behaviors.Add(credManager.CloneForTransport()); } internal static PeerSecurityManager CreateDummy() { PeerSecurityManager manager = new PeerSecurityManager(PeerAuthenticationMode.None, false); return manager; } static public PeerSecurityManager Create(PeerAuthenticationMode authenticationMode, bool messageAuthentication, PeerSecurityCredentialsManager credman, ChannelProtectionRequirements reqs, XmlDictionaryReaderQuotas readerQuotas) { PeerSecurityManager manager = null; X509CertificateValidator connectionValidator = null; X509CertificateValidator messageValidator = null; PeerCredential credential = credman.Credential; if (null == credential && credman == null) { if (authenticationMode != PeerAuthenticationMode.None || messageAuthentication) PeerExceptionHelper.ThrowArgument_InsufficientCredentials(PeerPropertyNames.Credentials); //create one that doesnt have any credentials in it. return CreateDummy(); } manager = new PeerSecurityManager(authenticationMode, messageAuthentication); manager.credManager = credman; manager.password = credman.Password; manager.readerQuotas = readerQuotas; if (reqs != null) { manager.protection = new ChannelProtectionRequirements(reqs); } manager.tokenManager = credman.CreateSecurityTokenManager(); if(credential == null) return manager; switch (authenticationMode) { case PeerAuthenticationMode.None: break; case PeerAuthenticationMode.Password: { manager.password = credential.MeshPassword; if (String.IsNullOrEmpty(manager.credManager.Password)) { PeerExceptionHelper.ThrowArgument_InsufficientCredentials(PeerPropertyNames.Password); } connectionValidator = X509CertificateValidator.None; } break; case PeerAuthenticationMode.MutualCertificate: { if (manager.credManager.Certificate == null) { PeerExceptionHelper.ThrowArgument_InsufficientCredentials(PeerPropertyNames.Certificate); } if(!credential.PeerAuthentication.TryGetCertificateValidator(out connectionValidator)) { PeerExceptionHelper.ThrowArgument_InsufficientCredentials(PeerPropertyNames.PeerAuthentication); } } break; } if (messageAuthentication) { if (credential.MessageSenderAuthentication != null) { if(!credential.MessageSenderAuthentication.TryGetCertificateValidator(out messageValidator)) { PeerExceptionHelper.ThrowArgument_InsufficientCredentials(PeerPropertyNames.MessageSenderAuthentication); } } else { PeerExceptionHelper.ThrowArgument_InsufficientCredentials(PeerPropertyNames.MessageSenderAuthentication); } } return manager; } void ApplySigningRequirements(ScopedMessagePartSpecification spec) { //following are the headers that we add and want signed. MessagePartSpecification partSpec = new MessagePartSpecification( new XmlQualifiedName(PeerStrings.Via, PeerStrings.Namespace), new XmlQualifiedName(PeerOperationNames.Flood, PeerStrings.Namespace), new XmlQualifiedName(PeerOperationNames.PeerTo, PeerStrings.Namespace), new XmlQualifiedName(PeerStrings.MessageId, PeerStrings.Namespace)); foreach (string action in spec.Actions) { spec.AddParts(partSpec, action); } spec.AddParts(partSpec, MessageHeaders.WildcardAction); } public void Open() { CreateSecurityProtocolFactory(); } void CreateSecurityProtocolFactory() { SecurityProtocolFactory incomingProtocolFactory; SecurityProtocolFactory outgoingProtocolFactory; ChannelProtectionRequirements protectionRequirements; lock (ThisLock) { if (null != securityProtocolFactory) return; TimeoutHelper timeoutHelper = new TimeoutHelper(ServiceDefaults.SendTimeout); if (!enableSigning) { outgoingProtocolFactory = new PeerDoNothingSecurityProtocolFactory(); incomingProtocolFactory = new PeerDoNothingSecurityProtocolFactory(); } else { X509Certificate2 cert = credManager.Certificate; if (cert != null) { SecurityBindingElement securityBindingElement = SecurityBindingElement.CreateCertificateSignatureBindingElement(); securityBindingElement.ReaderQuotas = this.readerQuotas; BindingParameterCollection bpc = new BindingParameterCollection(); if (protection == null) { protectionRequirements = new ChannelProtectionRequirements(); } else { protectionRequirements = new ChannelProtectionRequirements(protection); } ApplySigningRequirements(protectionRequirements.IncomingSignatureParts); ApplySigningRequirements(protectionRequirements.OutgoingSignatureParts); bpc.Add(protectionRequirements); bpc.Add(this.auditBehavior); bpc.Add(credManager); BindingContext context = new BindingContext(new CustomBinding(securityBindingElement), bpc); outgoingProtocolFactory = securityBindingElement.CreateSecurityProtocolFactory (context, credManager, false, null); } else { outgoingProtocolFactory = new PeerDoNothingSecurityProtocolFactory(); } SecurityTokenResolver resolver; X509SecurityTokenAuthenticator auth = tokenManager.CreateSecurityTokenAuthenticator(PeerSecurityCredentialsManager.PeerClientSecurityTokenManager.CreateRequirement(SecurityTokenTypes.X509Certificate, true), out resolver) as X509SecurityTokenAuthenticator ; if (auth != null) { SecurityBindingElement securityBindingElement = SecurityBindingElement.CreateCertificateSignatureBindingElement(); securityBindingElement.ReaderQuotas = this.readerQuotas; BindingParameterCollection bpc = new BindingParameterCollection(); if (protection == null) { protectionRequirements = new ChannelProtectionRequirements(); } else { protectionRequirements = new ChannelProtectionRequirements(protection); } ApplySigningRequirements(protectionRequirements.IncomingSignatureParts); ApplySigningRequirements(protectionRequirements.OutgoingSignatureParts); bpc.Add(protectionRequirements); bpc.Add(this.auditBehavior); bpc.Add(credManager); BindingContext context = new BindingContext(new CustomBinding(securityBindingElement), bpc); incomingProtocolFactory = securityBindingElement.CreateSecurityProtocolFactory (context, credManager, true, null); } else { incomingProtocolFactory = new PeerDoNothingSecurityProtocolFactory(); } } DuplexSecurityProtocolFactory tempFactory = new DuplexSecurityProtocolFactory(outgoingProtocolFactory, incomingProtocolFactory); tempFactory.Open(true, timeoutHelper.RemainingTime()); securityProtocolFactory = tempFactory; } } public SecurityProtocolFactory GetProtocolFactory () { if(securityProtocolFactory == null) { CreateSecurityProtocolFactory(); } if(typeof(TChannel) == typeof(IOutputChannel)) { if(enableSigning && securityProtocolFactory.ForwardProtocolFactory is PeerDoNothingSecurityProtocolFactory) PeerExceptionHelper.ThrowArgument_InsufficientCredentials(PeerPropertyNames.MessageSenderAuthentication); return securityProtocolFactory.ForwardProtocolFactory; } else if(typeof(TChannel) == typeof(IInputChannel)) { if(enableSigning && securityProtocolFactory.ReverseProtocolFactory is PeerDoNothingSecurityProtocolFactory) PeerExceptionHelper.ThrowArgument_InsufficientCredentials(PeerPropertyNames.MessageSenderAuthentication); return securityProtocolFactory.ReverseProtocolFactory; } else { if(enableSigning && ((securityProtocolFactory.ReverseProtocolFactory is PeerDoNothingSecurityProtocolFactory) || (securityProtocolFactory.ForwardProtocolFactory is PeerDoNothingSecurityProtocolFactory))) PeerExceptionHelper.ThrowArgument_InsufficientCredentials(PeerPropertyNames.MessageSenderAuthentication); return securityProtocolFactory; } } public SecurityProtocol CreateSecurityProtocol (EndpointAddress target, TimeSpan timespan) { TimeoutHelper timeoutHelper = new TimeoutHelper(timespan); SecurityProtocolFactory factory = GetProtocolFactory (); DiagnosticUtility.DebugAssert(factory != null, "SecurityProtocolFactory is NULL!"); SecurityProtocol instance = factory.CreateSecurityProtocol(target, null, /*listenerSecurityState*/null, /*isReturnLegSecurityRequired*/false, timeoutHelper.RemainingTime()); if(instance != null) instance.Open(timeoutHelper.RemainingTime()); return instance; } public void CheckIfCompatibleNodeSettings(object other) { string mismatch = null; PeerSecurityManager that = other as PeerSecurityManager; if (that == null) mismatch = PeerBindingPropertyNames.Security; else if (this.authenticationMode != that.authenticationMode) mismatch = PeerBindingPropertyNames.SecurityDotMode; else if(this.authenticationMode == PeerAuthenticationMode.None) return ; else if(!this.tokenManager.Equals(that.tokenManager)) { if(this.credManager != null) this.credManager.CheckIfCompatible(that.credManager); else { DiagnosticUtility.DebugAssert(typeof(PeerSecurityCredentialsManager.PeerClientSecurityTokenManager).IsAssignableFrom(tokenManager.GetType()), ""); mismatch = PeerBindingPropertyNames.Credentials; } } if(mismatch != null) PeerExceptionHelper.ThrowInvalidOperation_PeerConflictingPeerNodeSettings(mismatch); } public bool HasCompatibleMessageSecurity(PeerSecurityManager that) { return (this.MessageAuthentication == that.MessageAuthentication); } public byte[] GetAuthenticator() { if (authenticationMode != PeerAuthenticationMode.Password) return null; if (authenticatorHash == null) { lock (ThisLock) { if (authenticatorHash == null) { authenticatorHash = PeerSecurityHelpers.ComputeHash(credManager.Certificate, credManager.Password); } } } return authenticatorHash; } public bool Authenticate(ServiceSecurityContext context, byte[] message) { Claim claim = null; if (context == null) { return (authenticationMode == PeerAuthenticationMode.None); } if (authenticationMode == PeerAuthenticationMode.Password) { if (!(context != null)) { DiagnosticUtility.DebugAssert("No SecurityContext attached in security mode!"); throw DiagnosticUtility.ExceptionUtility.ThrowHelperInternal(false); } claim = FindClaim(context); return PeerSecurityHelpers.Authenticate(claim, this.credManager.Password, message); } else { if (message != null) { PeerExceptionHelper.ThrowInvalidOperation_UnexpectedSecurityTokensDuringHandshake(); } return true; } } public static Claim FindClaim(ServiceSecurityContext context) { Claim result = null; DiagnosticUtility.DebugAssert(context != null, "ServiceSecurityContext is null!"); for (int i = 0 ; i < context.AuthorizationContext.ClaimSets.Count ; ++i) { ClaimSet claimSet = context.AuthorizationContext.ClaimSets[i]; IEnumerator claims = claimSet.FindClaims(ClaimTypes.Rsa, null).GetEnumerator(); if(claims.MoveNext()) { result = claims.Current; break; } } return result; } public void ApplyClientSecurity(ChannelFactory factory) { factory.Endpoint.Behaviors.Remove (); if (authenticationMode != PeerAuthenticationMode.None) { factory.Endpoint.Behaviors.Add(this.credManager.CloneForTransport()); } } public BindingElement GetSecurityBindingElement() { SslStreamSecurityBindingElement security = null; if(this.AuthenticationMode != PeerAuthenticationMode.None) { security = new SslStreamSecurityBindingElement(); security.IdentityVerifier = new PeerIdentityVerifier(); security.RequireClientCertificate = true; } return security; } public PeerHashToken GetSelfToken() { if (!(this.authenticationMode == PeerAuthenticationMode.Password)) { DiagnosticUtility.DebugAssert("unexpected call to GetSelfToken"); throw DiagnosticUtility.ExceptionUtility.ThrowHelperInternal(false); } return new PeerHashToken(this.credManager.Certificate, this.credManager.Password); } public PeerHashToken GetExpectedTokenForClaim(Claim claim) { return new PeerHashToken(claim,this.password); } public void OnNeighborOpened(object sender, EventArgs args) { IPeerNeighbor neighbor = sender as IPeerNeighbor; EventHandler handler = this.OnNeighborAuthenticated; if (handler == null) { neighbor.Abort(PeerCloseReason.LeavingMesh, PeerCloseInitiator.LocalNode); return; } if(this.authenticationMode == PeerAuthenticationMode.Password) { if (!(neighbor.Extensions.Find ()==null)) { DiagnosticUtility.DebugAssert("extension already exists!"); throw DiagnosticUtility.ExceptionUtility.ThrowHelperInternal(false); } PeerChannelAuthenticatorExtension extension = new PeerChannelAuthenticatorExtension(this, handler, args, this.MeshId); neighbor.Extensions.Add(extension); if(neighbor.IsInitiator) extension.InitiateHandShake(); } else { neighbor.TrySetState(PeerNeighborState.Authenticated); handler(sender, args); } } public Message ProcessRequest(IPeerNeighbor neighbor, Message request) { if(this.authenticationMode != PeerAuthenticationMode.Password || request == null) { Abort(neighbor); return null; } PeerChannelAuthenticatorExtension extension = neighbor.Extensions.Find (); Claim claim = FindClaim(ServiceSecurityContext.Current); if (!(extension != null && claim != null)) { DiagnosticUtility.DebugAssert("No suitable claim found in the context to do security negotiation!"); throw DiagnosticUtility.ExceptionUtility.ThrowHelperInternal(false); } return extension.ProcessRst(request, claim); } void Abort(IPeerNeighbor neighbor) { neighbor.Abort(PeerCloseReason.AuthenticationFailure, PeerCloseInitiator.LocalNode); } } class PeerSecurityCredentialsManager : SecurityCredentialsManager, IEndpointBehavior, IServiceBehavior { SecurityTokenManager manager; PeerCredential credential; bool messageAuth; PeerAuthenticationMode mode = PeerAuthenticationMode.Password; SelfSignedCertificate ssl; PeerSecurityManager parent; public PeerSecurityCredentialsManager(SecurityTokenManager manager, PeerAuthenticationMode mode, bool messageAuth):base() { this.manager = manager; this.mode = mode; this.messageAuth = messageAuth; } public PeerSecurityCredentialsManager(PeerCredential credential, PeerAuthenticationMode mode, bool messageAuth):base() { this.credential = credential; this.mode = mode; this.messageAuth = messageAuth; } public PeerSecurityManager Parent { get { return this.parent; } set { parent = value; } } public override SecurityTokenManager CreateSecurityTokenManager() { if(manager != null) return new PeerClientSecurityTokenManager(this.parent, manager, mode, messageAuth); else return new PeerClientSecurityTokenManager(this.parent, credential, mode, messageAuth); } public PeerSecurityCredentialsManager():base(){} public PeerSecurityCredentialsManager CloneForTransport() { PeerSecurityCredentialsManager cloner = new PeerSecurityCredentialsManager(); if(this.credential != null) cloner.credential = new PeerCredential(this.credential); cloner.mode = this.mode; cloner.messageAuth = this.messageAuth; cloner.manager = this.manager; cloner.parent = parent; return cloner; } internal PeerCredential Credential { get { return this.credential; } } internal string Password { get { if(this.credential != null) return credential.MeshPassword; ServiceModelSecurityTokenRequirement req = PeerClientSecurityTokenManager.CreateRequirement(SecurityTokenTypes.UserName); UserNameSecurityTokenProvider tokenProvider = this.manager.CreateSecurityTokenProvider(req) as UserNameSecurityTokenProvider; if(tokenProvider == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("TokenProvider"); UserNameSecurityToken token = tokenProvider.GetToken(ServiceDefaults.SendTimeout) as UserNameSecurityToken; if(token == null || String.IsNullOrEmpty(token.Password)) throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("password"); return token.Password; } } internal X509Certificate2 Certificate { get { X509Certificate2 result = null; if(mode == PeerAuthenticationMode.Password) { if(ssl != null) result = ssl.GetX509Certificate(); } if(this.credential != null) { result = credential.Certificate; } else { ServiceModelSecurityTokenRequirement req = PeerClientSecurityTokenManager.CreateRequirement(SecurityTokenTypes.X509Certificate); X509SecurityTokenProvider tokenProvider = this.manager.CreateSecurityTokenProvider(req) as X509SecurityTokenProvider; if(tokenProvider == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("TokenProvider"); X509SecurityToken token = tokenProvider.GetToken(ServiceDefaults.SendTimeout) as X509SecurityToken; if(token == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("token"); result = token.Certificate; } if(result == null && mode == PeerAuthenticationMode.Password) { ssl = this.parent.GetCertificate(); result = ssl.GetX509Certificate(); } return result; } } void IEndpointBehavior.Validate(ServiceEndpoint serviceEndpoint) { } void IEndpointBehavior.AddBindingParameters(ServiceEndpoint serviceEndpoint, BindingParameterCollection bindingParameters) { if (bindingParameters != null) bindingParameters.Add(this); } void IEndpointBehavior.ApplyDispatchBehavior(ServiceEndpoint serviceEndpoint, EndpointDispatcher endpointDispatcher) { } void IEndpointBehavior.ApplyClientBehavior(ServiceEndpoint serviceEndpoint, ClientRuntime behavior) { } void IServiceBehavior.Validate(ServiceDescription description, ServiceHostBase serviceHostBase) { } void IServiceBehavior.AddBindingParameters(ServiceDescription description, ServiceHostBase serviceHostBase, Collection endpoints, BindingParameterCollection parameters) { if (parameters == null) { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("parameters"); } parameters.Add(this); } void IServiceBehavior.ApplyDispatchBehavior(ServiceDescription description, ServiceHostBase serviceHostBase) { } public override bool Equals(object other) { PeerSecurityCredentialsManager that = other as PeerSecurityCredentialsManager ; if(that == null) return false; if(this.credential != null) { return this.credential.Equals(that.credential, mode, messageAuth); } else { return this.manager.Equals(that.manager); } } public void CheckIfCompatible(PeerSecurityCredentialsManager that) { if(that == null) PeerExceptionHelper.ThrowInvalidOperation_PeerConflictingPeerNodeSettings(PeerBindingPropertyNames.Credentials); if(this.mode == PeerAuthenticationMode.None) return; if(this.mode == PeerAuthenticationMode.Password) { if(this.Password != that.Password) PeerExceptionHelper.ThrowInvalidOperation_PeerConflictingPeerNodeSettings(PeerBindingPropertyNames.Password); } if(!this.Certificate.Equals(that.Certificate)) PeerExceptionHelper.ThrowInvalidOperation_PeerConflictingPeerNodeSettings(PeerBindingPropertyNames.Certificate); } public override int GetHashCode() { return base.GetHashCode(); } public class PeerClientSecurityTokenManager : SecurityTokenManager { SecurityTokenManager delegateManager; PeerCredential credential; PeerAuthenticationMode mode; bool messageAuth; SelfSignedCertificate ssc; PeerSecurityManager parent; public PeerClientSecurityTokenManager(PeerSecurityManager parent, PeerCredential credential, PeerAuthenticationMode mode, bool messageAuth) { this.credential = credential; this.mode = mode; this.messageAuth = messageAuth; this.parent = parent; } public PeerClientSecurityTokenManager(PeerSecurityManager parent, SecurityTokenManager manager, PeerAuthenticationMode mode, bool messageAuth) { this.delegateManager = manager; this.mode = mode; this.messageAuth = messageAuth; this.parent = parent; } internal static ServiceModelSecurityTokenRequirement CreateRequirement(string tokenType) { return CreateRequirement(tokenType, false); } internal static ServiceModelSecurityTokenRequirement CreateRequirement(string tokenType, bool forMessageValidation) { InitiatorServiceModelSecurityTokenRequirement requirement = new InitiatorServiceModelSecurityTokenRequirement(); requirement.TokenType = tokenType; requirement.TransportScheme = PeerStrings.Scheme; if(forMessageValidation) requirement.Properties[SecurityTokenRequirement.PeerAuthenticationMode] = SecurityMode.Message; else requirement.Properties[SecurityTokenRequirement.PeerAuthenticationMode] = SecurityMode.Transport; return requirement; } UserNameSecurityTokenProvider GetPasswordTokenProvider() { if(delegateManager != null) { ServiceModelSecurityTokenRequirement requirement = CreateRequirement(SecurityTokenTypes.UserName); UserNameSecurityTokenProvider tokenProvider = delegateManager.CreateSecurityTokenProvider(requirement) as UserNameSecurityTokenProvider; if(tokenProvider == null) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.SecurityTokenManagerCannotCreateProviderForRequirement, requirement))); return tokenProvider; } else return new UserNameSecurityTokenProvider(string.Empty, credential.MeshPassword); } public override SecurityTokenSerializer CreateSecurityTokenSerializer(SecurityTokenVersion version) { if (delegateManager != null) return delegateManager.CreateSecurityTokenSerializer(version); else { MessageSecurityTokenVersion wsVersion = version as MessageSecurityTokenVersion; if (wsVersion != null) { return new WSSecurityTokenSerializer(wsVersion.SecurityVersion, wsVersion.TrustVersion, wsVersion.SecureConversationVersion, wsVersion.EmitBspRequiredAttributes, null, null, null); } else { throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.SecurityTokenManagerCannotCreateSerializerForVersion, version))); } } } public override SecurityTokenProvider CreateSecurityTokenProvider(SecurityTokenRequirement tokenRequirement) { ServiceModelSecurityTokenRequirement requirement = tokenRequirement as ServiceModelSecurityTokenRequirement; if(requirement != null) { if(IsX509TokenRequirement(requirement)) { if (IsForConnectionValidator(requirement)) { SecurityTokenProvider result = null; if(this.ssc != null) { result = new X509SecurityTokenProvider(this.ssc.GetX509Certificate()); } else { if (this.delegateManager != null) { requirement.Properties[SecurityTokenRequirement.PeerAuthenticationMode] = SecurityMode.Transport; requirement.TransportScheme = PeerStrings.Scheme; result = delegateManager.CreateSecurityTokenProvider(tokenRequirement); } else { if (this.credential.Certificate != null) result = new X509SecurityTokenProvider(this.credential.Certificate); } } if (result == null && mode == PeerAuthenticationMode.Password) { this.ssc = parent.GetCertificate(); result = new X509SecurityTokenProvider(this.ssc.GetX509Certificate()); } return result; } else { X509CertificateValidator validator; if (this.delegateManager != null) { requirement.TransportScheme = PeerStrings.Scheme; requirement.Properties[SecurityTokenRequirement.PeerAuthenticationMode] = SecurityMode.Message; return delegateManager.CreateSecurityTokenProvider(tokenRequirement); } if (!this.credential.MessageSenderAuthentication.TryGetCertificateValidator(out validator)) throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("TokenType"); return new PeerX509TokenProvider(validator, this.credential.Certificate); } } else if(IsPasswordTokenRequirement(requirement)) { return GetPasswordTokenProvider(); } else { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("TokenType"); } } else { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("tokenRequirement"); } } bool IsPasswordTokenRequirement(ServiceModelSecurityTokenRequirement requirement) { return ((requirement != null) && (requirement.TokenType == SecurityTokenTypes.UserName)); } bool IsX509TokenRequirement(ServiceModelSecurityTokenRequirement requirement) { return (requirement != null && requirement.TokenType == SecurityTokenTypes.X509Certificate); } bool IsForConnectionValidator(ServiceModelSecurityTokenRequirement requirement ) { return (requirement.TransportScheme == "net.tcp" && requirement.SecurityBindingElement == null && requirement.MessageSecurityVersion == null); } public override SecurityTokenAuthenticator CreateSecurityTokenAuthenticator(SecurityTokenRequirement tokenRequirement, out SecurityTokenResolver outOfBandTokenResolver) { ServiceModelSecurityTokenRequirement requirement = tokenRequirement as ServiceModelSecurityTokenRequirement; outOfBandTokenResolver = null; if(requirement != null) { if(IsX509TokenRequirement(requirement)) { if (mode == PeerAuthenticationMode.Password && IsForConnectionValidator(requirement)) { return new X509SecurityTokenAuthenticator(X509CertificateValidator.None); } if(delegateManager != null) { if (IsForConnectionValidator(requirement)) { requirement.TransportScheme = PeerStrings.Scheme; requirement.Properties[SecurityTokenRequirement.PeerAuthenticationMode] = SecurityMode.Transport; } else { requirement.TransportScheme = PeerStrings.Scheme; requirement.Properties[SecurityTokenRequirement.PeerAuthenticationMode] = SecurityMode.Message; } return delegateManager.CreateSecurityTokenAuthenticator(tokenRequirement, out outOfBandTokenResolver); } else { X509CertificateValidator validator = null; if(IsForConnectionValidator(requirement)) { if(this.mode == PeerAuthenticationMode.MutualCertificate) { if(!this.credential.PeerAuthentication.TryGetCertificateValidator(out validator)) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.SecurityTokenManagerCannotCreateProviderForRequirement, requirement))); } else validator = X509CertificateValidator.None; } else { if(!this.credential.MessageSenderAuthentication.TryGetCertificateValidator(out validator)) throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.SecurityTokenManagerCannotCreateProviderForRequirement, requirement))); } return new X509SecurityTokenAuthenticator(validator); } } else { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument("tokenRequirement"); } } else { throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("tokenRequirement"); } } public override bool Equals(object other) { PeerClientSecurityTokenManager that = other as PeerClientSecurityTokenManager; if(that == null) return false; if(this.credential != null) { if(that.credential == null || !this.credential.Equals(that.credential,this.mode,this.messageAuth)) return false; return true; } else { return this.delegateManager.Equals(that.delegateManager); } } internal bool HasCompatibleMessageSecuritySettings(PeerClientSecurityTokenManager that) { if(this.credential != null) return (that.credential != null && this.credential.Equals(that.credential)); else return this.delegateManager.Equals(that.delegateManager); } public override int GetHashCode() { if(credential != null) return credential.GetHashCode(); else if(delegateManager != null) return delegateManager.GetHashCode(); else return 0; } } } } // 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
- InvokeProviderWrapper.cs
- UniqueConstraint.cs
- RSAOAEPKeyExchangeFormatter.cs
- ImmutableObjectAttribute.cs
- IntranetCredentialPolicy.cs
- NamedPipeHostedTransportConfiguration.cs
- VectorConverter.cs
- ToolStripMenuItemDesigner.cs
- Pkcs7Signer.cs
- HtmlHead.cs
- ContextMenuStrip.cs
- RSAPKCS1KeyExchangeDeformatter.cs
- XmlEnumAttribute.cs
- CodeDelegateInvokeExpression.cs
- MetadataArtifactLoaderXmlReaderWrapper.cs
- PersonalizationProviderCollection.cs
- BaseTemplateParser.cs
- SerializationEventsCache.cs
- CLSCompliantAttribute.cs
- Module.cs
- CodeConstructor.cs
- StylusPointPropertyId.cs
- DocumentsTrace.cs
- SerialPort.cs
- NumberSubstitution.cs
- SchemaElementDecl.cs
- GenericsInstances.cs
- Int16.cs
- ObjectStateEntryDbUpdatableDataRecord.cs
- TextDecorationCollectionConverter.cs
- XPathNavigatorException.cs
- TemplateControl.cs
- X509SecurityTokenParameters.cs
- AnnouncementEndpointElement.cs
- HostElement.cs
- MonthCalendarDesigner.cs
- XsltException.cs
- RequestCacheManager.cs
- StringConverter.cs
- StateMachineDesignerPaint.cs
- WebPartMovingEventArgs.cs
- QueryStringParameter.cs
- TemplateComponentConnector.cs
- MatrixTransform3D.cs
- Debug.cs
- Token.cs
- ConsoleCancelEventArgs.cs
- CompressEmulationStream.cs
- SyndicationSerializer.cs
- TreeNodeClickEventArgs.cs
- CustomAttributeSerializer.cs
- Pointer.cs
- PropertyReferenceSerializer.cs
- RequestStatusBarUpdateEventArgs.cs
- FreezableCollection.cs
- PeerPresenceInfo.cs
- ComboBoxDesigner.cs
- FileAuthorizationModule.cs
- NetworkStream.cs
- UnknownBitmapDecoder.cs
- ISFClipboardData.cs
- UpDownEvent.cs
- TopClause.cs
- AppManager.cs
- XmlSerializerFactory.cs
- XmlWellformedWriter.cs
- GridViewEditEventArgs.cs
- DataGridViewCellStyleConverter.cs
- WeakReferenceEnumerator.cs
- ItemDragEvent.cs
- VariableQuery.cs
- Frame.cs
- HttpException.cs
- DragDrop.cs
- EventItfInfo.cs
- UIPermission.cs
- validationstate.cs
- SoapConverter.cs
- XmlDataImplementation.cs
- EventToken.cs
- MonitorWrapper.cs
- ColumnReorderedEventArgs.cs
- MultipleViewPatternIdentifiers.cs
- RadioButtonFlatAdapter.cs
- XNodeValidator.cs
- UserControlParser.cs
- InfiniteTimeSpanConverter.cs
- Selector.cs
- HttpServerVarsCollection.cs
- ISFTagAndGuidCache.cs
- SyndicationFeed.cs
- GeneralTransformGroup.cs
- PasswordBox.cs
- ObjectCacheSettings.cs
- ProcessProtocolHandler.cs
- SynchronizationContext.cs
- BaseTemplateCodeDomTreeGenerator.cs
- DependencySource.cs
- XmlEntity.cs
- ConfigsHelper.cs