I can now successfully call InitializeSecurityContext and get a status of ContinueNeeded.

This commit is contained in:
antiduh
2014-06-21 16:32:34 +00:00
parent cc0235262c
commit c64765fbdf
11 changed files with 210 additions and 36 deletions

View File

@@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Runtime.InteropServices;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
@@ -8,7 +9,7 @@ namespace NSspi.Contexts
{ {
public class ClientContext : Context public class ClientContext : Context
{ {
public ClientContext( ClientCredential cred, string serverPrinc, ContextReqAttrib attribs ) public ClientContext( ClientCredential cred, string serverPrinc, ContextAttrib attribs )
: base( cred ) : base( cred )
{ {
long credHandle = base.Credential.CredentialHandle; long credHandle = base.Credential.CredentialHandle;
@@ -17,26 +18,58 @@ namespace NSspi.Contexts
long newContextHandle = 0; long newContextHandle = 0;
long expiry = 0; long expiry = 0;
int newContextAttribs = 0; ContextAttrib newContextAttribs = 0;
SecurityStatus status; 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 );
descriptor = new SecureBufferDesc();
status = NativeMethods.InitializeSecurityContext_Client( 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 credHandle,
ref prevContextHandle, IntPtr.Zero,
serverPrinc, serverPrinc,
attribs,
0, 0,
0, SecureBufferDataRep.Network,
0,
IntPtr.Zero, IntPtr.Zero,
0, 0,
ref newContextHandle, ref newContextHandle,
IntPtr.Zero, descriptorHandle.AddrOfPinnedObject(),
ref newContextAttribs, ref newContextAttribs,
ref expiry ref expiry
); );
descriptorHandle.Free();
bufferArrayHandle.Free();
tokenBufferHandle.Free();
secureBuffer = bufferArray[0];
Console.Out.WriteLine( status );
base.ContextHandle = newContextHandle;
} }
} }

View File

@@ -43,11 +43,6 @@ namespace NSspi.Contexts
/// </summary> /// </summary>
ReplayDetect = 0x00000004, 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.
/// <summary> /// <summary>
/// Detect messages received out of sequence when using the message support functionality. /// 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 /// This flag implies all of the conditions specified by the Integrity flag - out-of-order sequence
@@ -126,6 +121,9 @@ namespace NSspi.Contexts
/// </summary> /// </summary>
AcceptIntegrity = 0x00020000, AcceptIntegrity = 0x00020000,
InitIdentify = 0x00020000,
AcceptIdentify = 0x00080000,
/// <summary> /// <summary>
/// An Schannel provider connection is instructed to not authenticate the server automatically. /// An Schannel provider connection is instructed to not authenticate the server automatically.
/// </summary> /// </summary>

20
Contexts/SecureBuffer.cs Normal file
View File

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

View File

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

View File

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

View File

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

View File

@@ -78,7 +78,7 @@ namespace NSspi
ref this.expiry ref this.expiry
); );
if ( status != SecurityStatus.Success ) if ( status != SecurityStatus.OK )
{ {
throw new SSPIException( "Failed to call AcquireCredentialHandle", status ); throw new SSPIException( "Failed to call AcquireCredentialHandle", status );
} }
@@ -117,7 +117,7 @@ namespace NSspi
ref carrier ref carrier
); );
if ( status == SecurityStatus.Success ) if ( status == SecurityStatus.OK )
{ {
name = Marshal.PtrToStringUni( carrier.Name ); name = Marshal.PtrToStringUni( carrier.Name );
NativeMethods.FreeContextBuffer( carrier.Name ); NativeMethods.FreeContextBuffer( carrier.Name );
@@ -155,7 +155,7 @@ namespace NSspi
this.disposed = true; this.disposed = true;
if ( disposing && result != SecurityStatus.Success ) if ( disposing && result != SecurityStatus.OK )
{ {
throw new SSPIException( "Failed to release credentials handle", result ); throw new SSPIException( "Failed to release credentials handle", result );
} }

View File

@@ -20,6 +20,7 @@
<DefineConstants>DEBUG;TRACE</DefineConstants> <DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType> <DebugType>pdbonly</DebugType>
@@ -47,6 +48,10 @@
<Compile Include="Contexts\ClientContext.cs" /> <Compile Include="Contexts\ClientContext.cs" />
<Compile Include="Contexts\Context.cs" /> <Compile Include="Contexts\Context.cs" />
<Compile Include="Contexts\ContextAttrib.cs" /> <Compile Include="Contexts\ContextAttrib.cs" />
<Compile Include="Contexts\SecureBuffer.cs" />
<Compile Include="Contexts\SecureBufferDataRep.cs" />
<Compile Include="Contexts\SecureBufferDesc.cs" />
<Compile Include="Contexts\SecureBufferType.cs" />
<Compile Include="Contexts\ServerContext.cs" /> <Compile Include="Contexts\ServerContext.cs" />
<Compile Include="Credentials\ClientCredential.cs" /> <Compile Include="Credentials\ClientCredential.cs" />
<Compile Include="Credentials\Credential.cs" /> <Compile Include="Credentials\Credential.cs" />

View File

@@ -1,4 +1,5 @@
using System; using NSspi.Contexts;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
@@ -11,6 +12,11 @@ namespace NSspi
{ {
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa374713(v=vs.85).aspx // 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( SECURITY_STATUS sResult = AcquireCredentialsHandle(
NULL, // [in] name of principal. NULL = principal of current security context NULL, // [in] name of principal. NULL = principal of current security context
@@ -166,18 +172,18 @@ namespace NSspi
CharSet = CharSet.Unicode, CharSet = CharSet.Unicode,
SetLastError = true SetLastError = true
)] )]
public static extern SecurityStatus InitializeSecurityContext_Client( public static extern SecurityStatus InitializeSecurityContext_Client1(
ref long credentialHandle, ref long credentialHandle,
ref long prevContextHandle, IntPtr zero,
string serverPrincipleName, string serverPrincipleName,
int requiredAttribs, ContextAttrib requiredAttribs,
int reserved1, int reserved1,
int dataRep, SecureBufferDataRep dataRep,
IntPtr inputBuffer, IntPtr inputBuffer,
int reserved2, int reserved2,
ref long newContextHandle, ref long newContextHandle,
IntPtr outputBuffer, IntPtr outputBuffer,
ref int contextAttribs, ref ContextAttrib contextAttribs,
ref long expiry ref long expiry
); );

View File

@@ -1,4 +1,5 @@
using System; using NSspi.Contexts;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
@@ -37,13 +38,23 @@ namespace NSspi
private static void CredTest() private static void CredTest()
{ {
Credential cred = null; ClientCredential cred = null;
ClientContext client;
try try
{ {
cred = new Credential( SecurityPackage.Negotiate, CredentialType.Client ); cred = new ClientCredential( SecurityPackage.Negotiate );
Console.Out.WriteLine( cred.Name );
string name = cred.Name; client = new ClientContext(
Console.Out.WriteLine( name ); cred,
"",
ContextAttrib.MutualAuth |
ContextAttrib.InitIdentify |
ContextAttrib.Confidentiality |
ContextAttrib.ReplayDetect |
ContextAttrib.SequenceDetect
);
Console.Out.Flush(); Console.Out.Flush();
} }
finally finally

View File

@@ -20,15 +20,49 @@ namespace NSspi
#define SEC_E_NO_CREDENTIALS _HRESULT_TYPEDEF_(0x8009030EL) #define SEC_E_NO_CREDENTIALS _HRESULT_TYPEDEF_(0x8009030EL)
*/ */
public enum SecurityStatus : uint public enum SecurityStatus : int
{ {
Success = 0, // Success / Informational
InsufficientMemory = 0x80090300, OK = 0x00000000,
InvalidHandle = 0x80090301, ContinueNeeded = unchecked( (int)0x00090312 ),
InternalError = 0x80090304, CompleteNeeded = unchecked( (int)0x00090313 ),
SecPkgNotFound = 0x80090305, CompAndContinue = unchecked( (int)0x00090314 ),
NotOwner = 0x80090306, ContextExpired = unchecked( (int)0x00090317 ),
NoCredentials = 0x8009030E, CredentialsNeeded = unchecked( (int)0x00090320 ),
UnknownCredentials = 0x8009030D 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 )
} }
} }