Exemplo n.º 1
0
        /// <summary>
        /// Grab from a settings file.
        /// </summary>
        /// <param name="path"></param>
        /// <param name="logger"></param>
        public void PopulateFromSettingsFile(string path, ILoggerInterface logger)
        {
            string file = UtilsSystem.CombinePaths(path, "artifact-settings.yml");

            if (!File.Exists(file))
            {
                return;
            }

            var configfile = new Configuration.YamlConfigurationFile();

            try
            {
                // This file might be malformed, do not crash and let other
                // environment information sources have their chance
                configfile.ParseFromFile(file);
            }
            catch (Exception e)
            {
                logger.LogException(new Exception("Error parsing file: " + file, e));
                return;
            }

            // Parse the artifact settings...
            this.branch     = configfile.GetStringValue("repo-branch", null);
            this.commit_sha = configfile.GetStringValue("repo-commit", null);
            this.version    = configfile.GetStringValue("build-id", null);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Get a setting
        /// </summary>
        /// <typeparam name="TType"></typeparam>
        /// <param name="name"></param>
        /// <param name="defaultValue"></param>
        /// <param name="logger"></param>
        /// <param name="isEnum"></param>
        /// <returns></returns>
        public TType GetSettingPersistent <TType>(string name, TType defaultValue, ILoggerInterface logger, bool isEnum = false)
        {
            this.privateDataPersistent = this.privateDataPersistent ?? new Dictionary <string, object>();

            TType result = defaultValue;

            if (!this.privateDataPersistent.ContainsKey(name))
            {
                return(defaultValue);
            }

            try
            {
                if (isEnum)
                {
                    result = (TType)Enum.Parse(typeof(TType), Convert.ToString(this.privateDataPersistent[name]));
                }
                else
                {
                    result = (TType)this.privateDataPersistent[name];
                }
            }
            catch (Exception e)
            {
                logger.LogInfo(false, "source value: '" + Convert.ToString(this.privateDataPersistent[name]) + "'");
                logger.LogException(e);
            }

            return(result);
        }
Exemplo n.º 3
0
        public static List <ProcessInfo> GetPathProcessesInfo(string path, ILoggerInterface logger, bool logDetails = false)
        {
            List <ProcessInfo> result = new List <ProcessInfo>();

            foreach (var process in GetProcessesThatBlockPathHandle(path, logger, logDetails))
            {
                try
                {
                    result.Add(GetProcessInfo(process.pid, logger));
                }
                catch (Exception e)
                {
                    logger.LogException(e, EventLogEntryType.Warning);
                }
            }

            return(result);
        }
Exemplo n.º 4
0
        private static List <Handle> GetProcessesThatBlockPathHandle(string path, ILoggerInterface logger, bool logDetails = false)
        {
            if (!File.Exists(path) && !Directory.Exists(path))
            {
                return(new List <Handle>());
            }

            string key  = "SOFTWARE\\Sysinternals\\Handle";
            string name = "EulaAccepted";

            // This Utility has an EULA GUI on first run... try to avoid that
            // by manually setting the registry
            int?eulaaccepted64 = (int?)UtilsRegistry.GetRegistryKeyValue64(RegistryHive.CurrentUser, key, name, null);
            int?eulaaccepted32 = (int?)UtilsRegistry.GetRegistryKeyValue32(RegistryHive.CurrentUser, key, name, null);

            bool eulaaccepted = (eulaaccepted32 == 1 && eulaaccepted64 == 1);

            if (!eulaaccepted)
            {
                UtilsRegistry.SetRegistryValue(RegistryHive.CurrentUser, key, name, 1, RegistryValueKind.DWord);
            }

            // Normalize the path, to ensure that long path is not used, otherwise handle.exe won't work as expected
            string fileName = UtilsSystem.RemoveLongPathSupport(path);

            List <Handle> result     = new List <Handle>();
            string        outputTool = string.Empty;

            // Gather the handle.exe from the embeded resource and into a temp file
            var handleexe = UtilsSystem.GetTempPath("handle") + Guid.NewGuid().ToString().Replace("-", "_") + ".exe";

            UtilsSystem.EmbededResourceToFile(Assembly.GetExecutingAssembly(), "_Resources.Handle.exe", handleexe);

            try
            {
                using (Process tool = new Process())
                {
                    tool.StartInfo.FileName               = handleexe;
                    tool.StartInfo.Arguments              = fileName;
                    tool.StartInfo.UseShellExecute        = false;
                    tool.StartInfo.Verb                   = "runas";
                    tool.StartInfo.RedirectStandardOutput = true;
                    tool.Start();
                    outputTool = tool.StandardOutput.ReadToEnd();
                    tool.WaitForExit(1000);

                    if (!tool.HasExited)
                    {
                        tool.Kill();
                    }
                }
            }
            catch (Exception e)
            {
                logger.LogException(e, EventLogEntryType.Warning);
            }
            finally
            {
                UtilsSystem.DeleteFile(handleexe, logger, 5);
            }

            string matchPattern = @"(?<=\s+pid:\s+)\b(\d+)\b(?=\s+)";

            foreach (Match match in Regex.Matches(outputTool, matchPattern))
            {
                if (int.TryParse(match.Value, out var pid))
                {
                    if (result.All(i => i.pid != pid))
                    {
                        result.Add(new Handle()
                        {
                            pid = pid
                        });
                    }
                }
            }

            if (result.Any() && logDetails)
            {
                logger?.LogInfo(true, outputTool);
            }

            return(result);
        }
Exemplo n.º 5
0
        /// <summary>
        /// Closes all the handles that block any files in the specified path
        /// </summary>
        /// <param name="path"></param>
        /// <param name="allowedProcesses">List of whitelisted processes</param>
        /// <param name="logger"></param>
        public static void ClosePathProcesses(
            string path,
            List <string> allowedProcesses,
            ILoggerInterface logger)
        {
            if (string.IsNullOrWhiteSpace(path))
            {
                return;
            }

            // Make sure the path exists
            if (!File.Exists(path) && !Directory.Exists(path))
            {
                return;
            }

            // Load list of processes that block directory
            var processes = GetPathProcessesInfo(path, logger);

            // Filter the whitelisted
            string regex = string.Join("|", allowedProcesses);
            var    processesThatWillBeClosed = processes.Where((i) => i.MainModulePath != null && Regex.IsMatch(i.MainModulePath, regex)).ToList();

            if (!processesThatWillBeClosed.Any())
            {
                return;
            }

            // Message of processes that will not be closed
            var processesThatWillNotBeClosed = processes.Except(processesThatWillBeClosed).ToList();

            if (processesThatWillNotBeClosed.Any())
            {
                logger.LogWarning(true, "The following processes are not whitelisted and will not be closed {0}", string.Join(", ", processesThatWillNotBeClosed.Select((i) => i.ProcessName)));
            }

            // Grab the actual process instances
            var processesInstances = GetProcessInstance(processesThatWillBeClosed);

            // First kill al the processes.
            foreach (var p in processesInstances)
            {
                try
                {
                    logger.LogInfo(true, "Killing process: {0}", p.ProcessName);

                    if (!p.HasExited)
                    {
                        p.Kill();
                        p.WaitForExit(3000);
                    }
                }
                catch (Exception e)
                {
                    logger.LogException(e, EventLogEntryType.Warning);
                }
            }

            // Even though the processes have exited, handles take a while to be released
            Thread.Sleep(500);

            foreach (var p in processesInstances)
            {
                bool hasClosed = UtilsSystem.WaitWhile(() => !p.HasExited, 15000, $"Waiting for process {p.ProcessName} to close.", logger);
                logger.LogInfo(true, "Process {0} has closed: {1}", p.ProcessName, hasClosed);
            }
        }
        /// <summary>
        /// Create a user or return one if it does not exist.
        /// </summary>
        /// <param name="identity"></param>
        /// <param name="password"></param>
        /// <param name="displayName"></param>
        /// <param name="logger"></param>
        /// <param name="acp"></param>
        /// <returns></returns>
        public static UserPrincipal EnsureUserExists(
            string identity,
            string password,
            string displayName,
            ILoggerInterface logger,
            AccountManagementPrincipalContext acp)
        {
            var parsedUserName = new FqdnNameParser(identity);

            if (parsedUserName.UserPrincipalName.Length > 64)
            {
                throw new Exception($"Windows account userPrincipalName '{parsedUserName.UserPrincipalName}' cannot be longer than 64 characters.");
            }

            using (PrincipalContext pc = BuildPrincipal(acp))
            {
                UserPrincipal up = FindUser(identity, pc);

                string samAccountName = parsedUserName.SamAccountName;

                logger.LogInfo(false, $"Ensure windows account exists '{samAccountName}@{password}' with userPrincipal '{identity}'");

                if (up == null)
                {
                    up = new UserPrincipal(pc, samAccountName, password, true);
                }
                else
                {
                    logger.LogInfo(true, $"Found account IsAccountLockedOut={up.IsAccountLockedOut()}, SamAccountName={up.SamAccountName}");

                    // Make sure we have the latest password, just in case
                    // the pwd algorithm generation changes...
                    try
                    {
                        up.SetPassword(password);
                    }
                    catch (Exception e)
                    {
                        logger.LogWarning(true, "Cannot update password for account: " + e.Message + e.InnerException?.Message);
                    }
                }

                up.UserCannotChangePassword = true;
                up.PasswordNeverExpires     = true;
                up.Enabled     = true;
                up.DisplayName = displayName;
                up.Description = parsedUserName.UserPrincipalName;

                // If we are in a domain, assign the user principal name
                if (pc.ContextType == ContextType.Domain)
                {
                    logger.LogInfo(true, "Setting UserPrincipalName to '{0}'", parsedUserName.UserPrincipalName);
                    up.UserPrincipalName = parsedUserName.UserPrincipalName + "@" + parsedUserName.DomainName.ToLower();
                }

                if (up.IsAccountLockedOut())
                {
                    try
                    {
                        up.UnlockAccount();
                    }
                    catch (Exception e)
                    {
                        logger.LogWarning(true, "Cannot unlock account: " + e.Message + e.InnerException?.Message);
                    }
                }

                try
                {
                    up.Save();
                }
                catch (Exception e)
                {
                    logger.LogException(new Exception("Error while saving user", e), EventLogEntryType.Warning);

                    // Sometimes it crashes, but everything was OK (weird?)
                    // so we check again if the user has been created
                    Thread.Sleep(500);
                    up = FindUser(identity, pc);

                    if (up == null)
                    {
                        // Rethrow the original, whatever it was.
                        ExceptionDispatchInfo.Capture(e).Throw();
                    }
                }

                return(up);
            }
        }