1 /*-
2  * SSLsplit - transparent SSL/TLS interception
3  * https://www.roe.ch/SSLsplit
4  *
5  * Copyright (c) 2009-2019, Daniel Roethlisberger <daniel@roe.ch>.
6  * Copyright (c) 2017-2021, Soner Tari <sonertari@gmail.com>.
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions are met:
11  * 1. Redistributions of source code must retain the above copyright notice,
12  *    this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright notice,
14  *    this list of conditions and the following disclaimer in the documentation
15  *    and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS''
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 #include "attrib.h"
31 #include "opts.h"
32 #include "filter.h"
33 
34 #include <check.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <unistd.h>
38 #include <netinet/in.h>
39 
40 static char *argv01[] = {
41 	"https", "127.0.0.1", "10443", "up:8080", "127.0.0.2", "443"
42 };
43 #ifndef TRAVIS
44 static char *argv02[] = {
45 	"https", "::1", "10443", "up:8080", "::2", "443"
46 };
47 #endif /* !TRAVIS */
48 static char *argv03[] = {
49 	"http", "127.0.0.1", "10443", "up:8080", "127.0.0.2", "443"
50 };
51 static char *argv04[] = {
52 	"ssl", "127.0.0.1", "10443", "up:8080", "127.0.0.2", "443"
53 };
54 static char *argv05[] = {
55 	"tcp", "127.0.0.1", "10443", "up:8080", "127.0.0.2", "443"
56 };
57 static char *argv06[] = {
58 	"https", "127.0.0.1", "10443", "up:8080", "sni", "443"
59 };
60 static char *argv07[] = {
61 	"http", "127.0.0.1", "10443", "up:8080", "sni", "443"
62 };
63 static char *argv08[] = {
64 	"https", "127.0.0.1", "10443", "up:8080", "no_such_engine"
65 };
66 #ifndef TRAVIS
67 static char *argv09[] = {
68 	"https", "127.0.0.1", "10443", "up:8080", "127.0.0.2", "443",
69 	"https", "::1", "10443", "up:8080", "::2", "443"
70 };
71 static char *argv10[] = {
72 	"https", "127.0.0.1", "10443", "up:8080",
73 	"https", "::1", "10443", "up:8080"
74 };
75 #endif /* !TRAVIS */
76 static char *argv11[] = {
77 	"autossl", "127.0.0.1", "10025", "up:8080"
78 };
79 static char *argv12[] = {
80 	"autossl", "127.0.0.1", "10025", "up:9199", "127.0.0.2", "25",
81 	"https", "127.0.0.1", "10443", "up:8080", "127.0.0.2", "443"
82 };
83 static char *argv13[] = {
84 	"autossl", "127.0.0.1", "10025", "up:9199", "sni", "25"
85 };
86 static char *argv14[] = {
87 	"https", "127.0.0.1", "10443", "up:8080",
88 	"autossl", "127.0.0.1", "10025", "up:9199", "127.0.0.2", "25"
89 };
90 
91 #ifdef __linux__
92 #define NATENGINE "netfilter"
93 #else
94 #define NATENGINE "pf"
95 #endif
96 
97 #if (OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)) || (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x3040100fL)
98 #ifdef HAVE_TLSV13
99 #define SSL_PROTO_CONFIG_PROXYSPEC "tls13 -tls13>=tls11<=tls12|no sslcomp|no_tls13"
100 #define SSL_PROTO_CONFIG_FILTERRULE "tls13 -tls13>=tls10<=tls11|no_tls13"
101 #else // openssl-1.1.0l = 101000cf
102 #define SSL_PROTO_CONFIG_PROXYSPEC "tls12 -tls10>=tls11<=tls12|no sslcomp|no_tls10"
103 #define SSL_PROTO_CONFIG_FILTERRULE "tls12>=tls10<=tls11"
104 #endif /* HAVE_TLSV13 */
105 #elif (OPENSSL_VERSION_NUMBER < 0x10000000L)
106 #define SSL_PROTO_CONFIG_PROXYSPEC "tls10 -tls10|no_tls10"
107 #define SSL_PROTO_CONFIG_FILTERRULE "tls10"
108 #elif (OPENSSL_VERSION_NUMBER <= 0x1000013fL)
109 #define SSL_PROTO_CONFIG_PROXYSPEC "tls10 -tls10|no sslcomp|no_tls10"
110 #define SSL_PROTO_CONFIG_FILTERRULE "tls10"
111 #elif (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x20702000L)
112 #define SSL_PROTO_CONFIG_PROXYSPEC "tls12 -tls10>=tls11<=tls12|no sslcomp|no_tls10"
113 #define SSL_PROTO_CONFIG_FILTERRULE "tls12>=tls10<=tls11"
114 #else // openssl-1.0.2g = 1000207f, libressl 2.2.7 = 20000000|20020006
115 #define SSL_PROTO_CONFIG_PROXYSPEC "tls12 -tls10|no sslcomp|no_tls10"
116 #define SSL_PROTO_CONFIG_FILTERRULE "tls12"
117 #endif /* OPENSSL_VERSION_NUMBER >= 0x10100000L */
118 
119 #ifdef HAVE_TLSV13
120 #define	FORCE_SSL_PROTO	"tls13"
121 #elif defined(HAVE_TLSV12)
122 #define	FORCE_SSL_PROTO	"tls12"
123 #elif defined(HAVE_TLSV11)
124 #define	FORCE_SSL_PROTO	"tls11"
125 #else
126 #define	FORCE_SSL_PROTO	"tls10"
127 #endif
128 
129 #ifndef OPENSSL_NO_ECDH
130 #define	ECDH_PRIME1 "prime256v1|"
131 #define	ECDH_PRIME2 "prime192v1|"
132 #else
133 #define	ECDH_PRIME1 ""
134 #define	ECDH_PRIME2 ""
135 #endif /* !OPENSSL_NO_ECDH */
136 
START_TEST(proxyspec_parse_01)137 START_TEST(proxyspec_parse_01)
138 {
139 	global_t *global = global_new();
140 	proxyspec_t *spec = NULL;
141 	int argc = 6;
142 	char **argv = argv01;
143 
144 	tmp_opts_t *tmp_opts = malloc(sizeof(tmp_opts_t));
145 	memset(tmp_opts, 0, sizeof(tmp_opts_t));
146 
147 	UNUSED int rv = proxyspec_parse(&argc, &argv, NATENGINE, global, "sslproxy", tmp_opts);
148 	spec = global->spec;
149 	fail_unless(!!spec, "failed to parse spec");
150 	fail_unless(spec->ssl, "not SSL");
151 	fail_unless(spec->http, "not HTTP");
152 	fail_unless(!spec->upgrade, "Upgrade");
153 	fail_unless(spec->listen_addrlen == sizeof(struct sockaddr_in),
154 	            "not IPv4 listen addr");
155 	fail_unless(spec->connect_addrlen == sizeof(struct sockaddr_in),
156 	            "not IPv4 connect addr");
157 	fail_unless(!spec->sni_port, "SNI port is set");
158 	fail_unless(!spec->natengine, "natengine is set");
159 	fail_unless(!spec->natlookup, "natlookup() is set");
160 	fail_unless(!spec->natsocket, "natsocket() is set");
161 	fail_unless(!spec->next, "next is set");
162 	global_free(global);
163 	tmp_opts_free(tmp_opts);
164 }
165 END_TEST
166 
167 #ifndef TRAVIS
START_TEST(proxyspec_parse_02)168 START_TEST(proxyspec_parse_02)
169 {
170 	global_t *global = global_new();
171 	proxyspec_t *spec = NULL;
172 	int argc = 6;
173 	char **argv = argv02;
174 
175 	tmp_opts_t *tmp_opts = malloc(sizeof(tmp_opts_t));
176 	memset(tmp_opts, 0, sizeof(tmp_opts_t));
177 
178 	UNUSED int rv = proxyspec_parse(&argc, &argv, NATENGINE, global, "sslproxy", tmp_opts);
179 	spec = global->spec;
180 	fail_unless(!!spec, "failed to parse spec");
181 	fail_unless(spec->ssl, "not SSL");
182 	fail_unless(spec->http, "not HTTP");
183 	fail_unless(!spec->upgrade, "Upgrade");
184 	fail_unless(spec->listen_addrlen == sizeof(struct sockaddr_in6),
185 	            "not IPv6 listen addr");
186 	fail_unless(spec->connect_addrlen == sizeof(struct sockaddr_in6),
187 	            "not IPv6 connect addr");
188 	fail_unless(!spec->sni_port, "SNI port is set");
189 	fail_unless(!spec->natengine, "natengine is set");
190 	fail_unless(!spec->natlookup, "natlookup() is set");
191 	fail_unless(!spec->natsocket, "natsocket() is set");
192 	fail_unless(!spec->next, "next is set");
193 	global_free(global);
194 	tmp_opts_free(tmp_opts);
195 }
196 END_TEST
197 #endif /* !TRAVIS */
198 
START_TEST(proxyspec_parse_03)199 START_TEST(proxyspec_parse_03)
200 {
201 	global_t *global = global_new();
202 	int argc = 2;
203 	char **argv = argv01;
204 
205 	tmp_opts_t *tmp_opts = malloc(sizeof(tmp_opts_t));
206 	memset(tmp_opts, 0, sizeof(tmp_opts_t));
207 
208 	// Disable error messages
209 	close(2);
210 
211 	int rv = proxyspec_parse(&argc, &argv, NATENGINE, global, "sslproxy", tmp_opts);
212 	fail_unless(rv == -1, "failed to reject spec");
213 
214 	argc = 5;
215 	rv = proxyspec_parse(&argc, &argv, NATENGINE, global, "sslproxy", tmp_opts);
216 	fail_unless(rv == -1, "failed to reject spec");
217 
218 	argc = 5;
219 	argv = argv07;
220 	rv = proxyspec_parse(&argc, &argv, NATENGINE, global, "sslproxy", tmp_opts);
221 	fail_unless(rv == -1, "failed to reject spec");
222 
223 	argc = 5;
224 	argv = argv06;
225 	rv = proxyspec_parse(&argc, &argv, NATENGINE, global, "sslproxy", tmp_opts);
226 	fail_unless(rv == -1, "failed to reject spec");
227 
228 	argc = 5;
229 	argv = argv08;
230 	rv = proxyspec_parse(&argc, &argv, NATENGINE, global, "sslproxy", tmp_opts);
231 	fail_unless(rv == -1, "failed to reject spec");
232 
233 	argc = 6;
234 	argv = argv13;
235 	rv = proxyspec_parse(&argc, &argv, NATENGINE, global, "sslproxy", tmp_opts);
236 	fail_unless(rv == -1, "failed to reject spec");
237 
238 	global_free(global);
239 	tmp_opts_free(tmp_opts);
240 }
241 END_TEST
242 
START_TEST(proxyspec_parse_04)243 START_TEST(proxyspec_parse_04)
244 {
245 	global_t *global = global_new();
246 	proxyspec_t *spec = NULL;
247 	int argc = 6;
248 	char **argv = argv03;
249 
250 	tmp_opts_t *tmp_opts = malloc(sizeof(tmp_opts_t));
251 	memset(tmp_opts, 0, sizeof(tmp_opts_t));
252 
253 	UNUSED int rv = proxyspec_parse(&argc, &argv, NATENGINE, global, "sslproxy", tmp_opts);
254 	spec = global->spec;
255 	fail_unless(!!spec, "failed to parse spec");
256 	fail_unless(!spec->ssl, "SSL");
257 	fail_unless(spec->http, "not HTTP");
258 	fail_unless(!spec->upgrade, "Upgrade");
259 	fail_unless(spec->listen_addrlen == sizeof(struct sockaddr_in),
260 	            "not IPv4 listen addr");
261 	fail_unless(spec->connect_addrlen == sizeof(struct sockaddr_in),
262 	            "not IPv4 connect addr");
263 	fail_unless(!spec->sni_port, "SNI port is set");
264 	fail_unless(!spec->natengine, "natengine is set");
265 	fail_unless(!spec->natlookup, "natlookup() is set");
266 	fail_unless(!spec->natsocket, "natsocket() is set");
267 	fail_unless(!spec->next, "next is set");
268 	global_free(global);
269 	tmp_opts_free(tmp_opts);
270 }
271 END_TEST
272 
START_TEST(proxyspec_parse_05)273 START_TEST(proxyspec_parse_05)
274 {
275 	global_t *global = global_new();
276 	proxyspec_t *spec = NULL;
277 	int argc = 6;
278 	char **argv = argv04;
279 
280 	tmp_opts_t *tmp_opts = malloc(sizeof(tmp_opts_t));
281 	memset(tmp_opts, 0, sizeof(tmp_opts_t));
282 
283 	UNUSED int rv = proxyspec_parse(&argc, &argv, NATENGINE, global, "sslproxy", tmp_opts);
284 	spec = global->spec;
285 	fail_unless(!!spec, "failed to parse spec");
286 	fail_unless(spec->ssl, "not SSL");
287 	fail_unless(!spec->http, "HTTP");
288 	fail_unless(!spec->upgrade, "Upgrade");
289 	fail_unless(spec->listen_addrlen == sizeof(struct sockaddr_in),
290 	            "not IPv4 listen addr");
291 	fail_unless(spec->connect_addrlen == sizeof(struct sockaddr_in),
292 	            "not IPv4 connect addr");
293 	fail_unless(!spec->sni_port, "SNI port is set");
294 	fail_unless(!spec->natengine, "natengine is set");
295 	fail_unless(!spec->natlookup, "natlookup() is set");
296 	fail_unless(!spec->natsocket, "natsocket() is set");
297 	fail_unless(!spec->next, "next is set");
298 	global_free(global);
299 	tmp_opts_free(tmp_opts);
300 }
301 END_TEST
302 
START_TEST(proxyspec_parse_06)303 START_TEST(proxyspec_parse_06)
304 {
305 	global_t *global = global_new();
306 	proxyspec_t *spec = NULL;
307 	int argc = 6;
308 	char **argv = argv05;
309 
310 	tmp_opts_t *tmp_opts = malloc(sizeof(tmp_opts_t));
311 	memset(tmp_opts, 0, sizeof(tmp_opts_t));
312 
313 	UNUSED int rv = proxyspec_parse(&argc, &argv, NATENGINE, global, "sslproxy", tmp_opts);
314 	spec = global->spec;
315 	fail_unless(!!spec, "failed to parse spec");
316 	fail_unless(!spec->ssl, "SSL");
317 	fail_unless(!spec->http, "HTTP");
318 	fail_unless(!spec->upgrade, "Upgrade");
319 	fail_unless(spec->listen_addrlen == sizeof(struct sockaddr_in),
320 	            "not IPv4 listen addr");
321 	fail_unless(spec->connect_addrlen == sizeof(struct sockaddr_in),
322 	            "not IPv4 connect addr");
323 	fail_unless(!spec->sni_port, "SNI port is set");
324 	fail_unless(!spec->natengine, "natengine is set");
325 	fail_unless(!spec->natlookup, "natlookup() is set");
326 	fail_unless(!spec->natsocket, "natsocket() is set");
327 	fail_unless(!spec->next, "next is set");
328 	global_free(global);
329 	tmp_opts_free(tmp_opts);
330 }
331 END_TEST
332 
START_TEST(proxyspec_parse_07)333 START_TEST(proxyspec_parse_07)
334 {
335 	global_t *global = global_new();
336 	proxyspec_t *spec = NULL;
337 	int argc = 6;
338 	char **argv = argv06;
339 
340 	tmp_opts_t *tmp_opts = malloc(sizeof(tmp_opts_t));
341 	memset(tmp_opts, 0, sizeof(tmp_opts_t));
342 
343 	UNUSED int rv = proxyspec_parse(&argc, &argv, NATENGINE, global, "sslproxy", tmp_opts);
344 	spec = global->spec;
345 	fail_unless(!!spec, "failed to parse spec");
346 	fail_unless(spec->ssl, "not SSL");
347 	fail_unless(spec->http, "not HTTP");
348 	fail_unless(!spec->upgrade, "Upgrade");
349 	fail_unless(spec->listen_addrlen == sizeof(struct sockaddr_in),
350 	            "not IPv4 listen addr");
351 	fail_unless(!spec->connect_addrlen, "connect addr set");
352 	fail_unless(spec->sni_port == 443, "SNI port is not set");
353 	fail_unless(!spec->natengine, "natengine is set");
354 	fail_unless(!spec->natlookup, "natlookup() is set");
355 	fail_unless(!spec->natsocket, "natsocket() is set");
356 	fail_unless(!spec->next, "next is set");
357 	global_free(global);
358 	tmp_opts_free(tmp_opts);
359 }
360 END_TEST
361 
START_TEST(proxyspec_parse_08)362 START_TEST(proxyspec_parse_08)
363 {
364 	global_t *global = global_new();
365 	proxyspec_t *spec = NULL;
366 	int argc = 4;
367 	char **argv = argv08;
368 
369 	tmp_opts_t *tmp_opts = malloc(sizeof(tmp_opts_t));
370 	memset(tmp_opts, 0, sizeof(tmp_opts_t));
371 
372 	UNUSED int rv = proxyspec_parse(&argc, &argv, NATENGINE, global, "sslproxy", tmp_opts);
373 	spec = global->spec;
374 	fail_unless(!!spec, "failed to parse spec");
375 	fail_unless(spec->ssl, "not SSL");
376 	fail_unless(spec->http, "not HTTP");
377 	fail_unless(!spec->upgrade, "Upgrade");
378 	fail_unless(spec->listen_addrlen == sizeof(struct sockaddr_in),
379 	            "not IPv4 listen addr");
380 	fail_unless(!spec->connect_addrlen, "connect addr set");
381 	fail_unless(!spec->sni_port, "SNI port is set");
382 	fail_unless(!!spec->natengine, "natengine not set");
383 	fail_unless(!strcmp(spec->natengine, NATENGINE), "natengine mismatch");
384 	fail_unless(!spec->natlookup, "natlookup() is set");
385 	fail_unless(!spec->natsocket, "natsocket() is set");
386 	fail_unless(!spec->next, "next is set");
387 	global_free(global);
388 	tmp_opts_free(tmp_opts);
389 }
390 END_TEST
391 
392 #ifndef TRAVIS
START_TEST(proxyspec_parse_09)393 START_TEST(proxyspec_parse_09)
394 {
395 	global_t *global = global_new();
396 	proxyspec_t *spec = NULL;
397 	int argc = 12;
398 	char **argv = argv09;
399 
400 	tmp_opts_t *tmp_opts = malloc(sizeof(tmp_opts_t));
401 	memset(tmp_opts, 0, sizeof(tmp_opts_t));
402 
403 	UNUSED int rv = proxyspec_parse(&argc, &argv, NATENGINE, global, "sslproxy", tmp_opts);
404 	spec = global->spec;
405 	fail_unless(!!spec, "failed to parse spec");
406 	fail_unless(spec->ssl, "not SSL");
407 	fail_unless(spec->http, "not HTTP");
408 	fail_unless(!spec->upgrade, "Upgrade");
409 	fail_unless(spec->listen_addrlen == sizeof(struct sockaddr_in6),
410 	            "not IPv6 listen addr");
411 	fail_unless(spec->connect_addrlen == sizeof(struct sockaddr_in6),
412 	            "not IPv6 connect addr");
413 	fail_unless(!spec->sni_port, "SNI port is set");
414 	fail_unless(!spec->natengine, "natengine is set");
415 	fail_unless(!spec->natlookup, "natlookup() is set");
416 	fail_unless(!spec->natsocket, "natsocket() is set");
417 	fail_unless(!!spec->next, "next is not set");
418 	fail_unless(spec->next->ssl, "not SSL");
419 	fail_unless(spec->next->http, "not HTTP");
420 	fail_unless(!spec->next->upgrade, "Upgrade");
421 	fail_unless(spec->next->listen_addrlen == sizeof(struct sockaddr_in),
422 	            "not IPv4 listen addr");
423 	fail_unless(spec->next->connect_addrlen == sizeof(struct sockaddr_in),
424 	            "not IPv4 connect addr");
425 	fail_unless(!spec->next->sni_port, "SNI port is set");
426 	fail_unless(!spec->next->natengine, "natengine is set");
427 	fail_unless(!spec->next->natlookup, "natlookup() is set");
428 	fail_unless(!spec->next->natsocket, "natsocket() is set");
429 	global_free(global);
430 	tmp_opts_free(tmp_opts);
431 }
432 END_TEST
433 
START_TEST(proxyspec_parse_10)434 START_TEST(proxyspec_parse_10)
435 {
436 	global_t *global = global_new();
437 	proxyspec_t *spec = NULL;
438 	int argc = 8;
439 	char **argv = argv10;
440 
441 	tmp_opts_t *tmp_opts = malloc(sizeof(tmp_opts_t));
442 	memset(tmp_opts, 0, sizeof(tmp_opts_t));
443 
444 	UNUSED int rv = proxyspec_parse(&argc, &argv, NATENGINE, global, "sslproxy", tmp_opts);
445 	spec = global->spec;
446 	fail_unless(!!spec, "failed to parse spec");
447 	fail_unless(spec->ssl, "not SSL");
448 	fail_unless(spec->http, "not HTTP");
449 	fail_unless(!spec->upgrade, "Upgrade");
450 	fail_unless(spec->listen_addrlen == sizeof(struct sockaddr_in6),
451 	            "not IPv6 listen addr");
452 	fail_unless(!spec->connect_addrlen, "connect addr set");
453 	fail_unless(!spec->sni_port, "SNI port is set");
454 	fail_unless(!!spec->natengine, "natengine not set");
455 	fail_unless(!strcmp(spec->natengine, NATENGINE), "natengine mismatch");
456 	fail_unless(!spec->natlookup, "natlookup() is set");
457 	fail_unless(!spec->natsocket, "natsocket() is set");
458 	fail_unless(!!spec->next, "next is not set");
459 	fail_unless(spec->next->ssl, "not SSL");
460 	fail_unless(spec->next->http, "not HTTP");
461 	fail_unless(!spec->next->upgrade, "Upgrade");
462 	fail_unless(spec->next->listen_addrlen == sizeof(struct sockaddr_in),
463 	            "not IPv4 listen addr");
464 	fail_unless(!spec->next->connect_addrlen, "connect addr set");
465 	fail_unless(!spec->next->sni_port, "SNI port is set");
466 	fail_unless(!!spec->next->natengine, "natengine not set");
467 	fail_unless(!strcmp(spec->next->natengine, NATENGINE),
468 	            "natengine mismatch");
469 	fail_unless(!spec->next->natlookup, "natlookup() is set");
470 	fail_unless(!spec->next->natsocket, "natsocket() is set");
471 	global_free(global);
472 	tmp_opts_free(tmp_opts);
473 }
474 END_TEST
475 #endif /* !TRAVIS */
476 
START_TEST(proxyspec_parse_11)477 START_TEST(proxyspec_parse_11)
478 {
479 	global_t *global = global_new();
480 	proxyspec_t *spec = NULL;
481 	int argc = 4;
482 	char **argv = argv11;
483 
484 	tmp_opts_t *tmp_opts = malloc(sizeof(tmp_opts_t));
485 	memset(tmp_opts, 0, sizeof(tmp_opts_t));
486 
487 	UNUSED int rv = proxyspec_parse(&argc, &argv, NATENGINE, global, "sslproxy", tmp_opts);
488 	spec = global->spec;
489 	fail_unless(!!spec, "failed to parse spec");
490 	fail_unless(!spec->ssl, "SSL");
491 	fail_unless(!spec->http, "HTTP");
492 	fail_unless(spec->upgrade, "not Upgrade");
493 	fail_unless(spec->listen_addrlen == sizeof(struct sockaddr_in),
494 	            "not IPv4 listen addr");
495 	fail_unless(!spec->connect_addrlen, "connect addr set");
496 	fail_unless(!spec->sni_port, "SNI port is set");
497 	fail_unless(!!spec->natengine, "natengine is not set");
498 	fail_unless(!spec->natlookup, "natlookup() is set");
499 	fail_unless(!spec->natsocket, "natsocket() is set");
500 	fail_unless(!spec->next, "next is set");
501 	global_free(global);
502 	tmp_opts_free(tmp_opts);
503 }
504 END_TEST
505 
START_TEST(proxyspec_parse_12)506 START_TEST(proxyspec_parse_12)
507 {
508 	global_t *global = global_new();
509 	proxyspec_t *spec = NULL;
510 	int argc = 12;
511 	char **argv = argv12;
512 
513 	tmp_opts_t *tmp_opts = malloc(sizeof(tmp_opts_t));
514 	memset(tmp_opts, 0, sizeof(tmp_opts_t));
515 
516 	UNUSED int rv = proxyspec_parse(&argc, &argv, NATENGINE, global, "sslproxy", tmp_opts);
517 	spec = global->spec;
518 	fail_unless(!!spec, "failed to parse spec");
519 	fail_unless(spec->ssl, "not SSL");
520 	fail_unless(spec->http, "not HTTP");
521 	fail_unless(!spec->upgrade, "Upgrade");
522 	fail_unless(spec->listen_addrlen == sizeof(struct sockaddr_in),
523 	            "not IPv4 listen addr");
524 	fail_unless(spec->connect_addrlen == sizeof(struct sockaddr_in),
525 	            "not IPv4 connect addr");
526 	fail_unless(!spec->sni_port, "SNI port is set");
527 	fail_unless(!spec->natengine, "natengine is set");
528 	fail_unless(!spec->natlookup, "natlookup() is set");
529 	fail_unless(!spec->natsocket, "natsocket() is set");
530 	fail_unless(!!spec->next, "next is not set");
531 	fail_unless(!spec->next->ssl, "SSL");
532 	fail_unless(!spec->next->http, "HTTP");
533 	fail_unless(spec->next->upgrade, "not Upgrade");
534 	fail_unless(spec->next->listen_addrlen == sizeof(struct sockaddr_in),
535 	            "not IPv4 listen addr");
536 	fail_unless(spec->next->connect_addrlen == sizeof(struct sockaddr_in),
537 	            "not IPv4 connect addr");
538 	fail_unless(!spec->next->sni_port, "SNI port is set");
539 	fail_unless(!spec->next->natengine, "natengine is set");
540 	fail_unless(!spec->next->natlookup, "natlookup() is set");
541 	fail_unless(!spec->next->natsocket, "natsocket() is set");
542 	global_free(global);
543 	tmp_opts_free(tmp_opts);
544 }
545 END_TEST
546 
START_TEST(proxyspec_parse_13)547 START_TEST(proxyspec_parse_13)
548 {
549 	global_t *global = global_new();
550 	proxyspec_t *spec = NULL;
551 	int argc = 10;
552 	char **argv = argv14;
553 
554 	tmp_opts_t *tmp_opts = malloc(sizeof(tmp_opts_t));
555 	memset(tmp_opts, 0, sizeof(tmp_opts_t));
556 
557 	UNUSED int rv = proxyspec_parse(&argc, &argv, NATENGINE, global, "sslproxy", tmp_opts);
558 	spec = global->spec;
559 	fail_unless(!!spec, "failed to parse spec");
560 	fail_unless(!spec->ssl, "SSL");
561 	fail_unless(!spec->http, "HTTP");
562 	fail_unless(spec->upgrade, "not Upgrade");
563 	fail_unless(spec->listen_addrlen == sizeof(struct sockaddr_in),
564 	            "not IPv4 listen addr");
565 	fail_unless(spec->connect_addrlen == sizeof(struct sockaddr_in),
566 	            "not IPv4 connect addr");
567 	fail_unless(!spec->sni_port, "SNI port is set");
568 	fail_unless(!spec->natengine, "natengine is set");
569 	fail_unless(!spec->natlookup, "natlookup() is set");
570 	fail_unless(!spec->natsocket, "natsocket() is set");
571 	fail_unless(!!spec->next, "next is not set");
572 	fail_unless(spec->next->ssl, "not SSL");
573 	fail_unless(spec->next->http, "not HTTP");
574 	fail_unless(!spec->next->upgrade, "Upgrade");
575 	fail_unless(spec->next->listen_addrlen == sizeof(struct sockaddr_in),
576 	            "not IPv4 listen addr");
577 	fail_unless(!spec->next->connect_addrlen, "connect addr set");
578 	fail_unless(!spec->next->sni_port, "SNI port is set");
579 	fail_unless(!!spec->next->natengine, "natengine is not set");
580 	fail_unless(!spec->next->natlookup, "natlookup() is set");
581 	fail_unless(!spec->next->natsocket, "natsocket() is set");
582 	global_free(global);
583 	tmp_opts_free(tmp_opts);
584 }
585 END_TEST
586 
START_TEST(proxyspec_set_proto_01)587 START_TEST(proxyspec_set_proto_01)
588 {
589 	global_t *global = global_new();
590 	proxyspec_t *spec  = proxyspec_new(global, "sslproxy", NULL);
591 
592 	UNUSED int rv = proxyspec_set_proto(spec, "tcp");
593 	fail_unless(!spec->ssl, "ssl set in tcp spec");
594 	fail_unless(!spec->http, "http set in tcp spec");
595 	fail_unless(!spec->upgrade, "upgrade set in tcp spec");
596 	fail_unless(!spec->pop3, "pop3 set in tcp spec");
597 	fail_unless(!spec->smtp, "smtp set in tcp spec");
598 
599 	rv = proxyspec_set_proto(spec, "ssl");
600 	fail_unless(spec->ssl, "ssl not set in ssl spec");
601 	fail_unless(!spec->http, "http set in ssl spec");
602 	fail_unless(!spec->upgrade, "upgrade set in ssl spec");
603 	fail_unless(!spec->pop3, "pop3 set in ssl spec");
604 	fail_unless(!spec->smtp, "smtp set in ssl spec");
605 
606 	rv = proxyspec_set_proto(spec, "http");
607 	fail_unless(!spec->ssl, "ssl set in http spec");
608 	fail_unless(spec->http, "http not set in http spec");
609 	fail_unless(!spec->upgrade, "upgrade set in http spec");
610 	fail_unless(!spec->pop3, "pop3 set in http spec");
611 	fail_unless(!spec->smtp, "smtp set in http spec");
612 
613 	rv = proxyspec_set_proto(spec, "https");
614 	fail_unless(spec->ssl, "ssl not set in https spec");
615 	fail_unless(spec->http, "http not set in https spec");
616 	fail_unless(!spec->upgrade, "upgrade set in https spec");
617 	fail_unless(!spec->pop3, "pop3 set in https spec");
618 	fail_unless(!spec->smtp, "smtp set in https spec");
619 
620 	rv = proxyspec_set_proto(spec, "autossl");
621 	fail_unless(!spec->ssl, "ssl set in autossl spec");
622 	fail_unless(!spec->http, "http set in autossl spec");
623 	fail_unless(spec->upgrade, "upgrade not set in autossl spec");
624 	fail_unless(!spec->pop3, "pop3 set in autossl spec");
625 	fail_unless(!spec->smtp, "smtp set in autossl spec");
626 
627 	rv = proxyspec_set_proto(spec, "pop3");
628 	fail_unless(!spec->ssl, "ssl set in pop3 spec");
629 	fail_unless(!spec->http, "http set in pop3 spec");
630 	fail_unless(!spec->upgrade, "upgrade set in pop3 spec");
631 	fail_unless(spec->pop3, "pop3 not set in pop3 spec");
632 	fail_unless(!spec->smtp, "smtp set in pop3 spec");
633 
634 	rv = proxyspec_set_proto(spec, "pop3s");
635 	fail_unless(spec->ssl, "ssl not set in pop3s spec");
636 	fail_unless(!spec->http, "http set in pop3s spec");
637 	fail_unless(!spec->upgrade, "upgrade set in pop3s spec");
638 	fail_unless(spec->pop3, "pop3 not set in pop3s spec");
639 	fail_unless(!spec->smtp, "smtp set in pop3s spec");
640 
641 	rv = proxyspec_set_proto(spec, "smtp");
642 	fail_unless(!spec->ssl, "ssl set in smtp spec");
643 	fail_unless(!spec->http, "http set in smtp spec");
644 	fail_unless(!spec->upgrade, "upgrade set in smtp spec");
645 	fail_unless(!spec->pop3, "pop3 set in smtp spec");
646 	fail_unless(spec->smtp, "smtp not set in smtp spec");
647 
648 	rv = proxyspec_set_proto(spec, "smtps");
649 	fail_unless(spec->ssl, "ssl not set in smtps spec");
650 	fail_unless(!spec->http, "http set in smtps spec");
651 	fail_unless(!spec->upgrade, "upgrade set in smtps spec");
652 	fail_unless(!spec->pop3, "pop3 set in smtps spec");
653 	fail_unless(spec->smtp, "smtp not set in smtps spec");
654 
655 	proxyspec_free(spec);
656 	global_free(global);
657 }
658 END_TEST
659 
START_TEST(proxyspec_struct_parse_01)660 START_TEST(proxyspec_struct_parse_01)
661 {
662 	char *s;
663 	int rv;
664 	global_t *global = global_new();
665 
666 	tmp_opts_t *tmp_opts = malloc(sizeof (tmp_opts_t));
667 	memset(tmp_opts, 0, sizeof (tmp_opts_t));
668 
669 	FILE *f;
670 	unsigned int line_num = 0;
671 
672 	s =
673 		"Proto https     # inline\n"
674 		"Addr 127.0.0.1  # comments\n"
675 		"Port 8213       # supported\n"
676 		"DivertPort 8080\n"
677 		"DivertAddr 192.168.1.1\n"
678 		"ReturnAddr 192.168.2.1\n"
679 		"TargetAddr 127.0.0.1\n"
680 		"TargetPort 9213\n"
681 		"Divert yes\n"
682 		"NatEngine "NATENGINE"\n"
683 		"SNIPort 4444\n"
684 		"\n"
685 		"# FilterRule below should override these options\n"
686 		"DenyOCSP yes\n"
687 		"Passthrough no\n"
688 		"CACert ../testproxy/ca2.crt\n"
689 		"CAKey ../testproxy/ca2.key\n"
690 		"ClientCert ../testproxy/ca.crt\n"
691 		"ClientKey ../testproxy/ca.key\n"
692 		"CAChain ../testproxy/server2.crt\n"
693 		"LeafCRLURL http://example2.com/example2.crl\n"
694 		"#DHGroupParams /etc/sslproxy/dh.pem\n"
695 #ifndef OPENSSL_NO_ECDH
696 		"ECDHCurve prime256v1\n"
697 #endif /* !OPENSSL_NO_ECDH */
698 #ifdef SSL_OP_NO_COMPRESSION
699 		"SSLCompression no\n"
700 #endif /* SSL_OP_NO_COMPRESSION */
701 		"ForceSSLProto "FORCE_SSL_PROTO"\n"
702 #ifdef HAVE_TLSV13
703 		"DisableSSLProto tls13\n"
704 #else
705 		"DisableSSLProto tls1\n"
706 #endif /* HAVE_TLSV13 */
707 #if (OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)) || (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x20702000L)
708 		"MinSSLProto tls11\n"
709 		"MaxSSLProto tls12\n"
710 #endif
711 		"Ciphers MEDIUM:HIGH\n"
712 		"CipherSuites TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256\n"
713 		"RemoveHTTPAcceptEncoding yes\n"
714 		"RemoveHTTPReferer yes\n"
715 		"VerifyPeer yes\n"
716 		"AllowWrongHost no\n"
717 #ifndef WITHOUT_USERAUTH
718 		"UserAuth yes\n"
719 		"UserTimeout 300\n"
720 		"UserAuthURL https://192.168.0.13/userdblogin3.php\n"
721 		"\n"
722 		"DivertUsers root daemon\n"
723 		"PassUsers root daemon\n"
724 #endif /* !WITHOUT_USERAUTH */
725 		"ValidateProto yes\n"
726 		"MaxHTTPHeaderSize 2048\n"
727 		"\n"
728 		"PassSite example4.com\n"
729 		"\n"
730 		"Define $ip 127.0.0.1\n"
731 		"Match from ip $ip to ip 127.0.0.1 port 9191 log content\n"
732 		"Block from ip $ip to ip 127.0.0.1 port 9191 log content\n"
733 		"Pass from ip $ip to ip 127.0.0.1 port 9191 log content\n"
734 		"Split from ip $ip to ip 127.0.0.1 port 9191 log content\n"
735 		"Divert from ip $ip to ip 127.0.0.1 port 9191 log content\n"
736 		"\n"
737 		"FilterRule {\n"
738 			"Action Match       # inline\n"
739 			"SrcIp 192.168.0.1  # comments\n"
740 			"DstIp 192.168.0.2  # supported\n"
741 			"Log connect\n"
742 			"ReconnectSSL yes\n"
743 			"DenyOCSP no\n"
744 			"Passthrough yes\n"
745 			"CACert ../testproxy/ca.crt\n"
746 			"CAKey ../testproxy/ca.key\n"
747 			"ClientCert ../testproxy/ca2.crt\n"
748 			"ClientKey ../testproxy/ca2.key\n"
749 			"CAChain ../testproxy/server.crt\n"
750 			"LeafCRLURL http://example1.com/example1.crl\n"
751 			"#DHGroupParams /etc/sslproxy/dh.pem\n"
752 #ifndef OPENSSL_NO_ECDH
753 			"ECDHCurve prime192v1\n"
754 #endif /* !OPENSSL_NO_ECDH */
755 #ifdef SSL_OP_NO_COMPRESSION
756 			"SSLCompression yes\n"
757 #endif /* SSL_OP_NO_COMPRESSION */
758 			"ForceSSLProto "FORCE_SSL_PROTO"\n"
759 #ifdef HAVE_TLSV13
760 			"DisableSSLProto tls13\n"
761 #else
762 			"DisableSSLProto tls1\n"
763 #endif /* HAVE_TLSV13 */
764 			"EnableSSLProto tls1\n"
765 #if (OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)) || (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER >= 0x20702000L)
766 			"MinSSLProto tls10\n"
767 			"MaxSSLProto tls11\n"
768 #endif
769 			"Ciphers LOW\n"
770 			"CipherSuites TLS_AES_128_CCM_SHA256\n"
771 			"RemoveHTTPAcceptEncoding no\n"
772 			"RemoveHTTPReferer no\n"
773 			"VerifyPeer no\n"
774 			"AllowWrongHost yes\n"
775 #ifndef WITHOUT_USERAUTH
776 			"UserAuth no\n"
777 			"UserTimeout 1200\n"
778 			"UserAuthURL https://192.168.0.12/userdblogin1.php\n"
779 #endif /* !WITHOUT_USERAUTH */
780 			"ValidateProto no\n"
781 			"MaxHTTPHeaderSize 2048\n"
782 			"}\n"
783 		"}";
784 	f = fmemopen(s, strlen(s), "r");
785 
786 	close(2);
787 
788 	char *natengine = "pf";
789 	rv = load_proxyspec_struct(global, "sslproxy", &natengine, &line_num, f, tmp_opts);
790 
791 	fclose(f);
792 	fail_unless(rv == 0, "failed to parse proxyspec");
793 
794 	global->spec->opts->filter = filter_set(global->spec->opts->filter_rules, "sslproxy", tmp_opts);
795 
796 	s = proxyspec_str(global->spec);
797 
798 #ifndef WITHOUT_USERAUTH
799 	fail_unless(!strcmp(s,
800 "listen=[127.0.0.1]:8213 ssl|http \n"
801 "sni 4444\n"
802 "divert addr= [127.0.0.1]:8080\n"
803 "return addr= [192.168.2.1]:0\n"
804 "opts= conn opts: "SSL_PROTO_CONFIG_PROXYSPEC"|deny_ocsp|MEDIUM:HIGH|TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256|"ECDH_PRIME1"http://example2.com/example2.crl|remove_http_accept_encoding|remove_http_referer|verify_peer|user_auth|https://192.168.0.13/userdblogin3.php|300|validate_proto|2048\n"
805 "divert|daemon,root|daemon,root\n"
806 "macro $ip = 127.0.0.1\n"
807 "filter rule 0: sni=example4.com, dstport=, srcip=, user=, desc=, exact=site||||, all=conns|||, action=||pass||, log=|||||, precedence=1\n"
808 "filter rule 0: cn=example4.com, dstport=, srcip=, user=, desc=, exact=site||||, all=conns|||, action=||pass||, log=|||||, precedence=1\n"
809 "filter rule 1: dstip=127.0.0.1, dstport=9191, srcip=127.0.0.1, user=, desc=, exact=site|port|ip||, all=|||, action=||||match, log=|||content||, precedence=4\n"
810 "filter rule 2: dstip=127.0.0.1, dstport=9191, srcip=127.0.0.1, user=, desc=, exact=site|port|ip||, all=|||, action=|||block|, log=|||content||, precedence=4\n"
811 "filter rule 3: dstip=127.0.0.1, dstport=9191, srcip=127.0.0.1, user=, desc=, exact=site|port|ip||, all=|||, action=||pass||, log=|||content||, precedence=4\n"
812 "filter rule 4: dstip=127.0.0.1, dstport=9191, srcip=127.0.0.1, user=, desc=, exact=site|port|ip||, all=|||, action=|split|||, log=|||content||, precedence=4\n"
813 "filter rule 5: dstip=127.0.0.1, dstport=9191, srcip=127.0.0.1, user=, desc=, exact=site|port|ip||, all=|||, action=divert||||, log=|||content||, precedence=4\n"
814 "filter rule 6: dstip=192.168.0.2, dstport=, srcip=192.168.0.1, user=, desc=, exact=site||ip||, all=|||, action=||||match, log=connect|||||, precedence=3\n"
815 "  conn opts: "SSL_PROTO_CONFIG_FILTERRULE"|passthrough|LOW|TLS_AES_128_CCM_SHA256|"ECDH_PRIME2"http://example1.com/example1.crl|allow_wrong_host|https://192.168.0.12/userdblogin1.php|1200|reconnect_ssl|2048\n"
816 "filter=>\n"
817 "userdesc_filter_exact->\n"
818 "userdesc_filter_substring->\n"
819 "user_filter_exact->\n"
820 "user_filter_substring->\n"
821 "desc_filter_exact->\n"
822 "desc_filter_substring->\n"
823 "user_filter_all->\n"
824 "ip_filter_exact->\n"
825 "  ip 0 127.0.0.1 (exact)=\n"
826 "    ip exact:\n"
827 "      0: 127.0.0.1 (exact, action=||||, log=|||||, precedence=0)\n"
828 "        port exact:\n"
829 "          0: 9191 (exact, action=divert|split|pass|block|match, log=|||content||, precedence=4)\n"
830 "  ip 1 192.168.0.1 (exact)=\n"
831 "    ip exact:\n"
832 "      0: 192.168.0.2 (exact, action=||||match, log=connect|||||, precedence=3\n"
833 "        conn opts: "SSL_PROTO_CONFIG_FILTERRULE"|passthrough|LOW|TLS_AES_128_CCM_SHA256|"ECDH_PRIME2"no leafcrlurl|allow_wrong_host|https://192.168.0.12/userdblogin1.php|1200|reconnect_ssl|2048)\n"
834 "ip_filter_substring->\n"
835 "filter_all->\n"
836 "    sni exact:\n"
837 "      0: example4.com (exact, action=||pass||, log=|||||, precedence=1)\n"
838 "    cn exact:\n"
839 "      0: example4.com (exact, action=||pass||, log=|||||, precedence=1)\n"),
840 		"failed to parse proxyspec: %s", s);
841 #else /* WITHOUT_USERAUTH */
842 	fail_unless(!strcmp(s,
843 "listen=[127.0.0.1]:8213 ssl|http \n"
844 "sni 4444\n"
845 "divert addr= [127.0.0.1]:8080\n"
846 "return addr= [192.168.2.1]:0\n"
847 "opts= conn opts: "SSL_PROTO_CONFIG_PROXYSPEC"|deny_ocsp|MEDIUM:HIGH|TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256|"ECDH_PRIME1"http://example2.com/example2.crl|remove_http_accept_encoding|remove_http_referer|verify_peer|validate_proto|2048\n"
848 "divert\n"
849 "macro $ip = 127.0.0.1\n"
850 "filter rule 0: sni=example4.com, dstport=, srcip=, exact=site||, all=conns||, action=||pass||, log=|||||, precedence=1\n"
851 "filter rule 0: cn=example4.com, dstport=, srcip=, exact=site||, all=conns||, action=||pass||, log=|||||, precedence=1\n"
852 "filter rule 1: dstip=127.0.0.1, dstport=9191, srcip=127.0.0.1, exact=site|port|ip, all=||, action=||||match, log=|||content||, precedence=4\n"
853 "filter rule 2: dstip=127.0.0.1, dstport=9191, srcip=127.0.0.1, exact=site|port|ip, all=||, action=|||block|, log=|||content||, precedence=4\n"
854 "filter rule 3: dstip=127.0.0.1, dstport=9191, srcip=127.0.0.1, exact=site|port|ip, all=||, action=||pass||, log=|||content||, precedence=4\n"
855 "filter rule 4: dstip=127.0.0.1, dstport=9191, srcip=127.0.0.1, exact=site|port|ip, all=||, action=|split|||, log=|||content||, precedence=4\n"
856 "filter rule 5: dstip=127.0.0.1, dstport=9191, srcip=127.0.0.1, exact=site|port|ip, all=||, action=divert||||, log=|||content||, precedence=4\n"
857 "filter rule 6: dstip=192.168.0.2, dstport=, srcip=192.168.0.1, exact=site||ip, all=||, action=||||match, log=connect|||||, precedence=3\n"
858 "  conn opts: "SSL_PROTO_CONFIG_FILTERRULE"|passthrough|LOW|TLS_AES_128_CCM_SHA256|"ECDH_PRIME2"http://example1.com/example1.crl|allow_wrong_host|reconnect_ssl|2048\n"
859 "filter=>\n"
860 "ip_filter_exact->\n"
861 "  ip 0 127.0.0.1 (exact)=\n"
862 "    ip exact:\n"
863 "      0: 127.0.0.1 (exact, action=||||, log=|||||, precedence=0)\n"
864 "        port exact:\n"
865 "          0: 9191 (exact, action=divert|split|pass|block|match, log=|||content||, precedence=4)\n"
866 "  ip 1 192.168.0.1 (exact)=\n"
867 "    ip exact:\n"
868 "      0: 192.168.0.2 (exact, action=||||match, log=connect|||||, precedence=3\n"
869 "        conn opts: "SSL_PROTO_CONFIG_FILTERRULE"|passthrough|LOW|TLS_AES_128_CCM_SHA256|"ECDH_PRIME2"no leafcrlurl|allow_wrong_host|reconnect_ssl|2048)\n"
870 "ip_filter_substring->\n"
871 "filter_all->\n"
872 "    sni exact:\n"
873 "      0: example4.com (exact, action=||pass||, log=|||||, precedence=1)\n"
874 "    cn exact:\n"
875 "      0: example4.com (exact, action=||pass||, log=|||||, precedence=1)\n"),
876 		"failed to parse proxyspec: %s", s);
877 #endif /* WITHOUT_USERAUTH */
878 	free(s);
879 
880 	tmp_opts_free(tmp_opts);
881 	global_free(global);
882 }
883 END_TEST
884 
START_TEST(opts_debug_01)885 START_TEST(opts_debug_01)
886 {
887 	global_t *global = global_new();
888 
889 	global->debug = 0;
890 	fail_unless(!global->debug, "plain 0");
891 	fail_unless(!OPTS_DEBUG(global), "macro 0");
892 	global->debug = 1;
893 	fail_unless(!!global->debug, "plain 1");
894 	fail_unless(!!OPTS_DEBUG(global), "macro 1");
895 	global_free(global);
896 }
897 END_TEST
898 
START_TEST(opts_set_passsite_01)899 START_TEST(opts_set_passsite_01)
900 {
901 	char *ps;
902 	opts_t *opts = opts_new();
903 	conn_opts_t *conn_opts = conn_opts_new();
904 
905 	char *s = strdup("example.com");
906 	UNUSED int rv = filter_passsite_set(opts, conn_opts, s, 0);
907 	free(s);
908 
909 	fail_unless(!strcmp(opts->filter_rules->sni, "example.com"), "site not example.com");
910 	fail_unless(!strcmp(opts->filter_rules->cn, "example.com"), "site not example.com");
911 	fail_unless(!opts->filter_rules->ip, "ip set");
912 #ifndef WITHOUT_USERAUTH
913 	fail_unless(!opts->filter_rules->user, "user set");
914 	fail_unless(opts->filter_rules->all_conns, "all_conns not 1");
915 	fail_unless(!opts->filter_rules->desc, "desc set");
916 #endif /* !WITHOUT_USERAUTH */
917 	fail_unless(!opts->filter_rules->next, "next set");
918 
919 	ps = filter_rule_str(opts->filter_rules);
920 #ifndef WITHOUT_USERAUTH
921 	fail_unless(!strcmp(ps, "filter rule 0: sni=example.com, dstport=, srcip=, user=, desc=, exact=site||||, all=conns|||, action=||pass||, log=|||||, precedence=1\n"
922 		"filter rule 0: cn=example.com, dstport=, srcip=, user=, desc=, exact=site||||, all=conns|||, action=||pass||, log=|||||, precedence=1\n"),
923 		"failed parsing passite example.com: %s", ps);
924 #else /* WITHOUT_USERAUTH */
925 	fail_unless(!strcmp(ps, "filter rule 0: sni=example.com, dstport=, srcip=, exact=site||, all=conns||, action=||pass||, log=|||||, precedence=1\n"
926 		"filter rule 0: cn=example.com, dstport=, srcip=, exact=site||, all=conns||, action=||pass||, log=|||||, precedence=1\n"),
927 		"failed parsing passite example.com: %s", ps);
928 #endif /* WITHOUT_USERAUTH */
929 	free(ps);
930 
931 	opts_free(opts);
932 	conn_opts_free(conn_opts);
933 }
934 END_TEST
935 
START_TEST(opts_set_passsite_02)936 START_TEST(opts_set_passsite_02)
937 {
938 	char *ps;
939 	opts_t *opts = opts_new();
940 	conn_opts_t *conn_opts = conn_opts_new();
941 
942 	char *s = strdup("example.com 192.168.0.1");
943 	UNUSED int rv = filter_passsite_set(opts, conn_opts, s, 0);
944 	free(s);
945 
946 	fail_unless(!strcmp(opts->filter_rules->sni, "example.com"), "site not example.com");
947 	fail_unless(!strcmp(opts->filter_rules->cn, "example.com"), "site not example.com");
948 	fail_unless(!strcmp(opts->filter_rules->ip, "192.168.0.1"), "ip not 192.168.0.1");
949 #ifndef WITHOUT_USERAUTH
950 	fail_unless(!opts->filter_rules->user, "user set");
951 	fail_unless(!opts->filter_rules->all_conns, "all_conns not 0");
952 	fail_unless(!opts->filter_rules->desc, "desc set");
953 #endif /* !WITHOUT_USERAUTH */
954 	fail_unless(!opts->filter_rules->next, "next set");
955 
956 	ps = filter_rule_str(opts->filter_rules);
957 #ifndef WITHOUT_USERAUTH
958 	fail_unless(!strcmp(ps, "filter rule 0: sni=example.com, dstport=, srcip=192.168.0.1, user=, desc=, exact=site||||, all=|||, action=||pass||, log=|||||, precedence=2\n"
959 		"filter rule 0: cn=example.com, dstport=, srcip=192.168.0.1, user=, desc=, exact=site||||, all=|||, action=||pass||, log=|||||, precedence=2\n"),
960 		"failed parsing passite example.com 192.168.0.1: %s", ps);
961 #else /* WITHOUT_USERAUTH */
962 	fail_unless(!strcmp(ps, "filter rule 0: sni=example.com, dstport=, srcip=192.168.0.1, exact=site||, all=||, action=||pass||, log=|||||, precedence=2\n"
963 		"filter rule 0: cn=example.com, dstport=, srcip=192.168.0.1, exact=site||, all=||, action=||pass||, log=|||||, precedence=2\n"),
964 		"failed parsing passite example.com 192.168.0.1: %s", ps);
965 #endif /* !WITHOUT_USERAUTH */
966 	free(ps);
967 
968 	opts_free(opts);
969 	conn_opts_free(conn_opts);
970 }
971 END_TEST
972 
973 #ifndef WITHOUT_USERAUTH
START_TEST(opts_set_passsite_03)974 START_TEST(opts_set_passsite_03)
975 {
976 	char *ps;
977 	opts_t *opts = opts_new();
978 	conn_opts_t *conn_opts = conn_opts_new();
979 
980 	conn_opts->user_auth = 1;
981 
982 	char *s = strdup("example.com root");
983 	UNUSED int rv = filter_passsite_set(opts, conn_opts, s, 0);
984 	free(s);
985 
986 	fail_unless(!strcmp(opts->filter_rules->sni, "example.com"), "site not example.com");
987 	fail_unless(!strcmp(opts->filter_rules->cn, "example.com"), "site not example.com");
988 	fail_unless(!opts->filter_rules->ip, "ip set");
989 	fail_unless(!strcmp(opts->filter_rules->user, "root"), "user not root");
990 	fail_unless(!opts->filter_rules->all_conns, "all_conns not 0");
991 	fail_unless(!opts->filter_rules->desc, "desc set");
992 	fail_unless(!opts->filter_rules->next, "next set");
993 
994 	ps = filter_rule_str(opts->filter_rules);
995 	fail_unless(!strcmp(ps, "filter rule 0: sni=example.com, dstport=, srcip=, user=root, desc=, exact=site||||, all=|||, action=||pass||, log=|||||, precedence=3\n"
996 		"filter rule 0: cn=example.com, dstport=, srcip=, user=root, desc=, exact=site||||, all=|||, action=||pass||, log=|||||, precedence=3\n"),
997 		"failed parsing passite example.com root: %s", ps);
998 	free(ps);
999 
1000 	opts_free(opts);
1001 	conn_opts_free(conn_opts);
1002 }
1003 END_TEST
1004 
START_TEST(opts_set_passsite_04)1005 START_TEST(opts_set_passsite_04)
1006 {
1007 	char *ps;
1008 	opts_t *opts = opts_new();
1009 	conn_opts_t *conn_opts = conn_opts_new();
1010 
1011 	conn_opts->user_auth = 1;
1012 
1013 	char *s = strdup("*.google.com * android");
1014 	UNUSED int rv = filter_passsite_set(opts, conn_opts, s, 0);
1015 	free(s);
1016 
1017 	fail_unless(!strcmp(opts->filter_rules->sni, "*.google.com"), "site not *.google.com");
1018 	fail_unless(!strcmp(opts->filter_rules->cn, "*.google.com"), "site not *.google.com");
1019 	fail_unless(!opts->filter_rules->ip, "ip set");
1020 	fail_unless(!opts->filter_rules->user, "user set");
1021 	fail_unless(!opts->filter_rules->all_conns, "all_conns not 0");
1022 	fail_unless(opts->filter_rules->all_users, "all_users not 1");
1023 	fail_unless(!strcmp(opts->filter_rules->desc, "android"), "desc not android");
1024 	fail_unless(!opts->filter_rules->next, "next set");
1025 
1026 	ps = filter_rule_str(opts->filter_rules);
1027 	fail_unless(!strcmp(ps, "filter rule 0: sni=*.google.com, dstport=, srcip=, user=, desc=android, exact=site||||, all=|users||, action=||pass||, log=|||||, precedence=3\n"
1028 		"filter rule 0: cn=*.google.com, dstport=, srcip=, user=, desc=android, exact=site||||, all=|users||, action=||pass||, log=|||||, precedence=3\n"),
1029 		"failed parsing passite *.google.com * android: %s", ps);
1030 	free(ps);
1031 
1032 	opts_free(opts);
1033 	conn_opts_free(conn_opts);
1034 }
1035 END_TEST
1036 #endif /* !WITHOUT_USERAUTH */
1037 
START_TEST(opts_set_passsite_05)1038 START_TEST(opts_set_passsite_05)
1039 {
1040 	char *ps;
1041 	char *s;
1042 	opts_t *opts = opts_new();
1043 	conn_opts_t *conn_opts = conn_opts_new();
1044 
1045 	// Dup string using strdup(), otherwise strtok_r() in opts_set_passsite() will cause segmentation fault
1046 	s = strdup("example.com");
1047 	UNUSED int rv = filter_passsite_set(opts, conn_opts, s, 0);
1048 	free(s);
1049 	fail_unless(!opts->filter_rules->next, "next set");
1050 
1051 	s = strdup("example.com *");
1052 	rv = filter_passsite_set(opts, conn_opts, s, 1);
1053 	free(s);
1054 	fail_unless(opts->filter_rules->next, "next not set");
1055 	fail_unless(!opts->filter_rules->next->next, "next->next set");
1056 
1057 	s = strdup("example.com 192.168.0.1");
1058 	rv = filter_passsite_set(opts, conn_opts, s, 2);
1059 	free(s);
1060 	fail_unless(opts->filter_rules->next, "next not set");
1061 	fail_unless(opts->filter_rules->next->next, "next->next not set");
1062 	fail_unless(!opts->filter_rules->next->next->next, "next->next->next set");
1063 
1064 #ifndef WITHOUT_USERAUTH
1065 	conn_opts->user_auth = 1;
1066 
1067 	// Use root user, opts_set_passsite() calls sys_isuser() to validate the user
1068 	s = strdup("example.com root");
1069 	rv = filter_passsite_set(opts, conn_opts, s, 3);
1070 	free(s);
1071 	fail_unless(opts->filter_rules->next, "next not set");
1072 	fail_unless(opts->filter_rules->next->next, "next->next not set");
1073 	fail_unless(opts->filter_rules->next->next->next, "next->next->next not set");
1074 	fail_unless(!opts->filter_rules->next->next->next->next, "next->next->next->next set");
1075 
1076 	s = strdup("*.google.com * android");
1077 	rv = filter_passsite_set(opts, conn_opts, s, 4);
1078 	free(s);
1079 #endif /* !WITHOUT_USERAUTH */
1080 	ps = filter_rule_str(opts->filter_rules);
1081 	fail_unless(opts->filter_rules->next, "next not set");
1082 	fail_unless(opts->filter_rules->next->next, "next->next not set");
1083 #ifndef WITHOUT_USERAUTH
1084 	fail_unless(opts->filter_rules->next->next->next, "next->next->next not set");
1085 	fail_unless(opts->filter_rules->next->next->next->next, "next->next->next->next not set");
1086 	fail_unless(!opts->filter_rules->next->next->next->next->next, "next->next->next->next->next set");
1087 	fail_unless(!strcmp(ps, "filter rule 0: sni=example.com, dstport=, srcip=, user=, desc=, exact=site||||, all=conns|||, action=||pass||, log=|||||, precedence=1\n"
1088 		"filter rule 0: cn=example.com, dstport=, srcip=, user=, desc=, exact=site||||, all=conns|||, action=||pass||, log=|||||, precedence=1\n"
1089 		"filter rule 1: sni=example.com, dstport=, srcip=, user=, desc=, exact=site||||, all=|users||, action=||pass||, log=|||||, precedence=2\n"
1090 		"filter rule 1: cn=example.com, dstport=, srcip=, user=, desc=, exact=site||||, all=|users||, action=||pass||, log=|||||, precedence=2\n"
1091 		"filter rule 2: sni=example.com, dstport=, srcip=192.168.0.1, user=, desc=, exact=site||||, all=|||, action=||pass||, log=|||||, precedence=2\n"
1092 		"filter rule 2: cn=example.com, dstport=, srcip=192.168.0.1, user=, desc=, exact=site||||, all=|||, action=||pass||, log=|||||, precedence=2\n"
1093 		"filter rule 3: sni=example.com, dstport=, srcip=, user=root, desc=, exact=site||||, all=|||, action=||pass||, log=|||||, precedence=3\n"
1094 		"filter rule 3: cn=example.com, dstport=, srcip=, user=root, desc=, exact=site||||, all=|||, action=||pass||, log=|||||, precedence=3\n"
1095 		"filter rule 4: sni=*.google.com, dstport=, srcip=, user=, desc=android, exact=site||||, all=|users||, action=||pass||, log=|||||, precedence=3\n"
1096 		"filter rule 4: cn=*.google.com, dstport=, srcip=, user=, desc=android, exact=site||||, all=|users||, action=||pass||, log=|||||, precedence=3\n"),
1097 		"failed parsing multiple passites: %s", ps);
1098 #else /* WITHOUT_USERAUTH */
1099 	fail_unless(!opts->filter_rules->next->next->next, "next->next->next set");
1100 	fail_unless(!strcmp(ps, "filter rule 0: sni=example.com, dstport=, srcip=, exact=site||, all=conns||, action=||pass||, log=|||||, precedence=1\n"
1101 		"filter rule 0: cn=example.com, dstport=, srcip=, exact=site||, all=conns||, action=||pass||, log=|||||, precedence=1\n"
1102 		"filter rule 1: sni=example.com, dstport=, srcip=, exact=site||, all=conns||, action=||pass||, log=|||||, precedence=1\n"
1103 		"filter rule 1: cn=example.com, dstport=, srcip=, exact=site||, all=conns||, action=||pass||, log=|||||, precedence=1\n"
1104 		"filter rule 2: sni=example.com, dstport=, srcip=192.168.0.1, exact=site||, all=||, action=||pass||, log=|||||, precedence=2\n"
1105 		"filter rule 2: cn=example.com, dstport=, srcip=192.168.0.1, exact=site||, all=||, action=||pass||, log=|||||, precedence=2\n"),
1106 		"failed parsing multiple passites: %s", ps);
1107 #endif /* WITHOUT_USERAUTH */
1108 	free(ps);
1109 
1110 	opts_free(opts);
1111 	conn_opts_free(conn_opts);
1112 }
1113 END_TEST
1114 
START_TEST(opts_is_yesno_01)1115 START_TEST(opts_is_yesno_01)
1116 {
1117 	int yes;
1118 
1119 	yes = is_yesno("yes");
1120 	fail_unless(yes == 1, "failed yes");
1121 
1122 	yes = is_yesno("ye");
1123 	fail_unless(yes == -1, "failed ye");
1124 
1125 	yes = is_yesno("yes1");
1126 	fail_unless(yes == -1, "failed yes1");
1127 
1128 	yes = is_yesno("");
1129 	fail_unless(yes == -1, "failed empty string");
1130 }
1131 END_TEST
1132 
START_TEST(opts_is_yesno_02)1133 START_TEST(opts_is_yesno_02)
1134 {
1135 	int yes;
1136 
1137 	yes = is_yesno("no");
1138 	fail_unless(yes == 0, "failed no");
1139 
1140 	yes = is_yesno("n");
1141 	fail_unless(yes == -1, "failed n");
1142 
1143 	yes = is_yesno("no1");
1144 	fail_unless(yes == -1, "failed no1");
1145 }
1146 END_TEST
1147 
START_TEST(opts_get_name_value_01)1148 START_TEST(opts_get_name_value_01)
1149 {
1150 	int retval;
1151 	char *name;
1152 	char *value;
1153 
1154 	name = strdup("Name Value");
1155 	retval = get_name_value(name, &value, ' ', 0);
1156 	fail_unless(!strcmp(name, "Name"), "failed parsing name");
1157 	fail_unless(!strcmp(value, "Value"), "failed parsing value");
1158 	fail_unless(retval == 0, "failed parsing name value");
1159 	free(name);
1160 
1161 	name = strdup("Name  Value");
1162 	retval = get_name_value(name, &value, ' ', 0);
1163 	fail_unless(!strcmp(name, "Name"), "failed parsing name");
1164 	fail_unless(!strcmp(value, "Value"), "failed parsing value");
1165 	fail_unless(retval == 0, "failed parsing name value");
1166 	free(name);
1167 
1168 	close(2);
1169 
1170 	// Leading white space must be handled by the caller
1171 	// We cannot modify the name pointer, so we return -1
1172 	// So we don't actually need a test for " Name Value", or similar
1173 	name = strdup(" Name Value");
1174 	retval = get_name_value(name, &value, ' ', 0);
1175 	fail_unless(!strcmp(name, ""), "failed parsing name");
1176 	fail_unless(!strcmp(value, ""), "failed parsing value");
1177 	fail_unless(retval == -1, "failed rejecting leading white space, empty name");
1178 	free(name);
1179 
1180 	name = strdup("Name Value ");
1181 	retval = get_name_value(name, &value, ' ', 0);
1182 	fail_unless(!strcmp(name, "Name"), "failed parsing name");
1183 	fail_unless(!strcmp(value, "Value"), "failed parsing value");
1184 	fail_unless(retval == 0, "failed parsing name value");
1185 	free(name);
1186 
1187 	name = strdup("Name=Value");
1188 	retval = get_name_value(name, &value, '=', 0);
1189 	fail_unless(!strcmp(name, "Name"), "failed parsing name");
1190 	fail_unless(!strcmp(value, "Value"), "failed parsing value");
1191 	fail_unless(retval == 0, "failed parsing name value");
1192 	free(name);
1193 
1194 	// Leading white space must be handled by the caller
1195 	// We cannot modify the name pointer, so we return -1
1196 	// So we don't actually need a test for " Name Value", or similar
1197 	name = strdup(" Name=Value");
1198 	retval = get_name_value(name, &value, ' ', 0);
1199 	fail_unless(!strcmp(name, ""), "failed parsing name");
1200 	fail_unless(!strcmp(value, ""), "failed parsing value");
1201 	fail_unless(retval == -1, "failed rejecting leading white space, empty name");
1202 	free(name);
1203 
1204 	name = strdup("Name=Value ");
1205 	retval = get_name_value(name, &value, '=', 0);
1206 	fail_unless(!strcmp(name, "Name"), "failed parsing name");
1207 	fail_unless(!strcmp(value, "Value"), "failed parsing value");
1208 	fail_unless(retval == 0, "failed parsing name value");
1209 	free(name);
1210 
1211 	name = strdup("Name = Value");
1212 	retval = get_name_value(name, &value, '=', 0);
1213 	fail_unless(!strcmp(name, "Name"), "failed parsing name");
1214 	fail_unless(!strcmp(value, "Value"), "failed parsing value");
1215 	fail_unless(retval == 0, "failed parsing name value");
1216 	free(name);
1217 
1218 	name = strdup("Name = Value ");
1219 	retval = get_name_value(name, &value, '=', 0);
1220 	fail_unless(!strcmp(name, "Name"), "failed parsing name");
1221 	fail_unless(!strcmp(value, "Value"), "failed parsing value");
1222 	fail_unless(retval == 0, "failed parsing name value");
1223 	free(name);
1224 
1225 	// Name without value, e.g. '}' char is used for marking the end of structured proxyspecs
1226 	// so do not reject any form of just name, return success
1227 	name = strdup("Name");
1228 	retval = get_name_value(name, &value, ' ', 0);
1229 	fail_unless(!strcmp(name, "Name"), "failed parsing name");
1230 	fail_unless(!strcmp(value, ""), "failed parsing value");
1231 	fail_unless(retval == 0, "failed parsing just name");
1232 	free(name);
1233 
1234 	name = strdup("Name ");
1235 	retval = get_name_value(name, &value, ' ', 0);
1236 	fail_unless(!strcmp(name, "Name"), "failed parsing name");
1237 	fail_unless(!strcmp(value, ""), "failed parsing value");
1238 	fail_unless(retval == 0, "failed parsing name empty value");
1239 	free(name);
1240 
1241 	name = strdup("Name  ");
1242 	retval = get_name_value(name, &value, ' ', 0);
1243 	fail_unless(!strcmp(name, "Name"), "failed parsing name");
1244 	fail_unless(!strcmp(value, ""), "failed parsing value");
1245 	fail_unless(retval == 0, "failed parsing name empty value");
1246 	free(name);
1247 
1248 	name = strdup("Name");
1249 	retval = get_name_value(name, &value, '=', 0);
1250 	fail_unless(!strcmp(name, "Name"), "failed parsing name");
1251 	fail_unless(!strcmp(value, ""), "failed parsing value");
1252 	fail_unless(retval == 0, "failed parsing name empty value");
1253 	free(name);
1254 
1255 	name = strdup("Name=");
1256 	retval = get_name_value(name, &value, '=', 0);
1257 	fail_unless(!strcmp(name, "Name"), "failed parsing name");
1258 	fail_unless(!strcmp(value, ""), "failed parsing value");
1259 	fail_unless(retval == 0, "failed parsing name empty value");
1260 	free(name);
1261 
1262 	name = strdup("Name= ");
1263 	retval = get_name_value(name, &value, '=', 0);
1264 	fail_unless(!strcmp(name, "Name"), "failed parsing name");
1265 	fail_unless(!strcmp(value, ""), "failed parsing value");
1266 	fail_unless(retval == 0, "failed parsing name empty value");
1267 	free(name);
1268 
1269 	name = strdup("Name =");
1270 	retval = get_name_value(name, &value, '=', 0);
1271 	fail_unless(!strcmp(name, "Name"), "failed parsing name");
1272 	fail_unless(!strcmp(value, ""), "failed parsing value");
1273 	fail_unless(retval == 0, "failed parsing name empty value");
1274 	free(name);
1275 
1276 	name = strdup("Name = ");
1277 	retval = get_name_value(name, &value, '=', 0);
1278 	fail_unless(!strcmp(name, "Name"), "failed parsing name");
1279 	fail_unless(!strcmp(value, ""), "failed parsing value");
1280 	fail_unless(retval == 0, "failed parsing name empty value");
1281 	free(name);
1282 }
1283 END_TEST
1284 
1285 Suite *
opts_suite(void)1286 opts_suite(void)
1287 {
1288 	Suite *s;
1289 	TCase *tc;
1290 	s = suite_create("opts");
1291 
1292 	tc = tcase_create("proxyspec_parse");
1293 	tcase_add_test(tc, proxyspec_parse_01);
1294 #ifndef TRAVIS
1295 	tcase_add_test(tc, proxyspec_parse_02); /* IPv6 */
1296 #endif /* !TRAVIS */
1297 	tcase_add_test(tc, proxyspec_parse_03);
1298 	tcase_add_test(tc, proxyspec_parse_04);
1299 	tcase_add_test(tc, proxyspec_parse_05);
1300 	tcase_add_test(tc, proxyspec_parse_06);
1301 	tcase_add_test(tc, proxyspec_parse_07);
1302 	tcase_add_test(tc, proxyspec_parse_08);
1303 #ifndef TRAVIS
1304 	tcase_add_test(tc, proxyspec_parse_09); /* IPv6 */
1305 	tcase_add_test(tc, proxyspec_parse_10); /* IPv6 */
1306 #endif /* !TRAVIS */
1307 	tcase_add_test(tc, proxyspec_parse_11);
1308 	tcase_add_test(tc, proxyspec_parse_12);
1309 	tcase_add_test(tc, proxyspec_parse_13);
1310 	tcase_add_test(tc, proxyspec_set_proto_01);
1311 	tcase_add_test(tc, proxyspec_struct_parse_01);
1312 	suite_add_tcase(s, tc);
1313 
1314 	tc = tcase_create("opts_config");
1315 	tcase_add_test(tc, opts_debug_01);
1316 	tcase_add_test(tc, opts_set_passsite_01);
1317 	tcase_add_test(tc, opts_set_passsite_02);
1318 #ifndef WITHOUT_USERAUTH
1319 	tcase_add_test(tc, opts_set_passsite_03);
1320 	tcase_add_test(tc, opts_set_passsite_04);
1321 #endif /* !WITHOUT_USERAUTH */
1322 	tcase_add_test(tc, opts_set_passsite_05);
1323 	tcase_add_test(tc, opts_is_yesno_01);
1324 	tcase_add_test(tc, opts_is_yesno_02);
1325 	tcase_add_test(tc, opts_get_name_value_01);
1326 	suite_add_tcase(s, tc);
1327 
1328 #ifdef TRAVIS
1329 	fprintf(stderr, "opts: 3 tests omitted because building in travis\n");
1330 #endif
1331 
1332 	return s;
1333 }
1334 
1335 /* vim: set noet ft=c: */
1336