diff --git a/plugin/business/pangu-http/CMakeLists.txt b/plugin/business/pangu-http/CMakeLists.txt index 49c48f9..fb43fd8 100644 --- a/plugin/business/pangu-http/CMakeLists.txt +++ b/plugin/business/pangu-http/CMakeLists.txt @@ -1,3 +1,3 @@ add_library(pangu-http pangu_logger.cpp pangu_http.cpp) -target_link_libraries(pangu-http common http librdkafka-static) -target_link_libraries(pangu-http cjson) \ No newline at end of file +target_link_libraries(pangu-http common http) +target_link_libraries(pangu-http librdkafka-static ctemplate-static cjson) \ No newline at end of file diff --git a/plugin/business/pangu-http/pangu_http.cpp b/plugin/business/pangu-http/pangu_http.cpp index 1fc63e7..313d89f 100644 --- a/plugin/business/pangu-http/pangu_http.cpp +++ b/plugin/business/pangu-http/pangu_http.cpp @@ -12,6 +12,7 @@ #include #include +#include #include #include @@ -54,6 +55,7 @@ struct pangu_rt int log_level; int thread_num; int scan_table_id[__SCAN_TABLE_MAX]; + ctemplate::Template* tpl_403,*tpl_404,*tpl_451; char* reject_page; int page_size; }; @@ -146,6 +148,15 @@ void pangu_http_init(struct tfe_proxy * proxy) goto error_out; } } + + char page_path[256]; + MESA_load_profile_string_def(profile, "TEMPLATE", "PAGE_403", page_path,sizeof(page_path), "./template/HTTP403.html"); + g_pangu_rt->tpl_403 = ctemplate::Template::GetTemplate(page_path,ctemplate::DO_NOT_STRIP); + MESA_load_profile_string_def(profile, "TEMPLATE", "PAGE_404", page_path,sizeof(page_path), "./template/HTTP404.html"); + g_pangu_rt->tpl_404 = ctemplate::Template::GetTemplate(page_path,ctemplate::DO_NOT_STRIP); + MESA_load_profile_string_def(profile, "TEMPLATE", "PAGE_451", page_path,sizeof(page_path), "./template/HTTP451.html"); + g_pangu_rt->tpl_451 = ctemplate::Template::GetTemplate(page_path,ctemplate::DO_NOT_STRIP); + TFE_LOG_INFO(NULL, "Pangu HTTP init success."); return; @@ -301,13 +312,36 @@ static enum pangu_action decide_ctrl_action(const struct Maat_rule_t* hit_rules, return prior_action; } //https://github.com/AndiDittrich/HttpErrorPages -static void html_generate(const char* enforce_para, char** page_buff,size_t *page_size) +static void html_generate(int cfg_id, int status_code, + char** page_buff,size_t *page_size) { - *page_buff=g_pangu_rt->reject_page; - *page_size=g_pangu_rt->page_size; + ctemplate::TemplateDictionary dict("pg_page_dict"); + dict.SetIntValue("cfg_id", cfg_id); + std::string output; + ctemplate::Template* tpl=NULL; + switch(status_code) + { + case 403: + tpl=g_pangu_rt->tpl_403; + break; + case 404: + tpl=g_pangu_rt->tpl_404; + break; + case 451: + tpl=g_pangu_rt->tpl_451; + break; + default: + return; + } + tpl->Expand(&output, &dict); + //todo: do I need to delete dict? + *page_size=output.length(); + *page_buff=ALLOC(char, *page_size); + memcpy(*page_buff,output.c_str(), *page_size); } static void html_free(char** page_buff) { + FREE(page_buff); return; } static int is_http_request(uint64_t events) @@ -668,13 +702,13 @@ static void http_reject(const struct tfe_http_session * session, uint64_t events if(ret!=1) { TFE_LOG_ERROR(g_pangu_rt->local_logger, "Invalid reject rule %d paramter %s", - ctx->enforce_rules->config_id, ctx->enforce_para); + ctx->enforce_rules[0].config_id, ctx->enforce_para); goto error_out; } to_write_sess=tfe_http_session_allow_write(session); response=tfe_http_session_response_create(to_write_sess, resp_code); - html_generate(ctx->enforce_para, &page_buff, &page_size); + html_generate(ctx->enforce_rules[0].config_id, resp_code, &page_buff, &page_size); _wrap_std_field_write(response, TFE_HTTP_CONT_TYPE, "text/html; charset=utf-8"); snprintf(cont_len_str,sizeof(cont_len_str), "%lu", page_size); _wrap_std_field_write(response, TFE_HTTP_CONT_LENGTH, cont_len_str); @@ -691,12 +725,12 @@ static void http_redirect(const struct tfe_http_session * session, uint64_t even char* url=NULL; struct tfe_http_half* response=NULL; struct tfe_http_session* to_write=NULL; - url=ALLOC(char, ctx->enforce_rules->serv_def_len); + url=ALLOC(char, ctx->enforce_rules[0].serv_def_len); ret=sscanf(ctx->enforce_para,"code=%d%[^;];url=%*[^;];",&resp_code,url); if(ret!=2) { TFE_LOG_ERROR(g_pangu_rt->local_logger, "Invalid redirect rule %d paramter %s", - ctx->enforce_rules->config_id, ctx->enforce_para); + ctx->enforce_rules[0].config_id, ctx->enforce_para); goto error_out; } @@ -827,7 +861,7 @@ void pangu_on_http_end(const struct tfe_stream * stream, { struct pangu_http_ctx* ctx=*(struct pangu_http_ctx**)pme; - struct pangu_log log_msg={.stream=stream, .http=session, .result=ctx->enforce_rules, .result_num=1}; + struct pangu_log log_msg={.stream=stream, .http=session, .result=ctx->enforce_rules, .result_num=ctx->n_enforce}; if(ctx->action!=PG_ACTION_NONE) { pangu_log_send(g_pangu_rt->send_logger, &log_msg); diff --git a/plugin/business/pangu-http/pangu_logger.cpp b/plugin/business/pangu-http/pangu_logger.cpp index 27f797b..eef2cf6 100644 --- a/plugin/business/pangu-http/pangu_logger.cpp +++ b/plugin/business/pangu-http/pangu_logger.cpp @@ -224,7 +224,7 @@ int pangu_send_log(struct pangu_logger* handle, const struct pangu_log* log_msg) cJSON_AddStringToObject(common_obj,resp_fields[i].log_filed_name, tmp_val); } } - for(int i=0; iresult_num; i++) + for(size_t i=0; iresult_num; i++) { if(log_msg->result[i].do_log==0) { diff --git a/plugin/business/pangu-http/pangu_logger.h b/plugin/business/pangu-http/pangu_logger.h index e8e5d01..e9f6413 100644 --- a/plugin/business/pangu-http/pangu_logger.h +++ b/plugin/business/pangu-http/pangu_logger.h @@ -9,7 +9,7 @@ struct pangu_log const struct tfe_stream *stream; const struct tfe_http_session* http; const Maat_rule_t*result; - int result_num; + size_t result_num; }; struct pangu_logger; struct pangu_logger* pangu_log_handle_create(const char* profile, const char* section, void* local_logger); diff --git a/plugin/business/pangu-http/template/HTTP403.html b/plugin/business/pangu-http/template/HTTP403.html new file mode 100644 index 0000000..1473af0 --- /dev/null +++ b/plugin/business/pangu-http/template/HTTP403.html @@ -0,0 +1,12 @@ + + + + + We've got some trouble | 403 - Access Denied + + + +

Access Denied Error 403

The requested resource requires an authentication (TFE-{{cfg_id}}).

+ + + diff --git a/plugin/business/pangu-http/template/HTTP404.html b/plugin/business/pangu-http/template/HTTP404.html new file mode 100644 index 0000000..ebaa2cd --- /dev/null +++ b/plugin/business/pangu-http/template/HTTP404.html @@ -0,0 +1,12 @@ + + + + + We've got some trouble | 404 - Resource not found + + + +

Resource not found Error 404

The requested resource could not be found but may be available again in the future (TFE-{{cfg_id}}).

+ + + diff --git a/plugin/business/pangu-http/template/HTTP451.html b/plugin/business/pangu-http/template/HTTP451.html new file mode 100644 index 0000000..1b40fa5 --- /dev/null +++ b/plugin/business/pangu-http/template/HTTP451.html @@ -0,0 +1,12 @@ + + + + + We've got some trouble | 451 - Unavailable For Legal Reasons + + + +

Unavailable For Legal Reasons Error 451

This request may not be serviced due to the regulations of your residency (TFE-{{cfg_id}}).

+ + + diff --git a/vendor/CMakeLists.txt b/vendor/CMakeLists.txt index 8eb8664..bea37f9 100644 --- a/vendor/CMakeLists.txt +++ b/vendor/CMakeLists.txt @@ -176,3 +176,17 @@ file(MAKE_DIRECTORY ${INSTALL_DIR}/include) add_library(librdkafka-static STATIC IMPORTED GLOBAL) set_property(TARGET librdkafka-static PROPERTY IMPORTED_LOCATION ${INSTALL_DIR}/lib/librdkafka.a) set_property(TARGET librdkafka-static PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${INSTALL_DIR}/include) + +### ctemplate +ExternalProject_Add(ctemplate PREFIX ctemplate + URL ${CMAKE_CURRENT_SOURCE_DIR}/ctemplate-2.3.tar.gz + URL_MD5 3b91f3c1e7aa55cb4c2957acf77d6b9a + BUILD_COMMAND sh autogen.sh + CONFIGURE_COMMAND ./configure --prefix= + BUILD_IN_SOURCE 1) +ExternalProject_Get_Property(ctemplate INSTALL_DIR) +file(MAKE_DIRECTORY ${INSTALL_DIR}/include) + +add_library(ctemplate-static STATIC IMPORTED GLOBAL) +set_property(TARGET ctemplate-static PROPERTY IMPORTED_LOCATION ${INSTALL_DIR}/lib/libctemplate.a) +set_property(TARGET ctemplate-static PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${INSTALL_DIR}/include) diff --git a/vendor/ctemplate-2.3.tar.gz b/vendor/ctemplate-2.3.tar.gz new file mode 100644 index 0000000..6ec1a72 Binary files /dev/null and b/vendor/ctemplate-2.3.tar.gz differ