diff -ur openssh-4.6p1-orig/Makefile.in openssh-4.6p1/Makefile.in --- openssh-4.6p1-orig/Makefile.in 2006-10-24 00:44:47.000000000 +0300 +++ openssh-4.6p1/Makefile.in 2007-07-21 14:34:14.000000000 +0300 @@ -141,8 +141,8 @@ sshd$(EXEEXT): libssh.a $(LIBCOMPAT) $(SSHDOBJS) $(LD) -o $@ $(SSHDOBJS) $(LDFLAGS) -lssh -lopenbsd-compat $(LIBWRAP) $(LIBPAM) $(LIBSELINUX) $(SSHDLIBS) $(LIBS) -scp$(EXEEXT): $(LIBCOMPAT) libssh.a scp.o progressmeter.o - $(LD) -o $@ scp.o progressmeter.o bufaux.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) +scp$(EXEEXT): $(LIBCOMPAT) libssh.a scp.o progressmeter.o entropy.o + $(LD) -o $@ scp.o progressmeter.o bufaux.o entropy.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) ssh-add$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-add.o $(LD) -o $@ ssh-add.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) @@ -159,8 +159,8 @@ ssh-keyscan$(EXEEXT): $(LIBCOMPAT) libssh.a ssh-keyscan.o $(LD) -o $@ ssh-keyscan.o $(LDFLAGS) -lssh -lopenbsd-compat -lssh $(LIBS) -sftp-server$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-common.o sftp-server.o - $(LD) -o $@ sftp-server.o sftp-common.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) +sftp-server$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-common.o sftp-server.o entropy.o + $(LD) -o $@ sftp-server.o sftp-common.o entropy.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) sftp$(EXEEXT): $(LIBCOMPAT) libssh.a sftp.o sftp-client.o sftp-common.o sftp-glob.o progressmeter.o $(LD) -o $@ progressmeter.o sftp.o sftp-client.o sftp-common.o sftp-glob.o $(LDFLAGS) -lssh -lopenbsd-compat $(LIBS) $(LIBEDIT) diff -ur openssh-4.6p1-orig/scp.c openssh-4.6p1/scp.c --- openssh-4.6p1-orig/scp.c 2007-02-19 13:14:11.000000000 +0200 +++ openssh-4.6p1/scp.c 2007-07-26 16:37:34.000000000 +0300 @@ -131,6 +131,9 @@ /* This is used to store the pid of ssh_program */ pid_t do_cmd_pid = -1; +/* temporary folder where the files will be storred before being moved to their actual location */ +char *tmpdir; + static void killchild(int signo) { @@ -382,6 +385,9 @@ if (!isatty(STDOUT_FILENO)) showprogress = 0; + + tmpdir=getenv("TMP"); + if(!tmpdir)tmpdir="/tmp"; remin = STDIN_FILENO; remout = STDOUT_FILENO; @@ -810,7 +816,7 @@ mode_t mode, omode, mask; off_t size, statbytes; int setimes, targisdir, wrerrno = 0; - char ch, *cp, *np, *targ, *why, *vect[1], buf[2048]; + char ch, *cp, *np, *targ, *why, *vect[1], buf[2048],*origname; struct timeval tv[2]; #define atime tv[0] @@ -966,6 +972,12 @@ } omode = mode; mode |= S_IWRITE; + + origname=np; + np=calloc(1,strlen(origname)+20); + sprintf(np,"%s.tmpscpparts.XXXXXX",origname); + mkstemp(np); + if ((ofd = open(np, O_WRONLY|O_CREAT, mode)) < 0) { bad: run_err("%s: %s", np, strerror(errno)); continue; @@ -1025,6 +1037,7 @@ run_err("%s: truncate: %s", np, strerror(errno)); wrerr = DISPLAYED; } + if (pflag) { if (exists || omode != mode) #ifdef HAVE_FCHMOD @@ -1051,6 +1064,16 @@ if (close(ofd) == -1) { wrerr = YES; wrerrno = errno; + }else{ + if(rename(np,origname)){ + wrerr = YES; + wrerrno = errno; + }else{ + xfree(np); + np=origname; + origname=0; + } + } (void) response(); if (setimes && wrerr == NO) { @@ -1071,6 +1094,10 @@ case DISPLAYED: break; } + if(origname){ + xfree(np); + np=origname; + } } screwup: run_err("protocol error: %s", why); diff -ur openssh-4.6p1-orig/sftp-server.c openssh-4.6p1/sftp-server.c --- openssh-4.6p1-orig/sftp-server.c 2007-01-05 07:31:03.000000000 +0200 +++ openssh-4.6p1/sftp-server.c 2007-07-18 17:47:01.000000000 +0300 @@ -56,6 +56,8 @@ /* Our client */ struct passwd *pw = NULL; char *client_addr = NULL; +char *origname = NULL; +char *tmpdir = NULL; /* input and output queue */ Buffer iqueue; @@ -498,8 +500,18 @@ a = get_attrib(); flags = flags_from_portable(pflags); mode = (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? a->perm : 0666; + origname=NULL; + if (pflags & SSH2_FXF_WRITE || pflags & SSH2_FXF_CREAT){ + origname=name; + name=calloc(1,11+strlen(tmpdir)+1); + sprintf(name,"%s/sftp_XXXXXX",tmpdir); + mkstemp(name); + logit("created tmp file for \"%s\": \"%s\"",origname,name); + } + logit("open \"%s\" flags %s mode 0%o", name, string_from_portable(pflags), mode); + fd = open(name, flags, mode); if (fd < 0) { status = errno_to_portable(errno); @@ -522,13 +534,26 @@ { u_int32_t id; int handle, ret, status = SSH2_FX_FAILURE; - + char *name; + int namel; id = get_int(); handle = get_handle(); debug3("request %u: close handle %u", id, handle); handle_log_close(handle, NULL); + name=handle_to_name(handle); + namel=strlen(name); + name=calloc(1,namel+1); + memcpy(name,handle_to_name(handle),namel); ret = handle_close(handle); status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK; + if(origname!=NULL && status==SSH2_FX_OK){ + if(rename(name,origname)){ + logit("error moving file %s: %s",name,strerror(errno)); + status = SSH2_FX_FAILURE; + } + xfree(origname); + } + xfree(name); send_status(id, status); } @@ -1222,7 +1247,7 @@ __progname = ssh_get_progname(argv[0]); log_init(__progname, log_level, log_facility, log_stderr); - while (!skipargs && (ch = getopt(argc, argv, "C:f:l:che")) != -1) { + while (!skipargs && (ch = getopt(argc, argv, "C:f:l:t:che")) != -1) { switch (ch) { case 'c': /* @@ -1244,6 +1269,10 @@ if (log_level == SYSLOG_FACILITY_NOT_SET) error("Invalid log facility \"%s\"", optarg); break; + case 't': + tmpdir=calloc(1,strlen(optarg)+1); + memcpy(tmpdir,optarg,strlen(optarg)); + break; case 'h': default: usage(); @@ -1251,6 +1280,12 @@ } log_init(__progname, log_level, log_facility, log_stderr); + + if(tmpdir==NULL){ + tmpdir=calloc(1,6), + strcpy(tmpdir,"/tmp/"); + } + debug2("tmp dir: \"%s\"",tmpdir); if ((cp = getenv("SSH_CONNECTION")) != NULL) { client_addr = xstrdup(cp);