| #include <stdlib.h> |
| #include <string.h> |
| |
| #include "port_internal.h" |
| #include "context_internal.h" |
| #include "debug.h" |
| |
| struct sepol_port { |
| /* Low - High range. Same for single ports. */ |
| int low, high; |
| |
| /* Protocol */ |
| int proto; |
| |
| /* Context */ |
| sepol_context_t *con; |
| }; |
| |
| struct sepol_port_key { |
| /* Low - High range. Same for single ports. */ |
| int low, high; |
| |
| /* Protocol */ |
| int proto; |
| }; |
| |
| /* Key */ |
| int sepol_port_key_create(sepol_handle_t * handle, |
| int low, int high, int proto, |
| sepol_port_key_t ** key_ptr) |
| { |
| |
| sepol_port_key_t *tmp_key = |
| (sepol_port_key_t *) malloc(sizeof(sepol_port_key_t)); |
| |
| if (!tmp_key) { |
| ERR(handle, "out of memory, could not create " "port key"); |
| return STATUS_ERR; |
| } |
| |
| tmp_key->low = low; |
| tmp_key->high = high; |
| tmp_key->proto = proto; |
| |
| *key_ptr = tmp_key; |
| return STATUS_SUCCESS; |
| } |
| |
| hidden_def(sepol_port_key_create) |
| |
| void sepol_port_key_unpack(const sepol_port_key_t * key, |
| int *low, int *high, int *proto) |
| { |
| |
| *low = key->low; |
| *high = key->high; |
| *proto = key->proto; |
| } |
| |
| hidden_def(sepol_port_key_unpack) |
| |
| int sepol_port_key_extract(sepol_handle_t * handle, |
| const sepol_port_t * port, |
| sepol_port_key_t ** key_ptr) |
| { |
| |
| if (sepol_port_key_create |
| (handle, port->low, port->high, port->proto, key_ptr) < 0) { |
| |
| ERR(handle, "could not extract key from port %s %d:%d", |
| sepol_port_get_proto_str(port->proto), |
| port->low, port->high); |
| |
| return STATUS_ERR; |
| } |
| |
| return STATUS_SUCCESS; |
| } |
| |
| void sepol_port_key_free(sepol_port_key_t * key) |
| { |
| free(key); |
| } |
| |
| int sepol_port_compare(const sepol_port_t * port, const sepol_port_key_t * key) |
| { |
| |
| if ((port->low == key->low) && |
| (port->high == key->high) && (port->proto == key->proto)) |
| return 0; |
| |
| if (port->low < key->low) |
| return -1; |
| |
| else if (key->low < port->low) |
| return 1; |
| |
| else if (port->high < key->high) |
| return -1; |
| |
| else if (key->high < port->high) |
| return 1; |
| |
| else if (port->proto < key->proto) |
| return -1; |
| |
| else |
| return 1; |
| } |
| |
| int sepol_port_compare2(const sepol_port_t * port, const sepol_port_t * port2) |
| { |
| |
| if ((port->low == port2->low) && |
| (port->high == port2->high) && (port->proto == port2->proto)) |
| return 0; |
| |
| if (port->low < port2->low) |
| return -1; |
| |
| else if (port2->low < port->low) |
| return 1; |
| |
| else if (port->high < port2->high) |
| return -1; |
| |
| else if (port2->high < port->high) |
| return 1; |
| |
| else if (port->proto < port2->proto) |
| return -1; |
| |
| else |
| return 1; |
| } |
| |
| /* Port */ |
| int sepol_port_get_low(const sepol_port_t * port) |
| { |
| |
| return port->low; |
| } |
| |
| hidden_def(sepol_port_get_low) |
| |
| int sepol_port_get_high(const sepol_port_t * port) |
| { |
| |
| return port->high; |
| } |
| |
| hidden_def(sepol_port_get_high) |
| |
| void sepol_port_set_port(sepol_port_t * port, int port_num) |
| { |
| |
| port->low = port_num; |
| port->high = port_num; |
| } |
| |
| void sepol_port_set_range(sepol_port_t * port, int low, int high) |
| { |
| |
| port->low = low; |
| port->high = high; |
| } |
| |
| hidden_def(sepol_port_set_range) |
| |
| /* Protocol */ |
| int sepol_port_get_proto(const sepol_port_t * port) |
| { |
| |
| return port->proto; |
| } |
| |
| hidden_def(sepol_port_get_proto) |
| |
| const char *sepol_port_get_proto_str(int proto) |
| { |
| |
| switch (proto) { |
| case SEPOL_PROTO_UDP: |
| return "udp"; |
| case SEPOL_PROTO_TCP: |
| return "tcp"; |
| default: |
| return "???"; |
| } |
| } |
| |
| hidden_def(sepol_port_get_proto_str) |
| |
| void sepol_port_set_proto(sepol_port_t * port, int proto) |
| { |
| |
| port->proto = proto; |
| } |
| |
| hidden_def(sepol_port_set_proto) |
| |
| /* Create */ |
| int sepol_port_create(sepol_handle_t * handle, sepol_port_t ** port) |
| { |
| |
| sepol_port_t *tmp_port = (sepol_port_t *) malloc(sizeof(sepol_port_t)); |
| |
| if (!tmp_port) { |
| ERR(handle, "out of memory, could not create " "port record"); |
| return STATUS_ERR; |
| } |
| |
| tmp_port->low = 0; |
| tmp_port->high = 0; |
| tmp_port->proto = SEPOL_PROTO_UDP; |
| tmp_port->con = NULL; |
| *port = tmp_port; |
| |
| return STATUS_SUCCESS; |
| } |
| |
| hidden_def(sepol_port_create) |
| |
| /* Deep copy clone */ |
| int sepol_port_clone(sepol_handle_t * handle, |
| const sepol_port_t * port, sepol_port_t ** port_ptr) |
| { |
| |
| sepol_port_t *new_port = NULL; |
| if (sepol_port_create(handle, &new_port) < 0) |
| goto err; |
| |
| new_port->low = port->low; |
| new_port->high = port->high; |
| new_port->proto = port->proto; |
| |
| if (port->con && |
| (sepol_context_clone(handle, port->con, &new_port->con) < 0)) |
| goto err; |
| |
| *port_ptr = new_port; |
| return STATUS_SUCCESS; |
| |
| err: |
| ERR(handle, "could not clone port record"); |
| sepol_port_free(new_port); |
| return STATUS_ERR; |
| } |
| |
| /* Destroy */ |
| void sepol_port_free(sepol_port_t * port) |
| { |
| |
| if (!port) |
| return; |
| |
| sepol_context_free(port->con); |
| free(port); |
| } |
| |
| hidden_def(sepol_port_free) |
| |
| /* Context */ |
| sepol_context_t *sepol_port_get_con(const sepol_port_t * port) |
| { |
| |
| return port->con; |
| } |
| |
| hidden_def(sepol_port_get_con) |
| |
| int sepol_port_set_con(sepol_handle_t * handle, |
| sepol_port_t * port, sepol_context_t * con) |
| { |
| |
| sepol_context_t *newcon; |
| |
| if (sepol_context_clone(handle, con, &newcon) < 0) { |
| ERR(handle, "out of memory, could not set port context"); |
| return STATUS_ERR; |
| } |
| |
| sepol_context_free(port->con); |
| port->con = newcon; |
| return STATUS_SUCCESS; |
| } |
| |
| hidden_def(sepol_port_set_con) |