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;
+ }
+ }
+}