summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--scp.c63
2 files changed, 44 insertions, 25 deletions
diff --git a/ChangeLog b/ChangeLog
index a843af0bd..111a2f36e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -3,6 +3,12 @@
3 - dtucker@cvs.openbsd.org 2013/06/10 19:19:44 3 - dtucker@cvs.openbsd.org 2013/06/10 19:19:44
4 [readconf.c] 4 [readconf.c]
5 revert 1.203 while we investigate crashes reported by okan@ 5 revert 1.203 while we investigate crashes reported by okan@
6 - guenther@cvs.openbsd.org 2013/06/17 04:48:42
7 [scp.c]
8 Handle time_t values as long long's when formatting them and when
9 parsing them from remote servers.
10 Improve error checking in parsing of 'T' lines.
11 ok dtucker@ deraadt@
6 12
720130702 1320130702
8 - (dtucker) [contrib/cygwin/README contrib/cygwin/ssh-host-config 14 - (dtucker) [contrib/cygwin/README contrib/cygwin/ssh-host-config
diff --git a/scp.c b/scp.c
index 9b5959d44..ca7948f62 100644
--- a/scp.c
+++ b/scp.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: scp.c,v 1.175 2013/06/04 19:12:23 dtucker Exp $ */ 1/* $OpenBSD: scp.c,v 1.176 2013/06/17 04:48:42 guenther 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).
@@ -550,6 +550,24 @@ scpio(void *_cnt, size_t s)
550 return 0; 550 return 0;
551} 551}
552 552
553static int
554do_times(int fd, int verb, const struct stat *sb)
555{
556 /* strlen(2^64) == 20; strlen(10^6) == 7 */
557 char buf[(20 + 7 + 2) * 2 + 2];
558
559 (void)snprintf(buf, sizeof(buf), "T%llu 0 %llu 0\n",
560 (unsigned long long) (sb->st_mtime < 0 ? 0 : sb->st_mtime),
561 (unsigned long long) (sb->st_atime < 0 ? 0 : sb->st_atime));
562 if (verb) {
563 fprintf(stderr, "File mtime %lld atime %lld\n",
564 (long long)sb->st_mtime, (long long)sb->st_atime);
565 fprintf(stderr, "Sending file timestamps: %s", buf);
566 }
567 (void) atomicio(vwrite, fd, buf, strlen(buf));
568 return (response());
569}
570
553void 571void
554toremote(char *targ, int argc, char **argv) 572toremote(char *targ, int argc, char **argv)
555{ 573{
@@ -774,21 +792,7 @@ syserr: run_err("%s: %s", name, strerror(errno));
774 ++last; 792 ++last;
775 curfile = last; 793 curfile = last;
776 if (pflag) { 794 if (pflag) {
777 /* 795 if (do_times(remout, verbose_mode, &stb) < 0)
778 * Make it compatible with possible future
779 * versions expecting microseconds.
780 */
781 (void) snprintf(buf, sizeof buf, "T%lu 0 %lu 0\n",
782 (u_long) (stb.st_mtime < 0 ? 0 : stb.st_mtime),
783 (u_long) (stb.st_atime < 0 ? 0 : stb.st_atime));
784 if (verbose_mode) {
785 fprintf(stderr, "File mtime %ld atime %ld\n",
786 (long)stb.st_mtime, (long)stb.st_atime);
787 fprintf(stderr, "Sending file timestamps: %s",
788 buf);
789 }
790 (void) atomicio(vwrite, remout, buf, strlen(buf));
791 if (response() < 0)
792 goto next; 796 goto next;
793 } 797 }
794#define FILEMODEMASK (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO) 798#define FILEMODEMASK (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO)
@@ -862,11 +866,7 @@ rsource(char *name, struct stat *statp)
862 else 866 else
863 last++; 867 last++;
864 if (pflag) { 868 if (pflag) {
865 (void) snprintf(path, sizeof(path), "T%lu 0 %lu 0\n", 869 if (do_times(remout, verbose_mode, statp) < 0) {
866 (u_long) statp->st_mtime,
867 (u_long) statp->st_atime);
868 (void) atomicio(vwrite, remout, path, strlen(path));
869 if (response() < 0) {
870 closedir(dirp); 870 closedir(dirp);
871 return; 871 return;
872 } 872 }
@@ -912,6 +912,7 @@ sink(int argc, char **argv)
912 int amt, exists, first, ofd; 912 int amt, exists, first, ofd;
913 mode_t mode, omode, mask; 913 mode_t mode, omode, mask;
914 off_t size, statbytes; 914 off_t size, statbytes;
915 unsigned long long ull;
915 int setimes, targisdir, wrerrno = 0; 916 int setimes, targisdir, wrerrno = 0;
916 char ch, *cp, *np, *targ, *why, *vect[1], buf[2048]; 917 char ch, *cp, *np, *targ, *why, *vect[1], buf[2048];
917 struct timeval tv[2]; 918 struct timeval tv[2];
@@ -970,17 +971,29 @@ sink(int argc, char **argv)
970 if (*cp == 'T') { 971 if (*cp == 'T') {
971 setimes++; 972 setimes++;
972 cp++; 973 cp++;
973 mtime.tv_sec = strtol(cp, &cp, 10); 974 if (!isdigit((unsigned char)*cp))
975 SCREWUP("mtime.sec not present");
976 ull = strtoull(cp, &cp, 10);
974 if (!cp || *cp++ != ' ') 977 if (!cp || *cp++ != ' ')
975 SCREWUP("mtime.sec not delimited"); 978 SCREWUP("mtime.sec not delimited");
979 if ((time_t)ull < 0 || (time_t)ull != ull)
980 setimes = 0; /* out of range */
981 mtime.tv_sec = ull;
976 mtime.tv_usec = strtol(cp, &cp, 10); 982 mtime.tv_usec = strtol(cp, &cp, 10);
977 if (!cp || *cp++ != ' ') 983 if (!cp || *cp++ != ' ' || mtime.tv_usec < 0 ||
984 mtime.tv_usec > 999999)
978 SCREWUP("mtime.usec not delimited"); 985 SCREWUP("mtime.usec not delimited");
979 atime.tv_sec = strtol(cp, &cp, 10); 986 if (!isdigit((unsigned char)*cp))
987 SCREWUP("atime.sec not present");
988 ull = strtoull(cp, &cp, 10);
980 if (!cp || *cp++ != ' ') 989 if (!cp || *cp++ != ' ')
981 SCREWUP("atime.sec not delimited"); 990 SCREWUP("atime.sec not delimited");
991 if ((time_t)ull < 0 || (time_t)ull != ull)
992 setimes = 0; /* out of range */
993 atime.tv_sec = ull;
982 atime.tv_usec = strtol(cp, &cp, 10); 994 atime.tv_usec = strtol(cp, &cp, 10);
983 if (!cp || *cp++ != '\0') 995 if (!cp || *cp++ != '\0' || atime.tv_usec < 0 ||
996 atime.tv_usec > 999999)
984 SCREWUP("atime.usec not delimited"); 997 SCREWUP("atime.usec not delimited");
985 (void) atomicio(vwrite, remout, "", 1); 998 (void) atomicio(vwrite, remout, "", 1);
986 continue; 999 continue;