Implemented the ability to query the EnumerateSecurityPackages native API safely.

This commit is contained in:
antiduh
2014-06-27 22:00:18 +00:00
parent 7e5f2a6308
commit 241da896b1
2 changed files with 69 additions and 1 deletions

View File

@@ -33,5 +33,10 @@ namespace NSspi
[ReliabilityContract( Consistency.WillNotCorruptState, Cer.Success )]
[DllImport( "Secur32.dll", EntryPoint = "QuerySecurityPackageInfo", CharSet = CharSet.Unicode )]
internal static extern SecurityStatus QuerySecurityPackageInfo( string packageName, ref IntPtr pkgInfo );
[ReliabilityContract( Consistency.WillNotCorruptState, Cer.Success )]
[DllImport( "Secur32.dll", EntryPoint = "EnumerateSecurityPackages", CharSet = CharSet.Unicode )]
internal static extern SecurityStatus EnumerateSecurityPackages( ref int numPackages, ref IntPtr pkgInfoArry );
}
}

View File

@@ -13,7 +13,7 @@ namespace NSspi
internal static SecPkgInfo GetPackageCapabilities( string packageName )
{
SecPkgInfo info;
SecurityStatus status;
SecurityStatus status = SecurityStatus.InternalError;
SecurityStatus freeStatus;
IntPtr rawInfoPtr;
@@ -45,8 +45,71 @@ namespace NSspi
}
}
if( status != SecurityStatus.OK )
{
throw new SSPIException( "Failed to query security package provider details", status );
}
return info;
}
public static SecPkgInfo[] EnumeratePackages()
{
SecurityStatus status = SecurityStatus.InternalError;
SecPkgInfo[] packages = null;
IntPtr pkgArrayPtr;
IntPtr pkgPtr;
int numPackages = 0;
int pkgSize = Marshal.SizeOf( typeof(SecPkgInfo) );
pkgArrayPtr = new IntPtr();
RuntimeHelpers.PrepareConstrainedRegions();
try { }
finally
{
status = NativeMethods.EnumerateSecurityPackages( ref numPackages, ref pkgArrayPtr );
if( pkgArrayPtr != IntPtr.Zero )
{
try
{
if( status == SecurityStatus.OK )
{
// Bwooop Bwooop Alocation Alert
// 1) We allocate the array
// 2) We allocate the individual elements in the array (they're class objects).
// 3) We allocate the strings in the individual elements in the array when we
// call Marshal.PtrToStructure()
packages = new SecPkgInfo[numPackages];
for( int i = 0; i < numPackages; i++ )
{
packages[i] = new SecPkgInfo();
}
for( int i = 0; i < numPackages; i++ )
{
pkgPtr = IntPtr.Add( pkgArrayPtr, i * pkgSize );
Marshal.PtrToStructure( pkgPtr, packages[i] );
}
}
}
finally
{
NativeMethods.FreeContextBuffer( pkgArrayPtr );
}
}
}
if( status != SecurityStatus.OK )
{
throw new SSPIException( "Failed to enumerate security package providers", status );
}
return packages;
}
}
}