MessageSecurityBindingSupport.cs :  » 2.6.4-mono-.net-core » System.ServiceModel » System » ServiceModel » Channels » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » 2.6.4 mono .net core » System.ServiceModel 
System.ServiceModel » System » ServiceModel » Channels » MessageSecurityBindingSupport.cs
//
// MessageSecurityBindingSupport.cs
//
// Author:
//  Atsushi Enomoto <atsushi@ximian.com>
//
// Copyright (C) 2005-2007 Novell, Inc.  http://www.novell.com
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
// 
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IdentityModel.Selectors;
using System.IdentityModel.Tokens;
using System.Net.Security;
using System.Security.Cryptography.Xml;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Security;
using System.ServiceModel.Security.Tokens;

using ReqTypeSystem.ServiceModel.Security.Tokens.ServiceModelSecurityTokenRequirement;

namespace System.ServiceModel.Channels{
  internal class SupportingTokenInfo
  {
    public SupportingTokenInfo (SecurityToken token,
      SecurityTokenAttachmentMode mode,
      bool isOptional)
    {
      Token = token;
      Mode = mode;
      IsOptional = isOptional;
    }

    public SecurityToken Token;
    public SecurityTokenAttachmentMode Mode;
    public bool IsOptional;
    public EncryptedData Encrypted;
  }

  internal class SupportingTokenInfoCollection : Collection<SupportingTokenInfo>
  {
    protected override void InsertItem (int index, SupportingTokenInfo item)
    {
      foreach (SupportingTokenInfo i in this)
        if (i.Token.GetType () == item.Token.GetType ())
          throw new ArgumentException (String.Format ("Supporting tokens do not allow multiple SecurityTokens of the same type: {0}", i.Token.GetType ()));
      base.InsertItem (index, item);
    }
  }

  internal abstract class MessageSecurityBindingSupport
  {
    SecurityTokenManager manager;
    ChannelProtectionRequirements requirements;
    SecurityTokenSerializer serializer;
    SecurityCapabilities element_support;

    // only filled at prepared state.
    SecurityTokenAuthenticator authenticator;
    SecurityTokenResolver auth_token_resolver;

    protected MessageSecurityBindingSupport (
      SecurityCapabilities elementSupport,
      SecurityTokenManager manager,
      ChannelProtectionRequirements requirements)
    {
      element_support = elementSupport;
      Initialize (manager, requirements);
    }

    public void Initialize (SecurityTokenManager manager,
      ChannelProtectionRequirements requirements)
    {
      this.manager = manager;
      if (requirements == null)
        requirements = new ChannelProtectionRequirements ();
      this.requirements = requirements;
    }

    public abstract IDefaultCommunicationTimeouts Timeouts { get; }

    public ChannelProtectionRequirements ChannelRequirements {
      get { return requirements; }
    }

    public SecurityTokenManager SecurityTokenManager {
      get { return manager; }
    }

    public SecurityTokenSerializer TokenSerializer {
      get {
        if (serializer == null)
          serializer = manager.CreateSecurityTokenSerializer (Element.MessageSecurityVersion.SecurityTokenVersion);
        return serializer;
      }
    }

    public SecurityTokenAuthenticator TokenAuthenticator {
      get { return authenticator; }
    }

    public SecurityTokenResolver OutOfBandTokenResolver {
      get { return auth_token_resolver; }
    }

    public abstract SecurityToken EncryptionToken { get; }

    public abstract SecurityToken SigningToken { get; }

    #region element_support

    public SecurityBindingElement Element {
      get { return element_support.Element; }
    }

    public bool AllowSerializedSigningTokenOnReply {
      get { return element_support.AllowSerializedSigningTokenOnReply; }
    }

    public MessageProtectionOrder MessageProtectionOrder { 
      get { return element_support.MessageProtectionOrder; }
    }

    public SecurityTokenParameters InitiatorParameters { 
      get { return element_support.InitiatorParameters; }
    }

    public SecurityTokenParameters RecipientParameters { 
      get { return element_support.RecipientParameters; }
    }

    public bool RequireSignatureConfirmation {
      get { return element_support.RequireSignatureConfirmation; }
    }

    public string DefaultSignatureAlgorithm {
      get { return element_support.DefaultSignatureAlgorithm; }
    }

    public string DefaultKeyWrapAlgorithm {
      get { return element_support.DefaultKeyWrapAlgorithm; }
    }

    #endregion

    public SecurityTokenProvider CreateTokenProvider (SecurityTokenRequirement requirement)
    {
      return manager.CreateSecurityTokenProvider (requirement);
    }

    public abstract SecurityTokenAuthenticator CreateTokenAuthenticator (SecurityTokenParameters p, out SecurityTokenResolver resolver);

    protected void PrepareAuthenticator ()
    {
      authenticator = CreateTokenAuthenticator (RecipientParameters, out auth_token_resolver);
    }

    protected void InitializeRequirement (SecurityTokenParameters p, SecurityTokenRequirement r)
    {
      p.CallInitializeSecurityTokenRequirement (r);

      // r.Properties [ChannelParametersCollectionProperty] =
      // r.Properties [ReqType.EndpointFilterTableProperty] =
      // r.Properties [ReqType.HttpAuthenticationSchemeProperty] =
      // r.Properties [ReqType.IsOutOfBandTokenProperty] =
      // r.Properties [ReqType.IssuerAddressProperty] =
      // r.Properties [ReqType.MessageDirectionProperty] = 
      r.Properties [ReqType.MessageSecurityVersionProperty] = Element.MessageSecurityVersion.SecurityTokenVersion;
      r.Properties [ReqType.SecurityAlgorithmSuiteProperty] = Element.DefaultAlgorithmSuite;
      r.Properties [ReqType.SecurityBindingElementProperty] = Element;
      // r.Properties [ReqType.SupportingTokenAttachmentModeProperty] =
      // r.TransportScheme =
    }

    public void Release ()
    {
      ReleaseCore ();

      authenticator = null;
    }

    protected abstract void ReleaseCore ();

    public SupportingTokenInfoCollection CollectSupportingTokens (string action)
    {
      SupportingTokenInfoCollection tokens =
        new SupportingTokenInfoCollection ();

      SupportingTokenParameters supp;

      CollectSupportingTokensCore (tokens, Element.EndpointSupportingTokenParameters, true);
      if (Element.OperationSupportingTokenParameters.TryGetValue (action, out supp))
        CollectSupportingTokensCore (tokens, supp, true);
      CollectSupportingTokensCore (tokens, Element.OptionalEndpointSupportingTokenParameters, false);
      if (Element.OptionalOperationSupportingTokenParameters.TryGetValue (action, out supp))
        CollectSupportingTokensCore (tokens, supp, false);

      return tokens;
    }

    void CollectSupportingTokensCore (
      SupportingTokenInfoCollection l,
      SupportingTokenParameters s,
      bool required)
    {
      foreach (SecurityTokenParameters p in s.Signed)
        l.Add (new SupportingTokenInfo (GetSigningToken (p), SecurityTokenAttachmentMode.Signed, required));
      foreach (SecurityTokenParameters p in s.Endorsing)
        l.Add (new SupportingTokenInfo (GetSigningToken (p), SecurityTokenAttachmentMode.Endorsing, required));
      foreach (SecurityTokenParameters p in s.SignedEndorsing)
        l.Add (new SupportingTokenInfo (GetSigningToken (p), SecurityTokenAttachmentMode.SignedEndorsing, required));
      foreach (SecurityTokenParameters p in s.SignedEncrypted)
        l.Add (new SupportingTokenInfo (GetSigningToken (p), SecurityTokenAttachmentMode.SignedEncrypted, required));
    }

    SecurityToken GetSigningToken (SecurityTokenParameters p)
    {
      return GetToken (CreateRequirement (), p, SecurityKeyUsage.Signature);
    }

    SecurityToken GetExchangeToken (SecurityTokenParameters p)
    {
      return GetToken (CreateRequirement (), p, SecurityKeyUsage.Exchange);
    }

    public SecurityToken GetToken (SecurityTokenRequirement requirement, SecurityTokenParameters targetParams, SecurityKeyUsage usage)
    {
      requirement.KeyUsage = usage;
      requirement.Properties [ReqType.SecurityBindingElementProperty] = Element;
      requirement.Properties [ReqType.MessageSecurityVersionProperty] =
        Element.MessageSecurityVersion.SecurityTokenVersion;

      InitializeRequirement (targetParams, requirement);

      SecurityTokenProvider provider =
        CreateTokenProvider (requirement);
      ICommunicationObject obj = provider as ICommunicationObject;
      try {
        if (obj != null)
          obj.Open (Timeouts.OpenTimeout);
        return provider.GetToken (Timeouts.SendTimeout);
      } finally {
        if (obj != null && obj.State == CommunicationState.Opened)
          obj.Close ();
      }
    }
    
    public abstract SecurityTokenRequirement CreateRequirement ();
  }

  internal class InitiatorMessageSecurityBindingSupport : MessageSecurityBindingSupport
  {
    ChannelFactoryBase factory;
    EndpointAddress message_to;
    SecurityToken encryption_token;
    SecurityToken signing_token;

    public InitiatorMessageSecurityBindingSupport (
      SecurityCapabilities elementSupport,
      SecurityTokenManager manager,
      ChannelProtectionRequirements requirements)
      : base (elementSupport, manager, requirements)
    {
    }

    public override IDefaultCommunicationTimeouts Timeouts {
      get { return factory; }
    }

    public void Prepare (ChannelFactoryBase factory, EndpointAddress address)
    {
      this.factory = factory;
      this.message_to = address;

      PrepareAuthenticator ();

      // This check is almost extra, though it is needed
      // to check correct signing token existence.
      if (EncryptionToken == null)
        throw new Exception ("INTERNAL ERROR");
    }

    public override SecurityToken EncryptionToken {
      get {
        if (encryption_token == null) {
          SecurityTokenRequirement r = CreateRequirement ();
          r.Properties [ReqType.MessageDirectionProperty] = MessageDirection.Input;
          InitializeRequirement (RecipientParameters, r);
          encryption_token = GetToken (r, RecipientParameters, SecurityKeyUsage.Exchange);
        }
        return encryption_token;
      }
    }

    public override SecurityToken SigningToken {
      get {
        if (signing_token == null) {
          SecurityTokenRequirement r = CreateRequirement ();
          r.Properties [ReqType.MessageDirectionProperty] = MessageDirection.Input;
          InitializeRequirement (InitiatorParameters, r);
          signing_token = GetToken (r, InitiatorParameters, SecurityKeyUsage.Signature);
        }
        return signing_token;
      }
    }

    protected override void ReleaseCore ()
    {
      this.factory = null;
      this.message_to = null;

      IDisposable disposable = signing_token as IDisposable;
      if (disposable != null)
        disposable.Dispose ();
      signing_token = null;

      disposable = encryption_token as IDisposable;
      if (disposable != null)
        disposable.Dispose ();
      encryption_token = null;
    }

    public override SecurityTokenRequirement CreateRequirement ()
    {
      SecurityTokenRequirement r = new InitiatorServiceModelSecurityTokenRequirement ();
//      r.Properties [ReqType.IssuerAddressProperty] = message_to;
      r.Properties [ReqType.TargetAddressProperty] = message_to;
      // FIXME: set Via
      return r;
    }

    public override SecurityTokenAuthenticator CreateTokenAuthenticator (SecurityTokenParameters p, out SecurityTokenResolver resolver)
    {
      resolver = null;
      // This check might be almost extra, though it is
      // needed to check correct signing token existence.
      //
      // Not sure if it is limited to this condition, but
      // Ssl parameters do not support token provider and
      // still do not fail. X509 parameters do fail.
      if (!InitiatorParameters.InternalSupportsClientAuthentication)
        return null;

      SecurityTokenRequirement r = CreateRequirement ();
      r.Properties [ReqType.MessageDirectionProperty] = MessageDirection.Output;
      InitializeRequirement (p, r);
      return SecurityTokenManager.CreateSecurityTokenAuthenticator (r, out resolver);
    }
  }

  class RecipientMessageSecurityBindingSupport : MessageSecurityBindingSupport
  {
    ChannelListenerBase listener;
    SecurityToken encryption_token;
    SecurityToken signing_token;

    public RecipientMessageSecurityBindingSupport (
      SecurityCapabilities elementSupport,
      SecurityTokenManager manager,
      ChannelProtectionRequirements requirements)
      : base (elementSupport, manager, requirements)
    {
    }

    public override IDefaultCommunicationTimeouts Timeouts {
      get { return listener; }
    }

    public void Prepare (ChannelListenerBase listener)
    {
      this.listener = listener;

      PrepareAuthenticator ();

      // This check is almost extra, though it is needed
      // to check correct signing token existence.
      //
      // Not sure if it is limited to this condition, but
      // Ssl parameters do not support token provider and
      // still do not fail. X509 parameters do fail.
      //
      // FIXME: as AsymmetricSecurityBindingElementTest
      // .ServiceRecipientHasNoKeys() implies, it should be
      // the recipient's parameters that is used. However
      // such changes will break some of existing tests...
      if (InitiatorParameters.InternalHasAsymmetricKey &&
          EncryptionToken == null)
        throw new Exception ("INTERNAL ERROR");
    }

    public override SecurityToken EncryptionToken {
      get {
        if (encryption_token == null) {
          SecurityTokenRequirement r = CreateRequirement ();
          r.Properties [ReqType.MessageDirectionProperty] = MessageDirection.Output;
          encryption_token = GetToken (r, InitiatorParameters, SecurityKeyUsage.Exchange);
        }
        return encryption_token;
      }
    }

    public override SecurityToken SigningToken {
      get {
        if (signing_token == null) {
          SecurityTokenRequirement r = CreateRequirement ();
          r.Properties [ReqType.MessageDirectionProperty] = MessageDirection.Input;
          InitializeRequirement (RecipientParameters, r);
          signing_token = GetToken (r, RecipientParameters, SecurityKeyUsage.Signature);
        }
        return signing_token;
      }
    }

    protected override void ReleaseCore ()
    {
      this.listener = null;

      IDisposable disposable = signing_token as IDisposable;
      if (disposable != null)
        disposable.Dispose ();
      signing_token = null;

      disposable = encryption_token as IDisposable;
      if (disposable != null)
        disposable.Dispose ();
      encryption_token = null;
    }

    public override SecurityTokenRequirement CreateRequirement ()
    {
      SecurityTokenRequirement requirement =
        new RecipientServiceModelSecurityTokenRequirement ();
      requirement.Properties [ReqType.ListenUriProperty] = listener.Uri;
      return requirement;
    }

    public override SecurityTokenAuthenticator CreateTokenAuthenticator (SecurityTokenParameters p, out SecurityTokenResolver resolver)
    {
      resolver = null;
      // This check might be almost extra, though it is
      // needed to check correct signing token existence.
      //
      // Not sure if it is limited to this condition, but
      // Ssl parameters do not support token provider and
      // still do not fail. X509 parameters do fail.
      if (!RecipientParameters.InternalSupportsServerAuthentication)
        return null;

      SecurityTokenRequirement r = CreateRequirement ();
      r.Properties [ReqType.MessageDirectionProperty] = MessageDirection.Input;
      InitializeRequirement (p, r);
      return SecurityTokenManager.CreateSecurityTokenAuthenticator (r, out resolver);
    }
  }

  internal abstract class SecurityCapabilities
    : ISecurityCapabilities
  {
    public abstract SecurityBindingElement Element { get; }

    public abstract bool AllowSerializedSigningTokenOnReply { get; }

    public abstract MessageProtectionOrder MessageProtectionOrder { get; }

    public abstract SecurityTokenParameters InitiatorParameters { get; }

    public abstract SecurityTokenParameters RecipientParameters { get; }

    public abstract bool RequireSignatureConfirmation { get; }

    public abstract string DefaultKeyWrapAlgorithm { get; }

    public abstract string DefaultSignatureAlgorithm { get; }


    // ISecurityCapabilities
    // FIXME: implement correctly
    public ProtectionLevel SupportedRequestProtectionLevel {
      get { return ProtectionLevel.EncryptAndSign; }
    }

    public ProtectionLevel SupportedResponseProtectionLevel {
      get { return ProtectionLevel.EncryptAndSign; }
    }

    public bool SupportsClientAuthentication {
      get { return InitiatorParameters != null ? InitiatorParameters.InternalSupportsClientAuthentication : false; }
    }

    public bool SupportsClientWindowsIdentity {
      get { return InitiatorParameters != null ? InitiatorParameters.InternalSupportsClientWindowsIdentity : false; }
    }

    public bool SupportsServerAuthentication {
      get { return RecipientParameters != null ? RecipientParameters.InternalSupportsServerAuthentication : false; }
    }
  }

  internal class SymmetricSecurityCapabilities : SecurityCapabilities
  {
    SymmetricSecurityBindingElement element;

    public SymmetricSecurityCapabilities (
      SymmetricSecurityBindingElement element)
    {
      this.element = element;
    }

    public override SecurityBindingElement Element {
      get { return element; }
    }

    // FIXME: const true or false
    public override bool AllowSerializedSigningTokenOnReply {
      get { throw new NotImplementedException (); }
    }

    public override MessageProtectionOrder MessageProtectionOrder {
      get { return element.MessageProtectionOrder; }
    }

    public override SecurityTokenParameters InitiatorParameters {
      get { return element.ProtectionTokenParameters; }
    }

    public override SecurityTokenParameters RecipientParameters {
      get { return element.ProtectionTokenParameters; }
    }

    public override bool RequireSignatureConfirmation {
      get { return element.RequireSignatureConfirmation; }
    }

    public override string DefaultSignatureAlgorithm {
      get { return element.DefaultAlgorithmSuite.DefaultSymmetricSignatureAlgorithm; }
    }

    public override string DefaultKeyWrapAlgorithm {
      get { return element.DefaultAlgorithmSuite.DefaultSymmetricKeyWrapAlgorithm; }
    }
  }

  internal class AsymmetricSecurityCapabilities : SecurityCapabilities
  {
    AsymmetricSecurityBindingElement element;

    public AsymmetricSecurityCapabilities (
      AsymmetricSecurityBindingElement element)
    {
      this.element = element;
    }

    public override bool AllowSerializedSigningTokenOnReply {
      get { return element.AllowSerializedSigningTokenOnReply; }
    }

    public override SecurityBindingElement Element {
      get { return element; }
    }

    public override MessageProtectionOrder MessageProtectionOrder {
      get { return element.MessageProtectionOrder; }
    }

    public override SecurityTokenParameters InitiatorParameters {
      get { return element.InitiatorTokenParameters; }
    }

    public override SecurityTokenParameters RecipientParameters {
      get { return element.RecipientTokenParameters; }
    }

    public override bool RequireSignatureConfirmation {
      get { return element.RequireSignatureConfirmation; }
    }

    public override string DefaultSignatureAlgorithm {
      get { return element.DefaultAlgorithmSuite.DefaultAsymmetricSignatureAlgorithm; }
    }

    public override string DefaultKeyWrapAlgorithm {
      get { return element.DefaultAlgorithmSuite.DefaultAsymmetricKeyWrapAlgorithm; }
    }
  }
}
www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.