backup: Wire up qemu full pull backup commands over QMP
[libvirt/ericb.git] / tests / securityselinuxtest.c
bloba2864cf57c9ad446ece0b5169b9b9e9ca7596968
1 /*
2 * Copyright (C) 2011-2013 Red Hat, Inc.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library. If not, see
16 * <http://www.gnu.org/licenses/>.
21 #include <config.h>
23 #include <time.h>
25 #include <selinux/selinux.h>
26 #include <selinux/context.h>
28 #include "internal.h"
29 #include "testutils.h"
30 #include "viralloc.h"
31 #include "virlog.h"
32 #include "virerror.h"
33 #include "virfile.h"
34 #include "security/security_manager.h"
35 #include "virstring.h"
37 #define VIR_FROM_THIS VIR_FROM_NONE
39 VIR_LOG_INIT("tests.securityselinuxtest");
41 struct testSELinuxGenLabelData {
42 virSecurityManagerPtr mgr;
44 const char *pidcon;
46 bool dynamic;
47 const char *label;
48 const char *baselabel;
50 const char *user;
51 const char *role;
52 const char *imagerole;
53 const char *type;
54 const char *imagetype;
56 int sensMin;
57 int sensMax;
58 int catMin;
59 int catMax;
62 static virDomainDefPtr
63 testBuildDomainDef(bool dynamic,
64 const char *label,
65 const char *baselabel)
67 virDomainDefPtr def;
68 virSecurityLabelDefPtr secdef = NULL;
70 if (!(def = virDomainDefNew()))
71 goto error;
73 def->virtType = VIR_DOMAIN_VIRT_KVM;
74 if (VIR_ALLOC_N(def->seclabels, 1) < 0)
75 goto error;
77 if (VIR_ALLOC(secdef) < 0)
78 goto error;
80 if (VIR_STRDUP(secdef->model, "selinux") < 0)
81 goto error;
83 secdef->type = dynamic ? VIR_DOMAIN_SECLABEL_DYNAMIC : VIR_DOMAIN_SECLABEL_STATIC;
84 if (label &&
85 VIR_STRDUP(secdef->label, label) < 0)
86 goto error;
88 if (baselabel &&
89 VIR_STRDUP(secdef->baselabel, baselabel) < 0)
90 goto error;
92 def->seclabels[0] = secdef;
93 def->nseclabels++;
94 return def;
96 error:
97 virDomainDefFree(def);
98 virSecurityLabelDefFree(secdef);
99 return NULL;
103 static bool
104 testSELinuxCheckCon(context_t con,
105 const char *user,
106 const char *role,
107 const char *type,
108 int sensMin,
109 int sensMax ATTRIBUTE_UNUSED,
110 int catMin,
111 int catMax)
113 const char *range;
114 char *tmp;
115 int gotSens;
116 int gotCatOne;
117 int gotCatTwo;
119 if (STRNEQ(context_user_get(con), user)) {
120 fprintf(stderr, "Expect user %s got %s\n",
121 user, context_user_get(con));
122 return false;
124 if (STRNEQ(context_role_get(con), role)) {
125 fprintf(stderr, "Expect role %s got %s\n",
126 role, context_role_get(con));
127 return false;
129 if (STRNEQ(context_type_get(con), type)) {
130 fprintf(stderr, "Expect type %s got %s\n",
131 type, context_type_get(con));
132 return false;
135 range = context_range_get(con);
136 if (range[0] != 's') {
137 fprintf(stderr, "Malformed range %s, cannot find sensitivity\n",
138 range);
139 return false;
141 if (virStrToLong_i(range + 1, &tmp, 10, &gotSens) < 0 ||
142 !tmp) {
143 fprintf(stderr, "Malformed range %s, cannot parse sensitivity\n",
144 range + 1);
145 return false;
147 if (*tmp != ':') {
148 fprintf(stderr, "Malformed range %s, too many sensitivity values\n",
149 tmp);
150 return false;
152 tmp++;
153 if (*tmp != 'c') {
154 fprintf(stderr, "Malformed range %s, cannot find first category\n",
155 tmp);
156 return false;
158 tmp++;
159 if (virStrToLong_i(tmp, &tmp, 10, &gotCatOne) < 0) {
160 fprintf(stderr, "Malformed range %s, cannot parse category one\n",
161 tmp);
162 return false;
164 if (tmp && *tmp == ',')
165 tmp++;
166 if (tmp && *tmp == 'c') {
167 tmp++;
168 if (virStrToLong_i(tmp, &tmp, 10, &gotCatTwo) < 0) {
169 fprintf(stderr, "Malformed range %s, cannot parse category two\n",
170 tmp);
171 return false;
173 if (*tmp != '\0') {
174 fprintf(stderr, "Malformed range %s, junk after second category\n",
175 tmp);
176 return false;
178 if (gotCatOne == gotCatTwo) {
179 fprintf(stderr, "Saw category pair %d,%d where cats were equal\n",
180 gotCatOne, gotCatTwo);
181 return false;
183 } else {
184 gotCatTwo = gotCatOne;
187 if (gotSens != sensMin) {
188 fprintf(stderr, "Sensitivity %d is not equal to min %d\n",
189 gotSens, sensMin);
190 return false;
192 if (gotCatOne < catMin ||
193 gotCatOne > catMax) {
194 fprintf(stderr, "Category one %d is out of range %d-%d\n",
195 gotCatTwo, catMin, catMax);
196 return false;
198 if (gotCatTwo < catMin ||
199 gotCatTwo > catMax) {
200 fprintf(stderr, "Category two %d is out of range %d-%d\n",
201 gotCatTwo, catMin, catMax);
202 return false;
205 if (gotCatOne > gotCatTwo) {
206 fprintf(stderr, "Category one %d is greater than category two %d\n",
207 gotCatOne, gotCatTwo);
208 return false;
211 return true;
214 static int
215 testSELinuxGenLabel(const void *opaque)
217 const struct testSELinuxGenLabelData *data = opaque;
218 int ret = -1;
219 virDomainDefPtr def;
220 context_t con = NULL;
221 context_t imgcon = NULL;
223 if (setcon_raw((security_context_t)data->pidcon) < 0) {
224 perror("Cannot set process security context");
225 return -1;
228 if (!(def = testBuildDomainDef(data->dynamic,
229 data->label,
230 data->baselabel)))
231 goto cleanup;
233 if (virSecurityManagerGenLabel(data->mgr, def) < 0) {
234 fprintf(stderr, "Cannot generate label: %s\n", virGetLastErrorMessage());
235 goto cleanup;
238 VIR_DEBUG("label=%s imagelabel=%s",
239 def->seclabels[0]->label, def->seclabels[0]->imagelabel);
241 if (!(con = context_new(def->seclabels[0]->label)))
242 goto cleanup;
243 if (!(imgcon = context_new(def->seclabels[0]->imagelabel)))
244 goto cleanup;
246 if (!testSELinuxCheckCon(con,
247 data->user, data->role, data->type,
248 data->sensMin, data->sensMax,
249 data->catMin, data->catMax))
250 goto cleanup;
252 if (!testSELinuxCheckCon(imgcon,
253 data->user, data->imagerole, data->imagetype,
254 data->sensMin, data->sensMax,
255 data->catMin, data->catMax))
256 goto cleanup;
258 ret = 0;
260 cleanup:
261 context_free(con);
262 context_free(imgcon);
263 virDomainDefFree(def);
264 return ret;
269 static int
270 mymain(void)
272 int ret = 0;
273 virSecurityManagerPtr mgr;
275 if (!(mgr = virSecurityManagerNew("selinux", "QEMU",
276 VIR_SECURITY_MANAGER_DEFAULT_CONFINED |
277 VIR_SECURITY_MANAGER_PRIVILEGED))) {
278 fprintf(stderr, "Unable to initialize security driver: %s\n",
279 virGetLastErrorMessage());
280 return EXIT_FAILURE;
283 #define DO_TEST_GEN_LABEL(desc, pidcon, \
284 dynamic, label, baselabel, \
285 user, role, imageRole, \
286 type, imageType, \
287 sensMin, sensMax, catMin, catMax) \
288 do { \
289 struct testSELinuxGenLabelData data = { \
290 mgr, pidcon, dynamic, label, baselabel, \
291 user, role, imageRole, type, imageType, \
292 sensMin, sensMax, catMin, catMax \
293 }; \
294 if (virTestRun("GenLabel " # desc, testSELinuxGenLabel, &data) < 0) \
295 ret = -1; \
296 } while (0)
298 DO_TEST_GEN_LABEL("dynamic unconfined, s0, c0.c1023",
299 "unconfined_u:unconfined_r:unconfined_t:s0",
300 true, NULL, NULL,
301 "unconfined_u", "unconfined_r", "object_r",
302 "svirt_t", "svirt_image_t",
303 0, 0, 0, 1023);
304 DO_TEST_GEN_LABEL("dynamic unconfined, s0, c0.c1023",
305 "unconfined_u:unconfined_r:unconfined_t:s0-s0",
306 true, NULL, NULL,
307 "unconfined_u", "unconfined_r", "object_r",
308 "svirt_t", "svirt_image_t",
309 0, 0, 0, 1023);
310 DO_TEST_GEN_LABEL("dynamic unconfined, s0, c0.c1023",
311 "unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023",
312 true, NULL, NULL,
313 "unconfined_u", "unconfined_r", "object_r",
314 "svirt_t", "svirt_image_t",
315 0, 0, 0, 1023);
316 DO_TEST_GEN_LABEL("dynamic virtd, s0, c0.c1023",
317 "system_u:system_r:virtd_t:s0-s0:c0.c1023",
318 true, NULL, NULL,
319 "system_u", "system_r", "object_r",
320 "svirt_t", "svirt_image_t",
321 0, 0, 0, 1023);
322 DO_TEST_GEN_LABEL("dynamic virtd, s0, c0.c10",
323 "system_u:system_r:virtd_t:s0-s0:c0.c10",
324 true, NULL, NULL,
325 "system_u", "system_r", "object_r",
326 "svirt_t", "svirt_image_t",
327 0, 0, 0, 10);
328 DO_TEST_GEN_LABEL("dynamic virtd, s2-s3, c0.c1023",
329 "system_u:system_r:virtd_t:s2-s3:c0.c1023",
330 true, NULL, NULL,
331 "system_u", "system_r", "object_r",
332 "svirt_t", "svirt_image_t",
333 2, 3, 0, 1023);
334 DO_TEST_GEN_LABEL("dynamic virtd, missing range",
335 "system_u:system_r:virtd_t",
336 true, NULL, NULL,
337 "system_u", "system_r", "object_r",
338 "svirt_t", "svirt_image_t",
339 0, 0, 0, 1023);
341 virObjectUnref(mgr);
342 return (ret == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
345 VIR_TEST_MAIN_PRELOAD(mymain, abs_builddir "/.libs/libsecurityselinuxhelper.so")