Added password authentication support.
Added the ability to acquire a valid credential by providing a username/password combination.
This commit is contained in:
55
NSspi/Credentials/AuthData.cs
Normal file
55
NSspi/Credentials/AuthData.cs
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
using System;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace NSspi.Credentials
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Provides authentication data in native method calls.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Implements the 'SEC_WINNT_AUTH_IDENTITY' structure. See:
|
||||||
|
///
|
||||||
|
/// https://msdn.microsoft.com/en-us/library/windows/desktop/aa380131(v=vs.85).aspx
|
||||||
|
/// </remarks>
|
||||||
|
[StructLayout( LayoutKind.Sequential )]
|
||||||
|
internal struct NativeAuthData
|
||||||
|
{
|
||||||
|
public NativeAuthData( string domain, string username, string password, NativeAuthDataFlag flag )
|
||||||
|
{
|
||||||
|
this.Domain = domain;
|
||||||
|
this.DomainLength = domain.Length;
|
||||||
|
|
||||||
|
this.User = username;
|
||||||
|
this.UserLength = username.Length;
|
||||||
|
|
||||||
|
this.Password = password;
|
||||||
|
this.PasswordLength = password.Length;
|
||||||
|
|
||||||
|
this.Flags = flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
[MarshalAs( UnmanagedType.LPWStr )]
|
||||||
|
public string User;
|
||||||
|
|
||||||
|
public int UserLength;
|
||||||
|
|
||||||
|
[MarshalAs( UnmanagedType.LPWStr )]
|
||||||
|
public string Domain;
|
||||||
|
|
||||||
|
public int DomainLength;
|
||||||
|
|
||||||
|
[MarshalAs( UnmanagedType.LPWStr )]
|
||||||
|
public string Password;
|
||||||
|
|
||||||
|
public int PasswordLength;
|
||||||
|
|
||||||
|
public NativeAuthDataFlag Flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal enum NativeAuthDataFlag : int
|
||||||
|
{
|
||||||
|
Ansi = 1,
|
||||||
|
|
||||||
|
Unicode = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -20,6 +20,21 @@ namespace NSspi.Credentials
|
|||||||
ref TimeStamp expiry
|
ref TimeStamp expiry
|
||||||
);
|
);
|
||||||
|
|
||||||
|
[ReliabilityContract( Consistency.WillNotCorruptState, Cer.MayFail )]
|
||||||
|
[DllImport( "Secur32.dll", EntryPoint = "AcquireCredentialsHandle", CharSet = CharSet.Unicode )]
|
||||||
|
internal static extern SecurityStatus AcquireCredentialsHandle_AuthData(
|
||||||
|
string principleName,
|
||||||
|
string packageName,
|
||||||
|
CredentialUse credentialUse,
|
||||||
|
IntPtr loginId,
|
||||||
|
ref NativeAuthData authData,
|
||||||
|
IntPtr getKeyFunc,
|
||||||
|
IntPtr getKeyData,
|
||||||
|
ref RawSspiHandle credentialHandle,
|
||||||
|
ref TimeStamp expiry
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
[ReliabilityContract( Consistency.WillNotCorruptState, Cer.Success )]
|
[ReliabilityContract( Consistency.WillNotCorruptState, Cer.Success )]
|
||||||
[DllImport( "Secur32.dll", EntryPoint = "FreeCredentialsHandle", CharSet = CharSet.Unicode )]
|
[DllImport( "Secur32.dll", EntryPoint = "FreeCredentialsHandle", CharSet = CharSet.Unicode )]
|
||||||
internal static extern SecurityStatus FreeCredentialsHandle(
|
internal static extern SecurityStatus FreeCredentialsHandle(
|
||||||
|
|||||||
78
NSspi/Credentials/PasswordCredential.cs
Normal file
78
NSspi/Credentials/PasswordCredential.cs
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace NSspi.Credentials
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents credentials acquired by providing a username, password, and domain.
|
||||||
|
/// </summary>
|
||||||
|
public class PasswordCredential : Credential
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the PasswordCredential class.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// It is possible to acquire a valid handle to credentials that do not provide a valid
|
||||||
|
/// username-password combination. The username and password are not validation until the
|
||||||
|
/// authentication cycle begins.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="domain">The domain to authenticate to.</param>
|
||||||
|
/// <param name="username">The username of the user to authenticate as.</param>
|
||||||
|
/// <param name="password">The user's password.</param>
|
||||||
|
/// <param name="secPackage">The SSPI security package to create credentials for.</param>
|
||||||
|
/// <param name="use">
|
||||||
|
/// Specify inbound when acquiring credentials for a server; outbound for a client.
|
||||||
|
/// </param>
|
||||||
|
public PasswordCredential( string domain, string username, string password, string secPackage, CredentialUse use )
|
||||||
|
: base( secPackage )
|
||||||
|
{
|
||||||
|
NativeAuthData authData = new NativeAuthData( domain, username, password, NativeAuthDataFlag.Unicode );
|
||||||
|
|
||||||
|
Init( authData, secPackage, use );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Init( NativeAuthData authData, string secPackage, CredentialUse use )
|
||||||
|
{
|
||||||
|
string packageName;
|
||||||
|
TimeStamp rawExpiry = new TimeStamp();
|
||||||
|
SecurityStatus status = SecurityStatus.InternalError;
|
||||||
|
|
||||||
|
// -- Package --
|
||||||
|
// Copy off for the call, since this.SecurityPackage is a property.
|
||||||
|
packageName = this.SecurityPackage;
|
||||||
|
|
||||||
|
this.Handle = new SafeCredentialHandle();
|
||||||
|
|
||||||
|
|
||||||
|
// The finally clause is the actual constrained region. The VM pre-allocates any stack space,
|
||||||
|
// performs any allocations it needs to prepare methods for execution, and postpones any
|
||||||
|
// instances of the 'uncatchable' exceptions (ThreadAbort, StackOverflow, OutOfMemory).
|
||||||
|
RuntimeHelpers.PrepareConstrainedRegions();
|
||||||
|
try { }
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
status = CredentialNativeMethods.AcquireCredentialsHandle_AuthData(
|
||||||
|
null,
|
||||||
|
packageName,
|
||||||
|
use,
|
||||||
|
IntPtr.Zero,
|
||||||
|
ref authData,
|
||||||
|
IntPtr.Zero,
|
||||||
|
IntPtr.Zero,
|
||||||
|
ref this.Handle.rawHandle,
|
||||||
|
ref rawExpiry
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if( status != SecurityStatus.OK )
|
||||||
|
{
|
||||||
|
throw new SSPIException( "Failed to call AcquireCredentialHandle", status );
|
||||||
|
}
|
||||||
|
|
||||||
|
this.Expiry = rawExpiry.ToDateTime();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -55,8 +55,10 @@
|
|||||||
<Compile Include="Contexts\ContextQueryAttrib.cs" />
|
<Compile Include="Contexts\ContextQueryAttrib.cs" />
|
||||||
<Compile Include="Contexts\ImpersonationHandle.cs" />
|
<Compile Include="Contexts\ImpersonationHandle.cs" />
|
||||||
<Compile Include="Contexts\SafeContextHandle.cs" />
|
<Compile Include="Contexts\SafeContextHandle.cs" />
|
||||||
|
<Compile Include="Credentials\AuthData.cs" />
|
||||||
<Compile Include="Credentials\ClientCurrentCredential.cs" />
|
<Compile Include="Credentials\ClientCurrentCredential.cs" />
|
||||||
<Compile Include="Credentials\CurrentCredential.cs" />
|
<Compile Include="Credentials\CurrentCredential.cs" />
|
||||||
|
<Compile Include="Credentials\PasswordCredential.cs" />
|
||||||
<Compile Include="Credentials\ServerCurrentCredential.cs" />
|
<Compile Include="Credentials\ServerCurrentCredential.cs" />
|
||||||
<Compile Include="EnumMgr.cs" />
|
<Compile Include="EnumMgr.cs" />
|
||||||
<Compile Include="SecPkgInfo.cs" />
|
<Compile Include="SecPkgInfo.cs" />
|
||||||
|
|||||||
Reference in New Issue
Block a user