Implemented Credential acquisition and release.

This commit is contained in:
antiduh
2014-06-19 02:26:30 +00:00
parent 22c6a5d3f9
commit f96ef74e9b
8 changed files with 168 additions and 21 deletions

View File

@@ -13,13 +13,74 @@ namespace NSspi
private SecurityPackage securityPackage; private SecurityPackage securityPackage;
private long credHandle;
private long expiry;
public Credential(SecurityPackage package, CredentialType credentialType) public Credential(SecurityPackage package, CredentialType credentialType)
{ {
this.disposed = false; this.disposed = false;
this.securityPackage = package; this.securityPackage = package;
Init(); this.credHandle = 0;
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 == NSspi.SecurityPackage.Negotiate )
{
packageName = PackageNames.Negotiate;
}
else if ( package == NSspi.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 = NativeMethods.AcquireCredentialsHandle(
null,
packageName,
use,
IntPtr.Zero,
IntPtr.Zero,
IntPtr.Zero,
IntPtr.Zero,
ref this.credHandle,
ref this.expiry
);
if ( status != SecurityStatus.Success )
{
throw new SSPIException( "Failed to call AcquireCredentialHandle", status );
}
} }
~Credential() ~Credential()
@@ -45,12 +106,11 @@ namespace NSspi
return null; return null;
} }
// TODO use safe handle ... public long CredentialHandle
public IntPtr CredentialHandle
{ {
get get
{ {
return IntPtr.Zero; return this.credHandle;
} }
} }
@@ -62,12 +122,19 @@ namespace NSspi
protected virtual void Dispose( bool disposing ) protected virtual void Dispose( bool disposing )
{ {
this.disposed = true; if ( this.disposed == false )
} {
SecurityStatus result;
private void Init() result = NativeMethods.FreeCredentialsHandle( ref this.credHandle );
{
}
this.disposed = true;
if ( disposing && result != SecurityStatus.Success )
{
throw new SSPIException( "Failed to release credentials handle", result );
}
}
}
} }
} }

View File

@@ -6,7 +6,7 @@ using System.Threading.Tasks;
namespace NSspi namespace NSspi
{ {
public enum CredentialUse : int public enum CredentialUse : uint
{ {
Inbound = 1, Inbound = 1,
Outbound = 2, Outbound = 2,

View File

@@ -5,7 +5,7 @@
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{4B4CD933-BF62-4F92-B8FA-6771758C5197}</ProjectGuid> <ProjectGuid>{4B4CD933-BF62-4F92-B8FA-6771758C5197}</ProjectGuid>
<OutputType>Library</OutputType> <OutputType>WinExe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder> <AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>NSspi</RootNamespace> <RootNamespace>NSspi</RootNamespace>
<AssemblyName>NSspi</AssemblyName> <AssemblyName>NSspi</AssemblyName>
@@ -29,6 +29,9 @@
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
</PropertyGroup> </PropertyGroup>
<PropertyGroup>
<StartupObject>NSspi.Program</StartupObject>
</PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Core" /> <Reference Include="System.Core" />
@@ -47,7 +50,9 @@
<Compile Include="CredentialUse.cs" /> <Compile Include="CredentialUse.cs" />
<Compile Include="NativeMethods.cs" /> <Compile Include="NativeMethods.cs" />
<Compile Include="PackageNames.cs" /> <Compile Include="PackageNames.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SecurityStatus.cs" />
<Compile Include="SSPIException.cs" /> <Compile Include="SSPIException.cs" />
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

View File

@@ -38,8 +38,14 @@ namespace NSspi
); );
*/ */
[DllImport( "Secur32.dll", CallingConvention = CallingConvention.Winapi, SetLastError=true)] [DllImport(
public extern int AcquireCredentialHandle( "Secur32.dll",
EntryPoint = "AcquireCredentialsHandle",
CallingConvention = CallingConvention.Winapi,
CharSet = CharSet.Unicode,
SetLastError = true
)]
public static extern SecurityStatus AcquireCredentialsHandle(
string principleName, string principleName,
string packageName, string packageName,
CredentialUse credentialUse, CredentialUse credentialUse,
@@ -47,8 +53,25 @@ namespace NSspi
IntPtr packageData, IntPtr packageData,
IntPtr getKeyFunc, IntPtr getKeyFunc,
IntPtr getKeyData, IntPtr getKeyData,
IntPtr credentialHandle, ref long credentialHandle,
ref long expiry ref long expiry
); );
/*
SECURITY_STATUS SEC_Entry FreeCredentialsHandle(
_In_ PCredHandle phCredential
);
*/
[DllImport(
"Secur32.dll",
EntryPoint = "FreeCredentialsHandle",
CallingConvention = CallingConvention.Winapi,
CharSet = CharSet.Unicode,
SetLastError = true
)]
public static extern SecurityStatus FreeCredentialsHandle(
ref long credentialHandle
);
} }
} }

View File

@@ -6,7 +6,7 @@ using System.Threading.Tasks;
namespace NSspi namespace NSspi
{ {
public static sealed class PackageNames public static class PackageNames
{ {
public const string Negotiate = "Negotiate"; public const string Negotiate = "Negotiate";

18
Program.cs Normal file
View File

@@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NSspi
{
public class Program
{
public static void Main( string[] args )
{
Credential cred = new Credential( SecurityPackage.Negotiate, CredentialType.Client );
cred.Dispose();
}
}
}

View File

@@ -10,17 +10,17 @@ namespace NSspi
[Serializable] [Serializable]
public class SSPIException : Exception public class SSPIException : Exception
{ {
private int errorCode; private SecurityStatus errorCode;
private string message; private string message;
public SSPIException( SerializationInfo info, StreamingContext context ) public SSPIException( SerializationInfo info, StreamingContext context )
: base( info, context ) : base( info, context )
{ {
this.message = info.GetString( "messsage" ); this.message = info.GetString( "messsage" );
this.errorCode = info.GetInt32( "errorCode" ); this.errorCode = (SecurityStatus)info.GetUInt32( "errorCode" );
} }
public SSPIException( string message, int errorCode ) public SSPIException( string message, SecurityStatus errorCode )
{ {
this.message = message; this.message = message;
this.errorCode = errorCode; this.errorCode = errorCode;
@@ -34,7 +34,7 @@ namespace NSspi
info.AddValue( "errorCode", this.errorCode ); info.AddValue( "errorCode", this.errorCode );
} }
public int ErrorCode public SecurityStatus ErrorCode
{ {
get get
{ {

34
SecurityStatus.cs Normal file
View File

@@ -0,0 +1,34 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace NSspi
{
/*
// From winerror.h
#define SEC_E_OK ((HRESULT)0x00000000L)
#define SEC_E_INSUFFICIENT_MEMORY _HRESULT_TYPEDEF_(0x80090300L)
#define SEC_E_INVALID_HANDLE _HRESULT_TYPEDEF_(0x80090301L)
#define SEC_E_UNSUPPORTED_FUNCTION _HRESULT_TYPEDEF_(0x80090302L)
#define SEC_E_TARGET_UNKNOWN _HRESULT_TYPEDEF_(0x80090303L)
#define SEC_E_INTERNAL_ERROR _HRESULT_TYPEDEF_(0x80090304L)
#define SEC_E_SECPKG_NOT_FOUND _HRESULT_TYPEDEF_(0x80090305L)
#define SEC_E_NOT_OWNER _HRESULT_TYPEDEF_(0x80090306L)
#define SEC_E_UNKNOWN_CREDENTIALS _HRESULT_TYPEDEF_(0x8009030DL)
#define SEC_E_NO_CREDENTIALS _HRESULT_TYPEDEF_(0x8009030EL)
*/
public enum SecurityStatus : uint
{
Success = 0,
InsufficientMemory = 0x80090300,
InvalidHandle = 0x80090301,
InternalError = 0x80090304,
SecPkgNotFound = 0x80090305,
NotOwner = 0x80090306,
NoCredentials = 0x8009030E,
UnknownCredentials = 0x8009030D
}
}