pscp.c 71 KB

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