diff --git a/.gitignore b/.gitignore index 78b2af6..625dec0 100644 --- a/.gitignore +++ b/.gitignore @@ -19,6 +19,7 @@ /frontend/dist/ /frontend/dist/** /backend/modules/cppqueue +/backend/binsrc/cppqueue /backend/modules/proxy docker-compose.yml firegex-compose.yml diff --git a/backend/app.py b/backend/app.py index 1ac8138..2f6f7e1 100644 --- a/backend/app.py +++ b/backend/app.py @@ -34,7 +34,14 @@ async def lifespan(app): yield await shutdown_main() -app = FastAPI(debug=DEBUG, redoc_url=None, lifespan=lifespan) +app = FastAPI( + debug=DEBUG, + redoc_url=None, + lifespan=lifespan, + docs_url="/api/docs", + title="Firegex API", + version=API_VERSION, +) utils.socketio = SocketManager(app, "/sock", socketio_path="") if DEBUG: @@ -183,9 +190,9 @@ if __name__ == '__main__': os.chdir(os.path.dirname(os.path.realpath(__file__))) uvicorn.run( "app:app", - host="::" if DEBUG else None, + host=None, #"::" if DEBUG else None, port=FIREGEX_PORT, - reload=DEBUG, + reload=False,#DEBUG, access_log=True, workers=1, # Multiple workers will cause a crash due to the creation # of multiple processes with separated memory diff --git a/backend/binsrc/classes/regex_rules.cpp b/backend/binsrc/classes/regex_rules.cpp index 2c2dc50..c335bf1 100644 --- a/backend/binsrc/classes/regex_rules.cpp +++ b/backend/binsrc/classes/regex_rules.cpp @@ -7,7 +7,6 @@ using namespace std; - #ifndef REGEX_FILTER_HPP #define REGEX_FILTER_HPP @@ -20,8 +19,8 @@ struct decoded_regex { }; struct regex_ruleset { - hs_database_t* hs_db; - char** regexes; + hs_database_t* hs_db = nullptr; + char** regexes = nullptr; }; decoded_regex decode_regex(string regex){ @@ -46,7 +45,7 @@ decoded_regex decode_regex(string regex){ } decoded_regex ruleset{ regex: expr, - direction: regex[1] == 'C'? CTOS : STOC, + direction: regex[1] == 'C' ? CTOS : STOC, is_case_sensitive: regex[0] == '1' }; return ruleset; @@ -66,9 +65,11 @@ class RegexRules{ void free_dbs(){ if (output_ruleset.hs_db != nullptr){ hs_free_database(output_ruleset.hs_db); + output_ruleset.hs_db = nullptr; } if (input_ruleset.hs_db != nullptr){ hs_free_database(input_ruleset.hs_db); + input_ruleset.hs_db = nullptr; } } diff --git a/backend/binsrc/cppqueue b/backend/binsrc/cppqueue deleted file mode 100755 index 84696ec..0000000 Binary files a/backend/binsrc/cppqueue and /dev/null differ diff --git a/backend/modules/nfregex/firegex.py b/backend/modules/nfregex/firegex.py index b04409a..2d4a9be 100644 --- a/backend/modules/nfregex/firegex.py +++ b/backend/modules/nfregex/firegex.py @@ -12,7 +12,6 @@ class RegexFilter: def __init__( self, regex, is_case_sensitive=True, - is_blacklist=True, input_mode=False, output_mode=False, blocked_packets=0, @@ -21,7 +20,6 @@ class RegexFilter: ): self.regex = regex self.is_case_sensitive = is_case_sensitive - self.is_blacklist = is_blacklist if input_mode == output_mode: input_mode = output_mode = True # (False, False) == (True, True) self.input_mode = input_mode @@ -35,7 +33,7 @@ class RegexFilter: def from_regex(cls, regex:Regex, update_func = None): return cls( id=regex.id, regex=regex.regex, is_case_sensitive=regex.is_case_sensitive, - is_blacklist=regex.is_blacklist, blocked_packets=regex.blocked_packets, + blocked_packets=regex.blocked_packets, input_mode = regex.mode in ["C","B"], output_mode=regex.mode in ["S","B"], update_func = update_func ) @@ -47,9 +45,9 @@ class RegexFilter: re.compile(self.regex) # raise re.error if it's invalid! case_sensitive = "1" if self.is_case_sensitive else "0" if self.input_mode: - yield case_sensitive + "C" + self.regex.hex() if self.is_blacklist else case_sensitive + "c"+ self.regex.hex() + yield case_sensitive + "C" + self.regex.hex() if self.output_mode: - yield case_sensitive + "S" + self.regex.hex() if self.is_blacklist else case_sensitive + "s"+ self.regex.hex() + yield case_sensitive + "S" + self.regex.hex() async def update(self): if self.update_func: diff --git a/backend/modules/nfregex/models.py b/backend/modules/nfregex/models.py index b81365a..0c36890 100644 --- a/backend/modules/nfregex/models.py +++ b/backend/modules/nfregex/models.py @@ -15,11 +15,10 @@ class Service: class Regex: - def __init__(self, regex_id: int, regex: bytes, mode: str, service_id: str, is_blacklist: bool, blocked_packets: int, is_case_sensitive: bool, active: bool, **other): + def __init__(self, regex_id: int, regex: bytes, mode: str, service_id: str, blocked_packets: int, is_case_sensitive: bool, active: bool, **other): self.regex = regex self.mode = mode self.service_id = service_id - self.is_blacklist = is_blacklist self.blocked_packets = blocked_packets self.id = regex_id self.is_case_sensitive = is_case_sensitive diff --git a/backend/routers/nfregex.py b/backend/routers/nfregex.py index d0cdf79..b895588 100644 --- a/backend/routers/nfregex.py +++ b/backend/routers/nfregex.py @@ -28,7 +28,6 @@ class RegexModel(BaseModel): mode:str id:int service_id:str - is_blacklist: bool n_packets:int is_case_sensitive:bool active:bool @@ -38,7 +37,6 @@ class RegexAddForm(BaseModel): regex: str mode: str active: bool|None = None - is_blacklist: bool is_case_sensitive: bool class ServiceAddForm(BaseModel): @@ -66,7 +64,6 @@ db = SQLite('db/nft-regex.db', { 'regex': 'TEXT NOT NULL', 'mode': 'VARCHAR(1) NOT NULL CHECK (mode IN ("C", "S", "B"))', # C = to the client, S = to the server, B = both 'service_id': 'VARCHAR(100) NOT NULL', - 'is_blacklist': 'BOOLEAN NOT NULL CHECK (is_blacklist IN (0, 1))', 'blocked_packets': 'INTEGER UNSIGNED NOT NULL DEFAULT 0', 'regex_id': 'INTEGER PRIMARY KEY', 'is_case_sensitive' : 'BOOLEAN NOT NULL CHECK (is_case_sensitive IN (0, 1))', @@ -75,7 +72,7 @@ db = SQLite('db/nft-regex.db', { }, 'QUERY':[ "CREATE UNIQUE INDEX IF NOT EXISTS unique_services ON services (port, ip_int, proto);", - "CREATE UNIQUE INDEX IF NOT EXISTS unique_regex_service ON regexes (regex,service_id,is_blacklist,mode,is_case_sensitive);" + "CREATE UNIQUE INDEX IF NOT EXISTS unique_regex_service ON regexes (regex,service_id,mode,is_case_sensitive);" ] }) @@ -194,7 +191,7 @@ async def get_service_regexe_list(service_id: str): raise HTTPException(status_code=400, detail="This service does not exists!") return db.query(""" SELECT - regex, mode, regex_id `id`, service_id, is_blacklist, + regex, mode, regex_id `id`, service_id, blocked_packets n_packets, is_case_sensitive, active FROM regexes WHERE service_id = ?; """, service_id) @@ -204,7 +201,7 @@ async def get_regex_by_id(regex_id: int): """Get regex info using his id""" res = db.query(""" SELECT - regex, mode, regex_id `id`, service_id, is_blacklist, + regex, mode, regex_id `id`, service_id, blocked_packets n_packets, is_case_sensitive, active FROM regexes WHERE `id` = ?; """, regex_id) @@ -251,8 +248,8 @@ async def add_new_regex(form: RegexAddForm): except Exception: raise HTTPException(status_code=400, detail="Invalid regex") try: - db.query("INSERT INTO regexes (service_id, regex, is_blacklist, mode, is_case_sensitive, active ) VALUES (?, ?, ?, ?, ?, ?);", - form.service_id, form.regex, form.is_blacklist, form.mode, form.is_case_sensitive, True if form.active is None else form.active ) + db.query("INSERT INTO regexes (service_id, regex, mode, is_case_sensitive, active ) VALUES (?, ?, ?, ?, ?);", + form.service_id, form.regex, form.mode, form.is_case_sensitive, True if form.active is None else form.active ) except sqlite3.IntegrityError: raise HTTPException(status_code=400, detail="An identical regex already exists") diff --git a/backend/utils/__init__.py b/backend/utils/__init__.py index bb8d985..52e753d 100644 --- a/backend/utils/__init__.py +++ b/backend/utils/__init__.py @@ -19,7 +19,7 @@ ON_DOCKER = "DOCKER" in sys.argv DEBUG = "DEBUG" in sys.argv FIREGEX_PORT = int(os.getenv("PORT","4444")) JWT_ALGORITHM: str = "HS256" -API_VERSION = "2.2.0" +API_VERSION = "3.0.0" PortType = Annotated[int, Path(gt=0, lt=65536)] diff --git a/frontend/src/js/models.ts b/frontend/src/js/models.ts index 3a78c15..3f9804a 100644 --- a/frontend/src/js/models.ts +++ b/frontend/src/js/models.ts @@ -36,7 +36,6 @@ export type RegexFilter = { id:number, service_id:string, regex:string - is_blacklist:boolean, is_case_sensitive:boolean, mode:string //C S B => C->S S->C BOTH n_packets:number, diff --git a/frontend/src/js/utils.tsx b/frontend/src/js/utils.tsx index 159d6d6..ba84bcf 100644 --- a/frontend/src/js/utils.tsx +++ b/frontend/src/js/utils.tsx @@ -16,7 +16,7 @@ export const regex_ipv4 = "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\. export const regex_ipv4_no_cidr = "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$" export const regex_port = "^([1-9]|[1-9][0-9]{1,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])?$" export const regex_range_port = "^(([1-9]|[1-9][0-9]{1,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])(-([1-9]|[1-9][0-9]{1,3}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])?)?)?$" -export const DEV_IP_BACKEND = "198.19.249.69:4444" +export const DEV_IP_BACKEND = "127.0.0.1:4444" export const queryClient = new QueryClient({ defaultOptions: { queries: { staleTime: Infinity diff --git a/tests/benchmark.py b/tests/benchmark.py index 0ff5a63..2f9d953 100644 --- a/tests/benchmark.py +++ b/tests/benchmark.py @@ -98,7 +98,7 @@ print(f"{results[0]} MB/s") #Add all the regexs for i in range(1,args.num_of_regexes+1): regex = base64.b64encode(bytes(secrets.token_hex(16).encode())).decode() - if not firegex.nf_add_regex(service_id,regex,"B",active=True,is_blacklist=True,is_case_sensitive=False): + if not firegex.nf_add_regex(service_id,regex,"B",active=True,is_case_sensitive=False): puts("Benchmark Failed: Coulnd't add the regex ✗", color=colors.red) exit_test(1) puts(f"Performance with {i} regex(s): ", color=colors.red, end='') diff --git a/tests/nf_test.py b/tests/nf_test.py index 7ff0405..efac378 100644 --- a/tests/nf_test.py +++ b/tests/nf_test.py @@ -67,7 +67,7 @@ else: #Add new regex secret = bytes(secrets.token_hex(16).encode()) regex = base64.b64encode(secret).decode() -if firegex.nf_add_regex(service_id,regex,"B",active=True,is_blacklist=True,is_case_sensitive=True): +if firegex.nf_add_regex(service_id,regex,"B",active=True,is_case_sensitive=True): puts(f"Sucessfully added regex {str(secret)} ✔", color=colors.green) else: puts("Test Failed: Coulnd't add the regex {str(secret)} ✗", color=colors.red) @@ -166,7 +166,7 @@ for r in firegex.nf_get_service_regexes(service_id): checkRegex(regex,should_work=False) #Add case insensitive regex -if(firegex.nf_add_regex(service_id,regex,"B",active=True,is_blacklist=True,is_case_sensitive=False)): +if(firegex.nf_add_regex(service_id,regex,"B",active=True, is_case_sensitive=False)): puts(f"Sucessfully added case insensitive regex {str(secret)} ✔", color=colors.green) else: puts(f"Test Failed: Coulnd't add the case insensitive regex {str(secret)} ✗", color=colors.red) diff --git a/tests/utils/firegexapi.py b/tests/utils/firegexapi.py index ad2930b..ce4a92c 100644 --- a/tests/utils/firegexapi.py +++ b/tests/utils/firegexapi.py @@ -121,9 +121,9 @@ class FiregexAPI: req = self.s.get(f"{self.address}api/nfregex/regex/{regex_id}/disable") return verify(req) - def nf_add_regex(self, service_id: str, regex: str, mode: str, active: bool, is_blacklist: bool, is_case_sensitive: bool): + def nf_add_regex(self, service_id: str, regex: str, mode: str, active: bool, is_case_sensitive: bool): req = self.s.post(f"{self.address}api/nfregex/regexes/add", - json={"service_id": service_id, "regex": regex, "mode": mode, "active": active, "is_blacklist": is_blacklist, "is_case_sensitive": is_case_sensitive}) + json={"service_id": service_id, "regex": regex, "mode": mode, "active": active, "is_case_sensitive": is_case_sensitive}) return verify(req) def nf_add_service(self, name: str, port: int, proto: str, ip_int: str):