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