1package ProFTPD::Tests::Commands::HELP; 2 3use lib qw(t/lib); 4use base qw(ProFTPD::TestSuite::Child); 5use strict; 6 7use File::Spec; 8use IO::Handle; 9 10use ProFTPD::TestSuite::FTP; 11use ProFTPD::TestSuite::Utils qw(:auth :config :features :running :test :testsuite); 12 13$| = 1; 14 15my $order = 0; 16 17my $TESTS = { 18 help_ok => { 19 order => ++$order, 20 test_class => [qw(forking)], 21 }, 22 23}; 24 25sub new { 26 return shift()->SUPER::new(@_); 27} 28 29sub list_tests { 30 return testsuite_get_runnable_tests($TESTS); 31} 32 33sub help_ok { 34 my $self = shift; 35 my $tmpdir = $self->{tmpdir}; 36 37 my $config_file = "$tmpdir/cmds.conf"; 38 my $pid_file = File::Spec->rel2abs("$tmpdir/cmds.pid"); 39 my $scoreboard_file = File::Spec->rel2abs("$tmpdir/cmds.scoreboard"); 40 41 my $log_file = test_get_logfile(); 42 43 my $auth_user_file = File::Spec->rel2abs("$tmpdir/cmds.passwd"); 44 my $auth_group_file = File::Spec->rel2abs("$tmpdir/cmds.group"); 45 46 my $user = 'proftpd'; 47 my $passwd = 'test'; 48 my $group = 'ftpd'; 49 my $home_dir = File::Spec->rel2abs($tmpdir); 50 my $uid = 500; 51 my $gid = 500; 52 53 # Make sure that, if we're running as root, that the home directory has 54 # permissions/privs set for the account we create 55 if ($< == 0) { 56 unless (chmod(0755, $home_dir)) { 57 die("Can't set perms on $home_dir to 0755: $!"); 58 } 59 60 unless (chown($uid, $gid, $home_dir)) { 61 die("Can't set owner of $home_dir to $uid/$gid: $!"); 62 } 63 } 64 65 auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir, 66 '/bin/bash'); 67 auth_group_write($auth_group_file, $group, $gid, $user); 68 69 my $config = { 70 PidFile => $pid_file, 71 ScoreboardFile => $scoreboard_file, 72 SystemLog => $log_file, 73 74 AuthUserFile => $auth_user_file, 75 AuthGroupFile => $auth_group_file, 76 77 IfModules => { 78 'mod_delay.c' => { 79 DelayEngine => 'off', 80 }, 81 }, 82 }; 83 84 my ($port, $config_user, $config_group) = config_write($config_file, $config); 85 86 my $auth_helps = [ 87 ' NOOP FEAT OPTS AUTH* CCC* CONF* ENC* MIC* ', 88 ' PBSZ* PROT* TYPE STRU MODE RETR STOR STOU ', 89 ]; 90 91 # Open pipes, for use between the parent and child processes. Specifically, 92 # the child will indicate when it's done with its test by writing a message 93 # to the parent. 94 my ($rfh, $wfh); 95 unless (pipe($rfh, $wfh)) { 96 die("Can't open pipe: $!"); 97 } 98 99 my $ex; 100 101 # Fork child 102 $self->handle_sigchld(); 103 defined(my $pid = fork()) or die("Can't fork: $!"); 104 if ($pid) { 105 eval { 106 my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port); 107 108 $client->help(); 109 my $resp_code = $client->response_code(); 110 my $resp_msgs = $client->response_msgs(); 111 112 my $expected; 113 114 $expected = 214; 115 $self->assert($expected == $resp_code, 116 test_msg("Expected $expected, got $resp_code")); 117 118 $expected = 9; 119 my $nhelp = scalar(@$resp_msgs); 120 $self->assert($expected == $nhelp, 121 test_msg("Expected $expected, got $nhelp")); 122 123 my $helps = [( 124 'The following commands are recognized (* =>\'s unimplemented):', 125 ' CWD XCWD CDUP XCUP SMNT* QUIT PORT PASV ', 126 ' EPRT EPSV ALLO* RNFR RNTO DELE MDTM RMD ', 127 ' XRMD MKD XMKD PWD XPWD SIZE SYST HELP ', 128 @$auth_helps, 129 ' APPE REST ABOR USER PASS ACCT* REIN* LIST ', 130 ' NLST STAT SITE MLSD MLST ', 131 'Direct comments to root@127.0.0.1', 132 )]; 133 134 for (my $i = 0; $i < $nhelp; $i++) { 135 $expected = $helps->[$i]; 136 $self->assert($expected eq $resp_msgs->[$i], 137 test_msg("Expected '$expected', got '$resp_msgs->[$i]'")); 138 } 139 }; 140 141 if ($@) { 142 $ex = $@; 143 } 144 145 $wfh->print("done\n"); 146 $wfh->flush(); 147 148 } else { 149 eval { server_wait($config_file, $rfh) }; 150 if ($@) { 151 warn($@); 152 exit 1; 153 } 154 155 exit 0; 156 } 157 158 # Stop server 159 server_stop($pid_file); 160 161 $self->assert_child_ok($pid); 162 163 if ($ex) { 164 test_append_logfile($log_file, $ex); 165 unlink($log_file); 166 167 die($ex); 168 } 169 170 unlink($log_file); 171} 172 1731; 174