node_record.c revision b1db49d77789525ac1f4e73e978e35694f21ea1a
1e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include <stdlib.h> 2e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include <stddef.h> 3e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include <string.h> 4e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include <netinet/in.h> 5e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include <arpa/inet.h> 6e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include <errno.h> 7e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 8e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "node_internal.h" 9e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "context_internal.h" 10e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#include "debug.h" 11e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 12e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstruct sepol_node { 13e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 14e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project /* Network address and mask */ 15e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project char *addr; 16e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project size_t addr_sz; 17e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 18e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project char *mask; 19e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project size_t mask_sz; 20e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 21e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project /* Protocol */ 22e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int proto; 23e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 24e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project /* Context */ 25e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project sepol_context_t *con; 26e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}; 27e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 28e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstruct sepol_node_key { 29e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 30e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project /* Network address and mask */ 31e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project char *addr; 32e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project size_t addr_sz; 33e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 34e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project char *mask; 35e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project size_t mask_sz; 36e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 37e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project /* Protocol */ 38e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int proto; 39e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project}; 40e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 41e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/* Converts a string represtation (addr_str) 42e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project * to a numeric representation (addr_bytes) */ 43e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 44e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic int node_parse_addr(sepol_handle_t * handle, 45e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project const char *addr_str, int proto, char *addr_bytes) 46e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{ 47e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 48e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project switch (proto) { 49e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 50e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project case SEPOL_PROTO_IP4: 51e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 52e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project struct in_addr in_addr; 53e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 54e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (inet_pton(AF_INET, addr_str, &in_addr) <= 0) { 55e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project ERR(handle, "could not parse IPv4 address " 56e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project "%s: %s", addr_str, strerror(errno)); 57e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return STATUS_ERR; 58e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 59e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 60e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project memcpy(addr_bytes, &in_addr.s_addr, 4); 61e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project break; 62e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 63e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project case SEPOL_PROTO_IP6: 64e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 65e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project struct in6_addr in_addr; 66e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 67e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (inet_pton(AF_INET6, addr_str, &in_addr) <= 0) { 68e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project ERR(handle, "could not parse IPv6 address " 69e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project "%s: %s", addr_str, strerror(errno)); 70e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return STATUS_ERR; 71e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 72e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 73e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#ifdef DARWIN 74e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project memcpy(addr_bytes, in_addr.s6_addr, 16); 75e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#else 76e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project memcpy(addr_bytes, in_addr.s6_addr32, 16); 77e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#endif 78e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project break; 79e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 80e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project default: 81e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project ERR(handle, "unsupported protocol %u, could not " 82e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project "parse address", proto); 83e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return STATUS_ERR; 84e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 85e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 86e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return STATUS_SUCCESS; 87e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 88e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 89e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/* Allocates a sufficiently large buffer (addr, addr_sz) 90e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project * according the the protocol */ 91e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 92e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic int node_alloc_addr(sepol_handle_t * handle, 93e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int proto, char **addr, size_t * addr_sz) 94e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{ 95e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 96e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project char *tmp_addr = NULL; 97e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project size_t tmp_addr_sz; 98e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 99e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project switch (proto) { 100e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 101e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project case SEPOL_PROTO_IP4: 102e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project tmp_addr_sz = 4; 103e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project tmp_addr = malloc(4); 104e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (!tmp_addr) 105e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project goto omem; 106e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project break; 107e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 108e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project case SEPOL_PROTO_IP6: 109e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project tmp_addr_sz = 16; 110e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project tmp_addr = malloc(16); 111e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (!tmp_addr) 112e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project goto omem; 113e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project break; 114e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 115e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project default: 116e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project ERR(handle, "unsupported protocol %u", proto); 117e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project goto err; 118e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 119e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 120e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project *addr = tmp_addr; 121e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project *addr_sz = tmp_addr_sz; 122e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return STATUS_SUCCESS; 123e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 124e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project omem: 125e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project ERR(handle, "out of memory"); 126e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 127e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project err: 128e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project free(tmp_addr); 129e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project ERR(handle, "could not allocate address of protocol %s", 130e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project sepol_node_get_proto_str(proto)); 131e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return STATUS_ERR; 132e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 133e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 134e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/* Converts a numeric representation (addr_bytes) 135e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project * to a string representation (addr_str), according to 136e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project * the protocol */ 137e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 138e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic int node_expand_addr(sepol_handle_t * handle, 139e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project char *addr_bytes, int proto, char *addr_str) 140e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{ 141e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 142e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project switch (proto) { 143e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 144e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project case SEPOL_PROTO_IP4: 145e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 146e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project struct in_addr addr; 147e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project memset(&addr, 0, sizeof(struct in_addr)); 148e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project memcpy(&addr.s_addr, addr_bytes, 4); 149e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 150e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (inet_ntop(AF_INET, &addr, addr_str, 151e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project INET_ADDRSTRLEN) == NULL) { 152e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 153e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project ERR(handle, 154e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project "could not expand IPv4 address to string: %s", 155e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project strerror(errno)); 156e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return STATUS_ERR; 157e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 158e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project break; 159e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 160e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 161e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project case SEPOL_PROTO_IP6: 162e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project { 163e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project struct in6_addr addr; 164e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project memset(&addr, 0, sizeof(struct in6_addr)); 165e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#ifdef DARWIN 166e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project memcpy(&addr.s6_addr[0], addr_bytes, 16); 167e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#else 168e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project memcpy(&addr.s6_addr32[0], addr_bytes, 16); 169e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project#endif 170e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (inet_ntop(AF_INET6, &addr, addr_str, 171e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project INET6_ADDRSTRLEN) == NULL) { 172e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 173e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project ERR(handle, 174e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project "could not expand IPv6 address to string: %s", 175e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project strerror(errno)); 176e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return STATUS_ERR; 177e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 178e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project break; 179e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 180e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 181e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project default: 182e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project ERR(handle, "unsupported protocol %u, could not" 183e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project " expand address to string", proto); 184e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return STATUS_ERR; 185e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 186e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 187e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return STATUS_SUCCESS; 188e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 189e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 190e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/* Allocates a sufficiently large address string (addr) 191e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project * according to the protocol */ 192e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 193e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectstatic int node_alloc_addr_string(sepol_handle_t * handle, 194e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int proto, char **addr) 195e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{ 196e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 197e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project char *tmp_addr = NULL; 198e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 199e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project switch (proto) { 200e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 201e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project case SEPOL_PROTO_IP4: 202e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project tmp_addr = malloc(INET_ADDRSTRLEN); 203e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (!tmp_addr) 204e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project goto omem; 205e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project break; 206e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 207e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project case SEPOL_PROTO_IP6: 208e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project tmp_addr = malloc(INET6_ADDRSTRLEN); 209e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (!tmp_addr) 210e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project goto omem; 211e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project break; 212e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 213e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project default: 214e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project ERR(handle, "unsupported protocol %u", proto); 215e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project goto err; 216e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project } 217e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 218e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project *addr = tmp_addr; 219e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return STATUS_SUCCESS; 220e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 221e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project omem: 222e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project ERR(handle, "out of memory"); 223e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 224e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project err: 225e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project free(tmp_addr); 226e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project ERR(handle, "could not allocate string buffer for " 227e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project "address of protocol %s", sepol_node_get_proto_str(proto)); 228e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return STATUS_ERR; 229e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 230e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 231e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/* Key */ 232e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectint sepol_node_key_create(sepol_handle_t * handle, 233e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project const char *addr, 234e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project const char *mask, 235e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int proto, sepol_node_key_t ** key_ptr) 236e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{ 237e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 238e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project sepol_node_key_t *tmp_key = 239e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project (sepol_node_key_t *) calloc(1, sizeof(sepol_node_key_t)); 240e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (!tmp_key) 241e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project goto omem; 242e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 243e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (node_alloc_addr(handle, proto, &tmp_key->addr, &tmp_key->addr_sz) < 244e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 0) 245e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project goto err; 246e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (node_parse_addr(handle, addr, proto, tmp_key->addr) < 0) 247e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project goto err; 248e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 249e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (node_alloc_addr(handle, proto, &tmp_key->mask, &tmp_key->mask_sz) < 250e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 0) 251e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project goto err; 252e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (node_parse_addr(handle, mask, proto, tmp_key->mask) < 0) 253e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project goto err; 254e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 255e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project tmp_key->proto = proto; 256e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 257e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project *key_ptr = tmp_key; 258e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return STATUS_SUCCESS; 259e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 260e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project omem: 261e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project ERR(handle, "out of memory"); 262e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 263e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project err: 264e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project sepol_node_key_free(tmp_key); 265e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project ERR(handle, "could not create node key for (%s, %s, %s)", 266e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project addr, mask, sepol_node_get_proto_str(proto)); 267e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return STATUS_ERR; 268e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 269e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 270e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projecthidden_def(sepol_node_key_create) 271e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 272e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectvoid sepol_node_key_unpack(const sepol_node_key_t * key, 273e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project const char **addr, const char **mask, int *proto) 274e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{ 275e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 276e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project *addr = key->addr; 277e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project *mask = key->mask; 278e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project *proto = key->proto; 279e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 280e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 281e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projecthidden_def(sepol_node_key_unpack) 282e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 283e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectint sepol_node_key_extract(sepol_handle_t * handle, 284e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project const sepol_node_t * node, 285e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project sepol_node_key_t ** key_ptr) 286e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{ 287e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 288e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project sepol_node_key_t *tmp_key = 289e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project (sepol_node_key_t *) calloc(1, sizeof(sepol_node_key_t)); 290e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (!tmp_key) 291e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project goto omem; 292e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 293e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project tmp_key->addr = malloc(node->addr_sz); 294e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project tmp_key->mask = malloc(node->mask_sz); 295e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 296e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (!tmp_key->addr || !tmp_key->mask) 297e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project goto omem; 298e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 299e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project memcpy(tmp_key->addr, node->addr, node->addr_sz); 300e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project memcpy(tmp_key->mask, node->mask, node->mask_sz); 301e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project tmp_key->addr_sz = node->addr_sz; 302e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project tmp_key->mask_sz = node->mask_sz; 303e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project tmp_key->proto = node->proto; 304e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 305e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project *key_ptr = tmp_key; 306e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return STATUS_SUCCESS; 307e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 308e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project omem: 309e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project sepol_node_key_free(tmp_key); 310e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project ERR(handle, "out of memory, could not extract node key"); 311e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return STATUS_ERR; 312e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 313e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 314e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectvoid sepol_node_key_free(sepol_node_key_t * key) 315e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{ 316e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 317e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (!key) 318e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return; 319e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 320e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project free(key->addr); 321e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project free(key->mask); 322e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project free(key); 323e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 324e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 325e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projecthidden_def(sepol_node_key_free) 326e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 327e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectint sepol_node_compare(const sepol_node_t * node, const sepol_node_key_t * key) 328e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{ 329e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 330e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int rc1, rc2; 331e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 332e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if ((node->addr_sz < key->addr_sz) || (node->mask_sz < key->mask_sz)) 333e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return -1; 334e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 335e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project else if ((node->addr_sz > key->addr_sz) || 336e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project (node->mask_sz > key->mask_sz)) 337e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return 1; 338e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 339e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project rc1 = memcmp(node->addr, key->addr, node->addr_sz); 340e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project rc2 = memcmp(node->mask, key->mask, node->mask_sz); 341e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 342e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return (rc2 != 0) ? rc2 : rc1; 343e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 344e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 345e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectint sepol_node_compare2(const sepol_node_t * node, const sepol_node_t * node2) 346e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{ 347e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 348e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project int rc1, rc2; 349e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 350e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if ((node->addr_sz < node2->addr_sz) || 351e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project (node->mask_sz < node2->mask_sz)) 352e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return -1; 353e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 354e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project else if ((node->addr_sz > node2->addr_sz) || 355e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project (node->mask_sz > node2->mask_sz)) 356e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return 1; 357e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 358e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project rc1 = memcmp(node->addr, node2->addr, node->addr_sz); 359e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project rc2 = memcmp(node->mask, node2->mask, node->mask_sz); 360e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 361e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return (rc2 != 0) ? rc2 : rc1; 362e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 363e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 364e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project/* Addr */ 365e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectint sepol_node_get_addr(sepol_handle_t * handle, 366e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project const sepol_node_t * node, char **addr) 367e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{ 368e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 369e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project char *tmp_addr = NULL; 370e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 371e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (node_alloc_addr_string(handle, node->proto, &tmp_addr) < 0) 372e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project goto err; 373e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 374e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project if (node_expand_addr(handle, node->addr, node->proto, tmp_addr) < 0) 375e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project goto err; 376e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 377e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project *addr = tmp_addr; 378e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return STATUS_SUCCESS; 379e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 380e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project err: 381e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project free(tmp_addr); 382e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project ERR(handle, "could not get node address"); 383e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project return STATUS_ERR; 384e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project} 385e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 386e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projecthidden_def(sepol_node_get_addr) 387e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 388e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Projectint sepol_node_get_addr_bytes(sepol_handle_t * handle, 389e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project const sepol_node_t * node, 390e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project char **buffer, size_t * bsize) 391e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project{ 392e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project 393e9df6ba5a8fcccf306a80b1670b423be8fe7746The Android Open Source Project char *tmp_buf = malloc(node->addr_sz); 394 if (!tmp_buf) { 395 ERR(handle, "out of memory, could not get address bytes"); 396 return STATUS_ERR; 397 } 398 399 memcpy(tmp_buf, node->addr, node->addr_sz); 400 *buffer = tmp_buf; 401 *bsize = node->addr_sz; 402 return STATUS_SUCCESS; 403} 404 405hidden_def(sepol_node_get_addr_bytes) 406 407int sepol_node_set_addr(sepol_handle_t * handle, 408 sepol_node_t * node, int proto, const char *addr) 409{ 410 411 char *tmp_addr = NULL; 412 size_t tmp_addr_sz; 413 414 if (node_alloc_addr(handle, proto, &tmp_addr, &tmp_addr_sz) < 0) 415 goto err; 416 417 if (node_parse_addr(handle, addr, proto, tmp_addr) < 0) 418 goto err; 419 420 free(node->addr); 421 node->addr = tmp_addr; 422 node->addr_sz = tmp_addr_sz; 423 return STATUS_SUCCESS; 424 425 err: 426 free(tmp_addr); 427 ERR(handle, "could not set node address to %s", addr); 428 return STATUS_ERR; 429} 430 431hidden_def(sepol_node_set_addr) 432 433int sepol_node_set_addr_bytes(sepol_handle_t * handle, 434 sepol_node_t * node, 435 const char *addr, size_t addr_sz) 436{ 437 438 char *tmp_addr = malloc(addr_sz); 439 if (!tmp_addr) { 440 ERR(handle, "out of memory, could not " "set node address"); 441 return STATUS_ERR; 442 } 443 444 memcpy(tmp_addr, addr, addr_sz); 445 free(node->addr); 446 node->addr = tmp_addr; 447 node->addr_sz = addr_sz; 448 return STATUS_SUCCESS; 449} 450 451hidden_def(sepol_node_set_addr_bytes) 452 453/* Mask */ 454int sepol_node_get_mask(sepol_handle_t * handle, 455 const sepol_node_t * node, char **mask) 456{ 457 458 char *tmp_mask = NULL; 459 460 if (node_alloc_addr_string(handle, node->proto, &tmp_mask) < 0) 461 goto err; 462 463 if (node_expand_addr(handle, node->mask, node->proto, tmp_mask) < 0) 464 goto err; 465 466 *mask = tmp_mask; 467 return STATUS_SUCCESS; 468 469 err: 470 free(tmp_mask); 471 ERR(handle, "could not get node netmask"); 472 return STATUS_ERR; 473} 474 475hidden_def(sepol_node_get_mask) 476 477int sepol_node_get_mask_bytes(sepol_handle_t * handle, 478 const sepol_node_t * node, 479 char **buffer, size_t * bsize) 480{ 481 482 char *tmp_buf = malloc(node->mask_sz); 483 if (!tmp_buf) { 484 ERR(handle, "out of memory, could not get netmask bytes"); 485 return STATUS_ERR; 486 } 487 488 memcpy(tmp_buf, node->mask, node->mask_sz); 489 *buffer = tmp_buf; 490 *bsize = node->mask_sz; 491 return STATUS_SUCCESS; 492} 493 494hidden_def(sepol_node_get_mask_bytes) 495 496int sepol_node_set_mask(sepol_handle_t * handle, 497 sepol_node_t * node, int proto, const char *mask) 498{ 499 500 char *tmp_mask = NULL; 501 size_t tmp_mask_sz; 502 503 if (node_alloc_addr(handle, proto, &tmp_mask, &tmp_mask_sz) < 0) 504 goto err; 505 506 if (node_parse_addr(handle, mask, proto, tmp_mask) < 0) 507 goto err; 508 509 free(node->mask); 510 node->mask = tmp_mask; 511 node->mask_sz = tmp_mask_sz; 512 return STATUS_SUCCESS; 513 514 err: 515 free(tmp_mask); 516 ERR(handle, "could not set node netmask to %s", mask); 517 return STATUS_ERR; 518} 519 520hidden_def(sepol_node_set_mask) 521 522int sepol_node_set_mask_bytes(sepol_handle_t * handle, 523 sepol_node_t * node, 524 const char *mask, size_t mask_sz) 525{ 526 527 char *tmp_mask = malloc(mask_sz); 528 if (!tmp_mask) { 529 ERR(handle, "out of memory, could not " "set node netmask"); 530 return STATUS_ERR; 531 } 532 memcpy(tmp_mask, mask, mask_sz); 533 free(node->mask); 534 node->mask = tmp_mask; 535 node->mask_sz = mask_sz; 536 return STATUS_SUCCESS; 537} 538 539hidden_def(sepol_node_set_mask_bytes) 540 541/* Protocol */ 542int sepol_node_get_proto(const sepol_node_t * node) 543{ 544 545 return node->proto; 546} 547 548hidden_def(sepol_node_get_proto) 549 550void sepol_node_set_proto(sepol_node_t * node, int proto) 551{ 552 553 node->proto = proto; 554} 555 556hidden_def(sepol_node_set_proto) 557 558const char *sepol_node_get_proto_str(int proto) 559{ 560 561 switch (proto) { 562 case SEPOL_PROTO_IP4: 563 return "ipv4"; 564 case SEPOL_PROTO_IP6: 565 return "ipv6"; 566 default: 567 return "???"; 568 } 569} 570 571hidden_def(sepol_node_get_proto_str) 572 573/* Create */ 574int sepol_node_create(sepol_handle_t * handle, sepol_node_t ** node) 575{ 576 577 sepol_node_t *tmp_node = (sepol_node_t *) malloc(sizeof(sepol_node_t)); 578 579 if (!tmp_node) { 580 ERR(handle, "out of memory, could not create " "node record"); 581 return STATUS_ERR; 582 } 583 584 tmp_node->addr = NULL; 585 tmp_node->addr_sz = 0; 586 tmp_node->mask = NULL; 587 tmp_node->mask_sz = 0; 588 tmp_node->proto = SEPOL_PROTO_IP4; 589 tmp_node->con = NULL; 590 *node = tmp_node; 591 592 return STATUS_SUCCESS; 593} 594 595hidden_def(sepol_node_create) 596 597/* Deep copy clone */ 598int sepol_node_clone(sepol_handle_t * handle, 599 const sepol_node_t * node, sepol_node_t ** node_ptr) 600{ 601 602 sepol_node_t *new_node = NULL; 603 if (sepol_node_create(handle, &new_node) < 0) 604 goto err; 605 606 /* Copy address, mask, protocol */ 607 new_node->addr = malloc(node->addr_sz); 608 new_node->mask = malloc(node->mask_sz); 609 if (!new_node->addr || !new_node->mask) 610 goto omem; 611 612 memcpy(new_node->addr, node->addr, node->addr_sz); 613 memcpy(new_node->mask, node->mask, node->mask_sz); 614 new_node->addr_sz = node->addr_sz; 615 new_node->mask_sz = node->mask_sz; 616 new_node->proto = node->proto; 617 618 /* Copy context */ 619 if (node->con && 620 (sepol_context_clone(handle, node->con, &new_node->con) < 0)) 621 goto err; 622 623 *node_ptr = new_node; 624 return STATUS_SUCCESS; 625 626 omem: 627 ERR(handle, "out of memory"); 628 629 err: 630 ERR(handle, "could not clone node record"); 631 sepol_node_free(new_node); 632 return STATUS_ERR; 633} 634 635/* Destroy */ 636void sepol_node_free(sepol_node_t * node) 637{ 638 639 if (!node) 640 return; 641 642 sepol_context_free(node->con); 643 free(node->addr); 644 free(node->mask); 645 free(node); 646} 647 648hidden_def(sepol_node_free) 649 650/* Context */ 651sepol_context_t *sepol_node_get_con(const sepol_node_t * node) 652{ 653 654 return node->con; 655} 656 657hidden_def(sepol_node_get_con) 658 659int sepol_node_set_con(sepol_handle_t * handle, 660 sepol_node_t * node, sepol_context_t * con) 661{ 662 663 sepol_context_t *newcon; 664 665 if (sepol_context_clone(handle, con, &newcon) < 0) { 666 ERR(handle, "out of memory, could not set node context"); 667 return STATUS_ERR; 668 } 669 670 sepol_context_free(node->con); 671 node->con = newcon; 672 return STATUS_SUCCESS; 673} 674 675hidden_def(sepol_node_set_con) 676