diff options
author | Colin Watson <cjwatson@debian.org> | 2013-09-14 15:43:03 +0100 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2013-09-14 15:43:03 +0100 |
commit | 8faf8c84430cf3c19705b1d9f8889d256e7fd1fd (patch) | |
tree | e6cb74192adb00fda5e4d1457547851d7e0d86af /scp.c | |
parent | 328b60656f29db6306994d7498dede386ec2d1c3 (diff) | |
parent | c41345ad7ee5a22689e2c009595e85fa27b4b39a (diff) |
merge 6.3p1
Diffstat (limited to 'scp.c')
-rw-r--r-- | scp.c | 91 |
1 files changed, 52 insertions, 39 deletions
@@ -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). |
@@ -550,6 +550,24 @@ scpio(void *_cnt, size_t s) | |||
550 | return 0; | 550 | return 0; |
551 | } | 551 | } |
552 | 552 | ||
553 | static int | ||
554 | do_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 | |||
553 | void | 571 | void |
554 | toremote(char *targ, int argc, char **argv) | 572 | toremote(char *targ, int argc, char **argv) |
555 | { | 573 | { |
@@ -578,7 +596,7 @@ toremote(char *targ, int argc, char **argv) | |||
578 | } | 596 | } |
579 | 597 | ||
580 | if (tuser != NULL && !okname(tuser)) { | 598 | if (tuser != NULL && !okname(tuser)) { |
581 | xfree(arg); | 599 | free(arg); |
582 | return; | 600 | return; |
583 | } | 601 | } |
584 | 602 | ||
@@ -605,13 +623,13 @@ toremote(char *targ, int argc, char **argv) | |||
605 | *src == '-' ? "-- " : "", src); | 623 | *src == '-' ? "-- " : "", src); |
606 | if (do_cmd(host, suser, bp, &remin, &remout) < 0) | 624 | if (do_cmd(host, suser, bp, &remin, &remout) < 0) |
607 | exit(1); | 625 | exit(1); |
608 | (void) xfree(bp); | 626 | free(bp); |
609 | host = cleanhostname(thost); | 627 | host = cleanhostname(thost); |
610 | xasprintf(&bp, "%s -t %s%s", cmd, | 628 | xasprintf(&bp, "%s -t %s%s", cmd, |
611 | *targ == '-' ? "-- " : "", targ); | 629 | *targ == '-' ? "-- " : "", targ); |
612 | if (do_cmd2(host, tuser, bp, remin, remout) < 0) | 630 | if (do_cmd2(host, tuser, bp, remin, remout) < 0) |
613 | exit(1); | 631 | exit(1); |
614 | (void) xfree(bp); | 632 | free(bp); |
615 | (void) close(remin); | 633 | (void) close(remin); |
616 | (void) close(remout); | 634 | (void) close(remout); |
617 | remin = remout = -1; | 635 | remin = remout = -1; |
@@ -662,12 +680,12 @@ toremote(char *targ, int argc, char **argv) | |||
662 | exit(1); | 680 | exit(1); |
663 | if (response() < 0) | 681 | if (response() < 0) |
664 | exit(1); | 682 | exit(1); |
665 | (void) xfree(bp); | 683 | free(bp); |
666 | } | 684 | } |
667 | source(1, argv + i); | 685 | source(1, argv + i); |
668 | } | 686 | } |
669 | } | 687 | } |
670 | xfree(arg); | 688 | free(arg); |
671 | } | 689 | } |
672 | 690 | ||
673 | void | 691 | void |
@@ -711,11 +729,11 @@ tolocal(int argc, char **argv) | |||
711 | xasprintf(&bp, "%s -f %s%s", | 729 | xasprintf(&bp, "%s -f %s%s", |
712 | cmd, *src == '-' ? "-- " : "", src); | 730 | cmd, *src == '-' ? "-- " : "", src); |
713 | if (do_cmd(host, suser, bp, &remin, &remout) < 0) { | 731 | if (do_cmd(host, suser, bp, &remin, &remout) < 0) { |
714 | (void) xfree(bp); | 732 | free(bp); |
715 | ++errs; | 733 | ++errs; |
716 | continue; | 734 | continue; |
717 | } | 735 | } |
718 | xfree(bp); | 736 | free(bp); |
719 | sink(1, argv + argc - 1); | 737 | sink(1, argv + argc - 1); |
720 | (void) close(remin); | 738 | (void) close(remin); |
721 | remin = remout = -1; | 739 | remin = remout = -1; |
@@ -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) |
@@ -850,7 +854,7 @@ rsource(char *name, struct stat *statp) | |||
850 | { | 854 | { |
851 | DIR *dirp; | 855 | DIR *dirp; |
852 | struct dirent *dp; | 856 | struct dirent *dp; |
853 | char *last, *vect[1], path[1100]; | 857 | char *last, *vect[1], path[MAXPATHLEN]; |
854 | 858 | ||
855 | if (!(dirp = opendir(name))) { | 859 | if (!(dirp = opendir(name))) { |
856 | run_err("%s: %s", name, strerror(errno)); | 860 | run_err("%s: %s", name, strerror(errno)); |
@@ -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,31 @@ 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 || | ||
980 | (unsigned long long)(time_t)ull != ull) | ||
981 | setimes = 0; /* out of range */ | ||
982 | mtime.tv_sec = ull; | ||
976 | mtime.tv_usec = strtol(cp, &cp, 10); | 983 | mtime.tv_usec = strtol(cp, &cp, 10); |
977 | if (!cp || *cp++ != ' ') | 984 | if (!cp || *cp++ != ' ' || mtime.tv_usec < 0 || |
985 | mtime.tv_usec > 999999) | ||
978 | SCREWUP("mtime.usec not delimited"); | 986 | SCREWUP("mtime.usec not delimited"); |
979 | atime.tv_sec = strtol(cp, &cp, 10); | 987 | if (!isdigit((unsigned char)*cp)) |
988 | SCREWUP("atime.sec not present"); | ||
989 | ull = strtoull(cp, &cp, 10); | ||
980 | if (!cp || *cp++ != ' ') | 990 | if (!cp || *cp++ != ' ') |
981 | SCREWUP("atime.sec not delimited"); | 991 | SCREWUP("atime.sec not delimited"); |
992 | if ((time_t)ull < 0 || | ||
993 | (unsigned long long)(time_t)ull != ull) | ||
994 | setimes = 0; /* out of range */ | ||
995 | atime.tv_sec = ull; | ||
982 | atime.tv_usec = strtol(cp, &cp, 10); | 996 | atime.tv_usec = strtol(cp, &cp, 10); |
983 | if (!cp || *cp++ != '\0') | 997 | if (!cp || *cp++ != '\0' || atime.tv_usec < 0 || |
998 | atime.tv_usec > 999999) | ||
984 | SCREWUP("atime.usec not delimited"); | 999 | SCREWUP("atime.usec not delimited"); |
985 | (void) atomicio(vwrite, remout, "", 1); | 1000 | (void) atomicio(vwrite, remout, "", 1); |
986 | continue; | 1001 | continue; |
@@ -1023,8 +1038,7 @@ sink(int argc, char **argv) | |||
1023 | 1038 | ||
1024 | need = strlen(targ) + strlen(cp) + 250; | 1039 | need = strlen(targ) + strlen(cp) + 250; |
1025 | if (need > cursize) { | 1040 | if (need > cursize) { |
1026 | if (namebuf) | 1041 | free(namebuf); |
1027 | xfree(namebuf); | ||
1028 | namebuf = xmalloc(need); | 1042 | namebuf = xmalloc(need); |
1029 | cursize = need; | 1043 | cursize = need; |
1030 | } | 1044 | } |
@@ -1063,12 +1077,11 @@ sink(int argc, char **argv) | |||
1063 | } | 1077 | } |
1064 | if (mod_flag) | 1078 | if (mod_flag) |
1065 | (void) chmod(vect[0], mode); | 1079 | (void) chmod(vect[0], mode); |
1066 | if (vect[0]) | 1080 | free(vect[0]); |
1067 | xfree(vect[0]); | ||
1068 | continue; | 1081 | continue; |
1069 | } | 1082 | } |
1070 | omode = mode; | 1083 | omode = mode; |
1071 | mode |= S_IWRITE; | 1084 | mode |= S_IWUSR; |
1072 | if ((ofd = open(np, O_WRONLY|O_CREAT, mode)) < 0) { | 1085 | if ((ofd = open(np, O_WRONLY|O_CREAT, mode)) < 0) { |
1073 | bad: run_err("%s: %s", np, strerror(errno)); | 1086 | bad: run_err("%s: %s", np, strerror(errno)); |
1074 | continue; | 1087 | continue; |
@@ -1325,7 +1338,7 @@ void | |||
1325 | lostconn(int signo) | 1338 | lostconn(int signo) |
1326 | { | 1339 | { |
1327 | if (!iamremote) | 1340 | if (!iamremote) |
1328 | write(STDERR_FILENO, "lost connection\n", 16); | 1341 | (void)write(STDERR_FILENO, "lost connection\n", 16); |
1329 | if (signo) | 1342 | if (signo) |
1330 | _exit(1); | 1343 | _exit(1); |
1331 | else | 1344 | else |