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 long credHandle;
private long expiry;
public Credential(SecurityPackage package, CredentialType credentialType)
{
this.disposed = false;
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()
@@ -45,12 +106,11 @@ namespace NSspi
return null;
}
// TODO use safe handle ...
public IntPtr CredentialHandle
public long CredentialHandle
{
get
{
return IntPtr.Zero;
return this.credHandle;
}
}
@@ -62,12 +122,19 @@ namespace NSspi
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
{
public enum CredentialUse : int
public enum CredentialUse : uint
{
Inbound = 1,
Outbound = 2,

View File

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

View File

@@ -38,8 +38,14 @@ namespace NSspi
);
*/
[DllImport( "Secur32.dll", CallingConvention = CallingConvention.Winapi, SetLastError=true)]
public extern int AcquireCredentialHandle(
[DllImport(
"Secur32.dll",
EntryPoint = "AcquireCredentialsHandle",
CallingConvention = CallingConvention.Winapi,
CharSet = CharSet.Unicode,
SetLastError = true
)]
public static extern SecurityStatus AcquireCredentialsHandle(
string principleName,
string packageName,
CredentialUse credentialUse,
@@ -47,8 +53,25 @@ namespace NSspi
IntPtr packageData,
IntPtr getKeyFunc,
IntPtr getKeyData,
IntPtr credentialHandle,
ref long credentialHandle,
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
{
public static sealed class PackageNames
public static class PackageNames
{
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]
public class SSPIException : Exception
{
private int errorCode;
private SecurityStatus errorCode;
private string message;
public SSPIException( SerializationInfo info, StreamingContext context )
: base( info, context )
{
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.errorCode = errorCode;
@@ -34,7 +34,7 @@ namespace NSspi
info.AddValue( "errorCode", this.errorCode );
}
public int ErrorCode
public SecurityStatus ErrorCode
{
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
}
}