10 Commits

Author SHA1 Message Date
Kevin Thompson
3a7629fada Removed the binaries link. 2019-08-09 12:22:25 -04:00
Kevin Thompson
0b81172157 Update readme.md 2019-08-09 12:20:19 -04:00
Kevin Thompson
d49e27109e Bumped the version to 0.3.1. 2019-08-05 21:02:31 -04:00
Kevin Thompson
b655f5650e Fixed the project file to write out documentation properly. 2019-08-05 20:54:39 -04:00
Kevin Thompson
2bc74ddb4f Added the strong-name key for nsspi to the repo. 2019-08-05 20:41:56 -04:00
Kevin Thompson
1a7f60d3e1 Finished implementing GetRemoteIdentity. 2019-08-02 13:52:52 -04:00
Kevin Thompson
16bd8b2d68 Fixed the project to open with the right version of Visual Studio. 2019-07-19 16:43:11 -04:00
Kevin Thompson
06f1b08050 Added support to retrieve the remote identity. 2019-07-19 16:42:41 -04:00
Kevin Thompson
8c3126316f Published release 0.3.0 2019-06-16 22:05:10 -04:00
Kevin Thompson
9cd6edbeb7 Added the project license to the package information. 2019-06-16 21:53:52 -04:00
11 changed files with 196 additions and 36 deletions

View File

@@ -1,7 +1,7 @@
 
Microsoft Visual Studio Solution File, Format Version 12.00 Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14 # Visual Studio 15
VisualStudioVersion = 14.0.25420.1 VisualStudioVersion = 16.0.28527.54
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestClient", "TestClient\TestClient.csproj", "{E93FBF1A-5198-44D6-BDF0-880D17F2B81A}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestClient", "TestClient\TestClient.csproj", "{E93FBF1A-5198-44D6-BDF0-880D17F2B81A}"
EndProject EndProject

View File

@@ -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,105 @@ namespace NSspi.Contexts
this.Disposed = true; this.Disposed = true;
} }
/// <summary>
/// Returns the identity of the remote entity.
/// </summary>
/// <returns></returns>
public IIdentity GetRemoteIdentity()
{
IIdentity result = null;
using( var tokenHandle = GetContextToken() )
{
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()
{
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>

View File

@@ -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
{ {

View File

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

View File

@@ -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 )
);
}
} }
} }

View File

@@ -5,21 +5,27 @@
<AssemblyName>NSspi</AssemblyName> <AssemblyName>NSspi</AssemblyName>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild> <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<Authors>Kevin Thompson</Authors> <Authors>Kevin Thompson</Authors>
<PackageReleaseNotes>Adds multi-targetting to support .Net Standard 2.0.</PackageReleaseNotes> <PackageReleaseNotes>Adds support for accessing the remote identity.</PackageReleaseNotes>
<PackageProjectUrl>https://github.com/antiduh/nsspi</PackageProjectUrl> <PackageProjectUrl>https://github.com/antiduh/nsspi</PackageProjectUrl>
<Version>0.3.0.0</Version> <Version>0.3.1.0</Version>
<SignAssembly>true</SignAssembly> <SignAssembly>true</SignAssembly>
<DelaySign>false</DelaySign> <DelaySign>false</DelaySign>
<AssemblyOriginatorKeyFile>nsspi key.snk</AssemblyOriginatorKeyFile> <AssemblyOriginatorKeyFile>nsspi key.snk</AssemblyOriginatorKeyFile>
<PackageLicenseFile>License.txt</PackageLicenseFile>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|netstandard2.0|AnyCPU'">
<DocumentationFile>NSspi.xml</DocumentationFile> <PropertyGroup>
</PropertyGroup> <GenerateDocumentationFile>true</GenerateDocumentationFile>
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Release|netstandard2.0|AnyCPU'">
<DocumentationFile>NSspi.xml</DocumentationFile>
</PropertyGroup> </PropertyGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' "> <ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' ">
<PackageReference Include="System.Security.Principal.Windows" Version="4.5.1" /> <PackageReference Include="System.Security.Principal.Windows" Version="4.5.1" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<None Include="..\License.txt">
<Pack>True</Pack>
<PackagePath></PackagePath>
</None>
</ItemGroup>
</Project> </Project>

View File

@@ -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 );
} }
} }

BIN
NSspi/nsspi key.snk Normal file

Binary file not shown.

View File

@@ -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;

View File

@@ -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

View File

@@ -1,11 +1,10 @@
## Downloads ## ## Downloads ##
The latest release of NSspi is v0.2.1. The latest release of NSspi is v0.3.1, released 5-Aug-2019.
Version 0.2.1 is a minor bugfix release that improves impersonation. Version 0.3.1 adds support to obtain an IIdentity/WindowsPrinciple representing the remote connection. This is useful for servers that wish to query the properties on the principle, such as claims.
* [Source](https://github.com/antiduh/nsspi/archive/0.2.1.zip) * [Source](https://github.com/antiduh/nsspi/archive/0.3.1.zip)
* [Binaries](https://github.com/antiduh/nsspi/releases/download/0.2.1/nsspi-0.2.1-bin.zip)
* [Nuget package](https://www.nuget.org/packages/NSspi) * [Nuget package](https://www.nuget.org/packages/NSspi)
You can also browse the list of [releases](https://github.com/antiduh/nsspi/releases). You can also browse the list of [releases](https://github.com/antiduh/nsspi/releases).