Rough implementation of impersonation.

This commit is contained in:
antiduh
2014-06-25 20:12:46 +00:00
parent 9118815314
commit 5f3fd64169
4 changed files with 124 additions and 10 deletions

View File

@@ -13,15 +13,13 @@ namespace NSspi.Contexts
{
public class Context : IDisposable
{
private bool disposed;
public Context( Credential cred )
{
this.Credential = cred;
this.ContextHandle = new SafeContextHandle();
this.disposed = false;
this.Disposed = false;
this.Initialized = false;
}
@@ -55,6 +53,8 @@ namespace NSspi.Contexts
}
}
public bool Disposed { get; private set; }
public void Dispose()
{
Dispose( true );
@@ -63,7 +63,7 @@ namespace NSspi.Contexts
protected virtual void Dispose( bool disposing )
{
if( this.disposed ) { return; }
if( this.Disposed ) { return; }
if( disposing )
{
@@ -72,7 +72,7 @@ namespace NSspi.Contexts
}
this.disposed = true;
this.Disposed = true;
}
/// <summary>
@@ -359,6 +359,10 @@ namespace NSspi.Contexts
return result;
}
private void InitSecPkgInfo()
{
}
}
}

View File

@@ -148,11 +148,11 @@ namespace NSspi.Contexts
[ReliabilityContract( Consistency.WillNotCorruptState, Cer.Success )]
[DllImport( "Secur32.dll", EntryPoint = "ImpersonateSecurityContext ", CharSet = CharSet.Unicode )]
[DllImport( "Secur32.dll", EntryPoint = "ImpersonateSecurityContext", CharSet = CharSet.Unicode )]
internal static extern SecurityStatus ImpersonateSecurityContext( ref RawSspiHandle contextHandle );
[ReliabilityContract( Consistency.WillNotCorruptState, Cer.Success )]
[DllImport( "Secur32.dll", EntryPoint = "RevertSecurityContext ", CharSet = CharSet.Unicode )]
[DllImport( "Secur32.dll", EntryPoint = "RevertSecurityContext", CharSet = CharSet.Unicode )]
internal static extern SecurityStatus RevertSecurityContext( ref RawSspiHandle contextHandle );

View File

@@ -39,7 +39,10 @@ namespace NSspi.Contexts
protected virtual void Dispose( bool disposing )
{
if( disposing && this.server != null && this.server.Disposed == false )
{
this.server.RevertImpersonate();
}
}
}

View File

@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using NSspi.Buffers;
@@ -12,11 +13,15 @@ namespace NSspi.Contexts
{
private ContextAttrib requestedAttribs;
private ContextAttrib finalAttribs;
private bool impersonating;
public ServerContext(ServerCredential cred, ContextAttrib requestedAttribs) : base ( cred )
{
this.requestedAttribs = requestedAttribs;
this.finalAttribs = ContextAttrib.Zero;
this.impersonating = false;
}
public SecurityStatus AcceptToken( byte[] clientToken, out byte[] nextToken )
@@ -81,6 +86,8 @@ namespace NSspi.Contexts
{
nextToken = null;
}
InitProviderCapabilities();
}
else if ( status == SecurityStatus.ContinueNeeded )
{
@@ -96,5 +103,105 @@ namespace NSspi.Contexts
return status;
}
public ImpersonationHandle ImpersonateClient()
{
ImpersonationHandle handle = new ImpersonationHandle( this );
SecurityStatus status = SecurityStatus.InternalError;
bool gotRef = false;
if( impersonating )
{
throw new InvalidOperationException( "Cannot impersonate again while already impersonating." );
}
RuntimeHelpers.PrepareConstrainedRegions();
try
{
this.ContextHandle.DangerousAddRef( ref gotRef );
}
catch( Exception )
{
if( gotRef )
{
this.ContextHandle.DangerousRelease();
gotRef = false;
}
throw;
}
finally
{
if( gotRef )
{
status = ContextNativeMethods.ImpersonateSecurityContext(
ref this.ContextHandle.rawHandle
);
this.ContextHandle.DangerousRelease();
this.impersonating = true;
}
}
if( status == SecurityStatus.NoImpersonation )
{
throw new SSPIException( "Impersonation could not be performed.", status );
}
else if( status == SecurityStatus.Unsupported )
{
throw new SSPIException( "Impersonation is not supported by the security context's Security Support Provider.", status );
}
else if( status != SecurityStatus.OK )
{
throw new SSPIException( "Failed to impersonate the client", status );
}
return handle;
}
internal void RevertImpersonate()
{
bool gotRef = false;
SecurityStatus status = SecurityStatus.InternalError;
if( impersonating == false || this.Disposed )
{
return;
}
RuntimeHelpers.PrepareConstrainedRegions();
try
{
this.ContextHandle.DangerousAddRef( ref gotRef );
}
catch( Exception )
{
if( gotRef )
{
this.ContextHandle.DangerousRelease();
gotRef = false;
}
throw;
}
finally
{
if( gotRef )
{
status = ContextNativeMethods.RevertSecurityContext(
ref this.ContextHandle.rawHandle
);
this.ContextHandle.DangerousRelease();
this.impersonating = false;
}
}
}
private void InitProviderCapabilities()
{
}
}
}