Imported Upstream version 4.0.0~alpha1

Former-commit-id: 806294f5ded97629b74c85c09952f2a74fe182d9
This commit is contained in:
Jo Shields
2015-04-07 09:35:12 +01:00
parent 283343f570
commit 3c1f479b9d
22469 changed files with 2931443 additions and 869343 deletions

View File

@@ -0,0 +1,77 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
using System.Web;
using System.Runtime.Diagnostics;
using System.Security.Claims;
using System.Xml;
using DiagnosticStrings = System.ServiceModel.Diagnostics.DiagnosticStrings;
namespace System.IdentityModel.Diagnostics
{
/// <summary>
/// This trace is used to when ClaimsAuthorizationModule.Authorize() is called.
/// Traces:
/// URL
/// Action
/// ClaimPrincipal that is being authorized
/// Helps users diagnose authorization issues. In Authorize() this trace is written at the start of the method,
/// so it will appear when Authorize() fails.
/// </summary>
internal class AuthorizeTraceRecord : TraceRecord
{
const string _elementName = "AuthorizeTraceRecord";
const string _eventId = TraceRecord.EventIdBase + _elementName;
ClaimsPrincipal _claimsPrincipal;
string _url;
string _action;
public AuthorizeTraceRecord( ClaimsPrincipal claimsPrincipal, string url, string action )
{
_claimsPrincipal = claimsPrincipal;
_url = url;
_action = action;
}
internal override string EventId
{
get { return AuthorizeTraceRecord._eventId; }
}
internal override void WriteTo( XmlWriter writer )
{
writer.WriteStartElement( _elementName );
writer.WriteAttributeString( DiagnosticStrings.NamespaceTag, EventId );
writer.WriteStartElement( "Authorize" );
writer.WriteElementString( "Url", _url );
writer.WriteElementString( "Action", _action );
writer.WriteStartElement( "ClaimsPrincipal");
writer.WriteAttributeString( "Identity.Name", _claimsPrincipal.Identity.Name );
foreach ( ClaimsIdentity ci in _claimsPrincipal.Identities )
{
writer.WriteStartElement( "ClaimsIdentity" );
writer.WriteAttributeString( "name", ci.Name );
foreach ( Claim c in ci.Claims )
{
writer.WriteStartElement( "Claim" );
writer.WriteAttributeString( "Value", c.Value );
writer.WriteAttributeString( "Type", c.Type );
writer.WriteAttributeString( "ValueType", c.ValueType );
writer.WriteEndElement();
}
writer.WriteEndElement();
}
writer.WriteEndElement();
writer.WriteEndElement();
writer.WriteEndElement();
}
}
}

View File

@@ -0,0 +1,85 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace System.IdentityModel.Diagnostics
{
using System.Runtime.Diagnostics;
using System.Security.Claims;
using System.ServiceModel.Diagnostics;
using System.Xml;
/// <summary>
/// This trace is used to trace a claims principal
/// Traces:
/// Name
/// For each Identity:
/// Name
/// NameClaimType
/// RoleClaimType
/// Label
/// Actor (if present)
/// Details about each claim
/// </summary>
internal class ClaimsPrincipalTraceRecord : TraceRecord
{
internal const string ElementName = "ClaimsPrincipalTraceRecord";
internal const string _eventId = TraceRecord.EventIdBase + ElementName;
ClaimsPrincipal _claimsPrincipal;
public ClaimsPrincipalTraceRecord( ClaimsPrincipal claimsPrincipal )
{
_claimsPrincipal = claimsPrincipal;
}
internal override string EventId
{
get { return ClaimsPrincipalTraceRecord._eventId; }
}
internal override void WriteTo( XmlWriter writer )
{
writer.WriteStartElement( ElementName );
writer.WriteAttributeString( DiagnosticStrings.NamespaceTag, EventId );
writer.WriteStartElement( "ClaimsPrincipal");
writer.WriteAttributeString( "Identity.Name", _claimsPrincipal.Identity.Name );
foreach ( ClaimsIdentity ci in _claimsPrincipal.Identities )
{
WriteClaimsIdentity( ci, writer );
}
writer.WriteEndElement();
writer.WriteEndElement();
}
private void WriteClaimsIdentity( ClaimsIdentity ci, XmlWriter writer )
{
writer.WriteStartElement( "ClaimsIdentity" );
writer.WriteAttributeString( "Name", ci.Name );
writer.WriteAttributeString( "NameClaimType", ci.NameClaimType );
writer.WriteAttributeString( "RoleClaimType", ci.RoleClaimType );
writer.WriteAttributeString( "Label", ci.Label );
if ( ci.Actor != null )
{
writer.WriteStartElement( "Actor" );
WriteClaimsIdentity( ci.Actor, writer );
writer.WriteEndElement();
}
foreach ( Claim c in ci.Claims )
{
writer.WriteStartElement( "Claim" );
writer.WriteAttributeString( "Value", c.Value );
writer.WriteAttributeString( "Type", c.Type );
writer.WriteAttributeString( "ValueType", c.ValueType );
writer.WriteEndElement();
}
writer.WriteEndElement();
}
}
}

View File

@@ -0,0 +1,50 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace System.IdentityModel.Diagnostics
{
using System.Globalization;
using System.Runtime.Diagnostics;
using System.ServiceModel.Diagnostics;
using System.Xml;
/// <summary>
/// This trace is used to when DeflateCookieTransform.Encode() is called.
/// Traces:
/// original size
/// deflated size
/// Helps users to determine if the compression algorithim is of value.
/// </summary>
internal class DeflateCookieTraceRecord : TraceRecord
{
const string ElementName = "DeflateCookieTraceRecord";
const string _eventId = TraceRecord.EventIdBase + ElementName;
int _originalSize;
int _deflatedSize;
public DeflateCookieTraceRecord( int originalSize, int deflatedSize )
{
_originalSize = originalSize;
_deflatedSize = deflatedSize;
}
internal override string EventId
{
get { return _eventId; }
}
internal override void WriteTo( XmlWriter writer )
{
writer.WriteStartElement( ElementName );
writer.WriteAttributeString( DiagnosticStrings.NamespaceTag, EventId );
writer.WriteElementString( DiagnosticStrings.DeflateCookieOriginalSizeTag, _originalSize.ToString( CultureInfo.InvariantCulture ) );
writer.WriteElementString( DiagnosticStrings.DeflateCookieAfterDeflatingTag, _deflatedSize.ToString( CultureInfo.InvariantCulture ) );
writer.WriteEndElement();
}
}
}

View File

@@ -0,0 +1,146 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace System.IdentityModel.Diagnostics
{
using System;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Runtime.Diagnostics;
using System.Security.Cryptography;
using System.ServiceModel.Diagnostics;
using System.Xml;
class DigestTraceRecord : TraceRecord
{
MemoryStream _logStream;
HashAlgorithm _hash;
string _traceName;
const string Empty = "Empty";
const string CanonicalElementString = "CanonicalElementString";
const string CanonicalElementStringLength = "CanonicalElementStringLength";
const string CanonicalOctets = "CanonicalOctets";
const string CanonicalOctetsLength = "CanonicalOctetsLength";
const string CanonicalOctetsHash = "CanonicalOctetsHash";
const string CanonicalOctetsHashLength = "CanonicalOctetsHashLength";
const string Key = "Key";
const string Length = "Length";
const string FirstByte = "FirstByte";
const string LastByte = "LastByte";
internal DigestTraceRecord(string traceName, MemoryStream logStream, HashAlgorithm hash)
{
if (string.IsNullOrEmpty(traceName))
_traceName = Empty;
else
_traceName = traceName;
_logStream = logStream;
_hash = hash;
}
internal override string EventId
{
get
{
return TraceRecord.EventIdBase + _traceName + TraceRecord.NamespaceSuffix;
}
}
internal override void WriteTo(XmlWriter writer)
{
base.WriteTo(writer);
//
// canonical element string
//
byte[] contentBuffer = _logStream.GetBuffer();
string contentAsString = System.Text.Encoding.UTF8.GetString(contentBuffer, 0, (int)_logStream.Length);
writer.WriteElementString(CanonicalElementStringLength, contentAsString.Length.ToString(CultureInfo.InvariantCulture));
writer.WriteComment(CanonicalElementString + ":" + contentAsString);
//
// canonical element base64 format
//
writer.WriteElementString(CanonicalOctetsLength, contentBuffer.Length.ToString(CultureInfo.InvariantCulture));
writer.WriteElementString(CanonicalOctets, Convert.ToBase64String(contentBuffer));
//
// Hash
//
writer.WriteElementString(CanonicalOctetsHashLength, _hash.Hash.Length.ToString(CultureInfo.InvariantCulture));
writer.WriteElementString(CanonicalOctetsHash, Convert.ToBase64String(_hash.Hash));
//
// Key: this will only be printed out for the symmetric key case
//
if (_hash is KeyedHashAlgorithm)
{
KeyedHashAlgorithm keyedHash = _hash as KeyedHashAlgorithm;
byte[] key = keyedHash.Key;
writer.WriteStartElement(Key); // start the key element
writer.WriteElementString(Length, key.Length.ToString(CultureInfo.InvariantCulture)); // key length
writer.WriteElementString(FirstByte, key[0].ToString(CultureInfo.InvariantCulture)); // first byte of the key
writer.WriteElementString(LastByte, key[key.Length - 1].ToString(CultureInfo.InvariantCulture)); // last byte of the key
writer.WriteEndElement(); // close the key element
}
}
}
internal static class DigestTraceRecordHelper
{
const string DigestTrace = "DigestTrace";
static bool _shouldTraceDigest = false;
static bool _initialized = false;
internal static bool ShouldTraceDigest
{
get
{
if (!_initialized)
InitializeShouldTraceDigest();
return _shouldTraceDigest;
}
}
static void InitializeShouldTraceDigest()
{
//
// Log the digest only if
// 1.Users ask for verbose AND
// 2.Users are fine with logging Pii ( private identity information )
//
if (DiagnosticUtility.DiagnosticTrace != null &&
DiagnosticUtility.DiagnosticTrace.TraceSource != null &&
DiagnosticUtility.DiagnosticTrace.ShouldLogPii &&
DiagnosticUtility.ShouldTraceVerbose)
{
_shouldTraceDigest = true;
}
_initialized = true;
}
internal static void TraceDigest(MemoryStream logStream, HashAlgorithm hash)
{
if (DigestTraceRecordHelper.ShouldTraceDigest)
{
TraceUtility.TraceEvent(TraceEventType.Verbose, TraceCode.IdentityModel, SR.GetString(SR.TraceCodeIdentityModel), new DigestTraceRecord(DigestTrace, logStream, hash), null, null);
}
}
}
}

View File

@@ -0,0 +1,239 @@

namespace System.IdentityModel.Diagnostics
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IdentityModel.Diagnostics;
using System.Diagnostics;
using System.Runtime.Diagnostics;
using System.Security.Authentication.ExtendedProtection;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.ServiceModel.Diagnostics;
using System.Xml;
using System.IdentityModel.Tokens;
using System.Security.Cryptography;
class SecurityTraceRecord : TraceRecord
{
String traceName;
internal SecurityTraceRecord(String traceName)
{
if (string.IsNullOrEmpty(traceName))
this.traceName = "Empty";
else
this.traceName = traceName;
}
internal override string EventId { get { return BuildEventId(traceName); } }
}
internal static class SecurityTraceRecordHelper
{
internal static void TraceServiceNameBindingOnServer(string serviceBindingNameSentByClient, string defaultServiceBindingNameOfServer, ServiceNameCollection serviceNameCollectionConfiguredOnServer)
{
TraceUtility.TraceEvent(TraceEventType.Information, TraceCode.ServiceBindingCheck, SR.GetString(SR.TraceCodeServiceBindingCheck), new ServiceBindingNameTraceRecord(serviceBindingNameSentByClient, defaultServiceBindingNameOfServer, serviceNameCollectionConfiguredOnServer), null, null);
}
internal static void TraceChannelBindingInformation(ExtendedProtectionPolicyHelper policyHelper, bool isServer, ChannelBinding channelBinding)
{
TraceUtility.TraceEvent(TraceEventType.Information, TraceCode.ChannelBindingCheck, SR.GetString(SR.TraceCodeChannelBindingCheck), new ChannelBindingNameTraceRecord(policyHelper, isServer, channelBinding), null, null);
}
class ServiceBindingNameTraceRecord : SecurityTraceRecord
{
string serviceBindingNameSentByClient;
string defaultServiceBindingNameOfServer;
ServiceNameCollection serviceNameCollectionConfiguredOnServer;
public ServiceBindingNameTraceRecord(string serviceBindingNameSentByClient, string defaultServiceBindingNameOfServer, ServiceNameCollection serviceNameCollectionConfiguredOnServer)
: base("ServiceBindingCheckAfterSpNego")
{
this.serviceBindingNameSentByClient = serviceBindingNameSentByClient;
this.defaultServiceBindingNameOfServer = defaultServiceBindingNameOfServer;
this.serviceNameCollectionConfiguredOnServer = serviceNameCollectionConfiguredOnServer;
}
internal override void WriteTo(XmlWriter xml)
{
if (xml == null)
return;
xml.WriteComment(SR.GetString(SR.ServiceNameFromClient));
xml.WriteElementString("ServiceName", this.serviceBindingNameSentByClient);
xml.WriteComment(SR.GetString(SR.ServiceNameOnService));
xml.WriteStartElement("ServiceNameCollection");
if (this.serviceNameCollectionConfiguredOnServer == null || this.serviceNameCollectionConfiguredOnServer.Count < 1)
{
xml.WriteElementString("ServiceName", this.defaultServiceBindingNameOfServer);
}
else
{
foreach (string serviceName in this.serviceNameCollectionConfiguredOnServer)
{
xml.WriteElementString("ServiceName", serviceName);
}
}
xml.WriteFullEndElement();
}
}
class ChannelBindingNameTraceRecord : SecurityTraceRecord
{
ExtendedProtectionPolicyHelper policyHelper;
bool isServer;
bool channelBindingUsed;
ChannelBinding channelBinding;
public ChannelBindingNameTraceRecord(ExtendedProtectionPolicyHelper policyHelper, bool isServer, ChannelBinding channelBinding)
: base("SpNegoChannelBindingInformation")
{
this.policyHelper = policyHelper;
this.isServer = isServer;
this.channelBindingUsed = false;
this.channelBinding = channelBinding;
}
internal override void WriteTo(XmlWriter xml)
{
if (xml == null)
return;
if (this.policyHelper != null)
{
xml.WriteElementString("PolicyEnforcement", this.policyHelper.PolicyEnforcement.ToString());
xml.WriteElementString("ProtectionScenario", this.policyHelper.ProtectionScenario.ToString());
xml.WriteStartElement("ServiceNameCollection");
if (this.policyHelper.ServiceNameCollection != null && this.policyHelper.ServiceNameCollection.Count > 0)
{
foreach (string serviceName in this.policyHelper.ServiceNameCollection)
{
xml.WriteElementString("ServiceName", serviceName);
}
}
xml.WriteFullEndElement();
if (this.isServer)
{
this.channelBindingUsed = this.policyHelper.ShouldAddChannelBindingToASC();
}
else
{
this.channelBindingUsed = this.policyHelper.ChannelBinding != null;
}
xml.WriteElementString("ChannelBindingUsed", this.channelBindingUsed.ToString());
if (this.channelBinding != null && this.policyHelper.PolicyEnforcement != PolicyEnforcement.Never && this.channelBindingUsed == true)
{
ExtendedProtectionPolicy extendedProtection = new ExtendedProtectionPolicy(policyHelper.PolicyEnforcement, channelBinding);
xml.WriteElementString("ChannelBindingData", GetBase64EncodedChannelBindingData(extendedProtection));
}
}
else
{
// This is the case for KerberosRequestorSecurityToken where policyHelper is null.
if (this.channelBinding != null)
{
xml.WriteElementString("ChannelBindingUsed", "true");
// We do not know the PolicyEnforcement value here on the client side and we can not pass Never
//as ExtendedProtectionPolicy constructor would throw on PolicyEnforcement.Never
ExtendedProtectionPolicy extendedProtection = new ExtendedProtectionPolicy(PolicyEnforcement.WhenSupported, channelBinding);
xml.WriteElementString("ChannelBindingData", GetBase64EncodedChannelBindingData(extendedProtection));
}
else
{
xml.WriteElementString("ChannelBindingUsed", "false");
xml.WriteElementString("ChannelBindingData", null);
}
}
}
internal string GetBase64EncodedChannelBindingData(ExtendedProtectionPolicy extendedProtectionPolicy)
{
MemoryStream ms = new MemoryStream();
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(ms, extendedProtectionPolicy);
byte[] channelBindingData = ms.GetBuffer();
return Convert.ToBase64String(channelBindingData, Base64FormattingOptions.None);
}
}
/// <summary>
/// Used to serialize a token to the trace. Used in multiple places.
/// </summary>
internal class TokenTraceRecord : SecurityTraceRecord
{
const string ElementName = "TokenTraceRecord";
SecurityToken _securityToken;
public TokenTraceRecord(SecurityToken securityToken)
: base(ElementName)
{
_securityToken = securityToken;
}
void WriteSessionToken(XmlWriter writer, SessionSecurityToken sessionToken)
{
SessionSecurityTokenHandler ssth = GetOrCreateSessionSecurityTokenHandler();
XmlDictionaryWriter dictionaryWriter = XmlDictionaryWriter.CreateDictionaryWriter(writer);
ssth.WriteToken(dictionaryWriter, sessionToken);
}
private static SessionSecurityTokenHandler GetOrCreateSessionSecurityTokenHandler()
{
SecurityTokenHandlerCollection defaultHandlers = SecurityTokenHandlerCollection.CreateDefaultSecurityTokenHandlerCollection();
SessionSecurityTokenHandler ssth = defaultHandlers[typeof(SessionSecurityToken)] as SessionSecurityTokenHandler;
if (ssth == null)
{
ssth = new SessionSecurityTokenHandler();
defaultHandlers.AddOrReplace(ssth);
}
return ssth;
}
internal override void WriteTo(XmlWriter writer)
{
writer.WriteStartElement(ElementName);
writer.WriteAttributeString(DiagnosticStrings.NamespaceTag, EventId);
writer.WriteStartElement("SecurityToken");
writer.WriteAttributeString("Type", _securityToken.GetType().ToString());
if (_securityToken is SessionSecurityToken)
{
WriteSessionToken(writer, _securityToken as SessionSecurityToken);
}
else
{
SecurityTokenHandlerCollection sthc = SecurityTokenHandlerCollection.CreateDefaultSecurityTokenHandlerCollection();
if (sthc.CanWriteToken(_securityToken))
{
{
sthc.WriteToken(writer, _securityToken);
}
}
else
{
writer.WriteElementString("Warning", SR.GetString(SR.TraceUnableToWriteToken, _securityToken.GetType().ToString()));
}
}
writer.WriteEndElement();
}
}
}
}

View File

@@ -0,0 +1,73 @@
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace System.IdentityModel.Diagnostics
{
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Runtime;
using System.Runtime.CompilerServices;
using System.Runtime.Diagnostics;
static class TraceCode
{
// IdentityModel TraceCodes
public const int IdentityModel = 0xC0000;
public const int AuthorizationContextCreated = TraceCode.IdentityModel | 0X0002;
public const int AuthorizationPolicyEvaluated = TraceCode.IdentityModel | 0X0003;
public const int ServiceBindingCheck = TraceCode.IdentityModel | 0X0004;
public const int ChannelBindingCheck = TraceCode.IdentityModel | 0x0005;
public const int Diagnostics = TraceCode.IdentityModel | 0x0006;
}
static class TraceUtility
{
static Dictionary<int, string> traceCodes = new Dictionary<int, string>( 5 )
{
{ TraceCode.IdentityModel, "IdentityModel" },
{ TraceCode.AuthorizationContextCreated, "AuthorizationContextCreated" },
{ TraceCode.AuthorizationPolicyEvaluated, "AuthorizationPolicyEvaluated" },
{ TraceCode.ServiceBindingCheck, "ServiceBindingCheck" },
{ TraceCode.ChannelBindingCheck, "ChannelBindingCheck" },
{ TraceCode.Diagnostics, "Diagnostics" }
};
internal static void TraceEvent( TraceEventType severity, int traceCode, string traceDescription )
{
TraceEvent( severity, traceCode, traceDescription, null, null, null );
}
// These methods require a TraceRecord to be allocated, so we want them to show up on profiles if the caller didn't avoid
// allocating the TraceRecord by using ShouldTrace.
[MethodImpl( MethodImplOptions.NoInlining )]
internal static void TraceEvent( TraceEventType severity, int traceCode, string traceDescription, TraceRecord extendedData, object source, Exception exception )
{
if ( DiagnosticUtility.ShouldTrace( severity ) )
{
Guid activityId = DiagnosticTraceBase.ActivityId;
Fx.Assert( traceCodes.ContainsKey( traceCode ),
string.Format( CultureInfo.InvariantCulture, "Unsupported trace code: Please add trace code 0x{0} to the dictionary TraceUtility.traceCodes in {1}",
traceCode.ToString( "X", CultureInfo.InvariantCulture ), typeof( TraceUtility ) ) );
string msdnTraceCode = System.ServiceModel.Diagnostics.LegacyDiagnosticTrace.GenerateMsdnTraceCode( "System.IdentityModel", traceCodes[traceCode]);
DiagnosticUtility.DiagnosticTrace.TraceEvent( severity, traceCode, msdnTraceCode, traceDescription, extendedData, exception, activityId, source );
}
}
internal static void TraceString( TraceEventType eventType, string formatString, params object[] args )
{
if ( DiagnosticUtility.ShouldTrace( eventType ) )
{
if ( null != args && args.Length > 0 )
{
TraceEvent( eventType, TraceCode.IdentityModel, String.Format( CultureInfo.InvariantCulture, formatString, args ) );
}
else
{
TraceEvent( eventType, TraceCode.IdentityModel, formatString );
}
}
}
}
}