Beispiel #1
0
        private LoginResponseMessage HandleLoginRequest(LoginRequestMessage msg)
        {
            try
            {
                PluginDriver sessionDriver = new PluginDriver();
                bool LastUsernameEnable = Settings.Get.LastUsernameEnable;

                msg = SplitDomainfromUsername(msg);
                sessionDriver.UserInformation.Username = msg.Username;
                sessionDriver.UserInformation.Password = (String.IsNullOrEmpty(msg.Password)) ? "" : msg.Password;
                sessionDriver.UserInformation.Domain = msg.Domain;
                sessionDriver.UserInformation.SessionID = msg.Session;
                if (msg.Reason == LoginRequestMessage.LoginReason.CredUI)
                {
                    sessionDriver.SessionProperties.CREDUI = true;
                }

                if (String.IsNullOrEmpty(sessionDriver.UserInformation.Username))
                {
                    return new LoginResponseMessage() { Result = false, Message = String.Format("No Username supplied\n\n'{0}' was entered and parsed to '{1}'", msg.Username, sessionDriver.UserInformation.Username) };
                }

                // check if a plugin still does some logoff work for this user
                Boolean thisUserLogoff = false;
                foreach (IPluginLogoffRequestAddTime plugin in PluginLoader.GetOrderedPluginsOfType<IPluginLogoffRequestAddTime>())
                {
                    if (plugin.LoginUserRequest(sessionDriver.UserInformation.Username))
                        thisUserLogoff = true;
                }
                if (thisUserLogoff)
                {
                    return new LoginResponseMessage() { Result = false, Message = String.Format("Still logoff work to do for user {0}\nWait a view seconds and retry", sessionDriver.UserInformation.Username) };
                }

                // do the domain logon
                string domainmember = Abstractions.WindowsApi.pInvokes.GetMachineDomainMembershipEX();
                m_logger.InfoFormat("domain check:[{0}] [{1}] [{2}]", Regex.IsMatch(msg.Username, "\\|@"), !String.IsNullOrEmpty(domainmember), !sessionDriver.UserInformation.Domain.Equals(Environment.MachineName, StringComparison.CurrentCultureIgnoreCase));
                if ((Regex.IsMatch(msg.Username, "\\|@") || !String.IsNullOrEmpty(domainmember)) && !sessionDriver.UserInformation.Domain.Equals(Environment.MachineName, StringComparison.CurrentCultureIgnoreCase))
                {
                    m_logger.DebugFormat("domain logon: Username:{0} domainmember:{1} domain:{2}", msg.Username, domainmember, sessionDriver.UserInformation.Domain);
                    // if domain was provided by username and it got messed up ...
                    if (String.IsNullOrEmpty(sessionDriver.UserInformation.Domain) && Regex.IsMatch(msg.Username, "\\|@"))
                    {
                        return new LoginResponseMessage() { Result = false, Message = String.Format("No Domainname supplied\n\n'{0}' was entered and parsed to '{1}'", msg.Username, sessionDriver.UserInformation.Domain) };
                    }

                    if (Abstractions.WindowsApi.pInvokes.DomainMember(sessionDriver.UserInformation.Domain))
                    {
                        m_logger.InfoFormat("DomainMember");
                        // pc is member of this domain provided by the username field
                        if (Abstractions.WindowsApi.pInvokes.ValidateUser(sessionDriver.UserInformation.Username, sessionDriver.UserInformation.Domain, sessionDriver.UserInformation.Password))
                        {
                            if (LastUsernameEnable && msg.Reason == LoginRequestMessage.LoginReason.Login)
                            {
                                Settings.s_settings.SetSetting("LastUsername", String.Format("{0}\\{1}", sessionDriver.UserInformation.Domain, sessionDriver.UserInformation.Username));
                            }
                            m_logger.InfoFormat("Sucess");
                            return new LoginResponseMessage()
                            {
                                Result = true,
                                Message = "",
                                Username = sessionDriver.UserInformation.Username,
                                Domain = sessionDriver.UserInformation.Domain,
                                Password = sessionDriver.UserInformation.Password
                            };
                        }
                        else
                        {
                            string message = String.Format("The provided account:{0} name does not exist on:{1} or the password is wrong", sessionDriver.UserInformation.Username, sessionDriver.UserInformation.Domain);
                            m_logger.InfoFormat(message);
                            return new LoginResponseMessage()
                            {
                                Result = false,
                                Message = message,
                                Username = sessionDriver.UserInformation.Username,
                                Domain = sessionDriver.UserInformation.Domain,
                                Password = sessionDriver.UserInformation.Password
                            };
                        }
                    }
                    else if (!String.IsNullOrEmpty(domainmember))
                    {
                        m_logger.InfoFormat("GetMachineDomainMembership");
                        // pc is member of a domain
                        sessionDriver.UserInformation.Domain = domainmember;
                        if (Abstractions.WindowsApi.pInvokes.ValidateUser(sessionDriver.UserInformation.Username, sessionDriver.UserInformation.Domain, sessionDriver.UserInformation.Password))
                        {
                            if (LastUsernameEnable && msg.Reason == LoginRequestMessage.LoginReason.Login)
                            {
                                Settings.s_settings.SetSetting("LastUsername", String.Format("{0}\\{1}", sessionDriver.UserInformation.Domain, sessionDriver.UserInformation.Username));
                            }
                            m_logger.InfoFormat("Sucess");
                            return new LoginResponseMessage()
                            {
                                Result = true,
                                Message = "",
                                Username = sessionDriver.UserInformation.Username,
                                Domain = sessionDriver.UserInformation.Domain,
                                Password = sessionDriver.UserInformation.Password
                            };
                        }
                        else
                        {
                            m_logger.InfoFormat("Failed, query Remote({0}) SAM", domainmember);
                            sessionDriver.UserInformation.Domain = Environment.MachineName;
                        }
                    }
                }

                BooleanResult result = new BooleanResult() { Success = true, Message = "" };

                if (new[] { LoginRequestMessage.LoginReason.Login, LoginRequestMessage.LoginReason.CredUI }.Contains(msg.Reason))
                {
                    m_logger.DebugFormat("Processing LoginRequest for: {0} in session: {1} reason: {2}", sessionDriver.UserInformation.Username, msg.Session, msg.Reason);

                    Boolean isLoggedIN = false;
                    Boolean isUACLoggedIN = false;

                    // is this user a local user and was not created by pGina
                    Abstractions.WindowsApi.pInvokes.structenums.USER_INFO_4 userinfo4 = new Abstractions.WindowsApi.pInvokes.structenums.USER_INFO_4();
                    if (Abstractions.WindowsApi.pInvokes.UserGet(sessionDriver.UserInformation.Username, ref userinfo4))
                    {
                        if (!userinfo4.comment.Contains("pGina created"))
                        {
                            result.Success = Abstractions.WindowsApi.pInvokes.ValidateUser(sessionDriver.UserInformation.Username, sessionDriver.UserInformation.Domain, sessionDriver.UserInformation.Password);
                            if (result.Success)
                            {
                                if (LastUsernameEnable && msg.Reason == LoginRequestMessage.LoginReason.Login)
                                {
                                    Settings.s_settings.SetSetting("LastUsername", String.Format("{0}", sessionDriver.UserInformation.Username));
                                }
                            }
                            return new LoginResponseMessage()
                            {
                                Result = result.Success,
                                Message = (result.Success) ? "Local non pGina user" : "Unknown username or bad password",
                                Username = sessionDriver.UserInformation.Username,
                                Domain = sessionDriver.UserInformation.Domain,
                                Password = sessionDriver.UserInformation.Password
                            };
                        }
                    }

                    Dictionary<int, List<string>> contextALL = Abstractions.WindowsApi.pInvokes.GetSessionContext();
                    List<string> Users = Abstractions.WindowsApi.pInvokes.GetSessionContextParser(-1, contextALL);
                    List<string> iUsers = Abstractions.WindowsApi.pInvokes.GetInteractiveUserList();
                    foreach (string user in Users)
                    {
                        m_logger.DebugFormat("Program running as user:{0}", user);
                        if (user.Equals(sessionDriver.UserInformation.Username, StringComparison.CurrentCultureIgnoreCase))
                        {
                            //the user is still logged in
                            isLoggedIN = true;
                            if (iUsers.Any(s => s.EndsWith("\\" + sessionDriver.UserInformation.Username, StringComparison.CurrentCultureIgnoreCase)))
                            {
                                int Locked_sessionID = Convert.ToInt32(iUsers.Find(s => s.EndsWith("\\" + sessionDriver.UserInformation.Username, StringComparison.CurrentCultureIgnoreCase)).Split('\\').First());
                                m_logger.DebugFormat("User:{0} is Locked in Session:{1}", sessionDriver.UserInformation.Username, Locked_sessionID);
                                // verify that this unlock is present somewhere in m_sessionPropertyCache
                                // if not, this login is not backed by m_sessionPropertyCache
                                if (m_sessionPropertyCache.GetAll().Any(i => i == Locked_sessionID))
                                {
                                    UserInformation uInfo = m_sessionPropertyCache.Get(Locked_sessionID).First().GetTrackedSingle<UserInformation>();
                                    if (!uInfo.Username.Equals(sessionDriver.UserInformation.Username, StringComparison.CurrentCultureIgnoreCase))
                                    {
                                        // that should never ever happen
                                        m_logger.ErrorFormat("User {0} is Locked in Session {1} but the username doesn't match the session information pGina contains. '{0}' vs. '{2}'", sessionDriver.UserInformation.Username, Locked_sessionID, uInfo.Username);
                                        return new LoginResponseMessage() { Result = false, Message = String.Format("User {0} is Locked in Session {1} but the username doesn't match the session information pGina contains\n\n'{0}' vs '{2}'", sessionDriver.UserInformation.Username, Locked_sessionID, uInfo.Username) };
                                    }
                                }
                                else
                                {
                                    m_logger.ErrorFormat("User {0} is Locked in Session {1} but was not authenticated by pGina. Unable to find SessionProperty in m_sessionPropertyCache.Get({1})", sessionDriver.UserInformation.Username, Locked_sessionID);
                                    return new LoginResponseMessage() { Result = false, Message = String.Format("User {0} is Locked in Session {1} but was not authenticated by pGina\n\nIt is possible that another Credential Provider was used\nor the pGina service has crashed.\n", sessionDriver.UserInformation.Username, Locked_sessionID) };
                                }
                            }
                            else
                            {
                                // verify that this UACed login is present somewhere in m_sessionPropertyCache
                                // if not, this login is not backed by m_sessionPropertyCache
                                foreach (int session in m_sessionPropertyCache.GetAll())
                                {
                                    if (m_sessionPropertyCache.Get(session).Any(s => s.GetTrackedSingle<UserInformation>().Username.Equals(sessionDriver.UserInformation.Username, StringComparison.CurrentCultureIgnoreCase)))
                                    {
                                        m_logger.DebugFormat("User:{0} is pGina UACed in Session:{1}", sessionDriver.UserInformation.Username, session);
                                        isUACLoggedIN = true;
                                        break;
                                    }
                                }
                                // is this user a local user and was not created by pGina
                                /*Abstractions.WindowsApi.pInvokes.structenums.USER_INFO_4 userinfo4 = new Abstractions.WindowsApi.pInvokes.structenums.USER_INFO_4();
                                if (Abstractions.WindowsApi.pInvokes.UserGet(sessionDriver.UserInformation.Username, ref userinfo4))
                                {
                                    if (!userinfo4.comment.Contains("pGina created"))
                                    {
                                        m_logger.DebugFormat("User:{0} is local non pGina", sessionDriver.UserInformation.Username);
                                        isUACLoggedIN = true;
                                    }
                                }*/

                                if (!isUACLoggedIN)
                                {
                                    List<string> runas_in_session = new List<string>();
                                    foreach (KeyValuePair<int, List<string>> pair in contextALL)
                                    {
                                        if (pair.Value.Any(s => s.Equals(sessionDriver.UserInformation.Username, StringComparison.CurrentCultureIgnoreCase)))
                                        {
                                            runas_in_session.Add(iUsers.DefaultIfEmpty("").FirstOrDefault(s => s.StartsWith(pair.Key.ToString())));
                                        }
                                    }
                                    m_logger.DebugFormat("There is a program running as {0} but it was'nt started with pGina. I can't log you in because this would conflict with the current running process. Session in which a process is running:{1}", sessionDriver.UserInformation.Username, String.Join(",", runas_in_session));
                                    return new LoginResponseMessage() { Result = false, Message = String.Format("There is a program running as {0} but it was'nt started with pGina.\nI can't log you in because this would conflict with the current running process.\n\nSession in which a process is running:\n{1}", sessionDriver.UserInformation.Username, String.Join("\n", runas_in_session)) };
                                }
                            }
                        }
                    }
                    if (!isLoggedIN)
                    {
                        result = sessionDriver.PerformLoginProcess();
                    }
                    else
                    {
                        // testing. ValidateCredentials would be correct here
                        if (!Abstractions.WindowsApi.pInvokes.ValidateUser(sessionDriver.UserInformation.Username, sessionDriver.UserInformation.Domain, sessionDriver.UserInformation.Password))
                        {
                            m_logger.ErrorFormat("Query local SAM: Bad password");
                            return new LoginResponseMessage()
                            {
                                Result = false,
                                Message = "Bad password",
                                Username = sessionDriver.UserInformation.Username,
                                Domain = sessionDriver.UserInformation.Domain,
                                Password = sessionDriver.UserInformation.Password
                            };
                        }
                    }

                    if (result.Success && (!isLoggedIN || msg.Reason == LoginRequestMessage.LoginReason.CredUI || isUACLoggedIN))
                    {
                        lock (m_sessionPropertyCache)
                        {
                            List<SessionProperties> ses = new List<SessionProperties>();
                            if (m_sessionPropertyCache.Exists(msg.Session))
                            {
                                ses = m_sessionPropertyCache.Get(msg.Session);
                            }
                            bool partof = false;
                            foreach (SessionProperties sess in ses)
                            {
                                UserInformation ui = sess.GetTrackedSingle<UserInformation>();
                                m_logger.InfoFormat("compare stored-user:{0} this-user:{1}", ui.Username, sessionDriver.UserInformation.Username);
                                if (sessionDriver.UserInformation.Username.Equals(ui.Username, StringComparison.CurrentCultureIgnoreCase))
                                {
                                    partof = true;
                                    m_logger.InfoFormat("contain user {0} in sessioninfo:{1} GUID:{2}", ui.Username, msg.Session, sess.Id);
                                    break;
                                }
                            }
                            if (!partof)
                            {
                                if (isLoggedIN)
                                {
                                    UserInformation ui = FindUserInfoInPropertyCache(sessionDriver.UserInformation.Username);
                                    if (ui != null)
                                    {
                                        ui.SessionID = msg.Session;
                                        sessionDriver.SessionProperties.AddTrackedSingle<UserInformation>(ui);
                                    }
                                }
                                else
                                {
                                    // add local profile path
                                    // its not sure that the profile realy ends up there
                                    // a win profile loading error can redirect the path to a temp path too
                                    UserInformation ui = sessionDriver.SessionProperties.GetTrackedSingle<UserInformation>();
                                    if (ui != null)
                                    {
                                        // worst case empty string
                                        ui.LocalProfilePath = Abstractions.Windows.User.GetProfileDir(ui.Username, ui.Password, ui.SID);
                                        sessionDriver.SessionProperties.AddTrackedSingle<UserInformation>(ui);
                                        m_logger.InfoFormat("ses add LocalProfilePath:[{0}]", ui.LocalProfilePath);
                                    }
                                }
                                ses.Add(sessionDriver.SessionProperties);
                                m_logger.InfoFormat("add user {0} to sessioninfo:{1} GUID:{2} CREDUI:{3}", sessionDriver.UserInformation.Username, msg.Session, sessionDriver.SessionProperties.Id, (msg.Reason == LoginRequestMessage.LoginReason.CredUI) ? "true" : "false");
                                m_logger.InfoFormat("ses username:{0} description:{1} credui:{2} isLoggedIN:{3}", ses.Last().GetTrackedSingle<UserInformation>().Username, ses.Last().GetTrackedSingle<UserInformation>().Description, ses.Last().CREDUI, isLoggedIN);
                                m_sessionPropertyCache.Add(msg.Session, ses);
                            }
                        }
                    }
                }
                else
                {
                    // check if username is equal originalusername
                    // if not return originalusername and password
                    bool originalUsernameUnlock = Settings.Get.UseOriginalUsernameInUnlockScenario;
                    if (originalUsernameUnlock && LoginRequestMessage.LoginReason.Unlock == msg.Reason)
                    {
                        m_logger.InfoFormat("Unlock with original Username:{0} for Session:{1}", sessionDriver.UserInformation.Username, msg.Session);
                        lock (m_sessionPropertyCache)
                        {
                            List<SessionProperties> ses = new List<SessionProperties>();
                            if (m_sessionPropertyCache.Exists(msg.Session))
                            {
                                ses = m_sessionPropertyCache.Get(msg.Session);
                            }
                            // the first entry is always the interactive user
                            SessionProperties sess = ses.DefaultIfEmpty(new SessionProperties(Guid.Empty, true)).FirstOrDefault();
                            UserInformation ui = sess.GetTrackedSingle<UserInformation>();
                            if (ui.Username != ui.OriginalUsername)
                            {
                                if (ui.OriginalPassword == sessionDriver.UserInformation.Password)
                                {
                                    sessionDriver.UserInformation.Username = ui.Username;
                                    sessionDriver.UserInformation.Domain = Environment.MachineName;
                                    sessionDriver.UserInformation.Password = ui.Password;
                                    result.Success = true;
                                    m_logger.InfoFormat("Unlock as:{0} for Session:{1}", sessionDriver.UserInformation.Username, msg.Session);
                                }
                                else
                                {
                                    result.Success = false;
                                    result.Message = "Password incorrect!";
                                }
                            }
                        }
                    }
                    else
                    {
                        m_logger.DebugFormat("Parse Request for: {0} in session: {1} reason: {2}", sessionDriver.UserInformation.Username, msg.Session, msg.Reason);
                    }
                }

                if (LastUsernameEnable && msg.Reason == LoginRequestMessage.LoginReason.Login && result.Success)
                {
                    Settings.s_settings.SetSetting("LastUsername", String.Format("{0}", sessionDriver.UserInformation.Username));
                }
                return new LoginResponseMessage()
                {
                    Result = result.Success,
                    Message = result.Message,
                    Username = sessionDriver.UserInformation.Username,
                    Domain = sessionDriver.UserInformation.Domain,
                    Password = sessionDriver.UserInformation.Password
                };
            }
            catch (Exception e)
            {
                m_logger.ErrorFormat("Internal error, unexpected exception while handling login request: {0}", e);
                return new LoginResponseMessage() { Result = false, Message = "Internal error" };
            }
        }
Beispiel #2
0
        private LoginResponseMessage HandleLoginRequest(LoginRequestMessage msg)
        {
            try
            {
                PluginDriver sessionDriver = new PluginDriver();
                sessionDriver.UserInformation.Username = msg.Username.Trim();
                sessionDriver.UserInformation.Password = msg.Password;

                m_logger.DebugFormat("Processing LoginRequest for: {0} in session: {1} reason: {2}",
                    sessionDriver.UserInformation.Username, msg.Session, msg.Reason);
                BooleanResult result = sessionDriver.PerformLoginProcess();

                if (msg.Reason == LoginRequestMessage.LoginReason.Login)
                {
                    lock (m_sessionPropertyCache)
                    {
                        m_sessionPropertyCache.Add(msg.Session, sessionDriver.SessionProperties);
                    }
                }

                return new LoginResponseMessage()
                {
                    Result = result.Success,
                    Message = result.Message,
                    Username = sessionDriver.UserInformation.Username,
                    Domain = sessionDriver.UserInformation.Domain,
                    Password = sessionDriver.UserInformation.Password
                };
            }
            catch (Exception e)
            {
                m_logger.ErrorFormat("Internal error, unexpected exception while handling login request: {0}", e);
                return new LoginResponseMessage() { Result = false, Message = "Internal error" };
            }
        }
Beispiel #3
0
        private LoginRequestMessage SplitDomainfromUsername(LoginRequestMessage msg)
        {
            LoginRequestMessage ret = msg;
            Dictionary<string, string> split = SplitDomainfromUsername(msg.Username, msg.Domain);
            ret.Username = split["username"];
            ret.Domain = split["domain"];

            return ret;
        }