7 use Getopt::Long 'GetOptions';
10 #==================== config =====================
11 my $logfile = 'test.log';
12 my $local_key_file = 'local_spa.key';
13 my $output_dir = 'output';
14 my $lib_dir = '../lib/.libs';
15 my $conf_dir = 'conf';
17 my $configure_path = '../configure';
18 my $cmd_out_tmp = 'cmd.out';
19 my $server_cmd_tmp = 'server_cmd.out';
20 my $gpg_client_home_dir = "$conf_dir/client-gpg";
21 my $gpg_client_home_dir_no_pw = "$conf_dir/client-gpg-no-pw";
24 'nat' => "$conf_dir/nat_fwknopd.conf",
25 'def' => "$conf_dir/default_fwknopd.conf",
26 'def_access' => "$conf_dir/default_access.conf",
27 'exp_access' => "$conf_dir/expired_stanza_access.conf",
28 'future_exp_access' => "$conf_dir/future_expired_stanza_access.conf",
29 'exp_epoch_access' => "$conf_dir/expired_epoch_stanza_access.conf",
30 'invalid_exp_access' => "$conf_dir/invalid_expire_access.conf",
31 'force_nat_access' => "$conf_dir/force_nat_access.conf",
32 'local_nat' => "$conf_dir/local_nat_fwknopd.conf",
33 'ipfw_active_expire' => "$conf_dir/ipfw_active_expire_equal_fwknopd.conf",
34 'dual_key_access' => "$conf_dir/dual_key_usage_access.conf",
35 'gpg_access' => "$conf_dir/gpg_access.conf",
36 'gpg_no_pw_access' => "$conf_dir/gpg_no_pw_access.conf",
37 'open_ports_access' => "$conf_dir/open_ports_access.conf",
38 'multi_gpg_access' => "$conf_dir/multi_gpg_access.conf",
39 'multi_stanza_access' => "$conf_dir/multi_stanzas_access.conf",
40 'broken_keys_access' => "$conf_dir/multi_stanzas_with_broken_keys.conf",
41 'open_ports_mismatch' => "$conf_dir/mismatch_open_ports_access.conf",
42 'require_user_access' => "$conf_dir/require_user_access.conf",
43 'user_mismatch_access' => "$conf_dir/mismatch_user_access.conf",
44 'require_src_access' => "$conf_dir/require_src_access.conf",
45 'no_src_match' => "$conf_dir/no_source_match_access.conf",
46 'no_subnet_match' => "$conf_dir/no_subnet_source_match_access.conf",
47 'no_multi_src' => "$conf_dir/no_multi_source_match_access.conf",
48 'multi_src_access' => "$conf_dir/multi_source_match_access.conf",
49 'ip_src_match' => "$conf_dir/ip_source_match_access.conf",
50 'subnet_src_match' => "$conf_dir/ip_source_match_access.conf",
51 'disable_aging' => "$conf_dir/disable_aging_fwknopd.conf",
54 my $default_digest_file = "$run_dir/digest.cache";
55 my $default_pid_file = "$run_dir/fwknopd.pid";
57 my $fwknopCmd = '../client/.libs/fwknop';
58 my $fwknopdCmd = '../server/.libs/fwknopd';
59 my $libfko_bin = "$lib_dir/libfko.so"; ### this is usually a link
60 my $valgrindCmd = '/usr/bin/valgrind';
62 my $gpg_server_key = '361BBAD4';
63 my $gpg_client_key = '6A3FAD56';
65 my $loopback_ip = '127.0.0.1';
66 my $fake_ip = '127.0.0.2';
67 my $internal_nat_host = '192.168.1.2';
68 my $force_nat_host = '192.168.1.123';
69 my $default_spa_port = 62201;
70 my $non_std_spa_port = 12345;
72 my $spoof_user = 'testuser';
73 #================== end config ===================
78 my $test_include = '';
79 my @tests_to_include = ();
80 my $test_exclude = '';
81 my @tests_to_exclude = ();
82 my %valgrind_flagged_fcns = ();
83 my %valgrind_flagged_fcns_unique = ();
87 my $loopback_intf = '';
88 my $anonymize_results = 0;
89 my $current_test_file = "$output_dir/init";
90 my $tarfile = 'test_fwknop.tar.gz';
91 my $server_test_file = '';
93 my $valgrind_str = '';
94 my $enable_client_ip_resolve_test = 0;
95 my $saved_last_results = 0;
97 my $enable_recompilation_warnings_check = 0;
98 my $enable_make_distcheck = 0;
105 my $USE_PREDEF_PKTS = 1;
109 my $NEW_RULE_REQUIRED = 1;
110 my $REQUIRE_NO_NEW_RULE = 2;
111 my $NEW_RULE_REMOVED = 1;
112 my $REQUIRE_NO_NEW_REMOVED = 2;
120 my $ip_re = qr|(?:[0-2]?\d{1,2}\.){3}[0-2]?\d{1,2}|; ### IPv4
124 exit 1 unless GetOptions(
125 'Anonymize-results' => \$anonymize_results,
126 'fwknop-path=s' => \$fwknopCmd,
127 'fwknopd-path=s' => \$fwknopdCmd,
128 'libfko-path=s' => \$libfko_bin,
129 'loopback-intf=s' => \$loopback_intf,
130 'test-include=s' => \$test_include,
131 'include=s' => \$test_include, ### synonym
132 'test-exclude=s' => \$test_exclude,
133 'exclude=s' => \$test_exclude, ### synonym
134 'enable-recompile-check' => \$enable_recompilation_warnings_check,
135 'enable-ip-resolve' => \$enable_client_ip_resolve_test,
136 'enable-distcheck' => \$enable_make_distcheck,
137 'List-mode' => \$list_mode,
138 'enable-valgrind' => \$use_valgrind,
139 'valgrind-path=s' => \$valgrindCmd,
140 'output-dir=s' => \$output_dir,
141 'diff' => \$diff_mode,
142 'diff-dir1=s' => \$diff_dir1,
143 'diff-dir2=s' => \$diff_dir2,
149 ### create an anonymized tar file of test suite results that can be
150 ### emailed around to assist in debugging fwknop communications
151 exit &anonymize_results() if $anonymize_results;
153 &identify_loopback_intf();
155 $valgrind_str = "$valgrindCmd --leak-check=full " .
156 "--show-reachable=yes --track-origins=yes" if $use_valgrind;
158 my $intf_str = "-i $loopback_intf --foreground --verbose --verbose";
160 my $default_client_args = "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
161 "$fwknopCmd -A tcp/22 -a $fake_ip -D $loopback_ip --get-key " .
162 "$local_key_file --verbose --verbose";
164 my $client_ip_resolve_args = "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
165 "$fwknopCmd -A tcp/22 -R -D $loopback_ip --get-key " .
166 "$local_key_file --verbose --verbose";
168 my $default_client_gpg_args = "$default_client_args " .
169 "--gpg-recipient-key $gpg_server_key " .
170 "--gpg-signer-key $gpg_client_key " .
171 "--gpg-home-dir $gpg_client_home_dir";
173 my $default_client_gpg_args_no_homedir = "$default_client_args " .
174 "--gpg-recipient-key $gpg_server_key " .
175 "--gpg-signer-key $gpg_client_key ";
177 my $default_server_conf_args = "-c $cf{'def'} -a $cf{'def_access'} " .
178 "-d $default_digest_file -p $default_pid_file";
180 my $default_server_gpg_args = "LD_LIBRARY_PATH=$lib_dir " .
181 "$valgrind_str $fwknopdCmd -c $cf{'def'} " .
182 "-a $cf{'gpg_access'} $intf_str " .
183 "-d $default_digest_file -p $default_pid_file";
185 my $default_server_gpg_args_no_pw = "LD_LIBRARY_PATH=$lib_dir " .
186 "$valgrind_str $fwknopdCmd -c $cf{'def'} " .
187 "-a $cf{'gpg_no_pw_access'} $intf_str " .
188 "-d $default_digest_file -p $default_pid_file";
190 ### point the compiled binaries at the local libary path
191 ### instead of any installed libfko instance
192 $ENV{'LD_LIBRARY_PATH'} = $lib_dir;
194 ### main array that defines the tests we will run
197 'category' => 'recompilation',
198 'detail' => 'recompile and look for compilation warnings',
199 'err_msg' => 'compile warnings exist',
200 'function' => \&compile_warnings,
204 'category' => 'make distcheck',
205 'detail' => 'ensure proper distribution creation',
206 'err_msg' => 'could not create proper tarball',
207 'function' => \&make_distcheck,
211 'category' => 'build',
212 'subcategory' => 'client',
213 'detail' => 'binary exists',
214 'err_msg' => 'binary not found',
215 'function' => \&binary_exists,
216 'binary' => $fwknopCmd,
220 'category' => 'build security',
221 'subcategory' => 'client',
222 'detail' => 'Position Independent Executable (PIE)',
223 'err_msg' => 'non PIE binary (fwknop client)',
224 'function' => \&pie_binary,
225 'binary' => $fwknopCmd,
229 'category' => 'build security',
230 'subcategory' => 'client',
231 'detail' => 'stack protected binary',
232 'err_msg' => 'non stack protected binary (fwknop client)',
233 'function' => \&stack_protected_binary,
234 'binary' => $fwknopCmd,
238 'category' => 'build security',
239 'subcategory' => 'client',
240 'detail' => 'fortify source functions',
241 'err_msg' => 'source functions not fortified (fwknop client)',
242 'function' => \&fortify_source_functions,
243 'binary' => $fwknopCmd,
247 'category' => 'build security',
248 'subcategory' => 'client',
249 'detail' => 'read-only relocations',
250 'err_msg' => 'no read-only relocations (fwknop client)',
251 'function' => \&read_only_relocations,
252 'binary' => $fwknopCmd,
256 'category' => 'build security',
257 'subcategory' => 'client',
258 'detail' => 'immediate binding',
259 'err_msg' => 'no immediate binding (fwknop client)',
260 'function' => \&immediate_binding,
261 'binary' => $fwknopCmd,
266 'category' => 'build',
267 'subcategory' => 'server',
268 'detail' => 'binary exists',
269 'err_msg' => 'binary not found',
270 'function' => \&binary_exists,
271 'binary' => $fwknopdCmd,
276 'category' => 'build security',
277 'subcategory' => 'server',
278 'detail' => 'Position Independent Executable (PIE)',
279 'err_msg' => 'non PIE binary (fwknopd server)',
280 'function' => \&pie_binary,
281 'binary' => $fwknopdCmd,
285 'category' => 'build security',
286 'subcategory' => 'server',
287 'detail' => 'stack protected binary',
288 'err_msg' => 'non stack protected binary (fwknopd server)',
289 'function' => \&stack_protected_binary,
290 'binary' => $fwknopdCmd,
294 'category' => 'build security',
295 'subcategory' => 'server',
296 'detail' => 'fortify source functions',
297 'err_msg' => 'source functions not fortified (fwknopd server)',
298 'function' => \&fortify_source_functions,
299 'binary' => $fwknopdCmd,
303 'category' => 'build security',
304 'subcategory' => 'server',
305 'detail' => 'read-only relocations',
306 'err_msg' => 'no read-only relocations (fwknopd server)',
307 'function' => \&read_only_relocations,
308 'binary' => $fwknopdCmd,
312 'category' => 'build security',
313 'subcategory' => 'server',
314 'detail' => 'immediate binding',
315 'err_msg' => 'no immediate binding (fwknopd server)',
316 'function' => \&immediate_binding,
317 'binary' => $fwknopdCmd,
322 'category' => 'build',
323 'subcategory' => 'libfko',
324 'detail' => 'binary exists',
325 'err_msg' => 'binary not found',
326 'function' => \&binary_exists,
327 'binary' => $libfko_bin,
331 'category' => 'build security',
332 'subcategory' => 'libfko',
333 'detail' => 'stack protected binary',
334 'err_msg' => 'non stack protected binary (libfko)',
335 'function' => \&stack_protected_binary,
336 'binary' => $libfko_bin,
340 'category' => 'build security',
341 'subcategory' => 'libfko',
342 'detail' => 'fortify source functions',
343 'err_msg' => 'source functions not fortified (libfko)',
344 'function' => \&fortify_source_functions,
345 'binary' => $libfko_bin,
349 'category' => 'build security',
350 'subcategory' => 'libfko',
351 'detail' => 'read-only relocations',
352 'err_msg' => 'no read-only relocations (libfko)',
353 'function' => \&read_only_relocations,
354 'binary' => $libfko_bin,
358 'category' => 'build security',
359 'subcategory' => 'libfko',
360 'detail' => 'immediate binding',
361 'err_msg' => 'no immediate binding (libfko)',
362 'function' => \&immediate_binding,
363 'binary' => $libfko_bin,
368 'category' => 'preliminaries',
369 'subcategory' => 'client',
370 'detail' => 'usage info',
371 'err_msg' => 'could not get usage info',
372 'function' => \&generic_exec,
373 'cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str $fwknopCmd -h",
377 'category' => 'preliminaries',
378 'subcategory' => 'client',
379 'detail' => 'getopt() no such argument',
380 'err_msg' => 'getopt() allowed non-existant argument',
381 'function' => \&generic_exec,
382 'cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str $fwknopCmd --no-such-arg",
387 'category' => 'preliminaries',
388 'subcategory' => 'client',
389 'detail' => '--test mode, packet not sent',
390 'err_msg' => '--test mode, packet sent?',
391 'function' => \&generic_exec,
392 'positive_output_matches' => [qr/test\smode\senabled/],
393 'cmdline' => "$default_client_args --test",
398 'category' => 'preliminaries',
399 'subcategory' => 'client',
400 'detail' => 'expected code version',
401 'err_msg' => 'code version mis-match',
402 'function' => \&expected_code_version,
403 'cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str $fwknopCmd --version",
408 'category' => 'preliminaries',
409 'subcategory' => 'server',
410 'detail' => 'usage info',
411 'err_msg' => 'could not get usage info',
412 'function' => \&generic_exec,
413 'cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str $fwknopdCmd -h",
417 'category' => 'preliminaries',
418 'subcategory' => 'server',
419 'detail' => 'getopt() no such argument',
420 'err_msg' => 'getopt() allowed non-existant argument',
421 'function' => \&generic_exec,
422 'cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str $fwknopdCmd --no-such-arg",
428 'category' => 'preliminaries',
429 'subcategory' => 'server',
430 'detail' => 'expected code version',
431 'err_msg' => 'code version mis-match',
432 'function' => \&expected_code_version,
433 'cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
434 "$fwknopdCmd -c $cf{'def'} -a " .
435 "$cf{'def_access'} --version",
439 'category' => 'preliminaries',
440 'detail' => 'collecting system specifics',
441 'err_msg' => 'could not get complete system specs',
442 'function' => \&specs,
443 'binary' => $fwknopdCmd,
448 'category' => 'basic operations',
449 'detail' => 'dump config',
450 'err_msg' => 'could not dump configuration',
451 'function' => \&generic_exec,
452 'positive_output_matches' => [qr/SYSLOG_IDENTITY/],
454 'cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
455 "$fwknopdCmd -c $cf{'def'} " .
456 "-a $cf{'def_access'} --dump-config",
460 'category' => 'basic operations',
461 'detail' => 'override config',
462 'err_msg' => 'could not override configuration',
463 'function' => \&generic_exec,
464 'positive_output_matches' => [qr/ENABLE_PCAP_PROMISC.*\'Y\'/],
466 'cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
467 "$fwknopdCmd $default_server_conf_args " .
468 "-O $conf_dir/override_fwknopd.conf --dump-config",
473 'category' => 'basic operations',
474 'subcategory' => 'client',
475 'detail' => '--get-key path validation',
476 'err_msg' => 'accepted improper --get-key path',
477 'function' => \&generic_exec,
478 'positive_output_matches' => [qr/could\snot\sopen/i],
480 'cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
481 "$fwknopCmd -A tcp/22 -s $fake_ip " .
482 "-D $loopback_ip --get-key not/there",
486 'category' => 'basic operations',
487 'subcategory' => 'client',
488 'detail' => 'require [-s|-R|-a]',
489 'err_msg' => 'allowed null allow IP',
490 'function' => \&generic_exec,
491 'positive_output_matches' => [qr/must\suse\sone\sof/i],
493 'cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
494 "$fwknopCmd -D $loopback_ip",
498 'category' => 'basic operations',
499 'subcategory' => 'client',
500 'detail' => '--allow-ip <IP> valid IP',
501 'err_msg' => 'permitted invalid --allow-ip arg',
502 'function' => \&generic_exec,
503 'positive_output_matches' => [qr/Invalid\sallow\sIP\saddress/i],
505 'cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
506 "$fwknopCmd -A tcp/22 -a invalidIP -D $loopback_ip",
510 'category' => 'basic operations',
511 'subcategory' => 'client',
512 'detail' => '-A <proto>/<port> specification (proto)',
513 'err_msg' => 'permitted invalid -A <proto>/<port>',
514 'function' => \&generic_exec,
515 'positive_output_matches' => [qr/Invalid\sSPA\saccess\smessage/i],
517 'cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
518 "$fwknopCmd -A invalid/22 -a $fake_ip -D $loopback_ip",
522 'category' => 'basic operations',
523 'subcategory' => 'client',
524 'detail' => '-A <proto>/<port> specification (port)',
525 'err_msg' => 'permitted invalid -A <proto>/<port>',
526 'function' => \&generic_exec,
527 'positive_output_matches' => [qr/Invalid\sSPA\saccess\smessage/i],
529 'cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
530 "$fwknopCmd -A tcp/600001 -a $fake_ip -D $loopback_ip",
535 'category' => 'basic operations',
536 'subcategory' => 'client',
537 'detail' => 'generate SPA packet',
538 'err_msg' => 'could not generate SPA packet',
539 'function' => \&client_send_spa_packet,
540 'cmdline' => $default_client_args,
545 'category' => 'basic operations',
546 'subcategory' => 'server',
547 'detail' => 'list current fwknopd fw rules',
548 'err_msg' => 'could not list current fwknopd fw rules',
549 'function' => \&generic_exec,
550 'cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
551 "$fwknopdCmd $default_server_conf_args --fw-list",
555 'category' => 'basic operations',
556 'subcategory' => 'server',
557 'detail' => 'list all current fw rules',
558 'err_msg' => 'could not list all current fw rules',
559 'function' => \&generic_exec,
560 'cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
561 "$fwknopdCmd $default_server_conf_args --fw-list-all",
565 'category' => 'basic operations',
566 'subcategory' => 'server',
567 'detail' => 'flush current firewall rules',
568 'err_msg' => 'could not flush current fw rules',
569 'function' => \&generic_exec,
570 'cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
571 "$fwknopdCmd $default_server_conf_args --fw-flush",
576 'category' => 'basic operations',
577 'subcategory' => 'server',
579 'err_msg' => 'start error',
580 'function' => \&server_start,
581 'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
582 "$fwknopdCmd $default_server_conf_args $intf_str",
586 'category' => 'basic operations',
587 'subcategory' => 'server',
589 'err_msg' => 'stop error',
590 'function' => \&server_stop,
591 'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
592 "$fwknopdCmd $default_server_conf_args $intf_str",
596 'category' => 'basic operations',
597 'subcategory' => 'server',
598 'detail' => 'write PID',
599 'err_msg' => 'did not write PID',
600 'function' => \&write_pid,
601 'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
602 "$fwknopdCmd $default_server_conf_args $intf_str",
607 'category' => 'basic operations',
608 'subcategory' => 'server',
609 'detail' => '--packet-limit 1 exit',
610 'err_msg' => 'did not exit after one packet',
611 'function' => \&server_packet_limit,
612 'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
613 "$fwknopdCmd $default_server_conf_args --packet-limit 1 $intf_str",
617 'category' => 'basic operations',
618 'subcategory' => 'server',
619 'detail' => 'ignore packets < min SPA len (140)',
620 'err_msg' => 'did not ignore small packets',
621 'function' => \&server_ignore_small_packets,
622 'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
623 "$fwknopdCmd $default_server_conf_args --packet-limit 1 $intf_str",
627 'category' => 'basic operations',
628 'subcategory' => 'server',
629 'detail' => '-P bpf filter ignore packet',
630 'err_msg' => 'filter did not ignore packet',
631 'function' => \&server_bpf_ignore_packet,
632 'cmdline' => $default_client_args,
633 'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
634 "$fwknopdCmd $default_server_conf_args --packet-limit 1 $intf_str " .
635 qq|-P "udp port $non_std_spa_port"|,
640 'category' => 'Rijndael SPA',
641 'subcategory' => 'client+server',
642 'detail' => 'complete cycle (tcp/22 ssh)',
643 'err_msg' => 'could not complete SPA cycle',
644 'function' => \&spa_cycle,
645 'cmdline' => $default_client_args,
646 'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
647 "$fwknopdCmd $default_server_conf_args $intf_str",
648 'fw_rule_created' => $NEW_RULE_REQUIRED,
649 'fw_rule_removed' => $NEW_RULE_REMOVED,
653 'category' => 'Rijndael SPA',
654 'subcategory' => 'client+server',
655 'detail' => 'client IP resolve (tcp/22 ssh)',
656 'err_msg' => 'could not complete SPA cycle',
657 'function' => \&spa_cycle,
658 'cmdline' => $client_ip_resolve_args,
660 'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
661 "$fwknopdCmd $default_server_conf_args $intf_str",
662 'fw_rule_created' => $NEW_RULE_REQUIRED,
663 'fw_rule_removed' => $NEW_RULE_REMOVED,
668 'category' => 'Rijndael SPA',
669 'subcategory' => 'client+server',
670 'detail' => 'dual usage access key (tcp/80 http)',
671 'err_msg' => 'could not complete SPA cycle',
672 'function' => \&spa_cycle,
673 'cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
674 "$fwknopCmd -A tcp/80 -a $fake_ip -D $loopback_ip --get-key " .
675 "$local_key_file --verbose --verbose",
676 'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
677 "$fwknopdCmd -c $cf{'def'} -a $cf{'dual_key_access'} " .
678 "-d $default_digest_file -p $default_pid_file $intf_str",
679 ### check for the first stanza that does not allow tcp/80 - the
680 ### second stanza allows this
681 'server_positive_output_matches' => [qr/stanza #1\)\sOne\sor\smore\srequested\sprotocol\/ports\swas\sdenied/],
682 'fw_rule_created' => $NEW_RULE_REQUIRED,
683 'fw_rule_removed' => $NEW_RULE_REMOVED,
687 'category' => 'Rijndael SPA',
688 'subcategory' => 'client+server',
689 'detail' => 'packet aging (past) (tcp/22 ssh)',
690 'err_msg' => 'old SPA packet accepted',
691 'function' => \&spa_cycle,
692 'cmdline' => "$default_client_args --time-offset-minus 300s",
693 'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
694 "$fwknopdCmd $default_server_conf_args $intf_str",
695 'server_positive_output_matches' => [qr/SPA\sdata\stime\sdifference/],
696 'fw_rule_created' => $REQUIRE_NO_NEW_RULE,
700 'category' => 'Rijndael SPA',
701 'subcategory' => 'client+server',
702 'detail' => 'packet aging (future) (tcp/22 ssh)',
703 'err_msg' => 'future SPA packet accepted',
704 'function' => \&spa_cycle,
705 'cmdline' => "$default_client_args --time-offset-plus 300s",
706 'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
707 "$fwknopdCmd $default_server_conf_args $intf_str",
708 'server_positive_output_matches' => [qr/SPA\sdata\stime\sdifference/],
709 'fw_rule_created' => $REQUIRE_NO_NEW_RULE,
713 'category' => 'Rijndael SPA',
714 'subcategory' => 'client+server',
715 'detail' => 'expired stanza (tcp/22 ssh)',
716 'err_msg' => 'SPA packet accepted',
717 'function' => \&spa_cycle,
718 'cmdline' => $default_client_args,
719 'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
720 "$fwknopdCmd -c $cf{'def'} -a $cf{'exp_access'} " .
721 "-d $default_digest_file -p $default_pid_file $intf_str",
722 'server_positive_output_matches' => [qr/Access\sstanza\shas\sexpired/],
723 'fw_rule_created' => $REQUIRE_NO_NEW_RULE,
727 'category' => 'Rijndael SPA',
728 'subcategory' => 'client+server',
729 'detail' => 'invalid expire date (tcp/22 ssh)',
730 'err_msg' => 'SPA packet accepted',
731 'function' => \&spa_cycle,
732 'cmdline' => $default_client_args,
733 'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
734 "$fwknopdCmd -c $cf{'def'} -a $cf{'invalid_exp_access'} " .
735 "-d $default_digest_file -p $default_pid_file $intf_str",
736 'server_positive_output_matches' => [qr/invalid\sdate\svalue/],
737 'fw_rule_created' => $REQUIRE_NO_NEW_RULE,
741 'category' => 'Rijndael SPA',
742 'subcategory' => 'client+server',
743 'detail' => 'expired epoch stanza (tcp/22 ssh)',
744 'err_msg' => 'SPA packet accepted',
745 'function' => \&spa_cycle,
746 'cmdline' => $default_client_args,
747 'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
748 "$fwknopdCmd -c $cf{'def'} -a $cf{'exp_epoch_access'} " .
749 "-d $default_digest_file -p $default_pid_file $intf_str",
750 'server_positive_output_matches' => [qr/Access\sstanza\shas\sexpired/],
751 'fw_rule_created' => $REQUIRE_NO_NEW_RULE,
755 'category' => 'Rijndael SPA',
756 'subcategory' => 'client+server',
757 'detail' => 'future expired stanza (tcp/22 ssh)',
758 'err_msg' => 'SPA packet not accepted',
759 'function' => \&spa_cycle,
760 'cmdline' => $default_client_args,
761 'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
762 "$fwknopdCmd -c $cf{'def'} -a $cf{'future_exp_access'} " .
763 "-d $default_digest_file -p $default_pid_file $intf_str",
764 'fw_rule_created' => $NEW_RULE_REQUIRED,
765 'fw_rule_removed' => $NEW_RULE_REMOVED,
770 'category' => 'Rijndael SPA',
771 'subcategory' => 'client+server',
772 'detail' => 'OPEN_PORTS (tcp/22 ssh)',
773 'err_msg' => "improper OPEN_PORTS result",
774 'function' => \&spa_cycle,
775 'cmdline' => $default_client_args,
776 'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
777 "$fwknopdCmd -c $cf{'def'} -a $cf{'open_ports_access'} " .
778 "-d $default_digest_file -p $default_pid_file $intf_str",
779 'fw_rule_created' => $NEW_RULE_REQUIRED,
780 'fw_rule_removed' => $NEW_RULE_REMOVED,
784 'category' => 'Rijndael SPA',
785 'subcategory' => 'client+server',
786 'detail' => 'OPEN_PORTS mismatch',
787 'err_msg' => "SPA packet accepted",
788 'function' => \&spa_cycle,
789 'cmdline' => $default_client_args,
790 'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
791 "$fwknopdCmd -c $cf{'def'} -a $cf{'open_ports_mismatch'} " .
792 "-d $default_digest_file -p $default_pid_file $intf_str",
793 'server_positive_output_matches' => [qr/One\s+or\s+more\s+requested/],
794 'fw_rule_created' => $REQUIRE_NO_NEW_RULE,
798 'category' => 'Rijndael SPA',
799 'subcategory' => 'client+server',
800 'detail' => 'require user (tcp/22 ssh)',
801 'err_msg' => "missed require user criteria",
802 'function' => \&spa_cycle,
803 'cmdline' => "SPOOF_USER=$spoof_user $default_client_args",
804 'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
805 "$fwknopdCmd -c $cf{'def'} -a $cf{'require_user_access'} " .
806 "-d $default_digest_file -p $default_pid_file $intf_str",
807 'fw_rule_created' => $NEW_RULE_REQUIRED,
808 'fw_rule_removed' => $NEW_RULE_REMOVED,
812 'category' => 'Rijndael SPA',
813 'subcategory' => 'client+server',
814 'detail' => 'user mismatch (tcp/22 ssh)',
815 'err_msg' => "improper user accepted for access",
816 'function' => \&user_mismatch,
817 'function' => \&spa_cycle,
818 'cmdline' => $default_client_args,
819 'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
820 "$fwknopdCmd -c $cf{'def'} -a $cf{'user_mismatch_access'} " .
821 "-d $default_digest_file -p $default_pid_file $intf_str",
822 'server_positive_output_matches' => [qr/Username\s+in\s+SPA\s+data/],
823 'fw_rule_created' => $REQUIRE_NO_NEW_RULE,
827 'category' => 'Rijndael SPA',
828 'subcategory' => 'client+server',
829 'detail' => 'require src (tcp/22 ssh)',
830 'err_msg' => "fw rule not created",
831 'function' => \&spa_cycle,
832 'cmdline' => $default_client_args,
833 'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
834 "$fwknopdCmd -c $cf{'def'} -a $cf{'require_src_access'} " .
835 "-d $default_digest_file -p $default_pid_file $intf_str",
836 'fw_rule_created' => $NEW_RULE_REQUIRED,
837 'fw_rule_removed' => $NEW_RULE_REMOVED,
841 'category' => 'Rijndael SPA',
842 'subcategory' => 'client+server',
843 'detail' => 'mismatch require src (tcp/22 ssh)',
844 'err_msg' => "fw rule created",
845 'function' => \&spa_cycle,
846 'cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
847 "$fwknopCmd -A tcp/22 -s -D $loopback_ip --get-key " .
848 "$local_key_file --verbose --verbose",
849 'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
850 "$fwknopdCmd -c $cf{'def'} -a $cf{'require_src_access'} " .
851 "-d $default_digest_file -p $default_pid_file $intf_str",
852 'server_positive_output_matches' => [qr/Got\s0.0.0.0\swhen\svalid\ssource\sIP/],
853 'fw_rule_created' => $REQUIRE_NO_NEW_RULE,
858 'category' => 'Rijndael SPA',
859 'subcategory' => 'client+server',
860 'detail' => 'IP filtering (tcp/22 ssh)',
861 'err_msg' => "did not filter $loopback_ip",
862 'function' => \&spa_cycle,
863 'cmdline' => $default_client_args,
864 'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
865 "$fwknopdCmd -c $cf{'def'} -a $cf{'no_src_match'} " .
866 "-d $default_digest_file -p $default_pid_file $intf_str",
867 'server_positive_output_matches' => [qr/No\saccess\sdata\sfound/],
868 'fw_rule_created' => $REQUIRE_NO_NEW_RULE,
872 'category' => 'Rijndael SPA',
873 'subcategory' => 'client+server',
874 'detail' => 'subnet filtering (tcp/22 ssh)',
875 'err_msg' => "did not filter $loopback_ip",
876 'function' => \&spa_cycle,
877 'cmdline' => $default_client_args,
878 'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
879 "$fwknopdCmd -c $cf{'def'} -a $cf{'no_subnet_match'} " .
880 "-d $default_digest_file -p $default_pid_file $intf_str",
881 'server_positive_output_matches' => [qr/No\saccess\sdata\sfound/],
882 'fw_rule_created' => $REQUIRE_NO_NEW_RULE,
886 'category' => 'Rijndael SPA',
887 'subcategory' => 'client+server',
888 'detail' => 'IP+subnet filtering (tcp/22 ssh)',
889 'err_msg' => "did not filter $loopback_ip",
890 'function' => \&spa_cycle,
891 'cmdline' => $default_client_args,
892 'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
893 "$fwknopdCmd -c $cf{'def'} -a $cf{'no_multi_src'} " .
894 "-d $default_digest_file -p $default_pid_file $intf_str",
895 'server_positive_output_matches' => [qr/No\saccess\sdata\sfound/],
896 'fw_rule_created' => $REQUIRE_NO_NEW_RULE,
900 'category' => 'Rijndael SPA',
901 'subcategory' => 'client+server',
902 'detail' => 'IP match (tcp/22 ssh)',
903 'err_msg' => "did not filter $loopback_ip",
904 'function' => \&spa_cycle,
905 'cmdline' => $default_client_args,
906 'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
907 "$fwknopdCmd -c $cf{'def'} -a $cf{'ip_src_match'} " .
908 "-d $default_digest_file -p $default_pid_file $intf_str",
909 'fw_rule_created' => $NEW_RULE_REQUIRED,
910 'fw_rule_removed' => $NEW_RULE_REMOVED,
914 'category' => 'Rijndael SPA',
915 'subcategory' => 'client+server',
916 'detail' => 'subnet match (tcp/22 ssh)',
917 'err_msg' => "did not filter $loopback_ip",
918 'function' => \&spa_cycle,
919 'cmdline' => $default_client_args,
920 'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
921 "$fwknopdCmd -c $cf{'def'} -a $cf{'subnet_src_match'} " .
922 "-d $default_digest_file -p $default_pid_file $intf_str",
923 'fw_rule_created' => $NEW_RULE_REQUIRED,
924 'fw_rule_removed' => $NEW_RULE_REMOVED,
928 'category' => 'Rijndael SPA',
929 'subcategory' => 'client+server',
930 'detail' => 'multi IP/net match (tcp/22 ssh)',
931 'err_msg' => "did not filter $loopback_ip",
932 'function' => \&spa_cycle,
933 'cmdline' => $default_client_args,
934 'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
935 "$fwknopdCmd -c $cf{'def'} -a $cf{'multi_src_access'} " .
936 "-d $default_digest_file -p $default_pid_file $intf_str",
937 'fw_rule_created' => $NEW_RULE_REQUIRED,
938 'fw_rule_removed' => $NEW_RULE_REMOVED,
942 'category' => 'Rijndael SPA',
943 'subcategory' => 'client+server',
944 'detail' => 'multi access stanzas (tcp/22 ssh)',
945 'err_msg' => "could not complete SPA cycle",
946 'function' => \&spa_cycle,
947 'cmdline' => $default_client_args,
948 'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
949 "$fwknopdCmd -c $cf{'def'} -a $cf{'multi_stanza_access'} " .
950 "-d $default_digest_file -p $default_pid_file $intf_str",
951 'fw_rule_created' => $NEW_RULE_REQUIRED,
952 'fw_rule_removed' => $NEW_RULE_REMOVED,
956 'category' => 'Rijndael SPA',
957 'subcategory' => 'client+server',
958 'detail' => 'bad/good key stanzas (tcp/22 ssh)',
959 'err_msg' => "could not complete SPA cycle",
960 'function' => \&spa_cycle,
961 'cmdline' => $default_client_args,
962 'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
963 "$fwknopdCmd -c $cf{'def'} -a $cf{'broken_keys_access'} " .
964 "-d $default_digest_file -p $default_pid_file $intf_str",
965 'fw_rule_created' => $NEW_RULE_REQUIRED,
966 'fw_rule_removed' => $NEW_RULE_REMOVED,
971 'category' => 'Rijndael SPA',
972 'subcategory' => 'client+server',
973 'detail' => "non-enabled NAT (tcp/22 ssh)",
974 'err_msg' => "SPA packet not filtered",
975 'function' => \&spa_cycle,
976 'cmdline' => "$default_client_args -N $internal_nat_host:22",
977 'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
978 "$fwknopdCmd $default_server_conf_args $intf_str",
979 'server_positive_output_matches' => [qr/requested\sNAT\saccess.*not\senabled/i],
980 'server_conf' => $cf{'nat'},
981 'fw_rule_created' => $REQUIRE_NO_NEW_RULE,
985 'category' => 'Rijndael SPA',
986 'subcategory' => 'client+server',
987 'detail' => "NAT to $internal_nat_host (tcp/22 ssh)",
988 'err_msg' => "could not complete NAT SPA cycle",
989 'function' => \&spa_cycle,
990 'cmdline' => "$default_client_args -N $internal_nat_host:22",
991 'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
992 "$fwknopdCmd -c $cf{'nat'} -a $cf{'open_ports_access'} " .
993 "-d $default_digest_file -p $default_pid_file $intf_str",
994 'server_positive_output_matches' => [qr/to\:$internal_nat_host\:22/i],
995 'fw_rule_created' => $NEW_RULE_REQUIRED,
996 'fw_rule_removed' => $NEW_RULE_REMOVED,
997 'server_conf' => $cf{'nat'},
1001 'category' => 'Rijndael SPA',
1002 'subcategory' => 'client+server',
1003 'detail' => "force NAT $force_nat_host (tcp/22 ssh)",
1004 'err_msg' => "could not complete NAT SPA cycle",
1005 'function' => \&spa_cycle,
1006 'cmdline' => $default_client_args,
1007 'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
1008 "$fwknopdCmd -c $cf{'nat'} -a $cf{'force_nat_access'} " .
1009 "-d $default_digest_file -p $default_pid_file $intf_str",
1010 'server_positive_output_matches' => [qr/to\:$force_nat_host\:22/i],
1011 'server_negative_output_matches' => [qr/to\:$internal_nat_host\:22/i],
1012 'fw_rule_created' => $NEW_RULE_REQUIRED,
1013 'fw_rule_removed' => $NEW_RULE_REMOVED,
1014 'server_conf' => $cf{'nat'},
1018 'category' => 'Rijndael SPA',
1019 'subcategory' => 'client+server',
1020 'detail' => "local NAT $force_nat_host (tcp/22 ssh)",
1021 'err_msg' => "could not complete NAT SPA cycle",
1022 'function' => \&spa_cycle,
1023 'cmdline' => "$default_client_args --nat-local",
1024 'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
1025 "$fwknopdCmd -c $cf{'local_nat'} -a $cf{'force_nat_access'} " .
1026 "-d $default_digest_file -p $default_pid_file $intf_str",
1027 'server_positive_output_matches' => [qr/to\:$force_nat_host\:22/i,
1028 qr/FWKNOP_INPUT.*dport\s22.*\sACCEPT/],
1029 'server_negative_output_matches' => [qr/to\:$internal_nat_host\:22/i],
1030 'fw_rule_created' => $NEW_RULE_REQUIRED,
1031 'fw_rule_removed' => $NEW_RULE_REMOVED,
1032 'server_conf' => $cf{'nat'},
1036 'category' => 'Rijndael SPA',
1037 'subcategory' => 'client+server',
1038 'detail' => "local NAT non-FORCE_NAT (tcp/22 ssh)",
1039 'err_msg' => "could not complete NAT SPA cycle",
1040 'function' => \&spa_cycle,
1041 'cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
1042 "$fwknopCmd -A tcp/80 -a $fake_ip -D $loopback_ip --get-key " .
1043 "$local_key_file --verbose --verbose --nat-local --nat-port 22",
1044 'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
1045 "$fwknopdCmd -c $cf{'local_nat'} -a $cf{'def_access'} " .
1046 "-d $default_digest_file -p $default_pid_file $intf_str",
1047 'server_positive_output_matches' => [qr/to\:$loopback_ip\:22/i,
1048 qr/FWKNOP_INPUT.*dport\s22.*\sACCEPT/],
1049 'server_negative_output_matches' => [qr/to\:$internal_nat_host\:22/i],
1050 'fw_rule_created' => $NEW_RULE_REQUIRED,
1051 'fw_rule_removed' => $NEW_RULE_REMOVED,
1052 'server_conf' => $cf{'nat'},
1057 'category' => 'Rijndael SPA',
1058 'subcategory' => 'client+server',
1059 'detail' => 'complete cycle (tcp/23 telnet)',
1060 'err_msg' => 'could not complete SPA cycle',
1061 'function' => \&spa_cycle,
1062 'cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
1063 "$fwknopCmd -A tcp/23 -a $fake_ip -D $loopback_ip --get-key " .
1064 "$local_key_file --verbose --verbose",
1065 'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
1066 "$fwknopdCmd $default_server_conf_args $intf_str",
1067 'fw_rule_created' => $NEW_RULE_REQUIRED,
1068 'fw_rule_removed' => $NEW_RULE_REMOVED,
1072 'category' => 'Rijndael SPA',
1073 'subcategory' => 'client+server',
1074 'detail' => 'complete cycle (tcp/9418 git)',
1075 'err_msg' => 'could not complete SPA cycle',
1076 'function' => \&spa_cycle,
1077 'cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
1078 "$fwknopCmd -A tcp/9418 -a $fake_ip -D $loopback_ip --get-key " .
1079 "$local_key_file --verbose --verbose",
1080 'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
1081 "$fwknopdCmd $default_server_conf_args $intf_str",
1082 'fw_rule_created' => $NEW_RULE_REQUIRED,
1083 'fw_rule_removed' => $NEW_RULE_REMOVED,
1087 'category' => 'Rijndael SPA',
1088 'subcategory' => 'client+server',
1089 'detail' => 'complete cycle (tcp/60001)',
1090 'err_msg' => 'could not complete SPA cycle',
1091 'function' => \&spa_cycle,
1092 'cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
1093 "$fwknopCmd -A tcp/60001 -a $fake_ip -D $loopback_ip --get-key " .
1094 "$local_key_file --verbose --verbose",
1095 'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
1096 "$fwknopdCmd $default_server_conf_args $intf_str",
1097 'fw_rule_created' => $NEW_RULE_REQUIRED,
1098 'fw_rule_removed' => $NEW_RULE_REMOVED,
1102 'category' => 'Rijndael SPA',
1103 'subcategory' => 'client+server',
1104 'detail' => 'multi port (tcp/60001,udp/60001)',
1105 'err_msg' => 'could not complete SPA cycle',
1106 'function' => \&spa_cycle,
1107 'cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
1108 "$fwknopCmd -A tcp/60001,udp/60001 -a $fake_ip -D $loopback_ip --get-key " .
1109 "$local_key_file --verbose --verbose",
1110 'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
1111 "$fwknopdCmd $default_server_conf_args $intf_str",
1112 'fw_rule_created' => $NEW_RULE_REQUIRED,
1113 'fw_rule_removed' => $NEW_RULE_REMOVED,
1117 'category' => 'Rijndael SPA',
1118 'subcategory' => 'client+server',
1119 'detail' => 'multi port (tcp/22,udp/53,tcp/1234)',
1120 'err_msg' => 'could not complete SPA cycle',
1121 'function' => \&spa_cycle,
1122 'cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
1123 "$fwknopCmd -A tcp/22,udp/53,tcp/1234 -a $fake_ip -D $loopback_ip --get-key " .
1124 "$local_key_file --verbose --verbose",
1125 'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
1126 "$fwknopdCmd $default_server_conf_args $intf_str",
1127 'fw_rule_created' => $NEW_RULE_REQUIRED,
1128 'fw_rule_removed' => $NEW_RULE_REMOVED,
1133 'category' => 'Rijndael SPA',
1134 'subcategory' => 'client+server',
1135 'detail' => 'complete cycle (udp/53 dns)',
1136 'err_msg' => 'could not complete SPA cycle',
1137 'function' => \&spa_cycle,
1138 'cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
1139 "$fwknopCmd -A udp/53 -a $fake_ip -D $loopback_ip --get-key " .
1140 "$local_key_file --verbose --verbose",
1141 'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
1142 "$fwknopdCmd $default_server_conf_args $intf_str",
1143 'fw_rule_created' => $NEW_RULE_REQUIRED,
1144 'fw_rule_removed' => $NEW_RULE_REMOVED,
1148 'category' => 'Rijndael SPA',
1149 'subcategory' => 'client+server',
1150 'detail' => "-P bpf SPA over port $non_std_spa_port",
1151 'err_msg' => 'could not complete SPA cycle',
1152 'function' => \&spa_cycle,
1153 'cmdline' => "$default_client_args --server-port $non_std_spa_port",
1154 'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
1155 "$fwknopdCmd $default_server_conf_args $intf_str " .
1156 qq|-P "udp port $non_std_spa_port"|,
1157 'server_positive_output_matches' => [qr/PCAP\sfilter.*\s$non_std_spa_port/],
1158 'fw_rule_created' => $NEW_RULE_REQUIRED,
1159 'fw_rule_removed' => $NEW_RULE_REMOVED,
1164 'category' => 'Rijndael SPA',
1165 'subcategory' => 'client+server',
1166 'detail' => 'random SPA port (tcp/22 ssh)',
1167 'err_msg' => 'could not complete SPA cycle',
1168 'function' => \&spa_cycle,
1169 'cmdline' => "$default_client_args -r",
1170 'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
1171 "$fwknopdCmd $default_server_conf_args $intf_str " .
1173 'fw_rule_created' => $NEW_RULE_REQUIRED,
1174 'fw_rule_removed' => $NEW_RULE_REMOVED,
1179 'category' => 'Rijndael SPA',
1180 'subcategory' => 'client+server',
1181 'detail' => 'spoof username (tcp/22)',
1182 'err_msg' => 'could not spoof username',
1183 'function' => \&spoof_username,
1184 'cmdline' => "SPOOF_USER=$spoof_user LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
1185 "$fwknopCmd -A tcp/22 -a $fake_ip -D $loopback_ip --get-key " .
1186 "$local_key_file --verbose --verbose",
1187 'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
1188 "$fwknopdCmd $default_server_conf_args $intf_str",
1193 'category' => 'Rijndael SPA',
1194 'subcategory' => 'client+server',
1195 'detail' => 'replay attack detection',
1196 'err_msg' => 'could not detect replay attack',
1197 'function' => \&replay_detection,
1198 'cmdline' => $default_client_args,
1199 'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
1200 "$fwknopdCmd $default_server_conf_args $intf_str",
1201 'replay_positive_output_matches' => [qr/Replay\sdetected\sfrom\ssource\sIP/],
1205 'category' => 'Rijndael SPA',
1206 'subcategory' => 'client+server',
1207 'detail' => 'replay detection (Rijndael prefix)',
1208 'err_msg' => 'could not detect replay attack',
1209 'function' => \&replay_detection,
1210 'pkt_prefix' => 'U2FsdGVkX1',
1211 'cmdline' => $default_client_args,
1212 'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
1213 "$fwknopdCmd $default_server_conf_args $intf_str",
1214 'replay_positive_output_matches' => [qr/Data\sis\snot\sa\svalid\sSPA\smessage\sformat/],
1220 'category' => 'Rijndael SPA',
1221 'subcategory' => 'FUZZING',
1222 'detail' => 'overly long port value',
1223 'err_msg' => 'server crashed or did not detect error condition',
1224 'function' => \&overly_long_port,
1225 'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
1226 "$fwknopdCmd -c $cf{'disable_aging'} -a $cf{'def_access'} " .
1227 "-d $default_digest_file -p $default_pid_file $intf_str",
1231 'category' => 'Rijndael SPA',
1232 'subcategory' => 'FUZZING',
1233 'detail' => 'overly long proto value',
1234 'err_msg' => 'server crashed or did not detect error condition',
1235 'function' => \&overly_long_proto,
1236 'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
1237 "$fwknopdCmd -c $cf{'disable_aging'} -a $cf{'def_access'} " .
1238 "-d $default_digest_file -p $default_pid_file $intf_str",
1242 'category' => 'Rijndael SPA',
1243 'subcategory' => 'FUZZING',
1244 'detail' => 'negative port value',
1245 'err_msg' => 'server crashed or did not detect error condition',
1246 'function' => \&negative_port,
1247 'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
1248 "$fwknopdCmd -c $cf{'disable_aging'} -a $cf{'def_access'} " .
1249 "-d $default_digest_file -p $default_pid_file $intf_str",
1253 'category' => 'Rijndael SPA',
1254 'subcategory' => 'FUZZING',
1255 'detail' => 'null port value',
1256 'err_msg' => 'server crashed or did not detect error condition',
1257 'function' => \&null_port,
1258 'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
1259 "$fwknopdCmd -c $cf{'disable_aging'} -a $cf{'def_access'} " .
1260 "-d $default_digest_file -p $default_pid_file $intf_str",
1264 'category' => 'Rijndael SPA',
1265 'subcategory' => 'FUZZING',
1266 'detail' => 'null proto value',
1267 'err_msg' => 'server crashed or did not detect error condition',
1268 'function' => \&null_proto,
1269 'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
1270 "$fwknopdCmd -c $cf{'disable_aging'} -a $cf{'def_access'} " .
1271 "-d $default_digest_file -p $default_pid_file $intf_str",
1276 'category' => 'Rijndael SPA',
1277 'subcategory' => 'server',
1278 'detail' => 'digest cache structure',
1279 'err_msg' => 'improper digest cache structure',
1280 'function' => \&digest_cache_structure,
1285 'category' => 'Rijndael SPA',
1286 'subcategory' => 'server',
1287 'detail' => 'ipfw active/expire sets not equal',
1288 'err_msg' => 'allowed active/expire sets to be the same',
1289 'function' => \&spa_cycle,
1290 'cmdline' => $default_client_args,
1291 'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
1292 "$fwknopdCmd -c $cf{'ipfw_active_expire'} -a $cf{'def_access'} " .
1293 "-d $default_digest_file -p $default_pid_file $intf_str",
1294 'server_positive_output_matches' => [qr/Cannot\sset\sidentical\sipfw\sactive\sand\sexpire\ssets/],
1295 'fw_rule_created' => $REQUIRE_NO_NEW_RULE,
1300 'category' => 'Rijndael SPA',
1301 'subcategory' => 'client+server',
1302 'detail' => 'non-base64 altered SPA data',
1303 'err_msg' => 'allowed improper SPA data',
1304 'function' => \&altered_non_base64_spa_data,
1305 'cmdline' => $default_client_args,
1306 'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
1307 "$fwknopdCmd $default_server_conf_args $intf_str",
1311 'category' => 'Rijndael SPA',
1312 'subcategory' => 'client+server',
1313 'detail' => 'base64 altered SPA data',
1314 'err_msg' => 'allowed improper SPA data',
1315 'function' => \&altered_base64_spa_data,
1316 'cmdline' => $default_client_args,
1317 'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
1318 "$fwknopdCmd $default_server_conf_args $intf_str",
1322 'category' => 'Rijndael SPA',
1323 'subcategory' => 'client+server',
1324 'detail' => 'appended data to SPA pkt',
1325 'err_msg' => 'allowed improper SPA data',
1326 'function' => \&appended_spa_data,
1327 'cmdline' => $default_client_args,
1328 'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
1329 "$fwknopdCmd $default_server_conf_args $intf_str",
1333 'category' => 'Rijndael SPA',
1334 'subcategory' => 'client+server',
1335 'detail' => 'prepended data to SPA pkt',
1336 'err_msg' => 'allowed improper SPA data',
1337 'function' => \&prepended_spa_data,
1338 'cmdline' => $default_client_args,
1339 'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
1340 "$fwknopdCmd $default_server_conf_args $intf_str",
1345 'category' => 'GPG (no pw) SPA',
1346 'subcategory' => 'client+server',
1347 'detail' => 'complete cycle (tcp/22 ssh)',
1348 'err_msg' => 'could not complete SPA cycle',
1349 'function' => \&spa_cycle,
1350 'cmdline' => "$default_client_gpg_args_no_homedir "
1351 . "--gpg-home-dir $gpg_client_home_dir_no_pw",
1352 'fwknopd_cmdline' => $default_server_gpg_args_no_pw,
1353 'fw_rule_created' => $NEW_RULE_REQUIRED,
1354 'fw_rule_removed' => $NEW_RULE_REMOVED,
1358 'category' => 'GPG (no pw) SPA',
1359 'subcategory' => 'client+server',
1360 'detail' => 'multi gpg-IDs (tcp/22 ssh)',
1361 'err_msg' => 'could not complete SPA cycle',
1362 'function' => \&spa_cycle,
1363 'cmdline' => "$default_client_gpg_args_no_homedir "
1364 . "--gpg-home-dir $gpg_client_home_dir_no_pw",
1365 'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir " .
1366 "$valgrind_str $fwknopdCmd -c $cf{'def'} " .
1367 "-a $cf{'multi_gpg_access'} $intf_str " .
1368 "-d $default_digest_file -p $default_pid_file",
1369 'fw_rule_created' => $NEW_RULE_REQUIRED,
1370 'fw_rule_removed' => $NEW_RULE_REMOVED,
1375 'category' => 'GPG (no pw) SPA',
1376 'subcategory' => 'client+server',
1377 'detail' => 'complete cycle (tcp/23 telnet)',
1378 'err_msg' => 'could not complete SPA cycle',
1379 'function' => \&spa_cycle,
1380 'cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
1381 "$fwknopCmd -A tcp/23 -a $fake_ip -D $loopback_ip --get-key " .
1382 "$local_key_file --verbose --verbose " .
1383 "--gpg-recipient-key $gpg_server_key " .
1384 "--gpg-signer-key $gpg_client_key " .
1385 "--gpg-home-dir $gpg_client_home_dir_no_pw",
1386 'fwknopd_cmdline' => $default_server_gpg_args_no_pw,
1387 'fw_rule_created' => $NEW_RULE_REQUIRED,
1388 'fw_rule_removed' => $NEW_RULE_REMOVED,
1392 'category' => 'GPG (no pw) SPA',
1393 'subcategory' => 'client+server',
1394 'detail' => 'complete cycle (tcp/9418 git)',
1395 'err_msg' => 'could not complete SPA cycle',
1396 'function' => \&spa_cycle,
1397 'cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
1398 "$fwknopCmd -A tcp/9418 -a $fake_ip -D $loopback_ip --get-key " .
1399 "$local_key_file --verbose --verbose " .
1400 "--gpg-recipient-key $gpg_server_key " .
1401 "--gpg-signer-key $gpg_client_key " .
1402 "--gpg-home-dir $gpg_client_home_dir_no_pw",
1403 'fwknopd_cmdline' => $default_server_gpg_args_no_pw,
1404 'fw_rule_created' => $NEW_RULE_REQUIRED,
1405 'fw_rule_removed' => $NEW_RULE_REMOVED,
1409 'category' => 'GPG (no pw) SPA',
1410 'subcategory' => 'client+server',
1411 'detail' => 'complete cycle (tcp/60001)',
1412 'err_msg' => 'could not complete SPA cycle',
1413 'function' => \&spa_cycle,
1414 'cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
1415 "$fwknopCmd -A tcp/60001 -a $fake_ip -D $loopback_ip --get-key " .
1416 "$local_key_file --verbose --verbose " .
1417 "--gpg-recipient-key $gpg_server_key " .
1418 "--gpg-signer-key $gpg_client_key " .
1419 "--gpg-home-dir $gpg_client_home_dir_no_pw",
1420 'fwknopd_cmdline' => $default_server_gpg_args_no_pw,
1421 'fw_rule_created' => $NEW_RULE_REQUIRED,
1422 'fw_rule_removed' => $NEW_RULE_REMOVED,
1427 'category' => 'GPG (no pw) SPA',
1428 'subcategory' => 'client+server',
1429 'detail' => 'complete cycle (udp/53 dns)',
1430 'err_msg' => 'could not complete SPA cycle',
1431 'function' => \&spa_cycle,
1432 'cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
1433 "$fwknopCmd -A udp/53 -a $fake_ip -D $loopback_ip --get-key " .
1434 "$local_key_file --verbose --verbose " .
1435 "--gpg-recipient-key $gpg_server_key " .
1436 "--gpg-signer-key $gpg_client_key " .
1437 "--gpg-home-dir $gpg_client_home_dir_no_pw",
1438 'fwknopd_cmdline' => $default_server_gpg_args_no_pw,
1439 'fw_rule_created' => $NEW_RULE_REQUIRED,
1440 'fw_rule_removed' => $NEW_RULE_REMOVED,
1445 'category' => 'GPG (no pw) SPA',
1446 'subcategory' => 'client+server',
1447 'detail' => 'replay attack detection',
1448 'err_msg' => 'could not detect replay attack',
1449 'function' => \&replay_detection,
1450 'cmdline' => "$default_client_gpg_args_no_homedir "
1451 . "--gpg-home-dir $gpg_client_home_dir_no_pw",
1452 'fwknopd_cmdline' => $default_server_gpg_args_no_pw,
1453 'replay_positive_output_matches' => [qr/Replay\sdetected\sfrom\ssource\sIP/],
1457 'category' => 'GPG (no pw) SPA',
1458 'subcategory' => 'client+server',
1459 'detail' => 'replay detection (GnuPG prefix)',
1460 'err_msg' => 'could not detect replay attack',
1461 'function' => \&replay_detection,
1462 'pkt_prefix' => 'hQ',
1463 'cmdline' => "$default_client_gpg_args_no_homedir "
1464 . "--gpg-home-dir $gpg_client_home_dir_no_pw",
1465 'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
1466 "$fwknopdCmd $default_server_conf_args $intf_str",
1467 'replay_positive_output_matches' => [qr/Data\sis\snot\sa\svalid\sSPA\smessage\sformat/],
1472 'category' => 'GPG (no pw) SPA',
1473 'subcategory' => 'client+server',
1474 'detail' => 'non-base64 altered SPA data',
1475 'err_msg' => 'allowed improper SPA data',
1476 'function' => \&altered_non_base64_spa_data,
1477 'cmdline' => "$default_client_gpg_args_no_homedir "
1478 . "--gpg-home-dir $gpg_client_home_dir_no_pw",
1479 'fwknopd_cmdline' => $default_server_gpg_args_no_pw,
1483 'category' => 'GPG (no pw) SPA',
1484 'subcategory' => 'client+server',
1485 'detail' => 'base64 altered SPA data',
1486 'err_msg' => 'allowed improper SPA data',
1487 'function' => \&altered_base64_spa_data,
1488 'cmdline' => "$default_client_gpg_args_no_homedir "
1489 . "--gpg-home-dir $gpg_client_home_dir_no_pw",
1490 'fwknopd_cmdline' => $default_server_gpg_args_no_pw,
1494 'category' => 'GPG (no pw) SPA',
1495 'subcategory' => 'client+server',
1496 'detail' => 'appended data to SPA pkt',
1497 'err_msg' => 'allowed improper SPA data',
1498 'function' => \&appended_spa_data,
1499 'cmdline' => "$default_client_gpg_args_no_homedir "
1500 . "--gpg-home-dir $gpg_client_home_dir_no_pw",
1501 'fwknopd_cmdline' => $default_server_gpg_args_no_pw,
1505 'category' => 'GPG (no pw) SPA',
1506 'subcategory' => 'client+server',
1507 'detail' => 'prepended data to SPA pkt',
1508 'err_msg' => 'allowed improper SPA data',
1509 'function' => \&prepended_spa_data,
1510 'cmdline' => "$default_client_gpg_args_no_homedir "
1511 . "--gpg-home-dir $gpg_client_home_dir_no_pw",
1512 'fwknopd_cmdline' => $default_server_gpg_args_no_pw,
1516 'category' => 'GPG (no pw) SPA',
1517 'subcategory' => 'client+server',
1518 'detail' => 'spoof username (tcp/22 ssh)',
1519 'err_msg' => 'could not spoof username',
1520 'function' => \&spoof_username,
1521 'cmdline' => "SPOOF_USER=$spoof_user $default_client_gpg_args_no_homedir "
1522 . "--gpg-home-dir $gpg_client_home_dir_no_pw",
1523 'fwknopd_cmdline' => $default_server_gpg_args_no_pw,
1528 'category' => 'GnuPG (GPG) SPA',
1529 'subcategory' => 'client+server',
1530 'detail' => 'complete cycle (tcp/22 ssh)',
1531 'err_msg' => 'could not complete SPA cycle',
1532 'function' => \&spa_cycle,
1533 'cmdline' => $default_client_gpg_args,
1534 'fwknopd_cmdline' => $default_server_gpg_args,
1535 'fw_rule_created' => $NEW_RULE_REQUIRED,
1536 'fw_rule_removed' => $NEW_RULE_REMOVED,
1540 'category' => 'GnuPG (GPG) SPA',
1541 'subcategory' => 'client+server',
1542 'detail' => 'multi gpg-IDs (tcp/22 ssh)',
1543 'err_msg' => 'could not complete SPA cycle',
1544 'function' => \&spa_cycle,
1545 'cmdline' => $default_client_gpg_args,
1546 'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir " .
1547 "$valgrind_str $fwknopdCmd -c $cf{'def'} " .
1548 "-a $cf{'multi_gpg_access'} $intf_str " .
1549 "-d $default_digest_file -p $default_pid_file",
1550 'fw_rule_created' => $NEW_RULE_REQUIRED,
1551 'fw_rule_removed' => $NEW_RULE_REMOVED,
1556 'category' => 'GnuPG (GPG) SPA',
1557 'subcategory' => 'client+server',
1558 'detail' => 'complete cycle (tcp/23 telnet)',
1559 'err_msg' => 'could not complete SPA cycle',
1560 'function' => \&spa_cycle,
1561 'cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
1562 "$fwknopCmd -A tcp/23 -a $fake_ip -D $loopback_ip --get-key " .
1563 "$local_key_file --verbose --verbose " .
1564 "--gpg-recipient-key $gpg_server_key " .
1565 "--gpg-signer-key $gpg_client_key " .
1566 "--gpg-home-dir $gpg_client_home_dir",
1567 'fwknopd_cmdline' => $default_server_gpg_args,
1568 'fw_rule_created' => $NEW_RULE_REQUIRED,
1569 'fw_rule_removed' => $NEW_RULE_REMOVED,
1573 'category' => 'GnuPG (GPG) SPA',
1574 'subcategory' => 'client+server',
1575 'detail' => 'complete cycle (tcp/9418 git)',
1576 'err_msg' => 'could not complete SPA cycle',
1577 'function' => \&spa_cycle,
1578 'cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
1579 "$fwknopCmd -A tcp/9418 -a $fake_ip -D $loopback_ip --get-key " .
1580 "$local_key_file --verbose --verbose " .
1581 "--gpg-recipient-key $gpg_server_key " .
1582 "--gpg-signer-key $gpg_client_key " .
1583 "--gpg-home-dir $gpg_client_home_dir",
1584 'fwknopd_cmdline' => $default_server_gpg_args,
1585 'fw_rule_created' => $NEW_RULE_REQUIRED,
1586 'fw_rule_removed' => $NEW_RULE_REMOVED,
1590 'category' => 'GnuPG (GPG) SPA',
1591 'subcategory' => 'client+server',
1592 'detail' => 'complete cycle (tcp/60001)',
1593 'err_msg' => 'could not complete SPA cycle',
1594 'function' => \&spa_cycle,
1595 'cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
1596 "$fwknopCmd -A tcp/60001 -a $fake_ip -D $loopback_ip --get-key " .
1597 "$local_key_file --verbose --verbose " .
1598 "--gpg-recipient-key $gpg_server_key " .
1599 "--gpg-signer-key $gpg_client_key " .
1600 "--gpg-home-dir $gpg_client_home_dir",
1601 'fwknopd_cmdline' => $default_server_gpg_args,
1602 'fw_rule_created' => $NEW_RULE_REQUIRED,
1603 'fw_rule_removed' => $NEW_RULE_REMOVED,
1608 'category' => 'GnuPG (GPG) SPA',
1609 'subcategory' => 'client+server',
1610 'detail' => 'complete cycle (udp/53 dns)',
1611 'err_msg' => 'could not complete SPA cycle',
1612 'function' => \&spa_cycle,
1613 'cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
1614 "$fwknopCmd -A udp/53 -a $fake_ip -D $loopback_ip --get-key " .
1615 "$local_key_file --verbose --verbose " .
1616 "--gpg-recipient-key $gpg_server_key " .
1617 "--gpg-signer-key $gpg_client_key " .
1618 "--gpg-home-dir $gpg_client_home_dir",
1619 'fwknopd_cmdline' => $default_server_gpg_args,
1620 'fw_rule_created' => $NEW_RULE_REQUIRED,
1621 'fw_rule_removed' => $NEW_RULE_REMOVED,
1626 'category' => 'GnuPG (GPG) SPA',
1627 'subcategory' => 'client+server',
1628 'detail' => 'replay attack detection',
1629 'err_msg' => 'could not detect replay attack',
1630 'function' => \&replay_detection,
1631 'cmdline' => $default_client_gpg_args,
1632 'fwknopd_cmdline' => $default_server_gpg_args,
1633 'replay_positive_output_matches' => [qr/Replay\sdetected\sfrom\ssource\sIP/],
1637 'category' => 'GnuPG (GPG) SPA',
1638 'subcategory' => 'client+server',
1639 'detail' => 'replay detection (GnuPG prefix)',
1640 'err_msg' => 'could not detect replay attack',
1641 'function' => \&replay_detection,
1642 'pkt_prefix' => 'hQ',
1643 'cmdline' => $default_client_gpg_args,
1644 'fwknopd_cmdline' => "LD_LIBRARY_PATH=$lib_dir $valgrind_str " .
1645 "$fwknopdCmd $default_server_conf_args $intf_str",
1646 'replay_positive_output_matches' => [qr/Data\sis\snot\sa\svalid\sSPA\smessage\sformat/],
1651 'category' => 'GnuPG (GPG) SPA',
1652 'subcategory' => 'client+server',
1653 'detail' => 'non-base64 altered SPA data',
1654 'err_msg' => 'allowed improper SPA data',
1655 'function' => \&altered_non_base64_spa_data,
1656 'cmdline' => $default_client_gpg_args,
1657 'fwknopd_cmdline' => $default_server_gpg_args,
1661 'category' => 'GnuPG (GPG) SPA',
1662 'subcategory' => 'client+server',
1663 'detail' => 'base64 altered SPA data',
1664 'err_msg' => 'allowed improper SPA data',
1665 'function' => \&altered_base64_spa_data,
1666 'cmdline' => $default_client_gpg_args,
1667 'fwknopd_cmdline' => $default_server_gpg_args,
1671 'category' => 'GnuPG (GPG) SPA',
1672 'subcategory' => 'client+server',
1673 'detail' => 'appended data to SPA pkt',
1674 'err_msg' => 'allowed improper SPA data',
1675 'function' => \&appended_spa_data,
1676 'cmdline' => $default_client_gpg_args,
1677 'fwknopd_cmdline' => $default_server_gpg_args,
1681 'category' => 'GnuPG (GPG) SPA',
1682 'subcategory' => 'client+server',
1683 'detail' => 'prepended data to SPA pkt',
1684 'err_msg' => 'allowed improper SPA data',
1685 'function' => \&prepended_spa_data,
1686 'cmdline' => $default_client_gpg_args,
1687 'fwknopd_cmdline' => $default_server_gpg_args,
1691 'category' => 'GnuPG (GPG) SPA',
1692 'subcategory' => 'client+server',
1693 'detail' => 'spoof username (tcp/22 ssh)',
1694 'err_msg' => 'could not spoof username',
1695 'function' => \&spoof_username,
1696 'cmdline' => "SPOOF_USER=$spoof_user $default_client_gpg_args",
1697 'fwknopd_cmdline' => $default_server_gpg_args,
1701 'category' => 'GnuPG (GPG) SPA',
1702 'subcategory' => 'server',
1703 'detail' => 'digest cache structure',
1704 'err_msg' => 'improper digest cache structure',
1705 'function' => \&digest_cache_structure,
1710 if ($use_valgrind) {
1713 'category' => 'valgrind output',
1714 'subcategory' => 'flagged functions',
1716 'err_msg' => 'could not parse flagged functions',
1717 'function' => \&parse_valgrind_flagged_functions,
1723 'category' => $REQUIRED,
1724 'subcategory' => $OPTIONAL,
1725 'detail' => $REQUIRED,
1726 'function' => $REQUIRED,
1727 'binary' => $OPTIONAL,
1728 'cmdline' => $OPTIONAL,
1729 'fwknopd_cmdline' => $OPTIONAL,
1730 'fatal' => $OPTIONAL,
1731 'exec_err' => $OPTIONAL,
1732 'fw_rule_created' => $OPTIONAL,
1733 'fw_rule_removed' => $OPTIONAL,
1734 'server_conf' => $OPTIONAL,
1735 'pkt_prefix' => $OPTIONAL,
1736 'no_ip_check' => $OPTIONAL,
1737 'positive_output_matches' => $OPTIONAL,
1738 'negative_output_matches' => $OPTIONAL,
1739 'server_positive_output_matches' => $OPTIONAL,
1740 'server_negative_output_matches' => $OPTIONAL,
1741 'replay_positive_output_matches' => $OPTIONAL,
1742 'replay_negative_output_matches' => $OPTIONAL,
1746 &diff_test_results();
1750 ### make sure everything looks as expected before continuing
1753 &logr("\n[+] Starting the fwknop test suite...\n\n" .
1754 " args: @args_cp\n\n"
1757 ### save the results from any previous test suite run
1758 ### so that we can potentially compare them with --diff
1759 if ($saved_last_results) {
1760 &logr(" Saved results from previous run " .
1761 "to: ${output_dir}.last/\n\n");
1764 ### main loop through all of the tests
1765 for my $test_hr (@tests) {
1766 &run_test($test_hr);
1769 &logr("\n[+] passed/failed/executed: $passed/$failed/$executed tests\n\n");
1771 copy $logfile, "$output_dir/$logfile" or die $!;
1775 #===================== end main =======================
1778 my $test_hr = shift;
1780 my $msg = "[$test_hr->{'category'}]";
1781 $msg .= " [$test_hr->{'subcategory'}]" if $test_hr->{'subcategory'};
1782 $msg .= " $test_hr->{'detail'}";
1784 return unless &process_include_exclude($msg);
1794 $current_test_file = "$output_dir/$executed.test";
1795 $server_test_file = "$output_dir/${executed}_fwknopd.test";
1797 &write_test_file("[+] TEST: $msg\n", $current_test_file);
1798 $test_hr->{'msg'} = $msg;
1799 if (&{$test_hr->{'function'}}($test_hr)) {
1800 &logr("pass ($executed)\n");
1803 &logr("fail ($executed)\n");
1806 if ($test_hr->{'fatal'} eq $YES) {
1807 die "[*] required test failed, exiting.";
1814 sub process_include_exclude() {
1817 ### inclusions/exclusions
1818 if (@tests_to_include) {
1820 for my $test (@tests_to_include) {
1821 if ($msg =~ $test or ($use_valgrind
1822 and $msg =~ /valgrind\soutput/)) {
1827 return 0 unless $found;
1829 if (@tests_to_exclude) {
1831 for my $test (@tests_to_exclude) {
1832 if ($msg =~ $test) {
1842 sub diff_test_results() {
1844 $diff_dir1 = "${output_dir}.last" unless $diff_dir1;
1845 $diff_dir2 = $output_dir unless $diff_dir2;
1847 die "[*] Need results from a previous run before running --diff"
1848 unless -d $diff_dir2;
1849 die "[*] Current results set does not exist." unless -d $diff_dir1;
1851 my %current_tests = ();
1852 my %previous_tests = ();
1854 ### Only diff results for matching tests (parse the logfile to see which
1855 ### test numbers match across the two test cycles).
1856 &build_results_hash(\%current_tests, $diff_dir1);
1857 &build_results_hash(\%previous_tests, $diff_dir2);
1859 for my $test_msg (sort {$current_tests{$a}{'num'} <=> $current_tests{$b}{'num'}}
1860 keys %current_tests) {
1861 my $current_result = $current_tests{$test_msg}{'pass_fail'};
1862 my $current_num = $current_tests{$test_msg}{'num'};
1863 if (defined $previous_tests{$test_msg}) {
1864 print "[+] Checking: $test_msg\n";
1865 my $previous_result = $previous_tests{$test_msg}{'pass_fail'};
1866 my $previous_num = $previous_tests{$test_msg}{'num'};
1867 if ($current_result ne $previous_result) {
1868 print " DIFF: **$current_result** $test_msg\n";
1871 &diff_results($previous_num, $current_num);
1879 sub diff_results() {
1880 my ($previous_num, $current_num) = @_;
1882 ### edit out any valgrind "==354==" prefixes
1883 my $valgrind_search_re = qr/^==\d+==\s/;
1885 ### remove CMD timestamps
1886 my $cmd_search_re = qr/^\S+\s.*?\s\d{4}\sCMD\:/;
1888 for my $file ("$diff_dir1/${previous_num}.test",
1889 "$diff_dir1/${previous_num}_fwknopd.test",
1890 "$diff_dir2/${current_num}.test",
1891 "$diff_dir2/${current_num}_fwknopd.test",
1893 system qq{perl -p -i -e 's|$valgrind_search_re||' $file} if -e $file;
1894 system qq{perl -p -i -e 's|$cmd_search_re|CMD:|' $file} if -e $file;
1897 if (-e "$diff_dir1/${previous_num}.test"
1898 and -e "$diff_dir2/${current_num}.test") {
1899 system "diff -u $diff_dir1/${previous_num}.test " .
1900 "$diff_dir2/${current_num}.test";
1903 if (-e "$diff_dir1/${previous_num}_fwknopd.test"
1904 and -e "$diff_dir2/${current_num}_fwknopd.test") {
1905 system "diff -u $diff_dir1/${previous_num}_fwknopd.test " .
1906 "$diff_dir2/${current_num}_fwknopd.test";
1912 sub build_results_hash() {
1913 my ($hr, $dir) = @_;
1915 open F, "< $dir/$logfile" or die $!;
1917 if (/^(.*?)\.\.\..*(pass|fail)\s\((\d+)\)/) {
1918 $hr->{$1}{'pass_fail'} = $2;
1919 $hr->{$1}{'num'} = $3;
1925 sub compile_warnings() {
1927 ### 'make clean' as root
1928 return 0 unless &run_cmd('make -C .. clean',
1929 $cmd_out_tmp, $current_test_file);
1932 my $username = getpwuid((stat($configure_path))[4]);
1933 die "[*] Could not determine $configure_path owner"
1936 return 0 unless &run_cmd("$sudo_path -u $username make -C ..",
1937 $cmd_out_tmp, $current_test_file);
1941 return 0 unless &run_cmd('make -C ..',
1942 $cmd_out_tmp, $current_test_file);
1946 ### look for compilation warnings - something like:
1947 ### warning: ‘test’ is used uninitialized in this function
1948 return 0 if &file_find_regex([qr/\swarning:\s/, qr/gcc\:.*\sunused/],
1949 $MATCH_ANY, $current_test_file);
1951 ### the new binaries should exist
1952 unless (-e $fwknopCmd and -x $fwknopCmd) {
1953 &write_test_file("[-] $fwknopCmd does not exist or not executable.\n",
1954 $current_test_file);
1956 unless (-e $fwknopdCmd and -x $fwknopdCmd) {
1957 &write_test_file("[-] $fwknopdCmd does not exist or not executable.\n",
1958 $current_test_file);
1964 sub make_distcheck() {
1966 ### 'make clean' as root
1967 return 0 unless &run_cmd('make -C .. distcheck',
1968 $cmd_out_tmp, $current_test_file);
1970 ### look for compilation warnings - something like:
1971 ### warning: ‘test’ is used uninitialized in this function
1972 return 1 if &file_find_regex([qr/archives\sready\sfor\sdistribution/],
1973 $MATCH_ALL, $current_test_file);
1979 sub binary_exists() {
1980 my $test_hr = shift;
1981 return 0 unless $test_hr->{'binary'};
1983 ### account for different libfko.so paths (e.g. libfko.so.0.3 with no
1984 ### libfko.so link on OpenBSD, and libfko.dylib path on Mac OS X)
1986 if ($test_hr->{'binary'} =~ /libfko/) {
1987 unless (-e $test_hr->{'binary'}) {
1988 my $file = "$lib_dir/libfko.dylib";
1990 $test_hr->{'binary'} = $file;
1991 $libfko_bin = $file;
1993 for my $f (glob("$lib_dir/libfko.so*")) {
1994 if (-e $f and -x $f) {
1995 $test_hr->{'binary'} = $f;
2004 return 0 unless -e $test_hr->{'binary'} and -x $test_hr->{'binary'};
2008 sub expected_code_version() {
2009 my $test_hr = shift;
2011 unless (-e '../VERSION') {
2012 &write_test_file("[-] ../VERSION file does not exist.\n",
2013 $current_test_file);
2017 open F, '< ../VERSION' or die $!;
2020 if ($line =~ /(\d.*\d)/) {
2022 return 0 unless &run_cmd($test_hr->{'cmdline'},
2023 $cmd_out_tmp, $current_test_file);
2024 return 1 if &file_find_regex([qr/$version/],
2025 $MATCH_ALL, $current_test_file);
2030 sub client_send_spa_packet() {
2031 my $test_hr = shift;
2033 &write_key('fwknoptest', $local_key_file);
2035 return 0 unless &run_cmd($test_hr->{'cmdline'},
2036 $cmd_out_tmp, $current_test_file);
2037 return 0 unless &file_find_regex([qr/final\spacked/i],
2038 $MATCH_ALL, $current_test_file);
2044 my $test_hr = shift;
2046 my ($rv, $server_was_stopped, $fw_rule_created, $fw_rule_removed)
2047 = &client_server_interaction($test_hr, [], $USE_CLIENT);
2049 if ($test_hr->{'fw_rule_created'} eq $NEW_RULE_REQUIRED) {
2050 $rv = 0 unless $fw_rule_created;
2051 } elsif ($test_hr->{'fw_rule_created'} eq $REQUIRE_NO_NEW_RULE) {
2052 $rv = 0 if $fw_rule_created;
2055 if ($test_hr->{'fw_rule_removed'} eq $NEW_RULE_REMOVED) {
2056 $rv = 0 unless $fw_rule_removed;
2057 } elsif ($test_hr->{'fw_rule_removed'} eq $REQUIRE_NO_NEW_REMOVED) {
2058 $rv = 0 if $fw_rule_removed;
2061 if ($test_hr->{'server_positive_output_matches'}) {
2062 $rv = 0 unless &file_find_regex(
2063 $test_hr->{'server_positive_output_matches'},
2064 $MATCH_ALL, $server_test_file);
2067 if ($test_hr->{'server_negative_output_matches'}) {
2068 $rv = 0 if &file_find_regex(
2069 $test_hr->{'server_negative_output_matches'},
2070 $MATCH_ANY, $server_test_file);
2076 sub spoof_username() {
2077 my $test_hr = shift;
2079 my $rv = &spa_cycle($test_hr);
2081 unless (&file_find_regex([qr/Username:\s*$spoof_user/],
2082 $MATCH_ALL, $current_test_file)) {
2086 unless (&file_find_regex([qr/Username:\s*$spoof_user/],
2087 $MATCH_ALL, $server_test_file)) {
2094 sub replay_detection() {
2095 my $test_hr = shift;
2097 ### do a complete SPA cycle and then parse the SPA packet out of the
2098 ### current test file and re-send
2100 return 0 unless &spa_cycle($test_hr);
2102 my $spa_pkt = &get_spa_packet_from_file($current_test_file);
2105 &write_test_file("[-] could not get SPA packet " .
2106 "from file: $current_test_file\n",
2107 $current_test_file);
2111 if ($test_hr->{'pkt_prefix'}) {
2112 $spa_pkt = $test_hr->{'pkt_prefix'} . $spa_pkt;
2118 'port' => $default_spa_port,
2119 'dst_ip' => $loopback_ip,
2124 my ($rv, $server_was_stopped, $fw_rule_created, $fw_rule_removed)
2125 = &client_server_interaction($test_hr, \@packets, $USE_PREDEF_PKTS);
2127 $rv = 0 unless $server_was_stopped;
2129 if ($test_hr->{'replay_positive_output_matches'}) {
2130 $rv = 0 unless &file_find_regex(
2131 $test_hr->{'replay_positive_output_matches'},
2132 $MATCH_ALL, $server_test_file);
2135 if ($test_hr->{'replay_negative_output_matches'}) {
2136 $rv = 0 if &file_find_regex(
2137 $test_hr->{'replay_negative_output_matches'},
2138 $MATCH_ANY, $server_test_file);
2144 sub digest_cache_structure() {
2145 my $test_hr = shift;
2148 &run_cmd("file $default_digest_file", $cmd_out_tmp, $current_test_file);
2150 if (&file_find_regex([qr/ASCII/i], $MATCH_ALL, $cmd_out_tmp)) {
2152 ### the format should be:
2153 ### <digest> <proto> <src_ip> <src_port> <dst_ip> <dst_port> <time>
2154 open F, "< $default_digest_file" or
2155 die "[*] could not open $default_digest_file: $!";
2159 unless (m|^\S+\s+\d+\s+$ip_re\s+\d+\s+$ip_re\s+\d+\s+\d+|) {
2160 &write_test_file("[-] invalid digest.cache line: $_",
2161 $current_test_file);
2167 } elsif (&file_find_regex([qr/dbm/i], $MATCH_ALL, $cmd_out_tmp)) {
2168 &write_test_file("[+] DBM digest file format, " .
2169 "assuming this is valid.\n", $current_test_file);
2171 ### don't know what kind of file the digest.cache is
2172 &write_test_file("[-] unrecognized file type for " .
2173 "$default_digest_file.\n", $current_test_file);
2178 &write_test_file("[+] valid digest.cache structure.\n",
2179 $current_test_file);
2185 sub server_bpf_ignore_packet() {
2186 my $test_hr = shift;
2189 my $server_was_stopped = 0;
2190 my $fw_rule_created = 0;
2191 my $fw_rule_removed = 0;
2193 unless (&client_send_spa_packet($test_hr)) {
2194 &write_test_file("[-] fwknop client execution error.\n",
2195 $current_test_file);
2199 my $spa_pkt = &get_spa_packet_from_file($current_test_file);
2202 &write_test_file("[-] could not get SPA packet " .
2203 "from file: $current_test_file\n", $current_test_file);
2210 'port' => $default_spa_port,
2211 'dst_ip' => $loopback_ip,
2216 ($rv, $server_was_stopped, $fw_rule_created, $fw_rule_removed)
2217 = &client_server_interaction($test_hr, \@packets, $USE_PREDEF_PKTS);
2219 unless (&file_find_regex([qr/PCAP\sfilter.*\s$non_std_spa_port/],
2220 $MATCH_ALL, $server_test_file)) {
2227 sub altered_non_base64_spa_data() {
2228 my $test_hr = shift;
2231 my $server_was_stopped = 0;
2232 my $fw_rule_created = 0;
2233 my $fw_rule_removed = 0;
2235 unless (&client_send_spa_packet($test_hr)) {
2236 &write_test_file("[-] fwknop client execution error.\n",
2237 $current_test_file);
2241 my $spa_pkt = &get_spa_packet_from_file($current_test_file);
2244 &write_test_file("[-] could not get SPA packet " .
2245 "from file: $current_test_file\n", $current_test_file);
2249 ### alter one byte (change to a ":")
2250 $spa_pkt =~ s|^(.{3}).|$1:|;
2255 'port' => $default_spa_port,
2256 'dst_ip' => $loopback_ip,
2261 ($rv, $server_was_stopped, $fw_rule_created, $fw_rule_removed)
2262 = &client_server_interaction($test_hr, \@packets, $USE_PREDEF_PKTS);
2264 $rv = 0 unless $server_was_stopped;
2270 my $test_hr = shift;
2273 my $server_was_stopped = 0;
2274 my $fw_rule_created = 0;
2275 my $fw_rule_removed = 0;
2277 ### this packet was generated with a modified fwknop client via the
2278 ### following command line:
2280 # LD_LIBRARY_PATH=../lib/.libs ../client/.libs/fwknop -A /22 \
2281 # -a 127.0.0.2 -D 127.0.0.1 --get-key local_spa.key \
2282 # --verbose --verbose
2285 '/JT14qxh9P4iy+CuUZahThaQjoEuL2zd46a+jL6sTrBZJSa6faUX4dH5fte/4ZJv+9f' .
2286 'd/diWYKAUvdQ4DydPGlR7mwQa2W+obKpqrsTBz7D4054z6ATAOGpCtifakEVl1XRc2+' .
2287 'hW04WpY8mdUNu9i+PrfPr7/KxqU';
2292 'port' => $default_spa_port,
2293 'dst_ip' => $loopback_ip,
2298 ($rv, $server_was_stopped, $fw_rule_created, $fw_rule_removed)
2299 = &client_server_interaction($test_hr, \@packets, $USE_PREDEF_PKTS);
2301 $rv = 0 unless $server_was_stopped;
2303 if ($fw_rule_created) {
2304 &write_test_file("[-] new fw rule created.\n", $current_test_file);
2307 &write_test_file("[+] new fw rule not created.\n", $current_test_file);
2310 unless (&file_find_regex([qr/Args\scontain\sinvalid\sdata/],
2311 $MATCH_ALL, $server_test_file)) {
2319 my $test_hr = shift;
2322 my $server_was_stopped = 0;
2323 my $fw_rule_created = 0;
2324 my $fw_rule_removed = 0;
2326 ### this packet was generated with a modified fwknop client via the
2327 ### following command line:
2329 # LD_LIBRARY_PATH=../lib/.libs ../client/.libs/fwknop -A tcp/ \
2330 # -a 127.0.0.2 -D 127.0.0.1 --get-key local_spa.key \
2331 # --verbose --verbose
2334 '94nu7hvq6V/3A27GzjHwfPnPCQfs44ySlraIFYHOAqy5YqjkrBS67nH35tX55N1BrYZ' .
2335 '07zvcT03keUhLE1Uo7Wme1nE7BfTOG5stmIK1UQI85sL52//lDHu+xCqNcL7GUKbVRz' .
2336 'ekw+EUscVvUkrsRcVtSvOm+fCNo';
2341 'port' => $default_spa_port,
2342 'dst_ip' => $loopback_ip,
2347 ($rv, $server_was_stopped, $fw_rule_created, $fw_rule_removed)
2348 = &client_server_interaction($test_hr, \@packets, $USE_PREDEF_PKTS);
2350 $rv = 0 unless $server_was_stopped;
2352 if ($fw_rule_created) {
2353 &write_test_file("[-] new fw rule created.\n", $current_test_file);
2356 &write_test_file("[+] new fw rule not created.\n", $current_test_file);
2359 unless (&file_find_regex([qr/Args\scontain\sinvalid\sdata/],
2360 $MATCH_ALL, $server_test_file)) {
2367 sub negative_port() {
2368 my $test_hr = shift;
2371 my $server_was_stopped = 0;
2372 my $fw_rule_created = 0;
2373 my $fw_rule_removed = 0;
2375 ### this packet was generated with a modified fwknop client via the
2376 ### following command line:
2378 # LD_LIBRARY_PATH=../lib/.libs ../client/.libs/fwknop -A \
2379 # tcp/-33 -a 127.0.0.2 -D 127.0.0.1 --get-key local_spa.key \
2380 # --verbose --verbose
2383 '/weoc+pEuQknZo8ImWTQBB+/PwSJ2/TcrmFoSkxpRXX4+jlUxoJakHrioxh8rhLmAD9' .
2384 '8E4lMnq+EbM2XYdhs2alpZ5bovAFojMsYRWwr/BvRO4Um4Fmo9z9sY3DR477TXNYXBR' .
2385 'iGXWxSL4u+AWSSePK3qiiYoRQVw';
2390 'port' => $default_spa_port,
2391 'dst_ip' => $loopback_ip,
2396 ($rv, $server_was_stopped, $fw_rule_created, $fw_rule_removed)
2397 = &client_server_interaction($test_hr, \@packets, $USE_PREDEF_PKTS);
2399 $rv = 0 unless $server_was_stopped;
2401 if ($fw_rule_created) {
2402 &write_test_file("[-] new fw rule created.\n", $current_test_file);
2405 &write_test_file("[+] new fw rule not created.\n", $current_test_file);
2408 unless (&file_find_regex([qr/Args\scontain\sinvalid\sdata/],
2409 $MATCH_ALL, $server_test_file)) {
2416 sub overly_long_proto() {
2417 my $test_hr = shift;
2420 my $server_was_stopped = 0;
2421 my $fw_rule_created = 0;
2422 my $fw_rule_removed = 0;
2424 ### this packet was generated with a modified fwknop client via the
2425 ### following command line:
2427 # LD_LIBRARY_PATH=../lib/.libs ../client/.libs/fwknop -A \
2428 # "tcp`perl -e '{print "A"x"28"}'`/1" -a 127.0.0.2 -D 127.0.0.1 \
2429 # --get-key local_spa.key --verbose --verbose
2431 # This problem was found by Fernando Arnaboldi of IOActive and exploits
2432 # a buffer overflow in the fwknopd servers prior to 2.0.3 from
2433 # authenticated clients.
2436 '/im5MiJQmOdzqrdWXv+AjEtAm/HsLrdaTFcSw3ZskqpGOdDIrSCz3VXbFfv7qDkc5Y4' .
2437 'q/k1mRXl9SGzpug87U5dZSyCdAr30z7/2kUFEPTGOQBi/x+L1t1pvdkm4xg13t09ldm' .
2438 '5OD8KiV6qzqLOvN4ULJjvvJJWBZ9qvo/f2Q9Wf67g2KHiwS6EeCINAuMoUw/mNRQMa4' .
2439 'oGnOXu3/DeWHJAwtSeh7EAr4';
2444 'port' => $default_spa_port,
2445 'dst_ip' => $loopback_ip,
2450 ($rv, $server_was_stopped, $fw_rule_created, $fw_rule_removed)
2451 = &client_server_interaction($test_hr, \@packets, $USE_PREDEF_PKTS);
2453 $rv = 0 unless $server_was_stopped;
2455 if ($fw_rule_created) {
2456 &write_test_file("[-] new fw rule created.\n", $current_test_file);
2459 &write_test_file("[+] new fw rule not created.\n", $current_test_file);
2462 unless (&file_find_regex([qr/Args\scontain\sinvalid\sdata/],
2463 $MATCH_ALL, $server_test_file)) {
2470 sub overly_long_port() {
2471 my $test_hr = shift;
2474 my $server_was_stopped = 0;
2475 my $fw_rule_created = 0;
2476 my $fw_rule_removed = 0;
2478 ### this packet was generated with a modified fwknop client via the
2479 ### following command line:
2481 # LD_LIBRARY_PATH=../lib/.libs ../client/.libs/fwknop -A \
2482 # "tcp/`perl -e '{print "1"x"40"}'`" -a 127.0.0.2 -D 127.0.0.1 \
2483 # --get-key local_spa.key --verbose --verbose
2485 # This problem was found by Fernando Arnaboldi of IOActive and exploits
2486 # a buffer overflow in the fwknopd servers prior to 2.0.3 from
2487 # authenticated clients.
2490 '+JzxeTGlc6lwwzbJSrYChKx8bonWBIPajwGfEtGOaoglcMLbTY/GGXo/nxqiN1LykFS' .
2491 'lDFXgrkyx2emJ7NGzYqQPUYZxLdZRocR9aRIptvXLLIPBcIpJASi/TUiJlw7CDFMcj0' .
2492 'ptSBJJUZi0tozpKHETp3AgqfzyOy5FNs38aZsV5/sDl3Pt+kF7fTZJ+YLbmYY4yCUz2' .
2493 'ZUYoCaJ7X78ULyJTi5eT7nug';
2498 'port' => $default_spa_port,
2499 'dst_ip' => $loopback_ip,
2504 ($rv, $server_was_stopped, $fw_rule_created, $fw_rule_removed)
2505 = &client_server_interaction($test_hr, \@packets, $USE_PREDEF_PKTS);
2507 $rv = 0 unless $server_was_stopped;
2509 if ($fw_rule_created) {
2510 &write_test_file("[-] new fw rule created.\n", $current_test_file);
2513 &write_test_file("[+] new fw rule not created.\n", $current_test_file);
2516 unless (&file_find_regex([qr/Args\scontain\sinvalid\sdata/],
2517 $MATCH_ALL, $server_test_file)) {
2524 sub altered_base64_spa_data() {
2525 my $test_hr = shift;
2528 my $server_was_stopped = 0;
2529 my $fw_rule_created = 0;
2530 my $fw_rule_removed = 0;
2532 unless (&client_send_spa_packet($test_hr)) {
2533 &write_test_file("[-] fwknop client execution error.\n",
2534 $current_test_file);
2538 my $spa_pkt = &get_spa_packet_from_file($current_test_file);
2541 &write_test_file("[-] could not get SPA packet " .
2542 "from file: $current_test_file\n", $current_test_file);
2546 $spa_pkt =~ s|^(.{3}).|AAAA|;
2551 'port' => $default_spa_port,
2552 'dst_ip' => $loopback_ip,
2557 ($rv, $server_was_stopped, $fw_rule_created, $fw_rule_removed)
2558 = &client_server_interaction($test_hr, \@packets, $USE_PREDEF_PKTS);
2560 $rv = 0 unless $server_was_stopped;
2562 if ($fw_rule_created) {
2563 &write_test_file("[-] new fw rule created.\n", $current_test_file);
2566 &write_test_file("[+] new fw rule not created.\n", $current_test_file);
2569 unless (&file_find_regex([qr/Error\screating\sfko\scontext/],
2570 $MATCH_ALL, $server_test_file)) {
2577 sub appended_spa_data() {
2578 my $test_hr = shift;
2581 my $server_was_stopped = 0;
2582 my $fw_rule_created = 0;
2583 my $fw_rule_removed = 0;
2585 unless (&client_send_spa_packet($test_hr)) {
2586 &write_test_file("[-] fwknop client execution error.\n",
2587 $current_test_file);
2591 my $spa_pkt = &get_spa_packet_from_file($current_test_file);
2594 &write_test_file("[-] could not get SPA packet " .
2595 "from file: $current_test_file\n", $current_test_file);
2604 'port' => $default_spa_port,
2605 'dst_ip' => $loopback_ip,
2610 ($rv, $server_was_stopped, $fw_rule_created, $fw_rule_removed)
2611 = &client_server_interaction($test_hr, \@packets, $USE_PREDEF_PKTS);
2613 $rv = 0 unless $server_was_stopped;
2615 if ($fw_rule_created) {
2616 &write_test_file("[-] new fw rule created.\n", $current_test_file);
2619 &write_test_file("[+] new fw rule not created.\n", $current_test_file);
2622 unless (&file_find_regex([qr/Error\screating\sfko\scontext/],
2623 $MATCH_ALL, $server_test_file)) {
2630 sub prepended_spa_data() {
2631 my $test_hr = shift;
2634 my $server_was_stopped = 0;
2635 my $fw_rule_created = 0;
2636 my $fw_rule_removed = 0;
2638 unless (&client_send_spa_packet($test_hr)) {
2639 &write_test_file("[-] fwknop client execution error.\n",
2640 $current_test_file);
2644 my $spa_pkt = &get_spa_packet_from_file($current_test_file);
2647 &write_test_file("[-] could not get SPA packet " .
2648 "from file: $current_test_file\n", $current_test_file);
2652 $spa_pkt = 'AAAA' . $spa_pkt;
2657 'port' => $default_spa_port,
2658 'dst_ip' => $loopback_ip,
2663 ($rv, $server_was_stopped, $fw_rule_created, $fw_rule_removed)
2664 = &client_server_interaction($test_hr, \@packets, $USE_PREDEF_PKTS);
2666 $rv = 0 unless $server_was_stopped;
2668 if ($fw_rule_created) {
2669 &write_test_file("[-] new fw rule created.\n", $current_test_file);
2672 &write_test_file("[+] new fw rule not created.\n", $current_test_file);
2675 unless (&file_find_regex([qr/Error\screating\sfko\scontext/],
2676 $MATCH_ALL, $server_test_file)) {
2683 sub server_start() {
2684 my $test_hr = shift;
2686 my ($rv, $server_was_stopped, $fw_rule_created, $fw_rule_removed)
2687 = &client_server_interaction($test_hr, [], $USE_PREDEF_PKTS);
2689 unless (&file_find_regex([qr/Starting\sfwknopd\smain\sevent\sloop/],
2690 $MATCH_ALL, $server_test_file)) {
2694 $rv = 0 unless $server_was_stopped;
2700 my $test_hr = shift;
2702 my ($rv, $server_was_stopped, $fw_rule_created, $fw_rule_removed)
2703 = &client_server_interaction($test_hr, [], $USE_PREDEF_PKTS);
2705 $rv = 0 unless $server_was_stopped;
2710 sub server_packet_limit() {
2711 my $test_hr = shift;
2716 'port' => $default_spa_port,
2717 'dst_ip' => $loopback_ip,
2722 my ($rv, $server_was_stopped, $fw_rule_created, $fw_rule_removed)
2723 = &client_server_interaction($test_hr, \@packets, $USE_PREDEF_PKTS);
2725 if (&is_fwknopd_running()) {
2730 unless (&file_find_regex([qr/count\slimit\sof\s1\sreached/],
2731 $MATCH_ALL, $server_test_file)) {
2735 unless (&file_find_regex([qr/Shutting\sDown\sfwknopd/i],
2736 $MATCH_ALL, $server_test_file)) {
2743 sub server_ignore_small_packets() {
2744 my $test_hr = shift;
2749 'port' => $default_spa_port,
2750 'dst_ip' => $loopback_ip,
2751 'data' => 'A'x120, ### < MIN_SPA_DATA_SIZE
2755 my ($rv, $server_was_stopped, $fw_rule_created, $fw_rule_removed)
2756 = &client_server_interaction($test_hr, \@packets, $USE_PREDEF_PKTS);
2760 if (&is_fwknopd_running()) {
2768 sub client_server_interaction() {
2769 my ($test_hr, $pkts_hr, $spa_client_flag) = @_;
2772 my $server_was_stopped = 1;
2773 my $fw_rule_created = 1;
2774 my $fw_rule_removed = 0;
2776 ### start fwknopd to monitor for the SPA packet over the loopback interface
2777 my $fwknopd_parent_pid = &start_fwknopd($test_hr);
2779 ### give fwknopd a chance to parse its config and start sniffing
2780 ### on the loopback interface
2781 if ($use_valgrind) {
2787 ### send the SPA packet(s) to the server either manually using IO::Socket or
2788 ### with the fwknopd client
2789 if ($spa_client_flag == $USE_CLIENT) {
2790 unless (&client_send_spa_packet($test_hr)) {
2791 &write_test_file("[-] fwknop client execution error.\n",
2792 $current_test_file);
2796 &send_packets($pkts_hr);
2799 ### check to see if the SPA packet resulted in a new fw access rule
2801 while (not &is_fw_rule_active($test_hr)) {
2802 &write_test_file("[-] new fw rule does not exist.\n",
2803 $current_test_file);
2809 $fw_rule_created = 0;
2810 $fw_rule_removed = 0;
2813 &time_for_valgrind() if $use_valgrind;
2815 if ($fw_rule_created) {
2816 sleep 3; ### allow time for rule time out.
2817 if (&is_fw_rule_active($test_hr)) {
2818 &write_test_file("[-] new fw rule not timed out.\n",
2819 $current_test_file);
2822 &write_test_file("[+] new fw rule timed out.\n",
2823 $current_test_file);
2824 $fw_rule_removed = 1;
2828 if (&is_fwknopd_running()) {
2830 unless (&file_find_regex([qr/Got\sSIGTERM/],
2831 $MATCH_ALL, $server_test_file)) {
2832 $server_was_stopped = 0;
2835 &write_test_file("[-] server is not running.\n",
2836 $current_test_file);
2837 $server_was_stopped = 0;
2840 return ($rv, $server_was_stopped, $fw_rule_created, $fw_rule_removed);
2843 sub get_spa_packet_from_file() {
2848 my $found_trigger_line = 0;
2849 open F, "< $file" or die "[*] Could not open file $file: $!";
2851 if (/final\spacked/i) {
2852 $found_trigger_line = 1;
2855 next unless $found_trigger_line;
2857 ### the next line with non whitespace is the SPA packet
2868 sub send_packets() {
2869 my $pkts_ar = shift;
2871 open F, ">> $current_test_file" or die $!;
2872 print F "[+] send_packets(): Sending the following packets...\n";
2873 print F Dumper $pkts_ar;
2876 for my $pkt_hr (@$pkts_ar) {
2877 if ($pkt_hr->{'proto'} eq 'tcp' or $pkt_hr->{'proto'} eq 'udp') {
2878 my $socket = IO::Socket::INET->new(
2879 PeerAddr => $pkt_hr->{'dst_ip'},
2880 PeerPort => $pkt_hr->{'port'},
2881 Proto => $pkt_hr->{'proto'},
2883 ) or die "[*] Could not acquire $pkt_hr->{'proto'}/$pkt_hr->{'port'} " .
2884 "socket to $pkt_hr->{'dst_ip'}: $!";
2886 $socket->send($pkt_hr->{'data'});
2889 } elsif ($pkt_hr->{'proto'} eq 'http') {
2891 } elsif ($pkt_hr->{'proto'} eq 'icmp') {
2895 sleep $pkt_hr->{'delay'} if defined $pkt_hr->{'delay'};
2900 sub generic_exec() {
2901 my $test_hr = shift;
2905 my $exec_rv = &run_cmd($test_hr->{'cmdline'},
2906 $cmd_out_tmp, $current_test_file);
2908 if ($test_hr->{'exec_err'} eq $YES) {
2909 $rv = 0 if $exec_rv;
2911 $rv = 0 unless $exec_rv;
2914 if ($test_hr->{'positive_output_matches'}) {
2915 $rv = 0 unless &file_find_regex(
2916 $test_hr->{'positive_output_matches'},
2917 $MATCH_ALL, $current_test_file);
2920 if ($test_hr->{'negative_output_matches'}) {
2921 $rv = 0 if &file_find_regex(
2922 $test_hr->{'negative_output_matches'},
2923 $MATCH_ANY, $current_test_file);
2931 my $test_hr = shift;
2932 return 0 unless $test_hr->{'binary'};
2933 &run_cmd("./hardening-check $test_hr->{'binary'}",
2934 $cmd_out_tmp, $current_test_file);
2935 return 0 if &file_find_regex([qr/Position\sIndependent.*:\sno/i],
2936 $MATCH_ALL, $current_test_file);
2940 ### check for stack protection
2941 sub stack_protected_binary() {
2942 my $test_hr = shift;
2943 return 0 unless $test_hr->{'binary'};
2944 &run_cmd("./hardening-check $test_hr->{'binary'}",
2945 $cmd_out_tmp, $current_test_file);
2946 return 0 if &file_find_regex([qr/Stack\sprotected.*:\sno/i],
2947 $MATCH_ALL, $current_test_file);
2951 ### check for fortified source functions
2952 sub fortify_source_functions() {
2953 my $test_hr = shift;
2954 return 0 unless $test_hr->{'binary'};
2955 &run_cmd("./hardening-check $test_hr->{'binary'}",
2956 $cmd_out_tmp, $current_test_file);
2957 return 0 if &file_find_regex([qr/Fortify\sSource\sfunctions:\sno/i],
2958 $MATCH_ALL, $current_test_file);
2962 ### check for read-only relocations
2963 sub read_only_relocations() {
2964 my $test_hr = shift;
2965 return 0 unless $test_hr->{'binary'};
2966 &run_cmd("./hardening-check $test_hr->{'binary'}",
2967 $cmd_out_tmp, $current_test_file);
2968 return 0 if &file_find_regex([qr/Read.only\srelocations:\sno/i],
2969 $MATCH_ALL, $current_test_file);
2973 ### check for immediate binding
2974 sub immediate_binding() {
2975 my $test_hr = shift;
2976 return 0 unless $test_hr->{'binary'};
2977 &run_cmd("./hardening-check $test_hr->{'binary'}",
2978 $cmd_out_tmp, $current_test_file);
2979 return 0 if &file_find_regex([qr/Immediate\sbinding:\sno/i],
2980 $MATCH_ALL, $current_test_file);
2986 &run_cmd("LD_LIBRARY_PATH=$lib_dir $valgrind_str $fwknopdCmd " .
2987 "$default_server_conf_args --fw-list-all",
2988 $cmd_out_tmp, $current_test_file);
2996 'ls -l /etc', 'if [ -e /etc/issue ]; then cat /etc/issue; fi',
2997 'if [ `which iptables` ]; then iptables -V; fi',
2998 'if [ -e /proc/cpuinfo ]; then cat /proc/cpuinfo; fi',
2999 'if [ -e /proc/config.gz ]; then zcat /proc/config.gz; fi',
3000 'if [ `which gpg` ]; then gpg --version; fi',
3001 'if [ `which tcpdump` ]; then ldd `which tcpdump`; fi',
3005 'ls -l /usr/lib/*pcap*',
3006 'ls -l /usr/local/lib/*pcap*',
3007 'ls -l /usr/lib/*fko*',
3008 'ls -l /usr/local/lib/*fko*',
3010 &run_cmd($cmd, $cmd_out_tmp, $current_test_file);
3012 if ($cmd =~ /^ldd/) {
3013 $have_gpgme++ if &file_find_regex([qr/gpgme/],
3014 $MATCH_ALL, $cmd_out_tmp);
3018 ### all three of fwknop/fwknopd/libfko must link against gpgme in order
3019 ### to enable gpg tests
3020 unless ($have_gpgme == 3) {
3021 push @tests_to_exclude, qr/GPG/;
3027 sub time_for_valgrind() {
3029 while (&run_cmd("ps axuww | grep LD_LIBRARY_PATH | " .
3030 "grep valgrind |grep -v perl | grep -v grep",
3031 $cmd_out_tmp, $current_test_file)) {
3039 sub anonymize_results() {
3041 die "[*] $output_dir does not exist" unless -d $output_dir;
3042 die "[*] $logfile does not exist, has $0 been executed?"
3045 unlink $tarfile or die "[*] Could not unlink $tarfile: $!";
3048 ### remove non-loopback IP addresses
3049 my $search_re = qr/\b127\.0\.0\.1\b/;
3050 system "perl -p -i -e 's|$search_re|00MY1271STR00|g' $output_dir/*.test";
3051 $search_re = qr/\b127\.0\.0\.2\b/;
3052 system "perl -p -i -e 's|$search_re|00MY1272STR00|g' $output_dir/*.test";
3053 $search_re = qr/\b0\.0\.0\.0\b/;
3054 system "perl -p -i -e 's|$search_re|00MY0000STR00|g' $output_dir/*.test";
3055 $search_re = qr/\b(?:[0-2]?\d{1,2}\.){3}[0-2]?\d{1,2}\b/;
3056 system "perl -p -i -e 's|$search_re|N.N.N.N|g' $output_dir/*.test";
3057 system "perl -p -i -e 's|00MY1271STR00|127.0.0.1|g' $output_dir/*.test";
3058 system "perl -p -i -e 's|00MY1272STR00|127.0.0.2|g' $output_dir/*.test";
3059 system "perl -p -i -e 's|00MY0000STR00|0.0.0.0|g' $output_dir/*.test";
3061 ### remove hostname from any uname output
3062 $search_re = qr/\suname\s+\-a\s*\n\s*(\S+)\s+\S+/;
3063 system "perl -p -i -e 'undef \$/; s|$search_re" .
3064 "| uname -a\n\$1 (removed)|s' $output_dir/*.test";
3066 $search_re = qr/uname=\x27(\S+)\s+\S+/;
3067 system "perl -p -i -e 's|$search_re|uname= \$1 (removed)|' $output_dir/*.test";
3070 system "tar cvfz $tarfile $logfile $output_dir";
3071 print "[+] Anonymized test results file: $tarfile\n";
3080 my $test_hr = shift;
3082 open F, "> $default_pid_file" or die $!;
3086 &server_start($test_hr);
3088 open F, "< $default_pid_file" or die $!;
3100 sub start_fwknopd() {
3101 my $test_hr = shift;
3103 &write_test_file("[+] TEST: $test_hr->{'msg'}\n", $server_test_file);
3106 die "[*] Could not fork: $!" unless defined $pid;
3110 ### we are the child, so start fwknopd
3111 exit &run_cmd($test_hr->{'fwknopd_cmdline'},
3112 $server_cmd_tmp, $server_test_file);
3118 my ($key, $file) = @_;
3120 open K, "> $file" or die "[*] Could not open $file: $!";
3121 print K "$loopback_ip: $key\n";
3122 print K "localhost: $key\n";
3123 print K "some.host.through.proxy.com: $key\n";
3129 open C, ">> $current_test_file"
3130 or die "[*] Could not open $current_test_file: $!";
3131 print C "\n" . localtime() . " [+] PID dump:\n";
3133 &run_cmd("ps auxww | grep knop |grep -v grep",
3134 $cmd_out_tmp, $current_test_file);
3139 my ($cmd, $cmd_out, $file) = @_;
3143 or die "[*] Could not open $file: $!";
3144 print F localtime() . " CMD: $cmd\n";
3148 or die "[*] Could not open $file: $!";
3149 print F localtime() . " CMD: $cmd\n";
3153 my $rv = ((system "$cmd > $cmd_out 2>&1") >> 8);
3155 open C, "< $cmd_out" or die "[*] Could not open $cmd_out: $!";
3156 my @cmd_lines = <C>;
3159 open F, ">> $file" or die "[*] Could not open $file: $!";
3160 print F $_ for @cmd_lines;
3173 for (my $i=length($msg); $i < $PRINT_LEN; $i++) {
3182 $|++; ### turn off buffering
3184 $< == 0 && $> == 0 or
3185 die "[*] $0: You must be root (or equivalent ",
3186 "UID 0 account) to effectively test fwknop";
3188 ### validate test hashes
3190 for my $test_hr (@tests) {
3191 for my $key (keys %test_keys) {
3192 if ($test_keys{$key} == $REQUIRED) {
3193 die "[*] Missing '$key' element in hash: $hash_num"
3194 unless defined $test_hr->{$key};
3196 $test_hr->{$key} = '' unless defined $test_hr->{$key};
3202 if ($use_valgrind) {
3203 die "[*] $valgrindCmd exec problem, use --valgrind-path"
3204 unless -e $valgrindCmd and -x $valgrindCmd;
3207 die "[*] $conf_dir directory does not exist." unless -d $conf_dir;
3208 die "[*] $lib_dir directory does not exist." unless -d $lib_dir;
3210 for my $name (keys %cf) {
3211 die "[*] $cf{$name} does not exist" unless -e $cf{$name};
3214 if (-d $output_dir) {
3215 if (-d "${output_dir}.last") {
3216 rmtree "${output_dir}.last"
3217 or die "[*] rmtree ${output_dir}.last $!";
3219 mkdir "${output_dir}.last"
3220 or die "[*] ${output_dir}.last: $!";
3221 for my $file (glob("$output_dir/*.test")) {
3222 if ($file =~ m|.*/(.*)|) {
3223 copy $file, "${output_dir}.last/$1" or die $!;
3226 if (-e "$output_dir/init") {
3227 copy "$output_dir/init", "${output_dir}.last/init";
3230 copy $logfile, "${output_dir}.last/$logfile" or die $!;
3232 $saved_last_results = 1;
3234 mkdir $output_dir or die "[*] Could not mkdir $output_dir: $!";
3236 unless (-d $run_dir) {
3237 mkdir $run_dir or die "[*] Could not mkdir $run_dir: $!";
3240 for my $file (glob("$output_dir/*.test")) {
3241 unlink $file or die "[*] Could not unlink($file)";
3243 if (-e "$output_dir/init") {
3244 unlink "$output_dir/init" or die $!;
3248 unlink $logfile or die $!;
3251 if ($test_include) {
3252 for my $re (split /\s*,\s*/, $test_include) {
3253 push @tests_to_include, qr/$re/;
3256 if ($test_exclude) {
3257 for my $re (split /\s*,\s*/, $test_exclude) {
3258 push @tests_to_exclude, qr/$re/;
3262 ### make sure no fwknopd instance is currently running
3263 die "[*] Please stop the running fwknopd instance."
3264 if &is_fwknopd_running();
3266 unless ($enable_recompilation_warnings_check) {
3267 push @tests_to_exclude, qr/recompilation/;
3270 unless ($enable_make_distcheck) {
3271 push @tests_to_exclude, qr/distcheck/;
3274 unless ($enable_client_ip_resolve_test) {
3275 push @tests_to_exclude, qr/IP resolve/;
3278 $sudo_path = &find_command('sudo');
3280 unless ((&find_command('cc') or &find_command('gcc')) and &find_command('make')) {
3281 ### disable compilation checks
3282 push @tests_to_exclude, qr/recompilation/;
3285 open UNAME, "uname |" or die "[*] Could not execute uname: $!";
3290 } elsif (/freebsd/i) {
3291 $platform = $FREEBSD;
3297 unless ($platform eq $LINUX) {
3298 push @tests_to_exclude, qr/NAT/;
3300 unless ($platform eq $FREEBSD or $platform eq $MACOSX) {
3301 push @tests_to_exclude, qr|active/expire sets|;
3304 if (-e $default_digest_file) {
3305 unlink $default_digest_file;
3311 sub identify_loopback_intf() {
3312 return if $loopback_intf;
3316 ### lo Link encap:Local Loopback
3317 ### inet addr:127.0.0.1 Mask:255.0.0.0
3318 ### inet6 addr: ::1/128 Scope:Host
3319 ### UP LOOPBACK RUNNING MTU:16436 Metric:1
3320 ### RX packets:534709 errors:0 dropped:0 overruns:0 frame:0
3321 ### TX packets:534709 errors:0 dropped:0 overruns:0 carrier:0
3322 ### collisions:0 txqueuelen:0
3323 ### RX bytes:101110617 (101.1 MB) TX bytes:101110617 (101.1 MB)
3327 ### lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384
3328 ### options=3<RXCSUM,TXCSUM>
3329 ### inet6 fe80::1%lo0 prefixlen 64 scopeid 0x2
3330 ### inet6 ::1 prefixlen 128
3331 ### inet 127.0.0.1 netmask 0xff000000
3332 ### nd6 options=3<PERFORMNUD,ACCEPT_RTADV>
3335 my $found_loopback_intf = 0;
3337 my $cmd = 'ifconfig -a';
3338 open C, "$cmd |" or die "[*] (use --loopback <name>) $cmd: $!";
3340 if (/^(\S+?):?\s+.*loopback/i) {
3344 if (/^\S/ and $intf and not $found_loopback_intf) {
3345 ### should not happen
3348 if ($intf and /\b127\.0\.0\.1\b/) {
3349 $found_loopback_intf = 1;
3355 die "[*] could not determine loopback interface, use --loopback <name>"
3356 unless $found_loopback_intf;
3358 $loopback_intf = $intf;
3363 sub parse_valgrind_flagged_functions() {
3364 for my $file (glob("$output_dir/*.test")) {
3365 my $type = 'server';
3366 $type = 'client' if $file =~ /\d\.test/;
3367 open F, "< $file" or die $!;
3369 ### ==30969== by 0x4E3983A: fko_set_username (fko_user.c:65)
3370 if (/^==.*\sby\s\S+\:\s(\S+)\s(.*)/) {
3371 $valgrind_flagged_fcns{$type}{"$1 $2"}++;
3372 $valgrind_flagged_fcns_unique{$type}{$1}++;
3378 open F, ">> $current_test_file" or die $!;
3379 for my $type ('client', 'server') {
3380 print F "\n[+] fwknop $type functions (unique view):\n";
3381 next unless defined $valgrind_flagged_fcns_unique{$type};
3382 for my $fcn (sort {$valgrind_flagged_fcns_unique{$type}{$b}
3383 <=> $valgrind_flagged_fcns_unique{$type}{$a}}
3384 keys %{$valgrind_flagged_fcns_unique{$type}}) {
3385 printf F " %5d : %s\n", $valgrind_flagged_fcns_unique{$type}{$fcn}, $fcn;
3387 print F "\n[+] fwknop $type functions (with call line numbers):\n";
3388 for my $fcn (sort {$valgrind_flagged_fcns{$type}{$b}
3389 <=> $valgrind_flagged_fcns{$type}{$a}} keys %{$valgrind_flagged_fcns{$type}}) {
3390 printf F " %5d : %s\n", $valgrind_flagged_fcns{$type}{$fcn}, $fcn;
3392 next unless defined $valgrind_flagged_fcns{$type};
3399 sub is_fw_rule_active() {
3400 my $test_hr = shift;
3402 my $conf_args = $default_server_conf_args;
3404 if ($test_hr->{'server_conf'}) {
3405 $conf_args = "-c $test_hr->{'server_conf'} -a $cf{'def_access'} " .
3406 "-d $default_digest_file -p $default_pid_file";
3409 if ($test_hr->{'no_ip_check'}) {
3410 return 1 if &run_cmd("LD_LIBRARY_PATH=$lib_dir $fwknopdCmd " .
3411 qq{$conf_args --fw-list | grep -v "# DISABLED" |grep _exp_},
3412 $cmd_out_tmp, $current_test_file);
3414 return 1 if &run_cmd("LD_LIBRARY_PATH=$lib_dir $fwknopdCmd " .
3415 qq{$conf_args --fw-list | grep -v "# DISABLED" |grep $fake_ip |grep _exp_},
3416 $cmd_out_tmp, $current_test_file);
3422 sub is_fwknopd_running() {
3424 sleep 2 if $use_valgrind;
3426 &run_cmd("LD_LIBRARY_PATH=$lib_dir $fwknopdCmd $default_server_conf_args " .
3427 "--status", $cmd_out_tmp, $current_test_file);
3429 return 1 if &file_find_regex([qr/Detected\sfwknopd\sis\srunning/i],
3430 $MATCH_ALL, $cmd_out_tmp);
3435 sub stop_fwknopd() {
3437 &run_cmd("LD_LIBRARY_PATH=$lib_dir $fwknopdCmd " .
3438 "$default_server_conf_args -K", $cmd_out_tmp, $current_test_file);