public IActionResult Manage(string name, string task) { if (Defaults.ValidServices.Any(s => name == s) && Defaults.ValidActions.Any(s => task == s)) { if (task.Equals("config")) { var type = Utility.GetServiceType(name); var config = _serviceConfigManager.Generate(type); _response.Result = config; return(Ok(_response)); } var message = _serviceManager.Process(name, task, out var error); if (error != null) { _response.Errors.Add(message, error); return(StatusCode(500, _response)); } _response.Message = message; return(Ok(_response)); } _response.Errors.Add(Errors.INVALID_SERVICE_OR_ACTION_ATTEMPT, ""); return(BadRequest(_response)); }
private static void ValidateDaemonStartup() { var marker = Utility.GetCurrentStartupMarker(); if (File.Exists(marker)) { throw new Exception($"Spectero Daemon currently seems to be starting up, and is not ready to service requests yet (marker: {marker}). Please try again later."); } }
public async Task <IActionResult> GetLocalIPs() { var ips = Utility.GetLocalIPs(AppConfig.IgnoreRFC1918); var addresses = ips.Select(ip => ip.ToString()).ToList(); if (addresses.Count == 0) { var ip = await _outgoingIpResolver.Resolve(); addresses.Add(ip.ToString()); } _response.Result = addresses; return(Ok(_response)); }
public async Task <IActionResult> HandleHttpProxyConfigUpdate([FromBody] HTTPConfig config) { if (!ModelState.IsValid || config.listeners.IsNullOrEmpty()) { // ModelState takes care of checking if the field map succeeded. This means mode | allowed.d | banned.d do not need manual checking _response.Errors.Add(Errors.MISSING_BODY, ""); return(BadRequest(_response)); } var currentConfig = (HTTPConfig)_serviceConfigManager.Generate(Utility.GetServiceType("HTTPProxy")).First(); var localAvailableIPs = Utility.GetLocalIPs(); var availableIPs = localAvailableIPs as IPAddress[] ?? localAvailableIPs.ToArray(); var consumedListenerMap = new Dictionary <int, List <IPAddress> >(); // Check if all listeners are valid foreach (var listener in config.listeners) { if (IPAddress.TryParse(listener.Item1, out var holder)) { var ipChecked = AppConfig.BindToUnbound || availableIPs.Contains(holder) || holder.Equals(IPAddress.Any); var portChecked = listener.Item2 > 1023 && listener.Item2 < 65535; consumedListenerMap.TryGetValue(listener.Item2, out var existingListOfAddresses); // DAEM-58 compliance: prevent unicast.any listeners if port is not entirely free. if (existingListOfAddresses != null) { foreach (var ipAddress in existingListOfAddresses) { if (ipAddress.Equals(IPAddress.Any)) { _response.Errors.Add(Errors.PORT_CONFLICT_FOUND, "0.0.0.0"); break; } // Duplicate listener found if (ipAddress.Equals(holder)) { _response.Errors.Add(Errors.DUPLICATE_IP_AS_LISTENER_REQUEST, listener.Item1); break; } } } if (!ipChecked) { _response.Errors.Add(Errors.INVALID_IP_AS_LISTENER_REQUEST, listener.Item1); break; } if (!portChecked) { _response.Errors.Add(Errors.INVALID_PORT_AS_LISTENER_REQUEST, listener.Item2); break; } if (existingListOfAddresses == null) { existingListOfAddresses = new List <IPAddress>(); // If it was null, that means it wasn't in the dict either. consumedListenerMap.Add(listener.Item2, existingListOfAddresses); } // List is guaranteed not null at this stage, add the IP to it. existingListOfAddresses.Add(holder); } else { _response.Errors.Add(Errors.MALFORMED_IP_AS_LISTENER_REQUEST, listener.Item1); break; } } if (HasErrors()) { Logger.LogError("CCHH: Invalid listener request found."); return(BadRequest(_response)); } if (config.listeners != currentConfig.listeners || config.proxyMode != currentConfig.proxyMode || config.allowedDomains != currentConfig.allowedDomains || config.bannedDomains != currentConfig.bannedDomains) { // A difference was found between the running config and the candidate config // If listener config changed AND service is running, the service needs restarting as it can't be adjusted without the sockets being re-initialized. var service = _serviceManager.GetService(typeof(HTTPProxy)); var restartNeeded = !config.listeners.SequenceEqual(currentConfig.listeners) && service.GetState() == ServiceState.Running; //Update the running config, listener config will not apply until a full system restart is made. service.SetConfig(new List <IServiceConfig> { config }, restartNeeded); if (restartNeeded) { _response.Message = Messages.SERVICE_RESTART_NEEDED; } } // If we get to this point, it means the candidate config was valid and should be committed into the DB. var dbConfig = await Db.SingleAsync <Configuration>(x => x.Key == ConfigKeys.HttpConfig); dbConfig.Value = JsonConvert.SerializeObject(config); await Db.UpdateAsync(dbConfig); _response.Result = config; return(Ok(_response)); }
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IOptionsMonitor <AppConfig> configMonitor, IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IMigration migration, IAutoStarter autoStarter, IServiceProvider serviceProvider, IApplicationLifetime applicationLifetime, ILifetimeHandler lifetimeHandler) { // Create the filesystem marker that says Startup is now underway. // This is removed in LifetimeHandler once init finishes. // And yeah, the logging context is NOT yet available -_- if (!Utility.ManageStartupMarker()) { Console.WriteLine($"ERROR: The startup marker ({Utility.GetCurrentStartupMarker()}) could NOT be created."); } var appConfig = configMonitor.CurrentValue; if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); app.UseCors("DefaultCORSPolicy"); app.UseInterceptOptions(); // Return 200/OK with correct CORS to allow preflight requests, giant hack. } app.UseSpecteroErrorHandler(); app.UseAddRequestIdHeader(); // This HAS TO BE before the AddMVC call. Route registration fails otherwise. var option = new BackgroundJobServerOptions { WorkerCount = 1 }; // Limited by SQLite, can't deal with concurrency welp. app.UseHangfireServer(option); app.UseHangfireDashboard($"/jobs"); app.UseMvc(); // Initialize Nlog loggerFactory.AddNLog(); loggerFactory.ConfigureNLog(appConfig.LoggingConfig); app.AddNLogWeb(); migration.Up(); autoStarter.Startup(); foreach (var implementer in serviceProvider.GetServices <IJob>()) { if (!implementer.IsEnabled()) { continue; } // Magic, autowiring is magic. RecurringJob.AddOrUpdate(implementer.GetType().ToString(), () => implementer.Perform(), implementer.GetSchedule); } applicationLifetime.ApplicationStarted.Register(lifetimeHandler.OnStarted); applicationLifetime.ApplicationStopping.Register(lifetimeHandler.OnStopping); applicationLifetime.ApplicationStopped.Register(lifetimeHandler.OnStopped); }