Link Here
|
1 |
--- util.c.orig 2012-11-27 12:14:49.000000000 +1100 |
1 |
Verifies the command line options for rysnc. This is an updated version that |
2 |
+++ util.c 2013-01-09 17:52:54.000000000 +1100 |
2 |
tightens the argument checking and requires to run rsync in server mode. |
|
|
3 |
Taken from Debian ("0007-Verify-rsync-command-options"). |
4 |
--- util.c.orig 2012-11-27 01:14:49 UTC |
5 |
+++ util.c |
3 |
@@ -56,6 +56,7 @@ |
6 |
@@ -56,6 +56,7 @@ |
4 |
#ifdef HAVE_LIBGEN_H |
7 |
#ifdef HAVE_LIBGEN_H |
5 |
#include <libgen.h> |
8 |
#include <libgen.h> |
Link Here
|
8 |
|
11 |
|
9 |
/* LOCAL INCLUDES */ |
12 |
/* LOCAL INCLUDES */ |
10 |
#include "pathnames.h" |
13 |
#include "pathnames.h" |
11 |
@@ -198,6 +199,73 @@ |
14 |
@@ -198,6 +199,71 @@ bool check_command( char *cl, ShellOptions_t *opts, ch |
12 |
|
15 |
|
13 |
|
16 |
|
14 |
/* |
17 |
/* |
15 |
+ * rsync_e_okay() - take the command line passed to rssh and look for an -e |
18 |
+ * rsync_okay() - require --server on all rsh command lines, check that -e |
16 |
+ * option. If one is found, make sure --server is provided |
19 |
+ * contains only protocol information, and reject any --rsh, |
17 |
+ * and the option contains only the protocol information. |
20 |
+ * --config, or --daemon option. Returns FALSE if the command |
18 |
+ * Also check for and reject any --rsh option. Returns FALSE |
21 |
+ * line should not be allowed, TRUE if it is okay. |
19 |
+ * if the command line should not be allowed, TRUE if it is |
|
|
20 |
+ * okay. |
21 |
+ */ |
22 |
+ */ |
22 |
+static int rsync_e_okay( char **vec ) |
23 |
+static int rsync_okay( char **vec ) |
23 |
+{ |
24 |
+{ |
24 |
+ regex_t re; |
25 |
+ regex_t re; |
25 |
+ int server = FALSE; |
26 |
+ int server = FALSE; |
Link Here
|
48 |
+ * could be hidden from the server as an argument to some other |
49 |
+ * could be hidden from the server as an argument to some other |
49 |
+ * option. |
50 |
+ * option. |
50 |
+ */ |
51 |
+ */ |
51 |
+ if ( vec && vec[0] && vec[1] && strcmp(vec[1], "--server") == 0 ){ |
52 |
+ if ( !(vec && vec[0] && vec[1] && strcmp(vec[1], "--server") == 0) ) |
52 |
+ server = TRUE; |
53 |
+ return FALSE; |
53 |
+ } |
|
|
54 |
+ |
54 |
+ |
55 |
+ /* Check the remaining options for -e or --rsh. */ |
55 |
+ /* Check the remaining options for -e or --rsh. */ |
56 |
+ if ( regcomp(&re, pattern, REG_EXTENDED | REG_NOSUB) != 0 ){ |
56 |
+ if ( regcomp(&re, pattern, REG_EXTENDED | REG_NOSUB) != 0 ){ |
Link Here
|
57 |
+ return FALSE; |
57 |
+ return FALSE; |
58 |
+ } |
58 |
+ } |
59 |
+ while (vec && *vec){ |
59 |
+ while (vec && *vec){ |
60 |
+ if ( strcmp(*vec, "--") == 0 ) break; |
|
|
61 |
+ if ( strcmp(*vec, "--rsh") == 0 |
60 |
+ if ( strcmp(*vec, "--rsh") == 0 |
62 |
+ || strncmp(*vec, "--rsh=", strlen("--rsh=")) == 0 ){ |
61 |
+ || strcmp(*vec, "--daemon") == 0 |
|
|
62 |
+ || strcmp(*vec, "--config") == 0 |
63 |
+ || strncmp(*vec, "--rsh=", strlen("--rsh=")) == 0 |
64 |
+ || strncmp(*vec, "--config=", strlen("--config=")) == 0 ){ |
63 |
+ regfree(&re); |
65 |
+ regfree(&re); |
64 |
+ return FALSE; |
66 |
+ return FALSE; |
65 |
+ } |
67 |
+ } |
Link Here
|
73 |
+ vec++; |
75 |
+ vec++; |
74 |
+ } |
76 |
+ } |
75 |
+ regfree(&re); |
77 |
+ regfree(&re); |
76 |
+ if ( e_found && !server ) return FALSE; |
|
|
77 |
+ return TRUE; |
78 |
+ return TRUE; |
78 |
+} |
79 |
+} |
79 |
+ |
80 |
+ |
Link Here
|
82 |
* check_command_line() - take the command line passed to rssh, and verify |
83 |
* check_command_line() - take the command line passed to rssh, and verify |
83 |
* that the specified command is one the user is |
84 |
* that the specified command is one the user is |
84 |
* allowed to run and validate the arguments. Return the |
85 |
* allowed to run and validate the arguments. Return the |
85 |
@@ -230,14 +298,10 @@ |
86 |
@@ -229,16 +295,27 @@ char *check_command_line( char **cl, ShellOptions_t *o |
|
|
87 |
} |
86 |
|
88 |
|
87 |
if ( check_command(*cl, opts, PATH_RSYNC, RSSH_ALLOW_RSYNC) ){ |
89 |
if ( check_command(*cl, opts, PATH_RSYNC, RSSH_ALLOW_RSYNC) ){ |
88 |
/* filter -e option */ |
90 |
- /* filter -e option */ |
89 |
- if ( opt_filter(cl, 'e') ) return NULL; |
91 |
- if ( opt_filter(cl, 'e') ) return NULL; |
90 |
- while (cl && *cl){ |
92 |
- while (cl && *cl){ |
91 |
- if ( strstr(*cl, "--rsh" ) ){ |
93 |
- if ( strstr(*cl, "--rsh" ) ){ |
Link Here
|
94 |
- return NULL; |
96 |
- return NULL; |
95 |
- } |
97 |
- } |
96 |
- cl++; |
98 |
- cl++; |
97 |
+ if ( !rsync_e_okay(cl) ){ |
99 |
+ if ( !rsync_okay(cl) ){ |
98 |
+ fprintf(stderr, "\ninsecure -e or --rsh option not allowed."); |
100 |
+ fprintf(stderr, "\ninsecure rsync options not allowed."); |
99 |
+ log_msg("insecure -e or --rsh option in rsync command line!"); |
101 |
+ log_msg("insecure rsync options in rsync command line!"); |
100 |
+ return NULL; |
102 |
+ return NULL; |
101 |
} |
103 |
} |
|
|
104 |
+ |
105 |
+ /* |
106 |
+ * rsync is linked with popt, which recognizes a configuration |
107 |
+ * file ~/.popt that can, among other things, define aliases. |
108 |
+ * If someone can write to the home directory of the rssh |
109 |
+ * user, they can upload a ~/.popt file that contains |
110 |
+ * something like "rsync alias --server --rsh" and then |
111 |
+ * execute commands they upload. popt does not try to read |
112 |
+ * its configuration file if HOME is not set, so unset HOME to |
113 |
+ * disable this behavior. |
114 |
+ */ |
115 |
+ if ( unsetenv("HOME") < 0 ){ |
116 |
+ log_msg("cannot unsetenv() HOME"); |
117 |
+ return NULL; |
118 |
+ } |
119 |
+ |
102 |
return PATH_RSYNC; |
120 |
return PATH_RSYNC; |
103 |
} |
121 |
} |
|
|
122 |
/* No match, return NULL */ |