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