1 #include <stdlib.h>
2 #include <string.h>
3 
4 #include "iface_internal.h"
5 #include "context_internal.h"
6 #include "debug.h"
7 
8 struct 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 
20 struct sepol_iface_key {
21 
22 	/* Interface name */
23 	const char *name;
24 };
25 
26 /* Key */
sepol_iface_key_create(sepol_handle_t * handle,const char * name,sepol_iface_key_t ** key_ptr)27 int 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 
hidden_def(sepol_iface_key_create)45 hidden_def(sepol_iface_key_create)
46 
47 void sepol_iface_key_unpack(const sepol_iface_key_t * key, const char **name)
48 {
49 
50 	*name = key->name;
51 }
52 
hidden_def(sepol_iface_key_unpack)53 hidden_def(sepol_iface_key_unpack)
54 
55 int 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 
sepol_iface_key_free(sepol_iface_key_t * key)69 void sepol_iface_key_free(sepol_iface_key_t * key)
70 {
71 	free(key);
72 }
73 
sepol_iface_compare(const sepol_iface_t * iface,const sepol_iface_key_t * key)74 int 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 
sepol_iface_compare2(const sepol_iface_t * iface,const sepol_iface_t * iface2)81 int 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 */
sepol_iface_create(sepol_handle_t * handle,sepol_iface_t ** iface)89 int 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 
hidden_def(sepol_iface_create)109 hidden_def(sepol_iface_create)
110 
111 /* Name */
112 const char *sepol_iface_get_name(const sepol_iface_t * iface)
113 {
114 
115 	return iface->name;
116 }
117 
hidden_def(sepol_iface_get_name)118 hidden_def(sepol_iface_get_name)
119 
120 int 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 
hidden_def(sepol_iface_set_name)134 hidden_def(sepol_iface_set_name)
135 
136 /* Interface Context */
137 sepol_context_t *sepol_iface_get_ifcon(const sepol_iface_t * iface)
138 {
139 
140 	return iface->netif_con;
141 }
142 
hidden_def(sepol_iface_get_ifcon)143 hidden_def(sepol_iface_get_ifcon)
144 
145 int 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 
hidden_def(sepol_iface_set_ifcon)161 hidden_def(sepol_iface_set_ifcon)
162 
163 /* Message Context */
164 sepol_context_t *sepol_iface_get_msgcon(const sepol_iface_t * iface)
165 {
166 
167 	return iface->netmsg_con;
168 }
169 
hidden_def(sepol_iface_get_msgcon)170 hidden_def(sepol_iface_get_msgcon)
171 
172 int 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 
hidden_def(sepol_iface_set_msgcon)187 hidden_def(sepol_iface_set_msgcon)
188 
189 /* Deep copy clone */
190 int 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 */
sepol_iface_free(sepol_iface_t * iface)221 void 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 
233 hidden_def(sepol_iface_free)
234