Exemple #1
0
        /// <summary>
        /// Gets the primary token of the first found active user session.
        /// </summary>
        /// <returns>A <see cref="TokenHelper"/> or null if no valid sessions was found.</returns>
        /// <exception cref="Win32Exception"></exception>
        public static SafeAccessTokenHandle GetPrimaryTokenOfFirstActiveSession()
        {
            //!!! Parts are from Copyright (c) 2014 Justin Murray - MIT-License, thanks to him !!!
            // https://github.com/murrayju/CreateProcessAsUser, 18.08.2019

            uint   activeSessionId = Wtsapi32.InvalidSessionId;
            IntPtr sessionInfos    = IntPtr.Zero;
            var    sessionCount    = 0;

            try
            {
                //Get a handle to the user access token for the current active session.
                if (Wtsapi32.WTSEnumerateSessions(Wtsapi32.WtsCurrentServerHandle, 0, 1, ref sessionInfos, ref sessionCount))
                {
                    int    arrayElementSize = Marshal.SizeOf <Wtsapi32.WtsSessionInfo>();
                    IntPtr current          = sessionInfos;

                    for (var i = 0; i < sessionCount; i++)
                    {
                        var sessionInfo = Marshal.PtrToStructure <Wtsapi32.WtsSessionInfo>(current);
                        current += arrayElementSize;

                        if (sessionInfo.State == Wtsapi32.WtsConnectstateClass.WTSActive)
                        {
                            activeSessionId = (uint)sessionInfo.SessionID;
                            break;
                        }
                    }
                }
            }
            finally
            {
                if (sessionInfos != IntPtr.Zero)
                {
                    Wtsapi32.WTSFreeMemory(sessionInfos);
                }
            }

            //If enumerating not working use the fall back method
            if (activeSessionId == Wtsapi32.InvalidSessionId)
            {
                activeSessionId = Kernel32.WTSGetActiveConsoleSessionId();

                if (activeSessionId == Wtsapi32.InvalidSessionId)
                {
                    return(null);
                }
            }

            return(GetPrimaryTokenFromSessionId(activeSessionId));
        }
Exemple #2
0
        /// <summary>
        /// Gets the active session user token.
        /// </summary>
        /// <param name="userToken">The user token.</param>
        /// <returns></returns>
        /// <exception cref="Win32Exception"></exception>
        public static TokenHandle GetActiveSessionUserToken()
        {
            //!!! Parts are from Copyright (c) 2014 Justin Murray - MIT-License, thanks to him !!!
            // https://github.com/murrayju/CreateProcessAsUser, 18.08.2019

            var    primTokenHandle = new TokenHandle();
            uint   activeSessionId = Wtsapi32.InvalidSessionId;
            IntPtr sessionInfos    = IntPtr.Zero;
            var    sessionCount    = 0;

            try
            {
                //Get a handle to the user access token for the current active session.
                if (Wtsapi32.WTSEnumerateSessions(Wtsapi32.WtsCurrentServerHandle, 0, 1, ref sessionInfos, ref sessionCount))
                {
                    int    arrayElementSize = Marshal.SizeOf(typeof(Wtsapi32.WtsSessionInfo));
                    IntPtr current          = sessionInfos;

                    for (var i = 0; i < sessionCount; i++)
                    {
                        var sessionInfo = (Wtsapi32.WtsSessionInfo)Marshal.PtrToStructure(current, typeof(Wtsapi32.WtsSessionInfo));
                        current += arrayElementSize;

                        if (sessionInfo.State == Wtsapi32.WtsConnectstateClass.WTSActive)
                        {
                            activeSessionId = (uint)sessionInfo.SessionID;
                        }
                    }
                }
            }
            finally
            {
                if (sessionInfos != IntPtr.Zero)
                {
                    Wtsapi32.WTSFreeMemory(sessionInfos);
                }
            }

            //If enumerating not working use the fall back method
            if (activeSessionId == Wtsapi32.InvalidSessionId)
            {
                activeSessionId = Kernel32.WTSGetActiveConsoleSessionId();

                if (activeSessionId == Wtsapi32.InvalidSessionId)
                {
                    throw new Exception("No valid session found.");
                }
            }

            var impersonationToken = new TokenHandle();

            try
            {
                //Get token
                if (!Wtsapi32.WTSQueryUserToken(activeSessionId, out impersonationToken))
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }

                //Convert the impersonation token to a primary token
                if (!Advapi32.DuplicateTokenEx(impersonationToken, 0, IntPtr.Zero, (int)Advapi32.SecurityImpersonationLevel.SecurityImpersonation, (int)Advapi32.TokenType.TokenPrimary, ref primTokenHandle))
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }
            }
            finally
            {
                impersonationToken.Close();
            }

            return(primTokenHandle);
        }
Exemple #3
0
        /// <summary>
        /// Gets the primary token from an first active user session with the given username.
        /// </summary>
        /// <param name="username">The username.</param>
        /// <returns>A <see cref="SafeAccessTokenHandle"/> or null if no valid sessions was found.</returns>
        /// <exception cref="Win32Exception">
        /// </exception>
        public static SafeAccessTokenHandle GetPrimaryTokenByUsername(string username)
        {
            //!!! Parts are from Copyright (c) 2014 Justin Murray - MIT-License, thanks to him !!!
            // https://github.com/murrayju/CreateProcessAsUser, 18.08.2019

            uint   activeSessionId = Wtsapi32.InvalidSessionId;
            IntPtr sessionInfos    = IntPtr.Zero;
            var    sessionCount    = 0;

            try
            {
                //Get a handle to the user access token for the current active session.
                if (Wtsapi32.WTSEnumerateSessions(Wtsapi32.WtsCurrentServerHandle, 0, 1, ref sessionInfos,
                                                  ref sessionCount))
                {
                    int    arrayElementSize = Marshal.SizeOf <Wtsapi32.WtsSessionInfo>();
                    IntPtr current          = sessionInfos;

                    for (var i = 0; i < sessionCount; i++)
                    {
                        IntPtr usernamePtr = IntPtr.Zero;
                        IntPtr domainPtr   = IntPtr.Zero;
                        try
                        {
                            var sessionInfo = Marshal.PtrToStructure <Wtsapi32.WtsSessionInfo>(current);
                            current += arrayElementSize;

                            //If the session is not active, go to the next
                            if (sessionInfo.State != Wtsapi32.WtsConnectstateClass.WTSActive)
                            {
                                continue;
                            }

                            //Get the username
                            if (!Wtsapi32.WTSQuerySessionInformation(Wtsapi32.WtsCurrentServerHandle, sessionInfo.SessionID, Wtsapi32.WtsInfoClass.WtsUserName, out usernamePtr, out uint bytesReturnedUsername))
                            {
                                throw new Win32Exception(Marshal.GetLastWin32Error());
                            }

                            //continue when no bytes returned
                            if (bytesReturnedUsername <= 0)
                            {
                                continue;
                            }

                            string sessionUsername = Marshal.PtrToStringUni(usernamePtr);

                            //Get the domain name
                            if (!Wtsapi32.WTSQuerySessionInformation(Wtsapi32.WtsCurrentServerHandle, sessionInfo.SessionID, Wtsapi32.WtsInfoClass.WtsDomainName, out domainPtr, out uint bytesReturnedDomainName))
                            {
                                throw new Win32Exception(Marshal.GetLastWin32Error());
                            }

                            //continue when no bytes returned
                            if (bytesReturnedDomainName <= 0)
                            {
                                continue;
                            }

                            string sessionDomainName = Marshal.PtrToStringUni(domainPtr);

                            //If the username is not the same, go to the next
                            string sessionFullUsername = sessionDomainName.ConvertNullTerminatedStringToString() + "\\" + sessionUsername.ConvertNullTerminatedStringToString();


                            //If the session is found break the for
                            if (!string.IsNullOrWhiteSpace(sessionFullUsername) && sessionFullUsername.Equals(username.Trim(), StringComparison.OrdinalIgnoreCase))
                            {
                                activeSessionId = (uint)sessionInfo.SessionID;
                                break;
                            }
                        }
                        finally
                        {
                            if (usernamePtr != IntPtr.Zero)
                            {
                                Wtsapi32.WTSFreeMemory(usernamePtr);
                            }

                            if (domainPtr != IntPtr.Zero)
                            {
                                Wtsapi32.WTSFreeMemory(domainPtr);
                            }
                        }
                    }
                }
                else
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }
            }
            finally
            {
                if (sessionInfos != IntPtr.Zero)
                {
                    Wtsapi32.WTSFreeMemory(sessionInfos);
                }
            }

            //If enumerating not working throw an exception
            if (activeSessionId == Wtsapi32.InvalidSessionId)
            {
                return(null);
            }

            return(GetPrimaryTokenFromSessionId(activeSessionId));
        }
Exemple #4
0
        /// <summary>
        /// Gets the session token by the username.
        /// </summary>
        /// <param name="username">The username.</param>
        /// <returns></returns>
        /// <exception cref="Exception">No valid session found.</exception>
        /// <exception cref="Win32Exception">
        /// </exception>
        public static TokenHandle GetSessionTokenByUsername(string username)
        {
            //!!! Parts are from Copyright (c) 2014 Justin Murray - MIT-License, thanks to him !!!
            // https://github.com/murrayju/CreateProcessAsUser, 18.08.2019

            var    primTokenHandle = new TokenHandle();
            uint   activeSessionId = Wtsapi32.InvalidSessionId;
            IntPtr sessionInfos    = IntPtr.Zero;
            IntPtr usernamePtr     = IntPtr.Zero;
            IntPtr domainPtr       = IntPtr.Zero;
            var    sessionCount    = 0;

            try
            {
                //Get a handle to the user access token for the current active session.
                if (Wtsapi32.WTSEnumerateSessions(Wtsapi32.WtsCurrentServerHandle, 0, 1, ref sessionInfos, ref sessionCount))
                {
                    int    arrayElementSize = Marshal.SizeOf(typeof(Wtsapi32.WtsSessionInfo));
                    IntPtr current          = sessionInfos;

                    for (var i = 0; i < sessionCount; i++)
                    {
                        var sessionInfo = (Wtsapi32.WtsSessionInfo)Marshal.PtrToStructure(current, typeof(Wtsapi32.WtsSessionInfo));
                        current += arrayElementSize;

                        //If the session is not active, go to the next
                        if (sessionInfo.State != Wtsapi32.WtsConnectstateClass.WTSActive)
                        {
                            continue;
                        }

                        //Get the username
                        if (!Wtsapi32.WTSQuerySessionInformation(Wtsapi32.WtsCurrentServerHandle, sessionInfo.SessionID, Wtsapi32.WtsInfoClass.WtsUserName, out usernamePtr, out uint bytesReturnedUsername))
                        {
                            throw new Win32Exception(Marshal.GetLastWin32Error());
                        }

                        //continue when no bytes returned
                        if (bytesReturnedUsername <= 0)
                        {
                            continue;
                        }

                        string sessionUsername = Marshal.PtrToStringUni(usernamePtr);

                        //Get the domain name
                        if (!Wtsapi32.WTSQuerySessionInformation(Wtsapi32.WtsCurrentServerHandle, sessionInfo.SessionID, Wtsapi32.WtsInfoClass.WtsDomainName, out domainPtr, out uint bytesReturnedDomainName))
                        {
                            throw new Win32Exception(Marshal.GetLastWin32Error());
                        }

                        //continue when no bytes returned
                        if (bytesReturnedDomainName <= 0)
                        {
                            continue;
                        }

                        string sessionDomainName = Marshal.PtrToStringUni(domainPtr);

                        //If the username is not the same, go to the next
                        string sessionFullUsername = sessionDomainName.ConvertNullTerminatedStringToString() + "\\" + sessionUsername.ConvertNullTerminatedStringToString();
                        if (sessionUsername == null || !string.Equals(username.Trim(), sessionFullUsername, StringComparison.CurrentCultureIgnoreCase))
                        {
                            continue;
                        }

                        //If the session is found break the for
                        activeSessionId = (uint)sessionInfo.SessionID;
                        break;
                    }
                }
                else
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }
            }
            finally
            {
                if (usernamePtr != IntPtr.Zero)
                {
                    Wtsapi32.WTSFreeMemory(usernamePtr);
                }

                if (domainPtr != IntPtr.Zero)
                {
                    Wtsapi32.WTSFreeMemory(domainPtr);
                }

                if (sessionInfos != IntPtr.Zero)
                {
                    Wtsapi32.WTSFreeMemory(sessionInfos);
                }
            }

            //If enumerating not working throw an exception
            if (activeSessionId == Wtsapi32.InvalidSessionId)
            {
                throw new Exception("No valid session found.");
            }

            var impersonationToken = new TokenHandle();

            try
            {
                //Get token
                if (!Wtsapi32.WTSQueryUserToken(activeSessionId, out impersonationToken))
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }

                //Convert the impersonation token to a primary token
                if (!Advapi32.DuplicateTokenEx(impersonationToken, 0, IntPtr.Zero, (int)Advapi32.SecurityImpersonationLevel.SecurityImpersonation, (int)Advapi32.TokenType.TokenPrimary, ref primTokenHandle))
                {
                    throw new Win32Exception(Marshal.GetLastWin32Error());
                }
            }
            finally
            {
                impersonationToken.Close();
            }

            return(primTokenHandle);
        }