scponly-4.8-rsync.patch 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. diff -Naur scponly-4.8.orig/CHANGELOG scponly-4.8/CHANGELOG
  2. --- scponly-4.8.orig/CHANGELOG 2008-01-15 15:26:13.000000000 +0900
  3. +++ scponly-4.8/CHANGELOG 2009-03-18 21:29:48.000000000 +0900
  4. @@ -1,3 +1,9 @@
  5. +CVS
  6. + Update the SECURITY document to include a reference to /etc/popt and ~/.popt as
  7. + they relate to rsync.
  8. + Fix for rsync-3.0 which now uses a short -e option, with an optional argument as
  9. + a server side option indicating protocol compatibility.
  10. +
  11. scponly v4.8 - jan 14 2008
  12. fix support for quota and passwd when running within the chroot (exec pre-chroot)
  13. disallow rsync and svnserve from being run as daemons that listen on a port
  14. diff -Naur scponly-4.8.orig/SECURITY scponly-4.8/SECURITY
  15. --- scponly-4.8.orig/SECURITY 2008-01-15 15:26:13.000000000 +0900
  16. +++ scponly-4.8/SECURITY 2009-03-18 21:29:48.000000000 +0900
  17. @@ -28,6 +28,10 @@
  18. svn, svnserve, rsync, and unison
  19. + Note specifically that rsync uses popt for parsing command line arguments
  20. + and popt explicitly checks /etc/popt and $HOME/.popt for aliases. Thus,
  21. + users can likely bypass argument checking for rsync.
  22. +
  23. 4) Make sure that all files required for the chroot have the IMMUTABLE and
  24. UNDELETABLE bits set. Other bits might also be prudent. See: man 1 chattr.
  25. @@ -39,13 +43,16 @@
  26. ~/.ssh, ~/.unison, ~/.subversion
  27. NOTE: depending on file permissions in the above, ssh, unison, and
  28. - subversion may not work correctly.
  29. + subversion may not work correctly. Also note that the location of the
  30. + above directories is sometimes system dependent, so please check the
  31. + documentation specific to your system.
  32. 7) Make sure that every directory the users have write permissions to are
  33. on a filesystem that is mounted NODEV, NOEXEC. Eg. Make sure that they
  34. cannot execute files that they have permissions to upload. They should
  35. also not need permissions to create any devices. If the user can't execute
  36. - any files that he has access to upload, then you need not worry about the
  37. + any files that he has access to upload and the executable files on the
  38. + system are not considered harmful, then you need not worry about the
  39. security problems referencing svn/svnserve above!
  40. 8) Monitor your logs! If you start to see something funny, odd, or strange in
  41. diff -Naur scponly-4.8.orig/helper.c scponly-4.8/helper.c
  42. --- scponly-4.8.orig/helper.c 2008-01-15 15:26:13.000000000 +0900
  43. +++ scponly-4.8/helper.c 2009-03-18 21:29:48.000000000 +0900
  44. @@ -6,17 +6,15 @@
  45. #include <sys/types.h> /* for stat, getpwuid */
  46. #include <sys/stat.h> /* for stat */
  47. #include <unistd.h> /* for exit, access, getpwuid, execve, getopt */
  48. -#ifdef HAVE_GETOPT_H
  49. -#include <getopt.h> /* for getopt */
  50. -#endif
  51. #include <errno.h> /* for debugging */
  52. #include <pwd.h> /* to get username for config parsing */
  53. #include <time.h> /* time */
  54. #include <libgen.h> /* basename */
  55. #include <stdlib.h> /* realloc */
  56. #include <syslog.h>
  57. -#include "scponly.h"
  58. +
  59. #include "config.h"
  60. +#include "scponly.h" /* includes getopt */
  61. #ifdef HAVE_GLOB
  62. #include <glob.h> /* for glob() */
  63. @@ -26,6 +24,11 @@
  64. #endif
  65. #endif
  66. +#ifdef RSYNC_COMPAT
  67. +#define RSYNC_ARG_SERVER 0x01
  68. +#define RSYNC_ARG_EXECUTE 0x02
  69. +#endif
  70. +
  71. #define MAX(x,y) ( ( x > y ) ? x : y )
  72. #define MIN(x,y) ( ( x < y ) ? x : y )
  73. @@ -164,6 +167,13 @@
  74. int ch;
  75. int ac=0;
  76. int longopt_index = 0;
  77. +#ifdef RSYNC_COMPAT
  78. + /*
  79. + * bitwise flag: 0x01 = server, 0x02 = -e.
  80. + * Thus 0x03 is allowed and 0x01 is allowed, but 0x02 is not allowed
  81. + */
  82. + int rsync_flags = 0;
  83. +#endif /* RSYNC_COMPAT */
  84. while (cmdarg != NULL)
  85. {
  86. @@ -207,7 +217,7 @@
  87. * otherwise, try a glibc-style reset of the global getopt vars
  88. */
  89. optind=0;
  90. -#endif
  91. +#endif /* HAVE_OPTRESET */
  92. /*
  93. * tell getopt to only be strict if the 'opts' is well defined
  94. */
  95. @@ -216,28 +226,49 @@
  96. debug(LOG_DEBUG, "getopt processing returned '%c' (%s)", ch, logstamp());
  97. +#ifdef RSYNC_COMPAT
  98. + if (exact_match(cmdarg->name, PROG_RSYNC) && (ch == 's' || ch == 'e')) {
  99. + if (ch == 's')
  100. + rsync_flags |= RSYNC_ARG_SERVER;
  101. + else
  102. + /* -e */
  103. + rsync_flags |= RSYNC_ARG_EXECUTE;
  104. + debug(LOG_DEBUG, "rsync_flags are now set to: %0x", rsync_flags);
  105. + }
  106. + else
  107. +#endif /* RSYNC_COMPAT */
  108. +
  109. /* if the character is found in badarg, then it's not a permitted option */
  110. if (cmdarg->badarg != NULL && (strchr(cmdarg->badarg, ch) != NULL))
  111. {
  112. syslog(LOG_ERR, "option '%c' or a related long option is not permitted for use with %s (arg was %s) (%s))",
  113. - ch, cmdarg->name, optarg, logstamp());
  114. + ch, cmdarg->name, (optarg!=NULL ? optarg : "<NULL>"), logstamp());
  115. return 1;
  116. }
  117. else if (cmdarg->strict && ch == '?')
  118. {
  119. syslog(LOG_ERR, "an unrecognized option was encountered while processing cmd %s (arg was %s) (%s))",
  120. - cmdarg->name, optarg, logstamp());
  121. + cmdarg->name, (optarg!=NULL ? optarg : "<NULL>"), logstamp());
  122. return 1;
  123. }
  124. }
  125. -#elif
  126. +#ifdef RSYNC_COMPAT
  127. + /* it's not safe if the execute flag was set and server was not set */
  128. + if ((rsync_flags & RSYNC_ARG_EXECUTE) != 0 && (rsync_flags & RSYNC_ARG_SERVER) == 0) {
  129. + syslog(LOG_ERR, "option 'e' is not allowed unless '--server' is also set with cmd %s (%s)",
  130. + PROG_RSYNC, logstamp());
  131. + return 1;
  132. + }
  133. +#endif /* RSYNC_COMPAT */
  134. +
  135. +#elif /* HAVE_GETOPT */
  136. /*
  137. * make sure that processing doesn't continue if we can't validate a rsync check
  138. * and if the getopt flag is set.
  139. */
  140. syslog(LOG_ERR, "a getopt() argument check could not be performed for %s, recompile scponly without support for %s or rebuild scponly with getopt", av[0], av[0]);
  141. return 1;
  142. -#endif
  143. +#endif /* HAVE_GETOPT */
  144. }
  145. else
  146. /*
  147. diff -Naur scponly-4.8.orig/scponly.c scponly-4.8/scponly.c
  148. --- scponly-4.8.orig/scponly.c 2008-01-15 15:28:24.000000000 +0900
  149. +++ scponly-4.8/scponly.c 2009-03-18 21:29:48.000000000 +0900
  150. @@ -91,16 +91,18 @@
  151. #ifdef RSYNC_COMPAT
  152. struct option rsync_longopts[] = {
  153. + /* options we need to know about that are safe */
  154. + {"server", 0, 0, (int)'s'},
  155. /* I use 'e' for val here because that's what's listed in cmd_arg_t->badarg */
  156. - {"rsh", 1, 0, (int)'e'},
  157. + {"rsh", 1, 0, (int)'r'},
  158. /* the following are disabled because they use daemon mode */
  159. - {"daemon", 0, 0, (int)'e'},
  160. - {"rsync-path", 1, 0, (int)'e'},
  161. - {"address", 1, 0, (int)'e'},
  162. - {"port", 1, 0, (int)'e'},
  163. - {"sockopts", 1, 0, (int)'e'},
  164. - {"config", 1, 0, (int)'e'},
  165. - {"no-detach", 0, 0, (int)'e'},
  166. + {"daemon", 0, 0, (int)'d'},
  167. + {"rsync-path", 1, 0, (int)'d'},
  168. + {"address", 1, 0, (int)'d'},
  169. + {"port", 1, 0, (int)'d'},
  170. + {"sockopts", 1, 0, (int)'d'},
  171. + {"config", 1, 0, (int)'d'},
  172. + {"no-detach", 0, 0, (int)'d'},
  173. { NULL, 0, NULL, 0 },
  174. };
  175. #endif
  176. @@ -157,7 +159,7 @@
  177. { PROG_SCP, 1, 1, "SoF", "dfl:prtvBCc:i:P:q1246S:o:F:", empty_longopts },
  178. #endif
  179. #ifdef RSYNC_COMPAT
  180. - { PROG_RSYNC, 1, 0, "e", "e:", rsync_longopts },
  181. + { PROG_RSYNC, 1, 0, "rde", "e::", rsync_longopts },
  182. #endif
  183. #ifdef UNISON_COMPAT
  184. { PROG_UNISON, 0, 0, "-rshcmd", NULL, empty_longopts },
  185. diff -Naur scponly-4.8.orig/scponly.h scponly-4.8/scponly.h
  186. --- scponly-4.8.orig/scponly.h 2008-01-15 15:26:13.000000000 +0900
  187. +++ scponly-4.8/scponly.h 2009-03-18 21:29:48.000000000 +0900
  188. @@ -1,6 +1,9 @@
  189. #include <stdio.h> /* FILENAME_MAX */
  190. -#include <getopt.h> /* struct option */
  191. -#include "config.h"
  192. +#include "config.h" /* include before most other files */
  193. +
  194. +#ifdef HAVE_GETOPT_H
  195. +#include <getopt.h> /* for struct option for getopt */
  196. +#endif
  197. #define MAX_USERNAME 32
  198. #define MAX_REQUEST (1024) /* any request exceeding this is truncated */