Skip to content

Commit

Permalink
Adding implementation and tests for TransportWithMessageCredential se…
Browse files Browse the repository at this point in the history
…curity mode for NetTcp
  • Loading branch information
mconnew committed May 15, 2019
1 parent fc02bab commit 23dd138
Show file tree
Hide file tree
Showing 15 changed files with 417 additions and 109 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,26 @@
// See the LICENSE file in the project root for more information.


using System.Security.Authentication.ExtendedProtection;

namespace System.ServiceModel.Channels
{
public class TcpTransportBindingElement : ConnectionOrientedTransportBindingElement
{
ExtendedProtectionPolicy _extendedProtectionPolicy;

public TcpTransportBindingElement()
: base()
{
ConnectionPoolSettings = new TcpConnectionPoolSettings();
_extendedProtectionPolicy = ChannelBindingUtility.DefaultPolicy;
}

protected TcpTransportBindingElement(TcpTransportBindingElement elementToBeCloned)
: base(elementToBeCloned)
{
ConnectionPoolSettings = elementToBeCloned.ConnectionPoolSettings.Clone();
_extendedProtectionPolicy = elementToBeCloned._extendedProtectionPolicy;
}

public TcpConnectionPoolSettings ConnectionPoolSettings { get; }
Expand All @@ -26,6 +32,30 @@ public override string Scheme
get { return "net.tcp"; }
}

public ExtendedProtectionPolicy ExtendedProtectionPolicy
{
get
{
return _extendedProtectionPolicy;
}
set
{
if (value == null)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(value));
}

if (value.PolicyEnforcement == PolicyEnforcement.Always &&
!ExtendedProtectionPolicy.OSSupportsExtendedProtection)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
new PlatformNotSupportedException(SR.ExtendedProtectionNotSupported));
}

_extendedProtectionPolicy = value;
}
}

public override BindingElement Clone()
{
return new TcpTransportBindingElement(this);
Expand Down Expand Up @@ -56,7 +86,10 @@ public override T GetProperty<T>(BindingContext context)
{
return (T)(object)new BindingDeliveryCapabilitiesHelper();
}

else if (typeof(T) == typeof(ExtendedProtectionPolicy))
{
return (T)(object)ExtendedProtectionPolicy;
}
else if (typeof(T) == typeof(ITransportCompressionSupport))
{
return (T)(object)new TransportCompressionSupportHelper();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,33 +4,35 @@


using System.ComponentModel;
using System.Runtime;
using System.Runtime.CompilerServices;
using System.ServiceModel.Channels;
using System.ServiceModel.Security;

namespace System.ServiceModel
{
public sealed class MessageSecurityOverTcp
{
internal const MessageCredentialType DefaultClientCredentialType = MessageCredentialType.Windows;
private MessageCredentialType _messageCredentialType;
private MessageCredentialType _clientCredentialType;
private SecurityAlgorithmSuite _algorithmSuite;

public MessageSecurityOverTcp()
{
_messageCredentialType = DefaultClientCredentialType;
_clientCredentialType = DefaultClientCredentialType;
_algorithmSuite = SecurityAlgorithmSuite.Default;
}

[DefaultValue(MessageSecurityOverTcp.DefaultClientCredentialType)]
[DefaultValue(DefaultClientCredentialType)]
public MessageCredentialType ClientCredentialType
{
get
{
if (_messageCredentialType != MessageCredentialType.None)
{
throw ExceptionHelper.PlatformNotSupported("MessageSecurityOverTcp.ClientCredentialType is not supported for values other than 'MessageCredentialType.None'.");
}
else
get {
if (_clientCredentialType == MessageCredentialType.IssuedToken || _clientCredentialType == MessageCredentialType.Windows)
{
return _messageCredentialType;
throw ExceptionHelper.PlatformNotSupported($"MessageSecurityOverTcp.ClientCredentialType is not supported for value {_clientCredentialType}.");
}

return _clientCredentialType;
}
set
{
Expand All @@ -39,20 +41,75 @@ public MessageCredentialType ClientCredentialType
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new ArgumentOutOfRangeException(nameof(value)));
}

if (value != MessageCredentialType.None)
if (value == MessageCredentialType.IssuedToken || value == MessageCredentialType.Windows)
{
throw ExceptionHelper.PlatformNotSupported("MessageSecurityOverTcp.ClientCredentialType is not supported for values other than 'MessageCredentialType.None'.");
}
else
{
_messageCredentialType = value;
throw ExceptionHelper.PlatformNotSupported($"MessageSecurityOverTcp.ClientCredentialType is not supported for value {value}.");
}

_clientCredentialType = value;
}
}

internal bool InternalShouldSerialize()
[DefaultValue(typeof(SecurityAlgorithmSuite), nameof(SecurityAlgorithmSuite.Default))]
public SecurityAlgorithmSuite AlgorithmSuite
{
return ClientCredentialType != NetTcpDefaults.MessageSecurityClientCredentialType;
get { return _algorithmSuite; }
set
{
_algorithmSuite = value ?? throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(value));
}
}

[MethodImpl(MethodImplOptions.NoInlining)]
internal SecurityBindingElement CreateSecurityBindingElement(bool isSecureTransportMode, bool isReliableSession, BindingElement transportBindingElement)
{
SecurityBindingElement result;
SecurityBindingElement oneShotSecurity;
if (isSecureTransportMode)
{
switch (_clientCredentialType)
{
case MessageCredentialType.None:
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.ClientCredentialTypeMustBeSpecifiedForMixedMode));
case MessageCredentialType.UserName:
oneShotSecurity = SecurityBindingElement.CreateUserNameOverTransportBindingElement();
break;
case MessageCredentialType.Certificate:
oneShotSecurity = SecurityBindingElement.CreateCertificateOverTransportBindingElement();
break;
case MessageCredentialType.Windows:
throw ExceptionHelper.PlatformNotSupported($"{nameof(MessageCredentialType)}.{nameof(MessageCredentialType.Windows)}");
case MessageCredentialType.IssuedToken:
throw ExceptionHelper.PlatformNotSupported($"{nameof(MessageCredentialType)}.{nameof(MessageCredentialType.IssuedToken)}");
default:
Fx.Assert("unknown ClientCredentialType");
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException());
}
result = SecurityBindingElement.CreateSecureConversationBindingElement(oneShotSecurity);
}
else
{
throw ExceptionHelper.PlatformNotSupported();
}

// set the algorithm suite and issued token params if required
result.DefaultAlgorithmSuite = oneShotSecurity.DefaultAlgorithmSuite = this.AlgorithmSuite;

result.IncludeTimestamp = true;
if (!isReliableSession)
{
result.LocalClientSettings.ReconnectTransportOnFailure = false;
}
else
{
throw ExceptionHelper.PlatformNotSupported();
}

// since a session is always bootstrapped, configure the transition sct to live for a short time only
result.MessageSecurityVersion = MessageSecurityVersion.WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11;
oneShotSecurity.MessageSecurityVersion = MessageSecurityVersion.WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11;

return result;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ public override SecurityPolicyVersion SecurityPolicyVersion

public override string ToString()
{
return "WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11";
return nameof(WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11);
}
}

Expand All @@ -158,7 +158,7 @@ public override SecurityPolicyVersion SecurityPolicyVersion

public override string ToString()
{
return "WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10";
return nameof(WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10);
}
}

Expand All @@ -183,7 +183,7 @@ internal override MessageSecurityTokenVersion MessageSecurityTokenVersion

public override string ToString()
{
return "WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10";
return nameof(WSSecurity11WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10);
}
}

Expand All @@ -208,7 +208,7 @@ internal override MessageSecurityTokenVersion MessageSecurityTokenVersion

public override string ToString()
{
return "WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10";
return nameof(WSSecurity10WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10);
}
}

Expand All @@ -233,7 +233,7 @@ internal override MessageSecurityTokenVersion MessageSecurityTokenVersion

public override string ToString()
{
return "WSSecurity11WSTrust13WSSecureConversation13WSSecurityPolicy12";
return nameof(WSSecurity11WSTrust13WSSecureConversation13WSSecurityPolicy12);
}
}

Expand All @@ -258,7 +258,7 @@ internal override MessageSecurityTokenVersion MessageSecurityTokenVersion

public override string ToString()
{
return "WSSecurity11WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10";
return nameof(WSSecurity11WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.


using System.ComponentModel;
using System.ServiceModel.Channels;
using System.Xml;
Expand All @@ -23,24 +22,15 @@ public NetTcpBinding(SecurityMode securityMode)
_security.Mode = securityMode;
}


public NetTcpBinding(string configurationName)
: this()
{
if (!String.IsNullOrEmpty(configurationName))
if (!string.IsNullOrEmpty(configurationName))
{
throw ExceptionHelper.PlatformNotSupported();
}
}

private NetTcpBinding(TcpTransportBindingElement transport,
BinaryMessageEncodingBindingElement encoding,
NetTcpSecurity security)
: this()
{
_security = security;
}

[DefaultValue(ConnectionOrientedTransportDefaults.TransferMode)]
public TransferMode TransferMode
{
Expand Down Expand Up @@ -148,7 +138,7 @@ public override BindingElementCollection CreateBindingElements()
{
bindingElements.Add(transportSecurity);
}

_transport.ExtendedProtectionPolicy = _security.Transport.ExtendedProtectionPolicy;
// add transport (tcp)
bindingElements.Add(_transport);

Expand All @@ -160,21 +150,15 @@ private BindingElement CreateTransportSecurity()
return _security.CreateTransportSecurity();
}

private static UnifiedSecurityMode GetModeFromTransportSecurity(BindingElement transport)
{
return NetTcpSecurity.GetModeFromTransportSecurity(transport);
}

private static bool SetTransportSecurity(BindingElement transport, SecurityMode mode, TcpTransportSecurity transportSecurity)
{
return NetTcpSecurity.SetTransportSecurity(transport, mode, transportSecurity);
}

private SecurityBindingElement CreateMessageSecurity()
{
if (_security.Mode == SecurityMode.Message || _security.Mode == SecurityMode.TransportWithMessageCredential)
if (_security.Mode == SecurityMode.Message)
{
throw ExceptionHelper.PlatformNotSupported(nameof(SecurityMode.Message));
}
if (_security.Mode == SecurityMode.TransportWithMessageCredential)
{
throw ExceptionHelper.PlatformNotSupported("NetTcpBinding.CreateMessageSecurity is not supported.");
return _security.CreateMessageSecurity(false);
}
else
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ public sealed class NetTcpSecurity
internal const SecurityMode DefaultMode = SecurityMode.Transport;

private SecurityMode _mode;
private MessageSecurityOverTcp _messageSecurity;

public NetTcpSecurity()
: this(DefaultMode, new TcpTransportSecurity(), new MessageSecurityOverTcp())
Expand All @@ -31,8 +30,8 @@ private NetTcpSecurity(SecurityMode mode, TcpTransportSecurity transportSecurity
SecurityMode.Transport.ToString()));

_mode = mode;
Transport = transportSecurity == null ? new TcpTransportSecurity() : transportSecurity;
_messageSecurity = messageSecurity == null ? new MessageSecurityOverTcp() : messageSecurity;
Transport = transportSecurity ?? new TcpTransportSecurity();
Message = messageSecurity ?? new MessageSecurityOverTcp();
}

[DefaultValue(DefaultMode)]
Expand All @@ -51,12 +50,7 @@ public SecurityMode Mode

public TcpTransportSecurity Transport { get; set; }

public MessageSecurityOverTcp Message
{
get { return _messageSecurity; }
set { _messageSecurity = value; }
}

public MessageSecurityOverTcp Message { get; set; }

internal BindingElement CreateTransportSecurity()
{
Expand All @@ -74,29 +68,20 @@ internal BindingElement CreateTransportSecurity()
}
}

internal static UnifiedSecurityMode GetModeFromTransportSecurity(BindingElement transport)
internal SecurityBindingElement CreateMessageSecurity(bool isReliableSessionEnabled)
{
if (transport == null)
if (_mode == SecurityMode.Message)
{
return UnifiedSecurityMode.None | UnifiedSecurityMode.Message;
throw ExceptionHelper.PlatformNotSupported();
}
else
else if (_mode == SecurityMode.TransportWithMessageCredential)
{
return UnifiedSecurityMode.TransportWithMessageCredential | UnifiedSecurityMode.Transport;
return Message.CreateSecurityBindingElement(true, isReliableSessionEnabled, CreateTransportSecurity());
}
}

internal static bool SetTransportSecurity(BindingElement transport, SecurityMode mode, TcpTransportSecurity transportSecurity)
{
if (mode == SecurityMode.TransportWithMessageCredential)
{
return TcpTransportSecurity.SetTransportProtectionOnly(transport, transportSecurity);
}
else if (mode == SecurityMode.Transport)
else
{
return TcpTransportSecurity.SetTransportProtectionAndAuthentication(transport, transportSecurity);
return null;
}
return transport == null;
}
}
}
Expand Down
Loading

0 comments on commit 23dd138

Please sign in to comment.