| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244 |
- //------------------------------------------------------------
- // Copyright (c) Microsoft Corporation. All rights reserved.
- //------------------------------------------------------------
- namespace System.ServiceModel
- {
- using System;
- using System.ComponentModel;
- using System.Runtime;
- using System.Runtime.CompilerServices;
- using System.ServiceModel.Channels;
- using System.ServiceModel.Security;
- using System.ServiceModel.Security.Tokens;
- public sealed class MessageSecurityOverTcp
- {
- internal const MessageCredentialType DefaultClientCredentialType = MessageCredentialType.Windows;
- MessageCredentialType clientCredentialType;
- SecurityAlgorithmSuite algorithmSuite;
- bool wasAlgorithmSuiteSet;
- public MessageSecurityOverTcp()
- {
- clientCredentialType = DefaultClientCredentialType;
- algorithmSuite = SecurityAlgorithmSuite.Default;
- }
- [DefaultValue(MessageSecurityOverTcp.DefaultClientCredentialType)]
- public MessageCredentialType ClientCredentialType
- {
- get { return this.clientCredentialType; }
- set
- {
- if (!MessageCredentialTypeHelper.IsDefined(value))
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException("value"));
- }
- this.clientCredentialType = value;
- }
- }
- [DefaultValue(typeof(SecurityAlgorithmSuite), System.ServiceModel.Configuration.ConfigurationStrings.Default)]
- public SecurityAlgorithmSuite AlgorithmSuite
- {
- get { return this.algorithmSuite; }
- set
- {
- if (value == null)
- {
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("value");
- }
- this.algorithmSuite = value;
- wasAlgorithmSuiteSet = true;
- }
- }
- internal bool WasAlgorithmSuiteSet
- {
- get { return this.wasAlgorithmSuiteSet; }
- }
- [MethodImpl(MethodImplOptions.NoInlining)]
- internal SecurityBindingElement CreateSecurityBindingElement(bool isSecureTransportMode, bool isReliableSession, BindingElement transportBindingElement)
- {
- SecurityBindingElement result;
- SecurityBindingElement oneShotSecurity;
- if (isSecureTransportMode)
- {
- switch (this.clientCredentialType)
- {
- case MessageCredentialType.None:
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ClientCredentialTypeMustBeSpecifiedForMixedMode)));
- case MessageCredentialType.UserName:
- oneShotSecurity = SecurityBindingElement.CreateUserNameOverTransportBindingElement();
- break;
- case MessageCredentialType.Certificate:
- oneShotSecurity = SecurityBindingElement.CreateCertificateOverTransportBindingElement();
- break;
- case MessageCredentialType.Windows:
- oneShotSecurity = SecurityBindingElement.CreateSspiNegotiationOverTransportBindingElement(true);
- break;
- case MessageCredentialType.IssuedToken:
- oneShotSecurity = SecurityBindingElement.CreateIssuedTokenOverTransportBindingElement(IssuedSecurityTokenParameters.CreateInfoCardParameters(new SecurityStandardsManager(), this.algorithmSuite));
- break;
- default:
- Fx.Assert("unknown ClientCredentialType");
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException());
- }
- result = SecurityBindingElement.CreateSecureConversationBindingElement(oneShotSecurity);
- }
- else
- {
- switch (this.clientCredentialType)
- {
- case MessageCredentialType.None:
- oneShotSecurity = SecurityBindingElement.CreateSslNegotiationBindingElement(false, true);
- break;
- case MessageCredentialType.UserName:
- // require cancellation so that impersonation is possible
- oneShotSecurity = SecurityBindingElement.CreateUserNameForSslBindingElement(true);
- break;
- case MessageCredentialType.Certificate:
- oneShotSecurity = SecurityBindingElement.CreateSslNegotiationBindingElement(true, true);
- break;
- case MessageCredentialType.Windows:
- // require cancellation so that impersonation is possible
- oneShotSecurity = SecurityBindingElement.CreateSspiNegotiationBindingElement(true);
- break;
- case MessageCredentialType.IssuedToken:
- oneShotSecurity = SecurityBindingElement.CreateIssuedTokenForSslBindingElement(IssuedSecurityTokenParameters.CreateInfoCardParameters(new SecurityStandardsManager(), this.algorithmSuite), true);
- break;
- default:
- Fx.Assert("unknown ClientCredentialType");
- throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException());
- }
- result = SecurityBindingElement.CreateSecureConversationBindingElement(oneShotSecurity, true);
- }
- // set the algorithm suite and issued token params if required
- result.DefaultAlgorithmSuite = oneShotSecurity.DefaultAlgorithmSuite = this.AlgorithmSuite;
- result.IncludeTimestamp = true;
- if (!isReliableSession)
- {
- result.LocalServiceSettings.ReconnectTransportOnFailure = false;
- result.LocalClientSettings.ReconnectTransportOnFailure = false;
- }
- else
- {
- result.LocalServiceSettings.ReconnectTransportOnFailure = true;
- result.LocalClientSettings.ReconnectTransportOnFailure = true;
- }
- // since a session is always bootstrapped, configure the transition sct to live for a short time only
- oneShotSecurity.LocalServiceSettings.IssuedCookieLifetime = SpnegoTokenAuthenticator.defaultServerIssuedTransitionTokenLifetime;
- result.MessageSecurityVersion = MessageSecurityVersion.WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11;
- oneShotSecurity.MessageSecurityVersion = MessageSecurityVersion.WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11;
- return result;
- }
- internal static bool TryCreate(SecurityBindingElement sbe, bool isReliableSession, BindingElement transportBindingElement, out MessageSecurityOverTcp messageSecurity)
- {
- messageSecurity = null;
- if (sbe == null)
- return false;
- // do not check local settings: sbe.LocalServiceSettings and sbe.LocalClientSettings
- if (!sbe.IncludeTimestamp)
- return false;
- if (sbe.MessageSecurityVersion != MessageSecurityVersion.WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11
- && sbe.MessageSecurityVersion != MessageSecurityVersion.WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10)
- {
- return false;
- }
- if (sbe.SecurityHeaderLayout != SecurityProtocolFactory.defaultSecurityHeaderLayout)
- return false;
- MessageCredentialType clientCredentialType;
- SecurityBindingElement bootstrapSecurity;
- if (!SecurityBindingElement.IsSecureConversationBinding(sbe, true, out bootstrapSecurity))
- return false;
- bool isSecureTransportMode = bootstrapSecurity is TransportSecurityBindingElement;
- IssuedSecurityTokenParameters infocardParameters;
- if (isSecureTransportMode)
- {
- if (SecurityBindingElement.IsUserNameOverTransportBinding(bootstrapSecurity))
- clientCredentialType = MessageCredentialType.UserName;
- else if (SecurityBindingElement.IsCertificateOverTransportBinding(bootstrapSecurity))
- clientCredentialType = MessageCredentialType.Certificate;
- else if (SecurityBindingElement.IsSspiNegotiationOverTransportBinding(bootstrapSecurity, true))
- clientCredentialType = MessageCredentialType.Windows;
- else if (SecurityBindingElement.IsIssuedTokenOverTransportBinding(bootstrapSecurity, out infocardParameters))
- {
- if (!IssuedSecurityTokenParameters.IsInfoCardParameters(
- infocardParameters,
- new SecurityStandardsManager(
- bootstrapSecurity.MessageSecurityVersion,
- new WSSecurityTokenSerializer(
- bootstrapSecurity.MessageSecurityVersion.SecurityVersion,
- bootstrapSecurity.MessageSecurityVersion.TrustVersion,
- bootstrapSecurity.MessageSecurityVersion.SecureConversationVersion,
- true,
- null, null, null))))
- return false;
- clientCredentialType = MessageCredentialType.IssuedToken;
- }
- else
- {
- // the standard binding does not support None client credential type in mixed mode
- return false;
- }
- }
- else
- {
- if (SecurityBindingElement.IsUserNameForSslBinding(bootstrapSecurity, true))
- clientCredentialType = MessageCredentialType.UserName;
- else if (SecurityBindingElement.IsSslNegotiationBinding(bootstrapSecurity, true, true))
- clientCredentialType = MessageCredentialType.Certificate;
- else if (SecurityBindingElement.IsSspiNegotiationBinding(bootstrapSecurity, true))
- clientCredentialType = MessageCredentialType.Windows;
- else if (SecurityBindingElement.IsIssuedTokenForSslBinding(bootstrapSecurity, true, out infocardParameters))
- {
- if (!IssuedSecurityTokenParameters.IsInfoCardParameters(
- infocardParameters,
- new SecurityStandardsManager(
- bootstrapSecurity.MessageSecurityVersion,
- new WSSecurityTokenSerializer(
- bootstrapSecurity.MessageSecurityVersion.SecurityVersion,
- bootstrapSecurity.MessageSecurityVersion.TrustVersion,
- bootstrapSecurity.MessageSecurityVersion.SecureConversationVersion,
- true,
- null, null, null))))
- return false;
- clientCredentialType = MessageCredentialType.IssuedToken;
- }
- else if (SecurityBindingElement.IsSslNegotiationBinding(bootstrapSecurity, false, true))
- clientCredentialType = MessageCredentialType.None;
- else
- return false;
- }
- messageSecurity = new MessageSecurityOverTcp();
- messageSecurity.ClientCredentialType = clientCredentialType;
- // set the algorithm suite and issued token params if required
- if (clientCredentialType != MessageCredentialType.IssuedToken)
- {
- messageSecurity.AlgorithmSuite = bootstrapSecurity.DefaultAlgorithmSuite;
- }
- return true;
- }
- internal bool InternalShouldSerialize()
- {
- return this.ClientCredentialType != NetTcpDefaults.MessageSecurityClientCredentialType
- || this.AlgorithmSuite != NetTcpDefaults.MessageSecurityAlgorithmSuite;
- }
- }
- }
|