2022-09-09 10:44:11 +08:00
|
|
|
#include "tsg_proxy_logger.h"
|
2021-12-17 16:39:49 +08:00
|
|
|
#include "edit_element.h"
|
2018-09-27 19:06:57 +08:00
|
|
|
#include "pattern_replace.h"
|
2022-07-29 15:39:25 +08:00
|
|
|
#include "http_lua.h"
|
2018-09-14 11:42:22 +08:00
|
|
|
|
2018-10-14 17:11:45 +08:00
|
|
|
#include <tfe_proxy.h>
|
2018-09-12 16:04:04 +08:00
|
|
|
#include <tfe_stream.h>
|
|
|
|
|
#include <tfe_utils.h>
|
|
|
|
|
#include <tfe_http.h>
|
2018-09-18 12:01:56 +08:00
|
|
|
#include <tfe_plugin.h>
|
2020-06-11 17:57:18 +08:00
|
|
|
#include <tfe_resource.h>
|
2020-08-10 18:13:44 +08:00
|
|
|
#include <tfe_scan.h>
|
2021-06-10 15:28:45 +08:00
|
|
|
#include <tfe_types.h>
|
2023-04-25 10:13:38 +08:00
|
|
|
#include <tfe_fieldstat.h>
|
2018-09-12 16:04:04 +08:00
|
|
|
|
|
|
|
|
#include <MESA/MESA_handle_logger.h>
|
|
|
|
|
#include <MESA/MESA_prof_load.h>
|
|
|
|
|
#include <MESA/stream.h>
|
2023-03-30 19:39:18 +08:00
|
|
|
#include <MESA/maat.h>
|
2018-09-09 15:21:26 +08:00
|
|
|
|
2018-09-13 19:28:13 +08:00
|
|
|
#include <event2/event.h>
|
|
|
|
|
#include <event2/buffer.h>
|
|
|
|
|
|
2019-05-21 19:15:37 +08:00
|
|
|
#include <cjson/cJSON.h>
|
|
|
|
|
|
2018-09-15 20:55:31 +08:00
|
|
|
#include <ctemplate/template.h>
|
2018-09-12 16:04:04 +08:00
|
|
|
#include <assert.h>
|
|
|
|
|
#include <time.h>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <string.h>
|
2018-09-13 19:28:13 +08:00
|
|
|
#include <sys/types.h>
|
2018-09-27 19:06:57 +08:00
|
|
|
|
2024-01-19 14:21:30 +08:00
|
|
|
#define MAX_EDIT_ZONE_NUM 64
|
|
|
|
|
#define MAX_SCAN_DATA_SIZE ((1 << 16) - 1)
|
2018-09-25 11:15:00 +08:00
|
|
|
|
2024-09-29 20:01:49 +08:00
|
|
|
enum proxy_action
|
|
|
|
|
{
|
|
|
|
|
PX_ACTION_NONE = 0,
|
2024-10-25 17:00:57 +08:00
|
|
|
PX_ACTION_ALLOW = 1,
|
|
|
|
|
PX_ACTION_DENY = 2,
|
2024-10-21 18:32:15 +08:00
|
|
|
PX_ACTION_MONITOR = 3,
|
|
|
|
|
PX_ACTION_REDIRECT = 4,
|
2024-10-25 17:00:57 +08:00
|
|
|
PX_ACTION_EXECUTE = 5,
|
|
|
|
|
PX_ACTION_MANIPULATE = 6,
|
2022-09-09 10:44:11 +08:00
|
|
|
__PX_ACTION_MAX
|
2018-09-12 16:04:04 +08:00
|
|
|
};
|
2018-09-25 11:15:00 +08:00
|
|
|
|
2024-10-25 17:00:57 +08:00
|
|
|
enum manipulate_action
|
|
|
|
|
{
|
|
|
|
|
MA_ACTION_REPLACE_TEXT,
|
|
|
|
|
MA_ACTION_REPLACE_FILE,
|
|
|
|
|
MA_ACTION_EDIT_ELEMENT,
|
|
|
|
|
MA_ACTION_INJECT_JAVESCRIPT,
|
|
|
|
|
MA_ACTION_INJECT_CSS,
|
|
|
|
|
__MA_ACTION_MAX
|
|
|
|
|
};
|
|
|
|
|
|
2018-09-12 16:04:04 +08:00
|
|
|
enum scan_table
|
|
|
|
|
{
|
|
|
|
|
PXY_CTRL_HTTP_URL,
|
2019-08-20 18:35:40 +08:00
|
|
|
PXY_CTRL_HTTP_FQDN,
|
2018-09-12 16:04:04 +08:00
|
|
|
PXY_CTRL_HTTP_REQ_HDR,
|
|
|
|
|
PXY_CTRL_HTTP_REQ_BODY,
|
|
|
|
|
PXY_CTRL_HTTP_RES_HDR,
|
|
|
|
|
PXY_CTRL_HTTP_RES_BODY,
|
2020-04-01 11:13:53 +08:00
|
|
|
PXY_CTRL_APP_ID,
|
2018-09-12 16:04:04 +08:00
|
|
|
__SCAN_TABLE_MAX
|
|
|
|
|
};
|
2018-09-25 11:15:00 +08:00
|
|
|
|
2022-09-09 10:44:11 +08:00
|
|
|
enum proxy_http_stat
|
2018-10-17 20:21:21 +08:00
|
|
|
{
|
|
|
|
|
STAT_SESSION,
|
|
|
|
|
STAT_LOG_NUM,
|
|
|
|
|
STAT_ACTION_MONIT,
|
|
|
|
|
STAT_ACTION_REJECT,
|
|
|
|
|
STAT_ACTION_REDIRECT,
|
|
|
|
|
STAT_ACTION_REPLACE,
|
2019-05-21 19:15:37 +08:00
|
|
|
STAT_ACTION_HIJACK,
|
2020-06-11 13:47:56 +08:00
|
|
|
STAT_ACTION_HIJACK_SZ,
|
2019-05-21 19:15:37 +08:00
|
|
|
STAT_ACTION_INSERT,
|
2020-06-11 13:47:56 +08:00
|
|
|
STAT_ACTION_INSERT_SZ,
|
2021-12-10 13:32:40 +08:00
|
|
|
STAT_ACTION_EDIT_ELEMENT,
|
2022-07-29 15:39:25 +08:00
|
|
|
STAT_ACTION_RUN_SCRIPT,
|
2018-10-17 20:21:21 +08:00
|
|
|
STAT_ACTION_WHITELSIT,
|
2018-11-28 20:32:10 +08:00
|
|
|
STAT_SUSPENDING,
|
2022-09-09 10:44:11 +08:00
|
|
|
__PX_STAT_MAX
|
2018-10-17 20:21:21 +08:00
|
|
|
};
|
2019-05-21 19:15:37 +08:00
|
|
|
|
2019-05-28 14:59:39 +08:00
|
|
|
enum manipulate_profile_table
|
2019-05-21 19:15:37 +08:00
|
|
|
{
|
2019-05-28 14:59:39 +08:00
|
|
|
POLICY_PROFLIE_TABLE_REJECT,
|
2024-10-25 17:00:57 +08:00
|
|
|
POLICY_PROFILE_TABLE_JS,
|
|
|
|
|
POLICY_PROFILE_TABLE_CSS,
|
2019-06-01 18:04:51 +08:00
|
|
|
POLICY_PROFILE_TABLE_HIJACK,
|
2022-07-29 15:39:25 +08:00
|
|
|
POLICY_PROFILE_TABLE_LUA,
|
2019-05-28 14:59:39 +08:00
|
|
|
POLICY_PROFILE_TABLE_MAX
|
2019-05-21 19:15:37 +08:00
|
|
|
};
|
|
|
|
|
|
2019-05-28 14:59:39 +08:00
|
|
|
struct manipulate_profile
|
2019-05-21 19:15:37 +08:00
|
|
|
{
|
2024-09-29 20:01:49 +08:00
|
|
|
char *profile_uuid;
|
2019-05-28 17:38:19 +08:00
|
|
|
int ref_cnt;
|
2019-05-21 19:15:37 +08:00
|
|
|
size_t msg_len;
|
|
|
|
|
char *profile_name;
|
|
|
|
|
char *profile_msg;
|
|
|
|
|
char *profile_type;
|
2019-08-21 19:47:30 +08:00
|
|
|
char *profile_position;
|
2022-09-09 10:44:11 +08:00
|
|
|
struct elua_script **escript_ctx;
|
2022-07-29 15:39:25 +08:00
|
|
|
int timeout;
|
2019-06-11 11:25:24 +08:00
|
|
|
ctemplate::Template * tpl;
|
2019-06-08 10:57:49 +08:00
|
|
|
pthread_mutex_t lock;
|
2019-05-21 19:15:37 +08:00
|
|
|
};
|
|
|
|
|
|
2023-03-30 19:39:18 +08:00
|
|
|
struct maat_rule_t
|
|
|
|
|
{
|
2024-09-29 20:01:49 +08:00
|
|
|
int vsys_id;
|
|
|
|
|
uuid_t config_uuid;
|
|
|
|
|
char *config_uuid_string;
|
2023-03-30 19:39:18 +08:00
|
|
|
int service_id;
|
|
|
|
|
unsigned char do_log;
|
|
|
|
|
unsigned char do_blacklist;
|
|
|
|
|
unsigned char action;
|
2024-09-29 20:01:49 +08:00
|
|
|
char *action_parameter;
|
2023-03-30 19:39:18 +08:00
|
|
|
};
|
|
|
|
|
|
2019-05-28 14:59:39 +08:00
|
|
|
struct policy_action_param
|
2019-05-21 19:15:37 +08:00
|
|
|
{
|
|
|
|
|
int ref_cnt;
|
2024-10-25 17:00:57 +08:00
|
|
|
enum manipulate_action action;
|
2019-05-21 19:15:37 +08:00
|
|
|
char *message;
|
|
|
|
|
char *position;
|
2020-04-29 14:00:13 +08:00
|
|
|
float enforcement_ratio;
|
2024-09-29 20:01:49 +08:00
|
|
|
char *profile_uuid_str;
|
|
|
|
|
|
2019-05-21 19:15:37 +08:00
|
|
|
int status_code;
|
|
|
|
|
|
|
|
|
|
size_t n_rule;
|
2021-12-06 18:14:10 +08:00
|
|
|
struct replace_rule *repl_rule;
|
|
|
|
|
size_t e_rule;
|
2021-12-17 16:39:49 +08:00
|
|
|
struct edit_element_rule *elem_rule;
|
2023-03-30 19:39:18 +08:00
|
|
|
struct maat_rule_t hit_rule;
|
2019-05-21 19:15:37 +08:00
|
|
|
pthread_mutex_t lock;
|
|
|
|
|
};
|
|
|
|
|
|
2022-09-09 10:44:11 +08:00
|
|
|
struct tsg_proxy_rt
|
2018-09-12 16:04:04 +08:00
|
|
|
{
|
2023-03-30 19:39:18 +08:00
|
|
|
struct maat *feather;
|
2022-09-09 10:44:11 +08:00
|
|
|
struct proxy_logger * send_logger;
|
2018-09-23 20:02:07 +08:00
|
|
|
void * local_logger;
|
2018-09-12 16:04:04 +08:00
|
|
|
int thread_num;
|
|
|
|
|
int scan_table_id[__SCAN_TABLE_MAX];
|
2019-05-28 14:59:39 +08:00
|
|
|
int plolicy_table_id[POLICY_PROFILE_TABLE_MAX];
|
2018-09-23 20:02:07 +08:00
|
|
|
ctemplate::Template * tpl_403, * tpl_404, * tpl_451;
|
2018-10-17 20:21:21 +08:00
|
|
|
|
2024-11-13 14:09:03 +08:00
|
|
|
struct fieldstat_easy *fs_handle;
|
2022-09-09 10:44:11 +08:00
|
|
|
long long stat_val[__PX_STAT_MAX];
|
|
|
|
|
int fs_id[__PX_STAT_MAX];
|
2018-10-17 20:21:21 +08:00
|
|
|
struct event_base* gc_evbase;
|
|
|
|
|
struct event* gcev;
|
2019-05-21 19:15:37 +08:00
|
|
|
|
2022-07-29 15:39:25 +08:00
|
|
|
struct tsg_lua_script lua_script;
|
2020-06-04 20:22:31 +08:00
|
|
|
int enable_rate;
|
|
|
|
|
|
2023-11-22 19:30:27 +08:00
|
|
|
int ctrl_plugin_idx;
|
2018-11-09 15:52:14 +08:00
|
|
|
int ca_store_reseting;
|
2020-07-28 18:54:00 +08:00
|
|
|
int enable_plugin;
|
2018-09-12 16:04:04 +08:00
|
|
|
};
|
2022-09-09 10:44:11 +08:00
|
|
|
struct tsg_proxy_rt * g_proxy_rt;
|
2018-09-25 11:15:00 +08:00
|
|
|
|
2024-11-13 14:09:03 +08:00
|
|
|
static void proxy_http_gc_cb(evutil_socket_t fd, short what, void *arg)
|
2018-10-17 20:21:21 +08:00
|
|
|
{
|
2024-11-13 14:09:03 +08:00
|
|
|
for (int i = 0; i < __PX_STAT_MAX; i++)
|
2018-10-17 20:21:21 +08:00
|
|
|
{
|
2024-11-13 14:09:03 +08:00
|
|
|
long long delta = ATOMIC_EXCHANGE(&(g_proxy_rt->stat_val[i]), 0);
|
|
|
|
|
fieldstat_easy_counter_incrby(g_proxy_rt->fs_handle, 0, g_proxy_rt->fs_id[i], NULL, 0, delta);
|
2018-10-17 20:21:21 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-09 10:44:11 +08:00
|
|
|
static void proxy_http_stat_init(struct tsg_proxy_rt * pangu_runtime)
|
2018-10-17 20:21:21 +08:00
|
|
|
{
|
|
|
|
|
int i=0;
|
|
|
|
|
struct timeval gc_delay = {0, 500*1000}; //Microseconds, we set 500 miliseconds here.
|
2022-09-09 10:44:11 +08:00
|
|
|
const char* spec[__PX_STAT_MAX]={0};
|
2018-10-17 20:21:21 +08:00
|
|
|
spec[STAT_SESSION]="http_sess";
|
|
|
|
|
spec[STAT_LOG_NUM]="log_num";
|
2020-09-03 11:50:52 +08:00
|
|
|
spec[STAT_ACTION_MONIT]="intcp_mon_num";
|
|
|
|
|
spec[STAT_ACTION_REJECT]="intcp_deny_num";
|
|
|
|
|
spec[STAT_ACTION_REDIRECT]="intcp_rdirt_num";
|
|
|
|
|
spec[STAT_ACTION_REPLACE]="intcp_repl_num";
|
|
|
|
|
spec[STAT_ACTION_HIJACK]="intcp_hijk_num";
|
|
|
|
|
spec[STAT_ACTION_HIJACK_SZ]="hijk_bytes";
|
|
|
|
|
spec[STAT_ACTION_INSERT]="intcp_ins_num";
|
|
|
|
|
spec[STAT_ACTION_INSERT_SZ]="ins_bytes";
|
2021-12-13 15:59:59 +08:00
|
|
|
spec[STAT_ACTION_EDIT_ELEMENT]="intcp_edit_elem_num";
|
2022-07-29 15:39:25 +08:00
|
|
|
spec[STAT_ACTION_RUN_SCRIPT]="intcp_rus_num";
|
2020-09-03 11:50:52 +08:00
|
|
|
spec[STAT_ACTION_WHITELSIT]="intcp_allow_num";
|
2018-11-28 20:32:10 +08:00
|
|
|
spec[STAT_SUSPENDING]="suspending";
|
2018-10-17 20:21:21 +08:00
|
|
|
|
2022-09-09 10:44:11 +08:00
|
|
|
for(i=0;i<__PX_STAT_MAX;i++)
|
2018-10-17 20:21:21 +08:00
|
|
|
{
|
2024-11-13 14:09:03 +08:00
|
|
|
if (spec[i] != NULL)
|
2018-10-17 20:21:21 +08:00
|
|
|
{
|
2024-11-13 14:09:03 +08:00
|
|
|
pangu_runtime->fs_id[i] = fieldstat_easy_register_counter(pangu_runtime->fs_handle, spec[i]);
|
2018-10-17 20:21:21 +08:00
|
|
|
}
|
|
|
|
|
}
|
2022-09-09 10:44:11 +08:00
|
|
|
g_proxy_rt->gcev = event_new(pangu_runtime->gc_evbase, -1, EV_PERSIST, proxy_http_gc_cb, NULL);
|
|
|
|
|
evtimer_add(g_proxy_rt->gcev, &gc_delay);
|
2018-10-17 20:21:21 +08:00
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2021-02-23 09:33:27 +08:00
|
|
|
void increase_redirect_policy_hit_num(void)
|
|
|
|
|
{
|
2022-09-09 10:44:11 +08:00
|
|
|
ATOMIC_INC(&(g_proxy_rt->stat_val[STAT_ACTION_REDIRECT]));
|
2021-02-23 09:33:27 +08:00
|
|
|
}
|
|
|
|
|
|
2018-11-09 15:52:14 +08:00
|
|
|
void trusted_CA_update_start_cb(int update_type, void* u_para)
|
|
|
|
|
{
|
2023-03-30 19:39:18 +08:00
|
|
|
if(update_type==MAAT_UPDATE_TYPE_FULL)
|
2018-11-09 15:52:14 +08:00
|
|
|
{
|
2022-09-09 10:44:11 +08:00
|
|
|
if(g_proxy_rt->ca_store_reseting==0)
|
2018-11-09 15:52:14 +08:00
|
|
|
{
|
|
|
|
|
tfe_proxy_ssl_reset_trust_ca();
|
2022-09-09 10:44:11 +08:00
|
|
|
TFE_LOG_INFO(g_proxy_rt->local_logger, "Trusted CA Store Reset Start.");
|
2018-11-09 15:52:14 +08:00
|
|
|
}
|
2022-09-09 10:44:11 +08:00
|
|
|
g_proxy_rt->ca_store_reseting++;
|
2018-11-09 15:52:14 +08:00
|
|
|
}
|
|
|
|
|
}
|
2024-09-29 20:01:49 +08:00
|
|
|
|
|
|
|
|
void trusted_CA_update_cert_cb(const char *table_name, const char *table_line, enum maat_operation op, void *u_para)
|
2018-11-09 15:52:14 +08:00
|
|
|
{
|
2024-09-29 20:01:49 +08:00
|
|
|
int ret = 0;
|
|
|
|
|
|
|
|
|
|
cJSON* trust_ca_cert = cJSON_Parse(table_line);
|
|
|
|
|
if(trust_ca_cert == NULL)
|
2018-11-09 15:52:14 +08:00
|
|
|
{
|
2024-10-16 16:16:44 +08:00
|
|
|
TFE_LOG_ERROR(g_proxy_rt->local_logger, "TRUSTED_CERTIFICATE_AUTHORITY parse table_line failed. table_line:%s", table_line);
|
2018-11-09 15:52:14 +08:00
|
|
|
return;
|
|
|
|
|
}
|
2024-09-29 20:01:49 +08:00
|
|
|
|
|
|
|
|
char *uuid_sring=NULL;
|
|
|
|
|
char cert_name[128]={0}, cert_file[1024]={0};
|
|
|
|
|
|
|
|
|
|
cJSON *uuid = cJSON_GetObjectItem(trust_ca_cert, "uuid");
|
|
|
|
|
if(uuid && uuid->type==cJSON_String)
|
|
|
|
|
{
|
|
|
|
|
uuid_sring = uuid->valuestring;
|
|
|
|
|
}
|
|
|
|
|
cJSON *item = cJSON_GetObjectItem(trust_ca_cert, "cert_name");
|
|
|
|
|
if(item && item->type==cJSON_String)
|
|
|
|
|
{
|
|
|
|
|
memcpy(cert_name, item->valuestring, strlen(item->valuestring));
|
|
|
|
|
}
|
|
|
|
|
item = cJSON_GetObjectItem(trust_ca_cert, "cert_file");
|
|
|
|
|
if(item && item->type==cJSON_String)
|
|
|
|
|
{
|
|
|
|
|
memcpy(cert_file, item->valuestring, strlen(item->valuestring));
|
|
|
|
|
}
|
|
|
|
|
|
2024-10-17 18:18:17 +08:00
|
|
|
if(op==MAAT_OP_ADD)
|
2018-11-09 15:52:14 +08:00
|
|
|
{
|
|
|
|
|
ret=tfe_proxy_ssl_add_trust_ca(cert_file);
|
|
|
|
|
if(ret<0)
|
|
|
|
|
{
|
2024-09-29 20:01:49 +08:00
|
|
|
TFE_LOG_ERROR(g_proxy_rt->local_logger, "Trusted CA Store add cert failed %s:%s:%s", uuid_sring, cert_name, cert_file);
|
2018-11-09 15:52:14 +08:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2024-09-29 20:01:49 +08:00
|
|
|
TFE_LOG_INFO(g_proxy_rt->local_logger, "Trusted CA Store add cert success %s:%s:%s", uuid_sring, cert_name, cert_file);
|
2018-11-09 15:52:14 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ret=tfe_proxy_ssl_del_trust_ca(cert_file);
|
|
|
|
|
if(ret<0)
|
|
|
|
|
{
|
2024-09-29 20:01:49 +08:00
|
|
|
TFE_LOG_ERROR(g_proxy_rt->local_logger, "Trusted CA Store del cert failed %s:%s:%s", uuid_sring, cert_name, cert_file);
|
2018-11-09 15:52:14 +08:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2024-09-29 20:01:49 +08:00
|
|
|
TFE_LOG_INFO(g_proxy_rt->local_logger, "Trusted CA Store del cert success %s:%s:%s", uuid_sring, cert_name, cert_file);
|
2018-11-09 15:52:14 +08:00
|
|
|
}
|
|
|
|
|
}
|
2024-09-29 20:01:49 +08:00
|
|
|
|
|
|
|
|
cJSON_Delete(trust_ca_cert);
|
|
|
|
|
trust_ca_cert=NULL;
|
2018-11-09 15:52:14 +08:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
void trusted_CA_update_crl_cb(int table_id,const char* table_line,void* u_para)
|
|
|
|
|
{
|
|
|
|
|
int ret=0, crl_id=0, cert_id=0, is_valid=0;
|
|
|
|
|
char crl_file[1024]={0};
|
|
|
|
|
ret=sscanf(table_line, "%d\t%d\t%s\t%d", &crl_id, &cert_id, crl_file, &is_valid);
|
|
|
|
|
if(ret!=4)
|
|
|
|
|
{
|
2022-09-09 10:44:11 +08:00
|
|
|
TFE_LOG_ERROR(g_proxy_rt->local_logger, "Trusted CA Store parse crl config failed: %s", table_line);
|
2018-11-09 15:52:14 +08:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if(is_valid==1)
|
|
|
|
|
{
|
|
|
|
|
ret=tfe_proxy_ssl_add_crl(crl_file);
|
|
|
|
|
if(ret<0)
|
|
|
|
|
{
|
2022-09-09 10:44:11 +08:00
|
|
|
TFE_LOG_ERROR(g_proxy_rt->local_logger, "Trusted CA Store add crl failed %d:%d:%s", crl_id, cert_id, crl_file);
|
2018-11-09 15:52:14 +08:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2022-09-09 10:44:11 +08:00
|
|
|
TFE_LOG_INFO(g_proxy_rt->local_logger, "Trusted CA Store add crl success %d:%d:%s", crl_id, cert_id, crl_file);
|
2018-11-09 15:52:14 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ret=tfe_proxy_ssl_del_crl(crl_file);
|
|
|
|
|
if(ret<0)
|
|
|
|
|
{
|
2022-09-09 10:44:11 +08:00
|
|
|
TFE_LOG_ERROR(g_proxy_rt->local_logger, "Trusted CA Store del crl failed %d:%d:%s", crl_id, cert_id, crl_file);
|
2018-11-09 15:52:14 +08:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2022-09-09 10:44:11 +08:00
|
|
|
TFE_LOG_INFO(g_proxy_rt->local_logger, "Trusted CA Store del crl success %d:%d:%s", crl_id, cert_id, crl_file);
|
2018-11-09 15:52:14 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
void trusted_CA_update_finish_cb(void* u_para)
|
|
|
|
|
{
|
2022-09-09 10:44:11 +08:00
|
|
|
if(g_proxy_rt->ca_store_reseting>0)
|
2018-11-09 15:52:14 +08:00
|
|
|
{
|
2022-09-09 10:44:11 +08:00
|
|
|
g_proxy_rt->ca_store_reseting--;
|
|
|
|
|
if(g_proxy_rt->ca_store_reseting==0)
|
2018-11-09 15:52:14 +08:00
|
|
|
{
|
2020-09-28 14:33:50 +08:00
|
|
|
tfe_proxy_ssl_reset_trust_ca_finish();
|
2022-09-09 10:44:11 +08:00
|
|
|
TFE_LOG_INFO(g_proxy_rt->local_logger, "Trusted CA Store Reset Finish.");
|
2018-11-09 15:52:14 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-05-21 19:15:37 +08:00
|
|
|
|
2024-10-25 17:00:57 +08:00
|
|
|
static enum manipulate_action manipulate_action_str2idx(const char *action_str)
|
|
|
|
|
{
|
|
|
|
|
const char *clue_action_map[__MA_ACTION_MAX];
|
|
|
|
|
clue_action_map[MA_ACTION_REPLACE_TEXT]= "replace_text";
|
|
|
|
|
clue_action_map[MA_ACTION_REPLACE_FILE]= "replace_file";
|
|
|
|
|
clue_action_map[MA_ACTION_EDIT_ELEMENT]= "edit_element";
|
|
|
|
|
clue_action_map[MA_ACTION_INJECT_JAVESCRIPT]= "inject_javascript";
|
|
|
|
|
clue_action_map[MA_ACTION_INJECT_CSS]= "inject_css";
|
|
|
|
|
|
|
|
|
|
size_t i = 0;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < sizeof(clue_action_map) / sizeof(const char *); i++)
|
|
|
|
|
{
|
|
|
|
|
if (0 == strcasecmp(action_str, clue_action_map[i]))
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return (enum manipulate_action)i;
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-09 10:44:11 +08:00
|
|
|
void octal_utf8_escapes(char *input)
|
|
|
|
|
{
|
|
|
|
|
#define AFMTSIZE (67+2+1+2)
|
|
|
|
|
char afmt [AFMTSIZE];
|
|
|
|
|
int num,NConsumed,last,lbuf_sz=0;
|
|
|
|
|
|
|
|
|
|
const char *fmt ="\\%3lo";
|
|
|
|
|
snprintf(afmt,AFMTSIZE,"%s%%n",fmt);
|
|
|
|
|
|
|
|
|
|
char lbuf[1024]={0};
|
|
|
|
|
snprintf(lbuf, sizeof(lbuf), "%s", input);
|
|
|
|
|
lbuf_sz = strlen(lbuf);
|
|
|
|
|
|
|
|
|
|
last = lbuf_sz - 1;
|
|
|
|
|
if(lbuf[last] == '\n')
|
|
|
|
|
{
|
|
|
|
|
lbuf[last] = '\0';
|
|
|
|
|
last--;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char *iptr = input;
|
|
|
|
|
while (*iptr)
|
|
|
|
|
{
|
|
|
|
|
if((last = sscanf(iptr,afmt,&num, &NConsumed)) > 0)
|
|
|
|
|
{
|
|
|
|
|
putchar(num);
|
|
|
|
|
iptr+=NConsumed;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
iptr+=1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2023-04-13 14:34:34 +08:00
|
|
|
char* str_unescape(char* s)
|
|
|
|
|
{
|
|
|
|
|
int i=0,j=0;
|
|
|
|
|
int len=strlen(s);
|
|
|
|
|
for(i=0,j=0;i<len;i++)
|
|
|
|
|
{
|
|
|
|
|
if(s[i]=='\\')
|
|
|
|
|
{
|
|
|
|
|
switch(s[i+1])
|
|
|
|
|
{
|
|
|
|
|
case '&':
|
|
|
|
|
s[j]='&';
|
|
|
|
|
break;
|
|
|
|
|
case 'b':
|
|
|
|
|
s[j]=' ';
|
|
|
|
|
break;
|
|
|
|
|
case '\\':
|
|
|
|
|
s[j]='\\';
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
s[j]=s[i];
|
|
|
|
|
i--;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
i++;
|
|
|
|
|
j++;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
s[j]=s[i];
|
|
|
|
|
j++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
s[j]='\0';
|
|
|
|
|
return s;
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-29 20:01:49 +08:00
|
|
|
unsigned char action_type_str2idx(const char *action_str)
|
2019-05-21 19:15:37 +08:00
|
|
|
{
|
2024-10-10 11:56:39 +08:00
|
|
|
const char * action_name[__PX_ACTION_MAX] ={0};
|
2024-09-29 20:01:49 +08:00
|
|
|
action_name[PX_ACTION_NONE] = "none";
|
2024-10-21 18:32:15 +08:00
|
|
|
action_name[PX_ACTION_ALLOW] = "allow";
|
2024-10-25 17:00:57 +08:00
|
|
|
action_name[PX_ACTION_DENY] = "deny";
|
2024-10-21 18:32:15 +08:00
|
|
|
action_name[PX_ACTION_MONITOR] = "monitor";
|
|
|
|
|
action_name[PX_ACTION_REDIRECT] = "redirect";
|
2024-10-25 17:00:57 +08:00
|
|
|
action_name[PX_ACTION_EXECUTE] = "execute";
|
|
|
|
|
action_name[PX_ACTION_MANIPULATE] = "modify";
|
2019-11-19 10:02:51 +08:00
|
|
|
|
2024-09-29 20:01:49 +08:00
|
|
|
int action = 0;
|
|
|
|
|
for ( action = PX_ACTION_NONE; action < __PX_ACTION_MAX; action++)
|
2023-03-30 19:39:18 +08:00
|
|
|
{
|
2024-10-10 11:56:39 +08:00
|
|
|
if (action_name[action] != NULL && 0 == strcasecmp(action_str, action_name[action]))
|
2024-09-29 20:01:49 +08:00
|
|
|
break;
|
2023-03-30 19:39:18 +08:00
|
|
|
}
|
2024-09-29 20:01:49 +08:00
|
|
|
return action;
|
|
|
|
|
}
|
2023-03-30 19:39:18 +08:00
|
|
|
|
2024-09-29 20:01:49 +08:00
|
|
|
unsigned char log_option_type_str2idx(const char *log_option)
|
|
|
|
|
{
|
|
|
|
|
size_t i = 0;
|
|
|
|
|
const char *log_option_name[] = {"none", "metadata", "all"};
|
|
|
|
|
for (i = 0; i < sizeof(log_option_name) / sizeof(const char *); i++)
|
|
|
|
|
{
|
|
|
|
|
if (0 == strcasecmp(log_option, log_option_name[i]))
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return i;
|
|
|
|
|
}
|
2023-04-13 14:34:34 +08:00
|
|
|
|
2024-10-30 16:26:38 +08:00
|
|
|
void policy_set_param_by_action(struct policy_action_param* param, cJSON *action_parameter)
|
2024-09-29 20:01:49 +08:00
|
|
|
{
|
2024-10-30 16:26:38 +08:00
|
|
|
cJSON *item=NULL;
|
2024-10-25 17:00:57 +08:00
|
|
|
switch(param->hit_rule.action)
|
2019-05-21 19:15:37 +08:00
|
|
|
{
|
2024-10-21 18:32:15 +08:00
|
|
|
case PX_ACTION_REDIRECT:
|
2024-09-29 20:01:49 +08:00
|
|
|
item=cJSON_GetObjectItem(action_parameter,"vsys_id");
|
2022-10-26 14:30:45 +08:00
|
|
|
if(item && item->type==cJSON_Number)
|
|
|
|
|
{
|
2023-04-04 16:06:40 +08:00
|
|
|
param->hit_rule.vsys_id=item->valueint;
|
2022-10-26 14:30:45 +08:00
|
|
|
}
|
2024-09-29 20:01:49 +08:00
|
|
|
item=cJSON_GetObjectItem(action_parameter,"code");
|
2019-05-28 14:59:39 +08:00
|
|
|
if(item && item->type==cJSON_Number)
|
|
|
|
|
{
|
2019-05-21 19:15:37 +08:00
|
|
|
param->status_code = item->valueint;
|
|
|
|
|
}
|
2024-09-29 20:01:49 +08:00
|
|
|
item=cJSON_GetObjectItem(action_parameter,"to");
|
2019-05-28 14:59:39 +08:00
|
|
|
if(item && item->type==cJSON_String)
|
|
|
|
|
{
|
2019-05-21 19:15:37 +08:00
|
|
|
param->message = tfe_strdup(item->valuestring);
|
|
|
|
|
}
|
2024-09-29 20:01:49 +08:00
|
|
|
item=cJSON_GetObjectItem(action_parameter,"enforcement_ratio");
|
2020-04-29 14:00:13 +08:00
|
|
|
if(item && item->type==cJSON_Number)
|
|
|
|
|
{
|
2020-04-29 17:11:10 +08:00
|
|
|
param->enforcement_ratio = item->valuedouble;
|
2020-04-29 14:00:13 +08:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
param->enforcement_ratio = 1;
|
|
|
|
|
}
|
2019-05-21 19:15:37 +08:00
|
|
|
break;
|
2024-10-21 18:32:15 +08:00
|
|
|
case PX_ACTION_DENY:
|
2024-09-29 20:01:49 +08:00
|
|
|
item=cJSON_GetObjectItem(action_parameter,"vsys_id");
|
2022-10-26 14:30:45 +08:00
|
|
|
if(item && item->type==cJSON_Number)
|
|
|
|
|
{
|
2023-04-04 16:06:40 +08:00
|
|
|
param->hit_rule.vsys_id=item->valueint;
|
2022-10-26 14:30:45 +08:00
|
|
|
}
|
2024-09-29 20:01:49 +08:00
|
|
|
item=cJSON_GetObjectItem(action_parameter,"code");
|
2019-05-28 14:59:39 +08:00
|
|
|
if(item && item->type==cJSON_Number)
|
|
|
|
|
{
|
2019-05-21 19:15:37 +08:00
|
|
|
param->status_code = item->valueint;
|
|
|
|
|
}
|
2024-09-29 20:01:49 +08:00
|
|
|
item=cJSON_GetObjectItem(action_parameter,"message");
|
2019-05-28 14:59:39 +08:00
|
|
|
if(item && item->type==cJSON_String)
|
|
|
|
|
{
|
2019-05-21 19:15:37 +08:00
|
|
|
param->message = tfe_strdup(item->valuestring);
|
|
|
|
|
}
|
2024-09-29 20:01:49 +08:00
|
|
|
item=cJSON_GetObjectItem(action_parameter,"html_profile");
|
|
|
|
|
if(item && item->type==cJSON_String)
|
2019-05-28 14:59:39 +08:00
|
|
|
{
|
2024-09-29 20:01:49 +08:00
|
|
|
param->profile_uuid_str = tfe_strdup(item->valuestring);
|
2019-05-21 19:15:37 +08:00
|
|
|
}
|
|
|
|
|
break;
|
2024-10-25 17:00:57 +08:00
|
|
|
case PX_ACTION_EXECUTE:
|
|
|
|
|
item=cJSON_GetObjectItem(action_parameter,"vsys_id");
|
|
|
|
|
if(item && item->type==cJSON_Number)
|
|
|
|
|
{
|
|
|
|
|
param->hit_rule.vsys_id=item->valueint;
|
|
|
|
|
}
|
|
|
|
|
item=cJSON_GetObjectItem(action_parameter,"lua_script");
|
|
|
|
|
if(item && item->type==cJSON_String)
|
|
|
|
|
{
|
|
|
|
|
param->profile_uuid_str =tfe_strdup(item->valuestring);
|
|
|
|
|
}
|
|
|
|
|
item=cJSON_GetObjectItem(action_parameter,"enforcement_ratio");
|
|
|
|
|
if(item && item->type==cJSON_Number)
|
|
|
|
|
{
|
|
|
|
|
param->enforcement_ratio = item->valuedouble;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
param->enforcement_ratio = 1;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
2024-10-30 16:26:38 +08:00
|
|
|
return;
|
|
|
|
|
}
|
2024-10-25 17:00:57 +08:00
|
|
|
|
2024-10-30 16:26:38 +08:00
|
|
|
void policy_set_param_by_sub_action(struct policy_action_param* param, cJSON *action_parameter)
|
|
|
|
|
{
|
|
|
|
|
int rule_id=0;
|
|
|
|
|
cJSON *rules=NULL, *item=NULL, *sub_item=NULL;
|
2024-10-25 17:00:57 +08:00
|
|
|
switch(param->action)
|
|
|
|
|
{
|
|
|
|
|
case MA_ACTION_REPLACE_TEXT:
|
2024-09-29 20:01:49 +08:00
|
|
|
item=cJSON_GetObjectItem(action_parameter,"vsys_id");
|
2022-10-26 14:30:45 +08:00
|
|
|
if(item && item->type==cJSON_Number)
|
|
|
|
|
{
|
2023-04-04 16:06:40 +08:00
|
|
|
param->hit_rule.vsys_id=item->valueint;
|
2022-10-26 14:30:45 +08:00
|
|
|
}
|
2024-09-29 20:01:49 +08:00
|
|
|
item=cJSON_GetObjectItem(action_parameter,"enforcement_ratio");
|
2020-04-29 14:00:13 +08:00
|
|
|
if(item && item->type==cJSON_Number)
|
|
|
|
|
{
|
2020-04-29 17:11:10 +08:00
|
|
|
param->enforcement_ratio = item->valuedouble;
|
2020-04-29 14:00:13 +08:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
param->enforcement_ratio = 1;
|
|
|
|
|
}
|
2024-09-29 20:01:49 +08:00
|
|
|
rules = cJSON_GetObjectItem(action_parameter, "rules");
|
2019-05-28 14:59:39 +08:00
|
|
|
if(rules == NULL)
|
2019-05-21 19:15:37 +08:00
|
|
|
{
|
2019-05-28 14:59:39 +08:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
rule_id = 0;
|
2021-12-06 18:14:10 +08:00
|
|
|
param->repl_rule = ALLOC(struct replace_rule, MAX_EDIT_ZONE_NUM);
|
2019-05-28 14:59:39 +08:00
|
|
|
for (item = rules->child; item != NULL; item = item->next)
|
|
|
|
|
{
|
|
|
|
|
char * search = cJSON_GetObjectItem(item , "search_in")->valuestring;
|
|
|
|
|
if (search == NULL) break;
|
|
|
|
|
|
2021-12-06 18:14:10 +08:00
|
|
|
param->repl_rule[rule_id].zone = zone_name_to_id(search);
|
|
|
|
|
if (param->repl_rule[rule_id].zone == kZoneMax)
|
2019-05-21 19:15:37 +08:00
|
|
|
{
|
2019-05-28 14:59:39 +08:00
|
|
|
break;
|
2019-05-21 19:15:37 +08:00
|
|
|
}
|
2021-12-06 18:14:10 +08:00
|
|
|
param->repl_rule[rule_id].find = tfe_strdup(cJSON_GetObjectItem(item , "find")->valuestring);
|
2022-09-09 10:44:11 +08:00
|
|
|
octal_utf8_escapes(param->repl_rule[rule_id].find);
|
2021-12-06 18:14:10 +08:00
|
|
|
param->repl_rule[rule_id].replace_with = tfe_strdup(cJSON_GetObjectItem(item , "replace_with")->valuestring);
|
2022-09-09 10:44:11 +08:00
|
|
|
octal_utf8_escapes(param->repl_rule[rule_id].replace_with);
|
2019-05-28 14:59:39 +08:00
|
|
|
rule_id++;
|
2019-05-21 19:15:37 +08:00
|
|
|
}
|
2019-05-28 14:59:39 +08:00
|
|
|
param->n_rule = rule_id;
|
2019-05-21 19:15:37 +08:00
|
|
|
break;
|
2024-10-25 17:00:57 +08:00
|
|
|
case MA_ACTION_REPLACE_FILE:
|
2024-09-29 20:01:49 +08:00
|
|
|
item=cJSON_GetObjectItem(action_parameter,"vsys_id");
|
2022-10-26 14:30:45 +08:00
|
|
|
if(item && item->type==cJSON_Number)
|
|
|
|
|
{
|
2023-04-04 16:06:40 +08:00
|
|
|
param->hit_rule.vsys_id=item->valueint;
|
2022-10-26 14:30:45 +08:00
|
|
|
}
|
2024-10-25 17:00:57 +08:00
|
|
|
item=cJSON_GetObjectItem(action_parameter,"replacement_file");
|
2024-09-29 20:01:49 +08:00
|
|
|
if(item && item->type==cJSON_String)
|
|
|
|
|
{
|
|
|
|
|
param->profile_uuid_str =tfe_strdup(item->valuestring);
|
2019-05-21 19:15:37 +08:00
|
|
|
}
|
2024-09-29 20:01:49 +08:00
|
|
|
item=cJSON_GetObjectItem(action_parameter,"enforcement_ratio");
|
2020-04-29 14:00:13 +08:00
|
|
|
if(item && item->type==cJSON_Number)
|
|
|
|
|
{
|
2020-04-29 17:11:10 +08:00
|
|
|
param->enforcement_ratio = item->valuedouble;
|
2020-04-29 14:00:13 +08:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
param->enforcement_ratio = 1;
|
|
|
|
|
}
|
2019-05-21 19:15:37 +08:00
|
|
|
break;
|
2024-10-25 17:00:57 +08:00
|
|
|
case MA_ACTION_INJECT_JAVESCRIPT:
|
2024-09-29 20:01:49 +08:00
|
|
|
item=cJSON_GetObjectItem(action_parameter,"vsys_id");
|
2022-10-26 14:30:45 +08:00
|
|
|
if(item && item->type==cJSON_Number)
|
|
|
|
|
{
|
2023-04-04 16:06:40 +08:00
|
|
|
param->hit_rule.vsys_id=item->valueint;
|
2022-10-26 14:30:45 +08:00
|
|
|
}
|
2024-10-25 17:00:57 +08:00
|
|
|
item=cJSON_GetObjectItem(action_parameter,"js_file");
|
2024-09-29 20:01:49 +08:00
|
|
|
if(item && item->type==cJSON_String)
|
|
|
|
|
{
|
|
|
|
|
param->profile_uuid_str =tfe_strdup(item->valuestring);
|
2019-05-21 19:15:37 +08:00
|
|
|
}
|
2024-10-25 17:00:57 +08:00
|
|
|
item=cJSON_GetObjectItem(action_parameter,"injection_section");
|
2019-05-21 19:15:37 +08:00
|
|
|
if(item && item->type==cJSON_String){
|
|
|
|
|
param->position = tfe_strdup(item->valuestring);
|
|
|
|
|
}
|
2024-09-29 20:01:49 +08:00
|
|
|
item=cJSON_GetObjectItem(action_parameter,"enforcement_ratio");
|
2020-04-29 14:00:13 +08:00
|
|
|
if(item && item->type==cJSON_Number)
|
|
|
|
|
{
|
2020-04-29 17:11:10 +08:00
|
|
|
param->enforcement_ratio = item->valuedouble;
|
2020-04-29 14:00:13 +08:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
param->enforcement_ratio = 1;
|
|
|
|
|
}
|
2019-05-21 19:15:37 +08:00
|
|
|
break;
|
2024-10-25 17:00:57 +08:00
|
|
|
case MA_ACTION_INJECT_CSS:
|
|
|
|
|
item=cJSON_GetObjectItem(action_parameter,"vsys_id");
|
|
|
|
|
if(item && item->type==cJSON_Number)
|
|
|
|
|
{
|
|
|
|
|
param->hit_rule.vsys_id=item->valueint;
|
|
|
|
|
}
|
|
|
|
|
item=cJSON_GetObjectItem(action_parameter,"css_file");
|
|
|
|
|
if(item && item->type==cJSON_String)
|
|
|
|
|
{
|
|
|
|
|
param->profile_uuid_str =tfe_strdup(item->valuestring);
|
|
|
|
|
}
|
|
|
|
|
item=cJSON_GetObjectItem(action_parameter,"enforcement_ratio");
|
|
|
|
|
if(item && item->type==cJSON_Number)
|
|
|
|
|
{
|
|
|
|
|
param->enforcement_ratio = item->valuedouble;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
param->enforcement_ratio = 1;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case MA_ACTION_EDIT_ELEMENT:
|
2024-09-29 20:01:49 +08:00
|
|
|
item=cJSON_GetObjectItem(action_parameter,"vsys_id");
|
2022-10-26 14:30:45 +08:00
|
|
|
if(item && item->type==cJSON_Number)
|
|
|
|
|
{
|
2023-04-04 16:06:40 +08:00
|
|
|
param->hit_rule.vsys_id=item->valueint;
|
2022-10-26 14:30:45 +08:00
|
|
|
}
|
2024-09-29 20:01:49 +08:00
|
|
|
rules = cJSON_GetObjectItem(action_parameter, "rules");
|
2021-12-06 18:14:10 +08:00
|
|
|
if(rules == NULL)
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
rule_id = 0;
|
2021-12-17 16:39:49 +08:00
|
|
|
param->elem_rule = ALLOC(struct edit_element_rule, MAX_EDIT_ZONE_NUM);
|
2021-12-06 18:14:10 +08:00
|
|
|
for (item = rules->child; item != NULL; item = item->next)
|
|
|
|
|
{
|
|
|
|
|
sub_item=cJSON_GetObjectItem(item,"anchor_element");
|
|
|
|
|
if(sub_item != NULL && sub_item->type ==cJSON_Object)
|
|
|
|
|
{
|
|
|
|
|
char * search_scope = cJSON_GetObjectItem(sub_item , "search_scope")->valuestring;
|
|
|
|
|
if (search_scope == NULL) break;
|
|
|
|
|
|
|
|
|
|
param->elem_rule[rule_id].scope = scope_name_to_id(search_scope);
|
|
|
|
|
if (param->elem_rule[rule_id].scope == KScopeMax)
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if(param->elem_rule[rule_id].scope == kScopeInside)
|
|
|
|
|
{
|
|
|
|
|
param->elem_rule[rule_id].start_indicator = tfe_strdup(cJSON_GetObjectItem(sub_item , "start_indicator")->valuestring);
|
|
|
|
|
}
|
|
|
|
|
param->elem_rule[rule_id].contained_keyword = tfe_strdup(cJSON_GetObjectItem(sub_item,"contained_keyword")->valuestring);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sub_item=cJSON_GetObjectItem(item,"target_element");
|
|
|
|
|
if(sub_item != NULL && sub_item->type ==cJSON_Object)
|
|
|
|
|
{
|
|
|
|
|
param->elem_rule[rule_id].distane_from_matching = cJSON_GetObjectItem(sub_item , "target_distance_from_matching")->valueint;
|
|
|
|
|
param->elem_rule[rule_id].element_treatment = tfe_strdup(cJSON_GetObjectItem(sub_item,"element_treatment")->valuestring);
|
|
|
|
|
}
|
|
|
|
|
rule_id++;
|
|
|
|
|
}
|
|
|
|
|
param->e_rule = rule_id;
|
|
|
|
|
break;
|
2024-10-25 17:00:57 +08:00
|
|
|
default:
|
2019-05-21 19:15:37 +08:00
|
|
|
break;
|
|
|
|
|
}
|
2024-10-30 16:26:38 +08:00
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void policy_action_param_new(const char *table_name, const char* key, const char* table_line, void **ad, long argl, void* argp)
|
|
|
|
|
{
|
|
|
|
|
cJSON* pxy_ctrl_rule = cJSON_Parse(table_line);
|
|
|
|
|
if(pxy_ctrl_rule == NULL)
|
|
|
|
|
{
|
|
|
|
|
TFE_LOG_ERROR(g_proxy_rt->local_logger, "PXY_CTRL_RULE parse table_line failed. table_line:%s", table_line);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct policy_action_param* param=ALLOC(struct policy_action_param, 1);
|
|
|
|
|
|
|
|
|
|
cJSON *uuid = cJSON_GetObjectItem(pxy_ctrl_rule, "uuid");
|
|
|
|
|
if(uuid && uuid->type==cJSON_String)
|
|
|
|
|
{
|
|
|
|
|
param->hit_rule.config_uuid_string = strdup(uuid->valuestring);
|
|
|
|
|
uuid_parse(uuid->valuestring, param->hit_rule.config_uuid);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cJSON *action = cJSON_GetObjectItem(pxy_ctrl_rule, "action");
|
|
|
|
|
if(action && action->type==cJSON_String)
|
|
|
|
|
{
|
|
|
|
|
param->hit_rule.action=action_type_str2idx(action->valuestring);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cJSON *blacklist_option = cJSON_GetObjectItem(pxy_ctrl_rule, "blacklist_option");
|
|
|
|
|
if(blacklist_option && blacklist_option->type==cJSON_Number)
|
|
|
|
|
{
|
|
|
|
|
param->hit_rule.do_blacklist=blacklist_option->valueint;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cJSON *log_option = cJSON_GetObjectItem(pxy_ctrl_rule, "log_option");
|
|
|
|
|
if(log_option && log_option->type==cJSON_String)
|
|
|
|
|
{
|
|
|
|
|
param->hit_rule.do_log=log_option_type_str2idx(log_option->valuestring);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cJSON *action_parameter = cJSON_GetObjectItem(pxy_ctrl_rule, "action_parameter");
|
|
|
|
|
if(action_parameter == NULL || action_parameter->type!=cJSON_Object)
|
|
|
|
|
{
|
|
|
|
|
FREE(¶m);
|
|
|
|
|
TFE_LOG_ERROR(g_proxy_rt->local_logger, "invalid policy parameter: id = %s", param->hit_rule.config_uuid_string);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
param->ref_cnt=1;
|
|
|
|
|
pthread_mutex_init(&(param->lock), NULL);
|
|
|
|
|
param->hit_rule.action_parameter = cJSON_PrintUnformatted(action_parameter);
|
|
|
|
|
policy_set_param_by_action(param, action_parameter);
|
|
|
|
|
|
|
|
|
|
cJSON *method=cJSON_GetObjectItem(action_parameter, "sub_action");
|
|
|
|
|
if(method && method->type==cJSON_String)
|
|
|
|
|
{
|
|
|
|
|
param->action=manipulate_action_str2idx(method->valuestring);
|
|
|
|
|
}
|
|
|
|
|
policy_set_param_by_sub_action(param, action_parameter);
|
|
|
|
|
|
2019-05-21 19:15:37 +08:00
|
|
|
*ad=param;
|
2024-09-29 20:01:49 +08:00
|
|
|
TFE_LOG_INFO(g_proxy_rt->local_logger, "Add ctrl policy: %s", param->hit_rule.config_uuid_string);
|
|
|
|
|
cJSON_Delete(pxy_ctrl_rule);
|
2019-05-21 19:15:37 +08:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-29 20:01:49 +08:00
|
|
|
void policy_action_param_free_cb(const char *table_name, void **ad, long argl, void *argp)
|
2019-05-21 19:15:37 +08:00
|
|
|
{
|
|
|
|
|
unsigned int i=0;
|
|
|
|
|
if(*ad==NULL)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
2019-05-28 14:59:39 +08:00
|
|
|
struct policy_action_param* param=(struct policy_action_param*)*ad;
|
2019-05-21 19:15:37 +08:00
|
|
|
pthread_mutex_lock(&(param->lock));
|
|
|
|
|
param->ref_cnt--;
|
|
|
|
|
if(param->ref_cnt>0)
|
|
|
|
|
{
|
|
|
|
|
pthread_mutex_unlock(&(param->lock));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
pthread_mutex_unlock(&(param->lock));
|
|
|
|
|
pthread_mutex_destroy(&(param->lock));
|
2021-12-06 18:14:10 +08:00
|
|
|
for(i=0; i<param->e_rule; i++)
|
|
|
|
|
{
|
|
|
|
|
if(param->elem_rule[i].start_indicator!=NULL)
|
|
|
|
|
{
|
|
|
|
|
FREE(&(param->elem_rule[i].start_indicator));
|
|
|
|
|
}
|
|
|
|
|
FREE(&(param->elem_rule[i].element_treatment));
|
|
|
|
|
FREE(&(param->elem_rule[i].contained_keyword));
|
|
|
|
|
}
|
2019-05-21 19:15:37 +08:00
|
|
|
for(i=0; i<param->n_rule; i++)
|
|
|
|
|
{
|
2021-12-06 18:14:10 +08:00
|
|
|
FREE(&(param->repl_rule[i].find));
|
|
|
|
|
FREE(&(param->repl_rule[i].replace_with));
|
2019-05-21 19:15:37 +08:00
|
|
|
}
|
|
|
|
|
|
2021-12-13 15:59:59 +08:00
|
|
|
if (param->elem_rule)
|
|
|
|
|
FREE(&(param->elem_rule));
|
|
|
|
|
if (param->repl_rule)
|
|
|
|
|
FREE(&(param->repl_rule));
|
2019-05-21 19:15:37 +08:00
|
|
|
if (param->message)
|
|
|
|
|
FREE(&(param->message));
|
|
|
|
|
if (param->position)
|
|
|
|
|
FREE(&(param->position));
|
2024-09-29 20:01:49 +08:00
|
|
|
if(param->profile_uuid_str)
|
|
|
|
|
FREE(&(param->profile_uuid_str));
|
|
|
|
|
if(param->hit_rule.config_uuid_string)
|
|
|
|
|
FREE(&(param->hit_rule.config_uuid_string));
|
|
|
|
|
if(param->hit_rule.action_parameter)
|
|
|
|
|
FREE(¶m->hit_rule.action_parameter);
|
2023-03-30 19:39:18 +08:00
|
|
|
|
2019-05-21 19:15:37 +08:00
|
|
|
FREE(&(param));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-28 14:59:39 +08:00
|
|
|
void policy_action_param_free(struct policy_action_param* param)
|
|
|
|
|
{
|
2024-09-29 20:01:49 +08:00
|
|
|
policy_action_param_free_cb("PXY_CTRL_RULE_PLUGIN", (void**)¶m, 0, NULL);
|
2019-05-28 14:59:39 +08:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-29 20:01:49 +08:00
|
|
|
void policy_action_param_dup(const char *table_name, void **to, void **from, long argl, void *argp)
|
2019-05-21 19:15:37 +08:00
|
|
|
{
|
2019-05-28 14:59:39 +08:00
|
|
|
struct policy_action_param* from_param=*((struct policy_action_param**)from);
|
2019-06-06 16:36:28 +08:00
|
|
|
if(from_param==NULL)
|
|
|
|
|
{
|
|
|
|
|
*to=NULL;
|
|
|
|
|
return;
|
|
|
|
|
}
|
2019-05-21 19:15:37 +08:00
|
|
|
pthread_mutex_lock(&(from_param->lock));
|
|
|
|
|
from_param->ref_cnt++;
|
|
|
|
|
pthread_mutex_unlock(&(from_param->lock));
|
2019-05-28 14:59:39 +08:00
|
|
|
*((struct policy_action_param**)to)=from_param;
|
2019-05-21 19:15:37 +08:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-29 20:01:49 +08:00
|
|
|
void ma_profile_table_new_cb(const char *table_name, const char* key, const char* table_line, void **ad, long argl, void* argp)
|
2019-05-21 19:15:37 +08:00
|
|
|
{
|
2024-09-29 20:01:49 +08:00
|
|
|
cJSON* response_pages = cJSON_Parse(table_line);
|
|
|
|
|
if(response_pages == NULL)
|
2019-05-21 19:15:37 +08:00
|
|
|
{
|
2024-10-16 16:16:44 +08:00
|
|
|
TFE_LOG_ERROR(g_proxy_rt->local_logger, "RESPONSE_PAGE parse table_line failed. table_line:%s", table_line);
|
2019-05-21 19:15:37 +08:00
|
|
|
return;
|
|
|
|
|
}
|
2019-08-21 19:47:30 +08:00
|
|
|
|
2024-09-29 20:01:49 +08:00
|
|
|
char *profile_path=NULL;
|
2019-08-21 19:47:30 +08:00
|
|
|
struct manipulate_profile* ply_profile=ALLOC(struct manipulate_profile, 1);
|
2024-09-29 20:01:49 +08:00
|
|
|
cJSON *uuid = cJSON_GetObjectItem(response_pages, "uuid");
|
|
|
|
|
if(uuid && uuid->type==cJSON_String)
|
|
|
|
|
{
|
|
|
|
|
ply_profile->profile_uuid = tfe_strdup(uuid->valuestring);
|
|
|
|
|
}
|
|
|
|
|
cJSON *profile_name = cJSON_GetObjectItem(response_pages, "profile_name");
|
|
|
|
|
if(profile_name && profile_name->type==cJSON_String)
|
|
|
|
|
{
|
|
|
|
|
ply_profile->profile_name=tfe_strdup(profile_name->valuestring);
|
|
|
|
|
}
|
|
|
|
|
cJSON *format = cJSON_GetObjectItem(response_pages, "format");
|
|
|
|
|
if(format && format->type==cJSON_String)
|
|
|
|
|
{
|
|
|
|
|
ply_profile->profile_type=tfe_strdup(format->valuestring);
|
|
|
|
|
}
|
|
|
|
|
cJSON *item = cJSON_GetObjectItem(response_pages, "path");
|
|
|
|
|
if(item && item->type==cJSON_String)
|
|
|
|
|
{
|
|
|
|
|
profile_path=item->valuestring;
|
|
|
|
|
}
|
2019-08-21 19:47:30 +08:00
|
|
|
|
|
|
|
|
ply_profile->ref_cnt=1;
|
|
|
|
|
pthread_mutex_init(&(ply_profile->lock), NULL);
|
|
|
|
|
|
2024-09-29 20:01:49 +08:00
|
|
|
if(strcasecmp(ply_profile->profile_type, "template") == 0)
|
2019-08-21 19:47:30 +08:00
|
|
|
{
|
|
|
|
|
ply_profile->tpl = ctemplate::Template::GetTemplate(profile_path, ctemplate::DO_NOT_STRIP);
|
|
|
|
|
}else
|
|
|
|
|
{
|
2020-05-21 17:15:40 +08:00
|
|
|
ply_profile->profile_msg = tfe_read_file(profile_path, &ply_profile->msg_len);
|
2019-08-21 19:47:30 +08:00
|
|
|
if (ply_profile->profile_msg == NULL)
|
|
|
|
|
{
|
2024-09-29 20:01:49 +08:00
|
|
|
TFE_LOG_ERROR(g_proxy_rt->local_logger, "Read file failed %s:%s:%s", ply_profile->profile_uuid, ply_profile->profile_name, profile_path);
|
2019-08-21 19:47:30 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-29 20:01:49 +08:00
|
|
|
cJSON_Delete(response_pages);
|
|
|
|
|
response_pages=NULL;
|
|
|
|
|
TFE_LOG_INFO(g_proxy_rt->local_logger, "Policy table add success %s", ply_profile->profile_uuid);
|
2019-08-21 19:47:30 +08:00
|
|
|
|
|
|
|
|
*ad = ply_profile;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-29 20:01:49 +08:00
|
|
|
void ma_insert_profile_table_new_cb(const char *table_name, const char* key, const char* table_line, void **ad, long argl, void* argp)
|
2019-08-21 19:47:30 +08:00
|
|
|
{
|
2024-09-29 20:01:49 +08:00
|
|
|
cJSON* insert_script = cJSON_Parse(table_line);
|
|
|
|
|
if(insert_script == NULL)
|
2019-08-21 19:47:30 +08:00
|
|
|
{
|
2024-10-16 16:16:44 +08:00
|
|
|
TFE_LOG_ERROR(g_proxy_rt->local_logger, "PROXY_INJECT_SCRIPT parse table_line failed. table_line:%s", table_line);
|
2019-08-21 19:47:30 +08:00
|
|
|
return;
|
|
|
|
|
}
|
2024-09-29 20:01:49 +08:00
|
|
|
|
|
|
|
|
char *profile_path=NULL;
|
2019-05-28 14:59:39 +08:00
|
|
|
struct manipulate_profile* ply_profile=ALLOC(struct manipulate_profile, 1);
|
2024-09-29 20:01:49 +08:00
|
|
|
cJSON *uuid = cJSON_GetObjectItem(insert_script, "uuid");
|
|
|
|
|
if(uuid && uuid->type==cJSON_String)
|
|
|
|
|
{
|
|
|
|
|
ply_profile->profile_uuid = tfe_strdup(uuid->valuestring);
|
|
|
|
|
}
|
|
|
|
|
cJSON *profile_name = cJSON_GetObjectItem(insert_script, "profile_name");
|
|
|
|
|
if(profile_name && profile_name->type==cJSON_String)
|
|
|
|
|
{
|
|
|
|
|
ply_profile->profile_name=tfe_strdup(profile_name->valuestring);
|
|
|
|
|
}
|
|
|
|
|
cJSON *item = cJSON_GetObjectItem(insert_script, "path");
|
|
|
|
|
if(item && item->type==cJSON_String)
|
|
|
|
|
{
|
|
|
|
|
profile_path=item->valuestring;
|
|
|
|
|
}
|
2019-05-21 19:15:37 +08:00
|
|
|
|
2019-06-11 11:25:24 +08:00
|
|
|
ply_profile->ref_cnt=1;
|
2019-06-08 10:57:49 +08:00
|
|
|
pthread_mutex_init(&(ply_profile->lock), NULL);
|
2019-06-11 11:25:24 +08:00
|
|
|
|
2024-10-25 17:00:57 +08:00
|
|
|
if(profile_path != NULL)
|
2019-05-21 19:15:37 +08:00
|
|
|
{
|
2020-05-21 17:15:40 +08:00
|
|
|
ply_profile->profile_msg = tfe_read_file(profile_path, &ply_profile->msg_len);
|
2019-05-28 14:59:39 +08:00
|
|
|
if (ply_profile->profile_msg == NULL)
|
2019-05-21 19:15:37 +08:00
|
|
|
{
|
2024-09-29 20:01:49 +08:00
|
|
|
TFE_LOG_ERROR(g_proxy_rt->local_logger, "Read file failed %s:%s:%s", ply_profile->profile_uuid, ply_profile->profile_name, profile_path);
|
2019-05-21 19:15:37 +08:00
|
|
|
}
|
|
|
|
|
}
|
2019-06-01 18:04:51 +08:00
|
|
|
|
2024-09-29 20:01:49 +08:00
|
|
|
cJSON_Delete(insert_script);
|
|
|
|
|
insert_script=NULL;
|
|
|
|
|
TFE_LOG_INFO(g_proxy_rt->local_logger, "Policy table add success %s", ply_profile->profile_uuid);
|
2019-06-01 18:04:51 +08:00
|
|
|
*ad = ply_profile;
|
2024-09-29 20:01:49 +08:00
|
|
|
|
2019-06-01 18:04:51 +08:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-29 20:01:49 +08:00
|
|
|
void ma_hijack_profile_table_new_cb(const char *table_name, const char* key, const char* table_line, void **ad, long argl, void* argp)
|
2019-06-01 18:04:51 +08:00
|
|
|
{
|
2024-09-29 20:01:49 +08:00
|
|
|
cJSON* hihijack_files = cJSON_Parse(table_line);
|
|
|
|
|
if(hihijack_files == NULL)
|
2019-06-01 18:04:51 +08:00
|
|
|
{
|
2024-10-25 17:00:57 +08:00
|
|
|
TFE_LOG_ERROR(g_proxy_rt->local_logger, "PROXY_REPLACEMENT_FILE parse table_line failed. table_line:%s", table_line);
|
2019-06-01 18:04:51 +08:00
|
|
|
return;
|
|
|
|
|
}
|
2024-09-29 20:01:49 +08:00
|
|
|
|
2019-06-01 18:04:51 +08:00
|
|
|
struct manipulate_profile* ply_profile=ALLOC(struct manipulate_profile, 1);
|
2024-09-29 20:01:49 +08:00
|
|
|
cJSON *uuid = cJSON_GetObjectItem(hihijack_files, "uuid");
|
|
|
|
|
if(uuid && uuid->type==cJSON_String)
|
|
|
|
|
{
|
|
|
|
|
ply_profile->profile_uuid = tfe_strdup(uuid->valuestring);
|
|
|
|
|
}
|
2024-11-07 16:13:55 +08:00
|
|
|
cJSON *profile_name = cJSON_GetObjectItem(hihijack_files, "content_name");
|
2024-09-29 20:01:49 +08:00
|
|
|
if(profile_name && profile_name->type==cJSON_String)
|
|
|
|
|
{
|
|
|
|
|
ply_profile->profile_name=tfe_strdup(profile_name->valuestring);
|
|
|
|
|
}
|
|
|
|
|
cJSON *content_type = cJSON_GetObjectItem(hihijack_files, "content_type");
|
|
|
|
|
if(content_type && content_type->type==cJSON_String)
|
|
|
|
|
{
|
|
|
|
|
ply_profile->profile_type=tfe_strdup(content_type->valuestring);
|
|
|
|
|
}
|
|
|
|
|
cJSON *path = cJSON_GetObjectItem(hihijack_files, "path");
|
|
|
|
|
if(path && path->type==cJSON_String)
|
|
|
|
|
{
|
|
|
|
|
ply_profile->profile_msg=tfe_strdup(path->valuestring);
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-11 11:25:24 +08:00
|
|
|
ply_profile->ref_cnt=1;
|
2019-06-08 10:57:49 +08:00
|
|
|
pthread_mutex_init(&(ply_profile->lock), NULL);
|
2019-06-01 18:04:51 +08:00
|
|
|
|
2024-09-29 20:01:49 +08:00
|
|
|
cJSON_Delete(hihijack_files);
|
|
|
|
|
hihijack_files=NULL;
|
|
|
|
|
TFE_LOG_INFO(g_proxy_rt->local_logger, "Policy table add success %s", ply_profile->profile_uuid);
|
2019-06-01 18:04:51 +08:00
|
|
|
|
2019-05-28 14:59:39 +08:00
|
|
|
*ad = ply_profile;
|
2019-05-21 19:15:37 +08:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-29 20:01:49 +08:00
|
|
|
void ma_lua_profile_table_new_cb(const char *table_name, const char* key, const char* table_line, void **ad, long argl, void* argp)
|
2022-07-29 15:39:25 +08:00
|
|
|
{
|
2024-09-29 20:01:49 +08:00
|
|
|
cJSON* run_scripts = cJSON_Parse(table_line);
|
|
|
|
|
if(run_scripts == NULL)
|
2022-07-29 15:39:25 +08:00
|
|
|
{
|
2024-10-25 17:00:57 +08:00
|
|
|
TFE_LOG_ERROR(g_proxy_rt->local_logger, "PROXY_LUA_SCRIPT parse table_line failed. table_line:%s", table_line);
|
2022-07-29 15:39:25 +08:00
|
|
|
return;
|
|
|
|
|
}
|
2024-09-29 20:01:49 +08:00
|
|
|
|
|
|
|
|
char *profile_path=NULL;
|
|
|
|
|
|
2022-07-29 15:39:25 +08:00
|
|
|
struct manipulate_profile* ply_profile=ALLOC(struct manipulate_profile, 1);
|
2024-09-29 20:01:49 +08:00
|
|
|
cJSON *uuid = cJSON_GetObjectItem(run_scripts, "uuid");
|
|
|
|
|
if(uuid && uuid->type==cJSON_String)
|
|
|
|
|
{
|
|
|
|
|
ply_profile->profile_uuid = tfe_strdup(uuid->valuestring);
|
|
|
|
|
}
|
|
|
|
|
cJSON *max_exec_time = cJSON_GetObjectItem(run_scripts, "max_exec_time");
|
|
|
|
|
if(max_exec_time && max_exec_time->type==cJSON_Number)
|
|
|
|
|
{
|
|
|
|
|
ply_profile->timeout=max_exec_time->valueint;
|
|
|
|
|
}
|
|
|
|
|
cJSON *path = cJSON_GetObjectItem(run_scripts, "path");
|
|
|
|
|
if(path && path->type==cJSON_String)
|
|
|
|
|
{
|
|
|
|
|
profile_path=path->valuestring;
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-29 15:39:25 +08:00
|
|
|
ply_profile->ref_cnt=1;
|
|
|
|
|
pthread_mutex_init(&(ply_profile->lock), NULL);
|
|
|
|
|
|
|
|
|
|
ply_profile->profile_name=tfe_strdup(profile_path);
|
|
|
|
|
ply_profile->profile_msg = tfe_read_file(profile_path, &ply_profile->msg_len);
|
2024-09-29 20:01:49 +08:00
|
|
|
|
2022-07-29 15:39:25 +08:00
|
|
|
if (ply_profile->profile_msg == NULL)
|
|
|
|
|
{
|
2024-09-29 20:01:49 +08:00
|
|
|
cJSON_Delete(run_scripts);
|
|
|
|
|
run_scripts=NULL;
|
|
|
|
|
TFE_LOG_ERROR(g_proxy_rt->local_logger, "Read file failed %s:%s:%s", ply_profile->profile_uuid, ply_profile->profile_name, profile_path);
|
2022-07-29 15:39:25 +08:00
|
|
|
*ad = ply_profile;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-11 16:28:52 +08:00
|
|
|
int thread_num = g_proxy_rt->thread_num;
|
2022-09-09 10:44:11 +08:00
|
|
|
ply_profile->escript_ctx = ALLOC(struct elua_script *, thread_num);
|
2024-09-29 20:01:49 +08:00
|
|
|
TFE_LOG_INFO(g_proxy_rt->local_logger, "Policy table add success %s", ply_profile->profile_uuid);
|
2022-07-29 15:39:25 +08:00
|
|
|
|
2024-09-29 20:01:49 +08:00
|
|
|
cJSON_Delete(run_scripts);
|
|
|
|
|
run_scripts=NULL;
|
2022-07-29 15:39:25 +08:00
|
|
|
*ad = ply_profile;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-29 20:01:49 +08:00
|
|
|
void ma_profile_table_free_cb(const char *table_name, void **ad, long argl, void *argp)
|
2019-05-21 19:15:37 +08:00
|
|
|
{
|
2019-06-08 10:57:49 +08:00
|
|
|
if(*ad==NULL)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
2019-05-28 14:59:39 +08:00
|
|
|
struct manipulate_profile* ply_obj=(struct manipulate_profile*)(*ad);
|
2019-06-08 10:57:49 +08:00
|
|
|
pthread_mutex_lock(&(ply_obj->lock));
|
2019-05-28 17:38:19 +08:00
|
|
|
ply_obj->ref_cnt--;
|
2019-06-08 10:57:49 +08:00
|
|
|
if(ply_obj->ref_cnt>0)
|
2019-05-28 17:38:19 +08:00
|
|
|
{
|
2019-06-08 10:57:49 +08:00
|
|
|
pthread_mutex_unlock(&(ply_obj->lock));
|
|
|
|
|
return;
|
2019-05-28 17:38:19 +08:00
|
|
|
}
|
2019-06-08 10:57:49 +08:00
|
|
|
pthread_mutex_unlock(&(ply_obj->lock));
|
|
|
|
|
pthread_mutex_destroy(&(ply_obj->lock));
|
2019-06-11 11:25:24 +08:00
|
|
|
|
2024-09-29 20:01:49 +08:00
|
|
|
if(ply_obj->profile_uuid)
|
|
|
|
|
FREE(&ply_obj->profile_uuid);
|
|
|
|
|
|
2022-07-29 15:39:25 +08:00
|
|
|
if(ply_obj->profile_type)
|
|
|
|
|
FREE(&ply_obj->profile_type);
|
|
|
|
|
|
|
|
|
|
if(ply_obj->profile_msg)
|
|
|
|
|
FREE(&ply_obj->profile_msg);
|
|
|
|
|
|
2022-09-09 10:44:11 +08:00
|
|
|
if(ply_obj->escript_ctx)
|
|
|
|
|
{
|
|
|
|
|
int i=0;
|
|
|
|
|
for(i=0; i<g_proxy_rt->thread_num; i++)
|
|
|
|
|
{
|
2023-07-11 16:28:52 +08:00
|
|
|
if(ply_obj->escript_ctx[i])
|
|
|
|
|
{
|
|
|
|
|
elua_cleanup_script(ply_obj->escript_ctx[i]);
|
|
|
|
|
FREE(&ply_obj->escript_ctx[i]);
|
|
|
|
|
ply_obj->escript_ctx[i]=NULL;
|
|
|
|
|
}
|
2022-09-09 10:44:11 +08:00
|
|
|
}
|
|
|
|
|
free(ply_obj->escript_ctx);
|
|
|
|
|
ply_obj->escript_ctx=NULL;
|
|
|
|
|
}
|
2022-07-29 15:39:25 +08:00
|
|
|
|
2019-06-08 10:57:49 +08:00
|
|
|
FREE(&ply_obj->profile_name);
|
2019-08-21 19:47:30 +08:00
|
|
|
if (ply_obj->profile_position)
|
|
|
|
|
FREE(&ply_obj->profile_position);
|
2019-06-08 10:57:49 +08:00
|
|
|
FREE(&ply_obj);
|
|
|
|
|
*ad=NULL;
|
|
|
|
|
return;
|
2019-05-28 17:38:19 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ma_profile_table_free(struct manipulate_profile* ply_obj)
|
|
|
|
|
{
|
|
|
|
|
ma_profile_table_free_cb(0, (void **)&ply_obj, 0, NULL);
|
2019-05-21 19:15:37 +08:00
|
|
|
}
|
|
|
|
|
|
2024-09-29 20:01:49 +08:00
|
|
|
void ma_profile_table_dup_cb(const char *table_name, void **to, void **from, long argl, void *argp)
|
2019-05-21 19:15:37 +08:00
|
|
|
{
|
2019-05-28 14:59:39 +08:00
|
|
|
struct manipulate_profile* ply_obj=(struct manipulate_profile*)(*from);
|
2019-06-08 10:57:49 +08:00
|
|
|
pthread_mutex_lock(&(ply_obj->lock));
|
2019-05-28 17:38:19 +08:00
|
|
|
ply_obj->ref_cnt++;
|
2019-06-08 10:57:49 +08:00
|
|
|
pthread_mutex_unlock(&(ply_obj->lock));
|
2019-05-21 19:15:37 +08:00
|
|
|
*to=ply_obj;
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-11 13:47:56 +08:00
|
|
|
const char* table_name_idx2str(int profile_idx)
|
|
|
|
|
{
|
2024-10-16 16:16:44 +08:00
|
|
|
const char *table_name_map[] = {"RESPONSE_PAGE",
|
2024-10-25 17:00:57 +08:00
|
|
|
"PROXY_JS_FILE",
|
|
|
|
|
"PROXY_CSS_FILE",
|
|
|
|
|
"PROXY_REPLACEMENT_FILE",
|
|
|
|
|
"PROXY_LUA_SCRIPT"};
|
2020-06-11 13:47:56 +08:00
|
|
|
|
|
|
|
|
return table_name_map[profile_idx];
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-28 14:59:39 +08:00
|
|
|
int maat_table_ex_init(int profile_idx,
|
2023-03-30 19:39:18 +08:00
|
|
|
maat_ex_free_func_t* free_func,
|
|
|
|
|
maat_ex_dup_func_t* dup_func)
|
2019-05-21 19:15:37 +08:00
|
|
|
{
|
2024-09-29 20:01:49 +08:00
|
|
|
int ret = 0;
|
2019-06-05 11:44:26 +08:00
|
|
|
|
2020-06-11 13:47:56 +08:00
|
|
|
const char *table_name = table_name_idx2str(profile_idx);
|
2023-03-30 19:39:18 +08:00
|
|
|
maat_ex_new_func_t *new_func[] = {
|
2020-06-11 13:47:56 +08:00
|
|
|
[POLICY_PROFLIE_TABLE_REJECT] = ma_profile_table_new_cb,
|
2024-10-25 17:00:57 +08:00
|
|
|
[POLICY_PROFILE_TABLE_JS] = ma_insert_profile_table_new_cb,
|
|
|
|
|
[POLICY_PROFILE_TABLE_CSS] = ma_insert_profile_table_new_cb,
|
2020-06-11 13:47:56 +08:00
|
|
|
[POLICY_PROFILE_TABLE_HIJACK] = ma_hijack_profile_table_new_cb,
|
2022-07-29 15:39:25 +08:00
|
|
|
[POLICY_PROFILE_TABLE_LUA] = ma_lua_profile_table_new_cb,
|
2020-06-11 13:47:56 +08:00
|
|
|
};
|
2019-05-21 19:15:37 +08:00
|
|
|
|
2024-09-29 20:01:49 +08:00
|
|
|
ret=maat_plugin_table_ex_schema_register(g_proxy_rt->feather, table_name,
|
|
|
|
|
new_func[profile_idx],
|
|
|
|
|
free_func,
|
|
|
|
|
dup_func,
|
|
|
|
|
0, NULL);
|
|
|
|
|
if(ret < 0)
|
2019-05-21 19:15:37 +08:00
|
|
|
{
|
2024-09-29 20:01:49 +08:00
|
|
|
TFE_LOG_INFO(NULL, "Pangu HTTP register table %s failed.", table_name);
|
|
|
|
|
return -1;
|
2019-05-21 19:15:37 +08:00
|
|
|
}
|
2024-09-29 20:01:49 +08:00
|
|
|
return ret;
|
2020-06-11 13:47:56 +08:00
|
|
|
}
|
|
|
|
|
|
2022-09-09 10:44:11 +08:00
|
|
|
int proxy_policy_init(const char* profile_path, const char* static_section, const char* dynamic_section)
|
2018-09-12 16:04:04 +08:00
|
|
|
{
|
2019-05-28 14:59:39 +08:00
|
|
|
int ret = 0;
|
2024-07-19 18:20:04 +08:00
|
|
|
g_proxy_rt->feather = tfe_get_maat_handle();
|
2018-12-16 22:47:03 +06:00
|
|
|
|
2024-09-29 20:01:49 +08:00
|
|
|
ret = maat_plugin_table_ex_schema_register(g_proxy_rt->feather, "PXY_CTRL_RULE_PLUGIN",
|
2023-03-30 19:39:18 +08:00
|
|
|
policy_action_param_new,
|
|
|
|
|
policy_action_param_free_cb,
|
|
|
|
|
policy_action_param_dup,
|
|
|
|
|
0, NULL);
|
2019-05-28 14:59:39 +08:00
|
|
|
if(ret<0)
|
|
|
|
|
{
|
2024-09-29 20:01:49 +08:00
|
|
|
TFE_LOG_INFO(NULL, "Pangu HTTP register table PXY_CTRL_RULE_PLUGIN failed.");
|
2019-05-28 14:59:39 +08:00
|
|
|
goto error_out;
|
|
|
|
|
}
|
|
|
|
|
|
2024-10-16 16:16:44 +08:00
|
|
|
ret = maat_table_callback_register(g_proxy_rt->feather, "TRUSTED_CERTIFICATE_AUTHORITY",
|
2024-09-29 20:01:49 +08:00
|
|
|
trusted_CA_update_start_cb,
|
|
|
|
|
trusted_CA_update_cert_cb,
|
|
|
|
|
trusted_CA_update_finish_cb,
|
|
|
|
|
g_proxy_rt);
|
2019-05-28 14:59:39 +08:00
|
|
|
if(ret<0)
|
2018-12-16 22:47:03 +06:00
|
|
|
{
|
2024-09-29 20:01:49 +08:00
|
|
|
TFE_LOG_INFO(NULL, "Pangu HTTP register table PXY_OBJ_TRUSTED_CA_CERT failed.");
|
2018-12-16 22:47:03 +06:00
|
|
|
goto error_out;
|
|
|
|
|
}
|
2019-05-21 19:15:37 +08:00
|
|
|
|
2022-07-29 15:39:25 +08:00
|
|
|
for(int i = 0; i <= POLICY_PROFILE_TABLE_LUA; i++)
|
2019-05-28 14:59:39 +08:00
|
|
|
{
|
2020-06-11 13:47:56 +08:00
|
|
|
ret = maat_table_ex_init(i, ma_profile_table_free_cb, ma_profile_table_dup_cb);
|
|
|
|
|
if(ret<0)
|
|
|
|
|
{
|
|
|
|
|
goto error_out;
|
|
|
|
|
}
|
2019-05-28 14:59:39 +08:00
|
|
|
}
|
2020-06-11 17:57:18 +08:00
|
|
|
|
2019-05-28 14:59:39 +08:00
|
|
|
error_out:
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-09 10:44:11 +08:00
|
|
|
int proxy_http_init(struct tfe_proxy * proxy)
|
2019-05-28 14:59:39 +08:00
|
|
|
{
|
2023-12-29 14:39:03 +08:00
|
|
|
const char * profile_path = "./conf/tfe/tfe.conf";;
|
2019-05-28 14:59:39 +08:00
|
|
|
|
2022-09-09 10:44:11 +08:00
|
|
|
g_proxy_rt = ALLOC(struct tsg_proxy_rt, 1);
|
2023-12-29 14:39:03 +08:00
|
|
|
MESA_load_profile_int_def(profile_path, "tsg_http", "enable_plugin", &(g_proxy_rt->enable_plugin), 1);
|
2022-09-09 10:44:11 +08:00
|
|
|
if (!g_proxy_rt->enable_plugin)
|
2020-07-28 18:54:00 +08:00
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2019-05-28 14:59:39 +08:00
|
|
|
|
2022-09-09 10:44:11 +08:00
|
|
|
g_proxy_rt->thread_num = tfe_proxy_get_work_thread_count();
|
|
|
|
|
g_proxy_rt->gc_evbase=tfe_proxy_get_gc_evbase();
|
2019-05-28 14:59:39 +08:00
|
|
|
|
2023-05-30 19:25:26 +08:00
|
|
|
g_proxy_rt->local_logger = (void *)MESA_create_runtime_log_handle("tsg_http", RLOG_LV_DEBUG);
|
2019-05-28 14:59:39 +08:00
|
|
|
|
2023-12-29 14:39:03 +08:00
|
|
|
g_proxy_rt->send_logger = proxy_log_handle_create(profile_path, "tsg_http", g_proxy_rt->local_logger);
|
2022-09-09 10:44:11 +08:00
|
|
|
if (!g_proxy_rt->send_logger)
|
2019-05-28 14:59:39 +08:00
|
|
|
{
|
|
|
|
|
goto error_out;
|
|
|
|
|
}
|
2022-09-09 10:44:11 +08:00
|
|
|
g_proxy_rt->fs_handle = tfe_proxy_get_fs_handle();
|
|
|
|
|
proxy_http_stat_init(g_proxy_rt);
|
2022-07-29 15:39:25 +08:00
|
|
|
|
2022-09-09 10:44:11 +08:00
|
|
|
if(http_lua_handle_create(&g_proxy_rt->lua_script, g_proxy_rt->thread_num, "tfe") <0)
|
2022-07-29 15:39:25 +08:00
|
|
|
{
|
|
|
|
|
goto error_out;
|
|
|
|
|
}
|
2022-09-09 10:44:11 +08:00
|
|
|
if(proxy_policy_init(profile_path, "MAAT", "DYNAMIC_MAAT")<0)
|
2019-05-28 14:59:39 +08:00
|
|
|
{
|
|
|
|
|
goto error_out;
|
|
|
|
|
}
|
|
|
|
|
|
2018-09-15 20:55:31 +08:00
|
|
|
char page_path[256];
|
2018-09-18 14:15:23 +08:00
|
|
|
memset(page_path, 0, sizeof(page_path));
|
2019-05-28 14:59:39 +08:00
|
|
|
MESA_load_profile_string_def(profile_path, "TEMPLATE", "PAGE_403", page_path, sizeof(page_path),
|
2018-11-19 15:00:07 +08:00
|
|
|
"./resource/pangu/HTTP403.html");
|
2022-09-09 10:44:11 +08:00
|
|
|
g_proxy_rt->tpl_403 = ctemplate::Template::GetTemplate(page_path, ctemplate::DO_NOT_STRIP);
|
2018-09-18 14:15:23 +08:00
|
|
|
memset(page_path, 0, sizeof(page_path));
|
2019-05-28 14:59:39 +08:00
|
|
|
MESA_load_profile_string_def(profile_path, "TEMPLATE", "PAGE_404", page_path, sizeof(page_path),
|
2018-11-20 20:54:03 +08:00
|
|
|
"./resource/pangu/HTTP404.html");
|
2022-09-09 10:44:11 +08:00
|
|
|
g_proxy_rt->tpl_404 = ctemplate::Template::GetTemplate(page_path, ctemplate::DO_NOT_STRIP);
|
2018-09-18 14:15:23 +08:00
|
|
|
memset(page_path, 0, sizeof(page_path));
|
2019-05-28 14:59:39 +08:00
|
|
|
MESA_load_profile_string_def(profile_path, "TEMPLATE", "PAGE_451", page_path, sizeof(page_path),
|
2018-11-20 20:54:03 +08:00
|
|
|
"./resource/pangu/HTTP451.html");
|
2022-09-09 10:44:11 +08:00
|
|
|
g_proxy_rt->tpl_451 = ctemplate::Template::GetTemplate(page_path, ctemplate::DO_NOT_STRIP);
|
2023-12-29 14:39:03 +08:00
|
|
|
g_proxy_rt->enable_rate=0;
|
2019-05-21 19:15:37 +08:00
|
|
|
|
2022-09-09 10:44:11 +08:00
|
|
|
TFE_LOG_INFO(NULL, "Tsg_pxy HTTP init success.");
|
2018-09-18 12:01:56 +08:00
|
|
|
return 0;
|
2018-09-23 20:02:07 +08:00
|
|
|
|
2018-09-12 16:04:04 +08:00
|
|
|
error_out:
|
2022-09-09 10:44:11 +08:00
|
|
|
TFE_LOG_ERROR(NULL, "Tsg_pxy HTTP init failed.");
|
2018-09-18 12:01:56 +08:00
|
|
|
return -1;
|
2018-09-12 16:04:04 +08:00
|
|
|
}
|
2018-09-27 19:06:57 +08:00
|
|
|
|
2018-09-13 19:28:13 +08:00
|
|
|
struct replace_ctx
|
|
|
|
|
{
|
2018-09-23 20:02:07 +08:00
|
|
|
struct replace_rule * rule;
|
2018-09-13 19:28:13 +08:00
|
|
|
size_t n_rule;
|
|
|
|
|
struct tfe_http_half * replacing;
|
2018-09-23 20:02:07 +08:00
|
|
|
struct evbuffer * http_body;
|
2018-09-28 19:27:44 +08:00
|
|
|
int actually_replaced;
|
2018-09-13 19:28:13 +08:00
|
|
|
};
|
2018-09-23 20:02:07 +08:00
|
|
|
|
2019-05-21 19:15:37 +08:00
|
|
|
struct insert_ctx
|
|
|
|
|
{
|
|
|
|
|
struct insert_rule *rule;
|
|
|
|
|
struct tfe_http_half * replacing;
|
|
|
|
|
struct evbuffer *http_body;
|
2020-09-25 10:11:41 +08:00
|
|
|
int actually_inserted;
|
2019-05-21 19:15:37 +08:00
|
|
|
};
|
|
|
|
|
|
2021-12-06 18:14:10 +08:00
|
|
|
struct edit_element_ctx
|
|
|
|
|
{
|
2021-12-17 16:39:49 +08:00
|
|
|
struct edit_element_rule *item;
|
2021-12-06 18:14:10 +08:00
|
|
|
size_t n_item;
|
|
|
|
|
struct tfe_http_half * editing;
|
|
|
|
|
struct evbuffer *http_body;
|
|
|
|
|
int actually_edited;
|
|
|
|
|
};
|
|
|
|
|
|
2022-09-09 10:44:11 +08:00
|
|
|
struct proxy_http_ctx
|
2018-09-12 16:04:04 +08:00
|
|
|
{
|
2018-10-21 15:03:04 +08:00
|
|
|
int magic_num;
|
2022-09-09 10:44:11 +08:00
|
|
|
enum proxy_action action;
|
2018-09-23 20:02:07 +08:00
|
|
|
char * action_para;
|
2021-05-28 10:51:22 +08:00
|
|
|
int hit_cnt;
|
2024-09-29 20:01:49 +08:00
|
|
|
uuid_t result[MAX_SCAN_RESULT];
|
2023-03-30 19:39:18 +08:00
|
|
|
struct maat_state *scan_mid;
|
|
|
|
|
struct maat_stream *sp;
|
|
|
|
|
struct maat_rule_t * enforce_rules;
|
2018-09-15 17:52:06 +08:00
|
|
|
size_t n_enforce;
|
2019-05-28 14:59:39 +08:00
|
|
|
struct policy_action_param *param;
|
2018-12-24 22:47:26 +06:00
|
|
|
struct evbuffer* log_req_body, *log_resp_body;
|
2018-09-23 20:02:07 +08:00
|
|
|
|
2020-04-03 16:16:07 +08:00
|
|
|
size_t inject_sz;
|
2020-04-29 14:00:13 +08:00
|
|
|
int manipulate_replaced;
|
2018-09-23 20:02:07 +08:00
|
|
|
struct replace_ctx * rep_ctx;
|
2019-05-21 19:15:37 +08:00
|
|
|
struct insert_ctx * ins_ctx;
|
2021-12-06 18:14:10 +08:00
|
|
|
struct edit_element_ctx * edit_ctx;
|
2022-07-29 15:39:25 +08:00
|
|
|
struct tsg_script_ctx *tsg_ctx;
|
2019-05-21 19:15:37 +08:00
|
|
|
|
2018-10-25 18:45:33 +08:00
|
|
|
int (* resumed_cb)(const struct tfe_stream * stream,
|
|
|
|
|
const struct tfe_http_session * session, enum tfe_http_event event, const unsigned char * data,
|
2022-09-09 10:44:11 +08:00
|
|
|
size_t datalen, unsigned int thread_id, struct proxy_http_ctx* ctx);
|
2018-10-14 17:11:45 +08:00
|
|
|
struct tfe_http_session * ref_session;
|
2019-05-21 19:15:37 +08:00
|
|
|
|
2023-08-02 16:55:56 +08:00
|
|
|
size_t c2s_byte_num;
|
|
|
|
|
size_t s2c_byte_num;
|
2018-09-12 16:04:04 +08:00
|
|
|
int thread_id;
|
|
|
|
|
};
|
2018-10-25 18:45:33 +08:00
|
|
|
|
2024-02-29 11:25:36 +08:00
|
|
|
static inline int ctx_actually_replaced(struct proxy_http_ctx * ctx)
|
|
|
|
|
{
|
2024-10-25 17:00:57 +08:00
|
|
|
if(ctx->action == PX_ACTION_MANIPULATE &&
|
|
|
|
|
ctx->param->action == MA_ACTION_REPLACE_TEXT &&
|
|
|
|
|
ctx->rep_ctx->actually_replaced==1)
|
2024-02-29 11:25:36 +08:00
|
|
|
{
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline int ctx_actually_ran_script(struct proxy_http_ctx * ctx)
|
|
|
|
|
{
|
2024-10-25 17:00:57 +08:00
|
|
|
if(ctx->action == PX_ACTION_EXECUTE && ctx->tsg_ctx->actually_executed==1)
|
2024-02-29 11:25:36 +08:00
|
|
|
{
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline int ctx_actually_inserted(struct proxy_http_ctx * ctx)
|
|
|
|
|
{
|
2024-10-25 17:00:57 +08:00
|
|
|
if((ctx->action == PX_ACTION_MANIPULATE && ctx->param->action == MA_ACTION_INJECT_JAVESCRIPT && ctx->ins_ctx->actually_inserted==1)
|
|
|
|
|
|| (ctx->action == PX_ACTION_MANIPULATE && ctx->param->action == MA_ACTION_INJECT_CSS && ctx->ins_ctx->actually_inserted==1))
|
2024-02-29 11:25:36 +08:00
|
|
|
{
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline int ctx_actually_edited(struct proxy_http_ctx * ctx)
|
|
|
|
|
{
|
2024-10-25 17:00:57 +08:00
|
|
|
if(ctx->action == PX_ACTION_MANIPULATE &&
|
|
|
|
|
ctx->param->action == MA_ACTION_EDIT_ELEMENT && ctx->edit_ctx != NULL &&
|
|
|
|
|
ctx->edit_ctx->actually_edited==1)
|
2024-02-29 11:25:36 +08:00
|
|
|
{
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline int ctx_actually_manipulate(struct proxy_http_ctx * ctx)
|
|
|
|
|
{
|
2024-10-25 17:00:57 +08:00
|
|
|
if((ctx->action == PX_ACTION_REDIRECT && ctx->manipulate_replaced==1) ||
|
|
|
|
|
(ctx->action == PX_ACTION_MANIPULATE && ctx->param->action == MA_ACTION_REPLACE_FILE && ctx->manipulate_replaced==1))
|
2024-02-29 11:25:36 +08:00
|
|
|
{
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-10-14 17:11:45 +08:00
|
|
|
void http_repl_ctx_free(struct replace_ctx* rep_ctx)
|
|
|
|
|
{
|
|
|
|
|
if (rep_ctx->http_body)
|
|
|
|
|
{
|
|
|
|
|
evbuffer_free(rep_ctx->http_body);
|
|
|
|
|
rep_ctx->http_body = NULL;
|
|
|
|
|
}
|
|
|
|
|
FREE(&rep_ctx);
|
|
|
|
|
return;
|
|
|
|
|
}
|
2019-05-21 19:15:37 +08:00
|
|
|
|
|
|
|
|
void http_ins_ctx_free(struct insert_ctx* ins_ctx)
|
|
|
|
|
{
|
2019-06-15 18:19:15 +08:00
|
|
|
if (ins_ctx->rule->script)
|
|
|
|
|
FREE(&ins_ctx->rule->script);
|
2019-05-28 14:59:39 +08:00
|
|
|
FREE(&ins_ctx->rule->type);
|
|
|
|
|
if (ins_ctx->rule->position)
|
|
|
|
|
FREE(&ins_ctx->rule->position);
|
2019-05-21 19:15:37 +08:00
|
|
|
FREE(&(ins_ctx->rule));
|
|
|
|
|
if (ins_ctx->http_body)
|
|
|
|
|
{
|
|
|
|
|
evbuffer_free(ins_ctx->http_body);
|
|
|
|
|
ins_ctx->http_body = NULL;
|
|
|
|
|
}
|
|
|
|
|
FREE(&ins_ctx);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-06 18:14:10 +08:00
|
|
|
void http_element_ctx_free(struct edit_element_ctx *edit_ctx)
|
|
|
|
|
{
|
|
|
|
|
if (edit_ctx->http_body)
|
|
|
|
|
{
|
|
|
|
|
evbuffer_free(edit_ctx->http_body);
|
|
|
|
|
edit_ctx->http_body = NULL;
|
|
|
|
|
}
|
|
|
|
|
FREE(&edit_ctx);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-29 15:39:25 +08:00
|
|
|
void http_tsg_ctx_free(struct tsg_script_ctx *tsg_ctx, int thread_id)
|
|
|
|
|
{
|
2024-09-29 20:01:49 +08:00
|
|
|
if(tsg_ctx->config_uuid_str)
|
|
|
|
|
{
|
|
|
|
|
FREE(&tsg_ctx->config_uuid_str)
|
|
|
|
|
}
|
|
|
|
|
if(tsg_ctx->profile_uuid_str)
|
|
|
|
|
{
|
|
|
|
|
FREE(&tsg_ctx->profile_uuid_str)
|
|
|
|
|
}
|
2022-07-29 15:39:25 +08:00
|
|
|
if (tsg_ctx->http_body)
|
|
|
|
|
{
|
|
|
|
|
evbuffer_free(tsg_ctx->http_body);
|
|
|
|
|
tsg_ctx->http_body = NULL;
|
|
|
|
|
}
|
|
|
|
|
if (tsg_ctx->http_lua_body)
|
|
|
|
|
{
|
|
|
|
|
evbuffer_free(tsg_ctx->http_lua_body);
|
|
|
|
|
tsg_ctx->http_lua_body = NULL;
|
|
|
|
|
}
|
2022-09-09 10:44:11 +08:00
|
|
|
http_lua_ctx_free(&g_proxy_rt->lua_script, thread_id, tsg_ctx->elua_ctx);
|
2022-07-29 15:39:25 +08:00
|
|
|
FREE(&tsg_ctx);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2018-10-21 15:03:04 +08:00
|
|
|
#define HTTP_CTX_MAGIC_NUM 20181021
|
2022-09-09 10:44:11 +08:00
|
|
|
static struct proxy_http_ctx * proxy_http_ctx_new(unsigned int thread_id)
|
2018-09-12 16:04:04 +08:00
|
|
|
{
|
2022-09-09 10:44:11 +08:00
|
|
|
struct proxy_http_ctx * ctx = ALLOC(struct proxy_http_ctx, 1);
|
2018-10-21 15:03:04 +08:00
|
|
|
ctx->magic_num=HTTP_CTX_MAGIC_NUM;
|
2023-03-30 19:39:18 +08:00
|
|
|
ctx->scan_mid = maat_state_new(g_proxy_rt->feather, thread_id);
|
2018-09-23 20:02:07 +08:00
|
|
|
ctx->thread_id = (int) thread_id;
|
2018-09-12 16:04:04 +08:00
|
|
|
return ctx;
|
|
|
|
|
}
|
2018-09-23 20:02:07 +08:00
|
|
|
|
2022-09-09 10:44:11 +08:00
|
|
|
static void proxy_http_ctx_free(struct proxy_http_ctx * ctx)
|
2018-09-12 16:04:04 +08:00
|
|
|
{
|
2018-10-21 15:03:04 +08:00
|
|
|
assert(ctx->magic_num==HTTP_CTX_MAGIC_NUM);
|
2020-06-11 13:47:56 +08:00
|
|
|
if(ctx->rep_ctx)
|
2018-09-25 20:32:24 +08:00
|
|
|
{
|
2018-10-14 17:11:45 +08:00
|
|
|
http_repl_ctx_free(ctx->rep_ctx);
|
|
|
|
|
ctx->rep_ctx = NULL;
|
2018-09-25 20:32:24 +08:00
|
|
|
}
|
2020-06-11 13:47:56 +08:00
|
|
|
if(ctx->ins_ctx)
|
2019-05-21 19:15:37 +08:00
|
|
|
{
|
|
|
|
|
http_ins_ctx_free(ctx->ins_ctx);
|
|
|
|
|
ctx->ins_ctx = NULL;
|
|
|
|
|
}
|
2021-12-06 18:14:10 +08:00
|
|
|
if(ctx->edit_ctx)
|
|
|
|
|
{
|
|
|
|
|
http_element_ctx_free(ctx->edit_ctx);
|
|
|
|
|
ctx->edit_ctx = NULL;
|
|
|
|
|
}
|
2022-07-29 15:39:25 +08:00
|
|
|
if(ctx->tsg_ctx)
|
|
|
|
|
{
|
|
|
|
|
http_tsg_ctx_free(ctx->tsg_ctx, ctx->thread_id);
|
|
|
|
|
ctx->tsg_ctx = NULL;
|
|
|
|
|
}
|
2020-06-11 13:47:56 +08:00
|
|
|
|
2020-04-29 14:00:13 +08:00
|
|
|
ctx->manipulate_replaced=0;
|
2018-09-15 17:52:06 +08:00
|
|
|
FREE(&ctx->enforce_rules);
|
2019-05-28 17:38:19 +08:00
|
|
|
policy_action_param_free(ctx->param);
|
|
|
|
|
ctx->param=NULL;
|
2023-03-30 19:39:18 +08:00
|
|
|
|
|
|
|
|
maat_state_free(ctx->scan_mid);
|
2018-11-09 15:52:14 +08:00
|
|
|
ctx->scan_mid = NULL;
|
2018-10-14 17:11:45 +08:00
|
|
|
|
2018-10-14 18:45:02 +08:00
|
|
|
if(ctx->sp)
|
2018-10-14 17:11:45 +08:00
|
|
|
{
|
2023-03-30 19:39:18 +08:00
|
|
|
maat_stream_free(ctx->sp);
|
|
|
|
|
ctx->sp=NULL;
|
2018-10-14 17:11:45 +08:00
|
|
|
}
|
2018-11-23 18:13:44 +08:00
|
|
|
|
2018-12-24 22:47:26 +06:00
|
|
|
if(ctx->log_req_body)
|
|
|
|
|
{
|
|
|
|
|
evbuffer_free(ctx->log_req_body);
|
|
|
|
|
ctx->log_req_body=NULL;
|
|
|
|
|
}
|
|
|
|
|
if(ctx->log_resp_body)
|
|
|
|
|
{
|
|
|
|
|
evbuffer_free(ctx->log_resp_body);
|
|
|
|
|
ctx->log_resp_body=NULL;
|
|
|
|
|
}
|
2018-10-21 15:03:04 +08:00
|
|
|
ctx->magic_num=0;
|
2018-09-15 17:52:06 +08:00
|
|
|
FREE(&ctx);
|
2018-09-12 16:04:04 +08:00
|
|
|
}
|
2018-09-23 20:02:07 +08:00
|
|
|
|
2018-10-23 10:41:16 +08:00
|
|
|
static inline void addr_tfe2sapp(const struct tfe_stream_addr * tfe_addr, struct ipaddr * sapp_addr)
|
2018-09-12 16:04:04 +08:00
|
|
|
{
|
2018-09-30 11:55:50 +08:00
|
|
|
if(tfe_addr->addrtype==TFE_ADDR_STREAM_TUPLE4_V4||tfe_addr->addrtype==TFE_ADDR_IPV4)
|
|
|
|
|
{
|
|
|
|
|
sapp_addr->addrtype = ADDR_TYPE_IPV4;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
sapp_addr->addrtype=ADDR_TYPE_IPV6;
|
|
|
|
|
}
|
2018-09-23 20:02:07 +08:00
|
|
|
sapp_addr->paddr = (char *) tfe_addr->paddr;
|
2018-09-12 16:04:04 +08:00
|
|
|
return;
|
|
|
|
|
}
|
2018-10-23 10:41:16 +08:00
|
|
|
|
2024-09-29 20:01:49 +08:00
|
|
|
static struct manipulate_profile* get_profile_by_id(const char *table_name, char *cfg_id_str)
|
2019-05-28 14:59:39 +08:00
|
|
|
{
|
|
|
|
|
struct manipulate_profile* result=NULL;
|
2024-09-29 20:01:49 +08:00
|
|
|
result = (struct manipulate_profile*)maat_plugin_table_get_ex_data(g_proxy_rt->feather, table_name, (const char*)cfg_id_str, strlen(cfg_id_str));
|
2019-05-28 14:59:39 +08:00
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-16 16:03:54 +08:00
|
|
|
void proxy_send_metric_log(const struct tfe_stream * stream, struct proxy_http_ctx * ctx, unsigned int thread_id, int state)
|
|
|
|
|
{
|
|
|
|
|
size_t i=0;
|
|
|
|
|
int hit_cnt=0;
|
2024-10-25 17:00:57 +08:00
|
|
|
const char *manipulate_action_map[]= {"replace_text","replace_file","edit_element","inject_javascript","inject_css"};
|
|
|
|
|
const char *proxy_action_map[] = {"none", "allow", "deny", "monitor", "redirect", "execute", "modify"};
|
2024-07-26 16:50:51 +08:00
|
|
|
|
|
|
|
|
struct filedstat_easy_manipulation *fieldstat = tfe_get_fieldstat_handle()->manipulation;
|
|
|
|
|
if(fieldstat == NULL)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
2024-01-16 16:03:54 +08:00
|
|
|
|
|
|
|
|
for(i=0; i< ctx->n_enforce; i++)
|
|
|
|
|
{
|
2024-11-04 16:27:16 +08:00
|
|
|
char uuid_string[UUID_STRING_SIZE] = {0};
|
|
|
|
|
uuid_unparse(ctx->enforce_rules[i].config_uuid, uuid_string);
|
2024-07-22 17:22:45 +08:00
|
|
|
fieldstat->tags[thread_id][TAG_VSYS_ID].value_longlong = ctx->enforce_rules[i].vsys_id;
|
2024-11-04 16:27:16 +08:00
|
|
|
fieldstat->tags[thread_id][TAG_RULE_ID].value_str = uuid_string;
|
2024-10-30 16:26:38 +08:00
|
|
|
fieldstat->tags[thread_id][TAG_ACTION].value_str = "manipulate";
|
2024-10-25 17:00:57 +08:00
|
|
|
if(ctx->enforce_rules[i].action == PX_ACTION_MANIPULATE)
|
|
|
|
|
{
|
|
|
|
|
fieldstat->tags[thread_id][TAG_SUB_ACTION].value_str = manipulate_action_map[ctx->param->action];
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
fieldstat->tags[thread_id][TAG_SUB_ACTION].value_str = proxy_action_map[ctx->enforce_rules[i].action];
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-16 16:03:54 +08:00
|
|
|
size_t c2s_byte_num = 0, s2c_byte_num =0;
|
|
|
|
|
tfe_stream_info_get(stream, INFO_FROM_DOWNSTREAM_RX_OFFSET, &c2s_byte_num, sizeof(c2s_byte_num));
|
|
|
|
|
tfe_stream_info_get(stream, INFO_FROM_UPSTREAM_RX_OFFSET, &s2c_byte_num, sizeof(s2c_byte_num));
|
|
|
|
|
|
|
|
|
|
uint16_t out_size;
|
|
|
|
|
unsigned int route_dir; int ret=0;
|
|
|
|
|
int in_bytes = 0, out_bytes = 0;
|
|
|
|
|
|
|
|
|
|
struct tfe_cmsg *cmsg = tfe_stream_get0_cmsg(stream);
|
|
|
|
|
if (cmsg != NULL)
|
|
|
|
|
{
|
|
|
|
|
ret = tfe_cmsg_get_value(cmsg, TFE_CMSG_COMMON_DIRECTION, (unsigned char *)&route_dir, sizeof(route_dir), &out_size);
|
|
|
|
|
if (ret != 0)
|
|
|
|
|
{
|
|
|
|
|
TFE_LOG_ERROR(g_proxy_rt->local_logger, "failed at fetch route_dir from cmsg: %s", strerror(-ret));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
int dir_is_e2i=(route_dir==69) ? 0 : 1;
|
|
|
|
|
if (dir_is_e2i == 1)
|
|
|
|
|
{
|
|
|
|
|
in_bytes = c2s_byte_num - ctx->c2s_byte_num;
|
|
|
|
|
out_bytes = s2c_byte_num - ctx->s2c_byte_num;
|
|
|
|
|
ctx->c2s_byte_num = c2s_byte_num;
|
|
|
|
|
ctx->s2c_byte_num = s2c_byte_num;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
in_bytes = s2c_byte_num - ctx->c2s_byte_num;
|
|
|
|
|
out_bytes = c2s_byte_num - ctx->s2c_byte_num;
|
|
|
|
|
ctx->c2s_byte_num = s2c_byte_num;
|
|
|
|
|
ctx->s2c_byte_num = c2s_byte_num;
|
|
|
|
|
}
|
|
|
|
|
if(state == 1)
|
|
|
|
|
{
|
|
|
|
|
hit_cnt=0;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
hit_cnt=1;
|
|
|
|
|
in_bytes=0;
|
|
|
|
|
out_bytes=0;
|
|
|
|
|
}
|
2024-07-22 17:22:45 +08:00
|
|
|
|
2024-08-30 11:47:22 +08:00
|
|
|
if(hit_cnt == 0 && in_bytes == 0 && out_bytes == 0)
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2024-07-26 16:50:51 +08:00
|
|
|
tfe_fieldstat_manipulation_incrby(fieldstat, fieldstat->counter_array[COLUMN_HIT_COUNT], hit_cnt, fieldstat->tags[thread_id], TAG_MAX - 1, thread_id);
|
|
|
|
|
tfe_fieldstat_manipulation_incrby(fieldstat, fieldstat->counter_array[COLUMN_IN_BYTES], in_bytes, fieldstat->tags[thread_id], TAG_MAX - 1, thread_id);
|
|
|
|
|
tfe_fieldstat_manipulation_incrby(fieldstat, fieldstat->counter_array[COLUMN_OUT_BYTES], out_bytes, fieldstat->tags[thread_id], TAG_MAX - 1, thread_id);
|
2024-01-16 16:03:54 +08:00
|
|
|
}
|
2024-07-26 16:50:51 +08:00
|
|
|
|
2024-01-16 16:03:54 +08:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-04 20:22:31 +08:00
|
|
|
static unsigned long long try_send_by_token(int inject_sz)
|
|
|
|
|
{
|
2022-09-09 10:44:11 +08:00
|
|
|
if (g_proxy_rt->enable_rate != 1)
|
2020-06-04 20:22:31 +08:00
|
|
|
{
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
2023-12-29 14:39:03 +08:00
|
|
|
return inject_sz;
|
2020-06-04 20:22:31 +08:00
|
|
|
}
|
|
|
|
|
|
2022-09-09 10:44:11 +08:00
|
|
|
static int pangu_action_weight[__PX_ACTION_MAX] = {0};
|
2018-10-23 10:41:16 +08:00
|
|
|
void __pangu_action_weight_init() __attribute__((constructor, used));
|
|
|
|
|
void __pangu_action_weight_init()
|
2018-09-29 16:05:10 +08:00
|
|
|
{
|
2022-09-09 10:44:11 +08:00
|
|
|
pangu_action_weight[PX_ACTION_NONE] = 0;
|
2024-10-21 18:32:15 +08:00
|
|
|
pangu_action_weight[PX_ACTION_MONITOR] = 1;
|
|
|
|
|
pangu_action_weight[PX_ACTION_REDIRECT] = 2;
|
2024-10-25 17:00:57 +08:00
|
|
|
pangu_action_weight[PX_ACTION_EXECUTE] = 2;
|
|
|
|
|
pangu_action_weight[PX_ACTION_MANIPULATE] = 2;
|
2024-10-21 18:32:15 +08:00
|
|
|
pangu_action_weight[PX_ACTION_DENY] = 3;
|
|
|
|
|
pangu_action_weight[PX_ACTION_ALLOW] = 4;
|
2018-09-29 16:05:10 +08:00
|
|
|
}
|
2018-10-23 10:41:16 +08:00
|
|
|
|
2022-09-09 10:44:11 +08:00
|
|
|
static inline int action_cmp(enum proxy_action a1, enum proxy_action a2)
|
2018-10-23 10:41:16 +08:00
|
|
|
{
|
|
|
|
|
return pangu_action_weight[a1] - pangu_action_weight[a2];
|
|
|
|
|
}
|
|
|
|
|
|
2018-09-15 17:52:06 +08:00
|
|
|
//enforce_rules[0] contains execute action.
|
2024-09-29 20:01:49 +08:00
|
|
|
static enum proxy_action decide_ctrl_action(uuid_t *result, size_t n_hit,
|
2023-03-30 19:39:18 +08:00
|
|
|
struct maat_rule_t** enforce_rules, size_t * n_enforce, struct policy_action_param **param)
|
2018-09-12 16:04:04 +08:00
|
|
|
{
|
2022-11-16 12:48:11 +08:00
|
|
|
void *ex_data=NULL;
|
2024-09-29 20:01:49 +08:00
|
|
|
char result_uuid_string[UUID_STRING_SIZE]={0};
|
2018-09-23 20:02:07 +08:00
|
|
|
size_t n_monit = 0, exist_enforce_num = 0, i = 0;
|
2023-03-30 19:39:18 +08:00
|
|
|
|
|
|
|
|
struct policy_action_param *get_ex_param=NULL;
|
|
|
|
|
struct maat_rule_t *hit_rules=NULL;
|
|
|
|
|
|
|
|
|
|
hit_rules=ALLOC(struct maat_rule_t, n_hit);
|
|
|
|
|
for (i = 0; i < n_hit && i<MAX_SCAN_RESULT; i++)
|
|
|
|
|
{
|
2024-09-29 20:01:49 +08:00
|
|
|
uuid_unparse(result[i], result_uuid_string);
|
|
|
|
|
get_ex_param =(struct policy_action_param *)maat_plugin_table_get_ex_data(g_proxy_rt->feather, "PXY_CTRL_RULE_PLUGIN", result_uuid_string, strlen(result_uuid_string));
|
2023-03-30 19:39:18 +08:00
|
|
|
if(get_ex_param==NULL)
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
memcpy(hit_rules+i, &get_ex_param->hit_rule, sizeof(struct maat_rule_t));
|
|
|
|
|
policy_action_param_free(get_ex_param);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const struct maat_rule_t * prior_rule = hit_rules;
|
|
|
|
|
struct maat_rule_t monit_rule[n_hit];
|
2022-09-09 10:44:11 +08:00
|
|
|
enum proxy_action prior_action = PX_ACTION_NONE;
|
2018-09-23 20:02:07 +08:00
|
|
|
|
2020-07-15 12:13:47 +08:00
|
|
|
for (i = 0; i < n_hit && i<MAX_SCAN_RESULT; i++)
|
2018-09-12 16:04:04 +08:00
|
|
|
{
|
2018-10-25 13:24:05 +08:00
|
|
|
unsigned char __expand_action = (unsigned char) hit_rules[i].action;
|
2022-09-09 10:44:11 +08:00
|
|
|
enum proxy_action __action = (enum proxy_action) __expand_action;
|
2018-10-25 13:24:05 +08:00
|
|
|
|
2024-10-21 18:32:15 +08:00
|
|
|
if (__action == PX_ACTION_MONITOR)
|
2018-09-12 16:04:04 +08:00
|
|
|
{
|
2023-03-30 19:39:18 +08:00
|
|
|
memcpy(monit_rule + n_monit, hit_rules + i, sizeof(struct maat_rule_t));
|
2018-09-15 17:52:06 +08:00
|
|
|
n_monit++;
|
2018-09-12 16:04:04 +08:00
|
|
|
}
|
2018-10-25 13:24:05 +08:00
|
|
|
if (action_cmp(__action, prior_action) > 0)
|
2018-09-12 16:04:04 +08:00
|
|
|
{
|
2018-09-23 20:02:07 +08:00
|
|
|
prior_rule = hit_rules + i;
|
2018-10-25 13:24:05 +08:00
|
|
|
prior_action = __action;
|
2018-09-15 17:52:06 +08:00
|
|
|
}
|
2018-10-25 13:24:05 +08:00
|
|
|
else if (action_cmp(__action, prior_action) == 0)
|
2018-09-15 17:52:06 +08:00
|
|
|
{
|
2024-09-29 20:01:49 +08:00
|
|
|
if(uuid_compare(hit_rules[i].config_uuid, prior_rule->config_uuid) > 0)
|
2018-09-12 16:04:04 +08:00
|
|
|
{
|
2018-09-23 20:02:07 +08:00
|
|
|
prior_rule = hit_rules + i;
|
2018-09-12 16:04:04 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-09-23 20:02:07 +08:00
|
|
|
|
2024-10-21 18:32:15 +08:00
|
|
|
if (prior_action == PX_ACTION_ALLOW)
|
2018-09-15 17:52:06 +08:00
|
|
|
{
|
2019-06-17 20:12:37 +08:00
|
|
|
if(*n_enforce==0)
|
|
|
|
|
{
|
2023-03-30 19:39:18 +08:00
|
|
|
*enforce_rules=ALLOC(struct maat_rule_t, 1);
|
2019-06-17 20:12:37 +08:00
|
|
|
}
|
|
|
|
|
*enforce_rules[0]=*prior_rule;
|
|
|
|
|
*n_enforce=1;
|
2024-09-29 20:01:49 +08:00
|
|
|
|
|
|
|
|
ex_data=maat_plugin_table_get_ex_data(g_proxy_rt->feather, "PXY_CTRL_RULE_PLUGIN", prior_rule->config_uuid_string, strlen(prior_rule->config_uuid_string));
|
2022-11-16 12:48:11 +08:00
|
|
|
if(ex_data!=NULL)
|
|
|
|
|
{
|
|
|
|
|
*param=(struct policy_action_param*)ex_data;
|
|
|
|
|
}
|
2023-04-13 14:34:34 +08:00
|
|
|
if(hit_rules)
|
|
|
|
|
{
|
|
|
|
|
FREE(&hit_rules);
|
|
|
|
|
}
|
2024-10-21 18:32:15 +08:00
|
|
|
return PX_ACTION_ALLOW;
|
2018-09-15 17:52:06 +08:00
|
|
|
}
|
2018-09-23 20:02:07 +08:00
|
|
|
|
|
|
|
|
exist_enforce_num = *n_enforce;
|
2024-10-21 18:32:15 +08:00
|
|
|
if (prior_action == PX_ACTION_MONITOR)
|
2018-09-15 17:52:06 +08:00
|
|
|
{
|
2018-09-23 20:02:07 +08:00
|
|
|
*n_enforce += n_monit;
|
2018-09-15 17:52:06 +08:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2018-09-23 20:02:07 +08:00
|
|
|
*n_enforce += n_monit + 1;
|
2018-09-15 17:52:06 +08:00
|
|
|
}
|
2018-09-23 20:02:07 +08:00
|
|
|
|
2023-03-30 19:39:18 +08:00
|
|
|
*enforce_rules = (struct maat_rule_t *) realloc(*enforce_rules, sizeof(struct maat_rule_t) * (*n_enforce));
|
2024-10-21 18:32:15 +08:00
|
|
|
if (prior_action == PX_ACTION_MONITOR)
|
2018-09-23 20:02:07 +08:00
|
|
|
{
|
2023-03-30 19:39:18 +08:00
|
|
|
memcpy(*enforce_rules + exist_enforce_num, monit_rule, n_monit * sizeof(struct maat_rule_t));
|
2018-09-23 20:02:07 +08:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2023-03-30 19:39:18 +08:00
|
|
|
memmove(*enforce_rules+1, *enforce_rules, exist_enforce_num*sizeof(struct maat_rule_t));
|
|
|
|
|
memcpy(*enforce_rules, prior_rule, sizeof(struct maat_rule_t));
|
|
|
|
|
memcpy(*enforce_rules + exist_enforce_num + 1, monit_rule, n_monit * sizeof(struct maat_rule_t));
|
2018-09-23 20:02:07 +08:00
|
|
|
}
|
2019-05-21 19:15:37 +08:00
|
|
|
|
2024-09-29 20:01:49 +08:00
|
|
|
ex_data=maat_plugin_table_get_ex_data(g_proxy_rt->feather, "PXY_CTRL_RULE_PLUGIN", prior_rule->config_uuid_string, strlen(prior_rule->config_uuid_string));
|
2019-05-21 19:15:37 +08:00
|
|
|
if(ex_data!=NULL)
|
2018-11-14 17:58:51 +08:00
|
|
|
{
|
2019-05-28 14:59:39 +08:00
|
|
|
*param=(struct policy_action_param*)ex_data;
|
2018-11-14 17:58:51 +08:00
|
|
|
}
|
2023-04-04 16:06:40 +08:00
|
|
|
if(hit_rules)
|
|
|
|
|
{
|
|
|
|
|
FREE(&hit_rules);
|
|
|
|
|
}
|
2018-09-23 20:02:07 +08:00
|
|
|
|
2018-09-15 17:52:06 +08:00
|
|
|
return prior_action;
|
2018-09-12 16:04:04 +08:00
|
|
|
}
|
2018-09-27 19:06:57 +08:00
|
|
|
//HTML template is downloaded from https://github.com/AndiDittrich/HttpErrorPages
|
2022-04-28 14:03:47 +08:00
|
|
|
static void template_generate(int status_code, const char* msg, char ** page_buff, size_t * page_size)
|
2018-09-12 16:04:04 +08:00
|
|
|
{
|
2018-09-27 19:06:57 +08:00
|
|
|
ctemplate::TemplateDictionary dict("pg_page_dict"); //dict is automatically finalized after function returned.
|
2019-06-05 11:44:26 +08:00
|
|
|
|
|
|
|
|
if (NULL == msg)
|
|
|
|
|
{
|
|
|
|
|
dict.SetValue("msg", "NULL");
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
dict.SetValue("msg", msg);
|
|
|
|
|
}
|
2018-09-15 20:55:31 +08:00
|
|
|
std::string output;
|
2018-09-23 20:02:07 +08:00
|
|
|
ctemplate::Template * tpl = NULL;
|
2018-09-25 11:15:00 +08:00
|
|
|
|
2018-09-23 20:02:07 +08:00
|
|
|
switch (status_code)
|
2018-09-15 20:55:31 +08:00
|
|
|
{
|
2022-09-09 10:44:11 +08:00
|
|
|
case 403: tpl = g_proxy_rt->tpl_403;
|
2018-09-15 20:55:31 +08:00
|
|
|
break;
|
2022-09-09 10:44:11 +08:00
|
|
|
case 404: tpl = g_proxy_rt->tpl_404;
|
2018-09-15 20:55:31 +08:00
|
|
|
break;
|
2022-09-09 10:44:11 +08:00
|
|
|
case 451: tpl = g_proxy_rt->tpl_451;
|
2018-09-15 20:55:31 +08:00
|
|
|
break;
|
2018-09-23 20:02:07 +08:00
|
|
|
default: return;
|
2018-09-15 20:55:31 +08:00
|
|
|
}
|
2018-09-25 11:15:00 +08:00
|
|
|
|
2018-09-15 20:55:31 +08:00
|
|
|
tpl->Expand(&output, &dict);
|
2018-10-11 10:42:05 +08:00
|
|
|
*page_size = output.length() + 1;
|
2018-10-14 17:11:45 +08:00
|
|
|
*page_buff = tfe_strdup(output.c_str());
|
2018-09-12 16:04:04 +08:00
|
|
|
}
|
2018-09-25 11:15:00 +08:00
|
|
|
|
2019-05-28 14:59:39 +08:00
|
|
|
void manipulate_profile_free(struct manipulate_profile* ma_profile)
|
2019-05-21 19:15:37 +08:00
|
|
|
{
|
2019-05-28 14:59:39 +08:00
|
|
|
FREE(&ma_profile->profile_type);
|
|
|
|
|
FREE(&ma_profile->profile_msg);
|
|
|
|
|
FREE(&ma_profile->profile_name);
|
|
|
|
|
FREE(&ma_profile);
|
|
|
|
|
}
|
2019-05-21 19:15:37 +08:00
|
|
|
|
2024-09-29 20:01:49 +08:00
|
|
|
static int html_generate(char *profile_uuid, const char* msg, char ** page_buff, size_t * page_size)
|
2019-05-28 14:59:39 +08:00
|
|
|
{
|
|
|
|
|
int ret = 0;
|
2019-05-21 19:15:37 +08:00
|
|
|
|
2024-10-16 16:16:44 +08:00
|
|
|
if(profile_uuid==NULL)
|
|
|
|
|
{
|
|
|
|
|
ret=-1;
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct manipulate_profile* block_profile=get_profile_by_id("RESPONSE_PAGE", profile_uuid);
|
2019-05-28 14:59:39 +08:00
|
|
|
if(block_profile==NULL)
|
2019-05-21 19:15:37 +08:00
|
|
|
{
|
|
|
|
|
ret=-1;
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
2019-05-28 14:59:39 +08:00
|
|
|
if(!strncmp(block_profile->profile_type, "template", strlen(block_profile->profile_type)))
|
2019-05-21 19:15:37 +08:00
|
|
|
{
|
|
|
|
|
ctemplate::TemplateDictionary dict("pg_page_dict"); //dict is automatically finalized after function returned.
|
|
|
|
|
dict.SetValue("msg", msg);
|
|
|
|
|
std::string output;
|
|
|
|
|
|
2019-05-28 14:59:39 +08:00
|
|
|
block_profile->tpl->Expand(&output, &dict);
|
2019-05-21 19:15:37 +08:00
|
|
|
*page_size = output.length() + 1;
|
|
|
|
|
*page_buff = tfe_strdup(output.c_str());
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2019-05-28 14:59:39 +08:00
|
|
|
*page_size = block_profile->msg_len;
|
|
|
|
|
*page_buff = tfe_strdup(block_profile->profile_msg);
|
2019-05-21 19:15:37 +08:00
|
|
|
}
|
2019-05-28 17:38:19 +08:00
|
|
|
ma_profile_table_free(block_profile);
|
2019-05-28 14:59:39 +08:00
|
|
|
block_profile=NULL;
|
2019-05-28 17:38:19 +08:00
|
|
|
|
|
|
|
|
return ret;
|
2019-05-21 19:15:37 +08:00
|
|
|
}
|
|
|
|
|
|
2018-09-23 20:02:07 +08:00
|
|
|
static void html_free(char ** page_buff)
|
2018-09-12 16:04:04 +08:00
|
|
|
{
|
2019-05-28 14:59:39 +08:00
|
|
|
FREE(page_buff);
|
2018-09-12 16:04:04 +08:00
|
|
|
return;
|
|
|
|
|
}
|
2018-10-16 17:57:28 +08:00
|
|
|
|
2020-04-29 14:00:13 +08:00
|
|
|
static int http_enforcement_ratio(float enforcement_ratio)
|
|
|
|
|
{
|
|
|
|
|
int enforcement_ratio_temp = 0;
|
|
|
|
|
enforcement_ratio_temp = enforcement_ratio * 10000;
|
|
|
|
|
|
|
|
|
|
srand(time(NULL));
|
|
|
|
|
int random = rand() % (10000-1);
|
|
|
|
|
if (random >=0 && random <= enforcement_ratio_temp)
|
|
|
|
|
{
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-29 20:01:49 +08:00
|
|
|
int http_lua_profile(char *profile_uuid_str, struct elua_script ***elua_ctx, char **profile_msg, size_t *msg_len, int *timeout)
|
2022-07-29 15:39:25 +08:00
|
|
|
{
|
|
|
|
|
int ret = 0;
|
|
|
|
|
|
2024-10-25 17:00:57 +08:00
|
|
|
struct manipulate_profile* lua_profile=get_profile_by_id("PROXY_LUA_SCRIPT", profile_uuid_str);
|
2022-07-29 15:39:25 +08:00
|
|
|
if(lua_profile==NULL)
|
|
|
|
|
{
|
|
|
|
|
ret=-1;
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-09 10:44:11 +08:00
|
|
|
*elua_ctx=lua_profile->escript_ctx;
|
2023-07-11 16:28:52 +08:00
|
|
|
*profile_msg=tfe_strdup(lua_profile->profile_msg);
|
|
|
|
|
*msg_len=lua_profile->msg_len;
|
|
|
|
|
*timeout=lua_profile->timeout;
|
2022-07-29 15:39:25 +08:00
|
|
|
ma_profile_table_free(lua_profile);
|
|
|
|
|
lua_profile = NULL;
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void http_lua(const struct tfe_stream * stream, const struct tfe_http_session * session, enum tfe_http_event events,
|
2022-09-09 10:44:11 +08:00
|
|
|
const unsigned char * body_frag, size_t frag_size, struct proxy_http_ctx * ctx)
|
2022-07-29 15:39:25 +08:00
|
|
|
{
|
|
|
|
|
int ret = 0;
|
|
|
|
|
struct tfe_http_session * to_write_sess = NULL;
|
|
|
|
|
|
2022-09-09 10:44:11 +08:00
|
|
|
struct tsg_lua_script *lua_script=&g_proxy_rt->lua_script;
|
2022-07-29 15:39:25 +08:00
|
|
|
lua_script->http_lua_profile=http_lua_profile;
|
|
|
|
|
|
|
|
|
|
to_write_sess = tfe_http_session_allow_write(session);
|
|
|
|
|
if (to_write_sess == NULL) //fail to wirte, abandon.
|
|
|
|
|
{
|
|
|
|
|
TFE_STREAM_LOG_INFO(stream, "tfe_http_session_allow_write() %s failed.", session->req->req_spec.uri);
|
2022-09-09 10:44:11 +08:00
|
|
|
ctx->action = PX_ACTION_NONE;
|
2022-07-29 15:39:25 +08:00
|
|
|
tfe_http_session_detach(session); return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct tsg_script_ctx *tsg_ctx = ctx->tsg_ctx;
|
|
|
|
|
if (ctx->tsg_ctx == NULL)
|
|
|
|
|
{
|
|
|
|
|
if ((events & EV_HTTP_REQ_HDR) || (events & EV_HTTP_RESP_HDR))
|
|
|
|
|
{
|
|
|
|
|
struct policy_action_param *param = ctx->param;
|
|
|
|
|
ctx->tsg_ctx = tsg_ctx = ALLOC(struct tsg_script_ctx, 1);
|
2024-09-29 20:01:49 +08:00
|
|
|
tsg_ctx->profile_uuid_str = tfe_strdup(param->profile_uuid_str);
|
2023-03-30 19:39:18 +08:00
|
|
|
tsg_ctx->addr = stream->addr;
|
2022-09-09 10:44:11 +08:00
|
|
|
tsg_ctx->elua_ctx = http_lua_ctx_new(lua_script, ctx->thread_id);
|
2022-07-29 15:39:25 +08:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
TFE_STREAM_LOG_INFO(stream, "Can only setup replace on REQ/RESP headers, detached.");
|
2022-09-09 10:44:11 +08:00
|
|
|
ctx->action = PX_ACTION_NONE;
|
2022-07-29 15:39:25 +08:00
|
|
|
tfe_http_session_detach(session); return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
tsg_ctx->events = events;
|
|
|
|
|
tsg_ctx->session = session;
|
2022-09-09 10:44:11 +08:00
|
|
|
tsg_ctx->local_logger = g_proxy_rt->local_logger;
|
2024-11-04 16:27:16 +08:00
|
|
|
tsg_ctx->config_uuid_str = tfe_strdup(ctx->enforce_rules[0].config_uuid_string);
|
2022-07-29 15:39:25 +08:00
|
|
|
|
|
|
|
|
struct tfe_http_half * in_req_half = session->req;
|
|
|
|
|
struct tfe_http_half * in_resp_half = session->resp;
|
|
|
|
|
struct tfe_http_req_spec * in_req_spec = &in_req_half->req_spec;
|
|
|
|
|
struct tfe_http_resp_spec * in_resp_spec = &in_resp_half->resp_spec;
|
|
|
|
|
|
|
|
|
|
if ((events & EV_HTTP_REQ_HDR) || (events & EV_HTTP_RESP_HDR))
|
|
|
|
|
{
|
2023-03-30 19:39:18 +08:00
|
|
|
tsg_ctx->http_req_uri=1; tsg_ctx->execut_lua_sucess=0;
|
2024-09-29 20:01:49 +08:00
|
|
|
ret=execute_lua_script_rule(lua_script, tsg_ctx->profile_uuid_str, tsg_ctx->elua_ctx, ctx->thread_id, (void *)tsg_ctx);
|
2023-03-30 19:39:18 +08:00
|
|
|
if(ret==0 && tsg_ctx->execut_lua_sucess==1)
|
|
|
|
|
{
|
|
|
|
|
tsg_ctx->actually_executed =1;
|
|
|
|
|
}
|
|
|
|
|
tsg_ctx->http_req_uri=0;
|
|
|
|
|
tsg_ctx->execut_lua_sucess=0;
|
|
|
|
|
|
2022-07-29 15:39:25 +08:00
|
|
|
if (tfe_http_in_request(events))
|
|
|
|
|
{
|
2022-09-09 10:44:11 +08:00
|
|
|
tsg_ctx->replacing = tfe_http_session_request_create(to_write_sess, in_req_spec->method, tsg_ctx->rewrite_uri !=NULL ? tsg_ctx->rewrite_uri : in_req_spec->uri);
|
2022-07-29 15:39:25 +08:00
|
|
|
tfe_http_session_request_set(to_write_sess, tsg_ctx->replacing);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
tsg_ctx->replacing = tfe_http_session_response_create(to_write_sess, in_resp_spec->resp_code);
|
|
|
|
|
tfe_http_session_response_set(to_write_sess, tsg_ctx->replacing);
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-09 10:44:11 +08:00
|
|
|
if (tsg_ctx->rewrite_uri != NULL)
|
|
|
|
|
{
|
|
|
|
|
FREE(&tsg_ctx->rewrite_uri);
|
|
|
|
|
}
|
|
|
|
|
|
2024-09-29 20:01:49 +08:00
|
|
|
ret=execute_lua_script_rule(lua_script, tsg_ctx->profile_uuid_str, tsg_ctx->elua_ctx, ctx->thread_id, (void *)tsg_ctx);
|
2022-09-09 10:44:11 +08:00
|
|
|
if(ret==0 && tsg_ctx->execut_lua_sucess==1)
|
2022-07-29 15:39:25 +08:00
|
|
|
{
|
|
|
|
|
tsg_ctx->actually_executed =1;
|
|
|
|
|
}
|
|
|
|
|
struct tfe_http_half * in_half = tfe_http_in_request(events) ? in_req_half : in_resp_half;
|
|
|
|
|
|
|
|
|
|
struct http_field_name in_header_field{};
|
|
|
|
|
const char * in_header_value = NULL;
|
|
|
|
|
void * iterator = NULL;
|
|
|
|
|
|
2023-03-30 19:39:18 +08:00
|
|
|
while (true && tsg_ctx->rewrite_header!=1)
|
2022-07-29 15:39:25 +08:00
|
|
|
{
|
|
|
|
|
if ((in_header_value = tfe_http_field_iterate(in_half, &iterator, &in_header_field)) == NULL)
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
tfe_http_field_write(tsg_ctx->replacing, &in_header_field, in_header_value);
|
|
|
|
|
}
|
2023-03-30 19:39:18 +08:00
|
|
|
tsg_ctx->rewrite_header=0;
|
2022-07-29 15:39:25 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((events & EV_HTTP_REQ_BODY_BEGIN) || (events & EV_HTTP_RESP_BODY_BEGIN))
|
|
|
|
|
{
|
|
|
|
|
assert(tsg_ctx->http_body == NULL);
|
|
|
|
|
tsg_ctx->http_body = evbuffer_new();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((events & EV_HTTP_REQ_BODY_CONT) || (events & EV_HTTP_RESP_BODY_CONT))
|
|
|
|
|
{
|
|
|
|
|
evbuffer_add(tsg_ctx->http_body, body_frag, frag_size);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((events & EV_HTTP_REQ_BODY_END) || (events & EV_HTTP_RESP_BODY_END))
|
|
|
|
|
{
|
|
|
|
|
char * __http_body = (char *) evbuffer_pullup(tsg_ctx->http_body, -1);
|
|
|
|
|
size_t __http_body_len = evbuffer_get_length(tsg_ctx->http_body);
|
|
|
|
|
|
2024-09-29 20:01:49 +08:00
|
|
|
ret=execute_lua_script_rule(lua_script, tsg_ctx->profile_uuid_str, tsg_ctx->elua_ctx, ctx->thread_id, (void *)tsg_ctx);
|
2022-07-29 15:39:25 +08:00
|
|
|
|
|
|
|
|
char * __http_lua_body = NULL; size_t __http_body_lua_len = 0;
|
2022-09-09 10:44:11 +08:00
|
|
|
if(ret == 0 && tsg_ctx->http_lua_body != NULL)
|
2022-07-29 15:39:25 +08:00
|
|
|
{
|
|
|
|
|
tsg_ctx->actually_executed =1;
|
|
|
|
|
__http_lua_body = (char *) evbuffer_pullup(tsg_ctx->http_lua_body, -1);
|
|
|
|
|
__http_body_lua_len = evbuffer_get_length(tsg_ctx->http_lua_body);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (__http_body_lua_len >0)
|
|
|
|
|
{
|
|
|
|
|
tfe_http_half_append_body(tsg_ctx->replacing, __http_lua_body, __http_body_lua_len, 0);
|
|
|
|
|
tsg_ctx->actually_executed=1;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
tfe_http_half_append_body(tsg_ctx->replacing, __http_body, __http_body_len, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (tsg_ctx->http_lua_body != NULL)
|
|
|
|
|
{
|
|
|
|
|
evbuffer_free(tsg_ctx->http_lua_body);
|
|
|
|
|
tsg_ctx->http_lua_body = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (tsg_ctx->http_body != NULL)
|
|
|
|
|
{
|
|
|
|
|
evbuffer_free(tsg_ctx->http_body);
|
|
|
|
|
tsg_ctx->http_body = NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((events & EV_HTTP_REQ_END) || (events & EV_HTTP_RESP_END))
|
|
|
|
|
{
|
|
|
|
|
tfe_http_half_append_body(tsg_ctx->replacing, NULL, 0, 0);
|
|
|
|
|
tsg_ctx->replacing = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-21 19:15:37 +08:00
|
|
|
void http_replace(const struct tfe_stream * stream, const struct tfe_http_session * session, enum tfe_http_event events,
|
2022-09-09 10:44:11 +08:00
|
|
|
const unsigned char * body_frag, size_t frag_size, struct proxy_http_ctx * ctx)
|
2018-09-12 16:04:04 +08:00
|
|
|
{
|
2018-09-23 20:02:07 +08:00
|
|
|
struct tfe_http_session * to_write_sess = NULL;
|
2018-09-28 15:41:29 +08:00
|
|
|
char * rewrite_buff = NULL;
|
|
|
|
|
size_t rewrite_sz = 0;
|
|
|
|
|
|
2020-04-29 14:00:13 +08:00
|
|
|
struct policy_action_param *param = ctx->param;
|
|
|
|
|
int ratio = http_enforcement_ratio(param->enforcement_ratio);
|
|
|
|
|
if (ratio != 1)
|
|
|
|
|
{
|
2022-09-09 10:44:11 +08:00
|
|
|
TFE_LOG_DEBUG(g_proxy_rt->local_logger, "enforcement ratio:%f", param->enforcement_ratio);
|
|
|
|
|
ctx->action = PX_ACTION_NONE;
|
2020-04-29 14:00:13 +08:00
|
|
|
return;
|
|
|
|
|
}
|
2018-09-23 20:02:07 +08:00
|
|
|
to_write_sess = tfe_http_session_allow_write(session);
|
|
|
|
|
if (to_write_sess == NULL) //fail to wirte, abandon.
|
|
|
|
|
{
|
|
|
|
|
TFE_STREAM_LOG_INFO(stream, "tfe_http_session_allow_write() %s failed.", session->req->req_spec.uri);
|
2022-09-09 10:44:11 +08:00
|
|
|
ctx->action = PX_ACTION_NONE;
|
2018-09-25 20:32:24 +08:00
|
|
|
tfe_http_session_detach(session); return;
|
2018-09-14 16:33:36 +08:00
|
|
|
}
|
2018-09-25 20:32:24 +08:00
|
|
|
|
|
|
|
|
struct replace_ctx * rep_ctx = ctx->rep_ctx;
|
2018-09-23 20:02:07 +08:00
|
|
|
if (ctx->rep_ctx == NULL)
|
2018-09-13 19:28:13 +08:00
|
|
|
{
|
2018-09-25 20:32:24 +08:00
|
|
|
/* we must determinate the replace action on HTTP header, otherwise,
|
|
|
|
|
* the header has been forwarded, only replace the body but not modify header will raise exception */
|
|
|
|
|
if ((events & EV_HTTP_REQ_HDR) || (events & EV_HTTP_RESP_HDR))
|
|
|
|
|
{
|
2019-05-28 14:59:39 +08:00
|
|
|
struct policy_action_param *param = ctx->param;
|
2018-09-25 20:32:24 +08:00
|
|
|
ctx->rep_ctx = rep_ctx = ALLOC(struct replace_ctx, 1);
|
2021-12-06 18:14:10 +08:00
|
|
|
rep_ctx->rule = param->repl_rule;
|
2019-05-21 19:15:37 +08:00
|
|
|
rep_ctx->n_rule = param->n_rule;
|
2018-09-25 20:32:24 +08:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
TFE_STREAM_LOG_INFO(stream, "Can only setup replace on REQ/RESP headers, detached.");
|
2022-09-09 10:44:11 +08:00
|
|
|
ctx->action = PX_ACTION_NONE;
|
2018-09-25 20:32:24 +08:00
|
|
|
tfe_http_session_detach(session); return;
|
|
|
|
|
}
|
2018-09-13 19:28:13 +08:00
|
|
|
}
|
2018-09-23 20:02:07 +08:00
|
|
|
|
2018-09-25 20:32:24 +08:00
|
|
|
struct tfe_http_half * in_req_half = session->req;
|
|
|
|
|
struct tfe_http_half * in_resp_half = session->resp;
|
|
|
|
|
struct tfe_http_req_spec * in_req_spec = &in_req_half->req_spec;
|
|
|
|
|
struct tfe_http_resp_spec * in_resp_spec = &in_resp_half->resp_spec;
|
|
|
|
|
|
|
|
|
|
if ((events & EV_HTTP_REQ_HDR) || (events & EV_HTTP_RESP_HDR))
|
|
|
|
|
{
|
2018-09-28 15:41:29 +08:00
|
|
|
char * rewrite_uri = NULL;
|
|
|
|
|
size_t rewrite_uri_sz=0;
|
2018-10-14 17:11:45 +08:00
|
|
|
if (tfe_http_in_request(events))
|
2018-09-13 19:28:13 +08:00
|
|
|
{
|
2024-01-19 14:21:30 +08:00
|
|
|
if(in_req_spec->uri != NULL)
|
|
|
|
|
{
|
|
|
|
|
rewrite_uri_sz = execute_replace_rule(in_req_spec->uri, strlen(in_req_spec->uri),
|
2019-06-14 13:15:49 +08:00
|
|
|
kZoneRequestUri, rep_ctx->rule, rep_ctx->n_rule, &rewrite_uri, 1);
|
2024-01-19 14:21:30 +08:00
|
|
|
}
|
2018-09-28 19:27:44 +08:00
|
|
|
if(rewrite_uri_sz>0) rep_ctx->actually_replaced=1;
|
2018-09-25 20:32:24 +08:00
|
|
|
rep_ctx->replacing = tfe_http_session_request_create(to_write_sess, in_req_spec->method,
|
2018-09-28 15:41:29 +08:00
|
|
|
rewrite_uri_sz >0 ? rewrite_uri : in_req_spec->uri);
|
2018-09-25 20:32:24 +08:00
|
|
|
tfe_http_session_request_set(to_write_sess, rep_ctx->replacing);
|
2018-09-13 19:28:13 +08:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2018-09-25 20:32:24 +08:00
|
|
|
rep_ctx->replacing = tfe_http_session_response_create(to_write_sess, in_resp_spec->resp_code);
|
|
|
|
|
tfe_http_session_response_set(to_write_sess, rep_ctx->replacing);
|
2018-09-13 19:28:13 +08:00
|
|
|
}
|
2018-09-25 20:32:24 +08:00
|
|
|
|
|
|
|
|
if (rewrite_uri != NULL)
|
2018-09-13 19:28:13 +08:00
|
|
|
{
|
2018-09-28 15:41:29 +08:00
|
|
|
FREE(&rewrite_uri);
|
2018-09-25 20:32:24 +08:00
|
|
|
}
|
|
|
|
|
|
2018-10-14 17:11:45 +08:00
|
|
|
enum replace_zone zone = tfe_http_in_request(events) ? kZoneRequestHeaders : kZoneResponseHeader;
|
|
|
|
|
struct tfe_http_half * in_half = tfe_http_in_request(events) ? in_req_half : in_resp_half;
|
2018-09-25 20:32:24 +08:00
|
|
|
|
|
|
|
|
struct http_field_name in_header_field{};
|
|
|
|
|
const char * in_header_value = NULL;
|
|
|
|
|
void * iterator = NULL;
|
|
|
|
|
|
|
|
|
|
while (true)
|
|
|
|
|
{
|
|
|
|
|
if ((in_header_value = tfe_http_field_iterate(in_half, &iterator, &in_header_field)) == NULL)
|
2018-09-13 19:28:13 +08:00
|
|
|
{
|
2018-09-25 20:32:24 +08:00
|
|
|
break;
|
2018-09-13 19:28:13 +08:00
|
|
|
}
|
|
|
|
|
|
2018-09-28 15:41:29 +08:00
|
|
|
rewrite_buff = NULL;
|
|
|
|
|
rewrite_sz = 0;
|
|
|
|
|
rewrite_sz=execute_replace_rule(in_header_value,
|
2019-06-14 13:15:49 +08:00
|
|
|
strlen(in_header_value), zone, rep_ctx->rule, rep_ctx->n_rule, &rewrite_buff, 1);
|
2018-09-28 19:27:44 +08:00
|
|
|
|
2019-05-21 19:15:37 +08:00
|
|
|
if(rewrite_sz>0) rep_ctx->actually_replaced=1;
|
2018-09-28 15:41:29 +08:00
|
|
|
tfe_http_field_write(rep_ctx->replacing, &in_header_field, rewrite_sz>0? rewrite_buff : in_header_value);
|
|
|
|
|
if(rewrite_buff != NULL)
|
2018-09-25 20:32:24 +08:00
|
|
|
{
|
2018-09-28 15:41:29 +08:00
|
|
|
FREE(&rewrite_buff);
|
2018-09-13 19:28:13 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-09-25 20:32:24 +08:00
|
|
|
|
|
|
|
|
if ((events & EV_HTTP_REQ_BODY_BEGIN) || (events & EV_HTTP_RESP_BODY_BEGIN))
|
2018-09-13 19:28:13 +08:00
|
|
|
{
|
2018-09-23 20:02:07 +08:00
|
|
|
assert(rep_ctx->http_body == NULL);
|
|
|
|
|
rep_ctx->http_body = evbuffer_new();
|
2018-09-13 19:28:13 +08:00
|
|
|
}
|
2018-09-25 20:32:24 +08:00
|
|
|
|
|
|
|
|
if ((events & EV_HTTP_REQ_BODY_CONT) || (events & EV_HTTP_RESP_BODY_CONT))
|
2018-09-13 19:28:13 +08:00
|
|
|
{
|
|
|
|
|
evbuffer_add(rep_ctx->http_body, body_frag, frag_size);
|
2018-09-25 20:32:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((events & EV_HTTP_REQ_BODY_END) || (events & EV_HTTP_RESP_BODY_END))
|
|
|
|
|
{
|
2019-06-14 13:15:49 +08:00
|
|
|
int options = 0;
|
2018-09-25 20:32:24 +08:00
|
|
|
char * __http_body = (char *) evbuffer_pullup(rep_ctx->http_body, -1);
|
|
|
|
|
size_t __http_body_len = evbuffer_get_length(rep_ctx->http_body);
|
|
|
|
|
|
2018-10-14 17:11:45 +08:00
|
|
|
enum replace_zone r_zone = tfe_http_in_request(events) ? kZoneRequestBody : kZoneResponseBody;
|
2019-05-21 19:15:37 +08:00
|
|
|
|
2018-09-28 15:41:29 +08:00
|
|
|
rewrite_buff = NULL;
|
|
|
|
|
rewrite_sz = 0;
|
2019-05-21 19:15:37 +08:00
|
|
|
|
2021-01-12 16:17:18 +08:00
|
|
|
if ((tfe_http_in_response(events) && in_resp_spec->content_type != NULL
|
|
|
|
|
&& strcasestr(in_resp_spec->content_type, "utf-8")) || tfe_http_in_request(events))
|
2019-06-14 13:15:49 +08:00
|
|
|
{
|
|
|
|
|
options = 1;
|
|
|
|
|
}
|
2021-12-06 18:14:10 +08:00
|
|
|
rewrite_sz = execute_replace_rule(__http_body, __http_body_len, r_zone, rep_ctx->rule, rep_ctx->n_rule, &rewrite_buff, options);
|
2019-05-21 19:15:37 +08:00
|
|
|
|
2018-09-28 15:41:29 +08:00
|
|
|
if (rewrite_sz >0 )
|
2018-09-13 19:28:13 +08:00
|
|
|
{
|
2018-09-28 15:41:29 +08:00
|
|
|
tfe_http_half_append_body(rep_ctx->replacing, rewrite_buff, rewrite_sz, 0);
|
2018-09-28 19:27:44 +08:00
|
|
|
rep_ctx->actually_replaced=1;
|
2018-09-25 20:32:24 +08:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
tfe_http_half_append_body(rep_ctx->replacing, __http_body, __http_body_len, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (rewrite_buff != NULL)
|
|
|
|
|
{
|
2018-09-28 15:41:29 +08:00
|
|
|
FREE(&rewrite_buff);
|
2018-09-25 20:32:24 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (rep_ctx->http_body != NULL)
|
|
|
|
|
{
|
|
|
|
|
evbuffer_free(rep_ctx->http_body);
|
|
|
|
|
rep_ctx->http_body = NULL;
|
|
|
|
|
}
|
2018-09-13 19:28:13 +08:00
|
|
|
}
|
2018-09-23 20:02:07 +08:00
|
|
|
|
2018-09-25 20:32:24 +08:00
|
|
|
if ((events & EV_HTTP_REQ_END) || (events & EV_HTTP_RESP_END))
|
|
|
|
|
{
|
|
|
|
|
tfe_http_half_append_body(rep_ctx->replacing, NULL, 0, 0);
|
|
|
|
|
rep_ctx->replacing = NULL;
|
|
|
|
|
}
|
2018-09-12 16:04:04 +08:00
|
|
|
}
|
2018-09-25 20:32:24 +08:00
|
|
|
|
2021-06-10 15:28:45 +08:00
|
|
|
static void http_get_client_id(const struct tfe_stream * stream, char *replace_regex)
|
|
|
|
|
{
|
|
|
|
|
const char *sip,*dip,*sport,*dport;
|
|
|
|
|
|
|
|
|
|
tfe_stream_addr_str_split((char *)stream->str_stream_info, &sip, &sport, &dip, &dport);
|
|
|
|
|
|
2021-07-23 15:55:42 +08:00
|
|
|
snprintf(replace_regex, TFE_SYMBOL_MAX, "%s", sip);
|
2021-06-10 15:28:45 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void http_get_subscriber_id(const struct tfe_stream * stream, char *replace_regex)
|
|
|
|
|
{
|
|
|
|
|
int ret = 0;
|
|
|
|
|
uint16_t opt_out_size;
|
2023-08-02 16:55:56 +08:00
|
|
|
char source_subscribe_id[TFE_SYMBOL_MAX] = {0};
|
2021-06-10 15:28:45 +08:00
|
|
|
struct tfe_cmsg *cmsg = tfe_stream_get0_cmsg(stream);
|
|
|
|
|
if (cmsg != NULL)
|
|
|
|
|
{
|
|
|
|
|
ret = tfe_cmsg_get_value(cmsg, TFE_CMSG_SRC_SUB_ID, (unsigned char *)source_subscribe_id, sizeof(source_subscribe_id), &opt_out_size);
|
|
|
|
|
if (ret != 0)
|
|
|
|
|
{
|
2022-09-09 10:44:11 +08:00
|
|
|
TFE_LOG_ERROR(g_proxy_rt->local_logger, "fetch src sub id from cmsg failed, ret: %d addr: %s", ret, stream->str_stream_info);
|
2021-06-10 15:28:45 +08:00
|
|
|
}
|
|
|
|
|
}
|
2022-05-20 17:14:01 +08:00
|
|
|
if(strlen(source_subscribe_id) > 0)
|
|
|
|
|
{
|
|
|
|
|
snprintf(replace_regex, TFE_SYMBOL_MAX, "%s", source_subscribe_id);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
snprintf(replace_regex, TFE_SYMBOL_MAX, "%s", " ");
|
|
|
|
|
}
|
2021-06-10 15:28:45 +08:00
|
|
|
}
|
|
|
|
|
|
2024-09-29 20:01:49 +08:00
|
|
|
static int http_regex_replace(const struct tfe_stream * stream, char *message, char *profile_id_str, char **rewrite_message)
|
2021-06-10 15:28:45 +08:00
|
|
|
{
|
|
|
|
|
int i=0, n_rule=0;
|
|
|
|
|
char replace_with[TFE_SYMBOL_MAX]={0};
|
2022-05-20 17:14:01 +08:00
|
|
|
|
|
|
|
|
struct replace_rule rule[3];
|
|
|
|
|
memset(rule, 0, sizeof(struct replace_rule));
|
2021-06-10 15:28:45 +08:00
|
|
|
|
2022-04-19 14:31:54 +08:00
|
|
|
if(message == NULL)
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2024-11-07 16:13:55 +08:00
|
|
|
if(strcasestr(message,"{{tsg_policy_uuid}}") != NULL)
|
2021-06-10 15:28:45 +08:00
|
|
|
{
|
2022-05-20 17:14:01 +08:00
|
|
|
rule[n_rule].zone = kZoneRequestUri;
|
2024-11-07 16:13:55 +08:00
|
|
|
rule[n_rule].find = tfe_strdup("{{tsg_policy_uuid}}");
|
2024-09-29 20:01:49 +08:00
|
|
|
snprintf(replace_with, TFE_SYMBOL_MAX, "%s", profile_id_str);
|
2022-05-20 17:14:01 +08:00
|
|
|
rule[n_rule].replace_with = tfe_strdup(replace_with);
|
|
|
|
|
n_rule++;
|
|
|
|
|
}
|
|
|
|
|
if(strcasestr(message,"tsg_subscriber_id") != NULL)
|
|
|
|
|
{
|
2023-08-02 16:55:56 +08:00
|
|
|
memset(replace_with, 0, TFE_SYMBOL_MAX);
|
2022-05-20 17:14:01 +08:00
|
|
|
rule[n_rule].zone = kZoneRequestUri;
|
|
|
|
|
rule[n_rule].find = tfe_strdup("{{tsg_subscriber_id}}");
|
|
|
|
|
http_get_subscriber_id(stream, replace_with);
|
|
|
|
|
rule[n_rule].replace_with = tfe_strdup(replace_with);
|
|
|
|
|
n_rule++;
|
|
|
|
|
}
|
|
|
|
|
if(strcasestr(message,"tsg_client_ip") != NULL)
|
|
|
|
|
{
|
2023-08-02 16:55:56 +08:00
|
|
|
memset(replace_with, 0, TFE_SYMBOL_MAX);
|
2022-05-20 17:14:01 +08:00
|
|
|
rule[n_rule].zone = kZoneRequestUri;
|
|
|
|
|
rule[n_rule].find = tfe_strdup("{{tsg_client_ip}}");
|
|
|
|
|
http_get_client_id(stream, replace_with);
|
|
|
|
|
rule[n_rule].replace_with = tfe_strdup(replace_with);
|
|
|
|
|
n_rule++;
|
2021-06-10 15:28:45 +08:00
|
|
|
}
|
|
|
|
|
|
2022-05-20 17:14:01 +08:00
|
|
|
size_t rewrite_uri_sz = execute_replace_rule(message, strlen(message), kZoneRequestUri, rule, n_rule, rewrite_message, 1);
|
2021-06-10 15:28:45 +08:00
|
|
|
|
2022-05-20 17:14:01 +08:00
|
|
|
for(i=0; i<n_rule; i++)
|
2021-06-10 15:28:45 +08:00
|
|
|
{
|
|
|
|
|
FREE(&(rule[i].find));
|
|
|
|
|
FREE(&(rule[i].replace_with));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return rewrite_uri_sz;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void http_redirect(const struct tfe_stream * stream, const struct tfe_http_session * session, enum tfe_http_event events,
|
2022-09-09 10:44:11 +08:00
|
|
|
struct proxy_http_ctx * ctx)
|
2018-09-23 20:02:07 +08:00
|
|
|
{
|
|
|
|
|
struct tfe_http_half * response = NULL;
|
|
|
|
|
struct tfe_http_session * to_write = NULL;
|
2021-06-10 15:28:45 +08:00
|
|
|
size_t rewrite_uri_sz=0; char *rewrite_uri=NULL;
|
2018-09-25 10:17:50 +08:00
|
|
|
|
2019-05-28 14:59:39 +08:00
|
|
|
struct policy_action_param *param = ctx->param;
|
2018-09-25 10:17:50 +08:00
|
|
|
|
2019-05-21 19:15:37 +08:00
|
|
|
int resp_code = param->status_code;
|
|
|
|
|
char *rd_url = param->message;
|
|
|
|
|
|
2020-04-29 14:00:13 +08:00
|
|
|
int ratio = http_enforcement_ratio(param->enforcement_ratio);
|
|
|
|
|
if (ratio != 1)
|
|
|
|
|
{
|
2022-09-09 10:44:11 +08:00
|
|
|
TFE_LOG_DEBUG(g_proxy_rt->local_logger, "enforcement ratio:%f", param->enforcement_ratio);
|
|
|
|
|
ctx->action = PX_ACTION_NONE;
|
2020-04-29 14:00:13 +08:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
ctx->manipulate_replaced = 1;
|
2019-05-21 19:15:37 +08:00
|
|
|
if (resp_code <= 0 || rd_url == NULL){
|
2024-09-29 20:01:49 +08:00
|
|
|
TFE_LOG_ERROR(g_proxy_rt->local_logger, "Invalid redirect rule %s paramter", ctx->enforce_rules[0].config_uuid_string);
|
2018-09-12 16:04:04 +08:00
|
|
|
goto error_out;
|
|
|
|
|
}
|
2019-06-22 17:44:52 +08:00
|
|
|
|
|
|
|
|
if ((events & EV_HTTP_RESP_BODY_BEGIN) || (events & EV_HTTP_RESP_BODY_CONT)
|
|
|
|
|
|| (events & EV_HTTP_RESP_BODY_END) || (events & EV_HTTP_RESP_END))
|
|
|
|
|
{
|
2022-09-09 10:44:11 +08:00
|
|
|
ctx->action = PX_ACTION_NONE;
|
2019-06-22 17:44:52 +08:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2018-09-23 20:02:07 +08:00
|
|
|
to_write = tfe_http_session_allow_write(session);
|
2018-09-25 10:17:50 +08:00
|
|
|
if (to_write == NULL)
|
|
|
|
|
{
|
|
|
|
|
assert(0);
|
|
|
|
|
}
|
2021-01-12 16:17:18 +08:00
|
|
|
|
2022-09-09 10:44:11 +08:00
|
|
|
ATOMIC_INC(&(g_proxy_rt->stat_val[STAT_ACTION_REDIRECT]));
|
2018-09-25 10:17:50 +08:00
|
|
|
|
2021-02-23 09:33:27 +08:00
|
|
|
response = tfe_http_session_response_create(to_write, resp_code);
|
2021-06-10 15:28:45 +08:00
|
|
|
|
2024-09-29 20:01:49 +08:00
|
|
|
rewrite_uri_sz = http_regex_replace(stream, rd_url, ctx->enforce_rules[0].config_uuid_string, &rewrite_uri);
|
2021-06-10 15:28:45 +08:00
|
|
|
if(rewrite_uri_sz>0 && rewrite_uri!= NULL)
|
|
|
|
|
{
|
|
|
|
|
tfe_http_std_field_write(response, TFE_HTTP_LOCATION, rewrite_uri);
|
|
|
|
|
FREE(&rewrite_uri);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
tfe_http_std_field_write(response, TFE_HTTP_LOCATION, rd_url);
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-10 15:48:22 +06:00
|
|
|
tfe_http_std_field_write(response, TFE_HTTP_CONT_LENGTH, "0");
|
2018-09-25 20:32:24 +08:00
|
|
|
tfe_http_half_append_body(response, NULL, 0, 0);
|
2018-09-25 10:17:50 +08:00
|
|
|
|
2018-09-13 19:28:13 +08:00
|
|
|
tfe_http_session_response_set(to_write, response);
|
2018-09-25 10:17:50 +08:00
|
|
|
tfe_http_session_detach(session);
|
2018-09-23 20:02:07 +08:00
|
|
|
|
2018-09-12 16:04:04 +08:00
|
|
|
error_out:
|
2019-05-21 19:15:37 +08:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-15 16:20:52 +08:00
|
|
|
static void http_block(const struct tfe_stream * stream, const struct tfe_http_session * session, enum tfe_http_event events,
|
2022-09-09 10:44:11 +08:00
|
|
|
struct proxy_http_ctx * ctx)
|
2019-05-21 19:15:37 +08:00
|
|
|
{
|
|
|
|
|
int ret = -1;
|
|
|
|
|
struct tfe_http_half * response = NULL;
|
2022-04-15 16:20:52 +08:00
|
|
|
char * page_buff = NULL; size_t page_size = 0;
|
|
|
|
|
size_t rewrite_message_sz=0; char *rewrite_message=NULL;
|
2019-05-21 19:15:37 +08:00
|
|
|
|
|
|
|
|
char cont_len_str[16];
|
|
|
|
|
|
2019-05-28 14:59:39 +08:00
|
|
|
struct policy_action_param *param = ctx->param;
|
2019-05-21 19:15:37 +08:00
|
|
|
|
|
|
|
|
int resp_code = param->status_code;
|
|
|
|
|
char *message = param->message;
|
|
|
|
|
|
|
|
|
|
struct tfe_http_session * to_write_sess = NULL;
|
2020-04-29 14:00:13 +08:00
|
|
|
if (events & EV_HTTP_RESP_HDR || tfe_http_in_hdr(events))
|
2019-05-21 19:15:37 +08:00
|
|
|
{
|
|
|
|
|
to_write_sess = tfe_http_session_allow_write(session);
|
|
|
|
|
response = tfe_http_session_response_create(to_write_sess, resp_code);
|
|
|
|
|
|
2024-09-29 20:01:49 +08:00
|
|
|
ret = html_generate(param->profile_uuid_str, message, &page_buff, &page_size);
|
2019-05-21 19:15:37 +08:00
|
|
|
if (ret != 0)
|
|
|
|
|
{
|
2024-09-29 20:01:49 +08:00
|
|
|
rewrite_message_sz = http_regex_replace(stream, message, ctx->enforce_rules[0].config_uuid_string, &rewrite_message);
|
2022-04-15 16:20:52 +08:00
|
|
|
if(rewrite_message_sz>0 && rewrite_message!= NULL)
|
|
|
|
|
{
|
2022-04-19 14:31:54 +08:00
|
|
|
message = rewrite_message;
|
2022-04-15 16:20:52 +08:00
|
|
|
}
|
2022-05-20 17:14:01 +08:00
|
|
|
|
2022-04-19 14:31:54 +08:00
|
|
|
/*read local configuration**/
|
2022-04-28 14:03:47 +08:00
|
|
|
template_generate(resp_code, message, &page_buff, &page_size);
|
2022-04-19 14:31:54 +08:00
|
|
|
if(rewrite_message_sz>0 && rewrite_message!= NULL)
|
2022-04-15 16:20:52 +08:00
|
|
|
{
|
2022-04-19 14:31:54 +08:00
|
|
|
FREE(&rewrite_message);
|
2022-04-15 16:20:52 +08:00
|
|
|
}
|
2019-05-21 19:15:37 +08:00
|
|
|
}
|
|
|
|
|
tfe_http_std_field_write(response, TFE_HTTP_CONT_TYPE, "text/html; charset=utf-8");
|
|
|
|
|
snprintf(cont_len_str, sizeof(cont_len_str), "%lu", page_size);
|
|
|
|
|
tfe_http_std_field_write(response, TFE_HTTP_CONT_LENGTH, cont_len_str);
|
|
|
|
|
|
2022-09-09 10:44:11 +08:00
|
|
|
ATOMIC_INC(&(g_proxy_rt->stat_val[STAT_ACTION_REJECT]));
|
2019-05-21 19:15:37 +08:00
|
|
|
tfe_http_half_append_body(response, page_buff, page_size, 0);
|
|
|
|
|
tfe_http_half_append_body(response, NULL, 0, 0);
|
|
|
|
|
tfe_http_session_response_set(to_write_sess, response);
|
|
|
|
|
tfe_http_session_detach(session);
|
|
|
|
|
html_free(&page_buff);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2022-09-09 10:44:11 +08:00
|
|
|
ATOMIC_INC(&(g_proxy_rt->stat_val[STAT_ACTION_REJECT]));
|
2019-05-21 19:15:37 +08:00
|
|
|
to_write_sess = tfe_http_session_allow_write(session);
|
|
|
|
|
tfe_http_session_kill(to_write_sess);
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void http_hijack(const struct tfe_http_session * session, enum tfe_http_event events,
|
2022-09-09 10:44:11 +08:00
|
|
|
struct proxy_http_ctx * ctx)
|
2019-05-21 19:15:37 +08:00
|
|
|
{
|
2019-05-28 14:59:39 +08:00
|
|
|
struct policy_action_param *param = ctx->param;
|
|
|
|
|
struct tfe_http_half * response = NULL;
|
2019-09-05 16:45:26 +08:00
|
|
|
struct tfe_http_session * to_write_sess = NULL;
|
2019-05-21 19:15:37 +08:00
|
|
|
|
2024-09-29 20:01:49 +08:00
|
|
|
if (param->profile_uuid_str == NULL)
|
2019-05-28 14:59:39 +08:00
|
|
|
{
|
2024-09-29 20:01:49 +08:00
|
|
|
TFE_LOG_ERROR(g_proxy_rt->local_logger, "Invalid hijack rule %s", ctx->enforce_rules[0].config_uuid_string);
|
2022-09-09 10:44:11 +08:00
|
|
|
ctx->action = PX_ACTION_NONE;
|
2019-05-21 19:15:37 +08:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-29 14:00:13 +08:00
|
|
|
if (http_enforcement_ratio(param->enforcement_ratio) != 1)
|
|
|
|
|
{
|
2022-09-09 10:44:11 +08:00
|
|
|
TFE_LOG_DEBUG(g_proxy_rt->local_logger, "enforcement ratio:%f", param->enforcement_ratio);
|
|
|
|
|
ctx->action = PX_ACTION_NONE;
|
2020-04-29 14:00:13 +08:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
ctx->manipulate_replaced = 1;
|
2019-09-05 16:45:26 +08:00
|
|
|
if (tfe_http_in_request(events))
|
2019-11-19 10:02:51 +08:00
|
|
|
{
|
2019-05-28 14:59:39 +08:00
|
|
|
return;
|
|
|
|
|
}
|
2019-05-21 19:15:37 +08:00
|
|
|
|
2019-09-05 16:45:26 +08:00
|
|
|
if(events & EV_HTTP_RESP_HDR)
|
|
|
|
|
{
|
2024-10-25 17:00:57 +08:00
|
|
|
struct manipulate_profile* hijack_profile=get_profile_by_id("PROXY_REPLACEMENT_FILE", param->profile_uuid_str);
|
2019-09-05 16:45:26 +08:00
|
|
|
if (NULL == hijack_profile)
|
|
|
|
|
{
|
2024-09-29 20:01:49 +08:00
|
|
|
TFE_LOG_ERROR(g_proxy_rt->local_logger, "get table obj faild, profile_id = %s", param->profile_uuid_str);
|
2022-09-09 10:44:11 +08:00
|
|
|
ctx->action = PX_ACTION_NONE;
|
2019-09-05 16:45:26 +08:00
|
|
|
return;
|
|
|
|
|
}
|
2019-06-03 15:12:59 +08:00
|
|
|
|
2019-09-05 16:45:26 +08:00
|
|
|
char * hijack_buff=NULL; size_t hijack_size=0;
|
2019-06-03 15:12:59 +08:00
|
|
|
|
2020-05-21 17:15:40 +08:00
|
|
|
hijack_buff = tfe_read_file(hijack_profile->profile_msg, &hijack_size);
|
2019-09-05 16:45:26 +08:00
|
|
|
if (NULL == hijack_buff){
|
2022-09-09 10:44:11 +08:00
|
|
|
TFE_LOG_ERROR(g_proxy_rt->local_logger, "read hijack file faild, path = %s", hijack_profile->profile_msg);
|
|
|
|
|
ctx->action = PX_ACTION_NONE;
|
2019-09-05 16:45:26 +08:00
|
|
|
return;
|
|
|
|
|
}
|
2020-06-04 20:22:31 +08:00
|
|
|
if (try_send_by_token(hijack_size) <= 0)
|
|
|
|
|
{
|
2020-09-25 10:11:41 +08:00
|
|
|
FREE(&hijack_buff);
|
2024-09-29 20:01:49 +08:00
|
|
|
TFE_LOG_ERROR(g_proxy_rt->local_logger, "No token is available to send data, profile_id = %s", param->profile_uuid_str);
|
2022-09-09 10:44:11 +08:00
|
|
|
ctx->action = PX_ACTION_NONE;
|
2020-06-04 20:22:31 +08:00
|
|
|
return;
|
|
|
|
|
}
|
2020-04-03 16:16:07 +08:00
|
|
|
ctx->inject_sz = hijack_size;
|
2022-09-09 10:44:11 +08:00
|
|
|
ATOMIC_ADD(&(g_proxy_rt->stat_val[STAT_ACTION_HIJACK_SZ]), hijack_size);
|
|
|
|
|
ATOMIC_INC(&(g_proxy_rt->stat_val[STAT_ACTION_HIJACK]));
|
2019-05-28 14:59:39 +08:00
|
|
|
|
2021-01-12 16:17:18 +08:00
|
|
|
char cont_len_str[16];
|
2019-09-05 16:45:26 +08:00
|
|
|
to_write_sess = tfe_http_session_allow_write(session);
|
|
|
|
|
response = tfe_http_session_response_create(to_write_sess, 200);
|
2019-06-03 15:12:59 +08:00
|
|
|
|
2019-09-05 16:45:26 +08:00
|
|
|
if (0!=strcasecmp(hijack_profile->profile_name, "null"))
|
|
|
|
|
{
|
|
|
|
|
int hijack_file_len = strlen(hijack_profile->profile_name)+strlen("filename=\"\"")+1;
|
|
|
|
|
char *hijack_file_name = ALLOC(char, hijack_file_len);
|
|
|
|
|
snprintf(hijack_file_name, hijack_file_len, "filename=\"%s\"", hijack_profile->profile_name);
|
|
|
|
|
tfe_http_nonstd_field_write(response, "Content-Disposition", hijack_file_name);
|
|
|
|
|
FREE(&hijack_file_name);
|
|
|
|
|
}
|
2020-07-10 16:48:29 +08:00
|
|
|
|
2019-09-05 16:45:26 +08:00
|
|
|
const char* cont_disposition_val=tfe_http_std_field_read(to_write_sess->resp, TFE_HTTP_CONT_DISPOSITION);
|
|
|
|
|
if (cont_disposition_val != NULL)
|
2019-11-19 10:02:51 +08:00
|
|
|
{
|
2019-09-05 16:45:26 +08:00
|
|
|
tfe_http_std_field_write(response, TFE_HTTP_CONT_DISPOSITION, cont_disposition_val);
|
2019-11-19 10:02:51 +08:00
|
|
|
}
|
2019-09-05 16:45:26 +08:00
|
|
|
tfe_http_std_field_write(response, TFE_HTTP_CONT_TYPE, hijack_profile->profile_type);
|
|
|
|
|
snprintf(cont_len_str, sizeof(cont_len_str), "%lu", hijack_size);
|
|
|
|
|
tfe_http_std_field_write(response, TFE_HTTP_CONT_LENGTH, cont_len_str);
|
2019-05-28 14:59:39 +08:00
|
|
|
|
2019-09-05 16:45:26 +08:00
|
|
|
tfe_http_half_append_body(response, hijack_buff, hijack_size, 0);
|
|
|
|
|
tfe_http_half_append_body(response, NULL, 0, 0);
|
|
|
|
|
tfe_http_session_response_set(to_write_sess, response);
|
|
|
|
|
tfe_http_session_detach(session);
|
|
|
|
|
ma_profile_table_free(hijack_profile);
|
2020-09-25 10:11:41 +08:00
|
|
|
FREE(&hijack_buff);
|
2019-09-05 16:45:26 +08:00
|
|
|
hijack_profile = NULL;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
to_write_sess = tfe_http_session_allow_write(session);
|
|
|
|
|
tfe_http_session_kill(to_write_sess);
|
|
|
|
|
}
|
2019-05-21 19:15:37 +08:00
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2024-10-25 17:00:57 +08:00
|
|
|
static int format_insert_rule(char *profile_uuid, char *position, enum manipulate_action action, struct insert_rule *rule)
|
2019-05-21 19:15:37 +08:00
|
|
|
{
|
|
|
|
|
int ret = 0;
|
|
|
|
|
|
2024-10-22 15:29:12 +08:00
|
|
|
if(profile_uuid == NULL)
|
|
|
|
|
{
|
|
|
|
|
ret=-1;
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
2024-10-25 17:00:57 +08:00
|
|
|
const char *profile_type = (action==MA_ACTION_INJECT_JAVESCRIPT)? "js" : "css";
|
|
|
|
|
const char *proflie_table_name = (action==MA_ACTION_INJECT_JAVESCRIPT)? "PROXY_JS_FILE" : "PROXY_CSS_FILE";
|
|
|
|
|
struct manipulate_profile* insert_profile=get_profile_by_id(proflie_table_name, profile_uuid);
|
2019-05-28 14:59:39 +08:00
|
|
|
if(insert_profile==NULL)
|
2019-05-21 19:15:37 +08:00
|
|
|
{
|
|
|
|
|
ret=-1;
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
2019-05-28 14:59:39 +08:00
|
|
|
rule->script = tfe_strdup(insert_profile->profile_msg);
|
2024-10-25 17:00:57 +08:00
|
|
|
rule->type = tfe_strdup(profile_type);
|
|
|
|
|
if(position)
|
|
|
|
|
{
|
|
|
|
|
rule->position = tfe_strdup(position);
|
|
|
|
|
}
|
2020-04-03 16:16:07 +08:00
|
|
|
rule->inject_sz = insert_profile->msg_len;
|
2019-05-21 19:15:37 +08:00
|
|
|
|
2019-05-28 17:38:19 +08:00
|
|
|
ma_profile_table_free(insert_profile);
|
|
|
|
|
insert_profile = NULL;
|
2019-05-21 19:15:37 +08:00
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void http_insert(const struct tfe_stream * stream, const struct tfe_http_session * session, enum tfe_http_event events,
|
2024-10-25 17:00:57 +08:00
|
|
|
const unsigned char * body_frag, size_t frag_size, enum manipulate_action action, struct proxy_http_ctx * ctx)
|
2019-05-21 19:15:37 +08:00
|
|
|
{
|
|
|
|
|
struct tfe_http_session * to_write_sess = NULL;
|
|
|
|
|
char * rewrite_buff = NULL;
|
|
|
|
|
size_t rewrite_sz = 0;
|
|
|
|
|
|
2019-05-28 14:59:39 +08:00
|
|
|
struct policy_action_param *param = ctx->param;
|
2020-04-29 14:00:13 +08:00
|
|
|
int ratio = http_enforcement_ratio(param->enforcement_ratio);
|
|
|
|
|
if (ratio != 1)
|
|
|
|
|
{
|
2022-09-09 10:44:11 +08:00
|
|
|
TFE_LOG_DEBUG(g_proxy_rt->local_logger, "enforcement ratio:%f", param->enforcement_ratio);
|
|
|
|
|
ctx->action = PX_ACTION_NONE;
|
2020-04-29 14:00:13 +08:00
|
|
|
return;
|
|
|
|
|
}
|
2019-05-21 19:15:37 +08:00
|
|
|
to_write_sess = tfe_http_session_allow_write(session);
|
|
|
|
|
if (to_write_sess == NULL) //fail to wirte, abandon.
|
|
|
|
|
{
|
|
|
|
|
TFE_STREAM_LOG_INFO(stream, "tfe_http_session_allow_write() %s failed.", session->req->req_spec.uri);
|
2022-09-09 10:44:11 +08:00
|
|
|
ctx->action = PX_ACTION_NONE;
|
2019-05-21 19:15:37 +08:00
|
|
|
tfe_http_session_detach(session); return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct insert_ctx *ins_ctx = ctx->ins_ctx;
|
|
|
|
|
if (ctx->ins_ctx == NULL)
|
|
|
|
|
{
|
2019-05-28 14:59:39 +08:00
|
|
|
/* we must determinate the replace action on HTTP header, otherwise,
|
|
|
|
|
* the header has been forwarded, only replace the body but not modify header will raise exception */
|
2019-05-21 19:15:37 +08:00
|
|
|
if ((events & EV_HTTP_REQ_HDR) || (events & EV_HTTP_RESP_HDR))
|
|
|
|
|
{
|
|
|
|
|
ctx->ins_ctx = ins_ctx = ALLOC(struct insert_ctx, 1);
|
|
|
|
|
ins_ctx->rule = ALLOC(struct insert_rule, 1);
|
2024-10-25 17:00:57 +08:00
|
|
|
int ret=format_insert_rule(param->profile_uuid_str, param->position, action, ins_ctx->rule);
|
2019-05-21 19:15:37 +08:00
|
|
|
if (ret<0)
|
|
|
|
|
{
|
2024-09-29 20:01:49 +08:00
|
|
|
TFE_LOG_ERROR(g_proxy_rt->local_logger, "Failed to get policy table, profile_id = %s", param->profile_uuid_str);
|
2022-09-09 10:44:11 +08:00
|
|
|
ctx->action = PX_ACTION_NONE;
|
2019-05-21 19:15:37 +08:00
|
|
|
return;
|
|
|
|
|
}
|
2020-06-04 20:22:31 +08:00
|
|
|
if (try_send_by_token(ins_ctx->rule->inject_sz) <= 0)
|
|
|
|
|
{
|
2024-09-29 20:01:49 +08:00
|
|
|
TFE_LOG_ERROR(g_proxy_rt->local_logger, "No token is available to send data, profile_id = %s", param->profile_uuid_str);
|
2022-09-09 10:44:11 +08:00
|
|
|
ctx->action = PX_ACTION_NONE;
|
2020-06-04 20:22:31 +08:00
|
|
|
return;
|
|
|
|
|
}
|
2020-04-03 16:16:07 +08:00
|
|
|
ctx->inject_sz = ins_ctx->rule->inject_sz;
|
2019-05-21 19:15:37 +08:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2021-12-06 18:14:10 +08:00
|
|
|
TFE_STREAM_LOG_INFO(stream, "Can only setup insert on REQ/RESP headers, detached.");
|
2022-09-09 10:44:11 +08:00
|
|
|
ctx->action = PX_ACTION_NONE;
|
2019-05-21 19:15:37 +08:00
|
|
|
tfe_http_session_detach(session); return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct tfe_http_half * in_req_half = session->req;
|
|
|
|
|
struct tfe_http_half * in_resp_half = session->resp;
|
|
|
|
|
struct tfe_http_req_spec * in_req_spec = &in_req_half->req_spec;
|
|
|
|
|
struct tfe_http_resp_spec * in_resp_spec = &in_resp_half->resp_spec;
|
|
|
|
|
|
|
|
|
|
if ((events & EV_HTTP_REQ_HDR) || (events & EV_HTTP_RESP_HDR))
|
|
|
|
|
{
|
|
|
|
|
if (tfe_http_in_request(events))
|
|
|
|
|
{
|
|
|
|
|
ins_ctx->replacing = tfe_http_session_request_create(to_write_sess, in_req_spec->method, in_req_spec->uri);
|
|
|
|
|
tfe_http_session_request_set(to_write_sess, ins_ctx->replacing);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
ins_ctx->replacing = tfe_http_session_response_create(to_write_sess, in_resp_spec->resp_code);
|
|
|
|
|
tfe_http_session_response_set(to_write_sess, ins_ctx->replacing);
|
|
|
|
|
}
|
|
|
|
|
struct tfe_http_half * in_half = tfe_http_in_request(events) ? in_req_half : in_resp_half;
|
|
|
|
|
|
|
|
|
|
struct http_field_name in_header_field{};
|
|
|
|
|
const char * in_header_value = NULL;
|
|
|
|
|
void * iterator = NULL;
|
|
|
|
|
|
|
|
|
|
while (true)
|
|
|
|
|
{
|
|
|
|
|
if ((in_header_value = tfe_http_field_iterate(in_half, &iterator, &in_header_field)) == NULL)
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
tfe_http_field_write(ins_ctx->replacing, &in_header_field, in_header_value);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((events & EV_HTTP_REQ_BODY_BEGIN) || (events & EV_HTTP_RESP_BODY_BEGIN))
|
|
|
|
|
{
|
|
|
|
|
assert(ins_ctx->http_body == NULL);
|
|
|
|
|
ins_ctx->http_body = evbuffer_new();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((events & EV_HTTP_REQ_BODY_CONT) || (events & EV_HTTP_RESP_BODY_CONT))
|
|
|
|
|
{
|
|
|
|
|
evbuffer_add(ins_ctx->http_body, body_frag, frag_size);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((events & EV_HTTP_REQ_BODY_END) || (events & EV_HTTP_RESP_BODY_END))
|
|
|
|
|
{
|
2019-05-28 14:59:39 +08:00
|
|
|
char * http_body = (char *) evbuffer_pullup(ins_ctx->http_body, -1);
|
|
|
|
|
size_t http_body_len = evbuffer_get_length(ins_ctx->http_body);
|
|
|
|
|
const char* cont_type_val=tfe_http_std_field_read(ins_ctx->replacing, TFE_HTTP_CONT_TYPE);
|
2019-05-21 19:15:37 +08:00
|
|
|
|
|
|
|
|
rewrite_buff = NULL;
|
|
|
|
|
rewrite_sz = 0;
|
|
|
|
|
|
2019-06-11 11:25:24 +08:00
|
|
|
if (cont_type_val != NULL && strstr(cont_type_val, "text/html") != NULL)
|
2019-06-10 17:20:05 +08:00
|
|
|
{
|
|
|
|
|
rewrite_sz = execute_insert_rule(http_body, http_body_len, ins_ctx->rule, &rewrite_buff);
|
|
|
|
|
}
|
|
|
|
|
if (rewrite_sz >0)
|
2019-05-21 19:15:37 +08:00
|
|
|
{
|
|
|
|
|
tfe_http_half_append_body(ins_ctx->replacing, rewrite_buff, rewrite_sz, 0);
|
2022-09-09 10:44:11 +08:00
|
|
|
ATOMIC_INC(&(g_proxy_rt->stat_val[STAT_ACTION_INSERT]));
|
|
|
|
|
ATOMIC_ADD(&(g_proxy_rt->stat_val[STAT_ACTION_INSERT_SZ]), ctx->inject_sz);
|
2020-09-25 10:11:41 +08:00
|
|
|
ins_ctx->actually_inserted=1;
|
2019-05-21 19:15:37 +08:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2019-05-28 14:59:39 +08:00
|
|
|
tfe_http_half_append_body(ins_ctx->replacing, http_body, http_body_len, 0);
|
2019-05-21 19:15:37 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (rewrite_buff != NULL)
|
|
|
|
|
{
|
|
|
|
|
FREE(&rewrite_buff);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ins_ctx->http_body != NULL)
|
|
|
|
|
{
|
|
|
|
|
evbuffer_free(ins_ctx->http_body);
|
|
|
|
|
ins_ctx->http_body = NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((events & EV_HTTP_REQ_END) || (events & EV_HTTP_RESP_END))
|
|
|
|
|
{
|
|
|
|
|
tfe_http_half_append_body(ins_ctx->replacing, NULL, 0, 0);
|
|
|
|
|
ins_ctx->replacing = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-06 18:14:10 +08:00
|
|
|
void http_element(const struct tfe_stream * stream, const struct tfe_http_session * session, enum tfe_http_event events,
|
2022-09-09 10:44:11 +08:00
|
|
|
const unsigned char * body_frag, size_t frag_size, struct proxy_http_ctx * ctx)
|
2021-12-06 18:14:10 +08:00
|
|
|
{
|
|
|
|
|
struct tfe_http_session * to_write_sess = NULL;
|
|
|
|
|
char * rewrite_buff = NULL;
|
|
|
|
|
size_t rewrite_sz = 0;
|
|
|
|
|
|
|
|
|
|
if (tfe_http_in_request(events))
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
to_write_sess = tfe_http_session_allow_write(session);
|
|
|
|
|
if (to_write_sess == NULL)
|
|
|
|
|
{
|
|
|
|
|
TFE_STREAM_LOG_INFO(stream, "tfe_http_session_allow_write() %s failed.", session->req->req_spec.uri);
|
2022-09-09 10:44:11 +08:00
|
|
|
ctx->action = PX_ACTION_NONE;
|
2021-12-06 18:14:10 +08:00
|
|
|
tfe_http_session_detach(session); return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct edit_element_ctx * edit_ctx = ctx->edit_ctx;
|
|
|
|
|
if (ctx->edit_ctx == NULL)
|
|
|
|
|
{
|
|
|
|
|
if (events & EV_HTTP_RESP_HDR)
|
|
|
|
|
{
|
|
|
|
|
struct policy_action_param *param = ctx->param;
|
|
|
|
|
ctx->edit_ctx = edit_ctx = ALLOC(struct edit_element_ctx, 1);
|
|
|
|
|
edit_ctx->item = param->elem_rule;
|
|
|
|
|
edit_ctx->n_item = param->e_rule;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
TFE_STREAM_LOG_INFO(stream, "Can only setup editing on RESP headers, detached.");
|
2022-09-09 10:44:11 +08:00
|
|
|
ctx->action = PX_ACTION_NONE;
|
2021-12-06 18:14:10 +08:00
|
|
|
tfe_http_session_detach(session); return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct tfe_http_half * in_resp_half = session->resp;
|
|
|
|
|
struct tfe_http_resp_spec * in_resp_spec = &in_resp_half->resp_spec;
|
|
|
|
|
|
|
|
|
|
if (events & EV_HTTP_RESP_HDR)
|
|
|
|
|
{
|
|
|
|
|
edit_ctx->editing= tfe_http_session_response_create(to_write_sess, in_resp_spec->resp_code);
|
|
|
|
|
tfe_http_session_response_set(to_write_sess, edit_ctx->editing);
|
|
|
|
|
struct tfe_http_half * in_half = in_resp_half;
|
|
|
|
|
|
|
|
|
|
struct http_field_name in_header_field{};
|
|
|
|
|
const char * in_header_value = NULL;
|
|
|
|
|
void * iterator = NULL;
|
|
|
|
|
|
|
|
|
|
while (true)
|
|
|
|
|
{
|
|
|
|
|
if ((in_header_value = tfe_http_field_iterate(in_half, &iterator, &in_header_field)) == NULL)
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
tfe_http_field_write(edit_ctx->editing, &in_header_field, in_header_value);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (events & EV_HTTP_RESP_BODY_BEGIN)
|
|
|
|
|
{
|
|
|
|
|
assert(edit_ctx->http_body == NULL);
|
|
|
|
|
edit_ctx->http_body = evbuffer_new();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (events & EV_HTTP_RESP_BODY_CONT)
|
|
|
|
|
{
|
|
|
|
|
evbuffer_add(edit_ctx->http_body, body_frag, frag_size);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (events & EV_HTTP_RESP_BODY_END)
|
|
|
|
|
{
|
|
|
|
|
char * __http_body = (char *) evbuffer_pullup(edit_ctx->http_body, -1);
|
|
|
|
|
size_t __http_body_len = evbuffer_get_length(edit_ctx->http_body);
|
|
|
|
|
|
|
|
|
|
rewrite_buff = NULL;
|
|
|
|
|
rewrite_sz = 0;
|
|
|
|
|
|
|
|
|
|
if(in_resp_spec->content_type != NULL && strcasestr(in_resp_spec->content_type, "text/html"))
|
|
|
|
|
{
|
|
|
|
|
rewrite_sz = execute_edit_element_rule(__http_body, __http_body_len, edit_ctx->item, edit_ctx->n_item, &rewrite_buff, 0);
|
|
|
|
|
}
|
2021-12-13 15:59:59 +08:00
|
|
|
if(in_resp_spec->content_type != NULL && (strcasestr(in_resp_spec->content_type, "json") || strcasestr(in_resp_spec->content_type, "text/javascript")))
|
2021-12-06 18:14:10 +08:00
|
|
|
{
|
|
|
|
|
rewrite_sz = execute_edit_element_rule(__http_body, __http_body_len, edit_ctx->item, edit_ctx->n_item, &rewrite_buff, 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (rewrite_sz >0 )
|
|
|
|
|
{
|
|
|
|
|
tfe_http_half_append_body(edit_ctx->editing, rewrite_buff, rewrite_sz, 0);
|
2022-09-09 10:44:11 +08:00
|
|
|
ATOMIC_INC(&(g_proxy_rt->stat_val[STAT_ACTION_EDIT_ELEMENT]));
|
2021-12-06 18:14:10 +08:00
|
|
|
edit_ctx->actually_edited=1;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
tfe_http_half_append_body(edit_ctx->editing, __http_body, __http_body_len, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (rewrite_buff != NULL)
|
|
|
|
|
{
|
|
|
|
|
FREE(&rewrite_buff);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (edit_ctx->http_body != NULL)
|
|
|
|
|
{
|
|
|
|
|
evbuffer_free(edit_ctx->http_body);
|
|
|
|
|
edit_ctx->http_body = NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (events & EV_HTTP_RESP_END)
|
|
|
|
|
{
|
|
|
|
|
tfe_http_half_append_body(edit_ctx->editing, NULL, 0, 0);
|
|
|
|
|
edit_ctx->editing = NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-21 19:15:37 +08:00
|
|
|
static void http_manipulate(const struct tfe_stream * stream, const struct tfe_http_session * session,
|
2022-09-09 10:44:11 +08:00
|
|
|
enum tfe_http_event events, const unsigned char * body_frag, size_t frag_size, struct proxy_http_ctx * ctx)
|
2019-05-21 19:15:37 +08:00
|
|
|
{
|
2019-05-28 14:59:39 +08:00
|
|
|
struct policy_action_param *param = ctx->param;
|
2019-05-21 19:15:37 +08:00
|
|
|
if (param == NULL)
|
|
|
|
|
{
|
2024-09-29 20:01:49 +08:00
|
|
|
TFE_LOG_ERROR(g_proxy_rt->local_logger, "Failed to get the json format parsed. config_id = %s",ctx->enforce_rules[0].config_uuid_string);
|
2022-09-09 10:44:11 +08:00
|
|
|
ctx->action = PX_ACTION_NONE;
|
2019-05-21 19:15:37 +08:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch(param->action)
|
|
|
|
|
{
|
2024-10-25 17:00:57 +08:00
|
|
|
case MA_ACTION_REPLACE_TEXT:
|
2019-05-21 19:15:37 +08:00
|
|
|
http_replace(stream, session, events, body_frag, frag_size, ctx);
|
|
|
|
|
break;
|
2024-10-25 17:00:57 +08:00
|
|
|
case MA_ACTION_REPLACE_FILE:
|
2019-05-21 19:15:37 +08:00
|
|
|
http_hijack(session, events, ctx);
|
|
|
|
|
break;
|
2024-10-25 17:00:57 +08:00
|
|
|
case MA_ACTION_INJECT_JAVESCRIPT:
|
|
|
|
|
case MA_ACTION_INJECT_CSS:
|
|
|
|
|
http_insert(stream, session, events, body_frag, frag_size, param->action, ctx);
|
2019-05-21 19:15:37 +08:00
|
|
|
break;
|
2024-10-25 17:00:57 +08:00
|
|
|
case MA_ACTION_EDIT_ELEMENT:
|
2021-12-06 18:14:10 +08:00
|
|
|
http_element(stream, session, events, body_frag, frag_size, ctx);
|
|
|
|
|
break;
|
2019-05-21 19:15:37 +08:00
|
|
|
default: assert(0);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return;
|
2018-09-12 16:04:04 +08:00
|
|
|
}
|
|
|
|
|
|
2022-02-11 09:57:33 +08:00
|
|
|
static int get_fqdn_len(char *str_host)
|
|
|
|
|
{
|
|
|
|
|
char *p=NULL; int fqdn_len=0;
|
|
|
|
|
|
|
|
|
|
if(str_host == NULL)
|
|
|
|
|
{
|
|
|
|
|
goto finish;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
p=index(str_host, ':');
|
|
|
|
|
if(p==NULL)
|
|
|
|
|
{
|
|
|
|
|
fqdn_len=strlen(str_host);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
fqdn_len=p-str_host;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
finish:
|
|
|
|
|
return fqdn_len;
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-09 10:44:11 +08:00
|
|
|
enum proxy_action http_scan(const struct tfe_http_session * session, enum tfe_http_event events,
|
|
|
|
|
const unsigned char * body_frag, size_t frag_size, struct proxy_http_ctx * ctx, const struct tfe_stream * stream)
|
2018-09-12 16:04:04 +08:00
|
|
|
{
|
2019-05-21 19:15:37 +08:00
|
|
|
void * iterator = NULL;
|
2024-11-27 10:40:40 +08:00
|
|
|
const char *filed_name=NULL;
|
2018-09-23 20:02:07 +08:00
|
|
|
const char * field_val = NULL;
|
2018-09-12 16:04:04 +08:00
|
|
|
struct http_field_name field_name;
|
2019-06-15 18:19:15 +08:00
|
|
|
struct tfe_http_half * http_half;
|
2024-09-29 20:01:49 +08:00
|
|
|
uuid_t *result = ctx->result;
|
2018-09-23 20:02:07 +08:00
|
|
|
char buff[TFE_STRING_MAX], * p = NULL;
|
2024-09-29 20:01:49 +08:00
|
|
|
int scan_ret = 0;
|
2023-03-30 19:39:18 +08:00
|
|
|
size_t n_hit_result=0;
|
2021-05-28 10:51:22 +08:00
|
|
|
size_t hit_cnt = ctx->hit_cnt, i = 0;
|
2018-09-23 20:02:07 +08:00
|
|
|
|
|
|
|
|
if (events & EV_HTTP_REQ_HDR)
|
|
|
|
|
{
|
2022-02-11 09:57:33 +08:00
|
|
|
char *str_host = (char *)session->req->req_spec.host;
|
|
|
|
|
int str_host_length = get_fqdn_len(str_host);
|
|
|
|
|
if (str_host != NULL && str_host_length != 0)
|
2019-08-20 13:48:38 +08:00
|
|
|
{
|
2024-11-27 10:40:40 +08:00
|
|
|
scan_ret = maat_scan_string(g_proxy_rt->feather, "TSG_OBJ_FQDN", "SERVER_FQDN", str_host, str_host_length,
|
2024-09-29 20:01:49 +08:00
|
|
|
result + hit_cnt, MAX_SCAN_RESULT - hit_cnt, &n_hit_result, ctx->scan_mid);
|
2023-03-30 19:39:18 +08:00
|
|
|
if (scan_ret == MAAT_SCAN_HIT)
|
2019-12-11 15:28:36 +08:00
|
|
|
{
|
2023-03-30 19:39:18 +08:00
|
|
|
hit_cnt += n_hit_result;
|
2019-12-11 15:28:36 +08:00
|
|
|
}
|
2024-11-27 10:40:40 +08:00
|
|
|
scan_ret = maat_scan_not_logic(g_proxy_rt->feather, "TSG_OBJ_FQDN", "SERVER_FQDN",
|
2023-12-14 15:08:19 +08:00
|
|
|
result + hit_cnt, MAX_SCAN_RESULT - hit_cnt, &n_hit_result, ctx->scan_mid);
|
|
|
|
|
if (scan_ret == MAAT_SCAN_HIT)
|
|
|
|
|
{
|
|
|
|
|
hit_cnt += n_hit_result;
|
|
|
|
|
}
|
2024-08-16 11:57:20 +08:00
|
|
|
|
2024-09-29 20:01:49 +08:00
|
|
|
scan_ret = tfe_scan_fqdn_tags(stream, result, ctx->scan_mid, hit_cnt, g_proxy_rt->local_logger);
|
2024-09-11 17:49:14 +08:00
|
|
|
if (scan_ret > 0)
|
2024-08-16 11:57:20 +08:00
|
|
|
{
|
2024-09-11 17:49:14 +08:00
|
|
|
hit_cnt += scan_ret;
|
2024-08-16 11:57:20 +08:00
|
|
|
}
|
2020-10-12 15:43:27 +08:00
|
|
|
}
|
2019-08-21 19:47:30 +08:00
|
|
|
|
2018-09-23 20:02:07 +08:00
|
|
|
const char * str_url = session->req->req_spec.url;
|
|
|
|
|
int str_url_length = (int) (strlen(session->req->req_spec.url));
|
2024-11-27 10:40:40 +08:00
|
|
|
scan_ret = maat_scan_string(g_proxy_rt->feather, "TSG_OBJ_URL", "HTTP_URL", str_url, str_url_length,
|
2024-09-29 20:01:49 +08:00
|
|
|
result + hit_cnt, MAX_SCAN_RESULT - hit_cnt, &n_hit_result, ctx->scan_mid);
|
2018-09-23 20:02:07 +08:00
|
|
|
|
2023-03-30 19:39:18 +08:00
|
|
|
if (scan_ret == MAAT_SCAN_HIT)
|
2018-09-12 16:04:04 +08:00
|
|
|
{
|
2023-03-30 19:39:18 +08:00
|
|
|
hit_cnt += n_hit_result;
|
2018-09-12 16:04:04 +08:00
|
|
|
}
|
2024-11-27 10:40:40 +08:00
|
|
|
scan_ret = maat_scan_not_logic(g_proxy_rt->feather, "TSG_OBJ_URL", "HTTP_URL",
|
2023-12-14 15:08:19 +08:00
|
|
|
result + hit_cnt, MAX_SCAN_RESULT - hit_cnt, &n_hit_result, ctx->scan_mid);
|
|
|
|
|
if (scan_ret == MAAT_SCAN_HIT)
|
|
|
|
|
{
|
|
|
|
|
hit_cnt += n_hit_result;
|
|
|
|
|
}
|
2018-09-12 16:04:04 +08:00
|
|
|
}
|
2018-09-23 20:02:07 +08:00
|
|
|
|
|
|
|
|
if ((events & EV_HTTP_REQ_HDR) || (events & EV_HTTP_RESP_HDR))
|
2018-09-12 16:04:04 +08:00
|
|
|
{
|
2024-11-27 10:40:40 +08:00
|
|
|
filed_name = events & EV_HTTP_REQ_HDR ? "HTTP_REQ_HDR" : "HTTP_RES_HDR";
|
|
|
|
|
struct maat_stream *sp = maat_stream_new(g_proxy_rt->feather, "TSG_OBJ_KEYWORD", filed_name, ctx->scan_mid);
|
2024-09-29 20:01:49 +08:00
|
|
|
|
2019-06-15 18:19:15 +08:00
|
|
|
http_half = events & EV_HTTP_REQ_HDR ? session->req : session->resp;
|
2018-09-23 20:02:07 +08:00
|
|
|
while (hit_cnt < MAX_SCAN_RESULT)
|
2018-09-12 16:04:04 +08:00
|
|
|
{
|
2019-06-15 18:19:15 +08:00
|
|
|
field_val = tfe_http_field_iterate(http_half, &iterator, &field_name);
|
2018-09-23 20:02:07 +08:00
|
|
|
if (field_val == NULL)
|
2018-09-14 16:33:36 +08:00
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
2024-10-25 17:00:57 +08:00
|
|
|
|
2024-11-12 15:44:10 +08:00
|
|
|
scan_ret = maat_stream_scan(sp, field_val, strlen(field_val), result + hit_cnt, MAX_SCAN_RESULT - hit_cnt, &n_hit_result, ctx->scan_mid);
|
2023-03-30 19:39:18 +08:00
|
|
|
if (scan_ret == MAAT_SCAN_HIT)
|
2018-09-12 16:04:04 +08:00
|
|
|
{
|
2023-03-30 19:39:18 +08:00
|
|
|
hit_cnt += n_hit_result;
|
2018-09-14 16:33:36 +08:00
|
|
|
}
|
2024-11-07 16:13:55 +08:00
|
|
|
|
|
|
|
|
const char * str_field_name = http_field_name_to_string(&field_name);
|
|
|
|
|
if(str_field_name == NULL)
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
2024-11-12 15:44:10 +08:00
|
|
|
scan_ret = maat_stream_scan(sp, str_field_name, strlen(str_field_name), result + hit_cnt, MAX_SCAN_RESULT - hit_cnt, &n_hit_result, ctx->scan_mid);
|
2024-11-07 16:13:55 +08:00
|
|
|
if (scan_ret == MAAT_SCAN_HIT)
|
|
|
|
|
{
|
|
|
|
|
hit_cnt += n_hit_result;
|
|
|
|
|
}
|
2018-09-12 16:04:04 +08:00
|
|
|
}
|
2024-11-27 10:40:40 +08:00
|
|
|
scan_ret = maat_scan_not_logic(g_proxy_rt->feather, "TSG_OBJ_KEYWORD", filed_name, result + hit_cnt, MAX_SCAN_RESULT - hit_cnt,
|
2024-09-29 20:01:49 +08:00
|
|
|
&n_hit_result, ctx->scan_mid);
|
2023-11-24 15:26:23 +08:00
|
|
|
if (scan_ret == MAAT_SCAN_HIT)
|
|
|
|
|
{
|
|
|
|
|
hit_cnt += n_hit_result;
|
|
|
|
|
}
|
2024-11-12 15:44:10 +08:00
|
|
|
maat_stream_free(sp);
|
2018-09-12 16:04:04 +08:00
|
|
|
}
|
2018-10-25 13:24:05 +08:00
|
|
|
|
2018-09-23 20:02:07 +08:00
|
|
|
if ((events & EV_HTTP_REQ_BODY_BEGIN) | (events & EV_HTTP_RESP_BODY_BEGIN))
|
2018-09-12 16:04:04 +08:00
|
|
|
{
|
2018-09-23 20:02:07 +08:00
|
|
|
assert(ctx->sp == NULL);
|
2024-11-27 10:40:40 +08:00
|
|
|
filed_name = events & EV_HTTP_REQ_BODY_BEGIN ? "HTTP_REQ_BODY" : "HTTP_RES_BODY";
|
|
|
|
|
ctx->sp = maat_stream_new(g_proxy_rt->feather, "TSG_OBJ_KEYWORD", filed_name, ctx->scan_mid);
|
2018-09-12 16:04:04 +08:00
|
|
|
}
|
2018-10-25 13:24:05 +08:00
|
|
|
|
2024-09-29 20:01:49 +08:00
|
|
|
const unsigned char *scan_body_frag=NULL; size_t scan_len=0;
|
2018-09-23 20:02:07 +08:00
|
|
|
if (body_frag != NULL)
|
2018-09-12 16:04:04 +08:00
|
|
|
{
|
2024-01-19 14:21:30 +08:00
|
|
|
scan_body_frag = body_frag;
|
|
|
|
|
while (scan_body_frag < body_frag + frag_size)
|
2018-09-12 16:04:04 +08:00
|
|
|
{
|
2024-01-19 14:21:30 +08:00
|
|
|
scan_len = (scan_body_frag + MAX_SCAN_DATA_SIZE < body_frag + frag_size) ? MAX_SCAN_DATA_SIZE : (body_frag + frag_size - scan_body_frag);
|
|
|
|
|
|
|
|
|
|
scan_ret = maat_stream_scan(ctx->sp, (const char *)scan_body_frag, scan_len,
|
2024-09-29 20:01:49 +08:00
|
|
|
result + hit_cnt, MAX_SCAN_RESULT - hit_cnt, &n_hit_result, ctx->scan_mid);
|
2024-01-19 14:21:30 +08:00
|
|
|
if (scan_ret == MAAT_SCAN_HIT)
|
|
|
|
|
{
|
|
|
|
|
hit_cnt += n_hit_result;
|
|
|
|
|
}
|
|
|
|
|
scan_body_frag += MAX_SCAN_DATA_SIZE;
|
2018-09-12 16:04:04 +08:00
|
|
|
}
|
|
|
|
|
}
|
2018-10-25 13:24:05 +08:00
|
|
|
|
2018-09-23 20:02:07 +08:00
|
|
|
if ((events & EV_HTTP_REQ_BODY_END) | (events & EV_HTTP_RESP_BODY_END))
|
2018-09-12 16:04:04 +08:00
|
|
|
{
|
2024-11-27 10:40:40 +08:00
|
|
|
filed_name = events & EV_HTTP_REQ_BODY_END ? "HTTP_REQ_BODY" : "HTTP_RES_BODY";
|
|
|
|
|
scan_ret = maat_scan_not_logic(g_proxy_rt->feather, "TSG_OBJ_KEYWORD", filed_name, result + hit_cnt, MAX_SCAN_RESULT - hit_cnt,
|
2023-11-24 15:26:23 +08:00
|
|
|
&n_hit_result, ctx->scan_mid);
|
|
|
|
|
if (scan_ret == MAAT_SCAN_HIT)
|
|
|
|
|
{
|
|
|
|
|
hit_cnt += n_hit_result;
|
|
|
|
|
}
|
2023-03-30 19:39:18 +08:00
|
|
|
maat_stream_free(ctx->sp);
|
2018-09-23 20:02:07 +08:00
|
|
|
ctx->sp = NULL;
|
2018-09-12 16:04:04 +08:00
|
|
|
}
|
2018-09-25 10:17:50 +08:00
|
|
|
|
2018-09-23 20:02:07 +08:00
|
|
|
if (hit_cnt > 0)
|
2018-09-12 16:04:04 +08:00
|
|
|
{
|
2019-05-21 19:15:37 +08:00
|
|
|
ctx->action = decide_ctrl_action(result, hit_cnt, &ctx->enforce_rules, &ctx->n_enforce, &ctx->param);
|
2024-10-21 18:32:15 +08:00
|
|
|
if (ctx->action == PX_ACTION_ALLOW)
|
2019-06-17 20:12:37 +08:00
|
|
|
{
|
2024-09-29 20:01:49 +08:00
|
|
|
TFE_LOG_INFO(g_proxy_rt->local_logger, "Bypass rules matched: url=%s policy id=%s.",
|
|
|
|
|
session->req->req_spec.url, ctx->enforce_rules[0].config_uuid_string);
|
2019-06-17 20:12:37 +08:00
|
|
|
goto __out;
|
|
|
|
|
}
|
2018-09-23 20:02:07 +08:00
|
|
|
if (hit_cnt > 1)
|
2018-09-12 16:04:04 +08:00
|
|
|
{
|
2018-09-23 20:02:07 +08:00
|
|
|
p = buff;
|
2020-07-15 12:13:47 +08:00
|
|
|
for (i = 0; i < hit_cnt && i<MAX_SCAN_RESULT; i++)
|
2018-09-12 16:04:04 +08:00
|
|
|
{
|
2024-09-29 20:01:49 +08:00
|
|
|
char result_uuid_string[UUID_STRING_SIZE]={0};
|
|
|
|
|
uuid_unparse(result[i], result_uuid_string);
|
|
|
|
|
p += snprintf(p, sizeof(buff) - (p - buff), "%s:", result_uuid_string);
|
2018-09-12 16:04:04 +08:00
|
|
|
}
|
2018-09-25 10:17:50 +08:00
|
|
|
|
2018-09-23 20:02:07 +08:00
|
|
|
*p = '\0';
|
2018-10-25 13:24:05 +08:00
|
|
|
|
2024-09-29 20:01:49 +08:00
|
|
|
TFE_LOG_INFO(g_proxy_rt->local_logger, "Multiple rules matched: url=%s num=%lu ids=%s execute=%s.",
|
|
|
|
|
session->req->req_spec.url, hit_cnt, buff, ctx->enforce_rules[0].config_uuid_string);
|
2018-09-12 16:04:04 +08:00
|
|
|
}
|
2022-11-28 16:27:08 +08:00
|
|
|
ctx->hit_cnt=0;
|
2018-09-12 16:04:04 +08:00
|
|
|
}
|
2018-10-25 13:24:05 +08:00
|
|
|
__out:
|
2018-09-12 16:04:04 +08:00
|
|
|
return ctx->action;
|
|
|
|
|
}
|
2019-05-21 19:15:37 +08:00
|
|
|
|
2018-10-14 17:11:45 +08:00
|
|
|
void enforce_control_policy(const struct tfe_stream * stream, const struct tfe_http_session * session,
|
|
|
|
|
enum tfe_http_event events, const unsigned char * body_frag, size_t frag_size, unsigned int thread_id,
|
2022-09-09 10:44:11 +08:00
|
|
|
struct proxy_http_ctx * ctx)
|
2018-10-14 17:11:45 +08:00
|
|
|
{
|
2024-10-21 18:32:15 +08:00
|
|
|
if(ctx->action==PX_ACTION_NONE||ctx->action==PX_ACTION_MONITOR)
|
2018-10-14 17:11:45 +08:00
|
|
|
{
|
|
|
|
|
//ctx->action changed in http_scan.
|
2020-10-12 11:04:35 +08:00
|
|
|
http_scan(session, events, body_frag, frag_size, ctx, stream);
|
2018-10-14 17:11:45 +08:00
|
|
|
}
|
|
|
|
|
switch (ctx->action)
|
|
|
|
|
{
|
2022-09-09 10:44:11 +08:00
|
|
|
case PX_ACTION_NONE:
|
2018-10-17 20:21:21 +08:00
|
|
|
break;
|
2024-10-21 18:32:15 +08:00
|
|
|
case PX_ACTION_MONITOR:
|
2018-10-14 17:11:45 +08:00
|
|
|
//send log on close.
|
|
|
|
|
break;
|
2024-10-21 18:32:15 +08:00
|
|
|
case PX_ACTION_DENY:
|
2022-04-15 16:20:52 +08:00
|
|
|
http_block(stream, session, events, ctx);
|
2018-10-14 17:11:45 +08:00
|
|
|
break;
|
2024-10-25 17:00:57 +08:00
|
|
|
case PX_ACTION_MANIPULATE:
|
|
|
|
|
http_manipulate(stream, session, events, body_frag, frag_size, ctx);
|
|
|
|
|
break;
|
2024-10-21 18:32:15 +08:00
|
|
|
case PX_ACTION_ALLOW:
|
2018-10-17 20:21:21 +08:00
|
|
|
tfe_http_session_detach(session);
|
2022-09-09 10:44:11 +08:00
|
|
|
ATOMIC_INC(&(g_proxy_rt->stat_val[STAT_ACTION_WHITELSIT]));
|
2018-10-14 17:11:45 +08:00
|
|
|
break;
|
2024-10-25 17:00:57 +08:00
|
|
|
case PX_ACTION_REDIRECT:
|
|
|
|
|
http_redirect(stream, session, events, ctx);
|
|
|
|
|
break;
|
|
|
|
|
case PX_ACTION_EXECUTE:
|
|
|
|
|
http_lua(stream, session, events, body_frag, frag_size, ctx);
|
|
|
|
|
break;
|
|
|
|
|
default: assert(0);
|
2018-10-14 17:11:45 +08:00
|
|
|
break;
|
|
|
|
|
}
|
2019-01-05 18:17:47 +06:00
|
|
|
|
|
|
|
|
/* Don't store reqeust/response body when NOT hit or hit whitelist */
|
2024-10-21 18:32:15 +08:00
|
|
|
if(ctx->action == PX_ACTION_NONE || ctx->action == PX_ACTION_ALLOW)
|
2018-12-24 22:47:26 +06:00
|
|
|
{
|
2019-01-05 18:17:47 +06:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Otherwise, store body */
|
|
|
|
|
if(events & EV_HTTP_REQ_BODY_CONT)
|
|
|
|
|
{
|
|
|
|
|
if(ctx->log_req_body == NULL) ctx->log_req_body = evbuffer_new();
|
|
|
|
|
evbuffer_add(ctx->log_req_body, body_frag, frag_size);
|
2018-12-24 22:47:26 +06:00
|
|
|
}
|
2019-01-05 18:17:47 +06:00
|
|
|
|
|
|
|
|
if(events & EV_HTTP_RESP_BODY_CONT)
|
|
|
|
|
{
|
|
|
|
|
if(ctx->log_resp_body == NULL) ctx->log_resp_body = evbuffer_new();
|
|
|
|
|
evbuffer_add(ctx->log_resp_body, body_frag, frag_size);
|
|
|
|
|
}
|
2024-02-29 11:25:36 +08:00
|
|
|
|
2024-09-29 20:01:49 +08:00
|
|
|
if((((ctx_actually_replaced(ctx)) || (ctx_actually_inserted(ctx)) || (ctx_actually_edited(ctx)) || (ctx_actually_manipulate(ctx))
|
2024-10-21 18:32:15 +08:00
|
|
|
|| ctx_actually_ran_script(ctx)) || ctx->action == PX_ACTION_DENY || (ctx->action == PX_ACTION_MONITOR)))
|
2024-02-29 11:25:36 +08:00
|
|
|
{
|
|
|
|
|
proxy_send_metric_log(stream, ctx, thread_id, 1);
|
|
|
|
|
}
|
2023-08-02 16:55:56 +08:00
|
|
|
|
2018-10-14 17:11:45 +08:00
|
|
|
return;
|
|
|
|
|
}
|
2018-10-25 18:45:33 +08:00
|
|
|
#define RESUMED_CB_NO_MORE_CALLS 0
|
2018-09-12 16:04:04 +08:00
|
|
|
|
2023-12-14 15:08:19 +08:00
|
|
|
void proxy_on_http_begin(const struct tfe_stream *stream, const struct tfe_http_session *session, unsigned int thread_id, void **pme)
|
2020-06-11 13:47:56 +08:00
|
|
|
{
|
2022-09-09 10:44:11 +08:00
|
|
|
if (!g_proxy_rt->enable_plugin)
|
2020-07-28 18:54:00 +08:00
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-09 10:44:11 +08:00
|
|
|
struct proxy_http_ctx * ctx = *(struct proxy_http_ctx **) pme;
|
2020-06-11 13:47:56 +08:00
|
|
|
struct ipaddr sapp_addr;
|
|
|
|
|
int hit_cnt = 0, scan_ret=0;
|
|
|
|
|
assert(ctx == NULL);
|
2022-09-09 10:44:11 +08:00
|
|
|
ATOMIC_INC(&(g_proxy_rt->stat_val[STAT_SESSION]));
|
|
|
|
|
ctx = proxy_http_ctx_new(thread_id);
|
2020-06-11 13:47:56 +08:00
|
|
|
|
2024-09-29 20:01:49 +08:00
|
|
|
scan_ret = tfe_scan_subscribe_id(stream, ctx->result, ctx->scan_mid, hit_cnt, g_proxy_rt->local_logger);
|
2020-06-11 13:47:56 +08:00
|
|
|
if(scan_ret>0)
|
|
|
|
|
{
|
2024-08-16 11:57:20 +08:00
|
|
|
hit_cnt += scan_ret;
|
2020-06-11 13:47:56 +08:00
|
|
|
}
|
2023-12-14 15:08:19 +08:00
|
|
|
|
2024-09-29 20:01:49 +08:00
|
|
|
scan_ret = tfe_scan_ip_tags(stream, ctx->result, ctx->scan_mid, hit_cnt, g_proxy_rt->local_logger);
|
2020-06-11 13:47:56 +08:00
|
|
|
if(scan_ret>0)
|
|
|
|
|
{
|
2024-08-16 11:57:20 +08:00
|
|
|
hit_cnt += scan_ret;
|
2020-06-11 13:47:56 +08:00
|
|
|
}
|
2024-08-16 11:57:20 +08:00
|
|
|
|
2023-11-24 15:26:23 +08:00
|
|
|
long long app_id=67;
|
2024-09-29 20:01:49 +08:00
|
|
|
scan_ret = tfe_scan_app_id(ctx->result, ctx->scan_mid, hit_cnt, app_id);
|
2023-12-14 15:08:19 +08:00
|
|
|
if(scan_ret > 0)
|
2020-04-01 11:13:53 +08:00
|
|
|
{
|
2023-12-14 15:08:19 +08:00
|
|
|
hit_cnt += scan_ret;
|
2020-04-01 11:13:53 +08:00
|
|
|
}
|
2024-09-29 20:01:49 +08:00
|
|
|
|
|
|
|
|
scan_ret = tfe_scan_device(stream, ctx->result, ctx->scan_mid, hit_cnt, g_proxy_rt->local_logger);
|
2024-08-30 11:13:04 +08:00
|
|
|
if(scan_ret > 0)
|
2024-11-27 17:26:57 +08:00
|
|
|
{
|
|
|
|
|
hit_cnt += scan_ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
scan_ret = tfe_scan_zone(stream, ctx->result, ctx->scan_mid, hit_cnt);
|
|
|
|
|
if(scan_ret > 0)
|
2024-08-30 11:13:04 +08:00
|
|
|
{
|
|
|
|
|
hit_cnt += scan_ret;
|
|
|
|
|
}
|
2018-12-16 22:47:03 +06:00
|
|
|
|
2018-09-14 16:33:36 +08:00
|
|
|
addr_tfe2sapp(stream->addr, &sapp_addr);
|
2023-03-30 19:39:18 +08:00
|
|
|
if (sapp_addr.addrtype == ADDR_TYPE_IPV4)
|
2020-06-18 19:36:10 +08:00
|
|
|
{
|
2024-09-29 20:01:49 +08:00
|
|
|
scan_ret = tfe_scan_ipv4_addr(stream, ctx->result, ctx->scan_mid, hit_cnt, sapp_addr);
|
2023-12-14 15:08:19 +08:00
|
|
|
if (scan_ret > 0)
|
2023-03-30 19:39:18 +08:00
|
|
|
{
|
2023-12-14 15:08:19 +08:00
|
|
|
hit_cnt += scan_ret;
|
2023-03-30 19:39:18 +08:00
|
|
|
}
|
2024-09-29 20:01:49 +08:00
|
|
|
scan_ret = tfe_scan_port(stream, ctx->result, ctx->scan_mid, hit_cnt, sapp_addr.v4->source, sapp_addr.v4->dest);
|
2024-02-01 16:03:49 +08:00
|
|
|
if(scan_ret > 0)
|
|
|
|
|
{
|
|
|
|
|
hit_cnt += scan_ret;
|
|
|
|
|
}
|
2023-03-30 19:39:18 +08:00
|
|
|
}
|
|
|
|
|
if (sapp_addr.addrtype == ADDR_TYPE_IPV6)
|
|
|
|
|
{
|
2024-09-29 20:01:49 +08:00
|
|
|
scan_ret = tfe_scan_ipv6_addr(stream, ctx->result, ctx->scan_mid, hit_cnt, sapp_addr);
|
2023-12-14 15:08:19 +08:00
|
|
|
if (scan_ret > 0)
|
2023-03-30 19:39:18 +08:00
|
|
|
{
|
2023-12-14 15:08:19 +08:00
|
|
|
hit_cnt += scan_ret;
|
2023-03-30 19:39:18 +08:00
|
|
|
}
|
2024-09-29 20:01:49 +08:00
|
|
|
scan_ret = tfe_scan_port(stream, ctx->result, ctx->scan_mid, hit_cnt, sapp_addr.v6->source, sapp_addr.v6->dest);
|
2024-02-01 16:03:49 +08:00
|
|
|
if(scan_ret > 0)
|
|
|
|
|
{
|
|
|
|
|
hit_cnt += scan_ret;
|
|
|
|
|
}
|
2023-03-30 19:39:18 +08:00
|
|
|
}
|
2023-12-14 15:08:19 +08:00
|
|
|
|
2021-05-28 10:51:22 +08:00
|
|
|
if(hit_cnt > 0)
|
2018-09-12 16:04:04 +08:00
|
|
|
{
|
2021-05-28 10:51:22 +08:00
|
|
|
ctx->hit_cnt = hit_cnt;
|
2018-09-12 16:04:04 +08:00
|
|
|
}
|
2018-09-18 18:48:21 +08:00
|
|
|
|
2018-09-23 20:02:07 +08:00
|
|
|
*pme = ctx;
|
2018-09-18 12:01:56 +08:00
|
|
|
return;
|
2018-09-12 16:04:04 +08:00
|
|
|
}
|
|
|
|
|
|
2022-09-09 10:44:11 +08:00
|
|
|
void proxy_on_http_end(const struct tfe_stream * stream,
|
2018-09-12 16:04:04 +08:00
|
|
|
const struct tfe_http_session * session, unsigned int thread_id, void ** pme)
|
|
|
|
|
{
|
2022-09-09 10:44:11 +08:00
|
|
|
if (!g_proxy_rt->enable_plugin)
|
2020-07-28 18:54:00 +08:00
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-09 10:44:11 +08:00
|
|
|
struct proxy_http_ctx * ctx = *(struct proxy_http_ctx **) pme;
|
2018-11-20 19:34:27 +08:00
|
|
|
size_t i=0, j=0;
|
|
|
|
|
int ret=0;
|
2019-05-21 19:15:37 +08:00
|
|
|
|
2024-10-25 17:00:57 +08:00
|
|
|
if(ctx->action == PX_ACTION_MANIPULATE && ctx->param->action == MA_ACTION_REPLACE_TEXT && ctx->rep_ctx->actually_replaced==0)
|
2018-09-29 16:05:10 +08:00
|
|
|
{
|
|
|
|
|
for(i=0; i< ctx->n_enforce; i++)
|
|
|
|
|
{
|
2024-10-25 17:00:57 +08:00
|
|
|
if((unsigned char)ctx->enforce_rules[i].action == PX_ACTION_MANIPULATE)
|
2018-09-29 16:05:10 +08:00
|
|
|
{
|
|
|
|
|
if(i+1 > ctx->n_enforce)
|
|
|
|
|
{
|
2023-03-30 19:39:18 +08:00
|
|
|
memmove(ctx->enforce_rules+i, ctx->enforce_rules+i+1, sizeof(struct maat_rule_t));
|
2018-09-29 16:05:10 +08:00
|
|
|
}
|
|
|
|
|
j++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
ctx->n_enforce-=j;
|
|
|
|
|
if(ctx->n_enforce==0)
|
|
|
|
|
{
|
2022-09-09 10:44:11 +08:00
|
|
|
ctx->action = PX_ACTION_NONE;
|
2018-09-29 16:05:10 +08:00
|
|
|
FREE(&(ctx->enforce_rules));
|
|
|
|
|
}
|
|
|
|
|
}
|
2023-03-30 19:39:18 +08:00
|
|
|
struct proxy_log log_msg = {.stream=stream, .http=session, .result=(struct log_rule_t *)ctx->enforce_rules, .result_num=ctx->n_enforce,
|
2024-10-25 17:00:57 +08:00
|
|
|
.req_body=ctx->log_req_body, .resp_body=ctx->log_resp_body, .action=0, .inject_sz=ctx->inject_sz, .c2s_byte_num=ctx->c2s_byte_num,
|
2024-04-03 16:50:54 +08:00
|
|
|
.s2c_byte_num=ctx->s2c_byte_num};
|
2024-10-25 17:00:57 +08:00
|
|
|
if(ctx->action == PX_ACTION_MANIPULATE)
|
|
|
|
|
{
|
|
|
|
|
log_msg.action = ctx->param->action;
|
|
|
|
|
}
|
2019-06-29 19:39:29 +08:00
|
|
|
|
2022-09-09 10:44:11 +08:00
|
|
|
if(ctx->action != PX_ACTION_NONE &&
|
2021-12-06 18:14:10 +08:00
|
|
|
(((ctx_actually_replaced(ctx)) || (ctx_actually_inserted(ctx)) || (ctx_actually_edited(ctx)) ||
|
2024-10-21 18:32:15 +08:00
|
|
|
(ctx_actually_manipulate(ctx)) || ctx_actually_ran_script(ctx)) || (ctx->action == PX_ACTION_MONITOR ||
|
|
|
|
|
ctx->action == PX_ACTION_DENY || ctx->action == PX_ACTION_ALLOW)))
|
2018-09-12 16:04:04 +08:00
|
|
|
{
|
2022-09-09 10:44:11 +08:00
|
|
|
ret=proxy_send_log(g_proxy_rt->send_logger, &log_msg);
|
|
|
|
|
ATOMIC_ADD(&(g_proxy_rt->stat_val[STAT_LOG_NUM]), ret);
|
2020-10-23 19:03:08 +08:00
|
|
|
|
|
|
|
|
for(i=0; i< ctx->n_enforce; i++)
|
|
|
|
|
{
|
2024-10-21 18:32:15 +08:00
|
|
|
if(ctx->enforce_rules[i].action == PX_ACTION_MONITOR)
|
2020-10-23 19:03:08 +08:00
|
|
|
{
|
2022-09-09 10:44:11 +08:00
|
|
|
ATOMIC_INC(&(g_proxy_rt->stat_val[STAT_ACTION_MONIT]));
|
2020-10-23 19:03:08 +08:00
|
|
|
}
|
|
|
|
|
}
|
2024-01-16 16:03:54 +08:00
|
|
|
proxy_send_metric_log(stream, ctx, thread_id, 0);
|
2018-09-12 16:04:04 +08:00
|
|
|
}
|
2020-09-25 10:11:41 +08:00
|
|
|
|
2021-01-12 16:17:18 +08:00
|
|
|
if(ctx->rep_ctx && ctx->rep_ctx->actually_replaced==1)
|
2018-10-21 15:03:04 +08:00
|
|
|
{
|
2022-09-09 10:44:11 +08:00
|
|
|
ATOMIC_INC(&(g_proxy_rt->stat_val[STAT_ACTION_REPLACE]));
|
2018-10-21 15:03:04 +08:00
|
|
|
}
|
2020-09-25 10:11:41 +08:00
|
|
|
|
2022-07-29 15:39:25 +08:00
|
|
|
if(ctx->tsg_ctx && ctx->tsg_ctx->actually_executed==1)
|
|
|
|
|
{
|
2022-09-09 10:44:11 +08:00
|
|
|
ATOMIC_INC(&(g_proxy_rt->stat_val[STAT_ACTION_RUN_SCRIPT]));
|
2022-07-29 15:39:25 +08:00
|
|
|
}
|
|
|
|
|
|
2022-09-09 10:44:11 +08:00
|
|
|
proxy_http_ctx_free(ctx);
|
2018-09-23 20:02:07 +08:00
|
|
|
*pme = NULL;
|
2018-09-12 16:04:04 +08:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-09 10:44:11 +08:00
|
|
|
int proxy_on_http_data(const struct tfe_stream * stream, const struct tfe_http_session * session,
|
2018-09-23 20:02:07 +08:00
|
|
|
enum tfe_http_event events, const unsigned char * body_frag, size_t frag_size, unsigned int thread_id, void ** pme)
|
2018-09-12 16:04:04 +08:00
|
|
|
{
|
2022-09-09 10:44:11 +08:00
|
|
|
if (!g_proxy_rt->enable_plugin)
|
2020-07-28 18:54:00 +08:00
|
|
|
{
|
|
|
|
|
return CALL_NEXT_PLUGIN;
|
|
|
|
|
}
|
|
|
|
|
|
2022-09-09 10:44:11 +08:00
|
|
|
struct proxy_http_ctx * ctx = *(struct proxy_http_ctx **) pme;
|
2018-10-25 18:45:33 +08:00
|
|
|
int ret=0;
|
|
|
|
|
if(ctx->resumed_cb)
|
2018-10-14 17:11:45 +08:00
|
|
|
{
|
2018-10-25 18:45:33 +08:00
|
|
|
ret=ctx->resumed_cb(stream, session, events, body_frag, frag_size,thread_id, ctx);
|
|
|
|
|
if(ret==RESUMED_CB_NO_MORE_CALLS)
|
|
|
|
|
{
|
|
|
|
|
ctx->resumed_cb=NULL;
|
|
|
|
|
}
|
2020-06-11 17:57:18 +08:00
|
|
|
return NO_CALL_NEXT_PLUGIN;
|
2018-10-14 17:11:45 +08:00
|
|
|
}
|
2019-05-21 19:15:37 +08:00
|
|
|
|
2018-10-25 18:45:33 +08:00
|
|
|
enforce_control_policy(stream, session, events, body_frag, frag_size,thread_id, ctx);
|
2020-06-11 17:57:18 +08:00
|
|
|
return NO_CALL_NEXT_PLUGIN;
|
2018-09-12 16:04:04 +08:00
|
|
|
}
|
2018-10-14 17:11:45 +08:00
|
|
|
|
2022-09-09 10:44:11 +08:00
|
|
|
struct tfe_plugin proxy_http_spec = {
|
2018-09-23 20:02:07 +08:00
|
|
|
.symbol=NULL,
|
|
|
|
|
.type = TFE_PLUGIN_TYPE_BUSINESS,
|
2022-09-09 10:44:11 +08:00
|
|
|
.on_init = proxy_http_init,
|
2018-09-23 20:02:07 +08:00
|
|
|
.on_deinit = NULL,
|
|
|
|
|
.on_open = NULL,
|
|
|
|
|
.on_data = NULL,
|
|
|
|
|
.on_close = NULL,
|
2022-09-09 10:44:11 +08:00
|
|
|
.on_session_begin=proxy_on_http_begin,
|
|
|
|
|
.on_session_data=proxy_on_http_data,
|
|
|
|
|
.on_session_end=proxy_on_http_end
|
2018-09-23 20:02:07 +08:00
|
|
|
};
|
2022-09-09 10:44:11 +08:00
|
|
|
TFE_PLUGIN_REGISTER(proxy_http, proxy_http_spec)
|
2018-09-09 15:21:26 +08:00
|
|
|
|