summaryrefslogtreecommitdiff
path: root/scp.c
diff options
context:
space:
mode:
Diffstat (limited to 'scp.c')
-rw-r--r--scp.c91
1 files changed, 52 insertions, 39 deletions
diff --git a/scp.c b/scp.c
index e1fdd3985..b7a17abfe 100644
--- a/scp.c
+++ b/scp.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: scp.c,v 1.171 2011/09/09 22:37:01 djm Exp $ */ 1/* $OpenBSD: scp.c,v 1.178 2013/06/22 06:31:57 djm Exp $ */
2/* 2/*
3 * scp - secure remote copy. This is basically patched BSD rcp which 3 * scp - secure remote copy. This is basically patched BSD rcp which
4 * uses ssh to do the data transfer (instead of using rcmd). 4 * uses ssh to do the data transfer (instead of using rcmd).
@@ -558,6 +558,24 @@ scpio(void *_cnt, size_t s)
558 return 0; 558 return 0;
559} 559}
560 560
561static int
562do_times(int fd, int verb, const struct stat *sb)
563{
564 /* strlen(2^64) == 20; strlen(10^6) == 7 */
565 char buf[(20 + 7 + 2) * 2 + 2];
566
567 (void)snprintf(buf, sizeof(buf), "T%llu 0 %llu 0\n",
568 (unsigned long long) (sb->st_mtime < 0 ? 0 : sb->st_mtime),
569 (unsigned long long) (sb->st_atime < 0 ? 0 : sb->st_atime));
570 if (verb) {
571 fprintf(stderr, "File mtime %lld atime %lld\n",
572 (long long)sb->st_mtime, (long long)sb->st_atime);
573 fprintf(stderr, "Sending file timestamps: %s", buf);
574 }
575 (void) atomicio(vwrite, fd, buf, strlen(buf));
576 return (response());
577}
578
561void 579void
562toremote(char *targ, int argc, char **argv) 580toremote(char *targ, int argc, char **argv)
563{ 581{
@@ -586,7 +604,7 @@ toremote(char *targ, int argc, char **argv)
586 } 604 }
587 605
588 if (tuser != NULL && !okname(tuser)) { 606 if (tuser != NULL && !okname(tuser)) {
589 xfree(arg); 607 free(arg);
590 return; 608 return;
591 } 609 }
592 610
@@ -613,13 +631,13 @@ toremote(char *targ, int argc, char **argv)
613 *src == '-' ? "-- " : "", src); 631 *src == '-' ? "-- " : "", src);
614 if (do_cmd(host, suser, bp, &remin, &remout) < 0) 632 if (do_cmd(host, suser, bp, &remin, &remout) < 0)
615 exit(1); 633 exit(1);
616 (void) xfree(bp); 634 free(bp);
617 host = cleanhostname(thost); 635 host = cleanhostname(thost);
618 xasprintf(&bp, "%s -t %s%s", cmd, 636 xasprintf(&bp, "%s -t %s%s", cmd,
619 *targ == '-' ? "-- " : "", targ); 637 *targ == '-' ? "-- " : "", targ);
620 if (do_cmd2(host, tuser, bp, remin, remout) < 0) 638 if (do_cmd2(host, tuser, bp, remin, remout) < 0)
621 exit(1); 639 exit(1);
622 (void) xfree(bp); 640 free(bp);
623 (void) close(remin); 641 (void) close(remin);
624 (void) close(remout); 642 (void) close(remout);
625 remin = remout = -1; 643 remin = remout = -1;
@@ -670,12 +688,12 @@ toremote(char *targ, int argc, char **argv)
670 exit(1); 688 exit(1);
671 if (response() < 0) 689 if (response() < 0)
672 exit(1); 690 exit(1);
673 (void) xfree(bp); 691 free(bp);
674 } 692 }
675 source(1, argv + i); 693 source(1, argv + i);
676 } 694 }
677 } 695 }
678 xfree(arg); 696 free(arg);
679} 697}
680 698
681void 699void
@@ -719,11 +737,11 @@ tolocal(int argc, char **argv)
719 xasprintf(&bp, "%s -f %s%s", 737 xasprintf(&bp, "%s -f %s%s",
720 cmd, *src == '-' ? "-- " : "", src); 738 cmd, *src == '-' ? "-- " : "", src);
721 if (do_cmd(host, suser, bp, &remin, &remout) < 0) { 739 if (do_cmd(host, suser, bp, &remin, &remout) < 0) {
722 (void) xfree(bp); 740 free(bp);
723 ++errs; 741 ++errs;
724 continue; 742 continue;
725 } 743 }
726 xfree(bp); 744 free(bp);
727 sink(1, argv + argc - 1); 745 sink(1, argv + argc - 1);
728 (void) close(remin); 746 (void) close(remin);
729 remin = remout = -1; 747 remin = remout = -1;
@@ -782,21 +800,7 @@ syserr: run_err("%s: %s", name, strerror(errno));
782 ++last; 800 ++last;
783 curfile = last; 801 curfile = last;
784 if (pflag) { 802 if (pflag) {
785 /* 803 if (do_times(remout, verbose_mode, &stb) < 0)
786 * Make it compatible with possible future
787 * versions expecting microseconds.
788 */
789 (void) snprintf(buf, sizeof buf, "T%lu 0 %lu 0\n",
790 (u_long) (stb.st_mtime < 0 ? 0 : stb.st_mtime),
791 (u_long) (stb.st_atime < 0 ? 0 : stb.st_atime));
792 if (verbose_mode) {
793 fprintf(stderr, "File mtime %ld atime %ld\n",
794 (long)stb.st_mtime, (long)stb.st_atime);
795 fprintf(stderr, "Sending file timestamps: %s",
796 buf);
797 }
798 (void) atomicio(vwrite, remout, buf, strlen(buf));
799 if (response() < 0)
800 goto next; 804 goto next;
801 } 805 }
802#define FILEMODEMASK (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO) 806#define FILEMODEMASK (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO)
@@ -858,7 +862,7 @@ rsource(char *name, struct stat *statp)
858{ 862{
859 DIR *dirp; 863 DIR *dirp;
860 struct dirent *dp; 864 struct dirent *dp;
861 char *last, *vect[1], path[1100]; 865 char *last, *vect[1], path[MAXPATHLEN];
862 866
863 if (!(dirp = opendir(name))) { 867 if (!(dirp = opendir(name))) {
864 run_err("%s: %s", name, strerror(errno)); 868 run_err("%s: %s", name, strerror(errno));
@@ -870,11 +874,7 @@ rsource(char *name, struct stat *statp)
870 else 874 else
871 last++; 875 last++;
872 if (pflag) { 876 if (pflag) {
873 (void) snprintf(path, sizeof(path), "T%lu 0 %lu 0\n", 877 if (do_times(remout, verbose_mode, statp) < 0) {
874 (u_long) statp->st_mtime,
875 (u_long) statp->st_atime);
876 (void) atomicio(vwrite, remout, path, strlen(path));
877 if (response() < 0) {
878 closedir(dirp); 878 closedir(dirp);
879 return; 879 return;
880 } 880 }
@@ -920,6 +920,7 @@ sink(int argc, char **argv)
920 int amt, exists, first, ofd; 920 int amt, exists, first, ofd;
921 mode_t mode, omode, mask; 921 mode_t mode, omode, mask;
922 off_t size, statbytes; 922 off_t size, statbytes;
923 unsigned long long ull;
923 int setimes, targisdir, wrerrno = 0; 924 int setimes, targisdir, wrerrno = 0;
924 char ch, *cp, *np, *targ, *why, *vect[1], buf[2048]; 925 char ch, *cp, *np, *targ, *why, *vect[1], buf[2048];
925 struct timeval tv[2]; 926 struct timeval tv[2];
@@ -978,17 +979,31 @@ sink(int argc, char **argv)
978 if (*cp == 'T') { 979 if (*cp == 'T') {
979 setimes++; 980 setimes++;
980 cp++; 981 cp++;
981 mtime.tv_sec = strtol(cp, &cp, 10); 982 if (!isdigit((unsigned char)*cp))
983 SCREWUP("mtime.sec not present");
984 ull = strtoull(cp, &cp, 10);
982 if (!cp || *cp++ != ' ') 985 if (!cp || *cp++ != ' ')
983 SCREWUP("mtime.sec not delimited"); 986 SCREWUP("mtime.sec not delimited");
987 if ((time_t)ull < 0 ||
988 (unsigned long long)(time_t)ull != ull)
989 setimes = 0; /* out of range */
990 mtime.tv_sec = ull;
984 mtime.tv_usec = strtol(cp, &cp, 10); 991 mtime.tv_usec = strtol(cp, &cp, 10);
985 if (!cp || *cp++ != ' ') 992 if (!cp || *cp++ != ' ' || mtime.tv_usec < 0 ||
993 mtime.tv_usec > 999999)
986 SCREWUP("mtime.usec not delimited"); 994 SCREWUP("mtime.usec not delimited");
987 atime.tv_sec = strtol(cp, &cp, 10); 995 if (!isdigit((unsigned char)*cp))
996 SCREWUP("atime.sec not present");
997 ull = strtoull(cp, &cp, 10);
988 if (!cp || *cp++ != ' ') 998 if (!cp || *cp++ != ' ')
989 SCREWUP("atime.sec not delimited"); 999 SCREWUP("atime.sec not delimited");
1000 if ((time_t)ull < 0 ||
1001 (unsigned long long)(time_t)ull != ull)
1002 setimes = 0; /* out of range */
1003 atime.tv_sec = ull;
990 atime.tv_usec = strtol(cp, &cp, 10); 1004 atime.tv_usec = strtol(cp, &cp, 10);
991 if (!cp || *cp++ != '\0') 1005 if (!cp || *cp++ != '\0' || atime.tv_usec < 0 ||
1006 atime.tv_usec > 999999)
992 SCREWUP("atime.usec not delimited"); 1007 SCREWUP("atime.usec not delimited");
993 (void) atomicio(vwrite, remout, "", 1); 1008 (void) atomicio(vwrite, remout, "", 1);
994 continue; 1009 continue;
@@ -1031,8 +1046,7 @@ sink(int argc, char **argv)
1031 1046
1032 need = strlen(targ) + strlen(cp) + 250; 1047 need = strlen(targ) + strlen(cp) + 250;
1033 if (need > cursize) { 1048 if (need > cursize) {
1034 if (namebuf) 1049 free(namebuf);
1035 xfree(namebuf);
1036 namebuf = xmalloc(need); 1050 namebuf = xmalloc(need);
1037 cursize = need; 1051 cursize = need;
1038 } 1052 }
@@ -1071,12 +1085,11 @@ sink(int argc, char **argv)
1071 } 1085 }
1072 if (mod_flag) 1086 if (mod_flag)
1073 (void) chmod(vect[0], mode); 1087 (void) chmod(vect[0], mode);
1074 if (vect[0]) 1088 free(vect[0]);
1075 xfree(vect[0]);
1076 continue; 1089 continue;
1077 } 1090 }
1078 omode = mode; 1091 omode = mode;
1079 mode |= S_IWRITE; 1092 mode |= S_IWUSR;
1080 if ((ofd = open(np, O_WRONLY|O_CREAT, mode)) < 0) { 1093 if ((ofd = open(np, O_WRONLY|O_CREAT, mode)) < 0) {
1081bad: run_err("%s: %s", np, strerror(errno)); 1094bad: run_err("%s: %s", np, strerror(errno));
1082 continue; 1095 continue;
@@ -1333,7 +1346,7 @@ void
1333lostconn(int signo) 1346lostconn(int signo)
1334{ 1347{
1335 if (!iamremote) 1348 if (!iamremote)
1336 write(STDERR_FILENO, "lost connection\n", 16); 1349 (void)write(STDERR_FILENO, "lost connection\n", 16);
1337 if (signo) 1350 if (signo)
1338 _exit(1); 1351 _exit(1);
1339 else 1352 else