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.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;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,11 +43,6 @@ namespace NSspi.Contexts
|
||||
/// </summary>
|
||||
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>
|
||||
/// 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
|
||||
/// </summary>
|
||||
AcceptIntegrity = 0x00020000,
|
||||
|
||||
InitIdentify = 0x00020000,
|
||||
AcceptIdentify = 0x00080000,
|
||||
|
||||
/// <summary>
|
||||
/// An Schannel provider connection is instructed to not authenticate the server automatically.
|
||||
/// </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
|
||||
);
|
||||
|
||||
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 );
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
@@ -47,6 +48,10 @@
|
||||
<Compile Include="Contexts\ClientContext.cs" />
|
||||
<Compile Include="Contexts\Context.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="Credentials\ClientCredential.cs" />
|
||||
<Compile Include="Credentials\Credential.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
|
||||
);
|
||||
|
||||
|
||||
21
Program.cs
21
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
|
||||
|
||||
@@ -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 )
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user