internal static int EnumeratePackages(SecurDll Dll, out int pkgnum, out SafeFreeContextBuffer pkgArray) { int num = -1; switch (Dll) { case SecurDll.SECURITY: { SafeFreeContextBuffer_SECURITY handle = null; num = UnsafeNclNativeMethods.SafeNetHandles_SECURITY.EnumerateSecurityPackagesW(out pkgnum, out handle); pkgArray = handle; break; } case SecurDll.SECUR32: { SafeFreeContextBuffer_SECUR32 r_secur = null; num = UnsafeNclNativeMethods.SafeNetHandles_SECUR32.EnumerateSecurityPackagesA(out pkgnum, out r_secur); pkgArray = r_secur; break; } case SecurDll.SCHANNEL: { SafeFreeContextBuffer_SCHANNEL r_schannel = null; num = UnsafeNclNativeMethods.SafeNetHandles_SCHANNEL.EnumerateSecurityPackagesA(out pkgnum, out r_schannel); pkgArray = r_schannel; break; } default: throw new ArgumentException(SR.GetString("net_invalid_enum", new object[] { "SecurDll" }), "Dll"); } if ((num != 0) && (pkgArray != null)) { pkgArray.SetHandleAsInvalid(); } return num; }
// // internal static int EnumeratePackages(SecurDll Dll, out int pkgnum, out SafeFreeContextBuffer pkgArray) { int res = -1; switch (Dll) { case SecurDll.SECURITY: SafeFreeContextBuffer_SECURITY pkgArray_SECURITY = null; res = UnsafeNclNativeMethods.SafeNetHandles_SECURITY.EnumerateSecurityPackagesW(out pkgnum, out pkgArray_SECURITY); pkgArray = pkgArray_SECURITY; break; default: throw new ArgumentException(SR.GetString(SR.net_invalid_enum, "SecurDll"), "Dll"); } if (res != 0 && pkgArray != null) { pkgArray.SetHandleAsInvalid(); } return res; }
// // After PINvoke call the method will fix the handleTemplate.handle with the returned value. // The caller is responsible for creating a correct SafeFreeContextBuffer_XXX flavour or null can be passed if no handle is returned. // // Since it has a CER, this method can't have any references to imports from DLLs that may not exist on the system. // private static unsafe int MustRunAcceptSecurityContext_SECURITY( ref SafeFreeCredentials inCredentials, void* inContextPtr, SecurityBufferDescriptor inputBuffer, ContextFlags inFlags, Endianness endianness, SafeDeleteContext outContext, SecurityBufferDescriptor outputBuffer, ref ContextFlags outFlags, SafeFreeContextBuffer handleTemplate) { int errorCode = (int) SecurityStatus.InvalidHandle; bool b1 = false; bool b2 = false; // Run the body of this method as a non-interruptible block. RuntimeHelpers.PrepareConstrainedRegions(); try { inCredentials.DangerousAddRef(ref b1); outContext.DangerousAddRef(ref b2); } catch(Exception e) { if (b1) { inCredentials.DangerousRelease(); b1 = false; } if (b2) { outContext.DangerousRelease(); b2 = false; } if (!(e is ObjectDisposedException)) throw; } finally { SSPIHandle credentialHandle = inCredentials._handle; long timeStamp; if (!b1) { // caller should retry inCredentials = null; } else if (b1 && b2) { errorCode = UnsafeNclNativeMethods.SafeNetHandles_SECURITY.AcceptSecurityContext( ref credentialHandle, inContextPtr, inputBuffer, inFlags, endianness, ref outContext._handle, outputBuffer, ref outFlags, out timeStamp); // // When a credential handle is first associated with the context we keep credential // ref count bumped up to ensure ordered finalization. // If the credential handle has been changed we de-ref the old one and associate the // context with the new cred handle but only if the call was successful. if (outContext._EffectiveCredential != inCredentials && (errorCode & 0x80000000) == 0) { // Disassociate the previous credential handle if (outContext._EffectiveCredential != null) outContext._EffectiveCredential.DangerousRelease(); outContext._EffectiveCredential = inCredentials; } else { inCredentials.DangerousRelease(); } outContext.DangerousRelease(); // The idea is that SSPI has allocated a block and filled up outUnmanagedBuffer+8 slot with the pointer. if (handleTemplate != null) { handleTemplate.Set(((SecurityBufferStruct*)outputBuffer.UnmanagedPointer)->token); //ATTN: on 64 BIT that is still +8 cause of 2* c++ unsigned long == 8 bytes if (handleTemplate.IsInvalid) { handleTemplate.SetHandleAsInvalid(); } } } if (inContextPtr == null && (errorCode & 0x80000000) != 0) { // an error on the first call, need to set the out handle to invalid value outContext._handle.SetToInvalid(); } } return errorCode; }