1 /* SPDX-License-Identifier: LGPL-2.1+ */
5 #include <sys/utsname.h>
10 #include "alloc-util.h"
11 #include "apparmor-util.h"
12 #include "architecture.h"
13 #include "audit-util.h"
14 #include "cgroup-util.h"
15 #include "condition.h"
17 #include "hostname-util.h"
18 #include "id128-util.h"
22 #include "selinux-util.h"
24 #include "smack-util.h"
25 #include "string-util.h"
27 #include "tomoyo-util.h"
28 #include "user-util.h"
32 static void test_condition_test_path(void) {
35 condition
= condition_new(CONDITION_PATH_EXISTS
, "/bin/sh", false, false);
37 assert_se(condition_test(condition
));
38 condition_free(condition
);
40 condition
= condition_new(CONDITION_PATH_EXISTS
, "/bin/s?", false, false);
42 assert_se(!condition_test(condition
));
43 condition_free(condition
);
45 condition
= condition_new(CONDITION_PATH_EXISTS_GLOB
, "/bin/s?", false, false);
47 assert_se(condition_test(condition
));
48 condition_free(condition
);
50 condition
= condition_new(CONDITION_PATH_EXISTS_GLOB
, "/bin/s?", false, true);
52 assert_se(!condition_test(condition
));
53 condition_free(condition
);
55 condition
= condition_new(CONDITION_PATH_EXISTS
, "/thiscertainlywontexist", false, false);
57 assert_se(!condition_test(condition
));
58 condition_free(condition
);
60 condition
= condition_new(CONDITION_PATH_EXISTS
, "/thiscertainlywontexist", false, true);
62 assert_se(condition_test(condition
));
63 condition_free(condition
);
65 condition
= condition_new(CONDITION_PATH_IS_DIRECTORY
, "/bin", false, false);
67 assert_se(condition_test(condition
));
68 condition_free(condition
);
70 condition
= condition_new(CONDITION_DIRECTORY_NOT_EMPTY
, "/bin", false, false);
72 assert_se(condition_test(condition
));
73 condition_free(condition
);
75 condition
= condition_new(CONDITION_FILE_NOT_EMPTY
, "/bin/sh", false, false);
77 assert_se(condition_test(condition
));
78 condition_free(condition
);
80 condition
= condition_new(CONDITION_FILE_IS_EXECUTABLE
, "/bin/sh", false, false);
82 assert_se(condition_test(condition
));
83 condition_free(condition
);
85 condition
= condition_new(CONDITION_FILE_IS_EXECUTABLE
, "/etc/passwd", false, false);
87 assert_se(!condition_test(condition
));
88 condition_free(condition
);
90 condition
= condition_new(CONDITION_PATH_IS_MOUNT_POINT
, "/proc", false, false);
92 assert_se(condition_test(condition
));
93 condition_free(condition
);
95 condition
= condition_new(CONDITION_PATH_IS_MOUNT_POINT
, "/", false, false);
97 assert_se(condition_test(condition
));
98 condition_free(condition
);
100 condition
= condition_new(CONDITION_PATH_IS_MOUNT_POINT
, "/bin", false, false);
101 assert_se(condition
);
102 assert_se(!condition_test(condition
));
103 condition_free(condition
);
105 condition
= condition_new(CONDITION_PATH_IS_READ_WRITE
, "/tmp", false, false);
106 assert_se(condition
);
107 assert_se(condition_test(condition
));
108 condition_free(condition
);
110 condition
= condition_new(CONDITION_PATH_IS_SYMBOLIC_LINK
, "/dev/stdout", false, false);
111 assert_se(condition
);
112 assert_se(condition_test(condition
));
113 condition_free(condition
);
116 static int test_condition_test_control_group_controller(void) {
117 Condition
*condition
;
118 CGroupMask system_mask
;
119 CGroupController controller
;
120 _cleanup_free_
char *controller_name
= NULL
;
123 r
= cg_unified_flush();
125 log_notice_errno(r
, "Skipping ConditionControlGroupController tests: %m");
126 return EXIT_TEST_SKIP
;
129 /* Invalid controllers are ignored */
130 condition
= condition_new(CONDITION_CONTROL_GROUP_CONTROLLER
, "thisisnotarealcontroller", false, false);
131 assert_se(condition
);
132 assert_se(condition_test(condition
));
133 condition_free(condition
);
135 condition
= condition_new(CONDITION_CONTROL_GROUP_CONTROLLER
, "thisisnotarealcontroller", false, true);
136 assert_se(condition
);
137 assert_se(!condition_test(condition
));
138 condition_free(condition
);
140 assert_se(cg_mask_supported(&system_mask
) >= 0);
142 /* Individual valid controllers one by one */
143 for (controller
= 0; controller
< _CGROUP_CONTROLLER_MAX
; controller
++) {
144 const char *local_controller_name
= cgroup_controller_to_string(controller
);
145 log_info("chosen controller is '%s'", local_controller_name
);
146 if (system_mask
& CGROUP_CONTROLLER_TO_MASK(controller
)) {
147 log_info("this controller is available");
148 condition
= condition_new(CONDITION_CONTROL_GROUP_CONTROLLER
, local_controller_name
, false, false);
149 assert_se(condition
);
150 assert_se(condition_test(condition
));
151 condition_free(condition
);
153 condition
= condition_new(CONDITION_CONTROL_GROUP_CONTROLLER
, local_controller_name
, false, true);
154 assert_se(condition
);
155 assert_se(!condition_test(condition
));
156 condition_free(condition
);
158 log_info("this controller is unavailable");
159 condition
= condition_new(CONDITION_CONTROL_GROUP_CONTROLLER
, local_controller_name
, false, false);
160 assert_se(condition
);
161 assert_se(!condition_test(condition
));
162 condition_free(condition
);
164 condition
= condition_new(CONDITION_CONTROL_GROUP_CONTROLLER
, local_controller_name
, false, true);
165 assert_se(condition
);
166 assert_se(condition_test(condition
));
167 condition_free(condition
);
171 /* Multiple valid controllers at the same time */
172 assert_se(cg_mask_to_string(system_mask
, &controller_name
) >= 0);
174 condition
= condition_new(CONDITION_CONTROL_GROUP_CONTROLLER
, strempty(controller_name
), false, false);
175 assert_se(condition
);
176 assert_se(condition_test(condition
));
177 condition_free(condition
);
179 condition
= condition_new(CONDITION_CONTROL_GROUP_CONTROLLER
, strempty(controller_name
), false, true);
180 assert_se(condition
);
181 assert_se(!condition_test(condition
));
182 condition_free(condition
);
187 static void test_condition_test_ac_power(void) {
188 Condition
*condition
;
190 condition
= condition_new(CONDITION_AC_POWER
, "true", false, false);
191 assert_se(condition
);
192 assert_se(condition_test(condition
) == on_ac_power());
193 condition_free(condition
);
195 condition
= condition_new(CONDITION_AC_POWER
, "false", false, false);
196 assert_se(condition
);
197 assert_se(condition_test(condition
) != on_ac_power());
198 condition_free(condition
);
200 condition
= condition_new(CONDITION_AC_POWER
, "false", false, true);
201 assert_se(condition
);
202 assert_se(condition_test(condition
) == on_ac_power());
203 condition_free(condition
);
206 static void test_condition_test_host(void) {
207 _cleanup_free_
char *hostname
= NULL
;
208 char sid
[SD_ID128_STRING_MAX
];
209 Condition
*condition
;
213 r
= sd_id128_get_machine(&id
);
215 assert_se(sd_id128_to_string(id
, sid
));
217 condition
= condition_new(CONDITION_HOST
, sid
, false, false);
218 assert_se(condition
);
219 assert_se(condition_test(condition
));
220 condition_free(condition
);
222 condition
= condition_new(CONDITION_HOST
, "garbage value jjjjjjjjjjjjjj", false, false);
223 assert_se(condition
);
224 assert_se(!condition_test(condition
));
225 condition_free(condition
);
227 condition
= condition_new(CONDITION_HOST
, sid
, false, true);
228 assert_se(condition
);
229 assert_se(!condition_test(condition
));
230 condition_free(condition
);
232 hostname
= gethostname_malloc();
235 /* if hostname looks like an id128 then skip testing it */
236 if (id128_is_valid(hostname
))
237 log_notice("hostname is an id128, skipping test");
239 condition
= condition_new(CONDITION_HOST
, hostname
, false, false);
240 assert_se(condition
);
241 assert_se(condition_test(condition
));
242 condition_free(condition
);
246 static void test_condition_test_architecture(void) {
247 Condition
*condition
;
251 a
= uname_architecture();
254 sa
= architecture_to_string(a
);
257 condition
= condition_new(CONDITION_ARCHITECTURE
, sa
, false, false);
258 assert_se(condition
);
259 assert_se(condition_test(condition
) > 0);
260 condition_free(condition
);
262 condition
= condition_new(CONDITION_ARCHITECTURE
, "garbage value", false, false);
263 assert_se(condition
);
264 assert_se(condition_test(condition
) == 0);
265 condition_free(condition
);
267 condition
= condition_new(CONDITION_ARCHITECTURE
, sa
, false, true);
268 assert_se(condition
);
269 assert_se(condition_test(condition
) == 0);
270 condition_free(condition
);
273 static void test_condition_test_kernel_command_line(void) {
274 Condition
*condition
;
276 condition
= condition_new(CONDITION_KERNEL_COMMAND_LINE
, "thisreallyshouldntbeonthekernelcommandline", false, false);
277 assert_se(condition
);
278 assert_se(!condition_test(condition
));
279 condition_free(condition
);
281 condition
= condition_new(CONDITION_KERNEL_COMMAND_LINE
, "andthis=neither", false, false);
282 assert_se(condition
);
283 assert_se(!condition_test(condition
));
284 condition_free(condition
);
287 static void test_condition_test_kernel_version(void) {
288 Condition
*condition
;
292 condition
= condition_new(CONDITION_KERNEL_VERSION
, "*thisreallyshouldntbeinthekernelversion*", false, false);
293 assert_se(condition
);
294 assert_se(!condition_test(condition
));
295 condition_free(condition
);
297 condition
= condition_new(CONDITION_KERNEL_VERSION
, "*", false, false);
298 assert_se(condition
);
299 assert_se(condition_test(condition
));
300 condition_free(condition
);
302 condition
= condition_new(CONDITION_KERNEL_VERSION
, "", false, false);
303 assert_se(condition
);
304 assert_se(!condition_test(condition
));
305 condition_free(condition
);
307 assert_se(uname(&u
) >= 0);
309 condition
= condition_new(CONDITION_KERNEL_VERSION
, u
.release
, false, false);
310 assert_se(condition
);
311 assert_se(condition_test(condition
));
312 condition_free(condition
);
314 strshorten(u
.release
, 4);
315 strcpy(strchr(u
.release
, 0), "*");
317 condition
= condition_new(CONDITION_KERNEL_VERSION
, u
.release
, false, false);
318 assert_se(condition
);
319 assert_se(condition_test(condition
));
320 condition_free(condition
);
322 /* 0.1.2 would be a very very very old kernel */
323 condition
= condition_new(CONDITION_KERNEL_VERSION
, "> 0.1.2", false, false);
324 assert_se(condition
);
325 assert_se(condition_test(condition
));
326 condition_free(condition
);
328 condition
= condition_new(CONDITION_KERNEL_VERSION
, ">= 0.1.2", false, false);
329 assert_se(condition
);
330 assert_se(condition_test(condition
));
331 condition_free(condition
);
333 condition
= condition_new(CONDITION_KERNEL_VERSION
, "< 0.1.2", false, false);
334 assert_se(condition
);
335 assert_se(!condition_test(condition
));
336 condition_free(condition
);
338 condition
= condition_new(CONDITION_KERNEL_VERSION
, "<= 0.1.2", false, false);
339 assert_se(condition
);
340 assert_se(!condition_test(condition
));
341 condition_free(condition
);
343 condition
= condition_new(CONDITION_KERNEL_VERSION
, "= 0.1.2", false, false);
344 assert_se(condition
);
345 assert_se(!condition_test(condition
));
346 condition_free(condition
);
348 /* 4711.8.15 is a very very very future kernel */
349 condition
= condition_new(CONDITION_KERNEL_VERSION
, "< 4711.8.15", false, false);
350 assert_se(condition
);
351 assert_se(condition_test(condition
));
352 condition_free(condition
);
354 condition
= condition_new(CONDITION_KERNEL_VERSION
, "<= 4711.8.15", false, false);
355 assert_se(condition
);
356 assert_se(condition_test(condition
));
357 condition_free(condition
);
359 condition
= condition_new(CONDITION_KERNEL_VERSION
, "= 4711.8.15", false, false);
360 assert_se(condition
);
361 assert_se(!condition_test(condition
));
362 condition_free(condition
);
364 condition
= condition_new(CONDITION_KERNEL_VERSION
, "> 4711.8.15", false, false);
365 assert_se(condition
);
366 assert_se(!condition_test(condition
));
367 condition_free(condition
);
369 condition
= condition_new(CONDITION_KERNEL_VERSION
, ">= 4711.8.15", false, false);
370 assert_se(condition
);
371 assert_se(!condition_test(condition
));
372 condition_free(condition
);
374 assert_se(uname(&u
) >= 0);
376 v
= strjoina(">=", u
.release
);
377 condition
= condition_new(CONDITION_KERNEL_VERSION
, v
, false, false);
378 assert_se(condition
);
379 assert_se(condition_test(condition
));
380 condition_free(condition
);
382 v
= strjoina("= ", u
.release
);
383 condition
= condition_new(CONDITION_KERNEL_VERSION
, v
, false, false);
384 assert_se(condition
);
385 assert_se(condition_test(condition
));
386 condition_free(condition
);
388 v
= strjoina("<=", u
.release
);
389 condition
= condition_new(CONDITION_KERNEL_VERSION
, v
, false, false);
390 assert_se(condition
);
391 assert_se(condition_test(condition
));
392 condition_free(condition
);
394 v
= strjoina("> ", u
.release
);
395 condition
= condition_new(CONDITION_KERNEL_VERSION
, v
, false, false);
396 assert_se(condition
);
397 assert_se(!condition_test(condition
));
398 condition_free(condition
);
400 v
= strjoina("< ", u
.release
);
401 condition
= condition_new(CONDITION_KERNEL_VERSION
, v
, false, false);
402 assert_se(condition
);
403 assert_se(!condition_test(condition
));
404 condition_free(condition
);
407 static void test_condition_test_null(void) {
408 Condition
*condition
;
410 condition
= condition_new(CONDITION_NULL
, NULL
, false, false);
411 assert_se(condition
);
412 assert_se(condition_test(condition
));
413 condition_free(condition
);
415 condition
= condition_new(CONDITION_NULL
, NULL
, false, true);
416 assert_se(condition
);
417 assert_se(!condition_test(condition
));
418 condition_free(condition
);
421 static void test_condition_test_security(void) {
422 Condition
*condition
;
424 condition
= condition_new(CONDITION_SECURITY
, "garbage oifdsjfoidsjoj", false, false);
425 assert_se(condition
);
426 assert_se(!condition_test(condition
));
427 condition_free(condition
);
429 condition
= condition_new(CONDITION_SECURITY
, "selinux", false, true);
430 assert_se(condition
);
431 assert_se(condition_test(condition
) != mac_selinux_use());
432 condition_free(condition
);
434 condition
= condition_new(CONDITION_SECURITY
, "apparmor", false, false);
435 assert_se(condition
);
436 assert_se(condition_test(condition
) == mac_apparmor_use());
437 condition_free(condition
);
439 condition
= condition_new(CONDITION_SECURITY
, "tomoyo", false, false);
440 assert_se(condition
);
441 assert_se(condition_test(condition
) == mac_tomoyo_use());
442 condition_free(condition
);
444 condition
= condition_new(CONDITION_SECURITY
, "ima", false, false);
445 assert_se(condition
);
446 assert_se(condition_test(condition
) == use_ima());
447 condition_free(condition
);
449 condition
= condition_new(CONDITION_SECURITY
, "smack", false, false);
450 assert_se(condition
);
451 assert_se(condition_test(condition
) == mac_smack_use());
452 condition_free(condition
);
454 condition
= condition_new(CONDITION_SECURITY
, "audit", false, false);
455 assert_se(condition
);
456 assert_se(condition_test(condition
) == use_audit());
457 condition_free(condition
);
459 condition
= condition_new(CONDITION_SECURITY
, "uefi-secureboot", false, false);
460 assert_se(condition
);
461 assert_se(condition_test(condition
) == is_efi_secure_boot());
462 condition_free(condition
);
465 static void print_securities(void) {
466 log_info("------ enabled security technologies ------");
467 log_info("SELinux: %s", yes_no(mac_selinux_use()));
468 log_info("AppArmor: %s", yes_no(mac_apparmor_use()));
469 log_info("Tomoyo: %s", yes_no(mac_tomoyo_use()));
470 log_info("IMA: %s", yes_no(use_ima()));
471 log_info("SMACK: %s", yes_no(mac_smack_use()));
472 log_info("Audit: %s", yes_no(use_audit()));
473 log_info("UEFI secure boot: %s", yes_no(is_efi_secure_boot()));
474 log_info("-------------------------------------------");
477 static void test_condition_test_virtualization(void) {
478 Condition
*condition
;
482 condition
= condition_new(CONDITION_VIRTUALIZATION
, "garbage oifdsjfoidsjoj", false, false);
483 assert_se(condition
);
484 r
= condition_test(condition
);
485 log_info("ConditionVirtualization=garbage → %i", r
);
487 condition_free(condition
);
489 condition
= condition_new(CONDITION_VIRTUALIZATION
, "container", false, false);
490 assert_se(condition
);
491 r
= condition_test(condition
);
492 log_info("ConditionVirtualization=container → %i", r
);
493 assert_se(r
== !!detect_container());
494 condition_free(condition
);
496 condition
= condition_new(CONDITION_VIRTUALIZATION
, "vm", false, false);
497 assert_se(condition
);
498 r
= condition_test(condition
);
499 log_info("ConditionVirtualization=vm → %i", r
);
500 assert_se(r
== (detect_vm() && !detect_container()));
501 condition_free(condition
);
503 condition
= condition_new(CONDITION_VIRTUALIZATION
, "private-users", false, false);
504 assert_se(condition
);
505 r
= condition_test(condition
);
506 log_info("ConditionVirtualization=private-users → %i", r
);
507 assert_se(r
== !!running_in_userns());
508 condition_free(condition
);
524 condition
= condition_new(CONDITION_VIRTUALIZATION
, virt
, false, false);
525 assert_se(condition
);
526 r
= condition_test(condition
);
527 log_info("ConditionVirtualization=%s → %i", virt
, r
);
529 condition_free(condition
);
533 static void test_condition_test_user(void) {
534 Condition
*condition
;
539 condition
= condition_new(CONDITION_USER
, "garbage oifdsjfoidsjoj", false, false);
540 assert_se(condition
);
541 r
= condition_test(condition
);
542 log_info("ConditionUser=garbage → %i", r
);
544 condition_free(condition
);
546 assert_se(asprintf(&uid
, "%"PRIu32
, UINT32_C(0xFFFF)) > 0);
547 condition
= condition_new(CONDITION_USER
, uid
, false, false);
548 assert_se(condition
);
549 r
= condition_test(condition
);
550 log_info("ConditionUser=%s → %i", uid
, r
);
552 condition_free(condition
);
555 assert_se(asprintf(&uid
, "%u", (unsigned)getuid()) > 0);
556 condition
= condition_new(CONDITION_USER
, uid
, false, false);
557 assert_se(condition
);
558 r
= condition_test(condition
);
559 log_info("ConditionUser=%s → %i", uid
, r
);
561 condition_free(condition
);
564 assert_se(asprintf(&uid
, "%u", (unsigned)getuid()+1) > 0);
565 condition
= condition_new(CONDITION_USER
, uid
, false, false);
566 assert_se(condition
);
567 r
= condition_test(condition
);
568 log_info("ConditionUser=%s → %i", uid
, r
);
570 condition_free(condition
);
573 username
= getusername_malloc();
575 condition
= condition_new(CONDITION_USER
, username
, false, false);
576 assert_se(condition
);
577 r
= condition_test(condition
);
578 log_info("ConditionUser=%s → %i", username
, r
);
580 condition_free(condition
);
583 username
= (char*)(geteuid() == 0 ? NOBODY_USER_NAME
: "root");
584 condition
= condition_new(CONDITION_USER
, username
, false, false);
585 assert_se(condition
);
586 r
= condition_test(condition
);
587 log_info("ConditionUser=%s → %i", username
, r
);
589 condition_free(condition
);
591 condition
= condition_new(CONDITION_USER
, "@system", false, false);
592 assert_se(condition
);
593 r
= condition_test(condition
);
594 log_info("ConditionUser=@system → %i", r
);
595 if (uid_is_system(getuid()) || uid_is_system(geteuid()))
599 condition_free(condition
);
602 static void test_condition_test_group(void) {
603 Condition
*condition
;
606 gid_t
*gids
, max_gid
;
607 int ngroups_max
, ngroups
, r
, i
;
609 assert_se(0 < asprintf(&gid
, "%u", UINT32_C(0xFFFF)));
610 condition
= condition_new(CONDITION_GROUP
, gid
, false, false);
611 assert_se(condition
);
612 r
= condition_test(condition
);
613 log_info("ConditionGroup=%s → %i", gid
, r
);
615 condition_free(condition
);
618 assert_se(0 < asprintf(&gid
, "%u", getgid()));
619 condition
= condition_new(CONDITION_GROUP
, gid
, false, false);
620 assert_se(condition
);
621 r
= condition_test(condition
);
622 log_info("ConditionGroup=%s → %i", gid
, r
);
624 condition_free(condition
);
627 ngroups_max
= sysconf(_SC_NGROUPS_MAX
);
628 assert(ngroups_max
> 0);
630 gids
= newa(gid_t
, ngroups_max
);
632 ngroups
= getgroups(ngroups_max
, gids
);
633 assert(ngroups
>= 0);
636 for (i
= 0; i
< ngroups
; i
++) {
637 assert_se(0 < asprintf(&gid
, "%u", gids
[i
]));
638 condition
= condition_new(CONDITION_GROUP
, gid
, false, false);
639 assert_se(condition
);
640 r
= condition_test(condition
);
641 log_info("ConditionGroup=%s → %i", gid
, r
);
643 condition_free(condition
);
645 max_gid
= gids
[i
] > max_gid
? gids
[i
] : max_gid
;
647 groupname
= gid_to_name(gids
[i
]);
648 assert_se(groupname
);
649 condition
= condition_new(CONDITION_GROUP
, groupname
, false, false);
650 assert_se(condition
);
651 r
= condition_test(condition
);
652 log_info("ConditionGroup=%s → %i", groupname
, r
);
654 condition_free(condition
);
656 max_gid
= gids
[i
] > max_gid
? gids
[i
] : max_gid
;
659 assert_se(0 < asprintf(&gid
, "%u", max_gid
+1));
660 condition
= condition_new(CONDITION_GROUP
, gid
, false, false);
661 assert_se(condition
);
662 r
= condition_test(condition
);
663 log_info("ConditionGroup=%s → %i", gid
, r
);
665 condition_free(condition
);
668 groupname
= (char*)(geteuid() == 0 ? NOBODY_GROUP_NAME
: "root");
669 condition
= condition_new(CONDITION_GROUP
, groupname
, false, false);
670 assert_se(condition
);
671 r
= condition_test(condition
);
672 log_info("ConditionGroup=%s → %i", groupname
, r
);
674 condition_free(condition
);
677 int main(int argc
, char *argv
[]) {
678 log_set_max_level(LOG_DEBUG
);
679 log_parse_environment();
682 test_condition_test_path();
683 test_condition_test_ac_power();
684 test_condition_test_host();
685 test_condition_test_architecture();
686 test_condition_test_kernel_command_line();
687 test_condition_test_kernel_version();
688 test_condition_test_null();
689 test_condition_test_security();
691 test_condition_test_virtualization();
692 test_condition_test_user();
693 test_condition_test_group();
694 test_condition_test_control_group_controller();