diff --git a/NSspi/Contexts/Context.cs b/NSspi/Contexts/Context.cs index 402ab30..67525bd 100644 --- a/NSspi/Contexts/Context.cs +++ b/NSspi/Contexts/Context.cs @@ -118,15 +118,52 @@ namespace NSspi.Contexts this.Disposed = true; } + /// + /// Returns the identity of the remote entity. + /// + /// public IIdentity GetRemoteIdentity() { + IIdentity result = null; + using( var tokenHandle = GetContextToken() ) { - return new WindowsIdentity( - tokenHandle.DangerousGetHandle(), - this.Credential.SecurityPackage - ); + bool gotRef = false; + + RuntimeHelpers.PrepareConstrainedRegions(); + try + { + tokenHandle.DangerousAddRef( ref gotRef ); + } + catch( Exception ) + { + if( gotRef ) + { + tokenHandle.DangerousRelease(); + gotRef = false; + } + + throw; + } + finally + { + try + { + result = new WindowsIdentity( + tokenHandle.DangerousGetHandle(), + this.Credential.SecurityPackage + ); + } + finally + { + // Make sure we release the handle, even if the allocation for + // WindowsIdentity fails. + tokenHandle.DangerousRelease(); + } + } } + + return result; } private SafeTokenHandle GetContextToken() diff --git a/NSspi/Contexts/SafeTokenHandle.cs b/NSspi/Contexts/SafeTokenHandle.cs new file mode 100644 index 0000000..d97134b --- /dev/null +++ b/NSspi/Contexts/SafeTokenHandle.cs @@ -0,0 +1,27 @@ +using System; +using System.Runtime.InteropServices; + +namespace NSspi.Contexts +{ + public class SafeTokenHandle : SafeHandle + { + public SafeTokenHandle() : base( IntPtr.Zero, true ) + { + } + + public override bool IsInvalid + { + get + { + return handle == IntPtr.Zero || handle == new IntPtr( -1 ); + } + } + + protected override bool ReleaseHandle() + { + NativeMethods.CloseHandle( this.handle ); + + return true; + } + } +}