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.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 |
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 |
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 |
207 replacearg(&args, 0, "%s", ssh_program); |
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 |
270 __progname = ssh_get_progname(argv[0]); 271 |
272 memset(&args, '\0', sizeof(args)); |
273 args.list = NULL; |
274 addargs(&args, "%s", ssh_program); |
275 addargs(&args, "-x"); 276 addargs(&args, "-oForwardAgent no"); |
277 addargs(&args, "-oPermitLocalCommand no"); |
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 { |
386 if (targetshouldbedirectory) 387 verifydir(argv[argc - 1]); |
388 tolocal(argc, argv); /* Dest is local host. */ |
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; |
415 |
416 memset(&alist, '\0', sizeof(alist)); 417 alist.list = NULL; 418 |
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 |
440 for (i = 0; i < argc - 1; i++) { 441 src = colon(argv[i]); 442 if (src) { /* remote to remote */ |
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 |
451 *src++ = 0; 452 if (*src == 0) 453 src = "."; 454 host = strrchr(argv[i], '@'); |
455 |
456 if (host) { 457 *host++ = 0; 458 host = cleanhostname(host); 459 suser = argv[i]; 460 if (*suser == '\0') 461 suser = pwd->pw_name; |
462 else if (!okname(suser)) |
463 continue; |
464 addargs(&alist, "-l"); 465 addargs(&alist, "%s", suser); |
466 } else { 467 host = cleanhostname(argv[i]); |
468 } |
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) |
476 errs = 1; |
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; |
501 |
502 memset(&alist, '\0', sizeof(alist)); 503 alist.list = NULL; 504 |
505 for (i = 0; i < argc - 1; i++) { 506 if (!(src = colon(argv[i]))) { /* Local to local. */ |
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)) |
516 ++errs; |
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), |
609 (long long)stb.st_size, last); |
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) { |
617next: if (fd != -1) { 618 (void) close(fd); 619 fd = -1; 620 } |
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 |
649 if (fd != -1) { 650 if (close(fd) < 0 && !haderr) 651 haderr = errno; 652 fd = -1; 653 } |
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 --- |