Skip to content

Commit

Permalink
Original commit messages in master were:
Browse files Browse the repository at this point in the history
Fix UpnEndpointIdentity on UWP

Re-enable tests disabled by issue 10, except for NET Native.

PR dotnet#1502 fixed issue dotnet#10 by implementing UpnEndpointIdentity.
But 2 tests were still disabled by issue 10, so this PR just
re-enables those tests.  Both require manual setup to run, so
we will not see them pass or fail in CI or VSO.

These tests still fail in UWP and so remain disabled there.
  • Loading branch information
mconnew committed Sep 22, 2016
1 parent fbb7984 commit 44466e6
Show file tree
Hide file tree
Showing 6 changed files with 154 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -146,15 +146,13 @@ public static Claim CreateThumbprintClaim(byte[] thumbprint)
return new Claim(ClaimTypes.Thumbprint, SecurityUtils.CloneBuffer(thumbprint), Rights.PossessProperty, ClaimComparer.Thumbprint);
}

#if SUPPORTS_WINDOWSIDENTITY
public static Claim CreateUpnClaim(string upn)
{
if (upn == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("upn");

return new Claim(ClaimTypes.Upn, upn, Rights.PossessProperty, ClaimComparer.Upn);
}
#endif // SUPPORTS_WINDOWSIDENTITY

public static Claim CreateUriClaim(Uri uri)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,7 @@ internal class ClaimComparer : IEqualityComparer<Claim>
private static IEqualityComparer<Claim> s_dnsComparer;
private static IEqualityComparer<Claim> s_rsaComparer;
private static IEqualityComparer<Claim> s_thumbprintComparer;
#if SUPPORTS_WINDOWSIDENTITY
private static IEqualityComparer<Claim> s_upnComparer;
#endif // SUPPORTS_WINDOWSIDENTITY
private static IEqualityComparer<Claim> s_x500DistinguishedNameComparer;
private IEqualityComparer _resourceComparer;

Expand Down Expand Up @@ -113,7 +111,6 @@ public static IEqualityComparer<Claim> Thumbprint
}
}

#if SUPPORTS_WINDOWSIDENTITY
public static IEqualityComparer<Claim> Upn
{
get
Expand All @@ -125,7 +122,6 @@ public static IEqualityComparer<Claim> Upn
return s_upnComparer;
}
}
#endif // SUPPORTS_WINDOWSIDENTITY

public static IEqualityComparer<Claim> X500DistinguishedName
{
Expand Down Expand Up @@ -160,7 +156,7 @@ public int GetHashCode(Claim claim)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("claim");

return claim.ClaimType.GetHashCode() ^ claim.Right.GetHashCode()
^ ((claim.Resource == null) ? 0 : _resourceComparer.GetHashCode(claim.Resource));
^ ((claim.Resource == null) ? 0 : _resourceComparer.GetHashCode(claim.Resource));
}

private class ObjectComparer : IEqualityComparer
Expand Down Expand Up @@ -240,6 +236,7 @@ int IEqualityComparer.GetHashCode(object obj)
private class X500DistinguishedNameObjectComparer : IEqualityComparer
{
private IEqualityComparer _binaryComparer;

public X500DistinguishedNameObjectComparer()
{
_binaryComparer = new BinaryObjectComparer();
Expand All @@ -258,12 +255,35 @@ int IEqualityComparer.GetHashCode(object obj)
}
}

#if SUPPORTS_WINDOWSIDENTITY
private class UpnObjectComparer : IEqualityComparer
{
bool IEqualityComparer.Equals(object obj1, object obj2)
{
throw ExceptionHelper.PlatformNotSupported();
if (StringComparer.OrdinalIgnoreCase.Equals(obj1 as string, obj2 as string))
return true;

string upn1 = obj1 as string;
string upn2 = obj2 as string;
if (upn1 == null || upn2 == null)
return false;

#if SUPPORTS_WINDOWSIDENTITY
SecurityIdentifier sid1;
if (!TryLookupSidFromName(upn1, out sid1))
return false;

// Normalize to sid
SecurityIdentifier sid2;
if (!TryLookupSidFromName(upn2, out sid2))
return false;

return sid1 == sid2;
#else
// If WindowsIdentity isn't supported, then we can't
// retrieve the SecurityIdentifier's to compare so
// must return false
return false;
#endif // SUPPORTS_WINDOWSIDENTITY
}

int IEqualityComparer.GetHashCode(object obj)
Expand All @@ -272,14 +292,17 @@ int IEqualityComparer.GetHashCode(object obj)
if (upn == null)
return 0;

#if SUPPORTS_WINDOWSIDENTITY
// Normalize to sid
SecurityIdentifier sid;
if (TryLookupSidFromName(upn, out sid))
return sid.GetHashCode();
#endif // SUPPORTS_WINDOWSIDENTITY

return StringComparer.OrdinalIgnoreCase.GetHashCode(upn);
}

#if SUPPORTS_WINDOWSIDENTITY
private bool TryLookupSidFromName(string upn, out SecurityIdentifier sid)
{
sid = null;
Expand All @@ -293,7 +316,7 @@ private bool TryLookupSidFromName(string upn, out SecurityIdentifier sid)
}
return sid != null;
}
#endif // SUPPORTS_WINDOWSIDENTITY
}
#endif // SUPPORTS_WINDOWSIDENTITY
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,5 +40,9 @@ internal static void TraceIdentityDeterminationSuccess(EndpointAddress epr, Endp
internal static void TraceIdentityDeterminationFailure(EndpointAddress epr, Type identityVerifier)
{
}

internal static void TraceSpnToSidMappingFailure(string spn, Exception e)
{
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,14 @@
// See the LICENSE file in the project root for more information.


using System.ComponentModel;
using System.Security.Principal;
using System.IdentityModel.Claims;
using System.Runtime;
using System.Runtime.InteropServices;
using System.ServiceModel.Diagnostics;
using System.Text;
using System.Xml;

namespace System.ServiceModel
{
Expand All @@ -23,24 +29,22 @@ public class UpnEndpointIdentity : EndpointIdentity
public UpnEndpointIdentity(string upnName)
{
if (upnName == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("upnName");
#if SUPPORTS_WINDOWSIDENTITY
base.Initialize(Claim.CreateUpnClaim(upnName));
#else
throw ExceptionHelper.PlatformNotSupported("UpnEndpointIdentity is not supported on this platform");
#endif // SUPPORTS_WINDOWSIDENTITY
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(upnName));
}

Initialize(Claim.CreateUpnClaim(upnName));
}

public UpnEndpointIdentity(Claim identity)
{
if (identity == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("identity");
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(identity));

// PreSharp Bug: Parameter 'identity.ResourceType' to this public method must be validated: A null-dereference can occur here.
if (!identity.ClaimType.Equals(ClaimTypes.Upn))
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgument(SR.Format(SR.UnrecognizedClaimTypeForIdentity, identity.ClaimType, ClaimTypes.Upn));

base.Initialize(identity);
Initialize(identity);
}

#if SUPPORTS_WINDOWSIDENTITY
Expand All @@ -53,6 +57,110 @@ internal UpnEndpointIdentity(WindowsIdentity windowsIdentity)
_upnSid = windowsIdentity.User;
_hasUpnSidBeenComputed = true;
}

internal override void EnsureIdentityClaim()
{
if (_windowsIdentity != null)
{
lock (_thisLock)
{
if (_windowsIdentity != null)
{
Initialize(Claim.CreateUpnClaim(GetUpnFromWindowsIdentity(_windowsIdentity)));
_windowsIdentity.Dispose();
_windowsIdentity = null;
}
}
}
}

string GetUpnFromWindowsIdentity(WindowsIdentity windowsIdentity)
{
string downlevelName = null;
string upnName = null;

try
{
downlevelName = windowsIdentity.Name;

if (IsMachineJoinedToDomain())
{
upnName = GetUpnFromDownlevelName(downlevelName);
}
}
catch (Exception e)
{
if (Fx.IsFatal(e))
{
throw;
}
}

// if the AD cannot be queried for the fully qualified domain name,
// fall back to the downlevel UPN name
return upnName ?? downlevelName;
}

bool IsMachineJoinedToDomain()
{
throw ExceptionHelper.PlatformNotSupported();
}

string GetUpnFromDownlevelName(string downlevelName)
{
throw ExceptionHelper.PlatformNotSupported();
}
#endif // SUPPORTS_WINDOWSIDENTITY

internal override void WriteContentsTo(XmlDictionaryWriter writer)
{
if (writer == null)
throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull(nameof(writer));

writer.WriteElementString(XD.AddressingDictionary.Upn, XD.AddressingDictionary.IdentityExtensionNamespace, (string)this.IdentityClaim.Resource);
}

#if SUPPORTS_WINDOWSIDENTITY
internal SecurityIdentifier GetUpnSid()
{
Fx.Assert(ClaimTypes.Upn.Equals(this.IdentityClaim.ClaimType), "");
if (!_hasUpnSidBeenComputed)
{
lock (_thisLock)
{
string upn = (string)this.IdentityClaim.Resource;
if (!_hasUpnSidBeenComputed)
{
try
{
NTAccount userAccount = new NTAccount(upn);
_upnSid = userAccount.Translate(typeof(SecurityIdentifier)) as SecurityIdentifier;
}
#pragma warning suppress 56500 // covered by FxCOP
catch (Exception e)
{
// Always immediately rethrow fatal exceptions.
if (Fx.IsFatal(e))
{
throw;
}

if (e is NullReferenceException)
{
throw;
}

SecurityTraceRecordHelper.TraceSpnToSidMappingFailure(upn, e);
}
finally
{
_hasUpnSidBeenComputed = true;
}
}
}
}
return _upnSid;
}
#endif
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ public static void NegotiateStream_Http_With_ExplicitSpn()
[Condition(nameof(Windows_Authentication_Available),
nameof(Root_Certificate_Installed),
nameof(UPN_Available))]
[Issue(10)]
[Issue(10, Framework = FrameworkID.NetNative)]
[OuterLoop]
public static void NegotiateStream_Http_With_Upn()
{
Expand Down Expand Up @@ -406,7 +406,7 @@ public static void NegotiateStream_Http_With_ExplicitUserNameAndPassword_With_Sp
nameof(Explicit_Credentials_Available),
nameof(Domain_Available),
nameof(UPN_Available))]
[Issue(10)]
[Issue(10, Framework = FrameworkID.NetNative)]
[OuterLoop]
public static void NegotiateStream_Http_With_ExplicitUserNameAndPassword_With_Upn()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ public static class UpnEndpointIdentityTest
[WcfTheory]
[InlineData("")]
[InlineData("test@wcf.example.com")]
[Issue(1454, Framework = FrameworkID.NetNative)]
public static void Ctor_UpnName(string upn)
{
UpnEndpointIdentity upnEndpointEntity = new UpnEndpointIdentity(upn);
Expand Down

0 comments on commit 44466e6

Please sign in to comment.