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