From 9a2d99905d77e1d94bc374a6cea4c4b86bb64889 Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Tue, 3 Apr 2012 18:16:40 -0500 Subject: [PATCH] Cleanup: Move private functions into its own source and header files It has become painfully apparent that much of the firewall main function needs to be broken down into smaller functions for managability and readability purposes. The first step in doing such is to create a privte header and source files and move all internal functions there. Everything in the private-* files are intended to never be exposed in the library. Its only purpose is to make programming large projects more managable and readable. As such, none of the functions should ever be considered part of the libraries/programs api. --- level_3/firewall/c/firewall.c | 703 +-------------------------------- level_3/firewall/c/private-firewall.c | 706 ++++++++++++++++++++++++++++++++++ level_3/firewall/c/private-firewall.h | 7 + level_3/firewall/data/build/settings | 2 +- 4 files changed, 715 insertions(+), 703 deletions(-) create mode 100644 level_3/firewall/c/private-firewall.c create mode 100644 level_3/firewall/c/private-firewall.h diff --git a/level_3/firewall/c/firewall.c b/level_3/firewall/c/firewall.c index bc0012e..c4924d4 100644 --- a/level_3/firewall/c/firewall.c +++ b/level_3/firewall/c/firewall.c @@ -5,6 +5,7 @@ * Programmers: Kevin Day */ #include +#include "private-firewall.h" #ifdef __cplusplus extern "C"{ @@ -106,8 +107,6 @@ extern "C"{ #endif // _di_firewall_print_help_ #ifndef _di_firewall_main_ - f_return_status firewall_perform_commands(const f_fss_objects objects, const f_fss_contents contents, const f_bool is_global, const f_string_length this_device, const f_dynamic_string buffer, const firewall_data data, const f_dynamic_string *custom_chain) __attribute__((visibility("internal"))); - f_return_status firewall_main(const f_s_int argc, const f_string argv[], firewall_data *data) { f_status status = f_status_initialize; f_status allocation_status = f_status_initialize; @@ -1433,706 +1432,6 @@ extern "C"{ firewall_delete_data(data); return status; } - - f_return_status firewall_perform_commands(const f_fss_objects objects, const f_fss_contents contents, const f_bool is_global, const f_string_length this_device, const f_dynamic_string buffer, const firewall_data data, const f_dynamic_string *custom_chain) { - f_status status = f_status_initialize; - f_status allocation_status = f_status_initialize; - - f_string_length counter = f_string_length_initialize; - f_dynamic_string argument = f_dynamic_string_initialize; - f_dynamic_strings arguments = f_dynamic_strings_initialize; - - f_s_int results = 0; - f_string_length length = f_string_length_initialize; - f_bool invalid = f_false; - f_bool is_ip_list = f_false; - f_dynamic_string ip_list = f_dynamic_string_initialize; - - // iptables command arguments - f_bool direction_input = f_true; - f_bool direction_output = f_false; - f_bool device_all = f_false; - f_bool ip_list_direction = f_false; // false = source, true = destination - - f_string_length direction = firewall_direction_none_id; - f_dynamic_string device = f_dynamic_string_initialize; - f_string_length action = firewall_action_append_id; - - if (is_global) { - device_all = f_true; - } else { - f_resize_dynamic_string(status, device, data.devices.array[this_device].used); - - if (f_macro_test_for_allocation_errors(status)) { - f_delete_dynamic_string(allocation_status, device); - - return status; - } - - strncat(device.string, data.devices.array[this_device].string, data.devices.array[this_device].used); - device.used = data.devices.array[this_device].used; - } - - for (; counter < objects.used; counter++) { - length = (objects.array[counter].stop - objects.array[counter].start) + 1; - invalid = f_false; - - is_ip_list = f_false; - ip_list_direction = f_false; - - f_delete_dynamic_string(allocation_status, ip_list); - - if (length >= firewall_direction_length && fl_compare_strings(buffer.string + objects.array[counter].start, (f_string) firewall_direction, length, firewall_direction_length) == f_equal_to) { - length = (contents.array[counter].array[0].stop - contents.array[counter].array[0].start) + 1; - - if (contents.array[counter].used <= 0 || contents.array[counter].used > 1) { - invalid = f_true; - } else { - if (length < firewall_direction_input_length || fl_compare_strings(buffer.string + contents.array[counter].array[0].start, (f_string) firewall_direction_input, length, firewall_direction_input_length) == f_not_equal_to) { - if (length < firewall_direction_output_length || fl_compare_strings(buffer.string + contents.array[counter].array[0].start, (f_string) firewall_direction_output, length, firewall_direction_output_length) == f_not_equal_to) { - if (length < firewall_direction_forward_length || fl_compare_strings(buffer.string + contents.array[counter].array[0].start, (f_string) firewall_direction_forward, length, firewall_direction_forward_length) == f_not_equal_to) { - if (length < firewall_direction_postrouting_length || fl_compare_strings(buffer.string + contents.array[counter].array[0].start, (f_string) firewall_direction_postrouting, length, firewall_direction_postrouting_length) == f_not_equal_to) { - if (length < firewall_direction_prerouting_length || fl_compare_strings(buffer.string + contents.array[counter].array[0].start, (f_string) firewall_direction_prerouting, length, firewall_direction_prerouting_length) == f_not_equal_to) { - if (length < firewall_direction_none_length || fl_compare_strings(buffer.string + contents.array[counter].array[0].start, (f_string) firewall_direction_none, length, firewall_direction_none_length) == f_not_equal_to) { - if (length < firewall_direction_forward_input_length || fl_compare_strings(buffer.string + contents.array[counter].array[0].start, (f_string) firewall_direction_forward_input, length, firewall_direction_forward_input_length) == f_not_equal_to) { - if (length < firewall_direction_forward_output_length || fl_compare_strings(buffer.string + contents.array[counter].array[0].start, (f_string) firewall_direction_forward_output, length, firewall_direction_forward_output_length) == f_not_equal_to) { - if (length < firewall_direction_postrouting_input_length || fl_compare_strings(buffer.string + contents.array[counter].array[0].start, (f_string) firewall_direction_postrouting_input, length, firewall_direction_postrouting_input_length) == f_not_equal_to) { - if (length < firewall_direction_postrouting_output_length || fl_compare_strings(buffer.string + contents.array[counter].array[0].start, (f_string) firewall_direction_postrouting_output, length, firewall_direction_postrouting_output_length) == f_not_equal_to) { - if (length < firewall_direction_prerouting_input_length || fl_compare_strings(buffer.string + contents.array[counter].array[0].start, (f_string) firewall_direction_prerouting_input, length, firewall_direction_prerouting_input_length) == f_not_equal_to) { - if (length < firewall_direction_prerouting_output_length || fl_compare_strings(buffer.string + contents.array[counter].array[0].start, (f_string) firewall_direction_prerouting_output, length, firewall_direction_prerouting_output_length) == f_not_equal_to) { - invalid = f_true; - } else { - direction_input = f_false; - direction_output = f_true; - direction = firewall_direction_prerouting_id; - } - } else { - direction_input = f_true; - direction_output = f_false; - direction = firewall_direction_prerouting_id; - } - } else { - direction_input = f_false; - direction_output = f_true; - direction = firewall_direction_postrouting_id; - } - } else { - direction_input = f_true; - direction_output = f_false; - direction = firewall_direction_postrouting_id; - } - } else { - direction_input = f_false; - direction_output = f_true; - direction = firewall_direction_forward_id; - } - } else { - direction_input = f_true; - direction_output = f_false; - direction = firewall_direction_forward_id; - } - } else { - direction_input = f_false; - direction_output = f_false; - direction = firewall_direction_none_id; - } - } else { - direction_input = f_false; - direction_output = f_false; - direction = firewall_direction_postrouting_id; - } - } else { - direction_input = f_false; - direction_output = f_false; - direction = firewall_direction_prerouting_id; - } - } else { - direction_input = f_false; - direction_output = f_false; - direction = firewall_direction_forward_id; - } - } else { - direction_input = f_false; - direction_output = f_true; - direction = firewall_direction_none_id; - } - } else { - direction_input = f_true; - direction_output = f_false; - direction = firewall_direction_none_id; - } - } - - if (!invalid) continue; - } else if (length >= firewall_device_length && fl_compare_strings(buffer.string + objects.array[counter].start, (f_string) firewall_device, length, firewall_device_length) == f_equal_to) { - length = (contents.array[counter].array[0].stop - contents.array[counter].array[0].start) + 1; - - if (contents.array[counter].used <= 0 || contents.array[counter].used > 1) { - invalid = f_true; - } else if (length >= firewall_device_all_length && fl_compare_strings(buffer.string + contents.array[counter].array[0].start, (f_string) firewall_device_all, length, firewall_device_all_length) == f_equal_to) { - f_delete_dynamic_string(status, device); - device_all = f_true; - continue; - } else if (length >= firewall_device_this_length && fl_compare_strings(buffer.string + contents.array[counter].array[0].start, (f_string) firewall_device_this, length, firewall_device_this_length) == f_equal_to) { - f_delete_dynamic_string(status, device); - f_resize_dynamic_string(status, device, data.devices.array[this_device].used); - - if (f_macro_test_for_allocation_errors(status)) break; - - strncat(device.string, data.devices.array[this_device].string, data.devices.array[this_device].used); - device.used = data.devices.array[this_device].used; - device_all = f_false; - continue; - } - - if (!invalid) { - f_delete_dynamic_string(status, device); - f_resize_dynamic_string(status, device, length); - - if (f_macro_test_for_allocation_errors(status)) break; - - strncat(device.string, buffer.string + contents.array[counter].array[0].start, length); - device.used = length; - device_all = f_false; - continue; - } - } else if (length >= firewall_action_length && fl_compare_strings(buffer.string + objects.array[counter].start, (f_string) firewall_action, length, firewall_action_length) == f_equal_to) { - length = (contents.array[counter].array[0].stop - contents.array[counter].array[0].start) + 1; - - if (contents.array[counter].used <= 0 || contents.array[counter].used > 1) { - invalid = f_true; - } else if (length < firewall_action_append_length || fl_compare_strings(buffer.string + contents.array[counter].array[0].start, (f_string) firewall_action_append, length, firewall_action_append_length) == f_not_equal_to) { - if (length < firewall_action_insert_length || fl_compare_strings(buffer.string + contents.array[counter].array[0].start, (f_string) firewall_action_insert, length, firewall_action_insert_length) == f_not_equal_to) { - if (length < firewall_action_policy_length || fl_compare_strings(buffer.string + contents.array[counter].array[0].start, (f_string) firewall_action_policy, length, firewall_action_policy_length) == f_not_equal_to) { - if (length < firewall_action_none_length || fl_compare_strings(buffer.string + contents.array[counter].array[0].start, (f_string) firewall_action_none, length, firewall_action_none_length) == f_not_equal_to) { - invalid = f_true; - } else { - action = firewall_action_none_id; - } - } else { - action = firewall_action_policy_id; - } - } else { - action = firewall_action_insert_id; - } - } else { - action = firewall_action_append_id; - } - - if (!invalid) continue; - } else if (length >= firewall_ip_list_length && fl_compare_strings(buffer.string + objects.array[counter].start, (f_string) firewall_ip_list, length, firewall_ip_list_length) == f_equal_to) { - length = (contents.array[counter].array[0].stop - contents.array[counter].array[0].start) + 1; - is_ip_list = f_true; - - if (length >= firewall_ip_list_source_length && fl_compare_strings(buffer.string + contents.array[counter].array[0].start, (f_string) firewall_ip_list_source, length, firewall_ip_list_source_length) == f_equal_to) { - ip_list_direction = f_false; - } else if (length >= firewall_ip_list_destination_length && fl_compare_strings(buffer.string + contents.array[counter].array[0].start, (f_string) firewall_ip_list_destination, length, firewall_ip_list_destination_length) == f_equal_to) { - ip_list_direction = f_true; - } else { - invalid = f_true; - } - } else if (length < firewall_rule_length || fl_compare_strings(buffer.string + objects.array[counter].start, (f_string) firewall_rule, length, firewall_rule_length) == f_not_equal_to) { - if (length > 0) { - fl_print_color_code(f_standard_warning, data.context.warning); - fprintf(f_standard_warning, "WARNING: At line %u, the object '", (unsigned int) counter); - f_print_string(f_standard_warning, buffer.string + objects.array[counter].start, length); - fprintf(f_standard_warning, "' is invalid"); - fl_print_color_code(f_standard_warning, data.context.reset); - } else { - fprintf(f_standard_warning, "WARNING: At line %u, the object is missing", (unsigned int) counter); - } - - fprintf(f_standard_warning, "\n"); - continue; - } - - if (invalid) { - length = (objects.array[counter].stop - objects.array[counter].start) + 1; - - if (length > 0) { - fl_print_color_code(f_standard_warning, data.context.warning); - fprintf(f_standard_warning, "WARNING: At line %u, the object '", (unsigned int) counter); - f_print_string(f_standard_warning, buffer.string + objects.array[counter].start, length); - fprintf(f_standard_warning, "' has invalid content '"); - f_print_string(f_standard_warning, buffer.string + contents.array[counter].array[0].start, contents.array[counter].array[0].stop - contents.array[counter].array[0].start + 1); - fprintf(f_standard_warning, "'"); - fl_print_color_code(f_standard_warning, data.context.reset); - fprintf(f_standard_warning, "\n"); - } else { - fl_print_color_line(f_standard_warning, data.context.warning, data.context.reset, "WARNING: At line %u, the object has no content", (unsigned int) counter); - } - - continue; - } - - - // first add the program name - f_delete_dynamic_strings(status, arguments); - f_resize_dynamic_strings(status, arguments, arguments.used + 1); - - if (f_macro_test_for_allocation_errors(status)) break; - - f_resize_dynamic_string(status, argument, firewall_program_name_length); - - if (f_macro_test_for_allocation_errors(status)) break; - - strncat(argument.string, firewall_program_name, firewall_program_name_length); - argument.used = firewall_program_name_length; - - arguments.array[arguments.used].string = argument.string; - arguments.array[arguments.used].size = argument.size; - arguments.array[arguments.used].used = argument.used; - arguments.used++; - argument.string = f_null; - argument.size = 0; - argument.used = 0; - - - // FIXME: (this issue is probably everywhere) Implement an strncat function for dynamic strings or if I already have one implement, make sure it is used in every applicable place - // (this way I can automatically handle updating the used buffer) - // also look into auto-allocated space if necessary with the said function - if (action == firewall_action_append_id) { - f_resize_dynamic_string(status, argument, firewall_action_append_command_length); - - if (f_macro_test_for_allocation_errors(status)) break; - - strncat(argument.string, firewall_action_append_command, firewall_action_append_command_length); - argument.used = firewall_action_append_command_length; - } else if (action == firewall_action_insert_id) { - f_resize_dynamic_string(status, argument, firewall_action_insert_command_length); - - if (f_macro_test_for_allocation_errors(status)) break; - - strncat(argument.string, firewall_action_insert_command, firewall_action_insert_command_length); - argument.used = firewall_action_insert_command_length; - } else if (action == firewall_action_policy_id) { - f_resize_dynamic_string(status, argument, firewall_action_policy_command_length); - - if (f_macro_test_for_allocation_errors(status)) break; - - strncat(argument.string, firewall_action_policy_command, firewall_action_policy_command_length); - argument.used = firewall_action_policy_command_length; - } - - if (argument.used > 0) { - f_resize_dynamic_strings(status, arguments, arguments.used + 1); - - if (f_macro_test_for_allocation_errors(status)) break; - - arguments.array[arguments.used].string = argument.string; - arguments.array[arguments.used].size = argument.size; - arguments.array[arguments.used].used = argument.used; - arguments.used++; - argument.string = f_null; - argument.size = 0; - argument.used = 0; - } - - if (action != firewall_action_none_id) { - if (custom_chain != f_null) { - f_resize_dynamic_string(status, argument, custom_chain->used); - - if (f_macro_test_for_allocation_errors(status)) break; - - strncat(argument.string, custom_chain->string, custom_chain->used); - argument.used = custom_chain->used; - } else if (direction == firewall_direction_forward_id) { - f_resize_dynamic_string(status, argument, firewall_direction_forward_command_length); - - if (f_macro_test_for_allocation_errors(status)) break; - - strncat(argument.string, firewall_direction_forward_command, firewall_direction_forward_command_length); - argument.used = firewall_direction_forward_command_length; - } else if (direction == firewall_direction_postrouting_id) { - f_resize_dynamic_string(status, argument, firewall_direction_postrouting_command_length); - - if (f_macro_test_for_allocation_errors(status)) break; - - strncat(argument.string, firewall_direction_postrouting_command, firewall_direction_postrouting_command_length); - argument.used += firewall_direction_postrouting_command_length; - } else if (direction == firewall_direction_prerouting_id) { - f_resize_dynamic_string(status, argument, firewall_direction_prerouting_command_length); - - if (f_macro_test_for_allocation_errors(status)) break; - - strncat(argument.string, firewall_direction_prerouting_command, firewall_direction_prerouting_command_length); - argument.used = firewall_direction_prerouting_command_length; - } else if (direction_input) { - f_resize_dynamic_string(status, argument, firewall_direction_input_command_length); - - if (f_macro_test_for_allocation_errors(status)) break; - - strncat(argument.string, firewall_direction_input_command, firewall_direction_input_command_length); - argument.used = firewall_direction_input_command_length; - } else if (direction_output) { - f_resize_dynamic_string(status, argument, firewall_direction_output_command_length); - - if (f_macro_test_for_allocation_errors(status)) break; - - strncat(argument.string, firewall_direction_output_command, firewall_direction_output_command_length); - argument.used = firewall_direction_output_command_length; - } - } - - if (argument.used > 0) { - f_resize_dynamic_strings(status, arguments, arguments.used + 1); - - if (f_macro_test_for_allocation_errors(status)) break; - - arguments.array[arguments.used].string = argument.string; - arguments.array[arguments.used].size = argument.size; - arguments.array[arguments.used].used = argument.used; - arguments.used++; - argument.string = f_null; - argument.size = 0; - argument.used = 0; - } - - if (device.used > 0) { - if (length < firewall_device_all_length || fl_compare_strings(buffer.string + contents.array[counter].array[0].start, (f_string) firewall_device_all, length, firewall_device_all_length) == f_not_equal_to) { - if (direction_input) { - f_resize_dynamic_string(status, argument, firewall_device_input_command_length); - if (f_macro_test_for_allocation_errors(status)) break; - - strncat(argument.string, firewall_device_input_command, firewall_device_input_command_length); - argument.used = firewall_device_input_command_length; - } else if (direction_output) { - f_resize_dynamic_string(status, argument, firewall_device_output_command_length); - if (f_macro_test_for_allocation_errors(status)) break; - - strncat(argument.string, firewall_device_output_command, firewall_device_output_command_length); - argument.used = firewall_device_output_command_length; - } - } - - if (argument.used > 0) { - f_resize_dynamic_strings(status, arguments, arguments.used + 1); - - if (f_macro_test_for_allocation_errors(status)) break; - - arguments.array[arguments.used].string = argument.string; - arguments.array[arguments.used].size = argument.size; - arguments.array[arguments.used].used = argument.used; - arguments.used++; - argument.string = f_null; - argument.size = 0; - argument.used = 0; - } - - if (direction_input || direction_output) { - f_resize_dynamic_string(status, argument, device.used); - if (f_macro_test_for_allocation_errors(status)) break; - - strncat(argument.string, device.string, device.used); - argument.used = device.used; - } - } - - if (argument.used > 0) { - f_resize_dynamic_strings(status, arguments, arguments.used + 1); - - if (f_macro_test_for_allocation_errors(status)) break; - - arguments.array[arguments.used].string = argument.string; - arguments.array[arguments.used].size = argument.size; - arguments.array[arguments.used].used = argument.used; - arguments.used++; - argument.string = f_null; - argument.size = 0; - argument.used = 0; - } - - // last up is the "rule" - if ((!is_ip_list && contents.array[counter].used > 0) || (is_ip_list && contents.array[counter].used > 1)) { - f_string_length subcounter = f_string_length_initialize; - - if (is_ip_list) { - // skip past the direction - subcounter++; - - length = (contents.array[counter].array[subcounter].stop - contents.array[counter].array[subcounter].start) + 1; - - f_resize_dynamic_string(status, ip_list, length); - - if (f_macro_test_for_allocation_errors(status)) { - subcounter = contents.array[counter].used; - } else { - strncat(ip_list.string, buffer.string + contents.array[counter].array[subcounter].start, length); - ip_list.used = length; - - subcounter++; - } - } - - for (; subcounter < contents.array[counter].used; subcounter++) { - length = (contents.array[counter].array[subcounter].stop - contents.array[counter].array[subcounter].start) + 1; - - f_resize_dynamic_string(status, argument, length); - - if (f_macro_test_for_allocation_errors(status)) break; - - strncat(argument.string, buffer.string + contents.array[counter].array[subcounter].start, length); - argument.used = length; - - if (length > 0) { - f_resize_dynamic_strings(status, arguments, arguments.used + 1); - - if (f_macro_test_for_allocation_errors(status)) break; - - arguments.array[arguments.used].string = argument.string; - arguments.array[arguments.used].size = argument.size; - arguments.array[arguments.used].used = argument.used; - arguments.used++; - argument.string = f_null; - argument.size = 0; - argument.used = 0; - } - } - } else { - length = (objects.array[counter].stop - objects.array[counter].start) + 1; - - fl_print_color_code(f_standard_warning, data.context.warning); - fprintf(f_standard_warning, "WARNING: At line %u, the object '", (unsigned int) counter); - f_print_string(f_standard_warning, buffer.string + objects.array[counter].start, objects.array[counter].stop - objects.array[counter].start + 1); - fprintf(f_standard_warning, "' has no content"); - fl_print_color_code(f_standard_warning, data.context.reset); - fprintf(f_standard_warning, "\n"); - - break; - } - - if (arguments.used > 1) { - if (is_ip_list) { - f_file file = f_file_initialize; - f_dynamic_string file_path = f_dynamic_string_initialize; - f_dynamic_string local_buffer = f_dynamic_string_initialize; - f_file_position file_position = f_file_position_initialize; - - f_fss_objects basic_objects = f_fss_objects_initialize; - f_fss_contents basic_contents = f_fss_objects_initialize; - - f_resize_dynamic_string(status, file_path, network_path_length + ip_list.used + 1); - - if (status == f_none) { - strncat(file_path.string, network_path, network_path_length); - strncat(file_path.string + network_path_length, ip_list.string, ip_list.used); - file_path.used = file_path.size; - file_path.string[file_path.used] = 0; - - status = f_file_open(&file, file_path.string); - } - - if (status != f_none) { - if (status == f_invalid_parameter) { - fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "INTERNAL ERROR: Invalid parameter when calling f_file_open()"); - } else if (status == f_file_not_found) { - // the file does not have to exist - fl_print_color_line(f_standard_warning, data.context.warning, data.context.reset, "WARNING: Cannot find the file '%s'", file_path.string); - status = f_none; - } else if (status == f_file_open_error) { - fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "ERROR: Unable to open the file '%s'", file_path.string); - } else if (status == f_file_descriptor_error) { - fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "ERROR: File descriptor error while trying to open the file '%s'", file_path.string); - } else if (f_macro_test_for_allocation_errors(status)) { - fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "CRITICAL ERROR: unable to allocate memory", status); - } else { - fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "INTERNAL ERROR: An unhandled error (%u) has occured while calling f_file_open()", status); - } - - f_file_close(&file); - } else { - if (file_position.total_elements == 0) { - fseek(file.file, 0, SEEK_END); - file_position.total_elements = ftell(file.file); - fseek(file.file, 0, SEEK_SET); - } - - status = fl_file_read(file, file_position, &local_buffer); - - f_file_close(&file); - - if (status != f_none && status != f_none_on_eof) { - if (status == f_invalid_parameter) { - fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "INTERNAL ERROR: Invalid parameter when calling fl_file_read()"); - } else if (status == f_overflow) { - fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "ERROR: Integer overflow while trying to buffer the file '%s'", file_path.string); - } else if (status == f_file_not_open) { - fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "INTERNAL ERROR: The file '%s' is no longer open", file_path.string); - } else if (status == f_file_seek_error) { - fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "ERROR: A seek error occurred while accessing the file '%s'", file_path.string); - } else if (status == f_file_read_error) { - fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "ERROR: A read error occurred while accessing the file '%s'", file_path.string); - } else if (f_macro_test_for_allocation_errors(status)) { - fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "CRITICAL ERROR: unable to allocate memory", status); - } else { - fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "INTERNAL ERROR: An unhandled error (%u) has occured while calling fl_file_read()", status); - } - } else { - { - f_string_location input = f_string_location_initialize; - - input.stop = local_buffer.used - 1; - - status = fll_fss_basic_read(&local_buffer, &input, &basic_objects, &basic_contents); - } - - if (status != f_none && status != f_none_on_eos && status != f_none_on_stop && status != fl_fss_found_object_no_content) { - 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_fss_basic_read() for the file '%s'", file_path.string); - } else if (status == f_no_data_on_eos || status == f_no_data || status == f_no_data_on_stop) { - // empty files are to be silently ignored - } else if (f_macro_test_for_allocation_errors(status)) { - fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "CRITICAL ERROR: unable to allocate memory", status); - } 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_fss_basic_read() for the file '%s'", status, file_path.string); - } - } else { - f_string_length buffer_counter = f_string_length_initialize; - f_string_length ip_length = f_string_length_initialize; - f_dynamic_string ip_argument = f_dynamic_string_initialize; - f_dynamic_string ip_list_action = f_dynamic_string_initialize; - - if (ip_list_direction) { - f_resize_dynamic_string(status, ip_list_action, firewall_ip_list_destination_action_length + 1); - strncat(ip_list_action.string, firewall_ip_list_destination_action, firewall_ip_list_destination_action_length); - } else { - f_resize_dynamic_string(status, ip_list_action, firewall_ip_list_source_action_length + 1); - strncat(ip_list_action.string, firewall_ip_list_source_action, firewall_ip_list_source_action_length); - } - - ip_list_action.used = ip_list_action.size; - ip_list_action.string[ip_list_action.used] = 0; - - if (f_macro_test_for_allocation_errors(status)) { - fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "CRITICAL ERROR: unable to allocate memory", status); - } else { - ip_list_action.used = ip_list_action.size; - - f_resize_dynamic_strings(status, arguments, arguments.used + 2); - - if (f_macro_test_for_allocation_errors(status)) { - fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "CRITICAL ERROR: unable to allocate memory", status); - } else { - arguments.array[arguments.used].string = ip_list_action.string; - arguments.array[arguments.used].size = ip_list_action.size; - arguments.array[arguments.used].used = ip_list_action.used; - arguments.used++; - - // the ip_list file contains objects and no content, all objects are what matter an nothing else - for (; buffer_counter < basic_objects.used; buffer_counter++) { - ip_length = (basic_objects.array[buffer_counter].stop - basic_objects.array[buffer_counter].start) + 1; - - f_resize_dynamic_string(status, ip_argument, ip_length); - - if (f_macro_test_for_allocation_errors(status)) { - fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "CRITICAL ERROR: unable to allocate memory", status); - break; - } - - strncat(ip_argument.string, local_buffer.string + basic_objects.array[buffer_counter].start, ip_length); - ip_argument.used = ip_argument.size; - ip_argument.string[ip_argument.used] = 0; - - arguments.array[arguments.used].string = ip_argument.string; - arguments.array[arguments.used].size = ip_argument.size; - arguments.array[arguments.used].used = ip_argument.used; - arguments.used++; - - status = fll_execute_program((f_string) firewall_program_name, arguments, &results); - - if (status == f_failure) { - fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "ERROR: Failed to perform requested %s operation:", firewall_program_name); - fprintf(f_standard_error, " "); - - f_string_length i = f_string_length_initialize; - - fl_print_color_code(f_standard_error, data.context.error); - - for (; i < arguments.used; i++) { - fprintf(f_standard_error, "%s ", arguments.array[i].string); - } - - fl_print_color_code(f_standard_error, data.context.reset); - fprintf(f_standard_error, "\n"); - - arguments.used--; - arguments.array[arguments.used].string = 0; - arguments.array[arguments.used].size = 0; - arguments.array[arguments.used].used = 0; - - break; - } 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 fl_execute_path()"); - - arguments.used--; - arguments.array[arguments.used].string = 0; - arguments.array[arguments.used].size = 0; - arguments.array[arguments.used].used = 0; - - break; - } - - arguments.used--; - arguments.array[arguments.used].string = 0; - arguments.array[arguments.used].size = 0; - arguments.array[arguments.used].used = 0; - - f_delete_dynamic_string(allocation_status, ip_argument); - } - } - } - - f_delete_dynamic_string(allocation_status, ip_argument); - f_delete_dynamic_string(allocation_status, ip_list_action); - - arguments.used--; - arguments.array[arguments.used].string = 0; - arguments.array[arguments.used].size = 0; - arguments.array[arguments.used].used = 0; - } - } - } - - f_delete_dynamic_string(allocation_status, local_buffer); - f_delete_dynamic_string(allocation_status, file_path); - f_delete_fss_objects(allocation_status, basic_objects); - f_delete_fss_contents(allocation_status, basic_contents); - - if (status == f_failure || status == f_invalid_parameter) break; - } else { - status = fll_execute_program((f_string) firewall_program_name, arguments, &results); - - if (status == f_failure) { - fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "ERROR: Failed to perform requested %s operation:", firewall_program_name); - fprintf(f_standard_error, " "); - - f_string_length i = f_string_length_initialize; - - fl_print_color_code(f_standard_error, data.context.error); - - for (; i < arguments.used; i++) { - fprintf(f_standard_error, "%s ", arguments.array[i].string); - } - - fl_print_color_code(f_standard_error, data.context.reset); - fprintf(f_standard_error, "\n"); - - break; - } 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 fl_execute_path()"); - break; - } - } - } - } - - f_delete_dynamic_string(allocation_status, ip_list); - f_delete_dynamic_string(allocation_status, argument); - f_delete_dynamic_strings(allocation_status, arguments); - f_delete_dynamic_string(allocation_status, device); - - return status; - } #endif // _di_firewall_main_ #ifndef _di_firewall_delete_data_ diff --git a/level_3/firewall/c/private-firewall.c b/level_3/firewall/c/private-firewall.c new file mode 100644 index 0000000..b846bde --- /dev/null +++ b/level_3/firewall/c/private-firewall.c @@ -0,0 +1,706 @@ +/** + * Private source file for firewall.c. + */ +#include + +#ifndef _di_firewall_main_ + f_return_status firewall_perform_commands(const f_fss_objects objects, const f_fss_contents contents, const f_bool is_global, const f_string_length this_device, const f_dynamic_string buffer, const firewall_data data, const f_dynamic_string *custom_chain) { + f_status status = f_status_initialize; + f_status allocation_status = f_status_initialize; + + f_string_length counter = f_string_length_initialize; + f_dynamic_string argument = f_dynamic_string_initialize; + f_dynamic_strings arguments = f_dynamic_strings_initialize; + + f_s_int results = 0; + f_string_length length = f_string_length_initialize; + f_bool invalid = f_false; + f_bool is_ip_list = f_false; + f_dynamic_string ip_list = f_dynamic_string_initialize; + + // iptables command arguments + f_bool direction_input = f_true; + f_bool direction_output = f_false; + f_bool device_all = f_false; + f_bool ip_list_direction = f_false; // false = source, true = destination + + f_string_length direction = firewall_direction_none_id; + f_dynamic_string device = f_dynamic_string_initialize; + f_string_length action = firewall_action_append_id; + + if (is_global) { + device_all = f_true; + } else { + f_resize_dynamic_string(status, device, data.devices.array[this_device].used); + + if (f_macro_test_for_allocation_errors(status)) { + f_delete_dynamic_string(allocation_status, device); + + return status; + } + + strncat(device.string, data.devices.array[this_device].string, data.devices.array[this_device].used); + device.used = data.devices.array[this_device].used; + } + + for (; counter < objects.used; counter++) { + length = (objects.array[counter].stop - objects.array[counter].start) + 1; + invalid = f_false; + + is_ip_list = f_false; + ip_list_direction = f_false; + + f_delete_dynamic_string(allocation_status, ip_list); + + if (length >= firewall_direction_length && fl_compare_strings(buffer.string + objects.array[counter].start, (f_string) firewall_direction, length, firewall_direction_length) == f_equal_to) { + length = (contents.array[counter].array[0].stop - contents.array[counter].array[0].start) + 1; + + if (contents.array[counter].used <= 0 || contents.array[counter].used > 1) { + invalid = f_true; + } else { + if (length < firewall_direction_input_length || fl_compare_strings(buffer.string + contents.array[counter].array[0].start, (f_string) firewall_direction_input, length, firewall_direction_input_length) == f_not_equal_to) { + if (length < firewall_direction_output_length || fl_compare_strings(buffer.string + contents.array[counter].array[0].start, (f_string) firewall_direction_output, length, firewall_direction_output_length) == f_not_equal_to) { + if (length < firewall_direction_forward_length || fl_compare_strings(buffer.string + contents.array[counter].array[0].start, (f_string) firewall_direction_forward, length, firewall_direction_forward_length) == f_not_equal_to) { + if (length < firewall_direction_postrouting_length || fl_compare_strings(buffer.string + contents.array[counter].array[0].start, (f_string) firewall_direction_postrouting, length, firewall_direction_postrouting_length) == f_not_equal_to) { + if (length < firewall_direction_prerouting_length || fl_compare_strings(buffer.string + contents.array[counter].array[0].start, (f_string) firewall_direction_prerouting, length, firewall_direction_prerouting_length) == f_not_equal_to) { + if (length < firewall_direction_none_length || fl_compare_strings(buffer.string + contents.array[counter].array[0].start, (f_string) firewall_direction_none, length, firewall_direction_none_length) == f_not_equal_to) { + if (length < firewall_direction_forward_input_length || fl_compare_strings(buffer.string + contents.array[counter].array[0].start, (f_string) firewall_direction_forward_input, length, firewall_direction_forward_input_length) == f_not_equal_to) { + if (length < firewall_direction_forward_output_length || fl_compare_strings(buffer.string + contents.array[counter].array[0].start, (f_string) firewall_direction_forward_output, length, firewall_direction_forward_output_length) == f_not_equal_to) { + if (length < firewall_direction_postrouting_input_length || fl_compare_strings(buffer.string + contents.array[counter].array[0].start, (f_string) firewall_direction_postrouting_input, length, firewall_direction_postrouting_input_length) == f_not_equal_to) { + if (length < firewall_direction_postrouting_output_length || fl_compare_strings(buffer.string + contents.array[counter].array[0].start, (f_string) firewall_direction_postrouting_output, length, firewall_direction_postrouting_output_length) == f_not_equal_to) { + if (length < firewall_direction_prerouting_input_length || fl_compare_strings(buffer.string + contents.array[counter].array[0].start, (f_string) firewall_direction_prerouting_input, length, firewall_direction_prerouting_input_length) == f_not_equal_to) { + if (length < firewall_direction_prerouting_output_length || fl_compare_strings(buffer.string + contents.array[counter].array[0].start, (f_string) firewall_direction_prerouting_output, length, firewall_direction_prerouting_output_length) == f_not_equal_to) { + invalid = f_true; + } else { + direction_input = f_false; + direction_output = f_true; + direction = firewall_direction_prerouting_id; + } + } else { + direction_input = f_true; + direction_output = f_false; + direction = firewall_direction_prerouting_id; + } + } else { + direction_input = f_false; + direction_output = f_true; + direction = firewall_direction_postrouting_id; + } + } else { + direction_input = f_true; + direction_output = f_false; + direction = firewall_direction_postrouting_id; + } + } else { + direction_input = f_false; + direction_output = f_true; + direction = firewall_direction_forward_id; + } + } else { + direction_input = f_true; + direction_output = f_false; + direction = firewall_direction_forward_id; + } + } else { + direction_input = f_false; + direction_output = f_false; + direction = firewall_direction_none_id; + } + } else { + direction_input = f_false; + direction_output = f_false; + direction = firewall_direction_postrouting_id; + } + } else { + direction_input = f_false; + direction_output = f_false; + direction = firewall_direction_prerouting_id; + } + } else { + direction_input = f_false; + direction_output = f_false; + direction = firewall_direction_forward_id; + } + } else { + direction_input = f_false; + direction_output = f_true; + direction = firewall_direction_none_id; + } + } else { + direction_input = f_true; + direction_output = f_false; + direction = firewall_direction_none_id; + } + } + + if (!invalid) continue; + } else if (length >= firewall_device_length && fl_compare_strings(buffer.string + objects.array[counter].start, (f_string) firewall_device, length, firewall_device_length) == f_equal_to) { + length = (contents.array[counter].array[0].stop - contents.array[counter].array[0].start) + 1; + + if (contents.array[counter].used <= 0 || contents.array[counter].used > 1) { + invalid = f_true; + } else if (length >= firewall_device_all_length && fl_compare_strings(buffer.string + contents.array[counter].array[0].start, (f_string) firewall_device_all, length, firewall_device_all_length) == f_equal_to) { + f_delete_dynamic_string(status, device); + device_all = f_true; + continue; + } else if (length >= firewall_device_this_length && fl_compare_strings(buffer.string + contents.array[counter].array[0].start, (f_string) firewall_device_this, length, firewall_device_this_length) == f_equal_to) { + f_delete_dynamic_string(status, device); + f_resize_dynamic_string(status, device, data.devices.array[this_device].used); + + if (f_macro_test_for_allocation_errors(status)) break; + + strncat(device.string, data.devices.array[this_device].string, data.devices.array[this_device].used); + device.used = data.devices.array[this_device].used; + device_all = f_false; + continue; + } + + if (!invalid) { + f_delete_dynamic_string(status, device); + f_resize_dynamic_string(status, device, length); + + if (f_macro_test_for_allocation_errors(status)) break; + + strncat(device.string, buffer.string + contents.array[counter].array[0].start, length); + device.used = length; + device_all = f_false; + continue; + } + } else if (length >= firewall_action_length && fl_compare_strings(buffer.string + objects.array[counter].start, (f_string) firewall_action, length, firewall_action_length) == f_equal_to) { + length = (contents.array[counter].array[0].stop - contents.array[counter].array[0].start) + 1; + + if (contents.array[counter].used <= 0 || contents.array[counter].used > 1) { + invalid = f_true; + } else if (length < firewall_action_append_length || fl_compare_strings(buffer.string + contents.array[counter].array[0].start, (f_string) firewall_action_append, length, firewall_action_append_length) == f_not_equal_to) { + if (length < firewall_action_insert_length || fl_compare_strings(buffer.string + contents.array[counter].array[0].start, (f_string) firewall_action_insert, length, firewall_action_insert_length) == f_not_equal_to) { + if (length < firewall_action_policy_length || fl_compare_strings(buffer.string + contents.array[counter].array[0].start, (f_string) firewall_action_policy, length, firewall_action_policy_length) == f_not_equal_to) { + if (length < firewall_action_none_length || fl_compare_strings(buffer.string + contents.array[counter].array[0].start, (f_string) firewall_action_none, length, firewall_action_none_length) == f_not_equal_to) { + invalid = f_true; + } else { + action = firewall_action_none_id; + } + } else { + action = firewall_action_policy_id; + } + } else { + action = firewall_action_insert_id; + } + } else { + action = firewall_action_append_id; + } + + if (!invalid) continue; + } else if (length >= firewall_ip_list_length && fl_compare_strings(buffer.string + objects.array[counter].start, (f_string) firewall_ip_list, length, firewall_ip_list_length) == f_equal_to) { + length = (contents.array[counter].array[0].stop - contents.array[counter].array[0].start) + 1; + is_ip_list = f_true; + + if (length >= firewall_ip_list_source_length && fl_compare_strings(buffer.string + contents.array[counter].array[0].start, (f_string) firewall_ip_list_source, length, firewall_ip_list_source_length) == f_equal_to) { + ip_list_direction = f_false; + } else if (length >= firewall_ip_list_destination_length && fl_compare_strings(buffer.string + contents.array[counter].array[0].start, (f_string) firewall_ip_list_destination, length, firewall_ip_list_destination_length) == f_equal_to) { + ip_list_direction = f_true; + } else { + invalid = f_true; + } + } else if (length < firewall_rule_length || fl_compare_strings(buffer.string + objects.array[counter].start, (f_string) firewall_rule, length, firewall_rule_length) == f_not_equal_to) { + if (length > 0) { + fl_print_color_code(f_standard_warning, data.context.warning); + fprintf(f_standard_warning, "WARNING: At line %u, the object '", (unsigned int) counter); + f_print_string(f_standard_warning, buffer.string + objects.array[counter].start, length); + fprintf(f_standard_warning, "' is invalid"); + fl_print_color_code(f_standard_warning, data.context.reset); + } else { + fprintf(f_standard_warning, "WARNING: At line %u, the object is missing", (unsigned int) counter); + } + + fprintf(f_standard_warning, "\n"); + continue; + } + + if (invalid) { + length = (objects.array[counter].stop - objects.array[counter].start) + 1; + + if (length > 0) { + fl_print_color_code(f_standard_warning, data.context.warning); + fprintf(f_standard_warning, "WARNING: At line %u, the object '", (unsigned int) counter); + f_print_string(f_standard_warning, buffer.string + objects.array[counter].start, length); + fprintf(f_standard_warning, "' has invalid content '"); + f_print_string(f_standard_warning, buffer.string + contents.array[counter].array[0].start, contents.array[counter].array[0].stop - contents.array[counter].array[0].start + 1); + fprintf(f_standard_warning, "'"); + fl_print_color_code(f_standard_warning, data.context.reset); + fprintf(f_standard_warning, "\n"); + } else { + fl_print_color_line(f_standard_warning, data.context.warning, data.context.reset, "WARNING: At line %u, the object has no content", (unsigned int) counter); + } + + continue; + } + + + // first add the program name + f_delete_dynamic_strings(status, arguments); + f_resize_dynamic_strings(status, arguments, arguments.used + 1); + + if (f_macro_test_for_allocation_errors(status)) break; + + f_resize_dynamic_string(status, argument, firewall_program_name_length); + + if (f_macro_test_for_allocation_errors(status)) break; + + strncat(argument.string, firewall_program_name, firewall_program_name_length); + argument.used = firewall_program_name_length; + + arguments.array[arguments.used].string = argument.string; + arguments.array[arguments.used].size = argument.size; + arguments.array[arguments.used].used = argument.used; + arguments.used++; + argument.string = f_null; + argument.size = 0; + argument.used = 0; + + + // FIXME: (this issue is probably everywhere) Implement an strncat function for dynamic strings or if I already have one implement, make sure it is used in every applicable place + // (this way I can automatically handle updating the used buffer) + // also look into auto-allocated space if necessary with the said function + if (action == firewall_action_append_id) { + f_resize_dynamic_string(status, argument, firewall_action_append_command_length); + + if (f_macro_test_for_allocation_errors(status)) break; + + strncat(argument.string, firewall_action_append_command, firewall_action_append_command_length); + argument.used = firewall_action_append_command_length; + } else if (action == firewall_action_insert_id) { + f_resize_dynamic_string(status, argument, firewall_action_insert_command_length); + + if (f_macro_test_for_allocation_errors(status)) break; + + strncat(argument.string, firewall_action_insert_command, firewall_action_insert_command_length); + argument.used = firewall_action_insert_command_length; + } else if (action == firewall_action_policy_id) { + f_resize_dynamic_string(status, argument, firewall_action_policy_command_length); + + if (f_macro_test_for_allocation_errors(status)) break; + + strncat(argument.string, firewall_action_policy_command, firewall_action_policy_command_length); + argument.used = firewall_action_policy_command_length; + } + + if (argument.used > 0) { + f_resize_dynamic_strings(status, arguments, arguments.used + 1); + + if (f_macro_test_for_allocation_errors(status)) break; + + arguments.array[arguments.used].string = argument.string; + arguments.array[arguments.used].size = argument.size; + arguments.array[arguments.used].used = argument.used; + arguments.used++; + argument.string = f_null; + argument.size = 0; + argument.used = 0; + } + + if (action != firewall_action_none_id) { + if (custom_chain != f_null) { + f_resize_dynamic_string(status, argument, custom_chain->used); + + if (f_macro_test_for_allocation_errors(status)) break; + + strncat(argument.string, custom_chain->string, custom_chain->used); + argument.used = custom_chain->used; + } else if (direction == firewall_direction_forward_id) { + f_resize_dynamic_string(status, argument, firewall_direction_forward_command_length); + + if (f_macro_test_for_allocation_errors(status)) break; + + strncat(argument.string, firewall_direction_forward_command, firewall_direction_forward_command_length); + argument.used = firewall_direction_forward_command_length; + } else if (direction == firewall_direction_postrouting_id) { + f_resize_dynamic_string(status, argument, firewall_direction_postrouting_command_length); + + if (f_macro_test_for_allocation_errors(status)) break; + + strncat(argument.string, firewall_direction_postrouting_command, firewall_direction_postrouting_command_length); + argument.used += firewall_direction_postrouting_command_length; + } else if (direction == firewall_direction_prerouting_id) { + f_resize_dynamic_string(status, argument, firewall_direction_prerouting_command_length); + + if (f_macro_test_for_allocation_errors(status)) break; + + strncat(argument.string, firewall_direction_prerouting_command, firewall_direction_prerouting_command_length); + argument.used = firewall_direction_prerouting_command_length; + } else if (direction_input) { + f_resize_dynamic_string(status, argument, firewall_direction_input_command_length); + + if (f_macro_test_for_allocation_errors(status)) break; + + strncat(argument.string, firewall_direction_input_command, firewall_direction_input_command_length); + argument.used = firewall_direction_input_command_length; + } else if (direction_output) { + f_resize_dynamic_string(status, argument, firewall_direction_output_command_length); + + if (f_macro_test_for_allocation_errors(status)) break; + + strncat(argument.string, firewall_direction_output_command, firewall_direction_output_command_length); + argument.used = firewall_direction_output_command_length; + } + } + + if (argument.used > 0) { + f_resize_dynamic_strings(status, arguments, arguments.used + 1); + + if (f_macro_test_for_allocation_errors(status)) break; + + arguments.array[arguments.used].string = argument.string; + arguments.array[arguments.used].size = argument.size; + arguments.array[arguments.used].used = argument.used; + arguments.used++; + argument.string = f_null; + argument.size = 0; + argument.used = 0; + } + + if (device.used > 0) { + if (length < firewall_device_all_length || fl_compare_strings(buffer.string + contents.array[counter].array[0].start, (f_string) firewall_device_all, length, firewall_device_all_length) == f_not_equal_to) { + if (direction_input) { + f_resize_dynamic_string(status, argument, firewall_device_input_command_length); + if (f_macro_test_for_allocation_errors(status)) break; + + strncat(argument.string, firewall_device_input_command, firewall_device_input_command_length); + argument.used = firewall_device_input_command_length; + } else if (direction_output) { + f_resize_dynamic_string(status, argument, firewall_device_output_command_length); + if (f_macro_test_for_allocation_errors(status)) break; + + strncat(argument.string, firewall_device_output_command, firewall_device_output_command_length); + argument.used = firewall_device_output_command_length; + } + } + + if (argument.used > 0) { + f_resize_dynamic_strings(status, arguments, arguments.used + 1); + + if (f_macro_test_for_allocation_errors(status)) break; + + arguments.array[arguments.used].string = argument.string; + arguments.array[arguments.used].size = argument.size; + arguments.array[arguments.used].used = argument.used; + arguments.used++; + argument.string = f_null; + argument.size = 0; + argument.used = 0; + } + + if (direction_input || direction_output) { + f_resize_dynamic_string(status, argument, device.used); + if (f_macro_test_for_allocation_errors(status)) break; + + strncat(argument.string, device.string, device.used); + argument.used = device.used; + } + } + + if (argument.used > 0) { + f_resize_dynamic_strings(status, arguments, arguments.used + 1); + + if (f_macro_test_for_allocation_errors(status)) break; + + arguments.array[arguments.used].string = argument.string; + arguments.array[arguments.used].size = argument.size; + arguments.array[arguments.used].used = argument.used; + arguments.used++; + argument.string = f_null; + argument.size = 0; + argument.used = 0; + } + + // last up is the "rule" + if ((!is_ip_list && contents.array[counter].used > 0) || (is_ip_list && contents.array[counter].used > 1)) { + f_string_length subcounter = f_string_length_initialize; + + if (is_ip_list) { + // skip past the direction + subcounter++; + + length = (contents.array[counter].array[subcounter].stop - contents.array[counter].array[subcounter].start) + 1; + + f_resize_dynamic_string(status, ip_list, length); + + if (f_macro_test_for_allocation_errors(status)) { + subcounter = contents.array[counter].used; + } else { + strncat(ip_list.string, buffer.string + contents.array[counter].array[subcounter].start, length); + ip_list.used = length; + + subcounter++; + } + } + + for (; subcounter < contents.array[counter].used; subcounter++) { + length = (contents.array[counter].array[subcounter].stop - contents.array[counter].array[subcounter].start) + 1; + + f_resize_dynamic_string(status, argument, length); + + if (f_macro_test_for_allocation_errors(status)) break; + + strncat(argument.string, buffer.string + contents.array[counter].array[subcounter].start, length); + argument.used = length; + + if (length > 0) { + f_resize_dynamic_strings(status, arguments, arguments.used + 1); + + if (f_macro_test_for_allocation_errors(status)) break; + + arguments.array[arguments.used].string = argument.string; + arguments.array[arguments.used].size = argument.size; + arguments.array[arguments.used].used = argument.used; + arguments.used++; + argument.string = f_null; + argument.size = 0; + argument.used = 0; + } + } + } else { + length = (objects.array[counter].stop - objects.array[counter].start) + 1; + + fl_print_color_code(f_standard_warning, data.context.warning); + fprintf(f_standard_warning, "WARNING: At line %u, the object '", (unsigned int) counter); + f_print_string(f_standard_warning, buffer.string + objects.array[counter].start, objects.array[counter].stop - objects.array[counter].start + 1); + fprintf(f_standard_warning, "' has no content"); + fl_print_color_code(f_standard_warning, data.context.reset); + fprintf(f_standard_warning, "\n"); + + break; + } + + if (arguments.used > 1) { + if (is_ip_list) { + f_file file = f_file_initialize; + f_dynamic_string file_path = f_dynamic_string_initialize; + f_dynamic_string local_buffer = f_dynamic_string_initialize; + f_file_position file_position = f_file_position_initialize; + + f_fss_objects basic_objects = f_fss_objects_initialize; + f_fss_contents basic_contents = f_fss_objects_initialize; + + f_resize_dynamic_string(status, file_path, network_path_length + ip_list.used + 1); + + if (status == f_none) { + strncat(file_path.string, network_path, network_path_length); + strncat(file_path.string + network_path_length, ip_list.string, ip_list.used); + file_path.used = file_path.size; + file_path.string[file_path.used] = 0; + + status = f_file_open(&file, file_path.string); + } + + if (status != f_none) { + if (status == f_invalid_parameter) { + fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "INTERNAL ERROR: Invalid parameter when calling f_file_open()"); + } else if (status == f_file_not_found) { + // the file does not have to exist + fl_print_color_line(f_standard_warning, data.context.warning, data.context.reset, "WARNING: Cannot find the file '%s'", file_path.string); + status = f_none; + } else if (status == f_file_open_error) { + fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "ERROR: Unable to open the file '%s'", file_path.string); + } else if (status == f_file_descriptor_error) { + fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "ERROR: File descriptor error while trying to open the file '%s'", file_path.string); + } else if (f_macro_test_for_allocation_errors(status)) { + fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "CRITICAL ERROR: unable to allocate memory", status); + } else { + fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "INTERNAL ERROR: An unhandled error (%u) has occured while calling f_file_open()", status); + } + + f_file_close(&file); + } else { + if (file_position.total_elements == 0) { + fseek(file.file, 0, SEEK_END); + file_position.total_elements = ftell(file.file); + fseek(file.file, 0, SEEK_SET); + } + + status = fl_file_read(file, file_position, &local_buffer); + + f_file_close(&file); + + if (status != f_none && status != f_none_on_eof) { + if (status == f_invalid_parameter) { + fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "INTERNAL ERROR: Invalid parameter when calling fl_file_read()"); + } else if (status == f_overflow) { + fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "ERROR: Integer overflow while trying to buffer the file '%s'", file_path.string); + } else if (status == f_file_not_open) { + fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "INTERNAL ERROR: The file '%s' is no longer open", file_path.string); + } else if (status == f_file_seek_error) { + fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "ERROR: A seek error occurred while accessing the file '%s'", file_path.string); + } else if (status == f_file_read_error) { + fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "ERROR: A read error occurred while accessing the file '%s'", file_path.string); + } else if (f_macro_test_for_allocation_errors(status)) { + fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "CRITICAL ERROR: unable to allocate memory", status); + } else { + fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "INTERNAL ERROR: An unhandled error (%u) has occured while calling fl_file_read()", status); + } + } else { + { + f_string_location input = f_string_location_initialize; + + input.stop = local_buffer.used - 1; + + status = fll_fss_basic_read(&local_buffer, &input, &basic_objects, &basic_contents); + } + + if (status != f_none && status != f_none_on_eos && status != f_none_on_stop && status != fl_fss_found_object_no_content) { + 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_fss_basic_read() for the file '%s'", file_path.string); + } else if (status == f_no_data_on_eos || status == f_no_data || status == f_no_data_on_stop) { + // empty files are to be silently ignored + } else if (f_macro_test_for_allocation_errors(status)) { + fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "CRITICAL ERROR: unable to allocate memory", status); + } 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_fss_basic_read() for the file '%s'", status, file_path.string); + } + } else { + f_string_length buffer_counter = f_string_length_initialize; + f_string_length ip_length = f_string_length_initialize; + f_dynamic_string ip_argument = f_dynamic_string_initialize; + f_dynamic_string ip_list_action = f_dynamic_string_initialize; + + if (ip_list_direction) { + f_resize_dynamic_string(status, ip_list_action, firewall_ip_list_destination_action_length + 1); + strncat(ip_list_action.string, firewall_ip_list_destination_action, firewall_ip_list_destination_action_length); + } else { + f_resize_dynamic_string(status, ip_list_action, firewall_ip_list_source_action_length + 1); + strncat(ip_list_action.string, firewall_ip_list_source_action, firewall_ip_list_source_action_length); + } + + ip_list_action.used = ip_list_action.size; + ip_list_action.string[ip_list_action.used] = 0; + + if (f_macro_test_for_allocation_errors(status)) { + fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "CRITICAL ERROR: unable to allocate memory", status); + } else { + ip_list_action.used = ip_list_action.size; + + f_resize_dynamic_strings(status, arguments, arguments.used + 2); + + if (f_macro_test_for_allocation_errors(status)) { + fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "CRITICAL ERROR: unable to allocate memory", status); + } else { + arguments.array[arguments.used].string = ip_list_action.string; + arguments.array[arguments.used].size = ip_list_action.size; + arguments.array[arguments.used].used = ip_list_action.used; + arguments.used++; + + // the ip_list file contains objects and no content, all objects are what matter an nothing else + for (; buffer_counter < basic_objects.used; buffer_counter++) { + ip_length = (basic_objects.array[buffer_counter].stop - basic_objects.array[buffer_counter].start) + 1; + + f_resize_dynamic_string(status, ip_argument, ip_length); + + if (f_macro_test_for_allocation_errors(status)) { + fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "CRITICAL ERROR: unable to allocate memory", status); + break; + } + + strncat(ip_argument.string, local_buffer.string + basic_objects.array[buffer_counter].start, ip_length); + ip_argument.used = ip_argument.size; + ip_argument.string[ip_argument.used] = 0; + + arguments.array[arguments.used].string = ip_argument.string; + arguments.array[arguments.used].size = ip_argument.size; + arguments.array[arguments.used].used = ip_argument.used; + arguments.used++; + + status = fll_execute_program((f_string) firewall_program_name, arguments, &results); + + if (status == f_failure) { + fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "ERROR: Failed to perform requested %s operation:", firewall_program_name); + fprintf(f_standard_error, " "); + + f_string_length i = f_string_length_initialize; + + fl_print_color_code(f_standard_error, data.context.error); + + for (; i < arguments.used; i++) { + fprintf(f_standard_error, "%s ", arguments.array[i].string); + } + + fl_print_color_code(f_standard_error, data.context.reset); + fprintf(f_standard_error, "\n"); + + arguments.used--; + arguments.array[arguments.used].string = 0; + arguments.array[arguments.used].size = 0; + arguments.array[arguments.used].used = 0; + + break; + } 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 fl_execute_path()"); + + arguments.used--; + arguments.array[arguments.used].string = 0; + arguments.array[arguments.used].size = 0; + arguments.array[arguments.used].used = 0; + + break; + } + + arguments.used--; + arguments.array[arguments.used].string = 0; + arguments.array[arguments.used].size = 0; + arguments.array[arguments.used].used = 0; + + f_delete_dynamic_string(allocation_status, ip_argument); + } + } + } + + f_delete_dynamic_string(allocation_status, ip_argument); + f_delete_dynamic_string(allocation_status, ip_list_action); + + arguments.used--; + arguments.array[arguments.used].string = 0; + arguments.array[arguments.used].size = 0; + arguments.array[arguments.used].used = 0; + } + } + } + + f_delete_dynamic_string(allocation_status, local_buffer); + f_delete_dynamic_string(allocation_status, file_path); + f_delete_fss_objects(allocation_status, basic_objects); + f_delete_fss_contents(allocation_status, basic_contents); + + if (status == f_failure || status == f_invalid_parameter) break; + } else { + status = fll_execute_program((f_string) firewall_program_name, arguments, &results); + + if (status == f_failure) { + fl_print_color_line(f_standard_error, data.context.error, data.context.reset, "ERROR: Failed to perform requested %s operation:", firewall_program_name); + fprintf(f_standard_error, " "); + + f_string_length i = f_string_length_initialize; + + fl_print_color_code(f_standard_error, data.context.error); + + for (; i < arguments.used; i++) { + fprintf(f_standard_error, "%s ", arguments.array[i].string); + } + + fl_print_color_code(f_standard_error, data.context.reset); + fprintf(f_standard_error, "\n"); + + break; + } 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 fl_execute_path()"); + break; + } + } + } + } + + f_delete_dynamic_string(allocation_status, ip_list); + f_delete_dynamic_string(allocation_status, argument); + f_delete_dynamic_strings(allocation_status, arguments); + f_delete_dynamic_string(allocation_status, device); + + return status; + } +#endif // _di_firewall_main_ diff --git a/level_3/firewall/c/private-firewall.h b/level_3/firewall/c/private-firewall.h new file mode 100644 index 0000000..cd37595 --- /dev/null +++ b/level_3/firewall/c/private-firewall.h @@ -0,0 +1,7 @@ +/** + * Private include file for firewall.c. + */ + +#ifndef _di_firewall_main_ + f_return_status firewall_perform_commands(const f_fss_objects objects, const f_fss_contents contents, const f_bool is_global, const f_string_length this_device, const f_dynamic_string buffer, const firewall_data data, const f_dynamic_string *custom_chain) __attribute__((visibility("internal"))); +#endif // _di_firewall_main_ diff --git a/level_3/firewall/data/build/settings b/level_3/firewall/data/build/settings index 4a71b85..957966a 100644 --- a/level_3/firewall/data/build/settings +++ b/level_3/firewall/data/build/settings @@ -9,7 +9,7 @@ version_micro 0 build_compiler gcc build_libraries -lc -lf_memory -lf_console -lf_conversion -lf_output -lf_file -lfl_fss -lfl_console -lfl_file -lfl_strings -lfl_colors -lfl_directory -lfll_execute -lfll_fss -lfll_colors -lf_pipe -build_sources_library firewall.c +build_sources_library firewall.c private-firewall.c build_sources_program main.c build_sources_headers firewall.h build_shared yes -- 1.8.3.1