From dc7a0525c27dad6ba899f359608b1bf3379edd14 Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Sat, 27 Jul 2019 16:31:09 -0500 Subject: [PATCH] Security: set default policy to DROP after deleting chains Performing numerous syscalls can by slow. During this time, if the default behavior is open, then unwanted packets may make it through. By dropping by default, these packets will not go through. --- level_3/firewall/c/firewall.c | 12 +++++ level_3/firewall/c/private-firewall.c | 96 ++++++++++++++++++++++++++++++++--- level_3/firewall/c/private-firewall.h | 4 ++ 3 files changed, 105 insertions(+), 7 deletions(-) diff --git a/level_3/firewall/c/firewall.c b/level_3/firewall/c/firewall.c index fdd625c..b4deb6d 100644 --- a/level_3/firewall/c/firewall.c +++ b/level_3/firewall/c/firewall.c @@ -455,6 +455,10 @@ extern "C"{ if (reserved.has_lock) { status = firewall_delete_chains(*data); + if (f_error_is_not_error(status)) { + status = firewall_default_lock(*data); + } + if (f_error_is_error(status)) { firewall_delete_local_data(&local); firewall_delete_data(data); @@ -488,6 +492,10 @@ extern "C"{ if (reserved.has_stop) { status = firewall_delete_chains(*data); + if (f_error_is_not_error(status)) { + status = firewall_default_lock(*data); + } + if (f_error_is_error(status)) { firewall_delete_local_data(&local); firewall_delete_data(data); @@ -535,6 +543,10 @@ extern "C"{ if (command == firewall_parameter_command_start) { status = firewall_delete_chains(*data); + if (f_error_is_not_error(status)) { + status = firewall_default_lock(*data); + } + if (f_error_is_error(status)) { firewall_delete_local_data(&local); firewall_delete_data(data); diff --git a/level_3/firewall/c/private-firewall.c b/level_3/firewall/c/private-firewall.c index d503837..812789f 100644 --- a/level_3/firewall/c/private-firewall.c +++ b/level_3/firewall/c/private-firewall.c @@ -1199,9 +1199,9 @@ fl_print_color_code(f_standard_debug, data.context.warning); fprintf(f_standard_debug, "DEBUG: %s ", tools[i]); - for (f_string_length i = 0; i < arguments.used; i++) { - fprintf(f_standard_debug, "%.*s ", arguments.array[i].used, arguments.array[i].string); - } + for (f_string_length j = 0; j < arguments.used; j++) { + fprintf(f_standard_debug, "%.*s ", arguments.array[j].used, arguments.array[j].string); + } // for fl_print_color_code(f_standard_debug, data.context.reset); fprintf(f_standard_debug, "\n"); @@ -1220,9 +1220,9 @@ fl_print_color_code(f_standard_error, data.context.error); fprintf(f_standard_error, "%s ", tools[i]); - for (f_string_length i = 0; i < arguments.used; i++) { - fprintf(f_standard_error, "%.*s ", arguments.array[i].used, arguments.array[i].string); - } + for (f_string_length j = 0; j < arguments.used; j++) { + fprintf(f_standard_error, "%.*s ", arguments.array[j].used, arguments.array[j].string); + } // for fl_print_color_code(f_standard_error, data.context.reset); fprintf(f_standard_error, "\n"); @@ -1236,12 +1236,94 @@ return status; } - } + } // for return status; } #endif // _di_firewall_delete_chains_ +#ifndef _di_firewall_default_lock_ + f_return_status firewall_default_lock(const firewall_data data) { + const f_string chains[3] = { firewall_chain_input, firewall_chain_output, firewall_chain_forward }; + const f_string tools[2] = { firewall_tool_iptables, firewall_tool_ip6tables }; + + const f_string_length lengths[3] = { firewall_chain_input_length, firewall_chain_output_length, firewall_chain_forward_length }; + + f_status status = f_none; + + for (f_string_length i = 0; i < 3; i++) { + f_dynamic_strings arguments = f_dynamic_strings_initialize; + f_dynamic_string argument[3]; + + arguments.array = argument; + arguments.used = 3; + arguments.size = arguments.used; + + arguments.array[0].string = (f_string) firewall_action_policy_command; + arguments.array[1].string = (f_string) chains[i]; + arguments.array[2].string = (f_string) "DROP"; + + arguments.array[0].used = firewall_action_append_command_length; + arguments.array[1].used = lengths[i]; + arguments.array[2].used = 4; + + arguments.array[0].size = arguments.array[0].used; + arguments.array[1].size = arguments.array[1].used; + arguments.array[2].size = arguments.array[2].used; + + for (f_string_length j = 0; j < 2; j++) { + f_s_int results = 0; + + // print command when debugging. + #ifdef _en_firewall_debug_ + if (data.parameters[firewall_parameter_debug].result == f_console_result_found) { + fl_print_color_code(f_standard_debug, data.context.warning); + fprintf(f_standard_debug, "DEBUG: %s ", tools[j]); + + for (f_string_length k = 0; k < arguments.used; k++) { + fprintf(f_standard_debug, "%.*s ", arguments.array[k].used, arguments.array[k].string); + } // for + + fl_print_color_code(f_standard_debug, data.context.reset); + fprintf(f_standard_debug, "\n"); + } + #endif // _en_firewall_debug_ + + status = fll_execute_program(tools[j], arguments, &results); + + if (f_error_is_error(status)) { + status = f_error_set_fine(status); + + if (status == f_failure) { + fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "ERROR: Failed to perform requested %s operation:", tools[j]); + + fprintf(f_standard_error, " "); + fl_print_color_code(f_standard_error, data.context.error); + + fprintf(f_standard_error, "%s ", tools[j]); + for (f_string_length k = 0; k < arguments.used; k++) { + fprintf(f_standard_error, "%.*s ", arguments.array[k].used, arguments.array[k].string); + } // for + + fl_print_color_code(f_standard_error, data.context.reset); + fprintf(f_standard_error, "\n"); + } + else if (status == f_invalid_parameter) { + fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "INTERNAL ERROR: Invalid parameter when calling fll_execute_program()"); + } + else { + fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "INTERNAL ERROR: An unhandled error (%u) has occured while calling fll_execute_program()", f_error_set_error(status)); + } + + return status; + } + } // for + } // for + + return status; + } +#endif // _di_firewall_default_lock + #ifndef _di_firewall_process_rules_ f_return_status firewall_buffer_rules(const f_string filename, const f_bool optional, firewall_local_data *local, firewall_data *data) { f_file file = f_file_initialize; diff --git a/level_3/firewall/c/private-firewall.h b/level_3/firewall/c/private-firewall.h index 33fd1d6..94b9214 100644 --- a/level_3/firewall/c/private-firewall.h +++ b/level_3/firewall/c/private-firewall.h @@ -118,6 +118,10 @@ extern "C"{ f_return_status firewall_delete_chains(const firewall_data data) __attribute__((visibility("internal"))); #endif // _di_firewall_delete_chains_ +#ifndef _di_firewall_default_lock_ + f_return_status firewall_default_lock(const firewall_data data) __attribute__((visibility("internal"))); +#endif // _di_firewall_default_lock + #ifndef _di_firewall_buffer_rules_ f_return_status firewall_buffer_rules(const f_string filename, const f_bool optional, firewall_local_data *local, firewall_data *data) __attribute__((visibility("internal"))); #endif // _di_firewall_buffer_rules_ -- 1.8.3.1