Scott Ehas <scott.e...@gigenet.com> writes:
> I am unable to find any documentation on the Rsync functions for RSSH.
> Every time I try to Rsync with the RSSH I get a "insecure -e option now
> allowed". I was wondering if you can spot the problem and review the
> output below. Please let me know if you can provide any help.
You need patches in order to work with the latest rsync. They reused the
-e option in a very unfortunate way to specify protocol information, and
it's quite tricky to ensure that the running command is still secure.
Debian (and I believe some others) are using the attached, which is
against 2.3.4. (I would point you to the Debian patch tracker, but it's
down at the moment; the link at:
http://patch-tracker.debian.org/package/rssh/2.3.3-6
has the patch set against 2.3.3, which includes the security fix in 2.3.4,
but that's not as clean as the patches based on 2.3.4 directly.)
--
Russ Allbery (r...@stanford.edu) <http://www.eyrie.org/~eagle/>
From: Russ Allbery <r...@stanford.edu>
Subject: [PATCH] Handle the rsync v3 -e option for protocol information
As of rsync 3, rsync reused the -e option to pass protocol information
from the client to the server. We therefore cannot reject all -e
options to rsync, only ones not sent with --server or containing
something other than protocol information as an argument.
Also scan the rsync command line for any --rsh option and reject it as
well. This replaces and improves the upstream strategy for rejecting
that command-line option, taking advantage of the parsing added to
check the -e option.
Based on work by Robert Hardy.
Debian Bug#471803
Signed-off-by: Russ Allbery <r...@stanford.edu>
---
util.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 72 insertions(+), 8 deletions(-)
diff --git a/util.c b/util.c
index f98d2bc..a257b06 100644
--- a/util.c
+++ b/util.c
@@ -56,6 +56,7 @@
#ifdef HAVE_LIBGEN_H
#include <libgen.h>
#endif /* HAVE_LIBGEN_H */
+#include <regex.h>
/* LOCAL INCLUDES */
#include "pathnames.h"
@@ -198,6 +199,73 @@ bool check_command( char *cl, ShellOptions_t *opts, char *cmd, int cmdflag )
/*
+ * rsync_e_okay() - take the command line passed to rssh and look for an -e
+ * option. If one is found, make sure --server is provided
+ * and the option contains only the protocol information.
+ * Also check for and reject any --rsh option. Returns FALSE
+ * if the command line should not be allowed, TRUE if it is
+ * okay.
+ */
+static int rsync_e_okay( char **vec )
+{
+ regex_t re;
+ int server = FALSE;
+ int e_found = FALSE;
+
+ /*
+ * rsync will send -e, followed by either just "." (meaning no special
+ * protocol) or "N.N" (meaning a pre-release protocol version),
+ * followed by some number of alphabetic flags indicating various
+ * supported options. There may be other options between - and the e,
+ * but -e will always be the last option in the string. A typical
+ * option passed by the client is "-ltpre.iL".
+ *
+ * Note that if --server is given, this should never be parsed as a
+ * shell, but we'll tightly verify it anyway, just in case.
+ *
+ * This regex matches the acceptable flags containing -e, so if it
+ * does not match, the command line should be rejected.
+ */
+ static const char pattern[]
+ = "^-[a-df-zA-Z]*e[0-9]*\\.[0-9]*[a-zA-Z]*$";
+
+ /*
+ * Only recognize --server if it's the first option. rsync itself
+ * always passes it that way, and if it's not the first argument, it
+ * could be hidden from the server as an argument to some other
+ * option.
+ */
+ if ( vec && vec[0] && vec[1] && strcmp(vec[1], "--server") == 0 ){
+ server = TRUE;
+ }
+
+ /* Check the remaining options for -e or --rsh. */
+ if ( regcomp(&re, pattern, REG_EXTENDED | REG_NOSUB) != 0 ){
+ return FALSE;
+ }
+ while (vec && *vec){
+ if ( strcmp(*vec, "--") == 0 ) break;
+ if ( strcmp(*vec, "--rsh") == 0
+ || strncmp(*vec, "--rsh=", strlen("--rsh=")) == 0 ){
+ regfree(&re);
+ return FALSE;
+ }
+ if ( strncmp(*vec, "--", 2) != 0 && opt_exist(*vec, 'e') ){
+ e_found = TRUE;
+ if ( regexec(&re, *vec, 0, NULL, 0) != 0 ){
+ regfree(&re);
+ return FALSE;
+ }
+ }
+ vec++;
+ }
+ regfree(&re);
+ if ( e_found && !server ) return FALSE;
+ return TRUE;
+}
+
+
+/*
* check_command_line() - take the command line passed to rssh, and verify
* that the specified command is one the user is
* allowed to run and validate the arguments. Return the
@@ -230,14 +298,10 @@ char *check_command_line( char **cl, ShellOptions_t *opts )
if ( check_command(*cl, opts, PATH_RSYNC, RSSH_ALLOW_RSYNC) ){
/* filter -e option */
- if ( opt_filter(cl, 'e') ) return NULL;
- while (cl && *cl){
- if ( strstr(*cl, "--rsh" ) ){
- fprintf(stderr, "\ninsecure --rsh= not allowed.");
- log_msg("insecure --rsh option in rsync command line!");
- return NULL;
- }
- cl++;
+ if ( !rsync_e_okay(cl) ){
+ fprintf(stderr, "\ninsecure -e or --rsh option not allowed.");
+ log_msg("insecure -e or --rsh option in rsync command line!");
+ return NULL;
}
return PATH_RSYNC;
}
--
tg: (f8b36e2..) fixes/rsync-protocol (depends on: upstream)
------------------------------------------------------------------------------
Get 100% visibility into Java/.NET code with AppDynamics Lite!
It's a free troubleshooting tool designed for production.
Get down to code-level detail for bottlenecks, with <2% overhead.
Download for free and get started troubleshooting in minutes.
http://pubads.g.doubleclick.net/gampad/clk?id=48897031&iu=/4140/ostg.clktrk
_______________________________________________
rssh-discuss mailing list
rssh-discuss@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/rssh-discuss