pscp.c 73 KB

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