1package ProFTPD::Tests::Modules::mod_lang; 2 3use lib qw(t/lib); 4use base qw(ProFTPD::TestSuite::Child); 5use strict; 6 7use File::Copy; 8use File::Path qw(mkpath); 9use File::Spec; 10use IO::Handle; 11 12use ProFTPD::TestSuite::FTP; 13use ProFTPD::TestSuite::Utils qw(:auth :config :running :test :testsuite); 14 15$| = 1; 16 17my $order = 0; 18 19my $TESTS = { 20 lang_feat_default => { 21 order => ++$order, 22 test_class => [qw(forking)], 23 }, 24 25 lang_feat_engine_off => { 26 order => ++$order, 27 test_class => [qw(forking)], 28 }, 29 30 lang_lang_none_ok => { 31 order => ++$order, 32 test_class => [qw(forking)], 33 }, 34 35 lang_lang_env_ok => { 36 order => ++$order, 37 test_class => [qw(forking)], 38 }, 39 40 lang_lang_default_ok => { 41 order => ++$order, 42 test_class => [qw(forking)], 43 }, 44 45 lang_lang_unknown_failed => { 46 order => ++$order, 47 test_class => [qw(forking)], 48 }, 49 50 lang_opts_utf8_ok => { 51 order => ++$order, 52 test_class => [qw(forking)], 53 }, 54 55 lang_opts_utf8_nonbool_failed => { 56 order => ++$order, 57 test_class => [qw(forking)], 58 }, 59 60 lang_lang_default_en_US => { 61 order => ++$order, 62 test_class => [qw(forking)], 63 }, 64 65 lang_lang_default_en_US_UTF8 => { 66 order => ++$order, 67 test_class => [qw(forking)], 68 }, 69 70 lang_opts_utf8_useencoding_on => { 71 order => ++$order, 72 test_class => [qw(forking)], 73 }, 74 75 lang_opts_utf8_useencoding_off => { 76 order => ++$order, 77 test_class => [qw(forking)], 78 }, 79 80 lang_opts_utf8_useencoding_charsets => { 81 order => ++$order, 82 test_class => [qw(forking)], 83 }, 84 85 lang_opts_utf8_useencoding_charsets_strict => { 86 order => ++$order, 87 test_class => [qw(forking)], 88 }, 89 90 lang_opts_utf8_useencoding_charsets_strict_with_utf8 => { 91 order => ++$order, 92 test_class => [qw(forking)], 93 }, 94 95 lang_opts_utf8_useencoding_charsets_with_env => { 96 order => ++$order, 97 test_class => [qw(forking)], 98 }, 99 100 lang_useencoding_latin1_utf8 => { 101 order => ++$order, 102 test_class => [qw(forking)], 103 }, 104 105 lang_useencoding_utf8_latin1 => { 106 order => ++$order, 107 test_class => [qw(forking)], 108 }, 109 110 lang_opts_utf8_prefer_server_encoding_bug4125 => { 111 order => ++$order, 112 test_class => [qw(bug forking)], 113 }, 114 115 lang_opts_utf8_useencoding_charsets_prefer_server_encoding_bug4125 => { 116 order => ++$order, 117 test_class => [qw(bug forking)], 118 }, 119 120 lang_useencoding_ascii_utf8_require_valid_encoding_bug4125 => { 121 order => ++$order, 122 test_class => [qw(bug forking)], 123 }, 124 125 lang_useencoding_latin1_utf8_per_user_bug4214 => { 126 order => ++$order, 127 test_class => [qw(forking mod_ifsession)], 128 }, 129 130 lang_useencoding_utf8_latin1_per_user_bug4214 => { 131 order => ++$order, 132 test_class => [qw(forking mod_ifsession)], 133 }, 134 135}; 136 137sub new { 138 return shift()->SUPER::new(@_); 139} 140 141sub list_tests { 142 return testsuite_get_runnable_tests($TESTS); 143} 144 145sub lang_feat_default { 146 my $self = shift; 147 my $tmpdir = $self->{tmpdir}; 148 149 my $config_file = "$tmpdir/lang.conf"; 150 my $pid_file = File::Spec->rel2abs("$tmpdir/lang.pid"); 151 my $scoreboard_file = File::Spec->rel2abs("$tmpdir/lang.scoreboard"); 152 153 my $log_file = test_get_logfile(); 154 155 my $auth_user_file = File::Spec->rel2abs("$tmpdir/lang.passwd"); 156 my $auth_group_file = File::Spec->rel2abs("$tmpdir/lang.group"); 157 158 my $user = 'proftpd'; 159 my $passwd = 'test'; 160 my $group = 'ftpd'; 161 my $home_dir = File::Spec->rel2abs($tmpdir); 162 my $uid = 500; 163 my $gid = 500; 164 165 # Make sure that, if we're running as root, that the home directory has 166 # permissions/privs set for the account we create 167 if ($< == 0) { 168 unless (chmod(0755, $home_dir)) { 169 die("Can't set perms on $home_dir to 0755: $!"); 170 } 171 172 unless (chown($uid, $gid, $home_dir)) { 173 die("Can't set owner of $home_dir to $uid/$gid: $!"); 174 } 175 } 176 177 auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir, 178 '/bin/bash'); 179 auth_group_write($auth_group_file, $group, $gid, $user); 180 181 my $config = { 182 PidFile => $pid_file, 183 ScoreboardFile => $scoreboard_file, 184 SystemLog => $log_file, 185 186 AuthUserFile => $auth_user_file, 187 AuthGroupFile => $auth_group_file, 188 189 IfModules => { 190 'mod_delay.c' => { 191 DelayEngine => 'off', 192 }, 193 }, 194 }; 195 196 my ($port, $config_user, $config_group) = config_write($config_file, $config); 197 198 # Open pipes, for use between the parent and child processes. Specifically, 199 # the child will indicate when it's done with its test by writing a message 200 # to the parent. 201 my ($rfh, $wfh); 202 unless (pipe($rfh, $wfh)) { 203 die("Can't open pipe: $!"); 204 } 205 206 my $ex; 207 208 # Fork child 209 $self->handle_sigchld(); 210 defined(my $pid = fork()) or die("Can't fork: $!"); 211 if ($pid) { 212 eval { 213 my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port); 214 $client->login($user, $passwd); 215 216 $client->feat(); 217 my $resp_code = $client->response_code(); 218 my $resp_msgs = $client->response_msgs(); 219 220 my $expected; 221 222 $expected = 211; 223 $self->assert($expected == $resp_code, 224 test_msg("Expected $expected, got $resp_code")); 225 226 my $feats = { 227 ' UTF8' => 1, 228 229 # One of the following will appear in the FEAT list, depending 230 # on the underlying platform. 231 ' LANG en_US' => 1, 232 ' LANG en-US' => 1, 233 ' LANG en-US*' => 1, 234 ' LANG en_US.UTF-8' => 1, 235 ' LANG en-US.UTF-8' => 1, 236 ' LANG en-US.UTF-8*' => 1, 237 }; 238 239 my $seen = 0; 240 241 my $nfeat = scalar(@$resp_msgs); 242 for (my $i = 0; $i < $nfeat; $i++) { 243 if (defined($feats->{$resp_msgs->[$i]})) { 244 $seen++; 245 } 246 } 247 248 $expected = 2; 249 $self->assert($expected == $seen, 250 test_msg("Expected $expected, got $seen")); 251 }; 252 253 if ($@) { 254 $ex = $@; 255 } 256 257 $wfh->print("done\n"); 258 $wfh->flush(); 259 260 } else { 261 eval { server_wait($config_file, $rfh) }; 262 if ($@) { 263 warn($@); 264 exit 1; 265 } 266 267 exit 0; 268 } 269 270 # Stop server 271 server_stop($pid_file); 272 273 $self->assert_child_ok($pid); 274 275 if ($ex) { 276 test_append_logfile($log_file, $ex); 277 unlink($log_file); 278 279 die($ex); 280 } 281 282 unlink($log_file); 283} 284 285sub lang_feat_engine_off { 286 my $self = shift; 287 my $tmpdir = $self->{tmpdir}; 288 289 my $config_file = "$tmpdir/lang.conf"; 290 my $pid_file = File::Spec->rel2abs("$tmpdir/lang.pid"); 291 my $scoreboard_file = File::Spec->rel2abs("$tmpdir/lang.scoreboard"); 292 293 my $log_file = test_get_logfile(); 294 295 my $auth_user_file = File::Spec->rel2abs("$tmpdir/lang.passwd"); 296 my $auth_group_file = File::Spec->rel2abs("$tmpdir/lang.group"); 297 298 my $user = 'proftpd'; 299 my $passwd = 'test'; 300 my $group = 'ftpd'; 301 my $home_dir = File::Spec->rel2abs($tmpdir); 302 my $uid = 500; 303 my $gid = 500; 304 305 # Make sure that, if we're running as root, that the home directory has 306 # permissions/privs set for the account we create 307 if ($< == 0) { 308 unless (chmod(0755, $home_dir)) { 309 die("Can't set perms on $home_dir to 0755: $!"); 310 } 311 312 unless (chown($uid, $gid, $home_dir)) { 313 die("Can't set owner of $home_dir to $uid/$gid: $!"); 314 } 315 } 316 317 auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir, 318 '/bin/bash'); 319 auth_group_write($auth_group_file, $group, $gid, $user); 320 321 my $config = { 322 PidFile => $pid_file, 323 ScoreboardFile => $scoreboard_file, 324 SystemLog => $log_file, 325 326 AuthUserFile => $auth_user_file, 327 AuthGroupFile => $auth_group_file, 328 329 IfModules => { 330 'mod_delay.c' => { 331 DelayEngine => 'off', 332 }, 333 334 'mod_lang.c' => { 335 LangEngine => 'off', 336 }, 337 }, 338 }; 339 340 my ($port, $config_user, $config_group) = config_write($config_file, $config); 341 342 # Open pipes, for use between the parent and child processes. Specifically, 343 # the child will indicate when it's done with its test by writing a message 344 # to the parent. 345 my ($rfh, $wfh); 346 unless (pipe($rfh, $wfh)) { 347 die("Can't open pipe: $!"); 348 } 349 350 my $ex; 351 352 # Fork child 353 $self->handle_sigchld(); 354 defined(my $pid = fork()) or die("Can't fork: $!"); 355 if ($pid) { 356 eval { 357 my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port); 358 $client->login($user, $passwd); 359 360 $client->feat(); 361 my $resp_code = $client->response_code(); 362 my $resp_msgs = $client->response_msgs(); 363 364 my $expected; 365 366 $expected = 211; 367 $self->assert($expected == $resp_code, 368 test_msg("Expected $expected, got $resp_code")); 369 370 my $feats = { 371 # None of the following should appear in the FEAT list 372 373 ' UTF8' => 1, 374 ' LANG en_US' => 1, 375 ' LANG en-US' => 1, 376 ' LANG en-US*' => 1, 377 ' LANG en_US.UTF-8' => 1, 378 ' LANG en-US.UTF-8' => 1, 379 ' LANG en-US.UTF-8*' => 1, 380 }; 381 382 my $seen = 0; 383 384 my $nfeat = scalar(@$resp_msgs); 385 for (my $i = 0; $i < $nfeat; $i++) { 386 if (defined($feats->{$resp_msgs->[$i]})) { 387 $seen++; 388 } 389 } 390 391 $expected = 0; 392 $self->assert($expected == $seen, 393 test_msg("Expected $expected, got $seen")); 394 }; 395 396 if ($@) { 397 $ex = $@; 398 } 399 400 $wfh->print("done\n"); 401 $wfh->flush(); 402 403 } else { 404 eval { server_wait($config_file, $rfh) }; 405 if ($@) { 406 warn($@); 407 exit 1; 408 } 409 410 exit 0; 411 } 412 413 # Stop server 414 server_stop($pid_file); 415 416 $self->assert_child_ok($pid); 417 418 if ($ex) { 419 test_append_logfile($log_file, $ex); 420 unlink($log_file); 421 422 die($ex); 423 } 424 425 unlink($log_file); 426} 427 428sub lang_lang_none_ok { 429 my $self = shift; 430 my $tmpdir = $self->{tmpdir}; 431 432 my $config_file = "$tmpdir/lang.conf"; 433 my $pid_file = File::Spec->rel2abs("$tmpdir/lang.pid"); 434 my $scoreboard_file = File::Spec->rel2abs("$tmpdir/lang.scoreboard"); 435 436 my $log_file = test_get_logfile(); 437 438 my $auth_user_file = File::Spec->rel2abs("$tmpdir/lang.passwd"); 439 my $auth_group_file = File::Spec->rel2abs("$tmpdir/lang.group"); 440 441 my $user = 'proftpd'; 442 my $passwd = 'test'; 443 my $group = 'ftpd'; 444 my $home_dir = File::Spec->rel2abs($tmpdir); 445 my $uid = 500; 446 my $gid = 500; 447 448 # Make sure that, if we're running as root, that the home directory has 449 # permissions/privs set for the account we create 450 if ($< == 0) { 451 unless (chmod(0755, $home_dir)) { 452 die("Can't set perms on $home_dir to 0755: $!"); 453 } 454 455 unless (chown($uid, $gid, $home_dir)) { 456 die("Can't set owner of $home_dir to $uid/$gid: $!"); 457 } 458 } 459 460 auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir, 461 '/bin/bash'); 462 auth_group_write($auth_group_file, $group, $gid, $user); 463 464 my $config = { 465 PidFile => $pid_file, 466 ScoreboardFile => $scoreboard_file, 467 SystemLog => $log_file, 468 469 AuthUserFile => $auth_user_file, 470 AuthGroupFile => $auth_group_file, 471 472 IfModules => { 473 'mod_delay.c' => { 474 DelayEngine => 'off', 475 }, 476 }, 477 }; 478 479 my ($port, $config_user, $config_group) = config_write($config_file, $config); 480 481 # Open pipes, for use between the parent and child processes. Specifically, 482 # the child will indicate when it's done with its test by writing a message 483 # to the parent. 484 my ($rfh, $wfh); 485 unless (pipe($rfh, $wfh)) { 486 die("Can't open pipe: $!"); 487 } 488 489 my $ex; 490 491 # Fork child 492 $self->handle_sigchld(); 493 defined(my $pid = fork()) or die("Can't fork: $!"); 494 if ($pid) { 495 eval { 496 my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port); 497 498 my ($resp_code, $resp_msg) = $client->lang(); 499 500 my $expected; 501 502 $expected = 200; 503 $self->assert($expected == $resp_code, 504 test_msg("Expected $expected, got $resp_code")); 505 506 $expected = 'Using default language \S+'; 507 $self->assert(qr/$expected/, $resp_msg, 508 test_msg("Expected '$expected', got '$resp_msg'")); 509 }; 510 511 if ($@) { 512 $ex = $@; 513 } 514 515 $wfh->print("done\n"); 516 $wfh->flush(); 517 518 } else { 519 eval { server_wait($config_file, $rfh) }; 520 if ($@) { 521 warn($@); 522 exit 1; 523 } 524 525 exit 0; 526 } 527 528 # Stop server 529 server_stop($pid_file); 530 531 $self->assert_child_ok($pid); 532 533 if ($ex) { 534 test_append_logfile($log_file, $ex); 535 unlink($log_file); 536 537 die($ex); 538 } 539 540 unlink($log_file); 541} 542 543sub lang_lang_env_ok { 544 my $self = shift; 545 my $tmpdir = $self->{tmpdir}; 546 547 my $config_file = "$tmpdir/lang.conf"; 548 my $pid_file = File::Spec->rel2abs("$tmpdir/lang.pid"); 549 my $scoreboard_file = File::Spec->rel2abs("$tmpdir/lang.scoreboard"); 550 551 my $log_file = test_get_logfile(); 552 553 my $auth_user_file = File::Spec->rel2abs("$tmpdir/lang.passwd"); 554 my $auth_group_file = File::Spec->rel2abs("$tmpdir/lang.group"); 555 556 my $user = 'proftpd'; 557 my $passwd = 'test'; 558 my $group = 'ftpd'; 559 my $home_dir = File::Spec->rel2abs($tmpdir); 560 my $uid = 500; 561 my $gid = 500; 562 563 # Make sure that, if we're running as root, that the home directory has 564 # permissions/privs set for the account we create 565 if ($< == 0) { 566 unless (chmod(0755, $home_dir)) { 567 die("Can't set perms on $home_dir to 0755: $!"); 568 } 569 570 unless (chown($uid, $gid, $home_dir)) { 571 die("Can't set owner of $home_dir to $uid/$gid: $!"); 572 } 573 } 574 575 auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir, 576 '/bin/bash'); 577 auth_group_write($auth_group_file, $group, $gid, $user); 578 579 my $config = { 580 PidFile => $pid_file, 581 ScoreboardFile => $scoreboard_file, 582 SystemLog => $log_file, 583 584 AuthUserFile => $auth_user_file, 585 AuthGroupFile => $auth_group_file, 586 587 IfModules => { 588 'mod_delay.c' => { 589 DelayEngine => 'off', 590 }, 591 }, 592 }; 593 594 my ($port, $config_user, $config_group) = config_write($config_file, $config); 595 596 my $lang = 'en_US'; 597 598 # Open pipes, for use between the parent and child processes. Specifically, 599 # the child will indicate when it's done with its test by writing a message 600 # to the parent. 601 my ($rfh, $wfh); 602 unless (pipe($rfh, $wfh)) { 603 die("Can't open pipe: $!"); 604 } 605 606 my $ex; 607 608 # Fork child 609 $self->handle_sigchld(); 610 defined(my $pid = fork()) or die("Can't fork: $!"); 611 if ($pid) { 612 eval { 613 my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port); 614 615 my ($resp_code, $resp_msg) = $client->lang(); 616 617 my $expected; 618 619 $expected = 200; 620 $self->assert($expected == $resp_code, 621 test_msg("Expected $expected, got $resp_code")); 622 623 $expected = "Using default language $lang"; 624 $self->assert(qr/$expected/, $resp_msg, 625 test_msg("Expected '$expected', got '$resp_msg'")); 626 }; 627 628 if ($@) { 629 $ex = $@; 630 } 631 632 $wfh->print("done\n"); 633 $wfh->flush(); 634 635 } else { 636 # Specify a LANG environment variable, for mod_lang to pick up 637 $ENV{LANG} = $lang; 638 639 eval { server_wait($config_file, $rfh) }; 640 if ($@) { 641 warn($@); 642 exit 1; 643 } 644 645 exit 0; 646 } 647 648 # Stop server 649 server_stop($pid_file); 650 651 $self->assert_child_ok($pid); 652 653 if ($ex) { 654 test_append_logfile($log_file, $ex); 655 unlink($log_file); 656 657 die($ex); 658 } 659 660 unlink($log_file); 661} 662 663sub lang_lang_default_ok { 664 my $self = shift; 665 my $tmpdir = $self->{tmpdir}; 666 667 my $config_file = "$tmpdir/lang.conf"; 668 my $pid_file = File::Spec->rel2abs("$tmpdir/lang.pid"); 669 my $scoreboard_file = File::Spec->rel2abs("$tmpdir/lang.scoreboard"); 670 671 my $log_file = test_get_logfile(); 672 673 my $auth_user_file = File::Spec->rel2abs("$tmpdir/lang.passwd"); 674 my $auth_group_file = File::Spec->rel2abs("$tmpdir/lang.group"); 675 676 my $user = 'proftpd'; 677 my $passwd = 'test'; 678 my $group = 'ftpd'; 679 my $home_dir = File::Spec->rel2abs($tmpdir); 680 my $uid = 500; 681 my $gid = 500; 682 683 # Make sure that, if we're running as root, that the home directory has 684 # permissions/privs set for the account we create 685 if ($< == 0) { 686 unless (chmod(0755, $home_dir)) { 687 die("Can't set perms on $home_dir to 0755: $!"); 688 } 689 690 unless (chown($uid, $gid, $home_dir)) { 691 die("Can't set owner of $home_dir to $uid/$gid: $!"); 692 } 693 } 694 695 auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir, 696 '/bin/bash'); 697 auth_group_write($auth_group_file, $group, $gid, $user); 698 699 my $config = { 700 PidFile => $pid_file, 701 ScoreboardFile => $scoreboard_file, 702 SystemLog => $log_file, 703 704 AuthUserFile => $auth_user_file, 705 AuthGroupFile => $auth_group_file, 706 707 IfModules => { 708 'mod_delay.c' => { 709 DelayEngine => 'off', 710 }, 711 }, 712 }; 713 714 my ($port, $config_user, $config_group) = config_write($config_file, $config); 715 716 # Open pipes, for use between the parent and child processes. Specifically, 717 # the child will indicate when it's done with its test by writing a message 718 # to the parent. 719 my ($rfh, $wfh); 720 unless (pipe($rfh, $wfh)) { 721 die("Can't open pipe: $!"); 722 } 723 724 my $ex; 725 726 # Fork child 727 $self->handle_sigchld(); 728 defined(my $pid = fork()) or die("Can't fork: $!"); 729 if ($pid) { 730 eval { 731 my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port); 732 733 my ($resp_code, $resp_msg); 734 735 # First, find out what the default language is. 736 ($resp_code, $resp_msg) = $client->lang(); 737 738 my $expected; 739 740 $expected = 200; 741 $self->assert($expected == $resp_code, 742 test_msg("Expected $expected, got $resp_code")); 743 744 $expected = '^Using default language (\S+)$'; 745 $self->assert(qr/$expected/, $resp_msg, 746 test_msg("Expected '$expected', got '$resp_msg'")); 747 748 $resp_msg =~ /$expected/; 749 my $default_lang = $1; 750 751 ($resp_code, $resp_msg) = $client->lang($default_lang); 752 753 $expected = 200; 754 $self->assert($expected == $resp_code, 755 test_msg("Expected $expected, got $resp_code")); 756 757 $expected = "Using language $default_lang"; 758 $self->assert($expected eq $resp_msg, 759 test_msg("Expected '$expected', got '$resp_msg'")); 760 }; 761 762 if ($@) { 763 $ex = $@; 764 } 765 766 $wfh->print("done\n"); 767 $wfh->flush(); 768 769 } else { 770 eval { server_wait($config_file, $rfh) }; 771 if ($@) { 772 warn($@); 773 exit 1; 774 } 775 776 exit 0; 777 } 778 779 # Stop server 780 server_stop($pid_file); 781 782 $self->assert_child_ok($pid); 783 784 if ($ex) { 785 test_append_logfile($log_file, $ex); 786 unlink($log_file); 787 788 die($ex); 789 } 790 791 unlink($log_file); 792} 793 794sub lang_lang_unknown_failed { 795 my $self = shift; 796 my $tmpdir = $self->{tmpdir}; 797 798 my $config_file = "$tmpdir/lang.conf"; 799 my $pid_file = File::Spec->rel2abs("$tmpdir/lang.pid"); 800 my $scoreboard_file = File::Spec->rel2abs("$tmpdir/lang.scoreboard"); 801 802 my $log_file = test_get_logfile(); 803 804 my $auth_user_file = File::Spec->rel2abs("$tmpdir/lang.passwd"); 805 my $auth_group_file = File::Spec->rel2abs("$tmpdir/lang.group"); 806 807 my $user = 'proftpd'; 808 my $passwd = 'test'; 809 my $group = 'ftpd'; 810 my $home_dir = File::Spec->rel2abs($tmpdir); 811 my $uid = 500; 812 my $gid = 500; 813 814 # Make sure that, if we're running as root, that the home directory has 815 # permissions/privs set for the account we create 816 if ($< == 0) { 817 unless (chmod(0755, $home_dir)) { 818 die("Can't set perms on $home_dir to 0755: $!"); 819 } 820 821 unless (chown($uid, $gid, $home_dir)) { 822 die("Can't set owner of $home_dir to $uid/$gid: $!"); 823 } 824 } 825 826 auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir, 827 '/bin/bash'); 828 auth_group_write($auth_group_file, $group, $gid, $user); 829 830 my $config = { 831 PidFile => $pid_file, 832 ScoreboardFile => $scoreboard_file, 833 SystemLog => $log_file, 834 835 AuthUserFile => $auth_user_file, 836 AuthGroupFile => $auth_group_file, 837 838 IfModules => { 839 'mod_delay.c' => { 840 DelayEngine => 'off', 841 }, 842 }, 843 }; 844 845 my ($port, $config_user, $config_group) = config_write($config_file, $config); 846 847 # Open pipes, for use between the parent and child processes. Specifically, 848 # the child will indicate when it's done with its test by writing a message 849 # to the parent. 850 my ($rfh, $wfh); 851 unless (pipe($rfh, $wfh)) { 852 die("Can't open pipe: $!"); 853 } 854 855 my $ex; 856 857 # Fork child 858 $self->handle_sigchld(); 859 defined(my $pid = fork()) or die("Can't fork: $!"); 860 if ($pid) { 861 eval { 862 my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port); 863 864 my ($resp_code, $resp_msg); 865 866 eval { $client->lang('foobarbaz') }; 867 unless ($@) { 868 die("LANG succeeded unexpectedly"); 869 870 } else { 871 $resp_code = $client->response_code(); 872 $resp_msg = $client->response_msg(); 873 } 874 875 my $expected; 876 877 $expected = 504; 878 $self->assert($expected == $resp_code, 879 test_msg("Expected $expected, got $resp_code")); 880 881 $expected = 'Language foobarbaz not supported'; 882 $self->assert($expected eq $resp_msg, 883 test_msg("Expected '$expected', got '$resp_msg'")); 884 }; 885 886 if ($@) { 887 $ex = $@; 888 } 889 890 $wfh->print("done\n"); 891 $wfh->flush(); 892 893 } else { 894 eval { server_wait($config_file, $rfh) }; 895 if ($@) { 896 warn($@); 897 exit 1; 898 } 899 900 exit 0; 901 } 902 903 # Stop server 904 server_stop($pid_file); 905 906 $self->assert_child_ok($pid); 907 908 if ($ex) { 909 test_append_logfile($log_file, $ex); 910 unlink($log_file); 911 912 die($ex); 913 } 914 915 unlink($log_file); 916} 917 918sub lang_opts_utf8_ok { 919 my $self = shift; 920 my $tmpdir = $self->{tmpdir}; 921 922 my $config_file = "$tmpdir/lang.conf"; 923 my $pid_file = File::Spec->rel2abs("$tmpdir/lang.pid"); 924 my $scoreboard_file = File::Spec->rel2abs("$tmpdir/lang.scoreboard"); 925 926 my $log_file = test_get_logfile(); 927 928 my $auth_user_file = File::Spec->rel2abs("$tmpdir/lang.passwd"); 929 my $auth_group_file = File::Spec->rel2abs("$tmpdir/lang.group"); 930 931 my $user = 'proftpd'; 932 my $passwd = 'test'; 933 my $group = 'ftpd'; 934 my $home_dir = File::Spec->rel2abs($tmpdir); 935 my $uid = 500; 936 my $gid = 500; 937 938 # Make sure that, if we're running as root, that the home directory has 939 # permissions/privs set for the account we create 940 if ($< == 0) { 941 unless (chmod(0755, $home_dir)) { 942 die("Can't set perms on $home_dir to 0755: $!"); 943 } 944 945 unless (chown($uid, $gid, $home_dir)) { 946 die("Can't set owner of $home_dir to $uid/$gid: $!"); 947 } 948 } 949 950 auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir, 951 '/bin/bash'); 952 auth_group_write($auth_group_file, $group, $gid, $user); 953 954 my $config = { 955 PidFile => $pid_file, 956 ScoreboardFile => $scoreboard_file, 957 SystemLog => $log_file, 958 959 AuthUserFile => $auth_user_file, 960 AuthGroupFile => $auth_group_file, 961 962 IfModules => { 963 'mod_delay.c' => { 964 DelayEngine => 'off', 965 }, 966 }, 967 }; 968 969 my ($port, $config_user, $config_group) = config_write($config_file, $config); 970 971 # Open pipes, for use between the parent and child processes. Specifically, 972 # the child will indicate when it's done with its test by writing a message 973 # to the parent. 974 my ($rfh, $wfh); 975 unless (pipe($rfh, $wfh)) { 976 die("Can't open pipe: $!"); 977 } 978 979 my $ex; 980 981 # Fork child 982 $self->handle_sigchld(); 983 defined(my $pid = fork()) or die("Can't fork: $!"); 984 if ($pid) { 985 eval { 986 my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port); 987 my ($resp_code, $resp_msg) = $client->opts('UTF8', 'off'); 988 989 my $expected; 990 991 $expected = 200; 992 $self->assert($expected == $resp_code, 993 test_msg("Expected response code $expected, got $resp_code")); 994 995 $expected = 'UTF8 set to off'; 996 $self->assert($expected eq $resp_msg, 997 test_msg("Expected response message '$expected', got '$resp_msg'")); 998 999 ($resp_code, $resp_msg) = $client->opts('UTF8', 'on'); 1000 1001 $expected = 200; 1002 $self->assert($expected == $resp_code, 1003 test_msg("Expected response code $expected, got $resp_code")); 1004 1005 $expected = 'UTF8 set to on'; 1006 $self->assert($expected eq $resp_msg, 1007 test_msg("Expected response message '$expected', got '$resp_msg'")); 1008 }; 1009 1010 if ($@) { 1011 $ex = $@; 1012 } 1013 1014 $wfh->print("done\n"); 1015 $wfh->flush(); 1016 1017 } else { 1018 eval { server_wait($config_file, $rfh) }; 1019 if ($@) { 1020 warn($@); 1021 exit 1; 1022 } 1023 1024 exit 0; 1025 } 1026 1027 # Stop server 1028 server_stop($pid_file); 1029 1030 $self->assert_child_ok($pid); 1031 1032 if ($ex) { 1033 test_append_logfile($log_file, $ex); 1034 unlink($log_file); 1035 1036 die($ex); 1037 } 1038 1039 unlink($log_file); 1040} 1041 1042sub lang_opts_utf8_nonbool_failed { 1043 my $self = shift; 1044 my $tmpdir = $self->{tmpdir}; 1045 1046 my $config_file = "$tmpdir/lang.conf"; 1047 my $pid_file = File::Spec->rel2abs("$tmpdir/lang.pid"); 1048 my $scoreboard_file = File::Spec->rel2abs("$tmpdir/lang.scoreboard"); 1049 1050 my $log_file = test_get_logfile(); 1051 1052 my $auth_user_file = File::Spec->rel2abs("$tmpdir/lang.passwd"); 1053 my $auth_group_file = File::Spec->rel2abs("$tmpdir/lang.group"); 1054 1055 my $user = 'proftpd'; 1056 my $passwd = 'test'; 1057 my $group = 'ftpd'; 1058 my $home_dir = File::Spec->rel2abs($tmpdir); 1059 my $uid = 500; 1060 my $gid = 500; 1061 1062 # Make sure that, if we're running as root, that the home directory has 1063 # permissions/privs set for the account we create 1064 if ($< == 0) { 1065 unless (chmod(0755, $home_dir)) { 1066 die("Can't set perms on $home_dir to 0755: $!"); 1067 } 1068 1069 unless (chown($uid, $gid, $home_dir)) { 1070 die("Can't set owner of $home_dir to $uid/$gid: $!"); 1071 } 1072 } 1073 1074 auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir, 1075 '/bin/bash'); 1076 auth_group_write($auth_group_file, $group, $gid, $user); 1077 1078 my $config = { 1079 PidFile => $pid_file, 1080 ScoreboardFile => $scoreboard_file, 1081 SystemLog => $log_file, 1082 1083 AuthUserFile => $auth_user_file, 1084 AuthGroupFile => $auth_group_file, 1085 1086 IfModules => { 1087 'mod_delay.c' => { 1088 DelayEngine => 'off', 1089 }, 1090 }, 1091 }; 1092 1093 my ($port, $config_user, $config_group) = config_write($config_file, $config); 1094 1095 # Open pipes, for use between the parent and child processes. Specifically, 1096 # the child will indicate when it's done with its test by writing a message 1097 # to the parent. 1098 my ($rfh, $wfh); 1099 unless (pipe($rfh, $wfh)) { 1100 die("Can't open pipe: $!"); 1101 } 1102 1103 my $ex; 1104 1105 # Fork child 1106 $self->handle_sigchld(); 1107 defined(my $pid = fork()) or die("Can't fork: $!"); 1108 if ($pid) { 1109 eval { 1110 my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port); 1111 1112 my ($resp_code, $resp_msg); 1113 1114 eval { $client->opts('UTF8', 'foobar') }; 1115 unless ($@) { 1116 die("OPTS UTF8 succeeded unexpectedly"); 1117 1118 } else { 1119 $resp_code = $client->response_code(); 1120 $resp_msg = $client->response_msg(); 1121 } 1122 1123 my $expected; 1124 1125 $expected = 501; 1126 $self->assert($expected == $resp_code, 1127 test_msg("Expected $expected, got $resp_code")); 1128 1129 $expected = "'OPTS UTF8' not understood"; 1130 $self->assert($expected eq $resp_msg, 1131 test_msg("Expected '$expected', got '$resp_msg'")); 1132 }; 1133 1134 if ($@) { 1135 $ex = $@; 1136 } 1137 1138 $wfh->print("done\n"); 1139 $wfh->flush(); 1140 1141 } else { 1142 eval { server_wait($config_file, $rfh) }; 1143 if ($@) { 1144 warn($@); 1145 exit 1; 1146 } 1147 1148 exit 0; 1149 } 1150 1151 # Stop server 1152 server_stop($pid_file); 1153 1154 $self->assert_child_ok($pid); 1155 1156 if ($ex) { 1157 test_append_logfile($log_file, $ex); 1158 unlink($log_file); 1159 1160 die($ex); 1161 } 1162 1163 unlink($log_file); 1164} 1165 1166sub lang_lang_default_en_US { 1167 my $self = shift; 1168 my $tmpdir = $self->{tmpdir}; 1169 1170 my $config_file = "$tmpdir/lang.conf"; 1171 my $pid_file = File::Spec->rel2abs("$tmpdir/lang.pid"); 1172 my $scoreboard_file = File::Spec->rel2abs("$tmpdir/lang.scoreboard"); 1173 1174 my $log_file = test_get_logfile(); 1175 1176 my $auth_user_file = File::Spec->rel2abs("$tmpdir/lang.passwd"); 1177 my $auth_group_file = File::Spec->rel2abs("$tmpdir/lang.group"); 1178 1179 my $user = 'proftpd'; 1180 my $passwd = 'test'; 1181 my $group = 'ftpd'; 1182 my $home_dir = File::Spec->rel2abs($tmpdir); 1183 my $uid = 500; 1184 my $gid = 500; 1185 1186 # Make sure that, if we're running as root, that the home directory has 1187 # permissions/privs set for the account we create 1188 if ($< == 0) { 1189 unless (chmod(0755, $home_dir)) { 1190 die("Can't set perms on $home_dir to 0755: $!"); 1191 } 1192 1193 unless (chown($uid, $gid, $home_dir)) { 1194 die("Can't set owner of $home_dir to $uid/$gid: $!"); 1195 } 1196 } 1197 1198 auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir, 1199 '/bin/bash'); 1200 auth_group_write($auth_group_file, $group, $gid, $user); 1201 1202 # Copy the en_US.mo file from the locale/ directory into a directory 1203 # that we can tell mod_lang to find. 1204 1205 my $lang_path = File::Spec->rel2abs("$tmpdir/locale"); 1206 mkpath("$lang_path/en_US/LC_MESSAGES"); 1207 1208 copy("../locale/en_US.mo", "$lang_path/en_US/LC_MESSAGES/proftpd.mo"); 1209 1210 my $config = { 1211 PidFile => $pid_file, 1212 ScoreboardFile => $scoreboard_file, 1213 SystemLog => $log_file, 1214 1215 AuthUserFile => $auth_user_file, 1216 AuthGroupFile => $auth_group_file, 1217 1218 IfModules => { 1219 'mod_delay.c' => { 1220 DelayEngine => 'off', 1221 }, 1222 1223 'mod_lang.c' => { 1224 LangPath => $lang_path, 1225 LangDefault => 'en_US', 1226 }, 1227 }, 1228 }; 1229 1230 my ($port, $config_user, $config_group) = config_write($config_file, $config); 1231 1232 # Open pipes, for use between the parent and child processes. Specifically, 1233 # the child will indicate when it's done with its test by writing a message 1234 # to the parent. 1235 my ($rfh, $wfh); 1236 unless (pipe($rfh, $wfh)) { 1237 die("Can't open pipe: $!"); 1238 } 1239 1240 my $ex; 1241 1242 # Fork child 1243 $self->handle_sigchld(); 1244 defined(my $pid = fork()) or die("Can't fork: $!"); 1245 if ($pid) { 1246 eval { 1247 my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port); 1248 my ($resp_code, $resp_msg) = $client->user($user); 1249 1250 my $expected; 1251 1252 $expected = 331; 1253 $self->assert($expected == $resp_code, 1254 test_msg("Expected $expected, got $resp_code")); 1255 1256 $expected = "Password required for $user"; 1257 $self->assert($expected eq $resp_msg, 1258 test_msg("Expected '$expected', got '$resp_msg'")); 1259 }; 1260 1261 if ($@) { 1262 $ex = $@; 1263 } 1264 1265 $wfh->print("done\n"); 1266 $wfh->flush(); 1267 1268 } else { 1269 eval { server_wait($config_file, $rfh) }; 1270 if ($@) { 1271 warn($@); 1272 exit 1; 1273 } 1274 1275 exit 0; 1276 } 1277 1278 # Stop server 1279 server_stop($pid_file); 1280 1281 $self->assert_child_ok($pid); 1282 1283 if ($ex) { 1284 test_append_logfile($log_file, $ex); 1285 unlink($log_file); 1286 1287 die($ex); 1288 } 1289 1290 unlink($log_file); 1291} 1292 1293sub lang_lang_default_en_US_UTF8 { 1294 my $self = shift; 1295 my $tmpdir = $self->{tmpdir}; 1296 1297 my $config_file = "$tmpdir/lang.conf"; 1298 my $pid_file = File::Spec->rel2abs("$tmpdir/lang.pid"); 1299 my $scoreboard_file = File::Spec->rel2abs("$tmpdir/lang.scoreboard"); 1300 1301 my $log_file = test_get_logfile(); 1302 1303 my $auth_user_file = File::Spec->rel2abs("$tmpdir/lang.passwd"); 1304 my $auth_group_file = File::Spec->rel2abs("$tmpdir/lang.group"); 1305 1306 my $user = 'proftpd'; 1307 my $passwd = 'test'; 1308 my $group = 'ftpd'; 1309 my $home_dir = File::Spec->rel2abs($tmpdir); 1310 my $uid = 500; 1311 my $gid = 500; 1312 1313 # Make sure that, if we're running as root, that the home directory has 1314 # permissions/privs set for the account we create 1315 if ($< == 0) { 1316 unless (chmod(0755, $home_dir)) { 1317 die("Can't set perms on $home_dir to 0755: $!"); 1318 } 1319 1320 unless (chown($uid, $gid, $home_dir)) { 1321 die("Can't set owner of $home_dir to $uid/$gid: $!"); 1322 } 1323 } 1324 1325 auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir, 1326 '/bin/bash'); 1327 auth_group_write($auth_group_file, $group, $gid, $user); 1328 1329 # Copy the en_US.mo file from the locale/ directory into a directory 1330 # that we can tell mod_lang to find. 1331 1332 my $lang_path = File::Spec->rel2abs("$tmpdir/locale"); 1333 mkpath("$lang_path/en_US/LC_MESSAGES"); 1334 1335 copy("../locale/en_US.mo", "$lang_path/en_US/LC_MESSAGES/proftpd.mo"); 1336 1337 my $config = { 1338 PidFile => $pid_file, 1339 ScoreboardFile => $scoreboard_file, 1340 SystemLog => $log_file, 1341 1342 AuthUserFile => $auth_user_file, 1343 AuthGroupFile => $auth_group_file, 1344 1345 IfModules => { 1346 'mod_delay.c' => { 1347 DelayEngine => 'off', 1348 }, 1349 1350 'mod_lang.c' => { 1351 LangPath => $lang_path, 1352 LangDefault => 'en_US.UTF-8', 1353 }, 1354 }, 1355 }; 1356 1357 my ($port, $config_user, $config_group) = config_write($config_file, $config); 1358 1359 # Open pipes, for use between the parent and child processes. Specifically, 1360 # the child will indicate when it's done with its test by writing a message 1361 # to the parent. 1362 my ($rfh, $wfh); 1363 unless (pipe($rfh, $wfh)) { 1364 die("Can't open pipe: $!"); 1365 } 1366 1367 my $ex; 1368 1369 # Fork child 1370 $self->handle_sigchld(); 1371 defined(my $pid = fork()) or die("Can't fork: $!"); 1372 if ($pid) { 1373 eval { 1374 my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port); 1375 my ($resp_code, $resp_msg) = $client->user($user); 1376 1377 my $expected; 1378 1379 $expected = 331; 1380 $self->assert($expected == $resp_code, 1381 test_msg("Expected $expected, got $resp_code")); 1382 1383 $expected = "Password required for $user"; 1384 $self->assert($expected eq $resp_msg, 1385 test_msg("Expected '$expected', got '$resp_msg'")); 1386 }; 1387 1388 if ($@) { 1389 $ex = $@; 1390 } 1391 1392 $wfh->print("done\n"); 1393 $wfh->flush(); 1394 1395 } else { 1396 eval { server_wait($config_file, $rfh) }; 1397 if ($@) { 1398 warn($@); 1399 exit 1; 1400 } 1401 1402 exit 0; 1403 } 1404 1405 # Stop server 1406 server_stop($pid_file); 1407 1408 $self->assert_child_ok($pid); 1409 1410 if ($ex) { 1411 test_append_logfile($log_file, $ex); 1412 unlink($log_file); 1413 1414 die($ex); 1415 } 1416 1417 unlink($log_file); 1418} 1419 1420sub lang_opts_utf8_useencoding_on { 1421 my $self = shift; 1422 my $tmpdir = $self->{tmpdir}; 1423 1424 my $config_file = "$tmpdir/lang.conf"; 1425 my $pid_file = File::Spec->rel2abs("$tmpdir/lang.pid"); 1426 my $scoreboard_file = File::Spec->rel2abs("$tmpdir/lang.scoreboard"); 1427 1428 my $log_file = test_get_logfile(); 1429 1430 my $auth_user_file = File::Spec->rel2abs("$tmpdir/lang.passwd"); 1431 my $auth_group_file = File::Spec->rel2abs("$tmpdir/lang.group"); 1432 1433 my $user = 'proftpd'; 1434 my $passwd = 'test'; 1435 my $group = 'ftpd'; 1436 my $home_dir = File::Spec->rel2abs($tmpdir); 1437 my $uid = 500; 1438 my $gid = 500; 1439 1440 # Make sure that, if we're running as root, that the home directory has 1441 # permissions/privs set for the account we create 1442 if ($< == 0) { 1443 unless (chmod(0755, $home_dir)) { 1444 die("Can't set perms on $home_dir to 0755: $!"); 1445 } 1446 1447 unless (chown($uid, $gid, $home_dir)) { 1448 die("Can't set owner of $home_dir to $uid/$gid: $!"); 1449 } 1450 } 1451 1452 auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir, 1453 '/bin/bash'); 1454 auth_group_write($auth_group_file, $group, $gid, $user); 1455 1456 my $config = { 1457 PidFile => $pid_file, 1458 ScoreboardFile => $scoreboard_file, 1459 SystemLog => $log_file, 1460 1461 AuthUserFile => $auth_user_file, 1462 AuthGroupFile => $auth_group_file, 1463 1464 IfModules => { 1465 'mod_delay.c' => { 1466 DelayEngine => 'off', 1467 }, 1468 1469 'mod_lang.c' => { 1470 UseEncoding => 'on', 1471 }, 1472 }, 1473 }; 1474 1475 my ($port, $config_user, $config_group) = config_write($config_file, $config); 1476 1477 # Open pipes, for use between the parent and child processes. Specifically, 1478 # the child will indicate when it's done with its test by writing a message 1479 # to the parent. 1480 my ($rfh, $wfh); 1481 unless (pipe($rfh, $wfh)) { 1482 die("Can't open pipe: $!"); 1483 } 1484 1485 my $ex; 1486 1487 # Fork child 1488 $self->handle_sigchld(); 1489 defined(my $pid = fork()) or die("Can't fork: $!"); 1490 if ($pid) { 1491 eval { 1492 my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port); 1493 1494 eval { $client->opts('UTF8', 'off') }; 1495 unless ($@) { 1496 die("OPTS UTF8 off succeeded unexpectedly"); 1497 } 1498 1499 my $resp_code = $client->response_code(); 1500 my $resp_msg = $client->response_msg(); 1501 1502 my $expected; 1503 1504 $expected = 451; 1505 $self->assert($expected == $resp_code, 1506 test_msg("Expected response code $expected, got $resp_code")); 1507 1508 $expected = 'Unable to accept OPTS UTF8'; 1509 $self->assert($expected eq $resp_msg, 1510 test_msg("Expected response message '$expected', got '$resp_msg'")); 1511 1512 ($resp_code, $resp_msg) = $client->opts('UTF8', 'on'); 1513 1514 $expected = 200; 1515 $self->assert($expected == $resp_code, 1516 test_msg("Expected response code $expected, got $resp_code")); 1517 1518 $expected = 'UTF8 set to on'; 1519 $self->assert($expected eq $resp_msg, 1520 test_msg("Expected '$expected', got '$resp_msg'")); 1521 }; 1522 1523 if ($@) { 1524 $ex = $@; 1525 } 1526 1527 $wfh->print("done\n"); 1528 $wfh->flush(); 1529 1530 } else { 1531 eval { server_wait($config_file, $rfh) }; 1532 if ($@) { 1533 warn($@); 1534 exit 1; 1535 } 1536 1537 exit 0; 1538 } 1539 1540 # Stop server 1541 server_stop($pid_file); 1542 1543 $self->assert_child_ok($pid); 1544 1545 if ($ex) { 1546 test_append_logfile($log_file, $ex); 1547 unlink($log_file); 1548 1549 die($ex); 1550 } 1551 1552 unlink($log_file); 1553} 1554 1555sub lang_opts_utf8_useencoding_off { 1556 my $self = shift; 1557 my $tmpdir = $self->{tmpdir}; 1558 1559 my $config_file = "$tmpdir/lang.conf"; 1560 my $pid_file = File::Spec->rel2abs("$tmpdir/lang.pid"); 1561 my $scoreboard_file = File::Spec->rel2abs("$tmpdir/lang.scoreboard"); 1562 1563 my $log_file = test_get_logfile(); 1564 1565 my $auth_user_file = File::Spec->rel2abs("$tmpdir/lang.passwd"); 1566 my $auth_group_file = File::Spec->rel2abs("$tmpdir/lang.group"); 1567 1568 my $user = 'proftpd'; 1569 my $passwd = 'test'; 1570 my $group = 'ftpd'; 1571 my $home_dir = File::Spec->rel2abs($tmpdir); 1572 my $uid = 500; 1573 my $gid = 500; 1574 1575 # Make sure that, if we're running as root, that the home directory has 1576 # permissions/privs set for the account we create 1577 if ($< == 0) { 1578 unless (chmod(0755, $home_dir)) { 1579 die("Can't set perms on $home_dir to 0755: $!"); 1580 } 1581 1582 unless (chown($uid, $gid, $home_dir)) { 1583 die("Can't set owner of $home_dir to $uid/$gid: $!"); 1584 } 1585 } 1586 1587 auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir, 1588 '/bin/bash'); 1589 auth_group_write($auth_group_file, $group, $gid, $user); 1590 1591 my $config = { 1592 PidFile => $pid_file, 1593 ScoreboardFile => $scoreboard_file, 1594 SystemLog => $log_file, 1595 1596 AuthUserFile => $auth_user_file, 1597 AuthGroupFile => $auth_group_file, 1598 1599 IfModules => { 1600 'mod_delay.c' => { 1601 DelayEngine => 'off', 1602 }, 1603 1604 'mod_lang.c' => { 1605 UseEncoding => 'off', 1606 }, 1607 }, 1608 }; 1609 1610 my ($port, $config_user, $config_group) = config_write($config_file, $config); 1611 1612 # Open pipes, for use between the parent and child processes. Specifically, 1613 # the child will indicate when it's done with its test by writing a message 1614 # to the parent. 1615 my ($rfh, $wfh); 1616 unless (pipe($rfh, $wfh)) { 1617 die("Can't open pipe: $!"); 1618 } 1619 1620 my $ex; 1621 1622 # Fork child 1623 $self->handle_sigchld(); 1624 defined(my $pid = fork()) or die("Can't fork: $!"); 1625 if ($pid) { 1626 eval { 1627 my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port); 1628 1629 my ($resp_code, $resp_msg); 1630 1631 ($resp_code, $resp_msg) = $client->opts('UTF8', 'off'); 1632 1633 my $expected; 1634 1635 $expected = 200; 1636 $self->assert($expected == $resp_code, 1637 test_msg("Expected $expected, got $resp_code")); 1638 1639 $expected = 'UTF8 set to off'; 1640 $self->assert($expected eq $resp_msg, 1641 test_msg("Expected '$expected', got '$resp_msg'")); 1642 1643 $expected = 200; 1644 $self->assert($expected == $resp_code, 1645 test_msg("Expected $expected, got $resp_code")); 1646 1647 eval { $client->opts('UTF8', 'on') }; 1648 unless ($@) { 1649 die("OPTS UTF8 on succeeded unexpectedly"); 1650 } 1651 1652 $resp_code = $client->response_code(); 1653 $resp_msg = $client->response_msg(); 1654 1655 $expected = 451; 1656 $self->assert($expected == $resp_code, 1657 test_msg("Expected response code $expected, got $resp_code")); 1658 1659 $expected = 'Unable to accept OPTS UTF8'; 1660 $self->assert($expected eq $resp_msg, 1661 test_msg("Expected response message '$expected', got '$resp_msg'")); 1662 }; 1663 1664 if ($@) { 1665 $ex = $@; 1666 } 1667 1668 $wfh->print("done\n"); 1669 $wfh->flush(); 1670 1671 } else { 1672 eval { server_wait($config_file, $rfh) }; 1673 if ($@) { 1674 warn($@); 1675 exit 1; 1676 } 1677 1678 exit 0; 1679 } 1680 1681 # Stop server 1682 server_stop($pid_file); 1683 1684 $self->assert_child_ok($pid); 1685 1686 if ($ex) { 1687 test_append_logfile($log_file, $ex); 1688 unlink($log_file); 1689 1690 die($ex); 1691 } 1692 1693 unlink($log_file); 1694} 1695 1696sub lang_opts_utf8_useencoding_charsets { 1697 my $self = shift; 1698 my $tmpdir = $self->{tmpdir}; 1699 1700 my $config_file = "$tmpdir/lang.conf"; 1701 my $pid_file = File::Spec->rel2abs("$tmpdir/lang.pid"); 1702 my $scoreboard_file = File::Spec->rel2abs("$tmpdir/lang.scoreboard"); 1703 1704 my $log_file = test_get_logfile(); 1705 1706 my $auth_user_file = File::Spec->rel2abs("$tmpdir/lang.passwd"); 1707 my $auth_group_file = File::Spec->rel2abs("$tmpdir/lang.group"); 1708 1709 my $user = 'proftpd'; 1710 my $passwd = 'test'; 1711 my $group = 'ftpd'; 1712 my $home_dir = File::Spec->rel2abs($tmpdir); 1713 my $uid = 500; 1714 my $gid = 500; 1715 1716 # Make sure that, if we're running as root, that the home directory has 1717 # permissions/privs set for the account we create 1718 if ($< == 0) { 1719 unless (chmod(0755, $home_dir)) { 1720 die("Can't set perms on $home_dir to 0755: $!"); 1721 } 1722 1723 unless (chown($uid, $gid, $home_dir)) { 1724 die("Can't set owner of $home_dir to $uid/$gid: $!"); 1725 } 1726 } 1727 1728 auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir, 1729 '/bin/bash'); 1730 auth_group_write($auth_group_file, $group, $gid, $user); 1731 1732 my $config = { 1733 PidFile => $pid_file, 1734 ScoreboardFile => $scoreboard_file, 1735 SystemLog => $log_file, 1736 TraceLog => $log_file, 1737 Trace => 'encode:10', 1738 1739 AuthUserFile => $auth_user_file, 1740 AuthGroupFile => $auth_group_file, 1741 1742 IfModules => { 1743 'mod_delay.c' => { 1744 DelayEngine => 'off', 1745 }, 1746 1747 'mod_lang.c' => { 1748 UseEncoding => 'iso-8859-1 iso-8859-1', 1749 }, 1750 }, 1751 }; 1752 1753 my ($port, $config_user, $config_group) = config_write($config_file, $config); 1754 1755 # Open pipes, for use between the parent and child processes. Specifically, 1756 # the child will indicate when it's done with its test by writing a message 1757 # to the parent. 1758 my ($rfh, $wfh); 1759 unless (pipe($rfh, $wfh)) { 1760 die("Can't open pipe: $!"); 1761 } 1762 1763 my $ex; 1764 1765 # Fork child 1766 $self->handle_sigchld(); 1767 defined(my $pid = fork()) or die("Can't fork: $!"); 1768 if ($pid) { 1769 eval { 1770 my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port); 1771 my ($resp_code, $resp_msg) = $client->opts('UTF8', 'off'); 1772 1773 my $expected; 1774 1775 $expected = 200; 1776 $self->assert($expected == $resp_code, 1777 test_msg("Expected response code $expected, got $resp_code")); 1778 1779 $expected = 'UTF8 set to off'; 1780 $self->assert($expected eq $resp_msg, 1781 test_msg("Expected response message '$expected', got '$resp_msg'")); 1782 1783 ($resp_code, $resp_msg) = $client->opts('UTF8', 'on'); 1784 1785 $expected = 200; 1786 $self->assert($expected == $resp_code, 1787 test_msg("Expected response code $expected, got $resp_code")); 1788 1789 $expected = 'UTF8 set to on'; 1790 $self->assert($expected eq $resp_msg, 1791 test_msg("Expected response message '$expected', got '$resp_msg'")); 1792 }; 1793 1794 if ($@) { 1795 $ex = $@; 1796 } 1797 1798 $wfh->print("done\n"); 1799 $wfh->flush(); 1800 1801 } else { 1802 eval { server_wait($config_file, $rfh) }; 1803 if ($@) { 1804 warn($@); 1805 exit 1; 1806 } 1807 1808 exit 0; 1809 } 1810 1811 # Stop server 1812 server_stop($pid_file); 1813 1814 $self->assert_child_ok($pid); 1815 1816 if ($ex) { 1817 test_append_logfile($log_file, $ex); 1818 unlink($log_file); 1819 1820 die($ex); 1821 } 1822 1823 unlink($log_file); 1824} 1825 1826sub lang_opts_utf8_useencoding_charsets_strict { 1827 my $self = shift; 1828 my $tmpdir = $self->{tmpdir}; 1829 1830 my $config_file = "$tmpdir/lang.conf"; 1831 my $pid_file = File::Spec->rel2abs("$tmpdir/lang.pid"); 1832 my $scoreboard_file = File::Spec->rel2abs("$tmpdir/lang.scoreboard"); 1833 1834 my $log_file = test_get_logfile(); 1835 1836 my $auth_user_file = File::Spec->rel2abs("$tmpdir/lang.passwd"); 1837 my $auth_group_file = File::Spec->rel2abs("$tmpdir/lang.group"); 1838 1839 my $user = 'proftpd'; 1840 my $passwd = 'test'; 1841 my $group = 'ftpd'; 1842 my $home_dir = File::Spec->rel2abs($tmpdir); 1843 my $uid = 500; 1844 my $gid = 500; 1845 1846 # Make sure that, if we're running as root, that the home directory has 1847 # permissions/privs set for the account we create 1848 if ($< == 0) { 1849 unless (chmod(0755, $home_dir)) { 1850 die("Can't set perms on $home_dir to 0755: $!"); 1851 } 1852 1853 unless (chown($uid, $gid, $home_dir)) { 1854 die("Can't set owner of $home_dir to $uid/$gid: $!"); 1855 } 1856 } 1857 1858 auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir, 1859 '/bin/bash'); 1860 auth_group_write($auth_group_file, $group, $gid, $user); 1861 1862 my $config = { 1863 PidFile => $pid_file, 1864 ScoreboardFile => $scoreboard_file, 1865 SystemLog => $log_file, 1866 TraceLog => $log_file, 1867 Trace => 'encode:10', 1868 1869 AuthUserFile => $auth_user_file, 1870 AuthGroupFile => $auth_group_file, 1871 1872 IfModules => { 1873 'mod_delay.c' => { 1874 DelayEngine => 'off', 1875 }, 1876 1877 'mod_lang.c' => { 1878 UseEncoding => 'iso-8859-1 iso-8859-1 strict', 1879 }, 1880 }, 1881 }; 1882 1883 my ($port, $config_user, $config_group) = config_write($config_file, $config); 1884 1885 # Open pipes, for use between the parent and child processes. Specifically, 1886 # the child will indicate when it's done with its test by writing a message 1887 # to the parent. 1888 my ($rfh, $wfh); 1889 unless (pipe($rfh, $wfh)) { 1890 die("Can't open pipe: $!"); 1891 } 1892 1893 my $ex; 1894 1895 # Fork child 1896 $self->handle_sigchld(); 1897 defined(my $pid = fork()) or die("Can't fork: $!"); 1898 if ($pid) { 1899 eval { 1900 my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port); 1901 1902 # Make sure the OPTS UTF8 command does not appear in the FEAT listing; 1903 # see Bug#3737. 1904 $client->feat(); 1905 my $resp_code = $client->response_code(); 1906 my $resp_msgs = $client->response_msgs(); 1907 1908 my $expected; 1909 1910 $expected = 211; 1911 $self->assert($expected == $resp_code, 1912 test_msg("Expected response code $expected, got $resp_code")); 1913 1914 foreach my $feat (@$resp_msgs) { 1915 if ($feat =~ /^ UTF8$/) { 1916 die("'$feat' feature listed unexpectedly via FEAT"); 1917 } 1918 } 1919 1920 my $resp_msg; 1921 ($resp_code, $resp_msg) = $client->opts('UTF8', 'off'); 1922 1923 $expected = 200; 1924 $self->assert($expected == $resp_code, 1925 test_msg("Expected response code $expected, got $resp_code")); 1926 1927 $expected = 'UTF8 set to off'; 1928 $self->assert($expected eq $resp_msg, 1929 test_msg("Expected response message '$expected', got '$resp_msg'")); 1930 1931 eval { $client->opts('UTF8', 'on') }; 1932 unless ($@) { 1933 die("OPTS UTF8 on succeeded unexpectedly"); 1934 } 1935 1936 $resp_code = $client->response_code(); 1937 $resp_msg = $client->response_msg(); 1938 1939 $expected = 451; 1940 $self->assert($expected == $resp_code, 1941 test_msg("Expected response code $expected, got $resp_code")); 1942 1943 $expected = 'Unable to accept OPTS UTF8'; 1944 $self->assert($expected eq $resp_msg, 1945 test_msg("Expected response message '$expected', got '$resp_msg'")); 1946 }; 1947 1948 if ($@) { 1949 $ex = $@; 1950 } 1951 1952 $wfh->print("done\n"); 1953 $wfh->flush(); 1954 1955 } else { 1956 eval { server_wait($config_file, $rfh) }; 1957 if ($@) { 1958 warn($@); 1959 exit 1; 1960 } 1961 1962 exit 0; 1963 } 1964 1965 # Stop server 1966 server_stop($pid_file); 1967 1968 $self->assert_child_ok($pid); 1969 1970 if ($ex) { 1971 test_append_logfile($log_file, $ex); 1972 unlink($log_file); 1973 1974 die($ex); 1975 } 1976 1977 unlink($log_file); 1978} 1979 1980sub lang_opts_utf8_useencoding_charsets_strict_with_utf8 { 1981 my $self = shift; 1982 my $tmpdir = $self->{tmpdir}; 1983 1984 my $config_file = "$tmpdir/lang.conf"; 1985 my $pid_file = File::Spec->rel2abs("$tmpdir/lang.pid"); 1986 my $scoreboard_file = File::Spec->rel2abs("$tmpdir/lang.scoreboard"); 1987 1988 my $log_file = test_get_logfile(); 1989 1990 my $auth_user_file = File::Spec->rel2abs("$tmpdir/lang.passwd"); 1991 my $auth_group_file = File::Spec->rel2abs("$tmpdir/lang.group"); 1992 1993 my $user = 'proftpd'; 1994 my $passwd = 'test'; 1995 my $group = 'ftpd'; 1996 my $home_dir = File::Spec->rel2abs($tmpdir); 1997 my $uid = 500; 1998 my $gid = 500; 1999 2000 # Make sure that, if we're running as root, that the home directory has 2001 # permissions/privs set for the account we create 2002 if ($< == 0) { 2003 unless (chmod(0755, $home_dir)) { 2004 die("Can't set perms on $home_dir to 0755: $!"); 2005 } 2006 2007 unless (chown($uid, $gid, $home_dir)) { 2008 die("Can't set owner of $home_dir to $uid/$gid: $!"); 2009 } 2010 } 2011 2012 auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir, 2013 '/bin/bash'); 2014 auth_group_write($auth_group_file, $group, $gid, $user); 2015 2016 my $config = { 2017 PidFile => $pid_file, 2018 ScoreboardFile => $scoreboard_file, 2019 SystemLog => $log_file, 2020 TraceLog => $log_file, 2021 Trace => 'encode:10', 2022 2023 AuthUserFile => $auth_user_file, 2024 AuthGroupFile => $auth_group_file, 2025 2026 IfModules => { 2027 'mod_delay.c' => { 2028 DelayEngine => 'off', 2029 }, 2030 2031 'mod_lang.c' => { 2032 UseEncoding => 'iso-8859-1 utf-8 strict', 2033 }, 2034 }, 2035 }; 2036 2037 my ($port, $config_user, $config_group) = config_write($config_file, $config); 2038 2039 # Open pipes, for use between the parent and child processes. Specifically, 2040 # the child will indicate when it's done with its test by writing a message 2041 # to the parent. 2042 my ($rfh, $wfh); 2043 unless (pipe($rfh, $wfh)) { 2044 die("Can't open pipe: $!"); 2045 } 2046 2047 my $ex; 2048 2049 # Fork child 2050 $self->handle_sigchld(); 2051 defined(my $pid = fork()) or die("Can't fork: $!"); 2052 if ($pid) { 2053 eval { 2054 my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port); 2055 2056 # Make sure the OPTS UTF8 command does not appear in the FEAT listing; 2057 # see Bug#3737. 2058 $client->feat(); 2059 my $resp_code = $client->response_code(); 2060 my $resp_msgs = $client->response_msgs(); 2061 2062 my $expected; 2063 2064 $expected = 211; 2065 $self->assert($expected == $resp_code, 2066 test_msg("Expected response code $expected, got $resp_code")); 2067 2068 # Since our strict UseEncoding expects UTF8, we should see UTF8 2069 # listed in the FEAT output (see Bug#3737). 2070 my $have_utf8 = 0; 2071 foreach my $feat (@$resp_msgs) { 2072 if ($feat =~ /^ UTF8$/) { 2073 $have_utf8 = 1; 2074 last; 2075 } 2076 } 2077 2078 $self->assert($have_utf8, 2079 test_msg("UTF8 feature not listed as expected via FEAT")); 2080 2081 eval { $client->opts('UTF8', 'off') }; 2082 unless ($@) { 2083 die("OPTS UTF8 off succeeded unexpectedly"); 2084 } 2085 2086 $resp_code = $client->response_code(); 2087 my $resp_msg = $client->response_msg(); 2088 2089 $expected = 451; 2090 $self->assert($expected == $resp_code, 2091 test_msg("Expected response code $expected, got $resp_code")); 2092 2093 $expected = 'Unable to accept OPTS UTF8'; 2094 $self->assert($expected eq $resp_msg, 2095 test_msg("Expected response message '$expected', got '$resp_msg'")); 2096 2097 ($resp_code, $resp_msg) = $client->opts('UTF8', 'on'); 2098 2099 $expected = 200; 2100 $self->assert($expected == $resp_code, 2101 test_msg("Expected response code $expected, got $resp_code")); 2102 2103 $expected = 'UTF8 set to on'; 2104 $self->assert($expected eq $resp_msg, 2105 test_msg("Expected response message '$expected', got '$resp_msg'")); 2106 }; 2107 2108 if ($@) { 2109 $ex = $@; 2110 } 2111 2112 $wfh->print("done\n"); 2113 $wfh->flush(); 2114 2115 } else { 2116 eval { server_wait($config_file, $rfh) }; 2117 if ($@) { 2118 warn($@); 2119 exit 1; 2120 } 2121 2122 exit 0; 2123 } 2124 2125 # Stop server 2126 server_stop($pid_file); 2127 2128 $self->assert_child_ok($pid); 2129 2130 if ($ex) { 2131 test_append_logfile($log_file, $ex); 2132 unlink($log_file); 2133 2134 die($ex); 2135 } 2136 2137 unlink($log_file); 2138} 2139 2140sub lang_opts_utf8_useencoding_charsets_with_env { 2141 my $self = shift; 2142 my $tmpdir = $self->{tmpdir}; 2143 2144 my $config_file = "$tmpdir/lang.conf"; 2145 my $pid_file = File::Spec->rel2abs("$tmpdir/lang.pid"); 2146 my $scoreboard_file = File::Spec->rel2abs("$tmpdir/lang.scoreboard"); 2147 2148 my $log_file = test_get_logfile(); 2149 2150 my $auth_user_file = File::Spec->rel2abs("$tmpdir/lang.passwd"); 2151 my $auth_group_file = File::Spec->rel2abs("$tmpdir/lang.group"); 2152 2153 my $user = 'proftpd'; 2154 my $passwd = 'test'; 2155 my $group = 'ftpd'; 2156 my $home_dir = File::Spec->rel2abs($tmpdir); 2157 my $uid = 500; 2158 my $gid = 500; 2159 2160 # Make sure that, if we're running as root, that the home directory has 2161 # permissions/privs set for the account we create 2162 if ($< == 0) { 2163 unless (chmod(0755, $home_dir)) { 2164 die("Can't set perms on $home_dir to 0755: $!"); 2165 } 2166 2167 unless (chown($uid, $gid, $home_dir)) { 2168 die("Can't set owner of $home_dir to $uid/$gid: $!"); 2169 } 2170 } 2171 2172 auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir, 2173 '/bin/bash'); 2174 auth_group_write($auth_group_file, $group, $gid, $user); 2175 2176 # Copy the en_US.mo file from the locale/ directory into a directory 2177 # that we can tell mod_lang to find. 2178 2179 my $lang_path = File::Spec->rel2abs("$tmpdir/locale"); 2180 mkpath("$lang_path/en_US/LC_MESSAGES"); 2181 2182 copy("../locale/en_US.mo", "$lang_path/en_US/LC_MESSAGES/proftpd.mo"); 2183 2184 my $config = { 2185 PidFile => $pid_file, 2186 ScoreboardFile => $scoreboard_file, 2187 SystemLog => $log_file, 2188 TraceLog => $log_file, 2189 Trace => 'encode:10', 2190 2191 AuthUserFile => $auth_user_file, 2192 AuthGroupFile => $auth_group_file, 2193 2194 IfModules => { 2195 'mod_delay.c' => { 2196 DelayEngine => 'off', 2197 }, 2198 2199 'mod_lang.c' => { 2200 UseEncoding => 'iso-8859-1 iso-8859-1', 2201 }, 2202 }, 2203 }; 2204 2205 my ($port, $config_user, $config_group) = config_write($config_file, $config); 2206 2207 # Open pipes, for use between the parent and child processes. Specifically, 2208 # the child will indicate when it's done with its test by writing a message 2209 # to the parent. 2210 my ($rfh, $wfh); 2211 unless (pipe($rfh, $wfh)) { 2212 die("Can't open pipe: $!"); 2213 } 2214 2215 my $ex; 2216 2217 # Fork child 2218 $self->handle_sigchld(); 2219 defined(my $pid = fork()) or die("Can't fork: $!"); 2220 if ($pid) { 2221 eval { 2222 my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port); 2223 my ($resp_code, $resp_msg) = $client->opts('UTF8', 'on'); 2224 2225 my $expected; 2226 2227 $expected = 200; 2228 $self->assert($expected == $resp_code, 2229 test_msg("Expected response code $expected, got $resp_code")); 2230 2231 $expected = 'UTF8 set to on'; 2232 $self->assert($expected eq $resp_msg, 2233 test_msg("Expected response message '$expected', got '$resp_msg'")); 2234 2235 ($resp_code, $resp_msg) = $client->opts('UTF8', 'on'); 2236 2237 $expected = 200; 2238 $self->assert($expected == $resp_code, 2239 test_msg("Expected response code $expected, got $resp_code")); 2240 2241 $expected = 'UTF8 set to on'; 2242 $self->assert($expected eq $resp_msg, 2243 test_msg("Expected response message '$expected', got '$resp_msg'")); 2244 }; 2245 2246 if ($@) { 2247 $ex = $@; 2248 } 2249 2250 $wfh->print("done\n"); 2251 $wfh->flush(); 2252 2253 } else { 2254 # Before we start the server, set the LANG environment variable to 2255 # something like "en_US.utf8", see what happens. 2256 # 2257 # Note: The list of allowed values here should be dynamically determined 2258 # by calling `locale -a'. 2259 $ENV{LANG} = "en_US.utf8"; 2260 2261 eval { server_wait($config_file, $rfh) }; 2262 if ($@) { 2263 warn($@); 2264 exit 1; 2265 } 2266 2267 exit 0; 2268 } 2269 2270 # Stop server 2271 server_stop($pid_file); 2272 2273 $self->assert_child_ok($pid); 2274 2275 if ($ex) { 2276 test_append_logfile($log_file, $ex); 2277 unlink($log_file); 2278 2279 die($ex); 2280 } 2281 2282 unlink($log_file); 2283} 2284 2285sub lang_useencoding_latin1_utf8 { 2286 my $self = shift; 2287 my $tmpdir = $self->{tmpdir}; 2288 2289 my $config_file = "$tmpdir/lang.conf"; 2290 my $pid_file = File::Spec->rel2abs("$tmpdir/lang.pid"); 2291 my $scoreboard_file = File::Spec->rel2abs("$tmpdir/lang.scoreboard"); 2292 2293 my $log_file = test_get_logfile(); 2294 2295 my $auth_user_file = File::Spec->rel2abs("$tmpdir/lang.passwd"); 2296 my $auth_group_file = File::Spec->rel2abs("$tmpdir/lang.group"); 2297 2298 my $user = 'proftpd'; 2299 my $passwd = 'test'; 2300 my $group = 'ftpd'; 2301 my $home_dir = File::Spec->rel2abs($tmpdir); 2302 my $uid = 500; 2303 my $gid = 500; 2304 2305 # Make sure that, if we're running as root, that the home directory has 2306 # permissions/privs set for the account we create 2307 if ($< == 0) { 2308 unless (chmod(0755, $home_dir)) { 2309 die("Can't set perms on $home_dir to 0755: $!"); 2310 } 2311 2312 unless (chown($uid, $gid, $home_dir)) { 2313 die("Can't set owner of $home_dir to $uid/$gid: $!"); 2314 } 2315 } 2316 2317 auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir, 2318 '/bin/bash'); 2319 auth_group_write($auth_group_file, $group, $gid, $user); 2320 2321 my $test_file = File::Spec->rel2abs("$home_dir/üöä"); 2322 2323 my $config = { 2324 PidFile => $pid_file, 2325 ScoreboardFile => $scoreboard_file, 2326 SystemLog => $log_file, 2327 TraceLog => $log_file, 2328 Trace => 'encode:20', 2329 2330 AuthUserFile => $auth_user_file, 2331 AuthGroupFile => $auth_group_file, 2332 2333 IfModules => { 2334 'mod_delay.c' => { 2335 DelayEngine => 'off', 2336 }, 2337 2338 'mod_lang.c' => { 2339 UseEncoding => 'utf-8 iso-8859-1', 2340 }, 2341 }, 2342 }; 2343 2344 my ($port, $config_user, $config_group) = config_write($config_file, $config); 2345 2346 # Open pipes, for use between the parent and child processes. Specifically, 2347 # the child will indicate when it's done with its test by writing a message 2348 # to the parent. 2349 my ($rfh, $wfh); 2350 unless (pipe($rfh, $wfh)) { 2351 die("Can't open pipe: $!"); 2352 } 2353 2354 my $ex; 2355 2356 # Fork child 2357 $self->handle_sigchld(); 2358 defined(my $pid = fork()) or die("Can't fork: $!"); 2359 if ($pid) { 2360 eval { 2361 my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port); 2362 $client->login($user, $passwd); 2363 2364 my $name = "üöä"; 2365 2366 my $conn = $client->stor_raw($name); 2367 unless ($conn) { 2368 die("STOR $name failed: " . $client->response_code() . " " . 2369 $client->response_msg()); 2370 } 2371 2372 my $buf = "Hello, world\n"; 2373 $conn->write($buf, length($buf), 15); 2374 eval { $conn->close() }; 2375 2376 my $resp_code = $client->response_code(); 2377 my $resp_msg = $client->response_msg(); 2378 $self->assert_transfer_ok($resp_code, $resp_msg); 2379 2380 $client->quit(); 2381 2382 $self->assert(-f $test_file, 2383 test_msg("File $test_file does not exist as expected")); 2384 }; 2385 2386 if ($@) { 2387 $ex = $@; 2388 } 2389 2390 $wfh->print("done\n"); 2391 $wfh->flush(); 2392 2393 } else { 2394 eval { server_wait($config_file, $rfh) }; 2395 if ($@) { 2396 warn($@); 2397 exit 1; 2398 } 2399 2400 exit 0; 2401 } 2402 2403 # Stop server 2404 server_stop($pid_file); 2405 2406 $self->assert_child_ok($pid); 2407 2408 if ($ex) { 2409 test_append_logfile($log_file, $ex); 2410 unlink($log_file); 2411 2412 die($ex); 2413 } 2414 2415 unlink($log_file); 2416} 2417 2418sub lang_useencoding_utf8_latin1 { 2419 my $self = shift; 2420 my $tmpdir = $self->{tmpdir}; 2421 2422 my $config_file = "$tmpdir/lang.conf"; 2423 my $pid_file = File::Spec->rel2abs("$tmpdir/lang.pid"); 2424 my $scoreboard_file = File::Spec->rel2abs("$tmpdir/lang.scoreboard"); 2425 2426 my $log_file = test_get_logfile(); 2427 2428 my $auth_user_file = File::Spec->rel2abs("$tmpdir/lang.passwd"); 2429 my $auth_group_file = File::Spec->rel2abs("$tmpdir/lang.group"); 2430 2431 my $user = 'proftpd'; 2432 my $passwd = 'test'; 2433 my $group = 'ftpd'; 2434 my $home_dir = File::Spec->rel2abs($tmpdir); 2435 my $uid = 500; 2436 my $gid = 500; 2437 2438 # Make sure that, if we're running as root, that the home directory has 2439 # permissions/privs set for the account we create 2440 if ($< == 0) { 2441 unless (chmod(0755, $home_dir)) { 2442 die("Can't set perms on $home_dir to 0755: $!"); 2443 } 2444 2445 unless (chown($uid, $gid, $home_dir)) { 2446 die("Can't set owner of $home_dir to $uid/$gid: $!"); 2447 } 2448 } 2449 2450 auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir, 2451 '/bin/bash'); 2452 auth_group_write($auth_group_file, $group, $gid, $user); 2453 2454 my $test_file = File::Spec->rel2abs("$home_dir/Grafik-Zentrumäüu.png"); 2455 if ($^O eq 'darwin') { 2456 # MacOSX hack 2457 $test_file = ('/private' . $test_file); 2458 } 2459 2460 my $config = { 2461 PidFile => $pid_file, 2462 ScoreboardFile => $scoreboard_file, 2463 SystemLog => $log_file, 2464 TraceLog => $log_file, 2465 Trace => 'encode:20', 2466 2467 AuthUserFile => $auth_user_file, 2468 AuthGroupFile => $auth_group_file, 2469 2470 IfModules => { 2471 'mod_delay.c' => { 2472 DelayEngine => 'off', 2473 }, 2474 2475 'mod_lang.c' => { 2476 UseEncoding => 'utf-8 iso-8859-1', 2477 }, 2478 }, 2479 }; 2480 2481 my ($port, $config_user, $config_group) = config_write($config_file, $config); 2482 2483 # Open pipes, for use between the parent and child processes. Specifically, 2484 # the child will indicate when it's done with its test by writing a message 2485 # to the parent. 2486 my ($rfh, $wfh); 2487 unless (pipe($rfh, $wfh)) { 2488 die("Can't open pipe: $!"); 2489 } 2490 2491 my $ex; 2492 2493 # Fork child 2494 $self->handle_sigchld(); 2495 defined(my $pid = fork()) or die("Can't fork: $!"); 2496 if ($pid) { 2497 eval { 2498 my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port); 2499 $client->login($user, $passwd); 2500 2501 my $name = "Grafik-Zentrumäüu.png"; 2502 2503 my $conn = $client->stor_raw($name); 2504 unless ($conn) { 2505 die("STOR $name failed: " . $client->response_code() . " " . 2506 $client->response_msg()); 2507 } 2508 2509 my $buf = "Hello, world\n"; 2510 $conn->write($buf, length($buf), 15); 2511 eval { $conn->close() }; 2512 2513 my $resp_code = $client->response_code(); 2514 my $resp_msg = $client->response_msg(); 2515 $self->assert_transfer_ok($resp_code, $resp_msg); 2516 2517 $client->quit(); 2518 2519 $self->assert(-f $test_file, 2520 test_msg("File $test_file does not exist as expected")); 2521 }; 2522 2523 if ($@) { 2524 $ex = $@; 2525 } 2526 2527 $wfh->print("done\n"); 2528 $wfh->flush(); 2529 2530 } else { 2531 eval { server_wait($config_file, $rfh) }; 2532 if ($@) { 2533 warn($@); 2534 exit 1; 2535 } 2536 2537 exit 0; 2538 } 2539 2540 # Stop server 2541 server_stop($pid_file); 2542 2543 $self->assert_child_ok($pid); 2544 2545 if ($ex) { 2546 test_append_logfile($log_file, $ex); 2547 unlink($log_file); 2548 2549 die($ex); 2550 } 2551 2552 unlink($log_file); 2553} 2554 2555sub lang_opts_utf8_prefer_server_encoding_bug4125 { 2556 my $self = shift; 2557 my $tmpdir = $self->{tmpdir}; 2558 2559 my $config_file = "$tmpdir/lang.conf"; 2560 my $pid_file = File::Spec->rel2abs("$tmpdir/lang.pid"); 2561 my $scoreboard_file = File::Spec->rel2abs("$tmpdir/lang.scoreboard"); 2562 2563 my $log_file = test_get_logfile(); 2564 2565 my $auth_user_file = File::Spec->rel2abs("$tmpdir/lang.passwd"); 2566 my $auth_group_file = File::Spec->rel2abs("$tmpdir/lang.group"); 2567 2568 my $user = 'proftpd'; 2569 my $passwd = 'test'; 2570 my $group = 'ftpd'; 2571 my $home_dir = File::Spec->rel2abs($tmpdir); 2572 my $uid = 500; 2573 my $gid = 500; 2574 2575 # Make sure that, if we're running as root, that the home directory has 2576 # permissions/privs set for the account we create 2577 if ($< == 0) { 2578 unless (chmod(0755, $home_dir)) { 2579 die("Can't set perms on $home_dir to 0755: $!"); 2580 } 2581 2582 unless (chown($uid, $gid, $home_dir)) { 2583 die("Can't set owner of $home_dir to $uid/$gid: $!"); 2584 } 2585 } 2586 2587 auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir, 2588 '/bin/bash'); 2589 auth_group_write($auth_group_file, $group, $gid, $user); 2590 2591 my $config = { 2592 PidFile => $pid_file, 2593 ScoreboardFile => $scoreboard_file, 2594 SystemLog => $log_file, 2595 TraceLog => $log_file, 2596 Trace => 'encode:10', 2597 2598 AuthUserFile => $auth_user_file, 2599 AuthGroupFile => $auth_group_file, 2600 2601 IfModules => { 2602 'mod_delay.c' => { 2603 DelayEngine => 'off', 2604 }, 2605 2606 'mod_lang.c' => { 2607 LangOptions => 'PreferServerEncoding', 2608 UseEncoding => 'iso-8859-1 iso-8859-1', 2609 }, 2610 }, 2611 }; 2612 2613 my ($port, $config_user, $config_group) = config_write($config_file, $config); 2614 2615 # Open pipes, for use between the parent and child processes. Specifically, 2616 # the child will indicate when it's done with its test by writing a message 2617 # to the parent. 2618 my ($rfh, $wfh); 2619 unless (pipe($rfh, $wfh)) { 2620 die("Can't open pipe: $!"); 2621 } 2622 2623 my $ex; 2624 2625 # Fork child 2626 $self->handle_sigchld(); 2627 defined(my $pid = fork()) or die("Can't fork: $!"); 2628 if ($pid) { 2629 eval { 2630 my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port); 2631 2632 # Make sure the OPTS UTF8 command does not appear in the FEAT listing; 2633 # see Bug#3737. 2634 $client->feat(); 2635 my $resp_code = $client->response_code(); 2636 my $resp_msgs = $client->response_msgs(); 2637 2638 my $expected; 2639 2640 $expected = 211; 2641 $self->assert($expected == $resp_code, 2642 test_msg("Expected response code $expected, got $resp_code")); 2643 2644 foreach my $feat (@$resp_msgs) { 2645 if ($feat =~ /^ UTF8$/) { 2646 die("'$feat' feature listed unexpectedly via FEAT"); 2647 } 2648 } 2649 2650 my $resp_msg; 2651 ($resp_code, $resp_msg) = $client->opts('UTF8', 'off'); 2652 2653 $expected = 200; 2654 $self->assert($expected == $resp_code, 2655 test_msg("Expected response code $expected, got $resp_code")); 2656 2657 $expected = 'UTF8 set to off'; 2658 $self->assert($expected eq $resp_msg, 2659 test_msg("Expected response message '$expected', got '$resp_msg'")); 2660 2661 eval { $client->opts('UTF8', 'on') }; 2662 unless ($@) { 2663 die("OPTS UTF8 on succeeded unexpectedly"); 2664 } 2665 2666 $resp_code = $client->response_code(); 2667 $resp_msg = $client->response_msg(); 2668 2669 $expected = 451; 2670 $self->assert($expected == $resp_code, 2671 test_msg("Expected response code $expected, got $resp_code")); 2672 2673 $expected = 'Unable to accept OPTS UTF8'; 2674 $self->assert($expected eq $resp_msg, 2675 test_msg("Expected response message '$expected', got '$resp_msg'")); 2676 }; 2677 2678 if ($@) { 2679 $ex = $@; 2680 } 2681 2682 $wfh->print("done\n"); 2683 $wfh->flush(); 2684 2685 } else { 2686 eval { server_wait($config_file, $rfh) }; 2687 if ($@) { 2688 warn($@); 2689 exit 1; 2690 } 2691 2692 exit 0; 2693 } 2694 2695 # Stop server 2696 server_stop($pid_file); 2697 2698 $self->assert_child_ok($pid); 2699 2700 if ($ex) { 2701 test_append_logfile($log_file, $ex); 2702 unlink($log_file); 2703 2704 die($ex); 2705 } 2706 2707 unlink($log_file); 2708} 2709 2710sub lang_opts_utf8_useencoding_charsets_prefer_server_encoding_bug4125 { 2711 my $self = shift; 2712 my $tmpdir = $self->{tmpdir}; 2713 2714 my $config_file = "$tmpdir/lang.conf"; 2715 my $pid_file = File::Spec->rel2abs("$tmpdir/lang.pid"); 2716 my $scoreboard_file = File::Spec->rel2abs("$tmpdir/lang.scoreboard"); 2717 2718 my $log_file = test_get_logfile(); 2719 2720 my $auth_user_file = File::Spec->rel2abs("$tmpdir/lang.passwd"); 2721 my $auth_group_file = File::Spec->rel2abs("$tmpdir/lang.group"); 2722 2723 my $user = 'proftpd'; 2724 my $passwd = 'test'; 2725 my $group = 'ftpd'; 2726 my $home_dir = File::Spec->rel2abs($tmpdir); 2727 my $uid = 500; 2728 my $gid = 500; 2729 2730 # Make sure that, if we're running as root, that the home directory has 2731 # permissions/privs set for the account we create 2732 if ($< == 0) { 2733 unless (chmod(0755, $home_dir)) { 2734 die("Can't set perms on $home_dir to 0755: $!"); 2735 } 2736 2737 unless (chown($uid, $gid, $home_dir)) { 2738 die("Can't set owner of $home_dir to $uid/$gid: $!"); 2739 } 2740 } 2741 2742 auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir, 2743 '/bin/bash'); 2744 auth_group_write($auth_group_file, $group, $gid, $user); 2745 2746 my $config = { 2747 PidFile => $pid_file, 2748 ScoreboardFile => $scoreboard_file, 2749 SystemLog => $log_file, 2750 TraceLog => $log_file, 2751 Trace => 'encode:10', 2752 2753 AuthUserFile => $auth_user_file, 2754 AuthGroupFile => $auth_group_file, 2755 2756 IfModules => { 2757 'mod_delay.c' => { 2758 DelayEngine => 'off', 2759 }, 2760 2761 'mod_lang.c' => { 2762 LangOptions => 'PreferServerEncoding', 2763 UseEncoding => 'iso-8859-1 utf-8', 2764 }, 2765 }, 2766 }; 2767 2768 my ($port, $config_user, $config_group) = config_write($config_file, $config); 2769 2770 # Open pipes, for use between the parent and child processes. Specifically, 2771 # the child will indicate when it's done with its test by writing a message 2772 # to the parent. 2773 my ($rfh, $wfh); 2774 unless (pipe($rfh, $wfh)) { 2775 die("Can't open pipe: $!"); 2776 } 2777 2778 my $ex; 2779 2780 # Fork child 2781 $self->handle_sigchld(); 2782 defined(my $pid = fork()) or die("Can't fork: $!"); 2783 if ($pid) { 2784 eval { 2785 my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port); 2786 2787 # Make sure the OPTS UTF8 command does not appear in the FEAT listing; 2788 # see Bug#3737. 2789 $client->feat(); 2790 my $resp_code = $client->response_code(); 2791 my $resp_msgs = $client->response_msgs(); 2792 2793 my $expected; 2794 2795 $expected = 211; 2796 $self->assert($expected == $resp_code, 2797 test_msg("Expected response code $expected, got $resp_code")); 2798 2799 # Since our strict UseEncoding expects UTF8, we should see UTF8 2800 # listed in the FEAT output (see Bug#3737). 2801 my $have_utf8 = 0; 2802 foreach my $feat (@$resp_msgs) { 2803 if ($feat =~ /^ UTF8$/) { 2804 $have_utf8 = 1; 2805 last; 2806 } 2807 } 2808 2809 $self->assert($have_utf8, 2810 test_msg("UTF8 feature not listed as expected via FEAT")); 2811 2812 eval { $client->opts('UTF8', 'off') }; 2813 unless ($@) { 2814 die("OPTS UTF8 off succeeded unexpectedly"); 2815 } 2816 2817 $resp_code = $client->response_code(); 2818 my $resp_msg = $client->response_msg(); 2819 2820 $expected = 451; 2821 $self->assert($expected == $resp_code, 2822 test_msg("Expected response code $expected, got $resp_code")); 2823 2824 $expected = 'Unable to accept OPTS UTF8'; 2825 $self->assert($expected eq $resp_msg, 2826 test_msg("Expected response message '$expected', got '$resp_msg'")); 2827 2828 ($resp_code, $resp_msg) = $client->opts('UTF8', 'on'); 2829 2830 $expected = 200; 2831 $self->assert($expected == $resp_code, 2832 test_msg("Expected response code $expected, got $resp_code")); 2833 2834 $expected = 'UTF8 set to on'; 2835 $self->assert($expected eq $resp_msg, 2836 test_msg("Expected response message '$expected', got '$resp_msg'")); 2837 }; 2838 2839 if ($@) { 2840 $ex = $@; 2841 } 2842 2843 $wfh->print("done\n"); 2844 $wfh->flush(); 2845 2846 } else { 2847 eval { server_wait($config_file, $rfh) }; 2848 if ($@) { 2849 warn($@); 2850 exit 1; 2851 } 2852 2853 exit 0; 2854 } 2855 2856 # Stop server 2857 server_stop($pid_file); 2858 2859 $self->assert_child_ok($pid); 2860 2861 if ($ex) { 2862 test_append_logfile($log_file, $ex); 2863 unlink($log_file); 2864 2865 die($ex); 2866 } 2867 2868 unlink($log_file); 2869} 2870 2871sub lang_useencoding_ascii_utf8_require_valid_encoding_bug4125 { 2872 my $self = shift; 2873 my $tmpdir = $self->{tmpdir}; 2874 2875 my $config_file = "$tmpdir/lang.conf"; 2876 my $pid_file = File::Spec->rel2abs("$tmpdir/lang.pid"); 2877 my $scoreboard_file = File::Spec->rel2abs("$tmpdir/lang.scoreboard"); 2878 2879 my $log_file = test_get_logfile(); 2880 2881 my $auth_user_file = File::Spec->rel2abs("$tmpdir/lang.passwd"); 2882 my $auth_group_file = File::Spec->rel2abs("$tmpdir/lang.group"); 2883 2884 my $user = 'proftpd'; 2885 my $passwd = 'test'; 2886 my $group = 'ftpd'; 2887 my $home_dir = File::Spec->rel2abs($tmpdir); 2888 my $uid = 500; 2889 my $gid = 500; 2890 2891 # Make sure that, if we're running as root, that the home directory has 2892 # permissions/privs set for the account we create 2893 if ($< == 0) { 2894 unless (chmod(0755, $home_dir)) { 2895 die("Can't set perms on $home_dir to 0755: $!"); 2896 } 2897 2898 unless (chown($uid, $gid, $home_dir)) { 2899 die("Can't set owner of $home_dir to $uid/$gid: $!"); 2900 } 2901 } 2902 2903 auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir, 2904 '/bin/bash'); 2905 auth_group_write($auth_group_file, $group, $gid, $user); 2906 2907 my $test_file = File::Spec->rel2abs("$home_dir/üöä"); 2908 2909 my $config = { 2910 PidFile => $pid_file, 2911 ScoreboardFile => $scoreboard_file, 2912 SystemLog => $log_file, 2913 TraceLog => $log_file, 2914 Trace => 'encode:20', 2915 2916 AuthUserFile => $auth_user_file, 2917 AuthGroupFile => $auth_group_file, 2918 2919 IfModules => { 2920 'mod_delay.c' => { 2921 DelayEngine => 'off', 2922 }, 2923 2924 'mod_lang.c' => { 2925 LangOptions => 'RequireValidEncoding', 2926 UseEncoding => 'utf-8 us-ascii', 2927 }, 2928 }, 2929 }; 2930 2931 my ($port, $config_user, $config_group) = config_write($config_file, $config); 2932 2933 # Open pipes, for use between the parent and child processes. Specifically, 2934 # the child will indicate when it's done with its test by writing a message 2935 # to the parent. 2936 my ($rfh, $wfh); 2937 unless (pipe($rfh, $wfh)) { 2938 die("Can't open pipe: $!"); 2939 } 2940 2941 my $ex; 2942 2943 # Fork child 2944 $self->handle_sigchld(); 2945 defined(my $pid = fork()) or die("Can't fork: $!"); 2946 if ($pid) { 2947 eval { 2948 my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port); 2949 $client->login($user, $passwd); 2950 2951 my $name = "üöä"; 2952 2953 my $conn = $client->stor_raw($name); 2954 if ($conn) { 2955 die("STORE $name succeeded unexpectedly"); 2956 } 2957 2958 my $resp_code = $client->response_code(); 2959 my $resp_msg = $client->response_msg(); 2960 2961 $client->quit(); 2962 2963 my $expected = 550; 2964 $self->assert($expected == $resp_code, 2965 test_msg("Expected response code $expected, got $resp_code")); 2966 2967 $expected = 'Illegal character sequence'; 2968 $self->assert(qr/$expected/, $resp_msg, 2969 test_msg("Expected response message '$expected', got '$resp_msg'")); 2970 }; 2971 2972 if ($@) { 2973 $ex = $@; 2974 } 2975 2976 $wfh->print("done\n"); 2977 $wfh->flush(); 2978 2979 } else { 2980 eval { server_wait($config_file, $rfh) }; 2981 if ($@) { 2982 warn($@); 2983 exit 1; 2984 } 2985 2986 exit 0; 2987 } 2988 2989 # Stop server 2990 server_stop($pid_file); 2991 2992 $self->assert_child_ok($pid); 2993 2994 if ($ex) { 2995 test_append_logfile($log_file, $ex); 2996 unlink($log_file); 2997 2998 die($ex); 2999 } 3000 3001 unlink($log_file); 3002} 3003 3004sub lang_useencoding_latin1_utf8_per_user_bug4214 { 3005 my $self = shift; 3006 my $tmpdir = $self->{tmpdir}; 3007 my $setup = test_setup($tmpdir, 'lang'); 3008 3009 my $test_file = File::Spec->rel2abs("$setup->{home_dir}/üöä"); 3010 3011 my $config = { 3012 PidFile => $setup->{pid_file}, 3013 ScoreboardFile => $setup->{scoreboard_file}, 3014 SystemLog => $setup->{log_file}, 3015 TraceLog => $setup->{log_file}, 3016 Trace => 'encode:20', 3017 3018 AuthUserFile => $setup->{auth_user_file}, 3019 AuthGroupFile => $setup->{auth_group_file}, 3020 3021 IfModules => { 3022 'mod_delay.c' => { 3023 DelayEngine => 'off', 3024 }, 3025 }, 3026 }; 3027 3028 my ($port, $config_user, $config_group) = config_write($setup->{config_file}, 3029 $config); 3030 3031 if (open(my $fh, ">> $setup->{config_file}")) { 3032 print $fh <<EOC; 3033<IfModule mod_lang.c> 3034 <IfUser $setup->{user}> 3035 UseEncoding utf-8 iso-8859-1 3036 </IfUser> 3037</IfModule> 3038EOC 3039 unless (close($fh)) { 3040 die("Can't write $setup->{config_file}: $!"); 3041 } 3042 3043 } else { 3044 die("Can't open $setup->{config_file}: $!"); 3045 } 3046 3047 # Open pipes, for use between the parent and child processes. Specifically, 3048 # the child will indicate when it's done with its test by writing a message 3049 # to the parent. 3050 my ($rfh, $wfh); 3051 unless (pipe($rfh, $wfh)) { 3052 die("Can't open pipe: $!"); 3053 } 3054 3055 my $ex; 3056 3057 # Fork child 3058 $self->handle_sigchld(); 3059 defined(my $pid = fork()) or die("Can't fork: $!"); 3060 if ($pid) { 3061 eval { 3062 my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port); 3063 $client->login($setup->{user}, $setup->{passwd}); 3064 3065 my $name = "üöä"; 3066 3067 my $conn = $client->stor_raw($name); 3068 unless ($conn) { 3069 die("STOR $name failed: " . $client->response_code() . " " . 3070 $client->response_msg()); 3071 } 3072 3073 my $buf = "Hello, world\n"; 3074 $conn->write($buf, length($buf), 15); 3075 eval { $conn->close() }; 3076 3077 my $resp_code = $client->response_code(); 3078 my $resp_msg = $client->response_msg(); 3079 $self->assert_transfer_ok($resp_code, $resp_msg); 3080 3081 $client->quit(); 3082 3083 $self->assert(-f $test_file, 3084 test_msg("File $test_file does not exist as expected")); 3085 }; 3086 3087 if ($@) { 3088 $ex = $@; 3089 } 3090 3091 $wfh->print("done\n"); 3092 $wfh->flush(); 3093 3094 } else { 3095 eval { server_wait($setup->{config_file}, $rfh) }; 3096 if ($@) { 3097 warn($@); 3098 exit 1; 3099 } 3100 3101 exit 0; 3102 } 3103 3104 # Stop server 3105 server_stop($setup->{pid_file}); 3106 $self->assert_child_ok($pid); 3107 test_cleanup($setup->{log_file}, $ex); 3108} 3109 3110sub lang_useencoding_utf8_latin1_per_user_bug4214 { 3111 my $self = shift; 3112 my $tmpdir = $self->{tmpdir}; 3113 my $setup = test_setup($tmpdir, 'lang'); 3114 3115 my $test_file = File::Spec->rel2abs("$setup->{home_dir}/Grafik-Zentrumäüu.png"); 3116 if ($^O eq 'darwin') { 3117 # MacOSX hack 3118 $test_file = ('/private' . $test_file); 3119 } 3120 3121 my $config = { 3122 PidFile => $setup->{pid_file}, 3123 ScoreboardFile => $setup->{scoreboard_file}, 3124 SystemLog => $setup->{log_file}, 3125 TraceLog => $setup->{log_file}, 3126 Trace => 'encode:20', 3127 3128 AuthUserFile => $setup->{auth_user_file}, 3129 AuthGroupFile => $setup->{auth_group_file}, 3130 3131 IfModules => { 3132 'mod_delay.c' => { 3133 DelayEngine => 'off', 3134 }, 3135 }, 3136 }; 3137 3138 my ($port, $config_user, $config_group) = config_write($setup->{config_file}, 3139 $config); 3140 3141 if (open(my $fh, ">> $setup->{config_file}")) { 3142 print $fh <<EOC; 3143<IfModule mod_lang.c> 3144 <IfUser $setup->{user}> 3145 UseEncoding utf-8 iso-8859-1 3146 </IfUser> 3147</IfModule> 3148EOC 3149 unless (close($fh)) { 3150 die("Can't write $setup->{config_file}: $!"); 3151 } 3152 3153 } else { 3154 die("Can't open $setup->{config_file}: $!"); 3155 } 3156 3157 # Open pipes, for use between the parent and child processes. Specifically, 3158 # the child will indicate when it's done with its test by writing a message 3159 # to the parent. 3160 my ($rfh, $wfh); 3161 unless (pipe($rfh, $wfh)) { 3162 die("Can't open pipe: $!"); 3163 } 3164 3165 my $ex; 3166 3167 # Fork child 3168 $self->handle_sigchld(); 3169 defined(my $pid = fork()) or die("Can't fork: $!"); 3170 if ($pid) { 3171 eval { 3172 my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port); 3173 $client->login($setup->{user}, $setup->{passwd}); 3174 3175 my $name = "Grafik-Zentrumäüu.png"; 3176 3177 my $conn = $client->stor_raw($name); 3178 unless ($conn) { 3179 die("STOR $name failed: " . $client->response_code() . " " . 3180 $client->response_msg()); 3181 } 3182 3183 my $buf = "Hello, world\n"; 3184 $conn->write($buf, length($buf), 15); 3185 eval { $conn->close() }; 3186 3187 my $resp_code = $client->response_code(); 3188 my $resp_msg = $client->response_msg(); 3189 $self->assert_transfer_ok($resp_code, $resp_msg); 3190 3191 $client->quit(); 3192 3193 $self->assert(-f $test_file, 3194 test_msg("File $test_file does not exist as expected")); 3195 }; 3196 3197 if ($@) { 3198 $ex = $@; 3199 } 3200 3201 $wfh->print("done\n"); 3202 $wfh->flush(); 3203 3204 } else { 3205 eval { server_wait($setup->{config_file}, $rfh) }; 3206 if ($@) { 3207 warn($@); 3208 exit 1; 3209 } 3210 3211 exit 0; 3212 } 3213 3214 # Stop server 3215 server_stop($setup->{pid_file}); 3216 $self->assert_child_ok($pid); 3217 test_cleanup($setup->{log_file}, $ex); 3218} 3219 32201; 3221