pscp.c 72 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367
  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(conf, CONF_username)[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. static char *colon(char *str)
  485. {
  486. /* We ignore a leading colon, since the hostname cannot be
  487. empty. We also ignore a colon as second character because
  488. of filenames like f:myfile.txt. */
  489. if (str[0] == '\0' || str[0] == ':' ||
  490. (str[0] != '[' && str[1] == ':'))
  491. return (NULL);
  492. str += host_strcspn(str, ":/\\");
  493. if (*str == ':')
  494. return (str);
  495. else
  496. return (NULL);
  497. }
  498. /*
  499. * Determine whether a string is entirely composed of dots.
  500. */
  501. static bool is_dots(char *str)
  502. {
  503. return str[strspn(str, ".")] == '\0';
  504. }
  505. /*
  506. * Wait for a response from the other side.
  507. * Return 0 if ok, -1 if error.
  508. */
  509. static int response(void)
  510. {
  511. char ch, resp, rbuf[2048];
  512. int p;
  513. if (!ssh_scp_recv(&resp, 1))
  514. bump("Lost connection");
  515. p = 0;
  516. switch (resp) {
  517. case 0: /* ok */
  518. return (0);
  519. default:
  520. rbuf[p++] = resp;
  521. /* fallthrough */
  522. case 1: /* error */
  523. case 2: /* fatal error */
  524. do {
  525. if (!ssh_scp_recv(&ch, 1))
  526. bump("Protocol error: Lost connection");
  527. rbuf[p++] = ch;
  528. } while (p < sizeof(rbuf) && ch != '\n');
  529. rbuf[p - 1] = '\0';
  530. if (resp == 1)
  531. tell_user(stderr, "%s", rbuf);
  532. else
  533. bump("%s", rbuf);
  534. errs++;
  535. return (-1);
  536. }
  537. }
  538. bool sftp_recvdata(char *buf, size_t len)
  539. {
  540. return ssh_scp_recv(buf, len);
  541. }
  542. bool sftp_senddata(const char *buf, size_t len)
  543. {
  544. backend_send(backend, buf, len);
  545. return true;
  546. }
  547. size_t sftp_sendbuffer(void)
  548. {
  549. return backend_sendbuffer(backend);
  550. }
  551. /* ----------------------------------------------------------------------
  552. * sftp-based replacement for the hacky `pscp -ls'.
  553. */
  554. void list_directory_from_sftp_warn_unsorted(void)
  555. {
  556. fprintf(stderr,
  557. "Directory is too large to sort; writing file names unsorted\n");
  558. }
  559. void list_directory_from_sftp_print(struct fxp_name *name)
  560. {
  561. with_stripctrl(san, name->longname)
  562. printf("%s\n", san);
  563. }
  564. void scp_sftp_listdir(const char *dirname)
  565. {
  566. struct fxp_handle *dirh;
  567. struct fxp_names *names;
  568. struct sftp_packet *pktin;
  569. struct sftp_request *req;
  570. if (!fxp_init()) {
  571. tell_user(stderr, "unable to initialise SFTP: %s", fxp_error());
  572. errs++;
  573. return;
  574. }
  575. printf("Listing directory %s\n", dirname);
  576. req = fxp_opendir_send(dirname);
  577. pktin = sftp_wait_for_reply(req);
  578. dirh = fxp_opendir_recv(pktin, req);
  579. if (dirh == NULL) {
  580. tell_user(stderr, "Unable to open %s: %s\n", dirname, fxp_error());
  581. errs++;
  582. } else {
  583. struct list_directory_from_sftp_ctx *ctx =
  584. list_directory_from_sftp_new();
  585. while (1) {
  586. req = fxp_readdir_send(dirh);
  587. pktin = sftp_wait_for_reply(req);
  588. names = fxp_readdir_recv(pktin, req);
  589. if (names == NULL) {
  590. if (fxp_error_type() == SSH_FX_EOF)
  591. break;
  592. printf("Reading directory %s: %s\n", dirname, fxp_error());
  593. break;
  594. }
  595. if (names->nnames == 0) {
  596. fxp_free_names(names);
  597. break;
  598. }
  599. for (size_t i = 0; i < names->nnames; i++)
  600. list_directory_from_sftp_feed(ctx, &names->names[i]);
  601. fxp_free_names(names);
  602. }
  603. req = fxp_close_send(dirh);
  604. pktin = sftp_wait_for_reply(req);
  605. fxp_close_recv(pktin, req);
  606. list_directory_from_sftp_finish(ctx);
  607. list_directory_from_sftp_free(ctx);
  608. }
  609. }
  610. /* ----------------------------------------------------------------------
  611. * Helper routines that contain the actual SCP protocol elements,
  612. * implemented both as SCP1 and SFTP.
  613. */
  614. static struct scp_sftp_dirstack {
  615. struct scp_sftp_dirstack *next;
  616. struct fxp_name *names;
  617. int namepos, namelen;
  618. char *dirpath;
  619. char *wildcard;
  620. bool matched_something; /* wildcard match set was non-empty */
  621. } *scp_sftp_dirstack_head;
  622. static char *scp_sftp_remotepath, *scp_sftp_currentname;
  623. static char *scp_sftp_wildcard;
  624. static bool scp_sftp_targetisdir, scp_sftp_donethistarget;
  625. static bool scp_sftp_preserve, scp_sftp_recursive;
  626. static unsigned long scp_sftp_mtime, scp_sftp_atime;
  627. static bool scp_has_times;
  628. static struct fxp_handle *scp_sftp_filehandle;
  629. static struct fxp_xfer *scp_sftp_xfer;
  630. static uint64_t scp_sftp_fileoffset;
  631. int scp_source_setup(const char *target, bool shouldbedir)
  632. {
  633. if (using_sftp) {
  634. /*
  635. * Find out whether the target filespec is in fact a
  636. * directory.
  637. */
  638. struct sftp_packet *pktin;
  639. struct sftp_request *req;
  640. struct fxp_attrs attrs;
  641. bool ret;
  642. if (!fxp_init()) {
  643. tell_user(stderr, "unable to initialise SFTP: %s", fxp_error());
  644. errs++;
  645. return 1;
  646. }
  647. req = fxp_stat_send(target);
  648. pktin = sftp_wait_for_reply(req);
  649. ret = fxp_stat_recv(pktin, req, &attrs);
  650. if (!ret || !(attrs.flags & SSH_FILEXFER_ATTR_PERMISSIONS))
  651. scp_sftp_targetisdir = false;
  652. else
  653. scp_sftp_targetisdir = (attrs.permissions & 0040000) != 0;
  654. if (shouldbedir && !scp_sftp_targetisdir) {
  655. bump("pscp: remote filespec %s: not a directory\n", target);
  656. }
  657. scp_sftp_remotepath = dupstr(target);
  658. scp_has_times = false;
  659. } else {
  660. (void) response();
  661. }
  662. return 0;
  663. }
  664. int scp_send_errmsg(char *str)
  665. {
  666. if (using_sftp) {
  667. /* do nothing; we never need to send our errors to the server */
  668. } else {
  669. backend_send(backend, "\001", 1);/* scp protocol error prefix */
  670. backend_send(backend, str, strlen(str));
  671. }
  672. return 0; /* can't fail */
  673. }
  674. int scp_send_filetimes(unsigned long mtime, unsigned long atime)
  675. {
  676. if (using_sftp) {
  677. scp_sftp_mtime = mtime;
  678. scp_sftp_atime = atime;
  679. scp_has_times = true;
  680. return 0;
  681. } else {
  682. char buf[80];
  683. sprintf(buf, "T%lu 0 %lu 0\n", mtime, atime);
  684. backend_send(backend, buf, strlen(buf));
  685. return response();
  686. }
  687. }
  688. int scp_send_filename(const char *name, uint64_t size, int permissions)
  689. {
  690. if (using_sftp) {
  691. char *fullname;
  692. struct sftp_packet *pktin;
  693. struct sftp_request *req;
  694. struct fxp_attrs attrs;
  695. if (scp_sftp_targetisdir) {
  696. fullname = dupcat(scp_sftp_remotepath, "/", name);
  697. } else {
  698. fullname = dupstr(scp_sftp_remotepath);
  699. }
  700. attrs.flags = 0;
  701. PUT_PERMISSIONS(attrs, permissions);
  702. req = fxp_open_send(fullname,
  703. SSH_FXF_WRITE | SSH_FXF_CREAT | SSH_FXF_TRUNC,
  704. &attrs);
  705. pktin = sftp_wait_for_reply(req);
  706. scp_sftp_filehandle = fxp_open_recv(pktin, req);
  707. if (!scp_sftp_filehandle) {
  708. tell_user(stderr, "pscp: unable to open %s: %s",
  709. fullname, fxp_error());
  710. sfree(fullname);
  711. errs++;
  712. return 1;
  713. }
  714. scp_sftp_fileoffset = 0;
  715. scp_sftp_xfer = xfer_upload_init(scp_sftp_filehandle,
  716. scp_sftp_fileoffset);
  717. sfree(fullname);
  718. return 0;
  719. } else {
  720. char *buf;
  721. if (permissions < 0)
  722. permissions = 0644;
  723. buf = dupprintf("C%04o %"PRIu64" ", (int)(permissions & 07777), size);
  724. backend_send(backend, buf, strlen(buf));
  725. sfree(buf);
  726. backend_send(backend, name, strlen(name));
  727. backend_send(backend, "\n", 1);
  728. return response();
  729. }
  730. }
  731. int scp_send_filedata(char *data, int len)
  732. {
  733. if (using_sftp) {
  734. int ret;
  735. struct sftp_packet *pktin;
  736. if (!scp_sftp_filehandle) {
  737. return 1;
  738. }
  739. while (!xfer_upload_ready(scp_sftp_xfer)) {
  740. if (toplevel_callback_pending()) {
  741. /* If we have pending callbacks, they might make
  742. * xfer_upload_ready start to return true. So we should
  743. * run them and then re-check xfer_upload_ready, before
  744. * we go as far as waiting for an entire packet to
  745. * arrive. */
  746. run_toplevel_callbacks();
  747. continue;
  748. }
  749. pktin = sftp_recv();
  750. ret = xfer_upload_gotpkt(scp_sftp_xfer, pktin);
  751. if (ret <= 0) {
  752. tell_user(stderr, "error while writing: %s", fxp_error());
  753. if (ret == INT_MIN) /* pktin not even freed */
  754. sfree(pktin);
  755. errs++;
  756. return 1;
  757. }
  758. }
  759. xfer_upload_data(scp_sftp_xfer, data, len);
  760. scp_sftp_fileoffset += len;
  761. return 0;
  762. } else {
  763. backend_send(backend, data, len);
  764. int bufsize = backend_sendbuffer(backend);
  765. /*
  766. * If the network transfer is backing up - that is, the
  767. * remote site is not accepting data as fast as we can
  768. * produce it - then we must loop on network events until
  769. * we have space in the buffer again.
  770. */
  771. while (bufsize > MAX_SCP_BUFSIZE) {
  772. if (ssh_sftp_loop_iteration() < 0)
  773. return 1;
  774. bufsize = backend_sendbuffer(backend);
  775. }
  776. return 0;
  777. }
  778. }
  779. int scp_send_finish(void)
  780. {
  781. if (using_sftp) {
  782. struct fxp_attrs attrs;
  783. struct sftp_packet *pktin;
  784. struct sftp_request *req;
  785. while (!xfer_done(scp_sftp_xfer)) {
  786. pktin = sftp_recv();
  787. int ret = xfer_upload_gotpkt(scp_sftp_xfer, pktin);
  788. if (ret <= 0) {
  789. tell_user(stderr, "error while writing: %s", fxp_error());
  790. if (ret == INT_MIN) /* pktin not even freed */
  791. sfree(pktin);
  792. errs++;
  793. return 1;
  794. }
  795. }
  796. xfer_cleanup(scp_sftp_xfer);
  797. if (!scp_sftp_filehandle) {
  798. return 1;
  799. }
  800. if (scp_has_times) {
  801. attrs.flags = SSH_FILEXFER_ATTR_ACMODTIME;
  802. attrs.atime = scp_sftp_atime;
  803. attrs.mtime = scp_sftp_mtime;
  804. req = fxp_fsetstat_send(scp_sftp_filehandle, attrs);
  805. pktin = sftp_wait_for_reply(req);
  806. bool ret = fxp_fsetstat_recv(pktin, req);
  807. if (!ret) {
  808. tell_user(stderr, "unable to set file times: %s", fxp_error());
  809. errs++;
  810. }
  811. }
  812. req = fxp_close_send(scp_sftp_filehandle);
  813. pktin = sftp_wait_for_reply(req);
  814. fxp_close_recv(pktin, req);
  815. scp_has_times = false;
  816. return 0;
  817. } else {
  818. backend_send(backend, "", 1);
  819. return response();
  820. }
  821. }
  822. char *scp_save_remotepath(void)
  823. {
  824. if (using_sftp)
  825. return scp_sftp_remotepath;
  826. else
  827. return NULL;
  828. }
  829. void scp_restore_remotepath(char *data)
  830. {
  831. if (using_sftp)
  832. scp_sftp_remotepath = data;
  833. }
  834. int scp_send_dirname(const char *name, int modes)
  835. {
  836. if (using_sftp) {
  837. char *fullname;
  838. char const *err;
  839. struct fxp_attrs attrs;
  840. struct sftp_packet *pktin;
  841. struct sftp_request *req;
  842. bool ret;
  843. if (scp_sftp_targetisdir) {
  844. fullname = dupcat(scp_sftp_remotepath, "/", name);
  845. } else {
  846. fullname = dupstr(scp_sftp_remotepath);
  847. }
  848. /*
  849. * We don't worry about whether we managed to create the
  850. * directory, because if it exists already it's OK just to
  851. * use it. Instead, we will stat it afterwards, and if it
  852. * exists and is a directory we will assume we were either
  853. * successful or it didn't matter.
  854. */
  855. req = fxp_mkdir_send(fullname, NULL);
  856. pktin = sftp_wait_for_reply(req);
  857. ret = fxp_mkdir_recv(pktin, req);
  858. if (!ret)
  859. err = fxp_error();
  860. else
  861. err = "server reported no error";
  862. req = fxp_stat_send(fullname);
  863. pktin = sftp_wait_for_reply(req);
  864. ret = fxp_stat_recv(pktin, req, &attrs);
  865. if (!ret || !(attrs.flags & SSH_FILEXFER_ATTR_PERMISSIONS) ||
  866. !(attrs.permissions & 0040000)) {
  867. tell_user(stderr, "unable to create directory %s: %s",
  868. fullname, err);
  869. sfree(fullname);
  870. errs++;
  871. return 1;
  872. }
  873. scp_sftp_remotepath = fullname;
  874. return 0;
  875. } else {
  876. char buf[40];
  877. sprintf(buf, "D%04o 0 ", modes);
  878. backend_send(backend, buf, strlen(buf));
  879. backend_send(backend, name, strlen(name));
  880. backend_send(backend, "\n", 1);
  881. return response();
  882. }
  883. }
  884. int scp_send_enddir(void)
  885. {
  886. if (using_sftp) {
  887. sfree(scp_sftp_remotepath);
  888. return 0;
  889. } else {
  890. backend_send(backend, "E\n", 2);
  891. return response();
  892. }
  893. }
  894. /*
  895. * Yes, I know; I have an scp_sink_setup _and_ an scp_sink_init.
  896. * That's bad. The difference is that scp_sink_setup is called once
  897. * right at the start, whereas scp_sink_init is called to
  898. * initialise every level of recursion in the protocol.
  899. */
  900. int scp_sink_setup(const char *source, bool preserve, bool recursive)
  901. {
  902. if (using_sftp) {
  903. char *newsource;
  904. if (!fxp_init()) {
  905. tell_user(stderr, "unable to initialise SFTP: %s", fxp_error());
  906. errs++;
  907. return 1;
  908. }
  909. /*
  910. * It's possible that the source string we've been given
  911. * contains a wildcard. If so, we must split the directory
  912. * away from the wildcard itself (throwing an error if any
  913. * wildcardness comes before the final slash) and arrange
  914. * things so that a dirstack entry will be set up.
  915. */
  916. newsource = snewn(1+strlen(source), char);
  917. if (!wc_unescape(newsource, source)) {
  918. /* Yes, here we go; it's a wildcard. Bah. */
  919. char *dupsource, *lastpart, *dirpart, *wildcard;
  920. sfree(newsource);
  921. dupsource = dupstr(source);
  922. lastpart = stripslashes(dupsource, false);
  923. wildcard = dupstr(lastpart);
  924. *lastpart = '\0';
  925. if (*dupsource && dupsource[1]) {
  926. /*
  927. * The remains of dupsource are at least two
  928. * characters long, meaning the pathname wasn't
  929. * empty or just `/'. Hence, we remove the trailing
  930. * slash.
  931. */
  932. lastpart[-1] = '\0';
  933. } else if (!*dupsource) {
  934. /*
  935. * The remains of dupsource are _empty_ - the whole
  936. * pathname was a wildcard. Hence we need to
  937. * replace it with ".".
  938. */
  939. sfree(dupsource);
  940. dupsource = dupstr(".");
  941. }
  942. /*
  943. * Now we have separated our string into dupsource (the
  944. * directory part) and wildcard. Both of these will
  945. * need freeing at some point. Next step is to remove
  946. * wildcard escapes from the directory part, throwing
  947. * an error if it contains a real wildcard.
  948. */
  949. dirpart = snewn(1+strlen(dupsource), char);
  950. if (!wc_unescape(dirpart, dupsource)) {
  951. tell_user(stderr, "%s: multiple-level wildcards unsupported",
  952. source);
  953. errs++;
  954. sfree(dirpart);
  955. sfree(wildcard);
  956. sfree(dupsource);
  957. return 1;
  958. }
  959. /*
  960. * Now we have dirpart (unescaped, ie a valid remote
  961. * path), and wildcard (a wildcard). This will be
  962. * sufficient to arrange a dirstack entry.
  963. */
  964. scp_sftp_remotepath = dirpart;
  965. scp_sftp_wildcard = wildcard;
  966. sfree(dupsource);
  967. } else {
  968. scp_sftp_remotepath = newsource;
  969. scp_sftp_wildcard = NULL;
  970. }
  971. scp_sftp_preserve = preserve;
  972. scp_sftp_recursive = recursive;
  973. scp_sftp_donethistarget = false;
  974. scp_sftp_dirstack_head = NULL;
  975. }
  976. return 0;
  977. }
  978. int scp_sink_init(void)
  979. {
  980. if (!using_sftp) {
  981. backend_send(backend, "", 1);
  982. }
  983. return 0;
  984. }
  985. #define SCP_SINK_FILE 1
  986. #define SCP_SINK_DIR 2
  987. #define SCP_SINK_ENDDIR 3
  988. #define SCP_SINK_RETRY 4 /* not an action; just try again */
  989. struct scp_sink_action {
  990. int action; /* FILE, DIR, ENDDIR */
  991. strbuf *buf; /* will need freeing after use */
  992. char *name; /* filename or dirname (not ENDDIR) */
  993. long permissions; /* access permissions (not ENDDIR) */
  994. uint64_t size; /* file size (not ENDDIR) */
  995. bool settime; /* true if atime and mtime are filled */
  996. unsigned long atime, mtime; /* access times for the file */
  997. };
  998. int scp_get_sink_action(struct scp_sink_action *act)
  999. {
  1000. if (using_sftp) {
  1001. char *fname;
  1002. bool must_free_fname;
  1003. struct fxp_attrs attrs;
  1004. struct sftp_packet *pktin;
  1005. struct sftp_request *req;
  1006. bool ret;
  1007. if (!scp_sftp_dirstack_head) {
  1008. if (!scp_sftp_donethistarget) {
  1009. /*
  1010. * Simple case: we are only dealing with one file.
  1011. */
  1012. fname = scp_sftp_remotepath;
  1013. must_free_fname = false;
  1014. scp_sftp_donethistarget = true;
  1015. } else {
  1016. /*
  1017. * Even simpler case: one file _which we've done_.
  1018. * Return 1 (finished).
  1019. */
  1020. return 1;
  1021. }
  1022. } else {
  1023. /*
  1024. * We're now in the middle of stepping through a list
  1025. * of names returned from fxp_readdir(); so let's carry
  1026. * on.
  1027. */
  1028. struct scp_sftp_dirstack *head = scp_sftp_dirstack_head;
  1029. while (head->namepos < head->namelen &&
  1030. (is_dots(head->names[head->namepos].filename) ||
  1031. (head->wildcard &&
  1032. !wc_match(head->wildcard,
  1033. head->names[head->namepos].filename))))
  1034. head->namepos++; /* skip . and .. */
  1035. if (head->namepos < head->namelen) {
  1036. head->matched_something = true;
  1037. fname = dupcat(head->dirpath, "/",
  1038. head->names[head->namepos++].filename);
  1039. must_free_fname = true;
  1040. } else {
  1041. /*
  1042. * We've come to the end of the list; pop it off
  1043. * the stack and return an ENDDIR action (or RETRY
  1044. * if this was a wildcard match).
  1045. */
  1046. if (head->wildcard) {
  1047. act->action = SCP_SINK_RETRY;
  1048. if (!head->matched_something) {
  1049. tell_user(stderr, "pscp: wildcard '%s' matched "
  1050. "no files", head->wildcard);
  1051. errs++;
  1052. }
  1053. sfree(head->wildcard);
  1054. } else {
  1055. act->action = SCP_SINK_ENDDIR;
  1056. }
  1057. sfree(head->dirpath);
  1058. sfree(head->names);
  1059. scp_sftp_dirstack_head = head->next;
  1060. sfree(head);
  1061. return 0;
  1062. }
  1063. }
  1064. /*
  1065. * Now we have a filename. Stat it, and see if it's a file
  1066. * or a directory.
  1067. */
  1068. req = fxp_stat_send(fname);
  1069. pktin = sftp_wait_for_reply(req);
  1070. ret = fxp_stat_recv(pktin, req, &attrs);
  1071. if (!ret || !(attrs.flags & SSH_FILEXFER_ATTR_PERMISSIONS)) {
  1072. with_stripctrl(san, fname)
  1073. tell_user(stderr, "unable to identify %s: %s", san,
  1074. ret ? "file type not supplied" : fxp_error());
  1075. if (must_free_fname) sfree(fname);
  1076. errs++;
  1077. return 1;
  1078. }
  1079. if (attrs.permissions & 0040000) {
  1080. struct scp_sftp_dirstack *newitem;
  1081. struct fxp_handle *dirhandle;
  1082. size_t nnames, namesize;
  1083. struct fxp_name *ournames;
  1084. struct fxp_names *names;
  1085. /*
  1086. * It's a directory. If we're not in recursive mode,
  1087. * this merits a complaint (which is fatal if the name
  1088. * was specified directly, but not if it was matched by
  1089. * a wildcard).
  1090. *
  1091. * We skip this complaint completely if
  1092. * scp_sftp_wildcard is set, because that's an
  1093. * indication that we're not actually supposed to
  1094. * _recursively_ transfer the dir, just scan it for
  1095. * things matching the wildcard.
  1096. */
  1097. if (!scp_sftp_recursive && !scp_sftp_wildcard) {
  1098. with_stripctrl(san, fname)
  1099. tell_user(stderr, "pscp: %s: is a directory", san);
  1100. errs++;
  1101. if (must_free_fname) sfree(fname);
  1102. if (scp_sftp_dirstack_head) {
  1103. act->action = SCP_SINK_RETRY;
  1104. return 0;
  1105. } else {
  1106. return 1;
  1107. }
  1108. }
  1109. /*
  1110. * Otherwise, the fun begins. We must fxp_opendir() the
  1111. * directory, slurp the filenames into memory, return
  1112. * SCP_SINK_DIR (unless this is a wildcard match), and
  1113. * set targetisdir. The next time we're called, we will
  1114. * run through the list of filenames one by one,
  1115. * matching them against a wildcard if present.
  1116. *
  1117. * If targetisdir is _already_ set (meaning we're
  1118. * already in the middle of going through another such
  1119. * list), we must push the other (target,namelist) pair
  1120. * on a stack.
  1121. */
  1122. req = fxp_opendir_send(fname);
  1123. pktin = sftp_wait_for_reply(req);
  1124. dirhandle = fxp_opendir_recv(pktin, req);
  1125. if (!dirhandle) {
  1126. with_stripctrl(san, fname)
  1127. tell_user(stderr, "pscp: unable to open directory %s: %s",
  1128. san, fxp_error());
  1129. if (must_free_fname) sfree(fname);
  1130. errs++;
  1131. return 1;
  1132. }
  1133. nnames = namesize = 0;
  1134. ournames = NULL;
  1135. while (1) {
  1136. int i;
  1137. req = fxp_readdir_send(dirhandle);
  1138. pktin = sftp_wait_for_reply(req);
  1139. names = fxp_readdir_recv(pktin, req);
  1140. if (names == NULL) {
  1141. if (fxp_error_type() == SSH_FX_EOF)
  1142. break;
  1143. with_stripctrl(san, fname)
  1144. tell_user(stderr, "pscp: reading directory %s: %s",
  1145. san, fxp_error());
  1146. req = fxp_close_send(dirhandle);
  1147. pktin = sftp_wait_for_reply(req);
  1148. fxp_close_recv(pktin, req);
  1149. if (must_free_fname) sfree(fname);
  1150. sfree(ournames);
  1151. errs++;
  1152. return 1;
  1153. }
  1154. if (names->nnames == 0) {
  1155. fxp_free_names(names);
  1156. break;
  1157. }
  1158. sgrowarrayn(ournames, namesize, nnames, names->nnames);
  1159. for (i = 0; i < names->nnames; i++) {
  1160. if (!strcmp(names->names[i].filename, ".") ||
  1161. !strcmp(names->names[i].filename, "..")) {
  1162. /*
  1163. * . and .. are normal consequences of
  1164. * reading a directory, and aren't worth
  1165. * complaining about.
  1166. */
  1167. } else if (!vet_filename(names->names[i].filename)) {
  1168. with_stripctrl(san, names->names[i].filename)
  1169. tell_user(stderr, "ignoring potentially dangerous "
  1170. "server-supplied filename '%s'", san);
  1171. } else
  1172. ournames[nnames++] = names->names[i];
  1173. }
  1174. names->nnames = 0; /* prevent free_names */
  1175. fxp_free_names(names);
  1176. }
  1177. req = fxp_close_send(dirhandle);
  1178. pktin = sftp_wait_for_reply(req);
  1179. fxp_close_recv(pktin, req);
  1180. newitem = snew(struct scp_sftp_dirstack);
  1181. newitem->next = scp_sftp_dirstack_head;
  1182. newitem->names = ournames;
  1183. newitem->namepos = 0;
  1184. newitem->namelen = nnames;
  1185. if (must_free_fname)
  1186. newitem->dirpath = fname;
  1187. else
  1188. newitem->dirpath = dupstr(fname);
  1189. if (scp_sftp_wildcard) {
  1190. newitem->wildcard = scp_sftp_wildcard;
  1191. newitem->matched_something = false;
  1192. scp_sftp_wildcard = NULL;
  1193. } else {
  1194. newitem->wildcard = NULL;
  1195. }
  1196. scp_sftp_dirstack_head = newitem;
  1197. if (newitem->wildcard) {
  1198. act->action = SCP_SINK_RETRY;
  1199. } else {
  1200. act->action = SCP_SINK_DIR;
  1201. strbuf_clear(act->buf);
  1202. put_asciz(act->buf, stripslashes(fname, false));
  1203. act->name = act->buf->s;
  1204. act->size = 0; /* duhh, it's a directory */
  1205. act->permissions = 07777 & attrs.permissions;
  1206. if (scp_sftp_preserve &&
  1207. (attrs.flags & SSH_FILEXFER_ATTR_ACMODTIME)) {
  1208. act->atime = attrs.atime;
  1209. act->mtime = attrs.mtime;
  1210. act->settime = true;
  1211. } else
  1212. act->settime = false;
  1213. }
  1214. return 0;
  1215. } else {
  1216. /*
  1217. * It's a file. Return SCP_SINK_FILE.
  1218. */
  1219. act->action = SCP_SINK_FILE;
  1220. strbuf_clear(act->buf);
  1221. put_asciz(act->buf, stripslashes(fname, false));
  1222. act->name = act->buf->s;
  1223. if (attrs.flags & SSH_FILEXFER_ATTR_SIZE) {
  1224. act->size = attrs.size;
  1225. } else
  1226. act->size = UINT64_MAX; /* no idea */
  1227. act->permissions = 07777 & attrs.permissions;
  1228. if (scp_sftp_preserve &&
  1229. (attrs.flags & SSH_FILEXFER_ATTR_ACMODTIME)) {
  1230. act->atime = attrs.atime;
  1231. act->mtime = attrs.mtime;
  1232. act->settime = true;
  1233. } else
  1234. act->settime = false;
  1235. if (must_free_fname)
  1236. scp_sftp_currentname = fname;
  1237. else
  1238. scp_sftp_currentname = dupstr(fname);
  1239. return 0;
  1240. }
  1241. } else {
  1242. bool done = false;
  1243. int action;
  1244. char ch;
  1245. act->settime = false;
  1246. strbuf_clear(act->buf);
  1247. while (!done) {
  1248. if (!ssh_scp_recv(&ch, 1))
  1249. return 1;
  1250. if (ch == '\n')
  1251. bump("Protocol error: Unexpected newline");
  1252. action = ch;
  1253. while (1) {
  1254. if (!ssh_scp_recv(&ch, 1))
  1255. bump("Lost connection");
  1256. if (ch == '\n')
  1257. break;
  1258. put_byte(act->buf, ch);
  1259. }
  1260. switch (action) {
  1261. case '\01': /* error */
  1262. with_stripctrl(san, act->buf->s)
  1263. tell_user(stderr, "%s", san);
  1264. errs++;
  1265. continue; /* go round again */
  1266. case '\02': /* fatal error */
  1267. with_stripctrl(san, act->buf->s)
  1268. bump("%s", san);
  1269. case 'E':
  1270. backend_send(backend, "", 1);
  1271. act->action = SCP_SINK_ENDDIR;
  1272. return 0;
  1273. case 'T':
  1274. if (sscanf(act->buf->s, "%lu %*d %lu %*d",
  1275. &act->mtime, &act->atime) == 2) {
  1276. act->settime = true;
  1277. backend_send(backend, "", 1);
  1278. strbuf_clear(act->buf);
  1279. continue; /* go round again */
  1280. }
  1281. bump("Protocol error: Illegal time format");
  1282. case 'C':
  1283. case 'D':
  1284. act->action = (action == 'C' ? SCP_SINK_FILE : SCP_SINK_DIR);
  1285. if (act->action == SCP_SINK_DIR && !recursive) {
  1286. bump("security violation: remote host attempted to create "
  1287. "a subdirectory in a non-recursive copy!");
  1288. }
  1289. break;
  1290. default:
  1291. bump("Protocol error: Expected control record");
  1292. }
  1293. /*
  1294. * We will go round this loop only once, unless we hit
  1295. * `continue' above.
  1296. */
  1297. done = true;
  1298. }
  1299. /*
  1300. * If we get here, we must have seen SCP_SINK_FILE or
  1301. * SCP_SINK_DIR.
  1302. */
  1303. {
  1304. int i;
  1305. if (sscanf(act->buf->s, "%lo %"SCNu64" %n", &act->permissions,
  1306. &act->size, &i) != 2)
  1307. bump("Protocol error: Illegal file descriptor format");
  1308. act->name = act->buf->s + i;
  1309. return 0;
  1310. }
  1311. }
  1312. }
  1313. int scp_accept_filexfer(void)
  1314. {
  1315. if (using_sftp) {
  1316. struct sftp_packet *pktin;
  1317. struct sftp_request *req;
  1318. req = fxp_open_send(scp_sftp_currentname, SSH_FXF_READ, NULL);
  1319. pktin = sftp_wait_for_reply(req);
  1320. scp_sftp_filehandle = fxp_open_recv(pktin, req);
  1321. if (!scp_sftp_filehandle) {
  1322. with_stripctrl(san, scp_sftp_currentname)
  1323. tell_user(stderr, "pscp: unable to open %s: %s",
  1324. san, fxp_error());
  1325. errs++;
  1326. return 1;
  1327. }
  1328. scp_sftp_fileoffset = 0;
  1329. scp_sftp_xfer = xfer_download_init(scp_sftp_filehandle,
  1330. scp_sftp_fileoffset);
  1331. sfree(scp_sftp_currentname);
  1332. return 0;
  1333. } else {
  1334. backend_send(backend, "", 1);
  1335. return 0; /* can't fail */
  1336. }
  1337. }
  1338. int scp_recv_filedata(char *data, int len)
  1339. {
  1340. if (using_sftp) {
  1341. struct sftp_packet *pktin;
  1342. int ret, actuallen;
  1343. void *vbuf;
  1344. xfer_download_queue(scp_sftp_xfer);
  1345. pktin = sftp_recv();
  1346. ret = xfer_download_gotpkt(scp_sftp_xfer, pktin);
  1347. if (ret <= 0) {
  1348. tell_user(stderr, "pscp: error while reading: %s", fxp_error());
  1349. if (ret == INT_MIN) /* pktin not even freed */
  1350. sfree(pktin);
  1351. errs++;
  1352. return -1;
  1353. }
  1354. if (xfer_download_data(scp_sftp_xfer, &vbuf, &actuallen)) {
  1355. if (actuallen <= 0) {
  1356. tell_user(stderr, "pscp: end of file while reading");
  1357. errs++;
  1358. sfree(vbuf);
  1359. return -1;
  1360. }
  1361. /*
  1362. * This assertion relies on the fact that the natural
  1363. * block size used in the xfer manager is at most that
  1364. * used in this module. I don't like crossing layers in
  1365. * this way, but it'll do for now.
  1366. */
  1367. assert(actuallen <= len);
  1368. memcpy(data, vbuf, actuallen);
  1369. sfree(vbuf);
  1370. } else
  1371. actuallen = 0;
  1372. scp_sftp_fileoffset += actuallen;
  1373. return actuallen;
  1374. } else {
  1375. return ssh_scp_recv(data, len) ? len : 0;
  1376. }
  1377. }
  1378. int scp_finish_filerecv(void)
  1379. {
  1380. if (using_sftp) {
  1381. struct sftp_packet *pktin;
  1382. struct sftp_request *req;
  1383. /*
  1384. * Ensure that xfer_done() will work correctly, so we can
  1385. * clean up any outstanding requests from the file
  1386. * transfer.
  1387. */
  1388. xfer_set_error(scp_sftp_xfer);
  1389. while (!xfer_done(scp_sftp_xfer)) {
  1390. void *vbuf;
  1391. int ret, len;
  1392. pktin = sftp_recv();
  1393. ret = xfer_download_gotpkt(scp_sftp_xfer, pktin);
  1394. if (ret <= 0) {
  1395. tell_user(stderr, "pscp: error while reading: %s", fxp_error());
  1396. if (ret == INT_MIN) /* pktin not even freed */
  1397. sfree(pktin);
  1398. errs++;
  1399. return -1;
  1400. }
  1401. if (xfer_download_data(scp_sftp_xfer, &vbuf, &len))
  1402. sfree(vbuf);
  1403. }
  1404. xfer_cleanup(scp_sftp_xfer);
  1405. req = fxp_close_send(scp_sftp_filehandle);
  1406. pktin = sftp_wait_for_reply(req);
  1407. fxp_close_recv(pktin, req);
  1408. return 0;
  1409. } else {
  1410. backend_send(backend, "", 1);
  1411. return response();
  1412. }
  1413. }
  1414. /* ----------------------------------------------------------------------
  1415. * Send an error message to the other side and to the screen.
  1416. * Increment error counter.
  1417. */
  1418. static PRINTF_LIKE(1, 2) void run_err(const char *fmt, ...)
  1419. {
  1420. char *str, *str2;
  1421. va_list ap;
  1422. va_start(ap, fmt);
  1423. errs++;
  1424. str = dupvprintf(fmt, ap);
  1425. str2 = dupcat("pscp: ", str, "\n");
  1426. sfree(str);
  1427. scp_send_errmsg(str2);
  1428. abandon_stats();
  1429. tell_user(stderr, "%s", str2);
  1430. va_end(ap);
  1431. sfree(str2);
  1432. }
  1433. /*
  1434. * Execute the source part of the SCP protocol.
  1435. */
  1436. static void source(const char *src)
  1437. {
  1438. uint64_t size;
  1439. unsigned long mtime, atime;
  1440. long permissions;
  1441. const char *last;
  1442. RFile *f;
  1443. int attr;
  1444. uint64_t i;
  1445. uint64_t stat_bytes;
  1446. time_t stat_starttime, stat_lasttime;
  1447. attr = file_type(src);
  1448. if (attr == FILE_TYPE_NONEXISTENT ||
  1449. attr == FILE_TYPE_WEIRD) {
  1450. run_err("%s: %s file or directory", src,
  1451. (attr == FILE_TYPE_WEIRD ? "Not a" : "No such"));
  1452. return;
  1453. }
  1454. if (attr == FILE_TYPE_DIRECTORY) {
  1455. if (recursive) {
  1456. /*
  1457. * Avoid . and .. directories.
  1458. */
  1459. const char *p;
  1460. p = strrchr(src, '/');
  1461. if (!p)
  1462. p = strrchr(src, '\\');
  1463. if (!p)
  1464. p = src;
  1465. else
  1466. p++;
  1467. if (!strcmp(p, ".") || !strcmp(p, ".."))
  1468. /* skip . and .. */ ;
  1469. else
  1470. rsource(src);
  1471. } else {
  1472. run_err("%s: not a regular file", src);
  1473. }
  1474. return;
  1475. }
  1476. if ((last = strrchr(src, '/')) == NULL)
  1477. last = src;
  1478. else
  1479. last++;
  1480. if (strrchr(last, '\\') != NULL)
  1481. last = strrchr(last, '\\') + 1;
  1482. if (last == src && strchr(src, ':') != NULL)
  1483. last = strchr(src, ':') + 1;
  1484. f = open_existing_file(src, &size, &mtime, &atime, &permissions);
  1485. if (f == NULL) {
  1486. run_err("%s: Cannot open file", src);
  1487. return;
  1488. }
  1489. if (preserve) {
  1490. if (scp_send_filetimes(mtime, atime)) {
  1491. close_rfile(f);
  1492. return;
  1493. }
  1494. }
  1495. if (verbose) {
  1496. tell_user(stderr, "Sending file %s, size=%"PRIu64, last, size);
  1497. }
  1498. if (scp_send_filename(last, size, permissions)) {
  1499. close_rfile(f);
  1500. return;
  1501. }
  1502. stat_bytes = 0;
  1503. stat_starttime = time(NULL);
  1504. stat_lasttime = 0;
  1505. #define PSCP_SEND_BLOCK 4096
  1506. for (i = 0; i < size; i += PSCP_SEND_BLOCK) {
  1507. char transbuf[PSCP_SEND_BLOCK];
  1508. int j, k = PSCP_SEND_BLOCK;
  1509. if (i + k > size)
  1510. k = size - i;
  1511. if ((j = read_from_file(f, transbuf, k)) != k) {
  1512. bump("%s: Read error", src);
  1513. }
  1514. if (scp_send_filedata(transbuf, k))
  1515. bump("%s: Network error occurred", src);
  1516. if (statistics) {
  1517. stat_bytes += k;
  1518. if (time(NULL) != stat_lasttime || i + k == size) {
  1519. stat_lasttime = time(NULL);
  1520. print_stats(last, size, stat_bytes,
  1521. stat_starttime, stat_lasttime);
  1522. }
  1523. }
  1524. }
  1525. close_rfile(f);
  1526. (void) scp_send_finish();
  1527. }
  1528. /*
  1529. * Recursively send the contents of a directory.
  1530. */
  1531. static void rsource(const char *src)
  1532. {
  1533. const char *last;
  1534. char *save_target;
  1535. DirHandle *dir;
  1536. if ((last = strrchr(src, '/')) == NULL)
  1537. last = src;
  1538. else
  1539. last++;
  1540. if (strrchr(last, '\\') != NULL)
  1541. last = strrchr(last, '\\') + 1;
  1542. if (last == src && strchr(src, ':') != NULL)
  1543. last = strchr(src, ':') + 1;
  1544. /* maybe send filetime */
  1545. save_target = scp_save_remotepath();
  1546. if (verbose)
  1547. tell_user(stderr, "Entering directory: %s", last);
  1548. if (scp_send_dirname(last, 0755))
  1549. return;
  1550. const char *opendir_err;
  1551. dir = open_directory(src, &opendir_err);
  1552. if (dir != NULL) {
  1553. char *filename;
  1554. while ((filename = read_filename(dir)) != NULL) {
  1555. char *foundfile = dupcat(src, "/", filename);
  1556. source(foundfile);
  1557. sfree(foundfile);
  1558. sfree(filename);
  1559. }
  1560. close_directory(dir);
  1561. } else {
  1562. tell_user(stderr, "Error opening directory %s: %s", src, opendir_err);
  1563. }
  1564. (void) scp_send_enddir();
  1565. scp_restore_remotepath(save_target);
  1566. }
  1567. /*
  1568. * Execute the sink part of the SCP protocol.
  1569. */
  1570. static void sink(const char *targ, const char *src)
  1571. {
  1572. char *destfname;
  1573. bool targisdir = false;
  1574. bool exists;
  1575. int attr;
  1576. WFile *f;
  1577. uint64_t received;
  1578. bool wrerror = false;
  1579. uint64_t stat_bytes;
  1580. time_t stat_starttime, stat_lasttime;
  1581. char *stat_name;
  1582. attr = file_type(targ);
  1583. if (attr == FILE_TYPE_DIRECTORY)
  1584. targisdir = true;
  1585. if (targetshouldbedirectory && !targisdir)
  1586. bump("%s: Not a directory", targ);
  1587. scp_sink_init();
  1588. struct scp_sink_action act;
  1589. act.buf = strbuf_new();
  1590. while (1) {
  1591. if (scp_get_sink_action(&act))
  1592. goto out;
  1593. if (act.action == SCP_SINK_ENDDIR)
  1594. goto out;
  1595. if (act.action == SCP_SINK_RETRY)
  1596. continue;
  1597. if (targisdir) {
  1598. /*
  1599. * Prevent the remote side from maliciously writing to
  1600. * files outside the target area by sending a filename
  1601. * containing `../'. In fact, it shouldn't be sending
  1602. * filenames with any slashes or colons in at all; so
  1603. * we'll find the last slash, backslash or colon in the
  1604. * filename and use only the part after that. (And
  1605. * warn!)
  1606. *
  1607. * In addition, we also ensure here that if we're
  1608. * copying a single file and the target is a directory
  1609. * (common usage: `pscp host:filename .') the remote
  1610. * can't send us a _different_ file name. We can
  1611. * distinguish this case because `src' will be non-NULL
  1612. * and the last component of that will fail to match
  1613. * (the last component of) the name sent.
  1614. *
  1615. * Well, not always; if `src' is a wildcard, we do
  1616. * expect to get back filenames that don't correspond
  1617. * exactly to it. Ideally in this case, we would like
  1618. * to ensure that the returned filename actually
  1619. * matches the wildcard pattern - but one of SCP's
  1620. * protocol infelicities is that wildcard matching is
  1621. * done at the server end _by the server's rules_ and
  1622. * so in general this is infeasible. Hence, we only
  1623. * accept filenames that don't correspond to `src' if
  1624. * unsafe mode is enabled or we are using SFTP (which
  1625. * resolves remote wildcards on the client side and can
  1626. * be trusted).
  1627. */
  1628. char *striptarget, *stripsrc;
  1629. striptarget = stripslashes(act.name, true);
  1630. if (striptarget != act.name) {
  1631. with_stripctrl(sanname, act.name) {
  1632. with_stripctrl(santarg, striptarget) {
  1633. tell_user(stderr, "warning: remote host sent a"
  1634. " compound pathname '%s'", sanname);
  1635. tell_user(stderr, " renaming local"
  1636. " file to '%s'", santarg);
  1637. }
  1638. }
  1639. }
  1640. /*
  1641. * Also check to see if the target filename is '.' or
  1642. * '..', or indeed '...' and so on because Windows
  1643. * appears to interpret those like '..'.
  1644. */
  1645. if (is_dots(striptarget)) {
  1646. bump("security violation: remote host attempted to write to"
  1647. " a '.' or '..' path!");
  1648. }
  1649. if (src) {
  1650. stripsrc = stripslashes(src, true);
  1651. if (strcmp(striptarget, stripsrc) &&
  1652. !using_sftp && !scp_unsafe_mode) {
  1653. with_stripctrl(san, striptarget)
  1654. tell_user(stderr, "warning: remote host tried to "
  1655. "write to a file called '%s'", san);
  1656. tell_user(stderr, " when we requested a file "
  1657. "called '%s'.", stripsrc);
  1658. tell_user(stderr, " If this is a wildcard, "
  1659. "consider upgrading to SSH-2 or using");
  1660. tell_user(stderr, " the '-unsafe' option. Renaming"
  1661. " of this file has been disallowed.");
  1662. /* Override the name the server provided with our own. */
  1663. striptarget = stripsrc;
  1664. }
  1665. }
  1666. if (targ[0] != '\0')
  1667. destfname = dir_file_cat(targ, striptarget);
  1668. else
  1669. destfname = dupstr(striptarget);
  1670. } else {
  1671. /*
  1672. * In this branch of the if, the target area is a
  1673. * single file with an explicitly specified name in any
  1674. * case, so there's no danger.
  1675. */
  1676. destfname = dupstr(targ);
  1677. }
  1678. attr = file_type(destfname);
  1679. exists = (attr != FILE_TYPE_NONEXISTENT);
  1680. if (act.action == SCP_SINK_DIR) {
  1681. if (exists && attr != FILE_TYPE_DIRECTORY) {
  1682. with_stripctrl(san, destfname)
  1683. run_err("%s: Not a directory", san);
  1684. sfree(destfname);
  1685. continue;
  1686. }
  1687. if (!exists) {
  1688. if (!create_directory(destfname)) {
  1689. with_stripctrl(san, destfname)
  1690. run_err("%s: Cannot create directory", san);
  1691. sfree(destfname);
  1692. continue;
  1693. }
  1694. }
  1695. sink(destfname, NULL);
  1696. /* can we set the timestamp for directories ? */
  1697. sfree(destfname);
  1698. continue;
  1699. }
  1700. f = open_new_file(destfname, act.permissions);
  1701. if (f == NULL) {
  1702. with_stripctrl(san, destfname)
  1703. run_err("%s: Cannot create file", san);
  1704. sfree(destfname);
  1705. continue;
  1706. }
  1707. if (scp_accept_filexfer()) {
  1708. sfree(destfname);
  1709. close_wfile(f);
  1710. goto out;
  1711. }
  1712. stat_bytes = 0;
  1713. stat_starttime = time(NULL);
  1714. stat_lasttime = 0;
  1715. stat_name = stripctrl_string(
  1716. string_scc, stripslashes(destfname, true));
  1717. received = 0;
  1718. while (received < act.size) {
  1719. char transbuf[32768];
  1720. uint64_t blksize;
  1721. int read;
  1722. blksize = 32768;
  1723. if (blksize > act.size - received)
  1724. blksize = act.size - received;
  1725. read = scp_recv_filedata(transbuf, (int)blksize);
  1726. if (read <= 0)
  1727. bump("Lost connection");
  1728. if (wrerror) {
  1729. received += read;
  1730. continue;
  1731. }
  1732. if (write_to_file(f, transbuf, read) != (int)read) {
  1733. wrerror = true;
  1734. /* FIXME: in sftp we can actually abort the transfer */
  1735. if (statistics)
  1736. printf("\r%-25.25s | %50s\n",
  1737. stat_name,
  1738. "Write error.. waiting for end of file");
  1739. received += read;
  1740. continue;
  1741. }
  1742. if (statistics) {
  1743. stat_bytes += read;
  1744. if (time(NULL) > stat_lasttime ||
  1745. received + read == act.size) {
  1746. stat_lasttime = time(NULL);
  1747. print_stats(stat_name, act.size, stat_bytes,
  1748. stat_starttime, stat_lasttime);
  1749. }
  1750. }
  1751. received += read;
  1752. }
  1753. if (act.settime) {
  1754. set_file_times(f, act.mtime, act.atime);
  1755. }
  1756. close_wfile(f);
  1757. if (wrerror) {
  1758. with_stripctrl(san, destfname)
  1759. run_err("%s: Write error", san);
  1760. sfree(destfname);
  1761. continue;
  1762. }
  1763. (void) scp_finish_filerecv();
  1764. sfree(stat_name);
  1765. sfree(destfname);
  1766. }
  1767. out:
  1768. strbuf_free(act.buf);
  1769. }
  1770. /*
  1771. * We will copy local files to a remote server.
  1772. */
  1773. static void toremote(int argc, char *argv[])
  1774. {
  1775. char *src, *wtarg, *host, *user;
  1776. const char *targ;
  1777. char *cmd;
  1778. int i, wc_type;
  1779. uploading = true;
  1780. wtarg = argv[argc - 1];
  1781. /* Separate host from filename */
  1782. host = wtarg;
  1783. wtarg = colon(wtarg);
  1784. if (wtarg == NULL)
  1785. bump("wtarg == NULL in toremote()");
  1786. *wtarg++ = '\0';
  1787. /* Substitute "." for empty target */
  1788. if (*wtarg == '\0')
  1789. targ = ".";
  1790. else
  1791. targ = wtarg;
  1792. /* Separate host and username */
  1793. user = host;
  1794. host = strrchr(host, '@');
  1795. if (host == NULL) {
  1796. host = user;
  1797. user = NULL;
  1798. } else {
  1799. *host++ = '\0';
  1800. if (*user == '\0')
  1801. user = NULL;
  1802. }
  1803. if (argc == 2) {
  1804. if (colon(argv[0]) != NULL)
  1805. bump("%s: Remote to remote not supported", argv[0]);
  1806. wc_type = test_wildcard(argv[0], true);
  1807. if (wc_type == WCTYPE_NONEXISTENT)
  1808. bump("%s: No such file or directory\n", argv[0]);
  1809. else if (wc_type == WCTYPE_WILDCARD)
  1810. targetshouldbedirectory = true;
  1811. }
  1812. cmd = dupprintf("scp%s%s%s%s -t %s",
  1813. verbose ? " -v" : "",
  1814. recursive ? " -r" : "",
  1815. preserve ? " -p" : "",
  1816. targetshouldbedirectory ? " -d" : "", targ);
  1817. do_cmd(host, user, cmd);
  1818. sfree(cmd);
  1819. if (scp_source_setup(targ, targetshouldbedirectory))
  1820. return;
  1821. for (i = 0; i < argc - 1; i++) {
  1822. src = argv[i];
  1823. if (colon(src) != NULL) {
  1824. tell_user(stderr, "%s: Remote to remote not supported\n", src);
  1825. errs++;
  1826. continue;
  1827. }
  1828. wc_type = test_wildcard(src, true);
  1829. if (wc_type == WCTYPE_NONEXISTENT) {
  1830. run_err("%s: No such file or directory", src);
  1831. continue;
  1832. } else if (wc_type == WCTYPE_FILENAME) {
  1833. source(src);
  1834. continue;
  1835. } else {
  1836. WildcardMatcher *wc;
  1837. char *filename;
  1838. wc = begin_wildcard_matching(src);
  1839. if (wc == NULL) {
  1840. run_err("%s: No such file or directory", src);
  1841. continue;
  1842. }
  1843. while ((filename = wildcard_get_filename(wc)) != NULL) {
  1844. source(filename);
  1845. sfree(filename);
  1846. }
  1847. finish_wildcard_matching(wc);
  1848. }
  1849. }
  1850. }
  1851. /*
  1852. * We will copy files from a remote server to the local machine.
  1853. */
  1854. static void tolocal(int argc, char *argv[])
  1855. {
  1856. char *wsrc, *host, *user;
  1857. const char *src, *targ;
  1858. char *cmd;
  1859. uploading = false;
  1860. if (argc != 2)
  1861. bump("More than one remote source not supported");
  1862. wsrc = argv[0];
  1863. targ = argv[1];
  1864. /* Separate host from filename */
  1865. host = wsrc;
  1866. wsrc = colon(wsrc);
  1867. if (wsrc == NULL)
  1868. bump("Local to local copy not supported");
  1869. *wsrc++ = '\0';
  1870. /* Substitute "." for empty filename */
  1871. if (*wsrc == '\0')
  1872. src = ".";
  1873. else
  1874. src = wsrc;
  1875. /* Separate username and hostname */
  1876. user = host;
  1877. host = strrchr(host, '@');
  1878. if (host == NULL) {
  1879. host = user;
  1880. user = NULL;
  1881. } else {
  1882. *host++ = '\0';
  1883. if (*user == '\0')
  1884. user = NULL;
  1885. }
  1886. cmd = dupprintf("scp%s%s%s%s -f %s",
  1887. verbose ? " -v" : "",
  1888. recursive ? " -r" : "",
  1889. preserve ? " -p" : "",
  1890. targetshouldbedirectory ? " -d" : "", src);
  1891. do_cmd(host, user, cmd);
  1892. sfree(cmd);
  1893. if (scp_sink_setup(src, preserve, recursive))
  1894. return;
  1895. sink(targ, src);
  1896. }
  1897. /*
  1898. * We will issue a list command to get a remote directory.
  1899. */
  1900. static void get_dir_list(int argc, char *argv[])
  1901. {
  1902. char *wsrc, *host, *user;
  1903. const char *src;
  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. strbuf *cmd = strbuf_new();
  1930. put_datalit(cmd, "ls -la '");
  1931. for (q = src; *q; q++) {
  1932. if (*q == '\'')
  1933. put_datalit(cmd, "'\\''");
  1934. else
  1935. put_byte(cmd, *q);
  1936. }
  1937. put_datalit(cmd, "'");
  1938. do_cmd(host, user, cmd->s);
  1939. strbuf_free(cmd);
  1940. if (using_sftp) {
  1941. scp_sftp_listdir(src);
  1942. } else {
  1943. stdio_sink ss;
  1944. stdio_sink_init(&ss, stdout);
  1945. StripCtrlChars *scc = stripctrl_new(
  1946. BinarySink_UPCAST(&ss), false, L'\0');
  1947. while (ssh_scp_recv(&c, 1))
  1948. put_byte(scc, c);
  1949. stripctrl_free(scc);
  1950. }
  1951. }
  1952. /*
  1953. * Short description of parameters.
  1954. */
  1955. static void usage(void)
  1956. {
  1957. printf("PuTTY Secure Copy client\n");
  1958. printf("%s\n", ver);
  1959. printf("Usage: pscp [options] [user@]host:source target\n");
  1960. printf(" pscp [options] source [source...] [user@]host:target\n");
  1961. printf(" pscp [options] -ls [user@]host:filespec\n");
  1962. printf("Options:\n");
  1963. printf(" -V print version information and exit\n");
  1964. printf(" -pgpfp print PGP key fingerprints and exit\n");
  1965. printf(" -p preserve file attributes\n");
  1966. printf(" -q quiet, don't show statistics\n");
  1967. printf(" -r copy directories recursively\n");
  1968. printf(" -v show verbose messages\n");
  1969. printf(" -load sessname Load settings from saved session\n");
  1970. printf(" -P port connect to specified port\n");
  1971. printf(" -l user connect with specified username\n");
  1972. printf(" -pwfile file login with password read from specified file\n");
  1973. printf(" -1 -2 force use of particular SSH protocol version\n");
  1974. printf(" -ssh -ssh-connection\n");
  1975. printf(" force use of particular SSH protocol variant\n");
  1976. printf(" -4 -6 force use of IPv4 or IPv6\n");
  1977. printf(" -C enable compression\n");
  1978. printf(" -i key private key file for user authentication\n");
  1979. printf(" -noagent disable use of Pageant\n");
  1980. printf(" -agent enable use of Pageant\n");
  1981. printf(" -no-trivial-auth\n");
  1982. printf(" disconnect if SSH authentication succeeds trivially\n");
  1983. printf(" -hostkey keyid\n");
  1984. printf(" manually specify a host key (may be repeated)\n");
  1985. printf(" -batch disable all interactive prompts\n");
  1986. printf(" -no-sanitise-stderr don't strip control chars from"
  1987. " standard error\n");
  1988. printf(" -proxycmd command\n");
  1989. printf(" use 'command' as local proxy\n");
  1990. printf(" -unsafe allow server-side wildcards (DANGEROUS)\n");
  1991. printf(" -sftp force use of SFTP protocol\n");
  1992. printf(" -scp force use of SCP protocol\n");
  1993. printf(" -sshlog file\n");
  1994. printf(" -sshrawlog file\n");
  1995. printf(" log protocol details to a file\n");
  1996. printf(" -logoverwrite\n");
  1997. printf(" -logappend\n");
  1998. printf(" control what happens when a log file already exists\n");
  1999. cleanup_exit(1);
  2000. }
  2001. void version(void)
  2002. {
  2003. char *buildinfo_text = buildinfo("\n");
  2004. printf("pscp: %s\n%s\n", ver, buildinfo_text);
  2005. sfree(buildinfo_text);
  2006. exit(0);
  2007. }
  2008. void cmdline_error(const char *p, ...)
  2009. {
  2010. va_list ap;
  2011. fprintf(stderr, "pscp: ");
  2012. va_start(ap, p);
  2013. vfprintf(stderr, p, ap);
  2014. va_end(ap);
  2015. fprintf(stderr, "\n try typing just \"pscp\" for help\n");
  2016. exit(1);
  2017. }
  2018. const bool share_can_be_downstream = true;
  2019. const bool share_can_be_upstream = false;
  2020. static stdio_sink stderr_ss;
  2021. static StripCtrlChars *stderr_scc;
  2022. const unsigned cmdline_tooltype = TOOLTYPE_FILETRANSFER;
  2023. /*
  2024. * Main program. (Called `psftp_main' because it gets called from
  2025. * *sftp.c; bit silly, I know, but it had to be called _something_.)
  2026. */
  2027. int psftp_main(int argc, char *argv[])
  2028. {
  2029. int i;
  2030. bool sanitise_stderr = true;
  2031. sk_init();
  2032. /* Load Default Settings before doing anything else. */
  2033. conf = conf_new();
  2034. do_defaults(NULL, conf);
  2035. for (i = 1; i < argc; i++) {
  2036. int ret;
  2037. if (argv[i][0] != '-')
  2038. break;
  2039. ret = cmdline_process_param(argv[i], i+1<argc?argv[i+1]:NULL, 1, conf);
  2040. if (ret == -2) {
  2041. cmdline_error("option \"%s\" requires an argument", argv[i]);
  2042. } else if (ret == 2) {
  2043. i++; /* skip next argument */
  2044. } else if (ret == 1) {
  2045. /* We have our own verbosity in addition to `flags'. */
  2046. if (cmdline_verbose())
  2047. verbose = true;
  2048. } else if (strcmp(argv[i], "-pgpfp") == 0) {
  2049. pgp_fingerprints();
  2050. return 1;
  2051. } else if (strcmp(argv[i], "-r") == 0) {
  2052. recursive = true;
  2053. } else if (strcmp(argv[i], "-p") == 0) {
  2054. preserve = true;
  2055. } else if (strcmp(argv[i], "-q") == 0) {
  2056. statistics = false;
  2057. } else if (strcmp(argv[i], "-h") == 0 ||
  2058. strcmp(argv[i], "-?") == 0 ||
  2059. strcmp(argv[i], "--help") == 0) {
  2060. usage();
  2061. } else if (strcmp(argv[i], "-V") == 0 ||
  2062. strcmp(argv[i], "--version") == 0) {
  2063. version();
  2064. } else if (strcmp(argv[i], "-ls") == 0) {
  2065. list = true;
  2066. } else if (strcmp(argv[i], "-unsafe") == 0) {
  2067. scp_unsafe_mode = true;
  2068. } else if (strcmp(argv[i], "-sftp") == 0) {
  2069. try_scp = false; try_sftp = true;
  2070. } else if (strcmp(argv[i], "-scp") == 0) {
  2071. try_scp = true; try_sftp = false;
  2072. } else if (strcmp(argv[i], "-sanitise-stderr") == 0) {
  2073. sanitise_stderr = true;
  2074. } else if (strcmp(argv[i], "-no-sanitise-stderr") == 0) {
  2075. sanitise_stderr = false;
  2076. } else if (strcmp(argv[i], "--") == 0) {
  2077. i++;
  2078. break;
  2079. } else {
  2080. cmdline_error("unknown option \"%s\"", argv[i]);
  2081. }
  2082. }
  2083. argc -= i;
  2084. argv += i;
  2085. backend = NULL;
  2086. stdio_sink_init(&stderr_ss, stderr);
  2087. stderr_bs = BinarySink_UPCAST(&stderr_ss);
  2088. if (sanitise_stderr) {
  2089. stderr_scc = stripctrl_new(stderr_bs, false, L'\0');
  2090. stderr_bs = BinarySink_UPCAST(stderr_scc);
  2091. }
  2092. string_scc = stripctrl_new(NULL, false, L'\0');
  2093. if (list) {
  2094. if (argc != 1)
  2095. usage();
  2096. get_dir_list(argc, argv);
  2097. } else {
  2098. if (argc < 2)
  2099. usage();
  2100. if (argc > 2)
  2101. targetshouldbedirectory = true;
  2102. if (colon(argv[argc - 1]) != NULL)
  2103. toremote(argc, argv);
  2104. else
  2105. tolocal(argc, argv);
  2106. }
  2107. if (backend && backend_connected(backend)) {
  2108. char ch;
  2109. backend_special(backend, SS_EOF, 0);
  2110. sent_eof = true;
  2111. ssh_scp_recv(&ch, 1);
  2112. }
  2113. random_save_seed();
  2114. cmdline_cleanup();
  2115. if (backend) {
  2116. backend_free(backend);
  2117. backend = NULL;
  2118. }
  2119. sk_cleanup();
  2120. return (errs == 0 ? 0 : 1);
  2121. }
  2122. /* end */