Added support for querying the context's user name and authority. Still working my way up to EncryptMessage.
This commit is contained in:
@@ -4,6 +4,7 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace NSspi
|
namespace NSspi
|
||||||
{
|
{
|
||||||
@@ -27,6 +28,22 @@ namespace NSspi
|
|||||||
|
|
||||||
public long ContextHandle { get; protected set; }
|
public long ContextHandle { get; protected set; }
|
||||||
|
|
||||||
|
public string AuthorityName
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return QueryContextString( ContextQueryAttrib.Authority );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string ContextUserName
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return QueryContextString( ContextQueryAttrib.Names );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
Dispose( true );
|
Dispose( true );
|
||||||
@@ -50,8 +67,79 @@ namespace NSspi
|
|||||||
this.disposed = true;
|
this.disposed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Encrypts the byte array using the context's session key. The encrypted data is stored in a new
|
||||||
|
/// byte array, which is formatted such that the first four bytes are the original message length
|
||||||
|
/// as an unsigned integer and the remaining bytes are the encrypted bytes of the original message.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="input"></param>
|
||||||
|
/// <returns></returns>
|
||||||
public byte[] Encrypt( byte[] input )
|
public byte[] Encrypt( byte[] input )
|
||||||
{
|
{
|
||||||
|
// The message is encrypted in place in the buffer we provide to Win32 EncryptMessage
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal SecPkgContext_Sizes QueryBufferSizes()
|
||||||
|
{
|
||||||
|
SecPkgContext_Sizes sizes = new SecPkgContext_Sizes();
|
||||||
|
long contextHandle = this.ContextHandle;
|
||||||
|
SecurityStatus status;
|
||||||
|
|
||||||
|
status = ContextNativeMethods.QueryContextAttributes_Sizes(
|
||||||
|
ref contextHandle,
|
||||||
|
ContextQueryAttrib.Sizes,
|
||||||
|
ref sizes
|
||||||
|
);
|
||||||
|
|
||||||
|
if( status != SecurityStatus.OK )
|
||||||
|
{
|
||||||
|
throw new SSPIException( "Failed to query context buffer size attributes", status );
|
||||||
|
}
|
||||||
|
|
||||||
|
return sizes;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal string QueryContextString(ContextQueryAttrib attrib)
|
||||||
|
{
|
||||||
|
SecPkgContext_String stringAttrib;
|
||||||
|
long contextHandle;
|
||||||
|
SecurityStatus status;
|
||||||
|
string result;
|
||||||
|
|
||||||
|
if( attrib != ContextQueryAttrib.Names && attrib != ContextQueryAttrib.Authority )
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException( "QueryContextString can only be used to query context Name and Authority attributes" );
|
||||||
|
}
|
||||||
|
|
||||||
|
stringAttrib = new SecPkgContext_String();
|
||||||
|
|
||||||
|
contextHandle = this.ContextHandle;
|
||||||
|
|
||||||
|
status = ContextNativeMethods.QueryContextAttributes_String(
|
||||||
|
ref contextHandle,
|
||||||
|
attrib,
|
||||||
|
ref stringAttrib
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
if( status == SecurityStatus.Unsupported )
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
else if( status == SecurityStatus.OK )
|
||||||
|
{
|
||||||
|
// TODO handle this safely.
|
||||||
|
result = Marshal.PtrToStringUni( stringAttrib.StringResult );
|
||||||
|
ContextNativeMethods.FreeContextBuffer( stringAttrib.StringResult );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new SSPIException( "Failed to query the context's associated user name", status );
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -151,7 +151,7 @@ namespace NSspi.Contexts
|
|||||||
|
|
||||||
[DllImport(
|
[DllImport(
|
||||||
"Secur32.dll",
|
"Secur32.dll",
|
||||||
EntryPoint = "EncryptMessag",
|
EntryPoint = "EncryptMessage",
|
||||||
CallingConvention = CallingConvention.Winapi,
|
CallingConvention = CallingConvention.Winapi,
|
||||||
CharSet = CharSet.Unicode,
|
CharSet = CharSet.Unicode,
|
||||||
SetLastError = true
|
SetLastError = true
|
||||||
@@ -162,5 +162,35 @@ namespace NSspi.Contexts
|
|||||||
IntPtr bufferDescriptor,
|
IntPtr bufferDescriptor,
|
||||||
int sequenceNumber
|
int sequenceNumber
|
||||||
);
|
);
|
||||||
|
|
||||||
|
[DllImport(
|
||||||
|
"Secur32.dll",
|
||||||
|
EntryPoint = "QueryContextAttributes",
|
||||||
|
CallingConvention = CallingConvention.Winapi,
|
||||||
|
CharSet = CharSet.Unicode )]
|
||||||
|
public static extern SecurityStatus QueryContextAttributes_Sizes(
|
||||||
|
ref long contextHandle,
|
||||||
|
ContextQueryAttrib attrib,
|
||||||
|
ref SecPkgContext_Sizes sizes
|
||||||
|
);
|
||||||
|
|
||||||
|
[DllImport(
|
||||||
|
"Secur32.dll",
|
||||||
|
EntryPoint = "QueryContextAttributes",
|
||||||
|
CallingConvention = CallingConvention.Winapi,
|
||||||
|
CharSet = CharSet.Unicode )]
|
||||||
|
public static extern SecurityStatus QueryContextAttributes_String(
|
||||||
|
ref long contextHandle,
|
||||||
|
ContextQueryAttrib attrib,
|
||||||
|
ref SecPkgContext_String names
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
[DllImport(
|
||||||
|
"Secur32.dll",
|
||||||
|
EntryPoint = "FreeContextBuffer",
|
||||||
|
CallingConvention = CallingConvention.Winapi,
|
||||||
|
CharSet = CharSet.Unicode )]
|
||||||
|
public static extern SecurityStatus FreeContextBuffer( IntPtr handle );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
44
Contexts/ContextQueries.cs
Normal file
44
Contexts/ContextQueries.cs
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
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 struct SecPkgContext_Sizes
|
||||||
|
{
|
||||||
|
public int MaxToken;
|
||||||
|
public int MaxSignature;
|
||||||
|
public int BlockSize;
|
||||||
|
public int SecurityTrailer;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout( LayoutKind.Sequential )]
|
||||||
|
public struct SecPkgContext_String
|
||||||
|
{
|
||||||
|
public IntPtr StringResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class ContextQueryHandle : SafeHandle
|
||||||
|
{
|
||||||
|
public ContextQueryHandle() :
|
||||||
|
base( IntPtr.Zero, true )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool IsInvalid
|
||||||
|
{
|
||||||
|
get { return base.handle.Equals( IntPtr.Zero ); }
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool ReleaseHandle()
|
||||||
|
{
|
||||||
|
return ContextNativeMethods.FreeContextBuffer( base.handle ) == SecurityStatus.OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
40
Contexts/ContextQueryAttrib.cs
Normal file
40
Contexts/ContextQueryAttrib.cs
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace NSspi.Contexts
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Defines the types of queries that can be performed with QueryContextAttribute.
|
||||||
|
/// Each query has a different result buffer.
|
||||||
|
/// </summary>
|
||||||
|
public enum ContextQueryAttrib : int
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Queries the buffer size parameters when performing message functions, such
|
||||||
|
/// as encryption, decryption, signing and signature validation.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Results for a query of this type are stored in a Win32 SecPkgContext_Sizes structure.
|
||||||
|
/// </remarks>
|
||||||
|
Sizes = 0,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Queries the context for the name of the user assocated with a security context.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Results for a query of this type are stored in a Win32 SecPkgContext_Name structure.
|
||||||
|
/// </remarks>
|
||||||
|
Names = 1,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Queries the name of the authenticating authority for the security context.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Results for a query of this type are stored in a Win32 SecPkgContext_Authority structure.
|
||||||
|
/// </remarks>
|
||||||
|
Authority = 6,
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -49,6 +49,8 @@
|
|||||||
<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\ContextNativeMethods.cs" />
|
||||||
|
<Compile Include="Contexts\ContextQueries.cs" />
|
||||||
|
<Compile Include="Contexts\ContextQueryAttrib.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" />
|
||||||
|
|||||||
11
Program.cs
11
Program.cs
@@ -91,7 +91,16 @@ namespace NSspi
|
|||||||
|
|
||||||
if ( serverStatus != SecurityStatus.ContinueNeeded && clientStatus != SecurityStatus.ContinueNeeded ) { break; }
|
if ( serverStatus != SecurityStatus.ContinueNeeded && clientStatus != SecurityStatus.ContinueNeeded ) { break; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Console.Out.WriteLine( "Server authority: " + server.AuthorityName );
|
||||||
|
Console.Out.WriteLine( "Server context user: " + server.ContextUserName );
|
||||||
|
|
||||||
|
Console.Out.WriteLine();
|
||||||
|
|
||||||
|
Console.Out.WriteLine( "Client authority: " + client.AuthorityName );
|
||||||
|
Console.Out.WriteLine( "Client context user: " + client.ContextUserName );
|
||||||
|
|
||||||
Console.Out.Flush();
|
Console.Out.Flush();
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
|
|||||||
Reference in New Issue
Block a user