9f9d18
Index: subversion/libsvn_ra_svn/client.c
9f9d18
===================================================================
9f9d18
--- subversion/libsvn_ra_svn/client.c	(revision 1803926)
9f9d18
+++ subversion/libsvn_ra_svn/client.c	(working copy)
9f9d18
@@ -46,6 +46,7 @@
9f9d18
 #include "svn_props.h"
9f9d18
 #include "svn_mergeinfo.h"
9f9d18
 #include "svn_version.h"
9f9d18
+#include "svn_ctype.h"
9f9d18
 
9f9d18
 #include "svn_private_config.h"
9f9d18
 
9f9d18
@@ -395,7 +396,7 @@
9f9d18
        * versions have it too. If the user is using some other ssh
9f9d18
        * implementation that doesn't accept it, they can override it
9f9d18
        * in the [tunnels] section of the config. */
9f9d18
-      val = "$SVN_SSH ssh -q";
9f9d18
+      val = "$SVN_SSH ssh -q --";
9f9d18
     }
9f9d18
 
9f9d18
   if (!val || !*val)
9f9d18
@@ -435,7 +436,7 @@
9f9d18
     ;
9f9d18
   *argv = apr_palloc(pool, (n + 4) * sizeof(char *));
9f9d18
   memcpy((void *) *argv, cmd_argv, n * sizeof(char *));
9f9d18
-  (*argv)[n++] = svn_path_uri_decode(hostinfo, pool);
9f9d18
+  (*argv)[n++] = hostinfo;
9f9d18
   (*argv)[n++] = "svnserve";
9f9d18
   (*argv)[n++] = "-t";
9f9d18
   (*argv)[n] = NULL;
9f9d18
@@ -716,7 +717,33 @@
9f9d18
 }
9f9d18
 
9f9d18
 
9f9d18
+/* A simple whitelist to ensure the following are valid:
9f9d18
+ *   user@server
9f9d18
+ *   [::1]:22
9f9d18
+ *   server-name
9f9d18
+ *   server_name
9f9d18
+ *   127.0.0.1
9f9d18
+ * with an extra restriction that a leading '-' is invalid.
9f9d18
+ */
9f9d18
+static svn_boolean_t
9f9d18
+is_valid_hostinfo(const char *hostinfo)
9f9d18
+{
9f9d18
+  const char *p = hostinfo;
9f9d18
 
9f9d18
+  if (p[0] == '-')
9f9d18
+    return FALSE;
9f9d18
+
9f9d18
+  while (*p)
9f9d18
+    {
9f9d18
+      if (!svn_ctype_isalnum(*p) && !strchr(":.-_[]@", *p))
9f9d18
+        return FALSE;
9f9d18
+
9f9d18
+      ++p;
9f9d18
+    }
9f9d18
+
9f9d18
+  return TRUE;
9f9d18
+}
9f9d18
+
9f9d18
 static svn_error_t *ra_svn_open(svn_ra_session_t *session,
9f9d18
                                 const char **corrected_url,
9f9d18
                                 const char *url,
9f9d18
@@ -740,8 +767,17 @@
9f9d18
   parse_tunnel(url, &tunnel, pool);
9f9d18
 
9f9d18
   if (tunnel)
9f9d18
-    SVN_ERR(find_tunnel_agent(tunnel, uri.hostinfo, &tunnel_argv, config,
9f9d18
-                              pool));
9f9d18
+    {
9f9d18
+      const char *decoded_hostinfo;
9f9d18
+
9f9d18
+      decoded_hostinfo = svn_path_uri_decode(uri.hostinfo, pool);
9f9d18
+      if (!is_valid_hostinfo(decoded_hostinfo))
9f9d18
+        return svn_error_createf(SVN_ERR_BAD_URL, NULL, _("Invalid host '%s'"),
9f9d18
+                                 uri.hostinfo);
9f9d18
+
9f9d18
+      SVN_ERR(find_tunnel_agent(tunnel, decoded_hostinfo, &tunnel_argv,
9f9d18
+                                config, pool));
9f9d18
+    }
9f9d18
   else
9f9d18
     tunnel_argv = NULL;
9f9d18
 
9f9d18
Index: subversion/libsvn_subr/config_file.c
9f9d18
===================================================================
9f9d18
--- subversion/libsvn_subr/config_file.c	(revision 1803926)
9f9d18
+++ subversion/libsvn_subr/config_file.c	(working copy)
9f9d18
@@ -1134,12 +1134,12 @@
9f9d18
         "### passed to the tunnel agent as <user>@<hostname>.)  If the"      NL
9f9d18
         "### built-in ssh scheme were not predefined, it could be defined"   NL
9f9d18
         "### as:"                                                            NL
9f9d18
-        "# ssh = $SVN_SSH ssh -q"                                            NL
9f9d18
+        "# ssh = $SVN_SSH ssh -q --"                                         NL
9f9d18
         "### If you wanted to define a new 'rsh' scheme, to be used with"    NL
9f9d18
         "### 'svn+rsh:' URLs, you could do so as follows:"                   NL
9f9d18
-        "# rsh = rsh"                                                        NL
9f9d18
+        "# rsh = rsh --"                                                     NL
9f9d18
         "### Or, if you wanted to specify a full path and arguments:"        NL
9f9d18
-        "# rsh = /path/to/rsh -l myusername"                                 NL
9f9d18
+        "# rsh = /path/to/rsh -l myusername --"                              NL
9f9d18
         "### On Windows, if you are specifying a full path to a command,"    NL
9f9d18
         "### use a forward slash (/) or a paired backslash (\\\\) as the"    NL
9f9d18
         "### path separator.  A single backslash will be treated as an"      NL