PCRE2 standard applied
This commit is contained in:
10
Dockerfile
10
Dockerfile
@@ -1,7 +1,13 @@
|
|||||||
#Building main conteiner
|
#Building main conteiner
|
||||||
FROM python:slim-buster
|
FROM python:slim-buster
|
||||||
|
|
||||||
RUN apt-get update && apt-get -y install build-essential libboost-system-dev libboost-thread-dev
|
RUN apt-get update && apt-get -y install build-essential libboost-system-dev libboost-thread-dev libpcre2-dev git
|
||||||
|
|
||||||
|
WORKDIR /tmp/
|
||||||
|
RUN git clone --branch release https://github.com/jpcre2/jpcre2
|
||||||
|
WORKDIR /tmp/jpcre2
|
||||||
|
RUN ./configure; make; make install
|
||||||
|
WORKDIR /
|
||||||
|
|
||||||
RUN mkdir /execute
|
RUN mkdir /execute
|
||||||
WORKDIR /execute
|
WORKDIR /execute
|
||||||
@@ -12,7 +18,7 @@ RUN pip install --no-cache-dir -r /execute/requirements.txt
|
|||||||
ARG GCC_PARAMS
|
ARG GCC_PARAMS
|
||||||
RUN mkdir proxy
|
RUN mkdir proxy
|
||||||
ADD ./backend/proxy/proxy.cpp /execute/proxy/proxy.cpp
|
ADD ./backend/proxy/proxy.cpp /execute/proxy/proxy.cpp
|
||||||
RUN c++ -O3 -march=native $GCC_PARAMS -o proxy/proxy proxy/proxy.cpp -pthread -lboost_system -lboost_thread
|
RUN c++ -O3 -march=native $GCC_PARAMS -o proxy/proxy proxy/proxy.cpp -pthread -lboost_system -lboost_thread -lpcre2-8
|
||||||
|
|
||||||
COPY ./backend/ /execute/
|
COPY ./backend/ /execute/
|
||||||
COPY ./frontend/build/ ./frontend/
|
COPY ./frontend/build/ ./frontend/
|
||||||
|
|||||||
@@ -269,6 +269,7 @@ class RegexAddForm(BaseModel):
|
|||||||
service_id: str
|
service_id: str
|
||||||
regex: str
|
regex: str
|
||||||
mode: str
|
mode: str
|
||||||
|
active: Union[bool,None]
|
||||||
is_blacklist: bool
|
is_blacklist: bool
|
||||||
is_case_sensitive: bool
|
is_case_sensitive: bool
|
||||||
|
|
||||||
@@ -279,8 +280,8 @@ async def post_regexes_add(form: RegexAddForm, auth: bool = Depends(is_loggined)
|
|||||||
except Exception:
|
except Exception:
|
||||||
return {"status":"Invalid regex"}
|
return {"status":"Invalid regex"}
|
||||||
try:
|
try:
|
||||||
db.query("INSERT INTO regexes (service_id, regex, is_blacklist, mode, is_case_sensitive ) VALUES (?, ?, ?, ?, ?);",
|
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)
|
form.service_id, form.regex, form.is_blacklist, form.mode, form.is_case_sensitive, True if form.active is None else form.active )
|
||||||
except sqlite3.IntegrityError:
|
except sqlite3.IntegrityError:
|
||||||
return {'status': 'An identical regex already exists'}
|
return {'status': 'An identical regex already exists'}
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,6 @@
|
|||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <regex>
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
#include <boost/thread.hpp>
|
#include <boost/thread.hpp>
|
||||||
@@ -16,7 +15,9 @@
|
|||||||
#include <boost/bind/bind.hpp>
|
#include <boost/bind/bind.hpp>
|
||||||
#include <boost/asio.hpp>
|
#include <boost/asio.hpp>
|
||||||
#include <boost/thread/mutex.hpp>
|
#include <boost/thread/mutex.hpp>
|
||||||
|
#include <jpcre2.hpp>
|
||||||
|
|
||||||
|
typedef jpcre2::select<char> jp;
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
bool unhexlify(string const &hex, string &newString) {
|
bool unhexlify(string const &hex, string &newString) {
|
||||||
@@ -35,7 +36,8 @@ bool unhexlify(string const &hex, string &newString) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef vector<pair<string,regex>> regex_rule_vector;
|
typedef pair<string,jp::Regex> regex_rule_pair;
|
||||||
|
typedef vector<regex_rule_pair> regex_rule_vector;
|
||||||
struct regex_rules{
|
struct regex_rules{
|
||||||
regex_rule_vector regex_s_c_w, regex_c_s_w, regex_s_c_b, regex_c_s_b;
|
regex_rule_vector regex_s_c_w, regex_c_s_w, regex_s_c_b, regex_c_s_b;
|
||||||
|
|
||||||
@@ -62,24 +64,14 @@ struct regex_rules{
|
|||||||
if (arg[1] != 'C' && arg[1] != 'c' && arg[1] != 'S' && arg[1] != 's') return;
|
if (arg[1] != 'C' && arg[1] != 'c' && arg[1] != 'S' && arg[1] != 's') return;
|
||||||
string hex(arg+2), expr;
|
string hex(arg+2), expr;
|
||||||
if (!unhexlify(hex, expr)) return;
|
if (!unhexlify(hex, expr)) return;
|
||||||
|
|
||||||
try{
|
|
||||||
|
|
||||||
//Push regex
|
//Push regex
|
||||||
if (arg[0] == '1'){
|
jp::Regex regex(expr,arg[0] == '1'?"gS":"giS");
|
||||||
regex regex(expr);
|
if (regex){
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
cerr << "Added case sensitive regex " << expr << endl;
|
cerr << "Added regex " << expr << " " << arg << endl;
|
||||||
#endif
|
#endif
|
||||||
getByCode(arg[1])->push_back(make_pair(string(arg), regex));
|
getByCode(arg[1])->push_back(make_pair(string(arg), regex));
|
||||||
} else {
|
} else {
|
||||||
regex regex(expr,regex_constants::icase);
|
|
||||||
#ifdef DEBUG
|
|
||||||
cerr << "Added case insensitive regex " << expr << endl;
|
|
||||||
#endif
|
|
||||||
getByCode(arg[1])->push_back(make_pair(string(arg), regex));
|
|
||||||
}
|
|
||||||
} catch(...){
|
|
||||||
cerr << "Regex " << arg << " was not compiled successfully" << endl;
|
cerr << "Regex " << arg << " was not compiled successfully" << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -92,17 +84,19 @@ mutex update_mutex;
|
|||||||
mutex stdout_mutex;
|
mutex stdout_mutex;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool filter_data(unsigned char* data, const size_t& bytes_transferred, vector<pair<string,regex>> const &blacklist, vector<pair<string,regex>> const &whitelist){
|
bool filter_data(unsigned char* data, const size_t& bytes_transferred, regex_rule_vector const &blacklist, regex_rule_vector const &whitelist){
|
||||||
#ifdef DEBUG_PACKET
|
#ifdef DEBUG_PACKET
|
||||||
cerr << "---------------- Packet ----------------" << endl;
|
cerr << "---------------- Packet ----------------" << endl;
|
||||||
for(int i=0;i<bytes_transferred;i++){
|
for(int i=0;i<bytes_transferred;i++) cerr << data[i];
|
||||||
cerr << data[i];
|
cerr << endl;
|
||||||
}
|
for(int i=0;i<bytes_transferred;i++) fprintf(stderr, "%x", data[i]);
|
||||||
cerr << "\n" << "---------------- End Packet ----------------" << endl;
|
cerr << endl;
|
||||||
|
cerr << "---------------- End Packet ----------------" << endl;
|
||||||
#endif
|
#endif
|
||||||
for (pair<string,regex> ele:blacklist){
|
string str_data((char *) data, bytes_transferred);
|
||||||
|
for (regex_rule_pair ele:blacklist){
|
||||||
try{
|
try{
|
||||||
if(regex_search(reinterpret_cast<const char*>(data), reinterpret_cast<const char*>(data)+bytes_transferred, ele.second)){
|
if(ele.second.match(str_data)){
|
||||||
#ifdef MULTI_THREAD
|
#ifdef MULTI_THREAD
|
||||||
std::unique_lock<std::mutex> lck(stdout_mutex);
|
std::unique_lock<std::mutex> lck(stdout_mutex);
|
||||||
#endif
|
#endif
|
||||||
@@ -113,9 +107,9 @@ bool filter_data(unsigned char* data, const size_t& bytes_transferred, vector<pa
|
|||||||
cerr << "Error while matching regex: " << ele.first << endl;
|
cerr << "Error while matching regex: " << ele.first << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (pair<string,regex> ele:whitelist){
|
for (regex_rule_pair ele:whitelist){
|
||||||
try{
|
try{
|
||||||
if(!regex_search(reinterpret_cast<const char*>(data),reinterpret_cast<const char*>(data)+bytes_transferred, ele.second)){
|
if(!ele.second.match(str_data)){
|
||||||
#ifdef MULTI_THREAD
|
#ifdef MULTI_THREAD
|
||||||
std::unique_lock<std::mutex> lck(stdout_mutex);
|
std::unique_lock<std::mutex> lck(stdout_mutex);
|
||||||
#endif
|
#endif
|
||||||
@@ -394,8 +388,9 @@ void update_config (boost::asio::streambuf &input_buffer){
|
|||||||
std::unique_lock<std::mutex> lck(update_mutex);
|
std::unique_lock<std::mutex> lck(update_mutex);
|
||||||
regex_rules *regex_new_config = new regex_rules();
|
regex_rules *regex_new_config = new regex_rules();
|
||||||
string data;
|
string data;
|
||||||
while(!config_stream.eof()){
|
while(true){
|
||||||
config_stream >> data;
|
config_stream >> data;
|
||||||
|
if (config_stream.eof()) break;
|
||||||
regex_new_config->add(data.c_str());
|
regex_new_config->add(data.c_str());
|
||||||
}
|
}
|
||||||
regex_config.reset(regex_new_config);
|
regex_config.reset(regex_new_config);
|
||||||
|
|||||||
@@ -1,46 +0,0 @@
|
|||||||
|
|
||||||
#Frontend build
|
|
||||||
FROM node:lts-alpine AS frontend
|
|
||||||
RUN apk add --update npm
|
|
||||||
RUN mkdir /app
|
|
||||||
WORKDIR /app
|
|
||||||
ENV PATH /app/node_modules/.bin:$PATH
|
|
||||||
ADD ./frontend/package.json .
|
|
||||||
ADD ./frontend/package-lock.json .
|
|
||||||
RUN npm ci --silent
|
|
||||||
COPY ./frontend/ .
|
|
||||||
RUN npm run build
|
|
||||||
|
|
||||||
#Building main conteiner
|
|
||||||
FROM python:slim-buster
|
|
||||||
|
|
||||||
RUN apt-get update && apt-get -y install curl supervisor gettext-base build-essential libboost-dev nginx libboost-regex-dev libboost-system-dev
|
|
||||||
RUN curl -sL https://deb.nodesource.com/setup_16.x | bash
|
|
||||||
RUN apt-get install nodejs
|
|
||||||
|
|
||||||
RUN npm install serve -g --silent
|
|
||||||
|
|
||||||
RUN mkdir /execute
|
|
||||||
WORKDIR /execute
|
|
||||||
|
|
||||||
ADD ./backend/requirements.txt /execute/requirements.txt
|
|
||||||
RUN pip install --no-cache-dir -r /execute/requirements.txt
|
|
||||||
|
|
||||||
COPY ./backend/ /execute/
|
|
||||||
RUN c++ -O3 -o proxy/proxy proxy/proxy.cpp -pthread -lboost_system
|
|
||||||
COPY ./config/supervisord.conf /etc/supervisor/supervisord.conf
|
|
||||||
COPY ./config/nginx.conf /tmp/nginx.conf
|
|
||||||
COPY ./config/start_nginx.sh /tmp/start_nginx.sh
|
|
||||||
|
|
||||||
#Copy react app in the main container
|
|
||||||
COPY --from=frontend /app/build/ ./frontend/
|
|
||||||
|
|
||||||
RUN usermod -a -G root nobody
|
|
||||||
RUN chown -R nobody:root /execute && \
|
|
||||||
chmod -R 660 /execute && chmod -R u+X /execute
|
|
||||||
|
|
||||||
RUN chmod ug+x /execute/proxy/proxy
|
|
||||||
|
|
||||||
ENTRYPOINT ["/usr/bin/supervisord","-c","/etc/supervisor/supervisord.conf"]
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,13 +1,13 @@
|
|||||||
{
|
{
|
||||||
"files": {
|
"files": {
|
||||||
"main.css": "/static/css/main.c375ae17.css",
|
"main.css": "/static/css/main.c375ae17.css",
|
||||||
"main.js": "/static/js/main.bf062beb.js",
|
"main.js": "/static/js/main.b694f5e6.js",
|
||||||
"index.html": "/index.html",
|
"index.html": "/index.html",
|
||||||
"main.c375ae17.css.map": "/static/css/main.c375ae17.css.map",
|
"main.c375ae17.css.map": "/static/css/main.c375ae17.css.map",
|
||||||
"main.bf062beb.js.map": "/static/js/main.bf062beb.js.map"
|
"main.b694f5e6.js.map": "/static/js/main.b694f5e6.js.map"
|
||||||
},
|
},
|
||||||
"entrypoints": [
|
"entrypoints": [
|
||||||
"static/css/main.c375ae17.css",
|
"static/css/main.c375ae17.css",
|
||||||
"static/js/main.bf062beb.js"
|
"static/js/main.b694f5e6.js"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -1 +1 @@
|
|||||||
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png"><link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png"><link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png"><link rel="manifest" href="/site.webmanifest"><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#FFFFFFFF"/><meta name="description" content="Firegex by Pwnzer0tt1"/><title>Firegex</title><script defer="defer" src="/static/js/main.bf062beb.js"></script><link href="/static/css/main.c375ae17.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
|
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png"><link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png"><link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png"><link rel="manifest" href="/site.webmanifest"><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#FFFFFFFF"/><meta name="description" content="Firegex by Pwnzer0tt1"/><title>Firegex</title><script defer="defer" src="/static/js/main.b694f5e6.js"></script><link href="/static/css/main.c375ae17.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,8 +1,8 @@
|
|||||||
import { Button, Group, Space, TextInput, Notification, Switch, NativeSelect, Tooltip, Modal } from '@mantine/core';
|
import { Button, Group, Space, TextInput, Notification, Switch, NativeSelect, Modal } from '@mantine/core';
|
||||||
import { useForm } from '@mantine/hooks';
|
import { useForm } from '@mantine/hooks';
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { RegexAddForm } from '../js/models';
|
import { RegexAddForm } from '../js/models';
|
||||||
import { addregex, b64encode, fireUpdateRequest, getBinaryRegex, getHumanReadableRegex, okNotify } from '../js/utils';
|
import { addregex, b64decode, b64encode, fireUpdateRequest, okNotify } from '../js/utils';
|
||||||
import { ImCross } from "react-icons/im"
|
import { ImCross } from "react-icons/im"
|
||||||
import FilterTypeSelector from './FilterTypeSelector';
|
import FilterTypeSelector from './FilterTypeSelector';
|
||||||
|
|
||||||
@@ -12,7 +12,7 @@ type RegexAddInfo = {
|
|||||||
type:string,
|
type:string,
|
||||||
mode:string,
|
mode:string,
|
||||||
is_case_insensitive:boolean,
|
is_case_insensitive:boolean,
|
||||||
percentage_encoding:boolean
|
deactive:boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
function AddNewRegex({ opened, onClose, service }:{ opened:boolean, onClose:()=>void, service:string }) {
|
function AddNewRegex({ opened, onClose, service }:{ opened:boolean, onClose:()=>void, service:string }) {
|
||||||
@@ -23,7 +23,7 @@ function AddNewRegex({ opened, onClose, service }:{ opened:boolean, onClose:()=>
|
|||||||
type:"blacklist",
|
type:"blacklist",
|
||||||
mode:"C -> S",
|
mode:"C -> S",
|
||||||
is_case_insensitive:false,
|
is_case_insensitive:false,
|
||||||
percentage_encoding:false
|
deactive:false
|
||||||
},
|
},
|
||||||
validationRules:{
|
validationRules:{
|
||||||
regex: (value) => value !== "",
|
regex: (value) => value !== "",
|
||||||
@@ -45,17 +45,13 @@ function AddNewRegex({ opened, onClose, service }:{ opened:boolean, onClose:()=>
|
|||||||
setSubmitLoading(true)
|
setSubmitLoading(true)
|
||||||
const filter_mode = ({'C -> S':'C', 'S -> C':'S', 'C <-> S':'B'}[values.mode])
|
const filter_mode = ({'C -> S':'C', 'S -> C':'S', 'C <-> S':'B'}[values.mode])
|
||||||
|
|
||||||
let final_regex:string|number[] = values.regex
|
|
||||||
if (values.percentage_encoding){
|
|
||||||
final_regex = getBinaryRegex(final_regex)
|
|
||||||
}
|
|
||||||
|
|
||||||
const request:RegexAddForm = {
|
const request:RegexAddForm = {
|
||||||
is_blacklist:values.type !== "whitelist",
|
is_blacklist:values.type !== "whitelist",
|
||||||
is_case_sensitive: !values.is_case_insensitive,
|
is_case_sensitive: !values.is_case_insensitive,
|
||||||
service_id: service,
|
service_id: service,
|
||||||
mode: filter_mode?filter_mode:"B",
|
mode: filter_mode?filter_mode:"B",
|
||||||
regex: b64encode(final_regex)
|
regex: b64encode(values.regex),
|
||||||
|
active: !values.deactive
|
||||||
}
|
}
|
||||||
setSubmitLoading(false)
|
setSubmitLoading(false)
|
||||||
addregex(request).then( res => {
|
addregex(request).then( res => {
|
||||||
@@ -63,7 +59,7 @@ function AddNewRegex({ opened, onClose, service }:{ opened:boolean, onClose:()=>
|
|||||||
setSubmitLoading(false)
|
setSubmitLoading(false)
|
||||||
close();
|
close();
|
||||||
fireUpdateRequest();
|
fireUpdateRequest();
|
||||||
okNotify(`Regex ${getHumanReadableRegex(request.regex)} has been added`, `Successfully added ${request.is_case_sensitive?"case sensitive":"case insensitive"} ${request.is_blacklist?"blacklist":"whitelist"} regex to ${request.service_id} service`)
|
okNotify(`Regex ${b64decode(request.regex)} has been added`, `Successfully added ${request.is_case_sensitive?"case sensitive":"case insensitive"} ${request.is_blacklist?"blacklist":"whitelist"} regex to ${request.service_id} service`)
|
||||||
}else if (res.toLowerCase() === "invalid regex"){
|
}else if (res.toLowerCase() === "invalid regex"){
|
||||||
setSubmitLoading(false)
|
setSubmitLoading(false)
|
||||||
form.setFieldError("regex", "Invalid Regex")
|
form.setFieldError("regex", "Invalid Regex")
|
||||||
@@ -87,19 +83,16 @@ function AddNewRegex({ opened, onClose, service }:{ opened:boolean, onClose:()=>
|
|||||||
{...form.getInputProps('regex')}
|
{...form.getInputProps('regex')}
|
||||||
/>
|
/>
|
||||||
<Space h="md" />
|
<Space h="md" />
|
||||||
<Tooltip label="To represent binary data use URL encoding. Example: %01" transition="slide-right" openDelay={500} transitionDuration={500} transitionTimingFunction="ease"
|
|
||||||
color="gray" wrapLines width={220} withArrow position='right' gutter={20}>
|
|
||||||
<Switch
|
|
||||||
label="Use percentage encoding for binary values"
|
|
||||||
{...form.getInputProps('percentage_encoding', { type: 'checkbox' })}
|
|
||||||
/>
|
|
||||||
</Tooltip>
|
|
||||||
<Space h="md" />
|
|
||||||
<Switch
|
<Switch
|
||||||
label="Case insensitive"
|
label="Case insensitive"
|
||||||
{...form.getInputProps('is_case_insensitive', { type: 'checkbox' })}
|
{...form.getInputProps('is_case_insensitive', { type: 'checkbox' })}
|
||||||
/>
|
/>
|
||||||
<Space h="md" />
|
<Space h="md" />
|
||||||
|
<Switch
|
||||||
|
label="Deactivate"
|
||||||
|
{...form.getInputProps('deactive', { type: 'checkbox' })}
|
||||||
|
/>
|
||||||
|
<Space h="md" />
|
||||||
<NativeSelect
|
<NativeSelect
|
||||||
data={['C -> S', 'S -> C', 'C <-> S']}
|
data={['C -> S', 'S -> C', 'C <-> S']}
|
||||||
label="Choose the source of the packets to filter"
|
label="Choose the source of the packets to filter"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Grid, Text, Title, Badge, Space, ActionIcon, Tooltip } from '@mantine/core';
|
import { Grid, Text, Title, Badge, Space, ActionIcon, Tooltip } from '@mantine/core';
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { RegexFilter } from '../../js/models';
|
import { RegexFilter } from '../../js/models';
|
||||||
import { activateregex, deactivateregex, deleteregex, errorNotify, fireUpdateRequest, getHumanReadableRegex, okNotify } from '../../js/utils';
|
import { activateregex, b64decode, deactivateregex, deleteregex, errorNotify, fireUpdateRequest, okNotify } from '../../js/utils';
|
||||||
import style from "./RegexView.module.scss";
|
import style from "./RegexView.module.scss";
|
||||||
import { BsTrashFill } from "react-icons/bs"
|
import { BsTrashFill } from "react-icons/bs"
|
||||||
import YesNoModal from '../YesNoModal';
|
import YesNoModal from '../YesNoModal';
|
||||||
@@ -15,7 +15,7 @@ function RegexView({ regexInfo }:{ regexInfo:RegexFilter }) {
|
|||||||
regexInfo.mode === "S"? "S -> C":
|
regexInfo.mode === "S"? "S -> C":
|
||||||
regexInfo.mode === "B"? "S <-> C": "🤔"
|
regexInfo.mode === "B"? "S <-> C": "🤔"
|
||||||
|
|
||||||
let regex_expr = getHumanReadableRegex(regexInfo.regex);
|
let regex_expr = b64decode(regexInfo.regex);
|
||||||
|
|
||||||
const [deleteModal, setDeleteModal] = useState(false);
|
const [deleteModal, setDeleteModal] = useState(false);
|
||||||
const [deleteTooltipOpened, setDeleteTooltipOpened] = useState(false);
|
const [deleteTooltipOpened, setDeleteTooltipOpened] = useState(false);
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import React, { useEffect, useState } from 'react';
|
|||||||
import { changeports, fireUpdateRequest, okNotify } from '../../js/utils';
|
import { changeports, fireUpdateRequest, okNotify } from '../../js/utils';
|
||||||
import { ImCross } from "react-icons/im"
|
import { ImCross } from "react-icons/im"
|
||||||
import { Service } from '../../js/models';
|
import { Service } from '../../js/models';
|
||||||
import { BsArrowDownSquareFill } from 'react-icons/bs';
|
import { FaLongArrowAltDown } from 'react-icons/fa';
|
||||||
|
|
||||||
type InputForm = {
|
type InputForm = {
|
||||||
internalPort:number,
|
internalPort:number,
|
||||||
@@ -70,7 +70,7 @@ function ChangePortModal({ service, opened, onClose }:{ service:Service, opened:
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<Space h="xl" />
|
<Space h="xl" />
|
||||||
<Center><BsArrowDownSquareFill size={50}/></Center>
|
<Center><FaLongArrowAltDown size={50}/></Center>
|
||||||
|
|
||||||
<NumberInput
|
<NumberInput
|
||||||
placeholder="8080"
|
placeholder="8080"
|
||||||
|
|||||||
@@ -74,5 +74,6 @@ export type RegexAddForm = {
|
|||||||
regex:string,
|
regex:string,
|
||||||
is_case_sensitive:boolean,
|
is_case_sensitive:boolean,
|
||||||
is_blacklist:boolean,
|
is_blacklist:boolean,
|
||||||
mode:string // C->S S->C BOTH
|
mode:string, // C->S S->C BOTH,
|
||||||
|
active: boolean
|
||||||
}
|
}
|
||||||
@@ -152,50 +152,7 @@ export async function serviceregexlist(service_id:string){
|
|||||||
return await getapi(`service/${service_id}/regexes`) as RegexFilter[];
|
return await getapi(`service/${service_id}/regexes`) as RegexFilter[];
|
||||||
}
|
}
|
||||||
|
|
||||||
const unescapedChars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!\"#$&'()*+,-./:;<=>?@[\\]^_`{|}~ ";
|
|
||||||
|
|
||||||
export function getHumanReadableRegex(regexB64:string){
|
|
||||||
const regex = Buffer.from(regexB64, "base64")
|
|
||||||
let res = ""
|
|
||||||
for (let i=0; i < regex.length; i++){
|
|
||||||
const byte = String.fromCharCode(regex[i]);
|
|
||||||
if (unescapedChars.includes(byte)){
|
|
||||||
res+=byte
|
|
||||||
}else{
|
|
||||||
let hex_data = regex[i].toString(16)
|
|
||||||
if (hex_data.length === 1) hex_data = "0"+hex_data
|
|
||||||
res+="%"+hex_data
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
const hexChars = "0123456789abcdefABCDEF"
|
|
||||||
|
|
||||||
export function getBinaryRegex(regexPercentageEncoded:string):number[]{
|
|
||||||
const regex = Buffer.from(regexPercentageEncoded)
|
|
||||||
let res = []
|
|
||||||
for (let i=0; i < regex.length; i++){
|
|
||||||
const byte = String.fromCharCode(regex[i]);
|
|
||||||
if ("%" === byte){
|
|
||||||
if(i+2 < regex.length){
|
|
||||||
const byte_1 = String.fromCharCode(regex[i+1]);
|
|
||||||
const byte_2 = String.fromCharCode(regex[i+2]);
|
|
||||||
if(hexChars.includes(byte_1) && hexChars.includes(byte_2)){
|
|
||||||
res.push(parseInt(byte_1+byte_2,16))
|
|
||||||
i += 2
|
|
||||||
}else{
|
|
||||||
res.push(regex[i])
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
res.push(regex[i])
|
|
||||||
}
|
|
||||||
}else{
|
|
||||||
res.push(regex[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
export function errorNotify(title:string, description:string ){
|
export function errorNotify(title:string, description:string ){
|
||||||
showNotification({
|
showNotification({
|
||||||
@@ -220,3 +177,7 @@ export function okNotify(title:string, description:string ){
|
|||||||
export function b64encode(data:number[]|string){
|
export function b64encode(data:number[]|string){
|
||||||
return Buffer.from(data).toString('base64')
|
return Buffer.from(data).toString('base64')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function b64decode(regexB64:string){
|
||||||
|
return Buffer.from(regexB64, "base64").toString()
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user