1#include <stdlib.h>
2#include <string.h>
3
4#include "iface_internal.h"
5#include "context_internal.h"
6#include "debug.h"
7
8struct sepol_iface {
9
10	/* Interface name */
11	char *name;
12
13	/* Interface context */
14	sepol_context_t *netif_con;
15
16	/* Message context */
17	sepol_context_t *netmsg_con;
18};
19
20struct sepol_iface_key {
21
22	/* Interface name */
23	const char *name;
24};
25
26/* Key */
27int sepol_iface_key_create(sepol_handle_t * handle,
28			   const char *name, sepol_iface_key_t ** key_ptr)
29{
30
31	sepol_iface_key_t *tmp_key =
32	    (sepol_iface_key_t *) malloc(sizeof(sepol_iface_key_t));
33
34	if (!tmp_key) {
35		ERR(handle, "out of memory, could not create interface key");
36		return STATUS_ERR;
37	}
38
39	tmp_key->name = name;
40
41	*key_ptr = tmp_key;
42	return STATUS_SUCCESS;
43}
44
45hidden_def(sepol_iface_key_create)
46
47void sepol_iface_key_unpack(const sepol_iface_key_t * key, const char **name)
48{
49
50	*name = key->name;
51}
52
53hidden_def(sepol_iface_key_unpack)
54
55int sepol_iface_key_extract(sepol_handle_t * handle,
56			    const sepol_iface_t * iface,
57			    sepol_iface_key_t ** key_ptr)
58{
59
60	if (sepol_iface_key_create(handle, iface->name, key_ptr) < 0) {
61		ERR(handle, "could not extract key from "
62		    "interface %s", iface->name);
63		return STATUS_ERR;
64	}
65
66	return STATUS_SUCCESS;
67}
68
69void sepol_iface_key_free(sepol_iface_key_t * key)
70{
71	free(key);
72}
73
74int sepol_iface_compare(const sepol_iface_t * iface,
75			const sepol_iface_key_t * key)
76{
77
78	return strcmp(iface->name, key->name);
79}
80
81int sepol_iface_compare2(const sepol_iface_t * iface,
82			 const sepol_iface_t * iface2)
83{
84
85	return strcmp(iface->name, iface2->name);
86}
87
88/* Create */
89int sepol_iface_create(sepol_handle_t * handle, sepol_iface_t ** iface)
90{
91
92	sepol_iface_t *tmp_iface =
93	    (sepol_iface_t *) malloc(sizeof(sepol_iface_t));
94
95	if (!tmp_iface) {
96		ERR(handle, "out of memory, could not create "
97		    "interface record");
98		return STATUS_ERR;
99	}
100
101	tmp_iface->name = NULL;
102	tmp_iface->netif_con = NULL;
103	tmp_iface->netmsg_con = NULL;
104	*iface = tmp_iface;
105
106	return STATUS_SUCCESS;
107}
108
109hidden_def(sepol_iface_create)
110
111/* Name */
112const char *sepol_iface_get_name(const sepol_iface_t * iface)
113{
114
115	return iface->name;
116}
117
118hidden_def(sepol_iface_get_name)
119
120int sepol_iface_set_name(sepol_handle_t * handle,
121			 sepol_iface_t * iface, const char *name)
122{
123
124	char *tmp_name = strdup(name);
125	if (!tmp_name) {
126		ERR(handle, "out of memory, " "could not set interface name");
127		return STATUS_ERR;
128	}
129	free(iface->name);
130	iface->name = tmp_name;
131	return STATUS_SUCCESS;
132}
133
134hidden_def(sepol_iface_set_name)
135
136/* Interface Context */
137sepol_context_t *sepol_iface_get_ifcon(const sepol_iface_t * iface)
138{
139
140	return iface->netif_con;
141}
142
143hidden_def(sepol_iface_get_ifcon)
144
145int sepol_iface_set_ifcon(sepol_handle_t * handle,
146			  sepol_iface_t * iface, sepol_context_t * con)
147{
148
149	sepol_context_t *newcon;
150
151	if (sepol_context_clone(handle, con, &newcon) < 0) {
152		ERR(handle, "out of memory, could not set interface context");
153		return STATUS_ERR;
154	}
155
156	sepol_context_free(iface->netif_con);
157	iface->netif_con = newcon;
158	return STATUS_SUCCESS;
159}
160
161hidden_def(sepol_iface_set_ifcon)
162
163/* Message Context */
164sepol_context_t *sepol_iface_get_msgcon(const sepol_iface_t * iface)
165{
166
167	return iface->netmsg_con;
168}
169
170hidden_def(sepol_iface_get_msgcon)
171
172int sepol_iface_set_msgcon(sepol_handle_t * handle,
173			   sepol_iface_t * iface, sepol_context_t * con)
174{
175
176	sepol_context_t *newcon;
177	if (sepol_context_clone(handle, con, &newcon) < 0) {
178		ERR(handle, "out of memory, could not set message context");
179		return STATUS_ERR;
180	}
181
182	sepol_context_free(iface->netmsg_con);
183	iface->netmsg_con = newcon;
184	return STATUS_SUCCESS;
185}
186
187hidden_def(sepol_iface_set_msgcon)
188
189/* Deep copy clone */
190int sepol_iface_clone(sepol_handle_t * handle,
191		      const sepol_iface_t * iface, sepol_iface_t ** iface_ptr)
192{
193
194	sepol_iface_t *new_iface = NULL;
195	if (sepol_iface_create(handle, &new_iface) < 0)
196		goto err;
197
198	if (sepol_iface_set_name(handle, new_iface, iface->name) < 0)
199		goto err;
200
201	if (iface->netif_con &&
202	    (sepol_context_clone
203	     (handle, iface->netif_con, &new_iface->netif_con) < 0))
204		goto err;
205
206	if (iface->netmsg_con &&
207	    (sepol_context_clone
208	     (handle, iface->netmsg_con, &new_iface->netmsg_con) < 0))
209		goto err;
210
211	*iface_ptr = new_iface;
212	return STATUS_SUCCESS;
213
214      err:
215	ERR(handle, "could not clone interface record");
216	sepol_iface_free(new_iface);
217	return STATUS_ERR;
218}
219
220/* Destroy */
221void sepol_iface_free(sepol_iface_t * iface)
222{
223
224	if (!iface)
225		return;
226
227	free(iface->name);
228	sepol_context_free(iface->netif_con);
229	sepol_context_free(iface->netmsg_con);
230	free(iface);
231}
232
233hidden_def(sepol_iface_free)
234