Implemented SafeHandle usage for Context et al. The usage isn't actually safe yet, since I still reference the rawHandle without doing safe (CER) reference counting on the handle.
This commit is contained in:
@@ -25,9 +25,6 @@ namespace NSspi.Contexts
|
|||||||
|
|
||||||
public SecurityStatus Init( byte[] serverToken, out byte[] outToken )
|
public SecurityStatus Init( byte[] serverToken, out byte[] outToken )
|
||||||
{
|
{
|
||||||
long prevContextHandle = base.ContextHandle;
|
|
||||||
long newContextHandle = 0;
|
|
||||||
|
|
||||||
long expiry = 0;
|
long expiry = 0;
|
||||||
|
|
||||||
SecurityStatus status;
|
SecurityStatus status;
|
||||||
@@ -38,11 +35,11 @@ namespace NSspi.Contexts
|
|||||||
SecureBuffer serverBuffer;
|
SecureBuffer serverBuffer;
|
||||||
SecureBufferAdapter serverAdapter;
|
SecureBufferAdapter serverAdapter;
|
||||||
|
|
||||||
if ( (serverToken != null) && (prevContextHandle == 0) )
|
if ( (serverToken != null) && ( this.ContextHandle.IsInvalid ) )
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException( "Out-of-order usage detected - have a server token, but no previous client token had been created." );
|
throw new InvalidOperationException( "Out-of-order usage detected - have a server token, but no previous client token had been created." );
|
||||||
}
|
}
|
||||||
else if ( (serverToken == null) && (prevContextHandle != 0) )
|
else if ( (serverToken == null) && ( this.ContextHandle.IsInvalid == false ) )
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException( "Must provide the server's response when continuing the init process." );
|
throw new InvalidOperationException( "Must provide the server's response when continuing the init process." );
|
||||||
}
|
}
|
||||||
@@ -55,9 +52,24 @@ namespace NSspi.Contexts
|
|||||||
serverBuffer = new SecureBuffer( serverToken, BufferType.Token );
|
serverBuffer = new SecureBuffer( serverToken, BufferType.Token );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Some notes on handles and invoking InitializeSecurityContext
|
||||||
|
// - The first time around, the phContext parameter (the 'old' handle) is a null pointer to what
|
||||||
|
// would be an RawSspiHandle, to indicate this is the first time it's being called.
|
||||||
|
// The phNewContext is a pointer (reference) to an RawSspiHandle struct of where to write the
|
||||||
|
// new handle's values.
|
||||||
|
// - The next time you invoke ISC, it takes a pointer to the handle it gave you last time in phContext,
|
||||||
|
// and takes a pointer to where it should write the new handle's values in phNewContext.
|
||||||
|
// - After the first time, you can provide the same handle to both parameters. From MSDN:
|
||||||
|
// "On the second call, phNewContext can be the same as the handle specified in the phContext
|
||||||
|
// parameter."
|
||||||
|
// It will overwrite the handle you gave it with the new handle value.
|
||||||
|
// - All handle structures themselves are actually *two* pointer variables, eg, 64 bits on 32-bit
|
||||||
|
// Windows, 128 bits on 64-bit Windows.
|
||||||
|
// - So in the end, on a 64-bit machine, we're passing a 64-bit value (the pointer to the struct) that
|
||||||
|
// points to 128 bits of memory (the struct itself) for where to write the handle numbers.
|
||||||
using ( outAdapter = new SecureBufferAdapter( outTokenBuffer ) )
|
using ( outAdapter = new SecureBufferAdapter( outTokenBuffer ) )
|
||||||
{
|
{
|
||||||
if ( prevContextHandle == 0 )
|
if ( this.ContextHandle.IsInvalid )
|
||||||
{
|
{
|
||||||
status = ContextNativeMethods.InitializeSecurityContext_1(
|
status = ContextNativeMethods.InitializeSecurityContext_1(
|
||||||
ref this.Credential.Handle.rawHandle,
|
ref this.Credential.Handle.rawHandle,
|
||||||
@@ -68,7 +80,7 @@ namespace NSspi.Contexts
|
|||||||
SecureBufferDataRep.Network,
|
SecureBufferDataRep.Network,
|
||||||
IntPtr.Zero,
|
IntPtr.Zero,
|
||||||
0,
|
0,
|
||||||
ref newContextHandle,
|
ref this.ContextHandle.rawHandle,
|
||||||
outAdapter.Handle,
|
outAdapter.Handle,
|
||||||
ref this.finalAttribs,
|
ref this.finalAttribs,
|
||||||
ref expiry
|
ref expiry
|
||||||
@@ -80,14 +92,14 @@ namespace NSspi.Contexts
|
|||||||
{
|
{
|
||||||
status = ContextNativeMethods.InitializeSecurityContext_2(
|
status = ContextNativeMethods.InitializeSecurityContext_2(
|
||||||
ref this.Credential.Handle.rawHandle,
|
ref this.Credential.Handle.rawHandle,
|
||||||
ref prevContextHandle,
|
ref this.ContextHandle.rawHandle,
|
||||||
this.serverPrinc,
|
this.serverPrinc,
|
||||||
this.requestedAttribs,
|
this.requestedAttribs,
|
||||||
0,
|
0,
|
||||||
SecureBufferDataRep.Network,
|
SecureBufferDataRep.Network,
|
||||||
serverAdapter.Handle,
|
serverAdapter.Handle,
|
||||||
0,
|
0,
|
||||||
ref newContextHandle,
|
ref this.ContextHandle.rawHandle,
|
||||||
outAdapter.Handle,
|
outAdapter.Handle,
|
||||||
ref this.finalAttribs,
|
ref this.finalAttribs,
|
||||||
ref expiry
|
ref expiry
|
||||||
@@ -114,8 +126,6 @@ namespace NSspi.Contexts
|
|||||||
throw new SSPIException( "Failed to invoke InitializeSecurityContext for a client", status );
|
throw new SSPIException( "Failed to invoke InitializeSecurityContext for a client", status );
|
||||||
}
|
}
|
||||||
|
|
||||||
base.ContextHandle = newContextHandle;
|
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,8 @@ namespace NSspi
|
|||||||
{
|
{
|
||||||
this.Credential = cred;
|
this.Credential = cred;
|
||||||
|
|
||||||
|
this.ContextHandle = new SafeContextHandle();
|
||||||
|
|
||||||
this.disposed = false;
|
this.disposed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -26,7 +28,7 @@ namespace NSspi
|
|||||||
|
|
||||||
protected Credential Credential { get; private set; }
|
protected Credential Credential { get; private set; }
|
||||||
|
|
||||||
public long ContextHandle { get; protected set; }
|
public SafeContextHandle ContextHandle { get; protected set; }
|
||||||
|
|
||||||
public string AuthorityName
|
public string AuthorityName
|
||||||
{
|
{
|
||||||
@@ -59,10 +61,10 @@ namespace NSspi
|
|||||||
this.Credential.Dispose();
|
this.Credential.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
long contextHandleCopy = this.ContextHandle;
|
// TODO SAFE_CER
|
||||||
ContextNativeMethods.DeleteSecurityContext( ref contextHandleCopy );
|
ContextNativeMethods.DeleteSecurityContext( ref this.ContextHandle.rawHandle );
|
||||||
|
|
||||||
this.ContextHandle = 0;
|
this.ContextHandle.Dispose();
|
||||||
|
|
||||||
this.disposed = true;
|
this.disposed = true;
|
||||||
}
|
}
|
||||||
@@ -90,8 +92,6 @@ namespace NSspi
|
|||||||
SecureBuffer paddingBuffer;
|
SecureBuffer paddingBuffer;
|
||||||
SecureBufferAdapter adapter;
|
SecureBufferAdapter adapter;
|
||||||
|
|
||||||
long contextHandle = this.ContextHandle;
|
|
||||||
|
|
||||||
SecurityStatus status;
|
SecurityStatus status;
|
||||||
byte[] result;
|
byte[] result;
|
||||||
|
|
||||||
@@ -103,8 +103,9 @@ namespace NSspi
|
|||||||
|
|
||||||
using( adapter = new SecureBufferAdapter( new[] { trailerBuffer, dataBuffer, paddingBuffer } ) )
|
using( adapter = new SecureBufferAdapter( new[] { trailerBuffer, dataBuffer, paddingBuffer } ) )
|
||||||
{
|
{
|
||||||
|
// TODO SAFE_CER
|
||||||
status = ContextNativeMethods.EncryptMessage(
|
status = ContextNativeMethods.EncryptMessage(
|
||||||
ref contextHandle,
|
ref this.ContextHandle.rawHandle,
|
||||||
0,
|
0,
|
||||||
adapter.Handle,
|
adapter.Handle,
|
||||||
0
|
0
|
||||||
@@ -154,9 +155,7 @@ namespace NSspi
|
|||||||
SecureBuffer dataBuffer;
|
SecureBuffer dataBuffer;
|
||||||
SecureBuffer paddingBuffer;
|
SecureBuffer paddingBuffer;
|
||||||
SecureBufferAdapter adapter;
|
SecureBufferAdapter adapter;
|
||||||
|
|
||||||
long contextHandle = this.ContextHandle;
|
|
||||||
|
|
||||||
SecurityStatus status;
|
SecurityStatus status;
|
||||||
byte[] result = null;
|
byte[] result = null;
|
||||||
int remaining;
|
int remaining;
|
||||||
@@ -221,8 +220,9 @@ namespace NSspi
|
|||||||
|
|
||||||
using( adapter = new SecureBufferAdapter( new [] { trailerBuffer, dataBuffer, paddingBuffer } ) )
|
using( adapter = new SecureBufferAdapter( new [] { trailerBuffer, dataBuffer, paddingBuffer } ) )
|
||||||
{
|
{
|
||||||
|
// TODO SAFE_CER
|
||||||
status = ContextNativeMethods.DecryptMessage(
|
status = ContextNativeMethods.DecryptMessage(
|
||||||
ref contextHandle,
|
ref this.ContextHandle.rawHandle,
|
||||||
adapter.Handle,
|
adapter.Handle,
|
||||||
0,
|
0,
|
||||||
0
|
0
|
||||||
@@ -243,11 +243,11 @@ namespace NSspi
|
|||||||
internal SecPkgContext_Sizes QueryBufferSizes()
|
internal SecPkgContext_Sizes QueryBufferSizes()
|
||||||
{
|
{
|
||||||
SecPkgContext_Sizes sizes = new SecPkgContext_Sizes();
|
SecPkgContext_Sizes sizes = new SecPkgContext_Sizes();
|
||||||
long contextHandle = this.ContextHandle;
|
|
||||||
SecurityStatus status;
|
SecurityStatus status;
|
||||||
|
|
||||||
|
// TODO SAFE_CER
|
||||||
status = ContextNativeMethods.QueryContextAttributes_Sizes(
|
status = ContextNativeMethods.QueryContextAttributes_Sizes(
|
||||||
ref contextHandle,
|
ref this.ContextHandle.rawHandle,
|
||||||
ContextQueryAttrib.Sizes,
|
ContextQueryAttrib.Sizes,
|
||||||
ref sizes
|
ref sizes
|
||||||
);
|
);
|
||||||
@@ -263,7 +263,6 @@ namespace NSspi
|
|||||||
internal string QueryContextString(ContextQueryAttrib attrib)
|
internal string QueryContextString(ContextQueryAttrib attrib)
|
||||||
{
|
{
|
||||||
SecPkgContext_String stringAttrib;
|
SecPkgContext_String stringAttrib;
|
||||||
long contextHandle;
|
|
||||||
SecurityStatus status;
|
SecurityStatus status;
|
||||||
string result;
|
string result;
|
||||||
|
|
||||||
@@ -274,10 +273,9 @@ namespace NSspi
|
|||||||
|
|
||||||
stringAttrib = new SecPkgContext_String();
|
stringAttrib = new SecPkgContext_String();
|
||||||
|
|
||||||
contextHandle = this.ContextHandle;
|
// TODO SAFE_CER
|
||||||
|
|
||||||
status = ContextNativeMethods.QueryContextAttributes_String(
|
status = ContextNativeMethods.QueryContextAttributes_String(
|
||||||
ref contextHandle,
|
ref this.ContextHandle.rawHandle,
|
||||||
attrib,
|
attrib,
|
||||||
ref stringAttrib
|
ref stringAttrib
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ namespace NSspi.Contexts
|
|||||||
IntPtr inputBuffer,
|
IntPtr inputBuffer,
|
||||||
ContextAttrib requestedAttribs,
|
ContextAttrib requestedAttribs,
|
||||||
SecureBufferDataRep dataRep,
|
SecureBufferDataRep dataRep,
|
||||||
ref long newContextHandle,
|
ref RawSspiHandle newContextHandle,
|
||||||
IntPtr outputBuffer,
|
IntPtr outputBuffer,
|
||||||
ref ContextAttrib outputAttribs,
|
ref ContextAttrib outputAttribs,
|
||||||
ref long expiry
|
ref long expiry
|
||||||
@@ -52,11 +52,11 @@ namespace NSspi.Contexts
|
|||||||
)]
|
)]
|
||||||
public static extern SecurityStatus AcceptSecurityContext_2(
|
public static extern SecurityStatus AcceptSecurityContext_2(
|
||||||
ref RawSspiHandle credHandle,
|
ref RawSspiHandle credHandle,
|
||||||
ref long oldContextHandle,
|
ref RawSspiHandle oldContextHandle,
|
||||||
IntPtr inputBuffer,
|
IntPtr inputBuffer,
|
||||||
ContextAttrib requestedAttribs,
|
ContextAttrib requestedAttribs,
|
||||||
SecureBufferDataRep dataRep,
|
SecureBufferDataRep dataRep,
|
||||||
ref long newContextHandle,
|
ref RawSspiHandle newContextHandle,
|
||||||
IntPtr outputBuffer,
|
IntPtr outputBuffer,
|
||||||
ref ContextAttrib outputAttribs,
|
ref ContextAttrib outputAttribs,
|
||||||
ref long expiry
|
ref long expiry
|
||||||
@@ -112,7 +112,7 @@ namespace NSspi.Contexts
|
|||||||
SecureBufferDataRep dataRep,
|
SecureBufferDataRep dataRep,
|
||||||
IntPtr inputBuffer,
|
IntPtr inputBuffer,
|
||||||
int reserved2,
|
int reserved2,
|
||||||
ref long newContextHandle,
|
ref RawSspiHandle newContextHandle,
|
||||||
IntPtr outputBuffer,
|
IntPtr outputBuffer,
|
||||||
ref ContextAttrib contextAttribs,
|
ref ContextAttrib contextAttribs,
|
||||||
ref long expiry
|
ref long expiry
|
||||||
@@ -127,14 +127,14 @@ namespace NSspi.Contexts
|
|||||||
)]
|
)]
|
||||||
public static extern SecurityStatus InitializeSecurityContext_2(
|
public static extern SecurityStatus InitializeSecurityContext_2(
|
||||||
ref RawSspiHandle credentialHandle,
|
ref RawSspiHandle credentialHandle,
|
||||||
ref long previousHandle,
|
ref RawSspiHandle previousHandle,
|
||||||
string serverPrincipleName,
|
string serverPrincipleName,
|
||||||
ContextAttrib requiredAttribs,
|
ContextAttrib requiredAttribs,
|
||||||
int reserved1,
|
int reserved1,
|
||||||
SecureBufferDataRep dataRep,
|
SecureBufferDataRep dataRep,
|
||||||
IntPtr inputBuffer,
|
IntPtr inputBuffer,
|
||||||
int reserved2,
|
int reserved2,
|
||||||
ref long newContextHandle,
|
ref RawSspiHandle newContextHandle,
|
||||||
IntPtr outputBuffer,
|
IntPtr outputBuffer,
|
||||||
ref ContextAttrib contextAttribs,
|
ref ContextAttrib contextAttribs,
|
||||||
ref long expiry
|
ref long expiry
|
||||||
@@ -147,7 +147,7 @@ namespace NSspi.Contexts
|
|||||||
CharSet = CharSet.Unicode,
|
CharSet = CharSet.Unicode,
|
||||||
SetLastError = true
|
SetLastError = true
|
||||||
)]
|
)]
|
||||||
public static extern SecurityStatus DeleteSecurityContext( ref long contextHandle );
|
public static extern SecurityStatus DeleteSecurityContext( ref RawSspiHandle contextHandle );
|
||||||
|
|
||||||
[DllImport(
|
[DllImport(
|
||||||
"Secur32.dll",
|
"Secur32.dll",
|
||||||
@@ -157,7 +157,7 @@ namespace NSspi.Contexts
|
|||||||
SetLastError = true
|
SetLastError = true
|
||||||
)]
|
)]
|
||||||
public static extern SecurityStatus EncryptMessage(
|
public static extern SecurityStatus EncryptMessage(
|
||||||
ref long contextHandle,
|
ref RawSspiHandle contextHandle,
|
||||||
int qualityOfProtection,
|
int qualityOfProtection,
|
||||||
IntPtr bufferDescriptor,
|
IntPtr bufferDescriptor,
|
||||||
int sequenceNumber
|
int sequenceNumber
|
||||||
@@ -172,7 +172,7 @@ namespace NSspi.Contexts
|
|||||||
SetLastError = true
|
SetLastError = true
|
||||||
)]
|
)]
|
||||||
public static extern SecurityStatus DecryptMessage(
|
public static extern SecurityStatus DecryptMessage(
|
||||||
ref long contextHandle,
|
ref RawSspiHandle contextHandle,
|
||||||
IntPtr bufferDescriptor,
|
IntPtr bufferDescriptor,
|
||||||
int sequenceNumber,
|
int sequenceNumber,
|
||||||
int qualityOfProtection
|
int qualityOfProtection
|
||||||
@@ -184,7 +184,7 @@ namespace NSspi.Contexts
|
|||||||
CallingConvention = CallingConvention.Winapi,
|
CallingConvention = CallingConvention.Winapi,
|
||||||
CharSet = CharSet.Unicode )]
|
CharSet = CharSet.Unicode )]
|
||||||
public static extern SecurityStatus QueryContextAttributes_Sizes(
|
public static extern SecurityStatus QueryContextAttributes_Sizes(
|
||||||
ref long contextHandle,
|
ref RawSspiHandle contextHandle,
|
||||||
ContextQueryAttrib attrib,
|
ContextQueryAttrib attrib,
|
||||||
ref SecPkgContext_Sizes sizes
|
ref SecPkgContext_Sizes sizes
|
||||||
);
|
);
|
||||||
@@ -195,7 +195,7 @@ namespace NSspi.Contexts
|
|||||||
CallingConvention = CallingConvention.Winapi,
|
CallingConvention = CallingConvention.Winapi,
|
||||||
CharSet = CharSet.Unicode )]
|
CharSet = CharSet.Unicode )]
|
||||||
public static extern SecurityStatus QueryContextAttributes_String(
|
public static extern SecurityStatus QueryContextAttributes_String(
|
||||||
ref long contextHandle,
|
ref RawSspiHandle contextHandle,
|
||||||
ContextQueryAttrib attrib,
|
ContextQueryAttrib attrib,
|
||||||
ref SecPkgContext_String names
|
ref SecPkgContext_String names
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -24,21 +24,17 @@ namespace NSspi.Contexts
|
|||||||
SecureBuffer clientBuffer = new SecureBuffer( clientToken, BufferType.Token );
|
SecureBuffer clientBuffer = new SecureBuffer( clientToken, BufferType.Token );
|
||||||
SecureBuffer outBuffer = new SecureBuffer( new byte[12288], BufferType.Token );
|
SecureBuffer outBuffer = new SecureBuffer( new byte[12288], BufferType.Token );
|
||||||
|
|
||||||
long oldContextHandle = base.ContextHandle;
|
|
||||||
long newContextHandle = 0;
|
|
||||||
|
|
||||||
SecurityStatus status;
|
SecurityStatus status;
|
||||||
long expiry = 0;
|
long expiry = 0;
|
||||||
|
|
||||||
SecureBufferAdapter clientAdapter;
|
SecureBufferAdapter clientAdapter;
|
||||||
SecureBufferAdapter outAdapter;
|
SecureBufferAdapter outAdapter;
|
||||||
|
|
||||||
|
|
||||||
using ( clientAdapter = new SecureBufferAdapter( clientBuffer ) )
|
using ( clientAdapter = new SecureBufferAdapter( clientBuffer ) )
|
||||||
{
|
{
|
||||||
using ( outAdapter = new SecureBufferAdapter( outBuffer ) )
|
using ( outAdapter = new SecureBufferAdapter( outBuffer ) )
|
||||||
{
|
{
|
||||||
if ( oldContextHandle == 0 )
|
if( this.ContextHandle.IsInvalid )
|
||||||
{
|
{
|
||||||
status = ContextNativeMethods.AcceptSecurityContext_1(
|
status = ContextNativeMethods.AcceptSecurityContext_1(
|
||||||
ref this.Credential.Handle.rawHandle,
|
ref this.Credential.Handle.rawHandle,
|
||||||
@@ -46,7 +42,7 @@ namespace NSspi.Contexts
|
|||||||
clientAdapter.Handle,
|
clientAdapter.Handle,
|
||||||
requestedAttribs,
|
requestedAttribs,
|
||||||
SecureBufferDataRep.Network,
|
SecureBufferDataRep.Network,
|
||||||
ref newContextHandle,
|
ref this.ContextHandle.rawHandle,
|
||||||
outAdapter.Handle,
|
outAdapter.Handle,
|
||||||
ref this.finalAttribs,
|
ref this.finalAttribs,
|
||||||
ref expiry
|
ref expiry
|
||||||
@@ -56,15 +52,17 @@ namespace NSspi.Contexts
|
|||||||
{
|
{
|
||||||
status = ContextNativeMethods.AcceptSecurityContext_2(
|
status = ContextNativeMethods.AcceptSecurityContext_2(
|
||||||
ref this.Credential.Handle.rawHandle,
|
ref this.Credential.Handle.rawHandle,
|
||||||
ref oldContextHandle,
|
ref this.ContextHandle.rawHandle,
|
||||||
clientAdapter.Handle,
|
clientAdapter.Handle,
|
||||||
requestedAttribs,
|
requestedAttribs,
|
||||||
SecureBufferDataRep.Network,
|
SecureBufferDataRep.Network,
|
||||||
ref newContextHandle,
|
ref this.ContextHandle.rawHandle,
|
||||||
outAdapter.Handle,
|
outAdapter.Handle,
|
||||||
ref this.finalAttribs,
|
ref this.finalAttribs,
|
||||||
ref expiry
|
ref expiry
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -96,8 +94,6 @@ namespace NSspi.Contexts
|
|||||||
throw new SSPIException( "Failed to call AcceptSecurityContext", status );
|
throw new SSPIException( "Failed to call AcceptSecurityContext", status );
|
||||||
}
|
}
|
||||||
|
|
||||||
base.ContextHandle = newContextHandle;
|
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ using System.Runtime.ConstrainedExecution;
|
|||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using NSspi.Contexts;
|
||||||
|
|
||||||
namespace NSspi
|
namespace NSspi
|
||||||
{
|
{
|
||||||
@@ -83,4 +84,22 @@ namespace NSspi
|
|||||||
return status == SecurityStatus.OK;
|
return status == SecurityStatus.OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class SafeContextHandle : SafeSspiHandle
|
||||||
|
{
|
||||||
|
public SafeContextHandle()
|
||||||
|
: base()
|
||||||
|
{ }
|
||||||
|
|
||||||
|
protected override bool ReleaseHandle()
|
||||||
|
{
|
||||||
|
SecurityStatus status = ContextNativeMethods.DeleteSecurityContext(
|
||||||
|
ref base.rawHandle
|
||||||
|
);
|
||||||
|
|
||||||
|
base.ReleaseHandle();
|
||||||
|
|
||||||
|
return status == SecurityStatus.OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user