Reorganized the project to put the library one folder down.

This commit is contained in:
antiduh
2014-06-27 14:38:28 +00:00
parent ffb7e36edb
commit c1b7785440
40 changed files with 9 additions and 9 deletions

View File

@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NSspi.Credentials
{
public class ClientCredential : Credential
{
public ClientCredential( SecurityPackage package ) : base( package, CredentialType.Client ) { }
}
}

View File

@@ -0,0 +1,202 @@
using System;
using System.Collections.Generic;
using System.DirectoryServices.AccountManagement;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using NSspi.Credentials;
using NSspi.Credentials.Credentials;
namespace NSspi.Credentials
{
public class Credential : IDisposable
{
private bool disposed;
private SecurityPackage securityPackage;
private SafeCredentialHandle safeCredHandle;
private long expiry;
public Credential(SecurityPackage package, CredentialType credentialType)
{
this.disposed = false;
this.securityPackage = package;
this.expiry = 0;
Init( package, credentialType );
}
private void Init( SecurityPackage package, CredentialType credentialType )
{
string packageName;
CredentialUse use;
// -- Package --
if ( package == SecurityPackage.Kerberos )
{
packageName = PackageNames.Kerberos;
}
else if ( package == SecurityPackage.Negotiate )
{
packageName = PackageNames.Negotiate;
}
else if ( package == SecurityPackage.NTLM )
{
packageName = PackageNames.Ntlm;
}
else
{
throw new ArgumentException( "Invalid value provided for the 'package' parameter." );
}
// -- Credential --
if ( credentialType == CredentialType.Client )
{
use = CredentialUse.Outbound;
}
else if ( credentialType == CredentialType.Server )
{
use = CredentialUse.Inbound;
}
else
{
throw new ArgumentException( "Invalid value provided for the 'credentialType' parameter." );
}
// -- Invoke --
SecurityStatus status = SecurityStatus.InternalError;
this.safeCredHandle = 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(
null,
packageName,
use,
IntPtr.Zero,
IntPtr.Zero,
IntPtr.Zero,
IntPtr.Zero,
ref this.safeCredHandle.rawHandle,
ref this.expiry
);
}
if ( status != SecurityStatus.OK )
{
throw new SSPIException( "Failed to call AcquireCredentialHandle", status );
}
}
~Credential()
{
Dispose( false );
}
public SecurityPackage SecurityPackage
{
get
{
if( this.disposed )
{
throw new ObjectDisposedException( base.GetType().Name );
}
return this.securityPackage;
}
}
public string Name
{
get
{
QueryNameAttribCarrier carrier = new QueryNameAttribCarrier();
SecurityStatus status = SecurityStatus.InternalError;
string name = null;
bool gotRef = false;
RuntimeHelpers.PrepareConstrainedRegions();
try
{
this.safeCredHandle.DangerousAddRef( ref gotRef );
}
catch( Exception )
{
if( gotRef == true )
{
this.safeCredHandle.DangerousRelease();
gotRef = false;
}
throw;
}
finally
{
if( gotRef )
{
status = CredentialNativeMethods.QueryCredentialsAttribute_Name(
ref this.safeCredHandle.rawHandle,
CredentialQueryAttrib.Names,
ref carrier
);
this.safeCredHandle.DangerousRelease();
if( status == SecurityStatus.OK && carrier.Name != IntPtr.Zero )
{
name = Marshal.PtrToStringUni( carrier.Name );
NativeMethods.FreeContextBuffer( carrier.Name );
}
}
}
if( status.IsError() )
{
throw new SSPIException( "Failed to query credential name", status );
}
return name;
}
}
public SafeCredentialHandle Handle
{
get
{
return this.safeCredHandle;
}
}
public void Dispose()
{
Dispose( true );
GC.SuppressFinalize( this );
}
protected virtual void Dispose( bool disposing )
{
if ( this.disposed == false )
{
if ( disposing )
{
this.safeCredHandle.Dispose();
}
this.disposed = true;
}
}
}
}

View File

@@ -0,0 +1,77 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using NSspi.Credentials;
using NSspi.Credentials.Credentials;
namespace NSspi.Credentials
{
internal static class CredentialNativeMethods
{
/*
SECURITY_STATUS SEC_Entry AcquireCredentialsHandle(
_In_ SEC_CHAR *pszPrincipal, // [in] name of principal. NULL = principal of current security context
_In_ SEC_CHAR *pszPackage, // [in] name of security package - "Kerberos", "Negotiate", "NTLM", etc
_In_ ULONG fCredentialUse, // [in] flags indicating use.
_In_ PLUID pvLogonID, // [in] pointer to logon identifier. NULL = we're not specifying the id of another logon session
_In_ PVOID pAuthData, // [in] package-specific data. NULL = default credentials for security package
_In_ SEC_GET_KEY_FN pGetKeyFn, // [in] pointer to GetKey function. NULL = we're not using a callback to retrieve the credentials
_In_ PVOID pvGetKeyArgument, // [in] value to pass to GetKey
_Out_ PCredHandle phCredential, // [out] credential handle (this must be already allocated)
_Out_ PTimeStamp ptsExpiry // [out] lifetime of the returned credentials
);
SECURITY_STATUS SEC_Entry FreeCredentialsHandle(
_In_ PCredHandle phCredential
);
SECURITY_STATUS SEC_Entry QueryCredentialsAttributes(
_In_ PCredHandle phCredential,
_In_ ULONG ulAttribute,
_Out_ PVOID pBuffer
);
*/
[ReliabilityContract( Consistency.WillNotCorruptState, Cer.MayFail)]
[DllImport( "Secur32.dll", EntryPoint = "AcquireCredentialsHandle", CharSet = CharSet.Unicode )]
internal static extern SecurityStatus AcquireCredentialsHandle(
string principleName,
string packageName,
CredentialUse credentialUse,
IntPtr loginId,
IntPtr packageData,
IntPtr getKeyFunc,
IntPtr getKeyData,
ref RawSspiHandle credentialHandle,
ref long expiry
);
[ReliabilityContract( Consistency.WillNotCorruptState, Cer.Success )]
[DllImport( "Secur32.dll", EntryPoint = "FreeCredentialsHandle", CharSet = CharSet.Unicode )]
internal static extern SecurityStatus FreeCredentialsHandle(
ref RawSspiHandle credentialHandle
);
/// <summary>
/// The overload of the QueryCredentialsAttribute method that is used for querying the name attribute.
/// In this call, it takes a void* to a structure that contains a wide char pointer. The wide character
/// pointer is allocated by the SSPI api, and thus needs to be released by a call to FreeContextBuffer().
/// </summary>
/// <param name="credentialHandle"></param>
/// <param name="attributeName"></param>
/// <param name="name"></param>
/// <returns></returns>
[ReliabilityContract( Consistency.WillNotCorruptState, Cer.Success )]
[DllImport( "Secur32.dll", EntryPoint = "QueryCredentialsAttributes", CharSet = CharSet.Unicode )]
internal static extern SecurityStatus QueryCredentialsAttribute_Name(
ref RawSspiHandle credentialHandle,
CredentialQueryAttrib attributeName,
ref QueryNameAttribCarrier name
);
}
}

View File

@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NSspi.Credentials
{
public enum SecurityPackage
{
Negotiate = 0,
Kerberos = 1,
NTLM = 2
}
}

View File

@@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NSspi.Credentials
{
/*
#define SECPKG_CRED_ATTR_NAMES 1
#define SECPKG_CRED_ATTR_SSI_PROVIDER 2
#define SECPKG_CRED_ATTR_KDC_PROXY_SETTINGS 3
#define SECPKG_CRED_ATTR_CERT 4
*/
public enum CredentialQueryAttrib : uint
{
Names = 1,
SsiProvider = 2,
KdcProxySettings = 3,
Cert = 4
}
}

View File

@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NSspi.Credentials
{
public enum CredentialType
{
Client = 0,
Server = 1
}
}

View File

@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NSspi.Credentials
{
public enum CredentialUse : uint
{
Inbound = 1,
Outbound = 2,
Both = 3,
}
}

View File

@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace NSspi.Credentials.Credentials
{
[StructLayout( LayoutKind.Sequential )]
public struct QueryNameAttribCarrier
{
public IntPtr Name;
}
}

View File

@@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NSspi.Credentials
{
public class SafeCredentialHandle : SafeSspiHandle
{
public SafeCredentialHandle()
: base()
{ }
protected override bool ReleaseHandle()
{
SecurityStatus status = CredentialNativeMethods.FreeCredentialsHandle(
ref base.rawHandle
);
base.ReleaseHandle();
return status == SecurityStatus.OK;
}
}
}

View File

@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NSspi.Credentials
{
public class ServerCredential : Credential
{
public ServerCredential( SecurityPackage package ) : base( package, CredentialType.Server ) { }
}
}