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