def services(): uploadForm = forms.ServicesUploadForm(prefix="upload-services") addServiceForm = forms.AddServiceForm(prefix="add-service") addServiceForm.serviceProtocol.choices = [("tcp", "TCP"), ("udp", "UDP")] if uploadForm.uploadFile.data and uploadForm.validate_on_submit(): newServicesContent = uploadForm.serviceFile.data.read().decode("utf-8").rstrip('\r\n') newServicesSha = hashlib.sha256(newServicesContent.encode()).hexdigest() if newServicesSha != current_app.current_services["sha256"]: ns = NatlasServices(sha256=newServicesSha, services=newServicesContent) db.session.add(ns) db.session.commit() current_app.current_services = NatlasServices.query.order_by(NatlasServices.id.desc()).first().as_dict() flash("New services file with hash %s has been uploaded." % current_app.current_services["sha256"], "success") else: flash("That file is an exact match for our current services file!", "warning") return redirect(url_for('admin.services')) if addServiceForm.serviceName.data and addServiceForm.validate_on_submit(): newServiceName = addServiceForm.serviceName.data newServicePort = str(addServiceForm.servicePort.data) + '/' + addServiceForm.serviceProtocol.data if '\t' + newServicePort in str(current_app.current_services['services']): flash("A service with port %s already exists!" % newServicePort, "danger") else: newServices = current_app.current_services["services"] + "\n" + newServiceName + "\t" + newServicePort newSha = hashlib.sha256(newServices.encode()).hexdigest() ns = NatlasServices(sha256=newSha, services=newServices) db.session.add(ns) db.session.commit() current_app.current_services = NatlasServices.query.order_by(NatlasServices.id.desc()).first().as_dict() flash("New service %s on port %s has been added." % (newServiceName, newServicePort), "success") return redirect(url_for('admin.services')) return render_template( 'admin/services.html', uploadForm=uploadForm, addServiceForm=addServiceForm, current_services=current_app.current_services, servlist=current_app.current_services['as_list'])
def services(): uploadForm = forms.ServicesUploadForm(prefix="upload-services") addServiceForm = forms.AddServiceForm(prefix="add-service") addServiceForm.serviceProtocol.choices = [("tcp", "TCP"), ("udp", "UDP")] if uploadForm.uploadFile.data and uploadForm.validate_on_submit(): newServicesContent = ( uploadForm.serviceFile.data.read().decode("utf-8").rstrip("\r\n")) new_services = NatlasServices(services=newServicesContent) if not new_services.hash_equals( current_app.current_services["sha256"]): db.session.add(new_services) db.session.commit() current_app.current_services = new_services.as_dict() flash( f'New services file with hash {current_app.current_services["sha256"]} has been uploaded.', "success", ) else: flash("That file is an exact match for our current services file!", "warning") return redirect(url_for("admin.services")) if addServiceForm.serviceName.data and addServiceForm.validate_on_submit(): newServiceName = addServiceForm.serviceName.data newServicePort = (str(addServiceForm.servicePort.data) + "/" + addServiceForm.serviceProtocol.data) if "\t" + newServicePort in str( current_app.current_services["services"]): flash(f"A service with port {newServicePort} already exists!", "danger") else: newServices = (current_app.current_services["services"] + "\n" + newServiceName + "\t" + newServicePort) ns = NatlasServices(services=newServices) db.session.add(ns) db.session.commit() current_app.current_services = (NatlasServices.query.order_by( NatlasServices.id.desc()).first().as_dict()) flash( f"New service {newServiceName} on port {newServicePort} has been added.", "success", ) return redirect(url_for("admin.services")) return render_template( "admin/services.html", uploadForm=uploadForm, addServiceForm=addServiceForm, current_services=current_app.current_services, servlist=current_app.current_services["as_list"], )
def load_natlas_services(app): if not db.engine.has_table("natlas_services"): return from app.models import NatlasServices current_services = NatlasServices.query.order_by(NatlasServices.id.desc()).first() if not current_services: # Let's populate server defaults with open(os.path.join(app.config["BASEDIR"], "defaults/natlas-services")) as f: defaultServices = f.read().rstrip("\r\n") current_services = NatlasServices(services=defaultServices) db.session.add(current_services) db.session.commit() print("NatlasServices populated with defaults") app.current_services = current_services.as_dict()
def load_natlas_services(app, db): if not db.engine.has_table("natlas_services"): return from app.models import NatlasServices app.current_services = NatlasServices.get_latest_services()
def create_app(config_class=Config, load_config=False): app = Flask(__name__) app.config.from_object(Config) app.jinja_env.add_extension('jinja2.ext.do') db.init_app(app) migrate.init_app(app, db) login.init_app(app) mail.init_app(app) csrf.init_app(app) if load_config: print("Loading Config from database") with app.app_context(): from app.models import ConfigItem try: # This is gross but we need it because otherwise flask db operations won't work to create the ConfigItem table in the first place. # Look to see if any new config items were added that aren't currently in db for item in get_defaults(): if not ConfigItem.query.filter_by(name=item[0]).first(): newConfItem = ConfigItem(name=item[0], type=item[1], value=item[2]) db.session.add(newConfItem) db.session.commit() conf = ConfigItem.query.all() if not conf: # We'll hit this if the table exists but there's no data populate_defaults(verbose=False) conf = ConfigItem.query.all( ) # populate_defaults should populate data that we can query now if not conf: # if it didn't, then we don't have config items that we need in order to run, so exit. raise (SystemExit()) for item in conf: if item.type == "int": app.config[item.name] = int(item.value) elif item.type == "bool": if item.value == "True": app.config[item.name] = True else: app.config[item.name] = False elif item.type == "string": app.config[item.name] = item.value else: print("Unsupported config type %s:%s:%s" % (item.name, item.type, item.value)) except Exception as e: print( "ConfigItem table doesn't exist yet. Ignore if flask db upgrade." ) from app.models import NatlasServices try: current_services = NatlasServices.query.order_by( NatlasServices.id.desc()).first() if current_services: app.current_services = current_services.as_dict() else: # Let's populate server defaults defaultServices = open( os.path.join( app.config["BASEDIR"], "defaults/natlas-services")).read().rstrip('\r\n') defaultSha = hashlib.sha256( defaultServices.encode()).hexdigest() current_services = NatlasServices( sha256=defaultSha, services=defaultServices ) # default values until we load something db.session.add(current_services) db.session.commit() print( "NatlasServices populated with defaults from defaults/natlas-services" ) app.current_services = current_services.as_dict() except Exception as e: print( "NatlasServices table doesn't exist yet. Ignore if flask db upgrade." ) # Load the current agent config, otherwise create it. from app.models import AgentConfig try: agentConfig = AgentConfig.query.get( 1) # the agent config is updated in place so only 1 record if agentConfig: app.agentConfig = agentConfig.as_dict() else: newAgentConfig = AgentConfig( ) # populate an agent config with database defaults db.session.add(newAgentConfig) db.session.commit() print("AgentConfig populated with defaults") app.agentConfig = newAgentConfig.as_dict() except Exception as e: print( "AgentConfig table doesn't exist yet. Ignore if flask db upgrade." ) # Load the current agent config, otherwise create it. from app.models import AgentScript try: agentScripts = AgentScript.query.all() if not agentScripts: defaultAgentScript = AgentScript(name="default") db.session.add(defaultAgentScript) db.session.commit() print("AgentScript populated with default") agentScripts = AgentScript.query.all() app.agentScripts = agentScripts app.agentScriptStr = AgentScript.getScriptsString( scriptList=agentScripts) except Exception as e: print( "AgentScript table doesn't exist yet. Ignore if flask db upgrade." ) # Grungy thing so we can use flask db and flask shell before the config items are initially populated if "ELASTICSEARCH_URL" in app.config: app.elastic = Elastic(app.config['ELASTICSEARCH_URL']) app.ScopeManager = ScopeManager() from app.errors import bp as errors_bp app.register_blueprint(errors_bp) from app.admin import bp as admin_bp app.register_blueprint(admin_bp, url_prefix='/admin') from app.api import bp as api_bp app.register_blueprint(api_bp, url_prefix='/api') csrf.exempt(api_bp) from app.auth import bp as auth_bp app.register_blueprint(auth_bp, url_prefix='/auth') from app.user import bp as user_bp app.register_blueprint(user_bp, url_prefix='/user') from app.main import bp as main_bp app.register_blueprint(main_bp) from app.filters import bp as filters_bp app.register_blueprint(filters_bp) return app
def export_services(): current_services = NatlasServices.get_latest_services() return Response(str(current_services["services"]), mimetype="text/plain")