* Programmers: Kevin Day
*/
#include <level_3/firewall.h>
+#include "private-firewall.h"
#ifdef __cplusplus
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;
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_
--- /dev/null
+/**
+ * Private source file for firewall.c.
+ */
+#include <level_3/firewall.h>
+
+#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_