1 /* Copyright (C) 2020-2021 Greenbone Networks GmbH
2  *
3  * SPDX-License-Identifier: GPL-2.0-or-later
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 
20 #include "util.c"
21 
22 #include <arpa/inet.h>
23 #include <cgreen/cgreen.h>
24 #include <cgreen/mocks.h>
25 
26 Describe (util);
BeforeEach(util)27 BeforeEach (util)
28 {
29 }
AfterEach(util)30 AfterEach (util)
31 {
32 }
33 
34 __attribute__ ((weak)) int
35 __real_socket (__attribute__ ((unused)) int domain,
36                __attribute__ ((unused)) int type,
37                __attribute__ ((unused)) int protocol);
38 
39 __attribute__ ((weak)) int
40 __real_setsockopt (__attribute__ ((unused)) int sockfd,
41                    __attribute__ ((unused)) int level,
42                    __attribute__ ((unused)) int optname,
43                    __attribute__ ((unused)) const void *optval,
44                    __attribute__ ((unused)) socklen_t optlen);
45 
46 bool g_socket_use_real = true;
47 int
__wrap_socket(int domain,int type,int protocol)48 __wrap_socket (__attribute__ ((unused)) int domain,
49                __attribute__ ((unused)) int type,
50                __attribute__ ((unused)) int protocol)
51 {
52   if (g_socket_use_real)
53     return __real_socket (domain, type, protocol);
54 
55   return (int) mock (domain, type, protocol);
56 }
57 
58 bool g_setsockopt_use_real = true;
59 int
__wrap_setsockopt(int sockfd,int level,int optname,const void * optval,socklen_t optlen)60 __wrap_setsockopt (__attribute__ ((unused)) int sockfd,
61                    __attribute__ ((unused)) int level,
62                    __attribute__ ((unused)) int optname,
63                    __attribute__ ((unused)) const void *optval,
64                    __attribute__ ((unused)) socklen_t optlen)
65 {
66   if (g_setsockopt_use_real)
67     return __real_setsockopt (sockfd, level, optname, optval, optlen);
68 
69   return (int) mock (sockfd, level, optname, optval, optlen);
70 }
71 
Ensure(util,set_all_needed_sockets)72 Ensure (util, set_all_needed_sockets)
73 {
74   g_socket_use_real = false;
75   g_setsockopt_use_real = false;
76 
77   alive_test_t alive_test;
78   struct scanner scanner = {0};
79 
80   /* All methods set. */
81   alive_test = ALIVE_TEST_TCP_ACK_SERVICE | ALIVE_TEST_ICMP | ALIVE_TEST_ARP
82                | ALIVE_TEST_CONSIDER_ALIVE | ALIVE_TEST_TCP_SYN_SERVICE;
83   expect (__wrap_socket, will_return (5), times (8));
84   expect (__wrap_setsockopt, will_return (5), times (10));
85   set_all_needed_sockets (&scanner, alive_test);
86 
87   /* Only one method set. */
88   alive_test = ALIVE_TEST_TCP_ACK_SERVICE;
89   expect (__wrap_socket, will_return (5), times (4));
90   expect (__wrap_setsockopt, will_return (5), times (6));
91   set_all_needed_sockets (&scanner, alive_test);
92 
93   /* ALIVE_TEST_CONSIDER_ALIVE set. */
94   alive_test = ALIVE_TEST_CONSIDER_ALIVE;
95   never_expect (__wrap_socket);
96   never_expect (__wrap_setsockopt);
97   never_expect (set_socket);
98   set_all_needed_sockets (&scanner, alive_test);
99 
100   g_socket_use_real = true;
101   g_setsockopt_use_real = true;
102 }
103 
Ensure(util,set_socket)104 Ensure (util, set_socket)
105 {
106   g_setsockopt_use_real = false;
107   g_socket_use_real = false;
108   int socket_location;
109 
110   /* socket() successful. */
111   expect (__wrap_socket, will_return (5));
112   expect (__wrap_setsockopt);
113   expect (__wrap_setsockopt);
114   assert_that (set_socket (TCPV4, &socket_location), is_equal_to (0));
115 
116   /* socket() error. */
117   expect (__wrap_socket, will_return (-5));
118   never_expect (__wrap_setsockopt);
119   assert_that (set_socket (TCPV4, &socket_location),
120                is_equal_to (BOREAS_OPENING_SOCKET_FAILED));
121   g_socket_use_real = true;
122   g_setsockopt_use_real = true;
123 }
124 
Ensure(util,get_source_addr_v4)125 Ensure (util, get_source_addr_v4)
126 {
127   int udpv4soc;
128   struct in_addr dst;
129   struct in_addr src;
130 
131   /* Open socket. */
132   set_socket (UDPV4, &udpv4soc);
133 
134   /* Destination is localhost. */
135   src.s_addr = INADDR_ANY;
136   dst.s_addr = inet_addr ("127.0.0.1");
137   get_source_addr_v4 (&udpv4soc, &dst, &src);
138   assert_that (src.s_addr, is_not_equal_to (INADDR_ANY));
139 
140   /* Destination is example.com. */
141   src.s_addr = INADDR_ANY;
142   dst.s_addr = inet_addr ("93.184.216.34");
143   get_source_addr_v4 (&udpv4soc, &dst, &src);
144   assert_that (src.s_addr, is_not_equal_to (INADDR_ANY));
145 
146   /* Close socket. */
147   close (udpv4soc);
148 }
149 
Ensure(util,get_source_addr_v6)150 Ensure (util, get_source_addr_v6)
151 {
152   int udpv6soc;
153   struct in6_addr dst;
154   struct in6_addr src;
155   boreas_error_t error;
156 
157   /* Open socket. */
158   set_socket (UDPV6, &udpv6soc);
159 
160   /* Localhost. */
161   inet_pton (AF_INET6, "::FFFF:127.0.0.1", &(dst));
162   error = get_source_addr_v6 (&udpv6soc, &dst, &src);
163   assert_that (error, is_equal_to (NO_ERROR));
164   assert_that (!IN6_IS_ADDR_UNSPECIFIED (&src));
165 
166   /* Dependent on local IPv6 configuration. */
167   // inet_pton (AF_INET6, "2001:0db8:0:f101::2", &(dst));
168   // error = get_source_addr_v6 (&udpv6soc, &dst, &src);
169   // assert_that (error, is_equal_to (NO_ERROR));
170   // assert_that (!IN6_IS_ADDR_UNSPECIFIED (&src));
171 
172   /* Close socket. */
173   close (udpv6soc);
174 }
175 
Ensure(util,fill_ports_array)176 Ensure (util, fill_ports_array)
177 {
178   GArray *ports_garray = NULL;
179   const gchar *port_list = NULL;
180   GPtrArray *portranges_array = NULL;
181 
182   /* Port list used in alivedetection.c. */
183   port_list = "80,137,587,3128,8081";
184   assert_that (validate_port_range (port_list), is_equal_to (0));
185   ports_garray = g_array_new (FALSE, TRUE, sizeof (uint16_t));
186   portranges_array = port_range_ranges (port_list);
187   assert_that (portranges_array, is_not_null);
188   /* Fill ports array with ports from the ranges. */
189   g_ptr_array_foreach (portranges_array, fill_ports_array, ports_garray);
190   array_free (portranges_array);
191   assert_that (ports_garray->len, is_equal_to (5));
192   assert_that (g_array_index (ports_garray, uint16_t, 0), is_equal_to (80));
193   assert_that (g_array_index (ports_garray, uint16_t, 4), is_equal_to (8081));
194   g_array_free (ports_garray, TRUE);
195 
196   /* Random port list. Duplicates are not removed. */
197   /* 1,2,5,6,10,11,12,10,10 */
198   port_list = "1-2,T:5-6,U:10-12,T:10,10";
199   assert_that (validate_port_range (port_list), is_equal_to (0));
200   ports_garray = g_array_new (FALSE, TRUE, sizeof (uint16_t));
201   portranges_array = port_range_ranges (port_list);
202   assert_that (portranges_array, is_not_null);
203   /* Fill ports array with ports from the ranges. */
204   g_ptr_array_foreach (portranges_array, fill_ports_array, ports_garray);
205   array_free (portranges_array);
206   assert_that (ports_garray->len, is_equal_to (9));
207   assert_that (g_array_index (ports_garray, uint16_t, 0), is_equal_to (1));
208   assert_that (g_array_index (ports_garray, uint16_t, 4), is_equal_to (10));
209   assert_that (g_array_index (ports_garray, uint16_t, 7), is_equal_to (10));
210   assert_that (g_array_index (ports_garray, uint16_t, 8), is_equal_to (10));
211   g_array_free (ports_garray, TRUE);
212 }
213 
214 int
main(int argc,char ** argv)215 main (int argc, char **argv)
216 {
217   TestSuite *suite;
218 
219   suite = create_test_suite ();
220 
221   add_test_with_context (suite, util, fill_ports_array);
222   add_test_with_context (suite, util, set_all_needed_sockets);
223   add_test_with_context (suite, util, set_socket);
224   add_test_with_context (suite, util, get_source_addr_v4);
225   add_test_with_context (suite, util, get_source_addr_v6);
226 
227   if (argc > 1)
228     return run_single_test (suite, argv[1], create_text_reporter ());
229 
230   return run_test_suite (suite, create_text_reporter ());
231 }
232