pscp.c 72 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375
  1. /*
  2. * pscp.c - Scp (Secure Copy) client for PuTTY.
  3. * Joris van Rantwijk, Simon Tatham
  4. *
  5. * This is mainly based on ssh-1.2.26/scp.c by Timo Rinne & Tatu Ylonen.
  6. * They, in turn, used stuff from BSD rcp.
  7. *
  8. * (SGT, 2001-09-10: Joris van Rantwijk assures me that although
  9. * this file as originally submitted was inspired by, and
  10. * _structurally_ based on, ssh-1.2.26's scp.c, there wasn't any
  11. * actual code duplicated, so the above comment shouldn't give rise
  12. * to licensing issues.)
  13. */
  14. #include <stdlib.h>
  15. #include <stdio.h>
  16. #include <string.h>
  17. #include <limits.h>
  18. #include <time.h>
  19. #include <assert.h>
  20. #include "putty.h"
  21. #include "psftp.h"
  22. #include "ssh.h"
  23. #include "ssh/sftp.h"
  24. #include "storage.h"
  25. static bool list = false;
  26. static bool verbose = false;
  27. static bool recursive = false;
  28. static bool preserve = false;
  29. static bool targetshouldbedirectory = false;
  30. static bool statistics = true;
  31. static int prev_stats_len = 0;
  32. static bool scp_unsafe_mode = false;
  33. static int errs = 0;
  34. static bool try_scp = true;
  35. static bool try_sftp = true;
  36. static bool main_cmd_is_sftp = false;
  37. static bool fallback_cmd_is_sftp = false;
  38. static bool using_sftp = false;
  39. static bool uploading = false;
  40. static Backend *backend;
  41. static Conf *conf;
  42. static bool sent_eof = false;
  43. static void source(const char *src);
  44. static void rsource(const char *src);
  45. static void sink(const char *targ, const char *src);
  46. /*
  47. * The maximum amount of queued data we accept before we stop and
  48. * wait for the server to process some.
  49. */
  50. #define MAX_SCP_BUFSIZE 16384
  51. void ldisc_echoedit_update(Ldisc *ldisc) { }
  52. void ldisc_check_sendok(Ldisc *ldisc) { }
  53. static size_t pscp_output(Seat *, SeatOutputType type, const void *, size_t);
  54. static bool pscp_eof(Seat *);
  55. static const SeatVtable pscp_seat_vt = {
  56. .output = pscp_output,
  57. .eof = pscp_eof,
  58. .sent = nullseat_sent,
  59. .banner = nullseat_banner_to_stderr,
  60. .get_userpass_input = filexfer_get_userpass_input,
  61. .notify_session_started = nullseat_notify_session_started,
  62. .notify_remote_exit = nullseat_notify_remote_exit,
  63. .notify_remote_disconnect = nullseat_notify_remote_disconnect,
  64. .connection_fatal = console_connection_fatal,
  65. .update_specials_menu = nullseat_update_specials_menu,
  66. .get_ttymode = nullseat_get_ttymode,
  67. .set_busy_status = nullseat_set_busy_status,
  68. .confirm_ssh_host_key = console_confirm_ssh_host_key,
  69. .confirm_weak_crypto_primitive = console_confirm_weak_crypto_primitive,
  70. .confirm_weak_cached_hostkey = console_confirm_weak_cached_hostkey,
  71. .prompt_descriptions = console_prompt_descriptions,
  72. .is_utf8 = nullseat_is_never_utf8,
  73. .echoedit_update = nullseat_echoedit_update,
  74. .get_x_display = nullseat_get_x_display,
  75. .get_windowid = nullseat_get_windowid,
  76. .get_window_pixel_size = nullseat_get_window_pixel_size,
  77. .stripctrl_new = console_stripctrl_new,
  78. .set_trust_status = nullseat_set_trust_status,
  79. .can_set_trust_status = nullseat_can_set_trust_status_yes,
  80. .has_mixed_input_stream = nullseat_has_mixed_input_stream_no,
  81. .verbose = cmdline_seat_verbose,
  82. .interactive = nullseat_interactive_no,
  83. .get_cursor_position = nullseat_get_cursor_position,
  84. };
  85. static Seat pscp_seat[1] = {{ &pscp_seat_vt }};
  86. static void tell_char(FILE *stream, char c)
  87. {
  88. fputc(c, stream);
  89. }
  90. static void tell_str(FILE *stream, const char *str)
  91. {
  92. unsigned int i;
  93. for (i = 0; i < strlen(str); ++i)
  94. tell_char(stream, str[i]);
  95. }
  96. static void abandon_stats(void)
  97. {
  98. /*
  99. * Output a \n to stdout (which is where we've been sending
  100. * transfer statistics) so that the cursor will move to the next
  101. * line. We should do this before displaying any other kind of
  102. * output like an error message.
  103. */
  104. if (prev_stats_len) {
  105. putchar('\n');
  106. fflush(stdout);
  107. prev_stats_len = 0;
  108. }
  109. }
  110. static PRINTF_LIKE(2, 3) void tell_user(FILE *stream, const char *fmt, ...)
  111. {
  112. char *str, *str2;
  113. va_list ap;
  114. va_start(ap, fmt);
  115. str = dupvprintf(fmt, ap);
  116. va_end(ap);
  117. str2 = dupcat(str, "\n");
  118. sfree(str);
  119. abandon_stats();
  120. tell_str(stream, str2);
  121. sfree(str2);
  122. }
  123. /*
  124. * Receive a block of data from the SSH link. Block until all data
  125. * is available.
  126. *
  127. * To do this, we repeatedly call the SSH protocol module, with our
  128. * own pscp_output() function to catch the data that comes back. We do
  129. * this until we have enough data.
  130. */
  131. static bufchain received_data;
  132. static BinarySink *stderr_bs;
  133. static size_t pscp_output(
  134. Seat *seat, SeatOutputType type, const void *data, size_t len)
  135. {
  136. /*
  137. * Non-stdout data (both stderr and SSH auth banners) is just
  138. * spouted to local stderr (optionally via a sanitiser) and
  139. * otherwise ignored.
  140. */
  141. if (type != SEAT_OUTPUT_STDOUT) {
  142. put_data(stderr_bs, data, len);
  143. return 0;
  144. }
  145. bufchain_add(&received_data, data, len);
  146. return 0;
  147. }
  148. static bool pscp_eof(Seat *seat)
  149. {
  150. /*
  151. * We usually expect to be the party deciding when to close the
  152. * connection, so if we see EOF before we sent it ourselves, we
  153. * should panic. The exception is if we're using old-style scp and
  154. * downloading rather than uploading.
  155. */
  156. if ((using_sftp || uploading) && !sent_eof) {
  157. seat_connection_fatal(
  158. pscp_seat, "Received unexpected end-of-file from server");
  159. }
  160. return false;
  161. }
  162. static bool ssh_scp_recv(void *vbuf, size_t len)
  163. {
  164. char *buf = (char *)vbuf;
  165. while (len > 0) {
  166. while (bufchain_size(&received_data) == 0) {
  167. if (backend_exitcode(backend) >= 0 ||
  168. ssh_sftp_loop_iteration() < 0)
  169. return false; /* doom */
  170. }
  171. size_t got = bufchain_fetch_consume_up_to(&received_data, buf, len);
  172. buf += got;
  173. len -= got;
  174. }
  175. return true;
  176. }
  177. /*
  178. * Loop through the ssh connection and authentication process.
  179. */
  180. static void ssh_scp_init(void)
  181. {
  182. while (!backend_sendok(backend)) {
  183. if (backend_exitcode(backend) >= 0) {
  184. errs++;
  185. return;
  186. }
  187. if (ssh_sftp_loop_iteration() < 0) {
  188. errs++;
  189. return; /* doom */
  190. }
  191. }
  192. /* Work out which backend we ended up using. */
  193. if (!ssh_fallback_cmd(backend))
  194. using_sftp = main_cmd_is_sftp;
  195. else
  196. using_sftp = fallback_cmd_is_sftp;
  197. if (verbose) {
  198. if (using_sftp)
  199. tell_user(stderr, "Using SFTP");
  200. else
  201. tell_user(stderr, "Using SCP1");
  202. }
  203. }
  204. /*
  205. * Print an error message and exit after closing the SSH link.
  206. */
  207. static NORETURN PRINTF_LIKE(1, 2) void bump(const char *fmt, ...)
  208. {
  209. char *str, *str2;
  210. va_list ap;
  211. va_start(ap, fmt);
  212. str = dupvprintf(fmt, ap);
  213. va_end(ap);
  214. str2 = dupcat(str, "\n");
  215. sfree(str);
  216. abandon_stats();
  217. tell_str(stderr, str2);
  218. sfree(str2);
  219. errs++;
  220. if (backend && backend_connected(backend)) {
  221. char ch;
  222. backend_special(backend, SS_EOF, 0);
  223. sent_eof = true;
  224. ssh_scp_recv(&ch, 1);
  225. }
  226. cleanup_exit(1);
  227. }
  228. /*
  229. * A nasty loop macro that lets me get an escape-sequence sanitised
  230. * version of a string for display, and free it automatically
  231. * afterwards.
  232. */
  233. static StripCtrlChars *string_scc;
  234. #define with_stripctrl(varname, input) \
  235. for (char *varname = stripctrl_string(string_scc, input); varname; \
  236. sfree(varname), varname = NULL)
  237. /*
  238. * Wait for the reply to a single SFTP request. Parallels the same
  239. * function in psftp.c (but isn't centralised into sftp.c because the
  240. * latter module handles SFTP only and shouldn't assume that SFTP is
  241. * the only thing going on by calling seat_connection_fatal).
  242. */
  243. struct sftp_packet *sftp_wait_for_reply(struct sftp_request *req)
  244. {
  245. struct sftp_packet *pktin;
  246. struct sftp_request *rreq;
  247. sftp_register(req);
  248. pktin = sftp_recv();
  249. if (pktin == NULL) {
  250. seat_connection_fatal(
  251. pscp_seat, "did not receive SFTP response packet from server");
  252. }
  253. rreq = sftp_find_request(pktin);
  254. if (rreq != req) {
  255. seat_connection_fatal(
  256. pscp_seat,
  257. "unable to understand SFTP response packet from server: %s",
  258. fxp_error());
  259. }
  260. return pktin;
  261. }
  262. /*
  263. * Open an SSH connection to user@host and execute cmd.
  264. */
  265. static void do_cmd(char *host, char *user, char *cmd)
  266. {
  267. const char *err;
  268. char *realhost;
  269. LogContext *logctx;
  270. if (host == NULL || host[0] == '\0')
  271. bump("Empty host name");
  272. /*
  273. * Remove a colon suffix.
  274. */
  275. host[host_strcspn(host, ":")] = '\0';
  276. /*
  277. * If we haven't loaded session details already (e.g., from -load),
  278. * try looking for a session called "host".
  279. */
  280. if (!cmdline_loaded_session()) {
  281. /* Try to load settings for `host' into a temporary config */
  282. Conf *conf2 = conf_new();
  283. conf_set_str(conf2, CONF_host, "");
  284. do_defaults(host, conf2);
  285. if (conf_get_str(conf2, CONF_host)[0] != '\0') {
  286. /* Settings present and include hostname */
  287. /* Re-load data into the real config. */
  288. do_defaults(host, conf);
  289. } else {
  290. /* Session doesn't exist or mention a hostname. */
  291. /* Use `host' as a bare hostname. */
  292. conf_set_str(conf, CONF_host, host);
  293. }
  294. conf_free(conf2);
  295. } else {
  296. /* Patch in hostname `host' to session details. */
  297. conf_set_str(conf, CONF_host, host);
  298. }
  299. /*
  300. * Force protocol to SSH if the user has somehow contrived to
  301. * select one we don't support (e.g. by loading an inappropriate
  302. * saved session). In that situation we assume the port number is
  303. * useless too.)
  304. */
  305. if (!backend_vt_from_proto(conf_get_int(conf, CONF_protocol))) {
  306. conf_set_int(conf, CONF_protocol, PROT_SSH);
  307. conf_set_int(conf, CONF_port, 22);
  308. }
  309. /*
  310. * Enact command-line overrides.
  311. */
  312. cmdline_run_saved(conf);
  313. /*
  314. * Muck about with the hostname in various ways.
  315. */
  316. {
  317. char *hostbuf = dupstr(conf_get_str(conf, CONF_host));
  318. char *host = hostbuf;
  319. char *p, *q;
  320. /*
  321. * Trim leading whitespace.
  322. */
  323. host += strspn(host, " \t");
  324. /*
  325. * See if host is of the form user@host, and separate out
  326. * the username if so.
  327. */
  328. if (host[0] != '\0') {
  329. char *atsign = strrchr(host, '@');
  330. if (atsign) {
  331. *atsign = '\0';
  332. conf_set_str(conf, CONF_username, host);
  333. host = atsign + 1;
  334. }
  335. }
  336. /*
  337. * Remove any remaining whitespace.
  338. */
  339. p = hostbuf;
  340. q = host;
  341. while (*q) {
  342. if (*q != ' ' && *q != '\t')
  343. *p++ = *q;
  344. q++;
  345. }
  346. *p = '\0';
  347. conf_set_str(conf, CONF_host, hostbuf);
  348. sfree(hostbuf);
  349. }
  350. /* Set username */
  351. if (user != NULL && user[0] != '\0') {
  352. conf_set_str(conf, CONF_username, user);
  353. } else if (conf_get_str(conf, CONF_username)[0] == '\0') {
  354. user = get_username();
  355. if (!user)
  356. bump("Empty user name");
  357. else {
  358. if (verbose)
  359. tell_user(stderr, "Guessing user name: %s", user);
  360. conf_set_str(conf, CONF_username, user);
  361. sfree(user);
  362. }
  363. }
  364. /*
  365. * Force protocol to SSH if the user has somehow contrived to
  366. * select one we don't support (e.g. by loading an inappropriate
  367. * saved session). In that situation we assume the port number is
  368. * useless too.)
  369. */
  370. if (!backend_vt_from_proto(conf_get_int(conf, CONF_protocol))) {
  371. conf_set_int(conf, CONF_protocol, PROT_SSH);
  372. conf_set_int(conf, CONF_port, 22);
  373. }
  374. /*
  375. * Disable scary things which shouldn't be enabled for simple
  376. * things like SCP and SFTP: agent forwarding, port forwarding,
  377. * X forwarding.
  378. */
  379. conf_set_bool(conf, CONF_x11_forward, false);
  380. conf_set_bool(conf, CONF_agentfwd, false);
  381. conf_set_bool(conf, CONF_ssh_simple, true);
  382. {
  383. char *key;
  384. while ((key = conf_get_str_nthstrkey(conf, CONF_portfwd, 0)) != NULL)
  385. conf_del_str_str(conf, CONF_portfwd, key);
  386. }
  387. /*
  388. * Set up main and possibly fallback command depending on
  389. * options specified by user.
  390. * Attempt to start the SFTP subsystem as a first choice,
  391. * falling back to the provided scp command if that fails.
  392. */
  393. conf_set_str(conf, CONF_remote_cmd2, "");
  394. if (try_sftp) {
  395. /* First choice is SFTP subsystem. */
  396. main_cmd_is_sftp = true;
  397. conf_set_str(conf, CONF_remote_cmd, "sftp");
  398. conf_set_bool(conf, CONF_ssh_subsys, true);
  399. if (try_scp) {
  400. /* Fallback is to use the provided scp command. */
  401. fallback_cmd_is_sftp = false;
  402. conf_set_str(conf, CONF_remote_cmd2, cmd);
  403. conf_set_bool(conf, CONF_ssh_subsys2, false);
  404. } else {
  405. /* Since we're not going to try SCP, we may as well try
  406. * harder to find an SFTP server, since in the current
  407. * implementation we have a spare slot. */
  408. fallback_cmd_is_sftp = true;
  409. /* see psftp.c for full explanation of this kludge */
  410. conf_set_str(conf, CONF_remote_cmd2,
  411. "test -x /usr/lib/sftp-server &&"
  412. " exec /usr/lib/sftp-server\n"
  413. "test -x /usr/local/lib/sftp-server &&"
  414. " exec /usr/local/lib/sftp-server\n"
  415. "exec sftp-server");
  416. conf_set_bool(conf, CONF_ssh_subsys2, false);
  417. }
  418. } else {
  419. /* Don't try SFTP at all; just try the scp command. */
  420. main_cmd_is_sftp = false;
  421. conf_set_str(conf, CONF_remote_cmd, cmd);
  422. conf_set_bool(conf, CONF_ssh_subsys, false);
  423. }
  424. conf_set_bool(conf, CONF_nopty, true);
  425. logctx = log_init(console_cli_logpolicy, conf);
  426. platform_psftp_pre_conn_setup(console_cli_logpolicy);
  427. err = backend_init(backend_vt_from_proto(
  428. conf_get_int(conf, CONF_protocol)),
  429. pscp_seat, &backend, logctx, conf,
  430. conf_get_str(conf, CONF_host),
  431. conf_get_int(conf, CONF_port),
  432. &realhost, 0,
  433. conf_get_bool(conf, CONF_tcp_keepalives));
  434. if (err != NULL)
  435. bump("ssh_init: %s", err);
  436. ssh_scp_init();
  437. if (verbose && realhost != NULL && errs == 0)
  438. tell_user(stderr, "Connected to %s", realhost);
  439. sfree(realhost);
  440. }
  441. /*
  442. * Update statistic information about current file.
  443. */
  444. static void print_stats(const char *name, uint64_t size, uint64_t done,
  445. time_t start, time_t now)
  446. {
  447. float ratebs;
  448. unsigned long eta;
  449. char *etastr;
  450. int pct;
  451. int len;
  452. int elap;
  453. elap = (unsigned long) difftime(now, start);
  454. if (now > start)
  455. ratebs = (float)done / elap;
  456. else
  457. ratebs = (float)done;
  458. if (ratebs < 1.0)
  459. eta = size - done;
  460. else
  461. eta = (unsigned long)((size - done) / ratebs);
  462. etastr = dupprintf("%02ld:%02ld:%02ld",
  463. eta / 3600, (eta % 3600) / 60, eta % 60);
  464. pct = (int) (100.0 * done / size);
  465. {
  466. /* divide by 1024 to provide kB */
  467. len = printf("\r%-25.25s | %"PRIu64" kB | %5.1f kB/s | "
  468. "ETA: %8s | %3d%%", name, done >> 10,
  469. ratebs / 1024.0, etastr, pct);
  470. if (len < prev_stats_len)
  471. printf("%*s", prev_stats_len - len, "");
  472. prev_stats_len = len;
  473. if (done == size)
  474. abandon_stats();
  475. fflush(stdout);
  476. }
  477. free(etastr);
  478. }
  479. /*
  480. * Find a colon in str and return a pointer to the colon.
  481. * This is used to separate hostname from filename.
  482. */
  483. static char *colon(char *str)
  484. {
  485. /* We ignore a leading colon, since the hostname cannot be
  486. empty. We also ignore a colon as second character because
  487. of filenames like f:myfile.txt. */
  488. if (str[0] == '\0' || str[0] == ':' ||
  489. (str[0] != '[' && str[1] == ':'))
  490. return (NULL);
  491. str += host_strcspn(str, ":/\\");
  492. if (*str == ':')
  493. return (str);
  494. else
  495. return (NULL);
  496. }
  497. /*
  498. * Determine whether a string is entirely composed of dots.
  499. */
  500. static bool is_dots(char *str)
  501. {
  502. return str[strspn(str, ".")] == '\0';
  503. }
  504. /*
  505. * Wait for a response from the other side.
  506. * Return 0 if ok, -1 if error.
  507. */
  508. static int response(void)
  509. {
  510. char ch, resp, rbuf[2048];
  511. int p;
  512. if (!ssh_scp_recv(&resp, 1))
  513. bump("Lost connection");
  514. p = 0;
  515. switch (resp) {
  516. case 0: /* ok */
  517. return (0);
  518. default:
  519. rbuf[p++] = resp;
  520. /* fallthrough */
  521. case 1: /* error */
  522. case 2: /* fatal error */
  523. do {
  524. if (!ssh_scp_recv(&ch, 1))
  525. bump("Protocol error: Lost connection");
  526. rbuf[p++] = ch;
  527. } while (p < sizeof(rbuf) && ch != '\n');
  528. rbuf[p - 1] = '\0';
  529. if (resp == 1)
  530. tell_user(stderr, "%s", rbuf);
  531. else
  532. bump("%s", rbuf);
  533. errs++;
  534. return (-1);
  535. }
  536. }
  537. bool sftp_recvdata(char *buf, size_t len)
  538. {
  539. return ssh_scp_recv(buf, len);
  540. }
  541. bool sftp_senddata(const char *buf, size_t len)
  542. {
  543. backend_send(backend, buf, len);
  544. return true;
  545. }
  546. size_t sftp_sendbuffer(void)
  547. {
  548. return backend_sendbuffer(backend);
  549. }
  550. /* ----------------------------------------------------------------------
  551. * sftp-based replacement for the hacky `pscp -ls'.
  552. */
  553. void list_directory_from_sftp_warn_unsorted(void)
  554. {
  555. fprintf(stderr,
  556. "Directory is too large to sort; writing file names unsorted\n");
  557. }
  558. void list_directory_from_sftp_print(struct fxp_name *name)
  559. {
  560. with_stripctrl(san, name->longname)
  561. printf("%s\n", san);
  562. }
  563. void scp_sftp_listdir(const char *dirname)
  564. {
  565. struct fxp_handle *dirh;
  566. struct fxp_names *names;
  567. struct sftp_packet *pktin;
  568. struct sftp_request *req;
  569. if (!fxp_init()) {
  570. tell_user(stderr, "unable to initialise SFTP: %s", fxp_error());
  571. errs++;
  572. return;
  573. }
  574. printf("Listing directory %s\n", dirname);
  575. req = fxp_opendir_send(dirname);
  576. pktin = sftp_wait_for_reply(req);
  577. dirh = fxp_opendir_recv(pktin, req);
  578. if (dirh == NULL) {
  579. tell_user(stderr, "Unable to open %s: %s\n", dirname, fxp_error());
  580. errs++;
  581. } else {
  582. struct list_directory_from_sftp_ctx *ctx =
  583. list_directory_from_sftp_new();
  584. while (1) {
  585. req = fxp_readdir_send(dirh);
  586. pktin = sftp_wait_for_reply(req);
  587. names = fxp_readdir_recv(pktin, req);
  588. if (names == NULL) {
  589. if (fxp_error_type() == SSH_FX_EOF)
  590. break;
  591. printf("Reading directory %s: %s\n", dirname, fxp_error());
  592. break;
  593. }
  594. if (names->nnames == 0) {
  595. fxp_free_names(names);
  596. break;
  597. }
  598. for (size_t i = 0; i < names->nnames; i++)
  599. list_directory_from_sftp_feed(ctx, &names->names[i]);
  600. fxp_free_names(names);
  601. }
  602. req = fxp_close_send(dirh);
  603. pktin = sftp_wait_for_reply(req);
  604. fxp_close_recv(pktin, req);
  605. list_directory_from_sftp_finish(ctx);
  606. list_directory_from_sftp_free(ctx);
  607. }
  608. }
  609. /* ----------------------------------------------------------------------
  610. * Helper routines that contain the actual SCP protocol elements,
  611. * implemented both as SCP1 and SFTP.
  612. */
  613. static struct scp_sftp_dirstack {
  614. struct scp_sftp_dirstack *next;
  615. struct fxp_name *names;
  616. int namepos, namelen;
  617. char *dirpath;
  618. char *wildcard;
  619. bool matched_something; /* wildcard match set was non-empty */
  620. } *scp_sftp_dirstack_head;
  621. static char *scp_sftp_remotepath, *scp_sftp_currentname;
  622. static char *scp_sftp_wildcard;
  623. static bool scp_sftp_targetisdir, scp_sftp_donethistarget;
  624. static bool scp_sftp_preserve, scp_sftp_recursive;
  625. static unsigned long scp_sftp_mtime, scp_sftp_atime;
  626. static bool scp_has_times;
  627. static struct fxp_handle *scp_sftp_filehandle;
  628. static struct fxp_xfer *scp_sftp_xfer;
  629. static uint64_t scp_sftp_fileoffset;
  630. int scp_source_setup(const char *target, bool shouldbedir)
  631. {
  632. if (using_sftp) {
  633. /*
  634. * Find out whether the target filespec is in fact a
  635. * directory.
  636. */
  637. struct sftp_packet *pktin;
  638. struct sftp_request *req;
  639. struct fxp_attrs attrs;
  640. bool ret;
  641. if (!fxp_init()) {
  642. tell_user(stderr, "unable to initialise SFTP: %s", fxp_error());
  643. errs++;
  644. return 1;
  645. }
  646. req = fxp_stat_send(target);
  647. pktin = sftp_wait_for_reply(req);
  648. ret = fxp_stat_recv(pktin, req, &attrs);
  649. if (!ret || !(attrs.flags & SSH_FILEXFER_ATTR_PERMISSIONS))
  650. scp_sftp_targetisdir = false;
  651. else
  652. scp_sftp_targetisdir = (attrs.permissions & 0040000) != 0;
  653. if (shouldbedir && !scp_sftp_targetisdir) {
  654. bump("pscp: remote filespec %s: not a directory\n", target);
  655. }
  656. scp_sftp_remotepath = dupstr(target);
  657. scp_has_times = false;
  658. } else {
  659. (void) response();
  660. }
  661. return 0;
  662. }
  663. int scp_send_errmsg(char *str)
  664. {
  665. if (using_sftp) {
  666. /* do nothing; we never need to send our errors to the server */
  667. } else {
  668. backend_send(backend, "\001", 1);/* scp protocol error prefix */
  669. backend_send(backend, str, strlen(str));
  670. }
  671. return 0; /* can't fail */
  672. }
  673. int scp_send_filetimes(unsigned long mtime, unsigned long atime)
  674. {
  675. if (using_sftp) {
  676. scp_sftp_mtime = mtime;
  677. scp_sftp_atime = atime;
  678. scp_has_times = true;
  679. return 0;
  680. } else {
  681. char buf[80];
  682. sprintf(buf, "T%lu 0 %lu 0\n", mtime, atime);
  683. backend_send(backend, buf, strlen(buf));
  684. return response();
  685. }
  686. }
  687. int scp_send_filename(const char *name, uint64_t size, int permissions)
  688. {
  689. if (using_sftp) {
  690. char *fullname;
  691. struct sftp_packet *pktin;
  692. struct sftp_request *req;
  693. struct fxp_attrs attrs;
  694. if (scp_sftp_targetisdir) {
  695. fullname = dupcat(scp_sftp_remotepath, "/", name);
  696. } else {
  697. fullname = dupstr(scp_sftp_remotepath);
  698. }
  699. attrs.flags = 0;
  700. PUT_PERMISSIONS(attrs, permissions);
  701. req = fxp_open_send(fullname,
  702. SSH_FXF_WRITE | SSH_FXF_CREAT | SSH_FXF_TRUNC,
  703. &attrs);
  704. pktin = sftp_wait_for_reply(req);
  705. scp_sftp_filehandle = fxp_open_recv(pktin, req);
  706. if (!scp_sftp_filehandle) {
  707. tell_user(stderr, "pscp: unable to open %s: %s",
  708. fullname, fxp_error());
  709. sfree(fullname);
  710. errs++;
  711. return 1;
  712. }
  713. scp_sftp_fileoffset = 0;
  714. scp_sftp_xfer = xfer_upload_init(scp_sftp_filehandle,
  715. scp_sftp_fileoffset);
  716. sfree(fullname);
  717. return 0;
  718. } else {
  719. char *buf;
  720. if (permissions < 0)
  721. permissions = 0644;
  722. buf = dupprintf("C%04o %"PRIu64" ", (int)(permissions & 07777), size);
  723. backend_send(backend, buf, strlen(buf));
  724. sfree(buf);
  725. backend_send(backend, name, strlen(name));
  726. backend_send(backend, "\n", 1);
  727. return response();
  728. }
  729. }
  730. int scp_send_filedata(char *data, int len)
  731. {
  732. if (using_sftp) {
  733. int ret;
  734. struct sftp_packet *pktin;
  735. if (!scp_sftp_filehandle) {
  736. return 1;
  737. }
  738. while (!xfer_upload_ready(scp_sftp_xfer)) {
  739. if (toplevel_callback_pending()) {
  740. /* If we have pending callbacks, they might make
  741. * xfer_upload_ready start to return true. So we should
  742. * run them and then re-check xfer_upload_ready, before
  743. * we go as far as waiting for an entire packet to
  744. * arrive. */
  745. run_toplevel_callbacks();
  746. continue;
  747. }
  748. pktin = sftp_recv();
  749. ret = xfer_upload_gotpkt(scp_sftp_xfer, pktin);
  750. if (ret <= 0) {
  751. tell_user(stderr, "error while writing: %s", fxp_error());
  752. if (ret == INT_MIN) /* pktin not even freed */
  753. sfree(pktin);
  754. errs++;
  755. return 1;
  756. }
  757. }
  758. xfer_upload_data(scp_sftp_xfer, data, len);
  759. scp_sftp_fileoffset += len;
  760. return 0;
  761. } else {
  762. backend_send(backend, data, len);
  763. int bufsize = backend_sendbuffer(backend);
  764. /*
  765. * If the network transfer is backing up - that is, the
  766. * remote site is not accepting data as fast as we can
  767. * produce it - then we must loop on network events until
  768. * we have space in the buffer again.
  769. */
  770. while (bufsize > MAX_SCP_BUFSIZE) {
  771. if (ssh_sftp_loop_iteration() < 0)
  772. return 1;
  773. bufsize = backend_sendbuffer(backend);
  774. }
  775. return 0;
  776. }
  777. }
  778. int scp_send_finish(void)
  779. {
  780. if (using_sftp) {
  781. struct fxp_attrs attrs;
  782. struct sftp_packet *pktin;
  783. struct sftp_request *req;
  784. while (!xfer_done(scp_sftp_xfer)) {
  785. pktin = sftp_recv();
  786. int ret = xfer_upload_gotpkt(scp_sftp_xfer, pktin);
  787. if (ret <= 0) {
  788. tell_user(stderr, "error while writing: %s", fxp_error());
  789. if (ret == INT_MIN) /* pktin not even freed */
  790. sfree(pktin);
  791. errs++;
  792. return 1;
  793. }
  794. }
  795. xfer_cleanup(scp_sftp_xfer);
  796. if (!scp_sftp_filehandle) {
  797. return 1;
  798. }
  799. if (scp_has_times) {
  800. attrs.flags = SSH_FILEXFER_ATTR_ACMODTIME;
  801. attrs.atime = scp_sftp_atime;
  802. attrs.mtime = scp_sftp_mtime;
  803. req = fxp_fsetstat_send(scp_sftp_filehandle, attrs);
  804. pktin = sftp_wait_for_reply(req);
  805. bool ret = fxp_fsetstat_recv(pktin, req);
  806. if (!ret) {
  807. tell_user(stderr, "unable to set file times: %s", fxp_error());
  808. errs++;
  809. }
  810. }
  811. req = fxp_close_send(scp_sftp_filehandle);
  812. pktin = sftp_wait_for_reply(req);
  813. fxp_close_recv(pktin, req);
  814. scp_has_times = false;
  815. return 0;
  816. } else {
  817. backend_send(backend, "", 1);
  818. return response();
  819. }
  820. }
  821. char *scp_save_remotepath(void)
  822. {
  823. if (using_sftp)
  824. return scp_sftp_remotepath;
  825. else
  826. return NULL;
  827. }
  828. void scp_restore_remotepath(char *data)
  829. {
  830. if (using_sftp)
  831. scp_sftp_remotepath = data;
  832. }
  833. int scp_send_dirname(const char *name, int modes)
  834. {
  835. if (using_sftp) {
  836. char *fullname;
  837. char const *err;
  838. struct fxp_attrs attrs;
  839. struct sftp_packet *pktin;
  840. struct sftp_request *req;
  841. bool ret;
  842. if (scp_sftp_targetisdir) {
  843. fullname = dupcat(scp_sftp_remotepath, "/", name);
  844. } else {
  845. fullname = dupstr(scp_sftp_remotepath);
  846. }
  847. /*
  848. * We don't worry about whether we managed to create the
  849. * directory, because if it exists already it's OK just to
  850. * use it. Instead, we will stat it afterwards, and if it
  851. * exists and is a directory we will assume we were either
  852. * successful or it didn't matter.
  853. */
  854. req = fxp_mkdir_send(fullname, NULL);
  855. pktin = sftp_wait_for_reply(req);
  856. ret = fxp_mkdir_recv(pktin, req);
  857. if (!ret)
  858. err = fxp_error();
  859. else
  860. err = "server reported no error";
  861. req = fxp_stat_send(fullname);
  862. pktin = sftp_wait_for_reply(req);
  863. ret = fxp_stat_recv(pktin, req, &attrs);
  864. if (!ret || !(attrs.flags & SSH_FILEXFER_ATTR_PERMISSIONS) ||
  865. !(attrs.permissions & 0040000)) {
  866. tell_user(stderr, "unable to create directory %s: %s",
  867. fullname, err);
  868. sfree(fullname);
  869. errs++;
  870. return 1;
  871. }
  872. scp_sftp_remotepath = fullname;
  873. return 0;
  874. } else {
  875. char buf[40];
  876. sprintf(buf, "D%04o 0 ", modes);
  877. backend_send(backend, buf, strlen(buf));
  878. backend_send(backend, name, strlen(name));
  879. backend_send(backend, "\n", 1);
  880. return response();
  881. }
  882. }
  883. int scp_send_enddir(void)
  884. {
  885. if (using_sftp) {
  886. sfree(scp_sftp_remotepath);
  887. return 0;
  888. } else {
  889. backend_send(backend, "E\n", 2);
  890. return response();
  891. }
  892. }
  893. /*
  894. * Yes, I know; I have an scp_sink_setup _and_ an scp_sink_init.
  895. * That's bad. The difference is that scp_sink_setup is called once
  896. * right at the start, whereas scp_sink_init is called to
  897. * initialise every level of recursion in the protocol.
  898. */
  899. int scp_sink_setup(const char *source, bool preserve, bool recursive)
  900. {
  901. if (using_sftp) {
  902. char *newsource;
  903. if (!fxp_init()) {
  904. tell_user(stderr, "unable to initialise SFTP: %s", fxp_error());
  905. errs++;
  906. return 1;
  907. }
  908. /*
  909. * It's possible that the source string we've been given
  910. * contains a wildcard. If so, we must split the directory
  911. * away from the wildcard itself (throwing an error if any
  912. * wildcardness comes before the final slash) and arrange
  913. * things so that a dirstack entry will be set up.
  914. */
  915. newsource = snewn(1+strlen(source), char);
  916. if (!wc_unescape(newsource, source)) {
  917. /* Yes, here we go; it's a wildcard. Bah. */
  918. char *dupsource, *lastpart, *dirpart, *wildcard;
  919. sfree(newsource);
  920. dupsource = dupstr(source);
  921. lastpart = stripslashes(dupsource, false);
  922. wildcard = dupstr(lastpart);
  923. *lastpart = '\0';
  924. if (*dupsource && dupsource[1]) {
  925. /*
  926. * The remains of dupsource are at least two
  927. * characters long, meaning the pathname wasn't
  928. * empty or just `/'. Hence, we remove the trailing
  929. * slash.
  930. */
  931. lastpart[-1] = '\0';
  932. } else if (!*dupsource) {
  933. /*
  934. * The remains of dupsource are _empty_ - the whole
  935. * pathname was a wildcard. Hence we need to
  936. * replace it with ".".
  937. */
  938. sfree(dupsource);
  939. dupsource = dupstr(".");
  940. }
  941. /*
  942. * Now we have separated our string into dupsource (the
  943. * directory part) and wildcard. Both of these will
  944. * need freeing at some point. Next step is to remove
  945. * wildcard escapes from the directory part, throwing
  946. * an error if it contains a real wildcard.
  947. */
  948. dirpart = snewn(1+strlen(dupsource), char);
  949. if (!wc_unescape(dirpart, dupsource)) {
  950. tell_user(stderr, "%s: multiple-level wildcards unsupported",
  951. source);
  952. errs++;
  953. sfree(dirpart);
  954. sfree(wildcard);
  955. sfree(dupsource);
  956. return 1;
  957. }
  958. /*
  959. * Now we have dirpart (unescaped, ie a valid remote
  960. * path), and wildcard (a wildcard). This will be
  961. * sufficient to arrange a dirstack entry.
  962. */
  963. scp_sftp_remotepath = dirpart;
  964. scp_sftp_wildcard = wildcard;
  965. sfree(dupsource);
  966. } else {
  967. scp_sftp_remotepath = newsource;
  968. scp_sftp_wildcard = NULL;
  969. }
  970. scp_sftp_preserve = preserve;
  971. scp_sftp_recursive = recursive;
  972. scp_sftp_donethistarget = false;
  973. scp_sftp_dirstack_head = NULL;
  974. }
  975. return 0;
  976. }
  977. int scp_sink_init(void)
  978. {
  979. if (!using_sftp) {
  980. backend_send(backend, "", 1);
  981. }
  982. return 0;
  983. }
  984. #define SCP_SINK_FILE 1
  985. #define SCP_SINK_DIR 2
  986. #define SCP_SINK_ENDDIR 3
  987. #define SCP_SINK_RETRY 4 /* not an action; just try again */
  988. struct scp_sink_action {
  989. int action; /* FILE, DIR, ENDDIR */
  990. strbuf *buf; /* will need freeing after use */
  991. char *name; /* filename or dirname (not ENDDIR) */
  992. long permissions; /* access permissions (not ENDDIR) */
  993. uint64_t size; /* file size (not ENDDIR) */
  994. bool settime; /* true if atime and mtime are filled */
  995. unsigned long atime, mtime; /* access times for the file */
  996. };
  997. int scp_get_sink_action(struct scp_sink_action *act)
  998. {
  999. if (using_sftp) {
  1000. char *fname;
  1001. bool must_free_fname;
  1002. struct fxp_attrs attrs;
  1003. struct sftp_packet *pktin;
  1004. struct sftp_request *req;
  1005. bool ret;
  1006. if (!scp_sftp_dirstack_head) {
  1007. if (!scp_sftp_donethistarget) {
  1008. /*
  1009. * Simple case: we are only dealing with one file.
  1010. */
  1011. fname = scp_sftp_remotepath;
  1012. must_free_fname = false;
  1013. scp_sftp_donethistarget = true;
  1014. } else {
  1015. /*
  1016. * Even simpler case: one file _which we've done_.
  1017. * Return 1 (finished).
  1018. */
  1019. return 1;
  1020. }
  1021. } else {
  1022. /*
  1023. * We're now in the middle of stepping through a list
  1024. * of names returned from fxp_readdir(); so let's carry
  1025. * on.
  1026. */
  1027. struct scp_sftp_dirstack *head = scp_sftp_dirstack_head;
  1028. while (head->namepos < head->namelen &&
  1029. (is_dots(head->names[head->namepos].filename) ||
  1030. (head->wildcard &&
  1031. !wc_match(head->wildcard,
  1032. head->names[head->namepos].filename))))
  1033. head->namepos++; /* skip . and .. */
  1034. if (head->namepos < head->namelen) {
  1035. head->matched_something = true;
  1036. fname = dupcat(head->dirpath, "/",
  1037. head->names[head->namepos++].filename);
  1038. must_free_fname = true;
  1039. } else {
  1040. /*
  1041. * We've come to the end of the list; pop it off
  1042. * the stack and return an ENDDIR action (or RETRY
  1043. * if this was a wildcard match).
  1044. */
  1045. if (head->wildcard) {
  1046. act->action = SCP_SINK_RETRY;
  1047. if (!head->matched_something) {
  1048. tell_user(stderr, "pscp: wildcard '%s' matched "
  1049. "no files", head->wildcard);
  1050. errs++;
  1051. }
  1052. sfree(head->wildcard);
  1053. } else {
  1054. act->action = SCP_SINK_ENDDIR;
  1055. }
  1056. sfree(head->dirpath);
  1057. sfree(head->names);
  1058. scp_sftp_dirstack_head = head->next;
  1059. sfree(head);
  1060. return 0;
  1061. }
  1062. }
  1063. /*
  1064. * Now we have a filename. Stat it, and see if it's a file
  1065. * or a directory.
  1066. */
  1067. req = fxp_stat_send(fname);
  1068. pktin = sftp_wait_for_reply(req);
  1069. ret = fxp_stat_recv(pktin, req, &attrs);
  1070. if (!ret || !(attrs.flags & SSH_FILEXFER_ATTR_PERMISSIONS)) {
  1071. with_stripctrl(san, fname)
  1072. tell_user(stderr, "unable to identify %s: %s", san,
  1073. ret ? "file type not supplied" : fxp_error());
  1074. if (must_free_fname) sfree(fname);
  1075. errs++;
  1076. return 1;
  1077. }
  1078. if (attrs.permissions & 0040000) {
  1079. struct scp_sftp_dirstack *newitem;
  1080. struct fxp_handle *dirhandle;
  1081. size_t nnames, namesize;
  1082. struct fxp_name *ournames;
  1083. struct fxp_names *names;
  1084. /*
  1085. * It's a directory. If we're not in recursive mode,
  1086. * this merits a complaint (which is fatal if the name
  1087. * was specified directly, but not if it was matched by
  1088. * a wildcard).
  1089. *
  1090. * We skip this complaint completely if
  1091. * scp_sftp_wildcard is set, because that's an
  1092. * indication that we're not actually supposed to
  1093. * _recursively_ transfer the dir, just scan it for
  1094. * things matching the wildcard.
  1095. */
  1096. if (!scp_sftp_recursive && !scp_sftp_wildcard) {
  1097. with_stripctrl(san, fname)
  1098. tell_user(stderr, "pscp: %s: is a directory", san);
  1099. errs++;
  1100. if (must_free_fname) sfree(fname);
  1101. if (scp_sftp_dirstack_head) {
  1102. act->action = SCP_SINK_RETRY;
  1103. return 0;
  1104. } else {
  1105. return 1;
  1106. }
  1107. }
  1108. /*
  1109. * Otherwise, the fun begins. We must fxp_opendir() the
  1110. * directory, slurp the filenames into memory, return
  1111. * SCP_SINK_DIR (unless this is a wildcard match), and
  1112. * set targetisdir. The next time we're called, we will
  1113. * run through the list of filenames one by one,
  1114. * matching them against a wildcard if present.
  1115. *
  1116. * If targetisdir is _already_ set (meaning we're
  1117. * already in the middle of going through another such
  1118. * list), we must push the other (target,namelist) pair
  1119. * on a stack.
  1120. */
  1121. req = fxp_opendir_send(fname);
  1122. pktin = sftp_wait_for_reply(req);
  1123. dirhandle = fxp_opendir_recv(pktin, req);
  1124. if (!dirhandle) {
  1125. with_stripctrl(san, fname)
  1126. tell_user(stderr, "pscp: unable to open directory %s: %s",
  1127. san, fxp_error());
  1128. if (must_free_fname) sfree(fname);
  1129. errs++;
  1130. return 1;
  1131. }
  1132. nnames = namesize = 0;
  1133. ournames = NULL;
  1134. while (1) {
  1135. int i;
  1136. req = fxp_readdir_send(dirhandle);
  1137. pktin = sftp_wait_for_reply(req);
  1138. names = fxp_readdir_recv(pktin, req);
  1139. if (names == NULL) {
  1140. if (fxp_error_type() == SSH_FX_EOF)
  1141. break;
  1142. with_stripctrl(san, fname)
  1143. tell_user(stderr, "pscp: reading directory %s: %s",
  1144. san, fxp_error());
  1145. req = fxp_close_send(dirhandle);
  1146. pktin = sftp_wait_for_reply(req);
  1147. fxp_close_recv(pktin, req);
  1148. if (must_free_fname) sfree(fname);
  1149. sfree(ournames);
  1150. errs++;
  1151. return 1;
  1152. }
  1153. if (names->nnames == 0) {
  1154. fxp_free_names(names);
  1155. break;
  1156. }
  1157. sgrowarrayn(ournames, namesize, nnames, names->nnames);
  1158. for (i = 0; i < names->nnames; i++) {
  1159. if (!strcmp(names->names[i].filename, ".") ||
  1160. !strcmp(names->names[i].filename, "..")) {
  1161. /*
  1162. * . and .. are normal consequences of
  1163. * reading a directory, and aren't worth
  1164. * complaining about.
  1165. */
  1166. } else if (!vet_filename(names->names[i].filename)) {
  1167. with_stripctrl(san, names->names[i].filename)
  1168. tell_user(stderr, "ignoring potentially dangerous "
  1169. "server-supplied filename '%s'", san);
  1170. } else
  1171. ournames[nnames++] = names->names[i];
  1172. }
  1173. names->nnames = 0; /* prevent free_names */
  1174. fxp_free_names(names);
  1175. }
  1176. req = fxp_close_send(dirhandle);
  1177. pktin = sftp_wait_for_reply(req);
  1178. fxp_close_recv(pktin, req);
  1179. newitem = snew(struct scp_sftp_dirstack);
  1180. newitem->next = scp_sftp_dirstack_head;
  1181. newitem->names = ournames;
  1182. newitem->namepos = 0;
  1183. newitem->namelen = nnames;
  1184. if (must_free_fname)
  1185. newitem->dirpath = fname;
  1186. else
  1187. newitem->dirpath = dupstr(fname);
  1188. if (scp_sftp_wildcard) {
  1189. newitem->wildcard = scp_sftp_wildcard;
  1190. newitem->matched_something = false;
  1191. scp_sftp_wildcard = NULL;
  1192. } else {
  1193. newitem->wildcard = NULL;
  1194. }
  1195. scp_sftp_dirstack_head = newitem;
  1196. if (newitem->wildcard) {
  1197. act->action = SCP_SINK_RETRY;
  1198. } else {
  1199. act->action = SCP_SINK_DIR;
  1200. strbuf_clear(act->buf);
  1201. put_asciz(act->buf, stripslashes(fname, false));
  1202. act->name = act->buf->s;
  1203. act->size = 0; /* duhh, it's a directory */
  1204. act->permissions = 07777 & attrs.permissions;
  1205. if (scp_sftp_preserve &&
  1206. (attrs.flags & SSH_FILEXFER_ATTR_ACMODTIME)) {
  1207. act->atime = attrs.atime;
  1208. act->mtime = attrs.mtime;
  1209. act->settime = true;
  1210. } else
  1211. act->settime = false;
  1212. }
  1213. return 0;
  1214. } else {
  1215. /*
  1216. * It's a file. Return SCP_SINK_FILE.
  1217. */
  1218. act->action = SCP_SINK_FILE;
  1219. strbuf_clear(act->buf);
  1220. put_asciz(act->buf, stripslashes(fname, false));
  1221. act->name = act->buf->s;
  1222. if (attrs.flags & SSH_FILEXFER_ATTR_SIZE) {
  1223. act->size = attrs.size;
  1224. } else
  1225. act->size = UINT64_MAX; /* no idea */
  1226. act->permissions = 07777 & attrs.permissions;
  1227. if (scp_sftp_preserve &&
  1228. (attrs.flags & SSH_FILEXFER_ATTR_ACMODTIME)) {
  1229. act->atime = attrs.atime;
  1230. act->mtime = attrs.mtime;
  1231. act->settime = true;
  1232. } else
  1233. act->settime = false;
  1234. if (must_free_fname)
  1235. scp_sftp_currentname = fname;
  1236. else
  1237. scp_sftp_currentname = dupstr(fname);
  1238. return 0;
  1239. }
  1240. } else {
  1241. bool done = false;
  1242. int action;
  1243. char ch;
  1244. act->settime = false;
  1245. strbuf_clear(act->buf);
  1246. while (!done) {
  1247. if (!ssh_scp_recv(&ch, 1))
  1248. return 1;
  1249. if (ch == '\n')
  1250. bump("Protocol error: Unexpected newline");
  1251. action = ch;
  1252. while (1) {
  1253. if (!ssh_scp_recv(&ch, 1))
  1254. bump("Lost connection");
  1255. if (ch == '\n')
  1256. break;
  1257. put_byte(act->buf, ch);
  1258. }
  1259. switch (action) {
  1260. case '\01': /* error */
  1261. with_stripctrl(san, act->buf->s)
  1262. tell_user(stderr, "%s", san);
  1263. errs++;
  1264. continue; /* go round again */
  1265. case '\02': /* fatal error */
  1266. with_stripctrl(san, act->buf->s)
  1267. bump("%s", san);
  1268. case 'E':
  1269. backend_send(backend, "", 1);
  1270. act->action = SCP_SINK_ENDDIR;
  1271. return 0;
  1272. case 'T':
  1273. if (sscanf(act->buf->s, "%lu %*d %lu %*d",
  1274. &act->mtime, &act->atime) == 2) {
  1275. act->settime = true;
  1276. backend_send(backend, "", 1);
  1277. strbuf_clear(act->buf);
  1278. continue; /* go round again */
  1279. }
  1280. bump("Protocol error: Illegal time format");
  1281. case 'C':
  1282. case 'D':
  1283. act->action = (action == 'C' ? SCP_SINK_FILE : SCP_SINK_DIR);
  1284. if (act->action == SCP_SINK_DIR && !recursive) {
  1285. bump("security violation: remote host attempted to create "
  1286. "a subdirectory in a non-recursive copy!");
  1287. }
  1288. break;
  1289. default:
  1290. bump("Protocol error: Expected control record");
  1291. }
  1292. /*
  1293. * We will go round this loop only once, unless we hit
  1294. * `continue' above.
  1295. */
  1296. done = true;
  1297. }
  1298. /*
  1299. * If we get here, we must have seen SCP_SINK_FILE or
  1300. * SCP_SINK_DIR.
  1301. */
  1302. {
  1303. int i;
  1304. if (sscanf(act->buf->s, "%lo %"SCNu64" %n", &act->permissions,
  1305. &act->size, &i) != 2)
  1306. bump("Protocol error: Illegal file descriptor format");
  1307. act->name = act->buf->s + i;
  1308. return 0;
  1309. }
  1310. }
  1311. }
  1312. int scp_accept_filexfer(void)
  1313. {
  1314. if (using_sftp) {
  1315. struct sftp_packet *pktin;
  1316. struct sftp_request *req;
  1317. req = fxp_open_send(scp_sftp_currentname, SSH_FXF_READ, NULL);
  1318. pktin = sftp_wait_for_reply(req);
  1319. scp_sftp_filehandle = fxp_open_recv(pktin, req);
  1320. if (!scp_sftp_filehandle) {
  1321. with_stripctrl(san, scp_sftp_currentname)
  1322. tell_user(stderr, "pscp: unable to open %s: %s",
  1323. san, fxp_error());
  1324. errs++;
  1325. return 1;
  1326. }
  1327. scp_sftp_fileoffset = 0;
  1328. scp_sftp_xfer = xfer_download_init(scp_sftp_filehandle,
  1329. scp_sftp_fileoffset);
  1330. sfree(scp_sftp_currentname);
  1331. return 0;
  1332. } else {
  1333. backend_send(backend, "", 1);
  1334. return 0; /* can't fail */
  1335. }
  1336. }
  1337. int scp_recv_filedata(char *data, int len)
  1338. {
  1339. if (using_sftp) {
  1340. struct sftp_packet *pktin;
  1341. int ret, actuallen;
  1342. void *vbuf;
  1343. xfer_download_queue(scp_sftp_xfer);
  1344. pktin = sftp_recv();
  1345. ret = xfer_download_gotpkt(scp_sftp_xfer, pktin);
  1346. if (ret <= 0) {
  1347. tell_user(stderr, "pscp: error while reading: %s", fxp_error());
  1348. if (ret == INT_MIN) /* pktin not even freed */
  1349. sfree(pktin);
  1350. errs++;
  1351. return -1;
  1352. }
  1353. if (xfer_download_data(scp_sftp_xfer, &vbuf, &actuallen)) {
  1354. if (actuallen <= 0) {
  1355. tell_user(stderr, "pscp: end of file while reading");
  1356. errs++;
  1357. sfree(vbuf);
  1358. return -1;
  1359. }
  1360. /*
  1361. * This assertion relies on the fact that the natural
  1362. * block size used in the xfer manager is at most that
  1363. * used in this module. I don't like crossing layers in
  1364. * this way, but it'll do for now.
  1365. */
  1366. assert(actuallen <= len);
  1367. memcpy(data, vbuf, actuallen);
  1368. sfree(vbuf);
  1369. } else
  1370. actuallen = 0;
  1371. scp_sftp_fileoffset += actuallen;
  1372. return actuallen;
  1373. } else {
  1374. return ssh_scp_recv(data, len) ? len : 0;
  1375. }
  1376. }
  1377. int scp_finish_filerecv(void)
  1378. {
  1379. if (using_sftp) {
  1380. struct sftp_packet *pktin;
  1381. struct sftp_request *req;
  1382. /*
  1383. * Ensure that xfer_done() will work correctly, so we can
  1384. * clean up any outstanding requests from the file
  1385. * transfer.
  1386. */
  1387. xfer_set_error(scp_sftp_xfer);
  1388. while (!xfer_done(scp_sftp_xfer)) {
  1389. void *vbuf;
  1390. int ret, len;
  1391. pktin = sftp_recv();
  1392. ret = xfer_download_gotpkt(scp_sftp_xfer, pktin);
  1393. if (ret <= 0) {
  1394. tell_user(stderr, "pscp: error while reading: %s", fxp_error());
  1395. if (ret == INT_MIN) /* pktin not even freed */
  1396. sfree(pktin);
  1397. errs++;
  1398. return -1;
  1399. }
  1400. if (xfer_download_data(scp_sftp_xfer, &vbuf, &len))
  1401. sfree(vbuf);
  1402. }
  1403. xfer_cleanup(scp_sftp_xfer);
  1404. req = fxp_close_send(scp_sftp_filehandle);
  1405. pktin = sftp_wait_for_reply(req);
  1406. fxp_close_recv(pktin, req);
  1407. return 0;
  1408. } else {
  1409. backend_send(backend, "", 1);
  1410. return response();
  1411. }
  1412. }
  1413. /* ----------------------------------------------------------------------
  1414. * Send an error message to the other side and to the screen.
  1415. * Increment error counter.
  1416. */
  1417. static PRINTF_LIKE(1, 2) void run_err(const char *fmt, ...)
  1418. {
  1419. char *str, *str2;
  1420. va_list ap;
  1421. va_start(ap, fmt);
  1422. errs++;
  1423. str = dupvprintf(fmt, ap);
  1424. str2 = dupcat("pscp: ", str, "\n");
  1425. sfree(str);
  1426. scp_send_errmsg(str2);
  1427. abandon_stats();
  1428. tell_user(stderr, "%s", str2);
  1429. va_end(ap);
  1430. sfree(str2);
  1431. }
  1432. /*
  1433. * Execute the source part of the SCP protocol.
  1434. */
  1435. static void source(const char *src)
  1436. {
  1437. uint64_t size;
  1438. unsigned long mtime, atime;
  1439. long permissions;
  1440. const char *last;
  1441. RFile *f;
  1442. int attr;
  1443. uint64_t i;
  1444. uint64_t stat_bytes;
  1445. time_t stat_starttime, stat_lasttime;
  1446. attr = file_type(src);
  1447. if (attr == FILE_TYPE_NONEXISTENT ||
  1448. attr == FILE_TYPE_WEIRD) {
  1449. run_err("%s: %s file or directory", src,
  1450. (attr == FILE_TYPE_WEIRD ? "Not a" : "No such"));
  1451. return;
  1452. }
  1453. if (attr == FILE_TYPE_DIRECTORY) {
  1454. if (recursive) {
  1455. /*
  1456. * Avoid . and .. directories.
  1457. */
  1458. const char *p;
  1459. p = strrchr(src, '/');
  1460. if (!p)
  1461. p = strrchr(src, '\\');
  1462. if (!p)
  1463. p = src;
  1464. else
  1465. p++;
  1466. if (!strcmp(p, ".") || !strcmp(p, ".."))
  1467. /* skip . and .. */ ;
  1468. else
  1469. rsource(src);
  1470. } else {
  1471. run_err("%s: not a regular file", src);
  1472. }
  1473. return;
  1474. }
  1475. if ((last = strrchr(src, '/')) == NULL)
  1476. last = src;
  1477. else
  1478. last++;
  1479. if (strrchr(last, '\\') != NULL)
  1480. last = strrchr(last, '\\') + 1;
  1481. if (last == src && strchr(src, ':') != NULL)
  1482. last = strchr(src, ':') + 1;
  1483. f = open_existing_file(src, &size, &mtime, &atime, &permissions);
  1484. if (f == NULL) {
  1485. run_err("%s: Cannot open file", src);
  1486. return;
  1487. }
  1488. if (preserve) {
  1489. if (scp_send_filetimes(mtime, atime)) {
  1490. close_rfile(f);
  1491. return;
  1492. }
  1493. }
  1494. if (verbose) {
  1495. tell_user(stderr, "Sending file %s, size=%"PRIu64, last, size);
  1496. }
  1497. if (scp_send_filename(last, size, permissions)) {
  1498. close_rfile(f);
  1499. return;
  1500. }
  1501. stat_bytes = 0;
  1502. stat_starttime = time(NULL);
  1503. stat_lasttime = 0;
  1504. #define PSCP_SEND_BLOCK 4096
  1505. for (i = 0; i < size; i += PSCP_SEND_BLOCK) {
  1506. char transbuf[PSCP_SEND_BLOCK];
  1507. int j, k = PSCP_SEND_BLOCK;
  1508. if (i + k > size)
  1509. k = size - i;
  1510. if ((j = read_from_file(f, transbuf, k)) != k) {
  1511. bump("%s: Read error", src);
  1512. }
  1513. if (scp_send_filedata(transbuf, k))
  1514. bump("%s: Network error occurred", src);
  1515. if (statistics) {
  1516. stat_bytes += k;
  1517. if (time(NULL) != stat_lasttime || i + k == size) {
  1518. stat_lasttime = time(NULL);
  1519. print_stats(last, size, stat_bytes,
  1520. stat_starttime, stat_lasttime);
  1521. }
  1522. }
  1523. }
  1524. close_rfile(f);
  1525. (void) scp_send_finish();
  1526. }
  1527. /*
  1528. * Recursively send the contents of a directory.
  1529. */
  1530. static void rsource(const char *src)
  1531. {
  1532. const char *last;
  1533. char *save_target;
  1534. DirHandle *dir;
  1535. if ((last = strrchr(src, '/')) == NULL)
  1536. last = src;
  1537. else
  1538. last++;
  1539. if (strrchr(last, '\\') != NULL)
  1540. last = strrchr(last, '\\') + 1;
  1541. if (last == src && strchr(src, ':') != NULL)
  1542. last = strchr(src, ':') + 1;
  1543. /* maybe send filetime */
  1544. save_target = scp_save_remotepath();
  1545. if (verbose)
  1546. tell_user(stderr, "Entering directory: %s", last);
  1547. if (scp_send_dirname(last, 0755))
  1548. return;
  1549. const char *opendir_err;
  1550. dir = open_directory(src, &opendir_err);
  1551. if (dir != NULL) {
  1552. char *filename;
  1553. while ((filename = read_filename(dir)) != NULL) {
  1554. char *foundfile = dupcat(src, "/", filename);
  1555. source(foundfile);
  1556. sfree(foundfile);
  1557. sfree(filename);
  1558. }
  1559. close_directory(dir);
  1560. } else {
  1561. tell_user(stderr, "Error opening directory %s: %s", src, opendir_err);
  1562. }
  1563. (void) scp_send_enddir();
  1564. scp_restore_remotepath(save_target);
  1565. }
  1566. /*
  1567. * Execute the sink part of the SCP protocol.
  1568. */
  1569. static void sink(const char *targ, const char *src)
  1570. {
  1571. char *destfname;
  1572. bool targisdir = false;
  1573. bool exists;
  1574. int attr;
  1575. WFile *f;
  1576. uint64_t received;
  1577. bool wrerror = false;
  1578. uint64_t stat_bytes;
  1579. time_t stat_starttime, stat_lasttime;
  1580. char *stat_name;
  1581. attr = file_type(targ);
  1582. if (attr == FILE_TYPE_DIRECTORY)
  1583. targisdir = true;
  1584. if (targetshouldbedirectory && !targisdir)
  1585. bump("%s: Not a directory", targ);
  1586. scp_sink_init();
  1587. struct scp_sink_action act;
  1588. act.buf = strbuf_new();
  1589. while (1) {
  1590. if (scp_get_sink_action(&act))
  1591. goto out;
  1592. if (act.action == SCP_SINK_ENDDIR)
  1593. goto out;
  1594. if (act.action == SCP_SINK_RETRY)
  1595. continue;
  1596. if (targisdir) {
  1597. /*
  1598. * Prevent the remote side from maliciously writing to
  1599. * files outside the target area by sending a filename
  1600. * containing `../'. In fact, it shouldn't be sending
  1601. * filenames with any slashes or colons in at all; so
  1602. * we'll find the last slash, backslash or colon in the
  1603. * filename and use only the part after that. (And
  1604. * warn!)
  1605. *
  1606. * In addition, we also ensure here that if we're
  1607. * copying a single file and the target is a directory
  1608. * (common usage: `pscp host:filename .') the remote
  1609. * can't send us a _different_ file name. We can
  1610. * distinguish this case because `src' will be non-NULL
  1611. * and the last component of that will fail to match
  1612. * (the last component of) the name sent.
  1613. *
  1614. * Well, not always; if `src' is a wildcard, we do
  1615. * expect to get back filenames that don't correspond
  1616. * exactly to it. Ideally in this case, we would like
  1617. * to ensure that the returned filename actually
  1618. * matches the wildcard pattern - but one of SCP's
  1619. * protocol infelicities is that wildcard matching is
  1620. * done at the server end _by the server's rules_ and
  1621. * so in general this is infeasible. Hence, we only
  1622. * accept filenames that don't correspond to `src' if
  1623. * unsafe mode is enabled or we are using SFTP (which
  1624. * resolves remote wildcards on the client side and can
  1625. * be trusted).
  1626. */
  1627. char *striptarget, *stripsrc;
  1628. striptarget = stripslashes(act.name, true);
  1629. if (striptarget != act.name) {
  1630. with_stripctrl(sanname, act.name) {
  1631. with_stripctrl(santarg, striptarget) {
  1632. tell_user(stderr, "warning: remote host sent a"
  1633. " compound pathname '%s'", sanname);
  1634. tell_user(stderr, " renaming local"
  1635. " file to '%s'", santarg);
  1636. }
  1637. }
  1638. }
  1639. /*
  1640. * Also check to see if the target filename is '.' or
  1641. * '..', or indeed '...' and so on because Windows
  1642. * appears to interpret those like '..'.
  1643. */
  1644. if (is_dots(striptarget)) {
  1645. bump("security violation: remote host attempted to write to"
  1646. " a '.' or '..' path!");
  1647. }
  1648. if (src) {
  1649. stripsrc = stripslashes(src, true);
  1650. if (strcmp(striptarget, stripsrc) &&
  1651. !using_sftp && !scp_unsafe_mode) {
  1652. with_stripctrl(san, striptarget)
  1653. tell_user(stderr, "warning: remote host tried to "
  1654. "write to a file called '%s'", san);
  1655. tell_user(stderr, " when we requested a file "
  1656. "called '%s'.", stripsrc);
  1657. tell_user(stderr, " If this is a wildcard, "
  1658. "consider upgrading to SSH-2 or using");
  1659. tell_user(stderr, " the '-unsafe' option. Renaming"
  1660. " of this file has been disallowed.");
  1661. /* Override the name the server provided with our own. */
  1662. striptarget = stripsrc;
  1663. }
  1664. }
  1665. if (targ[0] != '\0')
  1666. destfname = dir_file_cat(targ, striptarget);
  1667. else
  1668. destfname = dupstr(striptarget);
  1669. } else {
  1670. /*
  1671. * In this branch of the if, the target area is a
  1672. * single file with an explicitly specified name in any
  1673. * case, so there's no danger.
  1674. */
  1675. destfname = dupstr(targ);
  1676. }
  1677. attr = file_type(destfname);
  1678. exists = (attr != FILE_TYPE_NONEXISTENT);
  1679. if (act.action == SCP_SINK_DIR) {
  1680. if (exists && attr != FILE_TYPE_DIRECTORY) {
  1681. with_stripctrl(san, destfname)
  1682. run_err("%s: Not a directory", san);
  1683. sfree(destfname);
  1684. continue;
  1685. }
  1686. if (!exists) {
  1687. if (!create_directory(destfname)) {
  1688. with_stripctrl(san, destfname)
  1689. run_err("%s: Cannot create directory", san);
  1690. sfree(destfname);
  1691. continue;
  1692. }
  1693. }
  1694. sink(destfname, NULL);
  1695. /* can we set the timestamp for directories ? */
  1696. sfree(destfname);
  1697. continue;
  1698. }
  1699. f = open_new_file(destfname, act.permissions);
  1700. if (f == NULL) {
  1701. with_stripctrl(san, destfname)
  1702. run_err("%s: Cannot create file", san);
  1703. sfree(destfname);
  1704. continue;
  1705. }
  1706. if (scp_accept_filexfer()) {
  1707. sfree(destfname);
  1708. close_wfile(f);
  1709. goto out;
  1710. }
  1711. stat_bytes = 0;
  1712. stat_starttime = time(NULL);
  1713. stat_lasttime = 0;
  1714. stat_name = stripctrl_string(
  1715. string_scc, stripslashes(destfname, true));
  1716. received = 0;
  1717. while (received < act.size) {
  1718. char transbuf[32768];
  1719. uint64_t blksize;
  1720. int read;
  1721. blksize = 32768;
  1722. if (blksize > act.size - received)
  1723. blksize = act.size - received;
  1724. read = scp_recv_filedata(transbuf, (int)blksize);
  1725. if (read <= 0)
  1726. bump("Lost connection");
  1727. if (wrerror) {
  1728. received += read;
  1729. continue;
  1730. }
  1731. if (write_to_file(f, transbuf, read) != (int)read) {
  1732. wrerror = true;
  1733. /* FIXME: in sftp we can actually abort the transfer */
  1734. if (statistics)
  1735. printf("\r%-25.25s | %50s\n",
  1736. stat_name,
  1737. "Write error.. waiting for end of file");
  1738. received += read;
  1739. continue;
  1740. }
  1741. if (statistics) {
  1742. stat_bytes += read;
  1743. if (time(NULL) > stat_lasttime ||
  1744. received + read == act.size) {
  1745. stat_lasttime = time(NULL);
  1746. print_stats(stat_name, act.size, stat_bytes,
  1747. stat_starttime, stat_lasttime);
  1748. }
  1749. }
  1750. received += read;
  1751. }
  1752. if (act.settime) {
  1753. set_file_times(f, act.mtime, act.atime);
  1754. }
  1755. close_wfile(f);
  1756. if (wrerror) {
  1757. with_stripctrl(san, destfname)
  1758. run_err("%s: Write error", san);
  1759. sfree(destfname);
  1760. continue;
  1761. }
  1762. (void) scp_finish_filerecv();
  1763. sfree(stat_name);
  1764. sfree(destfname);
  1765. }
  1766. out:
  1767. strbuf_free(act.buf);
  1768. }
  1769. /*
  1770. * We will copy local files to a remote server.
  1771. */
  1772. static void toremote(int argc, char *argv[])
  1773. {
  1774. char *src, *wtarg, *host, *user;
  1775. const char *targ;
  1776. char *cmd;
  1777. int i, wc_type;
  1778. uploading = true;
  1779. wtarg = argv[argc - 1];
  1780. /* Separate host from filename */
  1781. host = wtarg;
  1782. wtarg = colon(wtarg);
  1783. if (wtarg == NULL)
  1784. bump("wtarg == NULL in toremote()");
  1785. *wtarg++ = '\0';
  1786. /* Substitute "." for empty target */
  1787. if (*wtarg == '\0')
  1788. targ = ".";
  1789. else
  1790. targ = wtarg;
  1791. /* Separate host and username */
  1792. user = host;
  1793. host = strrchr(host, '@');
  1794. if (host == NULL) {
  1795. host = user;
  1796. user = NULL;
  1797. } else {
  1798. *host++ = '\0';
  1799. if (*user == '\0')
  1800. user = NULL;
  1801. }
  1802. if (argc == 2) {
  1803. if (colon(argv[0]) != NULL)
  1804. bump("%s: Remote to remote not supported", argv[0]);
  1805. wc_type = test_wildcard(argv[0], true);
  1806. if (wc_type == WCTYPE_NONEXISTENT)
  1807. bump("%s: No such file or directory\n", argv[0]);
  1808. else if (wc_type == WCTYPE_WILDCARD)
  1809. targetshouldbedirectory = true;
  1810. }
  1811. cmd = dupprintf("scp%s%s%s%s -t %s",
  1812. verbose ? " -v" : "",
  1813. recursive ? " -r" : "",
  1814. preserve ? " -p" : "",
  1815. targetshouldbedirectory ? " -d" : "", targ);
  1816. do_cmd(host, user, cmd);
  1817. sfree(cmd);
  1818. if (scp_source_setup(targ, targetshouldbedirectory))
  1819. return;
  1820. for (i = 0; i < argc - 1; i++) {
  1821. src = argv[i];
  1822. if (colon(src) != NULL) {
  1823. tell_user(stderr, "%s: Remote to remote not supported\n", src);
  1824. errs++;
  1825. continue;
  1826. }
  1827. wc_type = test_wildcard(src, true);
  1828. if (wc_type == WCTYPE_NONEXISTENT) {
  1829. run_err("%s: No such file or directory", src);
  1830. continue;
  1831. } else if (wc_type == WCTYPE_FILENAME) {
  1832. source(src);
  1833. continue;
  1834. } else {
  1835. WildcardMatcher *wc;
  1836. char *filename;
  1837. wc = begin_wildcard_matching(src);
  1838. if (wc == NULL) {
  1839. run_err("%s: No such file or directory", src);
  1840. continue;
  1841. }
  1842. while ((filename = wildcard_get_filename(wc)) != NULL) {
  1843. source(filename);
  1844. sfree(filename);
  1845. }
  1846. finish_wildcard_matching(wc);
  1847. }
  1848. }
  1849. }
  1850. /*
  1851. * We will copy files from a remote server to the local machine.
  1852. */
  1853. static void tolocal(int argc, char *argv[])
  1854. {
  1855. char *wsrc, *host, *user;
  1856. const char *src, *targ;
  1857. char *cmd;
  1858. uploading = false;
  1859. if (argc != 2)
  1860. bump("More than one remote source not supported");
  1861. wsrc = argv[0];
  1862. targ = argv[1];
  1863. /* Separate host from filename */
  1864. host = wsrc;
  1865. wsrc = colon(wsrc);
  1866. if (wsrc == NULL)
  1867. bump("Local to local copy not supported");
  1868. *wsrc++ = '\0';
  1869. /* Substitute "." for empty filename */
  1870. if (*wsrc == '\0')
  1871. src = ".";
  1872. else
  1873. src = wsrc;
  1874. /* Separate username and hostname */
  1875. user = host;
  1876. host = strrchr(host, '@');
  1877. if (host == NULL) {
  1878. host = user;
  1879. user = NULL;
  1880. } else {
  1881. *host++ = '\0';
  1882. if (*user == '\0')
  1883. user = NULL;
  1884. }
  1885. cmd = dupprintf("scp%s%s%s%s -f %s",
  1886. verbose ? " -v" : "",
  1887. recursive ? " -r" : "",
  1888. preserve ? " -p" : "",
  1889. targetshouldbedirectory ? " -d" : "", src);
  1890. do_cmd(host, user, cmd);
  1891. sfree(cmd);
  1892. if (scp_sink_setup(src, preserve, recursive))
  1893. return;
  1894. sink(targ, src);
  1895. }
  1896. /*
  1897. * We will issue a list command to get a remote directory.
  1898. */
  1899. static void get_dir_list(int argc, char *argv[])
  1900. {
  1901. char *wsrc, *host, *user;
  1902. const char *src;
  1903. char *cmd, *p;
  1904. const char *q;
  1905. char c;
  1906. wsrc = argv[0];
  1907. /* Separate host from filename */
  1908. host = wsrc;
  1909. wsrc = colon(wsrc);
  1910. if (wsrc == NULL)
  1911. bump("Local file listing not supported");
  1912. *wsrc++ = '\0';
  1913. /* Substitute "." for empty filename */
  1914. if (*wsrc == '\0')
  1915. src = ".";
  1916. else
  1917. src = wsrc;
  1918. /* Separate username and hostname */
  1919. user = host;
  1920. host = strrchr(host, '@');
  1921. if (host == NULL) {
  1922. host = user;
  1923. user = NULL;
  1924. } else {
  1925. *host++ = '\0';
  1926. if (*user == '\0')
  1927. user = NULL;
  1928. }
  1929. cmd = snewn(4 * strlen(src) + 100, char);
  1930. strcpy(cmd, "ls -la '");
  1931. p = cmd + strlen(cmd);
  1932. for (q = src; *q; q++) {
  1933. if (*q == '\'') {
  1934. *p++ = '\'';
  1935. *p++ = '\\';
  1936. *p++ = '\'';
  1937. *p++ = '\'';
  1938. } else {
  1939. *p++ = *q;
  1940. }
  1941. }
  1942. *p++ = '\'';
  1943. *p = '\0';
  1944. do_cmd(host, user, cmd);
  1945. sfree(cmd);
  1946. if (using_sftp) {
  1947. scp_sftp_listdir(src);
  1948. } else {
  1949. stdio_sink ss;
  1950. stdio_sink_init(&ss, stdout);
  1951. StripCtrlChars *scc = stripctrl_new(
  1952. BinarySink_UPCAST(&ss), false, L'\0');
  1953. while (ssh_scp_recv(&c, 1))
  1954. put_byte(scc, c);
  1955. stripctrl_free(scc);
  1956. }
  1957. }
  1958. /*
  1959. * Short description of parameters.
  1960. */
  1961. static void usage(void)
  1962. {
  1963. printf("PuTTY Secure Copy client\n");
  1964. printf("%s\n", ver);
  1965. printf("Usage: pscp [options] [user@]host:source target\n");
  1966. printf(" pscp [options] source [source...] [user@]host:target\n");
  1967. printf(" pscp [options] -ls [user@]host:filespec\n");
  1968. printf("Options:\n");
  1969. printf(" -V print version information and exit\n");
  1970. printf(" -pgpfp print PGP key fingerprints and exit\n");
  1971. printf(" -p preserve file attributes\n");
  1972. printf(" -q quiet, don't show statistics\n");
  1973. printf(" -r copy directories recursively\n");
  1974. printf(" -v show verbose messages\n");
  1975. printf(" -load sessname Load settings from saved session\n");
  1976. printf(" -P port connect to specified port\n");
  1977. printf(" -l user connect with specified username\n");
  1978. printf(" -pwfile file login with password read from specified file\n");
  1979. printf(" -1 -2 force use of particular SSH protocol version\n");
  1980. printf(" -ssh -ssh-connection\n");
  1981. printf(" force use of particular SSH protocol variant\n");
  1982. printf(" -4 -6 force use of IPv4 or IPv6\n");
  1983. printf(" -C enable compression\n");
  1984. printf(" -i key private key file for user authentication\n");
  1985. printf(" -noagent disable use of Pageant\n");
  1986. printf(" -agent enable use of Pageant\n");
  1987. printf(" -no-trivial-auth\n");
  1988. printf(" disconnect if SSH authentication succeeds trivially\n");
  1989. printf(" -hostkey keyid\n");
  1990. printf(" manually specify a host key (may be repeated)\n");
  1991. printf(" -batch disable all interactive prompts\n");
  1992. printf(" -no-sanitise-stderr don't strip control chars from"
  1993. " standard error\n");
  1994. printf(" -proxycmd command\n");
  1995. printf(" use 'command' as local proxy\n");
  1996. printf(" -unsafe allow server-side wildcards (DANGEROUS)\n");
  1997. printf(" -sftp force use of SFTP protocol\n");
  1998. printf(" -scp force use of SCP protocol\n");
  1999. printf(" -sshlog file\n");
  2000. printf(" -sshrawlog file\n");
  2001. printf(" log protocol details to a file\n");
  2002. printf(" -logoverwrite\n");
  2003. printf(" -logappend\n");
  2004. printf(" control what happens when a log file already exists\n");
  2005. cleanup_exit(1);
  2006. }
  2007. void version(void)
  2008. {
  2009. char *buildinfo_text = buildinfo("\n");
  2010. printf("pscp: %s\n%s\n", ver, buildinfo_text);
  2011. sfree(buildinfo_text);
  2012. exit(0);
  2013. }
  2014. void cmdline_error(const char *p, ...)
  2015. {
  2016. va_list ap;
  2017. fprintf(stderr, "pscp: ");
  2018. va_start(ap, p);
  2019. vfprintf(stderr, p, ap);
  2020. va_end(ap);
  2021. fprintf(stderr, "\n try typing just \"pscp\" for help\n");
  2022. exit(1);
  2023. }
  2024. const bool share_can_be_downstream = true;
  2025. const bool share_can_be_upstream = false;
  2026. static stdio_sink stderr_ss;
  2027. static StripCtrlChars *stderr_scc;
  2028. const unsigned cmdline_tooltype = TOOLTYPE_FILETRANSFER;
  2029. /*
  2030. * Main program. (Called `psftp_main' because it gets called from
  2031. * *sftp.c; bit silly, I know, but it had to be called _something_.)
  2032. */
  2033. int psftp_main(int argc, char *argv[])
  2034. {
  2035. int i;
  2036. bool sanitise_stderr = true;
  2037. sk_init();
  2038. /* Load Default Settings before doing anything else. */
  2039. conf = conf_new();
  2040. do_defaults(NULL, conf);
  2041. for (i = 1; i < argc; i++) {
  2042. int ret;
  2043. if (argv[i][0] != '-')
  2044. break;
  2045. ret = cmdline_process_param(argv[i], i+1<argc?argv[i+1]:NULL, 1, conf);
  2046. if (ret == -2) {
  2047. cmdline_error("option \"%s\" requires an argument", argv[i]);
  2048. } else if (ret == 2) {
  2049. i++; /* skip next argument */
  2050. } else if (ret == 1) {
  2051. /* We have our own verbosity in addition to `flags'. */
  2052. if (cmdline_verbose())
  2053. verbose = true;
  2054. } else if (strcmp(argv[i], "-pgpfp") == 0) {
  2055. pgp_fingerprints();
  2056. return 1;
  2057. } else if (strcmp(argv[i], "-r") == 0) {
  2058. recursive = true;
  2059. } else if (strcmp(argv[i], "-p") == 0) {
  2060. preserve = true;
  2061. } else if (strcmp(argv[i], "-q") == 0) {
  2062. statistics = false;
  2063. } else if (strcmp(argv[i], "-h") == 0 ||
  2064. strcmp(argv[i], "-?") == 0 ||
  2065. strcmp(argv[i], "--help") == 0) {
  2066. usage();
  2067. } else if (strcmp(argv[i], "-V") == 0 ||
  2068. strcmp(argv[i], "--version") == 0) {
  2069. version();
  2070. } else if (strcmp(argv[i], "-ls") == 0) {
  2071. list = true;
  2072. } else if (strcmp(argv[i], "-batch") == 0) {
  2073. console_batch_mode = true;
  2074. } else if (strcmp(argv[i], "-unsafe") == 0) {
  2075. scp_unsafe_mode = true;
  2076. } else if (strcmp(argv[i], "-sftp") == 0) {
  2077. try_scp = false; try_sftp = true;
  2078. } else if (strcmp(argv[i], "-scp") == 0) {
  2079. try_scp = true; try_sftp = false;
  2080. } else if (strcmp(argv[i], "-sanitise-stderr") == 0) {
  2081. sanitise_stderr = true;
  2082. } else if (strcmp(argv[i], "-no-sanitise-stderr") == 0) {
  2083. sanitise_stderr = false;
  2084. } else if (strcmp(argv[i], "--") == 0) {
  2085. i++;
  2086. break;
  2087. } else {
  2088. cmdline_error("unknown option \"%s\"", argv[i]);
  2089. }
  2090. }
  2091. argc -= i;
  2092. argv += i;
  2093. backend = NULL;
  2094. stdio_sink_init(&stderr_ss, stderr);
  2095. stderr_bs = BinarySink_UPCAST(&stderr_ss);
  2096. if (sanitise_stderr) {
  2097. stderr_scc = stripctrl_new(stderr_bs, false, L'\0');
  2098. stderr_bs = BinarySink_UPCAST(stderr_scc);
  2099. }
  2100. string_scc = stripctrl_new(NULL, false, L'\0');
  2101. if (list) {
  2102. if (argc != 1)
  2103. usage();
  2104. get_dir_list(argc, argv);
  2105. } else {
  2106. if (argc < 2)
  2107. usage();
  2108. if (argc > 2)
  2109. targetshouldbedirectory = true;
  2110. if (colon(argv[argc - 1]) != NULL)
  2111. toremote(argc, argv);
  2112. else
  2113. tolocal(argc, argv);
  2114. }
  2115. if (backend && backend_connected(backend)) {
  2116. char ch;
  2117. backend_special(backend, SS_EOF, 0);
  2118. sent_eof = true;
  2119. ssh_scp_recv(&ch, 1);
  2120. }
  2121. random_save_seed();
  2122. cmdline_cleanup();
  2123. if (backend) {
  2124. backend_free(backend);
  2125. backend = NULL;
  2126. }
  2127. sk_cleanup();
  2128. return (errs == 0 ? 0 : 1);
  2129. }
  2130. /* end */