From: djm Date: Mon, 9 Aug 2021 07:13:54 +0000 (+0000) Subject: on fatal errors, make scp wait for ssh connection before exiting X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=88ae96e01b50eaa566c5c4c2343df71849f3a636;p=openbsd on fatal errors, make scp wait for ssh connection before exiting avoids LogLevel=verbose (or greater) messages from ssh appearing after scp has returned exited and control has returned to the shell; ok markus@ --- diff --git a/usr.bin/ssh/scp.c b/usr.bin/ssh/scp.c index 6a39bdb59ee..53c5225ad41 100644 --- a/usr.bin/ssh/scp.c +++ b/usr.bin/ssh/scp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: scp.c,v 1.222 2021/08/07 01:57:08 dtucker Exp $ */ +/* $OpenBSD: scp.c,v 1.223 2021/08/09 07:13:54 djm Exp $ */ /* * scp - secure remote copy. This is basically patched BSD rcp which * uses ssh to do the data transfer (instead of using rcmd). @@ -139,7 +139,7 @@ int showprogress = 1; * This is set to non-zero if remote-remote copy should be piped * through this process. */ -int throughlocal = 0; +int throughlocal = 1; /* Non-standard port to use for the ssh connection or -1. */ int sshport = -1; @@ -422,8 +422,7 @@ main(int argc, char **argv) const char *errstr; extern char *optarg; extern int optind; - /* For now, keep SCP as default */ - enum scp_mode_e mode = MODE_SCP; + enum scp_mode_e mode = MODE_SFTP; char *sftp_direct = NULL; /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ @@ -452,7 +451,7 @@ main(int argc, char **argv) fflag = Tflag = tflag = 0; while ((ch = getopt(argc, argv, - "12346ABCTdfpqrtvD:F:J:M:P:S:c:i:l:o:")) != -1) { + "12346ABCORTdfpqrtvD:F:J:P:S:c:i:l:o:")) != -1) { switch (ch) { /* User-visible flags. */ case '1': @@ -474,6 +473,9 @@ main(int argc, char **argv) case '3': throughlocal = 1; break; + case 'R': + throughlocal = 0; + break; case 'o': case 'c': case 'i': @@ -484,6 +486,9 @@ main(int argc, char **argv) addargs(&args, "-%c", ch); addargs(&args, "%s", optarg); break; + case 'O': + mode = MODE_SCP; + break; case 'P': sshport = a2port(optarg); if (sshport <= 0) @@ -493,14 +498,6 @@ main(int argc, char **argv) addargs(&remote_remote_args, "-oBatchmode=yes"); addargs(&args, "-oBatchmode=yes"); break; - case 'M': - if (strcmp(optarg, "sftp") == 0) - mode = MODE_SFTP; - else if (strcmp(optarg, "scp") == 0) - mode = MODE_SCP; - else - usage(); - break; case 'l': limit_kbps = strtonum(optarg, 1, 100 * 1024 * 1024, &errstr); @@ -1220,6 +1217,29 @@ tolocal(int argc, char **argv, enum scp_mode_e mode, char *sftp_direct) free(src); } +/* Canonicalise a remote path, handling ~ by assuming cwd is the homedir */ +static char * +absolute_remote_path(const char *path, const char *remote_path) +{ + char *ret; + + /* Handle ~ prefixed paths */ + if (*path != '~') + ret = xstrdup(path); + else { + if (strcmp(path, "~") == 0) + ret = xstrdup(""); + else if (strncmp(path, "~/", 2) == 0) + ret = xstrdup(path + 2); + else { + /* XXX could be supported with protocol extension */ + error("~user paths are not currently supported"); + return NULL; + } + } + return make_absolute(ret, remote_path); +} + void source_sftp(int argc, char *src, char *targ, struct sftp_conn *conn, char **remote_path) @@ -1240,8 +1260,8 @@ source_sftp(int argc, char *src, char *targ, * No need to glob here - the local shell already took care of * the expansions */ - target = xstrdup(targ); - target = make_absolute(target, *remote_path); + if ((target = absolute_remote_path(targ, *remote_path)) == NULL) + cleanup_exit(255); target_is_dir = remote_is_dir(conn, target); if (targetshouldbedirectory && !target_is_dir) { fatal("Target is not a directory, but more files selected " @@ -1438,6 +1458,7 @@ sink_sftp(int argc, char *dst, const char *src, struct sftp_conn *conn) char *filename, *tmp = NULL, *remote_path = NULL; int i, r, err = 0; + memset(&g, 0, sizeof(g)); /* * Here, we need remote glob as SFTP can not depend on remote shell * expansions @@ -1451,10 +1472,11 @@ sink_sftp(int argc, char *dst, const char *src, struct sftp_conn *conn) goto out; } - abs_src = xstrdup(src); - abs_src = make_absolute(abs_src, remote_path); + if ((abs_src = absolute_remote_path(src, remote_path)) == NULL) { + err = -1; + goto out; + } free(remote_path); - memset(&g, 0, sizeof(g)); debug3_f("copying remote %s to local %s", abs_src, dst); if ((r = remote_glob(conn, abs_src, GLOB_MARK, NULL, &g)) != 0) { @@ -1854,11 +1876,10 @@ throughlocal_sftp(struct sftp_conn *from, struct sftp_conn *to, if ((filename = basename(src)) == NULL) fatal("basename %s: %s", src, strerror(errno)); - abs_src = xstrdup(src); - abs_src = make_absolute(abs_src, from_remote_path); + if ((abs_src = absolute_remote_path(src, from_remote_path)) == NULL || + (target = absolute_remote_path(targ, *to_remote_path)) == NULL) + cleanup_exit(255); free(from_remote_path); - target = xstrdup(targ); - target = make_absolute(target, *to_remote_path); memset(&g, 0, sizeof(g)); targetisdir = remote_is_dir(to, target); @@ -1959,9 +1980,9 @@ void usage(void) { (void) fprintf(stderr, - "usage: scp [-346ABCpqrTv] [-c cipher] [-D sftp_server_path] [-F ssh_config]\n" - " [-i identity_file] [-J destination] [-l limit] [-M scp|sftp]\n" - " [-o ssh_option] [-P port] [-S program] source ... target\n"); + "usage: scp [-346ABCOpqrTv] [-c cipher] [-D sftp_server_path] [-F ssh_config]\n" + " [-i identity_file] [-J destination] [-l limit] [-o ssh_option]\n" + " [-P port] [-S program] source ... target\n"); exit(1); } @@ -2096,3 +2117,21 @@ lostconn(int signo) else exit(1); } + +void +cleanup_exit(int i) +{ + if (remin > 0) + close(remin); + if (remout > 0) + close(remout); + if (remin2 > 0) + close(remin2); + if (remout2 > 0) + close(remout2); + if (do_cmd_pid > 0) + waitpid(do_cmd_pid, NULL, 0); + if (do_cmd_pid2 > 0) + waitpid(do_cmd_pid2, NULL, 0); + exit(i); +} diff --git a/usr.bin/ssh/scp/Makefile b/usr.bin/ssh/scp/Makefile index 705f59af796..8e2d11b114b 100644 --- a/usr.bin/ssh/scp/Makefile +++ b/usr.bin/ssh/scp/Makefile @@ -1,9 +1,9 @@ -# $OpenBSD: Makefile,v 1.22 2021/08/02 23:38:27 djm Exp $ +# $OpenBSD: Makefile,v 1.23 2021/08/09 07:13:54 djm Exp $ .PATH: ${.CURDIR}/.. SRCS= scp.c -SRCS+= atomicio.c cleanup.c fatal.c progressmeter.c utf8.c +SRCS+= fatal.c atomicio.c progressmeter.c utf8.c SRCS+= sftp-common.c sftp-client.c sftp-glob.c SRCS+= ${SRCS_BASE}