diff --git a/NSspi/Credentials/AuthData.cs b/NSspi/Credentials/AuthData.cs
new file mode 100644
index 0000000..bfa3f9b
--- /dev/null
+++ b/NSspi/Credentials/AuthData.cs
@@ -0,0 +1,55 @@
+using System;
+using System.Runtime.InteropServices;
+
+namespace NSspi.Credentials
+{
+ ///
+ /// Provides authentication data in native method calls.
+ ///
+ ///
+ /// Implements the 'SEC_WINNT_AUTH_IDENTITY' structure. See:
+ ///
+ /// https://msdn.microsoft.com/en-us/library/windows/desktop/aa380131(v=vs.85).aspx
+ ///
+ [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
+ }
+}
\ No newline at end of file
diff --git a/NSspi/Credentials/CredentialNativeMethods.cs b/NSspi/Credentials/CredentialNativeMethods.cs
index 7db3c58..9b218f9 100644
--- a/NSspi/Credentials/CredentialNativeMethods.cs
+++ b/NSspi/Credentials/CredentialNativeMethods.cs
@@ -20,6 +20,21 @@ namespace NSspi.Credentials
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 )]
[DllImport( "Secur32.dll", EntryPoint = "FreeCredentialsHandle", CharSet = CharSet.Unicode )]
internal static extern SecurityStatus FreeCredentialsHandle(
diff --git a/NSspi/Credentials/PasswordCredential.cs b/NSspi/Credentials/PasswordCredential.cs
new file mode 100644
index 0000000..6ed3613
--- /dev/null
+++ b/NSspi/Credentials/PasswordCredential.cs
@@ -0,0 +1,78 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Text;
+
+namespace NSspi.Credentials
+{
+ ///
+ /// Represents credentials acquired by providing a username, password, and domain.
+ ///
+ public class PasswordCredential : Credential
+ {
+ ///
+ /// Initializes a new instance of the PasswordCredential class.
+ ///
+ ///
+ /// 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.
+ ///
+ /// The domain to authenticate to.
+ /// The username of the user to authenticate as.
+ /// The user's password.
+ /// The SSPI security package to create credentials for.
+ ///
+ /// Specify inbound when acquiring credentials for a server; outbound for a client.
+ ///
+ 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();
+ }
+ }
+}
diff --git a/NSspi/NSspi.csproj b/NSspi/NSspi.csproj
index 11649bf..b0f5a8c 100644
--- a/NSspi/NSspi.csproj
+++ b/NSspi/NSspi.csproj
@@ -55,8 +55,10 @@
+
+