Advertisement
Guest User

Untitled

a guest
May 5th, 2016
72
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 16.24 KB | None | 0 0
  1. Index: proftpd-dfsg/contrib/mod_copy.c
  2. ===================================================================
  3. --- proftpd-dfsg.orig/contrib/mod_copy.c
  4. +++ proftpd-dfsg/contrib/mod_copy.c
  5. @@ -2,7 +2,7 @@
  6. * ProFTPD: mod_copy -- a module supporting copying of files on the server
  7. * without transferring the data to the client and back
  8. *
  9. - * Copyright (c) 2009-2012 TJ Saunders
  10. + * Copyright (c) 2009-2015 TJ Saunders
  11. *
  12. * This program is free software; you can redistribute it and/or modify
  13. * it under the terms of the GNU General Public License as published by
  14. @@ -25,13 +25,11 @@
  15. *
  16. * This is mod_copy, contrib software for proftpd 1.3.x and above.
  17. * For more information contact TJ Saunders <tj@castaglia.org>.
  18. - *
  19. - * $Id: mod_copy.c,v 1.8 2012/12/27 22:31:29 castaglia Exp $
  20. */
  21.  
  22. #include "conf.h"
  23.  
  24. -#define MOD_COPY_VERSION "mod_copy/0.4"
  25. +#define MOD_COPY_VERSION "mod_copy/0.5"
  26.  
  27. /* Make sure the version of proftpd is as necessary. */
  28. #if PROFTPD_VERSION_NUMBER < 0x0001030401
  29. @@ -40,6 +38,8 @@
  30.  
  31. extern pr_response_t *resp_list, *resp_err_list;
  32.  
  33. +static int copy_engine = TRUE;
  34. +
  35. static const char *trace_channel = "copy";
  36.  
  37. /* These are copied largely from src/mkhome.c */
  38. @@ -165,7 +165,7 @@ static int copy_symlink(pool *p, const c
  39. src_path, strerror(xerrno));
  40.  
  41. errno = xerrno;
  42. - return -1;
  43. + return -1;
  44. }
  45. link_path[len] = '\0';
  46.  
  47. @@ -471,10 +471,37 @@ static int copy_paths(pool *p, const cha
  48. return 0;
  49. }
  50.  
  51. +/* Configuration handlers
  52. + */
  53. +
  54. +/* usage: CopyEngine on|off */
  55. +MODRET set_copyengine(cmd_rec *cmd) {
  56. + int engine = -1;
  57. + config_rec *c;
  58. +
  59. + CHECK_ARGS(cmd, 1);
  60. + CHECK_CONF(cmd, CONF_ROOT|CONF_VIRTUAL|CONF_GLOBAL);
  61. +
  62. + engine = get_boolean(cmd, 1);
  63. + if (engine == -1) {
  64. + CONF_ERROR(cmd, "expected Boolean parameter");
  65. + }
  66. +
  67. + c = add_config_param(cmd->argv[0], 1, NULL);
  68. + c->argv[0] = palloc(c->pool, sizeof(int));
  69. + *((int *) c->argv[0]) = engine;
  70. +
  71. + return PR_HANDLED(cmd);
  72. +}
  73. +
  74. /* Command handlers
  75. */
  76.  
  77. MODRET copy_copy(cmd_rec *cmd) {
  78. + if (copy_engine == FALSE) {
  79. + return PR_DECLINED(cmd);
  80. + }
  81. +
  82. if (cmd->argc < 2) {
  83. return PR_DECLINED(cmd);
  84. }
  85. @@ -539,12 +566,26 @@ MODRET copy_cpfr(cmd_rec *cmd) {
  86. register unsigned int i;
  87. int res;
  88. char *path = "";
  89. + unsigned char *authenticated = NULL;
  90. +
  91. + if (copy_engine == FALSE) {
  92. + return PR_DECLINED(cmd);
  93. + }
  94.  
  95. if (cmd->argc < 3 ||
  96. strncasecmp(cmd->argv[1], "CPFR", 5) != 0) {
  97. return PR_DECLINED(cmd);
  98. }
  99.  
  100. + authenticated = get_param_ptr(cmd->server->conf, "authenticated", FALSE);
  101. + if (authenticated == NULL ||
  102. + *authenticated == FALSE) {
  103. + pr_response_add_err(R_530, _("Please login with USER and PASS"));
  104. +
  105. + errno = EPERM;
  106. + return PR_ERROR(cmd);
  107. + }
  108. +
  109. CHECK_CMD_MIN_ARGS(cmd, 3);
  110.  
  111. /* Construct the target file name by concatenating all the parameters after
  112. @@ -594,12 +635,26 @@ MODRET copy_cpfr(cmd_rec *cmd) {
  113. MODRET copy_cpto(cmd_rec *cmd) {
  114. register unsigned int i;
  115. char *from, *to = "";
  116. + unsigned char *authenticated = NULL;
  117. +
  118. + if (copy_engine == FALSE) {
  119. + return PR_DECLINED(cmd);
  120. + }
  121.  
  122. if (cmd->argc < 3 ||
  123. strncasecmp(cmd->argv[1], "CPTO", 5) != 0) {
  124. return PR_DECLINED(cmd);
  125. }
  126.  
  127. + authenticated = get_param_ptr(cmd->server->conf, "authenticated", FALSE);
  128. + if (authenticated == NULL ||
  129. + *authenticated == FALSE) {
  130. + pr_response_add_err(R_530, _("Please login with USER and PASS"));
  131. +
  132. + errno = EPERM;
  133. + return PR_ERROR(cmd);
  134. + }
  135. +
  136. CHECK_CMD_MIN_ARGS(cmd, 3);
  137.  
  138. from = pr_table_get(session.notes, "mod_copy.cpfr-path", NULL);
  139. @@ -632,6 +687,10 @@ MODRET copy_cpto(cmd_rec *cmd) {
  140. }
  141.  
  142. MODRET copy_log_site(cmd_rec *cmd) {
  143. + if (copy_engine == FALSE) {
  144. + return PR_DECLINED(cmd);
  145. + }
  146. +
  147. if (cmd->argc < 3 ||
  148. strncasecmp(cmd->argv[1], "CPTO", 5) != 0) {
  149. return PR_DECLINED(cmd);
  150. @@ -643,23 +702,58 @@ MODRET copy_log_site(cmd_rec *cmd) {
  151. return PR_DECLINED(cmd);
  152. }
  153.  
  154. +MODRET copy_post_pass(cmd_rec *cmd) {
  155. + config_rec *c;
  156. +
  157. + if (copy_engine == FALSE) {
  158. + return PR_DECLINED(cmd);
  159. + }
  160. +
  161. + /* The CopyEngine directive may have been changed for this user by
  162. + * e.g. mod_ifsession, thus we check again.
  163. + */
  164. + c = find_config(main_server->conf, CONF_PARAM, "CopyEngine", FALSE);
  165. + if (c != NULL) {
  166. + copy_engine = *((int *) c->argv[0]);
  167. + }
  168. +
  169. + return PR_DECLINED(cmd);
  170. +}
  171. +
  172. /* Initialization functions
  173. */
  174.  
  175. static int copy_sess_init(void) {
  176. + config_rec *c;
  177. +
  178. + c = find_config(main_server->conf, CONF_PARAM, "CopyEngine", FALSE);
  179. + if (c != NULL) {
  180. + copy_engine = *((int *) c->argv[0]);
  181. + }
  182. +
  183. + if (copy_engine == FALSE) {
  184. + return 0;
  185. + }
  186. +
  187. /* Advertise support for the SITE command */
  188. pr_feat_add("SITE COPY");
  189. -
  190. return 0;
  191. }
  192.  
  193. /* Module API tables
  194. */
  195.  
  196. +static conftable copy_conftab[] = {
  197. + { "CopyEngine", set_copyengine, NULL },
  198. +
  199. + { NULL }
  200. +};
  201. +
  202. static cmdtable copy_cmdtab[] = {
  203. { CMD, C_SITE, G_WRITE, copy_copy, FALSE, FALSE, CL_MISC },
  204. { CMD, C_SITE, G_DIRS, copy_cpfr, FALSE, FALSE, CL_MISC },
  205. { CMD, C_SITE, G_WRITE, copy_cpto, FALSE, FALSE, CL_MISC },
  206. + { POST_CMD, C_PASS, G_NONE, copy_post_pass, FALSE, FALSE },
  207. { LOG_CMD, C_SITE, G_NONE, copy_log_site, FALSE, FALSE },
  208. { LOG_CMD_ERR, C_SITE, G_NONE, copy_log_site, FALSE, FALSE },
  209.  
  210. @@ -676,7 +770,7 @@ module copy_module = {
  211. "copy",
  212.  
  213. /* Module configuration handler table */
  214. - NULL,
  215. + copy_conftab,
  216.  
  217. /* Module command handler table */
  218. copy_cmdtab,
  219. Index: proftpd-dfsg/doc/contrib/mod_copy.html
  220. ===================================================================
  221. --- proftpd-dfsg.orig/doc/contrib/mod_copy.html
  222. +++ proftpd-dfsg/doc/contrib/mod_copy.html
  223. @@ -1,5 +1,5 @@
  224. -<!-- $Id: mod_copy.html,v 1.1 2010/03/10 19:20:43 castaglia Exp $ -->
  225. -<!-- $Source: /cvsroot/proftp/proftpd/doc/contrib/mod_copy.html,v $ -->
  226. +<!-- $Id: mod_copy.html,v 1.1 2010-03-10 19:20:43 castaglia Exp $ -->
  227. +<!-- $Source: /home/proftpd-core/backup/proftp-cvsroot/proftpd/doc/contrib/mod_copy.html,v $ -->
  228.  
  229. <html>
  230. <head>
  231. @@ -27,22 +27,40 @@ ProFTPD 1.3.<i>x</i>, and is not compile
  232. instructions are discussed <a href="#Installation">here</a>.
  233.  
  234. <p>
  235. -The most current version of <code>mod_copy</code> can be found at:
  236. -<pre>
  237. - <a href="http://www.castaglia.org/proftpd/">http://www.castaglia.org/proftpd/</a>
  238. -</pre>
  239. +The most current version of <code>mod_copy</code> is distributed with the
  240. +ProFTPD source code.
  241.  
  242. <h2>Author</h2>
  243. <p>
  244. Please contact TJ Saunders &lt;tj <i>at</i> castaglia.org&gt; with any
  245. questions, concerns, or suggestions regarding this module.
  246.  
  247. +<h2>Directives</h2>
  248. +<ul>
  249. + <li><a href="#CopyEngine">CopyEngine</a>
  250. +</ul>
  251. +
  252. <h2><code>SITE</code> Commands</h2>
  253. <ul>
  254. <li><a href="#SITE_CPFR">SITE CPFR</a>
  255. <li><a href="#SITE_CPTO">SITE CPTO</a>
  256. </ul>
  257.  
  258. +<p>
  259. +<hr>
  260. +<h2><a name="CopyEngine">CopyEngine</a></h2>
  261. +<strong>Syntax:</strong> CopyEngine <em>on|off</em><br>
  262. +<strong>Default:</strong> CopyEngine on<br>
  263. +<strong>Context:</strong> server config, <code>&lt;VirtualHost&gt;</code>, <code>&lt;Global&gt;</code><br>
  264. +<strong>Module:</strong> mod_radius<br>
  265. +<strong>Compatibility:</strong> 1.3.6rc1 and later
  266. +
  267. +<p>
  268. +The <code>CopyEngine</code> directive enables or disables the module's
  269. +handling of <code>SITE COPY</code> <i>et al</i> commands. If it is set to
  270. +<em>off</em> this module ignores these commands.
  271. +
  272. +<p>
  273. <hr>
  274. <h2><a name="SITE_CPFR">SITE CPFR</a></h2>
  275. This <code>SITE</code> command specifies the source file/directory to use
  276. @@ -118,13 +136,8 @@ your existing server:
  277. <p>
  278. <hr><br>
  279.  
  280. -Author: <i>$Author: castaglia $</i><br>
  281. -Last Updated: <i>$Date: 2010/03/10 19:20:43 $</i><br>
  282. -
  283. -<br><hr>
  284. -
  285. <font size=2><b><i>
  286. -&copy; Copyright 2009-2010 TJ Saunders<br>
  287. +&copy; Copyright 2009-2015 TJ Saunders<br>
  288. All Rights Reserved<br>
  289. </i></b></font>
  290.  
  291. Index: proftpd-dfsg/tests/t/lib/ProFTPD/Tests/Modules/mod_copy.pm
  292. ===================================================================
  293. --- proftpd-dfsg.orig/tests/t/lib/ProFTPD/Tests/Modules/mod_copy.pm
  294. +++ proftpd-dfsg/tests/t/lib/ProFTPD/Tests/Modules/mod_copy.pm
  295. @@ -21,6 +21,11 @@ my $TESTS = {
  296. test_class => [qw(forking)],
  297. },
  298.  
  299. + copy_file_no_login => {
  300. + order => ++$order,
  301. + test_class => [qw(bug forking)],
  302. + },
  303. +
  304. copy_dir => {
  305. order => ++$order,
  306. test_class => [qw(forking)],
  307. @@ -86,6 +91,11 @@ my $TESTS = {
  308. test_class => [qw(forking)],
  309. },
  310.  
  311. + copy_cpfr_cpto_no_login => {
  312. + order => ++$order,
  313. + test_class => [qw(bug forking)],
  314. + },
  315. +
  316. copy_cpto_no_cpfr => {
  317. order => ++$order,
  318. test_class => [qw(forking)],
  319. @@ -263,6 +273,137 @@ sub copy_file {
  320. unlink($log_file);
  321. }
  322.  
  323. +sub copy_file_no_login {
  324. + my $self = shift;
  325. + my $tmpdir = $self->{tmpdir};
  326. +
  327. + my $config_file = "$tmpdir/copy.conf";
  328. + my $pid_file = File::Spec->rel2abs("$tmpdir/copy.pid");
  329. + my $scoreboard_file = File::Spec->rel2abs("$tmpdir/copy.scoreboard");
  330. +
  331. + my $log_file = File::Spec->rel2abs('tests.log');
  332. +
  333. + my $auth_user_file = File::Spec->rel2abs("$tmpdir/copy.passwd");
  334. + my $auth_group_file = File::Spec->rel2abs("$tmpdir/copy.group");
  335. +
  336. + my $user = 'proftpd';
  337. + my $passwd = 'test';
  338. + my $group = 'ftpd';
  339. + my $home_dir = File::Spec->rel2abs($tmpdir);
  340. + my $uid = 500;
  341. + my $gid = 500;
  342. +
  343. + # Make sure that, if we're running as root, that the home directory has
  344. + # permissions/privs set for the account we create
  345. + if ($< == 0) {
  346. + unless (chmod(0755, $home_dir)) {
  347. + die("Can't set perms on $home_dir to 0755: $!");
  348. + }
  349. +
  350. + unless (chown($uid, $gid, $home_dir)) {
  351. + die("Can't set owner of $home_dir to $uid/$gid: $!");
  352. + }
  353. + }
  354. +
  355. + auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir,
  356. + '/bin/bash');
  357. + auth_group_write($auth_group_file, $group, $gid, $user);
  358. +
  359. + my $src_file = File::Spec->rel2abs("$home_dir/foo.txt");
  360. + if (open(my $fh, "> $src_file")) {
  361. + print $fh "Hello, World!\n";
  362. +
  363. + unless (close($fh)) {
  364. + die("Can't write $src_file: $!");
  365. + }
  366. +
  367. + } else {
  368. + die("Can't open $src_file: $!");
  369. + }
  370. +
  371. + my $dst_file = File::Spec->rel2abs("$home_dir/bar.txt");
  372. +
  373. + my $config = {
  374. + PidFile => $pid_file,
  375. + ScoreboardFile => $scoreboard_file,
  376. + SystemLog => $log_file,
  377. +
  378. + AuthUserFile => $auth_user_file,
  379. + AuthGroupFile => $auth_group_file,
  380. +
  381. + IfModules => {
  382. + 'mod_delay.c' => {
  383. + DelayEngine => 'off',
  384. + },
  385. + },
  386. + };
  387. +
  388. + my ($port, $config_user, $config_group) = config_write($config_file, $config);
  389. +
  390. + # Open pipes, for use between the parent and child processes. Specifically,
  391. + # the child will indicate when it's done with its test by writing a message
  392. + # to the parent.
  393. + my ($rfh, $wfh);
  394. + unless (pipe($rfh, $wfh)) {
  395. + die("Can't open pipe: $!");
  396. + }
  397. +
  398. + my $ex;
  399. +
  400. + # Fork child
  401. + $self->handle_sigchld();
  402. + defined(my $pid = fork()) or die("Can't fork: $!");
  403. + if ($pid) {
  404. + eval {
  405. + my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port);
  406. +
  407. + eval { $client->site('COPY', 'foo.txt', 'bar.txt') };
  408. + unless ($@) {
  409. + die("SITE COPY succeeded unexpectedly");
  410. + }
  411. +
  412. + my $resp_code = $client->response_code();
  413. + my $resp_msg = $client->response_msg();
  414. +
  415. + my $expected;
  416. + $expected = 530;
  417. + $self->assert($expected == $resp_code,
  418. + test_msg("Expected response code $expected, got $resp_code"));
  419. +
  420. + $expected = "Please login with USER and PASS";
  421. + $self->assert($expected eq $resp_msg,
  422. + test_msg("Expected response message '$expected', got '$resp_msg'"));
  423. + };
  424. +
  425. + if ($@) {
  426. + $ex = $@;
  427. + }
  428. +
  429. + $wfh->print("done\n");
  430. + $wfh->flush();
  431. +
  432. + } else {
  433. + eval { server_wait($config_file, $rfh) };
  434. + if ($@) {
  435. + warn($@);
  436. + exit 1;
  437. + }
  438. +
  439. + exit 0;
  440. + }
  441. +
  442. + # Stop server
  443. + server_stop($pid_file);
  444. +
  445. + $self->assert_child_ok($pid);
  446. +
  447. + if ($ex) {
  448. + die($ex);
  449. + }
  450. +
  451. + unlink($log_file);
  452. +}
  453. +
  454. sub copy_dir {
  455. my $self = shift;
  456. my $tmpdir = $self->{tmpdir};
  457. @@ -2578,6 +2719,153 @@ sub copy_cpfr_cpto {
  458. };
  459.  
  460. if ($@) {
  461. + $ex = $@;
  462. + }
  463. +
  464. + $wfh->print("done\n");
  465. + $wfh->flush();
  466. +
  467. + } else {
  468. + eval { server_wait($config_file, $rfh) };
  469. + if ($@) {
  470. + warn($@);
  471. + exit 1;
  472. + }
  473. +
  474. + exit 0;
  475. + }
  476. +
  477. + # Stop server
  478. + server_stop($pid_file);
  479. +
  480. + $self->assert_child_ok($pid);
  481. +
  482. + if ($ex) {
  483. + die($ex);
  484. + }
  485. +
  486. + unlink($log_file);
  487. +}
  488. +
  489. +sub copy_cpfr_cpto_no_login {
  490. + my $self = shift;
  491. + my $tmpdir = $self->{tmpdir};
  492. +
  493. + my $config_file = "$tmpdir/copy.conf";
  494. + my $pid_file = File::Spec->rel2abs("$tmpdir/copy.pid");
  495. + my $scoreboard_file = File::Spec->rel2abs("$tmpdir/copy.scoreboard");
  496. +
  497. + my $log_file = File::Spec->rel2abs('tests.log');
  498. +
  499. + my $auth_user_file = File::Spec->rel2abs("$tmpdir/copy.passwd");
  500. + my $auth_group_file = File::Spec->rel2abs("$tmpdir/copy.group");
  501. +
  502. + my $user = 'proftpd';
  503. + my $passwd = 'test';
  504. + my $group = 'ftpd';
  505. + my $home_dir = File::Spec->rel2abs($tmpdir);
  506. + my $uid = 500;
  507. + my $gid = 500;
  508. +
  509. + # Make sure that, if we're running as root, that the home directory has
  510. + # permissions/privs set for the account we create
  511. + if ($< == 0) {
  512. + unless (chmod(0755, $home_dir)) {
  513. + die("Can't set perms on $home_dir to 0755: $!");
  514. + }
  515. +
  516. + unless (chown($uid, $gid, $home_dir)) {
  517. + die("Can't set owner of $home_dir to $uid/$gid: $!");
  518. + }
  519. + }
  520. +
  521. + auth_user_write($auth_user_file, $user, $passwd, $uid, $gid, $home_dir,
  522. + '/bin/bash');
  523. + auth_group_write($auth_group_file, $group, $gid, $user);
  524. +
  525. + my $src_file = File::Spec->rel2abs("$home_dir/foo.txt");
  526. + if (open(my $fh, "> $src_file")) {
  527. + print $fh "Hello, World!\n";
  528. +
  529. + unless (close($fh)) {
  530. + die("Can't write $src_file: $!");
  531. + }
  532. +
  533. + } else {
  534. + die("Can't open $src_file: $!");
  535. + }
  536. +
  537. + my $dst_file = File::Spec->rel2abs("$home_dir/bar.txt");
  538. +
  539. + my $config = {
  540. + PidFile => $pid_file,
  541. + ScoreboardFile => $scoreboard_file,
  542. + SystemLog => $log_file,
  543. +
  544. + AuthUserFile => $auth_user_file,
  545. + AuthGroupFile => $auth_group_file,
  546. +
  547. + IfModules => {
  548. + 'mod_delay.c' => {
  549. + DelayEngine => 'off',
  550. + },
  551. + },
  552. + };
  553. +
  554. + my ($port, $config_user, $config_group) = config_write($config_file, $config);
  555. +
  556. + # Open pipes, for use between the parent and child processes. Specifically,
  557. + # the child will indicate when it's done with its test by writing a message
  558. + # to the parent.
  559. + my ($rfh, $wfh);
  560. + unless (pipe($rfh, $wfh)) {
  561. + die("Can't open pipe: $!");
  562. + }
  563. +
  564. + my $ex;
  565. +
  566. + # Fork child
  567. + $self->handle_sigchld();
  568. + defined(my $pid = fork()) or die("Can't fork: $!");
  569. + if ($pid) {
  570. + eval {
  571. + my $client = ProFTPD::TestSuite::FTP->new('127.0.0.1', $port);
  572. +
  573. + eval { $client->site('CPFR', 'foo.txt') };
  574. + unless ($@) {
  575. + die("SITE CPFR succeeded unexpectedly");
  576. + }
  577. +
  578. + my $resp_code = $client->response_code();
  579. + my $resp_msg = $client->response_msg();
  580. +
  581. + my $expected;
  582. + $expected = 530;
  583. + $self->assert($expected == $resp_code,
  584. + test_msg("Expected response code $expected, got $resp_code"));
  585. +
  586. + $expected = "Please login with USER and PASS";
  587. + $self->assert($expected eq $resp_msg,
  588. + test_msg("Expected response message '$expected', got '$resp_msg'"));
  589. +
  590. + eval { $client->site('CPTO', 'bar.txt') };
  591. + unless ($@) {
  592. + die("SITE CPTO succeeded unexpectedly");
  593. + }
  594. +
  595. + $resp_code = $client->response_code();
  596. + $resp_msg = $client->response_msg();
  597. +
  598. + $expected = 530;
  599. + $self->assert($expected == $resp_code,
  600. + test_msg("Expected response code $expected, got $resp_code"));
  601. +
  602. + $expected = "Please login with USER and PASS";
  603. + $self->assert($expected eq $resp_msg,
  604. + test_msg("Expected response message '$expected', got '$resp_msg'"));
  605. + };
  606. +
  607. + if ($@) {
  608. $ex = $@;
  609. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement