Implemented the ability to query the EnumerateSecurityPackages native API safely.
This commit is contained in:
@@ -33,5 +33,10 @@ namespace NSspi
|
|||||||
[ReliabilityContract( Consistency.WillNotCorruptState, Cer.Success )]
|
[ReliabilityContract( Consistency.WillNotCorruptState, Cer.Success )]
|
||||||
[DllImport( "Secur32.dll", EntryPoint = "QuerySecurityPackageInfo", CharSet = CharSet.Unicode )]
|
[DllImport( "Secur32.dll", EntryPoint = "QuerySecurityPackageInfo", CharSet = CharSet.Unicode )]
|
||||||
internal static extern SecurityStatus QuerySecurityPackageInfo( string packageName, ref IntPtr pkgInfo );
|
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 );
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ namespace NSspi
|
|||||||
internal static SecPkgInfo GetPackageCapabilities( string packageName )
|
internal static SecPkgInfo GetPackageCapabilities( string packageName )
|
||||||
{
|
{
|
||||||
SecPkgInfo info;
|
SecPkgInfo info;
|
||||||
SecurityStatus status;
|
SecurityStatus status = SecurityStatus.InternalError;
|
||||||
SecurityStatus freeStatus;
|
SecurityStatus freeStatus;
|
||||||
|
|
||||||
IntPtr rawInfoPtr;
|
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;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user