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
- ProcessThreadCollection.cs
- AbstractExpressions.cs
- Speller.cs
- DataTemplateSelector.cs
- ArrangedElementCollection.cs
- DataGridViewEditingControlShowingEventArgs.cs
- TextPointerBase.cs
- SchemaNames.cs
- UrlMappingsModule.cs
- PatternMatcher.cs
- TagPrefixAttribute.cs
- SwitchLevelAttribute.cs
- WebPartTracker.cs
- TraceContextEventArgs.cs
- MobileUserControl.cs
- FactoryGenerator.cs
- DataGridViewCellFormattingEventArgs.cs
- ObjectDataSourceSelectingEventArgs.cs
- SingleStorage.cs
- BulletChrome.cs
- ComponentDispatcherThread.cs
- ExceptionWrapper.cs
- Events.cs
- ListControl.cs
- SQLBytes.cs
- AnimationLayer.cs
- XLinq.cs
- Color.cs
- EncryptedPackage.cs
- baseaxisquery.cs
- FillBehavior.cs
- HostedTransportConfigurationBase.cs
- Package.cs
- XmlParser.cs
- ShowExpandedMultiValueConverter.cs
- SourceChangedEventArgs.cs
- DBBindings.cs
- Timer.cs
- XhtmlBasicValidationSummaryAdapter.cs
- TypeGeneratedEventArgs.cs
- AnnotationResource.cs
- HtmlInputButton.cs
- CharAnimationUsingKeyFrames.cs
- PreloadHost.cs
- ResourceExpressionEditorSheet.cs
- NonClientArea.cs
- TextEditorTyping.cs
- infer.cs
- ExpressionList.cs
- ResourcePart.cs
- ListDataBindEventArgs.cs
- EntityContainerRelationshipSetEnd.cs
- TextDecorationUnitValidation.cs
- SqlUserDefinedTypeAttribute.cs
- MultiByteCodec.cs
- bidPrivateBase.cs
- FormsAuthenticationModule.cs
- ColumnReorderedEventArgs.cs
- MetadataArtifactLoaderComposite.cs
- DataFormats.cs
- PersonalizationProvider.cs
- InstanceNameConverter.cs
- SubpageParaClient.cs
- mediapermission.cs
- ToolStripButton.cs
- CodeAttributeDeclaration.cs
- ProcessManager.cs
- SqlClientMetaDataCollectionNames.cs
- OdbcReferenceCollection.cs
- PenLineJoinValidation.cs
- SemanticTag.cs
- recordstatefactory.cs
- ValidationManager.cs
- SafeEventLogReadHandle.cs
- CommentAction.cs
- CloseSequence.cs
- XmlSerializerAssemblyAttribute.cs
- wgx_render.cs
- MexNamedPipeBindingCollectionElement.cs
- SystemException.cs
- HotSpot.cs
- SessionPageStatePersister.cs
- XpsFont.cs
- LocalFileSettingsProvider.cs
- CodeObject.cs
- MemoryMappedViewAccessor.cs
- CornerRadiusConverter.cs
- MethodBuilder.cs
- ResourceAssociationSet.cs
- Scheduling.cs
- XmlSchemaAnnotated.cs
- HideDisabledControlAdapter.cs
- WorkItem.cs
- Attributes.cs
- SafeCertificateStore.cs
- DiscoveryDocumentSearchPattern.cs
- WebBrowserEvent.cs
- LookupBindingPropertiesAttribute.cs
- ProxyHwnd.cs
- Sequence.cs