4 #include <dpl/test/test_runner.h>
5 #include <dpl/test/test_runner_multiprocess.h>
7 #include "tests_common.h"
9 #define DBUS_SERVER_NAME "test.method.server"
10 #define DBUS_CALLER_NAME "test.method.caller"
12 #define DBUS_SMACK_NAME "org.freedesktop.DBus"
13 #define DBUS_SMACK_OBJECT "/org/freedesktop/DBus"
14 #define DBUS_SMACK_INTERFACE "org.freedesktop.DBus"
15 #define DBUS_SMACK_METHOD "GetConnectionCredentials"
17 RUNNER_TEST_GROUP_INIT(SMACK_DBUS);
19 RUNNER_MULTIPROCESS_TEST_SMACK(tc01_smack_context_from_DBus)
21 RUNNER_IGNORED_MSG("dbus does not support smack context in GetConnectionCredentials method"
25 const char *subject_parent = "subject_parent";
26 const char *subject_child = "subject_child";
28 DBusMessage* msg = nullptr;
29 DBusMessageIter args, iter, var, var_iter, var_value;
30 DBusConnection* conn = nullptr;
32 DBusPendingCall *pending = nullptr;
33 const char *dbus_server_name = DBUS_SERVER_NAME;
34 char *smack_context = nullptr;
37 RUNNER_ASSERT_ERRNO_MSG(-1 != pid, "fork() failed");
41 ret = smack_set_label_for_self(subject_child);
42 RUNNER_ASSERT_MSG(ret == PC_OPERATION_SUCCESS,
43 "smack_set__label_for_self() failed, ret: " << ret);
45 // initialize the errors
46 dbus_error_init(&err);
48 // connect to the system bus and check for errors
49 conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
50 ret = dbus_error_is_set(&err);
52 dbus_error_free(&err);
53 RUNNER_ASSERT_MSG(0 == ret, "dbus_bus_get() failed, ret: " << ret);
56 // request our name on the bus
57 ret = dbus_bus_request_name(conn, DBUS_CALLER_NAME, DBUS_NAME_FLAG_REPLACE_EXISTING , &err);
58 if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) {
59 dbus_error_free(&err);
60 RUNNER_ASSERT_MSG(DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret,
61 "dbus_bus_request_name() failed, ret: " << ret);
64 // crate a new method call for checking SMACK context from DBus interface
65 msg = dbus_message_new_method_call(DBUS_SMACK_NAME,
70 RUNNER_ASSERT_MSG(nullptr != msg,
71 "dbus_message_new_method_call() failed, ret: " << ret);
73 // append arguments, we need SMACK context for our parent process "test.method.server"
74 dbus_message_iter_init_append(msg, &args);
75 ret = dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &dbus_server_name);
76 RUNNER_ASSERT_MSG(1 == ret, "Out of memory");
78 // wait for parent to connect to DBus
81 // send message and get a handle for a reply
82 // -1 is default timeout
83 ret = dbus_connection_send_with_reply (conn, msg, &pending, -1);
84 RUNNER_ASSERT_MSG(1 == ret, "Out of memory");
85 RUNNER_ASSERT_MSG(nullptr != pending, "Pending call null");
87 dbus_connection_flush(conn);
90 dbus_message_unref(msg);
93 dbus_pending_call_block(pending);
96 msg = dbus_pending_call_steal_reply(pending);
97 RUNNER_ASSERT_MSG(nullptr != msg, "Reply null");
99 // free message handle
100 dbus_pending_call_unref(pending);
102 ret = dbus_message_iter_init(msg, &iter);
103 RUNNER_ASSERT_MSG(0 != ret, "Message has no arguments");
105 dbus_message_iter_recurse(&iter, &var);
107 while (dbus_message_iter_get_arg_type(&var) != DBUS_TYPE_INVALID) {
108 dbus_message_iter_recurse(&var, &var_iter);
109 while(dbus_message_iter_get_arg_type(&var_iter) != DBUS_TYPE_INVALID) {
110 dbus_message_iter_recurse(&var_iter, &var_value);
111 switch(dbus_message_iter_get_arg_type(&var_value)) {
112 case DBUS_TYPE_STRING:
113 dbus_message_iter_get_basic(&var_value, &smack_context);
118 dbus_message_iter_next(&var_iter);
120 dbus_message_iter_next(&var);
123 // free reply and close connection
124 dbus_message_unref(msg);
125 dbus_connection_unref(conn);
127 RUNNER_ASSERT(smack_context != nullptr);
128 ret = strcmp(smack_context, subject_parent);
129 RUNNER_ASSERT_MSG(0 == ret,
130 "Context mismatch! context from dbus: " << smack_context);
136 ret = smack_set_label_for_self(subject_parent);
137 RUNNER_ASSERT_MSG(ret == PC_OPERATION_SUCCESS,
138 "smack_set_label_for_self() failed, ret: " << ret);
140 // initialise the error
141 dbus_error_init(&err);
143 // connect to the bus and check for errors
144 conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
145 ret = dbus_error_is_set(&err);
147 dbus_error_free(&err);
148 RUNNER_ASSERT_MSG(0 == ret, "dbus_bus_get() failed, ret: " << ret);
151 // request our name on the bus and check for errors
152 ret = dbus_bus_request_name(conn, DBUS_SERVER_NAME, DBUS_NAME_FLAG_REPLACE_EXISTING , &err);
153 if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) {
154 dbus_error_free(&err);
155 RUNNER_ASSERT_MSG(DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret,
156 "dbus_bus_request_name() failed, ret: " << ret);
159 // close the connection
160 dbus_connection_unref(conn);
164 ///////////////////////////////////////
165 //////NOSMACK ENV TESTS////////////////
166 ///////////////////////////////////////
168 RUNNER_MULTIPROCESS_TEST_NOSMACK(tc01_smack_context_from_DBus_nosmack)
170 RUNNER_IGNORED_MSG("dbus does not support smack context in GetConnectionCredentials method"
174 const char* subject_parent = "subject_parent";
176 DBusMessage* msg = nullptr;
177 DBusMessageIter args, iter, var, var_iter, var_value;
178 DBusConnection* conn = nullptr;
180 DBusPendingCall *pending = nullptr;
181 const char *dbus_server_name = DBUS_SERVER_NAME;
182 char *smack_context = nullptr;
185 RUNNER_ASSERT_ERRNO_MSG(-1 != pid, "fork() failed");
190 // initialize the errors
191 dbus_error_init(&err);
193 // connect to the system bus and check for errors; failure = exit with result 1
194 conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
195 ret = dbus_error_is_set(&err);
197 dbus_error_free(&err);
198 RUNNER_FAIL_MSG("Failed to connect to system bus. Ret " << ret);
201 // request our name on the bus; failure = exit with result 2
202 ret = dbus_bus_request_name(conn, DBUS_CALLER_NAME, DBUS_NAME_FLAG_REPLACE_EXISTING , &err);
203 if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) {
204 dbus_error_free(&err);
205 RUNNER_FAIL_MSG("Failed to request name on the bus. Ret " << ret);
208 // crate a new method call for checking SMACK context from DBus interface
209 msg = dbus_message_new_method_call(DBUS_SMACK_NAME,
211 DBUS_SMACK_INTERFACE,
214 RUNNER_ASSERT_MSG(msg != nullptr, "dbus_message_new_method_call() failed.");
216 // append arguments, we need SMACK context for our parent process "test.method.server"
217 dbus_message_iter_init_append(msg, &args);
218 ret = dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &dbus_server_name);
219 RUNNER_ASSERT_MSG(ret == 1, "Out of memory. Ret " << ret);
221 // wait for parent to connect to DBus
224 // send message and get a handle for a reply
225 // -1 is default timeout
226 ret = dbus_connection_send_with_reply (conn, msg, &pending, -1);
227 RUNNER_ASSERT_MSG(ret == 1, "Out of memory. Ret " << ret);
228 RUNNER_ASSERT_MSG(pending != nullptr, "Pending call is nullptr.");
230 dbus_connection_flush(conn);
233 dbus_message_unref(msg);
236 dbus_pending_call_block(pending);
239 msg = dbus_pending_call_steal_reply(pending);
240 RUNNER_ASSERT_MSG(msg != nullptr, "Failed to get the reply from bus.");
242 // free message handle
243 dbus_pending_call_unref(pending);
245 ret = dbus_message_iter_init(msg, &iter);
246 RUNNER_ASSERT_MSG(ret != 0, "DBus message has no arguments. Ret " << ret);
248 dbus_message_iter_recurse(&iter, &var);
249 while (dbus_message_iter_get_arg_type(&var) != DBUS_TYPE_INVALID) {
250 dbus_message_iter_recurse(&var, &var_iter);
251 while(dbus_message_iter_get_arg_type(&var_iter) != DBUS_TYPE_INVALID) {
252 dbus_message_iter_recurse(&var_iter, &var_value);
253 switch(dbus_message_iter_get_arg_type(&var_value)) {
254 case DBUS_TYPE_STRING:
255 dbus_message_iter_get_basic(&var_value, &smack_context);
260 dbus_message_iter_next(&var_iter);
262 dbus_message_iter_next(&var);
265 // free reply and close connection
266 dbus_message_unref(msg);
267 dbus_connection_unref(conn);
269 RUNNER_ASSERT(smack_context != nullptr);
270 ret = strcmp(smack_context, subject_parent);
271 RUNNER_ASSERT_MSG(ret == 0, "Context mismatch. Context " << smack_context);
278 // initialise the error
279 dbus_error_init(&err);
281 // connect to the bus and check for errors
282 conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
283 ret = dbus_error_is_set(&err);
285 dbus_error_free(&err);
286 RUNNER_ASSERT_MSG(0 == ret, "dbus_bus_get() failed, ret: " << ret);
289 // request our name on the bus and check for errors
290 ret = dbus_bus_request_name(conn, DBUS_SERVER_NAME, DBUS_NAME_FLAG_REPLACE_EXISTING , &err);
291 if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) {
292 dbus_error_free(&err);
293 RUNNER_ASSERT_MSG(DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret,
294 "dbus_bus_request_name() failed, ret: " << ret);
297 // close the connection
298 dbus_connection_unref(conn);
302 int main(int argc, char *argv[])
304 return DPL::Test::TestRunnerSingleton::Instance().ExecTestRunner(argc, argv);