1package ProFTPD::Tests::Modules::mod_wrap2_sql; 2 3use lib qw(t/lib); 4use base qw(ProFTPD::TestSuite::Child); 5use strict; 6 7use File::Spec; 8use IO::Handle; 9use IO::Socket::INET6; 10 11use ProFTPD::TestSuite::FTP; 12use ProFTPD::TestSuite::Utils qw(:auth :config :features :running :test :testsuite); 13 14$| = 1; 15 16my $order = 0; 17 18my $TESTS = { 19 wrap2_allow_msg => { 20 order => ++$order, 21 test_class => [qw(forking)], 22 }, 23 24 wrap2_deny_msg => { 25 order => ++$order, 26 test_class => [qw(forking)], 27 }, 28 29 wrap2_engine => { 30 order => ++$order, 31 test_class => [qw(forking)], 32 }, 33 34 wrap2_sql_allow_table => { 35 order => ++$order, 36 test_class => [qw(forking)], 37 }, 38 39 wrap2_sql_allow_table_multi_rows_multi_entries => { 40 order => ++$order, 41 test_class => [qw(bug forking)], 42 }, 43 44 wrap2_sql_allow_table_all => { 45 order => ++$order, 46 test_class => [qw(bug forking)], 47 }, 48 49 wrap2_sql_deny_table_ip_addr => { 50 order => ++$order, 51 test_class => [qw(forking)], 52 }, 53 54 wrap2_sql_deny_table_ipv4_netmask => { 55 order => ++$order, 56 test_class => [qw(forking)], 57 }, 58 59 wrap2_sql_deny_table_ipv4mappedv6_netmask => { 60 order => ++$order, 61 test_class => [qw(bug feature_ipv6 forking)], 62 }, 63 64 wrap2_sql_deny_table_ipv6_netmask_bug3606 => { 65 order => ++$order, 66 test_class => [qw(bug feature_ipv6 forking)], 67 }, 68 69 wrap2_sql_deny_table_dns_name => { 70 order => ++$order, 71 test_class => [qw(forking)], 72 }, 73 74 wrap2_sql_deny_table_dns_domain_bug3558 => { 75 order => ++$order, 76 test_class => [qw(bug forking)], 77 }, 78 79 wrap2_sql_user_tables => { 80 order => ++$order, 81 test_class => [qw(forking)], 82 }, 83 84 wrap2_sql_group_tables => { 85 order => ++$order, 86 test_class => [qw(forking)], 87 }, 88 89 wrap2_sql_bug3215 => { 90 order => ++$order, 91 test_class => [qw(bug forking)], 92 }, 93 94 wrap2_bug3341 => { 95 order => ++$order, 96 test_class => [qw(bug forking)], 97 }, 98 99 wrap2_sql_opt_check_on_connect_bug3508 => { 100 order => ++$order, 101 test_class => [qw(bug forking)], 102 }, 103 104 wrap2_allow_msg_bug3538 => { 105 order => ++$order, 106 test_class => [qw(forking)], 107 }, 108 109 wrap2_allow_msg_anon_bug3538 => { 110 order => ++$order, 111 test_class => [qw(forking rootprivs)], 112 }, 113 114 wrap2_sql_deny_event_exec_bug3209 => { 115 order => ++$order, 116 test_class => [qw(forking mod_exec)], 117 }, 118 119}; 120 121sub new { 122 return shift()->SUPER::new(@_); 123} 124 125sub list_tests { 126 return testsuite_get_runnable_tests($TESTS); 127} 128 129sub wrap2_allow_msg { 130 my $self = shift; 131 my $tmpdir = $self->{tmpdir}; 132 133 my $config_file = "$tmpdir/wrap2.conf"; 134 my $pid_file = File::Spec->rel2abs("$tmpdir/wrap2.pid"); 135 my $scoreboard_file = File::Spec->rel2abs("$tmpdir/wrap2.scoreboard"); 136 137 my $log_file = test_get_logfile(); 138 139 my $auth_user_file = File::Spec->rel2abs("$tmpdir/wrap2.passwd"); 140 my $auth_group_file = File::Spec->rel2abs("$tmpdir/wrap2.group"); 141 142 my $db_file = File::Spec->rel2abs("$tmpdir/wrap2.db"); 143 144 # Build up sqlite3 command to create allow, deny tables and populate them 145 my $db_script = File::Spec->rel2abs("$tmpdir/wrap2.sql"); 146 147 my $fh; 148 if (open($fh, "> $db_script")) { 149 print $fh <<EOS; 150CREATE TABLE ftpallow ( 151 name TEXT, 152 allowed TEXT 153); 154 155CREATE TABLE ftpdeny ( 156 name TEXT, 157 denied TEXT 158); 159 160EOS 161 162 unless (close($fh)) { 163 die("Can't write $db_script: $!"); 164 } 165 166 } else { 167 die("Can't open $db_script: $!"); 168 } 169 170 my $cmd = "sqlite3 $db_file < $db_script"; 171 172 if ($ENV{TEST_VERBOSE}) { 173 print STDERR "Executing sqlite3: $cmd\n"; 174 } 175 176 my @output = `$cmd`; 177 178 unlink($db_script); 179 180 my $user = 'proftpd'; 181 my $passwd = 'test'; 182 my $group = 'ftpd'; 183 my $home_dir = File::Spec->rel2abs($tmpdir); 184 my $uid = 500; 185 my $gid = 500; 186 187 # Make sure that, if we're running as root, that the home directory has 188 # permissions/privs set for the account we create 189 if ($< == 0) { 190 unless (chmod(0755, $home_dir)) { 191 die("Can't set perms on $home_dir to 0755: $!"); 192 } 193 194 unless (chown($uid, $gid, $home_dir)) { 195 die("Can't set owner of $home_dir to $uid/$gid: $!"); 196 } 197 } 198 199 auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir, 200 '/bin/bash'); 201 auth_group_write($auth_group_file, $group, $gid, $user); 202 203 my $timeout_idle = 30; 204 205 my $config = { 206 PidFile => $pid_file, 207 ScoreboardFile => $scoreboard_file, 208 SystemLog => $log_file, 209 210 AuthUserFile => $auth_user_file, 211 AuthGroupFile => $auth_group_file, 212 TimeoutIdle => $timeout_idle, 213 214 IfModules => { 215 'mod_delay.c' => { 216 DelayEngine => 'off', 217 }, 218 219 'mod_sql_sqlite.c' => [ 220 'SQLAuthenticate off', 221 "SQLConnectInfo $db_file", 222 'SQLNamedQuery get-allowed-clients SELECT "allowed FROM ftpallow WHERE name = \'%{0}\'"', 223 'SQLNamedQuery get-denied-clients SELECT "denied FROM ftpdeny WHERE name = \'%{0}\'"', 224 "SQLLogFile $log_file", 225 ], 226 227 'mod_wrap2_sql.c' => { 228 WrapEngine => 'on', 229 WrapAllowMsg => '"User %u allowed by access rules"', 230 WrapTables => "sql:/get-allowed-clients sql:/get-denied-clients", 231 WrapLog => $log_file, 232 }, 233 }, 234 }; 235 236 my ($port, $config_user, $config_group) = config_write($config_file, $config); 237 238 # Open pipes, for use between the parent and child processes. Specifically, 239 # the child will indicate when it's done with its test by writing a message 240 # to the parent. 241 my ($rfh, $wfh); 242 unless (pipe($rfh, $wfh)) { 243 die("Can't open pipe: $!"); 244 } 245 246 my $ex; 247 248 # Fork child 249 $self->handle_sigchld(); 250 defined(my $pid = fork()) or die("Can't fork: $!"); 251 if ($pid) { 252 eval { 253 my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port); 254 $client->login($user, $passwd); 255 256 my $resp_code = $client->response_code(); 257 my $resp_msg = $client->response_msg(0); 258 259 my $expected; 260 261 $expected = 230; 262 $self->assert($expected == $resp_code, 263 test_msg("Expected response code $expected, got $resp_code")); 264 265 $expected = "User $user allowed by access rules"; 266 $self->assert($expected eq $resp_msg, 267 test_msg("Expected response message '$expected', got '$resp_msg'")); 268 }; 269 270 if ($@) { 271 $ex = $@; 272 } 273 274 $wfh->print("done\n"); 275 $wfh->flush(); 276 277 } else { 278 eval { server_wait($config_file, $rfh, $timeout_idle + 2) }; 279 if ($@) { 280 warn($@); 281 exit 1; 282 } 283 284 exit 0; 285 } 286 287 # Stop server 288 server_stop($pid_file); 289 290 $self->assert_child_ok($pid); 291 292 if ($ex) { 293 test_append_logfile($log_file, $ex); 294 unlink($log_file); 295 296 die($ex); 297 } 298 299 unlink($log_file); 300} 301 302sub wrap2_deny_msg { 303 my $self = shift; 304 my $tmpdir = $self->{tmpdir}; 305 306 my $config_file = "$tmpdir/wrap2.conf"; 307 my $pid_file = File::Spec->rel2abs("$tmpdir/wrap2.pid"); 308 my $scoreboard_file = File::Spec->rel2abs("$tmpdir/wrap2.scoreboard"); 309 310 my $log_file = test_get_logfile(); 311 312 my $auth_user_file = File::Spec->rel2abs("$tmpdir/wrap2.passwd"); 313 my $auth_group_file = File::Spec->rel2abs("$tmpdir/wrap2.group"); 314 315 my $db_file = File::Spec->rel2abs("$tmpdir/wrap2.db"); 316 317 # Build up sqlite3 command to create allow, deny tables and populate them 318 my $db_script = File::Spec->rel2abs("$tmpdir/wrap2.sql"); 319 320 my $fh; 321 if (open($fh, "> $db_script")) { 322 print $fh <<EOS; 323CREATE TABLE ftpallow ( 324 name TEXT, 325 allowed TEXT 326); 327 328CREATE TABLE ftpdeny ( 329 name TEXT, 330 denied TEXT 331); 332 333INSERT INTO ftpdeny (name, denied) VALUES ('', 'ALL'); 334EOS 335 336 unless (close($fh)) { 337 die("Can't write $db_script: $!"); 338 } 339 340 } else { 341 die("Can't open $db_script: $!"); 342 } 343 344 my $cmd = "sqlite3 $db_file < $db_script"; 345 346 if ($ENV{TEST_VERBOSE}) { 347 print STDERR "Executing sqlite3: $cmd\n"; 348 } 349 350 my @output = `$cmd`; 351 352 unlink($db_script); 353 354 my $user = 'proftpd'; 355 my $passwd = 'test'; 356 my $group = 'ftpd'; 357 my $home_dir = File::Spec->rel2abs($tmpdir); 358 my $uid = 500; 359 my $gid = 500; 360 361 # Make sure that, if we're running as root, that the home directory has 362 # permissions/privs set for the account we create 363 if ($< == 0) { 364 unless (chmod(0755, $home_dir)) { 365 die("Can't set perms on $home_dir to 0755: $!"); 366 } 367 368 unless (chown($uid, $gid, $home_dir)) { 369 die("Can't set owner of $home_dir to $uid/$gid: $!"); 370 } 371 } 372 373 auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir, 374 '/bin/bash'); 375 auth_group_write($auth_group_file, $group, $gid, $user); 376 377 my $timeout_idle = 30; 378 379 my $config = { 380 PidFile => $pid_file, 381 ScoreboardFile => $scoreboard_file, 382 SystemLog => $log_file, 383 384 AuthUserFile => $auth_user_file, 385 AuthGroupFile => $auth_group_file, 386 TimeoutIdle => $timeout_idle, 387 388 IfModules => { 389 'mod_delay.c' => { 390 DelayEngine => 'off', 391 }, 392 393 'mod_sql_sqlite.c' => [ 394 'SQLAuthenticate off', 395 "SQLConnectInfo $db_file", 396 'SQLNamedQuery get-allowed-clients SELECT "allowed FROM ftpallow WHERE name = \'%{0}\'"', 397 'SQLNamedQuery get-denied-clients SELECT "denied FROM ftpdeny WHERE name = \'%{0}\'"', 398 "SQLLogFile $log_file", 399 ], 400 401 'mod_wrap2_sql.c' => { 402 WrapEngine => 'on', 403 WrapDenyMsg => '"User %u rejected by access rules"', 404 WrapTables => "sql:/get-allowed-clients sql:/get-denied-clients", 405 WrapLog => $log_file, 406 }, 407 }, 408 }; 409 410 my ($port, $config_user, $config_group) = config_write($config_file, $config); 411 412 # Open pipes, for use between the parent and child processes. Specifically, 413 # the child will indicate when it's done with its test by writing a message 414 # to the parent. 415 my ($rfh, $wfh); 416 unless (pipe($rfh, $wfh)) { 417 die("Can't open pipe: $!"); 418 } 419 420 my $ex; 421 422 # Fork child 423 $self->handle_sigchld(); 424 defined(my $pid = fork()) or die("Can't fork: $!"); 425 if ($pid) { 426 eval { 427 my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port); 428 429 my ($resp_code, $resp_msg); 430 431 eval { $client->login($user, $passwd) }; 432 unless ($@) { 433 die("Login succeeded unexpectedly"); 434 435 } else { 436 $resp_code = $client->response_code(); 437 $resp_msg = $client->response_msg(); 438 } 439 440 my $expected; 441 442 $expected = 530; 443 $self->assert($expected == $resp_code, 444 test_msg("Expected response code $expected, got $resp_code")); 445 446 $expected = "User $user rejected by access rules"; 447 $self->assert($expected eq $resp_msg, 448 test_msg("Expected response message '$expected', got '$resp_msg'")); 449 }; 450 451 if ($@) { 452 $ex = $@; 453 } 454 455 $wfh->print("done\n"); 456 $wfh->flush(); 457 458 } else { 459 eval { server_wait($config_file, $rfh, $timeout_idle + 2) }; 460 if ($@) { 461 warn($@); 462 exit 1; 463 } 464 465 exit 0; 466 } 467 468 # Stop server 469 server_stop($pid_file); 470 471 $self->assert_child_ok($pid); 472 473 if ($ex) { 474 test_append_logfile($log_file, $ex); 475 unlink($log_file); 476 477 die($ex); 478 } 479 480 unlink($log_file); 481} 482 483sub wrap2_engine { 484 my $self = shift; 485 my $tmpdir = $self->{tmpdir}; 486 487 my $config_file = "$tmpdir/wrap2.conf"; 488 my $pid_file = File::Spec->rel2abs("$tmpdir/wrap2.pid"); 489 my $scoreboard_file = File::Spec->rel2abs("$tmpdir/wrap2.scoreboard"); 490 491 my $log_file = test_get_logfile(); 492 493 my $auth_user_file = File::Spec->rel2abs("$tmpdir/wrap2.passwd"); 494 my $auth_group_file = File::Spec->rel2abs("$tmpdir/wrap2.group"); 495 496 my $db_file = File::Spec->rel2abs("$tmpdir/wrap2.db"); 497 498 # Build up sqlite3 command to create allow, deny tables and populate them 499 my $db_script = File::Spec->rel2abs("$tmpdir/wrap2.sql"); 500 501 my $fh; 502 if (open($fh, "> $db_script")) { 503 print $fh <<EOS; 504CREATE TABLE ftpallow ( 505 name TEXT, 506 allowed TEXT 507); 508 509CREATE TABLE ftpdeny ( 510 name TEXT, 511 denied TEXT 512); 513 514INSERT INTO ftpdeny (name, denied) VALUES ('', 'ALL'); 515EOS 516 517 unless (close($fh)) { 518 die("Can't write $db_script: $!"); 519 } 520 521 } else { 522 die("Can't open $db_script: $!"); 523 } 524 525 my $cmd = "sqlite3 $db_file < $db_script"; 526 527 if ($ENV{TEST_VERBOSE}) { 528 print STDERR "Executing sqlite3: $cmd\n"; 529 } 530 531 my @output = `$cmd`; 532 533 unlink($db_script); 534 535 my $user = 'proftpd'; 536 my $passwd = 'test'; 537 my $group = 'ftpd'; 538 my $home_dir = File::Spec->rel2abs($tmpdir); 539 my $uid = 500; 540 my $gid = 500; 541 542 # Make sure that, if we're running as root, that the home directory has 543 # permissions/privs set for the account we create 544 if ($< == 0) { 545 unless (chmod(0755, $home_dir)) { 546 die("Can't set perms on $home_dir to 0755: $!"); 547 } 548 549 unless (chown($uid, $gid, $home_dir)) { 550 die("Can't set owner of $home_dir to $uid/$gid: $!"); 551 } 552 } 553 554 auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir, 555 '/bin/bash'); 556 auth_group_write($auth_group_file, $group, $gid, $user); 557 558 my $timeout_idle = 30; 559 560 my $config = { 561 PidFile => $pid_file, 562 ScoreboardFile => $scoreboard_file, 563 SystemLog => $log_file, 564 565 AuthUserFile => $auth_user_file, 566 AuthGroupFile => $auth_group_file, 567 TimeoutIdle => $timeout_idle, 568 569 IfModules => { 570 'mod_delay.c' => { 571 DelayEngine => 'off', 572 }, 573 574 'mod_sql_sqlite.c' => [ 575 'SQLAuthenticate off', 576 "SQLConnectInfo $db_file", 577 'SQLNamedQuery get-allowed-clients SELECT "allowed FROM ftpallow WHERE name = \'%{0}\'"', 578 'SQLNamedQuery get-denied-clients SELECT "denied FROM ftpdeny WHERE name = \'%{0}\'"', 579 "SQLLogFile $log_file", 580 ], 581 582 'mod_wrap2_sql.c' => { 583 WrapEngine => 'off', 584 WrapAllowMsg => '"User %u allowed by access rules"', 585 WrapDenyMsg => '"User %u rejected by access rules"', 586 WrapTables => "sql:/get-allowed-clients sql:/get-denied-clients", 587 }, 588 }, 589 }; 590 591 my ($port, $config_user, $config_group) = config_write($config_file, $config); 592 593 # Open pipes, for use between the parent and child processes. Specifically, 594 # the child will indicate when it's done with its test by writing a message 595 # to the parent. 596 my ($rfh, $wfh); 597 unless (pipe($rfh, $wfh)) { 598 die("Can't open pipe: $!"); 599 } 600 601 my $ex; 602 603 # Fork child 604 $self->handle_sigchld(); 605 defined(my $pid = fork()) or die("Can't fork: $!"); 606 if ($pid) { 607 eval { 608 my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port); 609 my ($resp_code, $resp_msg) = $client->login($user, $passwd); 610 611 my $expected; 612 613 $expected = 230; 614 $self->assert($expected == $resp_code, 615 test_msg("Expected response code $expected, got $resp_code")); 616 617 $expected = "User $user logged in"; 618 $self->assert($expected eq $resp_msg, 619 test_msg("Expected response message '$expected', got '$resp_msg'")); 620 }; 621 622 if ($@) { 623 $ex = $@; 624 } 625 626 $wfh->print("done\n"); 627 $wfh->flush(); 628 629 } else { 630 eval { server_wait($config_file, $rfh, $timeout_idle + 2) }; 631 if ($@) { 632 warn($@); 633 exit 1; 634 } 635 636 exit 0; 637 } 638 639 # Stop server 640 server_stop($pid_file); 641 642 $self->assert_child_ok($pid); 643 644 if ($ex) { 645 test_append_logfile($log_file, $ex); 646 unlink($log_file); 647 648 die($ex); 649 } 650 651 unlink($log_file); 652} 653 654sub wrap2_sql_allow_table { 655 my $self = shift; 656 my $tmpdir = $self->{tmpdir}; 657 658 my $config_file = "$tmpdir/wrap2.conf"; 659 my $pid_file = File::Spec->rel2abs("$tmpdir/wrap2.pid"); 660 my $scoreboard_file = File::Spec->rel2abs("$tmpdir/wrap2.scoreboard"); 661 662 my $log_file = test_get_logfile(); 663 664 my $auth_user_file = File::Spec->rel2abs("$tmpdir/wrap2.passwd"); 665 my $auth_group_file = File::Spec->rel2abs("$tmpdir/wrap2.group"); 666 667 my $db_file = File::Spec->rel2abs("$tmpdir/wrap2.db"); 668 669 # Build up sqlite3 command to create allow, deny tables and populate them 670 my $db_script = File::Spec->rel2abs("$tmpdir/wrap2.sql"); 671 672 my $fh; 673 if (open($fh, "> $db_script")) { 674 print $fh <<EOS; 675CREATE TABLE ftpallow ( 676 name TEXT, 677 allowed TEXT 678); 679 680CREATE TABLE ftpdeny ( 681 name TEXT, 682 denied TEXT 683); 684 685EOS 686 687 unless (close($fh)) { 688 die("Can't write $db_script: $!"); 689 } 690 691 } else { 692 die("Can't open $db_script: $!"); 693 } 694 695 my $cmd = "sqlite3 $db_file < $db_script"; 696 697 if ($ENV{TEST_VERBOSE}) { 698 print STDERR "Executing sqlite3: $cmd\n"; 699 } 700 701 my @output = `$cmd`; 702 703 unlink($db_script); 704 705 my $user = 'proftpd'; 706 my $passwd = 'test'; 707 my $group = 'ftpd'; 708 my $home_dir = File::Spec->rel2abs($tmpdir); 709 my $uid = 500; 710 my $gid = 500; 711 712 # Make sure that, if we're running as root, that the home directory has 713 # permissions/privs set for the account we create 714 if ($< == 0) { 715 unless (chmod(0755, $home_dir)) { 716 die("Can't set perms on $home_dir to 0755: $!"); 717 } 718 719 unless (chown($uid, $gid, $home_dir)) { 720 die("Can't set owner of $home_dir to $uid/$gid: $!"); 721 } 722 } 723 724 auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir, 725 '/bin/bash'); 726 auth_group_write($auth_group_file, $group, $gid, $user); 727 728 my $timeout_idle = 30; 729 730 my $config = { 731 PidFile => $pid_file, 732 ScoreboardFile => $scoreboard_file, 733 SystemLog => $log_file, 734 735 AuthUserFile => $auth_user_file, 736 AuthGroupFile => $auth_group_file, 737 TimeoutIdle => $timeout_idle, 738 739 IfModules => { 740 'mod_delay.c' => { 741 DelayEngine => 'off', 742 }, 743 744 'mod_sql_sqlite.c' => [ 745 'SQLAuthenticate off', 746 "SQLConnectInfo $db_file", 747 'SQLNamedQuery get-allowed-clients SELECT "allowed FROM ftpallow WHERE name = \'%{0}\'"', 748 'SQLNamedQuery get-denied-clients SELECT "denied FROM ftpdeny WHERE name = \'%{0}\'"', 749 "SQLLogFile $log_file", 750 ], 751 752 'mod_wrap2_sql.c' => { 753 WrapEngine => 'on', 754 WrapTables => "sql:/get-allowed-clients sql:/get-denied-clients", 755 }, 756 }, 757 }; 758 759 my ($port, $config_user, $config_group) = config_write($config_file, $config); 760 761 # Open pipes, for use between the parent and child processes. Specifically, 762 # the child will indicate when it's done with its test by writing a message 763 # to the parent. 764 my ($rfh, $wfh); 765 unless (pipe($rfh, $wfh)) { 766 die("Can't open pipe: $!"); 767 } 768 769 my $ex; 770 771 # Fork child 772 $self->handle_sigchld(); 773 defined(my $pid = fork()) or die("Can't fork: $!"); 774 if ($pid) { 775 eval { 776 my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port); 777 my ($resp_code, $resp_msg) = $client->login($user, $passwd); 778 779 my $expected; 780 781 $expected = 230; 782 $self->assert($expected == $resp_code, 783 test_msg("Expected response code $expected, got $resp_code")); 784 785 $expected = "User $user logged in"; 786 $self->assert($expected eq $resp_msg, 787 test_msg("Expected response message '$expected', got '$resp_msg'")); 788 }; 789 790 if ($@) { 791 $ex = $@; 792 } 793 794 $wfh->print("done\n"); 795 $wfh->flush(); 796 797 } else { 798 eval { server_wait($config_file, $rfh, $timeout_idle + 2) }; 799 if ($@) { 800 warn($@); 801 exit 1; 802 } 803 804 exit 0; 805 } 806 807 # Stop server 808 server_stop($pid_file); 809 810 $self->assert_child_ok($pid); 811 812 if ($ex) { 813 die($ex); 814 } 815 816 if (open($fh, "> $db_script")) { 817 print $fh <<EOS; 818INSERT INTO ftpallow (name, allowed) VALUES ('', '127.0.0.1'); 819EOS 820 unless (close($fh)) { 821 die("Can't write $db_script: $!"); 822 } 823 824 } else { 825 die("Can't open $db_script: $!"); 826 } 827 828 $cmd = "sqlite3 $db_file < $db_script"; 829 830 if ($ENV{TEST_VERBOSE}) { 831 print STDERR "Executing sqlite3: $cmd\n"; 832 } 833 834 @output = `$cmd`; 835 836 unlink($db_script); 837 838 ($port, $config_user, $config_group) = config_write($config_file, $config); 839 840 # Fork child 841 $self->handle_sigchld(); 842 defined($pid = fork()) or die("Can't fork: $!"); 843 if ($pid) { 844 eval { 845 my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port); 846 my ($resp_code, $resp_msg) = $client->login($user, $passwd); 847 848 my $expected; 849 850 $expected = 230; 851 $self->assert($expected == $resp_code, 852 test_msg("Expected response code $expected, got $resp_code")); 853 854 $expected = "User $user logged in"; 855 $self->assert($expected eq $resp_msg, 856 test_msg("Expected response message '$expected', got '$resp_msg'")); 857 }; 858 859 if ($@) { 860 $ex = $@; 861 } 862 863 $wfh->print("done\n"); 864 $wfh->flush(); 865 866 } else { 867 eval { server_wait($config_file, $rfh, $timeout_idle + 2) }; 868 if ($@) { 869 warn($@); 870 exit 1; 871 } 872 873 exit 0; 874 } 875 876 # Stop server 877 server_stop($pid_file); 878 879 $self->assert_child_ok($pid); 880 881 if ($ex) { 882 test_append_logfile($log_file, $ex); 883 unlink($log_file); 884 885 die($ex); 886 } 887 888 unlink($log_file); 889} 890 891sub wrap2_sql_allow_table_multi_rows_multi_entries { 892 my $self = shift; 893 my $tmpdir = $self->{tmpdir}; 894 895 my $config_file = "$tmpdir/wrap2.conf"; 896 my $pid_file = File::Spec->rel2abs("$tmpdir/wrap2.pid"); 897 my $scoreboard_file = File::Spec->rel2abs("$tmpdir/wrap2.scoreboard"); 898 899 my $log_file = test_get_logfile(); 900 901 my $auth_user_file = File::Spec->rel2abs("$tmpdir/wrap2.passwd"); 902 my $auth_group_file = File::Spec->rel2abs("$tmpdir/wrap2.group"); 903 904 my $user = 'proftpd'; 905 my $passwd = 'test'; 906 my $group = 'ftpd'; 907 my $home_dir = File::Spec->rel2abs($tmpdir); 908 my $uid = 500; 909 my $gid = 500; 910 911 my $db_file = File::Spec->rel2abs("$tmpdir/wrap2.db"); 912 913 # Build up sqlite3 command to create allow, deny tables and populate them 914 my $db_script = File::Spec->rel2abs("$tmpdir/wrap2.sql"); 915 916 my $fh; 917 if (open($fh, "> $db_script")) { 918 print $fh <<EOS; 919CREATE TABLE ftpallow ( 920 name TEXT, 921 allowed TEXT 922); 923 924INSERT INTO ftpallow (name, allowed) VALUES ('', '192.168.127.5, 192.168.127.6'); 925INSERT INTO ftpallow (name, allowed) VALUES ('', '192.168.127.1 192.168.127.2 127.0.0.1'); 926INSERT INTO ftpallow (name, allowed) VALUES ('', '192.168.127.3,192.168.127.4 127.0.0.1'); 927 928CREATE TABLE ftpdeny ( 929 name TEXT, 930 denied TEXT 931); 932 933INSERT INTO ftpdeny (name, denied) VALUES ('', 'ALL'); 934EOS 935 936 unless (close($fh)) { 937 die("Can't write $db_script: $!"); 938 } 939 940 } else { 941 die("Can't open $db_script: $!"); 942 } 943 944 my $cmd = "sqlite3 $db_file < $db_script"; 945 if ($ENV{TEST_VERBOSE}) { 946 print STDERR "Executing sqlite3: $cmd\n"; 947 } 948 949 my @output = `$cmd`; 950 951 unlink($db_script); 952 953 # Make sure that, if we're running as root, that the home directory has 954 # permissions/privs set for the account we create 955 if ($< == 0) { 956 unless (chmod(0755, $home_dir)) { 957 die("Can't set perms on $home_dir to 0755: $!"); 958 } 959 960 unless (chown($uid, $gid, $home_dir)) { 961 die("Can't set owner of $home_dir to $uid/$gid: $!"); 962 } 963 } 964 965 auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir, 966 '/bin/bash'); 967 auth_group_write($auth_group_file, $group, $gid, $user); 968 969 my $timeout_idle = 30; 970 971 my $config = { 972 PidFile => $pid_file, 973 ScoreboardFile => $scoreboard_file, 974 SystemLog => $log_file, 975 976 AuthUserFile => $auth_user_file, 977 AuthGroupFile => $auth_group_file, 978 TimeoutIdle => $timeout_idle, 979 980 IfModules => { 981 'mod_delay.c' => { 982 DelayEngine => 'off', 983 }, 984 985 'mod_sql_sqlite.c' => [ 986 'SQLAuthenticate off', 987 "SQLConnectInfo $db_file", 988 "SQLLogFile $log_file", 989 'SQLNamedQuery get-allowed-clients SELECT "allowed FROM ftpallow WHERE name = \'%{0}\'"', 990 'SQLNamedQuery get-denied-clients SELECT "denied FROM ftpdeny WHERE name = \'%{0}\'"', 991 ], 992 993 'mod_wrap2_sql.c' => { 994 WrapEngine => 'on', 995 WrapLog => $log_file, 996 WrapTables => "sql:/get-allowed-clients sql:/get-denied-clients", 997 }, 998 }, 999 }; 1000 1001 my ($port, $config_user, $config_group) = config_write($config_file, $config); 1002 1003 # Open pipes, for use between the parent and child processes. Specifically, 1004 # the child will indicate when it's done with its test by writing a message 1005 # to the parent. 1006 my ($rfh, $wfh); 1007 unless (pipe($rfh, $wfh)) { 1008 die("Can't open pipe: $!"); 1009 } 1010 1011 my $ex; 1012 1013 # Fork child 1014 $self->handle_sigchld(); 1015 defined(my $pid = fork()) or die("Can't fork: $!"); 1016 if ($pid) { 1017 eval { 1018 my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port); 1019 my ($resp_code, $resp_msg) = $client->login($user, $passwd); 1020 1021 my $expected; 1022 1023 $expected = 230; 1024 $self->assert($expected == $resp_code, 1025 test_msg("Expected response code $expected, got $resp_code")); 1026 1027 $expected = "User $user logged in"; 1028 $self->assert($expected eq $resp_msg, 1029 test_msg("Expected response message '$expected', got '$resp_msg'")); 1030 }; 1031 1032 if ($@) { 1033 $ex = $@; 1034 } 1035 1036 $wfh->print("done\n"); 1037 $wfh->flush(); 1038 1039 } else { 1040 eval { server_wait($config_file, $rfh, $timeout_idle + 2) }; 1041 if ($@) { 1042 warn($@); 1043 exit 1; 1044 } 1045 1046 exit 0; 1047 } 1048 1049 # Stop server 1050 server_stop($pid_file); 1051 1052 $self->assert_child_ok($pid); 1053 1054 if ($ex) { 1055 test_append_logfile($log_file, $ex); 1056 unlink($log_file); 1057 1058 die($ex); 1059 } 1060 1061 unlink($log_file); 1062} 1063 1064sub wrap2_sql_allow_table_all { 1065 my $self = shift; 1066 my $tmpdir = $self->{tmpdir}; 1067 1068 my $config_file = "$tmpdir/wrap2.conf"; 1069 my $pid_file = File::Spec->rel2abs("$tmpdir/wrap2.pid"); 1070 my $scoreboard_file = File::Spec->rel2abs("$tmpdir/wrap2.scoreboard"); 1071 1072 my $log_file = test_get_logfile(); 1073 1074 my $auth_user_file = File::Spec->rel2abs("$tmpdir/wrap2.passwd"); 1075 my $auth_group_file = File::Spec->rel2abs("$tmpdir/wrap2.group"); 1076 1077 my $db_file = File::Spec->rel2abs("$tmpdir/wrap2.db"); 1078 1079 # Build up sqlite3 command to create allow, deny tables and populate them 1080 my $db_script = File::Spec->rel2abs("$tmpdir/wrap2.sql"); 1081 1082 my $fh; 1083 if (open($fh, "> $db_script")) { 1084 print $fh <<EOS; 1085CREATE TABLE ftpallow ( 1086 name TEXT, 1087 allowed TEXT 1088); 1089 1090INSERT INTO ftpallow (name, allowed) VALUES ('', 'ALL'); 1091 1092CREATE TABLE ftpdeny ( 1093 name TEXT, 1094 denied TEXT 1095); 1096 1097INSERT INTO ftpdeny (name, allowed) VALUES ('', 'ALL'); 1098EOS 1099 1100 unless (close($fh)) { 1101 die("Can't write $db_script: $!"); 1102 } 1103 1104 } else { 1105 die("Can't open $db_script: $!"); 1106 } 1107 1108 my $cmd = "sqlite3 $db_file < $db_script"; 1109 if ($ENV{TEST_VERBOSE}) { 1110 print STDERR "Executing sqlite3: $cmd\n"; 1111 } 1112 1113 my @output = `$cmd`; 1114 1115 unlink($db_script); 1116 1117 my $user = 'proftpd'; 1118 my $passwd = 'test'; 1119 my $group = 'ftpd'; 1120 my $home_dir = File::Spec->rel2abs($tmpdir); 1121 my $uid = 500; 1122 my $gid = 500; 1123 1124 # Make sure that, if we're running as root, that the home directory has 1125 # permissions/privs set for the account we create 1126 if ($< == 0) { 1127 unless (chmod(0755, $home_dir)) { 1128 die("Can't set perms on $home_dir to 0755: $!"); 1129 } 1130 1131 unless (chown($uid, $gid, $home_dir)) { 1132 die("Can't set owner of $home_dir to $uid/$gid: $!"); 1133 } 1134 } 1135 1136 auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir, 1137 '/bin/bash'); 1138 auth_group_write($auth_group_file, $group, $gid, $user); 1139 1140 my $timeout_idle = 30; 1141 1142 my $config = { 1143 TraceLog => $log_file, 1144 Trace => 'dns:10', 1145 PidFile => $pid_file, 1146 ScoreboardFile => $scoreboard_file, 1147 SystemLog => $log_file, 1148 1149 AuthUserFile => $auth_user_file, 1150 AuthGroupFile => $auth_group_file, 1151 TimeoutIdle => $timeout_idle, 1152 1153 IfModules => { 1154 'mod_delay.c' => { 1155 DelayEngine => 'off', 1156 }, 1157 1158 'mod_sql_sqlite.c' => [ 1159 'SQLAuthenticate off', 1160 "SQLConnectInfo $db_file", 1161 'SQLNamedQuery get-allowed-clients SELECT "allowed FROM ftpallow WHERE name = \'%{0}\'"', 1162 'SQLNamedQuery get-denied-clients SELECT "denied FROM ftpdeny WHERE name = \'%{0}\'"', 1163 "SQLLogFile $log_file", 1164 ], 1165 1166 'mod_wrap2_sql.c' => { 1167 WrapEngine => 'on', 1168 WrapTables => "sql:/get-allowed-clients sql:/get-denied-clients", 1169 }, 1170 }, 1171 }; 1172 1173 my ($port, $config_user, $config_group) = config_write($config_file, $config); 1174 1175 # Open pipes, for use between the parent and child processes. Specifically, 1176 # the child will indicate when it's done with its test by writing a message 1177 # to the parent. 1178 my ($rfh, $wfh); 1179 unless (pipe($rfh, $wfh)) { 1180 die("Can't open pipe: $!"); 1181 } 1182 1183 my $ex; 1184 1185 # Fork child 1186 $self->handle_sigchld(); 1187 defined(my $pid = fork()) or die("Can't fork: $!"); 1188 if ($pid) { 1189 eval { 1190 my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port); 1191 my ($resp_code, $resp_msg) = $client->login($user, $passwd); 1192 1193 my $expected; 1194 1195 $expected = 230; 1196 $self->assert($expected == $resp_code, 1197 test_msg("Expected response code $expected, got $resp_code")); 1198 1199 $expected = "User $user logged in"; 1200 $self->assert($expected eq $resp_msg, 1201 test_msg("Expected response message '$expected', got '$resp_msg'")); 1202 }; 1203 1204 if ($@) { 1205 $ex = $@; 1206 } 1207 1208 $wfh->print("done\n"); 1209 $wfh->flush(); 1210 1211 } else { 1212 eval { server_wait($config_file, $rfh, $timeout_idle + 2) }; 1213 if ($@) { 1214 warn($@); 1215 exit 1; 1216 } 1217 1218 exit 0; 1219 } 1220 1221 # Stop server 1222 server_stop($pid_file); 1223 1224 $self->assert_child_ok($pid); 1225 1226 if ($ex) { 1227 test_append_logfile($log_file, $ex); 1228 unlink($log_file); 1229 1230 die($ex); 1231 } 1232 1233 unlink($log_file); 1234} 1235 1236sub wrap2_sql_deny_table_ip_addr { 1237 my $self = shift; 1238 my $tmpdir = $self->{tmpdir}; 1239 1240 my $config_file = "$tmpdir/wrap2.conf"; 1241 my $pid_file = File::Spec->rel2abs("$tmpdir/wrap2.pid"); 1242 my $scoreboard_file = File::Spec->rel2abs("$tmpdir/wrap2.scoreboard"); 1243 1244 my $log_file = test_get_logfile(); 1245 1246 my $auth_user_file = File::Spec->rel2abs("$tmpdir/wrap2.passwd"); 1247 my $auth_group_file = File::Spec->rel2abs("$tmpdir/wrap2.group"); 1248 1249 my $db_file = File::Spec->rel2abs("$tmpdir/wrap2.db"); 1250 1251 # Build up sqlite3 command to create allow, deny tables and populate them 1252 my $db_script = File::Spec->rel2abs("$tmpdir/wrap2.sql"); 1253 1254 my $fh; 1255 if (open($fh, "> $db_script")) { 1256 print $fh <<EOS; 1257CREATE TABLE ftpallow ( 1258 name TEXT, 1259 allowed TEXT 1260); 1261 1262CREATE TABLE ftpdeny ( 1263 name TEXT, 1264 denied TEXT 1265); 1266 1267INSERT INTO ftpdeny (name, denied) VALUES ('', 'ALL'); 1268EOS 1269 1270 unless (close($fh)) { 1271 die("Can't write $db_script: $!"); 1272 } 1273 1274 } else { 1275 die("Can't open $db_script: $!"); 1276 } 1277 1278 my $cmd = "sqlite3 $db_file < $db_script"; 1279 1280 if ($ENV{TEST_VERBOSE}) { 1281 print STDERR "Executing sqlite3: $cmd\n"; 1282 } 1283 1284 my @output = `$cmd`; 1285 1286 unlink($db_script); 1287 1288 my $user = 'proftpd'; 1289 my $passwd = 'test'; 1290 my $group = 'ftpd'; 1291 my $home_dir = File::Spec->rel2abs($tmpdir); 1292 my $uid = 500; 1293 my $gid = 500; 1294 1295 # Make sure that, if we're running as root, that the home directory has 1296 # permissions/privs set for the account we create 1297 if ($< == 0) { 1298 unless (chmod(0755, $home_dir)) { 1299 die("Can't set perms on $home_dir to 0755: $!"); 1300 } 1301 1302 unless (chown($uid, $gid, $home_dir)) { 1303 die("Can't set owner of $home_dir to $uid/$gid: $!"); 1304 } 1305 } 1306 1307 auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir, 1308 '/bin/bash'); 1309 auth_group_write($auth_group_file, $group, $gid, $user); 1310 1311 my $timeout_idle = 30; 1312 1313 my $config = { 1314 PidFile => $pid_file, 1315 ScoreboardFile => $scoreboard_file, 1316 SystemLog => $log_file, 1317 1318 AuthUserFile => $auth_user_file, 1319 AuthGroupFile => $auth_group_file, 1320 TimeoutIdle => $timeout_idle, 1321 1322 IfModules => { 1323 'mod_delay.c' => { 1324 DelayEngine => 'off', 1325 }, 1326 1327 'mod_sql_sqlite.c' => [ 1328 "SQLAuthenticate off", 1329 "SQLConnectInfo $db_file", 1330 'SQLNamedQuery get-allowed-clients SELECT "allowed FROM ftpallow WHERE name = \'%{0}\'"', 1331 'SQLNamedQuery get-denied-clients SELECT "denied FROM ftpdeny WHERE name = \'%{0}\'"', 1332 "SQLLogFile $log_file", 1333 ], 1334 1335 'mod_wrap2_sql.c' => { 1336 WrapEngine => 'on', 1337 WrapTables => "sql:/get-allowed-clients sql:/get-denied-clients", 1338 WrapLog => $log_file, 1339 }, 1340 }, 1341 }; 1342 1343 my ($port, $config_user, $config_group) = config_write($config_file, $config); 1344 1345 # Open pipes, for use between the parent and child processes. Specifically, 1346 # the child will indicate when it's done with its test by writing a message 1347 # to the parent. 1348 my ($rfh, $wfh); 1349 unless (pipe($rfh, $wfh)) { 1350 die("Can't open pipe: $!"); 1351 } 1352 1353 my $ex; 1354 1355 # Fork child 1356 $self->handle_sigchld(); 1357 defined(my $pid = fork()) or die("Can't fork: $!"); 1358 if ($pid) { 1359 eval { 1360 my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port); 1361 eval { $client->login($user, $passwd) }; 1362 unless ($@) { 1363 die("Login succeeded unexpectedly"); 1364 } 1365 1366 my $resp_code = $client->response_code(); 1367 my $resp_msg = $client->response_msg(); 1368 1369 my $expected; 1370 1371 $expected = 530; 1372 $self->assert($expected == $resp_code, 1373 test_msg("Expected response code $expected, got $resp_code")); 1374 1375 $expected = "Access denied"; 1376 $self->assert($expected eq $resp_msg, 1377 test_msg("Expected response message '$expected', got '$resp_msg'")); 1378 }; 1379 1380 if ($@) { 1381 $ex = $@; 1382 } 1383 1384 $wfh->print("done\n"); 1385 $wfh->flush(); 1386 1387 } else { 1388 eval { server_wait($config_file, $rfh, $timeout_idle + 2) }; 1389 if ($@) { 1390 warn($@); 1391 exit 1; 1392 } 1393 1394 exit 0; 1395 } 1396 1397 # Stop server 1398 server_stop($pid_file); 1399 1400 $self->assert_child_ok($pid); 1401 1402 if ($ex) { 1403 die($ex); 1404 } 1405 1406 if (open($fh, "> $db_script")) { 1407 print $fh <<EOS; 1408DELETE FROM ftpdeny; 1409INSERT INTO ftpdeny (name, denied) VALUES ('', '127.0.0.1'); 1410EOS 1411 unless (close($fh)) { 1412 die("Can't write $db_script: $!"); 1413 } 1414 1415 } else { 1416 die("Can't open $db_script: $!"); 1417 } 1418 1419 $cmd = "sqlite3 $db_file < $db_script"; 1420 1421 if ($ENV{TEST_VERBOSE}) { 1422 print STDERR "Executing sqlite3: $cmd\n"; 1423 } 1424 1425 @output = `$cmd`; 1426 1427 unlink($db_script); 1428 1429 ($port, $config_user, $config_group) = config_write($config_file, $config); 1430 1431 # Fork child 1432 $self->handle_sigchld(); 1433 defined($pid = fork()) or die("Can't fork: $!"); 1434 if ($pid) { 1435 eval { 1436 my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port); 1437 eval { $client->login($user, $passwd) }; 1438 unless ($@) { 1439 die("Login succeeded unexpectedly"); 1440 } 1441 1442 my $resp_code = $client->response_code(); 1443 my $resp_msg = $client->response_msg(); 1444 1445 my $expected; 1446 1447 $expected = 530; 1448 $self->assert($expected == $resp_code, 1449 test_msg("Expected response code $expected, got $resp_code")); 1450 1451 $expected = "Access denied"; 1452 $self->assert($expected eq $resp_msg, 1453 test_msg("Expected response message '$expected', got '$resp_msg'")); 1454 }; 1455 1456 if ($@) { 1457 $ex = $@; 1458 } 1459 1460 $wfh->print("done\n"); 1461 $wfh->flush(); 1462 1463 } else { 1464 eval { server_wait($config_file, $rfh, $timeout_idle + 2) }; 1465 if ($@) { 1466 warn($@); 1467 exit 1; 1468 } 1469 1470 exit 0; 1471 } 1472 1473 # Stop server 1474 server_stop($pid_file); 1475 1476 $self->assert_child_ok($pid); 1477 1478 if ($ex) { 1479 test_append_logfile($log_file, $ex); 1480 unlink($log_file); 1481 1482 die($ex); 1483 } 1484 1485 unlink($log_file); 1486} 1487 1488sub wrap2_sql_deny_table_ipv4_netmask { 1489 my $self = shift; 1490 my $tmpdir = $self->{tmpdir}; 1491 1492 my $config_file = "$tmpdir/wrap2.conf"; 1493 my $pid_file = File::Spec->rel2abs("$tmpdir/wrap2.pid"); 1494 my $scoreboard_file = File::Spec->rel2abs("$tmpdir/wrap2.scoreboard"); 1495 1496 my $log_file = test_get_logfile(); 1497 1498 my $auth_user_file = File::Spec->rel2abs("$tmpdir/wrap2.passwd"); 1499 my $auth_group_file = File::Spec->rel2abs("$tmpdir/wrap2.group"); 1500 1501 my $db_file = File::Spec->rel2abs("$tmpdir/wrap2.db"); 1502 1503 # Build up sqlite3 command to create allow, deny tables and populate them 1504 my $db_script = File::Spec->rel2abs("$tmpdir/wrap2.sql"); 1505 1506 my $fh; 1507 if (open($fh, "> $db_script")) { 1508 print $fh <<EOS; 1509CREATE TABLE ftpallow ( 1510 name TEXT, 1511 allowed TEXT 1512); 1513 1514CREATE TABLE ftpdeny ( 1515 name TEXT, 1516 denied TEXT 1517); 1518 1519INSERT INTO ftpdeny (name, denied) VALUES ('', 'ALL'); 1520EOS 1521 1522 unless (close($fh)) { 1523 die("Can't write $db_script: $!"); 1524 } 1525 1526 } else { 1527 die("Can't open $db_script: $!"); 1528 } 1529 1530 my $cmd = "sqlite3 $db_file < $db_script"; 1531 1532 if ($ENV{TEST_VERBOSE}) { 1533 print STDERR "Executing sqlite3: $cmd\n"; 1534 } 1535 1536 my @output = `$cmd`; 1537 1538 unlink($db_script); 1539 1540 my $user = 'proftpd'; 1541 my $passwd = 'test'; 1542 my $group = 'ftpd'; 1543 my $home_dir = File::Spec->rel2abs($tmpdir); 1544 my $uid = 500; 1545 my $gid = 500; 1546 1547 # Make sure that, if we're running as root, that the home directory has 1548 # permissions/privs set for the account we create 1549 if ($< == 0) { 1550 unless (chmod(0755, $home_dir)) { 1551 die("Can't set perms on $home_dir to 0755: $!"); 1552 } 1553 1554 unless (chown($uid, $gid, $home_dir)) { 1555 die("Can't set owner of $home_dir to $uid/$gid: $!"); 1556 } 1557 } 1558 1559 auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir, 1560 '/bin/bash'); 1561 auth_group_write($auth_group_file, $group, $gid, $user); 1562 1563 my $timeout_idle = 30; 1564 1565 my $config = { 1566 PidFile => $pid_file, 1567 ScoreboardFile => $scoreboard_file, 1568 SystemLog => $log_file, 1569 1570 AuthUserFile => $auth_user_file, 1571 AuthGroupFile => $auth_group_file, 1572 TimeoutIdle => $timeout_idle, 1573 1574 IfModules => { 1575 'mod_delay.c' => { 1576 DelayEngine => 'off', 1577 }, 1578 1579 'mod_sql_sqlite.c' => [ 1580 "SQLAuthenticate off", 1581 "SQLConnectInfo $db_file", 1582 'SQLNamedQuery get-allowed-clients SELECT "allowed FROM ftpallow WHERE name = \'%{0}\'"', 1583 'SQLNamedQuery get-denied-clients SELECT "denied FROM ftpdeny WHERE name = \'%{0}\'"', 1584 "SQLLogFile $log_file", 1585 ], 1586 1587 'mod_wrap2_sql.c' => { 1588 WrapEngine => 'on', 1589 WrapTables => "sql:/get-allowed-clients sql:/get-denied-clients", 1590 WrapLog => $log_file, 1591 }, 1592 }, 1593 }; 1594 1595 my ($port, $config_user, $config_group) = config_write($config_file, $config); 1596 1597 # Open pipes, for use between the parent and child processes. Specifically, 1598 # the child will indicate when it's done with its test by writing a message 1599 # to the parent. 1600 my ($rfh, $wfh); 1601 unless (pipe($rfh, $wfh)) { 1602 die("Can't open pipe: $!"); 1603 } 1604 1605 my $ex; 1606 1607 # Fork child 1608 $self->handle_sigchld(); 1609 defined(my $pid = fork()) or die("Can't fork: $!"); 1610 if ($pid) { 1611 eval { 1612 my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port); 1613 eval { $client->login($user, $passwd) }; 1614 unless ($@) { 1615 die("Login succeeded unexpectedly"); 1616 } 1617 1618 my $resp_code = $client->response_code(); 1619 my $resp_msg = $client->response_msg(); 1620 1621 my $expected; 1622 1623 $expected = 530; 1624 $self->assert($expected == $resp_code, 1625 test_msg("Expected response code $expected, got $resp_code")); 1626 1627 $expected = "Access denied"; 1628 $self->assert($expected eq $resp_msg, 1629 test_msg("Expected response message '$expected', got '$resp_msg'")); 1630 }; 1631 1632 if ($@) { 1633 $ex = $@; 1634 } 1635 1636 $wfh->print("done\n"); 1637 $wfh->flush(); 1638 1639 } else { 1640 eval { server_wait($config_file, $rfh, $timeout_idle + 2) }; 1641 if ($@) { 1642 warn($@); 1643 exit 1; 1644 } 1645 1646 exit 0; 1647 } 1648 1649 # Stop server 1650 server_stop($pid_file); 1651 1652 $self->assert_child_ok($pid); 1653 1654 if ($ex) { 1655 die($ex); 1656 } 1657 1658 if (open($fh, "> $db_script")) { 1659 print $fh <<EOS; 1660DELETE FROM ftpdeny; 1661INSERT INTO ftpdeny (name, denied) VALUES ('', '127.0.0.0/255.255.255.0'); 1662EOS 1663 unless (close($fh)) { 1664 die("Can't write $db_script: $!"); 1665 } 1666 1667 } else { 1668 die("Can't open $db_script: $!"); 1669 } 1670 1671 $cmd = "sqlite3 $db_file < $db_script"; 1672 1673 if ($ENV{TEST_VERBOSE}) { 1674 print STDERR "Executing sqlite3: $cmd\n"; 1675 } 1676 1677 @output = `$cmd`; 1678 1679 unlink($db_script); 1680 1681 ($port, $config_user, $config_group) = config_write($config_file, $config); 1682 1683 # Fork child 1684 $self->handle_sigchld(); 1685 defined($pid = fork()) or die("Can't fork: $!"); 1686 if ($pid) { 1687 eval { 1688 my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port); 1689 eval { $client->login($user, $passwd) }; 1690 unless ($@) { 1691 die("Login succeeded unexpectedly"); 1692 } 1693 1694 my $resp_code = $client->response_code(); 1695 my $resp_msg = $client->response_msg(); 1696 1697 my $expected; 1698 1699 $expected = 530; 1700 $self->assert($expected == $resp_code, 1701 test_msg("Expected response code $expected, got $resp_code")); 1702 1703 $expected = "Access denied"; 1704 $self->assert($expected eq $resp_msg, 1705 test_msg("Expected response message '$expected', got '$resp_msg'")); 1706 }; 1707 1708 if ($@) { 1709 $ex = $@; 1710 } 1711 1712 $wfh->print("done\n"); 1713 $wfh->flush(); 1714 1715 } else { 1716 eval { server_wait($config_file, $rfh, $timeout_idle + 2) }; 1717 if ($@) { 1718 warn($@); 1719 exit 1; 1720 } 1721 1722 exit 0; 1723 } 1724 1725 # Stop server 1726 server_stop($pid_file); 1727 1728 $self->assert_child_ok($pid); 1729 1730 if ($ex) { 1731 test_append_logfile($log_file, $ex); 1732 unlink($log_file); 1733 1734 die($ex); 1735 } 1736 1737 unlink($log_file); 1738} 1739 1740sub wrap2_sql_deny_table_ipv4mappedv6_netmask { 1741 my $self = shift; 1742 my $tmpdir = $self->{tmpdir}; 1743 1744 my $config_file = "$tmpdir/wrap2.conf"; 1745 my $pid_file = File::Spec->rel2abs("$tmpdir/wrap2.pid"); 1746 my $scoreboard_file = File::Spec->rel2abs("$tmpdir/wrap2.scoreboard"); 1747 1748 my $log_file = test_get_logfile(); 1749 1750 my $auth_user_file = File::Spec->rel2abs("$tmpdir/wrap2.passwd"); 1751 my $auth_group_file = File::Spec->rel2abs("$tmpdir/wrap2.group"); 1752 1753 my $db_file = File::Spec->rel2abs("$tmpdir/wrap2.db"); 1754 1755 # Build up sqlite3 command to create allow, deny tables and populate them 1756 my $db_script = File::Spec->rel2abs("$tmpdir/wrap2.sql"); 1757 1758 my $fh; 1759 if (open($fh, "> $db_script")) { 1760 print $fh <<EOS; 1761CREATE TABLE ftpallow ( 1762 name TEXT, 1763 allowed TEXT 1764); 1765 1766CREATE TABLE ftpdeny ( 1767 name TEXT, 1768 denied TEXT 1769); 1770 1771INSERT INTO ftpdeny (name, denied) VALUES ('', 'ALL'); 1772EOS 1773 1774 unless (close($fh)) { 1775 die("Can't write $db_script: $!"); 1776 } 1777 1778 } else { 1779 die("Can't open $db_script: $!"); 1780 } 1781 1782 my $cmd = "sqlite3 $db_file < $db_script"; 1783 1784 if ($ENV{TEST_VERBOSE}) { 1785 print STDERR "Executing sqlite3: $cmd\n"; 1786 } 1787 1788 my @output = `$cmd`; 1789 1790 unlink($db_script); 1791 1792 my $user = 'proftpd'; 1793 my $passwd = 'test'; 1794 my $group = 'ftpd'; 1795 my $home_dir = File::Spec->rel2abs($tmpdir); 1796 my $uid = 500; 1797 my $gid = 500; 1798 1799 # Make sure that, if we're running as root, that the home directory has 1800 # permissions/privs set for the account we create 1801 if ($< == 0) { 1802 unless (chmod(0755, $home_dir)) { 1803 die("Can't set perms on $home_dir to 0755: $!"); 1804 } 1805 1806 unless (chown($uid, $gid, $home_dir)) { 1807 die("Can't set owner of $home_dir to $uid/$gid: $!"); 1808 } 1809 } 1810 1811 auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir, 1812 '/bin/bash'); 1813 auth_group_write($auth_group_file, $group, $gid, $user); 1814 1815 my $timeout_idle = 30; 1816 1817 my $config = { 1818 PidFile => $pid_file, 1819 ScoreboardFile => $scoreboard_file, 1820 SystemLog => $log_file, 1821 1822 AuthUserFile => $auth_user_file, 1823 AuthGroupFile => $auth_group_file, 1824 TimeoutIdle => $timeout_idle, 1825 1826 UseIPv6 => 'on', 1827 1828 IfModules => { 1829 'mod_delay.c' => { 1830 DelayEngine => 'off', 1831 }, 1832 1833 'mod_sql_sqlite.c' => [ 1834 "SQLAuthenticate off", 1835 "SQLConnectInfo $db_file", 1836 'SQLNamedQuery get-allowed-clients SELECT "allowed FROM ftpallow WHERE name = \'%{0}\'"', 1837 'SQLNamedQuery get-denied-clients SELECT "denied FROM ftpdeny WHERE name = \'%{0}\'"', 1838 "SQLLogFile $log_file", 1839 ], 1840 1841 'mod_wrap2_sql.c' => { 1842 WrapEngine => 'on', 1843 WrapTables => "sql:/get-allowed-clients sql:/get-denied-clients", 1844 WrapLog => $log_file, 1845 }, 1846 }, 1847 }; 1848 1849 my ($port, $config_user, $config_group) = config_write($config_file, $config); 1850 1851 # Open pipes, for use between the parent and child processes. Specifically, 1852 # the child will indicate when it's done with its test by writing a message 1853 # to the parent. 1854 my ($rfh, $wfh); 1855 unless (pipe($rfh, $wfh)) { 1856 die("Can't open pipe: $!"); 1857 } 1858 1859 my $ex; 1860 1861 # Fork child 1862 $self->handle_sigchld(); 1863 defined(my $pid = fork()) or die("Can't fork: $!"); 1864 if ($pid) { 1865 eval { 1866 my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port); 1867 eval { $client->login($user, $passwd) }; 1868 unless ($@) { 1869 die("Login succeeded unexpectedly"); 1870 } 1871 1872 my $resp_code = $client->response_code(); 1873 my $resp_msg = $client->response_msg(); 1874 1875 my $expected; 1876 1877 $expected = 530; 1878 $self->assert($expected == $resp_code, 1879 test_msg("Expected response code $expected, got $resp_code")); 1880 1881 $expected = "Access denied"; 1882 $self->assert($expected eq $resp_msg, 1883 test_msg("Expected response message '$expected', got '$resp_msg'")); 1884 }; 1885 1886 if ($@) { 1887 $ex = $@; 1888 } 1889 1890 $wfh->print("done\n"); 1891 $wfh->flush(); 1892 1893 } else { 1894 eval { server_wait($config_file, $rfh, $timeout_idle + 2) }; 1895 if ($@) { 1896 warn($@); 1897 exit 1; 1898 } 1899 1900 exit 0; 1901 } 1902 1903 # Stop server 1904 server_stop($pid_file); 1905 1906 $self->assert_child_ok($pid); 1907 1908 if ($ex) { 1909 die($ex); 1910 } 1911 1912 if (open($fh, "> $db_script")) { 1913 print $fh <<EOS; 1914DELETE FROM ftpdeny; 1915INSERT INTO ftpdeny (name, denied) VALUES ('', '127.0.0.0/255.255.255.0'); 1916EOS 1917 unless (close($fh)) { 1918 die("Can't write $db_script: $!"); 1919 } 1920 1921 } else { 1922 die("Can't open $db_script: $!"); 1923 } 1924 1925 $cmd = "sqlite3 $db_file < $db_script"; 1926 1927 if ($ENV{TEST_VERBOSE}) { 1928 print STDERR "Executing sqlite3: $cmd\n"; 1929 } 1930 1931 @output = `$cmd`; 1932 1933 unlink($db_script); 1934 1935 ($port, $config_user, $config_group) = config_write($config_file, $config); 1936 1937 # Fork child 1938 $self->handle_sigchld(); 1939 defined($pid = fork()) or die("Can't fork: $!"); 1940 if ($pid) { 1941 eval { 1942 my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port); 1943 1944 eval { $client->login($user, $passwd) }; 1945 unless ($@) { 1946 die("Login succeeded unexpectedly"); 1947 } 1948 1949 my $resp_code = $client->response_code(); 1950 my $resp_msg = $client->response_msg(); 1951 1952 my $expected; 1953 1954 $expected = 530; 1955 $self->assert($expected == $resp_code, 1956 test_msg("Expected response code $expected, got $resp_code")); 1957 1958 $expected = "Access denied"; 1959 $self->assert($expected eq $resp_msg, 1960 test_msg("Expected response message '$expected', got '$resp_msg'")); 1961 }; 1962 1963 if ($@) { 1964 $ex = $@; 1965 } 1966 1967 $wfh->print("done\n"); 1968 $wfh->flush(); 1969 1970 } else { 1971 eval { server_wait($config_file, $rfh, $timeout_idle + 2) }; 1972 if ($@) { 1973 warn($@); 1974 exit 1; 1975 } 1976 1977 exit 0; 1978 } 1979 1980 # Stop server 1981 server_stop($pid_file); 1982 1983 $self->assert_child_ok($pid); 1984 1985 if ($ex) { 1986 test_append_logfile($log_file, $ex); 1987 unlink($log_file); 1988 1989 die($ex); 1990 } 1991 1992 unlink($log_file); 1993} 1994 1995sub wrap2_sql_deny_table_ipv6_netmask_bug3606 { 1996 my $self = shift; 1997 my $tmpdir = $self->{tmpdir}; 1998 1999 my $config_file = "$tmpdir/wrap2.conf"; 2000 my $pid_file = File::Spec->rel2abs("$tmpdir/wrap2.pid"); 2001 my $scoreboard_file = File::Spec->rel2abs("$tmpdir/wrap2.scoreboard"); 2002 2003 my $log_file = test_get_logfile(); 2004 2005 my $auth_user_file = File::Spec->rel2abs("$tmpdir/wrap2.passwd"); 2006 my $auth_group_file = File::Spec->rel2abs("$tmpdir/wrap2.group"); 2007 2008 my $db_file = File::Spec->rel2abs("$tmpdir/wrap2.db"); 2009 2010 # Build up sqlite3 command to create allow, deny tables and populate them 2011 my $db_script = File::Spec->rel2abs("$tmpdir/wrap2.sql"); 2012 2013 my $fh; 2014 if (open($fh, "> $db_script")) { 2015 print $fh <<EOS; 2016CREATE TABLE ftpallow ( 2017 name TEXT, 2018 allowed TEXT 2019); 2020 2021CREATE TABLE ftpdeny ( 2022 name TEXT, 2023 denied TEXT 2024); 2025 2026INSERT INTO ftpdeny (name, denied) VALUES ('', 'ALL'); 2027EOS 2028 2029 unless (close($fh)) { 2030 die("Can't write $db_script: $!"); 2031 } 2032 2033 } else { 2034 die("Can't open $db_script: $!"); 2035 } 2036 2037 my $cmd = "sqlite3 $db_file < $db_script"; 2038 2039 if ($ENV{TEST_VERBOSE}) { 2040 print STDERR "Executing sqlite3: $cmd\n"; 2041 } 2042 2043 my @output = `$cmd`; 2044 2045 unlink($db_script); 2046 2047 my $user = 'proftpd'; 2048 my $passwd = 'test'; 2049 my $group = 'ftpd'; 2050 my $home_dir = File::Spec->rel2abs($tmpdir); 2051 my $uid = 500; 2052 my $gid = 500; 2053 2054 # Make sure that, if we're running as root, that the home directory has 2055 # permissions/privs set for the account we create 2056 if ($< == 0) { 2057 unless (chmod(0755, $home_dir)) { 2058 die("Can't set perms on $home_dir to 0755: $!"); 2059 } 2060 2061 unless (chown($uid, $gid, $home_dir)) { 2062 die("Can't set owner of $home_dir to $uid/$gid: $!"); 2063 } 2064 } 2065 2066 auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir, 2067 '/bin/bash'); 2068 auth_group_write($auth_group_file, $group, $gid, $user); 2069 2070 my $timeout_idle = 30; 2071 2072 my $config = { 2073 PidFile => $pid_file, 2074 ScoreboardFile => $scoreboard_file, 2075 SystemLog => $log_file, 2076 2077 AuthUserFile => $auth_user_file, 2078 AuthGroupFile => $auth_group_file, 2079 TimeoutIdle => $timeout_idle, 2080 2081 DefaultAddress => '::1', 2082 UseIPv6 => 'on', 2083 2084 IfModules => { 2085 'mod_delay.c' => { 2086 DelayEngine => 'off', 2087 }, 2088 2089 'mod_sql_sqlite.c' => [ 2090 "SQLAuthenticate off", 2091 "SQLConnectInfo $db_file", 2092 'SQLNamedQuery get-allowed-clients SELECT "allowed FROM ftpallow WHERE name = \'%{0}\'"', 2093 'SQLNamedQuery get-denied-clients SELECT "denied FROM ftpdeny WHERE name = \'%{0}\'"', 2094 "SQLLogFile $log_file", 2095 ], 2096 2097 'mod_wrap2_sql.c' => { 2098 WrapEngine => 'on', 2099 WrapTables => "sql:/get-allowed-clients sql:/get-denied-clients", 2100 WrapLog => $log_file, 2101 }, 2102 }, 2103 }; 2104 2105 my ($port, $config_user, $config_group) = config_write($config_file, $config); 2106 2107 # Open pipes, for use between the parent and child processes. Specifically, 2108 # the child will indicate when it's done with its test by writing a message 2109 # to the parent. 2110 my ($rfh, $wfh); 2111 unless (pipe($rfh, $wfh)) { 2112 die("Can't open pipe: $!"); 2113 } 2114 2115 my $ex; 2116 2117 # Fork child 2118 $self->handle_sigchld(); 2119 defined(my $pid = fork()) or die("Can't fork: $!"); 2120 if ($pid) { 2121 eval { 2122 sleep(2); 2123 2124 my $client = IO::Socket::INET6->new( 2125 PeerAddr => '::1', 2126 PeerPort => $port, 2127 Proto => 'tcp', 2128 Timeout => 5, 2129 ); 2130 unless ($client) { 2131 die("Can't connect to ::1: $!"); 2132 } 2133 2134 # Read the banner 2135 my $banner = <$client>; 2136 2137 # Send the USER command 2138 my $cmd = "USER $user\r\n"; 2139 $client->print($cmd); 2140 $client->flush(); 2141 2142 # Read USER response 2143 my $resp = <$client>; 2144 2145 my $expected = "331 Password required for $user\r\n"; 2146 $self->assert($expected eq $resp, 2147 test_msg("Expected '$expected', got '$resp'")); 2148 2149 # Send the PASS command 2150 $cmd = "PASS $passwd\r\n"; 2151 $client->print($cmd); 2152 $client->flush(); 2153 2154 # Read PASS response 2155 $resp = <$client>; 2156 2157 $expected = "530 Access denied\r\n"; 2158 $self->assert($expected eq $resp, 2159 test_msg("Expected '$expected', got '$resp'")); 2160 2161 $client->close(); 2162 }; 2163 2164 if ($@) { 2165 $ex = $@; 2166 } 2167 2168 $wfh->print("done\n"); 2169 $wfh->flush(); 2170 2171 } else { 2172 eval { server_wait($config_file, $rfh, $timeout_idle + 2) }; 2173 if ($@) { 2174 warn($@); 2175 exit 1; 2176 } 2177 2178 exit 0; 2179 } 2180 2181 # Stop server 2182 server_stop($pid_file); 2183 2184 $self->assert_child_ok($pid); 2185 2186 if ($ex) { 2187 die($ex); 2188 } 2189 2190 if (open($fh, "> $db_script")) { 2191 print $fh <<EOS; 2192DELETE FROM ftpdeny; 2193INSERT INTO ftpdeny (name, denied) VALUES ('', '[::1]/32'); 2194EOS 2195 unless (close($fh)) { 2196 die("Can't write $db_script: $!"); 2197 } 2198 2199 } else { 2200 die("Can't open $db_script: $!"); 2201 } 2202 2203 $cmd = "sqlite3 $db_file < $db_script"; 2204 2205 if ($ENV{TEST_VERBOSE}) { 2206 print STDERR "Executing sqlite3: $cmd\n"; 2207 } 2208 2209 @output = `$cmd`; 2210 2211 unlink($db_script); 2212 2213 ($port, $config_user, $config_group) = config_write($config_file, $config); 2214 2215 # Fork child 2216 $self->handle_sigchld(); 2217 defined($pid = fork()) or die("Can't fork: $!"); 2218 if ($pid) { 2219 eval { 2220 sleep(2); 2221 2222 my $client = IO::Socket::INET6->new( 2223 PeerAddr => '::1', 2224 PeerPort => $port, 2225 Proto => 'tcp', 2226 Timeout => 5, 2227 ); 2228 unless ($client) { 2229 die("Can't connect to ::1: $!"); 2230 } 2231 2232 # Read the banner 2233 my $banner = <$client>; 2234 2235 # Send the USER command 2236 my $cmd = "USER $user\r\n"; 2237 $client->print($cmd); 2238 $client->flush(); 2239 2240 # Read USER response 2241 my $resp = <$client>; 2242 2243 my $expected = "331 Password required for $user\r\n"; 2244 $self->assert($expected eq $resp, 2245 test_msg("Expected '$expected', got '$resp'")); 2246 2247 # Send the PASS command 2248 $cmd = "PASS $passwd\r\n"; 2249 $client->print($cmd); 2250 $client->flush(); 2251 2252 # Read PASS response 2253 $resp = <$client>; 2254 2255 $expected = "530 Access denied\r\n"; 2256 $self->assert($expected eq $resp, 2257 test_msg("Expected '$expected', got '$resp'")); 2258 2259 $client->close(); 2260 }; 2261 2262 if ($@) { 2263 $ex = $@; 2264 } 2265 2266 $wfh->print("done\n"); 2267 $wfh->flush(); 2268 2269 } else { 2270 eval { server_wait($config_file, $rfh, $timeout_idle + 2) }; 2271 if ($@) { 2272 warn($@); 2273 exit 1; 2274 } 2275 2276 exit 0; 2277 } 2278 2279 # Stop server 2280 server_stop($pid_file); 2281 2282 $self->assert_child_ok($pid); 2283 2284 if ($ex) { 2285 test_append_logfile($log_file, $ex); 2286 unlink($log_file); 2287 2288 die($ex); 2289 } 2290 2291 unlink($log_file); 2292} 2293 2294sub wrap2_sql_deny_table_dns_name { 2295 my $self = shift; 2296 my $tmpdir = $self->{tmpdir}; 2297 2298 my $config_file = "$tmpdir/wrap2.conf"; 2299 my $pid_file = File::Spec->rel2abs("$tmpdir/wrap2.pid"); 2300 my $scoreboard_file = File::Spec->rel2abs("$tmpdir/wrap2.scoreboard"); 2301 2302 my $log_file = test_get_logfile(); 2303 2304 my $auth_user_file = File::Spec->rel2abs("$tmpdir/wrap2.passwd"); 2305 my $auth_group_file = File::Spec->rel2abs("$tmpdir/wrap2.group"); 2306 2307 my $db_file = File::Spec->rel2abs("$tmpdir/wrap2.db"); 2308 2309 # Build up sqlite3 command to create allow, deny tables and populate them 2310 my $db_script = File::Spec->rel2abs("$tmpdir/wrap2.sql"); 2311 2312 my $fh; 2313 if (open($fh, "> $db_script")) { 2314 print $fh <<EOS; 2315CREATE TABLE ftpallow ( 2316 name TEXT, 2317 allowed TEXT 2318); 2319 2320CREATE TABLE ftpdeny ( 2321 name TEXT, 2322 denied TEXT 2323); 2324 2325INSERT INTO ftpdeny (name, denied) VALUES ('', 'ALL'); 2326EOS 2327 2328 unless (close($fh)) { 2329 die("Can't write $db_script: $!"); 2330 } 2331 2332 } else { 2333 die("Can't open $db_script: $!"); 2334 } 2335 2336 my $cmd = "sqlite3 $db_file < $db_script"; 2337 2338 if ($ENV{TEST_VERBOSE}) { 2339 print STDERR "Executing sqlite3: $cmd\n"; 2340 } 2341 2342 my @output = `$cmd`; 2343 2344 unlink($db_script); 2345 2346 my $user = 'proftpd'; 2347 my $passwd = 'test'; 2348 my $group = 'ftpd'; 2349 my $home_dir = File::Spec->rel2abs($tmpdir); 2350 my $uid = 500; 2351 my $gid = 500; 2352 2353 # Make sure that, if we're running as root, that the home directory has 2354 # permissions/privs set for the account we create 2355 if ($< == 0) { 2356 unless (chmod(0755, $home_dir)) { 2357 die("Can't set perms on $home_dir to 0755: $!"); 2358 } 2359 2360 unless (chown($uid, $gid, $home_dir)) { 2361 die("Can't set owner of $home_dir to $uid/$gid: $!"); 2362 } 2363 } 2364 2365 auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir, 2366 '/bin/bash'); 2367 auth_group_write($auth_group_file, $group, $gid, $user); 2368 2369 my $timeout_idle = 30; 2370 2371 my $config = { 2372 PidFile => $pid_file, 2373 ScoreboardFile => $scoreboard_file, 2374 SystemLog => $log_file, 2375 2376 AuthUserFile => $auth_user_file, 2377 AuthGroupFile => $auth_group_file, 2378 TimeoutIdle => $timeout_idle, 2379 UseReverseDNS => 'on', 2380 2381 IfModules => { 2382 'mod_delay.c' => { 2383 DelayEngine => 'off', 2384 }, 2385 2386 'mod_sql_sqlite.c' => [ 2387 'SQLAuthenticate off', 2388 "SQLConnectInfo $db_file", 2389 'SQLNamedQuery get-allowed-clients SELECT "allowed FROM ftpallow WHERE name = \'%{0}\'"', 2390 'SQLNamedQuery get-denied-clients SELECT "denied FROM ftpdeny WHERE name = \'%{0}\'"', 2391 "SQLLogFile $log_file", 2392 ], 2393 2394 'mod_wrap2_sql.c' => { 2395 WrapEngine => 'on', 2396 WrapTables => "sql:/get-allowed-clients sql:/get-denied-clients", 2397 WrapLog => $log_file, 2398 }, 2399 }, 2400 }; 2401 2402 my ($port, $config_user, $config_group) = config_write($config_file, $config); 2403 2404 # Open pipes, for use between the parent and child processes. Specifically, 2405 # the child will indicate when it's done with its test by writing a message 2406 # to the parent. 2407 my ($rfh, $wfh); 2408 unless (pipe($rfh, $wfh)) { 2409 die("Can't open pipe: $!"); 2410 } 2411 2412 my $ex; 2413 2414 # Fork child 2415 $self->handle_sigchld(); 2416 defined(my $pid = fork()) or die("Can't fork: $!"); 2417 if ($pid) { 2418 eval { 2419 my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port); 2420 eval { $client->login($user, $passwd) }; 2421 unless ($@) { 2422 die("Login succeeded unexpectedly"); 2423 } 2424 2425 my $resp_code = $client->response_code(); 2426 my $resp_msg = $client->response_msg(); 2427 2428 my $expected; 2429 2430 $expected = 530; 2431 $self->assert($expected == $resp_code, 2432 test_msg("Expected response code $expected, got $resp_code")); 2433 2434 $expected = "Access denied"; 2435 $self->assert($expected eq $resp_msg, 2436 test_msg("Expected response message '$expected', got '$resp_msg'")); 2437 }; 2438 2439 if ($@) { 2440 $ex = $@; 2441 } 2442 2443 $wfh->print("done\n"); 2444 $wfh->flush(); 2445 2446 } else { 2447 eval { server_wait($config_file, $rfh, $timeout_idle + 2) }; 2448 if ($@) { 2449 warn($@); 2450 exit 1; 2451 } 2452 2453 exit 0; 2454 } 2455 2456 # Stop server 2457 server_stop($pid_file); 2458 2459 $self->assert_child_ok($pid); 2460 2461 if ($ex) { 2462 die($ex); 2463 } 2464 2465 if (open($fh, "> $db_script")) { 2466 print $fh <<EOS; 2467DELETE FROM ftpdeny; 2468INSERT INTO ftpdeny (name, denied) VALUES ('', 'localhost'); 2469EOS 2470 unless (close($fh)) { 2471 die("Can't write $db_script: $!"); 2472 } 2473 2474 } else { 2475 die("Can't open $db_script: $!"); 2476 } 2477 2478 $cmd = "sqlite3 $db_file < $db_script"; 2479 2480 if ($ENV{TEST_VERBOSE}) { 2481 print STDERR "Executing sqlite3: $cmd\n"; 2482 } 2483 2484 @output = `$cmd`; 2485 2486 unlink($db_script); 2487 2488 ($port, $config_user, $config_group) = config_write($config_file, $config); 2489 2490 # Fork child 2491 $self->handle_sigchld(); 2492 defined($pid = fork()) or die("Can't fork: $!"); 2493 if ($pid) { 2494 eval { 2495 my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port); 2496 eval { $client->login($user, $passwd) }; 2497 unless ($@) { 2498 die("Login succeeded unexpectedly"); 2499 } 2500 2501 my $resp_code = $client->response_code(); 2502 my $resp_msg = $client->response_msg(); 2503 2504 my $expected; 2505 2506 $expected = 530; 2507 $self->assert($expected == $resp_code, 2508 test_msg("Expected response code $expected, got $resp_code")); 2509 2510 $expected = "Access denied"; 2511 $self->assert($expected eq $resp_msg, 2512 test_msg("Expected response message '$expected', got '$resp_msg'")); 2513 }; 2514 2515 if ($@) { 2516 $ex = $@; 2517 } 2518 2519 $wfh->print("done\n"); 2520 $wfh->flush(); 2521 2522 } else { 2523 eval { server_wait($config_file, $rfh, $timeout_idle + 2) }; 2524 if ($@) { 2525 warn($@); 2526 exit 1; 2527 } 2528 2529 exit 0; 2530 } 2531 2532 # Stop server 2533 server_stop($pid_file); 2534 2535 $self->assert_child_ok($pid); 2536 2537 if ($ex) { 2538 test_append_logfile($log_file, $ex); 2539 unlink($log_file); 2540 2541 die($ex); 2542 } 2543 2544 unlink($log_file); 2545} 2546 2547sub wrap2_sql_deny_table_dns_domain_bug3558 { 2548 my $self = shift; 2549 my $tmpdir = $self->{tmpdir}; 2550 2551 my $config_file = "$tmpdir/wrap2.conf"; 2552 my $pid_file = File::Spec->rel2abs("$tmpdir/wrap2.pid"); 2553 my $scoreboard_file = File::Spec->rel2abs("$tmpdir/wrap2.scoreboard"); 2554 2555 my $log_file = test_get_logfile(); 2556 2557 my $auth_user_file = File::Spec->rel2abs("$tmpdir/wrap2.passwd"); 2558 my $auth_group_file = File::Spec->rel2abs("$tmpdir/wrap2.group"); 2559 2560 my $db_file = File::Spec->rel2abs("$tmpdir/wrap2.db"); 2561 2562 # Build up sqlite3 command to create allow, deny tables and populate them 2563 my $db_script = File::Spec->rel2abs("$tmpdir/wrap2.sql"); 2564 2565 my $fh; 2566 if (open($fh, "> $db_script")) { 2567 print $fh <<EOS; 2568CREATE TABLE ftpallow ( 2569 name TEXT, 2570 allowed TEXT 2571); 2572 2573CREATE TABLE ftpdeny ( 2574 name TEXT, 2575 denied TEXT 2576); 2577 2578INSERT INTO ftpdeny (name, denied) VALUES ('', 'ALL'); 2579EOS 2580 2581 unless (close($fh)) { 2582 die("Can't write $db_script: $!"); 2583 } 2584 2585 } else { 2586 die("Can't open $db_script: $!"); 2587 } 2588 2589 my $cmd = "sqlite3 $db_file < $db_script"; 2590 2591 if ($ENV{TEST_VERBOSE}) { 2592 print STDERR "Executing sqlite3: $cmd\n"; 2593 } 2594 2595 my @output = `$cmd`; 2596 2597 unlink($db_script); 2598 2599 my $user = 'proftpd'; 2600 my $passwd = 'test'; 2601 my $group = 'ftpd'; 2602 my $home_dir = File::Spec->rel2abs($tmpdir); 2603 my $uid = 500; 2604 my $gid = 500; 2605 2606 # Make sure that, if we're running as root, that the home directory has 2607 # permissions/privs set for the account we create 2608 if ($< == 0) { 2609 unless (chmod(0755, $home_dir)) { 2610 die("Can't set perms on $home_dir to 0755: $!"); 2611 } 2612 2613 unless (chown($uid, $gid, $home_dir)) { 2614 die("Can't set owner of $home_dir to $uid/$gid: $!"); 2615 } 2616 } 2617 2618 auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir, 2619 '/bin/bash'); 2620 auth_group_write($auth_group_file, $group, $gid, $user); 2621 2622 my $timeout_idle = 30; 2623 2624 my $config = { 2625 PidFile => $pid_file, 2626 ScoreboardFile => $scoreboard_file, 2627 SystemLog => $log_file, 2628 TraceLog => $log_file, 2629 Trace => 'dns:20', 2630 2631 AuthUserFile => $auth_user_file, 2632 AuthGroupFile => $auth_group_file, 2633 TimeoutIdle => $timeout_idle, 2634 2635 UseReverseDNS => 'on', 2636 2637 IfModules => { 2638 'mod_delay.c' => { 2639 DelayEngine => 'off', 2640 }, 2641 2642 'mod_sql_sqlite.c' => [ 2643 'SQLAuthenticate off', 2644 "SQLConnectInfo $db_file", 2645 'SQLNamedQuery get-allowed-clients SELECT "allowed FROM ftpallow WHERE name = \'%{0}\'"', 2646 'SQLNamedQuery get-denied-clients SELECT "denied FROM ftpdeny WHERE name = \'%{0}\'"', 2647 "SQLLogFile $log_file", 2648 ], 2649 2650 'mod_wrap2_sql.c' => { 2651 WrapEngine => 'on', 2652 WrapTables => "sql:/get-allowed-clients sql:/get-denied-clients", 2653 WrapLog => $log_file, 2654 WrapOptions => 'CheckAllNames', 2655 }, 2656 }, 2657 }; 2658 2659 my ($port, $config_user, $config_group) = config_write($config_file, $config); 2660 2661 # Open pipes, for use between the parent and child processes. Specifically, 2662 # the child will indicate when it's done with its test by writing a message 2663 # to the parent. 2664 my ($rfh, $wfh); 2665 unless (pipe($rfh, $wfh)) { 2666 die("Can't open pipe: $!"); 2667 } 2668 2669 my $ex; 2670 2671 # Fork child 2672 $self->handle_sigchld(); 2673 defined(my $pid = fork()) or die("Can't fork: $!"); 2674 if ($pid) { 2675 eval { 2676 my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port); 2677 eval { $client->login($user, $passwd) }; 2678 unless ($@) { 2679 die("Login succeeded unexpectedly"); 2680 } 2681 2682 my $resp_code = $client->response_code(); 2683 my $resp_msg = $client->response_msg(); 2684 2685 my $expected; 2686 2687 $expected = 530; 2688 $self->assert($expected == $resp_code, 2689 test_msg("Expected response code $expected, got $resp_code")); 2690 2691 $expected = "Access denied"; 2692 $self->assert($expected eq $resp_msg, 2693 test_msg("Expected response message '$expected', got '$resp_msg'")); 2694 }; 2695 2696 if ($@) { 2697 $ex = $@; 2698 } 2699 2700 $wfh->print("done\n"); 2701 $wfh->flush(); 2702 2703 } else { 2704 eval { server_wait($config_file, $rfh, $timeout_idle + 2) }; 2705 if ($@) { 2706 warn($@); 2707 exit 1; 2708 } 2709 2710 exit 0; 2711 } 2712 2713 # Stop server 2714 server_stop($pid_file); 2715 2716 $self->assert_child_ok($pid); 2717 2718 if ($ex) { 2719 die($ex); 2720 } 2721 2722 if (open($fh, "> $db_script")) { 2723 print $fh <<EOS; 2724DELETE FROM ftpdeny; 2725INSERT INTO ftpdeny (name, denied) VALUES ('', '.castaglia.org'); 2726EOS 2727 unless (close($fh)) { 2728 die("Can't write $db_script: $!"); 2729 } 2730 2731 } else { 2732 die("Can't open $db_script: $!"); 2733 } 2734 2735 $cmd = "sqlite3 $db_file < $db_script"; 2736 2737 if ($ENV{TEST_VERBOSE}) { 2738 print STDERR "Executing sqlite3: $cmd\n"; 2739 } 2740 2741 @output = `$cmd`; 2742 2743 unlink($db_script); 2744 2745 ($port, $config_user, $config_group) = config_write($config_file, $config); 2746 2747 # Fork child 2748 $self->handle_sigchld(); 2749 defined($pid = fork()) or die("Can't fork: $!"); 2750 if ($pid) { 2751 eval { 2752 my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port); 2753 eval { $client->login($user, $passwd) }; 2754 unless ($@) { 2755 die("Login succeeded unexpectedly"); 2756 } 2757 2758 my $resp_code = $client->response_code(); 2759 my $resp_msg = $client->response_msg(); 2760 2761 my $expected; 2762 2763 $expected = 530; 2764 $self->assert($expected == $resp_code, 2765 test_msg("Expected response code $expected, got $resp_code")); 2766 2767 $expected = "Access denied"; 2768 $self->assert($expected eq $resp_msg, 2769 test_msg("Expected response message '$expected', got '$resp_msg'")); 2770 }; 2771 2772 if ($@) { 2773 $ex = $@; 2774 } 2775 2776 $wfh->print("done\n"); 2777 $wfh->flush(); 2778 2779 } else { 2780 eval { server_wait($config_file, $rfh, $timeout_idle + 2) }; 2781 if ($@) { 2782 warn($@); 2783 exit 1; 2784 } 2785 2786 exit 0; 2787 } 2788 2789 # Stop server 2790 server_stop($pid_file); 2791 2792 $self->assert_child_ok($pid); 2793 2794 if ($ex) { 2795 test_append_logfile($log_file, $ex); 2796 unlink($log_file); 2797 2798 die($ex); 2799 } 2800 2801 unlink($log_file); 2802} 2803 2804sub wrap2_sql_user_tables { 2805 my $self = shift; 2806 my $tmpdir = $self->{tmpdir}; 2807 2808 my $config_file = "$tmpdir/wrap2.conf"; 2809 my $pid_file = File::Spec->rel2abs("$tmpdir/wrap2.pid"); 2810 my $scoreboard_file = File::Spec->rel2abs("$tmpdir/wrap2.scoreboard"); 2811 2812 my $log_file = test_get_logfile(); 2813 2814 my $auth_user_file = File::Spec->rel2abs("$tmpdir/wrap2.passwd"); 2815 my $auth_group_file = File::Spec->rel2abs("$tmpdir/wrap2.group"); 2816 2817 my $user = 'proftpd'; 2818 my $passwd = 'test'; 2819 my $group = 'ftpd'; 2820 my $home_dir = File::Spec->rel2abs($tmpdir); 2821 my $uid = 500; 2822 my $gid = 500; 2823 2824 my $db_file = File::Spec->rel2abs("$tmpdir/wrap2.db"); 2825 2826 # Build up sqlite3 command to create allow, deny tables and populate them 2827 my $db_script = File::Spec->rel2abs("$tmpdir/wrap2.sql"); 2828 2829 my $fh; 2830 if (open($fh, "> $db_script")) { 2831 print $fh <<EOS; 2832CREATE TABLE ftpallow ( 2833 name TEXT, 2834 allowed TEXT 2835); 2836 2837CREATE TABLE ftpdeny ( 2838 name TEXT, 2839 denied TEXT 2840); 2841 2842INSERT INTO ftpdeny (name, denied) VALUES ('$user', 'ALL'); 2843EOS 2844 2845 unless (close($fh)) { 2846 die("Can't write $db_script: $!"); 2847 } 2848 2849 } else { 2850 die("Can't open $db_script: $!"); 2851 } 2852 2853 my $cmd = "sqlite3 $db_file < $db_script"; 2854 2855 if ($ENV{TEST_VERBOSE}) { 2856 print STDERR "Executing sqlite3: $cmd\n"; 2857 } 2858 2859 my @output = `$cmd`; 2860 2861 unlink($db_script); 2862 2863 # Make sure that, if we're running as root, that the home directory has 2864 # permissions/privs set for the account we create 2865 if ($< == 0) { 2866 unless (chmod(0755, $home_dir)) { 2867 die("Can't set perms on $home_dir to 0755: $!"); 2868 } 2869 2870 unless (chown($uid, $gid, $home_dir)) { 2871 die("Can't set owner of $home_dir to $uid/$gid: $!"); 2872 } 2873 } 2874 2875 auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir, 2876 '/bin/bash'); 2877 auth_group_write($auth_group_file, $group, $gid, $user); 2878 2879 my $timeout_idle = 30; 2880 2881 my $config = { 2882 PidFile => $pid_file, 2883 ScoreboardFile => $scoreboard_file, 2884 SystemLog => $log_file, 2885 2886 AuthUserFile => $auth_user_file, 2887 AuthGroupFile => $auth_group_file, 2888 TimeoutIdle => $timeout_idle, 2889 2890 IfModules => { 2891 'mod_delay.c' => { 2892 DelayEngine => 'off', 2893 }, 2894 2895 'mod_sql_sqlite.c' => [ 2896 'SQLAuthenticate off', 2897 "SQLConnectInfo $db_file", 2898 'SQLNamedQuery get-allowed-clients SELECT "allowed FROM ftpallow WHERE name = \'%{0}\'"', 2899 'SQLNamedQuery get-denied-clients SELECT "denied FROM ftpdeny WHERE name = \'%{0}\'"', 2900 "SQLLogFile $log_file", 2901 ], 2902 2903 'mod_wrap2_sql.c' => { 2904 WrapEngine => 'on', 2905 WrapUserTables => "!$user sql:/get-allowed-clients sql:/get-denied-clients", 2906 WrapLog => $log_file, 2907 }, 2908 }, 2909 }; 2910 2911 my ($port, $config_user, $config_group) = config_write($config_file, $config); 2912 2913 # Open pipes, for use between the parent and child processes. Specifically, 2914 # the child will indicate when it's done with its test by writing a message 2915 # to the parent. 2916 my ($rfh, $wfh); 2917 unless (pipe($rfh, $wfh)) { 2918 die("Can't open pipe: $!"); 2919 } 2920 2921 my $ex; 2922 2923 # Fork child 2924 $self->handle_sigchld(); 2925 defined(my $pid = fork()) or die("Can't fork: $!"); 2926 if ($pid) { 2927 eval { 2928 my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port); 2929 my ($resp_code, $resp_msg) = $client->login($user, $passwd); 2930 2931 my $expected; 2932 2933 $expected = 230; 2934 $self->assert($expected == $resp_code, 2935 test_msg("Expected response code $expected, got $resp_code")); 2936 2937 $expected = "User $user logged in"; 2938 $self->assert($expected eq $resp_msg, 2939 test_msg("Expected response message '$expected', got '$resp_msg'")); 2940 }; 2941 2942 if ($@) { 2943 $ex = $@; 2944 } 2945 2946 $wfh->print("done\n"); 2947 $wfh->flush(); 2948 2949 } else { 2950 eval { server_wait($config_file, $rfh, $timeout_idle + 2) }; 2951 if ($@) { 2952 warn($@); 2953 exit 1; 2954 } 2955 2956 exit 0; 2957 } 2958 2959 # Stop server 2960 server_stop($pid_file); 2961 2962 $self->assert_child_ok($pid); 2963 2964 if ($ex) { 2965 die($ex); 2966 } 2967 2968 # Modify the config a little 2969 $config->{IfModules}->{'mod_wrap2_sql.c'}->{WrapUserTables} = "$user sql:/get-allowed-clients sql:/get-denied-clients"; 2970 2971 ($port, $config_user, $config_group) = config_write($config_file, $config); 2972 2973 # Fork child 2974 $self->handle_sigchld(); 2975 defined($pid = fork()) or die("Can't fork: $!"); 2976 if ($pid) { 2977 eval { 2978 my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port); 2979 eval { $client->login($user, $passwd) }; 2980 unless ($@) { 2981 die("Login succeeded unexpectedly"); 2982 } 2983 2984 my $resp_code = $client->response_code(); 2985 my $resp_msg = $client->response_msg(); 2986 2987 my $expected; 2988 2989 $expected = 530; 2990 $self->assert($expected == $resp_code, 2991 test_msg("Expected response code $expected, got $resp_code")); 2992 2993 $expected = "Access denied"; 2994 $self->assert($expected eq $resp_msg, 2995 test_msg("Expected response message '$expected', got '$resp_msg'")); 2996 }; 2997 2998 if ($@) { 2999 $ex = $@; 3000 } 3001 3002 $wfh->print("done\n"); 3003 $wfh->flush(); 3004 3005 } else { 3006 eval { server_wait($config_file, $rfh, $timeout_idle + 2) }; 3007 if ($@) { 3008 warn($@); 3009 exit 1; 3010 } 3011 3012 exit 0; 3013 } 3014 3015 # Stop server 3016 server_stop($pid_file); 3017 3018 $self->assert_child_ok($pid); 3019 3020 if ($ex) { 3021 test_append_logfile($log_file, $ex); 3022 unlink($log_file); 3023 3024 die($ex); 3025 } 3026 3027 unlink($log_file); 3028} 3029 3030sub wrap2_sql_group_tables { 3031 my $self = shift; 3032 my $tmpdir = $self->{tmpdir}; 3033 3034 my $config_file = "$tmpdir/wrap2.conf"; 3035 my $pid_file = File::Spec->rel2abs("$tmpdir/wrap2.pid"); 3036 my $scoreboard_file = File::Spec->rel2abs("$tmpdir/wrap2.scoreboard"); 3037 3038 my $log_file = test_get_logfile(); 3039 3040 my $auth_user_file = File::Spec->rel2abs("$tmpdir/wrap2.passwd"); 3041 my $auth_group_file = File::Spec->rel2abs("$tmpdir/wrap2.group"); 3042 3043 my $user = 'proftpd'; 3044 my $passwd = 'test'; 3045 my $group = 'ftpd'; 3046 my $home_dir = File::Spec->rel2abs($tmpdir); 3047 my $uid = 500; 3048 my $gid = 500; 3049 3050 my $db_file = File::Spec->rel2abs("$tmpdir/wrap2.db"); 3051 3052 # Build up sqlite3 command to create allow, deny tables and populate them 3053 my $db_script = File::Spec->rel2abs("$tmpdir/wrap2.sql"); 3054 3055 my $fh; 3056 if (open($fh, "> $db_script")) { 3057 print $fh <<EOS; 3058CREATE TABLE ftpallow ( 3059 name TEXT, 3060 allowed TEXT 3061); 3062 3063CREATE TABLE ftpdeny ( 3064 name TEXT, 3065 denied TEXT 3066); 3067 3068INSERT INTO ftpdeny (name, denied) VALUES ('$group', 'ALL'); 3069EOS 3070 3071 unless (close($fh)) { 3072 die("Can't write $db_script: $!"); 3073 } 3074 3075 } else { 3076 die("Can't open $db_script: $!"); 3077 } 3078 3079 my $cmd = "sqlite3 $db_file < $db_script"; 3080 3081 if ($ENV{TEST_VERBOSE}) { 3082 print STDERR "Executing sqlite3: $cmd\n"; 3083 } 3084 3085 my @output = `$cmd`; 3086 3087 unlink($db_script); 3088 3089 # Make sure that, if we're running as root, that the home directory has 3090 # permissions/privs set for the account we create 3091 if ($< == 0) { 3092 unless (chmod(0755, $home_dir)) { 3093 die("Can't set perms on $home_dir to 0755: $!"); 3094 } 3095 3096 unless (chown($uid, $gid, $home_dir)) { 3097 die("Can't set owner of $home_dir to $uid/$gid: $!"); 3098 } 3099 } 3100 3101 auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir, 3102 '/bin/bash'); 3103 auth_group_write($auth_group_file, $group, $gid, $user); 3104 3105 my $timeout_idle = 30; 3106 3107 my $config = { 3108 PidFile => $pid_file, 3109 ScoreboardFile => $scoreboard_file, 3110 SystemLog => $log_file, 3111 3112 AuthUserFile => $auth_user_file, 3113 AuthGroupFile => $auth_group_file, 3114 TimeoutIdle => $timeout_idle, 3115 3116 IfModules => { 3117 'mod_delay.c' => { 3118 DelayEngine => 'off', 3119 }, 3120 3121 'mod_sql_sqlite.c' => [ 3122 'SQLAuthenticate off', 3123 "SQLConnectInfo $db_file", 3124 'SQLNamedQuery get-allowed-clients SELECT "allowed FROM ftpallow WHERE name = \'%{0}\'"', 3125 'SQLNamedQuery get-denied-clients SELECT "denied FROM ftpdeny WHERE name = \'%{0}\'"', 3126 "SQLLogFile $log_file", 3127 ], 3128 3129 'mod_wrap2_sql.c' => { 3130 WrapEngine => 'on', 3131 WrapGroupTables => "foo sql:/get-allowed-clients sql:/get-denied-clients", 3132 WrapLog => $log_file, 3133 }, 3134 }, 3135 }; 3136 3137 my ($port, $config_user, $config_group) = config_write($config_file, $config); 3138 3139 # Open pipes, for use between the parent and child processes. Specifically, 3140 # the child will indicate when it's done with its test by writing a message 3141 # to the parent. 3142 my ($rfh, $wfh); 3143 unless (pipe($rfh, $wfh)) { 3144 die("Can't open pipe: $!"); 3145 } 3146 3147 my $ex; 3148 3149 # Fork child 3150 $self->handle_sigchld(); 3151 defined(my $pid = fork()) or die("Can't fork: $!"); 3152 if ($pid) { 3153 eval { 3154 my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port); 3155 my ($resp_code, $resp_msg) = $client->login($user, $passwd); 3156 3157 my $expected; 3158 3159 $expected = 230; 3160 $self->assert($expected == $resp_code, 3161 test_msg("Expected response code $expected, got $resp_code")); 3162 3163 $expected = "User $user logged in"; 3164 $self->assert($expected eq $resp_msg, 3165 test_msg("Expected response message '$expected', got '$resp_msg'")); 3166 }; 3167 3168 if ($@) { 3169 $ex = $@; 3170 } 3171 3172 $wfh->print("done\n"); 3173 $wfh->flush(); 3174 3175 } else { 3176 eval { server_wait($config_file, $rfh, $timeout_idle + 2) }; 3177 if ($@) { 3178 warn($@); 3179 exit 1; 3180 } 3181 3182 exit 0; 3183 } 3184 3185 # Stop server 3186 server_stop($pid_file); 3187 3188 $self->assert_child_ok($pid); 3189 3190 if ($ex) { 3191 die($ex); 3192 } 3193 3194 # Modify the config a little 3195 $config->{IfModules}->{'mod_wrap2_sql.c'}->{WrapGroupTables} = "ftpd sql:/get-allowed-clients sql:/get-denied-clients"; 3196 3197 ($port, $config_user, $config_group) = config_write($config_file, $config); 3198 3199 # Fork child 3200 $self->handle_sigchld(); 3201 defined($pid = fork()) or die("Can't fork: $!"); 3202 if ($pid) { 3203 eval { 3204 my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port); 3205 eval { $client->login($user, $passwd) }; 3206 unless ($@) { 3207 die("Login succeeded unexpectedly"); 3208 } 3209 3210 my $resp_code = $client->response_code(); 3211 my $resp_msg = $client->response_msg(); 3212 3213 my $expected; 3214 3215 $expected = 530; 3216 $self->assert($expected == $resp_code, 3217 test_msg("Expected response code $expected, got $resp_code")); 3218 3219 $expected = "Access denied"; 3220 $self->assert($expected eq $resp_msg, 3221 test_msg("Expected response message '$expected', got '$resp_msg'")); 3222 }; 3223 3224 if ($@) { 3225 $ex = $@; 3226 } 3227 3228 $wfh->print("done\n"); 3229 $wfh->flush(); 3230 3231 } else { 3232 eval { server_wait($config_file, $rfh, $timeout_idle + 2) }; 3233 if ($@) { 3234 warn($@); 3235 exit 1; 3236 } 3237 3238 exit 0; 3239 } 3240 3241 # Stop server 3242 server_stop($pid_file); 3243 3244 $self->assert_child_ok($pid); 3245 3246 if ($ex) { 3247 test_append_logfile($log_file, $ex); 3248 unlink($log_file); 3249 3250 die($ex); 3251 } 3252 3253 unlink($log_file); 3254} 3255 3256sub wrap2_sql_bug3215 { 3257 my $self = shift; 3258 my $tmpdir = $self->{tmpdir}; 3259 3260 my $config_file = "$tmpdir/wrap2.conf"; 3261 my $pid_file = File::Spec->rel2abs("$tmpdir/wrap2.pid"); 3262 my $scoreboard_file = File::Spec->rel2abs("$tmpdir/wrap2.scoreboard"); 3263 3264 my $log_file = test_get_logfile(); 3265 3266 my $auth_user_file = File::Spec->rel2abs("$tmpdir/wrap2.passwd"); 3267 my $auth_group_file = File::Spec->rel2abs("$tmpdir/wrap2.group"); 3268 3269 my $user = 'proftpd'; 3270 my $passwd = 'test'; 3271 my $group = 'ftpd'; 3272 my $home_dir = File::Spec->rel2abs($tmpdir); 3273 my $uid = 500; 3274 my $gid = 500; 3275 3276 my $db_file = File::Spec->rel2abs("$tmpdir/wrap2.db"); 3277 3278 # Build up sqlite3 command to create allow, deny tables and populate them 3279 my $db_script = File::Spec->rel2abs("$tmpdir/wrap2.sql"); 3280 3281 my $fh; 3282 if (open($fh, "> $db_script")) { 3283 print $fh <<EOS; 3284CREATE TABLE ftpallow ( 3285 allowed TEXT 3286); 3287 3288INSERT INTO ftpallow (allowed) VALUES ('192.168.0.1,192.168.0.2 192.168.0.3, 192.168.0.4 127.0.0.1'); 3289 3290CREATE TABLE ftpdeny ( 3291 denied TEXT 3292); 3293 3294INSERT INTO ftpdeny (denied) VALUES ('ALL'); 3295EOS 3296 3297 unless (close($fh)) { 3298 die("Can't write $db_script: $!"); 3299 } 3300 3301 } else { 3302 die("Can't open $db_script: $!"); 3303 } 3304 3305 my $cmd = "sqlite3 $db_file < $db_script"; 3306 3307 if ($ENV{TEST_VERBOSE}) { 3308 print STDERR "Executing sqlite3: $cmd\n"; 3309 } 3310 3311 my @output = `$cmd`; 3312 3313 unlink($db_script); 3314 3315 # Make sure that, if we're running as root, that the home directory has 3316 # permissions/privs set for the account we create 3317 if ($< == 0) { 3318 unless (chmod(0755, $home_dir)) { 3319 die("Can't set perms on $home_dir to 0755: $!"); 3320 } 3321 3322 unless (chown($uid, $gid, $home_dir)) { 3323 die("Can't set owner of $home_dir to $uid/$gid: $!"); 3324 } 3325 } 3326 3327 auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir, 3328 '/bin/bash'); 3329 auth_group_write($auth_group_file, $group, $gid, $user); 3330 3331 my $timeout_idle = 30; 3332 3333 my $config = { 3334 PidFile => $pid_file, 3335 ScoreboardFile => $scoreboard_file, 3336 SystemLog => $log_file, 3337 3338 AuthUserFile => $auth_user_file, 3339 AuthGroupFile => $auth_group_file, 3340 TimeoutIdle => $timeout_idle, 3341 3342 IfModules => { 3343 'mod_delay.c' => { 3344 DelayEngine => 'off', 3345 }, 3346 3347 'mod_sql_sqlite.c' => [ 3348 'SQLAuthenticate off', 3349 "SQLConnectInfo $db_file", 3350 'SQLNamedQuery get-allowed-clients SELECT "allowed FROM ftpallow"', 3351 'SQLNamedQuery get-denied-clients SELECT "denied FROM ftpdeny"', 3352 "SQLLogFile $log_file", 3353 ], 3354 3355 'mod_wrap2_sql.c' => { 3356 WrapEngine => 'on', 3357 WrapTables => "sql:/get-allowed-clients sql:/get-denied-clients", 3358 WrapLog => $log_file, 3359 }, 3360 }, 3361 }; 3362 3363 my ($port, $config_user, $config_group) = config_write($config_file, $config); 3364 3365 # Open pipes, for use between the parent and child processes. Specifically, 3366 # the child will indicate when it's done with its test by writing a message 3367 # to the parent. 3368 my ($rfh, $wfh); 3369 unless (pipe($rfh, $wfh)) { 3370 die("Can't open pipe: $!"); 3371 } 3372 3373 my $ex; 3374 3375 # Fork child 3376 $self->handle_sigchld(); 3377 defined(my $pid = fork()) or die("Can't fork: $!"); 3378 if ($pid) { 3379 eval { 3380 my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port); 3381 my ($resp_code, $resp_msg) = $client->login($user, $passwd); 3382 3383 my $expected; 3384 3385 $expected = 230; 3386 $self->assert($expected == $resp_code, 3387 test_msg("Expected response code $expected, got $resp_code")); 3388 3389 $expected = "User $user logged in"; 3390 $self->assert($expected eq $resp_msg, 3391 test_msg("Expected response message '$expected', got '$resp_msg'")); 3392 }; 3393 3394 if ($@) { 3395 $ex = $@; 3396 } 3397 3398 $wfh->print("done\n"); 3399 $wfh->flush(); 3400 3401 } else { 3402 eval { server_wait($config_file, $rfh, $timeout_idle + 2) }; 3403 if ($@) { 3404 warn($@); 3405 exit 1; 3406 } 3407 3408 exit 0; 3409 } 3410 3411 # Stop server 3412 server_stop($pid_file); 3413 3414 $self->assert_child_ok($pid); 3415 3416 if ($ex) { 3417 test_append_logfile($log_file, $ex); 3418 unlink($log_file); 3419 3420 die($ex); 3421 } 3422 3423 unlink($log_file); 3424} 3425 3426sub wrap2_bug3341 { 3427 my $self = shift; 3428 my $tmpdir = $self->{tmpdir}; 3429 3430 my $config_file = "$tmpdir/wrap2.conf"; 3431 my $pid_file = File::Spec->rel2abs("$tmpdir/wrap2.pid"); 3432 my $scoreboard_file = File::Spec->rel2abs("$tmpdir/wrap2.scoreboard"); 3433 3434 my $log_file = test_get_logfile(); 3435 3436 my $auth_user_file = File::Spec->rel2abs("$tmpdir/wrap2.passwd"); 3437 my $auth_group_file = File::Spec->rel2abs("$tmpdir/wrap2.group"); 3438 3439 my $user = 'proftpd'; 3440 my $passwd = 'test'; 3441 my $group = 'ftpd'; 3442 my $home_dir = File::Spec->rel2abs($tmpdir); 3443 my $uid = 500; 3444 my $gid = 500; 3445 3446 my $db_file = File::Spec->rel2abs("$tmpdir/wrap2.db"); 3447 3448 # Build up sqlite3 command to create allow, deny tables and populate them 3449 my $db_script = File::Spec->rel2abs("$tmpdir/wrap2.sql"); 3450 3451 my $fh; 3452 if (open($fh, "> $db_script")) { 3453 print $fh <<EOS; 3454CREATE TABLE ftpallow ( 3455 allowed TEXT 3456); 3457 3458INSERT INTO ftpallow (allowed) VALUES ('192.168.0.1,192.168.0.2 192.168.0.3, 192.168.0.4 127.0.0.1'); 3459 3460CREATE TABLE ftpdeny ( 3461 denied TEXT 3462); 3463 3464INSERT INTO ftpdeny (denied) VALUES ('ALL'); 3465EOS 3466 3467 unless (close($fh)) { 3468 die("Can't write $db_script: $!"); 3469 } 3470 3471 } else { 3472 die("Can't open $db_script: $!"); 3473 } 3474 3475 my $cmd = "sqlite3 $db_file < $db_script"; 3476 3477 if ($ENV{TEST_VERBOSE}) { 3478 print STDERR "Executing sqlite3: $cmd\n"; 3479 } 3480 3481 my @output = `$cmd`; 3482 3483 unlink($db_script); 3484 3485 # Make sure that, if we're running as root, that the home directory has 3486 # permissions/privs set for the account we create 3487 if ($< == 0) { 3488 unless (chmod(0755, $home_dir)) { 3489 die("Can't set perms on $home_dir to 0755: $!"); 3490 } 3491 3492 unless (chown($uid, $gid, $home_dir)) { 3493 die("Can't set owner of $home_dir to $uid/$gid: $!"); 3494 } 3495 } 3496 3497 auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir, 3498 '/bin/bash'); 3499 auth_group_write($auth_group_file, $group, $gid, $user); 3500 3501 my $timeout_idle = 30; 3502 3503 my $config = { 3504 PidFile => $pid_file, 3505 ScoreboardFile => $scoreboard_file, 3506 SystemLog => $log_file, 3507 3508 AuthUserFile => $auth_user_file, 3509 AuthGroupFile => $auth_group_file, 3510 TimeoutIdle => $timeout_idle, 3511 3512 IfModules => { 3513 'mod_delay.c' => { 3514 DelayEngine => 'off', 3515 }, 3516 3517 'mod_sql_sqlite.c' => [ 3518 'SQLAuthenticate off', 3519 "SQLConnectInfo $db_file", 3520 'SQLNamedQuery get-allowed-clients SELECT "allowed FROM ftpallow"', 3521 'SQLNamedQuery get-denied-clients SELECT "denied FROM ftpdeny"', 3522 "SQLLogFile $log_file", 3523 ], 3524 3525 'mod_wrap2_sql.c' => { 3526 WrapEngine => 'on', 3527 WrapTables => "sql:/get-allowed-clients sql:/get-denied-clients", 3528 WrapLog => $log_file, 3529 }, 3530 }, 3531 }; 3532 3533 my ($port, $config_user, $config_group) = config_write($config_file, $config); 3534 3535 # Open pipes, for use between the parent and child processes. Specifically, 3536 # the child will indicate when it's done with its test by writing a message 3537 # to the parent. 3538 my ($rfh, $wfh); 3539 unless (pipe($rfh, $wfh)) { 3540 die("Can't open pipe: $!"); 3541 } 3542 3543 my $ex; 3544 3545 # Fork child 3546 $self->handle_sigchld(); 3547 defined(my $pid = fork()) or die("Can't fork: $!"); 3548 if ($pid) { 3549 eval { 3550 my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port); 3551 3552 # As per Bug#3341, we need to send a bad password twice. The second 3553 # attempt triggered a segfault in mod_wrap2. 3554 eval { $client->login($user, 'foo') }; 3555 unless ($@) { 3556 die("Login succeeded unexpectedly"); 3557 } 3558 3559 my $resp_code = $client->response_code(); 3560 my $resp_msg = $client->response_msg(); 3561 3562 my $expected; 3563 3564 $expected = 530; 3565 $self->assert($expected == $resp_code, 3566 test_msg("Expected response code $expected, got $resp_code")); 3567 3568 $expected = "Login incorrect."; 3569 $self->assert($expected eq $resp_msg, 3570 test_msg("Expected response message '$expected', got '$resp_msg'")); 3571 3572 # Now try to login again 3573 eval { $client->login($user, 'foo') }; 3574 unless ($@) { 3575 die("Login succeeded unexpectedly"); 3576 } 3577 3578 $resp_code = $client->response_code(); 3579 $resp_msg = $client->response_msg(); 3580 3581 $expected = 530; 3582 $self->assert($expected == $resp_code, 3583 test_msg("Expected response code $expected, got $resp_code")); 3584 3585 $expected = "Login incorrect."; 3586 $self->assert($expected eq $resp_msg, 3587 test_msg("Expected response message '$expected', got '$resp_msg'")); 3588 3589 ($resp_code, $resp_msg) = $client->login($user, $passwd); 3590 3591 $expected = 230; 3592 $self->assert($expected == $resp_code, 3593 test_msg("Expected response code $expected, got $resp_code")); 3594 3595 $expected = "User $user logged in"; 3596 $self->assert($expected eq $resp_msg, 3597 test_msg("Expected response message '$expected', got '$resp_msg'")); 3598 }; 3599 3600 if ($@) { 3601 $ex = $@; 3602 } 3603 3604 $wfh->print("done\n"); 3605 $wfh->flush(); 3606 3607 } else { 3608 eval { server_wait($config_file, $rfh, $timeout_idle + 2) }; 3609 if ($@) { 3610 warn($@); 3611 exit 1; 3612 } 3613 3614 exit 0; 3615 } 3616 3617 # Stop server 3618 server_stop($pid_file); 3619 3620 $self->assert_child_ok($pid); 3621 3622 if ($ex) { 3623 test_append_logfile($log_file, $ex); 3624 unlink($log_file); 3625 3626 die($ex); 3627 } 3628 3629 unlink($log_file); 3630} 3631 3632sub wrap2_sql_opt_check_on_connect_bug3508 { 3633 my $self = shift; 3634 my $tmpdir = $self->{tmpdir}; 3635 3636 # XXX NOTE: In order for the CheckOnConnect WrapOption to work properly 3637 # with mod_wrap2_sql, the module load order must be very specific, e.g.: 3638 # 3639 # --with-modules=mod_wrap2:mod_wrap2_sql:mod_sql:mod_sqlite 3640 # 3641 # Specifically, mod_sql and its backend(s) MUST appear AFTER mod_wrap2 and 3642 # its submodules in the module load order list. This is necessary because 3643 # mod_sql's session init callback is where the database connection is 3644 # defined. If mod_wrap2 appears after mod_sql in the module load order 3645 # list, then mod_wrap2's session init callback is called first, and it 3646 # will try to use mod_wrap2_sql to get the table data, which will try to 3647 # use mod_sql -- and the database connection won't be defined. And only 3648 # mod_sql has the knowledge of how to handle the SQLConnectInfo directive, 3649 # which is needed in order to define/create that database connection. 3650 3651 my $mod_list = feature_get_compiled_modules(); 3652 my ($mod_wrap2_idx, $mod_sql_idx); 3653 3654 my $nmodules = scalar(@$mod_list); 3655 for (my $i = 0; $i < $nmodules; $i++) { 3656 if ($mod_list->[$i] =~ /mod_wrap2\.c/) { 3657 $mod_wrap2_idx = $i; 3658 } 3659 3660 if ($mod_list->[$i] =~ /mod_sql\.c/) { 3661 $mod_sql_idx = $i; 3662 } 3663 } 3664 3665 if ($mod_sql_idx < $mod_wrap2_idx) { 3666 print STDERR " + unable to run 'wrap2_sql_opt_check_on_connect_bug3508' test with current module order (mod_sql appears BEFORE mod_wrap2), skipping\n"; 3667 return; 3668 } 3669 3670 my $config_file = "$tmpdir/wrap2.conf"; 3671 my $pid_file = File::Spec->rel2abs("$tmpdir/wrap2.pid"); 3672 my $scoreboard_file = File::Spec->rel2abs("$tmpdir/wrap2.scoreboard"); 3673 3674 my $log_file = test_get_logfile(); 3675 3676 my $auth_user_file = File::Spec->rel2abs("$tmpdir/wrap2.passwd"); 3677 my $auth_group_file = File::Spec->rel2abs("$tmpdir/wrap2.group"); 3678 3679 my $db_file = File::Spec->rel2abs("$tmpdir/wrap2.db"); 3680 3681 # Build up sqlite3 command to create allow, deny tables and populate them 3682 my $db_script = File::Spec->rel2abs("$tmpdir/wrap2.sql"); 3683 3684 my $fh; 3685 if (open($fh, "> $db_script")) { 3686 print $fh <<EOS; 3687CREATE TABLE ftpallow ( 3688 name TEXT, 3689 allowed TEXT 3690); 3691 3692CREATE TABLE ftpdeny ( 3693 name TEXT, 3694 denied TEXT 3695); 3696 3697EOS 3698 3699 unless (close($fh)) { 3700 die("Can't write $db_script: $!"); 3701 } 3702 3703 } else { 3704 die("Can't open $db_script: $!"); 3705 } 3706 3707 my $cmd = "sqlite3 $db_file < $db_script"; 3708 3709 if ($ENV{TEST_VERBOSE}) { 3710 print STDERR "Executing sqlite3: $cmd\n"; 3711 } 3712 3713 my @output = `$cmd`; 3714 if (scalar(@output) && 3715 $ENV{TEST_VERBOSE}) { 3716 print STDERR "Output: ", join("", @output), "\n"; 3717 } 3718 3719 unlink($db_script); 3720 3721 my $user = 'proftpd'; 3722 my $passwd = 'test'; 3723 my $group = 'ftpd'; 3724 my $home_dir = File::Spec->rel2abs($tmpdir); 3725 my $uid = 500; 3726 my $gid = 500; 3727 3728 # Make sure that, if we're running as root, that the home directory has 3729 # permissions/privs set for the account we create 3730 if ($< == 0) { 3731 unless (chmod(0755, $home_dir)) { 3732 die("Can't set perms on $home_dir to 0755: $!"); 3733 } 3734 3735 unless (chown($uid, $gid, $home_dir)) { 3736 die("Can't set owner of $home_dir to $uid/$gid: $!"); 3737 } 3738 } 3739 3740 auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir, 3741 '/bin/bash'); 3742 auth_group_write($auth_group_file, $group, $gid, $user); 3743 3744 my $timeout_idle = 30; 3745 3746 my $config = { 3747 PidFile => $pid_file, 3748 ScoreboardFile => $scoreboard_file, 3749 SystemLog => $log_file, 3750 3751 AuthUserFile => $auth_user_file, 3752 AuthGroupFile => $auth_group_file, 3753 TimeoutIdle => $timeout_idle, 3754 3755 IfModules => { 3756 'mod_delay.c' => { 3757 DelayEngine => 'off', 3758 }, 3759 3760 'mod_sql_sqlite.c' => [ 3761 'SQLAuthenticate off', 3762 "SQLConnectInfo $db_file", 3763 'SQLNamedQuery get-allowed-clients SELECT "allowed FROM ftpallow WHERE name = \'%{0}\'"', 3764 'SQLNamedQuery get-denied-clients SELECT "denied FROM ftpdeny WHERE name = \'%{0}\'"', 3765 "SQLLogFile $log_file", 3766 ], 3767 3768 'mod_wrap2_sql.c' => { 3769 WrapEngine => 'on', 3770 WrapTables => "sql:/get-allowed-clients sql:/get-denied-clients", 3771 WrapLog => $log_file, 3772 WrapOptions => 'CheckOnConnect', 3773 }, 3774 }, 3775 }; 3776 3777 my ($port, $config_user, $config_group) = config_write($config_file, $config); 3778 3779 # Open pipes, for use between the parent and child processes. Specifically, 3780 # the child will indicate when it's done with its test by writing a message 3781 # to the parent. 3782 my ($rfh, $wfh); 3783 unless (pipe($rfh, $wfh)) { 3784 die("Can't open pipe: $!"); 3785 } 3786 3787 my $ex; 3788 3789 # Fork child 3790 $self->handle_sigchld(); 3791 defined(my $pid = fork()) or die("Can't fork: $!"); 3792 if ($pid) { 3793 eval { 3794 my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port); 3795 my ($resp_code, $resp_msg) = $client->login($user, $passwd); 3796 3797 my $expected; 3798 3799 $expected = 230; 3800 $self->assert($expected == $resp_code, 3801 test_msg("Expected response code $expected, got $resp_code")); 3802 3803 $expected = "User $user logged in"; 3804 $self->assert($expected eq $resp_msg, 3805 test_msg("Expected response message '$expected', got '$resp_msg'")); 3806 }; 3807 3808 if ($@) { 3809 $ex = $@; 3810 } 3811 3812 $wfh->print("done\n"); 3813 $wfh->flush(); 3814 3815 } else { 3816 eval { server_wait($config_file, $rfh, $timeout_idle + 2) }; 3817 if ($@) { 3818 warn($@); 3819 exit 1; 3820 } 3821 3822 exit 0; 3823 } 3824 3825 # Stop server 3826 server_stop($pid_file); 3827 3828 $self->assert_child_ok($pid); 3829 3830 if ($ex) { 3831 die($ex); 3832 } 3833 3834 if (open($fh, "> $db_script")) { 3835 print $fh <<EOS; 3836INSERT INTO ftpdeny (name, denied) VALUES ('', '127.0.0.1'); 3837EOS 3838 unless (close($fh)) { 3839 die("Can't write $db_script: $!"); 3840 } 3841 3842 } else { 3843 die("Can't open $db_script: $!"); 3844 } 3845 3846 $cmd = "sqlite3 $db_file < $db_script"; 3847 3848 if ($ENV{TEST_VERBOSE}) { 3849 print STDERR "Executing sqlite3: $cmd\n"; 3850 } 3851 3852 @output = `$cmd`; 3853 if (scalar(@output) && 3854 $ENV{TEST_VERBOSE}) { 3855 print STDERR "Output: ", join('', @output), "\n"; 3856 } 3857 3858 unlink($db_script); 3859 3860 ($port, $config_user, $config_group) = config_write($config_file, $config); 3861 3862 # Fork child 3863 $self->handle_sigchld(); 3864 defined($pid = fork()) or die("Can't fork: $!"); 3865 if ($pid) { 3866 eval { 3867 my $client; 3868 3869 eval { 3870 $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port, undef, 2); 3871 }; 3872 unless ($@) { 3873 die("Connect succeeded unexpectedly"); 3874 } 3875 3876 my $ex = ProFTPD::TestSuite::FTP::get_connect_exception(); 3877 3878 my $expected = "Access denied"; 3879 $self->assert($expected eq $ex, 3880 test_msg("Expected '$expected', got '$ex'")); 3881 }; 3882 3883 if ($@) { 3884 $ex = $@; 3885 } 3886 3887 $wfh->print("done\n"); 3888 $wfh->flush(); 3889 3890 } else { 3891 eval { server_wait($config_file, $rfh, $timeout_idle + 2) }; 3892 if ($@) { 3893 warn($@); 3894 exit 1; 3895 } 3896 3897 exit 0; 3898 } 3899 3900 # Stop server 3901 server_stop($pid_file); 3902 3903 $self->assert_child_ok($pid); 3904 3905 if ($ex) { 3906 test_append_logfile($log_file, $ex); 3907 unlink($log_file); 3908 3909 die($ex); 3910 } 3911 3912 unlink($log_file); 3913} 3914 3915sub wrap2_allow_msg_bug3538 { 3916 my $self = shift; 3917 my $tmpdir = $self->{tmpdir}; 3918 3919 my $config_file = "$tmpdir/wrap2.conf"; 3920 my $pid_file = File::Spec->rel2abs("$tmpdir/wrap2.pid"); 3921 my $scoreboard_file = File::Spec->rel2abs("$tmpdir/wrap2.scoreboard"); 3922 3923 my $log_file = test_get_logfile(); 3924 3925 my $auth_user_file = File::Spec->rel2abs("$tmpdir/wrap2.passwd"); 3926 my $auth_group_file = File::Spec->rel2abs("$tmpdir/wrap2.group"); 3927 3928 my $db_file = File::Spec->rel2abs("$tmpdir/wrap2.db"); 3929 3930 # Build up sqlite3 command to create allow, deny tables and populate them 3931 my $db_script = File::Spec->rel2abs("$tmpdir/wrap2.sql"); 3932 3933 my $fh; 3934 if (open($fh, "> $db_script")) { 3935 print $fh <<EOS; 3936CREATE TABLE ftpallow ( 3937 name TEXT, 3938 allowed TEXT 3939); 3940 3941CREATE TABLE ftpdeny ( 3942 name TEXT, 3943 denied TEXT 3944); 3945 3946EOS 3947 3948 unless (close($fh)) { 3949 die("Can't write $db_script: $!"); 3950 } 3951 3952 } else { 3953 die("Can't open $db_script: $!"); 3954 } 3955 3956 my $cmd = "sqlite3 $db_file < $db_script"; 3957 3958 if ($ENV{TEST_VERBOSE}) { 3959 print STDERR "Executing sqlite3: $cmd\n"; 3960 } 3961 3962 my @output = `$cmd`; 3963 3964 unlink($db_script); 3965 3966 my $user = 'proftpd'; 3967 my $passwd = 'test'; 3968 my $group = 'ftpd'; 3969 my $home_dir = File::Spec->rel2abs($tmpdir); 3970 my $uid = 500; 3971 my $gid = 500; 3972 3973 # Make sure that, if we're running as root, that the home directory has 3974 # permissions/privs set for the account we create 3975 if ($< == 0) { 3976 unless (chmod(0755, $home_dir)) { 3977 die("Can't set perms on $home_dir to 0755: $!"); 3978 } 3979 3980 unless (chown($uid, $gid, $home_dir)) { 3981 die("Can't set owner of $home_dir to $uid/$gid: $!"); 3982 } 3983 } 3984 3985 auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir, 3986 '/bin/bash'); 3987 auth_group_write($auth_group_file, $group, $gid, $user); 3988 3989 my $timeout_idle = 30; 3990 3991 my $config = { 3992 PidFile => $pid_file, 3993 ScoreboardFile => $scoreboard_file, 3994 SystemLog => $log_file, 3995 3996 AccessGrantMsg => '"User %u logged in."', 3997 AuthUserFile => $auth_user_file, 3998 AuthGroupFile => $auth_group_file, 3999 TimeoutIdle => $timeout_idle, 4000 4001 IfModules => { 4002 'mod_delay.c' => { 4003 DelayEngine => 'off', 4004 }, 4005 4006 'mod_sql_sqlite.c' => [ 4007 'SQLAuthenticate off', 4008 "SQLConnectInfo $db_file", 4009 'SQLNamedQuery get-allowed-clients SELECT "allowed FROM ftpallow WHERE name = \'%{0}\'"', 4010 'SQLNamedQuery get-denied-clients SELECT "denied FROM ftpdeny WHERE name = \'%{0}\'"', 4011 "SQLLogFile $log_file", 4012 ], 4013 4014 'mod_wrap2_sql.c' => { 4015 WrapEngine => 'on', 4016 WrapAllowMsg => '"User %u allowed by access rules"', 4017 WrapTables => "sql:/get-allowed-clients sql:/get-denied-clients", 4018 WrapLog => $log_file, 4019 }, 4020 }, 4021 }; 4022 4023 my ($port, $config_user, $config_group) = config_write($config_file, $config); 4024 4025 # Open pipes, for use between the parent and child processes. Specifically, 4026 # the child will indicate when it's done with its test by writing a message 4027 # to the parent. 4028 my ($rfh, $wfh); 4029 unless (pipe($rfh, $wfh)) { 4030 die("Can't open pipe: $!"); 4031 } 4032 4033 my $ex; 4034 4035 # Fork child 4036 $self->handle_sigchld(); 4037 defined(my $pid = fork()) or die("Can't fork: $!"); 4038 if ($pid) { 4039 eval { 4040 my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port); 4041 $client->login($user, $passwd); 4042 4043 my $resp_code = $client->response_code(); 4044 my $resp_msg = $client->response_msg(0); 4045 4046 my $expected; 4047 4048 $expected = 230; 4049 $self->assert($expected == $resp_code, 4050 test_msg("Expected response code $expected, got $resp_code")); 4051 4052 $expected = "User $user allowed by access rules"; 4053 $self->assert($expected eq $resp_msg, 4054 test_msg("Expected response message '$expected', got '$resp_msg'")); 4055 4056 $resp_msg = $client->response_msg(1); 4057 4058 $expected = "User $user logged in."; 4059 $self->assert($expected eq $resp_msg, 4060 test_msg("Expected response meessage '$expected', got '$resp_msg'")); 4061 }; 4062 4063 if ($@) { 4064 $ex = $@; 4065 } 4066 4067 $wfh->print("done\n"); 4068 $wfh->flush(); 4069 4070 } else { 4071 eval { server_wait($config_file, $rfh, $timeout_idle + 2) }; 4072 if ($@) { 4073 warn($@); 4074 exit 1; 4075 } 4076 4077 exit 0; 4078 } 4079 4080 # Stop server 4081 server_stop($pid_file); 4082 4083 $self->assert_child_ok($pid); 4084 4085 if ($ex) { 4086 test_append_logfile($log_file, $ex); 4087 unlink($log_file); 4088 4089 die($ex); 4090 } 4091 4092 unlink($log_file); 4093} 4094 4095sub wrap2_allow_msg_anon_bug3538 { 4096 my $self = shift; 4097 my $tmpdir = $self->{tmpdir}; 4098 4099 my $config_file = "$tmpdir/wrap2.conf"; 4100 my $pid_file = File::Spec->rel2abs("$tmpdir/wrap2.pid"); 4101 my $scoreboard_file = File::Spec->rel2abs("$tmpdir/wrap2.scoreboard"); 4102 4103 my $log_file = test_get_logfile(); 4104 4105 my $auth_user_file = File::Spec->rel2abs("$tmpdir/wrap2.passwd"); 4106 my $auth_group_file = File::Spec->rel2abs("$tmpdir/wrap2.group"); 4107 4108 my $db_file = File::Spec->rel2abs("$tmpdir/wrap2.db"); 4109 4110 # Build up sqlite3 command to create allow, deny tables and populate them 4111 my $db_script = File::Spec->rel2abs("$tmpdir/wrap2.sql"); 4112 4113 my $fh; 4114 if (open($fh, "> $db_script")) { 4115 print $fh <<EOS; 4116CREATE TABLE ftpallow ( 4117 name TEXT, 4118 allowed TEXT 4119); 4120 4121CREATE TABLE ftpdeny ( 4122 name TEXT, 4123 denied TEXT 4124); 4125 4126EOS 4127 4128 unless (close($fh)) { 4129 die("Can't write $db_script: $!"); 4130 } 4131 4132 } else { 4133 die("Can't open $db_script: $!"); 4134 } 4135 4136 my $cmd = "sqlite3 $db_file < $db_script"; 4137 4138 if ($ENV{TEST_VERBOSE}) { 4139 print STDERR "Executing sqlite3: $cmd\n"; 4140 } 4141 4142 my @output = `$cmd`; 4143 4144 unlink($db_script); 4145 4146 my ($test_user, $test_group) = config_get_identity(); 4147 my $passwd = 'test'; 4148 my $home_dir = File::Spec->rel2abs($tmpdir); 4149 my $uid = 500; 4150 my $gid = 500; 4151 4152 # Make sure that, if we're running as root, that the home directory has 4153 # permissions/privs set for the account we create 4154 if ($< == 0) { 4155 unless (chmod(0755, $home_dir)) { 4156 die("Can't set perms on $home_dir to 0755: $!"); 4157 } 4158 4159 unless (chown($uid, $gid, $home_dir)) { 4160 die("Can't set owner of $home_dir to $uid/$gid: $!"); 4161 } 4162 } 4163 4164 auth_user_write($auth_user_file, $test_user, $passwd, $uid, $gid, '/tmp', 4165 '/bin/bash'); 4166 auth_group_write($auth_group_file, $test_group, $gid, $test_user); 4167 4168 my $timeout_idle = 30; 4169 4170 my $config = { 4171 PidFile => $pid_file, 4172 ScoreboardFile => $scoreboard_file, 4173 SystemLog => $log_file, 4174 4175 AccessGrantMsg => '"User %u logged in."', 4176 AuthUserFile => $auth_user_file, 4177 AuthGroupFile => $auth_group_file, 4178 TimeoutIdle => $timeout_idle, 4179 4180 Anonymous => { 4181 $home_dir => { 4182 User => $test_user, 4183 Group => $test_group, 4184 UserAlias => "anonymous $test_user", 4185 RequireValidShell => 'off', 4186 }, 4187 }, 4188 4189 IfModules => { 4190 'mod_delay.c' => { 4191 DelayEngine => 'off', 4192 }, 4193 4194 'mod_sql_sqlite.c' => [ 4195 'SQLAuthenticate off', 4196 "SQLConnectInfo $db_file", 4197 'SQLNamedQuery get-allowed-clients SELECT "allowed FROM ftpallow WHERE name = \'%{0}\'"', 4198 'SQLNamedQuery get-denied-clients SELECT "denied FROM ftpdeny WHERE name = \'%{0}\'"', 4199 "SQLLogFile $log_file", 4200 ], 4201 4202 'mod_wrap2_sql.c' => { 4203 WrapEngine => 'on', 4204 WrapAllowMsg => '"User %u allowed by access rules"', 4205 WrapTables => "sql:/get-allowed-clients sql:/get-denied-clients", 4206 WrapLog => $log_file, 4207 }, 4208 }, 4209 }; 4210 4211 my ($port, $config_user, $config_group) = config_write($config_file, $config); 4212 4213 # Open pipes, for use between the parent and child processes. Specifically, 4214 # the child will indicate when it's done with its test by writing a message 4215 # to the parent. 4216 my ($rfh, $wfh); 4217 unless (pipe($rfh, $wfh)) { 4218 die("Can't open pipe: $!"); 4219 } 4220 4221 my $ex; 4222 4223 # Fork child 4224 $self->handle_sigchld(); 4225 defined(my $pid = fork()) or die("Can't fork: $!"); 4226 if ($pid) { 4227 eval { 4228 my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port); 4229 4230 $client->login('anonymous', 'ftp@nospam.org'); 4231 4232 my $resp_code = $client->response_code(); 4233 my $resp_msg = $client->response_msg(0); 4234 4235 my $expected; 4236 4237 $expected = 230; 4238 $self->assert($expected == $resp_code, 4239 test_msg("Expected $expected, got $resp_code")); 4240 4241 $expected = "User anonymous logged in."; 4242 $self->assert($expected eq $resp_msg, 4243 test_msg("Expected '$expected', got '$resp_msg'")); 4244 4245 $resp_msg = $client->response_msg(1); 4246 4247 $expected = "User anonymous allowed by access rules"; 4248 $self->assert($expected eq $resp_msg, 4249 test_msg("Expected '$expected', got '$resp_msg'")); 4250 }; 4251 4252 if ($@) { 4253 $ex = $@; 4254 } 4255 4256 $wfh->print("done\n"); 4257 $wfh->flush(); 4258 4259 } else { 4260 eval { server_wait($config_file, $rfh, $timeout_idle + 2) }; 4261 if ($@) { 4262 warn($@); 4263 exit 1; 4264 } 4265 4266 exit 0; 4267 } 4268 4269 # Stop server 4270 server_stop($pid_file); 4271 4272 $self->assert_child_ok($pid); 4273 4274 if ($ex) { 4275 test_append_logfile($log_file, $ex); 4276 unlink($log_file); 4277 4278 die($ex); 4279 } 4280 4281 unlink($log_file); 4282} 4283 4284sub wrap2_sql_deny_event_exec_bug3209 { 4285 my $self = shift; 4286 my $tmpdir = $self->{tmpdir}; 4287 4288 my $config_file = "$tmpdir/wrap2.conf"; 4289 my $pid_file = File::Spec->rel2abs("$tmpdir/wrap2.pid"); 4290 my $scoreboard_file = File::Spec->rel2abs("$tmpdir/wrap2.scoreboard"); 4291 4292 my $log_file = test_get_logfile(); 4293 4294 my $auth_user_file = File::Spec->rel2abs("$tmpdir/wrap2.passwd"); 4295 my $auth_group_file = File::Spec->rel2abs("$tmpdir/wrap2.group"); 4296 4297 my $db_file = File::Spec->rel2abs("$tmpdir/wrap2.db"); 4298 4299 # Build up sqlite3 command to create allow, deny tables and populate them 4300 my $db_script = File::Spec->rel2abs("$tmpdir/wrap2.sql"); 4301 4302 my $fh; 4303 if (open($fh, "> $db_script")) { 4304 print $fh <<EOS; 4305CREATE TABLE ftpallow ( 4306 name TEXT, 4307 allowed TEXT 4308); 4309 4310CREATE TABLE ftpdeny ( 4311 name TEXT, 4312 denied TEXT 4313); 4314 4315INSERT INTO ftpdeny (name, denied) VALUES ('', 'ALL'); 4316EOS 4317 4318 unless (close($fh)) { 4319 die("Can't write $db_script: $!"); 4320 } 4321 4322 } else { 4323 die("Can't open $db_script: $!"); 4324 } 4325 4326 my $cmd = "sqlite3 $db_file < $db_script"; 4327 4328 if ($ENV{TEST_VERBOSE}) { 4329 print STDERR "Executing sqlite3: $cmd\n"; 4330 } 4331 4332 my @output = `$cmd`; 4333 4334 unlink($db_script); 4335 4336 my $user = 'proftpd'; 4337 my $passwd = 'test'; 4338 my $group = 'ftpd'; 4339 my $home_dir = File::Spec->rel2abs($tmpdir); 4340 my $uid = 500; 4341 my $gid = 500; 4342 4343 # Make sure that, if we're running as root, that the home directory has 4344 # permissions/privs set for the account we create 4345 if ($< == 0) { 4346 unless (chmod(0755, $home_dir)) { 4347 die("Can't set perms on $home_dir to 0755: $!"); 4348 } 4349 4350 unless (chown($uid, $gid, $home_dir)) { 4351 die("Can't set owner of $home_dir to $uid/$gid: $!"); 4352 } 4353 } 4354 4355 auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir, 4356 '/bin/bash'); 4357 auth_group_write($auth_group_file, $group, $gid, $user); 4358 4359 my $event_file = File::Spec->rel2abs("$tmpdir/denied-client.txt"); 4360 my $spawn_script = File::Spec->rel2abs("$tmpdir/spawn.sh"); 4361 if (open(my $fh, "> $spawn_script")) { 4362 print $fh <<EOS; 4363#!/usr/bin/env bash 4364echo $@ > $event_file 4365exit 4366EOS 4367 unless (close($fh)) { 4368 die("Can't write $spawn_script: $!"); 4369 } 4370 4371 unless (chmod(0777, $spawn_script)) { 4372 die("Can't set perms on $spawn_script to 0777: $!"); 4373 } 4374 4375 } else { 4376 die("Can't open $spawn_script: $!"); 4377 } 4378 4379 my $timeout_idle = 30; 4380 4381 my $config = { 4382 PidFile => $pid_file, 4383 ScoreboardFile => $scoreboard_file, 4384 SystemLog => $log_file, 4385 TraceLog => $log_file, 4386 Trace => 'event:20', 4387 4388 AuthUserFile => $auth_user_file, 4389 AuthGroupFile => $auth_group_file, 4390 TimeoutIdle => $timeout_idle, 4391 4392 IfModules => { 4393 'mod_delay.c' => { 4394 DelayEngine => 'off', 4395 }, 4396 4397 'mod_exec.c' => { 4398 ExecEngine => 'on', 4399 ExecLog => $log_file, 4400 ExecTimeout => 1, 4401 ExecOnEvent => "mod_wrap.connection-denied $spawn_script %a", 4402 }, 4403 4404 'mod_sql_sqlite.c' => [ 4405 "SQLAuthenticate off", 4406 "SQLConnectInfo $db_file", 4407 'SQLNamedQuery get-allowed-clients SELECT "allowed FROM ftpallow WHERE name = \'%{0}\'"', 4408 'SQLNamedQuery get-denied-clients SELECT "denied FROM ftpdeny WHERE name = \'%{0}\'"', 4409 "SQLLogFile $log_file", 4410 ], 4411 4412 'mod_wrap2_sql.c' => { 4413 WrapEngine => 'on', 4414 WrapTables => "sql:/get-allowed-clients sql:/get-denied-clients", 4415 WrapLog => $log_file, 4416 }, 4417 }, 4418 }; 4419 4420 my ($port, $config_user, $config_group) = config_write($config_file, $config); 4421 4422 # Open pipes, for use between the parent and child processes. Specifically, 4423 # the child will indicate when it's done with its test by writing a message 4424 # to the parent. 4425 my ($rfh, $wfh); 4426 unless (pipe($rfh, $wfh)) { 4427 die("Can't open pipe: $!"); 4428 } 4429 4430 my $ex; 4431 4432 # Fork child 4433 $self->handle_sigchld(); 4434 defined(my $pid = fork()) or die("Can't fork: $!"); 4435 if ($pid) { 4436 eval { 4437 my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port); 4438 eval { $client->login($user, $passwd) }; 4439 unless ($@) { 4440 die("Login succeeded unexpectedly"); 4441 } 4442 4443 my $resp_code = $client->response_code(); 4444 my $resp_msg = $client->response_msg(); 4445 4446 my $expected; 4447 4448 $expected = 530; 4449 $self->assert($expected == $resp_code, 4450 test_msg("Expected $expected, got $resp_code")); 4451 4452 $expected = "Access denied"; 4453 $self->assert($expected eq $resp_msg, 4454 test_msg("Expected '$expected', got '$resp_msg'")); 4455 4456 if (open(my $fh, "< $event_file")) { 4457 my $line = <$fh>; 4458 chomp($line); 4459 close($fh); 4460 4461 my $expected = '127.0.0.1'; 4462 $self->assert($expected eq $line, 4463 test_msg("Expected line '$expected', got '$line'")); 4464 4465 } else { 4466 die("Can't read $event_file: $!"); 4467 } 4468 4469 }; 4470 4471 if ($@) { 4472 $ex = $@; 4473 } 4474 4475 $wfh->print("done\n"); 4476 $wfh->flush(); 4477 4478 } else { 4479 eval { server_wait($config_file, $rfh, $timeout_idle + 2) }; 4480 if ($@) { 4481 warn($@); 4482 exit 1; 4483 } 4484 4485 exit 0; 4486 } 4487 4488 # Stop server 4489 server_stop($pid_file); 4490 4491 $self->assert_child_ok($pid); 4492 4493 if ($ex) { 4494 test_append_logfile($log_file, $ex); 4495 unlink($log_file); 4496 4497 die($ex); 4498 } 4499 4500 unlink($log_file); 4501} 4502 45031; 4504