1package ProFTPD::Tests::Config::RewriteHome; 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 :running :test :testsuite); 12 13$| = 1; 14 15my $order = 0; 16 17my $TESTS = { 18 rewritehome_ok => { 19 order => ++$order, 20 test_class => [qw(forking mod_rewrite)], 21 }, 22 23 rewritehome_bad_home => { 24 order => ++$order, 25 test_class => [qw(forking mod_rewrite)], 26 }, 27 28 rewritehome_chroot_bug3348 => { 29 order => ++$order, 30 test_class => [qw(bug forking mod_rewrite rootprivs)], 31 }, 32 33}; 34 35sub new { 36 return shift()->SUPER::new(@_); 37} 38 39sub list_tests { 40 return testsuite_get_runnable_tests($TESTS); 41} 42 43sub rewritehome_ok { 44 my $self = shift; 45 my $tmpdir = $self->{tmpdir}; 46 47 my $config_file = "$tmpdir/config.conf"; 48 my $pid_file = File::Spec->rel2abs("$tmpdir/config.pid"); 49 my $scoreboard_file = File::Spec->rel2abs("$tmpdir/config.scoreboard"); 50 51 my $log_file = File::Spec->rel2abs('tests.log'); 52 53 my $auth_user_file = File::Spec->rel2abs("$tmpdir/config.passwd"); 54 my $auth_group_file = File::Spec->rel2abs("$tmpdir/config.group"); 55 56 my $user = 'proftpd'; 57 my $passwd = 'test'; 58 my $group = 'ftpd'; 59 my $home_dir = File::Spec->rel2abs($tmpdir); 60 my $uid = 500; 61 my $gid = 500; 62 63 # Make sure that, if we're running as root, that the home directory has 64 # permissions/privs set for the account we create 65 if ($< == 0) { 66 unless (chmod(0755, $home_dir)) { 67 die("Can't set perms on $home_dir to 0755: $!"); 68 } 69 70 unless (chown($uid, $gid, $home_dir)) { 71 die("Can't set owner of $home_dir to $uid/$gid: $!"); 72 } 73 } 74 75 auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, '/foo/bar/baz', 76 '/bin/bash'); 77 auth_group_write($auth_group_file, $group, $gid, $user); 78 79 my $config = { 80 PidFile => $pid_file, 81 ScoreboardFile => $scoreboard_file, 82 SystemLog => $log_file, 83 84 AuthUserFile => $auth_user_file, 85 AuthGroupFile => $auth_group_file, 86 87 IfModules => { 88 'mod_delay.c' => { 89 DelayEngine => 'off', 90 }, 91 92 'mod_rewrite.c' => [ 93 'RewriteHome on', 94 'RewriteEngine on', 95 "RewriteLog $log_file", 96 'RewriteCondition %m REWRITE_HOME', 97 "RewriteRule ^(.*) $home_dir", 98 ], 99 }, 100 }; 101 102 my ($port, $config_user, $config_group) = config_write($config_file, $config); 103 104 # Open pipes, for use between the parent and child processes. Specifically, 105 # the child will indicate when it's done with its test by writing a message 106 # to the parent. 107 my ($rfh, $wfh); 108 unless (pipe($rfh, $wfh)) { 109 die("Can't open pipe: $!"); 110 } 111 112 my $ex; 113 114 # Fork child 115 $self->handle_sigchld(); 116 defined(my $pid = fork()) or die("Can't fork: $!"); 117 if ($pid) { 118 eval { 119 my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port); 120 $client->login($user, $passwd); 121 122 my ($resp_code, $resp_msg) = $client->pwd(); 123 124 my $expected; 125 126 $expected = 257; 127 $self->assert($expected == $resp_code, 128 test_msg("Expected $expected, got $resp_code")); 129 130 $expected = "\"$home_dir\" is the current directory"; 131 $self->assert($expected eq $resp_msg, 132 test_msg("Expected '$expected', got '$resp_msg'")); 133 }; 134 135 if ($@) { 136 $ex = $@; 137 } 138 139 $wfh->print("done\n"); 140 $wfh->flush(); 141 142 } else { 143 eval { server_wait($config_file, $rfh) }; 144 if ($@) { 145 warn($@); 146 exit 1; 147 } 148 149 exit 0; 150 } 151 152 # Stop server 153 server_stop($pid_file); 154 155 $self->assert_child_ok($pid); 156 157 if ($ex) { 158 die($ex); 159 } 160 161 unlink($log_file); 162} 163 164sub rewritehome_bad_home { 165 my $self = shift; 166 my $tmpdir = $self->{tmpdir}; 167 168 my $config_file = "$tmpdir/config.conf"; 169 my $pid_file = File::Spec->rel2abs("$tmpdir/config.pid"); 170 my $scoreboard_file = File::Spec->rel2abs("$tmpdir/config.scoreboard"); 171 172 my $log_file = File::Spec->rel2abs('tests.log'); 173 174 my $auth_user_file = File::Spec->rel2abs("$tmpdir/config.passwd"); 175 my $auth_group_file = File::Spec->rel2abs("$tmpdir/config.group"); 176 177 my $user = 'proftpd'; 178 my $passwd = 'test'; 179 my $group = 'ftpd'; 180 my $home_dir = File::Spec->rel2abs($tmpdir); 181 my $uid = 500; 182 my $gid = 500; 183 184 # Make sure that, if we're running as root, that the home directory has 185 # permissions/privs set for the account we create 186 if ($< == 0) { 187 unless (chmod(0755, $home_dir)) { 188 die("Can't set perms on $home_dir to 0755: $!"); 189 } 190 191 unless (chown($uid, $gid, $home_dir)) { 192 die("Can't set owner of $home_dir to $uid/$gid: $!"); 193 } 194 } 195 196 auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir, 197 '/bin/bash'); 198 auth_group_write($auth_group_file, $group, $gid, $user); 199 200 my $config = { 201 PidFile => $pid_file, 202 ScoreboardFile => $scoreboard_file, 203 SystemLog => $log_file, 204 205 AuthUserFile => $auth_user_file, 206 AuthGroupFile => $auth_group_file, 207 208 IfModules => { 209 'mod_delay.c' => { 210 DelayEngine => 'off', 211 }, 212 213 'mod_rewrite.c' => [ 214 'RewriteHome on', 215 'RewriteEngine on', 216 "RewriteLog $log_file", 217 'RewriteCondition %m REWRITE_HOME', 218 'RewriteRule ^(.*) /foo/bar/baz/quxx/quzz/alef/bet', 219 ], 220 }, 221 }; 222 223 my ($port, $config_user, $config_group) = config_write($config_file, $config); 224 225 # Open pipes, for use between the parent and child processes. Specifically, 226 # the child will indicate when it's done with its test by writing a message 227 # to the parent. 228 my ($rfh, $wfh); 229 unless (pipe($rfh, $wfh)) { 230 die("Can't open pipe: $!"); 231 } 232 233 my $ex; 234 235 # Fork child 236 $self->handle_sigchld(); 237 defined(my $pid = fork()) or die("Can't fork: $!"); 238 if ($pid) { 239 eval { 240 my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port); 241 242 # Because we rewrote the home directory to one that doesn't exist, 243 # the login should not succeed. 244 eval { $client->login($user, $passwd) }; 245 unless ($@) { 246 die("Login succeeded expectedly"); 247 } 248 }; 249 250 if ($@) { 251 $ex = $@; 252 } 253 254 $wfh->print("done\n"); 255 $wfh->flush(); 256 257 } else { 258 eval { server_wait($config_file, $rfh) }; 259 if ($@) { 260 warn($@); 261 exit 1; 262 } 263 264 exit 0; 265 } 266 267 # Stop server 268 server_stop($pid_file); 269 270 $self->assert_child_ok($pid); 271 272 if ($ex) { 273 die($ex); 274 } 275 276 unlink($log_file); 277} 278 279sub rewritehome_chroot_bug3348 { 280 my $self = shift; 281 my $tmpdir = $self->{tmpdir}; 282 283 my $config_file = "$tmpdir/config.conf"; 284 my $pid_file = File::Spec->rel2abs("$tmpdir/config.pid"); 285 my $scoreboard_file = File::Spec->rel2abs("$tmpdir/config.scoreboard"); 286 287 my $log_file = File::Spec->rel2abs('tests.log'); 288 289 my $auth_user_file = File::Spec->rel2abs("$tmpdir/config.passwd"); 290 my $auth_group_file = File::Spec->rel2abs("$tmpdir/config.group"); 291 292 my $user = 'proftpd'; 293 my $passwd = 'test'; 294 my $group = 'ftpd'; 295 my $home_dir = File::Spec->rel2abs($tmpdir); 296 my $uid = 500; 297 my $gid = 500; 298 299 # Make sure that, if we're running as root, that the home directory has 300 # permissions/privs set for the account we create 301 if ($< == 0) { 302 unless (chmod(0755, $home_dir)) { 303 die("Can't set perms on $home_dir to 0755: $!"); 304 } 305 306 unless (chown($uid, $gid, $home_dir)) { 307 die("Can't set owner of $home_dir to $uid/$gid: $!"); 308 } 309 } 310 311 auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, '/foo/bar/baz', 312 '/bin/bash'); 313 auth_group_write($auth_group_file, $group, $gid, $user); 314 315 my $config = { 316 PidFile => $pid_file, 317 ScoreboardFile => $scoreboard_file, 318 SystemLog => $log_file, 319 320 AuthUserFile => $auth_user_file, 321 AuthGroupFile => $auth_group_file, 322 DefaultRoot => '~/', 323 324 IfModules => { 325 'mod_delay.c' => { 326 DelayEngine => 'off', 327 }, 328 329 'mod_rewrite.c' => [ 330 'RewriteHome on', 331 'RewriteEngine on', 332 "RewriteLog $log_file", 333 'RewriteCondition %m REWRITE_HOME', 334 "RewriteRule ^(.*) $home_dir", 335 ], 336 }, 337 }; 338 339 my ($port, $config_user, $config_group) = config_write($config_file, $config); 340 341 # Open pipes, for use between the parent and child processes. Specifically, 342 # the child will indicate when it's done with its test by writing a message 343 # to the parent. 344 my ($rfh, $wfh); 345 unless (pipe($rfh, $wfh)) { 346 die("Can't open pipe: $!"); 347 } 348 349 my $ex; 350 351 # Fork child 352 $self->handle_sigchld(); 353 defined(my $pid = fork()) or die("Can't fork: $!"); 354 if ($pid) { 355 eval { 356 my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port); 357 $client->login($user, $passwd); 358 359 my ($resp_code, $resp_msg) = $client->pwd(); 360 361 my $expected; 362 363 $expected = 257; 364 $self->assert($expected == $resp_code, 365 test_msg("Expected $expected, got $resp_code")); 366 367 $expected = "\"/\" is the current directory"; 368 $self->assert($expected eq $resp_msg, 369 test_msg("Expected '$expected', got '$resp_msg'")); 370 }; 371 372 if ($@) { 373 $ex = $@; 374 } 375 376 $wfh->print("done\n"); 377 $wfh->flush(); 378 379 } else { 380 eval { server_wait($config_file, $rfh) }; 381 if ($@) { 382 warn($@); 383 exit 1; 384 } 385 386 exit 0; 387 } 388 389 # Stop server 390 server_stop($pid_file); 391 392 $self->assert_child_ok($pid); 393 394 if ($ex) { 395 die($ex); 396 } 397 398 unlink($log_file); 399} 400 4011; 402