Deleted Added
full compact
scp.c (149753) scp.c (157019)
1/*
2 * scp - secure remote copy. This is basically patched BSD rcp which
3 * uses ssh to do the data transfer (instead of using rcmd).
4 *
5 * NOTE: This version should NOT be suid root. (This uses ssh to
6 * do the transfer and ssh has the necessary privileges.)
7 *
8 * 1995 Timo Rinne <tri@iki.fi>, Tatu Ylonen <ylo@cs.hut.fi>

--- 57 unchanged lines hidden (view full) ---

66 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
67 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
68 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
69 * SUCH DAMAGE.
70 *
71 */
72
73#include "includes.h"
1/*
2 * scp - secure remote copy. This is basically patched BSD rcp which
3 * uses ssh to do the data transfer (instead of using rcmd).
4 *
5 * NOTE: This version should NOT be suid root. (This uses ssh to
6 * do the transfer and ssh has the necessary privileges.)
7 *
8 * 1995 Timo Rinne <tri@iki.fi>, Tatu Ylonen <ylo@cs.hut.fi>

--- 57 unchanged lines hidden (view full) ---

66 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
67 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
68 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
69 * SUCH DAMAGE.
70 *
71 */
72
73#include "includes.h"
74RCSID("$OpenBSD: scp.c,v 1.125 2005/07/27 10:39:03 dtucker Exp $");
74RCSID("$OpenBSD: scp.c,v 1.130 2006/01/31 10:35:43 djm Exp $");
75
76#include "xmalloc.h"
77#include "atomicio.h"
78#include "pathnames.h"
79#include "log.h"
80#include "misc.h"
81#include "progressmeter.h"
82

--- 30 unchanged lines hidden (view full) ---

113 waitpid(do_cmd_pid, NULL, 0);
114 }
115
116 if (signo)
117 _exit(1);
118 exit(1);
119}
120
75
76#include "xmalloc.h"
77#include "atomicio.h"
78#include "pathnames.h"
79#include "log.h"
80#include "misc.h"
81#include "progressmeter.h"
82

--- 30 unchanged lines hidden (view full) ---

113 waitpid(do_cmd_pid, NULL, 0);
114 }
115
116 if (signo)
117 _exit(1);
118 exit(1);
119}
120
121static int
122do_local_cmd(arglist *a)
123{
124 u_int i;
125 int status;
126 pid_t pid;
127
128 if (a->num == 0)
129 fatal("do_local_cmd: no arguments");
130
131 if (verbose_mode) {
132 fprintf(stderr, "Executing:");
133 for (i = 0; i < a->num; i++)
134 fprintf(stderr, " %s", a->list[i]);
135 fprintf(stderr, "\n");
136 }
137 if ((pid = fork()) == -1)
138 fatal("do_local_cmd: fork: %s", strerror(errno));
139
140 if (pid == 0) {
141 execvp(a->list[0], a->list);
142 perror(a->list[0]);
143 exit(1);
144 }
145
146 do_cmd_pid = pid;
147 signal(SIGTERM, killchild);
148 signal(SIGINT, killchild);
149 signal(SIGHUP, killchild);
150
151 while (waitpid(pid, &status, 0) == -1)
152 if (errno != EINTR)
153 fatal("do_local_cmd: waitpid: %s", strerror(errno));
154
155 do_cmd_pid = -1;
156
157 if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
158 return (-1);
159
160 return (0);
161}
162
121/*
122 * This function executes the given command as the specified user on the
123 * given host. This returns < 0 if execution fails, and >= 0 otherwise. This
124 * assigns the input and output file descriptors on success.
125 */
126
127int
128do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc)

--- 28 unchanged lines hidden (view full) ---

157 /* Child. */
158 close(pin[1]);
159 close(pout[0]);
160 dup2(pin[0], 0);
161 dup2(pout[1], 1);
162 close(pin[0]);
163 close(pout[1]);
164
163/*
164 * This function executes the given command as the specified user on the
165 * given host. This returns < 0 if execution fails, and >= 0 otherwise. This
166 * assigns the input and output file descriptors on success.
167 */
168
169int
170do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc)

--- 28 unchanged lines hidden (view full) ---

199 /* Child. */
200 close(pin[1]);
201 close(pout[0]);
202 dup2(pin[0], 0);
203 dup2(pout[1], 1);
204 close(pin[0]);
205 close(pout[1]);
206
165 args.list[0] = ssh_program;
207 replacearg(&args, 0, "%s", ssh_program);
166 if (remuser != NULL)
167 addargs(&args, "-l%s", remuser);
168 addargs(&args, "%s", host);
169 addargs(&args, "%s", cmd);
170
171 execvp(ssh_program, args.list);
172 perror(ssh_program);
173 exit(1);

--- 43 unchanged lines hidden (view full) ---

217main(int argc, char **argv)
218{
219 int ch, fflag, tflag, status;
220 double speed;
221 char *targ, *endp;
222 extern char *optarg;
223 extern int optind;
224
208 if (remuser != NULL)
209 addargs(&args, "-l%s", remuser);
210 addargs(&args, "%s", host);
211 addargs(&args, "%s", cmd);
212
213 execvp(ssh_program, args.list);
214 perror(ssh_program);
215 exit(1);

--- 43 unchanged lines hidden (view full) ---

259main(int argc, char **argv)
260{
261 int ch, fflag, tflag, status;
262 double speed;
263 char *targ, *endp;
264 extern char *optarg;
265 extern int optind;
266
267 /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
268 sanitise_stdfd();
269
225 __progname = ssh_get_progname(argv[0]);
226
270 __progname = ssh_get_progname(argv[0]);
271
272 memset(&args, '\0', sizeof(args));
227 args.list = NULL;
273 args.list = NULL;
228 addargs(&args, "ssh"); /* overwritten with ssh_program */
274 addargs(&args, "%s", ssh_program);
229 addargs(&args, "-x");
230 addargs(&args, "-oForwardAgent no");
275 addargs(&args, "-x");
276 addargs(&args, "-oForwardAgent no");
277 addargs(&args, "-oPermitLocalCommand no");
231 addargs(&args, "-oClearAllForwardings yes");
232
233 fflag = tflag = 0;
234 while ((ch = getopt(argc, argv, "dfl:prtvBCc:i:P:q1246S:o:F:")) != -1)
235 switch (ch) {
236 /* User-visible flags. */
237 case '1':
238 case '2':

--- 92 unchanged lines hidden (view full) ---

331 iamrecursive ? " -r" : "", pflag ? " -p" : "",
332 targetshouldbedirectory ? " -d" : "");
333
334 (void) signal(SIGPIPE, lostconn);
335
336 if ((targ = colon(argv[argc - 1]))) /* Dest is remote host. */
337 toremote(targ, argc, argv);
338 else {
278 addargs(&args, "-oClearAllForwardings yes");
279
280 fflag = tflag = 0;
281 while ((ch = getopt(argc, argv, "dfl:prtvBCc:i:P:q1246S:o:F:")) != -1)
282 switch (ch) {
283 /* User-visible flags. */
284 case '1':
285 case '2':

--- 92 unchanged lines hidden (view full) ---

378 iamrecursive ? " -r" : "", pflag ? " -p" : "",
379 targetshouldbedirectory ? " -d" : "");
380
381 (void) signal(SIGPIPE, lostconn);
382
383 if ((targ = colon(argv[argc - 1]))) /* Dest is remote host. */
384 toremote(targ, argc, argv);
385 else {
339 tolocal(argc, argv); /* Dest is local host. */
340 if (targetshouldbedirectory)
341 verifydir(argv[argc - 1]);
386 if (targetshouldbedirectory)
387 verifydir(argv[argc - 1]);
388 tolocal(argc, argv); /* Dest is local host. */
342 }
343 /*
344 * Finally check the exit status of the ssh process, if one was forked
345 * and no error has occured yet
346 */
347 if (do_cmd_pid != -1 && errs == 0) {
348 if (remin != -1)
349 (void) close(remin);

--- 9 unchanged lines hidden (view full) ---

359 exit(errs != 0);
360}
361
362void
363toremote(char *targ, int argc, char **argv)
364{
365 int i, len;
366 char *bp, *host, *src, *suser, *thost, *tuser, *arg;
389 }
390 /*
391 * Finally check the exit status of the ssh process, if one was forked
392 * and no error has occured yet
393 */
394 if (do_cmd_pid != -1 && errs == 0) {
395 if (remin != -1)
396 (void) close(remin);

--- 9 unchanged lines hidden (view full) ---

406 exit(errs != 0);
407}
408
409void
410toremote(char *targ, int argc, char **argv)
411{
412 int i, len;
413 char *bp, *host, *src, *suser, *thost, *tuser, *arg;
414 arglist alist;
367
415
416 memset(&alist, '\0', sizeof(alist));
417 alist.list = NULL;
418
368 *targ++ = 0;
369 if (*targ == 0)
370 targ = ".";
371
372 arg = xstrdup(argv[argc - 1]);
373 if ((thost = strrchr(arg, '@'))) {
374 /* user@host */
375 *thost++ = 0;
376 tuser = arg;
377 if (*tuser == '\0')
378 tuser = NULL;
379 } else {
380 thost = arg;
381 tuser = NULL;
382 }
383
419 *targ++ = 0;
420 if (*targ == 0)
421 targ = ".";
422
423 arg = xstrdup(argv[argc - 1]);
424 if ((thost = strrchr(arg, '@'))) {
425 /* user@host */
426 *thost++ = 0;
427 tuser = arg;
428 if (*tuser == '\0')
429 tuser = NULL;
430 } else {
431 thost = arg;
432 tuser = NULL;
433 }
434
435 if (tuser != NULL && !okname(tuser)) {
436 xfree(arg);
437 return;
438 }
439
384 for (i = 0; i < argc - 1; i++) {
385 src = colon(argv[i]);
386 if (src) { /* remote to remote */
440 for (i = 0; i < argc - 1; i++) {
441 src = colon(argv[i]);
442 if (src) { /* remote to remote */
387 static char *ssh_options =
388 "-x -o'ClearAllForwardings yes'";
443 freeargs(&alist);
444 addargs(&alist, "%s", ssh_program);
445 if (verbose_mode)
446 addargs(&alist, "-v");
447 addargs(&alist, "-x");
448 addargs(&alist, "-oClearAllForwardings yes");
449 addargs(&alist, "-n");
450
389 *src++ = 0;
390 if (*src == 0)
391 src = ".";
392 host = strrchr(argv[i], '@');
451 *src++ = 0;
452 if (*src == 0)
453 src = ".";
454 host = strrchr(argv[i], '@');
393 len = strlen(ssh_program) + strlen(argv[i]) +
394 strlen(src) + (tuser ? strlen(tuser) : 0) +
395 strlen(thost) + strlen(targ) +
396 strlen(ssh_options) + CMDNEEDS + 20;
397 bp = xmalloc(len);
455
398 if (host) {
399 *host++ = 0;
400 host = cleanhostname(host);
401 suser = argv[i];
402 if (*suser == '\0')
403 suser = pwd->pw_name;
456 if (host) {
457 *host++ = 0;
458 host = cleanhostname(host);
459 suser = argv[i];
460 if (*suser == '\0')
461 suser = pwd->pw_name;
404 else if (!okname(suser)) {
405 xfree(bp);
462 else if (!okname(suser))
406 continue;
463 continue;
407 }
408 if (tuser && !okname(tuser)) {
409 xfree(bp);
410 continue;
411 }
412 snprintf(bp, len,
413 "%s%s %s -n "
414 "-l %s %s %s %s '%s%s%s:%s'",
415 ssh_program, verbose_mode ? " -v" : "",
416 ssh_options, suser, host, cmd, src,
417 tuser ? tuser : "", tuser ? "@" : "",
418 thost, targ);
464 addargs(&alist, "-l");
465 addargs(&alist, "%s", suser);
419 } else {
420 host = cleanhostname(argv[i]);
466 } else {
467 host = cleanhostname(argv[i]);
421 snprintf(bp, len,
422 "exec %s%s %s -n %s "
423 "%s %s '%s%s%s:%s'",
424 ssh_program, verbose_mode ? " -v" : "",
425 ssh_options, host, cmd, src,
426 tuser ? tuser : "", tuser ? "@" : "",
427 thost, targ);
428 }
468 }
429 if (verbose_mode)
430 fprintf(stderr, "Executing: %s\n", bp);
431 if (system(bp) != 0)
469 addargs(&alist, "%s", host);
470 addargs(&alist, "%s", cmd);
471 addargs(&alist, "%s", src);
472 addargs(&alist, "%s%s%s:%s",
473 tuser ? tuser : "", tuser ? "@" : "",
474 thost, targ);
475 if (do_local_cmd(&alist) != 0)
432 errs = 1;
476 errs = 1;
433 (void) xfree(bp);
434 } else { /* local to remote */
435 if (remin == -1) {
436 len = strlen(targ) + CMDNEEDS + 20;
437 bp = xmalloc(len);
438 (void) snprintf(bp, len, "%s -t %s", cmd, targ);
439 host = cleanhostname(thost);
440 if (do_cmd(host, tuser, bp, &remin,
441 &remout, argc) < 0)

--- 7 unchanged lines hidden (view full) ---

449 }
450}
451
452void
453tolocal(int argc, char **argv)
454{
455 int i, len;
456 char *bp, *host, *src, *suser;
477 } else { /* local to remote */
478 if (remin == -1) {
479 len = strlen(targ) + CMDNEEDS + 20;
480 bp = xmalloc(len);
481 (void) snprintf(bp, len, "%s -t %s", cmd, targ);
482 host = cleanhostname(thost);
483 if (do_cmd(host, tuser, bp, &remin,
484 &remout, argc) < 0)

--- 7 unchanged lines hidden (view full) ---

492 }
493}
494
495void
496tolocal(int argc, char **argv)
497{
498 int i, len;
499 char *bp, *host, *src, *suser;
500 arglist alist;
457
501
502 memset(&alist, '\0', sizeof(alist));
503 alist.list = NULL;
504
458 for (i = 0; i < argc - 1; i++) {
459 if (!(src = colon(argv[i]))) { /* Local to local. */
505 for (i = 0; i < argc - 1; i++) {
506 if (!(src = colon(argv[i]))) { /* Local to local. */
460 len = strlen(_PATH_CP) + strlen(argv[i]) +
461 strlen(argv[argc - 1]) + 20;
462 bp = xmalloc(len);
463 (void) snprintf(bp, len, "exec %s%s%s %s %s", _PATH_CP,
464 iamrecursive ? " -r" : "", pflag ? " -p" : "",
465 argv[i], argv[argc - 1]);
466 if (verbose_mode)
467 fprintf(stderr, "Executing: %s\n", bp);
468 if (system(bp))
507 freeargs(&alist);
508 addargs(&alist, "%s", _PATH_CP);
509 if (iamrecursive)
510 addargs(&alist, "-r");
511 if (pflag)
512 addargs(&alist, "-p");
513 addargs(&alist, "%s", argv[i]);
514 addargs(&alist, "%s", argv[argc-1]);
515 if (do_local_cmd(&alist))
469 ++errs;
516 ++errs;
470 (void) xfree(bp);
471 continue;
472 }
473 *src++ = 0;
474 if (*src == 0)
475 src = ".";
476 if ((host = strrchr(argv[i], '@')) == NULL) {
477 host = argv[i];
478 suser = NULL;

--- 76 unchanged lines hidden (view full) ---

555 (u_long) stb.st_atime);
556 (void) atomicio(vwrite, remout, buf, strlen(buf));
557 if (response() < 0)
558 goto next;
559 }
560#define FILEMODEMASK (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO)
561 snprintf(buf, sizeof buf, "C%04o %lld %s\n",
562 (u_int) (stb.st_mode & FILEMODEMASK),
517 continue;
518 }
519 *src++ = 0;
520 if (*src == 0)
521 src = ".";
522 if ((host = strrchr(argv[i], '@')) == NULL) {
523 host = argv[i];
524 suser = NULL;

--- 76 unchanged lines hidden (view full) ---

601 (u_long) stb.st_atime);
602 (void) atomicio(vwrite, remout, buf, strlen(buf));
603 if (response() < 0)
604 goto next;
605 }
606#define FILEMODEMASK (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO)
607 snprintf(buf, sizeof buf, "C%04o %lld %s\n",
608 (u_int) (stb.st_mode & FILEMODEMASK),
563 (int64_t)stb.st_size, last);
609 (long long)stb.st_size, last);
564 if (verbose_mode) {
565 fprintf(stderr, "Sending file modes: %s", buf);
566 }
567 (void) atomicio(vwrite, remout, buf, strlen(buf));
568 if (response() < 0)
569 goto next;
570 if ((bp = allocbuf(&buffer, fd, 2048)) == NULL) {
610 if (verbose_mode) {
611 fprintf(stderr, "Sending file modes: %s", buf);
612 }
613 (void) atomicio(vwrite, remout, buf, strlen(buf));
614 if (response() < 0)
615 goto next;
616 if ((bp = allocbuf(&buffer, fd, 2048)) == NULL) {
571next: (void) close(fd);
617next: if (fd != -1) {
618 (void) close(fd);
619 fd = -1;
620 }
572 continue;
573 }
574 if (showprogress)
575 start_progress_meter(curfile, stb.st_size, &statbytes);
576 /* Keep writing after an error so that we stay sync'd up. */
577 for (haderr = i = 0; i < stb.st_size; i += bp->cnt) {
578 amt = bp->cnt;
579 if (i + amt > stb.st_size)

--- 12 unchanged lines hidden (view full) ---

592 statbytes += result;
593 }
594 if (limit_rate)
595 bwlimit(amt);
596 }
597 if (showprogress)
598 stop_progress_meter();
599
621 continue;
622 }
623 if (showprogress)
624 start_progress_meter(curfile, stb.st_size, &statbytes);
625 /* Keep writing after an error so that we stay sync'd up. */
626 for (haderr = i = 0; i < stb.st_size; i += bp->cnt) {
627 amt = bp->cnt;
628 if (i + amt > stb.st_size)

--- 12 unchanged lines hidden (view full) ---

641 statbytes += result;
642 }
643 if (limit_rate)
644 bwlimit(amt);
645 }
646 if (showprogress)
647 stop_progress_meter();
648
600 if (close(fd) < 0 && !haderr)
601 haderr = errno;
649 if (fd != -1) {
650 if (close(fd) < 0 && !haderr)
651 haderr = errno;
652 fd = -1;
653 }
602 if (!haderr)
603 (void) atomicio(vwrite, remout, "", 1);
604 else
605 run_err("%s: %s", name, strerror(haderr));
606 (void) response();
607 }
608}
609

--- 538 unchanged lines hidden ---
654 if (!haderr)
655 (void) atomicio(vwrite, remout, "", 1);
656 else
657 run_err("%s: %s", name, strerror(haderr));
658 (void) response();
659 }
660}
661

--- 538 unchanged lines hidden ---