sftp-client.c 52 KB

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