diff --git a/Contexts/ClientContext.cs b/Contexts/ClientContext.cs index 53baa40..9093f71 100644 --- a/Contexts/ClientContext.cs +++ b/Contexts/ClientContext.cs @@ -21,54 +21,30 @@ namespace NSspi.Contexts ContextAttrib newContextAttribs = 0; SecurityStatus status; - SecureBufferDesc descriptor; - SecureBuffer secureBuffer; - byte[] tokenBuffer = new byte[100000]; - GCHandle tokenBufferHandle; - GCHandle bufferArrayHandle; - GCHandle descriptorHandle; - SecureBuffer[] bufferArray; + SecureBuffer tokenBuffer = new SecureBuffer( new byte[12288], BufferType.Token ); + SecureBufferAdapter list = new SecureBufferAdapter( tokenBuffer ); - tokenBufferHandle = GCHandle.Alloc( tokenBuffer, GCHandleType.Pinned ); - - secureBuffer = new SecureBuffer(); - secureBuffer.Type = BufferType.Token; - secureBuffer.Count = tokenBuffer.Length; - secureBuffer.Buffer = tokenBufferHandle.AddrOfPinnedObject(); - - bufferArray = new SecureBuffer[1]; - bufferArray[0] = secureBuffer; - bufferArrayHandle = GCHandle.Alloc( bufferArray, GCHandleType.Pinned ); + using ( list ) + { + status = NativeMethods.InitializeSecurityContext_Client1( + ref credHandle, + IntPtr.Zero, + serverPrinc, + attribs, + 0, + SecureBufferDataRep.Network, + IntPtr.Zero, + 0, + ref newContextHandle, + list.Handle, + ref newContextAttribs, + ref expiry + ); + } - descriptor = new SecureBufferDesc(); - descriptor.Version = SecureBufferDesc.ApiVersion; - descriptor.NumBuffers = bufferArray.Length; - descriptor.Buffers = bufferArrayHandle.AddrOfPinnedObject(); - - descriptorHandle = GCHandle.Alloc( descriptor, GCHandleType.Pinned ); - - status = NativeMethods.InitializeSecurityContext_Client1( - ref credHandle, - IntPtr.Zero, - serverPrinc, - attribs, - 0, - SecureBufferDataRep.Network, - IntPtr.Zero, - 0, - ref newContextHandle, - descriptorHandle.AddrOfPinnedObject(), - ref newContextAttribs, - ref expiry - ); - - descriptorHandle.Free(); - bufferArrayHandle.Free(); - tokenBufferHandle.Free(); - - secureBuffer = bufferArray[0]; - - Console.Out.WriteLine( status ); + Console.Out.WriteLine( "Call status: " + status ); + Console.Out.WriteLine( "Buffer length: " + tokenBuffer.Length ); + Console.Out.WriteLine( "First bytes: " + tokenBuffer.Buffer[0] ); base.ContextHandle = newContextHandle; } diff --git a/NSspi.csproj b/NSspi.csproj index 807e806..baacf47 100644 --- a/NSspi.csproj +++ b/NSspi.csproj @@ -61,6 +61,7 @@ + diff --git a/SecureBuffer/SecureBuffer.cs b/SecureBuffer/SecureBuffer.cs index adfffcf..18d4e8c 100644 --- a/SecureBuffer/SecureBuffer.cs +++ b/SecureBuffer/SecureBuffer.cs @@ -8,7 +8,7 @@ using System.Threading.Tasks; namespace NSspi.Contexts { [StructLayout( LayoutKind.Sequential )] - public unsafe struct SecureBuffer + public unsafe struct SecureBufferInternal { public int Count; @@ -17,4 +17,20 @@ namespace NSspi.Contexts // A pointer to a byte[] public IntPtr Buffer; } + + public class SecureBuffer + { + public SecureBuffer( byte[] buffer, BufferType type ) + { + this.Buffer = buffer; + this.Type = type; + this.Length = this.Buffer.Length; + } + + public BufferType Type { get; set; } + + public byte[] Buffer { get; set; } + + public int Length { get; internal set; } + } } diff --git a/SecureBuffer/SecureBufferAdapter.cs b/SecureBuffer/SecureBufferAdapter.cs new file mode 100644 index 0000000..e4ecb48 --- /dev/null +++ b/SecureBuffer/SecureBufferAdapter.cs @@ -0,0 +1,108 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; + +namespace NSspi.Contexts +{ + public class SecureBufferAdapter : IDisposable + { + private bool disposed; + + private IList buffers; + + private GCHandle descriptorHandle; + + private GCHandle[] bufferHandles; + + private SecureBufferDescInternal descriptor; + private SecureBufferInternal[] bufferCarrier; + private GCHandle bufferCarrierHandle; + + public SecureBufferAdapter( SecureBuffer buffer ) + : this( new[] { buffer } ) + { + + } + + //[ReliabilityContract( Consistency.MayCorruptAppDomain, Cer.None)] + public SecureBufferAdapter( IList buffers ) + { + this.buffers = buffers; + + this.disposed = false; + + this.bufferHandles = new GCHandle[this.buffers.Count]; + this.bufferCarrier = new SecureBufferInternal[this.buffers.Count]; + + for ( int i = 0; i < this.buffers.Count; i++ ) + { + this.bufferHandles[i] = GCHandle.Alloc( this.buffers[i].Buffer, GCHandleType.Pinned ); + + this.bufferCarrier[i] = new SecureBufferInternal(); + this.bufferCarrier[i].Type = this.buffers[i].Type; + this.bufferCarrier[i].Count = this.buffers[i].Buffer.Length; + this.bufferCarrier[i].Buffer = bufferHandles[i].AddrOfPinnedObject(); + } + + this.bufferCarrierHandle = GCHandle.Alloc( bufferCarrier, GCHandleType.Pinned ); + + this.descriptor = new SecureBufferDescInternal(); + this.descriptor.Version = SecureBufferDescInternal.ApiVersion; + this.descriptor.NumBuffers = this.buffers.Count; + this.descriptor.Buffers = bufferCarrierHandle.AddrOfPinnedObject(); + + this.descriptorHandle = GCHandle.Alloc( descriptor, GCHandleType.Pinned ); + } + + ~SecureBufferAdapter() + { + Dispose( false ); + } + + public IntPtr Handle + { + get + { + if ( this.disposed ) + { + throw new ObjectDisposedException( "Cannot use SecureBufferListHandle after it has been disposed" ); + } + + return this.descriptorHandle.AddrOfPinnedObject(); + } + } + + public void Dispose() + { + this.Dispose( true ); + GC.SuppressFinalize( this ); + } + + protected virtual void Dispose( bool disposing ) + { + if ( this.disposed == true ) { return; } + + if ( disposing ) + { + for ( int i = 0; i < this.buffers.Count; i++ ) + { + this.buffers[i].Length = this.bufferCarrier[i].Count; + } + } + + for ( int i = 0; i < this.bufferHandles.Length; i++ ) + { + this.bufferHandles[i].Free(); + } + + this.bufferCarrierHandle.Free(); + this.descriptorHandle.Free(); + + this.disposed = true; + } + + } +} diff --git a/SecureBuffer/SecureBufferDesc.cs b/SecureBuffer/SecureBufferDesc.cs index 5671e54..0fac74f 100644 --- a/SecureBuffer/SecureBufferDesc.cs +++ b/SecureBuffer/SecureBufferDesc.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Runtime.ConstrainedExecution; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; @@ -8,7 +9,7 @@ using System.Threading.Tasks; namespace NSspi.Contexts { [StructLayout( LayoutKind.Sequential)] - public unsafe struct SecureBufferDesc + public struct SecureBufferDescInternal { public int Version; public int NumBuffers; @@ -18,6 +19,4 @@ namespace NSspi.Contexts public const int ApiVersion = 0; } - - }