[PATCH] supporting a remote scp path option in scp

David Leach dlssh at leach.net.au
Wed Sep 1 03:23:41 EST 2004


Hi there,

I've written some enhancements to scp.c and pathnames.h to enable the scp
to arbitrarily set the remote scp path.
(eg $ scp -e /usr/bin/scp foo user at bar:foo)

I did read the "scp: command not found" FAQ entry but I'm not quite sure
why we can't do this, unless it's because enhancements to scp are no
longer a priority.  Any other reason why it "is the way it is" other than
that?

The patch is below, all I've really done is replaced char cmd[CMDNEEDS]
with char *rspcmd throughout.  Forgive any dodgy coding, I'm not a
developer during the day :).  I haven't been able to test the patch below
because I don't have a handy openbsd box, I have tested a patch under the
portable version that seems to work fine.  Let me know if I'm better off
providing that.

My reason for wanting is that it means server side scripts that wrap
around forced commands can tie scp down to the absolute path. 
Incidentally, if there is a reason why anyone thinks this is a bad idea,
please let me know.

Regards,

David.

--- pathnames.h Mon Jul 12 01:48:47 2004
+++ pathnames.h Wed Sep  1 00:48:12 2004
@@ -45,6 +45,8 @@
  */
 #define _PATH_SSH_DAEMON_PID_FILE      _PATH_SSH_PIDDIR "/sshd.pid"

+#define _PATH_SCP_REMOTE_PROGRAM       "/usr/bin/scp"
+
 /*
  * The directory in user\'s home directory in which the files reside. The
  * directory should be world-readable (though not all files are).
--- scp.c       Thu Aug 12 05:44:32 2004
+++ scp.c       Wed Sep  1 00:48:51 2004
@@ -102,6 +102,9 @@
 /* This is the program to execute for the secured connection. ("ssh" or
-S) */
 char *ssh_program = _PATH_SSH_PROGRAM;

+/* This is the program to execute for the remote scp. ("scp" or -e) */
+char *scp_remote_program = _PATH_SCP_REMOTE_PROGRAM;
+
 /* This is used to store the pid of ssh_program */
 pid_t do_cmd_pid = -1;

@@ -198,8 +201,8 @@
 int errs, remin, remout;
 int pflag, iamremote, iamrecursive, targetshouldbedirectory;

-#define        CMDNEEDS        64
-char cmd[CMDNEEDS];            /* must hold "rcp -r -p -d\0" */
+char *rscpcmd;           /* must hold scp_remote_program + "-r -p -d\0" */
+

 int response(void);
 void rsource(char *, struct stat *);
@@ -212,12 +215,13 @@
 int
 main(int argc, char **argv)
 {
-       int ch, fflag, tflag, status;
+       int ch, fflag, tflag, status, rscpcmdlen;
        double speed;
        char *targ, *endp;
        extern char *optarg;
        extern int optind;

+        rscpcmdlen = 1;
        args.list = NULL;
        addargs(&args, "ssh");          /* overwritten with ssh_program */
        addargs(&args, "-x");
@@ -225,7 +229,7 @@
        addargs(&args, "-oClearAllForwardings yes");

        fflag = tflag = 0;
-       while ((ch = getopt(argc, argv, "dfl:prtvBCc:i:P:q1246S:o:F:")) !=
-1)
+       while ((ch = getopt(argc, argv, "dfl:prtvBCc:i:P:q1246S:o:F:e:"))
!= -1)
                switch (ch) {
                /* User-visible flags. */
                case '1':
@@ -255,9 +259,14 @@
                        break;
                case 'p':
                        pflag = 1;
+                        rscpcmdlen += 3;
                        break;
                case 'r':
                        iamrecursive = 1;
+                        rscpcmdlen += 3;
+                       break;
+               case 'e':
+                       scp_remote_program = xstrdup(optarg);
                        break;
                case 'S':
                        ssh_program = xstrdup(optarg);
@@ -265,6 +274,7 @@
                case 'v':
                        addargs(&args, "-v");
                        verbose_mode = 1;
+                        rscpcmdlen += 3;
                        break;
                case 'q':
                        addargs(&args, "-q");
@@ -274,6 +284,7 @@
                /* Server options. */
                case 'd':
                        targetshouldbedirectory = 1;
+                        rscpcmdlen += 3;
                        break;
                case 'f':       /* "from" */
                        iamremote = 1;
@@ -316,8 +327,11 @@

        remin = remout = -1;
        do_cmd_pid = -1;
+        rscpcmdlen += strlen(scp_remote_program);
+        rscpcmd = xmalloc(rscpcmdlen);
        /* Command to be executed on remote system using "ssh". */
-       (void) snprintf(cmd, sizeof cmd, "scp%s%s%s%s",
+       (void) snprintf(rscpcmd, rscpcmdlen, "%s%s%s%s%s",
+            scp_remote_program,
            verbose_mode ? " -v" : "",
            iamrecursive ? " -r" : "", pflag ? " -p" : "",
            targetshouldbedirectory ? " -d" : "");
@@ -347,6 +361,7 @@
                                errs = 1;
                }
        }
+        xfree(rscpcmd);
        exit(errs != 0);
 }

@@ -383,7 +398,7 @@
                        len = strlen(ssh_program) + strlen(argv[i]) +
                            strlen(src) + (tuser ? strlen(tuser) : 0) +
                            strlen(thost) + strlen(targ) +
-                           strlen(ssh_options) + CMDNEEDS + 20;
+                           strlen(ssh_options) + strlen(rscpcmd) + 20;
                        bp = xmalloc(len);
                        if (host) {
                                *host++ = 0;
@@ -403,7 +418,7 @@
                                    "%s%s %s -n "
                                    "-l %s %s %s %s '%s%s%s:%s'",
                                    ssh_program, verbose_mode ? " -v" : "",
-                                   ssh_options, suser, host, cmd, src,
+                                   ssh_options, suser, host, rscpcmd, src,
                                    tuser ? tuser : "", tuser ? "@" : "",
                                    thost, targ);
                        } else {
@@ -412,7 +427,7 @@
                                    "exec %s%s %s -n %s "
                                    "%s %s '%s%s%s:%s'",
                                    ssh_program, verbose_mode ? " -v" : "",
-                                   ssh_options, host, cmd, src,
+                                   ssh_options, host, rscpcmd, src,
                                    tuser ? tuser : "", tuser ? "@" : "",
                                    thost, targ);
                        }
@@ -423,9 +438,9 @@
                        (void) xfree(bp);
                } else {        /* local to remote */
                        if (remin == -1) {
-                               len = strlen(targ) + CMDNEEDS + 20;
+                               len = strlen(targ) + strlen(rscpcmd) + 20;
                                bp = xmalloc(len);
-                               (void) snprintf(bp, len, "%s -t %s", cmd,
targ);
+                               (void) snprintf(bp, len, "%s -t %s",
rscpcmd, targ);
                                host = cleanhostname(thost);
                                if (do_cmd(host, tuser, bp, &remin,
                                    &remout, argc) < 0)
@@ -473,9 +488,9 @@
                                suser = pwd->pw_name;
                }
                host = cleanhostname(host);
-               len = strlen(src) + CMDNEEDS + 20;
+               len = strlen(src) + strlen(rscpcmd) + 20;
                bp = xmalloc(len);
-               (void) snprintf(bp, len, "%s -f %s", cmd, src);
+               (void) snprintf(bp, len, "%s -f %s", rscpcmd, src);
                if (do_cmd(host, suser, bp, &remin, &remout, argc) < 0) {
                        (void) xfree(bp);
                        ++errs;
@@ -1013,7 +1028,7 @@
 {
        (void) fprintf(stderr,
            "usage: scp [-1246BCpqrv] [-c cipher] [-F ssh_config] [-i
identity_file]\n"
-           "           [-l limit] [-o ssh_option] [-P port] [-S program]\n"
+           "           [-l limit] [-o ssh_option] [-P port] [-S program]
[-e program]\n"
            "           [[user@]host1:]file1 [...] [[user@]host2:]file2\n");
        exit(1);
 }




More information about the openssh-unix-dev mailing list