I can now successfully call InitializeSecurityContext and get a status of ContinueNeeded.
This commit is contained in:
@@ -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;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
20
Contexts/SecureBuffer.cs
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
18
Contexts/SecureBufferDataRep.cs
Normal file
18
Contexts/SecureBufferDataRep.cs
Normal 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
|
||||||
|
}
|
||||||
|
}
|
||||||
23
Contexts/SecureBufferDesc.cs
Normal file
23
Contexts/SecureBufferDesc.cs
Normal 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
26
Contexts/SecureBufferType.cs
Normal file
26
Contexts/SecureBufferType.cs
Normal 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
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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 );
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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" />
|
||||||
|
|||||||
@@ -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
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
21
Program.cs
21
Program.cs
@@ -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
|
||||||
|
|||||||
@@ -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 )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user