Пример #1
0
        public void Run(RunOptions options)
        {
            config = GetConfig(options);
            logger.Info("Loaded {0} with {1} triggers and {2} services", options.ConfigFile, config.Triggers.Count, config.Services.Count);

            // Secrets stores must be loaded before any services or notifyservices as they can use it in their options
            var secretsStoreTypes = GetSubTypes(typeof(BaseSecretsStore));

            logger.Debug("Loaded {0} secrets store types", secretsStoreTypes.Count);

            var secretsStores = new List <Tuple <BaseSecretsStore, SecretsStoreConfig> >();

            if (config.SecretsStores != null)
            {
                foreach (var secretsStoreConfig in config.SecretsStores)
                {
                    var secretsStoreType = secretsStoreTypes.SingleOrDefault(t => t.Name.Equals(secretsStoreConfig.Type, StringComparison.InvariantCultureIgnoreCase));

                    if (secretsStoreType == null)
                    {
                        logger.Error("Unable to find secrets store {0}, skipping", secretsStoreConfig.Type);
                    }
                    else
                    {
                        try
                        {
                            logger.Debug("Adding secrets store {0}", secretsStoreType.FullName);

                            // secretsStoreConfig.Options is a JObject, we need to convert it to the SecretsStoreOptions on the service
                            // This is kind of dirty (see BaseService discussion) but it works
                            var secretsStoreOptionsType = secretsStoreType.GetNestedType("SecretsStoreOptions", BindingFlags.Public | BindingFlags.NonPublic);

                            if (secretsStoreOptionsType == null)
                            {
                                logger.Trace("Did not locate SecretsStoreOptions nested type for secrets store {0}", secretsStoreOptionsType.FullName);
                                secretsStoreConfig.Options = null;
                            }
                            else
                            {
                                logger.Trace("Located SecretsStoreOptions nested type {0} for secrets store {1}", secretsStoreOptionsType.FullName, secretsStoreOptionsType.FullName);
                                secretsStoreConfig.Options = ((JObject)secretsStoreConfig.Options).ToObject(secretsStoreOptionsType);
                            }

                            var secretsStore = (BaseSecretsStore)Activator.CreateInstance(secretsStoreType, secretsStoreConfig.Options);
                            secretsStores.Add(new Tuple <BaseSecretsStore, SecretsStoreConfig>(secretsStore, secretsStoreConfig));
                            logger.Info("Loaded secrets store {0}", secretsStoreConfig.Type);
                        }
                        catch (Exception ex)
                        {
                            logger.Error(ex, "Error while loading secrets store {0}, skipping", secretsStoreConfig.Type);
                        }
                    }
                }
            }
            secretsStoreManager = new SecretsStoreManager(secretsStores);

            var notifyServiceTypes = GetSubTypes(typeof(BaseNotifyService));

            logger.Debug("Loaded {0} notify service types", notifyServiceTypes.Count);

            if (config.NotifyServices != null)
            {
                foreach (var notifyServiceConfig in config.NotifyServices)
                {
                    var notifyServiceType = notifyServiceTypes.SingleOrDefault(t => t.Name.Equals(notifyServiceConfig.Type, StringComparison.InvariantCultureIgnoreCase));

                    if (notifyServiceType == null)
                    {
                        logger.Error("Unable to find notify service {0}, skipping", notifyServiceConfig.Type);
                    }
                    else
                    {
                        try
                        {
                            logger.Debug("Adding notify service {0}", notifyServiceType.FullName);

                            // notifyServiceConfig.Options is a JObject, we need to convert it to the ServiceOptions on the service
                            // This is kind of dirty (see BaseService discussion) but it works
                            var notifyServiceOptionsType = notifyServiceType.GetNestedType("NotifyServiceOptions", BindingFlags.Public | BindingFlags.NonPublic);

                            if (notifyServiceOptionsType == null)
                            {
                                logger.Trace("Did not locate NotifyServiceOptions nested type for notify service {0}", notifyServiceType.FullName);
                                notifyServiceConfig.Options = null;
                            }
                            else
                            {
                                logger.Trace("Located ServiceOptions nested type {0} for notify service {1}", notifyServiceOptionsType.FullName, notifyServiceType.FullName);
                                notifyServiceConfig.Options = ((JObject)notifyServiceConfig.Options).ToObject(notifyServiceOptionsType);
                            }

                            var notifyService = (BaseNotifyService)Activator.CreateInstance(notifyServiceType, secretsStoreManager, notifyServiceConfig.Options);
                            notifyServices.Add(new Tuple <BaseNotifyService, NotifyServiceConfig>(notifyService, notifyServiceConfig));
                            logger.Info("Loaded notify service {0}", notifyServiceConfig.Type);
                        }
                        catch (Exception ex)
                        {
                            logger.Error(ex, "Error while loading notify service {0}, skipping", notifyServiceConfig.Type);
                        }
                    }
                }
            }

            // Send notification ASAP about startup
            foreach (var notifyService in notifyServices.Where(t => t.Item2.NotifyStartup))
            {
                try
                {
                    notifyService.Item1.NotifyStartup();
                }
                catch (Exception ex)
                {
                    logger.Error(ex, "Error while trying to notify startup for notify service {0}", notifyService.Item2.Type);
                }
            }


            // Start up web server for multi-factor requests
            //if (config.EnableMultiFactorRequests)
            //{
#if DEBUG
            webServer = new SentryWebServer(options.MfaBindUrl);
            webServer.Start();
            logger.Info("Started web server bound to {0}", options.MfaBindUrl);
#endif
            //}

            var serviceTypes = GetSubTypes(typeof(BaseService));
            logger.Debug("Loaded {0} service types", serviceTypes.Count);

            foreach (var serviceConfig in config.Services)
            {
                var serviceType = serviceTypes.SingleOrDefault(t => t.Name.Equals(serviceConfig.Type, StringComparison.InvariantCultureIgnoreCase));

                if (serviceType == null)
                {
                    logger.Error("Unable to find service {0}, skipping {1}", serviceConfig.Type, serviceConfig.Id);
                }
                else
                {
                    try
                    {
                        logger.Debug("Adding service {0} with Id {1}", serviceType.FullName, serviceConfig.Id);

                        // serviceConfig.Options is a JObject, we need to convert it to the ServiceOptions on the service
                        // This is kind of dirty (see BaseService discussion) but it works
                        var serviceOptionsType = serviceType.GetNestedType("ServiceOptions", BindingFlags.Public | BindingFlags.NonPublic);

                        if (serviceOptionsType == null)
                        {
                            logger.Trace("Did not locate ServiceOptions nested type for service {0}", serviceType.FullName);
                            serviceConfig.Options = null;
                        }
                        else
                        {
                            logger.Trace("Located ServiceOptions nested type {0} for service {1}", serviceOptionsType.FullName, serviceType.FullName);
                            serviceConfig.Options = ((JObject)serviceConfig.Options).ToObject(serviceOptionsType);
                        }

                        var service = (BaseService)Activator.CreateInstance(serviceType, secretsStoreManager, serviceConfig.Id, serviceConfig.Options);
                        services.Add(serviceConfig.Id.ToLowerInvariant(), service);
                        logger.Info("Loaded service {0}", serviceConfig.Id);
                    }
                    catch (Exception ex)
                    {
                        logger.Error(ex, "Error while loading service {0}, skipping", serviceConfig.Id);
                    }
                }
            }

            if (options.SkipVerify)
            {
                logger.Info("Skipping verify step");
            }
            else
            {
                var servicesToRemove = new List <string>();
                foreach (var service in services)
                {
                    logger.Debug("Verifying {0}", service.Key);
                    try
                    {
                        service.Value.Verify();
                        logger.Info("Verified {0}", service.Key);
                    }
                    catch (Exception ex)
                    {
                        logger.Error(ex, "Error verifying {0}, removing", service.Key);
                        servicesToRemove.Add(service.Key);
                    }
                }
                foreach (var serviceToRemove in servicesToRemove)
                {
                    services.Remove(serviceToRemove);
                }
            }

            if (options.JustFuckMyShitUpFam)
            {
                if (options.SkipJFMSUFConfirmation)
                {
                    logger.Info("Skipping JustFuckMyShitUpFam mode confirmation");
                }
                else
                {
                    logger.Warn("JustFuckMyShitUpFam mode requested");
                    Console.WriteLine("**********************************************************");
                    Console.WriteLine(" WARNING: JustFuckMyShitUpFam mode will run ALL triggers");
                    Console.WriteLine("    As if ALL trigger phrases had been detected");
                    Console.WriteLine("      The following actions will be performed:");
                    Console.WriteLine("");

                    var triggerConfigs = config.Triggers.SelectMany(t => t.Services).ToList();
                    foreach (var trigger in triggerConfigs)
                    {
                        var actionsAggregated = trigger.Actions.Aggregate((sum, addition) => sum + ", " + addition);
                        Console.WriteLine("  Service: " + trigger.Id + " Actions: " + actionsAggregated);
                    }

                    Console.WriteLine("");
                    Console.WriteLine("       These actions may not be reversible");
                    Console.WriteLine("  There is no additional confirmation or delay");
                    Console.WriteLine("        Are you SURE you want to do this?");
                    Console.WriteLine("**********************************************************");
                    Console.Write("Enter JFMSUF to confirm: ");

                    var userInput = Console.ReadLine();
                    if (userInput != "JFMSUF")
                    {
                        logger.Info("JustFuckMyShitUpFam mode canceled");
                        Environment.Exit(1);
                        return;
                    }
                }
                JFMSUF(options);
            }
            else
            {
                // Start main checking loop
                Loop(options);
            }

            // If cancellation is requested via cancellationToken, this exits the main thread
            exitEvent.Set();
        }
Пример #2
0
 protected BaseNotifyService(SecretsStoreManager secretsStoreManager)
 {
     this.logger = LogManager.GetLogger(this.GetType().Name);
     this.secretsStoreManager = secretsStoreManager;
 }
Пример #3
0
 protected BaseService(SecretsStoreManager secretsStoreManager, string id)
 {
     this.logger = LogManager.GetLogger(id);
     this.secretsStoreManager = secretsStoreManager;
 }
Пример #4
0
 /**
  * NotifyServices should implement this constructor.
  * Ideally implement a sub-class called "NotifyServiceOptions" and it will be casted here
  */
 public BaseNotifyService(SecretsStoreManager secretsStoreManager, object NotifyServiceOptions) : this(secretsStoreManager) { }
Пример #5
0
 /**
  * Services should implement this constructor.
  * Ideally implement a sub-class called "ServiceOptions" and it will be casted here
  */
 public BaseService(SecretsStoreManager secretsStoreManager, string id, object ServiceOptions) : this(secretsStoreManager, id)
 {
 }