scp.c (157019) | scp.c (162856) |
---|---|
1/* $OpenBSD: scp.c,v 1.155 2006/08/03 03:34:42 deraadt Exp $ */ |
|
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" | 2/* 3 * scp - secure remote copy. This is basically patched BSD rcp which 4 * uses ssh to do the data transfer (instead of using rcmd). 5 * 6 * NOTE: This version should NOT be suid root. (This uses ssh to 7 * do the transfer and ssh has the necessary privileges.) 8 * 9 * 1995 Timo Rinne <tri@iki.fi>, Tatu Ylonen <ylo@cs.hut.fi> --- 57 unchanged lines hidden (view full) --- 67 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 68 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 69 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 70 * SUCH DAMAGE. 71 * 72 */ 73 74#include "includes.h" |
74RCSID("$OpenBSD: scp.c,v 1.130 2006/01/31 10:35:43 djm Exp $"); | |
75 | 75 |
76#include <sys/types.h> 77#include <sys/param.h> 78#ifdef HAVE_SYS_STAT_H 79# include <sys/stat.h> 80#endif 81#ifdef HAVE_SYS_TIME_H 82# include <sys/time.h> 83#endif 84#include <sys/wait.h> 85#include <sys/uio.h> 86 87#include <ctype.h> 88#include <dirent.h> 89#include <errno.h> 90#include <fcntl.h> 91#include <pwd.h> 92#include <signal.h> 93#include <stdarg.h> 94#include <stdio.h> 95#include <stdlib.h> 96#include <string.h> 97#include <time.h> 98#include <unistd.h> 99 |
|
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 83extern char *__progname; 84 | 100#include "xmalloc.h" 101#include "atomicio.h" 102#include "pathnames.h" 103#include "log.h" 104#include "misc.h" 105#include "progressmeter.h" 106 107extern char *__progname; 108 |
109int do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout); 110 |
|
85void bwlimit(int); 86 87/* Struct for addargs */ 88arglist args; 89 90/* Bandwidth limit */ 91off_t limit_rate = 0; 92 --- 69 unchanged lines hidden (view full) --- 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 | 111void bwlimit(int); 112 113/* Struct for addargs */ 114arglist args; 115 116/* Bandwidth limit */ 117off_t limit_rate = 0; 118 --- 69 unchanged lines hidden (view full) --- 188 189/* 190 * This function executes the given command as the specified user on the 191 * given host. This returns < 0 if execution fails, and >= 0 otherwise. This 192 * assigns the input and output file descriptors on success. 193 */ 194 195int |
170do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc) | 196do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout) |
171{ 172 int pin[2], pout[2], reserved[2]; 173 174 if (verbose_mode) 175 fprintf(stderr, 176 "Executing: program %s host %s, user %s, command %s\n", 177 ssh_program, host, 178 remuser ? remuser : "(unspecified)", cmd); 179 180 /* 181 * Reserve two descriptors so that the real pipes won't get 182 * descriptors 0 and 1 because that will screw up dup2 below. 183 */ | 197{ 198 int pin[2], pout[2], reserved[2]; 199 200 if (verbose_mode) 201 fprintf(stderr, 202 "Executing: program %s host %s, user %s, command %s\n", 203 ssh_program, host, 204 remuser ? remuser : "(unspecified)", cmd); 205 206 /* 207 * Reserve two descriptors so that the real pipes won't get 208 * descriptors 0 and 1 because that will screw up dup2 below. 209 */ |
184 pipe(reserved); | 210 if (pipe(reserved) < 0) 211 fatal("pipe: %s", strerror(errno)); |
185 186 /* Create a socket pair for communicating with ssh. */ 187 if (pipe(pin) < 0) 188 fatal("pipe: %s", strerror(errno)); 189 if (pipe(pout) < 0) 190 fatal("pipe: %s", strerror(errno)); 191 192 /* Free the reserved descriptors. */ --- 36 unchanged lines hidden (view full) --- 229 230typedef struct { 231 size_t cnt; 232 char *buf; 233} BUF; 234 235BUF *allocbuf(BUF *, int, int); 236void lostconn(int); | 212 213 /* Create a socket pair for communicating with ssh. */ 214 if (pipe(pin) < 0) 215 fatal("pipe: %s", strerror(errno)); 216 if (pipe(pout) < 0) 217 fatal("pipe: %s", strerror(errno)); 218 219 /* Free the reserved descriptors. */ --- 36 unchanged lines hidden (view full) --- 256 257typedef struct { 258 size_t cnt; 259 char *buf; 260} BUF; 261 262BUF *allocbuf(BUF *, int, int); 263void lostconn(int); |
237void nospace(void); | |
238int okname(char *); 239void run_err(const char *,...); 240void verifydir(char *); 241 242struct passwd *pwd; 243uid_t userid; 244int errs, remin, remout; 245int pflag, iamremote, iamrecursive, targetshouldbedirectory; --- 7 unchanged lines hidden (view full) --- 253void source(int, char *[]); 254void tolocal(int, char *[]); 255void toremote(char *, int, char *[]); 256void usage(void); 257 258int 259main(int argc, char **argv) 260{ | 264int okname(char *); 265void run_err(const char *,...); 266void verifydir(char *); 267 268struct passwd *pwd; 269uid_t userid; 270int errs, remin, remout; 271int pflag, iamremote, iamrecursive, targetshouldbedirectory; --- 7 unchanged lines hidden (view full) --- 279void source(int, char *[]); 280void tolocal(int, char *[]); 281void toremote(char *, int, char *[]); 282void usage(void); 283 284int 285main(int argc, char **argv) 286{ |
261 int ch, fflag, tflag, status; | 287 int ch, fflag, tflag, status, n; |
262 double speed; | 288 double speed; |
263 char *targ, *endp; | 289 char *targ, *endp, **newargv; |
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 | 290 extern char *optarg; 291 extern int optind; 292 293 /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ 294 sanitise_stdfd(); 295 |
296 /* Copy argv, because we modify it */ 297 newargv = xcalloc(MAX(argc + 1, 1), sizeof(*newargv)); 298 for (n = 0; n < argc; n++) 299 newargv[n] = xstrdup(argv[n]); 300 argv = newargv; 301 |
|
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"); --- 126 unchanged lines hidden (view full) --- 404 } 405 } 406 exit(errs != 0); 407} 408 409void 410toremote(char *targ, int argc, char **argv) 411{ | 302 __progname = ssh_get_progname(argv[0]); 303 304 memset(&args, '\0', sizeof(args)); 305 args.list = NULL; 306 addargs(&args, "%s", ssh_program); 307 addargs(&args, "-x"); 308 addargs(&args, "-oForwardAgent no"); 309 addargs(&args, "-oPermitLocalCommand no"); --- 126 unchanged lines hidden (view full) --- 436 } 437 } 438 exit(errs != 0); 439} 440 441void 442toremote(char *targ, int argc, char **argv) 443{ |
412 int i, len; | |
413 char *bp, *host, *src, *suser, *thost, *tuser, *arg; 414 arglist alist; | 444 char *bp, *host, *src, *suser, *thost, *tuser, *arg; 445 arglist alist; |
446 int i; |
|
415 416 memset(&alist, '\0', sizeof(alist)); 417 alist.list = NULL; 418 419 *targ++ = 0; 420 if (*targ == 0) 421 targ = "."; 422 --- 48 unchanged lines hidden (view full) --- 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) { | 447 448 memset(&alist, '\0', sizeof(alist)); 449 alist.list = NULL; 450 451 *targ++ = 0; 452 if (*targ == 0) 453 targ = "."; 454 --- 48 unchanged lines hidden (view full) --- 503 addargs(&alist, "%s", src); 504 addargs(&alist, "%s%s%s:%s", 505 tuser ? tuser : "", tuser ? "@" : "", 506 thost, targ); 507 if (do_local_cmd(&alist) != 0) 508 errs = 1; 509 } else { /* local to remote */ 510 if (remin == -1) { |
479 len = strlen(targ) + CMDNEEDS + 20; 480 bp = xmalloc(len); 481 (void) snprintf(bp, len, "%s -t %s", cmd, targ); | 511 xasprintf(&bp, "%s -t %s", cmd, targ); |
482 host = cleanhostname(thost); 483 if (do_cmd(host, tuser, bp, &remin, | 512 host = cleanhostname(thost); 513 if (do_cmd(host, tuser, bp, &remin, |
484 &remout, argc) < 0) | 514 &remout) < 0) |
485 exit(1); 486 if (response() < 0) 487 exit(1); 488 (void) xfree(bp); 489 } 490 source(1, argv + i); 491 } 492 } | 515 exit(1); 516 if (response() < 0) 517 exit(1); 518 (void) xfree(bp); 519 } 520 source(1, argv + i); 521 } 522 } |
523 xfree(arg); |
|
493} 494 495void 496tolocal(int argc, char **argv) 497{ | 524} 525 526void 527tolocal(int argc, char **argv) 528{ |
498 int i, len; | |
499 char *bp, *host, *src, *suser; 500 arglist alist; | 529 char *bp, *host, *src, *suser; 530 arglist alist; |
531 int i; |
|
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); --- 15 unchanged lines hidden (view full) --- 524 suser = NULL; 525 } else { 526 *host++ = 0; 527 suser = argv[i]; 528 if (*suser == '\0') 529 suser = pwd->pw_name; 530 } 531 host = cleanhostname(host); | 532 533 memset(&alist, '\0', sizeof(alist)); 534 alist.list = NULL; 535 536 for (i = 0; i < argc - 1; i++) { 537 if (!(src = colon(argv[i]))) { /* Local to local. */ 538 freeargs(&alist); 539 addargs(&alist, "%s", _PATH_CP); --- 15 unchanged lines hidden (view full) --- 555 suser = NULL; 556 } else { 557 *host++ = 0; 558 suser = argv[i]; 559 if (*suser == '\0') 560 suser = pwd->pw_name; 561 } 562 host = cleanhostname(host); |
532 len = strlen(src) + CMDNEEDS + 20; 533 bp = xmalloc(len); 534 (void) snprintf(bp, len, "%s -f %s", cmd, src); 535 if (do_cmd(host, suser, bp, &remin, &remout, argc) < 0) { | 563 xasprintf(&bp, "%s -f %s", cmd, src); 564 if (do_cmd(host, suser, bp, &remin, &remout) < 0) { |
536 (void) xfree(bp); 537 ++errs; 538 continue; 539 } 540 xfree(bp); 541 sink(1, argv + argc - 1); 542 (void) close(remin); 543 remin = remout = -1; --- 228 unchanged lines hidden (view full) --- 772 static BUF buffer; 773 struct stat stb; 774 enum { 775 YES, NO, DISPLAYED 776 } wrerr; 777 BUF *bp; 778 off_t i; 779 size_t j, count; | 565 (void) xfree(bp); 566 ++errs; 567 continue; 568 } 569 xfree(bp); 570 sink(1, argv + argc - 1); 571 (void) close(remin); 572 remin = remout = -1; --- 228 unchanged lines hidden (view full) --- 801 static BUF buffer; 802 struct stat stb; 803 enum { 804 YES, NO, DISPLAYED 805 } wrerr; 806 BUF *bp; 807 off_t i; 808 size_t j, count; |
780 int amt, exists, first, mask, mode, ofd, omode; | 809 int amt, exists, first, ofd; 810 mode_t mode, omode, mask; |
781 off_t size, statbytes; 782 int setimes, targisdir, wrerrno = 0; 783 char ch, *cp, *np, *targ, *why, *vect[1], buf[2048]; 784 struct timeval tv[2]; 785 786#define atime tv[0] 787#define mtime tv[1] 788#define SCREWUP(str) { why = str; goto screwup; } --- 303 unchanged lines hidden (view full) --- 1092 1093void 1094run_err(const char *fmt,...) 1095{ 1096 static FILE *fp; 1097 va_list ap; 1098 1099 ++errs; | 811 off_t size, statbytes; 812 int setimes, targisdir, wrerrno = 0; 813 char ch, *cp, *np, *targ, *why, *vect[1], buf[2048]; 814 struct timeval tv[2]; 815 816#define atime tv[0] 817#define mtime tv[1] 818#define SCREWUP(str) { why = str; goto screwup; } --- 303 unchanged lines hidden (view full) --- 1122 1123void 1124run_err(const char *fmt,...) 1125{ 1126 static FILE *fp; 1127 va_list ap; 1128 1129 ++errs; |
1100 if (fp == NULL && !(fp = fdopen(remout, "w"))) 1101 return; 1102 (void) fprintf(fp, "%c", 0x01); 1103 (void) fprintf(fp, "scp: "); 1104 va_start(ap, fmt); 1105 (void) vfprintf(fp, fmt, ap); 1106 va_end(ap); 1107 (void) fprintf(fp, "\n"); 1108 (void) fflush(fp); | 1130 if (fp != NULL || (remout != -1 && (fp = fdopen(remout, "w")))) { 1131 (void) fprintf(fp, "%c", 0x01); 1132 (void) fprintf(fp, "scp: "); 1133 va_start(ap, fmt); 1134 (void) vfprintf(fp, fmt, ap); 1135 va_end(ap); 1136 (void) fprintf(fp, "\n"); 1137 (void) fflush(fp); 1138 } |
1109 1110 if (!iamremote) { 1111 va_start(ap, fmt); 1112 vfprintf(stderr, fmt, ap); 1113 va_end(ap); 1114 fprintf(stderr, "\n"); 1115 } 1116} --- 59 unchanged lines hidden (view full) --- 1176#else /* HAVE_STRUCT_STAT_ST_BLKSIZE */ 1177 size = blksize; 1178#endif /* HAVE_STRUCT_STAT_ST_BLKSIZE */ 1179 if (bp->cnt >= size) 1180 return (bp); 1181 if (bp->buf == NULL) 1182 bp->buf = xmalloc(size); 1183 else | 1139 1140 if (!iamremote) { 1141 va_start(ap, fmt); 1142 vfprintf(stderr, fmt, ap); 1143 va_end(ap); 1144 fprintf(stderr, "\n"); 1145 } 1146} --- 59 unchanged lines hidden (view full) --- 1206#else /* HAVE_STRUCT_STAT_ST_BLKSIZE */ 1207 size = blksize; 1208#endif /* HAVE_STRUCT_STAT_ST_BLKSIZE */ 1209 if (bp->cnt >= size) 1210 return (bp); 1211 if (bp->buf == NULL) 1212 bp->buf = xmalloc(size); 1213 else |
1184 bp->buf = xrealloc(bp->buf, size); | 1214 bp->buf = xrealloc(bp->buf, 1, size); |
1185 memset(bp->buf, 0, size); 1186 bp->cnt = size; 1187 return (bp); 1188} 1189 1190void 1191lostconn(int signo) 1192{ 1193 if (!iamremote) 1194 write(STDERR_FILENO, "lost connection\n", 16); 1195 if (signo) 1196 _exit(1); 1197 else 1198 exit(1); 1199} | 1215 memset(bp->buf, 0, size); 1216 bp->cnt = size; 1217 return (bp); 1218} 1219 1220void 1221lostconn(int signo) 1222{ 1223 if (!iamremote) 1224 write(STDERR_FILENO, "lost connection\n", 16); 1225 if (signo) 1226 _exit(1); 1227 else 1228 exit(1); 1229} |