4 #include <dpl/test/test_runner.h>
5 #include <dpl/test/test_runner_multiprocess.h>
6 #include <dpl/log/log.h>
9 #include <glib-object.h>
10 #include <summary_collector.h>
11 #include "tests_common.h"
12 #include "security-server.h"
13 #include "privilege-control.h"
15 #define API_DATA_SHARE "security-server::api-data-share"
16 #define API_FREE_ACCESS "*"
18 #define DBUS_SERVER_NAME "test.method.server"
19 #define DBUS_SERVER_OBJECT "/test/method/server/Object"
20 #define DBUS_SERVER_INTERFACE DBUS_SERVER_NAME ".Type"
21 #define DBUS_SERVER_METHOD "Method"
22 #define DBUS_CALLER_NAME "test.method.caller"
24 #define DBUS_SMACK_NAME "org.freedesktop.DBus"
25 #define DBUS_SMACK_OBJECT "/org/freedesktop/DBus"
26 #define DBUS_SMACK_INTERFACE "org.freedesktop.DBus"
27 #define DBUS_SMACK_METHOD "GetConnectionCredentials"
29 RUNNER_TEST_GROUP_INIT(SECURITY_SERVER_TESTS_DBUS);
31 RUNNER_MULTIPROCESS_TEST_SMACK(tc01_smack_context_from_DBus)
34 const char *subject_parent = "subject_parent";
35 const char *subject_child = "subject_child";
36 struct smack_accesses *handle = NULL;
38 DBusMessage* msg = NULL;
39 DBusMessageIter args, iter, var, var_iter, var_value;
40 DBusConnection* conn = NULL;
42 DBusPendingCall *pending = NULL;
43 const char *dbus_server_name = DBUS_SERVER_NAME;
44 char *smack_context = NULL;
47 RUNNER_ASSERT_MSG_BT(-1 != pid, "fork() failed");
51 ret = smack_set_label_for_self(subject_child);
52 RUNNER_ASSERT_MSG_BT(ret == PC_OPERATION_SUCCESS,
53 "smack_set__label_for_self() failed, ret: " << ret);
55 ret = smack_accesses_new(&handle);
56 RUNNER_ASSERT_MSG_BT(ret == PC_OPERATION_SUCCESS,
57 "smack_accesses_new() failed, ret: " << ret);
59 ret = smack_accesses_add(handle, subject_child, API_DATA_SHARE, API_FREE_ACCESS);
60 RUNNER_ASSERT_MSG_BT(ret == PC_OPERATION_SUCCESS,
61 "smack_accesses_add() failed, ret: " << ret);
63 ret = smack_accesses_apply(handle);
64 RUNNER_ASSERT_MSG_BT(ret == PC_OPERATION_SUCCESS,
65 "smack_accesses_apply() failed, ret: " << ret);
67 ret = smack_set_label_for_self(subject_child);
68 RUNNER_ASSERT_MSG_BT(ret == PC_OPERATION_SUCCESS,
69 "smack_set_label_for_self() failed, ret: " << ret);
71 smack_accesses_free(handle);
73 // initialize the errors
74 dbus_error_init(&err);
76 // connect to the system bus and check for errors
77 conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
78 ret = dbus_error_is_set(&err);
80 dbus_error_free(&err);
81 RUNNER_ASSERT_MSG_BT(0 == ret, "dbus_bus_get() failed, ret: " << ret);
84 // request our name on the bus
85 ret = dbus_bus_request_name(conn, DBUS_CALLER_NAME, DBUS_NAME_FLAG_REPLACE_EXISTING , &err);
86 if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) {
87 dbus_error_free(&err);
88 RUNNER_ASSERT_MSG_BT(DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret,
89 "dbus_bus_request_name() failed, ret: " << ret);
92 // crate a new method call for checking SMACK context from DBus interface
93 msg = dbus_message_new_method_call(DBUS_SMACK_NAME,
98 RUNNER_ASSERT_MSG_BT(NULL != msg,
99 "dbus_message_new_method_call() failed, ret: " << ret);
101 // append arguments, we need SMACK context for our parent process "test.method.server"
102 dbus_message_iter_init_append(msg, &args);
103 ret = dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &dbus_server_name);
104 RUNNER_ASSERT_MSG_BT(1 == ret, "Out of memory");
106 // wait for parent to connect to DBus
109 // send message and get a handle for a reply
110 // -1 is default timeout
111 ret = dbus_connection_send_with_reply (conn, msg, &pending, -1);
112 RUNNER_ASSERT_MSG_BT(1 == ret, "Out of memory");
113 RUNNER_ASSERT_MSG_BT(NULL != pending, "Pending call null");
115 dbus_connection_flush(conn);
118 dbus_message_unref(msg);
121 dbus_pending_call_block(pending);
124 msg = dbus_pending_call_steal_reply(pending);
125 RUNNER_ASSERT_MSG_BT(NULL != msg, "Reply null");
127 // free message handle
128 dbus_pending_call_unref(pending);
130 ret = dbus_message_iter_init(msg, &iter);
131 RUNNER_ASSERT_MSG_BT(0 != ret, "Message has no arguments");
133 dbus_message_iter_recurse(&iter, &var);
135 while (dbus_message_iter_get_arg_type(&var) != DBUS_TYPE_INVALID) {
136 dbus_message_iter_recurse(&var, &var_iter);
137 while(dbus_message_iter_get_arg_type(&var_iter) != DBUS_TYPE_INVALID) {
138 dbus_message_iter_recurse(&var_iter, &var_value);
139 switch(dbus_message_iter_get_arg_type(&var_value)) {
140 case DBUS_TYPE_STRING:
141 dbus_message_iter_get_basic(&var_value, &smack_context);
146 dbus_message_iter_next(&var_iter);
148 dbus_message_iter_next(&var);
151 // free reply and close connection
152 dbus_message_unref(msg);
153 dbus_connection_unref(conn);
155 RUNNER_ASSERT_BT(smack_context != NULL);
156 ret = strcmp(smack_context, subject_parent);
157 RUNNER_ASSERT_MSG_BT(0 == ret,
158 "Context mismatch! context from dbus: " << smack_context);
164 ret = smack_set_label_for_self(subject_parent);
165 RUNNER_ASSERT_MSG_BT(ret == PC_OPERATION_SUCCESS,
166 "smack_set_label_for_self() failed, ret: " << ret);
168 ret = smack_accesses_new(&handle);
169 RUNNER_ASSERT_MSG_BT(ret == PC_OPERATION_SUCCESS,
170 "smack_accesses_new() failed, ret: " << ret);
172 ret = smack_accesses_add(handle, subject_parent, API_DATA_SHARE, API_FREE_ACCESS);
173 RUNNER_ASSERT_MSG_BT(ret == PC_OPERATION_SUCCESS,
174 "smack_accesses_add() failed, ret: " << ret);
176 ret = smack_accesses_apply(handle);
177 RUNNER_ASSERT_MSG_BT(ret == PC_OPERATION_SUCCESS,
178 "smack_accesses_apply() failed, ret: " << ret);
180 ret = smack_set_label_for_self(subject_parent);
181 RUNNER_ASSERT_MSG_BT(ret == PC_OPERATION_SUCCESS,
182 "smack_set_label_for_self() failed, ret: " << ret);
184 smack_accesses_free(handle);
186 // initialise the error
187 dbus_error_init(&err);
189 // connect to the bus and check for errors
190 conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
191 ret = dbus_error_is_set(&err);
193 dbus_error_free(&err);
194 RUNNER_ASSERT_MSG_BT(0 == ret, "dbus_bus_get() failed, ret: " << ret);
197 // request our name on the bus and check for errors
198 ret = dbus_bus_request_name(conn, DBUS_SERVER_NAME, DBUS_NAME_FLAG_REPLACE_EXISTING , &err);
199 if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) {
200 dbus_error_free(&err);
201 RUNNER_ASSERT_MSG_BT(DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret,
202 "dbus_bus_request_name() failed, ret: " << ret);
205 // close the connection
206 dbus_connection_unref(conn);
210 ///////////////////////////////////////
211 //////NOSMACK ENV TESTS////////////////
212 ///////////////////////////////////////
215 * NOSMACK version of tc01 test.
217 * This is almost an exact copy of the original SMACK DBus test. As in previous security-server
218 * tests, parts where SMACK is used are skipped, because most important functions will return error.
220 RUNNER_MULTIPROCESS_TEST_NOSMACK(tc01_smack_context_from_DBus_nosmack)
223 const char* subject_parent = "subject_parent";
225 DBusMessage* msg = NULL;
226 DBusMessageIter args, iter, var, var_iter, var_value;
227 DBusConnection* conn = NULL;
229 DBusPendingCall *pending = NULL;
230 const char *dbus_server_name = DBUS_SERVER_NAME;
231 char *smack_context = NULL;
234 RUNNER_ASSERT_MSG_BT(-1 != pid, "fork() failed");
239 // initialize the errors
240 dbus_error_init(&err);
242 // connect to the system bus and check for errors; failure = exit with result 1
243 conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
244 ret = dbus_error_is_set(&err);
246 dbus_error_free(&err);
247 RUNNER_ASSERT_MSG_BT(false, "Failed to connect to system bus. Ret " << ret);
250 // request our name on the bus; failure = exit with result 2
251 ret = dbus_bus_request_name(conn, DBUS_CALLER_NAME, DBUS_NAME_FLAG_REPLACE_EXISTING , &err);
252 if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) {
253 dbus_error_free(&err);
254 RUNNER_ASSERT_MSG_BT(false, "Failed to request name on the bus. Ret " << ret);
257 // crate a new method call for checking SMACK context from DBus interface
258 msg = dbus_message_new_method_call(DBUS_SMACK_NAME,
260 DBUS_SMACK_INTERFACE,
263 RUNNER_ASSERT_MSG_BT(msg != NULL, "dbus_message_new_method_call() failed.");
265 // append arguments, we need SMACK context for our parent process "test.method.server"
266 dbus_message_iter_init_append(msg, &args);
267 ret = dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &dbus_server_name);
268 RUNNER_ASSERT_MSG_BT(ret == 1, "Out of memory. Ret " << ret);
270 // wait for parent to connect to DBus
273 // send message and get a handle for a reply
274 // -1 is default timeout
275 ret = dbus_connection_send_with_reply (conn, msg, &pending, -1);
276 RUNNER_ASSERT_MSG_BT(ret == 1, "Out of memory. Ret " << ret);
277 RUNNER_ASSERT_MSG_BT(pending != NULL, "Pending call is NULL.");
279 dbus_connection_flush(conn);
282 dbus_message_unref(msg);
285 dbus_pending_call_block(pending);
288 msg = dbus_pending_call_steal_reply(pending);
289 RUNNER_ASSERT_MSG_BT(msg != NULL, "Failed to get the reply from bus.");
291 // free message handle
292 dbus_pending_call_unref(pending);
294 ret = dbus_message_iter_init(msg, &iter);
295 RUNNER_ASSERT_MSG_BT(ret != 0, "DBus message has no arguments. Ret " << ret);
297 dbus_message_iter_recurse(&iter, &var);
298 while (dbus_message_iter_get_arg_type(&var) != DBUS_TYPE_INVALID) {
299 dbus_message_iter_recurse(&var, &var_iter);
300 while(dbus_message_iter_get_arg_type(&var_iter) != DBUS_TYPE_INVALID) {
301 dbus_message_iter_recurse(&var_iter, &var_value);
302 switch(dbus_message_iter_get_arg_type(&var_value)) {
303 case DBUS_TYPE_STRING:
304 dbus_message_iter_get_basic(&var_value, &smack_context);
309 dbus_message_iter_next(&var_iter);
311 dbus_message_iter_next(&var);
314 // free reply and close connection
315 dbus_message_unref(msg);
316 dbus_connection_unref(conn);
318 RUNNER_ASSERT_BT(smack_context != NULL);
319 ret = strcmp(smack_context, subject_parent);
320 RUNNER_ASSERT_MSG_BT(ret == 0, "Context mismatch. Context " << smack_context);
327 // initialise the error
328 dbus_error_init(&err);
330 // connect to the bus and check for errors
331 conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
332 ret = dbus_error_is_set(&err);
334 dbus_error_free(&err);
335 RUNNER_ASSERT_MSG_BT(0 == ret, "dbus_bus_get() failed, ret: " << ret);
338 // request our name on the bus and check for errors
339 ret = dbus_bus_request_name(conn, DBUS_SERVER_NAME, DBUS_NAME_FLAG_REPLACE_EXISTING , &err);
340 if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) {
341 dbus_error_free(&err);
342 RUNNER_ASSERT_MSG_BT(DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret,
343 "dbus_bus_request_name() failed, ret: " << ret);
346 // close the connection
347 dbus_connection_unref(conn);
351 int main(int argc, char *argv[])
353 SummaryCollector::Register();
354 return DPL::Test::TestRunnerSingleton::Instance().ExecTestRunner(argc, argv);