diff --git a/Contexts/ClientContext.cs b/Contexts/ClientContext.cs
index 209280a..53baa40 100644
--- a/Contexts/ClientContext.cs
+++ b/Contexts/ClientContext.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
@@ -8,7 +9,7 @@ namespace NSspi.Contexts
{
public class ClientContext : Context
{
- public ClientContext( ClientCredential cred, string serverPrinc, ContextReqAttrib attribs )
+ public ClientContext( ClientCredential cred, string serverPrinc, ContextAttrib attribs )
: base( cred )
{
long credHandle = base.Credential.CredentialHandle;
@@ -17,26 +18,58 @@ namespace NSspi.Contexts
long newContextHandle = 0;
long expiry = 0;
- int newContextAttribs = 0;
+ ContextAttrib newContextAttribs = 0;
SecurityStatus status;
+ SecureBufferDesc descriptor;
+ SecureBuffer secureBuffer;
+ byte[] tokenBuffer = new byte[100000];
+ GCHandle tokenBufferHandle;
+ GCHandle bufferArrayHandle;
+ GCHandle descriptorHandle;
+ SecureBuffer[] bufferArray;
+
+ 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 );
-
- status = NativeMethods.InitializeSecurityContext_Client(
+ 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,
- ref prevContextHandle,
+ IntPtr.Zero,
serverPrinc,
+ attribs,
0,
- 0,
- 0,
+ SecureBufferDataRep.Network,
IntPtr.Zero,
0,
ref newContextHandle,
- IntPtr.Zero,
+ descriptorHandle.AddrOfPinnedObject(),
ref newContextAttribs,
ref expiry
);
+ descriptorHandle.Free();
+ bufferArrayHandle.Free();
+ tokenBufferHandle.Free();
+
+ secureBuffer = bufferArray[0];
+
+ Console.Out.WriteLine( status );
+ base.ContextHandle = newContextHandle;
}
}
diff --git a/Contexts/ContextAttrib.cs b/Contexts/ContextAttrib.cs
index 9d2b5fb..2ead196 100644
--- a/Contexts/ContextAttrib.cs
+++ b/Contexts/ContextAttrib.cs
@@ -43,11 +43,6 @@ namespace NSspi.Contexts
///
ReplayDetect = 0x00000004,
- // The context must be allowed to detect out-of-order
- // delivery of packets later through the message support
- // functions. Use of this flag implies all of the
- // conditions specified by the Integrity flag.
-
///
/// Detect messages received out of sequence when using the message support functionality.
/// This flag implies all of the conditions specified by the Integrity flag - out-of-order sequence
@@ -126,6 +121,9 @@ namespace NSspi.Contexts
///
AcceptIntegrity = 0x00020000,
+ InitIdentify = 0x00020000,
+ AcceptIdentify = 0x00080000,
+
///
/// An Schannel provider connection is instructed to not authenticate the server automatically.
///
diff --git a/Contexts/SecureBuffer.cs b/Contexts/SecureBuffer.cs
new file mode 100644
index 0000000..adfffcf
--- /dev/null
+++ b/Contexts/SecureBuffer.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace NSspi.Contexts
+{
+ [StructLayout( LayoutKind.Sequential )]
+ public unsafe struct SecureBuffer
+ {
+ public int Count;
+
+ public BufferType Type;
+
+ // A pointer to a byte[]
+ public IntPtr Buffer;
+ }
+}
diff --git a/Contexts/SecureBufferDataRep.cs b/Contexts/SecureBufferDataRep.cs
new file mode 100644
index 0000000..734fd26
--- /dev/null
+++ b/Contexts/SecureBufferDataRep.cs
@@ -0,0 +1,18 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace NSspi.Contexts
+{
+ public enum SecureBufferDataRep : int
+ {
+ /*
+ #define SECURITY_NATIVE_DREP 0x00000010
+ #define SECURITY_NETWORK_DREP 0x00000000
+ */
+ Nativee = 0x10,
+ Network = 0x00
+ }
+}
diff --git a/Contexts/SecureBufferDesc.cs b/Contexts/SecureBufferDesc.cs
new file mode 100644
index 0000000..5671e54
--- /dev/null
+++ b/Contexts/SecureBufferDesc.cs
@@ -0,0 +1,23 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace NSspi.Contexts
+{
+ [StructLayout( LayoutKind.Sequential)]
+ public unsafe struct SecureBufferDesc
+ {
+ public int Version;
+ public int NumBuffers;
+
+ // A pointer to a SecureBuffer[]
+ public IntPtr Buffers;
+
+ public const int ApiVersion = 0;
+ }
+
+
+}
diff --git a/Contexts/SecureBufferType.cs b/Contexts/SecureBufferType.cs
new file mode 100644
index 0000000..fdab381
--- /dev/null
+++ b/Contexts/SecureBufferType.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace NSspi.Contexts
+{
+ public enum BufferType : int
+ {
+ Empty = 0x00,
+ Data = 0x01,
+ Token = 0x02,
+ Parameters = 0x03,
+ Missing = 0x04,
+ Extra = 0x05,
+ Trailer = 0x06,
+ Header = 0x07,
+ Padding = 0x09,
+ Stream = 0x0A,
+ ChannelBindings = 0x0E,
+ TargetHost = 0x10,
+ ReadOnlyFlag = unchecked( (int)0x80000000 ),
+ ReadOnlyWithChecksum = 0x10000000
+ }
+}
diff --git a/Credentials/Credential.cs b/Credentials/Credential.cs
index 724759a..eb3e042 100644
--- a/Credentials/Credential.cs
+++ b/Credentials/Credential.cs
@@ -78,7 +78,7 @@ namespace NSspi
ref this.expiry
);
- if ( status != SecurityStatus.Success )
+ if ( status != SecurityStatus.OK )
{
throw new SSPIException( "Failed to call AcquireCredentialHandle", status );
}
@@ -117,7 +117,7 @@ namespace NSspi
ref carrier
);
- if ( status == SecurityStatus.Success )
+ if ( status == SecurityStatus.OK )
{
name = Marshal.PtrToStringUni( carrier.Name );
NativeMethods.FreeContextBuffer( carrier.Name );
@@ -155,7 +155,7 @@ namespace NSspi
this.disposed = true;
- if ( disposing && result != SecurityStatus.Success )
+ if ( disposing && result != SecurityStatus.OK )
{
throw new SSPIException( "Failed to release credentials handle", result );
}
diff --git a/NSspi.csproj b/NSspi.csproj
index e9ebffb..f23a55a 100644
--- a/NSspi.csproj
+++ b/NSspi.csproj
@@ -20,6 +20,7 @@
DEBUG;TRACE
prompt
4
+ true
pdbonly
@@ -47,6 +48,10 @@
+
+
+
+
diff --git a/NativeMethods.cs b/NativeMethods.cs
index 85b8772..693108d 100644
--- a/NativeMethods.cs
+++ b/NativeMethods.cs
@@ -1,4 +1,5 @@
-using System;
+using NSspi.Contexts;
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
@@ -11,6 +12,11 @@ namespace NSspi
{
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa374713(v=vs.85).aspx
+ // The REMSSPI sample:
+
+ // A C++ pure client/server example:
+ // http://msdn.microsoft.com/en-us/library/windows/desktop/aa380536(v=vs.85).aspx
+
/*
SECURITY_STATUS sResult = AcquireCredentialsHandle(
NULL, // [in] name of principal. NULL = principal of current security context
@@ -166,18 +172,18 @@ namespace NSspi
CharSet = CharSet.Unicode,
SetLastError = true
)]
- public static extern SecurityStatus InitializeSecurityContext_Client(
+ public static extern SecurityStatus InitializeSecurityContext_Client1(
ref long credentialHandle,
- ref long prevContextHandle,
+ IntPtr zero,
string serverPrincipleName,
- int requiredAttribs,
+ ContextAttrib requiredAttribs,
int reserved1,
- int dataRep,
+ SecureBufferDataRep dataRep,
IntPtr inputBuffer,
int reserved2,
ref long newContextHandle,
IntPtr outputBuffer,
- ref int contextAttribs,
+ ref ContextAttrib contextAttribs,
ref long expiry
);
diff --git a/Program.cs b/Program.cs
index dc35a5d..2327a41 100644
--- a/Program.cs
+++ b/Program.cs
@@ -1,4 +1,5 @@
-using System;
+using NSspi.Contexts;
+using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
@@ -37,13 +38,23 @@ namespace NSspi
private static void CredTest()
{
- Credential cred = null;
+ ClientCredential cred = null;
+ ClientContext client;
try
{
- cred = new Credential( SecurityPackage.Negotiate, CredentialType.Client );
+ cred = new ClientCredential( SecurityPackage.Negotiate );
+ Console.Out.WriteLine( cred.Name );
- string name = cred.Name;
- Console.Out.WriteLine( name );
+ client = new ClientContext(
+ cred,
+ "",
+ ContextAttrib.MutualAuth |
+ ContextAttrib.InitIdentify |
+ ContextAttrib.Confidentiality |
+ ContextAttrib.ReplayDetect |
+ ContextAttrib.SequenceDetect
+ );
+
Console.Out.Flush();
}
finally
diff --git a/SecurityStatus.cs b/SecurityStatus.cs
index 62ed767..34936b8 100644
--- a/SecurityStatus.cs
+++ b/SecurityStatus.cs
@@ -20,15 +20,49 @@ namespace NSspi
#define SEC_E_NO_CREDENTIALS _HRESULT_TYPEDEF_(0x8009030EL)
*/
- public enum SecurityStatus : uint
+ public enum SecurityStatus : int
{
- Success = 0,
- InsufficientMemory = 0x80090300,
- InvalidHandle = 0x80090301,
- InternalError = 0x80090304,
- SecPkgNotFound = 0x80090305,
- NotOwner = 0x80090306,
- NoCredentials = 0x8009030E,
- UnknownCredentials = 0x8009030D
+ // Success / Informational
+ OK = 0x00000000,
+ ContinueNeeded = unchecked( (int)0x00090312 ),
+ CompleteNeeded = unchecked( (int)0x00090313 ),
+ CompAndContinue = unchecked( (int)0x00090314 ),
+ ContextExpired = unchecked( (int)0x00090317 ),
+ CredentialsNeeded = unchecked( (int)0x00090320 ),
+ Renegotiate = unchecked( (int)0x00090321 ),
+
+ // Errors
+ OutOfMemory = unchecked( (int)0x80090300 ),
+ InvalidHandle = unchecked( (int)0x80090301 ),
+ Unsupported = unchecked( (int)0x80090302 ),
+ TargetUnknown = unchecked( (int)0x80090303 ),
+ InternalError = unchecked( (int)0x80090304 ),
+ PackageNotFound = unchecked( (int)0x80090305 ),
+ NotOwner = unchecked( (int)0x80090306 ),
+ CannotInstall = unchecked( (int)0x80090307 ),
+ InvalidToken = unchecked( (int)0x80090308 ),
+ CannotPack = unchecked( (int)0x80090309 ),
+ QopNotSupported = unchecked( (int)0x8009030A ),
+ NoImpersonation = unchecked( (int)0x8009030B ),
+ LogonDenied = unchecked( (int)0x8009030C ),
+ UnknownCredentials = unchecked( (int)0x8009030D ),
+ NoCredentials = unchecked( (int)0x8009030E ),
+ MessageAltered = unchecked( (int)0x8009030F ),
+ OutOfSequence = unchecked( (int)0x80090310 ),
+ NoAuthenticatingAuthority = unchecked( (int)0x80090311 ),
+ IncompleteMessage = unchecked( (int)0x80090318 ),
+ IncompleteCredentials = unchecked( (int)0x80090320 ),
+ BufferNotEnough = unchecked( (int)0x80090321 ),
+ WrongPrincipal = unchecked( (int)0x80090322 ),
+ TimeSkew = unchecked( (int)0x80090324 ),
+ UntrustedRoot = unchecked( (int)0x80090325 ),
+ IllegalMessage = unchecked( (int)0x80090326 ),
+ CertUnknown = unchecked( (int)0x80090327 ),
+ CertExpired = unchecked( (int)0x80090328 ),
+ AlgorithmMismatch = unchecked( (int)0x80090331 ),
+ SecurityQosFailed = unchecked( (int)0x80090332 ),
+ SmartcardLogonRequired = unchecked( (int)0x8009033E ),
+ UnsupportedPreauth = unchecked( (int)0x80090343 ),
+ BadBinding = unchecked( (int)0x80090346 )
}
}