Added support to retrieve the remote identity.
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Security.Principal;
|
||||||
using NSspi.Buffers;
|
using NSspi.Buffers;
|
||||||
using NSspi.Credentials;
|
using NSspi.Credentials;
|
||||||
|
|
||||||
@@ -117,6 +118,68 @@ namespace NSspi.Contexts
|
|||||||
this.Disposed = true;
|
this.Disposed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IIdentity GetRemoteIdentity()
|
||||||
|
{
|
||||||
|
using( var tokenHandle = GetContextToken() )
|
||||||
|
{
|
||||||
|
return new WindowsIdentity(
|
||||||
|
tokenHandle.DangerousGetHandle(),
|
||||||
|
this.Credential.SecurityPackage
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private SafeTokenHandle GetContextToken()
|
||||||
|
{
|
||||||
|
bool gotRef = false;
|
||||||
|
SecurityStatus status = SecurityStatus.InternalError;
|
||||||
|
SafeTokenHandle token;
|
||||||
|
|
||||||
|
RuntimeHelpers.PrepareConstrainedRegions();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
this.ContextHandle.DangerousAddRef( ref gotRef );
|
||||||
|
}
|
||||||
|
catch( Exception )
|
||||||
|
{
|
||||||
|
if( gotRef )
|
||||||
|
{
|
||||||
|
this.ContextHandle.DangerousRelease();
|
||||||
|
gotRef = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if( gotRef )
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
status = ContextNativeMethods.QuerySecurityContextToken(
|
||||||
|
ref this.ContextHandle.rawHandle,
|
||||||
|
out token
|
||||||
|
);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
this.ContextHandle.DangerousRelease();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
token = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( status != SecurityStatus.OK )
|
||||||
|
{
|
||||||
|
throw new SSPIException( "Failed to query context token.", status );
|
||||||
|
}
|
||||||
|
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Encrypts the byte array using the context's session key.
|
/// Encrypts the byte array using the context's session key.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -174,6 +174,10 @@ namespace NSspi.Contexts
|
|||||||
[DllImport( "Secur32.dll", EntryPoint = "RevertSecurityContext", CharSet = CharSet.Unicode )]
|
[DllImport( "Secur32.dll", EntryPoint = "RevertSecurityContext", CharSet = CharSet.Unicode )]
|
||||||
internal static extern SecurityStatus RevertSecurityContext( ref RawSspiHandle contextHandle );
|
internal static extern SecurityStatus RevertSecurityContext( ref RawSspiHandle contextHandle );
|
||||||
|
|
||||||
|
[ReliabilityContract( Consistency.WillNotCorruptState, Cer.Success )]
|
||||||
|
[DllImport( "Secur32.dll", EntryPoint = "QuerySecurityContextToken", SetLastError = true )]
|
||||||
|
internal static extern SecurityStatus QuerySecurityContextToken( ref RawSspiHandle contextHandle, [Out] out SafeTokenHandle handle );
|
||||||
|
|
||||||
[StructLayout( LayoutKind.Sequential )]
|
[StructLayout( LayoutKind.Sequential )]
|
||||||
private class KeyStruct
|
private class KeyStruct
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -246,7 +246,7 @@ namespace NSspi.Contexts
|
|||||||
|
|
||||||
if( this.impersonating && this.impersonationSetsThreadPrinciple )
|
if( this.impersonating && this.impersonationSetsThreadPrinciple )
|
||||||
{
|
{
|
||||||
SetThreadPrinciple();
|
Thread.CurrentPrincipal = new WindowsPrincipal( (WindowsIdentity)GetRemoteIdentity() );
|
||||||
}
|
}
|
||||||
|
|
||||||
return handle;
|
return handle;
|
||||||
@@ -315,15 +315,5 @@ namespace NSspi.Contexts
|
|||||||
|
|
||||||
base.Dispose( disposing );
|
base.Dispose( disposing );
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Set the current thread security context to the impersonated identity.
|
|
||||||
/// </summary>
|
|
||||||
private void SetThreadPrinciple()
|
|
||||||
{
|
|
||||||
Thread.CurrentPrincipal = new WindowsPrincipal(
|
|
||||||
WindowsIdentity.GetCurrent( TokenAccessLevels.AllAccess )
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -17,5 +17,9 @@ namespace NSspi
|
|||||||
[ReliabilityContract( Consistency.WillNotCorruptState, Cer.Success )]
|
[ReliabilityContract( Consistency.WillNotCorruptState, Cer.Success )]
|
||||||
[DllImport( "Secur32.dll", EntryPoint = "EnumerateSecurityPackages", CharSet = CharSet.Unicode )]
|
[DllImport( "Secur32.dll", EntryPoint = "EnumerateSecurityPackages", CharSet = CharSet.Unicode )]
|
||||||
internal static extern SecurityStatus EnumerateSecurityPackages( ref int numPackages, ref IntPtr pkgInfoArry );
|
internal static extern SecurityStatus EnumerateSecurityPackages( ref int numPackages, ref IntPtr pkgInfoArry );
|
||||||
|
|
||||||
|
[DllImport( "Kernel32.dll", EntryPoint = "CloseHandle", SetLastError = true )]
|
||||||
|
[ReliabilityContract( Consistency.WillNotCorruptState, Cer.Success )]
|
||||||
|
internal static extern bool CloseHandle( IntPtr handle );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
3
TestServer/ServerForm.Designer.cs
generated
3
TestServer/ServerForm.Designer.cs
generated
@@ -170,7 +170,8 @@
|
|||||||
//
|
//
|
||||||
// impersonateButton
|
// impersonateButton
|
||||||
//
|
//
|
||||||
this.impersonateButton.Location = new System.Drawing.Point(262, 350);
|
this.impersonateButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||||
|
this.impersonateButton.Location = new System.Drawing.Point(262, 356);
|
||||||
this.impersonateButton.Name = "impersonateButton";
|
this.impersonateButton.Name = "impersonateButton";
|
||||||
this.impersonateButton.Size = new System.Drawing.Size(116, 23);
|
this.impersonateButton.Size = new System.Drawing.Size(116, 23);
|
||||||
this.impersonateButton.TabIndex = 4;
|
this.impersonateButton.TabIndex = 4;
|
||||||
|
|||||||
@@ -1,14 +1,16 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Security.Principal;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
using NSspi;
|
||||||
|
using NSspi.Contexts;
|
||||||
|
using NSspi.Credentials;
|
||||||
using TestProtocol;
|
using TestProtocol;
|
||||||
|
|
||||||
namespace TestServer
|
namespace TestServer
|
||||||
{
|
{
|
||||||
using System.IO;
|
|
||||||
using NSspi;
|
|
||||||
using NSspi.Contexts;
|
|
||||||
using NSspi.Credentials;
|
|
||||||
using Message = TestProtocol.Message;
|
using Message = TestProtocol.Message;
|
||||||
|
|
||||||
public partial class ServerForm : Form
|
public partial class ServerForm : Form
|
||||||
@@ -38,7 +40,8 @@ namespace TestServer
|
|||||||
ContextAttrib.SequenceDetect |
|
ContextAttrib.SequenceDetect |
|
||||||
ContextAttrib.MutualAuth |
|
ContextAttrib.MutualAuth |
|
||||||
ContextAttrib.Delegate |
|
ContextAttrib.Delegate |
|
||||||
ContextAttrib.Confidentiality
|
ContextAttrib.Confidentiality,
|
||||||
|
true
|
||||||
);
|
);
|
||||||
|
|
||||||
this.server = new CustomServer();
|
this.server = new CustomServer();
|
||||||
@@ -123,7 +126,11 @@ namespace TestServer
|
|||||||
{
|
{
|
||||||
MessageBox.Show( "Starting impersonation: " + Environment.UserName );
|
MessageBox.Show( "Starting impersonation: " + Environment.UserName );
|
||||||
|
|
||||||
FileStream stream = File.Create( Environment.GetFolderPath( Environment.SpecialFolder.DesktopDirectory ) + @"\test.txt" );
|
var directory = Environment.GetFolderPath( Environment.SpecialFolder.DesktopDirectory );
|
||||||
|
|
||||||
|
Directory.CreateDirectory( directory );
|
||||||
|
|
||||||
|
FileStream stream = File.Create( directory + @"\test.txt" );
|
||||||
StreamWriter writer = new StreamWriter( stream, Encoding.UTF8 );
|
StreamWriter writer = new StreamWriter( stream, Encoding.UTF8 );
|
||||||
|
|
||||||
writer.WriteLine( "Hello world." );
|
writer.WriteLine( "Hello world." );
|
||||||
@@ -164,6 +171,32 @@ namespace TestServer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void InitComplete()
|
||||||
|
{
|
||||||
|
UpdateButtons();
|
||||||
|
this.clientUsernameTextBox.Text = serverContext.ContextUserName;
|
||||||
|
|
||||||
|
var builder = new StringBuilder();
|
||||||
|
var remoteId = this.serverContext.GetRemoteIdentity();
|
||||||
|
|
||||||
|
builder.AppendLine( "Client identity information:" );
|
||||||
|
builder.AppendLine( " - Name: " + remoteId.Name );
|
||||||
|
|
||||||
|
var windowsId = remoteId as WindowsIdentity;
|
||||||
|
|
||||||
|
if( windowsId != null )
|
||||||
|
{
|
||||||
|
builder.AppendLine( " - User SID: " + windowsId.User.Value );
|
||||||
|
|
||||||
|
foreach( var claim in windowsId.Claims )
|
||||||
|
{
|
||||||
|
builder.AppendLine( " - " + claim.ToString() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.receivedTextbox.AppendText( builder.ToString() );
|
||||||
|
}
|
||||||
|
|
||||||
private void server_Disconnected()
|
private void server_Disconnected()
|
||||||
{
|
{
|
||||||
this.running = true;
|
this.running = true;
|
||||||
@@ -209,11 +242,7 @@ namespace TestServer
|
|||||||
this.initializing = false;
|
this.initializing = false;
|
||||||
this.connected = true;
|
this.connected = true;
|
||||||
|
|
||||||
this.Invoke( (Action)delegate ()
|
this.Invoke( (Action)InitComplete );
|
||||||
{
|
|
||||||
UpdateButtons();
|
|
||||||
this.clientUsernameTextBox.Text = serverContext.ContextUserName;
|
|
||||||
} );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
Reference in New Issue
Block a user