Make sure that Connman is used as a DNS proxy
[platform/core/test/security-tests.git] / src / nether-tests / nether_tests.cpp
1 /*
2  * Copyright (c) 2017 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 /*
18  * @file        nether_tests.cpp
19  * @author      Piotr Sawicki (p.sawicki2@partner.samsung.com)
20  * @version     1.0
21  * @brief       Tests for Nether service
22  */
23
24 #include <errno.h>
25 #include <fcntl.h>
26 #include <poll.h>
27 #include <unistd.h>
28 #include <arpa/inet.h>
29 #include <linux/netlink.h>
30 #include <netdb.h>
31 #include <net/if.h>
32 #include <netinet/in.h>
33 #include <sys/mount.h>
34 #include <sys/socket.h>
35 #include <sys/stat.h>
36 #include <sys/types.h>
37 #include <sys/wait.h>
38
39 #include <condition_variable>
40 #include <string>
41 #include <thread>
42 #include <vector>
43
44 #include <scoped_installer.h>
45 #include <sm_commons.h>
46 #include <tests_common.h>
47 #include <dpl/test/safe_cleanup.h>
48
49
50 using namespace SecurityManagerTest;
51 using namespace DPL::Test;
52
53 const std::string INTERNET_ACCESS_PRIVILEGE = "http://tizen.org/privilege/internet";
54 const std::string NETHER_NETNS_NAME_NONE = "";
55 const std::string NETHER_NETNS_NAME_TEST = "nether_test_network_ns";
56 const std::string NETNS_RUN_DIR = "/var/run/netns"; // taken from iproute2
57 const std::string NETHER_NETNS_SETUP_COMMAND = "/usr/bin/setup-nether-tests-nns.sh " + NETHER_NETNS_NAME_TEST;
58 const std::string NETHER_NETNS_TEARDOWN_COMMAND = "/usr/bin/teardown-nether-tests-nns.sh " + NETHER_NETNS_NAME_TEST;
59 const std::string NETHER_DNS_SETUP_COMMAND = "/usr/bin/setup-nether-tests-dns.sh";
60 const std::string NETHER_DNS_TEARDOWN_COMMAND = "/usr/bin/teardown-nether-tests-dns.sh";
61
62
63 const ssize_t NET_BUFFER_SIZE = 1024;
64 const int UDP_MESSAGES_COUNT = 20000;
65 const int TCP_MESSAGES_COUNT = 20000;
66
67 const uint16_t UDP_TEST_PORT = 12000;
68 const uint16_t TCP_TEST_PORT = 12000;
69
70 const std::string REMOTE_INTERFACE_ADDRESS = "10.1.0.2";
71 const std::string REMOTE_INTERFACE_NAME = "veth1";
72 const std::string LOCAL_HOST_TEST_SERVER_ADDRESS = "127.0.0.1";
73 const std::string LOCAL_TEST_MCAST_GROUP = "225.0.0.250";
74 const std::string DNS_TEST_ADDRESS = "www.samsung.com";
75 const std::string ANY_INTERFACE = "";
76
77 const char TTL_MCAST_RESTRIC_SUBNET = 1;
78
79 const int MONITOR_TIMEOUT = 1000; // ms
80
81 enum class NetherInternetAccess {
82     ACCESS_GRANTED,
83     ACCESS_DENIED
84 };
85
86
87 void runShellScriptInChildAndWait(const std::string &command)
88 {
89     RUNNER_ASSERT_MSG(system(command.c_str()) != -1, "Couldn't run command: " << command);
90 }
91
92
93 class ScopedShellScriptRunner final {
94 public:
95     ScopedShellScriptRunner(const std::string &setupCmd, const std::string &teardownCmd)
96     : m_teardownCmd(teardownCmd)
97     {
98         runShellScriptInChildAndWait(setupCmd);
99     }
100
101     ~ScopedShellScriptRunner()
102     {
103         SafeCleanup::run([this]() {
104             runShellScriptInChildAndWait(m_teardownCmd);
105         });
106     }
107
108     ScopedShellScriptRunner(const ScopedShellScriptRunner &) = delete;
109     ScopedShellScriptRunner &operator=(const ScopedShellScriptRunner &) = delete;
110
111 private:
112     std::string m_teardownCmd;
113 };
114
115
116 void createChildProcess(const std::function<int(int)> &procedure, pid_t &childPid, int &childPipeFd)
117 {
118     int pipeFd[2];
119     RUNNER_ASSERT_ERRNO_MSG(pipe2(pipeFd, O_DIRECT) == 0, "pipe() failed");
120
121     pid_t pid = fork();
122     RUNNER_ASSERT_ERRNO_MSG(pid != -1, "fork() failed");
123
124     if (pid != 0) {
125         // parent code
126         TEMP_FAILURE_RETRY(close(pipeFd[1]));
127
128         childPipeFd = pipeFd[0];
129         childPid = pid;
130     } else {
131         // child code
132         TestRunnerSingleton::Instance().Terminate();
133
134         close(STDIN_FILENO);
135         close(STDOUT_FILENO);
136         close(STDERR_FILENO);
137
138         close(pipeFd[0]);
139
140         int retStatus = EXIT_FAILURE;
141
142         int devNullFd = TEMP_FAILURE_RETRY(open("/dev/null", O_WRONLY));
143         if (devNullFd == -1) {
144             goto end;
145         }
146
147         if (TEMP_FAILURE_RETRY(dup2(devNullFd, STDIN_FILENO)) == -1) {
148             goto end;
149         }
150
151         if (TEMP_FAILURE_RETRY(dup2(devNullFd, STDOUT_FILENO)) == -1) {
152             goto end;
153         }
154
155         if (TEMP_FAILURE_RETRY(dup2(devNullFd, STDERR_FILENO)) == -1) {
156             goto end;
157         }
158
159         retStatus = procedure(pipeFd[1]);
160 end:
161         exit(retStatus);
162     }
163 }
164
165
166 int switchToNetworkNamespace(const std::string &netnsName)
167 {
168     if (netnsName == NETHER_NETNS_NAME_NONE) {
169         return 0;
170     }
171
172     const std::string netnsPath { NETNS_RUN_DIR + "/" + netnsName };
173     if (netnsPath.length() >= PATH_MAX) {
174         return -1;
175     }
176
177     int netNsFd = open(netnsPath.c_str(), O_RDONLY);
178     if (netNsFd == -1) {
179         return -1;
180     }
181
182     // uses an existing network name-space (previously created by "ip netns" command)
183     if (setns(netNsFd, CLONE_NEWNET) == -1) {
184         close(netNsFd);
185         return -1;
186     }
187
188     return 0;
189 }
190
191
192 class TemporaryNormalTestUser
193 {
194 public:
195     TemporaryNormalTestUser(const std::string &userName)
196     : m_user(userName, GUM_USERTYPE_NORMAL, false)
197     {
198         m_user.create();
199     }
200
201     uid_t getUid() const
202     {
203         return m_user.getUid();
204     }
205
206 private:
207     TemporaryTestUser m_user;
208 };
209
210
211 class InternetLocalAppInstallHelper : public AppInstallHelper
212 {
213 public:
214     InternetLocalAppInstallHelper(const std::string &namePrefix, uid_t uid, NetherInternetAccess access)
215     : AppInstallHelper(namePrefix, uid)
216     {
217         setInstallType(app_install_type::SM_APP_INSTALL_LOCAL);
218         if (access == NetherInternetAccess::ACCESS_GRANTED) {
219             addPrivilege(INTERNET_ACCESS_PRIVILEGE);
220         }
221     }
222 };
223
224
225 class AppContext
226 {
227 public:
228     AppContext()
229     : m_appId{}
230     , m_appUID(-1)
231     , m_appGID(-1)
232     {
233     }
234
235     AppContext(const std::string &appId, uid_t appUID, gid_t appGID)
236     : m_appId(appId)
237     , m_appUID(appUID)
238     , m_appGID(appGID)
239     {
240     }
241
242     const std::string &appId() const
243     {
244         return m_appId;
245     }
246
247     void setAppId(const std::string &appId)
248     {
249         m_appId = appId;
250     }
251
252     uid_t getUID() const
253     {
254         return m_appUID;
255     }
256
257     void setUID(uid_t appUID)
258     {
259         m_appUID = appUID;
260     }
261
262     gid_t getGID() const
263     {
264         return m_appGID;
265     }
266
267     void setGID(gid_t appGID)
268     {
269         m_appGID = appGID;
270     }
271
272 private:
273     std::string m_appId;
274     uid_t m_appUID;
275     gid_t m_appGID;
276 };
277
278
279 class ScopedAppContext : public AppContext
280 {
281 public:
282     ScopedAppContext(const std::string &appPrefix, NetherInternetAccess access)
283     : m_user(appPrefix + "_user")
284     , m_installHelper(appPrefix + "_app_normal", m_user.getUid(), access)
285     , m_scopedInstaller(m_installHelper)
286     {
287         setAppId(m_installHelper.getAppId());
288         setUID(m_installHelper.getUID());
289         setGID(m_installHelper.getGID());
290     }
291
292 private:
293     TemporaryNormalTestUser m_user;
294     InternetLocalAppInstallHelper m_installHelper;
295     ScopedInstaller m_scopedInstaller;
296 };
297
298
299 void runProcedureInNetAppContext(
300     const std::string &appPrefix,
301     const std::function<void(void)> &procedure,
302     const NetherInternetAccess access = NetherInternetAccess::ACCESS_DENIED)
303 {
304     ScopedAppContext scopedAppContext(appPrefix, access);
305
306     auto smackLabel = scopedAppContext.appId();
307     auto appUID = scopedAppContext.getUID();
308     auto appGID = scopedAppContext.getGID();
309
310     // run client procedure in app context
311     runInChildParentWait([=]() {
312         Api::setProcessLabel(smackLabel);
313         RUNNER_ASSERT_ERRNO_MSG(drop_root_privileges(appUID, appGID) == 0,
314                                 "drop_root_privileges() failed");
315         procedure();
316     });
317 }
318
319
320 class NetServer
321 {
322 public:
323     NetServer()
324     : m_monitorIsRunning(false)
325     , m_receivedBytes(0ull)
326     , m_serverPid(-1)
327     , m_serverPipeFd(-1)
328     {}
329
330     NetServer(const NetServer &) = delete;
331     NetServer &operator=(const NetServer &) = delete;
332
333     virtual ~NetServer()
334     {
335         SafeCleanup::run([this]() {
336             stop();
337         });
338     }
339
340     void start(const std::string &netnsName = NETHER_NETNS_NAME_NONE)
341     {
342         std::unique_lock<std::mutex> lock(m_monitorMutex);
343
344         RUNNER_ASSERT_MSG(!m_monitorIsRunning, "Monitor thread is already running");
345
346         createChildProcess([=] (int pipeFd) -> int {
347             if (netnsName != NETHER_NETNS_NAME_NONE) {
348                 if (switchToNetworkNamespace(netnsName) == -1) {
349                     exit(EXIT_FAILURE);
350                 }
351             }
352             return serverProcedure(pipeFd);
353         }, m_serverPid, m_serverPipeFd);
354
355         waitForServer();
356
357         m_monitorThread = std::move(std::thread(&NetServer::monitorThreadProc, this));
358
359         m_monitorSyncPoint.wait(lock, [this]() {
360            return m_monitorIsRunning;
361         });
362     }
363
364     void stop()
365     {
366         stopMonitor();
367         closeServerPipe();
368         stopServerProcess();
369     }
370
371     uint64_t getReceivedBytes() const
372     {
373         RUNNER_ASSERT_MSG(!isAlive(), "Cannot read statistics. Server is still running: " << (*this));
374         return m_receivedBytes;
375     }
376
377     bool isAlive() const
378     {
379         int status;
380         return waitpid(m_serverPid, &status, WNOHANG) == 0;
381     }
382
383     virtual int serverProcedure(int) = 0;
384
385     virtual std::string getDescription() const = 0;
386
387 protected:
388     void notifyManager(int pipeFd)
389     {
390         char c = 'X';
391         ssize_t ret = TEMP_FAILURE_RETRY(write(pipeFd, &c, sizeof(c)));
392         if (ret == -1) {
393             exit(EXIT_FAILURE);
394         }
395     }
396
397 private:
398     void waitForServer() const
399     {
400         pollfd pfd { m_serverPipeFd, POLLIN, 0 };
401
402         int ret = TEMP_FAILURE_RETRY(poll(&pfd, 1, MONITOR_TIMEOUT));
403         RUNNER_ASSERT_ERRNO_MSG(ret >= 0, "poll() failed");
404
405         if (pfd.revents & POLLIN) {
406             char c;
407             ssize_t len = TEMP_FAILURE_RETRY(read(m_serverPipeFd, &c, sizeof(c)));
408             RUNNER_ASSERT_ERRNO_MSG(len >= 0, "Read pipe failed");
409         }
410     }
411
412     ssize_t collectStatistics()
413     {
414         char buffer[NET_BUFFER_SIZE];
415
416         ssize_t ret = TEMP_FAILURE_RETRY(read(m_serverPipeFd, buffer, sizeof(buffer)));
417         if (ret > 0) {
418             m_receivedBytes += static_cast<uint64_t>(ret);
419         }
420
421         return ret;
422     }
423
424     void closeServerPipe()
425     {
426         if (m_serverPipeFd == -1) {
427             return;
428         }
429
430         close(m_serverPipeFd);
431         m_serverPipeFd = -1;
432     }
433
434     void stopServerProcess()
435     {
436         if (m_serverPid == -1) {
437             return;
438         }
439
440         if (!isAlive()) {
441             m_serverPid = -1;
442             return;
443         }
444
445         RUNNER_ASSERT_ERRNO_MSG(kill(m_serverPid, SIGTERM) == 0, "kill() failed");
446
447         int status;
448         do {
449             pid_t ret = TEMP_FAILURE_RETRY(waitpid(m_serverPid, &status, WUNTRACED | WCONTINUED));
450             RUNNER_ASSERT_ERRNO_MSG(ret != -1, "waitpid() failed");
451         } while (!WIFEXITED(status) && !WIFSIGNALED(status));
452
453         m_serverPid = -1;
454     }
455
456     void stopMonitor()
457     {
458         {
459             std::lock_guard<std::mutex> lock(m_monitorMutex);
460             m_monitorIsRunning = false;
461         }
462
463         if (m_monitorThread.joinable()) {
464             m_monitorThread.join();
465         }
466     }
467
468     void monitorThreadProc()
469     {
470         std::unique_lock<std::mutex> lock(m_monitorMutex);
471         m_monitorIsRunning = true;
472         lock.unlock();
473
474         m_monitorSyncPoint.notify_one();
475
476         lock.lock();
477
478         pollfd pollFd{ m_serverPipeFd, POLLIN, 0 };
479
480         while (m_monitorIsRunning) {
481
482             lock.unlock();
483
484             int ret = TEMP_FAILURE_RETRY(poll(&pollFd, 1, MONITOR_TIMEOUT));
485             if (ret == -1) {
486                 lock.lock();
487                 break;
488             }
489
490             if (ret > 0 && (pollFd.revents & POLLIN)) {
491                 if (collectStatistics() == -1) {
492                     lock.lock();
493                     break;
494                 }
495             }
496
497             lock.lock();
498         }
499
500         m_monitorIsRunning = false;
501         lock.unlock();
502     }
503
504     // monitor variables
505     std::thread m_monitorThread;
506     bool m_monitorIsRunning;
507     std::mutex m_monitorMutex;
508     std::condition_variable m_monitorSyncPoint;
509
510     // server variables
511     uint64_t m_receivedBytes;
512     pid_t m_serverPid;
513     int m_serverPipeFd;
514
515     friend std::ostream &operator<<(std::ostream &os, const NetServer &);
516 };
517
518
519 std::ostream &operator<<(std::ostream &os, const NetServer &server)
520 {
521     os << server.getDescription();
522     return os;
523 }
524
525
526 class UDPServer : public NetServer
527 {
528 public:
529     UDPServer(uint16_t port, int protocol = IPPROTO_UDP)
530     : NetServer{}
531     , m_port(port)
532     , m_protocol(protocol)
533     {}
534
535     virtual ~UDPServer() {}
536
537     virtual std::string getDescription() const override
538     {
539         return "UDPServer port: " + std::to_string(m_port);
540     }
541
542     virtual bool applyExtraSocketOptions(int)
543     {
544         return true;
545     }
546
547     virtual int serverProcedure(int pipeFd) override
548     {
549         FdUniquePtr pipePtr(&pipeFd);
550
551         int sockFd = socket(AF_INET, SOCK_DGRAM, m_protocol);
552         if (sockFd == -1) {
553             exit(EXIT_FAILURE);
554         }
555
556         SockUniquePtr sockPtr(&sockFd);
557
558         int optionValue = 1;
559         if (setsockopt(sockFd, SOL_SOCKET, SO_REUSEADDR, static_cast<const void *>(&optionValue) , sizeof(int)) == -1) {
560             exit(EXIT_FAILURE);
561         }
562
563         struct sockaddr_in serverAddress;
564         memset(&serverAddress, 0, sizeof(serverAddress));
565         serverAddress.sin_family = AF_INET;
566         serverAddress.sin_addr.s_addr = htonl(INADDR_ANY);
567         serverAddress.sin_port = htons(m_port);
568
569         if (bind(sockFd, reinterpret_cast<struct sockaddr *>(&serverAddress), sizeof(serverAddress)) == -1) {
570             exit(EXIT_FAILURE);
571         }
572
573         if (!applyExtraSocketOptions(sockFd)) {
574             exit(EXIT_FAILURE);
575         }
576
577         struct sockaddr_in clntAddress;
578         socklen_t clntAddressLength = static_cast<socklen_t>(sizeof(clntAddress));
579         char receiveBuffer[NET_BUFFER_SIZE];
580
581         notifyManager(pipeFd);
582
583         while (true) {
584             ssize_t len = TEMP_FAILURE_RETRY(recvfrom(sockFd, receiveBuffer, sizeof(receiveBuffer), 0,
585                     reinterpret_cast<struct sockaddr *>(&clntAddress), &clntAddressLength));
586
587             if (len == -1) {
588                 exit(EXIT_FAILURE);
589             }
590
591             if (len == 0) {
592                 continue;
593             }
594
595             do {
596                 ssize_t pos = 0;
597                 ssize_t ret = TEMP_FAILURE_RETRY(write(pipeFd, &receiveBuffer[pos], len));
598                 if (ret == -1) {
599                     exit(EXIT_FAILURE);
600                 }
601
602                 len -= ret;
603                 pos += ret;
604             } while (len != 0);
605         }
606
607         return EXIT_SUCCESS;
608     }
609
610 private:
611     uint16_t m_port;
612     int m_protocol;
613 };
614
615
616 class UDPServerApp : public UDPServer
617 {
618 public:
619     UDPServerApp(uint16_t port, int protocol, const AppContext &appContext)
620     : UDPServer(port, protocol)
621     , m_appContext(appContext)
622     {
623     }
624
625     virtual int serverProcedure(int pipeFd) override
626     {
627         Api::setProcessLabel(m_appContext.appId());
628         RUNNER_ASSERT_ERRNO_MSG(drop_root_privileges(m_appContext.getUID(), m_appContext.getGID()) == 0,
629                                 "drop_root_privileges() failed");
630
631         return UDPServer::serverProcedure(pipeFd);
632     }
633
634 private:
635     AppContext m_appContext;
636 };
637
638 class UDPMulticastServer : public UDPServer
639 {
640 public:
641     UDPMulticastServer(uint16_t port, int protocol,
642             const std::string &mcastGroup, const std::string &networkInterface)
643     : UDPServer(port, protocol)
644     , m_mcastGroup(mcastGroup)
645     , m_networkInterface(networkInterface)
646     {
647     }
648
649     bool applyExtraSocketOptions(int sockFd) override
650     {
651         struct ip_mreq multicastRequest;
652         memset(&multicastRequest, 0, sizeof(multicastRequest));
653
654         in_addr_t mcastGroupAddr = inet_addr(m_mcastGroup.c_str());
655         if (!IN_MULTICAST(ntohl(mcastGroupAddr))) {
656             return false;
657         }
658
659         multicastRequest.imr_multiaddr.s_addr = mcastGroupAddr;
660
661         if (m_networkInterface == ANY_INTERFACE) {
662             multicastRequest.imr_interface.s_addr = INADDR_ANY;
663         } else {
664             struct ifreq interfaceRequest;
665             memset(&interfaceRequest, 0, sizeof(interfaceRequest));
666
667             interfaceRequest.ifr_addr.sa_family = AF_INET;
668             strncpy(interfaceRequest.ifr_name, m_networkInterface.c_str(), IFNAMSIZ);
669             interfaceRequest.ifr_name[IFNAMSIZ - 1] = '\0';
670
671             if (ioctl(sockFd, SIOCGIFADDR, &interfaceRequest) == -1) {
672                 return false;
673             }
674
675             struct sockaddr_in *addr = reinterpret_cast<struct sockaddr_in *>(&interfaceRequest.ifr_addr);
676             multicastRequest.imr_interface.s_addr = addr->sin_addr.s_addr;
677         }
678
679         return setsockopt(sockFd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
680                 static_cast<const void *>(&multicastRequest), sizeof(multicastRequest)) == 0;
681     }
682
683 private:
684     std::string m_mcastGroup;
685     std::string m_networkInterface;
686 };
687
688
689 class UDPMulticastServerApp : public UDPMulticastServer
690 {
691 public:
692     UDPMulticastServerApp(uint16_t port, int protocol, const std::string &mcastGroup, const std::string &networkInterface,
693             const AppContext &appContext)
694     : UDPMulticastServer(port, protocol, mcastGroup, networkInterface)
695     , m_appContext(appContext)
696     {
697     }
698
699     virtual int serverProcedure(int pipeFd) override
700     {
701         Api::setProcessLabel(m_appContext.appId());
702         RUNNER_ASSERT_ERRNO_MSG(drop_root_privileges(m_appContext.getUID(), m_appContext.getGID()) == 0,
703                                 "drop_root_privileges() failed");
704
705         return UDPServer::serverProcedure(pipeFd);
706     }
707
708 private:
709     AppContext m_appContext;
710 };
711
712
713 class TCPServer : public NetServer
714 {
715 public:
716     explicit TCPServer(uint16_t port)
717     : NetServer{}
718     , m_port(port)
719     {}
720
721     virtual ~TCPServer() {}
722
723     virtual std::string getDescription() const override
724     {
725         return "TCPServer port: " + std::to_string(m_port);
726     }
727
728     virtual int serverProcedure(int pipeFd) override
729     {
730         FdUniquePtr pipePtr(&pipeFd);
731
732         int sockFd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
733         if (sockFd == -1) {
734             exit(EXIT_FAILURE);
735         }
736
737         SockUniquePtr sockPtr(&sockFd);
738
739         int optionValue = 1;
740         if (setsockopt(sockFd, SOL_SOCKET, SO_REUSEADDR, static_cast<const void *>(&optionValue) , sizeof(int)) == -1) {
741             exit(EXIT_FAILURE);
742         }
743
744         struct sockaddr_in serverAddress;
745         memset(&serverAddress, 0, sizeof(serverAddress));
746         serverAddress.sin_family = AF_INET;
747         serverAddress.sin_addr.s_addr = htonl(INADDR_ANY);
748         serverAddress.sin_port = htons(m_port);
749
750         if (bind(sockFd, reinterpret_cast<struct sockaddr *>(&serverAddress), sizeof(serverAddress)) == -1) {
751             exit(EXIT_FAILURE);
752         }
753
754         if (listen(sockFd, 1) == -1) {
755             exit(EXIT_FAILURE);
756         }
757
758         struct sockaddr_in clntAddress;
759         socklen_t clntAddressLength = static_cast<socklen_t>(sizeof(clntAddress));
760         char receiveBuffer[NET_BUFFER_SIZE];
761
762         notifyManager(pipeFd);
763
764         while (true) {
765             int acceptedSocketFd = TEMP_FAILURE_RETRY(accept(sockFd, reinterpret_cast<struct sockaddr *>(&clntAddress),
766                     &clntAddressLength));
767             if (acceptedSocketFd == -1) {
768                 exit(EXIT_FAILURE);
769             }
770
771             SockUniquePtr acceptSockPtr(&acceptedSocketFd);
772
773             while (true) {
774                 ssize_t len = TEMP_FAILURE_RETRY(recv(acceptedSocketFd, receiveBuffer, sizeof(receiveBuffer), 0));
775                 if (len == -1) {
776                     exit(EXIT_FAILURE);
777                 }
778
779                 if (len == 0) {
780                     break;
781                 }
782
783                 do {
784                     ssize_t pos = 0;
785                     ssize_t ret = TEMP_FAILURE_RETRY(write(pipeFd, &receiveBuffer[pos], len));
786                     if (ret == -1) {
787                         exit(EXIT_FAILURE);
788                     }
789
790                     len -= ret;
791                     pos += ret;
792                 } while (len != 0);
793             }
794         }
795
796         return EXIT_SUCCESS;
797     }
798
799 private:
800     uint16_t m_port;
801 };
802
803
804 class TCPServerApp : public TCPServer
805 {
806 public:
807     TCPServerApp(int port, const AppContext &appContext)
808     : TCPServer(port)
809     , m_appContext(appContext)
810     {
811     }
812
813     virtual int serverProcedure(int pipeFd) override
814     {
815         Api::setProcessLabel(m_appContext.appId());
816         RUNNER_ASSERT_ERRNO_MSG(drop_root_privileges(m_appContext.getUID(), m_appContext.getGID()) == 0,
817                                 "drop_root_privileges() failed");
818
819         return TCPServer::serverProcedure(pipeFd);
820     }
821
822 private:
823     AppContext m_appContext;
824 };
825
826
827 class NetClient
828 {
829 public:
830     NetClient(const std::string &appPrefix, NetherInternetAccess access, int msgCount)
831     : m_appPrefix(appPrefix)
832     , m_access(access)
833     , m_msgCount(msgCount)
834     {
835     }
836
837     NetClient(const NetClient &) = delete;
838     NetClient &operator=(const NetClient &) = delete;
839
840     void start()
841     {
842         runProcedureInNetAppContext(m_appPrefix, [this]() { clientProcedure(); } , m_access);
843     }
844
845     virtual void clientProcedure() = 0;
846
847 protected:
848     std::string m_appPrefix;
849     NetherInternetAccess m_access;
850     int m_msgCount;
851 };
852
853 class UDPClientApp : public NetClient
854 {
855 public:
856     UDPClientApp(const std::string &appPrefix, NetherInternetAccess access, int msgCount,
857             int protocol, const std::string &hostName, uint16_t port)
858     : NetClient(appPrefix, access, msgCount)
859     , m_protocol(protocol)
860     , m_hostName(hostName)
861     , m_port(port)
862     {
863     }
864
865     virtual bool applyExtraSocketOptions(int)
866     {
867         return true;
868     }
869
870 private:
871     virtual void clientProcedure() override
872     {
873         int sockFd = socket(AF_INET, SOCK_DGRAM, m_protocol);
874         RUNNER_ASSERT_ERRNO_MSG(sockFd >= 0, "socket() failed");
875         SockUniquePtr sockPtr(&sockFd);
876
877         struct hostent *server = gethostbyname(m_hostName.c_str());
878         RUNNER_ASSERT_MSG(server != nullptr, "Couldn't find host " << m_hostName
879                 << " h_errno = " << hstrerror(h_errno));
880
881         RUNNER_ASSERT_MSG (applyExtraSocketOptions(sockFd), "Couldn't prepare socket");
882
883         struct sockaddr_in serverAddress;
884         memset(&serverAddress, 0, sizeof(serverAddress));
885         serverAddress.sin_family = AF_INET;
886         memcpy(&serverAddress.sin_addr.s_addr, server->h_addr, server->h_length);
887         serverAddress.sin_port = htons(m_port);
888
889         char sendBuffer[NET_BUFFER_SIZE];
890
891         memset(sendBuffer, 'X', sizeof(sendBuffer));
892         size_t serverAddressLength = sizeof(serverAddress);
893
894         int msgCount = m_msgCount;
895         while (msgCount-- > 0) {
896             ssize_t len = sizeof(sendBuffer);
897             ssize_t pos = 0;
898             do {
899                 ssize_t ret = TEMP_FAILURE_RETRY(sendto(sockFd, &sendBuffer[pos], len, 0,
900                         reinterpret_cast<struct sockaddr *>(&serverAddress), serverAddressLength));
901                 RUNNER_ASSERT_ERRNO_MSG(ret >= 0, "sendto() failed");
902                 len -= ret;
903                 pos += ret;
904             } while (len != 0);
905         }
906     }
907
908     int m_protocol;
909     std::string m_hostName;
910     uint16_t m_port;
911 };
912
913 class UDPMulticastClientApp : public UDPClientApp
914 {
915 public:
916     UDPMulticastClientApp(const std::string &appPrefix, NetherInternetAccess access, int msgCount,
917             int protocol, const std::string &hostName, uint16_t port, char ttl, bool enableLoop)
918     : UDPClientApp(appPrefix, access, msgCount, protocol, hostName, port)
919     , m_ttl(ttl)
920     , m_enableLoop(enableLoop)
921     {
922     }
923
924     virtual bool applyExtraSocketOptions(int sockFd) override
925     {
926         if (setsockopt(sockFd, IPPROTO_IP, IP_MULTICAST_TTL, static_cast<void *>(&m_ttl), sizeof(m_ttl)) == -1) {
927             return false;
928         }
929
930         char multicastEnableLoop = m_enableLoop ? 1 : 0;
931         return setsockopt(sockFd, IPPROTO_IP, IP_MULTICAST_LOOP, static_cast<void *>(&multicastEnableLoop),
932                 sizeof(multicastEnableLoop)) == 0;
933     }
934
935 private:
936     char m_ttl;
937     bool m_enableLoop;
938 };
939
940 class TCPClientApp : public NetClient
941 {
942 public:
943     TCPClientApp(const std::string &appPrefix, NetherInternetAccess access, int msgCount,
944             const std::string &hostName, int port, bool expectConnectionError)
945     : NetClient(appPrefix, access, msgCount)
946     , m_hostName(hostName)
947     , m_port(port)
948     , m_expectConnectionError(expectConnectionError)
949     {
950     }
951
952 private:
953     virtual void clientProcedure() override
954     {
955         int sockFd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
956         RUNNER_ASSERT_ERRNO_MSG(sockFd >= 0, "socket() failed");
957         SockUniquePtr sockPtr(&sockFd);
958
959         struct hostent *server = gethostbyname(m_hostName.c_str());
960         RUNNER_ASSERT_MSG(server != nullptr, "Couldn't find host " << m_hostName
961                 << " h_errno = " << hstrerror(h_errno));
962
963         struct sockaddr_in serverAddress;
964         memset(&serverAddress, 0, sizeof(serverAddress));
965         serverAddress.sin_family = AF_INET;
966         memcpy(&serverAddress.sin_addr.s_addr, server->h_addr, server->h_length);
967         serverAddress.sin_port = htons(m_port);
968         size_t serverAddressLength = sizeof(serverAddress);
969
970         int ret = TEMP_FAILURE_RETRY(connect(sockFd,
971                 reinterpret_cast<struct sockaddr *>(&serverAddress),serverAddressLength));
972         if (ret == -1 && m_expectConnectionError) {
973             return;
974         }
975
976         RUNNER_ASSERT_ERRNO_MSG(ret == 0, "Couldn't connect to " << m_hostName);
977
978         char sendBuffer[NET_BUFFER_SIZE];
979         memset(sendBuffer, 'X', sizeof(sendBuffer));
980
981         int msgCount = m_msgCount;
982         while (msgCount-- > 0) {
983             ssize_t len = sizeof(sendBuffer);
984             ssize_t pos = 0;
985             do {
986                 ssize_t ret = TEMP_FAILURE_RETRY(send(sockFd, &sendBuffer[pos], len, 0));
987                 RUNNER_ASSERT_ERRNO_MSG(ret >= 0, "send() failed");
988                 len -= ret;
989                 pos += ret;
990             } while (len != 0);
991         }
992     }
993
994     std::string m_hostName;
995     uint16_t m_port;
996     bool m_expectConnectionError;
997 };
998
999
1000 RUNNER_TEST_GROUP_INIT(NETHER_REMOTE_CONNECTION)
1001
1002
1003 RUNNER_CHILD_TEST(nether_check_udp_connection_internet_access_granted)
1004 {
1005     RUNNER_IGNORED_MSG("Disabled until the implementation of handling of UDP traffic is finished.");
1006     ScopedShellScriptRunner networkNSRunner(NETHER_NETNS_SETUP_COMMAND,
1007                                             NETHER_NETNS_TEARDOWN_COMMAND);
1008
1009     UDPServer udpServer(UDP_TEST_PORT);
1010     udpServer.start(NETHER_NETNS_NAME_TEST);
1011
1012     UDPClientApp udpClientApp("nether_test_uciag", NetherInternetAccess::ACCESS_GRANTED, UDP_MESSAGES_COUNT,
1013         IPPROTO_UDP, REMOTE_INTERFACE_ADDRESS, UDP_TEST_PORT);
1014     udpClientApp.start();
1015
1016     RUNNER_ASSERT_MSG(udpServer.isAlive(), "UDP server was not running");
1017     udpServer.stop();
1018     RUNNER_ASSERT_MSG(udpServer.getReceivedBytes() > 0, "UDP server didn't receive any data");
1019 }
1020
1021
1022 RUNNER_CHILD_TEST(nether_check_udp_connection_internet_access_denied)
1023 {
1024     RUNNER_IGNORED_MSG("Disabled until the implementation of handling of UDP traffic is finished.");
1025     ScopedShellScriptRunner networkNSRunner(NETHER_NETNS_SETUP_COMMAND,
1026                                             NETHER_NETNS_TEARDOWN_COMMAND);
1027
1028     UDPServer udpServer(UDP_TEST_PORT);
1029     udpServer.start(NETHER_NETNS_NAME_TEST);
1030
1031     UDPClientApp udpClientApp("nether_test_uciad", NetherInternetAccess::ACCESS_DENIED, UDP_MESSAGES_COUNT,
1032         IPPROTO_UDP, REMOTE_INTERFACE_ADDRESS, UDP_TEST_PORT);
1033     udpClientApp.start();
1034
1035     RUNNER_ASSERT_MSG(udpServer.isAlive(), "UDP server was not running");
1036     udpServer.stop();
1037     RUNNER_ASSERT_MSG(udpServer.getReceivedBytes() == 0, "UDP server received some data");
1038 }
1039
1040
1041 RUNNER_CHILD_TEST(nether_check_udp_lite_connection_internet_access_granted)
1042 {
1043     RUNNER_IGNORED_MSG("Disabled until the implementation of handling of UDP traffic is finished.");
1044     ScopedShellScriptRunner networkNSRunner(NETHER_NETNS_SETUP_COMMAND,
1045                                             NETHER_NETNS_TEARDOWN_COMMAND);
1046
1047     UDPServer udpLiteServer(UDP_TEST_PORT, IPPROTO_UDPLITE);
1048     udpLiteServer.start(NETHER_NETNS_NAME_TEST);
1049
1050     UDPClientApp udpClientApp("nether_test_ulciag", NetherInternetAccess::ACCESS_GRANTED, UDP_MESSAGES_COUNT,
1051         IPPROTO_UDPLITE, REMOTE_INTERFACE_ADDRESS, UDP_TEST_PORT);
1052     udpClientApp.start();
1053
1054     RUNNER_ASSERT_MSG(udpLiteServer.isAlive(), "UDPLite server was not running");
1055     udpLiteServer.stop();
1056     RUNNER_ASSERT_MSG(udpLiteServer.getReceivedBytes() > 0, "UDPLite server didn't receive any data");
1057 }
1058
1059
1060 RUNNER_CHILD_TEST(nether_check_udp_lite_connection_internet_access_denied)
1061 {
1062     RUNNER_IGNORED_MSG("Disabled until the implementation of handling of UDP traffic is finished.");
1063     ScopedShellScriptRunner networkNSRunner(NETHER_NETNS_SETUP_COMMAND,
1064                                             NETHER_NETNS_TEARDOWN_COMMAND);
1065
1066     UDPServer udpLiteServer(UDP_TEST_PORT, IPPROTO_UDPLITE);
1067     udpLiteServer.start(NETHER_NETNS_NAME_TEST);
1068
1069     UDPClientApp udpClientApp("nether_test_ulciad", NetherInternetAccess::ACCESS_DENIED, UDP_MESSAGES_COUNT,
1070         IPPROTO_UDPLITE, REMOTE_INTERFACE_ADDRESS, UDP_TEST_PORT);
1071     udpClientApp.start();
1072
1073     RUNNER_ASSERT_MSG(udpLiteServer.isAlive(), "UDP server was not running");
1074     udpLiteServer.stop();
1075     RUNNER_ASSERT_MSG(udpLiteServer.getReceivedBytes() == 0, "UDP server received some data");
1076 }
1077
1078
1079 RUNNER_CHILD_TEST(nether_check_tcp_connection_internet_access_granted)
1080 {
1081     ScopedShellScriptRunner networkNSRunner(NETHER_NETNS_SETUP_COMMAND,
1082                                             NETHER_NETNS_TEARDOWN_COMMAND);
1083
1084     TCPServer tcpServer(TCP_TEST_PORT);
1085     tcpServer.start(NETHER_NETNS_NAME_TEST);
1086
1087     TCPClientApp tcpClientApp("nether_test_tciag", NetherInternetAccess::ACCESS_GRANTED, TCP_MESSAGES_COUNT,
1088         REMOTE_INTERFACE_ADDRESS, TCP_TEST_PORT, false);
1089     tcpClientApp.start();
1090
1091     RUNNER_ASSERT_MSG(tcpServer.isAlive(), "TCP server was not running");
1092     tcpServer.stop();
1093     RUNNER_ASSERT_MSG(tcpServer.getReceivedBytes() > 0, "TCP server didn't receive any data");
1094 }
1095
1096
1097 RUNNER_CHILD_TEST(nether_check_tcp_connection_internet_access_denied)
1098 {
1099     ScopedShellScriptRunner networkNSRunner(NETHER_NETNS_SETUP_COMMAND,
1100                                             NETHER_NETNS_TEARDOWN_COMMAND);
1101
1102     TCPServer tcpServer(TCP_TEST_PORT);
1103     tcpServer.start(NETHER_NETNS_NAME_TEST);
1104
1105     TCPClientApp tcpClientApp("nether_test_tciad", NetherInternetAccess::ACCESS_DENIED, TCP_MESSAGES_COUNT,
1106         REMOTE_INTERFACE_ADDRESS, TCP_TEST_PORT, true);
1107     tcpClientApp.start();
1108
1109     RUNNER_ASSERT_MSG(tcpServer.isAlive(), "TCP server was not running");
1110     tcpServer.stop();
1111     RUNNER_ASSERT_MSG(tcpServer.getReceivedBytes() == 0, "TCP server received some data");
1112 }
1113
1114 // Communication between application and local service
1115 RUNNER_TEST_GROUP_INIT(NETHER_LOCAL_SERVICE_CONNECTION)
1116
1117
1118 RUNNER_CHILD_TEST(nether_check_udp_local_connection_internet_access_granted)
1119 {
1120     RUNNER_IGNORED_MSG("Disabled until the implementation of handling of UDP traffic is finished.");
1121     UDPServer udpLiteServer(UDP_TEST_PORT, IPPROTO_UDP);
1122     udpLiteServer.start();
1123
1124     UDPClientApp udpClientApp("nether_test_ulciag", NetherInternetAccess::ACCESS_GRANTED, UDP_MESSAGES_COUNT,
1125         IPPROTO_UDP, LOCAL_HOST_TEST_SERVER_ADDRESS, UDP_TEST_PORT);
1126     udpClientApp.start();
1127
1128     RUNNER_ASSERT_MSG(udpLiteServer.isAlive(), "UDP server was not running");
1129     udpLiteServer.stop();
1130     RUNNER_ASSERT_MSG(udpLiteServer.getReceivedBytes() > 0, "UDP server didn't receive any data");
1131 }
1132
1133
1134 RUNNER_CHILD_TEST(nether_check_udp_local_connection_internet_access_denied)
1135 {
1136     RUNNER_IGNORED_MSG("Disabled until the implementation of handling of UDP traffic is finished.");
1137     UDPServer udpLiteServer(UDP_TEST_PORT, IPPROTO_UDP);
1138     udpLiteServer.start();
1139
1140     UDPClientApp udpClientApp("nether_test_ulciad", NetherInternetAccess::ACCESS_DENIED, UDP_MESSAGES_COUNT,
1141         IPPROTO_UDP, LOCAL_HOST_TEST_SERVER_ADDRESS, UDP_TEST_PORT);
1142     udpClientApp.start();
1143
1144     RUNNER_ASSERT_MSG(udpLiteServer.isAlive(), "UDP server was not running");
1145     udpLiteServer.stop();
1146     RUNNER_ASSERT_MSG(udpLiteServer.getReceivedBytes() > 0, "UDP server didn't receive any data");
1147 }
1148
1149
1150 RUNNER_CHILD_TEST(nether_check_udp_lite_local_connection_internet_access_granted)
1151 {
1152     RUNNER_IGNORED_MSG("Disabled until the implementation of handling of UDP traffic is finished.");
1153     UDPServer udpLiteServer(UDP_TEST_PORT, IPPROTO_UDPLITE);
1154     udpLiteServer.start();
1155
1156     UDPClientApp udpClientApp("nether_test_ullciag", NetherInternetAccess::ACCESS_GRANTED, UDP_MESSAGES_COUNT,
1157         IPPROTO_UDPLITE, LOCAL_HOST_TEST_SERVER_ADDRESS, UDP_TEST_PORT);
1158     udpClientApp.start();
1159
1160     RUNNER_ASSERT_MSG(udpLiteServer.isAlive(), "UDP server was not running");
1161     udpLiteServer.stop();
1162     RUNNER_ASSERT_MSG(udpLiteServer.getReceivedBytes() > 0, "UDP server didn't receive any data");
1163 }
1164
1165
1166 RUNNER_CHILD_TEST(nether_check_udp_lite_local_connection_internet_access_denied)
1167 {
1168     RUNNER_IGNORED_MSG("Disabled until the implementation of handling of UDP traffic is finished.");
1169     UDPServer udpLiteServer(UDP_TEST_PORT, IPPROTO_UDPLITE);
1170     udpLiteServer.start();
1171
1172     UDPClientApp udpClientApp("nether_test_ullciad", NetherInternetAccess::ACCESS_DENIED, UDP_MESSAGES_COUNT,
1173         IPPROTO_UDPLITE, LOCAL_HOST_TEST_SERVER_ADDRESS, UDP_TEST_PORT);
1174     udpClientApp.start();
1175
1176     RUNNER_ASSERT_MSG(udpLiteServer.isAlive(), "UDP server was not running");
1177     udpLiteServer.stop();
1178     RUNNER_ASSERT_MSG(udpLiteServer.getReceivedBytes() > 0, "UDP server didn't receive any data");
1179 }
1180
1181
1182 RUNNER_CHILD_TEST(nether_check_tcp_local_connection_internet_access_granted)
1183 {
1184     TCPServer tcpServer(TCP_TEST_PORT);
1185     tcpServer.start();
1186
1187     TCPClientApp tcpClientApp("nether_test_tlciad", NetherInternetAccess::ACCESS_GRANTED, TCP_MESSAGES_COUNT,
1188         LOCAL_HOST_TEST_SERVER_ADDRESS, TCP_TEST_PORT, false);
1189     tcpClientApp.start();
1190
1191     RUNNER_ASSERT_MSG(tcpServer.isAlive(), "TCP server was not running");
1192     tcpServer.stop();
1193     RUNNER_ASSERT_MSG(tcpServer.getReceivedBytes() > 0, "TCP server didn't receive any data");
1194 }
1195
1196
1197 RUNNER_CHILD_TEST(nether_check_tcp_local_connection_internet_access_denied)
1198 {
1199     TCPServer tcpServer(TCP_TEST_PORT);
1200     tcpServer.start();
1201
1202     TCPClientApp tcpClientApp("nether_test_tlciad", NetherInternetAccess::ACCESS_DENIED, TCP_MESSAGES_COUNT,
1203         LOCAL_HOST_TEST_SERVER_ADDRESS, TCP_TEST_PORT, false);
1204     tcpClientApp.start();
1205
1206     RUNNER_ASSERT_MSG(tcpServer.isAlive(), "TCP server was not running");
1207     tcpServer.stop();
1208     RUNNER_ASSERT_MSG(tcpServer.getReceivedBytes() > 0, "TCP server didn't receive any data");
1209 }
1210
1211
1212 // Applications mustn't communicate with each other even if access to the Internet is granted.
1213 RUNNER_TEST_GROUP_INIT(NETHER_LOCAL_INTER_APP_CONNECTION)
1214
1215
1216 RUNNER_CHILD_TEST(nether_check_udp_local_inter_app_connection_internet_access_granted)
1217 {
1218     RUNNER_IGNORED_MSG("Disabled until the implementation of handling of UDP traffic is finished.");
1219     ScopedAppContext appContext("nether_test_uliaciag_a", NetherInternetAccess::ACCESS_GRANTED);
1220     UDPServerApp udpServerApp(UDP_TEST_PORT, IPPROTO_UDP, appContext);
1221     udpServerApp.start();
1222
1223     UDPClientApp udpClientApp("nether_test_uliaciag_b", NetherInternetAccess::ACCESS_GRANTED, UDP_MESSAGES_COUNT,
1224         IPPROTO_UDP, LOCAL_HOST_TEST_SERVER_ADDRESS, UDP_TEST_PORT);
1225     udpClientApp.start();
1226
1227     RUNNER_ASSERT_MSG(udpServerApp.isAlive(), "UDP server was not running");
1228     udpServerApp.stop();
1229     RUNNER_ASSERT_MSG(udpServerApp.getReceivedBytes() == 0, "UDP server received some data");
1230 }
1231
1232
1233 RUNNER_CHILD_TEST(nether_check_udp_local_inter_app_connection_internet_access_denied)
1234 {
1235     RUNNER_IGNORED_MSG("Disabled until the implementation of handling of UDP traffic is finished.");
1236     ScopedAppContext appContext("nether_test_uliaciad_a", NetherInternetAccess::ACCESS_DENIED);
1237     UDPServerApp udpServerApp(UDP_TEST_PORT, IPPROTO_UDP, appContext);
1238     udpServerApp.start();
1239
1240     UDPClientApp udpClientApp("nether_test_uliaciad_b", NetherInternetAccess::ACCESS_DENIED, UDP_MESSAGES_COUNT,
1241         IPPROTO_UDP, LOCAL_HOST_TEST_SERVER_ADDRESS, UDP_TEST_PORT);
1242     udpClientApp.start();
1243
1244     RUNNER_ASSERT_MSG(udpServerApp.isAlive(), "UDP server was not running");
1245     udpServerApp.stop();
1246     RUNNER_ASSERT_MSG(udpServerApp.getReceivedBytes() == 0, "UDP server received some data");
1247 }
1248
1249
1250 RUNNER_CHILD_TEST(nether_check_udp_lite_local_inter_app_connection_internet_access_granted)
1251 {
1252     RUNNER_IGNORED_MSG("Disabled until the implementation of handling of UDP traffic is finished.");
1253     ScopedAppContext appContext("nether_test_ulliaciag_a", NetherInternetAccess::ACCESS_GRANTED);
1254     UDPServerApp udpLiteServerApp(UDP_TEST_PORT, IPPROTO_UDPLITE, appContext);
1255     udpLiteServerApp.start();
1256
1257     UDPClientApp udpClientApp("nether_ulliaciag_b", NetherInternetAccess::ACCESS_GRANTED, UDP_MESSAGES_COUNT,
1258         IPPROTO_UDPLITE, LOCAL_HOST_TEST_SERVER_ADDRESS, UDP_TEST_PORT);
1259     udpClientApp.start();
1260
1261     RUNNER_ASSERT_MSG(udpLiteServerApp.isAlive(), "UDP server was not running");
1262     udpLiteServerApp.stop();
1263     RUNNER_ASSERT_MSG(udpLiteServerApp.getReceivedBytes() == 0, "UDP server received some data");
1264 }
1265
1266
1267 RUNNER_CHILD_TEST(nether_check_udp_lite_local_inter_app_connection_internet_access_denied)
1268 {
1269     RUNNER_IGNORED_MSG("Disabled until the implementation of handling of UDP traffic is finished.");
1270     ScopedAppContext appContext("nether_test_ulliaciad_a", NetherInternetAccess::ACCESS_DENIED);
1271     UDPServerApp udpLiteServerApp(UDP_TEST_PORT, IPPROTO_UDPLITE, appContext);
1272     udpLiteServerApp.start();
1273
1274     UDPClientApp udpClientApp("nether_ulliaciad_b", NetherInternetAccess::ACCESS_DENIED, UDP_MESSAGES_COUNT,
1275         IPPROTO_UDPLITE, LOCAL_HOST_TEST_SERVER_ADDRESS, UDP_TEST_PORT);
1276     udpClientApp.start();
1277
1278     RUNNER_ASSERT_MSG(udpLiteServerApp.isAlive(), "UDP server was not running");
1279     udpLiteServerApp.stop();
1280     RUNNER_ASSERT_MSG(udpLiteServerApp.getReceivedBytes() == 0, "UDP server received some data");
1281 }
1282
1283
1284 RUNNER_CHILD_TEST(nether_check_tcp_local_inter_app_connection_internet_access_granted)
1285 {
1286     ScopedAppContext appContext("nether_test_tliaciag_a", NetherInternetAccess::ACCESS_GRANTED);
1287     TCPServerApp tcpServerApp(TCP_TEST_PORT, appContext);
1288     tcpServerApp.start();
1289
1290     TCPClientApp tcpClientApp("nether_test_tliaciag_b", NetherInternetAccess::ACCESS_GRANTED, TCP_MESSAGES_COUNT,
1291         LOCAL_HOST_TEST_SERVER_ADDRESS, TCP_TEST_PORT, true);
1292     tcpClientApp.start();
1293
1294     RUNNER_ASSERT_MSG(tcpServerApp.isAlive(), "TCP server was not running");
1295     tcpServerApp.stop();
1296     RUNNER_ASSERT_MSG(tcpServerApp.getReceivedBytes() == 0, "TCP server received some data");
1297 }
1298
1299
1300 RUNNER_CHILD_TEST(nether_check_tcp_local_inter_app_connection_internet_access_denied)
1301 {
1302     ScopedAppContext appContext("nether_test_tliaciad_a", NetherInternetAccess::ACCESS_DENIED);
1303     TCPServerApp tcpServerApp(TCP_TEST_PORT, appContext);
1304     tcpServerApp.start();
1305
1306     TCPClientApp tcpClientApp("nether_test_tliaciad_b", NetherInternetAccess::ACCESS_DENIED, TCP_MESSAGES_COUNT,
1307         LOCAL_HOST_TEST_SERVER_ADDRESS, TCP_TEST_PORT, true);
1308     tcpClientApp.start();
1309
1310     RUNNER_ASSERT_MSG(tcpServerApp.isAlive(), "TCP server was not running");
1311     tcpServerApp.stop();
1312     RUNNER_ASSERT_MSG(tcpServerApp.getReceivedBytes() == 0, "TCP server received some data");
1313 }
1314
1315
1316 RUNNER_TEST_GROUP_INIT(NETHER_MULTICAST)
1317
1318
1319 RUNNER_CHILD_TEST(nether_check_multicast_inter_app_connection_access_granted)
1320 {
1321     // one app acts as a server (receiver), the second as a sender
1322     RUNNER_IGNORED_MSG("Disabled until the implementation of handling of UDP traffic is finished.");
1323     ScopedAppContext appContext("nether_test_miacag_a", NetherInternetAccess::ACCESS_GRANTED);
1324     UDPMulticastServerApp udpMulticastServerApp(UDP_TEST_PORT, IPPROTO_UDP, LOCAL_TEST_MCAST_GROUP,
1325         ANY_INTERFACE, appContext);
1326     udpMulticastServerApp.start();
1327
1328     UDPMulticastClientApp udpMulticastClientApp("nether_test_miacag_b", NetherInternetAccess::ACCESS_GRANTED,
1329         UDP_MESSAGES_COUNT, IPPROTO_UDP, LOCAL_TEST_MCAST_GROUP, UDP_TEST_PORT, TTL_MCAST_RESTRIC_SUBNET, true);
1330     udpMulticastClientApp.start();
1331
1332     RUNNER_ASSERT_MSG(udpMulticastServerApp.isAlive(), "UDP multicast server was not running");
1333     udpMulticastServerApp.stop();
1334     RUNNER_ASSERT_MSG(udpMulticastServerApp.getReceivedBytes() > 0, "UDP multicast server didn't receive any data");
1335 }
1336
1337
1338 RUNNER_CHILD_TEST(nether_check_multicast_inter_app_connection_access_denied)
1339 {
1340     RUNNER_IGNORED_MSG("Disabled until the implementation of handling of UDP traffic is finished.");
1341     ScopedAppContext appContext("nether_test_miacad_a", NetherInternetAccess::ACCESS_DENIED);
1342     UDPMulticastServerApp udpMulticastServerApp(UDP_TEST_PORT, IPPROTO_UDP, LOCAL_TEST_MCAST_GROUP,
1343         ANY_INTERFACE, appContext);
1344     udpMulticastServerApp.start();
1345
1346     UDPMulticastClientApp udpMulticastClientApp("nether_test_miacad_b", NetherInternetAccess::ACCESS_DENIED,
1347         UDP_MESSAGES_COUNT, IPPROTO_UDP, LOCAL_TEST_MCAST_GROUP, UDP_TEST_PORT, TTL_MCAST_RESTRIC_SUBNET, true);
1348     udpMulticastClientApp.start();
1349
1350     RUNNER_ASSERT_MSG(udpMulticastServerApp.isAlive(), "UDP multicast server was not running");
1351     udpMulticastServerApp.stop();
1352     RUNNER_ASSERT_MSG(udpMulticastServerApp.getReceivedBytes() == 0, "UDP multicast server received some data");
1353 }
1354
1355
1356 RUNNER_CHILD_TEST(nether_check_multicast_remote_connection_app_sender_access_granted)
1357 {
1358     RUNNER_IGNORED_MSG("Disabled until the implementation of handling of UDP traffic is finished.");
1359     ScopedShellScriptRunner networkNSRunner(NETHER_NETNS_SETUP_COMMAND,
1360                                             NETHER_NETNS_TEARDOWN_COMMAND);
1361
1362     UDPMulticastServer udpMulticastServer(UDP_TEST_PORT, IPPROTO_UDP, LOCAL_TEST_MCAST_GROUP, REMOTE_INTERFACE_NAME);
1363     udpMulticastServer.start(NETHER_NETNS_NAME_TEST);
1364
1365     UDPMulticastClientApp udpMulticastClientApp("nether_test_mrcasag", NetherInternetAccess::ACCESS_GRANTED,
1366         UDP_MESSAGES_COUNT, IPPROTO_UDP, LOCAL_TEST_MCAST_GROUP, UDP_TEST_PORT, TTL_MCAST_RESTRIC_SUBNET, false);
1367     udpMulticastClientApp.start();
1368
1369     RUNNER_ASSERT_MSG(udpMulticastServer.isAlive(), "UDP multicast server was not running");
1370     udpMulticastServer.stop();
1371     RUNNER_ASSERT_MSG(udpMulticastServer.getReceivedBytes() > 0, "UDP multicast server didn't receive any data");
1372 }
1373
1374
1375 RUNNER_CHILD_TEST(nether_check_multicast_remote_connection_app_sender_access_denied)
1376 {
1377     RUNNER_IGNORED_MSG("Disabled until the implementation of handling of UDP traffic is finished.");
1378     ScopedShellScriptRunner networkNSRunner(NETHER_NETNS_SETUP_COMMAND,
1379                                             NETHER_NETNS_TEARDOWN_COMMAND);
1380
1381     UDPMulticastServer udpMulticastServer(UDP_TEST_PORT, IPPROTO_UDP, LOCAL_TEST_MCAST_GROUP, REMOTE_INTERFACE_NAME);
1382     udpMulticastServer.start(NETHER_NETNS_NAME_TEST);
1383
1384     UDPMulticastClientApp udpMulticastClientApp("nether_test_mrcasad", NetherInternetAccess::ACCESS_DENIED,
1385         UDP_MESSAGES_COUNT, IPPROTO_UDP, LOCAL_TEST_MCAST_GROUP, UDP_TEST_PORT, TTL_MCAST_RESTRIC_SUBNET, false);
1386     udpMulticastClientApp.start();
1387
1388     RUNNER_ASSERT_MSG(udpMulticastServer.isAlive(), "UDP multicast server was not running");
1389     udpMulticastServer.stop();
1390     RUNNER_ASSERT_MSG(udpMulticastServer.getReceivedBytes() == 0, "UDP multicast server received some data");
1391 }
1392
1393
1394 RUNNER_TEST_GROUP_INIT(NETHER_LOCAL_DNS_CONNECTION)
1395
1396
1397 RUNNER_CHILD_TEST(nether_check_gethostbyname_internet_access_granted)
1398 {
1399     RUNNER_IGNORED_MSG("Disabled until the implementation of handling of DNS queries is finished.");
1400
1401     ScopedShellScriptRunner networkDNSRunner(NETHER_DNS_SETUP_COMMAND,
1402                                              NETHER_DNS_TEARDOWN_COMMAND);
1403
1404     const auto getHostAddress = [](void) {
1405       struct hostent *server = gethostbyname(DNS_TEST_ADDRESS.c_str());
1406       RUNNER_ASSERT_MSG(server != nullptr, "Couldn't find host "
1407               << DNS_TEST_ADDRESS << " h_errno = " << h_errno);
1408     };
1409     runProcedureInNetAppContext("nether_test_giag", getHostAddress, NetherInternetAccess::ACCESS_GRANTED);
1410 }
1411
1412
1413 RUNNER_CHILD_TEST(nether_check_gethostbyname_internet_access_denied)
1414 {
1415     RUNNER_IGNORED_MSG("Disabled until the implementation of handling of DNS queries is finished.");
1416
1417     ScopedShellScriptRunner networkDNSRunner(NETHER_DNS_SETUP_COMMAND,
1418                                              NETHER_DNS_TEARDOWN_COMMAND);
1419
1420     const auto getHostAddress = [](void) {
1421       struct hostent *server = gethostbyname(DNS_TEST_ADDRESS.c_str());
1422       RUNNER_ASSERT_MSG(server == nullptr, "Host was found " << DNS_TEST_ADDRESS);
1423     };
1424
1425     runProcedureInNetAppContext("nether_test_giad", getHostAddress, NetherInternetAccess::ACCESS_DENIED);
1426 }
1427
1428
1429 void checkRawSocket(void)
1430 {
1431     const std::vector<int> protocols {
1432         IPPROTO_ICMP,
1433         IPPROTO_IGMP
1434     };
1435
1436     for (const auto protocol : protocols) {
1437         int sockFd = socket(AF_INET, SOCK_RAW, protocol);
1438         RUNNER_ASSERT_ERRNO_MSG(sockFd == -1, "RAW socket was successfully created for protocol " << protocol);
1439     }
1440 };
1441
1442
1443 RUNNER_TEST_GROUP_INIT(NETHER_RAW_SOCKET)
1444
1445
1446 RUNNER_CHILD_TEST(nether_check_raw_socket_access_granted)
1447 {
1448     runProcedureInNetAppContext("nether_test_rsag", checkRawSocket, NetherInternetAccess::ACCESS_GRANTED);
1449 }
1450
1451
1452 RUNNER_CHILD_TEST(nether_check_raw_socket_access_denied)
1453 {
1454     runProcedureInNetAppContext("nether_test_rsad", checkRawSocket, NetherInternetAccess::ACCESS_DENIED);
1455 }
1456
1457
1458 int main(int argc, char *argv[])
1459 {
1460     return DPL::Test::TestRunnerSingleton::Instance().ExecTestRunner(argc, argv);
1461 }