A little cleaner, and we can complete negotiation.
This commit is contained in:
@@ -50,14 +50,18 @@ namespace NSspi.Contexts
|
|||||||
}
|
}
|
||||||
|
|
||||||
outTokenBuffer = new SecureBuffer( new byte[12288], BufferType.Token );
|
outTokenBuffer = new SecureBuffer( new byte[12288], BufferType.Token );
|
||||||
serverBuffer = new SecureBuffer( serverToken, BufferType.Token );
|
|
||||||
|
|
||||||
|
serverBuffer = null;
|
||||||
|
if ( serverToken != null )
|
||||||
|
{
|
||||||
|
serverBuffer = new SecureBuffer( serverToken, BufferType.Token );
|
||||||
|
}
|
||||||
|
|
||||||
using ( outAdapter = new SecureBufferAdapter( outTokenBuffer ) )
|
using ( outAdapter = new SecureBufferAdapter( outTokenBuffer ) )
|
||||||
{
|
{
|
||||||
if ( prevContextHandle == 0 )
|
if ( prevContextHandle == 0 )
|
||||||
{
|
{
|
||||||
status = NativeMethods.InitializeSecurityContext_1(
|
status = ContextNativeMethods.InitializeSecurityContext_1(
|
||||||
ref credHandle,
|
ref credHandle,
|
||||||
IntPtr.Zero,
|
IntPtr.Zero,
|
||||||
this.serverPrinc,
|
this.serverPrinc,
|
||||||
@@ -76,7 +80,7 @@ namespace NSspi.Contexts
|
|||||||
{
|
{
|
||||||
using ( serverAdapter = new SecureBufferAdapter( serverBuffer ) )
|
using ( serverAdapter = new SecureBufferAdapter( serverBuffer ) )
|
||||||
{
|
{
|
||||||
status = NativeMethods.InitializeSecurityContext_2(
|
status = ContextNativeMethods.InitializeSecurityContext_2(
|
||||||
ref credHandle,
|
ref credHandle,
|
||||||
ref prevContextHandle,
|
ref prevContextHandle,
|
||||||
this.serverPrinc,
|
this.serverPrinc,
|
||||||
|
|||||||
@@ -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.Text;
|
using System.Text;
|
||||||
@@ -42,7 +43,7 @@ namespace NSspi
|
|||||||
}
|
}
|
||||||
|
|
||||||
long contextHandleCopy = this.ContextHandle;
|
long contextHandleCopy = this.ContextHandle;
|
||||||
NativeMethods.DeleteSecurityContext( ref contextHandleCopy );
|
ContextNativeMethods.DeleteSecurityContext( ref contextHandleCopy );
|
||||||
|
|
||||||
this.ContextHandle = 0;
|
this.ContextHandle = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -61,5 +61,92 @@ namespace NSspi.Contexts
|
|||||||
ref ContextAttrib outputAttribs,
|
ref ContextAttrib outputAttribs,
|
||||||
ref long expiry
|
ref long expiry
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// When used in the ClientContext:
|
||||||
|
/*
|
||||||
|
SECURITY_STATUS sResult = InitializeSecurityContext(
|
||||||
|
phCredential, // [in] handle to the credentials
|
||||||
|
NULL, // [in/out] handle of partially formed context. Always NULL the first time through
|
||||||
|
pwszServerPrincipalName, // [in] name of the target of the context. Not needed by NTLM
|
||||||
|
reqContextAttributes, // [in] required context attributes
|
||||||
|
0, // [reserved] reserved; must be zero
|
||||||
|
SECURITY_NATIVE_DREP, // [in] data representation on the target
|
||||||
|
NULL, // [in/out] pointer to the input buffers. Always NULL the first time through
|
||||||
|
0, // [reserved] reserved; must be zero
|
||||||
|
this->contextHandle, // [in/out] receives the new context handle (must be pre-allocated)
|
||||||
|
&outBuffDesc, // [out] pointer to the output buffers
|
||||||
|
pulContextAttributes, // [out] receives the context attributes
|
||||||
|
&tsLifeSpan // [out] receives the life span of the security context
|
||||||
|
);
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
SECURITY_STATUS SEC_Entry InitializeSecurityContext(
|
||||||
|
_In_opt_ PCredHandle phCredential,
|
||||||
|
_In_opt_ PCtxtHandle phContext,
|
||||||
|
_In_opt_ SEC_CHAR *pszTargetName,
|
||||||
|
_In_ ULONG fContextReq,
|
||||||
|
_In_ ULONG Reserved1,
|
||||||
|
_In_ ULONG TargetDataRep,
|
||||||
|
_In_opt_ PSecBufferDesc pInput,
|
||||||
|
_In_ ULONG Reserved2,
|
||||||
|
_Inout_opt_ PCtxtHandle phNewContext,
|
||||||
|
_Inout_opt_ PSecBufferDesc pOutput,
|
||||||
|
_Out_ PULONG pfContextAttr,
|
||||||
|
_Out_opt_ PTimeStamp ptsExpiry
|
||||||
|
);
|
||||||
|
*/
|
||||||
|
|
||||||
|
[DllImport(
|
||||||
|
"Secur32.dll",
|
||||||
|
EntryPoint = "InitializeSecurityContext",
|
||||||
|
CallingConvention = CallingConvention.Winapi,
|
||||||
|
CharSet = CharSet.Unicode,
|
||||||
|
SetLastError = true
|
||||||
|
)]
|
||||||
|
public static extern SecurityStatus InitializeSecurityContext_1(
|
||||||
|
ref long credentialHandle,
|
||||||
|
IntPtr zero,
|
||||||
|
string serverPrincipleName,
|
||||||
|
ContextAttrib requiredAttribs,
|
||||||
|
int reserved1,
|
||||||
|
SecureBufferDataRep dataRep,
|
||||||
|
IntPtr inputBuffer,
|
||||||
|
int reserved2,
|
||||||
|
ref long newContextHandle,
|
||||||
|
IntPtr outputBuffer,
|
||||||
|
ref ContextAttrib contextAttribs,
|
||||||
|
ref long expiry
|
||||||
|
);
|
||||||
|
|
||||||
|
[DllImport(
|
||||||
|
"Secur32.dll",
|
||||||
|
EntryPoint = "InitializeSecurityContext",
|
||||||
|
CallingConvention = CallingConvention.Winapi,
|
||||||
|
CharSet = CharSet.Unicode,
|
||||||
|
SetLastError = true
|
||||||
|
)]
|
||||||
|
public static extern SecurityStatus InitializeSecurityContext_2(
|
||||||
|
ref long credentialHandle,
|
||||||
|
ref long previousHandle,
|
||||||
|
string serverPrincipleName,
|
||||||
|
ContextAttrib requiredAttribs,
|
||||||
|
int reserved1,
|
||||||
|
SecureBufferDataRep dataRep,
|
||||||
|
IntPtr inputBuffer,
|
||||||
|
int reserved2,
|
||||||
|
ref long newContextHandle,
|
||||||
|
IntPtr outputBuffer,
|
||||||
|
ref ContextAttrib contextAttribs,
|
||||||
|
ref long expiry
|
||||||
|
);
|
||||||
|
|
||||||
|
[DllImport(
|
||||||
|
"Secur32.dll",
|
||||||
|
EntryPoint = "DeleteSecurityContext",
|
||||||
|
CallingConvention = CallingConvention.Winapi,
|
||||||
|
CharSet = CharSet.Unicode,
|
||||||
|
SetLastError = true
|
||||||
|
)]
|
||||||
|
public static extern SecurityStatus DeleteSecurityContext( ref long contextHandle );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,6 +75,16 @@ namespace NSspi.Contexts
|
|||||||
{
|
{
|
||||||
nextToken = null;
|
nextToken = null;
|
||||||
this.complete = true;
|
this.complete = true;
|
||||||
|
|
||||||
|
if ( outBuffer.Length != 0 )
|
||||||
|
{
|
||||||
|
nextToken = new byte[outBuffer.Length];
|
||||||
|
Array.Copy( outBuffer.Buffer, nextToken, nextToken.Length );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nextToken = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if ( status == SecurityStatus.ContinueNeeded )
|
else if ( status == SecurityStatus.ContinueNeeded )
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -48,6 +48,7 @@
|
|||||||
<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\ContextNativeMethods.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" />
|
||||||
|
|||||||
@@ -129,93 +129,5 @@ namespace NSspi
|
|||||||
public IntPtr Name;
|
public IntPtr Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// When used in the ClientContext:
|
|
||||||
/*
|
|
||||||
SECURITY_STATUS sResult = InitializeSecurityContext(
|
|
||||||
phCredential, // [in] handle to the credentials
|
|
||||||
NULL, // [in/out] handle of partially formed context. Always NULL the first time through
|
|
||||||
pwszServerPrincipalName, // [in] name of the target of the context. Not needed by NTLM
|
|
||||||
reqContextAttributes, // [in] required context attributes
|
|
||||||
0, // [reserved] reserved; must be zero
|
|
||||||
SECURITY_NATIVE_DREP, // [in] data representation on the target
|
|
||||||
NULL, // [in/out] pointer to the input buffers. Always NULL the first time through
|
|
||||||
0, // [reserved] reserved; must be zero
|
|
||||||
this->contextHandle, // [in/out] receives the new context handle (must be pre-allocated)
|
|
||||||
&outBuffDesc, // [out] pointer to the output buffers
|
|
||||||
pulContextAttributes, // [out] receives the context attributes
|
|
||||||
&tsLifeSpan // [out] receives the life span of the security context
|
|
||||||
);
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
SECURITY_STATUS SEC_Entry InitializeSecurityContext(
|
|
||||||
_In_opt_ PCredHandle phCredential,
|
|
||||||
_In_opt_ PCtxtHandle phContext,
|
|
||||||
_In_opt_ SEC_CHAR *pszTargetName,
|
|
||||||
_In_ ULONG fContextReq,
|
|
||||||
_In_ ULONG Reserved1,
|
|
||||||
_In_ ULONG TargetDataRep,
|
|
||||||
_In_opt_ PSecBufferDesc pInput,
|
|
||||||
_In_ ULONG Reserved2,
|
|
||||||
_Inout_opt_ PCtxtHandle phNewContext,
|
|
||||||
_Inout_opt_ PSecBufferDesc pOutput,
|
|
||||||
_Out_ PULONG pfContextAttr,
|
|
||||||
_Out_opt_ PTimeStamp ptsExpiry
|
|
||||||
);
|
|
||||||
*/
|
|
||||||
|
|
||||||
[DllImport(
|
|
||||||
"Secur32.dll",
|
|
||||||
EntryPoint = "InitializeSecurityContext",
|
|
||||||
CallingConvention = CallingConvention.Winapi,
|
|
||||||
CharSet = CharSet.Unicode,
|
|
||||||
SetLastError = true
|
|
||||||
)]
|
|
||||||
public static extern SecurityStatus InitializeSecurityContext_1(
|
|
||||||
ref long credentialHandle,
|
|
||||||
IntPtr zero,
|
|
||||||
string serverPrincipleName,
|
|
||||||
ContextAttrib requiredAttribs,
|
|
||||||
int reserved1,
|
|
||||||
SecureBufferDataRep dataRep,
|
|
||||||
IntPtr inputBuffer,
|
|
||||||
int reserved2,
|
|
||||||
ref long newContextHandle,
|
|
||||||
IntPtr outputBuffer,
|
|
||||||
ref ContextAttrib contextAttribs,
|
|
||||||
ref long expiry
|
|
||||||
);
|
|
||||||
|
|
||||||
[DllImport(
|
|
||||||
"Secur32.dll",
|
|
||||||
EntryPoint = "InitializeSecurityContext",
|
|
||||||
CallingConvention = CallingConvention.Winapi,
|
|
||||||
CharSet = CharSet.Unicode,
|
|
||||||
SetLastError = true
|
|
||||||
)]
|
|
||||||
public static extern SecurityStatus InitializeSecurityContext_2(
|
|
||||||
ref long credentialHandle,
|
|
||||||
ref long previousHandle,
|
|
||||||
string serverPrincipleName,
|
|
||||||
ContextAttrib requiredAttribs,
|
|
||||||
int reserved1,
|
|
||||||
SecureBufferDataRep dataRep,
|
|
||||||
IntPtr inputBuffer,
|
|
||||||
int reserved2,
|
|
||||||
ref long newContextHandle,
|
|
||||||
IntPtr outputBuffer,
|
|
||||||
ref ContextAttrib contextAttribs,
|
|
||||||
ref long expiry
|
|
||||||
);
|
|
||||||
|
|
||||||
[DllImport(
|
|
||||||
"Secur32.dll",
|
|
||||||
EntryPoint = "DeleteSecurityContext",
|
|
||||||
CallingConvention = CallingConvention.Winapi,
|
|
||||||
CharSet = CharSet.Unicode,
|
|
||||||
SetLastError = true
|
|
||||||
)]
|
|
||||||
public static extern SecurityStatus DeleteSecurityContext( ref long contextHandle );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
66
Program.cs
66
Program.cs
@@ -38,15 +38,25 @@ namespace NSspi
|
|||||||
|
|
||||||
private static void CredTest()
|
private static void CredTest()
|
||||||
{
|
{
|
||||||
ClientCredential cred = null;
|
ClientCredential clientCred = null;
|
||||||
ClientContext client;
|
ClientContext client = null;
|
||||||
|
|
||||||
|
ServerCredential serverCred = null;
|
||||||
|
ServerContext server = null;
|
||||||
|
|
||||||
|
byte[] clientToken;
|
||||||
|
byte[] serverToken;
|
||||||
|
|
||||||
|
SecurityStatus clientStatus;
|
||||||
|
SecurityStatus serverStatus;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
cred = new ClientCredential( SecurityPackage.Negotiate );
|
clientCred = new ClientCredential( SecurityPackage.Negotiate );
|
||||||
Console.Out.WriteLine( cred.Name );
|
Console.Out.WriteLine( clientCred.Name );
|
||||||
|
|
||||||
client = new ClientContext(
|
client = new ClientContext(
|
||||||
cred,
|
clientCred,
|
||||||
"",
|
"",
|
||||||
ContextAttrib.MutualAuth |
|
ContextAttrib.MutualAuth |
|
||||||
ContextAttrib.InitIdentify |
|
ContextAttrib.InitIdentify |
|
||||||
@@ -54,14 +64,56 @@ namespace NSspi
|
|||||||
ContextAttrib.ReplayDetect |
|
ContextAttrib.ReplayDetect |
|
||||||
ContextAttrib.SequenceDetect
|
ContextAttrib.SequenceDetect
|
||||||
);
|
);
|
||||||
|
|
||||||
|
serverCred = new ServerCredential( SecurityPackage.Negotiate );
|
||||||
|
|
||||||
|
server = new ServerContext(
|
||||||
|
serverCred,
|
||||||
|
ContextAttrib.MutualAuth |
|
||||||
|
ContextAttrib.AcceptIdentify |
|
||||||
|
ContextAttrib.Confidentiality |
|
||||||
|
ContextAttrib.ReplayDetect |
|
||||||
|
ContextAttrib.SequenceDetect
|
||||||
|
);
|
||||||
|
|
||||||
|
clientToken = null;
|
||||||
|
serverToken = null;
|
||||||
|
|
||||||
|
clientStatus = client.Init( serverToken, out clientToken );
|
||||||
|
|
||||||
|
while ( true )
|
||||||
|
{
|
||||||
|
serverStatus = server.AcceptToken( clientToken, out serverToken );
|
||||||
|
|
||||||
|
if ( serverStatus != SecurityStatus.ContinueNeeded && clientStatus != SecurityStatus.ContinueNeeded ) { break; }
|
||||||
|
|
||||||
|
clientStatus = client.Init( serverToken, out clientToken );
|
||||||
|
|
||||||
|
if ( serverStatus != SecurityStatus.ContinueNeeded && clientStatus != SecurityStatus.ContinueNeeded ) { break; }
|
||||||
|
}
|
||||||
|
|
||||||
Console.Out.Flush();
|
Console.Out.Flush();
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
if( cred != null )
|
if ( server != null )
|
||||||
{
|
{
|
||||||
cred.Dispose();
|
server.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( client != null )
|
||||||
|
{
|
||||||
|
client.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
if( clientCred != null )
|
||||||
|
{
|
||||||
|
clientCred.Dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( serverCred != null )
|
||||||
|
{
|
||||||
|
serverCred.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user