[cynara] Tests for new credentials helpers API
[platform/core/test/security-tests.git] / src / cynara-tests / test_cases_helpers.cpp
1 /*
2  * Copyright (c) 2015-2022 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *    Licensed under the Apache License, Version 2.0 (the "License");
5  *    you may not use this file except in compliance with the License.
6  *    You may obtain a copy of the License at
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *    Unless required by applicable law or agreed to in writing, software
11  *    distributed under the License is distributed on an "AS IS" BASIS,
12  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *    See the License for the specific language governing permissions and
14  *    limitations under the License.
15  */
16 /**
17  * @file        test_cases_helpers.cpp
18  * @author      Aleksander Zdyb <a.zdyb@samsung.com>
19  * @version     1.0
20  * @brief       Tests for cynara-helper-credentials-socket and cynara-helper-credentials-dbus
21  */
22
23 #include <cstdlib>
24 #include <functional>
25 #include <string>
26 #include <sys/types.h>
27 #include <sys/un.h>
28 #include <unistd.h>
29 #include <utility>
30
31 #include <dbus/dbus.h>
32 #include <glib-object.h>
33 #include <gio/gio.h>
34 #include <systemd/sd-bus.h>
35
36 #include <tests_common.h>
37 #include <app_context.h>
38 #include <dpl/test/test_runner.h>
39 #include <memory.h>
40 #include <synchronization_pipe.h>
41 #include <tests_common.h>
42 #include <uds.h>
43 #include <passwd_access.h>
44 #include <cynara_helpers_creds.h>
45 #include <cynara_helpers_dbus.h>
46
47 #include <cynara-creds-dbus.h>
48 #include <cynara-creds-gdbus.h>
49 #include <cynara-creds-self.h>
50 #include <scoped_process_label.h>
51
52
53 static const cynara_client_creds G_CLIENT_METHOD_DEFAULT = CLIENT_METHOD_DEFAULT;
54 static const cynara_client_creds G_CLIENT_METHOD_SMACK   = CLIENT_METHOD_SMACK;
55 static const cynara_client_creds G_CLIENT_METHOD_PID     = CLIENT_METHOD_PID;
56
57 static const cynara_user_creds G_USER_METHOD_DEFAULT = USER_METHOD_DEFAULT;
58 static const cynara_user_creds G_USER_METHOD_UID     = USER_METHOD_UID;
59 static const cynara_user_creds G_USER_METHOD_GID     = USER_METHOD_GID;
60
61 static const cynara_client_creds G_CLIENT_METHOD_LOW = (cynara_client_creds)-1;
62 static const cynara_client_creds G_CLIENT_METHOD_HIGH = (cynara_client_creds)(CLIENT_METHOD_PID+10);
63
64 static const cynara_user_creds G_USER_METHOD_LOW = (cynara_user_creds)-1;
65 static const cynara_user_creds G_USER_METHOD_HIGH = (cynara_user_creds)(USER_METHOD_GID+10);
66
67
68 class ProcessCredentials {
69 public:
70     ProcessCredentials() {}
71
72     const std::string &label(void) const {
73         return m_label;
74     }
75
76     uid_t uid(void) const {
77         return PasswdAccess::uid(APP_USER);
78     }
79
80     gid_t gid(void) const {
81         return PasswdAccess::gid("users");
82     }
83
84 private:
85     std::string m_label = "cynara_helpers";
86 };
87
88 cynara_client_creds getClientDefaultMethod() {
89     cynara_client_creds def;
90     int ret = cynara_creds_get_default_client_method(&def);
91     RUNNER_ASSERT_MSG(ret == CYNARA_API_SUCCESS,
92                       "cynara_creds_get_default_client_method failed with " << ret);
93     return def;
94 }
95
96 cynara_user_creds getUserDefaultMethod() {
97     cynara_user_creds def;
98     int ret = cynara_creds_get_default_user_method(&def);
99     RUNNER_ASSERT_MSG(ret == CYNARA_API_SUCCESS,
100                       "cynara_creds_get_default_user_method failed with " << ret);
101     return def;
102 }
103
104
105 void udsServer(SynchronizationPipe &pipe, const struct sockaddr_un &sockaddr,
106                const struct ProcessCredentials &peerCredentials) {
107     AppContext ctx(peerCredentials.label());
108     ctx.apply(peerCredentials.uid(), peerCredentials.gid());
109     pipe.claimChildEp();
110
111     int sock = UDSHelpers::createServer(&sockaddr);
112     SockUniquePtr sockPtr(&sock);
113     pipe.post();
114     int clientSock = UDSHelpers::acceptClient(sock);
115
116     UDSHelpers::waitForDisconnect(clientSock);
117 }
118
119 typedef std::function<void(int sock, pid_t pid,
120         const ProcessCredentials &peerCredentials)> SocketAssertionFn;
121
122 void socketTestTemplate(SocketAssertionFn assertion, const std::string &scope) {
123     const auto sockaddr = UDSHelpers::makeAbstractAddress("helper_" + scope + ".socket");
124     const ProcessCredentials peerCredentials;
125
126     SynchronizationPipe pipe;
127
128     pid_t pid = runInChild(std::bind(udsServer, std::ref(pipe), std::cref(sockaddr),
129                            std::cref(peerCredentials)));
130
131     pipe.claimParentEp();
132     pipe.wait();
133     int sock = UDSHelpers::createClient(&sockaddr);
134     SockUniquePtr sockPtr(&sock);
135
136     assertion(sock, pid, peerCredentials);
137 }
138
139 RUNNER_TEST_GROUP_INIT(cynara_creds_socket)
140
141 void testSocketClientSmack(cynara_client_creds method = CLIENT_METHOD_SMACK) {
142     socketTestTemplate([method] (int sock, pid_t, const ProcessCredentials &peerCredentials) {
143         CStringPtr label(CynaraHelperCredentials::socketGetClient(sock, method));
144         RUNNER_ASSERT_MSG(peerCredentials.label() == label.get(),
145                           "Labels don't match ret = " << label.get()
146                           << "; expected = " << peerCredentials.label());
147     }, "tccs01");
148 }
149
150 void testSocketClientPid(cynara_client_creds method = CLIENT_METHOD_PID) {
151     socketTestTemplate([method] (int sock, pid_t pid, const ProcessCredentials &) {
152         CStringPtr clientPidStr(CynaraHelperCredentials::socketGetClient(sock, method));
153         pid_t clientPid = std::stoi(clientPidStr.get());
154         RUNNER_ASSERT_MSG(pid == clientPid, "PIDs don't match ret = " << clientPid
155                           << "; expected = " << pid);
156     }, "tccs02");
157 }
158
159 RUNNER_MULTIPROCESS_TEST_SMACK(tccs01_socket_credentials_client_smack)
160 {
161     testSocketClientSmack();
162 }
163
164 RUNNER_MULTIPROCESS_TEST(tccs02_socket_credentials_client_pid)
165 {
166     testSocketClientPid();
167 }
168
169 RUNNER_MULTIPROCESS_TEST_SMACK(tccs03_socket_credentials_client_default)
170 {
171     auto method = getClientDefaultMethod();
172     switch(method) {
173     case CLIENT_METHOD_SMACK:
174         testSocketClientSmack(CLIENT_METHOD_DEFAULT);
175         break;
176     case CLIENT_METHOD_PID:
177         testSocketClientPid(CLIENT_METHOD_DEFAULT);
178         break;
179     default:
180         RUNNER_FAIL_MSG("cynara_creds_get_default_client_method returned unexpected value "
181                         << method);
182     }
183 }
184
185 void testSocketUserUid(cynara_user_creds method = USER_METHOD_UID) {
186     socketTestTemplate([method] (int sock, pid_t, const ProcessCredentials &peerCredentials) {
187         CStringPtr uidStr(CynaraHelperCredentials::socketGetUser(sock, method));
188         uid_t uid = std::stoul(uidStr.get());
189         RUNNER_ASSERT_MSG(peerCredentials.uid() == uid, "UIDs don't match ret = " << uid
190                           << "; expected = "<< peerCredentials.uid());
191     }, "tccs04");
192 }
193
194 void testSocketUserGid(cynara_user_creds method = USER_METHOD_GID) {
195     socketTestTemplate([method] (int sock, pid_t, const ProcessCredentials &peerCredentials) {
196         CStringPtr gidStr(CynaraHelperCredentials::socketGetUser(sock, method));
197         gid_t gid = std::stoul(gidStr.get());
198         RUNNER_ASSERT_MSG(peerCredentials.gid() == gid, "GIDs don't match ret = " << gid
199                           << "; expected = "<< peerCredentials.gid());
200     }, "tccs05");
201 }
202
203 RUNNER_MULTIPROCESS_TEST(tccs04_socket_credentials_user_uid)
204 {
205     testSocketUserUid();
206 }
207
208 RUNNER_MULTIPROCESS_TEST(tccs05_socket_credentials_user_gid)
209 {
210     testSocketUserGid();
211 }
212
213 RUNNER_MULTIPROCESS_TEST(tccs06_socket_credentials_user_default)
214 {
215     auto method = getUserDefaultMethod();
216     switch(method) {
217     case USER_METHOD_UID:
218         testSocketUserUid(USER_METHOD_DEFAULT);
219         break;
220     case USER_METHOD_GID:
221         testSocketUserGid(USER_METHOD_DEFAULT);
222         break;
223     default:
224         RUNNER_FAIL_MSG("cynara_creds_get_default_user_method returned unexpected value "
225                  << method);
226     }
227 }
228
229 RUNNER_MULTIPROCESS_TEST(tccs07_socket_credentials_pid)
230 {
231     socketTestTemplate([] (int sock, pid_t expectedPid, const ProcessCredentials &) {
232         pid_t peerPid(CynaraHelperCredentials::socketGetPid(sock));
233         RUNNER_ASSERT_MSG(peerPid == expectedPid, "Pids don't match ret = " << peerPid
234                           << "; expected = "<< expectedPid);
235     }, "tccs05");
236 }
237
238
239 //=====================================DBus===========================================
240
241 // TODO: Create utility namespace for DBus, maybe?
242 DBusConnectionPtr createDBusConnection(const std::string &name) {
243     DBusError err;
244
245     dbus_error_init(&err);
246     DBusConnection *conn = dbus_bus_get_private(DBUS_BUS_SYSTEM, &err);
247     RUNNER_ASSERT_MSG(dbus_error_is_set(&err) != 1, "Error in dbus_bus_get: " << err.message);
248     dbus_connection_set_exit_on_disconnect(conn, FALSE);
249
250     DBusConnectionPtr ret(conn, [] (DBusConnection *conn) {
251         dbus_connection_close(conn);
252         dbus_connection_unref(conn);
253     });
254
255     if (name.empty() == false) {
256         dbus_bus_request_name(conn, name.c_str(), DBUS_NAME_FLAG_REPLACE_EXISTING , &err);
257         RUNNER_ASSERT_MSG(dbus_error_is_set(&err) != TRUE,
258                           "Error in dbus_bus_request_name: " << err.message);
259     }
260
261     return ret;
262 }
263
264 void dbusServer(SynchronizationPipe &pipe, const std::string &requestedName,
265                 const ProcessCredentials &peerCredentials) {
266     AppContext ctx(peerCredentials.label());
267     ctx.allowAccessFrom("System", "rwx"); // for DBus connection
268     ctx.allowAccessFrom("System::Privileged", "rwx"); // for piping
269     ctx.allowAccessTo("System", "w");
270     ctx.allowAccessTo("System::Privileged", "rwx"); // for GDB and piping
271     ctx.allowAccessTo("System::Run", "x");
272     ctx.allowAccessTo("System::Shared", "rwx"); // for GDB
273     ctx.allowAccessTo("User", "r"); // for /usr/lib/debug access
274     ctx.apply(peerCredentials.uid(), peerCredentials.gid());
275     pipe.claimChildEp();
276
277     auto conn = createDBusConnection(requestedName);
278     pipe.post();
279     pipe.wait();
280 }
281
282 typedef std::function<void(DBusConnectionPtr conn, pid_t pid,
283                            const std::string &requestedName,
284                            const ProcessCredentials &peerCredentials)> DBusAssertionFn;
285
286 void dbusTestTemplate(DBusAssertionFn assertion) {
287     std::string requestedName = "tests.dbus.cynara";
288     const ProcessCredentials peerCredentials;
289
290     SynchronizationPipe pipe;
291     pid_t pid = runInChild(std::bind(dbusServer, std::ref(pipe), std::cref(requestedName),
292                            std::cref(peerCredentials)));
293
294     pipe.claimParentEp();
295     pipe.wait();
296
297     auto conn = createDBusConnection("");
298     assertion(std::move(conn), pid, requestedName, peerCredentials);
299     pipe.post();
300 }
301
302
303 RUNNER_TEST_GROUP_INIT(cynara_creds_dbus)
304
305 void testDbusClientPid(cynara_client_creds method = CLIENT_METHOD_PID) {
306     dbusTestTemplate([method] (DBusConnectionPtr conn, pid_t pid, const std::string &requestedName,
307                          const ProcessCredentials &) {
308         CStringPtr clientPidStr(CynaraHelperCredentials::dbusGetClient(std::move(conn),
309             requestedName.c_str(), method, CYNARA_API_SUCCESS));
310         pid_t clientPid = std::stoi(clientPidStr.get());
311         RUNNER_ASSERT_MSG(pid == clientPid, "PIDs don't match ret = " << clientPid
312                           << "; expected = " << pid);
313     });
314 }
315
316 void testDbusClientSmack(cynara_client_creds method = CLIENT_METHOD_SMACK) {
317     dbusTestTemplate([method] (DBusConnectionPtr conn, pid_t, const std::string &requestedName,
318                          const ProcessCredentials &peerCredentials) {
319         CStringPtr label(CynaraHelperCredentials::dbusGetClient(std::move(conn),
320             requestedName.c_str(), method, CYNARA_API_SUCCESS));
321         RUNNER_ASSERT_MSG(peerCredentials.label() == label.get(),
322                           "Labels don't match ret = " << label.get()
323                           << "; expected = " << peerCredentials.label());
324     });
325 }
326
327 RUNNER_MULTIPROCESS_TEST(tccd01_dbus_credentials_client_pid)
328 {
329     testDbusClientPid();
330 }
331
332 RUNNER_MULTIPROCESS_TEST_SMACK(tccd02_dbus_credentials_client_smack)
333 {
334     testDbusClientSmack();
335 }
336
337 RUNNER_MULTIPROCESS_TEST_SMACK(tccd03_dbus_credentials_client_default)
338 {
339     auto method = getClientDefaultMethod();
340     switch(method) {
341     case CLIENT_METHOD_SMACK:
342         testDbusClientSmack(CLIENT_METHOD_DEFAULT);
343         break;
344     case CLIENT_METHOD_PID:
345         testDbusClientPid(CLIENT_METHOD_DEFAULT);
346         break;
347     default:
348         RUNNER_FAIL_MSG("cynara_creds_get_default_client_method returned unexpected value "
349                         << method);
350     }
351 }
352
353 void testDbusUserUid(cynara_user_creds method = USER_METHOD_UID) {
354     dbusTestTemplate([method] (DBusConnectionPtr conn, pid_t, const std::string &requestedName,
355                          const ProcessCredentials &peerCredentials) {
356         CStringPtr uidStr(CynaraHelperCredentials::dbusGetUser(std::move(conn),
357             requestedName.c_str(), method, CYNARA_API_SUCCESS));
358         uid_t uid = std::stoul(uidStr.get());
359         RUNNER_ASSERT_MSG(peerCredentials.uid() == uid, "UIDs don't match ret = " << uid
360                           << "; expected = "<< peerCredentials.uid());
361     });
362 }
363
364 void testDbusUserGid(cynara_user_creds method = USER_METHOD_GID) {
365     // Acquiring gid from dbus connection is not yet implemented for cynara helpers
366     dbusTestTemplate([method] (DBusConnectionPtr conn, pid_t, const std::string &requestedName,
367                          const ProcessCredentials &) {
368         CStringPtr gidStr(CynaraHelperCredentials::dbusGetUser(std::move(conn),
369             requestedName.c_str(), method, CYNARA_API_METHOD_NOT_SUPPORTED));
370     });
371 }
372
373 RUNNER_MULTIPROCESS_TEST(tccd04_dbus_credentials_user_uid)
374 {
375     testDbusUserUid();
376 }
377
378 RUNNER_MULTIPROCESS_TEST(tccd05_dbus_credentials_user_gid)
379 {
380     testDbusUserGid();
381 }
382
383 RUNNER_MULTIPROCESS_TEST(tccd06_dbus_credentials_user_default) {
384     auto method = getUserDefaultMethod();
385     switch(method) {
386     case USER_METHOD_UID:
387         testDbusUserUid(USER_METHOD_DEFAULT);
388         break;
389     case USER_METHOD_GID:
390         testDbusUserGid(USER_METHOD_DEFAULT);
391         break;
392     default:
393         RUNNER_FAIL_MSG("cynara_creds_get_default_user_method returned unexpected value "
394                         << method);
395     }
396 }
397
398 RUNNER_TEST_SMACK(tccd07_dbus_credentials_pid) {
399     dbusTestTemplate([] (DBusConnectionPtr conn, pid_t expectedPid,
400                          const std::string &requestedName, const ProcessCredentials &) {
401         auto helperPid = CynaraHelperCredentials::dbusGetPid(std::move(conn),
402             requestedName.c_str(), CYNARA_API_SUCCESS);
403         RUNNER_ASSERT_MSG(helperPid == expectedPid, "PIDs don't match ret = " << helperPid
404                           << "; expected = " << expectedPid);
405     });
406 }
407
408 void testDbusCredsDefault(int expectedResult, char **pClientBuff,
409                           char **pUserBuff, pid_t *pPidCred)
410 {
411     // reset variables if set by previous test cases
412     if (pClientBuff != nullptr) *pClientBuff = nullptr;
413     if (pUserBuff != nullptr) *pUserBuff = nullptr;
414     if (pPidCred != nullptr) *pPidCred = -1;
415
416     dbusTestTemplate([&] (DBusConnectionPtr conn, pid_t pid,
417                           const std::string &requestedName,
418                           const ProcessCredentials &peerCredentials) {
419         cynara_user_creds userMethod = getUserDefaultMethod();
420         cynara_client_creds clientMethod = getClientDefaultMethod();
421
422         // exception override
423         if (expectedResult == CYNARA_API_SUCCESS && userMethod == USER_METHOD_GID) {
424             expectedResult = CYNARA_API_METHOD_NOT_SUPPORTED;
425         }
426
427         int ret = cynara_creds_dbus_get_default(conn.get(), requestedName.c_str(),
428                                                 pClientBuff, pUserBuff, pPidCred);
429
430         RUNNER_ASSERT_MSG(ret == expectedResult,
431                           "cynara_creds_dbus_get_default returned unexpected result: " << ret <<
432                           "; expected: " << expectedResult);
433
434         if (ret != CYNARA_API_SUCCESS) {
435             return;
436         }
437
438         if (pClientBuff != nullptr) {
439             switch (clientMethod) {
440             case CLIENT_METHOD_SMACK:
441                 RUNNER_ASSERT_MSG(*pClientBuff == peerCredentials.label(),
442                                   "Client labels don't match, ret = "
443                                   << *pClientBuff << "; expected = "
444                                   << peerCredentials.label());
445                 free(*pClientBuff);
446                 break;
447             case CLIENT_METHOD_PID:
448                 RUNNER_ASSERT_MSG(*pClientBuff == std::to_string(pid),
449                                   "PIDs don't match, ret = "
450                                   << *pClientBuff << "; expected = " << pid);
451                 free(*pClientBuff);
452                 break;
453             default:
454                 break;
455             }
456         }
457
458         if (pUserBuff != nullptr) {
459             switch (userMethod) {
460             case USER_METHOD_UID:
461                 RUNNER_ASSERT_MSG(*pUserBuff == std::to_string(peerCredentials.uid()),
462                                   "UIDs don't match, ret = "
463                                   << *pUserBuff
464                                   << "; expected = " << peerCredentials.uid());
465                 free(*pUserBuff);
466                 break;
467             default:
468                 break;
469             }
470         }
471
472         if (pPidCred != nullptr) {
473             RUNNER_ASSERT_MSG(*pPidCred == pid, "PIDs don't match, ret = "
474                               << *pPidCred
475                               << "; expected = " << pid);
476         }
477     });
478 }
479
480 RUNNER_MULTIPROCESS_TEST(tccd08_dbus_credentials_default_positive_all)
481 {
482     char *clientBuff = nullptr;
483     char *userBuff = nullptr;
484     pid_t pidCred = -1;
485
486     testDbusCredsDefault(CYNARA_API_SUCCESS, &clientBuff, &userBuff, &pidCred);
487 }
488
489 RUNNER_MULTIPROCESS_TEST(tccd09_dbus_credentials_default_positive_partial_single)
490 {
491     char *clientBuff = nullptr;
492     char *userBuff = nullptr;
493     pid_t pidCred = -1;
494
495     testDbusCredsDefault(CYNARA_API_SUCCESS, &clientBuff, nullptr, nullptr);
496     testDbusCredsDefault(CYNARA_API_SUCCESS, nullptr, &userBuff, nullptr);
497     testDbusCredsDefault(CYNARA_API_SUCCESS, nullptr, nullptr, &pidCred);
498 }
499
500 RUNNER_MULTIPROCESS_TEST(tccd10_dbus_credentials_default_positive_partial_double)
501 {
502     char *clientBuff = nullptr;
503     char *userBuff = nullptr;
504     pid_t pidCred = -1;
505
506     testDbusCredsDefault(CYNARA_API_SUCCESS, nullptr, &userBuff, &pidCred);
507     testDbusCredsDefault(CYNARA_API_SUCCESS, &clientBuff, nullptr, &pidCred);
508     testDbusCredsDefault(CYNARA_API_SUCCESS, &clientBuff, &userBuff, nullptr);
509 }
510
511 RUNNER_MULTIPROCESS_TEST(tccd11_dbus_credentials_default_negative_incomplete)
512 {
513     testDbusCredsDefault(CYNARA_API_INVALID_PARAM, nullptr, nullptr, nullptr);
514 }
515
516 void testDbusCreds(int expectedResult,
517                    const cynara_client_creds *pClientMethod, char **pClientBuff,
518                    const cynara_user_creds *pUserMethod, char **pUserBuff,
519                    pid_t *pPidCred)
520 {
521     // reset variables if set by previous test cases
522     if (pClientBuff != nullptr) *pClientBuff = nullptr;
523     if (pUserBuff != nullptr) *pUserBuff = nullptr;
524     if (pPidCred != nullptr) *pPidCred = -1;
525
526     dbusTestTemplate([&] (DBusConnectionPtr conn, pid_t pid,
527                           const std::string &requestedName,
528                           const ProcessCredentials &peerCredentials) {
529
530         int ret = cynara_creds_dbus_get(conn.get(), requestedName.c_str(),
531                                         pClientMethod, pClientBuff,
532                                         pUserMethod, pUserBuff, pPidCred);
533
534         RUNNER_ASSERT_MSG(ret == expectedResult,
535                           "cynara_creds_dbus_get returned unexpected result: " << ret <<
536                           "; expected: " << expectedResult);
537
538         if (ret != CYNARA_API_SUCCESS) {
539             return;
540         }
541
542         if (pClientBuff != nullptr && pClientMethod != nullptr) {
543             switch (*pClientMethod) {
544             case CLIENT_METHOD_SMACK:
545                 RUNNER_ASSERT_MSG(*pClientBuff == peerCredentials.label(),
546                                   "Client labels don't match, ret = "
547                                   << *pClientBuff << "; expected = "
548                                   << peerCredentials.label());
549                 free(*pClientBuff);
550                 break;
551             case CLIENT_METHOD_PID:
552                 RUNNER_ASSERT_MSG(*pClientBuff == std::to_string(pid),
553                                   "PIDs don't match, ret = "
554                                   << *pClientBuff << "; expected = " << pid);
555                 free(*pClientBuff);
556                 break;
557             default:
558                 break;
559             }
560         }
561
562         if (pUserBuff != nullptr && pUserMethod != nullptr) {
563             switch (*pUserMethod) {
564             case USER_METHOD_UID:
565                 RUNNER_ASSERT_MSG(*pUserBuff == std::to_string(peerCredentials.uid()),
566                                   "UIDs don't match, ret = "
567                                   << *pUserBuff
568                                   << "; expected = " << peerCredentials.uid());
569                 free(*pUserBuff);
570                 break;
571             default:
572                 break;
573             }
574         }
575
576         if (pPidCred != nullptr) {
577             RUNNER_ASSERT_MSG(*pPidCred == pid, "PIDs don't match, ret = "
578                               << *pPidCred
579                               << "; expected = " << pid);
580         }
581     });
582 }
583
584 RUNNER_MULTIPROCESS_TEST(tccd12_dbus_credentials_positive_all)
585 {
586     char *clientBuff = nullptr;
587     char *userBuff = nullptr;
588     pid_t pidCred = -1;
589
590     testDbusCreds(CYNARA_API_SUCCESS,
591                   &G_CLIENT_METHOD_DEFAULT, &clientBuff,
592                   &G_USER_METHOD_DEFAULT, &userBuff, &pidCred);
593     testDbusCreds(CYNARA_API_SUCCESS,
594                   &G_CLIENT_METHOD_SMACK, &clientBuff,
595                   &G_USER_METHOD_UID, &userBuff, &pidCred);
596     testDbusCreds(CYNARA_API_SUCCESS,
597                   &G_CLIENT_METHOD_PID, &clientBuff,
598                   &G_USER_METHOD_UID, &userBuff, &pidCred);
599
600     testDbusCreds(CYNARA_API_METHOD_NOT_SUPPORTED,
601                   &G_CLIENT_METHOD_SMACK, &clientBuff,
602                   &G_USER_METHOD_GID, &userBuff, &pidCred);
603     testDbusCreds(CYNARA_API_METHOD_NOT_SUPPORTED,
604                   &G_CLIENT_METHOD_PID, &clientBuff,
605                   &G_USER_METHOD_GID, &userBuff, &pidCred);
606 }
607
608 RUNNER_MULTIPROCESS_TEST(tccd13_dbus_credentials_positive_partial_single)
609 {
610     char *clientBuff = nullptr;
611     char *userBuff = nullptr;
612     pid_t pidCred = -1;
613
614     testDbusCreds(CYNARA_API_SUCCESS,
615                   &G_CLIENT_METHOD_PID, &clientBuff,
616                   &G_USER_METHOD_DEFAULT, nullptr,
617                   nullptr);
618     testDbusCreds(CYNARA_API_SUCCESS,
619                   &G_CLIENT_METHOD_SMACK, &clientBuff,
620                   nullptr, nullptr,
621                   nullptr);
622
623     testDbusCreds(CYNARA_API_SUCCESS,
624                   &G_CLIENT_METHOD_DEFAULT, nullptr,
625                   &G_USER_METHOD_DEFAULT, &userBuff,
626                   nullptr);
627     testDbusCreds(CYNARA_API_SUCCESS,
628                   nullptr, nullptr,
629                   &G_USER_METHOD_DEFAULT, &userBuff,
630                   nullptr);
631
632     testDbusCreds(CYNARA_API_SUCCESS,
633                   nullptr, nullptr,
634                   &G_USER_METHOD_DEFAULT, nullptr,
635                   &pidCred);
636     testDbusCreds(CYNARA_API_SUCCESS,
637                   &G_CLIENT_METHOD_DEFAULT, nullptr,
638                   nullptr, nullptr,
639                   &pidCred);
640     testDbusCreds(CYNARA_API_SUCCESS,
641                   nullptr, nullptr,
642                   nullptr, nullptr,
643                   &pidCred);
644 }
645
646 RUNNER_MULTIPROCESS_TEST(tccd14_dbus_credentials_positive_partial_double)
647 {
648     char *clientBuff = nullptr;
649     char *userBuff = nullptr;
650     pid_t pidCred = -1;
651
652     testDbusCreds(CYNARA_API_SUCCESS,
653                   &G_CLIENT_METHOD_DEFAULT, nullptr,
654                   &G_USER_METHOD_UID, &userBuff, &pidCred);
655     testDbusCreds(CYNARA_API_SUCCESS,
656                   nullptr, nullptr,
657                   &G_USER_METHOD_DEFAULT, &userBuff, &pidCred);
658
659     testDbusCreds(CYNARA_API_SUCCESS,
660                   &G_CLIENT_METHOD_PID, &clientBuff,
661                   &G_USER_METHOD_DEFAULT, nullptr, &pidCred);
662     testDbusCreds(CYNARA_API_SUCCESS,
663                   &G_CLIENT_METHOD_DEFAULT, &clientBuff,
664                   nullptr, nullptr, &pidCred);
665
666     testDbusCreds(CYNARA_API_SUCCESS,
667                   &G_CLIENT_METHOD_SMACK, &clientBuff,
668                   &G_USER_METHOD_UID, &userBuff, nullptr);
669 }
670
671 RUNNER_MULTIPROCESS_TEST(tccd14_dbus_credentials_negative_incomplete)
672 {
673     char *clientBuff = nullptr;
674     char *userBuff = nullptr;
675     pid_t pidCred = -1;
676
677     testDbusCreds(CYNARA_API_INVALID_PARAM,
678                   nullptr, &clientBuff,
679                   &G_USER_METHOD_UID, &userBuff, &pidCred);
680     testDbusCreds(CYNARA_API_INVALID_PARAM,
681                   nullptr, &clientBuff,
682                   &G_USER_METHOD_UID, nullptr, &pidCred);
683     testDbusCreds(CYNARA_API_INVALID_PARAM,
684                   nullptr, &clientBuff,
685                   nullptr, nullptr, &pidCred);
686
687     testDbusCreds(CYNARA_API_INVALID_PARAM,
688                   &G_CLIENT_METHOD_DEFAULT, &clientBuff,
689                   nullptr, &userBuff, &pidCred);
690     testDbusCreds(CYNARA_API_INVALID_PARAM,
691                   &G_CLIENT_METHOD_DEFAULT, nullptr,
692                   nullptr, &userBuff, &pidCred);
693     testDbusCreds(CYNARA_API_INVALID_PARAM,
694                   nullptr, nullptr,
695                   nullptr, &userBuff, &pidCred);
696
697     testDbusCreds(CYNARA_API_INVALID_PARAM,
698                   &G_CLIENT_METHOD_DEFAULT, nullptr,
699                   &G_USER_METHOD_UID, nullptr, nullptr);
700     testDbusCreds(CYNARA_API_INVALID_PARAM,
701                   &G_CLIENT_METHOD_DEFAULT, nullptr,
702                   nullptr, nullptr, nullptr);
703     testDbusCreds(CYNARA_API_INVALID_PARAM,
704                   nullptr, nullptr,
705                   &G_USER_METHOD_DEFAULT, nullptr, nullptr);
706     testDbusCreds(CYNARA_API_INVALID_PARAM,
707                   nullptr, nullptr,
708                   nullptr, nullptr, nullptr);
709 }
710
711 RUNNER_MULTIPROCESS_TEST(tccd14_dbus_credentials_negative_incorrect)
712 {
713     char *clientBuff = nullptr;
714     char *userBuff = nullptr;
715     pid_t pidCred = -1;
716
717     testDbusCreds(CYNARA_API_METHOD_NOT_SUPPORTED,
718                   &G_CLIENT_METHOD_LOW, &clientBuff,
719                   &G_USER_METHOD_DEFAULT, &userBuff, &pidCred);
720     testDbusCreds(CYNARA_API_METHOD_NOT_SUPPORTED,
721                   &G_CLIENT_METHOD_HIGH, &clientBuff,
722                   &G_USER_METHOD_DEFAULT, &userBuff, &pidCred);
723     testDbusCreds(CYNARA_API_METHOD_NOT_SUPPORTED,
724                   &G_CLIENT_METHOD_DEFAULT, &clientBuff,
725                   &G_USER_METHOD_LOW, &userBuff, &pidCred);
726     testDbusCreds(CYNARA_API_METHOD_NOT_SUPPORTED,
727                   &G_CLIENT_METHOD_DEFAULT, &clientBuff,
728                   &G_USER_METHOD_HIGH, &userBuff, &pidCred);
729 }
730
731
732 //===============================GDBUS======================================
733
734 GDBusConnectionPtr createGDBusConnection() {
735     GDBusConnection *conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, NULL);
736
737     return GDBusConnectionPtr(conn, [] (GDBusConnection *conn) {
738         g_object_unref(G_OBJECT(conn));
739     });
740 }
741
742
743 typedef std::function<void(GDBusConnectionPtr conn, pid_t pid,
744                            const std::string &requestedName,
745                            const ProcessCredentials &peerCredentials)> GDBusAssertionFn;
746
747 void gdbusTestTemplate(GDBusAssertionFn assertion) {
748     std::string requestedName = "tests.dbus.cynara";
749     const ProcessCredentials peerCredentials;
750
751     SynchronizationPipe pipe;
752     pid_t pid = runInChild(std::bind(dbusServer, std::ref(pipe), std::cref(requestedName),
753                            std::cref(peerCredentials)));
754
755     pipe.claimParentEp();
756     pipe.wait();
757
758     auto conn = createGDBusConnection();
759     assertion(std::move(conn), pid, requestedName, peerCredentials);
760     pipe.post();
761 }
762
763
764 RUNNER_TEST_GROUP_INIT(cynara_creds_gdbus)
765
766 void testGdbusClientPid(cynara_client_creds method = CLIENT_METHOD_PID) {
767     gdbusTestTemplate([method] (GDBusConnectionPtr conn, pid_t pid,
768                                 const std::string &requestedName,
769                                 const ProcessCredentials &) {
770         GStringPtr clientPidStr(CynaraHelperCredentials::gdbusGetClient(std::move(conn),
771                                 requestedName.c_str(), method));
772         pid_t clientPid = std::stoi(clientPidStr.get());
773         RUNNER_ASSERT_MSG(pid == clientPid, "PIDs don't match ret = " << clientPid
774                           << "; expected = " << pid);
775     });
776 }
777
778 void testGdbusClientSmack(cynara_client_creds method = CLIENT_METHOD_SMACK) {
779     gdbusTestTemplate([method] (GDBusConnectionPtr conn, pid_t,
780                                 const std::string &requestedName,
781                                 const ProcessCredentials &peerCredentials) {
782         GStringPtr label(CynaraHelperCredentials::gdbusGetClient(std::move(conn),
783                          requestedName.c_str(), method));
784         RUNNER_ASSERT_MSG(peerCredentials.label() == label.get(),
785                           "Labels don't match ret = " << label.get()
786                           << "; expected = " << peerCredentials.label());
787     });
788 }
789
790 RUNNER_MULTIPROCESS_TEST(tccgd01_gdbus_credentials_client_pid)
791 {
792     testGdbusClientPid();
793 }
794
795 RUNNER_MULTIPROCESS_TEST_SMACK(tccgd02_gdbus_credentials_client_smack)
796 {
797     testGdbusClientSmack();
798 }
799
800 RUNNER_MULTIPROCESS_TEST_SMACK(tccgd03_gdbus_credentials_client_default)
801 {
802     auto method = getClientDefaultMethod();
803     switch(method) {
804     case CLIENT_METHOD_SMACK:
805         testGdbusClientSmack(CLIENT_METHOD_DEFAULT);
806         break;
807     case CLIENT_METHOD_PID:
808         testGdbusClientPid(CLIENT_METHOD_DEFAULT);
809         break;
810     default:
811         RUNNER_FAIL_MSG("cynara_creds_get_default_client_method returned unexpected value "
812                         << method);
813     }
814 }
815
816 void testGdbusUserUid(cynara_user_creds method = USER_METHOD_UID) {
817     gdbusTestTemplate([method] (GDBusConnectionPtr conn, pid_t,
818                                 const std::string &requestedName,
819                                 const ProcessCredentials &peerCredentials) {
820         GStringPtr uidStr(CynaraHelperCredentials::gdbusGetUser(std::move(conn),
821                           requestedName.c_str(), method));
822         uid_t uid = std::stoul(uidStr.get());
823         RUNNER_ASSERT_MSG(peerCredentials.uid() == uid, "UIDs don't match ret = " << uid
824                           << "; expected = "<< peerCredentials.uid());
825     });
826 }
827
828 void testGdbusUserGid(cynara_user_creds method = USER_METHOD_GID) {
829     // Getting gid for gdbus connection is not yet implemented in cynara helpers
830     gdbusTestTemplate([method] (GDBusConnectionPtr conn, pid_t,
831                                 const std::string &requestedName,
832                                 const ProcessCredentials &) {
833         GStringPtr gidStr(CynaraHelperCredentials::gdbusGetUser(std::move(conn),
834                           requestedName.c_str(), method, CYNARA_API_METHOD_NOT_SUPPORTED));
835     });
836 }
837
838 RUNNER_MULTIPROCESS_TEST(tccgd04_gdbus_credentials_user_uid)
839 {
840     testGdbusUserUid();
841 }
842
843 RUNNER_MULTIPROCESS_TEST(tccgd05_gdbus_credentials_user_gid)
844 {
845     testGdbusUserGid();
846 }
847
848 RUNNER_MULTIPROCESS_TEST(tccgd06_gdbus_credentials_user_default) {
849     auto method = getUserDefaultMethod();
850     switch(method) {
851     case USER_METHOD_UID:
852         testGdbusUserUid(USER_METHOD_DEFAULT);
853         break;
854     case USER_METHOD_GID:
855         testGdbusUserGid(USER_METHOD_DEFAULT);
856         break;
857     default:
858         RUNNER_FAIL_MSG("cynara_creds_get_default_user_method returned unexpected value "
859                         << method);
860     }
861 }
862
863 RUNNER_MULTIPROCESS_TEST(tccgd07_gdbus_credentials_pid) {
864     gdbusTestTemplate([] (GDBusConnectionPtr conn, pid_t expectedPid,
865                           const std::string &requestedName, const ProcessCredentials &) {
866         auto helperPid = CynaraHelperCredentials::gdbusGetPid(std::move(conn),
867                          requestedName.c_str());
868         RUNNER_ASSERT_MSG(helperPid == expectedPid, "PIDs don't match ret = " << helperPid
869                           << "; expected = " << expectedPid);
870     });
871 }
872
873 void testGDbusCredsDefault(int expectedResult, char **pClientBuff,
874                            char **pUserBuff, pid_t *pPidCred)
875 {
876     // reset variables if set by previous test cases
877     if (pClientBuff != nullptr) *pClientBuff = nullptr;
878     if (pUserBuff != nullptr) *pUserBuff = nullptr;
879     if (pPidCred != nullptr) *pPidCred = -1;
880
881     gdbusTestTemplate([&] (GDBusConnectionPtr conn, pid_t pid,
882                            const std::string &requestedName,
883                            const ProcessCredentials &peerCredentials) {
884         cynara_user_creds userMethod = getUserDefaultMethod();
885         cynara_client_creds clientMethod = getClientDefaultMethod();
886
887         // exception override
888         if (expectedResult == CYNARA_API_SUCCESS && userMethod == USER_METHOD_GID) {
889             expectedResult = CYNARA_API_METHOD_NOT_SUPPORTED;
890         }
891
892         int ret = cynara_creds_gdbus_get_default(conn.get(), requestedName.c_str(),
893                                                  pClientBuff, pUserBuff, pPidCred);
894
895         RUNNER_ASSERT_MSG(ret == expectedResult,
896                           "cynara_creds_gdbus_get_default returned unexpected result: " << ret <<
897                           "; expected: " << expectedResult);
898
899         if (ret != CYNARA_API_SUCCESS) {
900             return;
901         }
902
903         if (pClientBuff != nullptr) {
904             switch (clientMethod) {
905             case CLIENT_METHOD_SMACK:
906                 RUNNER_ASSERT_MSG(*pClientBuff == peerCredentials.label(),
907                                   "Client labels don't match, ret = "
908                                   << *pClientBuff << "; expected = "
909                                   << peerCredentials.label());
910                 g_free(*pClientBuff);
911                 break;
912             case CLIENT_METHOD_PID:
913                 RUNNER_ASSERT_MSG(*pClientBuff == std::to_string(pid),
914                                   "PIDs don't match, ret = "
915                                   << *pClientBuff << "; expected = " << pid);
916                 g_free(*pClientBuff);
917                 break;
918             default:
919                 break;
920             }
921         }
922
923         if (pUserBuff != nullptr) {
924             switch (userMethod) {
925             case USER_METHOD_UID:
926                 RUNNER_ASSERT_MSG(*pUserBuff == std::to_string(peerCredentials.uid()),
927                                   "UIDs don't match, ret = "
928                                   << *pUserBuff
929                                   << "; expected = " << peerCredentials.uid());
930                 g_free(*pUserBuff);
931                 break;
932             default:
933                 break;
934             }
935         }
936
937         if (pPidCred != nullptr) {
938             RUNNER_ASSERT_MSG(*pPidCred == pid, "PIDs don't match, ret = "
939                               << *pPidCred
940                               << "; expected = " << pid);
941         }
942     });
943 }
944
945 RUNNER_MULTIPROCESS_TEST(tccgd08_gdbus_credentials_default_positive_all)
946 {
947     char *clientBuff = nullptr;
948     char *userBuff = nullptr;
949     pid_t pidCred = -1;
950
951     testGDbusCredsDefault(CYNARA_API_SUCCESS, &clientBuff, &userBuff, &pidCred);
952 }
953
954 RUNNER_MULTIPROCESS_TEST(tccgd09_gdbus_credentials_default_positive_partial_single)
955 {
956     char *clientBuff = nullptr;
957     char *userBuff = nullptr;
958     pid_t pidCred = -1;
959
960     testGDbusCredsDefault(CYNARA_API_SUCCESS, &clientBuff, nullptr, nullptr);
961     testGDbusCredsDefault(CYNARA_API_SUCCESS, nullptr, &userBuff, nullptr);
962     testGDbusCredsDefault(CYNARA_API_SUCCESS, nullptr, nullptr, &pidCred);
963 }
964
965 RUNNER_MULTIPROCESS_TEST(tccgd10_gdbus_credentials_default_positive_partial_double)
966 {
967     char *clientBuff = nullptr;
968     char *userBuff = nullptr;
969     pid_t pidCred = -1;
970
971     testGDbusCredsDefault(CYNARA_API_SUCCESS, nullptr, &userBuff, &pidCred);
972     testGDbusCredsDefault(CYNARA_API_SUCCESS, &clientBuff, nullptr, &pidCred);
973     testGDbusCredsDefault(CYNARA_API_SUCCESS, &clientBuff, &userBuff, nullptr);
974 }
975
976 RUNNER_MULTIPROCESS_TEST(tccgd11_gdbus_credentials_default_negative_incomplete)
977 {
978     testGDbusCredsDefault(CYNARA_API_INVALID_PARAM, nullptr, nullptr, nullptr);
979 }
980
981 void testGDbusCreds(int expectedResult,
982                     const cynara_client_creds *pClientMethod, char **pClientBuff,
983                     const cynara_user_creds *pUserMethod, char **pUserBuff,
984                     pid_t *pPidCred)
985 {
986     // reset variables if set by previous test cases
987     if (pClientBuff != nullptr) *pClientBuff = nullptr;
988     if (pUserBuff != nullptr) *pUserBuff = nullptr;
989     if (pPidCred != nullptr) *pPidCred = -1;
990
991     gdbusTestTemplate([&] (GDBusConnectionPtr conn, pid_t pid,
992                            const std::string &requestedName,
993                            const ProcessCredentials &peerCredentials) {
994
995         int ret = cynara_creds_gdbus_get(conn.get(), requestedName.c_str(),
996                                          pClientMethod, pClientBuff,
997                                          pUserMethod, pUserBuff, pPidCred);
998
999         RUNNER_ASSERT_MSG(ret == expectedResult,
1000                           "cynara_creds_gdbus_get returned unexpected result: " << ret <<
1001                           "; expected: " << expectedResult);
1002
1003         if (ret != CYNARA_API_SUCCESS) {
1004             return;
1005         }
1006
1007         if (pClientBuff != nullptr && pClientMethod != nullptr) {
1008             switch (*pClientMethod) {
1009             case CLIENT_METHOD_SMACK:
1010                 RUNNER_ASSERT_MSG(*pClientBuff == peerCredentials.label(),
1011                                   "Client labels don't match, ret = "
1012                                   << *pClientBuff << "; expected = "
1013                                   << peerCredentials.label());
1014                 g_free(*pClientBuff);
1015                 break;
1016             case CLIENT_METHOD_PID:
1017                 RUNNER_ASSERT_MSG(*pClientBuff == std::to_string(pid),
1018                                   "PIDs don't match, ret = "
1019                                   << *pClientBuff << "; expected = " << pid);
1020                 g_free(*pClientBuff);
1021                 break;
1022             default:
1023                 break;
1024             }
1025         }
1026
1027         if (pUserBuff != nullptr && pUserMethod != nullptr) {
1028             switch (*pUserMethod) {
1029             case USER_METHOD_UID:
1030                 RUNNER_ASSERT_MSG(*pUserBuff == std::to_string(peerCredentials.uid()),
1031                                   "UIDs don't match, ret = "
1032                                   << *pUserBuff
1033                                   << "; expected = " << peerCredentials.uid());
1034                 g_free(*pUserBuff);
1035                 break;
1036             default:
1037                 break;
1038             }
1039         }
1040
1041         if (pPidCred != nullptr) {
1042             RUNNER_ASSERT_MSG(*pPidCred == pid, "PIDs don't match, ret = "
1043                               << *pPidCred
1044                               << "; expected = " << pid);
1045         }
1046     });
1047 }
1048
1049 RUNNER_MULTIPROCESS_TEST(tccgd12_gdbus_credentials_positive_all)
1050 {
1051     char *clientBuff = nullptr;
1052     char *userBuff = nullptr;
1053     pid_t pidCred = -1;
1054
1055     testGDbusCreds(CYNARA_API_SUCCESS,
1056                    &G_CLIENT_METHOD_DEFAULT, &clientBuff,
1057                    &G_USER_METHOD_DEFAULT, &userBuff, &pidCred);
1058     testGDbusCreds(CYNARA_API_SUCCESS,
1059                    &G_CLIENT_METHOD_SMACK, &clientBuff,
1060                    &G_USER_METHOD_UID, &userBuff, &pidCred);
1061     testGDbusCreds(CYNARA_API_SUCCESS,
1062                    &G_CLIENT_METHOD_PID, &clientBuff,
1063                    &G_USER_METHOD_UID, &userBuff, &pidCred);
1064
1065     testGDbusCreds(CYNARA_API_METHOD_NOT_SUPPORTED,
1066                    &G_CLIENT_METHOD_SMACK, &clientBuff,
1067                    &G_USER_METHOD_GID, &userBuff, &pidCred);
1068     testGDbusCreds(CYNARA_API_METHOD_NOT_SUPPORTED,
1069                    &G_CLIENT_METHOD_PID, &clientBuff,
1070                    &G_USER_METHOD_GID, &userBuff, &pidCred);
1071 }
1072
1073 RUNNER_MULTIPROCESS_TEST(tccgd13_gdbus_credentials_positive_partial_single)
1074 {
1075     char *clientBuff = nullptr;
1076     char *userBuff = nullptr;
1077     pid_t pidCred = -1;
1078
1079     testGDbusCreds(CYNARA_API_SUCCESS,
1080                    &G_CLIENT_METHOD_PID, &clientBuff,
1081                    &G_USER_METHOD_DEFAULT, nullptr,
1082                    nullptr);
1083     testGDbusCreds(CYNARA_API_SUCCESS,
1084                    &G_CLIENT_METHOD_SMACK, &clientBuff,
1085                    nullptr, nullptr,
1086                    nullptr);
1087
1088     testGDbusCreds(CYNARA_API_SUCCESS,
1089                    &G_CLIENT_METHOD_DEFAULT, nullptr,
1090                    &G_USER_METHOD_DEFAULT, &userBuff,
1091                    nullptr);
1092     testGDbusCreds(CYNARA_API_SUCCESS,
1093                    nullptr, nullptr,
1094                    &G_USER_METHOD_DEFAULT, &userBuff,
1095                    nullptr);
1096
1097     testGDbusCreds(CYNARA_API_SUCCESS,
1098                    nullptr, nullptr,
1099                    &G_USER_METHOD_DEFAULT, nullptr,
1100                    &pidCred);
1101     testGDbusCreds(CYNARA_API_SUCCESS,
1102                    &G_CLIENT_METHOD_DEFAULT, nullptr,
1103                    nullptr, nullptr,
1104                    &pidCred);
1105     testGDbusCreds(CYNARA_API_SUCCESS,
1106                    nullptr, nullptr,
1107                    nullptr, nullptr,
1108                    &pidCred);
1109  }
1110
1111 RUNNER_MULTIPROCESS_TEST(tccgd14_gdbus_credentials_positive_partial_double)
1112 {
1113     char *clientBuff = nullptr;
1114     char *userBuff = nullptr;
1115     pid_t pidCred = -1;
1116
1117     testGDbusCreds(CYNARA_API_SUCCESS,
1118                    &G_CLIENT_METHOD_DEFAULT, nullptr,
1119                    &G_USER_METHOD_UID, &userBuff, &pidCred);
1120     testGDbusCreds(CYNARA_API_SUCCESS,
1121                    nullptr, nullptr,
1122                    &G_USER_METHOD_DEFAULT, &userBuff, &pidCred);
1123
1124     testGDbusCreds(CYNARA_API_SUCCESS,
1125                    &G_CLIENT_METHOD_PID, &clientBuff,
1126                    &G_USER_METHOD_DEFAULT, nullptr, &pidCred);
1127     testGDbusCreds(CYNARA_API_SUCCESS,
1128                    &G_CLIENT_METHOD_DEFAULT, &clientBuff,
1129                    nullptr, nullptr, &pidCred);
1130
1131     testGDbusCreds(CYNARA_API_SUCCESS,
1132                    &G_CLIENT_METHOD_SMACK, &clientBuff,
1133                    &G_USER_METHOD_UID, &userBuff, nullptr);
1134 }
1135
1136 RUNNER_MULTIPROCESS_TEST(tccgd14_gdbus_credentials_negative_incomplete)
1137 {
1138     char *clientBuff = nullptr;
1139     char *userBuff = nullptr;
1140     pid_t pidCred = -1;
1141
1142     testGDbusCreds(CYNARA_API_INVALID_PARAM,
1143                    nullptr, &clientBuff,
1144                    &G_USER_METHOD_UID, &userBuff, &pidCred);
1145     testGDbusCreds(CYNARA_API_INVALID_PARAM,
1146                    nullptr, &clientBuff,
1147                    &G_USER_METHOD_UID, nullptr, &pidCred);
1148     testGDbusCreds(CYNARA_API_INVALID_PARAM,
1149                    nullptr, &clientBuff,
1150                    nullptr, nullptr, &pidCred);
1151
1152     testGDbusCreds(CYNARA_API_INVALID_PARAM,
1153                    &G_CLIENT_METHOD_DEFAULT, &clientBuff,
1154                    nullptr, &userBuff, &pidCred);
1155     testGDbusCreds(CYNARA_API_INVALID_PARAM,
1156                    &G_CLIENT_METHOD_DEFAULT, nullptr,
1157                    nullptr, &userBuff, &pidCred);
1158     testGDbusCreds(CYNARA_API_INVALID_PARAM,
1159                    nullptr, nullptr,
1160                    nullptr, &userBuff, &pidCred);
1161
1162     testGDbusCreds(CYNARA_API_INVALID_PARAM,
1163                    &G_CLIENT_METHOD_DEFAULT, nullptr,
1164                    &G_USER_METHOD_UID, nullptr, nullptr);
1165     testGDbusCreds(CYNARA_API_INVALID_PARAM,
1166                    &G_CLIENT_METHOD_DEFAULT, nullptr,
1167                    nullptr, nullptr, nullptr);
1168     testGDbusCreds(CYNARA_API_INVALID_PARAM,
1169                    nullptr, nullptr,
1170                    &G_USER_METHOD_DEFAULT, nullptr, nullptr);
1171     testGDbusCreds(CYNARA_API_INVALID_PARAM,
1172                    nullptr, nullptr,
1173                    nullptr, nullptr, nullptr);
1174 }
1175
1176 RUNNER_MULTIPROCESS_TEST(tccgd14_gdbus_credentials_negative_incorrect)
1177 {
1178     char *clientBuff = nullptr;
1179     char *userBuff = nullptr;
1180     pid_t pidCred = -1;
1181
1182     testGDbusCreds(CYNARA_API_METHOD_NOT_SUPPORTED,
1183                    &G_CLIENT_METHOD_LOW, &clientBuff,
1184                    &G_USER_METHOD_DEFAULT, &userBuff, &pidCred);
1185     testGDbusCreds(CYNARA_API_METHOD_NOT_SUPPORTED,
1186                    &G_CLIENT_METHOD_HIGH, &clientBuff,
1187                    &G_USER_METHOD_DEFAULT, &userBuff, &pidCred);
1188     testGDbusCreds(CYNARA_API_METHOD_NOT_SUPPORTED,
1189                    &G_CLIENT_METHOD_DEFAULT, &clientBuff,
1190                    &G_USER_METHOD_LOW, &userBuff, &pidCred);
1191     testGDbusCreds(CYNARA_API_METHOD_NOT_SUPPORTED,
1192                    &G_CLIENT_METHOD_DEFAULT, &clientBuff,
1193                    &G_USER_METHOD_HIGH, &userBuff, &pidCred);
1194 }
1195
1196
1197 //================================SdBus===============================================
1198
1199 SdBusConnectionPtr createSdBusConnection(const std::string &requestedName) {
1200     sd_bus *bus = NULL;
1201
1202     int r = sd_bus_default_system(&bus);
1203     RUNNER_ASSERT_MSG(r >= 0, "Failed to connect do system bus: %s" << strerror(-r));
1204
1205     if (requestedName.empty() == false) {
1206         r = sd_bus_request_name(bus, requestedName.c_str(), SD_BUS_NAME_REPLACE_EXISTING);
1207         RUNNER_ASSERT_MSG(r >= 0, "Error in sd_bus_request_name");
1208     }
1209
1210     SdBusConnectionPtr ret(bus, [] (sd_bus *busConnection) {
1211         sd_bus_unref(busConnection);
1212     });
1213
1214     return ret;
1215 }
1216
1217 typedef std::function<void(SdBusConnectionPtr conn, pid_t pid, const std::string &requestedName,
1218                            const ProcessCredentials &peerCredentials)> SdBusAssertionFn;
1219
1220 void sdBusTestTemplate(SdBusAssertionFn assertion) {
1221     std::string requestedName = "tests.dbus.cynara";
1222     const ProcessCredentials peerCredentials;
1223
1224     SynchronizationPipe pipe;
1225     pid_t pid = runInChild(std::bind(dbusServer, std::ref(pipe), std::cref(requestedName),
1226                            std::cref(peerCredentials)));
1227
1228     pipe.claimParentEp();
1229     pipe.wait();
1230
1231     auto conn = createSdBusConnection("");
1232     assertion(std::move(conn), pid, requestedName, peerCredentials);
1233     pipe.post();
1234 }
1235
1236
1237 RUNNER_TEST_GROUP_INIT(cynara_creds_sd_bus)
1238
1239 void testSdBusClientPid(cynara_client_creds method = CLIENT_METHOD_PID) {
1240     sdBusTestTemplate([method] (SdBusConnectionPtr conn, pid_t pid,
1241                         const std::string &requestedName,
1242                         const ProcessCredentials &) {
1243         CStringPtr clientPidStr(CynaraHelperCredentials::sdBusGetClient(std::move(conn),
1244                                 requestedName.c_str(), method, CYNARA_API_SUCCESS));
1245         pid_t clientPid = std::stoi(clientPidStr.get());
1246         RUNNER_ASSERT_MSG(pid == clientPid, "PIDs don't match ret = " << clientPid
1247                           << "; expected = " << pid);
1248     });
1249 }
1250
1251 void testSdBusClientSmack(cynara_client_creds method = CLIENT_METHOD_SMACK) {
1252     sdBusTestTemplate([method] (SdBusConnectionPtr conn, pid_t,
1253                         const std::string &requestedName,
1254                         const ProcessCredentials &peerCredentials) {
1255         CStringPtr label(CynaraHelperCredentials::sdBusGetClient(std::move(conn),
1256                          requestedName.c_str(), method, CYNARA_API_SUCCESS));
1257         RUNNER_ASSERT_MSG(peerCredentials.label() == label.get(),
1258                           "Labels don't match ret = " << label.get()
1259                           << "; expected = " << peerCredentials.label());
1260     });
1261 }
1262
1263 RUNNER_MULTIPROCESS_TEST(tccsd01_sd_bus_credentials_client_pid)
1264 {
1265     testSdBusClientPid();
1266 }
1267
1268 RUNNER_MULTIPROCESS_TEST_SMACK(tccsd02_sd_bus_credentials_client_smack)
1269 {
1270     testSdBusClientSmack();
1271 }
1272
1273 RUNNER_MULTIPROCESS_TEST_SMACK(tccsd03_sd_bus_credentials_client_default)
1274 {
1275     auto method = getClientDefaultMethod();
1276     switch(method) {
1277     case CLIENT_METHOD_SMACK:
1278         testSdBusClientSmack(CLIENT_METHOD_DEFAULT);
1279         break;
1280     case CLIENT_METHOD_PID:
1281         testSdBusClientPid(CLIENT_METHOD_DEFAULT);
1282         break;
1283     default:
1284         RUNNER_FAIL_MSG("cynara_creds_get_default_client_method returned unexpected value "
1285                         << method);
1286     }
1287 }
1288
1289 void testSdBusUserUid(cynara_user_creds method = USER_METHOD_UID) {
1290     sdBusTestTemplate([method] (SdBusConnectionPtr conn, pid_t,
1291                         const std::string &requestedName,
1292                         const ProcessCredentials &peerCredentials) {
1293         CStringPtr uidStr(CynaraHelperCredentials::sdBusGetUser(std::move(conn),
1294                           requestedName.c_str(), method, CYNARA_API_SUCCESS));
1295         uid_t uid = std::stoul(uidStr.get());
1296         RUNNER_ASSERT_MSG(peerCredentials.uid() == uid, "UIDs don't match ret = " << uid
1297                           << "; expected = "<< peerCredentials.uid());
1298     });
1299 }
1300
1301 void testSdBusUserGid(cynara_user_creds method = USER_METHOD_GID) {
1302     sdBusTestTemplate([method] (SdBusConnectionPtr conn, pid_t,
1303                         const std::string &requestedName,
1304                         const ProcessCredentials &peerCredentials) {
1305         CStringPtr gidStr(CynaraHelperCredentials::sdBusGetUser(std::move(conn),
1306                           requestedName.c_str(), method, CYNARA_API_SUCCESS));
1307         gid_t gid = std::stoul(gidStr.get());
1308         RUNNER_ASSERT_MSG(peerCredentials.gid() == gid, "GIDs don't match ret = " << gid
1309                           << "; expected = "<< peerCredentials.gid());
1310     });
1311 }
1312
1313 RUNNER_MULTIPROCESS_TEST(tccsd04_sd_bus_credentials_user_uid)
1314 {
1315     testSdBusUserUid();
1316 }
1317
1318 RUNNER_MULTIPROCESS_TEST(tccsd05_sd_bus_credentials_user_gid)
1319 {
1320     testSdBusUserGid();
1321 }
1322
1323 RUNNER_MULTIPROCESS_TEST(tccsd06_sd_bus_credentials_user_default)
1324 {
1325     auto method = getUserDefaultMethod();
1326     switch(method) {
1327     case USER_METHOD_UID:
1328         testSdBusUserUid(USER_METHOD_DEFAULT);
1329         break;
1330     case USER_METHOD_GID:
1331         testSdBusUserGid(USER_METHOD_DEFAULT);
1332         break;
1333     default:
1334         RUNNER_FAIL_MSG("cynara_creds_get_default_user_method returned unexpected value "
1335                         << method);
1336     }
1337 }
1338
1339 RUNNER_TEST_SMACK(tccd07_sd_bus_credentials_pid) {
1340     sdBusTestTemplate([] (SdBusConnectionPtr conn, pid_t expectedPid,
1341                           const std::string &requestedName, const ProcessCredentials &) {
1342         auto helperPid = CynaraHelperCredentials::sdBusGetPid(std::move(conn),
1343                          requestedName.c_str(), CYNARA_API_SUCCESS);
1344         RUNNER_ASSERT_MSG(helperPid == expectedPid, "PIDs don't match ret = " << helperPid
1345                           << "; expected = " << expectedPid);
1346     });
1347 }
1348
1349
1350 RUNNER_TEST_GROUP_INIT(cynara_creds_self)
1351
1352 void testCredsClientSelf(cynara_client_creds method, const std::string &expected) {
1353     char *client;
1354     int ret = cynara_creds_self_get_client(method, &client);
1355     CStringPtr clientPtr(client);
1356     RUNNER_ASSERT_MSG(ret == CYNARA_API_SUCCESS, "cynara_creds_self_get_client failed with " << ret);
1357     RUNNER_ASSERT_MSG(expected == client, "expected client doesn't match, expected: " << expected
1358                                           << ", got : " << client);
1359 }
1360
1361 void testCredsUserSelf(cynara_user_creds method, const std::string &expected) {
1362     char *user;
1363     int ret = cynara_creds_self_get_user(method, &user);
1364     CStringPtr clientPtr(user);
1365     RUNNER_ASSERT_MSG(ret == CYNARA_API_SUCCESS, "cynara_creds_self_get_user failed with " << ret);
1366     RUNNER_ASSERT_MSG(expected == user, "expected user doesn't match, expected: " << expected
1367                                           << ", got : " << user);
1368 }
1369
1370 void testSelfClientSmack(cynara_client_creds method = CLIENT_METHOD_SMACK) {
1371     std::string label = "test-label";
1372     ScopedProcessLabel spl(label, false);
1373     testCredsClientSelf(method, label);
1374 }
1375
1376 void testSelfClientPid(cynara_client_creds method = CLIENT_METHOD_PID) {
1377     pid_t pid = getpid();
1378     testCredsClientSelf(method, std::to_string(pid));
1379 }
1380
1381 void testSelfUserUid(cynara_user_creds method = USER_METHOD_UID) {
1382     uid_t uid = getuid();
1383     testCredsUserSelf(method, std::to_string(uid));
1384 }
1385
1386 void testSelfUserGid(cynara_user_creds method = USER_METHOD_GID) {
1387     gid_t gid = getgid();
1388     testCredsUserSelf(method, std::to_string(gid));
1389 }
1390
1391 RUNNER_CHILD_TEST_SMACK(tccsl01_self_credentials_client_smack) {
1392     testSelfClientSmack();
1393 }
1394
1395 RUNNER_CHILD_TEST_SMACK(tccsl02_self_credentials_client_pid) {
1396     testSelfClientPid();
1397 }
1398
1399 RUNNER_CHILD_TEST_SMACK(tccsl03_self_credentials_user_uid) {
1400     testSelfUserUid();
1401 }
1402
1403 RUNNER_CHILD_TEST_SMACK(tccsl04_self_credentials_user_gid) {
1404     testSelfUserGid();
1405 }
1406
1407 RUNNER_CHILD_TEST_SMACK(tccsl05_self_credentials_client_default) {
1408     auto method = getClientDefaultMethod();
1409     switch(method) {
1410     case CLIENT_METHOD_SMACK:
1411         testSelfClientSmack(CLIENT_METHOD_DEFAULT);
1412         break;
1413     case CLIENT_METHOD_PID:
1414         testSelfClientPid(CLIENT_METHOD_DEFAULT);
1415         break;
1416     default:
1417         RUNNER_FAIL_MSG("cynara_creds_get_default_client_method returned unexpected value " << method);
1418     }
1419 }
1420
1421 RUNNER_CHILD_TEST_SMACK(tccsl06_self_credentials_user_default) {
1422     auto method = getUserDefaultMethod();
1423     switch(method) {
1424     case USER_METHOD_UID:
1425         testSelfUserUid(USER_METHOD_DEFAULT);
1426         break;
1427     case USER_METHOD_GID:
1428         testSelfUserGid(USER_METHOD_DEFAULT);
1429         break;
1430     default:
1431         RUNNER_FAIL_MSG("cynara_creds_get_default_user_method returned unexpected value " << method);
1432     }
1433 }