summaryrefslogtreecommitdiff
path: root/extra/rssh/rsync.patch
blob: 7d0a511950878254eeb50040230421aa84f152c1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
diff -Naur old/util.c new/util.c
--- old/util.c	2012-08-01 13:48:47.803620731 +1000
+++ new/util.c	2012-08-01 13:55:13.622614598 +1000
@@ -56,6 +56,7 @@
 #ifdef HAVE_LIBGEN_H
 #include <libgen.h>
 #endif /* HAVE_LIBGEN_H */
+#include <regex.h>
 
 /* LOCAL INCLUDES */
 #include "pathnames.h"
@@ -192,6 +193,33 @@
 
 
 /*
+ * check_rsync_e() - take the command line passed to rssh and look for a -e
+ *                   option.  If one is found, make sure --server is provided
+ *                   and the option contains only the protocol information.
+ *                   Returns 1 if the command line is safe; 0 otherwise.
+ */
+static int check_rsync_e( char *cl )
+{
+	int	status;
+	regex_t	re;
+
+	/*
+	 * This is more complicated than it looks because we don't want to
+	 * trigger on the e in --server, but we do want to catch the common
+	 * case of -ltpre.iL (which contains -e.).
+	 */
+	static const char pattern[] = "[ \t\v\f]-([^-][^ ]*)?e[^.0-9]";
+
+	if ( strstr(cl, "--server") == NULL ) return 0;
+	if ( regcomp(&re, pattern, REG_EXTENDED | REG_NOSUB) != 0 ){
+		return 0;
+	}
+	status = regexec(&re, cl, 0, NULL, 0);
+	regfree(&re);
+	return (status == 0) ? 0 : 1;
+}
+
+/*
  * 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
@@ -211,7 +239,7 @@
 	}
 
 	if ( check_command(*cl, opts, PATH_CVS, RSSH_ALLOW_CVS) ){
-		if ( opt_filter(cl, 'e') ) return NULL;
+		if ( opt_filter(cl, 'e') && !check_rsync_e(cl) ) return NULL;
 		return PATH_CVS;
 	}