public SspiCredentials(string principal, string username, string password, string domain)
        {
            long expiry = 0;

            var authenticationData = new SEC_WINNT_AUTH_IDENTITY
            {
                User           = username,
                UserLength     = username.Length,
                Domain         = domain,
                DomainLength   = domain.Length,
                Password       = password,
                PasswordLength = password.Length,
                Flags          = SspiInterop.SEC_WINNT_AUTH_IDENTITY_UNICODE
            };

            var result = SspiInterop.AcquireCredentialsHandle(
                principal,
                SecurityPackage,
                SspiInterop.SECPKG_CRED_BOTH,
                IntPtr.Zero,
                authenticationData,
                0,
                IntPtr.Zero,
                ref _credentials,
                ref expiry);

            if (result != SspiInterop.SEC_E_OK)
            {
                throw new Exception($"Unable to aquire credentials for {principal},  SECURITY_STATUS 0x{result:x8}");
            }
            Credentials = _credentials;
        }
Beispiel #2
0
        private static IEnumerable <string> GetMemebershipSids(IntPtr token)
        {
            var length = 0;

            SspiInterop.GetTokenInformation(token, TokenInformationClass.TokenGroups, IntPtr.Zero, length, out length);

            var buffer = Marshal.AllocHGlobal(length);

            if (SspiInterop.GetTokenInformation(token, TokenInformationClass.TokenGroups, buffer, length, out length))
            {
                var groups         = Marshal.PtrToStructure <TOKEN_GROUPS>(buffer);
                var sidAndAttrSize = Marshal.SizeOf(new SID_AND_ATTRIBUTES());
                for (var i = 0; i < groups.GroupCount; i++)
                {
                    var sidAndAttributes = Marshal.PtrToStructure <SID_AND_ATTRIBUTES>(
                        new IntPtr(buffer.ToInt64() + i * sidAndAttrSize + IntPtr.Size));

                    SspiInterop.ConvertSidToStringSid(sidAndAttributes.Sid, out var pstr);
                    var sidString = Marshal.PtrToStringAuto(pstr);
                    SspiInterop.LocalFree(pstr);
                    yield return(sidString);
                }
            }
            else
            {
                throw new AuthenticationException($"An unhandled exception occurred obtaining group membership from the context (Win32 error {Marshal.GetLastWin32Error()})");
            }
            Marshal.FreeHGlobal(buffer);
        }
Beispiel #3
0
        private static string GetPrincipalNameFromContext(SecurityHandle context)
        {
            // We must pass SSPI a pointer to a structure, where upon SSPI will allocate additional memory for the
            // fields of the structure. We have to call back into SSPI to free the buffers it allocated, this code is
            // pretty verbose, probably should be refactored
            var name    = new SecurityContextNamesBuffer();
            var namePtr = Marshal.AllocHGlobal(Marshal.SizeOf(name));

            Marshal.StructureToPtr(name, namePtr, false);
            var status = SspiInterop.QueryContextAttributes(ref context, SspiInterop.SECPKG_ATTR_NATIVE_NAMES, namePtr);

            if (status != SspiInterop.SEC_E_OK)
            {
                Marshal.FreeHGlobal(namePtr);
                throw new AuthenticationException($"An unhandled exception occurred obtaining the username from the context (QueryContextAttributes returned: {status})");
            }
            var usernamePtr   = Marshal.PtrToStructure <SecurityContextNamesBuffer>(namePtr).clientname;
            var servernamePtr = Marshal.PtrToStructure <SecurityContextNamesBuffer>(namePtr).servername;
            var username      = Marshal.PtrToStringUni(usernamePtr);

            SspiInterop.FreeContextBuffer(usernamePtr);
            SspiInterop.FreeContextBuffer(servernamePtr);
            Marshal.FreeHGlobal(namePtr);

            return(username);
        }
        public SspiCredentials()
        {
            long expiry = 0;

            var result = SspiInterop.AcquireCredentialsHandle(
                IntPtr.Zero,
                SecurityPackage,
                SspiInterop.SECPKG_CRED_BOTH,
                IntPtr.Zero,
                IntPtr.Zero,
                0,
                IntPtr.Zero,
                ref _credentials,
                ref expiry);

            if (result != SspiInterop.SEC_E_OK)
            {
                throw new Exception($"Unable to aquire credentials for current user,  SECURITY_STATUS 0x{result:x8}");
            }

            Credentials = _credentials;
        }
Beispiel #5
0
        private static string[] GetGroupMembershipFromContext(SecurityHandle context)
        {
            // Query the context to obtain the Win32 Access Token, this will enable us to get the list of SID's that
            // represent group membership for the principal, we will use these to populate the Roles property
            var accessToken    = new SecurityContextBuffer();
            var accessTokenPtr = Marshal.AllocHGlobal(Marshal.SizeOf(accessToken));

            Marshal.StructureToPtr(accessToken, accessTokenPtr, false);

            var status = SspiInterop.QueryContextAttributes(ref context, SspiInterop.SECPKG_ATTR_ACCESS_TOKEN, accessTokenPtr);

            if (status != SspiInterop.SEC_E_OK)
            {
                Marshal.FreeHGlobal(accessTokenPtr);
                throw new AuthenticationException($"An unhandled exception occurred obtaining the access token from the context (QueryContextAttributes returned: {status})");
            }
            // who closes the access token, I assume when we delete the context
            var tokenPtr = Marshal.PtrToStructure <SecurityContextBuffer>(accessTokenPtr).Buffer;
            var groups   = GetMemebershipSids(tokenPtr).ToArray();

            Marshal.FreeHGlobal(accessTokenPtr);

            return(groups);
        }