1package ProFTPD::Tests::Config::Limit::OPTS;
2
3use lib qw(t/lib);
4use base qw(ProFTPD::TestSuite::Child);
5use strict;
6
7use File::Spec;
8use IO::Handle;
9
10use ProFTPD::TestSuite::FTP;
11use ProFTPD::TestSuite::Utils qw(:auth :config :running :test :testsuite);
12
13$| = 1;
14
15my $order = 0;
16
17my $TESTS = {
18  opts_limit_utf8_bug3438 => {
19    order => ++$order,
20    test_class => [qw(bug forking mod_lang)],
21  },
22
23  opts_limit_all_bug3438 => {
24    order => ++$order,
25    test_class => [qw(bug forking mod_lang)],
26  },
27
28};
29
30sub new {
31  return shift()->SUPER::new(@_);
32}
33
34sub list_tests {
35  return testsuite_get_runnable_tests($TESTS);
36}
37
38sub opts_limit_utf8_bug3438 {
39  my $self = shift;
40  my $tmpdir = $self->{tmpdir};
41
42  my $config_file = "$tmpdir/limit.conf";
43  my $pid_file = File::Spec->rel2abs("$tmpdir/limit.pid");
44  my $scoreboard_file = File::Spec->rel2abs("$tmpdir/limit.scoreboard");
45
46  my $log_file = File::Spec->rel2abs('tests.log');
47
48  my $auth_user_file = File::Spec->rel2abs("$tmpdir/limit.passwd");
49  my $auth_group_file = File::Spec->rel2abs("$tmpdir/limit.group");
50
51  my $user = 'proftpd';
52  my $passwd = 'test';
53  my $home_dir = File::Spec->rel2abs($tmpdir);
54  my $uid = 500;
55  my $gid = 500;
56
57  # Make sure that, if we're running as root, that the home directory has
58  # permissions/privs set for the account we create
59  if ($< == 0) {
60    unless (chmod(0755, $home_dir)) {
61      die("Can't set perms on $home_dir to 0755: $!");
62    }
63
64    unless (chown($uid, $gid, $home_dir)) {
65      die("Can't set owner of $home_dir to $uid/$gid: $!");
66    }
67  }
68
69  auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir,
70    '/bin/bash');
71  auth_group_write($auth_group_file, 'ftpd', $gid, $user);
72
73  my $config = {
74    PidFile => $pid_file,
75    ScoreboardFile => $scoreboard_file,
76    SystemLog => $log_file,
77
78    AuthUserFile => $auth_user_file,
79    AuthGroupFile => $auth_group_file,
80
81    IfModules => {
82      'mod_delay.c' => {
83        DelayEngine => 'off',
84      },
85    },
86
87    Limit => {
88      OPTS_UTF8 => {
89        DenyAll => '',
90      },
91    },
92
93  };
94
95  my ($port, $config_user, $config_group) = config_write($config_file, $config);
96
97  # Open pipes, for use between the parent and child processes.  Specifically,
98  # the child will indicate when it's done with its test by writing a message
99  # to the parent.
100  my ($rfh, $wfh);
101  unless (pipe($rfh, $wfh)) {
102    die("Can't open pipe: $!");
103  }
104
105  my $ex;
106
107  # Fork child
108  $self->handle_sigchld();
109  defined(my $pid = fork()) or die("Can't fork: $!");
110  if ($pid) {
111    eval {
112      my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port);
113      $client->login($user, $passwd);
114
115      my ($resp_code, $resp_msg);
116
117      eval { $client->opts('UTF8', 'on') };
118      unless ($@) {
119        die("OPTS UTF8 succeeded unexpectedly");
120
121      } else {
122        $resp_code = $client->response_code();
123        $resp_msg = $client->response_msg();
124      }
125
126      my $expected;
127
128      $expected = 550;
129      $self->assert($expected == $resp_code,
130        test_msg("Expected $expected, got $resp_code"));
131
132      $expected = "OPTS UTF8: Permission denied";
133      $self->assert($expected eq $resp_msg,
134        test_msg("Expected '$expected', got '$resp_msg'"));
135
136      $client->quit();
137    };
138
139    if ($@) {
140      $ex = $@;
141    }
142
143    $wfh->print("done\n");
144    $wfh->flush();
145
146  } else {
147    eval { server_wait($config_file, $rfh) };
148    if ($@) {
149      warn($@);
150      exit 1;
151    }
152
153    exit 0;
154  }
155
156  # Stop server
157  server_stop($pid_file);
158
159  $self->assert_child_ok($pid);
160
161  if ($ex) {
162    die($ex);
163  }
164
165  unlink($log_file);
166}
167
168sub opts_limit_all_bug3438 {
169  my $self = shift;
170  my $tmpdir = $self->{tmpdir};
171
172  my $config_file = "$tmpdir/limit.conf";
173  my $pid_file = File::Spec->rel2abs("$tmpdir/limit.pid");
174  my $scoreboard_file = File::Spec->rel2abs("$tmpdir/limit.scoreboard");
175
176  my $log_file = File::Spec->rel2abs('tests.log');
177
178  my $auth_user_file = File::Spec->rel2abs("$tmpdir/limit.passwd");
179  my $auth_group_file = File::Spec->rel2abs("$tmpdir/limit.group");
180
181  my $user = 'proftpd';
182  my $passwd = 'test';
183  my $home_dir = File::Spec->rel2abs($tmpdir);
184  my $uid = 500;
185  my $gid = 500;
186
187  # Make sure that, if we're running as root, that the home directory has
188  # permissions/privs set for the account we create
189  if ($< == 0) {
190    unless (chmod(0755, $home_dir)) {
191      die("Can't set perms on $home_dir to 0755: $!");
192    }
193
194    unless (chown($uid, $gid, $home_dir)) {
195      die("Can't set owner of $home_dir to $uid/$gid: $!");
196    }
197  }
198
199  auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir,
200    '/bin/bash');
201  auth_group_write($auth_group_file, 'ftpd', $gid, $user);
202
203  my $config = {
204    PidFile => $pid_file,
205    ScoreboardFile => $scoreboard_file,
206    SystemLog => $log_file,
207
208    AuthUserFile => $auth_user_file,
209    AuthGroupFile => $auth_group_file,
210
211    IfModules => {
212      'mod_delay.c' => {
213        DelayEngine => 'off',
214      },
215    },
216
217    Limit => {
218      ALL => {
219        DenyAll => '',
220      },
221    },
222
223  };
224
225  my ($port, $config_user, $config_group) = config_write($config_file, $config);
226
227  # Open pipes, for use between the parent and child processes.  Specifically,
228  # the child will indicate when it's done with its test by writing a message
229  # to the parent.
230  my ($rfh, $wfh);
231  unless (pipe($rfh, $wfh)) {
232    die("Can't open pipe: $!");
233  }
234
235  my $ex;
236
237  # Fork child
238  $self->handle_sigchld();
239  defined(my $pid = fork()) or die("Can't fork: $!");
240  if ($pid) {
241    eval {
242      my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port);
243      $client->login($user, $passwd);
244      $client->opts('UTF8', 'on');
245      $client->quit();
246    };
247
248    if ($@) {
249      $ex = $@;
250    }
251
252    $wfh->print("done\n");
253    $wfh->flush();
254
255  } else {
256    eval { server_wait($config_file, $rfh) };
257    if ($@) {
258      warn($@);
259      exit 1;
260    }
261
262    exit 0;
263  }
264
265  # Stop server
266  server_stop($pid_file);
267
268  $self->assert_child_ok($pid);
269
270  if ($ex) {
271    die($ex);
272  }
273
274  unlink($log_file);
275}
276
2771;
278