16cd6a6acSopenharmony_ci#include <stdlib.h>
26cd6a6acSopenharmony_ci#include <string.h>
36cd6a6acSopenharmony_ci
46cd6a6acSopenharmony_ci#include "iface_internal.h"
56cd6a6acSopenharmony_ci#include "context_internal.h"
66cd6a6acSopenharmony_ci#include "debug.h"
76cd6a6acSopenharmony_ci
86cd6a6acSopenharmony_cistruct sepol_iface {
96cd6a6acSopenharmony_ci
106cd6a6acSopenharmony_ci	/* Interface name */
116cd6a6acSopenharmony_ci	char *name;
126cd6a6acSopenharmony_ci
136cd6a6acSopenharmony_ci	/* Interface context */
146cd6a6acSopenharmony_ci	sepol_context_t *netif_con;
156cd6a6acSopenharmony_ci
166cd6a6acSopenharmony_ci	/* Message context */
176cd6a6acSopenharmony_ci	sepol_context_t *netmsg_con;
186cd6a6acSopenharmony_ci};
196cd6a6acSopenharmony_ci
206cd6a6acSopenharmony_cistruct sepol_iface_key {
216cd6a6acSopenharmony_ci
226cd6a6acSopenharmony_ci	/* Interface name */
236cd6a6acSopenharmony_ci	char *name;
246cd6a6acSopenharmony_ci};
256cd6a6acSopenharmony_ci
266cd6a6acSopenharmony_ci/* Key */
276cd6a6acSopenharmony_ciint sepol_iface_key_create(sepol_handle_t * handle,
286cd6a6acSopenharmony_ci			   const char *name, sepol_iface_key_t ** key_ptr)
296cd6a6acSopenharmony_ci{
306cd6a6acSopenharmony_ci
316cd6a6acSopenharmony_ci	sepol_iface_key_t *tmp_key =
326cd6a6acSopenharmony_ci	    (sepol_iface_key_t *) malloc(sizeof(sepol_iface_key_t));
336cd6a6acSopenharmony_ci
346cd6a6acSopenharmony_ci	if (!tmp_key) {
356cd6a6acSopenharmony_ci		ERR(handle, "out of memory, could not create interface key");
366cd6a6acSopenharmony_ci		return STATUS_ERR;
376cd6a6acSopenharmony_ci	}
386cd6a6acSopenharmony_ci
396cd6a6acSopenharmony_ci	tmp_key->name = strdup(name);
406cd6a6acSopenharmony_ci	if (!tmp_key->name) {
416cd6a6acSopenharmony_ci		ERR(handle, "out of memory, could not create interface key");
426cd6a6acSopenharmony_ci		free(tmp_key);
436cd6a6acSopenharmony_ci		return STATUS_ERR;
446cd6a6acSopenharmony_ci	}
456cd6a6acSopenharmony_ci
466cd6a6acSopenharmony_ci	*key_ptr = tmp_key;
476cd6a6acSopenharmony_ci	return STATUS_SUCCESS;
486cd6a6acSopenharmony_ci}
496cd6a6acSopenharmony_ci
506cd6a6acSopenharmony_ci
516cd6a6acSopenharmony_civoid sepol_iface_key_unpack(const sepol_iface_key_t * key, const char **name)
526cd6a6acSopenharmony_ci{
536cd6a6acSopenharmony_ci
546cd6a6acSopenharmony_ci	*name = key->name;
556cd6a6acSopenharmony_ci}
566cd6a6acSopenharmony_ci
576cd6a6acSopenharmony_ci
586cd6a6acSopenharmony_ciint sepol_iface_key_extract(sepol_handle_t * handle,
596cd6a6acSopenharmony_ci			    const sepol_iface_t * iface,
606cd6a6acSopenharmony_ci			    sepol_iface_key_t ** key_ptr)
616cd6a6acSopenharmony_ci{
626cd6a6acSopenharmony_ci
636cd6a6acSopenharmony_ci	if (sepol_iface_key_create(handle, iface->name, key_ptr) < 0) {
646cd6a6acSopenharmony_ci		ERR(handle, "could not extract key from "
656cd6a6acSopenharmony_ci		    "interface %s", iface->name);
666cd6a6acSopenharmony_ci		return STATUS_ERR;
676cd6a6acSopenharmony_ci	}
686cd6a6acSopenharmony_ci
696cd6a6acSopenharmony_ci	return STATUS_SUCCESS;
706cd6a6acSopenharmony_ci}
716cd6a6acSopenharmony_ci
726cd6a6acSopenharmony_civoid sepol_iface_key_free(sepol_iface_key_t * key)
736cd6a6acSopenharmony_ci{
746cd6a6acSopenharmony_ci	if (!key)
756cd6a6acSopenharmony_ci		return;
766cd6a6acSopenharmony_ci	free(key->name);
776cd6a6acSopenharmony_ci	free(key);
786cd6a6acSopenharmony_ci}
796cd6a6acSopenharmony_ci
806cd6a6acSopenharmony_ciint sepol_iface_compare(const sepol_iface_t * iface,
816cd6a6acSopenharmony_ci			const sepol_iface_key_t * key)
826cd6a6acSopenharmony_ci{
836cd6a6acSopenharmony_ci
846cd6a6acSopenharmony_ci	return strcmp(iface->name, key->name);
856cd6a6acSopenharmony_ci}
866cd6a6acSopenharmony_ci
876cd6a6acSopenharmony_ciint sepol_iface_compare2(const sepol_iface_t * iface,
886cd6a6acSopenharmony_ci			 const sepol_iface_t * iface2)
896cd6a6acSopenharmony_ci{
906cd6a6acSopenharmony_ci
916cd6a6acSopenharmony_ci	return strcmp(iface->name, iface2->name);
926cd6a6acSopenharmony_ci}
936cd6a6acSopenharmony_ci
946cd6a6acSopenharmony_ci/* Create */
956cd6a6acSopenharmony_ciint sepol_iface_create(sepol_handle_t * handle, sepol_iface_t ** iface)
966cd6a6acSopenharmony_ci{
976cd6a6acSopenharmony_ci
986cd6a6acSopenharmony_ci	sepol_iface_t *tmp_iface =
996cd6a6acSopenharmony_ci	    (sepol_iface_t *) malloc(sizeof(sepol_iface_t));
1006cd6a6acSopenharmony_ci
1016cd6a6acSopenharmony_ci	if (!tmp_iface) {
1026cd6a6acSopenharmony_ci		ERR(handle, "out of memory, could not create "
1036cd6a6acSopenharmony_ci		    "interface record");
1046cd6a6acSopenharmony_ci		return STATUS_ERR;
1056cd6a6acSopenharmony_ci	}
1066cd6a6acSopenharmony_ci
1076cd6a6acSopenharmony_ci	tmp_iface->name = NULL;
1086cd6a6acSopenharmony_ci	tmp_iface->netif_con = NULL;
1096cd6a6acSopenharmony_ci	tmp_iface->netmsg_con = NULL;
1106cd6a6acSopenharmony_ci	*iface = tmp_iface;
1116cd6a6acSopenharmony_ci
1126cd6a6acSopenharmony_ci	return STATUS_SUCCESS;
1136cd6a6acSopenharmony_ci}
1146cd6a6acSopenharmony_ci
1156cd6a6acSopenharmony_ci
1166cd6a6acSopenharmony_ci/* Name */
1176cd6a6acSopenharmony_ciconst char *sepol_iface_get_name(const sepol_iface_t * iface)
1186cd6a6acSopenharmony_ci{
1196cd6a6acSopenharmony_ci
1206cd6a6acSopenharmony_ci	return iface->name;
1216cd6a6acSopenharmony_ci}
1226cd6a6acSopenharmony_ci
1236cd6a6acSopenharmony_ci
1246cd6a6acSopenharmony_ciint sepol_iface_set_name(sepol_handle_t * handle,
1256cd6a6acSopenharmony_ci			 sepol_iface_t * iface, const char *name)
1266cd6a6acSopenharmony_ci{
1276cd6a6acSopenharmony_ci
1286cd6a6acSopenharmony_ci	char *tmp_name = strdup(name);
1296cd6a6acSopenharmony_ci	if (!tmp_name) {
1306cd6a6acSopenharmony_ci		ERR(handle, "out of memory, " "could not set interface name");
1316cd6a6acSopenharmony_ci		return STATUS_ERR;
1326cd6a6acSopenharmony_ci	}
1336cd6a6acSopenharmony_ci	free(iface->name);
1346cd6a6acSopenharmony_ci	iface->name = tmp_name;
1356cd6a6acSopenharmony_ci	return STATUS_SUCCESS;
1366cd6a6acSopenharmony_ci}
1376cd6a6acSopenharmony_ci
1386cd6a6acSopenharmony_ci
1396cd6a6acSopenharmony_ci/* Interface Context */
1406cd6a6acSopenharmony_cisepol_context_t *sepol_iface_get_ifcon(const sepol_iface_t * iface)
1416cd6a6acSopenharmony_ci{
1426cd6a6acSopenharmony_ci
1436cd6a6acSopenharmony_ci	return iface->netif_con;
1446cd6a6acSopenharmony_ci}
1456cd6a6acSopenharmony_ci
1466cd6a6acSopenharmony_ci
1476cd6a6acSopenharmony_ciint sepol_iface_set_ifcon(sepol_handle_t * handle,
1486cd6a6acSopenharmony_ci			  sepol_iface_t * iface, sepol_context_t * con)
1496cd6a6acSopenharmony_ci{
1506cd6a6acSopenharmony_ci
1516cd6a6acSopenharmony_ci	sepol_context_t *newcon;
1526cd6a6acSopenharmony_ci
1536cd6a6acSopenharmony_ci	if (sepol_context_clone(handle, con, &newcon) < 0) {
1546cd6a6acSopenharmony_ci		ERR(handle, "out of memory, could not set interface context");
1556cd6a6acSopenharmony_ci		return STATUS_ERR;
1566cd6a6acSopenharmony_ci	}
1576cd6a6acSopenharmony_ci
1586cd6a6acSopenharmony_ci	sepol_context_free(iface->netif_con);
1596cd6a6acSopenharmony_ci	iface->netif_con = newcon;
1606cd6a6acSopenharmony_ci	return STATUS_SUCCESS;
1616cd6a6acSopenharmony_ci}
1626cd6a6acSopenharmony_ci
1636cd6a6acSopenharmony_ci
1646cd6a6acSopenharmony_ci/* Message Context */
1656cd6a6acSopenharmony_cisepol_context_t *sepol_iface_get_msgcon(const sepol_iface_t * iface)
1666cd6a6acSopenharmony_ci{
1676cd6a6acSopenharmony_ci
1686cd6a6acSopenharmony_ci	return iface->netmsg_con;
1696cd6a6acSopenharmony_ci}
1706cd6a6acSopenharmony_ci
1716cd6a6acSopenharmony_ci
1726cd6a6acSopenharmony_ciint sepol_iface_set_msgcon(sepol_handle_t * handle,
1736cd6a6acSopenharmony_ci			   sepol_iface_t * iface, sepol_context_t * con)
1746cd6a6acSopenharmony_ci{
1756cd6a6acSopenharmony_ci
1766cd6a6acSopenharmony_ci	sepol_context_t *newcon;
1776cd6a6acSopenharmony_ci	if (sepol_context_clone(handle, con, &newcon) < 0) {
1786cd6a6acSopenharmony_ci		ERR(handle, "out of memory, could not set message context");
1796cd6a6acSopenharmony_ci		return STATUS_ERR;
1806cd6a6acSopenharmony_ci	}
1816cd6a6acSopenharmony_ci
1826cd6a6acSopenharmony_ci	sepol_context_free(iface->netmsg_con);
1836cd6a6acSopenharmony_ci	iface->netmsg_con = newcon;
1846cd6a6acSopenharmony_ci	return STATUS_SUCCESS;
1856cd6a6acSopenharmony_ci}
1866cd6a6acSopenharmony_ci
1876cd6a6acSopenharmony_ci
1886cd6a6acSopenharmony_ci/* Deep copy clone */
1896cd6a6acSopenharmony_ciint sepol_iface_clone(sepol_handle_t * handle,
1906cd6a6acSopenharmony_ci		      const sepol_iface_t * iface, sepol_iface_t ** iface_ptr)
1916cd6a6acSopenharmony_ci{
1926cd6a6acSopenharmony_ci
1936cd6a6acSopenharmony_ci	sepol_iface_t *new_iface = NULL;
1946cd6a6acSopenharmony_ci	if (sepol_iface_create(handle, &new_iface) < 0)
1956cd6a6acSopenharmony_ci		goto err;
1966cd6a6acSopenharmony_ci
1976cd6a6acSopenharmony_ci	if (sepol_iface_set_name(handle, new_iface, iface->name) < 0)
1986cd6a6acSopenharmony_ci		goto err;
1996cd6a6acSopenharmony_ci
2006cd6a6acSopenharmony_ci	if (iface->netif_con &&
2016cd6a6acSopenharmony_ci	    (sepol_context_clone
2026cd6a6acSopenharmony_ci	     (handle, iface->netif_con, &new_iface->netif_con) < 0))
2036cd6a6acSopenharmony_ci		goto err;
2046cd6a6acSopenharmony_ci
2056cd6a6acSopenharmony_ci	if (iface->netmsg_con &&
2066cd6a6acSopenharmony_ci	    (sepol_context_clone
2076cd6a6acSopenharmony_ci	     (handle, iface->netmsg_con, &new_iface->netmsg_con) < 0))
2086cd6a6acSopenharmony_ci		goto err;
2096cd6a6acSopenharmony_ci
2106cd6a6acSopenharmony_ci	*iface_ptr = new_iface;
2116cd6a6acSopenharmony_ci	return STATUS_SUCCESS;
2126cd6a6acSopenharmony_ci
2136cd6a6acSopenharmony_ci      err:
2146cd6a6acSopenharmony_ci	ERR(handle, "could not clone interface record");
2156cd6a6acSopenharmony_ci	sepol_iface_free(new_iface);
2166cd6a6acSopenharmony_ci	return STATUS_ERR;
2176cd6a6acSopenharmony_ci}
2186cd6a6acSopenharmony_ci
2196cd6a6acSopenharmony_ci/* Destroy */
2206cd6a6acSopenharmony_civoid sepol_iface_free(sepol_iface_t * iface)
2216cd6a6acSopenharmony_ci{
2226cd6a6acSopenharmony_ci
2236cd6a6acSopenharmony_ci	if (!iface)
2246cd6a6acSopenharmony_ci		return;
2256cd6a6acSopenharmony_ci
2266cd6a6acSopenharmony_ci	free(iface->name);
2276cd6a6acSopenharmony_ci	sepol_context_free(iface->netif_con);
2286cd6a6acSopenharmony_ci	sepol_context_free(iface->netmsg_con);
2296cd6a6acSopenharmony_ci	free(iface);
2306cd6a6acSopenharmony_ci}
2316cd6a6acSopenharmony_ci
232