1/* $OpenBSD: scp.c,v 1.155 2006/08/03 03:34:42 deraadt Exp $ */ |
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" |
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 |
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 |
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 |
196do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout) |
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 */ |
210 if (pipe(reserved) < 0) 211 fatal("pipe: %s", strerror(errno)); |
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); |
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{ |
287 int ch, fflag, tflag, status, n; |
288 double speed; |
289 char *targ, *endp, **newargv; |
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 |
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{ |
444 char *bp, *host, *src, *suser, *thost, *tuser, *arg; 445 arglist alist; |
446 int i; |
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) { |
511 xasprintf(&bp, "%s -t %s", cmd, targ); |
512 host = cleanhostname(thost); 513 if (do_cmd(host, tuser, bp, &remin, |
514 &remout) < 0) |
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); |
524} 525 526void 527tolocal(int argc, char **argv) 528{ |
529 char *bp, *host, *src, *suser; 530 arglist alist; |
531 int i; |
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); |
563 xasprintf(&bp, "%s -f %s", cmd, src); 564 if (do_cmd(host, suser, bp, &remin, &remout) < 0) { |
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; |
809 int amt, exists, first, ofd; 810 mode_t mode, omode, mask; |
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; |
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 } |
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 |
1214 bp->buf = xrealloc(bp->buf, 1, size); |
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} |