sftp-server.c 46 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838
  1. /* $OpenBSD: sftp-server.c,v 1.119 2020/07/17 03:51:32 djm Exp $ */
  2. /*
  3. * Copyright (c) 2000-2004 Markus Friedl. All rights reserved.
  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. #include "includes.h"
  18. #include <sys/types.h>
  19. #include <sys/stat.h>
  20. #include <sys/resource.h>
  21. #ifdef HAVE_SYS_TIME_H
  22. # include <sys/time.h>
  23. #endif
  24. #ifdef HAVE_SYS_MOUNT_H
  25. #include <sys/mount.h>
  26. #endif
  27. #ifdef HAVE_SYS_STATVFS_H
  28. #include <sys/statvfs.h>
  29. #endif
  30. #include <dirent.h>
  31. #include <errno.h>
  32. #include <fcntl.h>
  33. #include <pwd.h>
  34. #include <stdlib.h>
  35. #include <stdio.h>
  36. #include <string.h>
  37. #include <time.h>
  38. #include <unistd.h>
  39. #include <stdarg.h>
  40. #include "xmalloc.h"
  41. #include "sshbuf.h"
  42. #include "ssherr.h"
  43. #include "log.h"
  44. #include "misc.h"
  45. #include "match.h"
  46. #include "uidswap.h"
  47. #include "sftp.h"
  48. #include "sftp-common.h"
  49. char *sftp_realpath(const char *, char *); /* sftp-realpath.c */
  50. /* Maximum data read that we are willing to accept */
  51. #define SFTP_MAX_READ_LENGTH (64 * 1024)
  52. /* Our verbosity */
  53. static LogLevel log_level = SYSLOG_LEVEL_ERROR;
  54. /* Our client */
  55. static struct passwd *pw = NULL;
  56. static char *client_addr = NULL;
  57. /* input and output queue */
  58. struct sshbuf *iqueue;
  59. struct sshbuf *oqueue;
  60. /* Version of client */
  61. static u_int version;
  62. /* Force file permissions */
  63. int permforce = 0;
  64. long permforcemode;
  65. /* SSH2_FXP_INIT received */
  66. static int init_done;
  67. /* Disable writes */
  68. static int readonly;
  69. /* Requests that are allowed/denied */
  70. static char *request_allowlist, *request_denylist;
  71. /* portable attributes, etc. */
  72. typedef struct Stat Stat;
  73. struct Stat {
  74. char *name;
  75. char *long_name;
  76. Attrib attrib;
  77. };
  78. /* Packet handlers */
  79. static void process_open(u_int32_t id);
  80. static void process_close(u_int32_t id);
  81. static void process_read(u_int32_t id);
  82. static void process_write(u_int32_t id);
  83. static void process_stat(u_int32_t id);
  84. static void process_lstat(u_int32_t id);
  85. static void process_fstat(u_int32_t id);
  86. static void process_setstat(u_int32_t id);
  87. static void process_fsetstat(u_int32_t id);
  88. static void process_opendir(u_int32_t id);
  89. static void process_readdir(u_int32_t id);
  90. static void process_remove(u_int32_t id);
  91. static void process_mkdir(u_int32_t id);
  92. static void process_rmdir(u_int32_t id);
  93. static void process_realpath(u_int32_t id);
  94. static void process_rename(u_int32_t id);
  95. static void process_readlink(u_int32_t id);
  96. static void process_symlink(u_int32_t id);
  97. static void process_extended_posix_rename(u_int32_t id);
  98. static void process_extended_statvfs(u_int32_t id);
  99. static void process_extended_fstatvfs(u_int32_t id);
  100. static void process_extended_hardlink(u_int32_t id);
  101. static void process_extended_fsync(u_int32_t id);
  102. static void process_extended_lsetstat(u_int32_t id);
  103. static void process_extended_limits(u_int32_t id);
  104. static void process_extended(u_int32_t id);
  105. struct sftp_handler {
  106. const char *name; /* user-visible name for fine-grained perms */
  107. const char *ext_name; /* extended request name */
  108. u_int type; /* packet type, for non extended packets */
  109. void (*handler)(u_int32_t);
  110. int does_write; /* if nonzero, banned for readonly mode */
  111. };
  112. static const struct sftp_handler handlers[] = {
  113. /* NB. SSH2_FXP_OPEN does the readonly check in the handler itself */
  114. { "open", NULL, SSH2_FXP_OPEN, process_open, 0 },
  115. { "close", NULL, SSH2_FXP_CLOSE, process_close, 0 },
  116. { "read", NULL, SSH2_FXP_READ, process_read, 0 },
  117. { "write", NULL, SSH2_FXP_WRITE, process_write, 1 },
  118. { "lstat", NULL, SSH2_FXP_LSTAT, process_lstat, 0 },
  119. { "fstat", NULL, SSH2_FXP_FSTAT, process_fstat, 0 },
  120. { "setstat", NULL, SSH2_FXP_SETSTAT, process_setstat, 1 },
  121. { "fsetstat", NULL, SSH2_FXP_FSETSTAT, process_fsetstat, 1 },
  122. { "opendir", NULL, SSH2_FXP_OPENDIR, process_opendir, 0 },
  123. { "readdir", NULL, SSH2_FXP_READDIR, process_readdir, 0 },
  124. { "remove", NULL, SSH2_FXP_REMOVE, process_remove, 1 },
  125. { "mkdir", NULL, SSH2_FXP_MKDIR, process_mkdir, 1 },
  126. { "rmdir", NULL, SSH2_FXP_RMDIR, process_rmdir, 1 },
  127. { "realpath", NULL, SSH2_FXP_REALPATH, process_realpath, 0 },
  128. { "stat", NULL, SSH2_FXP_STAT, process_stat, 0 },
  129. { "rename", NULL, SSH2_FXP_RENAME, process_rename, 1 },
  130. { "readlink", NULL, SSH2_FXP_READLINK, process_readlink, 0 },
  131. { "symlink", NULL, SSH2_FXP_SYMLINK, process_symlink, 1 },
  132. { NULL, NULL, 0, NULL, 0 }
  133. };
  134. /* SSH2_FXP_EXTENDED submessages */
  135. static const struct sftp_handler extended_handlers[] = {
  136. { "posix-rename", "posix-rename@openssh.com", 0,
  137. process_extended_posix_rename, 1 },
  138. { "statvfs", "statvfs@openssh.com", 0, process_extended_statvfs, 0 },
  139. { "fstatvfs", "fstatvfs@openssh.com", 0, process_extended_fstatvfs, 0 },
  140. { "hardlink", "hardlink@openssh.com", 0, process_extended_hardlink, 1 },
  141. { "fsync", "fsync@openssh.com", 0, process_extended_fsync, 1 },
  142. { "lsetstat", "lsetstat@openssh.com", 0, process_extended_lsetstat, 1 },
  143. { "limits", "limits@openssh.com", 0, process_extended_limits, 1 },
  144. { NULL, NULL, 0, NULL, 0 }
  145. };
  146. static int
  147. request_permitted(const struct sftp_handler *h)
  148. {
  149. char *result;
  150. if (readonly && h->does_write) {
  151. verbose("Refusing %s request in read-only mode", h->name);
  152. return 0;
  153. }
  154. if (request_denylist != NULL &&
  155. ((result = match_list(h->name, request_denylist, NULL))) != NULL) {
  156. free(result);
  157. verbose("Refusing denylisted %s request", h->name);
  158. return 0;
  159. }
  160. if (request_allowlist != NULL &&
  161. ((result = match_list(h->name, request_allowlist, NULL))) != NULL) {
  162. free(result);
  163. debug2("Permitting allowlisted %s request", h->name);
  164. return 1;
  165. }
  166. if (request_allowlist != NULL) {
  167. verbose("Refusing non-allowlisted %s request", h->name);
  168. return 0;
  169. }
  170. return 1;
  171. }
  172. static int
  173. errno_to_portable(int unixerrno)
  174. {
  175. int ret = 0;
  176. switch (unixerrno) {
  177. case 0:
  178. ret = SSH2_FX_OK;
  179. break;
  180. case ENOENT:
  181. case ENOTDIR:
  182. case EBADF:
  183. case ELOOP:
  184. ret = SSH2_FX_NO_SUCH_FILE;
  185. break;
  186. case EPERM:
  187. case EACCES:
  188. case EFAULT:
  189. ret = SSH2_FX_PERMISSION_DENIED;
  190. break;
  191. case ENAMETOOLONG:
  192. case EINVAL:
  193. ret = SSH2_FX_BAD_MESSAGE;
  194. break;
  195. case ENOSYS:
  196. ret = SSH2_FX_OP_UNSUPPORTED;
  197. break;
  198. default:
  199. ret = SSH2_FX_FAILURE;
  200. break;
  201. }
  202. return ret;
  203. }
  204. static int
  205. flags_from_portable(int pflags)
  206. {
  207. int flags = 0;
  208. if ((pflags & SSH2_FXF_READ) &&
  209. (pflags & SSH2_FXF_WRITE)) {
  210. flags = O_RDWR;
  211. } else if (pflags & SSH2_FXF_READ) {
  212. flags = O_RDONLY;
  213. } else if (pflags & SSH2_FXF_WRITE) {
  214. flags = O_WRONLY;
  215. }
  216. if (pflags & SSH2_FXF_APPEND)
  217. flags |= O_APPEND;
  218. if (pflags & SSH2_FXF_CREAT)
  219. flags |= O_CREAT;
  220. if (pflags & SSH2_FXF_TRUNC)
  221. flags |= O_TRUNC;
  222. if (pflags & SSH2_FXF_EXCL)
  223. flags |= O_EXCL;
  224. return flags;
  225. }
  226. static const char *
  227. string_from_portable(int pflags)
  228. {
  229. static char ret[128];
  230. *ret = '\0';
  231. #define PAPPEND(str) { \
  232. if (*ret != '\0') \
  233. strlcat(ret, ",", sizeof(ret)); \
  234. strlcat(ret, str, sizeof(ret)); \
  235. }
  236. if (pflags & SSH2_FXF_READ)
  237. PAPPEND("READ")
  238. if (pflags & SSH2_FXF_WRITE)
  239. PAPPEND("WRITE")
  240. if (pflags & SSH2_FXF_APPEND)
  241. PAPPEND("APPEND")
  242. if (pflags & SSH2_FXF_CREAT)
  243. PAPPEND("CREATE")
  244. if (pflags & SSH2_FXF_TRUNC)
  245. PAPPEND("TRUNCATE")
  246. if (pflags & SSH2_FXF_EXCL)
  247. PAPPEND("EXCL")
  248. return ret;
  249. }
  250. /* handle handles */
  251. typedef struct Handle Handle;
  252. struct Handle {
  253. int use;
  254. DIR *dirp;
  255. int fd;
  256. int flags;
  257. char *name;
  258. u_int64_t bytes_read, bytes_write;
  259. int next_unused;
  260. };
  261. enum {
  262. HANDLE_UNUSED,
  263. HANDLE_DIR,
  264. HANDLE_FILE
  265. };
  266. static Handle *handles = NULL;
  267. static u_int num_handles = 0;
  268. static int first_unused_handle = -1;
  269. static void handle_unused(int i)
  270. {
  271. handles[i].use = HANDLE_UNUSED;
  272. handles[i].next_unused = first_unused_handle;
  273. first_unused_handle = i;
  274. }
  275. static int
  276. handle_new(int use, const char *name, int fd, int flags, DIR *dirp)
  277. {
  278. int i;
  279. if (first_unused_handle == -1) {
  280. if (num_handles + 1 <= num_handles)
  281. return -1;
  282. num_handles++;
  283. handles = xreallocarray(handles, num_handles, sizeof(Handle));
  284. handle_unused(num_handles - 1);
  285. }
  286. i = first_unused_handle;
  287. first_unused_handle = handles[i].next_unused;
  288. handles[i].use = use;
  289. handles[i].dirp = dirp;
  290. handles[i].fd = fd;
  291. handles[i].flags = flags;
  292. handles[i].name = xstrdup(name);
  293. handles[i].bytes_read = handles[i].bytes_write = 0;
  294. return i;
  295. }
  296. static int
  297. handle_is_ok(int i, int type)
  298. {
  299. return i >= 0 && (u_int)i < num_handles && handles[i].use == type;
  300. }
  301. static int
  302. handle_to_string(int handle, u_char **stringp, int *hlenp)
  303. {
  304. if (stringp == NULL || hlenp == NULL)
  305. return -1;
  306. *stringp = xmalloc(sizeof(int32_t));
  307. put_u32(*stringp, handle);
  308. *hlenp = sizeof(int32_t);
  309. return 0;
  310. }
  311. static int
  312. handle_from_string(const u_char *handle, u_int hlen)
  313. {
  314. int val;
  315. if (hlen != sizeof(int32_t))
  316. return -1;
  317. val = get_u32(handle);
  318. if (handle_is_ok(val, HANDLE_FILE) ||
  319. handle_is_ok(val, HANDLE_DIR))
  320. return val;
  321. return -1;
  322. }
  323. static char *
  324. handle_to_name(int handle)
  325. {
  326. if (handle_is_ok(handle, HANDLE_DIR)||
  327. handle_is_ok(handle, HANDLE_FILE))
  328. return handles[handle].name;
  329. return NULL;
  330. }
  331. static DIR *
  332. handle_to_dir(int handle)
  333. {
  334. if (handle_is_ok(handle, HANDLE_DIR))
  335. return handles[handle].dirp;
  336. return NULL;
  337. }
  338. static int
  339. handle_to_fd(int handle)
  340. {
  341. if (handle_is_ok(handle, HANDLE_FILE))
  342. return handles[handle].fd;
  343. return -1;
  344. }
  345. static int
  346. handle_to_flags(int handle)
  347. {
  348. if (handle_is_ok(handle, HANDLE_FILE))
  349. return handles[handle].flags;
  350. return 0;
  351. }
  352. static void
  353. handle_update_read(int handle, ssize_t bytes)
  354. {
  355. if (handle_is_ok(handle, HANDLE_FILE) && bytes > 0)
  356. handles[handle].bytes_read += bytes;
  357. }
  358. static void
  359. handle_update_write(int handle, ssize_t bytes)
  360. {
  361. if (handle_is_ok(handle, HANDLE_FILE) && bytes > 0)
  362. handles[handle].bytes_write += bytes;
  363. }
  364. static u_int64_t
  365. handle_bytes_read(int handle)
  366. {
  367. if (handle_is_ok(handle, HANDLE_FILE))
  368. return (handles[handle].bytes_read);
  369. return 0;
  370. }
  371. static u_int64_t
  372. handle_bytes_write(int handle)
  373. {
  374. if (handle_is_ok(handle, HANDLE_FILE))
  375. return (handles[handle].bytes_write);
  376. return 0;
  377. }
  378. static int
  379. handle_close(int handle)
  380. {
  381. int ret = -1;
  382. if (handle_is_ok(handle, HANDLE_FILE)) {
  383. ret = close(handles[handle].fd);
  384. free(handles[handle].name);
  385. handle_unused(handle);
  386. } else if (handle_is_ok(handle, HANDLE_DIR)) {
  387. ret = closedir(handles[handle].dirp);
  388. free(handles[handle].name);
  389. handle_unused(handle);
  390. } else {
  391. errno = ENOENT;
  392. }
  393. return ret;
  394. }
  395. static void
  396. handle_log_close(int handle, char *emsg)
  397. {
  398. if (handle_is_ok(handle, HANDLE_FILE)) {
  399. logit("%s%sclose \"%s\" bytes read %llu written %llu",
  400. emsg == NULL ? "" : emsg, emsg == NULL ? "" : " ",
  401. handle_to_name(handle),
  402. (unsigned long long)handle_bytes_read(handle),
  403. (unsigned long long)handle_bytes_write(handle));
  404. } else {
  405. logit("%s%sclosedir \"%s\"",
  406. emsg == NULL ? "" : emsg, emsg == NULL ? "" : " ",
  407. handle_to_name(handle));
  408. }
  409. }
  410. static void
  411. handle_log_exit(void)
  412. {
  413. u_int i;
  414. for (i = 0; i < num_handles; i++)
  415. if (handles[i].use != HANDLE_UNUSED)
  416. handle_log_close(i, "forced");
  417. }
  418. static int
  419. get_handle(struct sshbuf *queue, int *hp)
  420. {
  421. u_char *handle;
  422. int r;
  423. size_t hlen;
  424. *hp = -1;
  425. if ((r = sshbuf_get_string(queue, &handle, &hlen)) != 0)
  426. return r;
  427. if (hlen < 256)
  428. *hp = handle_from_string(handle, hlen);
  429. free(handle);
  430. return 0;
  431. }
  432. /* send replies */
  433. static void
  434. send_msg(struct sshbuf *m)
  435. {
  436. int r;
  437. if ((r = sshbuf_put_stringb(oqueue, m)) != 0)
  438. fatal("%s: buffer error: %s", __func__, ssh_err(r));
  439. sshbuf_reset(m);
  440. }
  441. static const char *
  442. status_to_message(u_int32_t status)
  443. {
  444. const char *status_messages[] = {
  445. "Success", /* SSH_FX_OK */
  446. "End of file", /* SSH_FX_EOF */
  447. "No such file", /* SSH_FX_NO_SUCH_FILE */
  448. "Permission denied", /* SSH_FX_PERMISSION_DENIED */
  449. "Failure", /* SSH_FX_FAILURE */
  450. "Bad message", /* SSH_FX_BAD_MESSAGE */
  451. "No connection", /* SSH_FX_NO_CONNECTION */
  452. "Connection lost", /* SSH_FX_CONNECTION_LOST */
  453. "Operation unsupported", /* SSH_FX_OP_UNSUPPORTED */
  454. "Unknown error" /* Others */
  455. };
  456. return (status_messages[MINIMUM(status,SSH2_FX_MAX)]);
  457. }
  458. static void
  459. send_status(u_int32_t id, u_int32_t status)
  460. {
  461. struct sshbuf *msg;
  462. int r;
  463. debug3("request %u: sent status %u", id, status);
  464. if (log_level > SYSLOG_LEVEL_VERBOSE ||
  465. (status != SSH2_FX_OK && status != SSH2_FX_EOF))
  466. logit("sent status %s", status_to_message(status));
  467. if ((msg = sshbuf_new()) == NULL)
  468. fatal("%s: sshbuf_new failed", __func__);
  469. if ((r = sshbuf_put_u8(msg, SSH2_FXP_STATUS)) != 0 ||
  470. (r = sshbuf_put_u32(msg, id)) != 0 ||
  471. (r = sshbuf_put_u32(msg, status)) != 0)
  472. fatal("%s: buffer error: %s", __func__, ssh_err(r));
  473. if (version >= 3) {
  474. if ((r = sshbuf_put_cstring(msg,
  475. status_to_message(status))) != 0 ||
  476. (r = sshbuf_put_cstring(msg, "")) != 0)
  477. fatal("%s: buffer error: %s", __func__, ssh_err(r));
  478. }
  479. send_msg(msg);
  480. sshbuf_free(msg);
  481. }
  482. static void
  483. send_data_or_handle(char type, u_int32_t id, const u_char *data, int dlen)
  484. {
  485. struct sshbuf *msg;
  486. int r;
  487. if ((msg = sshbuf_new()) == NULL)
  488. fatal("%s: sshbuf_new failed", __func__);
  489. if ((r = sshbuf_put_u8(msg, type)) != 0 ||
  490. (r = sshbuf_put_u32(msg, id)) != 0 ||
  491. (r = sshbuf_put_string(msg, data, dlen)) != 0)
  492. fatal("%s: buffer error: %s", __func__, ssh_err(r));
  493. send_msg(msg);
  494. sshbuf_free(msg);
  495. }
  496. static void
  497. send_data(u_int32_t id, const u_char *data, int dlen)
  498. {
  499. debug("request %u: sent data len %d", id, dlen);
  500. send_data_or_handle(SSH2_FXP_DATA, id, data, dlen);
  501. }
  502. static void
  503. send_handle(u_int32_t id, int handle)
  504. {
  505. u_char *string;
  506. int hlen;
  507. handle_to_string(handle, &string, &hlen);
  508. debug("request %u: sent handle handle %d", id, handle);
  509. send_data_or_handle(SSH2_FXP_HANDLE, id, string, hlen);
  510. free(string);
  511. }
  512. static void
  513. send_names(u_int32_t id, int count, const Stat *stats)
  514. {
  515. struct sshbuf *msg;
  516. int i, r;
  517. if ((msg = sshbuf_new()) == NULL)
  518. fatal("%s: sshbuf_new failed", __func__);
  519. if ((r = sshbuf_put_u8(msg, SSH2_FXP_NAME)) != 0 ||
  520. (r = sshbuf_put_u32(msg, id)) != 0 ||
  521. (r = sshbuf_put_u32(msg, count)) != 0)
  522. fatal("%s: buffer error: %s", __func__, ssh_err(r));
  523. debug("request %u: sent names count %d", id, count);
  524. for (i = 0; i < count; i++) {
  525. if ((r = sshbuf_put_cstring(msg, stats[i].name)) != 0 ||
  526. (r = sshbuf_put_cstring(msg, stats[i].long_name)) != 0 ||
  527. (r = encode_attrib(msg, &stats[i].attrib)) != 0)
  528. fatal("%s: buffer error: %s", __func__, ssh_err(r));
  529. }
  530. send_msg(msg);
  531. sshbuf_free(msg);
  532. }
  533. static void
  534. send_attrib(u_int32_t id, const Attrib *a)
  535. {
  536. struct sshbuf *msg;
  537. int r;
  538. debug("request %u: sent attrib have 0x%x", id, a->flags);
  539. if ((msg = sshbuf_new()) == NULL)
  540. fatal("%s: sshbuf_new failed", __func__);
  541. if ((r = sshbuf_put_u8(msg, SSH2_FXP_ATTRS)) != 0 ||
  542. (r = sshbuf_put_u32(msg, id)) != 0 ||
  543. (r = encode_attrib(msg, a)) != 0)
  544. fatal("%s: buffer error: %s", __func__, ssh_err(r));
  545. send_msg(msg);
  546. sshbuf_free(msg);
  547. }
  548. static void
  549. send_statvfs(u_int32_t id, struct statvfs *st)
  550. {
  551. struct sshbuf *msg;
  552. u_int64_t flag;
  553. int r;
  554. flag = (st->f_flag & ST_RDONLY) ? SSH2_FXE_STATVFS_ST_RDONLY : 0;
  555. flag |= (st->f_flag & ST_NOSUID) ? SSH2_FXE_STATVFS_ST_NOSUID : 0;
  556. if ((msg = sshbuf_new()) == NULL)
  557. fatal("%s: sshbuf_new failed", __func__);
  558. if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED_REPLY)) != 0 ||
  559. (r = sshbuf_put_u32(msg, id)) != 0 ||
  560. (r = sshbuf_put_u64(msg, st->f_bsize)) != 0 ||
  561. (r = sshbuf_put_u64(msg, st->f_frsize)) != 0 ||
  562. (r = sshbuf_put_u64(msg, st->f_blocks)) != 0 ||
  563. (r = sshbuf_put_u64(msg, st->f_bfree)) != 0 ||
  564. (r = sshbuf_put_u64(msg, st->f_bavail)) != 0 ||
  565. (r = sshbuf_put_u64(msg, st->f_files)) != 0 ||
  566. (r = sshbuf_put_u64(msg, st->f_ffree)) != 0 ||
  567. (r = sshbuf_put_u64(msg, st->f_favail)) != 0 ||
  568. (r = sshbuf_put_u64(msg, FSID_TO_ULONG(st->f_fsid))) != 0 ||
  569. (r = sshbuf_put_u64(msg, flag)) != 0 ||
  570. (r = sshbuf_put_u64(msg, st->f_namemax)) != 0)
  571. fatal("%s: buffer error: %s", __func__, ssh_err(r));
  572. send_msg(msg);
  573. sshbuf_free(msg);
  574. }
  575. /* parse incoming */
  576. static void
  577. process_init(void)
  578. {
  579. struct sshbuf *msg;
  580. int r;
  581. if ((r = sshbuf_get_u32(iqueue, &version)) != 0)
  582. fatal("%s: buffer error: %s", __func__, ssh_err(r));
  583. verbose("received client version %u", version);
  584. if ((msg = sshbuf_new()) == NULL)
  585. fatal("%s: sshbuf_new failed", __func__);
  586. if ((r = sshbuf_put_u8(msg, SSH2_FXP_VERSION)) != 0 ||
  587. (r = sshbuf_put_u32(msg, SSH2_FILEXFER_VERSION)) != 0 ||
  588. /* POSIX rename extension */
  589. (r = sshbuf_put_cstring(msg, "posix-rename@openssh.com")) != 0 ||
  590. (r = sshbuf_put_cstring(msg, "1")) != 0 || /* version */
  591. /* statvfs extension */
  592. (r = sshbuf_put_cstring(msg, "statvfs@openssh.com")) != 0 ||
  593. (r = sshbuf_put_cstring(msg, "2")) != 0 || /* version */
  594. /* fstatvfs extension */
  595. (r = sshbuf_put_cstring(msg, "fstatvfs@openssh.com")) != 0 ||
  596. (r = sshbuf_put_cstring(msg, "2")) != 0 || /* version */
  597. /* hardlink extension */
  598. (r = sshbuf_put_cstring(msg, "hardlink@openssh.com")) != 0 ||
  599. (r = sshbuf_put_cstring(msg, "1")) != 0 || /* version */
  600. /* fsync extension */
  601. (r = sshbuf_put_cstring(msg, "fsync@openssh.com")) != 0 ||
  602. (r = sshbuf_put_cstring(msg, "1")) != 0 || /* version */
  603. /* lsetstat extension */
  604. (r = sshbuf_put_cstring(msg, "lsetstat@openssh.com")) != 0 ||
  605. (r = sshbuf_put_cstring(msg, "1")) != 0 || /* version */
  606. /* limits extension */
  607. (r = sshbuf_put_cstring(msg, "limits@openssh.com")) != 0 ||
  608. (r = sshbuf_put_cstring(msg, "1")) != 0) /* version */
  609. fatal("%s: buffer error: %s", __func__, ssh_err(r));
  610. send_msg(msg);
  611. sshbuf_free(msg);
  612. }
  613. static void
  614. process_open(u_int32_t id)
  615. {
  616. u_int32_t pflags;
  617. Attrib a;
  618. char *name;
  619. int r, handle, fd, flags, mode, status = SSH2_FX_FAILURE;
  620. mode_t old_umask = 0;
  621. if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0 ||
  622. (r = sshbuf_get_u32(iqueue, &pflags)) != 0 || /* portable flags */
  623. (r = decode_attrib(iqueue, &a)) != 0)
  624. fatal("%s: buffer error: %s", __func__, ssh_err(r));
  625. debug3("request %u: open flags %d", id, pflags);
  626. flags = flags_from_portable(pflags);
  627. mode = (a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ? a.perm : 0666;
  628. if (permforce == 1) { /* Force perm if -m is set */
  629. mode = permforcemode;
  630. old_umask = umask(0); /* so umask does not interfere */
  631. }
  632. logit("open \"%s\" flags %s mode 0%o",
  633. name, string_from_portable(pflags), mode);
  634. if (readonly &&
  635. ((flags & O_ACCMODE) != O_RDONLY ||
  636. (flags & (O_CREAT|O_TRUNC)) != 0)) {
  637. verbose("Refusing open request in read-only mode");
  638. status = SSH2_FX_PERMISSION_DENIED;
  639. } else {
  640. fd = open(name, flags, mode);
  641. if (fd == -1) {
  642. status = errno_to_portable(errno);
  643. } else {
  644. handle = handle_new(HANDLE_FILE, name, fd, flags, NULL);
  645. if (handle < 0) {
  646. close(fd);
  647. } else {
  648. send_handle(id, handle);
  649. status = SSH2_FX_OK;
  650. }
  651. }
  652. }
  653. if (permforce == 1)
  654. (void) umask(old_umask); /* restore umask to something sane */
  655. if (status != SSH2_FX_OK)
  656. send_status(id, status);
  657. free(name);
  658. }
  659. static void
  660. process_close(u_int32_t id)
  661. {
  662. int r, handle, ret, status = SSH2_FX_FAILURE;
  663. if ((r = get_handle(iqueue, &handle)) != 0)
  664. fatal("%s: buffer error: %s", __func__, ssh_err(r));
  665. debug3("request %u: close handle %u", id, handle);
  666. handle_log_close(handle, NULL);
  667. ret = handle_close(handle);
  668. status = (ret == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
  669. send_status(id, status);
  670. }
  671. static void
  672. process_read(u_int32_t id)
  673. {
  674. u_char buf[SFTP_MAX_READ_LENGTH];
  675. u_int32_t len;
  676. int r, handle, fd, ret, status = SSH2_FX_FAILURE;
  677. u_int64_t off;
  678. if ((r = get_handle(iqueue, &handle)) != 0 ||
  679. (r = sshbuf_get_u64(iqueue, &off)) != 0 ||
  680. (r = sshbuf_get_u32(iqueue, &len)) != 0)
  681. fatal("%s: buffer error: %s", __func__, ssh_err(r));
  682. debug("request %u: read \"%s\" (handle %d) off %llu len %d",
  683. id, handle_to_name(handle), handle, (unsigned long long)off, len);
  684. if (len > sizeof buf) {
  685. len = sizeof buf;
  686. debug2("read change len %d", len);
  687. }
  688. fd = handle_to_fd(handle);
  689. if (fd >= 0) {
  690. if (lseek(fd, off, SEEK_SET) == -1) {
  691. error("process_read: seek failed");
  692. status = errno_to_portable(errno);
  693. } else {
  694. ret = read(fd, buf, len);
  695. if (ret == -1) {
  696. status = errno_to_portable(errno);
  697. } else if (ret == 0) {
  698. status = SSH2_FX_EOF;
  699. } else {
  700. send_data(id, buf, ret);
  701. status = SSH2_FX_OK;
  702. handle_update_read(handle, ret);
  703. }
  704. }
  705. }
  706. if (status != SSH2_FX_OK)
  707. send_status(id, status);
  708. }
  709. static void
  710. process_write(u_int32_t id)
  711. {
  712. u_int64_t off;
  713. size_t len;
  714. int r, handle, fd, ret, status;
  715. u_char *data;
  716. if ((r = get_handle(iqueue, &handle)) != 0 ||
  717. (r = sshbuf_get_u64(iqueue, &off)) != 0 ||
  718. (r = sshbuf_get_string(iqueue, &data, &len)) != 0)
  719. fatal("%s: buffer error: %s", __func__, ssh_err(r));
  720. debug("request %u: write \"%s\" (handle %d) off %llu len %zu",
  721. id, handle_to_name(handle), handle, (unsigned long long)off, len);
  722. fd = handle_to_fd(handle);
  723. if (fd < 0)
  724. status = SSH2_FX_FAILURE;
  725. else {
  726. if (!(handle_to_flags(handle) & O_APPEND) &&
  727. lseek(fd, off, SEEK_SET) == -1) {
  728. status = errno_to_portable(errno);
  729. error("%s: seek failed", __func__);
  730. } else {
  731. /* XXX ATOMICIO ? */
  732. ret = write(fd, data, len);
  733. if (ret == -1) {
  734. error("%s: write: %s", __func__,
  735. strerror(errno));
  736. status = errno_to_portable(errno);
  737. } else if ((size_t)ret == len) {
  738. status = SSH2_FX_OK;
  739. handle_update_write(handle, ret);
  740. } else {
  741. debug2("%s: nothing at all written", __func__);
  742. status = SSH2_FX_FAILURE;
  743. }
  744. }
  745. }
  746. send_status(id, status);
  747. free(data);
  748. }
  749. static void
  750. process_do_stat(u_int32_t id, int do_lstat)
  751. {
  752. Attrib a;
  753. struct stat st;
  754. char *name;
  755. int r, status = SSH2_FX_FAILURE;
  756. if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0)
  757. fatal("%s: buffer error: %s", __func__, ssh_err(r));
  758. debug3("request %u: %sstat", id, do_lstat ? "l" : "");
  759. verbose("%sstat name \"%s\"", do_lstat ? "l" : "", name);
  760. r = do_lstat ? lstat(name, &st) : stat(name, &st);
  761. if (r == -1) {
  762. status = errno_to_portable(errno);
  763. } else {
  764. stat_to_attrib(&st, &a);
  765. send_attrib(id, &a);
  766. status = SSH2_FX_OK;
  767. }
  768. if (status != SSH2_FX_OK)
  769. send_status(id, status);
  770. free(name);
  771. }
  772. static void
  773. process_stat(u_int32_t id)
  774. {
  775. process_do_stat(id, 0);
  776. }
  777. static void
  778. process_lstat(u_int32_t id)
  779. {
  780. process_do_stat(id, 1);
  781. }
  782. static void
  783. process_fstat(u_int32_t id)
  784. {
  785. Attrib a;
  786. struct stat st;
  787. int fd, r, handle, status = SSH2_FX_FAILURE;
  788. if ((r = get_handle(iqueue, &handle)) != 0)
  789. fatal("%s: buffer error: %s", __func__, ssh_err(r));
  790. debug("request %u: fstat \"%s\" (handle %u)",
  791. id, handle_to_name(handle), handle);
  792. fd = handle_to_fd(handle);
  793. if (fd >= 0) {
  794. r = fstat(fd, &st);
  795. if (r == -1) {
  796. status = errno_to_portable(errno);
  797. } else {
  798. stat_to_attrib(&st, &a);
  799. send_attrib(id, &a);
  800. status = SSH2_FX_OK;
  801. }
  802. }
  803. if (status != SSH2_FX_OK)
  804. send_status(id, status);
  805. }
  806. static struct timeval *
  807. attrib_to_tv(const Attrib *a)
  808. {
  809. static struct timeval tv[2];
  810. tv[0].tv_sec = a->atime;
  811. tv[0].tv_usec = 0;
  812. tv[1].tv_sec = a->mtime;
  813. tv[1].tv_usec = 0;
  814. return tv;
  815. }
  816. static struct timespec *
  817. attrib_to_ts(const Attrib *a)
  818. {
  819. static struct timespec ts[2];
  820. ts[0].tv_sec = a->atime;
  821. ts[0].tv_nsec = 0;
  822. ts[1].tv_sec = a->mtime;
  823. ts[1].tv_nsec = 0;
  824. return ts;
  825. }
  826. static void
  827. process_setstat(u_int32_t id)
  828. {
  829. Attrib a;
  830. char *name;
  831. int r, status = SSH2_FX_OK;
  832. if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0 ||
  833. (r = decode_attrib(iqueue, &a)) != 0)
  834. fatal("%s: buffer error: %s", __func__, ssh_err(r));
  835. debug("request %u: setstat name \"%s\"", id, name);
  836. if (a.flags & SSH2_FILEXFER_ATTR_SIZE) {
  837. logit("set \"%s\" size %llu",
  838. name, (unsigned long long)a.size);
  839. r = truncate(name, a.size);
  840. if (r == -1)
  841. status = errno_to_portable(errno);
  842. }
  843. if (a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) {
  844. logit("set \"%s\" mode %04o", name, a.perm);
  845. r = chmod(name, a.perm & 07777);
  846. if (r == -1)
  847. status = errno_to_portable(errno);
  848. }
  849. if (a.flags & SSH2_FILEXFER_ATTR_ACMODTIME) {
  850. char buf[64];
  851. time_t t = a.mtime;
  852. strftime(buf, sizeof(buf), "%Y%m%d-%H:%M:%S",
  853. localtime(&t));
  854. logit("set \"%s\" modtime %s", name, buf);
  855. r = utimes(name, attrib_to_tv(&a));
  856. if (r == -1)
  857. status = errno_to_portable(errno);
  858. }
  859. if (a.flags & SSH2_FILEXFER_ATTR_UIDGID) {
  860. logit("set \"%s\" owner %lu group %lu", name,
  861. (u_long)a.uid, (u_long)a.gid);
  862. r = chown(name, a.uid, a.gid);
  863. if (r == -1)
  864. status = errno_to_portable(errno);
  865. }
  866. send_status(id, status);
  867. free(name);
  868. }
  869. static void
  870. process_fsetstat(u_int32_t id)
  871. {
  872. Attrib a;
  873. int handle, fd, r;
  874. int status = SSH2_FX_OK;
  875. if ((r = get_handle(iqueue, &handle)) != 0 ||
  876. (r = decode_attrib(iqueue, &a)) != 0)
  877. fatal("%s: buffer error: %s", __func__, ssh_err(r));
  878. debug("request %u: fsetstat handle %d", id, handle);
  879. fd = handle_to_fd(handle);
  880. if (fd < 0)
  881. status = SSH2_FX_FAILURE;
  882. else {
  883. char *name = handle_to_name(handle);
  884. if (a.flags & SSH2_FILEXFER_ATTR_SIZE) {
  885. logit("set \"%s\" size %llu",
  886. name, (unsigned long long)a.size);
  887. r = ftruncate(fd, a.size);
  888. if (r == -1)
  889. status = errno_to_portable(errno);
  890. }
  891. if (a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) {
  892. logit("set \"%s\" mode %04o", name, a.perm);
  893. #ifdef HAVE_FCHMOD
  894. r = fchmod(fd, a.perm & 07777);
  895. #else
  896. r = chmod(name, a.perm & 07777);
  897. #endif
  898. if (r == -1)
  899. status = errno_to_portable(errno);
  900. }
  901. if (a.flags & SSH2_FILEXFER_ATTR_ACMODTIME) {
  902. char buf[64];
  903. time_t t = a.mtime;
  904. strftime(buf, sizeof(buf), "%Y%m%d-%H:%M:%S",
  905. localtime(&t));
  906. logit("set \"%s\" modtime %s", name, buf);
  907. #ifdef HAVE_FUTIMES
  908. r = futimes(fd, attrib_to_tv(&a));
  909. #else
  910. r = utimes(name, attrib_to_tv(&a));
  911. #endif
  912. if (r == -1)
  913. status = errno_to_portable(errno);
  914. }
  915. if (a.flags & SSH2_FILEXFER_ATTR_UIDGID) {
  916. logit("set \"%s\" owner %lu group %lu", name,
  917. (u_long)a.uid, (u_long)a.gid);
  918. #ifdef HAVE_FCHOWN
  919. r = fchown(fd, a.uid, a.gid);
  920. #else
  921. r = chown(name, a.uid, a.gid);
  922. #endif
  923. if (r == -1)
  924. status = errno_to_portable(errno);
  925. }
  926. }
  927. send_status(id, status);
  928. }
  929. static void
  930. process_opendir(u_int32_t id)
  931. {
  932. DIR *dirp = NULL;
  933. char *path;
  934. int r, handle, status = SSH2_FX_FAILURE;
  935. if ((r = sshbuf_get_cstring(iqueue, &path, NULL)) != 0)
  936. fatal("%s: buffer error: %s", __func__, ssh_err(r));
  937. debug3("request %u: opendir", id);
  938. logit("opendir \"%s\"", path);
  939. dirp = opendir(path);
  940. if (dirp == NULL) {
  941. status = errno_to_portable(errno);
  942. } else {
  943. handle = handle_new(HANDLE_DIR, path, 0, 0, dirp);
  944. if (handle < 0) {
  945. closedir(dirp);
  946. } else {
  947. send_handle(id, handle);
  948. status = SSH2_FX_OK;
  949. }
  950. }
  951. if (status != SSH2_FX_OK)
  952. send_status(id, status);
  953. free(path);
  954. }
  955. static void
  956. process_readdir(u_int32_t id)
  957. {
  958. DIR *dirp;
  959. struct dirent *dp;
  960. char *path;
  961. int r, handle;
  962. if ((r = get_handle(iqueue, &handle)) != 0)
  963. fatal("%s: buffer error: %s", __func__, ssh_err(r));
  964. debug("request %u: readdir \"%s\" (handle %d)", id,
  965. handle_to_name(handle), handle);
  966. dirp = handle_to_dir(handle);
  967. path = handle_to_name(handle);
  968. if (dirp == NULL || path == NULL) {
  969. send_status(id, SSH2_FX_FAILURE);
  970. } else {
  971. struct stat st;
  972. char pathname[PATH_MAX];
  973. Stat *stats;
  974. int nstats = 10, count = 0, i;
  975. stats = xcalloc(nstats, sizeof(Stat));
  976. while ((dp = readdir(dirp)) != NULL) {
  977. if (count >= nstats) {
  978. nstats *= 2;
  979. stats = xreallocarray(stats, nstats, sizeof(Stat));
  980. }
  981. /* XXX OVERFLOW ? */
  982. snprintf(pathname, sizeof pathname, "%s%s%s", path,
  983. strcmp(path, "/") ? "/" : "", dp->d_name);
  984. if (lstat(pathname, &st) == -1)
  985. continue;
  986. stat_to_attrib(&st, &(stats[count].attrib));
  987. stats[count].name = xstrdup(dp->d_name);
  988. stats[count].long_name = ls_file(dp->d_name, &st, 0, 0);
  989. count++;
  990. /* send up to 100 entries in one message */
  991. /* XXX check packet size instead */
  992. if (count == 100)
  993. break;
  994. }
  995. if (count > 0) {
  996. send_names(id, count, stats);
  997. for (i = 0; i < count; i++) {
  998. free(stats[i].name);
  999. free(stats[i].long_name);
  1000. }
  1001. } else {
  1002. send_status(id, SSH2_FX_EOF);
  1003. }
  1004. free(stats);
  1005. }
  1006. }
  1007. static void
  1008. process_remove(u_int32_t id)
  1009. {
  1010. char *name;
  1011. int r, status = SSH2_FX_FAILURE;
  1012. if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0)
  1013. fatal("%s: buffer error: %s", __func__, ssh_err(r));
  1014. debug3("request %u: remove", id);
  1015. logit("remove name \"%s\"", name);
  1016. r = unlink(name);
  1017. status = (r == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
  1018. send_status(id, status);
  1019. free(name);
  1020. }
  1021. static void
  1022. process_mkdir(u_int32_t id)
  1023. {
  1024. Attrib a;
  1025. char *name;
  1026. int r, mode, status = SSH2_FX_FAILURE;
  1027. if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0 ||
  1028. (r = decode_attrib(iqueue, &a)) != 0)
  1029. fatal("%s: buffer error: %s", __func__, ssh_err(r));
  1030. mode = (a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) ?
  1031. a.perm & 07777 : 0777;
  1032. debug3("request %u: mkdir", id);
  1033. logit("mkdir name \"%s\" mode 0%o", name, mode);
  1034. r = mkdir(name, mode);
  1035. status = (r == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
  1036. send_status(id, status);
  1037. free(name);
  1038. }
  1039. static void
  1040. process_rmdir(u_int32_t id)
  1041. {
  1042. char *name;
  1043. int r, status;
  1044. if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0)
  1045. fatal("%s: buffer error: %s", __func__, ssh_err(r));
  1046. debug3("request %u: rmdir", id);
  1047. logit("rmdir name \"%s\"", name);
  1048. r = rmdir(name);
  1049. status = (r == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
  1050. send_status(id, status);
  1051. free(name);
  1052. }
  1053. static void
  1054. process_realpath(u_int32_t id)
  1055. {
  1056. char resolvedname[PATH_MAX];
  1057. char *path;
  1058. int r;
  1059. if ((r = sshbuf_get_cstring(iqueue, &path, NULL)) != 0)
  1060. fatal("%s: buffer error: %s", __func__, ssh_err(r));
  1061. if (path[0] == '\0') {
  1062. free(path);
  1063. path = xstrdup(".");
  1064. }
  1065. debug3("request %u: realpath", id);
  1066. verbose("realpath \"%s\"", path);
  1067. if (sftp_realpath(path, resolvedname) == NULL) {
  1068. send_status(id, errno_to_portable(errno));
  1069. } else {
  1070. Stat s;
  1071. attrib_clear(&s.attrib);
  1072. s.name = s.long_name = resolvedname;
  1073. send_names(id, 1, &s);
  1074. }
  1075. free(path);
  1076. }
  1077. static void
  1078. process_rename(u_int32_t id)
  1079. {
  1080. char *oldpath, *newpath;
  1081. int r, status;
  1082. struct stat sb;
  1083. if ((r = sshbuf_get_cstring(iqueue, &oldpath, NULL)) != 0 ||
  1084. (r = sshbuf_get_cstring(iqueue, &newpath, NULL)) != 0)
  1085. fatal("%s: buffer error: %s", __func__, ssh_err(r));
  1086. debug3("request %u: rename", id);
  1087. logit("rename old \"%s\" new \"%s\"", oldpath, newpath);
  1088. status = SSH2_FX_FAILURE;
  1089. if (lstat(oldpath, &sb) == -1)
  1090. status = errno_to_portable(errno);
  1091. else if (S_ISREG(sb.st_mode)) {
  1092. /* Race-free rename of regular files */
  1093. if (link(oldpath, newpath) == -1) {
  1094. if (errno == EOPNOTSUPP || errno == ENOSYS
  1095. #ifdef EXDEV
  1096. || errno == EXDEV
  1097. #endif
  1098. #ifdef LINK_OPNOTSUPP_ERRNO
  1099. || errno == LINK_OPNOTSUPP_ERRNO
  1100. #endif
  1101. ) {
  1102. struct stat st;
  1103. /*
  1104. * fs doesn't support links, so fall back to
  1105. * stat+rename. This is racy.
  1106. */
  1107. if (stat(newpath, &st) == -1) {
  1108. if (rename(oldpath, newpath) == -1)
  1109. status =
  1110. errno_to_portable(errno);
  1111. else
  1112. status = SSH2_FX_OK;
  1113. }
  1114. } else {
  1115. status = errno_to_portable(errno);
  1116. }
  1117. } else if (unlink(oldpath) == -1) {
  1118. status = errno_to_portable(errno);
  1119. /* clean spare link */
  1120. unlink(newpath);
  1121. } else
  1122. status = SSH2_FX_OK;
  1123. } else if (stat(newpath, &sb) == -1) {
  1124. if (rename(oldpath, newpath) == -1)
  1125. status = errno_to_portable(errno);
  1126. else
  1127. status = SSH2_FX_OK;
  1128. }
  1129. send_status(id, status);
  1130. free(oldpath);
  1131. free(newpath);
  1132. }
  1133. static void
  1134. process_readlink(u_int32_t id)
  1135. {
  1136. int r, len;
  1137. char buf[PATH_MAX];
  1138. char *path;
  1139. if ((r = sshbuf_get_cstring(iqueue, &path, NULL)) != 0)
  1140. fatal("%s: buffer error: %s", __func__, ssh_err(r));
  1141. debug3("request %u: readlink", id);
  1142. verbose("readlink \"%s\"", path);
  1143. if ((len = readlink(path, buf, sizeof(buf) - 1)) == -1)
  1144. send_status(id, errno_to_portable(errno));
  1145. else {
  1146. Stat s;
  1147. buf[len] = '\0';
  1148. attrib_clear(&s.attrib);
  1149. s.name = s.long_name = buf;
  1150. send_names(id, 1, &s);
  1151. }
  1152. free(path);
  1153. }
  1154. static void
  1155. process_symlink(u_int32_t id)
  1156. {
  1157. char *oldpath, *newpath;
  1158. int r, status;
  1159. if ((r = sshbuf_get_cstring(iqueue, &oldpath, NULL)) != 0 ||
  1160. (r = sshbuf_get_cstring(iqueue, &newpath, NULL)) != 0)
  1161. fatal("%s: buffer error: %s", __func__, ssh_err(r));
  1162. debug3("request %u: symlink", id);
  1163. logit("symlink old \"%s\" new \"%s\"", oldpath, newpath);
  1164. /* this will fail if 'newpath' exists */
  1165. r = symlink(oldpath, newpath);
  1166. status = (r == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
  1167. send_status(id, status);
  1168. free(oldpath);
  1169. free(newpath);
  1170. }
  1171. static void
  1172. process_extended_posix_rename(u_int32_t id)
  1173. {
  1174. char *oldpath, *newpath;
  1175. int r, status;
  1176. if ((r = sshbuf_get_cstring(iqueue, &oldpath, NULL)) != 0 ||
  1177. (r = sshbuf_get_cstring(iqueue, &newpath, NULL)) != 0)
  1178. fatal("%s: buffer error: %s", __func__, ssh_err(r));
  1179. debug3("request %u: posix-rename", id);
  1180. logit("posix-rename old \"%s\" new \"%s\"", oldpath, newpath);
  1181. r = rename(oldpath, newpath);
  1182. status = (r == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
  1183. send_status(id, status);
  1184. free(oldpath);
  1185. free(newpath);
  1186. }
  1187. static void
  1188. process_extended_statvfs(u_int32_t id)
  1189. {
  1190. char *path;
  1191. struct statvfs st;
  1192. int r;
  1193. if ((r = sshbuf_get_cstring(iqueue, &path, NULL)) != 0)
  1194. fatal("%s: buffer error: %s", __func__, ssh_err(r));
  1195. debug3("request %u: statvfs", id);
  1196. logit("statvfs \"%s\"", path);
  1197. if (statvfs(path, &st) != 0)
  1198. send_status(id, errno_to_portable(errno));
  1199. else
  1200. send_statvfs(id, &st);
  1201. free(path);
  1202. }
  1203. static void
  1204. process_extended_fstatvfs(u_int32_t id)
  1205. {
  1206. int r, handle, fd;
  1207. struct statvfs st;
  1208. if ((r = get_handle(iqueue, &handle)) != 0)
  1209. fatal("%s: buffer error: %s", __func__, ssh_err(r));
  1210. debug("request %u: fstatvfs \"%s\" (handle %u)",
  1211. id, handle_to_name(handle), handle);
  1212. if ((fd = handle_to_fd(handle)) < 0) {
  1213. send_status(id, SSH2_FX_FAILURE);
  1214. return;
  1215. }
  1216. if (fstatvfs(fd, &st) != 0)
  1217. send_status(id, errno_to_portable(errno));
  1218. else
  1219. send_statvfs(id, &st);
  1220. }
  1221. static void
  1222. process_extended_hardlink(u_int32_t id)
  1223. {
  1224. char *oldpath, *newpath;
  1225. int r, status;
  1226. if ((r = sshbuf_get_cstring(iqueue, &oldpath, NULL)) != 0 ||
  1227. (r = sshbuf_get_cstring(iqueue, &newpath, NULL)) != 0)
  1228. fatal("%s: buffer error: %s", __func__, ssh_err(r));
  1229. debug3("request %u: hardlink", id);
  1230. logit("hardlink old \"%s\" new \"%s\"", oldpath, newpath);
  1231. r = link(oldpath, newpath);
  1232. status = (r == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
  1233. send_status(id, status);
  1234. free(oldpath);
  1235. free(newpath);
  1236. }
  1237. static void
  1238. process_extended_fsync(u_int32_t id)
  1239. {
  1240. int handle, fd, r, status = SSH2_FX_OP_UNSUPPORTED;
  1241. if ((r = get_handle(iqueue, &handle)) != 0)
  1242. fatal("%s: buffer error: %s", __func__, ssh_err(r));
  1243. debug3("request %u: fsync (handle %u)", id, handle);
  1244. verbose("fsync \"%s\"", handle_to_name(handle));
  1245. if ((fd = handle_to_fd(handle)) < 0)
  1246. status = SSH2_FX_NO_SUCH_FILE;
  1247. else if (handle_is_ok(handle, HANDLE_FILE)) {
  1248. r = fsync(fd);
  1249. status = (r == -1) ? errno_to_portable(errno) : SSH2_FX_OK;
  1250. }
  1251. send_status(id, status);
  1252. }
  1253. static void
  1254. process_extended_lsetstat(u_int32_t id)
  1255. {
  1256. Attrib a;
  1257. char *name;
  1258. int r, status = SSH2_FX_OK;
  1259. if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0 ||
  1260. (r = decode_attrib(iqueue, &a)) != 0)
  1261. fatal("%s: buffer error: %s", __func__, ssh_err(r));
  1262. debug("request %u: lsetstat name \"%s\"", id, name);
  1263. if (a.flags & SSH2_FILEXFER_ATTR_SIZE) {
  1264. /* nonsensical for links */
  1265. status = SSH2_FX_BAD_MESSAGE;
  1266. goto out;
  1267. }
  1268. if (a.flags & SSH2_FILEXFER_ATTR_PERMISSIONS) {
  1269. logit("set \"%s\" mode %04o", name, a.perm);
  1270. r = fchmodat(AT_FDCWD, name,
  1271. a.perm & 07777, AT_SYMLINK_NOFOLLOW);
  1272. if (r == -1)
  1273. status = errno_to_portable(errno);
  1274. }
  1275. if (a.flags & SSH2_FILEXFER_ATTR_ACMODTIME) {
  1276. char buf[64];
  1277. time_t t = a.mtime;
  1278. strftime(buf, sizeof(buf), "%Y%m%d-%H:%M:%S",
  1279. localtime(&t));
  1280. logit("set \"%s\" modtime %s", name, buf);
  1281. r = utimensat(AT_FDCWD, name,
  1282. attrib_to_ts(&a), AT_SYMLINK_NOFOLLOW);
  1283. if (r == -1)
  1284. status = errno_to_portable(errno);
  1285. }
  1286. if (a.flags & SSH2_FILEXFER_ATTR_UIDGID) {
  1287. logit("set \"%s\" owner %lu group %lu", name,
  1288. (u_long)a.uid, (u_long)a.gid);
  1289. r = fchownat(AT_FDCWD, name, a.uid, a.gid,
  1290. AT_SYMLINK_NOFOLLOW);
  1291. if (r == -1)
  1292. status = errno_to_portable(errno);
  1293. }
  1294. out:
  1295. send_status(id, status);
  1296. free(name);
  1297. }
  1298. static void
  1299. process_extended_limits(u_int32_t id)
  1300. {
  1301. struct sshbuf *msg;
  1302. int r;
  1303. uint64_t nfiles = 0;
  1304. struct rlimit rlim;
  1305. debug("request %u: limits", id);
  1306. if (getrlimit(RLIMIT_NOFILE, &rlim) != -1 && rlim.rlim_cur > 5)
  1307. nfiles = rlim.rlim_cur - 5; /* stdio(3) + syslog + spare */
  1308. if ((msg = sshbuf_new()) == NULL)
  1309. fatal("sshbuf_new failed");
  1310. if ((r = sshbuf_put_u8(msg, SSH2_FXP_EXTENDED_REPLY)) != 0 ||
  1311. (r = sshbuf_put_u32(msg, id)) != 0 ||
  1312. /* max-packet-length */
  1313. (r = sshbuf_put_u64(msg, SFTP_MAX_MSG_LENGTH)) != 0 ||
  1314. /* max-read-length */
  1315. (r = sshbuf_put_u64(msg, SFTP_MAX_READ_LENGTH)) != 0 ||
  1316. /* max-write-length */
  1317. (r = sshbuf_put_u64(msg, SFTP_MAX_MSG_LENGTH - 1024)) != 0 ||
  1318. /* max-open-handles */
  1319. (r = sshbuf_put_u64(msg, nfiles)) != 0)
  1320. fatal(r, "compose");
  1321. send_msg(msg);
  1322. sshbuf_free(msg);
  1323. }
  1324. static void
  1325. process_extended(u_int32_t id)
  1326. {
  1327. char *request;
  1328. int i, r;
  1329. if ((r = sshbuf_get_cstring(iqueue, &request, NULL)) != 0)
  1330. fatal("%s: buffer error: %s", __func__, ssh_err(r));
  1331. for (i = 0; extended_handlers[i].handler != NULL; i++) {
  1332. if (strcmp(request, extended_handlers[i].ext_name) == 0) {
  1333. if (!request_permitted(&extended_handlers[i]))
  1334. send_status(id, SSH2_FX_PERMISSION_DENIED);
  1335. else
  1336. extended_handlers[i].handler(id);
  1337. break;
  1338. }
  1339. }
  1340. if (extended_handlers[i].handler == NULL) {
  1341. error("Unknown extended request \"%.100s\"", request);
  1342. send_status(id, SSH2_FX_OP_UNSUPPORTED); /* MUST */
  1343. }
  1344. free(request);
  1345. }
  1346. /* stolen from ssh-agent */
  1347. static void
  1348. process(void)
  1349. {
  1350. u_int msg_len;
  1351. u_int buf_len;
  1352. u_int consumed;
  1353. u_char type;
  1354. const u_char *cp;
  1355. int i, r;
  1356. u_int32_t id;
  1357. buf_len = sshbuf_len(iqueue);
  1358. if (buf_len < 5)
  1359. return; /* Incomplete message. */
  1360. cp = sshbuf_ptr(iqueue);
  1361. msg_len = get_u32(cp);
  1362. if (msg_len > SFTP_MAX_MSG_LENGTH) {
  1363. error("bad message from %s local user %s",
  1364. client_addr, pw->pw_name);
  1365. sftp_server_cleanup_exit(11);
  1366. }
  1367. if (buf_len < msg_len + 4)
  1368. return;
  1369. if ((r = sshbuf_consume(iqueue, 4)) != 0)
  1370. fatal("%s: buffer error: %s", __func__, ssh_err(r));
  1371. buf_len -= 4;
  1372. if ((r = sshbuf_get_u8(iqueue, &type)) != 0)
  1373. fatal("%s: buffer error: %s", __func__, ssh_err(r));
  1374. switch (type) {
  1375. case SSH2_FXP_INIT:
  1376. process_init();
  1377. init_done = 1;
  1378. break;
  1379. case SSH2_FXP_EXTENDED:
  1380. if (!init_done)
  1381. fatal("Received extended request before init");
  1382. if ((r = sshbuf_get_u32(iqueue, &id)) != 0)
  1383. fatal("%s: buffer error: %s", __func__, ssh_err(r));
  1384. process_extended(id);
  1385. break;
  1386. default:
  1387. if (!init_done)
  1388. fatal("Received %u request before init", type);
  1389. if ((r = sshbuf_get_u32(iqueue, &id)) != 0)
  1390. fatal("%s: buffer error: %s", __func__, ssh_err(r));
  1391. for (i = 0; handlers[i].handler != NULL; i++) {
  1392. if (type == handlers[i].type) {
  1393. if (!request_permitted(&handlers[i])) {
  1394. send_status(id,
  1395. SSH2_FX_PERMISSION_DENIED);
  1396. } else {
  1397. handlers[i].handler(id);
  1398. }
  1399. break;
  1400. }
  1401. }
  1402. if (handlers[i].handler == NULL)
  1403. error("Unknown message %u", type);
  1404. }
  1405. /* discard the remaining bytes from the current packet */
  1406. if (buf_len < sshbuf_len(iqueue)) {
  1407. error("iqueue grew unexpectedly");
  1408. sftp_server_cleanup_exit(255);
  1409. }
  1410. consumed = buf_len - sshbuf_len(iqueue);
  1411. if (msg_len < consumed) {
  1412. error("msg_len %u < consumed %u", msg_len, consumed);
  1413. sftp_server_cleanup_exit(255);
  1414. }
  1415. if (msg_len > consumed &&
  1416. (r = sshbuf_consume(iqueue, msg_len - consumed)) != 0)
  1417. fatal("%s: buffer error: %s", __func__, ssh_err(r));
  1418. }
  1419. /* Cleanup handler that logs active handles upon normal exit */
  1420. void
  1421. sftp_server_cleanup_exit(int i)
  1422. {
  1423. if (pw != NULL && client_addr != NULL) {
  1424. handle_log_exit();
  1425. logit("session closed for local user %s from [%s]",
  1426. pw->pw_name, client_addr);
  1427. }
  1428. _exit(i);
  1429. }
  1430. static void
  1431. sftp_server_usage(void)
  1432. {
  1433. extern char *__progname;
  1434. fprintf(stderr,
  1435. "usage: %s [-ehR] [-d start_directory] [-f log_facility] "
  1436. "[-l log_level]\n\t[-P denied_requests] "
  1437. "[-p allowed_requests] [-u umask] [-m force_file_perms]\n"
  1438. " %s -Q protocol_feature\n",
  1439. __progname, __progname);
  1440. exit(1);
  1441. }
  1442. int
  1443. sftp_server_main(int argc, char **argv, struct passwd *user_pw, int reset_handler)
  1444. {
  1445. fd_set *rset, *wset;
  1446. int i, r, in, out, max, ch, skipargs = 0, log_stderr = 0;
  1447. ssize_t len, olen, set_size;
  1448. SyslogFacility log_facility = SYSLOG_FACILITY_AUTH;
  1449. char *cp, *homedir = NULL, uidstr[32], buf[4*4096];
  1450. long mask;
  1451. extern char *optarg;
  1452. extern char *__progname;
  1453. __progname = ssh_get_progname(argv[0]);
  1454. log_init_handler(__progname, log_level, log_facility, log_stderr, reset_handler);
  1455. pw = pwcopy(user_pw);
  1456. while (!skipargs && (ch = getopt(argc, argv,
  1457. "d:f:l:P:p:Q:u:m:cehR")) != -1) {
  1458. switch (ch) {
  1459. case 'Q':
  1460. if (strcasecmp(optarg, "requests") != 0) {
  1461. fprintf(stderr, "Invalid query type\n");
  1462. exit(1);
  1463. }
  1464. for (i = 0; handlers[i].handler != NULL; i++)
  1465. printf("%s\n", handlers[i].name);
  1466. for (i = 0; extended_handlers[i].handler != NULL; i++)
  1467. printf("%s\n", extended_handlers[i].name);
  1468. exit(0);
  1469. break;
  1470. case 'R':
  1471. readonly = 1;
  1472. break;
  1473. case 'c':
  1474. /*
  1475. * Ignore all arguments if we are invoked as a
  1476. * shell using "sftp-server -c command"
  1477. */
  1478. skipargs = 1;
  1479. break;
  1480. case 'e':
  1481. log_stderr = 1;
  1482. break;
  1483. case 'l':
  1484. log_level = log_level_number(optarg);
  1485. if (log_level == SYSLOG_LEVEL_NOT_SET)
  1486. error("Invalid log level \"%s\"", optarg);
  1487. break;
  1488. case 'f':
  1489. log_facility = log_facility_number(optarg);
  1490. if (log_facility == SYSLOG_FACILITY_NOT_SET)
  1491. error("Invalid log facility \"%s\"", optarg);
  1492. break;
  1493. case 'd':
  1494. cp = tilde_expand_filename(optarg, user_pw->pw_uid);
  1495. snprintf(uidstr, sizeof(uidstr), "%llu",
  1496. (unsigned long long)pw->pw_uid);
  1497. homedir = percent_expand(cp, "d", user_pw->pw_dir,
  1498. "u", user_pw->pw_name, "U", uidstr, (char *)NULL);
  1499. free(cp);
  1500. break;
  1501. case 'p':
  1502. if (request_allowlist != NULL)
  1503. fatal("Permitted requests already set");
  1504. request_allowlist = xstrdup(optarg);
  1505. break;
  1506. case 'P':
  1507. if (request_denylist != NULL)
  1508. fatal("Refused requests already set");
  1509. request_denylist = xstrdup(optarg);
  1510. break;
  1511. case 'u':
  1512. errno = 0;
  1513. mask = strtol(optarg, &cp, 8);
  1514. if (mask < 0 || mask > 0777 || *cp != '\0' ||
  1515. cp == optarg || (mask == 0 && errno != 0))
  1516. fatal("Invalid umask \"%s\"", optarg);
  1517. (void)umask((mode_t)mask);
  1518. break;
  1519. case 'm':
  1520. /* Force permissions on file received via sftp */
  1521. permforce = 1;
  1522. permforcemode = strtol(optarg, &cp, 8);
  1523. if (permforcemode < 0 || permforcemode > 0777 ||
  1524. *cp != '\0' || (permforcemode == 0 &&
  1525. errno != 0))
  1526. fatal("Invalid file mode \"%s\"", optarg);
  1527. break;
  1528. case 'h':
  1529. default:
  1530. sftp_server_usage();
  1531. }
  1532. }
  1533. log_init_handler(__progname, log_level, log_facility, log_stderr, reset_handler);
  1534. /*
  1535. * On platforms where we can, avoid making /proc/self/{mem,maps}
  1536. * available to the user so that sftp access doesn't automatically
  1537. * imply arbitrary code execution access that will break
  1538. * restricted configurations.
  1539. */
  1540. platform_disable_tracing(1); /* strict */
  1541. /* Drop any fine-grained privileges we don't need */
  1542. platform_pledge_sftp_server();
  1543. if ((cp = getenv("SSH_CONNECTION")) != NULL) {
  1544. client_addr = xstrdup(cp);
  1545. if ((cp = strchr(client_addr, ' ')) == NULL) {
  1546. error("Malformed SSH_CONNECTION variable: \"%s\"",
  1547. getenv("SSH_CONNECTION"));
  1548. sftp_server_cleanup_exit(255);
  1549. }
  1550. *cp = '\0';
  1551. } else
  1552. client_addr = xstrdup("UNKNOWN");
  1553. logit("session opened for local user %s from [%s]",
  1554. pw->pw_name, client_addr);
  1555. in = STDIN_FILENO;
  1556. out = STDOUT_FILENO;
  1557. #ifdef HAVE_CYGWIN
  1558. setmode(in, O_BINARY);
  1559. setmode(out, O_BINARY);
  1560. #endif
  1561. max = 0;
  1562. if (in > max)
  1563. max = in;
  1564. if (out > max)
  1565. max = out;
  1566. if ((iqueue = sshbuf_new()) == NULL)
  1567. fatal("%s: sshbuf_new failed", __func__);
  1568. if ((oqueue = sshbuf_new()) == NULL)
  1569. fatal("%s: sshbuf_new failed", __func__);
  1570. rset = xcalloc(howmany(max + 1, NFDBITS), sizeof(fd_mask));
  1571. wset = xcalloc(howmany(max + 1, NFDBITS), sizeof(fd_mask));
  1572. if (homedir != NULL) {
  1573. if (chdir(homedir) != 0) {
  1574. error("chdir to \"%s\" failed: %s", homedir,
  1575. strerror(errno));
  1576. }
  1577. }
  1578. set_size = howmany(max + 1, NFDBITS) * sizeof(fd_mask);
  1579. for (;;) {
  1580. memset(rset, 0, set_size);
  1581. memset(wset, 0, set_size);
  1582. /*
  1583. * Ensure that we can read a full buffer and handle
  1584. * the worst-case length packet it can generate,
  1585. * otherwise apply backpressure by stopping reads.
  1586. */
  1587. if ((r = sshbuf_check_reserve(iqueue, sizeof(buf))) == 0 &&
  1588. (r = sshbuf_check_reserve(oqueue,
  1589. SFTP_MAX_MSG_LENGTH)) == 0)
  1590. FD_SET(in, rset);
  1591. else if (r != SSH_ERR_NO_BUFFER_SPACE)
  1592. fatal("%s: sshbuf_check_reserve failed: %s",
  1593. __func__, ssh_err(r));
  1594. olen = sshbuf_len(oqueue);
  1595. if (olen > 0)
  1596. FD_SET(out, wset);
  1597. if (select(max+1, rset, wset, NULL, NULL) == -1) {
  1598. if (errno == EINTR)
  1599. continue;
  1600. error("select: %s", strerror(errno));
  1601. sftp_server_cleanup_exit(2);
  1602. }
  1603. /* copy stdin to iqueue */
  1604. if (FD_ISSET(in, rset)) {
  1605. len = read(in, buf, sizeof buf);
  1606. if (len == 0) {
  1607. debug("read eof");
  1608. sftp_server_cleanup_exit(0);
  1609. } else if (len == -1) {
  1610. error("read: %s", strerror(errno));
  1611. sftp_server_cleanup_exit(1);
  1612. } else if ((r = sshbuf_put(iqueue, buf, len)) != 0) {
  1613. fatal("%s: buffer error: %s",
  1614. __func__, ssh_err(r));
  1615. }
  1616. }
  1617. /* send oqueue to stdout */
  1618. if (FD_ISSET(out, wset)) {
  1619. len = write(out, sshbuf_ptr(oqueue), olen);
  1620. if (len == -1) {
  1621. error("write: %s", strerror(errno));
  1622. sftp_server_cleanup_exit(1);
  1623. } else if ((r = sshbuf_consume(oqueue, len)) != 0) {
  1624. fatal("%s: buffer error: %s",
  1625. __func__, ssh_err(r));
  1626. }
  1627. }
  1628. /*
  1629. * Process requests from client if we can fit the results
  1630. * into the output buffer, otherwise stop processing input
  1631. * and let the output queue drain.
  1632. */
  1633. r = sshbuf_check_reserve(oqueue, SFTP_MAX_MSG_LENGTH);
  1634. if (r == 0)
  1635. process();
  1636. else if (r != SSH_ERR_NO_BUFFER_SPACE)
  1637. fatal("%s: sshbuf_check_reserve: %s",
  1638. __func__, ssh_err(r));
  1639. }
  1640. }