sftp-client.c revision 323134
1/* $OpenBSD: sftp-client.c,v 1.125 2016/09/12 01:22:38 deraadt Exp $ */
2/*
3 * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18/* XXX: memleaks */
19/* XXX: signed vs unsigned */
20/* XXX: remove all logging, only return status codes */
21/* XXX: copy between two remote sites */
22
23#include "includes.h"
24
25#include <sys/types.h>
26#ifdef HAVE_SYS_STATVFS_H
27#include <sys/statvfs.h>
28#endif
29#include "openbsd-compat/sys-queue.h"
30#ifdef HAVE_SYS_STAT_H
31# include <sys/stat.h>
32#endif
33#ifdef HAVE_SYS_TIME_H
34# include <sys/time.h>
35#endif
36#include <sys/uio.h>
37
38#include <dirent.h>
39#include <errno.h>
40#include <fcntl.h>
41#include <signal.h>
42#include <stdarg.h>
43#include <stdio.h>
44#include <stdlib.h>
45#include <string.h>
46#include <unistd.h>
47
48#include "xmalloc.h"
49#include "ssherr.h"
50#include "sshbuf.h"
51#include "log.h"
52#include "atomicio.h"
53#include "progressmeter.h"
54#include "misc.h"
55#include "utf8.h"
56
57#include "sftp.h"
58#include "sftp-common.h"
59#include "sftp-client.h"
60
61extern volatile sig_atomic_t interrupted;
62extern int showprogress;
63
64/* Minimum amount of data to read at a time */
65#define MIN_READ_SIZE	512
66
67/* Maximum depth to descend in directory trees */
68#define MAX_DIR_DEPTH 64
69
70struct sftp_conn {
71	int fd_in;
72	int fd_out;
73	u_int transfer_buflen;
74	u_int num_requests;
75	u_int version;
76	u_int msg_id;
77#define SFTP_EXT_POSIX_RENAME	0x00000001
78#define SFTP_EXT_STATVFS	0x00000002
79#define SFTP_EXT_FSTATVFS	0x00000004
80#define SFTP_EXT_HARDLINK	0x00000008
81#define SFTP_EXT_FSYNC		0x00000010
82	u_int exts;
83	u_int64_t limit_kbps;
84	struct bwlimit bwlimit_in, bwlimit_out;
85};
86
87static u_char *
88get_handle(struct sftp_conn *conn, u_int expected_id, size_t *len,
89    const char *errfmt, ...) __attribute__((format(printf, 4, 5)));
90
91/* ARGSUSED */
92static int
93sftpio(void *_bwlimit, size_t amount)
94{
95	struct bwlimit *bwlimit = (struct bwlimit *)_bwlimit;
96
97	bandwidth_limit(bwlimit, amount);
98	return 0;
99}
100
101static void
102send_msg(struct sftp_conn *conn, struct sshbuf *m)
103{
104	u_char mlen[4];
105	struct iovec iov[2];
106
107	if (sshbuf_len(m) > SFTP_MAX_MSG_LENGTH)
108		fatal("Outbound message too long %zu", sshbuf_len(m));
109
110	/* Send length first */
111	put_u32(mlen, sshbuf_len(m));
112	iov[0].iov_base = mlen;
113	iov[0].iov_len = sizeof(mlen);
114	iov[1].iov_base = (u_char *)sshbuf_ptr(m);
115	iov[1].iov_len = sshbuf_len(m);
116
117	if (atomiciov6(writev, conn->fd_out, iov, 2,
118	    conn->limit_kbps > 0 ? sftpio : NULL, &conn->bwlimit_out) !=
119	    sshbuf_len(m) + sizeof(mlen))
120		fatal("Couldn't send packet: %s", strerror(errno));
121
122	sshbuf_reset(m);
123}
124
125static void
126get_msg(struct sftp_conn *conn, struct sshbuf *m)
127{
128	u_int msg_len;
129	u_char *p;
130	int r;
131
132	if ((r = sshbuf_reserve(m, 4, &p)) != 0)
133		fatal("%s: buffer error: %s", __func__, ssh_err(r));
134	if (atomicio6(read, conn->fd_in, p, 4,
135	    conn->limit_kbps > 0 ? sftpio : NULL, &conn->bwlimit_in) != 4) {
136		if (errno == EPIPE)
137			fatal("Connection closed");
138		else
139			fatal("Couldn't read packet: %s", strerror(errno));
140	}
141
142	if ((r = sshbuf_get_u32(m, &msg_len)) != 0)
143		fatal("%s: buffer error: %s", __func__, ssh_err(r));
144	if (msg_len > SFTP_MAX_MSG_LENGTH)
145		fatal("Received message too long %u", msg_len);
146
147	if ((r = sshbuf_reserve(m, msg_len, &p)) != 0)
148		fatal("%s: buffer error: %s", __func__, ssh_err(r));
149	if (atomicio6(read, conn->fd_in, p, msg_len,
150	    conn->limit_kbps > 0 ? sftpio : NULL, &conn->bwlimit_in)
151	    != msg_len) {
152		if (errno == EPIPE)
153			fatal("Connection closed");
154		else
155			fatal("Read packet: %s", strerror(errno));
156	}
157}
158
159static void
160send_string_request(struct sftp_conn *conn, u_int id, u_int code, const char *s,
161    u_int len)
162{
163	struct sshbuf *msg;
164	int r;
165
166	if ((msg = sshbuf_new()) == NULL)
167		fatal("%s: sshbuf_new failed", __func__);
168	if ((r = sshbuf_put_u8(msg, code)) != 0 ||
169	    (r = sshbuf_put_u32(msg, id)) != 0 ||
170	    (r = sshbuf_put_string(msg, s, len)) != 0)
171		fatal("%s: buffer error: %s", __func__, ssh_err(r));
172	send_msg(conn, msg);
173	debug3("Sent message fd %d T:%u I:%u", conn->fd_out, code, id);
174	sshbuf_free(msg);
175}
176
177static void
178send_string_attrs_request(struct sftp_conn *conn, u_int id, u_int code,
179    const void *s, u_int len, Attrib *a)
180{
181	struct sshbuf *msg;
182	int r;
183
184	if ((msg = sshbuf_new()) == NULL)
185		fatal("%s: sshbuf_new failed", __func__);
186	if ((r = sshbuf_put_u8(msg, code)) != 0 ||
187	    (r = sshbuf_put_u32(msg, id)) != 0 ||
188	    (r = sshbuf_put_string(msg, s, len)) != 0 ||
189	    (r = encode_attrib(msg, a)) != 0)
190		fatal("%s: buffer error: %s", __func__, ssh_err(r));
191	send_msg(conn, msg);
192	debug3("Sent message fd %d T:%u I:%u", conn->fd_out, code, id);
193	sshbuf_free(msg);
194}
195
196static u_int
197get_status(struct sftp_conn *conn, u_int expected_id)
198{
199	struct sshbuf *msg;
200	u_char type;
201	u_int id, status;
202	int r;
203
204	if ((msg = sshbuf_new()) == NULL)
205		fatal("%s: sshbuf_new failed", __func__);
206	get_msg(conn, msg);
207	if ((r = sshbuf_get_u8(msg, &type)) != 0 ||
208	    (r = sshbuf_get_u32(msg, &id)) != 0)
209		fatal("%s: buffer error: %s", __func__, ssh_err(r));
210
211	if (id != expected_id)
212		fatal("ID mismatch (%u != %u)", id, expected_id);
213	if (type != SSH2_FXP_STATUS)
214		fatal("Expected SSH2_FXP_STATUS(%u) packet, got %u",
215		    SSH2_FXP_STATUS, type);
216
217	if ((r = sshbuf_get_u32(msg, &status)) != 0)
218		fatal("%s: buffer error: %s", __func__, ssh_err(r));
219	sshbuf_free(msg);
220
221	debug3("SSH2_FXP_STATUS %u", status);
222
223	return status;
224}
225
226static u_char *
227get_handle(struct sftp_conn *conn, u_int expected_id, size_t *len,
228    const char *errfmt, ...)
229{
230	struct sshbuf *msg;
231	u_int id, status;
232	u_char type;
233	u_char *handle;
234	char errmsg[256];
235	va_list args;
236	int r;
237
238	va_start(args, errfmt);
239	if (errfmt != NULL)
240		vsnprintf(errmsg, sizeof(errmsg), errfmt, args);
241	va_end(args);
242
243	if ((msg = sshbuf_new()) == NULL)
244		fatal("%s: sshbuf_new failed", __func__);
245	get_msg(conn, msg);
246	if ((r = sshbuf_get_u8(msg, &type)) != 0 ||
247	    (r = sshbuf_get_u32(msg, &id)) != 0)
248		fatal("%s: buffer error: %s", __func__, ssh_err(r));
249
250	if (id != expected_id)
251		fatal("%s: ID mismatch (%u != %u)",
252		    errfmt == NULL ? __func__ : errmsg, id, expected_id);
253	if (type == SSH2_FXP_STATUS) {
254		if ((r = sshbuf_get_u32(msg, &status)) != 0)
255			fatal("%s: buffer error: %s", __func__, ssh_err(r));
256		if (errfmt != NULL)
257			error("%s: %s", errmsg, fx2txt(status));
258		sshbuf_free(msg);
259		return(NULL);
260	} else if (type != SSH2_FXP_HANDLE)
261		fatal("%s: Expected SSH2_FXP_HANDLE(%u) packet, got %u",
262		    errfmt == NULL ? __func__ : errmsg, SSH2_FXP_HANDLE, type);
263
264	if ((r = sshbuf_get_string(msg, &handle, len)) != 0)
265		fatal("%s: buffer error: %s", __func__, ssh_err(r));
266	sshbuf_free(msg);
267
268	return handle;
269}
270
271static Attrib *
272get_decode_stat(struct sftp_conn *conn, u_int expected_id, int quiet)
273{
274	struct sshbuf *msg;
275	u_int id;
276	u_char type;
277	int r;
278	static Attrib a;
279
280	if ((msg = sshbuf_new()) == NULL)
281		fatal("%s: sshbuf_new failed", __func__);
282	get_msg(conn, msg);
283
284	if ((r = sshbuf_get_u8(msg, &type)) != 0 ||
285	    (r = sshbuf_get_u32(msg, &id)) != 0)
286		fatal("%s: buffer error: %s", __func__, ssh_err(r));
287
288	debug3("Received stat reply T:%u I:%u", type, id);
289	if (id != expected_id)
290		fatal("ID mismatch (%u != %u)", id, expected_id);
291	if (type == SSH2_FXP_STATUS) {
292		u_int status;
293
294		if ((r = sshbuf_get_u32(msg, &status)) != 0)
295			fatal("%s: buffer error: %s", __func__, ssh_err(r));
296		if (quiet)
297			debug("Couldn't stat remote file: %s", fx2txt(status));
298		else
299			error("Couldn't stat remote file: %s", fx2txt(status));
300		sshbuf_free(msg);
301		return(NULL);
302	} else if (type != SSH2_FXP_ATTRS) {
303		fatal("Expected SSH2_FXP_ATTRS(%u) packet, got %u",
304		    SSH2_FXP_ATTRS, type);
305	}
306	if ((r = decode_attrib(msg, &a)) != 0) {
307		error("%s: couldn't decode attrib: %s", __func__, ssh_err(r));
308		sshbuf_free(msg);
309		return NULL;
310	}
311	sshbuf_free(msg);
312
313	return &a;
314}
315
316static int
317get_decode_statvfs(struct sftp_conn *conn, struct sftp_statvfs *st,
318    u_int expected_id, int quiet)
319{
320	struct sshbuf *msg;
321	u_char type;
322	u_int id;
323	u_int64_t flag;
324	int r;
325
326	if ((msg = sshbuf_new()) == NULL)
327		fatal("%s: sshbuf_new failed", __func__);
328	get_msg(conn, msg);
329
330	if ((r = sshbuf_get_u8(msg, &type)) != 0 ||
331	    (r = sshbuf_get_u32(msg, &id)) != 0)
332		fatal("%s: buffer error: %s", __func__, ssh_err(r));
333
334	debug3("Received statvfs reply T:%u I:%u", type, id);
335	if (id != expected_id)
336		fatal("ID mismatch (%u != %u)", id, expected_id);
337	if (type == SSH2_FXP_STATUS) {
338		u_int status;
339
340		if ((r = sshbuf_get_u32(msg, &status)) != 0)
341			fatal("%s: buffer error: %s", __func__, ssh_err(r));
342		if (quiet)
343			debug("Couldn't statvfs: %s", fx2txt(status));
344		else
345			error("Couldn't statvfs: %s", fx2txt(status));
346		sshbuf_free(msg);
347		return -1;
348	} else if (type != SSH2_FXP_EXTENDED_REPLY) {
349		fatal("Expected SSH2_FXP_EXTENDED_REPLY(%u) packet, got %u",
350		    SSH2_FXP_EXTENDED_REPLY, type);
351	}
352
353	memset(st, 0, sizeof(*st));
354	if ((r = sshbuf_get_u64(msg, &st->f_bsize)) != 0 ||
355	    (r = sshbuf_get_u64(msg, &st->f_frsize)) != 0 ||
356	    (r = sshbuf_get_u64(msg, &st->f_blocks)) != 0 ||
357	    (r = sshbuf_get_u64(msg, &st->f_bfree)) != 0 ||
358	    (r = sshbuf_get_u64(msg, &st->f_bavail)) != 0 ||
359	    (r = sshbuf_get_u64(msg, &st->f_files)) != 0 ||
360	    (r = sshbuf_get_u64(msg, &st->f_ffree)) != 0 ||
361	    (r = sshbuf_get_u64(msg, &st->f_favail)) != 0 ||
362	    (r = sshbuf_get_u64(msg, &st->f_fsid)) != 0 ||
363	    (r = sshbuf_get_u64(msg, &flag)) != 0 ||
364	    (r = sshbuf_get_u64(msg, &st->f_namemax)) != 0)
365		fatal("%s: buffer error: %s", __func__, ssh_err(r));
366
367	st->f_flag = (flag & SSH2_FXE_STATVFS_ST_RDONLY) ? ST_RDONLY : 0;
368	st->f_flag |= (flag & SSH2_FXE_STATVFS_ST_NOSUID) ? ST_NOSUID : 0;
369
370	sshbuf_free(msg);
371
372	return 0;
373}
374
375struct sftp_conn *
376do_init(int fd_in, int fd_out, u_int transfer_buflen, u_int num_requests,
377    u_int64_t limit_kbps)
378{
379	u_char type;
380	struct sshbuf *msg;
381	struct sftp_conn *ret;
382	int r;
383
384	ret = xcalloc(1, sizeof(*ret));
385	ret->msg_id = 1;
386	ret->fd_in = fd_in;
387	ret->fd_out = fd_out;
388	ret->transfer_buflen = transfer_buflen;
389	ret->num_requests = num_requests;
390	ret->exts = 0;
391	ret->limit_kbps = 0;
392
393	if ((msg = sshbuf_new()) == NULL)
394		fatal("%s: sshbuf_new failed", __func__);
395	if ((r = sshbuf_put_u8(msg, SSH2_FXP_INIT)) != 0 ||
396	    (r = sshbuf_put_u32(msg, SSH2_FILEXFER_VERSION)) != 0)
397		fatal("%s: buffer error: %s", __func__, ssh_err(r));
398	send_msg(ret, msg);
399
400	sshbuf_reset(msg);
401
402	get_msg(ret, msg);
403
404	/* Expecting a VERSION reply */
405	if ((r = sshbuf_get_u8(msg, &type)) != 0)
406		fatal("%s: buffer error: %s", __func__, ssh_err(r));
407	if (type != SSH2_FXP_VERSION) {
408		error("Invalid packet back from SSH2_FXP_INIT (type %u)",
409		    type);
410		sshbuf_free(msg);
411		free(ret);
412		return(NULL);
413	}
414	if ((r = sshbuf_get_u32(msg, &ret->version)) != 0)
415		fatal("%s: buffer error: %s", __func__, ssh_err(r));
416
417	debug2("Remote version: %u", ret->version);
418
419	/* Check for extensions */
420	while (sshbuf_len(msg) > 0) {
421		char *name;
422		u_char *value;
423		size_t vlen;
424		int known = 0;
425
426		if ((r = sshbuf_get_cstring(msg, &name, NULL)) != 0 ||
427		    (r = sshbuf_get_string(msg, &value, &vlen)) != 0)
428			fatal("%s: buffer error: %s", __func__, ssh_err(r));
429		if (strcmp(name, "posix-rename@openssh.com") == 0 &&
430		    strcmp((char *)value, "1") == 0) {
431			ret->exts |= SFTP_EXT_POSIX_RENAME;
432			known = 1;
433		} else if (strcmp(name, "statvfs@openssh.com") == 0 &&
434		    strcmp((char *)value, "2") == 0) {
435			ret->exts |= SFTP_EXT_STATVFS;
436			known = 1;
437		} else if (strcmp(name, "fstatvfs@openssh.com") == 0 &&
438		    strcmp((char *)value, "2") == 0) {
439			ret->exts |= SFTP_EXT_FSTATVFS;
440			known = 1;
441		} else if (strcmp(name, "hardlink@openssh.com") == 0 &&
442		    strcmp((char *)value, "1") == 0) {
443			ret->exts |= SFTP_EXT_HARDLINK;
444			known = 1;
445		} else if (strcmp(name, "fsync@openssh.com") == 0 &&
446		    strcmp((char *)value, "1") == 0) {
447			ret->exts |= SFTP_EXT_FSYNC;
448			known = 1;
449		}
450		if (known) {
451			debug2("Server supports extension \"%s\" revision %s",
452			    name, value);
453		} else {
454			debug2("Unrecognised server extension \"%s\"", name);
455		}
456		free(name);
457		free(value);
458	}
459
460	sshbuf_free(msg);
461
462	/* Some filexfer v.0 servers don't support large packets */
463	if (ret->version == 0)
464		ret->transfer_buflen = MINIMUM(ret->transfer_buflen, 20480);
465
466	ret->limit_kbps = limit_kbps;
467	if (ret->limit_kbps > 0) {
468		bandwidth_limit_init(&ret->bwlimit_in, ret->limit_kbps,
469		    ret->transfer_buflen);
470		bandwidth_limit_init(&ret->bwlimit_out, ret->limit_kbps,
471		    ret->transfer_buflen);
472	}
473
474	return ret;
475}
476
477u_int
478sftp_proto_version(struct sftp_conn *conn)
479{
480	return conn->version;
481}
482
483int
484do_close(struct sftp_conn *conn, const u_char *handle, u_int handle_len)
485{
486	u_int id, status;
487	struct sshbuf *msg;
488	int r;
489
490	if ((msg = sshbuf_new()) == NULL)
491		fatal("%s: sshbuf_new failed", __func__);
492
493	id = conn->msg_id++;
494	if ((r = sshbuf_put_u8(msg, SSH2_FXP_CLOSE)) != 0 ||
495	    (r = sshbuf_put_u32(msg, id)) != 0 ||
496	    (r = sshbuf_put_string(msg, handle, handle_len)) != 0)
497		fatal("%s: buffer error: %s", __func__, ssh_err(r));
498	send_msg(conn, msg);
499	debug3("Sent message SSH2_FXP_CLOSE I:%u", id);
500
501	status = get_status(conn, id);
502	if (status != SSH2_FX_OK)
503		error("Couldn't close file: %s", fx2txt(status));
504
505	sshbuf_free(msg);
506
507	return status == SSH2_FX_OK ? 0 : -1;
508}
509
510
511static int
512do_lsreaddir(struct sftp_conn *conn, const char *path, int print_flag,
513    SFTP_DIRENT ***dir)
514{
515	struct sshbuf *msg;
516	u_int count, id, i, expected_id, ents = 0;
517	size_t handle_len;
518	u_char type, *handle;
519	int status = SSH2_FX_FAILURE;
520	int r;
521
522	if (dir)
523		*dir = NULL;
524
525	id = conn->msg_id++;
526
527	if ((msg = sshbuf_new()) == NULL)
528		fatal("%s: sshbuf_new failed", __func__);
529	if ((r = sshbuf_put_u8(msg, SSH2_FXP_OPENDIR)) != 0 ||
530	    (r = sshbuf_put_u32(msg, id)) != 0 ||
531	    (r = sshbuf_put_cstring(msg, path)) != 0)
532		fatal("%s: buffer error: %s", __func__, ssh_err(r));
533	send_msg(conn, msg);
534
535	handle = get_handle(conn, id, &handle_len,
536	    "remote readdir(\"%s\")", path);
537	if (handle == NULL) {
538		sshbuf_free(msg);
539		return -1;
540	}
541
542	if (dir) {
543		ents = 0;
544		*dir = xcalloc(1, sizeof(**dir));
545		(*dir)[0] = NULL;
546	}
547
548	for (; !interrupted;) {
549		id = expected_id = conn->msg_id++;
550
551		debug3("Sending SSH2_FXP_READDIR I:%u", id);
552
553		sshbuf_reset(msg);
554		if ((r = sshbuf_put_u8(msg, SSH2_FXP_READDIR)) != 0 ||
555		    (r = sshbuf_put_u32(msg, id)) != 0 ||
556		    (r = sshbuf_put_string(msg, handle, handle_len)) != 0)
557			fatal("%s: buffer error: %s", __func__, ssh_err(r));
558		send_msg(conn, msg);
559
560		sshbuf_reset(msg);
561
562		get_msg(conn, msg);
563
564		if ((r = sshbuf_get_u8(msg, &type)) != 0 ||
565		    (r = sshbuf_get_u32(msg, &id)) != 0)
566			fatal("%s: buffer error: %s", __func__, ssh_err(r));
567
568		debug3("Received reply T:%u I:%u", type, id);
569
570		if (id != expected_id)
571			fatal("ID mismatch (%u != %u)", id, expected_id);
572
573		if (type == SSH2_FXP_STATUS) {
574			u_int rstatus;
575
576			if ((r = sshbuf_get_u32(msg, &rstatus)) != 0)
577				fatal("%s: buffer error: %s",
578				    __func__, ssh_err(r));
579			debug3("Received SSH2_FXP_STATUS %d", rstatus);
580			if (rstatus == SSH2_FX_EOF)
581				break;
582			error("Couldn't read directory: %s", fx2txt(rstatus));
583			goto out;
584		} else if (type != SSH2_FXP_NAME)
585			fatal("Expected SSH2_FXP_NAME(%u) packet, got %u",
586			    SSH2_FXP_NAME, type);
587
588		if ((r = sshbuf_get_u32(msg, &count)) != 0)
589			fatal("%s: buffer error: %s", __func__, ssh_err(r));
590		if (count == 0)
591			break;
592		debug3("Received %d SSH2_FXP_NAME responses", count);
593		for (i = 0; i < count; i++) {
594			char *filename, *longname;
595			Attrib a;
596
597			if ((r = sshbuf_get_cstring(msg, &filename,
598			    NULL)) != 0 ||
599			    (r = sshbuf_get_cstring(msg, &longname,
600			    NULL)) != 0)
601				fatal("%s: buffer error: %s",
602				    __func__, ssh_err(r));
603			if ((r = decode_attrib(msg, &a)) != 0) {
604				error("%s: couldn't decode attrib: %s",
605				    __func__, ssh_err(r));
606				free(filename);
607				free(longname);
608				sshbuf_free(msg);
609				return -1;
610			}
611
612			if (print_flag)
613				mprintf("%s\n", longname);
614
615			/*
616			 * Directory entries should never contain '/'
617			 * These can be used to attack recursive ops
618			 * (e.g. send '../../../../etc/passwd')
619			 */
620			if (strchr(filename, '/') != NULL) {
621				error("Server sent suspect path \"%s\" "
622				    "during readdir of \"%s\"", filename, path);
623			} else if (dir) {
624				*dir = xreallocarray(*dir, ents + 2, sizeof(**dir));
625				(*dir)[ents] = xcalloc(1, sizeof(***dir));
626				(*dir)[ents]->filename = xstrdup(filename);
627				(*dir)[ents]->longname = xstrdup(longname);
628				memcpy(&(*dir)[ents]->a, &a, sizeof(a));
629				(*dir)[++ents] = NULL;
630			}
631			free(filename);
632			free(longname);
633		}
634	}
635	status = 0;
636
637 out:
638	sshbuf_free(msg);
639	do_close(conn, handle, handle_len);
640	free(handle);
641
642	if (status != 0 && dir != NULL) {
643		/* Don't return results on error */
644		free_sftp_dirents(*dir);
645		*dir = NULL;
646	} else if (interrupted && dir != NULL && *dir != NULL) {
647		/* Don't return partial matches on interrupt */
648		free_sftp_dirents(*dir);
649		*dir = xcalloc(1, sizeof(**dir));
650		**dir = NULL;
651	}
652
653	return status;
654}
655
656int
657do_readdir(struct sftp_conn *conn, const char *path, SFTP_DIRENT ***dir)
658{
659	return(do_lsreaddir(conn, path, 0, dir));
660}
661
662void free_sftp_dirents(SFTP_DIRENT **s)
663{
664	int i;
665
666	if (s == NULL)
667		return;
668	for (i = 0; s[i]; i++) {
669		free(s[i]->filename);
670		free(s[i]->longname);
671		free(s[i]);
672	}
673	free(s);
674}
675
676int
677do_rm(struct sftp_conn *conn, const char *path)
678{
679	u_int status, id;
680
681	debug2("Sending SSH2_FXP_REMOVE \"%s\"", path);
682
683	id = conn->msg_id++;
684	send_string_request(conn, id, SSH2_FXP_REMOVE, path, strlen(path));
685	status = get_status(conn, id);
686	if (status != SSH2_FX_OK)
687		error("Couldn't delete file: %s", fx2txt(status));
688	return status == SSH2_FX_OK ? 0 : -1;
689}
690
691int
692do_mkdir(struct sftp_conn *conn, const char *path, Attrib *a, int print_flag)
693{
694	u_int status, id;
695
696	id = conn->msg_id++;
697	send_string_attrs_request(conn, id, SSH2_FXP_MKDIR, path,
698	    strlen(path), a);
699
700	status = get_status(conn, id);
701	if (status != SSH2_FX_OK && print_flag)
702		error("Couldn't create directory: %s", fx2txt(status));
703
704	return status == SSH2_FX_OK ? 0 : -1;
705}
706
707int
708do_rmdir(struct sftp_conn *conn, const char *path)
709{
710	u_int status, id;
711
712	id = conn->msg_id++;
713	send_string_request(conn, id, SSH2_FXP_RMDIR, path,
714	    strlen(path));
715
716	status = get_status(conn, id);
717	if (status != SSH2_FX_OK)
718		error("Couldn't remove directory: %s", fx2txt(status));
719
720	return status == SSH2_FX_OK ? 0 : -1;
721}
722
723Attrib *
724do_stat(struct sftp_conn *conn, const char *path, int quiet)
725{
726	u_int id;
727
728	id = conn->msg_id++;
729
730	send_string_request(conn, id,
731	    conn->version == 0 ? SSH2_FXP_STAT_VERSION_0 : SSH2_FXP_STAT,
732	    path, strlen(path));
733
734	return(get_decode_stat(conn, id, quiet));
735}
736
737Attrib *
738do_lstat(struct sftp_conn *conn, const char *path, int quiet)
739{
740	u_int id;
741
742	if (conn->version == 0) {
743		if (quiet)
744			debug("Server version does not support lstat operation");
745		else
746			logit("Server version does not support lstat operation");
747		return(do_stat(conn, path, quiet));
748	}
749
750	id = conn->msg_id++;
751	send_string_request(conn, id, SSH2_FXP_LSTAT, path,
752	    strlen(path));
753
754	return(get_decode_stat(conn, id, quiet));
755}
756
757#ifdef notyet
758Attrib *
759do_fstat(struct sftp_conn *conn, const u_char *handle, u_int handle_len,
760    int quiet)
761{
762	u_int id;
763
764	id = conn->msg_id++;
765	send_string_request(conn, id, SSH2_FXP_FSTAT, handle,
766	    handle_len);
767
768	return(get_decode_stat(conn, id, quiet));
769}
770#endif
771
772int
773do_setstat(struct sftp_conn *conn, const char *path, Attrib *a)
774{
775	u_int status, id;
776
777	id = conn->msg_id++;
778	send_string_attrs_request(conn, id, SSH2_FXP_SETSTAT, path,
779	    strlen(path), a);
780
781	status = get_status(conn, id);
782	if (status != SSH2_FX_OK)
783		error("Couldn't setstat on \"%s\": %s", path,
784		    fx2txt(status));
785
786	return status == SSH2_FX_OK ? 0 : -1;
787}
788
789int
790do_fsetstat(struct sftp_conn *conn, const u_char *handle, u_int handle_len,
791    Attrib *a)
792{
793	u_int status, id;
794
795	id = conn->msg_id++;
796	send_string_attrs_request(conn, id, SSH2_FXP_FSETSTAT, handle,
797	    handle_len, a);
798
799	status = get_status(conn, id);
800	if (status != SSH2_FX_OK)
801		error("Couldn't fsetstat: %s", fx2txt(status));
802
803	return status == SSH2_FX_OK ? 0 : -1;
804}
805
806char *
807do_realpath(struct sftp_conn *conn, const char *path)
808{
809	struct sshbuf *msg;
810	u_int expected_id, count, id;
811	char *filename, *longname;
812	Attrib a;
813	u_char type;
814	int r;
815
816	expected_id = id = conn->msg_id++;
817	send_string_request(conn, id, SSH2_FXP_REALPATH, path,
818	    strlen(path));
819
820	if ((msg = sshbuf_new()) == NULL)
821		fatal("%s: sshbuf_new failed", __func__);
822
823	get_msg(conn, msg);
824	if ((r = sshbuf_get_u8(msg, &type)) != 0 ||
825	    (r = sshbuf_get_u32(msg, &id)) != 0)
826		fatal("%s: buffer error: %s", __func__, ssh_err(r));
827
828	if (id != expected_id)
829		fatal("ID mismatch (%u != %u)", id, expected_id);
830
831	if (type == SSH2_FXP_STATUS) {
832		u_int status;
833
834		if ((r = sshbuf_get_u32(msg, &status)) != 0)
835			fatal("%s: buffer error: %s", __func__, ssh_err(r));
836		error("Couldn't canonicalize: %s", fx2txt(status));
837		sshbuf_free(msg);
838		return NULL;
839	} else if (type != SSH2_FXP_NAME)
840		fatal("Expected SSH2_FXP_NAME(%u) packet, got %u",
841		    SSH2_FXP_NAME, type);
842
843	if ((r = sshbuf_get_u32(msg, &count)) != 0)
844		fatal("%s: buffer error: %s", __func__, ssh_err(r));
845	if (count != 1)
846		fatal("Got multiple names (%d) from SSH_FXP_REALPATH", count);
847
848	if ((r = sshbuf_get_cstring(msg, &filename, NULL)) != 0 ||
849	    (r = sshbuf_get_cstring(msg, &longname, NULL)) != 0 ||
850	    (r = decode_attrib(msg, &a)) != 0)
851		fatal("%s: buffer error: %s", __func__, ssh_err(r));
852
853	debug3("SSH_FXP_REALPATH %s -> %s size %lu", path, filename,
854	    (unsigned long)a.size);
855
856	free(longname);
857
858	sshbuf_free(msg);
859
860	return(filename);
861}
862
863int
864do_rename(struct sftp_conn *conn, const char *oldpath, const char *newpath,
865    int force_legacy)
866{
867	struct sshbuf *msg;
868	u_int status, id;
869	int r, use_ext = (conn->exts & SFTP_EXT_POSIX_RENAME) && !force_legacy;
870
871	if ((msg = sshbuf_new()) == NULL)
872		fatal("%s: sshbuf_new failed", __func__);
873
874	/* Send rename request */
875	id = conn->msg_id++;
876	if (use_ext) {
877		if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED)) != 0 ||
878		    (r = sshbuf_put_u32(msg, id)) != 0 ||
879		    (r = sshbuf_put_cstring(msg,
880		    "posix-rename@openssh.com")) != 0)
881			fatal("%s: buffer error: %s", __func__, ssh_err(r));
882	} else {
883		if ((r = sshbuf_put_u8(msg, SSH2_FXP_RENAME)) != 0 ||
884		    (r = sshbuf_put_u32(msg, id)) != 0)
885			fatal("%s: buffer error: %s", __func__, ssh_err(r));
886	}
887	if ((r = sshbuf_put_cstring(msg, oldpath)) != 0 ||
888	    (r = sshbuf_put_cstring(msg, newpath)) != 0)
889		fatal("%s: buffer error: %s", __func__, ssh_err(r));
890	send_msg(conn, msg);
891	debug3("Sent message %s \"%s\" -> \"%s\"",
892	    use_ext ? "posix-rename@openssh.com" :
893	    "SSH2_FXP_RENAME", oldpath, newpath);
894	sshbuf_free(msg);
895
896	status = get_status(conn, id);
897	if (status != SSH2_FX_OK)
898		error("Couldn't rename file \"%s\" to \"%s\": %s", oldpath,
899		    newpath, fx2txt(status));
900
901	return status == SSH2_FX_OK ? 0 : -1;
902}
903
904int
905do_hardlink(struct sftp_conn *conn, const char *oldpath, const char *newpath)
906{
907	struct sshbuf *msg;
908	u_int status, id;
909	int r;
910
911	if ((conn->exts & SFTP_EXT_HARDLINK) == 0) {
912		error("Server does not support hardlink@openssh.com extension");
913		return -1;
914	}
915
916	if ((msg = sshbuf_new()) == NULL)
917		fatal("%s: sshbuf_new failed", __func__);
918
919	/* Send link request */
920	id = conn->msg_id++;
921	if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED)) != 0 ||
922	    (r = sshbuf_put_u32(msg, id)) != 0 ||
923	    (r = sshbuf_put_cstring(msg, "hardlink@openssh.com")) != 0 ||
924	    (r = sshbuf_put_cstring(msg, oldpath)) != 0 ||
925	    (r = sshbuf_put_cstring(msg, newpath)) != 0)
926		fatal("%s: buffer error: %s", __func__, ssh_err(r));
927	send_msg(conn, msg);
928	debug3("Sent message hardlink@openssh.com \"%s\" -> \"%s\"",
929	       oldpath, newpath);
930	sshbuf_free(msg);
931
932	status = get_status(conn, id);
933	if (status != SSH2_FX_OK)
934		error("Couldn't link file \"%s\" to \"%s\": %s", oldpath,
935		    newpath, fx2txt(status));
936
937	return status == SSH2_FX_OK ? 0 : -1;
938}
939
940int
941do_symlink(struct sftp_conn *conn, const char *oldpath, const char *newpath)
942{
943	struct sshbuf *msg;
944	u_int status, id;
945	int r;
946
947	if (conn->version < 3) {
948		error("This server does not support the symlink operation");
949		return(SSH2_FX_OP_UNSUPPORTED);
950	}
951
952	if ((msg = sshbuf_new()) == NULL)
953		fatal("%s: sshbuf_new failed", __func__);
954
955	/* Send symlink request */
956	id = conn->msg_id++;
957	if ((r = sshbuf_put_u8(msg, SSH2_FXP_SYMLINK)) != 0 ||
958	    (r = sshbuf_put_u32(msg, id)) != 0 ||
959	    (r = sshbuf_put_cstring(msg, oldpath)) != 0 ||
960	    (r = sshbuf_put_cstring(msg, newpath)) != 0)
961		fatal("%s: buffer error: %s", __func__, ssh_err(r));
962	send_msg(conn, msg);
963	debug3("Sent message SSH2_FXP_SYMLINK \"%s\" -> \"%s\"", oldpath,
964	    newpath);
965	sshbuf_free(msg);
966
967	status = get_status(conn, id);
968	if (status != SSH2_FX_OK)
969		error("Couldn't symlink file \"%s\" to \"%s\": %s", oldpath,
970		    newpath, fx2txt(status));
971
972	return status == SSH2_FX_OK ? 0 : -1;
973}
974
975int
976do_fsync(struct sftp_conn *conn, u_char *handle, u_int handle_len)
977{
978	struct sshbuf *msg;
979	u_int status, id;
980	int r;
981
982	/* Silently return if the extension is not supported */
983	if ((conn->exts & SFTP_EXT_FSYNC) == 0)
984		return -1;
985
986	/* Send fsync request */
987	if ((msg = sshbuf_new()) == NULL)
988		fatal("%s: sshbuf_new failed", __func__);
989	id = conn->msg_id++;
990	if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED)) != 0 ||
991	    (r = sshbuf_put_u32(msg, id)) != 0 ||
992	    (r = sshbuf_put_cstring(msg, "fsync@openssh.com")) != 0 ||
993	    (r = sshbuf_put_string(msg, handle, handle_len)) != 0)
994		fatal("%s: buffer error: %s", __func__, ssh_err(r));
995	send_msg(conn, msg);
996	debug3("Sent message fsync@openssh.com I:%u", id);
997	sshbuf_free(msg);
998
999	status = get_status(conn, id);
1000	if (status != SSH2_FX_OK)
1001		error("Couldn't sync file: %s", fx2txt(status));
1002
1003	return status;
1004}
1005
1006#ifdef notyet
1007char *
1008do_readlink(struct sftp_conn *conn, const char *path)
1009{
1010	struct sshbuf *msg;
1011	u_int expected_id, count, id;
1012	char *filename, *longname;
1013	Attrib a;
1014	u_char type;
1015	int r;
1016
1017	expected_id = id = conn->msg_id++;
1018	send_string_request(conn, id, SSH2_FXP_READLINK, path, strlen(path));
1019
1020	if ((msg = sshbuf_new()) == NULL)
1021		fatal("%s: sshbuf_new failed", __func__);
1022
1023	get_msg(conn, msg);
1024	if ((r = sshbuf_get_u8(msg, &type)) != 0 ||
1025	    (r = sshbuf_get_u32(msg, &id)) != 0)
1026		fatal("%s: buffer error: %s", __func__, ssh_err(r));
1027
1028	if (id != expected_id)
1029		fatal("ID mismatch (%u != %u)", id, expected_id);
1030
1031	if (type == SSH2_FXP_STATUS) {
1032		u_int status;
1033
1034		if ((r = sshbuf_get_u32(msg, &status)) != 0)
1035			fatal("%s: buffer error: %s", __func__, ssh_err(r));
1036		error("Couldn't readlink: %s", fx2txt(status));
1037		sshbuf_free(msg);
1038		return(NULL);
1039	} else if (type != SSH2_FXP_NAME)
1040		fatal("Expected SSH2_FXP_NAME(%u) packet, got %u",
1041		    SSH2_FXP_NAME, type);
1042
1043	if ((r = sshbuf_get_u32(msg, &count)) != 0)
1044		fatal("%s: buffer error: %s", __func__, ssh_err(r));
1045	if (count != 1)
1046		fatal("Got multiple names (%d) from SSH_FXP_READLINK", count);
1047
1048	if ((r = sshbuf_get_cstring(msg, &filename, NULL)) != 0 ||
1049	    (r = sshbuf_get_cstring(msg, &longname, NULL)) != 0 ||
1050	    (r = decode_attrib(msg, &a)) != 0)
1051		fatal("%s: buffer error: %s", __func__, ssh_err(r));
1052
1053	debug3("SSH_FXP_READLINK %s -> %s", path, filename);
1054
1055	free(longname);
1056
1057	sshbuf_free(msg);
1058
1059	return filename;
1060}
1061#endif
1062
1063int
1064do_statvfs(struct sftp_conn *conn, const char *path, struct sftp_statvfs *st,
1065    int quiet)
1066{
1067	struct sshbuf *msg;
1068	u_int id;
1069	int r;
1070
1071	if ((conn->exts & SFTP_EXT_STATVFS) == 0) {
1072		error("Server does not support statvfs@openssh.com extension");
1073		return -1;
1074	}
1075
1076	id = conn->msg_id++;
1077
1078	if ((msg = sshbuf_new()) == NULL)
1079		fatal("%s: sshbuf_new failed", __func__);
1080	sshbuf_reset(msg);
1081	if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED)) != 0 ||
1082	    (r = sshbuf_put_u32(msg, id)) != 0 ||
1083	    (r = sshbuf_put_cstring(msg, "statvfs@openssh.com")) != 0 ||
1084	    (r = sshbuf_put_cstring(msg, path)) != 0)
1085		fatal("%s: buffer error: %s", __func__, ssh_err(r));
1086	send_msg(conn, msg);
1087	sshbuf_free(msg);
1088
1089	return get_decode_statvfs(conn, st, id, quiet);
1090}
1091
1092#ifdef notyet
1093int
1094do_fstatvfs(struct sftp_conn *conn, const u_char *handle, u_int handle_len,
1095    struct sftp_statvfs *st, int quiet)
1096{
1097	struct sshbuf *msg;
1098	u_int id;
1099
1100	if ((conn->exts & SFTP_EXT_FSTATVFS) == 0) {
1101		error("Server does not support fstatvfs@openssh.com extension");
1102		return -1;
1103	}
1104
1105	id = conn->msg_id++;
1106
1107	if ((msg = sshbuf_new()) == NULL)
1108		fatal("%s: sshbuf_new failed", __func__);
1109	sshbuf_reset(msg);
1110	if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED)) != 0 ||
1111	    (r = sshbuf_put_u32(msg, id)) != 0 ||
1112	    (r = sshbuf_put_cstring(msg, "fstatvfs@openssh.com")) != 0 ||
1113	    (r = sshbuf_put_string(msg, handle, handle_len)) != 0)
1114		fatal("%s: buffer error: %s", __func__, ssh_err(r));
1115	send_msg(conn, msg);
1116	sshbuf_free(msg);
1117
1118	return get_decode_statvfs(conn, st, id, quiet);
1119}
1120#endif
1121
1122static void
1123send_read_request(struct sftp_conn *conn, u_int id, u_int64_t offset,
1124    u_int len, const u_char *handle, u_int handle_len)
1125{
1126	struct sshbuf *msg;
1127	int r;
1128
1129	if ((msg = sshbuf_new()) == NULL)
1130		fatal("%s: sshbuf_new failed", __func__);
1131	sshbuf_reset(msg);
1132	if ((r = sshbuf_put_u8(msg, SSH2_FXP_READ)) != 0 ||
1133	    (r = sshbuf_put_u32(msg, id)) != 0 ||
1134	    (r = sshbuf_put_string(msg, handle, handle_len)) != 0 ||
1135	    (r = sshbuf_put_u64(msg, offset)) != 0 ||
1136	    (r = sshbuf_put_u32(msg, len)) != 0)
1137		fatal("%s: buffer error: %s", __func__, ssh_err(r));
1138	send_msg(conn, msg);
1139	sshbuf_free(msg);
1140}
1141
1142int
1143do_download(struct sftp_conn *conn, const char *remote_path,
1144    const char *local_path, Attrib *a, int preserve_flag, int resume_flag,
1145    int fsync_flag)
1146{
1147	Attrib junk;
1148	struct sshbuf *msg;
1149	u_char *handle;
1150	int local_fd = -1, write_error;
1151	int read_error, write_errno, reordered = 0, r;
1152	u_int64_t offset = 0, size, highwater;
1153	u_int mode, id, buflen, num_req, max_req, status = SSH2_FX_OK;
1154	off_t progress_counter;
1155	size_t handle_len;
1156	struct stat st;
1157	struct request {
1158		u_int id;
1159		size_t len;
1160		u_int64_t offset;
1161		TAILQ_ENTRY(request) tq;
1162	};
1163	TAILQ_HEAD(reqhead, request) requests;
1164	struct request *req;
1165	u_char type;
1166
1167	TAILQ_INIT(&requests);
1168
1169	if (a == NULL && (a = do_stat(conn, remote_path, 0)) == NULL)
1170		return -1;
1171
1172	/* Do not preserve set[ug]id here, as we do not preserve ownership */
1173	if (a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS)
1174		mode = a->perm & 0777;
1175	else
1176		mode = 0666;
1177
1178	if ((a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS) &&
1179	    (!S_ISREG(a->perm))) {
1180		error("Cannot download non-regular file: %s", remote_path);
1181		return(-1);
1182	}
1183
1184	if (a->flags & SSH2_FILEXFER_ATTR_SIZE)
1185		size = a->size;
1186	else
1187		size = 0;
1188
1189	buflen = conn->transfer_buflen;
1190	if ((msg = sshbuf_new()) == NULL)
1191		fatal("%s: sshbuf_new failed", __func__);
1192
1193	attrib_clear(&junk); /* Send empty attributes */
1194
1195	/* Send open request */
1196	id = conn->msg_id++;
1197	if ((r = sshbuf_put_u8(msg, SSH2_FXP_OPEN)) != 0 ||
1198	    (r = sshbuf_put_u32(msg, id)) != 0 ||
1199	    (r = sshbuf_put_cstring(msg, remote_path)) != 0 ||
1200	    (r = sshbuf_put_u32(msg, SSH2_FXF_READ)) != 0 ||
1201	    (r = encode_attrib(msg, &junk)) != 0)
1202		fatal("%s: buffer error: %s", __func__, ssh_err(r));
1203	send_msg(conn, msg);
1204	debug3("Sent message SSH2_FXP_OPEN I:%u P:%s", id, remote_path);
1205
1206	handle = get_handle(conn, id, &handle_len,
1207	    "remote open(\"%s\")", remote_path);
1208	if (handle == NULL) {
1209		sshbuf_free(msg);
1210		return(-1);
1211	}
1212
1213	local_fd = open(local_path,
1214	    O_WRONLY | O_CREAT | (resume_flag ? 0 : O_TRUNC), mode | S_IWUSR);
1215	if (local_fd == -1) {
1216		error("Couldn't open local file \"%s\" for writing: %s",
1217		    local_path, strerror(errno));
1218		goto fail;
1219	}
1220	offset = highwater = 0;
1221	if (resume_flag) {
1222		if (fstat(local_fd, &st) == -1) {
1223			error("Unable to stat local file \"%s\": %s",
1224			    local_path, strerror(errno));
1225			goto fail;
1226		}
1227		if (st.st_size < 0) {
1228			error("\"%s\" has negative size", local_path);
1229			goto fail;
1230		}
1231		if ((u_int64_t)st.st_size > size) {
1232			error("Unable to resume download of \"%s\": "
1233			    "local file is larger than remote", local_path);
1234 fail:
1235			do_close(conn, handle, handle_len);
1236			sshbuf_free(msg);
1237			free(handle);
1238			if (local_fd != -1)
1239				close(local_fd);
1240			return -1;
1241		}
1242		offset = highwater = st.st_size;
1243	}
1244
1245	/* Read from remote and write to local */
1246	write_error = read_error = write_errno = num_req = 0;
1247	max_req = 1;
1248	progress_counter = offset;
1249
1250	if (showprogress && size != 0)
1251		start_progress_meter(remote_path, size, &progress_counter);
1252
1253	while (num_req > 0 || max_req > 0) {
1254		u_char *data;
1255		size_t len;
1256
1257		/*
1258		 * Simulate EOF on interrupt: stop sending new requests and
1259		 * allow outstanding requests to drain gracefully
1260		 */
1261		if (interrupted) {
1262			if (num_req == 0) /* If we haven't started yet... */
1263				break;
1264			max_req = 0;
1265		}
1266
1267		/* Send some more requests */
1268		while (num_req < max_req) {
1269			debug3("Request range %llu -> %llu (%d/%d)",
1270			    (unsigned long long)offset,
1271			    (unsigned long long)offset + buflen - 1,
1272			    num_req, max_req);
1273			req = xcalloc(1, sizeof(*req));
1274			req->id = conn->msg_id++;
1275			req->len = buflen;
1276			req->offset = offset;
1277			offset += buflen;
1278			num_req++;
1279			TAILQ_INSERT_TAIL(&requests, req, tq);
1280			send_read_request(conn, req->id, req->offset,
1281			    req->len, handle, handle_len);
1282		}
1283
1284		sshbuf_reset(msg);
1285		get_msg(conn, msg);
1286		if ((r = sshbuf_get_u8(msg, &type)) != 0 ||
1287		    (r = sshbuf_get_u32(msg, &id)) != 0)
1288			fatal("%s: buffer error: %s", __func__, ssh_err(r));
1289		debug3("Received reply T:%u I:%u R:%d", type, id, max_req);
1290
1291		/* Find the request in our queue */
1292		for (req = TAILQ_FIRST(&requests);
1293		    req != NULL && req->id != id;
1294		    req = TAILQ_NEXT(req, tq))
1295			;
1296		if (req == NULL)
1297			fatal("Unexpected reply %u", id);
1298
1299		switch (type) {
1300		case SSH2_FXP_STATUS:
1301			if ((r = sshbuf_get_u32(msg, &status)) != 0)
1302				fatal("%s: buffer error: %s",
1303				    __func__, ssh_err(r));
1304			if (status != SSH2_FX_EOF)
1305				read_error = 1;
1306			max_req = 0;
1307			TAILQ_REMOVE(&requests, req, tq);
1308			free(req);
1309			num_req--;
1310			break;
1311		case SSH2_FXP_DATA:
1312			if ((r = sshbuf_get_string(msg, &data, &len)) != 0)
1313				fatal("%s: buffer error: %s",
1314				    __func__, ssh_err(r));
1315			debug3("Received data %llu -> %llu",
1316			    (unsigned long long)req->offset,
1317			    (unsigned long long)req->offset + len - 1);
1318			if (len > req->len)
1319				fatal("Received more data than asked for "
1320				    "%zu > %zu", len, req->len);
1321			if ((lseek(local_fd, req->offset, SEEK_SET) == -1 ||
1322			    atomicio(vwrite, local_fd, data, len) != len) &&
1323			    !write_error) {
1324				write_errno = errno;
1325				write_error = 1;
1326				max_req = 0;
1327			}
1328			else if (!reordered && req->offset <= highwater)
1329				highwater = req->offset + len;
1330			else if (!reordered && req->offset > highwater)
1331				reordered = 1;
1332			progress_counter += len;
1333			free(data);
1334
1335			if (len == req->len) {
1336				TAILQ_REMOVE(&requests, req, tq);
1337				free(req);
1338				num_req--;
1339			} else {
1340				/* Resend the request for the missing data */
1341				debug3("Short data block, re-requesting "
1342				    "%llu -> %llu (%2d)",
1343				    (unsigned long long)req->offset + len,
1344				    (unsigned long long)req->offset +
1345				    req->len - 1, num_req);
1346				req->id = conn->msg_id++;
1347				req->len -= len;
1348				req->offset += len;
1349				send_read_request(conn, req->id,
1350				    req->offset, req->len, handle, handle_len);
1351				/* Reduce the request size */
1352				if (len < buflen)
1353					buflen = MAXIMUM(MIN_READ_SIZE, len);
1354			}
1355			if (max_req > 0) { /* max_req = 0 iff EOF received */
1356				if (size > 0 && offset > size) {
1357					/* Only one request at a time
1358					 * after the expected EOF */
1359					debug3("Finish at %llu (%2d)",
1360					    (unsigned long long)offset,
1361					    num_req);
1362					max_req = 1;
1363				} else if (max_req <= conn->num_requests) {
1364					++max_req;
1365				}
1366			}
1367			break;
1368		default:
1369			fatal("Expected SSH2_FXP_DATA(%u) packet, got %u",
1370			    SSH2_FXP_DATA, type);
1371		}
1372	}
1373
1374	if (showprogress && size)
1375		stop_progress_meter();
1376
1377	/* Sanity check */
1378	if (TAILQ_FIRST(&requests) != NULL)
1379		fatal("Transfer complete, but requests still in queue");
1380	/* Truncate at highest contiguous point to avoid holes on interrupt */
1381	if (read_error || write_error || interrupted) {
1382		if (reordered && resume_flag) {
1383			error("Unable to resume download of \"%s\": "
1384			    "server reordered requests", local_path);
1385		}
1386		debug("truncating at %llu", (unsigned long long)highwater);
1387		if (ftruncate(local_fd, highwater) == -1)
1388			error("ftruncate \"%s\": %s", local_path,
1389			    strerror(errno));
1390	}
1391	if (read_error) {
1392		error("Couldn't read from remote file \"%s\" : %s",
1393		    remote_path, fx2txt(status));
1394		status = -1;
1395		do_close(conn, handle, handle_len);
1396	} else if (write_error) {
1397		error("Couldn't write to \"%s\": %s", local_path,
1398		    strerror(write_errno));
1399		status = SSH2_FX_FAILURE;
1400		do_close(conn, handle, handle_len);
1401	} else {
1402		if (do_close(conn, handle, handle_len) != 0 || interrupted)
1403			status = SSH2_FX_FAILURE;
1404		else
1405			status = SSH2_FX_OK;
1406		/* Override umask and utimes if asked */
1407#ifdef HAVE_FCHMOD
1408		if (preserve_flag && fchmod(local_fd, mode) == -1)
1409#else
1410		if (preserve_flag && chmod(local_path, mode) == -1)
1411#endif /* HAVE_FCHMOD */
1412			error("Couldn't set mode on \"%s\": %s", local_path,
1413			    strerror(errno));
1414		if (preserve_flag &&
1415		    (a->flags & SSH2_FILEXFER_ATTR_ACMODTIME)) {
1416			struct timeval tv[2];
1417			tv[0].tv_sec = a->atime;
1418			tv[1].tv_sec = a->mtime;
1419			tv[0].tv_usec = tv[1].tv_usec = 0;
1420			if (utimes(local_path, tv) == -1)
1421				error("Can't set times on \"%s\": %s",
1422				    local_path, strerror(errno));
1423		}
1424		if (fsync_flag) {
1425			debug("syncing \"%s\"", local_path);
1426			if (fsync(local_fd) == -1)
1427				error("Couldn't sync file \"%s\": %s",
1428				    local_path, strerror(errno));
1429		}
1430	}
1431	close(local_fd);
1432	sshbuf_free(msg);
1433	free(handle);
1434
1435	return(status);
1436}
1437
1438static int
1439download_dir_internal(struct sftp_conn *conn, const char *src, const char *dst,
1440    int depth, Attrib *dirattrib, int preserve_flag, int print_flag,
1441    int resume_flag, int fsync_flag)
1442{
1443	int i, ret = 0;
1444	SFTP_DIRENT **dir_entries;
1445	char *filename, *new_src, *new_dst;
1446	mode_t mode = 0777;
1447
1448	if (depth >= MAX_DIR_DEPTH) {
1449		error("Maximum directory depth exceeded: %d levels", depth);
1450		return -1;
1451	}
1452
1453	if (dirattrib == NULL &&
1454	    (dirattrib = do_stat(conn, src, 1)) == NULL) {
1455		error("Unable to stat remote directory \"%s\"", src);
1456		return -1;
1457	}
1458	if (!S_ISDIR(dirattrib->perm)) {
1459		error("\"%s\" is not a directory", src);
1460		return -1;
1461	}
1462	if (print_flag)
1463		mprintf("Retrieving %s\n", src);
1464
1465	if (dirattrib->flags & SSH2_FILEXFER_ATTR_PERMISSIONS)
1466		mode = dirattrib->perm & 01777;
1467	else {
1468		debug("Server did not send permissions for "
1469		    "directory \"%s\"", dst);
1470	}
1471
1472	if (mkdir(dst, mode) == -1 && errno != EEXIST) {
1473		error("mkdir %s: %s", dst, strerror(errno));
1474		return -1;
1475	}
1476
1477	if (do_readdir(conn, src, &dir_entries) == -1) {
1478		error("%s: Failed to get directory contents", src);
1479		return -1;
1480	}
1481
1482	for (i = 0; dir_entries[i] != NULL && !interrupted; i++) {
1483		filename = dir_entries[i]->filename;
1484
1485		new_dst = path_append(dst, filename);
1486		new_src = path_append(src, filename);
1487
1488		if (S_ISDIR(dir_entries[i]->a.perm)) {
1489			if (strcmp(filename, ".") == 0 ||
1490			    strcmp(filename, "..") == 0)
1491				continue;
1492			if (download_dir_internal(conn, new_src, new_dst,
1493			    depth + 1, &(dir_entries[i]->a), preserve_flag,
1494			    print_flag, resume_flag, fsync_flag) == -1)
1495				ret = -1;
1496		} else if (S_ISREG(dir_entries[i]->a.perm) ) {
1497			if (do_download(conn, new_src, new_dst,
1498			    &(dir_entries[i]->a), preserve_flag,
1499			    resume_flag, fsync_flag) == -1) {
1500				error("Download of file %s to %s failed",
1501				    new_src, new_dst);
1502				ret = -1;
1503			}
1504		} else
1505			logit("%s: not a regular file\n", new_src);
1506
1507		free(new_dst);
1508		free(new_src);
1509	}
1510
1511	if (preserve_flag) {
1512		if (dirattrib->flags & SSH2_FILEXFER_ATTR_ACMODTIME) {
1513			struct timeval tv[2];
1514			tv[0].tv_sec = dirattrib->atime;
1515			tv[1].tv_sec = dirattrib->mtime;
1516			tv[0].tv_usec = tv[1].tv_usec = 0;
1517			if (utimes(dst, tv) == -1)
1518				error("Can't set times on \"%s\": %s",
1519				    dst, strerror(errno));
1520		} else
1521			debug("Server did not send times for directory "
1522			    "\"%s\"", dst);
1523	}
1524
1525	free_sftp_dirents(dir_entries);
1526
1527	return ret;
1528}
1529
1530int
1531download_dir(struct sftp_conn *conn, const char *src, const char *dst,
1532    Attrib *dirattrib, int preserve_flag, int print_flag, int resume_flag,
1533    int fsync_flag)
1534{
1535	char *src_canon;
1536	int ret;
1537
1538	if ((src_canon = do_realpath(conn, src)) == NULL) {
1539		error("Unable to canonicalize path \"%s\"", src);
1540		return -1;
1541	}
1542
1543	ret = download_dir_internal(conn, src_canon, dst, 0,
1544	    dirattrib, preserve_flag, print_flag, resume_flag, fsync_flag);
1545	free(src_canon);
1546	return ret;
1547}
1548
1549int
1550do_upload(struct sftp_conn *conn, const char *local_path,
1551    const char *remote_path, int preserve_flag, int resume, int fsync_flag)
1552{
1553	int r, local_fd;
1554	u_int status = SSH2_FX_OK;
1555	u_int id;
1556	u_char type;
1557	off_t offset, progress_counter;
1558	u_char *handle, *data;
1559	struct sshbuf *msg;
1560	struct stat sb;
1561	Attrib a, *c = NULL;
1562	u_int32_t startid;
1563	u_int32_t ackid;
1564	struct outstanding_ack {
1565		u_int id;
1566		u_int len;
1567		off_t offset;
1568		TAILQ_ENTRY(outstanding_ack) tq;
1569	};
1570	TAILQ_HEAD(ackhead, outstanding_ack) acks;
1571	struct outstanding_ack *ack = NULL;
1572	size_t handle_len;
1573
1574	TAILQ_INIT(&acks);
1575
1576	if ((local_fd = open(local_path, O_RDONLY, 0)) == -1) {
1577		error("Couldn't open local file \"%s\" for reading: %s",
1578		    local_path, strerror(errno));
1579		return(-1);
1580	}
1581	if (fstat(local_fd, &sb) == -1) {
1582		error("Couldn't fstat local file \"%s\": %s",
1583		    local_path, strerror(errno));
1584		close(local_fd);
1585		return(-1);
1586	}
1587	if (!S_ISREG(sb.st_mode)) {
1588		error("%s is not a regular file", local_path);
1589		close(local_fd);
1590		return(-1);
1591	}
1592	stat_to_attrib(&sb, &a);
1593
1594	a.flags &= ~SSH2_FILEXFER_ATTR_SIZE;
1595	a.flags &= ~SSH2_FILEXFER_ATTR_UIDGID;
1596	a.perm &= 0777;
1597	if (!preserve_flag)
1598		a.flags &= ~SSH2_FILEXFER_ATTR_ACMODTIME;
1599
1600	if (resume) {
1601		/* Get remote file size if it exists */
1602		if ((c = do_stat(conn, remote_path, 0)) == NULL) {
1603			close(local_fd);
1604			return -1;
1605		}
1606
1607		if ((off_t)c->size >= sb.st_size) {
1608			error("destination file bigger or same size as "
1609			      "source file");
1610			close(local_fd);
1611			return -1;
1612		}
1613
1614		if (lseek(local_fd, (off_t)c->size, SEEK_SET) == -1) {
1615			close(local_fd);
1616			return -1;
1617		}
1618	}
1619
1620	if ((msg = sshbuf_new()) == NULL)
1621		fatal("%s: sshbuf_new failed", __func__);
1622
1623	/* Send open request */
1624	id = conn->msg_id++;
1625	if ((r = sshbuf_put_u8(msg, SSH2_FXP_OPEN)) != 0 ||
1626	    (r = sshbuf_put_u32(msg, id)) != 0 ||
1627	    (r = sshbuf_put_cstring(msg, remote_path)) != 0 ||
1628	    (r = sshbuf_put_u32(msg, SSH2_FXF_WRITE|SSH2_FXF_CREAT|
1629	    (resume ? SSH2_FXF_APPEND : SSH2_FXF_TRUNC))) != 0 ||
1630	    (r = encode_attrib(msg, &a)) != 0)
1631		fatal("%s: buffer error: %s", __func__, ssh_err(r));
1632	send_msg(conn, msg);
1633	debug3("Sent message SSH2_FXP_OPEN I:%u P:%s", id, remote_path);
1634
1635	sshbuf_reset(msg);
1636
1637	handle = get_handle(conn, id, &handle_len,
1638	    "remote open(\"%s\")", remote_path);
1639	if (handle == NULL) {
1640		close(local_fd);
1641		sshbuf_free(msg);
1642		return -1;
1643	}
1644
1645	startid = ackid = id + 1;
1646	data = xmalloc(conn->transfer_buflen);
1647
1648	/* Read from local and write to remote */
1649	offset = progress_counter = (resume ? c->size : 0);
1650	if (showprogress)
1651		start_progress_meter(local_path, sb.st_size,
1652		    &progress_counter);
1653
1654	for (;;) {
1655		int len;
1656
1657		/*
1658		 * Can't use atomicio here because it returns 0 on EOF,
1659		 * thus losing the last block of the file.
1660		 * Simulate an EOF on interrupt, allowing ACKs from the
1661		 * server to drain.
1662		 */
1663		if (interrupted || status != SSH2_FX_OK)
1664			len = 0;
1665		else do
1666			len = read(local_fd, data, conn->transfer_buflen);
1667		while ((len == -1) &&
1668		    (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK));
1669
1670		if (len == -1)
1671			fatal("Couldn't read from \"%s\": %s", local_path,
1672			    strerror(errno));
1673
1674		if (len != 0) {
1675			ack = xcalloc(1, sizeof(*ack));
1676			ack->id = ++id;
1677			ack->offset = offset;
1678			ack->len = len;
1679			TAILQ_INSERT_TAIL(&acks, ack, tq);
1680
1681			sshbuf_reset(msg);
1682			if ((r = sshbuf_put_u8(msg, SSH2_FXP_WRITE)) != 0 ||
1683			    (r = sshbuf_put_u32(msg, ack->id)) != 0 ||
1684			    (r = sshbuf_put_string(msg, handle,
1685			    handle_len)) != 0 ||
1686			    (r = sshbuf_put_u64(msg, offset)) != 0 ||
1687			    (r = sshbuf_put_string(msg, data, len)) != 0)
1688				fatal("%s: buffer error: %s",
1689				    __func__, ssh_err(r));
1690			send_msg(conn, msg);
1691			debug3("Sent message SSH2_FXP_WRITE I:%u O:%llu S:%u",
1692			    id, (unsigned long long)offset, len);
1693		} else if (TAILQ_FIRST(&acks) == NULL)
1694			break;
1695
1696		if (ack == NULL)
1697			fatal("Unexpected ACK %u", id);
1698
1699		if (id == startid || len == 0 ||
1700		    id - ackid >= conn->num_requests) {
1701			u_int rid;
1702
1703			sshbuf_reset(msg);
1704			get_msg(conn, msg);
1705			if ((r = sshbuf_get_u8(msg, &type)) != 0 ||
1706			    (r = sshbuf_get_u32(msg, &rid)) != 0)
1707				fatal("%s: buffer error: %s",
1708				    __func__, ssh_err(r));
1709
1710			if (type != SSH2_FXP_STATUS)
1711				fatal("Expected SSH2_FXP_STATUS(%d) packet, "
1712				    "got %d", SSH2_FXP_STATUS, type);
1713
1714			if ((r = sshbuf_get_u32(msg, &status)) != 0)
1715				fatal("%s: buffer error: %s",
1716				    __func__, ssh_err(r));
1717			debug3("SSH2_FXP_STATUS %u", status);
1718
1719			/* Find the request in our queue */
1720			for (ack = TAILQ_FIRST(&acks);
1721			    ack != NULL && ack->id != rid;
1722			    ack = TAILQ_NEXT(ack, tq))
1723				;
1724			if (ack == NULL)
1725				fatal("Can't find request for ID %u", rid);
1726			TAILQ_REMOVE(&acks, ack, tq);
1727			debug3("In write loop, ack for %u %u bytes at %lld",
1728			    ack->id, ack->len, (long long)ack->offset);
1729			++ackid;
1730			progress_counter += ack->len;
1731			free(ack);
1732		}
1733		offset += len;
1734		if (offset < 0)
1735			fatal("%s: offset < 0", __func__);
1736	}
1737	sshbuf_free(msg);
1738
1739	if (showprogress)
1740		stop_progress_meter();
1741	free(data);
1742
1743	if (status != SSH2_FX_OK) {
1744		error("Couldn't write to remote file \"%s\": %s",
1745		    remote_path, fx2txt(status));
1746		status = SSH2_FX_FAILURE;
1747	}
1748
1749	if (close(local_fd) == -1) {
1750		error("Couldn't close local file \"%s\": %s", local_path,
1751		    strerror(errno));
1752		status = SSH2_FX_FAILURE;
1753	}
1754
1755	/* Override umask and utimes if asked */
1756	if (preserve_flag)
1757		do_fsetstat(conn, handle, handle_len, &a);
1758
1759	if (fsync_flag)
1760		(void)do_fsync(conn, handle, handle_len);
1761
1762	if (do_close(conn, handle, handle_len) != 0)
1763		status = SSH2_FX_FAILURE;
1764
1765	free(handle);
1766
1767	return status == SSH2_FX_OK ? 0 : -1;
1768}
1769
1770static int
1771upload_dir_internal(struct sftp_conn *conn, const char *src, const char *dst,
1772    int depth, int preserve_flag, int print_flag, int resume, int fsync_flag)
1773{
1774	int ret = 0;
1775	DIR *dirp;
1776	struct dirent *dp;
1777	char *filename, *new_src, *new_dst;
1778	struct stat sb;
1779	Attrib a, *dirattrib;
1780
1781	if (depth >= MAX_DIR_DEPTH) {
1782		error("Maximum directory depth exceeded: %d levels", depth);
1783		return -1;
1784	}
1785
1786	if (stat(src, &sb) == -1) {
1787		error("Couldn't stat directory \"%s\": %s",
1788		    src, strerror(errno));
1789		return -1;
1790	}
1791	if (!S_ISDIR(sb.st_mode)) {
1792		error("\"%s\" is not a directory", src);
1793		return -1;
1794	}
1795	if (print_flag)
1796		mprintf("Entering %s\n", src);
1797
1798	attrib_clear(&a);
1799	stat_to_attrib(&sb, &a);
1800	a.flags &= ~SSH2_FILEXFER_ATTR_SIZE;
1801	a.flags &= ~SSH2_FILEXFER_ATTR_UIDGID;
1802	a.perm &= 01777;
1803	if (!preserve_flag)
1804		a.flags &= ~SSH2_FILEXFER_ATTR_ACMODTIME;
1805
1806	/*
1807	 * sftp lacks a portable status value to match errno EEXIST,
1808	 * so if we get a failure back then we must check whether
1809	 * the path already existed and is a directory.
1810	 */
1811	if (do_mkdir(conn, dst, &a, 0) != 0) {
1812		if ((dirattrib = do_stat(conn, dst, 0)) == NULL)
1813			return -1;
1814		if (!S_ISDIR(dirattrib->perm)) {
1815			error("\"%s\" exists but is not a directory", dst);
1816			return -1;
1817		}
1818	}
1819
1820	if ((dirp = opendir(src)) == NULL) {
1821		error("Failed to open dir \"%s\": %s", src, strerror(errno));
1822		return -1;
1823	}
1824
1825	while (((dp = readdir(dirp)) != NULL) && !interrupted) {
1826		if (dp->d_ino == 0)
1827			continue;
1828		filename = dp->d_name;
1829		new_dst = path_append(dst, filename);
1830		new_src = path_append(src, filename);
1831
1832		if (lstat(new_src, &sb) == -1) {
1833			logit("%s: lstat failed: %s", filename,
1834			    strerror(errno));
1835			ret = -1;
1836		} else if (S_ISDIR(sb.st_mode)) {
1837			if (strcmp(filename, ".") == 0 ||
1838			    strcmp(filename, "..") == 0)
1839				continue;
1840
1841			if (upload_dir_internal(conn, new_src, new_dst,
1842			    depth + 1, preserve_flag, print_flag, resume,
1843			    fsync_flag) == -1)
1844				ret = -1;
1845		} else if (S_ISREG(sb.st_mode)) {
1846			if (do_upload(conn, new_src, new_dst,
1847			    preserve_flag, resume, fsync_flag) == -1) {
1848				error("Uploading of file %s to %s failed!",
1849				    new_src, new_dst);
1850				ret = -1;
1851			}
1852		} else
1853			logit("%s: not a regular file\n", filename);
1854		free(new_dst);
1855		free(new_src);
1856	}
1857
1858	do_setstat(conn, dst, &a);
1859
1860	(void) closedir(dirp);
1861	return ret;
1862}
1863
1864int
1865upload_dir(struct sftp_conn *conn, const char *src, const char *dst,
1866    int preserve_flag, int print_flag, int resume, int fsync_flag)
1867{
1868	char *dst_canon;
1869	int ret;
1870
1871	if ((dst_canon = do_realpath(conn, dst)) == NULL) {
1872		error("Unable to canonicalize path \"%s\"", dst);
1873		return -1;
1874	}
1875
1876	ret = upload_dir_internal(conn, src, dst_canon, 0, preserve_flag,
1877	    print_flag, resume, fsync_flag);
1878
1879	free(dst_canon);
1880	return ret;
1881}
1882
1883char *
1884path_append(const char *p1, const char *p2)
1885{
1886	char *ret;
1887	size_t len = strlen(p1) + strlen(p2) + 2;
1888
1889	ret = xmalloc(len);
1890	strlcpy(ret, p1, len);
1891	if (p1[0] != '\0' && p1[strlen(p1) - 1] != '/')
1892		strlcat(ret, "/", len);
1893	strlcat(ret, p2, len);
1894
1895	return(ret);
1896}
1897
1898