Implement `pscp-select-backend'.
authorjacob <jacob@cda61777-01e9-0310-a592-d414129be87e>
Sun, 25 Apr 2004 22:18:19 +0000 (22:18 +0000)
committerjacob <jacob@cda61777-01e9-0310-a592-d414129be87e>
Sun, 25 Apr 2004 22:18:19 +0000 (22:18 +0000)
git-svn-id: svn://svn.tartarus.org/sgt/putty@4142 cda61777-01e9-0310-a592-d414129be87e

doc/pscp.but
scp.c

index c4ccc64..c69b022 100644 (file)
@@ -1,4 +1,4 @@
-\versionid $Id: pscp.but,v 1.26 2004/04/24 12:25:08 jacob Exp $
+\versionid $Id: pscp.but,v 1.27 2004/04/25 22:18:19 jacob Exp $
 
 \#FIXME: Need examples
 
@@ -60,6 +60,8 @@ use PSCP:
 \c   -batch    disable all interactive prompts
 \c   -unsafe   allow server-side wildcards (DANGEROUS)
 \c   -V        print version information
+\c   -scp      force use of SCP protocol
+\c   -sftp     force use of SFTP protocol
 
 (PSCP's interface is much like the Unix \c{scp} command, if you're
 familiar with that.)
@@ -113,7 +115,8 @@ pattern.
 PSCP will attempt to use the newer SFTP protocol (part of SSH 2)
 where possible, which does not suffer from this security flaw. If
 you are talking to an SSH 2 server which supports SFTP, you will
-never see this warning.
+never see this warning. (You can force use of the SFTP protocol,
+if available, with \c{-sftp} - see \k{pscp-usage-options-backend}.)
 
 If you really need to use a server-side wildcard with an SSH 1
 server, you can use the \c{-unsafe} command line option with PSCP:
@@ -222,6 +225,36 @@ This may help PSCP's behaviour when it is used in automated
 scripts: using \c{-batch}, if something goes wrong at connection
 time, the batch job will fail rather than hang.
 
+\S2{pscp-usage-options-backend}\c{-sftp}, \c{-scp} force use of
+particular protocol
+
+As mentioned in \k{pscp-usage-basics}, there are two different file
+transfer protocols in use with SSH. Despite its name, PSCP (like many
+other ostensible \cw{scp} clients) can use either of these protocols.
+
+The older SCP protocol does not have a written specification and
+leaves a lot of detail to the server platform. Wildcards are expanded
+on the server. The simple design means that any wildcard specification
+supported by the server platform (such as brace expansion) can be
+used, but also leads to interoperability issues such as with filename
+quoting (for instance, where filenames contain spaces), and also the
+security issue described in \k{pscp-usage-basics}.
+
+The newer SFTP protocol, which is usually associated with SSH 2
+servers, is specified in a more platform independent way, and leaves
+issues such as wildcard syntax up to the client. This makes it more
+consistent across platforms, more suitable for scripting and
+automation, and avoids security issues with wilcard matching.
+
+Normally PSCP will attempt to use the SFTP protocol, and only fall
+back to the SCP protocol if SFTP is not available on the server.
+
+The \c{-scp} option forces PSCP to use the SCP protocol or quit.
+
+The \c{-sftp} option forces PSCP to use the SFTP protocol or quit.
+When this option is specified, PSCP looks harder for an SFTP server,
+which may allow use of SFTP with SSH 1 depending on server setup.
+
 \S{pscp-retval} Return value
 
 PSCP returns an \cw{ERRORLEVEL} of zero (success) only if the files
diff --git a/scp.c b/scp.c
index f3aa5e0..781e375 100644 (file)
--- a/scp.c
+++ b/scp.c
@@ -36,6 +36,10 @@ static int prev_stats_len = 0;
 static int scp_unsafe_mode = 0;
 static int errs = 0;
 static int gui_mode = 0;
+static int try_scp = 1;
+static int try_sftp = 1;
+static int main_cmd_is_sftp = 0;
+static int fallback_cmd_is_sftp = 0;
 static int using_sftp = 0;
 
 static Backend *back;
@@ -262,7 +266,13 @@ static void ssh_scp_init(void)
        if (ssh_sftp_loop_iteration() < 0)
            return;                    /* doom */
     }
-    using_sftp = !ssh_fallback_cmd(backhandle);
+
+    /* Work out which backend we ended up using. */
+    if (!ssh_fallback_cmd(backhandle))
+       using_sftp = main_cmd_is_sftp;
+    else
+       using_sftp = fallback_cmd_is_sftp;
+
     if (verbose) {
        if (using_sftp)
            tell_user(stderr, "Using SFTP");
@@ -402,13 +412,40 @@ static void do_cmd(char *host, char *user, char *cmd)
     cfg.portfwd[0] = cfg.portfwd[1] = '\0';
 
     /*
+     * Set up main and possibly fallback command depending on
+     * options specified by user.
      * Attempt to start the SFTP subsystem as a first choice,
      * falling back to the provided scp command if that fails.
      */
-    strcpy(cfg.remote_cmd, "sftp");
-    cfg.ssh_subsys = TRUE;
-    cfg.remote_cmd_ptr2 = cmd;
-    cfg.ssh_subsys2 = FALSE;
+    cfg.remote_cmd_ptr2 = NULL;
+    if (try_sftp) {
+       /* First choice is SFTP subsystem. */
+       main_cmd_is_sftp = 1;
+       strcpy(cfg.remote_cmd, "sftp");
+       cfg.ssh_subsys = TRUE;
+       if (try_scp) {
+           /* Fallback is to use the provided scp command. */
+           fallback_cmd_is_sftp = 0;
+           cfg.remote_cmd_ptr2 = cmd;
+           cfg.ssh_subsys2 = FALSE;
+       } else {
+           /* Since we're not going to try SCP, we may as well try
+            * harder to find an SFTP server, since in the current
+            * implementation we have a spare slot. */
+           fallback_cmd_is_sftp = 1;
+           /* see psftp.c for full explanation of this kludge */
+           cfg.remote_cmd_ptr2 = 
+               "test -x /usr/lib/sftp-server && exec /usr/lib/sftp-server\n"
+               "test -x /usr/local/lib/sftp-server && exec /usr/local/lib/sftp-server\n"
+               "exec sftp-server";
+           cfg.ssh_subsys2 = FALSE;
+       }
+    } else {
+       /* Don't try SFTP at all; just try the scp command. */
+       main_cmd_is_sftp = 0;
+       cfg.remote_cmd_ptr = cmd;
+       cfg.ssh_subsys = FALSE;
+    }
     cfg.nopty = TRUE;
 
     back = &ssh_backend;
@@ -2065,6 +2102,8 @@ static void usage(void)
     printf("  -batch    disable all interactive prompts\n");
     printf("  -unsafe   allow server-side wildcards (DANGEROUS)\n");
     printf("  -V        print version information\n");
+    printf("  -sftp     force use of SFTP protocol\n");
+    printf("  -scp      force use of SCP protocol\n");
 #if 0
     /*
      * -gui is an internal option, used by GUI front ends to get
@@ -2148,6 +2187,10 @@ int psftp_main(int argc, char *argv[])
            console_batch_mode = 1;
        } else if (strcmp(argv[i], "-unsafe") == 0) {
            scp_unsafe_mode = 1;
+       } else if (strcmp(argv[i], "-sftp") == 0) {
+           try_scp = 0; try_sftp = 1;
+       } else if (strcmp(argv[i], "-scp") == 0) {
+           try_scp = 1; try_sftp = 0;
        } else if (strcmp(argv[i], "--") == 0) {
            i++;
            break;