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 "tests_common.h"
11 #include "security-server.h"
12 #include "privilege-control.h"
14 #define API_DATA_SHARE "security-server::api-data-share"
15 #define API_FREE_ACCESS "*"
17 #define DBUS_SERVER_NAME "test.method.server"
18 #define DBUS_SERVER_OBJECT "/test/method/server/Object"
19 #define DBUS_SERVER_INTERFACE DBUS_SERVER_NAME ".Type"
20 #define DBUS_SERVER_METHOD "Method"
21 #define DBUS_CALLER_NAME "test.method.caller"
23 #define DBUS_SMACK_NAME "org.freedesktop.DBus"
24 #define DBUS_SMACK_OBJECT "/org/freedesktop/DBus"
25 #define DBUS_SMACK_INTERFACE "org.freedesktop.DBus"
26 #define DBUS_SMACK_METHOD "GetConnectionCredentials"
28 RUNNER_TEST_GROUP_INIT(SECURITY_SERVER_TESTS_DBUS);
30 RUNNER_MULTIPROCESS_TEST_SMACK(tc01_smack_context_from_DBus)
33 const char *subject_parent = "subject_parent";
34 const char *subject_child = "subject_child";
35 struct smack_accesses *handle = NULL;
37 DBusMessage* msg = NULL;
38 DBusMessageIter args, iter, var, var_iter, var_value;
39 DBusConnection* conn = NULL;
41 DBusPendingCall *pending = NULL;
42 const char *dbus_server_name = DBUS_SERVER_NAME;
43 char *smack_context = NULL;
46 RUNNER_ASSERT_MSG(-1 != pid, "fork() failed");
50 ret = smack_set_label_for_self(subject_child);
51 RUNNER_ASSERT_MSG(ret == PC_OPERATION_SUCCESS,
52 "smack_set__label_for_self() failed, ret: " << ret);
54 ret = smack_accesses_new(&handle);
55 RUNNER_ASSERT_MSG(ret == PC_OPERATION_SUCCESS,
56 "smack_accesses_new() failed, ret: " << ret);
58 ret = smack_accesses_add(handle, subject_child, API_DATA_SHARE, API_FREE_ACCESS);
59 RUNNER_ASSERT_MSG(ret == PC_OPERATION_SUCCESS,
60 "smack_accesses_add() failed, ret: " << ret);
62 ret = smack_accesses_apply(handle);
63 RUNNER_ASSERT_MSG(ret == PC_OPERATION_SUCCESS,
64 "smack_accesses_apply() failed, ret: " << ret);
66 ret = smack_set_label_for_self(subject_child);
67 RUNNER_ASSERT_MSG(ret == PC_OPERATION_SUCCESS,
68 "smack_set_label_for_self() failed, ret: " << ret);
70 smack_accesses_free(handle);
72 // initialize the errors
73 dbus_error_init(&err);
75 // connect to the system bus and check for errors
76 conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
77 ret = dbus_error_is_set(&err);
79 dbus_error_free(&err);
80 RUNNER_ASSERT_MSG(0 == ret, "dbus_bus_get() failed, ret: " << ret);
83 // request our name on the bus
84 ret = dbus_bus_request_name(conn, DBUS_CALLER_NAME, DBUS_NAME_FLAG_REPLACE_EXISTING , &err);
85 if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) {
86 dbus_error_free(&err);
87 RUNNER_ASSERT_MSG(DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret,
88 "dbus_bus_request_name() failed, ret: " << ret);
91 // crate a new method call for checking SMACK context from DBus interface
92 msg = dbus_message_new_method_call(DBUS_SMACK_NAME,
97 RUNNER_ASSERT_MSG(NULL != msg,
98 "dbus_message_new_method_call() failed, ret: " << ret);
100 // append arguments, we need SMACK context for our parent process "test.method.server"
101 dbus_message_iter_init_append(msg, &args);
102 ret = dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &dbus_server_name);
103 RUNNER_ASSERT_MSG(1 == ret, "Out of memory");
105 // wait for parent to connect to DBus
108 // send message and get a handle for a reply
109 // -1 is default timeout
110 ret = dbus_connection_send_with_reply (conn, msg, &pending, -1);
111 RUNNER_ASSERT_MSG(1 == ret, "Out of memory");
112 RUNNER_ASSERT_MSG(NULL != pending, "Pending call null");
114 dbus_connection_flush(conn);
117 dbus_message_unref(msg);
120 dbus_pending_call_block(pending);
123 msg = dbus_pending_call_steal_reply(pending);
124 RUNNER_ASSERT_MSG(NULL != msg, "Reply null");
126 // free message handle
127 dbus_pending_call_unref(pending);
129 ret = dbus_message_iter_init(msg, &iter);
131 RUNNER_ASSERT_MSG(0 == ret, "Message has no arguments");
133 dbus_message_iter_recurse(&iter, &var);
134 while (dbus_message_iter_get_arg_type(&var) != DBUS_TYPE_INVALID) {
135 dbus_message_iter_recurse(&var, &var_iter);
136 while(dbus_message_iter_get_arg_type(&var_iter) != DBUS_TYPE_INVALID) {
137 dbus_message_iter_recurse(&var_iter, &var_value);
138 switch(dbus_message_iter_get_arg_type(&var_value)) {
139 case DBUS_TYPE_STRING:
140 dbus_message_iter_get_basic(&var_value, &smack_context);
145 dbus_message_iter_next(&var_iter);
147 dbus_message_iter_next(&var);
151 // free reply and close connection
152 dbus_message_unref(msg);
153 dbus_connection_unref(conn);
155 ret = strcmp(smack_context, subject_parent);
156 RUNNER_ASSERT_MSG(0 == ret,
157 "Context mismatch! context from dbus: " << smack_context);
163 ret = smack_set_label_for_self(subject_parent);
164 RUNNER_ASSERT_MSG(ret == PC_OPERATION_SUCCESS,
165 "smack_set_label_for_self() failed, ret: " << ret);
167 ret = smack_accesses_new(&handle);
168 RUNNER_ASSERT_MSG(ret == PC_OPERATION_SUCCESS,
169 "smack_accesses_new() failed, ret: " << ret);
171 ret = smack_accesses_add(handle, subject_parent, API_DATA_SHARE, API_FREE_ACCESS);
172 RUNNER_ASSERT_MSG(ret == PC_OPERATION_SUCCESS,
173 "smack_accesses_add() failed, ret: " << ret);
175 ret = smack_accesses_apply(handle);
176 RUNNER_ASSERT_MSG(ret == PC_OPERATION_SUCCESS,
177 "smack_accesses_apply() failed, ret: " << ret);
179 ret = smack_set_label_for_self(subject_parent);
180 RUNNER_ASSERT_MSG(ret == PC_OPERATION_SUCCESS,
181 "smack_set_label_for_self() failed, ret: " << ret);
183 smack_accesses_free(handle);
185 // initialise the error
186 dbus_error_init(&err);
188 // connect to the bus and check for errors
189 conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
190 ret = dbus_error_is_set(&err);
192 dbus_error_free(&err);
193 RUNNER_ASSERT_MSG(0 == ret, "dbus_bus_get() failed, ret: " << ret);
196 // request our name on the bus and check for errors
197 ret = dbus_bus_request_name(conn, DBUS_SERVER_NAME, DBUS_NAME_FLAG_REPLACE_EXISTING , &err);
198 if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) {
199 dbus_error_free(&err);
200 RUNNER_ASSERT_MSG(DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret,
201 "dbus_bus_request_name() failed, ret: " << ret);
204 // close the connection
205 dbus_connection_unref(conn);
209 ///////////////////////////////////////
210 //////NOSMACK ENV TESTS////////////////
211 ///////////////////////////////////////
214 * NOSMACK version of tc01 test.
216 * This is almost an exact copy of the original SMACK DBus test. As in previous security-server
217 * tests, parts where SMACK is used are skipped, because most important functions will return error.
219 RUNNER_MULTIPROCESS_TEST_NOSMACK(tc01_smack_context_from_DBus_nosmack)
222 const char* subject_parent = "subject_parent";
224 DBusMessage* msg = NULL;
225 DBusMessageIter args, iter, var, var_iter, var_value;
226 DBusConnection* conn = NULL;
228 DBusPendingCall *pending = NULL;
229 const char *dbus_server_name = DBUS_SERVER_NAME;
230 char *smack_context = NULL;
233 RUNNER_ASSERT_MSG(-1 != pid, "fork() failed");
238 // initialize the errors
239 dbus_error_init(&err);
241 // connect to the system bus and check for errors; failure = exit with result 1
242 conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
243 ret = dbus_error_is_set(&err);
245 dbus_error_free(&err);
246 RUNNER_ASSERT_MSG(false, "Failed to connect to system bus. Ret " << ret);
249 // request our name on the bus; failure = exit with result 2
250 ret = dbus_bus_request_name(conn, DBUS_CALLER_NAME, DBUS_NAME_FLAG_REPLACE_EXISTING , &err);
251 if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) {
252 dbus_error_free(&err);
253 RUNNER_ASSERT_MSG(false, "Failed to request name on the bus. Ret " << ret);
256 // crate a new method call for checking SMACK context from DBus interface
257 msg = dbus_message_new_method_call(DBUS_SMACK_NAME,
259 DBUS_SMACK_INTERFACE,
262 RUNNER_ASSERT_MSG(msg != NULL, "dbus_message_new_method_call() failed.");
264 // append arguments, we need SMACK context for our parent process "test.method.server"
265 dbus_message_iter_init_append(msg, &args);
266 ret = dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &dbus_server_name);
267 RUNNER_ASSERT_MSG(ret == 1, "Out of memory. Ret " << ret);
269 // wait for parent to connect to DBus
272 // send message and get a handle for a reply
273 // -1 is default timeout
274 ret = dbus_connection_send_with_reply (conn, msg, &pending, -1);
275 RUNNER_ASSERT_MSG(ret == 1, "Out of memory. Ret " << ret);
276 RUNNER_ASSERT_MSG(pending != NULL, "Pending call is NULL.");
278 dbus_connection_flush(conn);
281 dbus_message_unref(msg);
284 dbus_pending_call_block(pending);
287 msg = dbus_pending_call_steal_reply(pending);
288 RUNNER_ASSERT_MSG(msg != NULL, "Failed to get the reply from bus.");
290 // free message handle
291 dbus_pending_call_unref(pending);
293 ret = dbus_message_iter_init(msg, &iter);
294 RUNNER_ASSERT_MSG(ret != 0, "DBus message has no arguments. Ret " << ret);
296 dbus_message_iter_recurse(&iter, &var);
297 while (dbus_message_iter_get_arg_type(&var) != DBUS_TYPE_INVALID) {
298 dbus_message_iter_recurse(&var, &var_iter);
299 while(dbus_message_iter_get_arg_type(&var_iter) != DBUS_TYPE_INVALID) {
300 dbus_message_iter_recurse(&var_iter, &var_value);
301 switch(dbus_message_iter_get_arg_type(&var_value)) {
302 case DBUS_TYPE_STRING:
303 dbus_message_iter_get_basic(&var_value, &smack_context);
308 dbus_message_iter_next(&var_iter);
310 dbus_message_iter_next(&var);
313 // free reply and close connection
314 dbus_message_unref(msg);
315 dbus_connection_unref(conn);
317 ret = strcmp(smack_context, subject_parent);
318 RUNNER_ASSERT_MSG(ret == 0, "Context mismatch. Context " << smack_context);
325 // initialise the error
326 dbus_error_init(&err);
328 // connect to the bus and check for errors
329 conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
330 ret = dbus_error_is_set(&err);
332 dbus_error_free(&err);
333 RUNNER_ASSERT_MSG(0 == ret, "dbus_bus_get() failed, ret: " << ret);
336 // request our name on the bus and check for errors
337 ret = dbus_bus_request_name(conn, DBUS_SERVER_NAME, DBUS_NAME_FLAG_REPLACE_EXISTING , &err);
338 if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) {
339 dbus_error_free(&err);
340 RUNNER_ASSERT_MSG(DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret,
341 "dbus_bus_request_name() failed, ret: " << ret);
344 // close the connection
345 dbus_connection_unref(conn);
349 int main(int argc, char *argv[])
351 int status = DPL::Test::TestRunnerSingleton::Instance().ExecTestRunner(argc, argv);