예제 #1
0
        public static SecPkgInfo[] GetSSPackages()
        {
            int    count;
            IntPtr packages;

            int result = Win32.EnumerateSecurityPackages(out count, out packages);

            if (result != 0)
            {
                Win32.Throw(result);
            }

            var alloc = new MemoryRegion(packages);

            try
            {
                SecPkgInfo[] array = new SecPkgInfo[count];

                for (int i = 0; i < count; i++)
                {
                    array[i] = alloc.ReadStruct <SecPkgInfo>(0, SecPkgInfo.SizeOf, i);
                }

                return(array);
            }
            finally
            {
                Win32.FreeContextBuffer(packages);
            }
        }
예제 #2
0
 private AuthenticationPackage(SecPkgInfo pkg)
 {
     Capabilities = pkg.fCapabilities;
     Version      = pkg.wVersion;
     RpcId        = pkg.wRPCID;
     MaxTokenSize = pkg.cbMaxToken;
     Name         = pkg.Name;
     Comment      = pkg.Comment;
 }
        internal AuthenticationPackage(IntPtr pkg_ptr)
        {
            SecPkgInfo pkg = (SecPkgInfo)Marshal.PtrToStructure(pkg_ptr, typeof(SecPkgInfo));

            Capabilities = pkg.fCapabilities;
            Version      = pkg.wVersion;
            RpcId        = pkg.wRPCID;
            MaxTokenSize = pkg.cbMaxToken;
            Name         = pkg.Name;
            Comment      = pkg.Comment;
        }
예제 #4
0
        /// <summary>
        /// Get authentication packages.
        /// </summary>
        /// <returns>The list of authentication packages.</returns>
        public static IEnumerable <AuthenticationPackage> Get()
        {
            List <AuthenticationPackage> packages = new List <AuthenticationPackage>();

            if (SecurityNativeMethods.EnumerateSecurityPackages(out int count,
                                                                out IntPtr ppPackageInfo) == SecStatusCode.Success)
            {
                try {
                    int size = Marshal.SizeOf(typeof(SecPkgInfo));
                    for (int i = 0; i < count; ++i)
                    {
                        SecPkgInfo pkg = (SecPkgInfo)Marshal.PtrToStructure(ppPackageInfo + i * size, typeof(SecPkgInfo));
                        packages.Add(new AuthenticationPackage(pkg));
                    }
                } finally {
                    SecurityNativeMethods.FreeContextBuffer(ppPackageInfo);
                }
            }
            return(packages.AsReadOnly());
        }
예제 #5
0
        private void GetMaxTokenSize()
        {
            int num;
            SafeContextBufferHandle safeContextBufferHandle;

            if (Sspi.EnumerateSecurityPackages(out num, out safeContextBufferHandle) != SecurityStatus.SEC_E_OK)
            {
                throw new Win32Exception("Failed to EnumerateSecurityPackages");
            }
            for (int i = 0; i < num; i++)
            {
                SecPkgInfo item = safeContextBufferHandle.GetItem <SecPkgInfo>(i);
                if (string.Compare(item.GetName(), "Schannel", true) == 0)
                {
                    this.maxTokenSize = item.cbMaxToken;
                    break;
                }
            }
            if (this.maxTokenSize == 0)
            {
                throw new Exception("Failed to retrive cbMaxToken for Schannel");
            }
        }
        public static List <string> GetAvailableProvidersList()
        {
            List <string> configuredProviders    = new List <string>();
            List <string> availableProvidersList = new List <string>();

            try {
                const int SEC_E_OK = 0;
                const int SECPKG_FLAG_NEGOTIABLE2 = 0x00200000;
                const int SECPKG_FLAG_NEGOTIABLE  = 0x00000800;
                IntPtr    pcPackages = (IntPtr)1;
                IntPtr    secPkgInfoPtr;
                int       retValue = EnumerateSecuirtyPackagesW(out pcPackages, out secPkgInfoPtr);
                if (retValue != SEC_E_OK)
                {
                    if (secPkgInfoPtr != null)
                    {
                        retValue = FreeContextBuffer(secPkgInfoPtr);
                        if (retValue != SEC_E_OK)
                        {
                            // Failed to release memory
                        }
                    }
                    return(null);
                }
                int    nego2FlagIntValue  = (int)SECPKG_FLAG_NEGOTIABLE2;
                int    negoFlagIntValue   = (int)SECPKG_FLAG_NEGOTIABLE;
                IntPtr currentPtrToStruct = secPkgInfoPtr;
                for (int i = 0; i < (int)pcPackages; ++i)
                {
                    SecPkgInfo currentPackageStruct = (SecPkgInfo)Marshal.PtrToStructure <SecPkgInfo>(currentPtrToStruct);
                    // Ignore NegoExtender package (because NegoExtender is a psuedo authentication protocol)
                    // and show 'pku2u' because it proven that it works over HTTP
                    if ((currentPackageStruct.Name).Equals("NegoExtender", StringComparison.OrdinalIgnoreCase))
                    {
                        // Go to the next available struct
                        currentPtrToStruct = (IntPtr)((Int64)currentPtrToStruct + Marshal.SizeOf <SecPkgInfo>());
                        continue;
                    }
                    if (((currentPackageStruct.fCapabilities & nego2FlagIntValue) == 0) && ((currentPackageStruct.fCapabilities & negoFlagIntValue) == 0))
                    {
                        currentPtrToStruct = (IntPtr)((Int64)currentPtrToStruct + Marshal.SizeOf <SecPkgInfo>());
                        continue;
                    }
                    string strPackageName = null;
                    // 1. If this is a Negotiable2 package, prefix package name with 'Negotiate:'
                    // 2. If this is a Negotiable package and it's name is not 'Negotiate' and 'NTLM' , then add prefix 'Negotiate:' to the pacakge name
                    // IMPORTANT NOTE: Runtime sends Nego2 package when one of the enabled provider is prefixed with 'Negotiate:' (which is considered as Nego2 package)
                    //    Just to be consistent with the runtime behavior we will display a warning message for all the Negotiate packages which are prefixed with 'Negotiate:'
                    if (((currentPackageStruct.fCapabilities & nego2FlagIntValue) != 0) ||
                        ((currentPackageStruct.fCapabilities & negoFlagIntValue) != 0 &&
                         !(currentPackageStruct.Name).Equals("Negotiate", StringComparison.OrdinalIgnoreCase) &&
                         !(currentPackageStruct.Name).Equals("NTLM", StringComparison.OrdinalIgnoreCase)
                        )
                        )
                    {
                        strPackageName = "Negotiate:";
                    }
                    strPackageName += currentPackageStruct.Name;

                    // Add it to the available providers list
                    availableProvidersList.Add(strPackageName);

                    // Go to the next available struct
                    currentPtrToStruct = (IntPtr)((Int64)currentPtrToStruct + Marshal.SizeOf <SecPkgInfo>());
                }
                // Free the memory
                retValue = FreeContextBuffer(secPkgInfoPtr);
                if (retValue != SEC_E_OK)
                {
                    // Failed to release the memory...
                }
            }
            catch (Exception) { }
            return(availableProvidersList);
        }