ssh.c 75 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572
  1. /***************************************************************************
  2. * _ _ ____ _
  3. * Project ___| | | | _ \| |
  4. * / __| | | | |_) | |
  5. * | (__| |_| | _ <| |___
  6. * \___|\___/|_| \_\_____|
  7. *
  8. * Copyright (C) 1998 - 2008, Daniel Stenberg, <[email protected]>, et al.
  9. *
  10. * This software is licensed as described in the file COPYING, which
  11. * you should have received as part of this distribution. The terms
  12. * are also available at http://curl.haxx.se/docs/copyright.html.
  13. *
  14. * You may opt to use, copy, modify, merge, publish, distribute and/or sell
  15. * copies of the Software, and permit persons to whom the Software is
  16. * furnished to do so, under the terms of the COPYING file.
  17. *
  18. * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
  19. * KIND, either express or implied.
  20. *
  21. * $Id$
  22. ***************************************************************************/
  23. /* #define CURL_LIBSSH2_DEBUG */
  24. #include "setup.h"
  25. #ifdef USE_LIBSSH2
  26. #include <stdio.h>
  27. #include <string.h>
  28. #include <stdlib.h>
  29. #include <stdarg.h>
  30. #include <ctype.h>
  31. #include <limits.h>
  32. #include <libssh2.h>
  33. #include <libssh2_sftp.h>
  34. #if !defined(LIBSSH2_VERSION_NUM) || (LIBSSH2_VERSION_NUM < 0x001000)
  35. #error "this requires libssh2 0.16 or later"
  36. #endif
  37. #ifdef HAVE_UNISTD_H
  38. #include <unistd.h>
  39. #endif
  40. #ifdef HAVE_FCNTL_H
  41. #include <fcntl.h>
  42. #endif
  43. #ifdef HAVE_TIME_H
  44. #include <time.h>
  45. #endif
  46. #ifndef WIN32
  47. #ifdef HAVE_SYS_SOCKET_H
  48. #include <sys/socket.h>
  49. #endif
  50. #ifdef HAVE_NETINET_IN_H
  51. #include <netinet/in.h>
  52. #endif
  53. #ifdef HAVE_ARPA_INET_H
  54. #include <arpa/inet.h>
  55. #endif
  56. #ifdef HAVE_UTSNAME_H
  57. #include <sys/utsname.h>
  58. #endif
  59. #ifdef HAVE_NETDB_H
  60. #include <netdb.h>
  61. #endif
  62. #ifdef VMS
  63. #include <in.h>
  64. #include <inet.h>
  65. #endif
  66. #endif /* !WIN32 */
  67. #if (defined(NETWARE) && defined(__NOVELL_LIBC__))
  68. #undef in_addr_t
  69. #define in_addr_t unsigned long
  70. #endif
  71. #include <curl/curl.h>
  72. #include "urldata.h"
  73. #include "sendf.h"
  74. #include "easyif.h" /* for Curl_convert_... prototypes */
  75. #include "hostip.h"
  76. #include "progress.h"
  77. #include "transfer.h"
  78. #include "escape.h"
  79. #include "http.h" /* for HTTP proxy tunnel stuff */
  80. #include "ssh.h"
  81. #include "url.h"
  82. #include "speedcheck.h"
  83. #include "getinfo.h"
  84. #include "strequal.h"
  85. #include "sslgen.h"
  86. #include "connect.h"
  87. #include "strerror.h"
  88. #include "memory.h"
  89. #include "inet_ntop.h"
  90. #include "parsedate.h" /* for the week day and month names */
  91. #include "sockaddr.h" /* required for Curl_sockaddr_storage */
  92. #include "multiif.h"
  93. #if defined(HAVE_INET_NTOA_R) && !defined(HAVE_INET_NTOA_R_DECL)
  94. #include "inet_ntoa_r.h"
  95. #endif
  96. #define _MPRINTF_REPLACE /* use our functions only */
  97. #include <curl/mprintf.h>
  98. /* The last #include file should be: */
  99. #ifdef CURLDEBUG
  100. #include "memdebug.h"
  101. #endif
  102. #ifndef PATH_MAX
  103. #define PATH_MAX 1024 /* just an extra precaution since there are systems that
  104. have their definition hidden well */
  105. #endif
  106. /* Local functions: */
  107. static const char *sftp_libssh2_strerror(unsigned long err);
  108. static LIBSSH2_ALLOC_FUNC(libssh2_malloc);
  109. static LIBSSH2_REALLOC_FUNC(libssh2_realloc);
  110. static LIBSSH2_FREE_FUNC(libssh2_free);
  111. static CURLcode get_pathname(const char **cpp, char **path);
  112. static CURLcode ssh_connect(struct connectdata *conn, bool *done);
  113. static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done);
  114. static CURLcode ssh_do(struct connectdata *conn, bool *done);
  115. static CURLcode ssh_getworkingpath(struct connectdata *conn,
  116. char *homedir, /* when SFTP is used */
  117. char **path);
  118. static CURLcode scp_done(struct connectdata *conn,
  119. CURLcode, bool premature);
  120. static CURLcode scp_doing(struct connectdata *conn,
  121. bool *dophase_done);
  122. static CURLcode scp_disconnect(struct connectdata *conn);
  123. static CURLcode sftp_done(struct connectdata *conn,
  124. CURLcode, bool premature);
  125. static CURLcode sftp_doing(struct connectdata *conn,
  126. bool *dophase_done);
  127. static CURLcode sftp_disconnect(struct connectdata *conn);
  128. static
  129. CURLcode sftp_perform(struct connectdata *conn,
  130. bool *connected,
  131. bool *dophase_done);
  132. /*
  133. * SCP protocol handler.
  134. */
  135. const struct Curl_handler Curl_handler_scp = {
  136. "SCP", /* scheme */
  137. ZERO_NULL, /* setup_connection */
  138. ssh_do, /* do_it */
  139. scp_done, /* done */
  140. ZERO_NULL, /* do_more */
  141. ssh_connect, /* connect_it */
  142. ssh_multi_statemach, /* connecting */
  143. scp_doing, /* doing */
  144. ZERO_NULL, /* proto_getsock */
  145. ZERO_NULL, /* doing_getsock */
  146. scp_disconnect, /* disconnect */
  147. PORT_SSH, /* defport */
  148. PROT_SCP /* protocol */
  149. };
  150. /*
  151. * SFTP protocol handler.
  152. */
  153. const struct Curl_handler Curl_handler_sftp = {
  154. "SFTP", /* scheme */
  155. ZERO_NULL, /* setup_connection */
  156. ssh_do, /* do_it */
  157. sftp_done, /* done */
  158. ZERO_NULL, /* do_more */
  159. ssh_connect, /* connect_it */
  160. ssh_multi_statemach, /* connecting */
  161. sftp_doing, /* doing */
  162. ZERO_NULL, /* proto_getsock */
  163. ZERO_NULL, /* doing_getsock */
  164. sftp_disconnect, /* disconnect */
  165. PORT_SSH, /* defport */
  166. PROT_SFTP /* protocol */
  167. };
  168. static void
  169. kbd_callback(const char *name, int name_len, const char *instruction,
  170. int instruction_len, int num_prompts,
  171. const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts,
  172. LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses,
  173. void **abstract)
  174. {
  175. struct connectdata *conn = (struct connectdata *)*abstract;
  176. #ifdef CURL_LIBSSH2_DEBUG
  177. fprintf(stderr, "name=%s\n", name);
  178. fprintf(stderr, "name_len=%d\n", name_len);
  179. fprintf(stderr, "instruction=%s\n", instruction);
  180. fprintf(stderr, "instruction_len=%d\n", instruction_len);
  181. fprintf(stderr, "num_prompts=%d\n", num_prompts);
  182. #else
  183. (void)name;
  184. (void)name_len;
  185. (void)instruction;
  186. (void)instruction_len;
  187. #endif /* CURL_LIBSSH2_DEBUG */
  188. if(num_prompts == 1) {
  189. responses[0].text = strdup(conn->passwd);
  190. responses[0].length = strlen(conn->passwd);
  191. }
  192. (void)prompts;
  193. (void)abstract;
  194. } /* kbd_callback */
  195. static CURLcode sftp_libssh2_error_to_CURLE(unsigned long err)
  196. {
  197. switch (err) {
  198. case LIBSSH2_FX_OK:
  199. return CURLE_OK;
  200. case LIBSSH2_ERROR_ALLOC:
  201. return CURLE_OUT_OF_MEMORY;
  202. case LIBSSH2_FX_NO_SUCH_FILE:
  203. case LIBSSH2_FX_NO_SUCH_PATH:
  204. return CURLE_REMOTE_FILE_NOT_FOUND;
  205. case LIBSSH2_FX_PERMISSION_DENIED:
  206. case LIBSSH2_FX_WRITE_PROTECT:
  207. case LIBSSH2_FX_LOCK_CONFlICT:
  208. return CURLE_REMOTE_ACCESS_DENIED;
  209. case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
  210. case LIBSSH2_FX_QUOTA_EXCEEDED:
  211. return CURLE_REMOTE_DISK_FULL;
  212. case LIBSSH2_FX_FILE_ALREADY_EXISTS:
  213. return CURLE_REMOTE_FILE_EXISTS;
  214. case LIBSSH2_FX_DIR_NOT_EMPTY:
  215. return CURLE_QUOTE_ERROR;
  216. default:
  217. break;
  218. }
  219. return CURLE_SSH;
  220. }
  221. static CURLcode libssh2_session_error_to_CURLE(int err)
  222. {
  223. if(err == LIBSSH2_ERROR_ALLOC)
  224. return CURLE_OUT_OF_MEMORY;
  225. /* TODO: map some more of the libssh2 errors to the more appropriate CURLcode
  226. error code, and possibly add a few new SSH-related one. We must however
  227. not return or even depend on libssh2 errors in the public libcurl API */
  228. return CURLE_SSH;
  229. }
  230. static LIBSSH2_ALLOC_FUNC(libssh2_malloc)
  231. {
  232. (void)abstract; /* arg not used */
  233. return malloc(count);
  234. }
  235. static LIBSSH2_REALLOC_FUNC(libssh2_realloc)
  236. {
  237. (void)abstract; /* arg not used */
  238. return realloc(ptr, count);
  239. }
  240. static LIBSSH2_FREE_FUNC(libssh2_free)
  241. {
  242. (void)abstract; /* arg not used */
  243. free(ptr);
  244. }
  245. /*
  246. * SSH State machine related code
  247. */
  248. /* This is the ONLY way to change SSH state! */
  249. static void state(struct connectdata *conn, sshstate nowstate)
  250. {
  251. #if defined(CURLDEBUG) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
  252. /* for debug purposes */
  253. static const char * const names[] = {
  254. "SSH_STOP",
  255. "SSH_S_STARTUP",
  256. "SSH_AUTHLIST",
  257. "SSH_AUTH_PKEY_INIT",
  258. "SSH_AUTH_PKEY",
  259. "SSH_AUTH_PASS_INIT",
  260. "SSH_AUTH_PASS",
  261. "SSH_AUTH_HOST_INIT",
  262. "SSH_AUTH_HOST",
  263. "SSH_AUTH_KEY_INIT",
  264. "SSH_AUTH_KEY",
  265. "SSH_AUTH_DONE",
  266. "SSH_SFTP_INIT",
  267. "SSH_SFTP_REALPATH",
  268. "SSH_SFTP_QUOTE_INIT",
  269. "SSH_SFTP_POSTQUOTE_INIT",
  270. "SSH_SFTP_QUOTE",
  271. "SSH_SFTP_NEXT_QUOTE",
  272. "SSH_SFTP_QUOTE_STAT",
  273. "SSH_SFTP_QUOTE_SETSTAT",
  274. "SSH_SFTP_QUOTE_SYMLINK",
  275. "SSH_SFTP_QUOTE_MKDIR",
  276. "SSH_SFTP_QUOTE_RENAME",
  277. "SSH_SFTP_QUOTE_RMDIR",
  278. "SSH_SFTP_QUOTE_UNLINK",
  279. "SSH_SFTP_TRANS_INIT",
  280. "SSH_SFTP_UPLOAD_INIT",
  281. "SSH_SFTP_CREATE_DIRS_INIT",
  282. "SSH_SFTP_CREATE_DIRS",
  283. "SSH_SFTP_CREATE_DIRS_MKDIR",
  284. "SSH_SFTP_READDIR_INIT",
  285. "SSH_SFTP_READDIR",
  286. "SSH_SFTP_READDIR_LINK",
  287. "SSH_SFTP_READDIR_BOTTOM",
  288. "SSH_SFTP_READDIR_DONE",
  289. "SSH_SFTP_DOWNLOAD_INIT",
  290. "SSH_SFTP_DOWNLOAD_STAT",
  291. "SSH_SFTP_CLOSE",
  292. "SSH_SFTP_SHUTDOWN",
  293. "SSH_SCP_TRANS_INIT",
  294. "SSH_SCP_UPLOAD_INIT",
  295. "SSH_SCP_DOWNLOAD_INIT",
  296. "SSH_SCP_DONE",
  297. "SSH_SCP_SEND_EOF",
  298. "SSH_SCP_WAIT_EOF",
  299. "SSH_SCP_WAIT_CLOSE",
  300. "SSH_SCP_CHANNEL_FREE",
  301. "SSH_SESSION_DISCONNECT",
  302. "SSH_SESSION_FREE",
  303. "QUIT"
  304. };
  305. #endif
  306. struct ssh_conn *sshc = &conn->proto.sshc;
  307. #if defined(CURLDEBUG) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
  308. if(sshc->state != nowstate) {
  309. infof(conn->data, "SFTP %p state change from %s to %s\n",
  310. sshc, names[sshc->state], names[nowstate]);
  311. }
  312. #endif
  313. sshc->state = nowstate;
  314. }
  315. /* figure out the path to work with in this particular request */
  316. static CURLcode ssh_getworkingpath(struct connectdata *conn,
  317. char *homedir, /* when SFTP is used */
  318. char **path) /* returns the allocated
  319. real path to work with */
  320. {
  321. struct SessionHandle *data = conn->data;
  322. char *real_path = NULL;
  323. char *working_path;
  324. int working_path_len;
  325. working_path = curl_easy_unescape(data, data->state.path, 0,
  326. &working_path_len);
  327. if(!working_path)
  328. return CURLE_OUT_OF_MEMORY;
  329. /* Check for /~/ , indicating relative to the user's home directory */
  330. if(conn->protocol & PROT_SCP) {
  331. real_path = (char *)malloc(working_path_len+1);
  332. if(real_path == NULL) {
  333. free(working_path);
  334. return CURLE_OUT_OF_MEMORY;
  335. }
  336. if((working_path_len > 1) && (working_path[1] == '~'))
  337. /* It is referenced to the home directory, so strip the leading '/' */
  338. memcpy(real_path, working_path+1, 1 + working_path_len-1);
  339. else
  340. memcpy(real_path, working_path, 1 + working_path_len);
  341. }
  342. else if(conn->protocol & PROT_SFTP) {
  343. if((working_path_len > 1) && (working_path[1] == '~')) {
  344. size_t homelen = strlen(homedir);
  345. real_path = (char *)malloc(homelen + working_path_len + 1);
  346. if(real_path == NULL) {
  347. free(working_path);
  348. return CURLE_OUT_OF_MEMORY;
  349. }
  350. /* It is referenced to the home directory, so strip the
  351. leading '/' */
  352. memcpy(real_path, homedir, homelen);
  353. real_path[homelen] = '/';
  354. real_path[homelen+1] = '\0';
  355. if(working_path_len > 3) {
  356. memcpy(real_path+homelen+1, working_path + 3,
  357. 1 + working_path_len -3);
  358. }
  359. }
  360. else {
  361. real_path = (char *)malloc(working_path_len+1);
  362. if(real_path == NULL) {
  363. free(working_path);
  364. return CURLE_OUT_OF_MEMORY;
  365. }
  366. memcpy(real_path, working_path, 1+working_path_len);
  367. }
  368. }
  369. free(working_path);
  370. /* store the pointer for the caller to receive */
  371. *path = real_path;
  372. return CURLE_OK;
  373. }
  374. static CURLcode ssh_statemach_act(struct connectdata *conn)
  375. {
  376. CURLcode result = CURLE_OK;
  377. struct SessionHandle *data = conn->data;
  378. struct SSHPROTO *sftp_scp = data->state.proto.ssh;
  379. struct ssh_conn *sshc = &conn->proto.sshc;
  380. curl_socket_t sock = conn->sock[FIRSTSOCKET];
  381. #ifdef CURL_LIBSSH2_DEBUG
  382. const char *fingerprint;
  383. #endif /* CURL_LIBSSH2_DEBUG */
  384. const char *host_public_key_md5;
  385. int rc,i;
  386. int err;
  387. switch(sshc->state) {
  388. case SSH_S_STARTUP:
  389. sshc->secondCreateDirs = 0;
  390. sshc->nextstate = SSH_NO_STATE;
  391. sshc->actualcode = CURLE_OK;
  392. rc = libssh2_session_startup(sshc->ssh_session, sock);
  393. if(rc == LIBSSH2_ERROR_EAGAIN) {
  394. break;
  395. }
  396. else if(rc) {
  397. failf(data, "Failure establishing ssh session");
  398. state(conn, SSH_SESSION_FREE);
  399. sshc->actualcode = CURLE_FAILED_INIT;
  400. break;
  401. }
  402. /* Set libssh2 to non-blocking, since cURL is all non-blocking */
  403. libssh2_session_set_blocking(sshc->ssh_session, 0);
  404. #ifdef CURL_LIBSSH2_DEBUG
  405. /*
  406. * Before we authenticate we should check the hostkey's fingerprint
  407. * against our known hosts. How that is handled (reading from file,
  408. * whatever) is up to us. As for know not much is implemented, besides
  409. * showing how to get the fingerprint.
  410. */
  411. fingerprint = libssh2_hostkey_hash(sshc->ssh_session,
  412. LIBSSH2_HOSTKEY_HASH_MD5);
  413. /* The fingerprint points to static storage (!), don't free() it. */
  414. infof(data, "Fingerprint: ");
  415. for (rc = 0; rc < 16; rc++) {
  416. infof(data, "%02X ", (unsigned char) fingerprint[rc]);
  417. }
  418. infof(data, "\n");
  419. #endif /* CURL_LIBSSH2_DEBUG */
  420. /* Before we authenticate we check the hostkey's MD5 fingerprint
  421. * against a known fingerprint, if available. This implementation pulls
  422. * it from the curl option.
  423. */
  424. if(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5] &&
  425. strlen(data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]) == 32) {
  426. char buf[33];
  427. host_public_key_md5 = libssh2_hostkey_hash(sshc->ssh_session,
  428. LIBSSH2_HOSTKEY_HASH_MD5);
  429. for (i = 0; i < 16; i++)
  430. snprintf(&buf[i*2], 3, "%02x",
  431. (unsigned char) host_public_key_md5[i]);
  432. if(!strequal(buf, data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5])) {
  433. failf(data,
  434. "Denied establishing ssh session: mismatch md5 fingerprint. "
  435. "Remote %s is not equal to %s",
  436. buf, data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]);
  437. state(conn, SSH_SESSION_FREE);
  438. sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
  439. break;
  440. }
  441. }
  442. state(conn, SSH_AUTHLIST);
  443. break;
  444. case SSH_AUTHLIST:
  445. /* TBD - methods to check the host keys need to be done */
  446. /*
  447. * Figure out authentication methods
  448. * NB: As soon as we have provided a username to an openssh server we
  449. * must never change it later. Thus, always specify the correct username
  450. * here, even though the libssh2 docs kind of indicate that it should be
  451. * possible to get a 'generic' list (not user-specific) of authentication
  452. * methods, presumably with a blank username. That won't work in my
  453. * experience.
  454. * So always specify it here.
  455. */
  456. sshc->authlist = libssh2_userauth_list(sshc->ssh_session,
  457. conn->user,
  458. strlen(conn->user));
  459. if(!sshc->authlist) {
  460. if((err = libssh2_session_last_errno(sshc->ssh_session)) ==
  461. LIBSSH2_ERROR_EAGAIN) {
  462. break;
  463. }
  464. else {
  465. state(conn, SSH_SESSION_FREE);
  466. sshc->actualcode = libssh2_session_error_to_CURLE(err);
  467. break;
  468. }
  469. }
  470. infof(data, "SSH authentication methods available: %s\n", sshc->authlist);
  471. state(conn, SSH_AUTH_PKEY_INIT);
  472. break;
  473. case SSH_AUTH_PKEY_INIT:
  474. /*
  475. * Check the supported auth types in the order I feel is most secure
  476. * with the requested type of authentication
  477. */
  478. sshc->authed = FALSE;
  479. if((data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY) &&
  480. (strstr(sshc->authlist, "publickey") != NULL)) {
  481. char *home;
  482. sshc->rsa_pub = sshc->rsa = NULL;
  483. /* To ponder about: should really the lib be messing about with the
  484. HOME environment variable etc? */
  485. home = curl_getenv("HOME");
  486. if(data->set.str[STRING_SSH_PUBLIC_KEY])
  487. sshc->rsa_pub = aprintf("%s", data->set.str[STRING_SSH_PUBLIC_KEY]);
  488. else if(home)
  489. sshc->rsa_pub = aprintf("%s/.ssh/id_dsa.pub", home);
  490. else
  491. /* as a final resort, try current dir! */
  492. sshc->rsa_pub = strdup("id_dsa.pub");
  493. if(sshc->rsa_pub == NULL) {
  494. Curl_safefree(home);
  495. home = NULL;
  496. state(conn, SSH_SESSION_FREE);
  497. sshc->actualcode = CURLE_OUT_OF_MEMORY;
  498. break;
  499. }
  500. if(data->set.str[STRING_SSH_PRIVATE_KEY])
  501. sshc->rsa = aprintf("%s", data->set.str[STRING_SSH_PRIVATE_KEY]);
  502. else if(home)
  503. sshc->rsa = aprintf("%s/.ssh/id_dsa", home);
  504. else
  505. /* as a final resort, try current dir! */
  506. sshc->rsa = strdup("id_dsa");
  507. if(sshc->rsa == NULL) {
  508. Curl_safefree(home);
  509. home = NULL;
  510. Curl_safefree(sshc->rsa_pub);
  511. sshc->rsa_pub = NULL;
  512. state(conn, SSH_SESSION_FREE);
  513. sshc->actualcode = CURLE_OUT_OF_MEMORY;
  514. break;
  515. }
  516. sshc->passphrase = data->set.str[STRING_KEY_PASSWD];
  517. if(!sshc->passphrase)
  518. sshc->passphrase = "";
  519. Curl_safefree(home);
  520. home = NULL;
  521. infof(data, "Using ssh public key file %s\n", sshc->rsa_pub);
  522. infof(data, "Using ssh private key file %s\n", sshc->rsa);
  523. state(conn, SSH_AUTH_PKEY);
  524. }
  525. else {
  526. state(conn, SSH_AUTH_PASS_INIT);
  527. }
  528. break;
  529. case SSH_AUTH_PKEY:
  530. /* The function below checks if the files exists, no need to stat() here.
  531. */
  532. rc = libssh2_userauth_publickey_fromfile(sshc->ssh_session,
  533. conn->user, sshc->rsa_pub,
  534. sshc->rsa, sshc->passphrase);
  535. if(rc == LIBSSH2_ERROR_EAGAIN) {
  536. break;
  537. }
  538. Curl_safefree(sshc->rsa_pub);
  539. sshc->rsa_pub = NULL;
  540. Curl_safefree(sshc->rsa);
  541. sshc->rsa = NULL;
  542. if(rc == 0) {
  543. sshc->authed = TRUE;
  544. infof(data, "Initialized SSH public key authentication\n");
  545. state(conn, SSH_AUTH_DONE);
  546. }
  547. else {
  548. char *err_msg;
  549. (void)libssh2_session_last_error(sshc->ssh_session,
  550. &err_msg, NULL, 0);
  551. infof(data, "SSH public key authentication failed: %s\n", err_msg);
  552. state(conn, SSH_AUTH_PASS_INIT);
  553. }
  554. break;
  555. case SSH_AUTH_PASS_INIT:
  556. if((data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD) &&
  557. (strstr(sshc->authlist, "password") != NULL)) {
  558. state(conn, SSH_AUTH_PASS);
  559. }
  560. else {
  561. state(conn, SSH_AUTH_HOST_INIT);
  562. }
  563. break;
  564. case SSH_AUTH_PASS:
  565. rc = libssh2_userauth_password(sshc->ssh_session, conn->user,
  566. conn->passwd);
  567. if(rc == LIBSSH2_ERROR_EAGAIN) {
  568. break;
  569. }
  570. else if(rc == 0) {
  571. sshc->authed = TRUE;
  572. infof(data, "Initialized password authentication\n");
  573. state(conn, SSH_AUTH_DONE);
  574. }
  575. else {
  576. state(conn, SSH_AUTH_HOST_INIT);
  577. }
  578. break;
  579. case SSH_AUTH_HOST_INIT:
  580. if((data->set.ssh_auth_types & CURLSSH_AUTH_HOST) &&
  581. (strstr(sshc->authlist, "hostbased") != NULL)) {
  582. state(conn, SSH_AUTH_HOST);
  583. }
  584. else {
  585. state(conn, SSH_AUTH_KEY_INIT);
  586. }
  587. break;
  588. case SSH_AUTH_HOST:
  589. state(conn, SSH_AUTH_KEY_INIT);
  590. break;
  591. case SSH_AUTH_KEY_INIT:
  592. if((data->set.ssh_auth_types & CURLSSH_AUTH_KEYBOARD)
  593. && (strstr(sshc->authlist, "keyboard-interactive") != NULL)) {
  594. state(conn, SSH_AUTH_KEY);
  595. }
  596. else {
  597. state(conn, SSH_AUTH_DONE);
  598. }
  599. break;
  600. case SSH_AUTH_KEY:
  601. /* Authentication failed. Continue with keyboard-interactive now. */
  602. rc = libssh2_userauth_keyboard_interactive_ex(sshc->ssh_session,
  603. conn->user,
  604. strlen(conn->user),
  605. &kbd_callback);
  606. if(rc == LIBSSH2_ERROR_EAGAIN) {
  607. break;
  608. }
  609. else if(rc == 0) {
  610. sshc->authed = TRUE;
  611. infof(data, "Initialized keyboard interactive authentication\n");
  612. }
  613. state(conn, SSH_AUTH_DONE);
  614. break;
  615. case SSH_AUTH_DONE:
  616. if(!sshc->authed) {
  617. failf(data, "Authentication failure");
  618. state(conn, SSH_SESSION_FREE);
  619. sshc->actualcode = CURLE_LOGIN_DENIED;
  620. break;
  621. }
  622. /*
  623. * At this point we have an authenticated ssh session.
  624. */
  625. infof(data, "Authentication complete\n");
  626. Curl_pgrsTime(conn->data, TIMER_APPCONNECT); /* SSH is connected */
  627. conn->sockfd = sock;
  628. conn->writesockfd = CURL_SOCKET_BAD;
  629. if(conn->protocol == PROT_SFTP) {
  630. state(conn, SSH_SFTP_INIT);
  631. break;
  632. }
  633. infof(data, "SSH CONNECT phase done\n");
  634. state(conn, SSH_STOP);
  635. break;
  636. case SSH_SFTP_INIT:
  637. /*
  638. * Start the libssh2 sftp session
  639. */
  640. sshc->sftp_session = libssh2_sftp_init(sshc->ssh_session);
  641. if(!sshc->sftp_session) {
  642. if(libssh2_session_last_errno(sshc->ssh_session) ==
  643. LIBSSH2_ERROR_EAGAIN) {
  644. break;
  645. }
  646. else {
  647. char *err_msg;
  648. (void)libssh2_session_last_error(sshc->ssh_session,
  649. &err_msg, NULL, 0);
  650. failf(data, "Failure initializing sftp session: %s", err_msg);
  651. state(conn, SSH_SESSION_FREE);
  652. sshc->actualcode = CURLE_FAILED_INIT;
  653. break;
  654. }
  655. }
  656. state(conn, SSH_SFTP_REALPATH);
  657. break;
  658. case SSH_SFTP_REALPATH:
  659. {
  660. char tempHome[PATH_MAX];
  661. /*
  662. * Get the "home" directory
  663. */
  664. rc = libssh2_sftp_realpath(sshc->sftp_session, ".",
  665. tempHome, PATH_MAX-1);
  666. if(rc == LIBSSH2_ERROR_EAGAIN) {
  667. break;
  668. }
  669. else if(rc > 0) {
  670. /* It seems that this string is not always NULL terminated */
  671. tempHome[rc] = '\0';
  672. sshc->homedir = (char *)strdup(tempHome);
  673. if(!sshc->homedir) {
  674. state(conn, SSH_SFTP_CLOSE);
  675. sshc->actualcode = CURLE_OUT_OF_MEMORY;
  676. break;
  677. }
  678. }
  679. else {
  680. /* Return the error type */
  681. err = libssh2_sftp_last_error(sshc->sftp_session);
  682. result = sftp_libssh2_error_to_CURLE(err);
  683. DEBUGF(infof(data, "error = %d makes libcurl = %d\n", err, result));
  684. state(conn, SSH_STOP);
  685. break;
  686. }
  687. }
  688. /* This is the last step in the SFTP connect phase. Do note that while
  689. we get the homedir here, we get the "workingpath" in the DO action
  690. since the homedir will remain the same between request but the
  691. working path will not. */
  692. DEBUGF(infof(data, "SSH CONNECT phase done\n"));
  693. state(conn, SSH_STOP);
  694. break;
  695. case SSH_SFTP_QUOTE_INIT:
  696. result = ssh_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
  697. if(result) {
  698. sshc->actualcode = result;
  699. state(conn, SSH_STOP);
  700. break;
  701. }
  702. if(data->set.quote) {
  703. infof(data, "Sending quote commands\n");
  704. sshc->quote_item = data->set.quote;
  705. state(conn, SSH_SFTP_QUOTE);
  706. }
  707. else {
  708. state(conn, SSH_SFTP_TRANS_INIT);
  709. }
  710. break;
  711. case SSH_SFTP_POSTQUOTE_INIT:
  712. if(data->set.postquote) {
  713. infof(data, "Sending quote commands\n");
  714. sshc->quote_item = data->set.postquote;
  715. state(conn, SSH_SFTP_QUOTE);
  716. }
  717. else {
  718. state(conn, SSH_STOP);
  719. }
  720. break;
  721. case SSH_SFTP_QUOTE:
  722. /* Send any quote commands */
  723. {
  724. const char *cp;
  725. /*
  726. * Support some of the "FTP" commands
  727. */
  728. if(curl_strnequal(sshc->quote_item->data, "PWD", 3)) {
  729. /* output debug output if that is requested */
  730. if(data->set.verbose) {
  731. char tmp[PATH_MAX+1];
  732. Curl_debug(data, CURLINFO_HEADER_OUT, (char *)"PWD\n", 4, conn);
  733. snprintf(tmp, PATH_MAX, "257 \"%s\" is current directory.\n",
  734. sftp_scp->path);
  735. Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp), conn);
  736. }
  737. state(conn, SSH_SFTP_NEXT_QUOTE);
  738. break;
  739. }
  740. else if(sshc->quote_item->data) {
  741. /*
  742. * the arguments following the command must be separated from the
  743. * command with a space so we can check for it unconditionally
  744. */
  745. cp = strchr(sshc->quote_item->data, ' ');
  746. if(cp == NULL) {
  747. failf(data, "Syntax error in SFTP command. Supply parameter(s)!");
  748. state(conn, SSH_SFTP_CLOSE);
  749. sshc->actualcode = CURLE_QUOTE_ERROR;
  750. break;
  751. }
  752. /*
  753. * also, every command takes at least one argument so we get that
  754. * first argument right now
  755. */
  756. result = get_pathname(&cp, &sshc->quote_path1);
  757. if(result) {
  758. if(result == CURLE_OUT_OF_MEMORY)
  759. failf(data, "Out of memory");
  760. else
  761. failf(data, "Syntax error: Bad first parameter");
  762. state(conn, SSH_SFTP_CLOSE);
  763. sshc->actualcode = result;
  764. break;
  765. }
  766. /*
  767. * SFTP is a binary protocol, so we don't send text commands to
  768. * the server. Instead, we scan for commands for commands used by
  769. * OpenSSH's sftp program and call the appropriate libssh2
  770. * functions.
  771. */
  772. if(curl_strnequal(sshc->quote_item->data, "chgrp ", 6) ||
  773. curl_strnequal(sshc->quote_item->data, "chmod ", 6) ||
  774. curl_strnequal(sshc->quote_item->data, "chown ", 6) ) {
  775. /* attribute change */
  776. /* sshc->quote_path1 contains the mode to set */
  777. /* get the destination */
  778. result = get_pathname(&cp, &sshc->quote_path2);
  779. if(result) {
  780. if(result == CURLE_OUT_OF_MEMORY)
  781. failf(data, "Out of memory");
  782. else
  783. failf(data, "Syntax error in chgrp/chmod/chown: "
  784. "Bad second parameter");
  785. Curl_safefree(sshc->quote_path1);
  786. sshc->quote_path1 = NULL;
  787. state(conn, SSH_SFTP_CLOSE);
  788. sshc->actualcode = result;
  789. break;
  790. }
  791. memset(&sshc->quote_attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES));
  792. state(conn, SSH_SFTP_QUOTE_STAT);
  793. break;
  794. }
  795. else if(curl_strnequal(sshc->quote_item->data, "ln ", 3) ||
  796. curl_strnequal(sshc->quote_item->data, "symlink ", 8)) {
  797. /* symbolic linking */
  798. /* sshc->quote_path1 is the source */
  799. /* get the destination */
  800. result = get_pathname(&cp, &sshc->quote_path2);
  801. if(result) {
  802. if(result == CURLE_OUT_OF_MEMORY)
  803. failf(data, "Out of memory");
  804. else
  805. failf(data,
  806. "Syntax error in ln/symlink: Bad second parameter");
  807. Curl_safefree(sshc->quote_path1);
  808. sshc->quote_path1 = NULL;
  809. state(conn, SSH_SFTP_CLOSE);
  810. sshc->actualcode = result;
  811. break;
  812. }
  813. state(conn, SSH_SFTP_QUOTE_SYMLINK);
  814. break;
  815. }
  816. else if(curl_strnequal(sshc->quote_item->data, "mkdir ", 6)) {
  817. /* create dir */
  818. state(conn, SSH_SFTP_QUOTE_MKDIR);
  819. break;
  820. }
  821. else if(curl_strnequal(sshc->quote_item->data, "rename ", 7)) {
  822. /* rename file */
  823. /* first param is the source path */
  824. /* second param is the dest. path */
  825. result = get_pathname(&cp, &sshc->quote_path2);
  826. if(result) {
  827. if(result == CURLE_OUT_OF_MEMORY)
  828. failf(data, "Out of memory");
  829. else
  830. failf(data, "Syntax error in rename: Bad second parameter");
  831. Curl_safefree(sshc->quote_path1);
  832. sshc->quote_path1 = NULL;
  833. state(conn, SSH_SFTP_CLOSE);
  834. sshc->actualcode = result;
  835. break;
  836. }
  837. state(conn, SSH_SFTP_QUOTE_RENAME);
  838. break;
  839. }
  840. else if(curl_strnequal(sshc->quote_item->data, "rmdir ", 6)) {
  841. /* delete dir */
  842. state(conn, SSH_SFTP_QUOTE_RMDIR);
  843. break;
  844. }
  845. else if(curl_strnequal(sshc->quote_item->data, "rm ", 3)) {
  846. state(conn, SSH_SFTP_QUOTE_UNLINK);
  847. break;
  848. }
  849. failf(data, "Unknown SFTP command");
  850. Curl_safefree(sshc->quote_path1);
  851. sshc->quote_path1 = NULL;
  852. Curl_safefree(sshc->quote_path2);
  853. sshc->quote_path2 = NULL;
  854. state(conn, SSH_SFTP_CLOSE);
  855. sshc->actualcode = CURLE_QUOTE_ERROR;
  856. break;
  857. }
  858. }
  859. if(!sshc->quote_item) {
  860. state(conn, SSH_SFTP_TRANS_INIT);
  861. }
  862. break;
  863. case SSH_SFTP_NEXT_QUOTE:
  864. if(sshc->quote_path1) {
  865. Curl_safefree(sshc->quote_path1);
  866. sshc->quote_path1 = NULL;
  867. }
  868. if(sshc->quote_path2) {
  869. Curl_safefree(sshc->quote_path2);
  870. sshc->quote_path2 = NULL;
  871. }
  872. sshc->quote_item = sshc->quote_item->next;
  873. if(sshc->quote_item) {
  874. state(conn, SSH_SFTP_QUOTE);
  875. }
  876. else {
  877. if(sshc->nextstate != SSH_NO_STATE) {
  878. state(conn, sshc->nextstate);
  879. sshc->nextstate = SSH_NO_STATE;
  880. }
  881. else {
  882. state(conn, SSH_SFTP_TRANS_INIT);
  883. }
  884. }
  885. break;
  886. case SSH_SFTP_QUOTE_STAT:
  887. if(!curl_strnequal(sshc->quote_item->data, "chmod", 5)) {
  888. /* Since chown and chgrp only set owner OR group but libssh2 wants to
  889. * set them both at once, we need to obtain the current ownership first.
  890. * This takes an extra protocol round trip.
  891. */
  892. rc = libssh2_sftp_stat(sshc->sftp_session, sshc->quote_path2,
  893. &sshc->quote_attrs);
  894. if(rc == LIBSSH2_ERROR_EAGAIN) {
  895. break;
  896. }
  897. else if(rc != 0) { /* get those attributes */
  898. err = libssh2_sftp_last_error(sshc->sftp_session);
  899. Curl_safefree(sshc->quote_path1);
  900. sshc->quote_path1 = NULL;
  901. Curl_safefree(sshc->quote_path2);
  902. sshc->quote_path2 = NULL;
  903. failf(data, "Attempt to get SFTP stats failed: %s",
  904. sftp_libssh2_strerror(err));
  905. state(conn, SSH_SFTP_CLOSE);
  906. sshc->actualcode = CURLE_QUOTE_ERROR;
  907. break;
  908. }
  909. }
  910. /* Now set the new attributes... */
  911. if(curl_strnequal(sshc->quote_item->data, "chgrp", 5)) {
  912. sshc->quote_attrs.gid = strtol(sshc->quote_path1, NULL, 10);
  913. sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
  914. if(sshc->quote_attrs.gid == 0 && !ISDIGIT(sshc->quote_path1[0])) {
  915. Curl_safefree(sshc->quote_path1);
  916. sshc->quote_path1 = NULL;
  917. Curl_safefree(sshc->quote_path2);
  918. sshc->quote_path2 = NULL;
  919. failf(data, "Syntax error: chgrp gid not a number");
  920. state(conn, SSH_SFTP_CLOSE);
  921. sshc->actualcode = CURLE_QUOTE_ERROR;
  922. break;
  923. }
  924. }
  925. else if(curl_strnequal(sshc->quote_item->data, "chmod", 5)) {
  926. sshc->quote_attrs.permissions = strtol(sshc->quote_path1, NULL, 8);
  927. sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_PERMISSIONS;
  928. /* permissions are octal */
  929. if(sshc->quote_attrs.permissions == 0 &&
  930. !ISDIGIT(sshc->quote_path1[0])) {
  931. Curl_safefree(sshc->quote_path1);
  932. sshc->quote_path1 = NULL;
  933. Curl_safefree(sshc->quote_path2);
  934. sshc->quote_path2 = NULL;
  935. failf(data, "Syntax error: chmod permissions not a number");
  936. state(conn, SSH_SFTP_CLOSE);
  937. sshc->actualcode = CURLE_QUOTE_ERROR;
  938. break;
  939. }
  940. }
  941. else if(curl_strnequal(sshc->quote_item->data, "chown", 5)) {
  942. sshc->quote_attrs.uid = strtol(sshc->quote_path1, NULL, 10);
  943. sshc->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
  944. if(sshc->quote_attrs.uid == 0 && !ISDIGIT(sshc->quote_path1[0])) {
  945. Curl_safefree(sshc->quote_path1);
  946. sshc->quote_path1 = NULL;
  947. Curl_safefree(sshc->quote_path2);
  948. sshc->quote_path2 = NULL;
  949. failf(data, "Syntax error: chown uid not a number");
  950. state(conn, SSH_SFTP_CLOSE);
  951. sshc->actualcode = CURLE_QUOTE_ERROR;
  952. break;
  953. }
  954. }
  955. /* Now send the completed structure... */
  956. state(conn, SSH_SFTP_QUOTE_SETSTAT);
  957. break;
  958. case SSH_SFTP_QUOTE_SETSTAT:
  959. rc = libssh2_sftp_setstat(sshc->sftp_session, sshc->quote_path2,
  960. &sshc->quote_attrs);
  961. if(rc == LIBSSH2_ERROR_EAGAIN) {
  962. break;
  963. }
  964. else if(rc != 0) {
  965. err = libssh2_sftp_last_error(sshc->sftp_session);
  966. Curl_safefree(sshc->quote_path1);
  967. sshc->quote_path1 = NULL;
  968. Curl_safefree(sshc->quote_path2);
  969. sshc->quote_path2 = NULL;
  970. failf(data, "Attempt to set SFTP stats failed: %s",
  971. sftp_libssh2_strerror(err));
  972. state(conn, SSH_SFTP_CLOSE);
  973. sshc->actualcode = CURLE_QUOTE_ERROR;
  974. break;
  975. }
  976. state(conn, SSH_SFTP_NEXT_QUOTE);
  977. break;
  978. case SSH_SFTP_QUOTE_SYMLINK:
  979. rc = libssh2_sftp_symlink(sshc->sftp_session, sshc->quote_path1,
  980. sshc->quote_path2);
  981. if(rc == LIBSSH2_ERROR_EAGAIN) {
  982. break;
  983. }
  984. else if(rc != 0) {
  985. err = libssh2_sftp_last_error(sshc->sftp_session);
  986. Curl_safefree(sshc->quote_path1);
  987. sshc->quote_path1 = NULL;
  988. Curl_safefree(sshc->quote_path2);
  989. sshc->quote_path2 = NULL;
  990. failf(data, "symlink command failed: %s",
  991. sftp_libssh2_strerror(err));
  992. state(conn, SSH_SFTP_CLOSE);
  993. sshc->actualcode = CURLE_QUOTE_ERROR;
  994. break;
  995. }
  996. state(conn, SSH_SFTP_NEXT_QUOTE);
  997. break;
  998. case SSH_SFTP_QUOTE_MKDIR:
  999. rc = libssh2_sftp_mkdir(sshc->sftp_session, sshc->quote_path1, 0755);
  1000. if(rc == LIBSSH2_ERROR_EAGAIN) {
  1001. break;
  1002. }
  1003. else if(rc != 0) {
  1004. err = libssh2_sftp_last_error(sshc->sftp_session);
  1005. Curl_safefree(sshc->quote_path1);
  1006. sshc->quote_path1 = NULL;
  1007. failf(data, "mkdir command failed: %s", sftp_libssh2_strerror(err));
  1008. state(conn, SSH_SFTP_CLOSE);
  1009. sshc->actualcode = CURLE_QUOTE_ERROR;
  1010. break;
  1011. }
  1012. state(conn, SSH_SFTP_NEXT_QUOTE);
  1013. break;
  1014. case SSH_SFTP_QUOTE_RENAME:
  1015. rc = libssh2_sftp_rename(sshc->sftp_session, sshc->quote_path1,
  1016. sshc->quote_path2);
  1017. if(rc == LIBSSH2_ERROR_EAGAIN) {
  1018. break;
  1019. }
  1020. else if(rc != 0) {
  1021. err = libssh2_sftp_last_error(sshc->sftp_session);
  1022. Curl_safefree(sshc->quote_path1);
  1023. sshc->quote_path1 = NULL;
  1024. Curl_safefree(sshc->quote_path2);
  1025. sshc->quote_path2 = NULL;
  1026. failf(data, "rename command failed: %s", sftp_libssh2_strerror(err));
  1027. state(conn, SSH_SFTP_CLOSE);
  1028. sshc->actualcode = CURLE_QUOTE_ERROR;
  1029. break;
  1030. }
  1031. state(conn, SSH_SFTP_NEXT_QUOTE);
  1032. break;
  1033. case SSH_SFTP_QUOTE_RMDIR:
  1034. rc = libssh2_sftp_rmdir(sshc->sftp_session, sshc->quote_path1);
  1035. if(rc == LIBSSH2_ERROR_EAGAIN) {
  1036. break;
  1037. }
  1038. else if(rc != 0) {
  1039. err = libssh2_sftp_last_error(sshc->sftp_session);
  1040. Curl_safefree(sshc->quote_path1);
  1041. sshc->quote_path1 = NULL;
  1042. failf(data, "rmdir command failed: %s", sftp_libssh2_strerror(err));
  1043. state(conn, SSH_SFTP_CLOSE);
  1044. sshc->actualcode = CURLE_QUOTE_ERROR;
  1045. break;
  1046. }
  1047. state(conn, SSH_SFTP_NEXT_QUOTE);
  1048. break;
  1049. case SSH_SFTP_QUOTE_UNLINK:
  1050. rc = libssh2_sftp_unlink(sshc->sftp_session, sshc->quote_path1);
  1051. if(rc == LIBSSH2_ERROR_EAGAIN) {
  1052. break;
  1053. }
  1054. else if(rc != 0) {
  1055. err = libssh2_sftp_last_error(sshc->sftp_session);
  1056. Curl_safefree(sshc->quote_path1);
  1057. sshc->quote_path1 = NULL;
  1058. failf(data, "rm command failed: %s", sftp_libssh2_strerror(err));
  1059. state(conn, SSH_SFTP_CLOSE);
  1060. sshc->actualcode = CURLE_QUOTE_ERROR;
  1061. break;
  1062. }
  1063. state(conn, SSH_SFTP_NEXT_QUOTE);
  1064. break;
  1065. case SSH_SFTP_TRANS_INIT:
  1066. if(data->set.upload)
  1067. state(conn, SSH_SFTP_UPLOAD_INIT);
  1068. else {
  1069. if(data->set.opt_no_body)
  1070. state(conn, SSH_STOP);
  1071. else if(sftp_scp->path[strlen(sftp_scp->path)-1] == '/')
  1072. state(conn, SSH_SFTP_READDIR_INIT);
  1073. else
  1074. state(conn, SSH_SFTP_DOWNLOAD_INIT);
  1075. }
  1076. break;
  1077. case SSH_SFTP_UPLOAD_INIT:
  1078. {
  1079. unsigned long flags;
  1080. /*
  1081. * NOTE!!! libssh2 requires that the destination path is a full path
  1082. * that includes the destination file and name OR ends in a "/"
  1083. * If this is not done the destination file will be named the
  1084. * same name as the last directory in the path.
  1085. */
  1086. if(data->state.resume_from != 0) {
  1087. LIBSSH2_SFTP_ATTRIBUTES attrs;
  1088. if(data->state.resume_from< 0) {
  1089. rc = libssh2_sftp_stat(sshc->sftp_session, sftp_scp->path, &attrs);
  1090. if(rc == LIBSSH2_ERROR_EAGAIN) {
  1091. break;
  1092. }
  1093. else if(rc) {
  1094. data->state.resume_from = 0;
  1095. }
  1096. else {
  1097. data->state.resume_from = attrs.filesize;
  1098. }
  1099. }
  1100. }
  1101. if(data->set.ftp_append)
  1102. /* Try to open for append, but create if nonexisting */
  1103. flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_APPEND;
  1104. else if (data->state.resume_from > 0)
  1105. /* If we have restart position then open for append */
  1106. flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_APPEND;
  1107. else
  1108. /* Clear file before writing (normal behaviour) */
  1109. flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC;
  1110. sshc->sftp_handle =
  1111. libssh2_sftp_open(sshc->sftp_session, sftp_scp->path,
  1112. flags, data->set.new_file_perms);
  1113. if(!sshc->sftp_handle) {
  1114. if(libssh2_session_last_errno(sshc->ssh_session) ==
  1115. LIBSSH2_ERROR_EAGAIN) {
  1116. break;
  1117. }
  1118. else {
  1119. err = libssh2_sftp_last_error(sshc->sftp_session);
  1120. if(sshc->secondCreateDirs) {
  1121. state(conn, SSH_SFTP_CLOSE);
  1122. sshc->actualcode = sftp_libssh2_error_to_CURLE(err);
  1123. failf(data, "Creating the dir/file failed: %s",
  1124. sftp_libssh2_strerror(err));
  1125. break;
  1126. }
  1127. else if(((err == LIBSSH2_FX_NO_SUCH_FILE) ||
  1128. (err == LIBSSH2_FX_FAILURE) ||
  1129. (err == LIBSSH2_FX_NO_SUCH_PATH)) &&
  1130. (data->set.ftp_create_missing_dirs &&
  1131. (strlen(sftp_scp->path) > 1))) {
  1132. /* try to create the path remotely */
  1133. sshc->secondCreateDirs = 1;
  1134. state(conn, SSH_SFTP_CREATE_DIRS_INIT);
  1135. break;
  1136. }
  1137. state(conn, SSH_SFTP_CLOSE);
  1138. sshc->actualcode = sftp_libssh2_error_to_CURLE(err);
  1139. failf(data, "Upload failed: %s", sftp_libssh2_strerror(err));
  1140. break;
  1141. }
  1142. }
  1143. /* If we have restart point then we need to seek to the correct position. */
  1144. if(data->state.resume_from > 0) {
  1145. /* Let's read off the proper amount of bytes from the input. */
  1146. if(conn->seek_func) {
  1147. curl_off_t readthisamountnow = data->state.resume_from;
  1148. if(conn->seek_func(conn->seek_client,
  1149. readthisamountnow, SEEK_SET) != 0) {
  1150. failf(data, "Could not seek stream");
  1151. return CURLE_FTP_COULDNT_USE_REST;
  1152. }
  1153. }
  1154. else {
  1155. curl_off_t passed=0;
  1156. curl_off_t readthisamountnow;
  1157. curl_off_t actuallyread;
  1158. do {
  1159. readthisamountnow = (data->state.resume_from - passed);
  1160. if(readthisamountnow > BUFSIZE)
  1161. readthisamountnow = BUFSIZE;
  1162. actuallyread =
  1163. (curl_off_t) conn->fread_func(data->state.buffer, 1,
  1164. (size_t)readthisamountnow,
  1165. conn->fread_in);
  1166. passed += actuallyread;
  1167. if((actuallyread <= 0) || (actuallyread > readthisamountnow)) {
  1168. /* this checks for greater-than only to make sure that the
  1169. CURL_READFUNC_ABORT return code still aborts */
  1170. failf(data, "Failed to read data");
  1171. return CURLE_FTP_COULDNT_USE_REST;
  1172. }
  1173. } while(passed < data->state.resume_from);
  1174. }
  1175. /* now, decrease the size of the read */
  1176. if(data->set.infilesize>0) {
  1177. data->set.infilesize -= data->state.resume_from;
  1178. data->req.size = data->set.infilesize;
  1179. Curl_pgrsSetUploadSize(data, data->set.infilesize);
  1180. }
  1181. libssh2_sftp_seek(sshc->sftp_handle, data->state.resume_from);
  1182. }
  1183. if(data->set.infilesize>0) {
  1184. data->req.size = data->set.infilesize;
  1185. Curl_pgrsSetUploadSize(data, data->set.infilesize);
  1186. }
  1187. /* upload data */
  1188. result = Curl_setup_transfer(conn, -1, -1, FALSE, NULL,
  1189. FIRSTSOCKET, NULL);
  1190. if(result) {
  1191. state(conn, SSH_SFTP_CLOSE);
  1192. sshc->actualcode = result;
  1193. }
  1194. else {
  1195. state(conn, SSH_STOP);
  1196. }
  1197. break;
  1198. }
  1199. case SSH_SFTP_CREATE_DIRS_INIT:
  1200. if(strlen(sftp_scp->path) > 1) {
  1201. sshc->slash_pos = sftp_scp->path + 1; /* ignore the leading '/' */
  1202. state(conn, SSH_SFTP_CREATE_DIRS);
  1203. }
  1204. else {
  1205. state(conn, SSH_SFTP_UPLOAD_INIT);
  1206. }
  1207. break;
  1208. case SSH_SFTP_CREATE_DIRS:
  1209. if((sshc->slash_pos = strchr(sshc->slash_pos, '/')) != NULL) {
  1210. *sshc->slash_pos = 0;
  1211. infof(data, "Creating directory '%s'\n", sftp_scp->path);
  1212. state(conn, SSH_SFTP_CREATE_DIRS_MKDIR);
  1213. break;
  1214. }
  1215. else {
  1216. state(conn, SSH_SFTP_UPLOAD_INIT);
  1217. }
  1218. break;
  1219. case SSH_SFTP_CREATE_DIRS_MKDIR:
  1220. /* 'mode' - parameter is preliminary - default to 0644 */
  1221. rc = libssh2_sftp_mkdir(sshc->sftp_session, sftp_scp->path,
  1222. data->set.new_directory_perms);
  1223. if(rc == LIBSSH2_ERROR_EAGAIN) {
  1224. break;
  1225. }
  1226. *sshc->slash_pos = '/';
  1227. ++sshc->slash_pos;
  1228. if(rc == -1) {
  1229. unsigned int sftp_err = 0;
  1230. /*
  1231. * abort if failure wasn't that the dir already exists or the
  1232. * permission was denied (creation might succeed further
  1233. * down the path) - retry on unspecific FAILURE also
  1234. */
  1235. sftp_err = libssh2_sftp_last_error(sshc->sftp_session);
  1236. if((sftp_err != LIBSSH2_FX_FILE_ALREADY_EXISTS) &&
  1237. (sftp_err != LIBSSH2_FX_FAILURE) &&
  1238. (sftp_err != LIBSSH2_FX_PERMISSION_DENIED)) {
  1239. result = sftp_libssh2_error_to_CURLE(sftp_err);
  1240. state(conn, SSH_SFTP_CLOSE);
  1241. sshc->actualcode = result;
  1242. break;
  1243. }
  1244. }
  1245. state(conn, SSH_SFTP_CREATE_DIRS);
  1246. break;
  1247. case SSH_SFTP_READDIR_INIT:
  1248. /*
  1249. * This is a directory that we are trying to get, so produce a
  1250. * directory listing
  1251. */
  1252. sshc->sftp_handle = libssh2_sftp_opendir(sshc->sftp_session,
  1253. sftp_scp->path);
  1254. if(!sshc->sftp_handle) {
  1255. if(libssh2_session_last_errno(sshc->ssh_session) ==
  1256. LIBSSH2_ERROR_EAGAIN) {
  1257. break;
  1258. }
  1259. else {
  1260. err = libssh2_sftp_last_error(sshc->sftp_session);
  1261. failf(data, "Could not open directory for reading: %s",
  1262. sftp_libssh2_strerror(err));
  1263. state(conn, SSH_SFTP_CLOSE);
  1264. sshc->actualcode = sftp_libssh2_error_to_CURLE(err);
  1265. break;
  1266. }
  1267. }
  1268. if((sshc->readdir_filename = (char *)malloc(PATH_MAX+1)) == NULL) {
  1269. state(conn, SSH_SFTP_CLOSE);
  1270. sshc->actualcode = CURLE_OUT_OF_MEMORY;
  1271. break;
  1272. }
  1273. if((sshc->readdir_longentry = (char *)malloc(PATH_MAX+1)) == NULL) {
  1274. Curl_safefree(sshc->readdir_filename);
  1275. sshc->readdir_filename = NULL;
  1276. state(conn, SSH_SFTP_CLOSE);
  1277. sshc->actualcode = CURLE_OUT_OF_MEMORY;
  1278. break;
  1279. }
  1280. state(conn, SSH_SFTP_READDIR);
  1281. break;
  1282. case SSH_SFTP_READDIR:
  1283. sshc->readdir_len = libssh2_sftp_readdir_ex(sshc->sftp_handle,
  1284. sshc->readdir_filename,
  1285. PATH_MAX,
  1286. sshc->readdir_longentry,
  1287. PATH_MAX,
  1288. &sshc->readdir_attrs);
  1289. if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
  1290. break;
  1291. }
  1292. if(sshc->readdir_len > 0) {
  1293. sshc->readdir_filename[sshc->readdir_len] = '\0';
  1294. if(data->set.ftp_list_only) {
  1295. char *tmpLine;
  1296. tmpLine = aprintf("%s\n", sshc->readdir_filename);
  1297. if(tmpLine == NULL) {
  1298. state(conn, SSH_SFTP_CLOSE);
  1299. sshc->actualcode = CURLE_OUT_OF_MEMORY;
  1300. break;
  1301. }
  1302. result = Curl_client_write(conn, CLIENTWRITE_BODY,
  1303. tmpLine, sshc->readdir_len+1);
  1304. Curl_safefree(tmpLine);
  1305. if(result) {
  1306. state(conn, SSH_STOP);
  1307. break;
  1308. }
  1309. /* since this counts what we send to the client, we include the newline
  1310. in this counter */
  1311. data->req.bytecount += sshc->readdir_len+1;
  1312. /* output debug output if that is requested */
  1313. if(data->set.verbose) {
  1314. Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_filename,
  1315. sshc->readdir_len, conn);
  1316. }
  1317. }
  1318. else {
  1319. sshc->readdir_currLen = strlen(sshc->readdir_longentry);
  1320. sshc->readdir_totalLen = 80 + sshc->readdir_currLen;
  1321. sshc->readdir_line = (char *)calloc(sshc->readdir_totalLen, 1);
  1322. if(!sshc->readdir_line) {
  1323. Curl_safefree(sshc->readdir_filename);
  1324. sshc->readdir_filename = NULL;
  1325. Curl_safefree(sshc->readdir_longentry);
  1326. sshc->readdir_longentry = NULL;
  1327. state(conn, SSH_SFTP_CLOSE);
  1328. sshc->actualcode = CURLE_OUT_OF_MEMORY;
  1329. break;
  1330. }
  1331. memcpy(sshc->readdir_line, sshc->readdir_longentry,
  1332. sshc->readdir_currLen);
  1333. if((sshc->readdir_attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) &&
  1334. ((sshc->readdir_attrs.permissions & LIBSSH2_SFTP_S_IFMT) ==
  1335. LIBSSH2_SFTP_S_IFLNK)) {
  1336. sshc->readdir_linkPath = (char *)malloc(PATH_MAX + 1);
  1337. if(sshc->readdir_linkPath == NULL) {
  1338. Curl_safefree(sshc->readdir_filename);
  1339. sshc->readdir_filename = NULL;
  1340. Curl_safefree(sshc->readdir_longentry);
  1341. sshc->readdir_longentry = NULL;
  1342. state(conn, SSH_SFTP_CLOSE);
  1343. sshc->actualcode = CURLE_OUT_OF_MEMORY;
  1344. break;
  1345. }
  1346. snprintf(sshc->readdir_linkPath, PATH_MAX, "%s%s", sftp_scp->path,
  1347. sshc->readdir_filename);
  1348. state(conn, SSH_SFTP_READDIR_LINK);
  1349. break;
  1350. }
  1351. state(conn, SSH_SFTP_READDIR_BOTTOM);
  1352. break;
  1353. }
  1354. }
  1355. else if(sshc->readdir_len == 0) {
  1356. Curl_safefree(sshc->readdir_filename);
  1357. sshc->readdir_filename = NULL;
  1358. Curl_safefree(sshc->readdir_longentry);
  1359. sshc->readdir_longentry = NULL;
  1360. state(conn, SSH_SFTP_READDIR_DONE);
  1361. break;
  1362. }
  1363. else if(sshc->readdir_len <= 0) {
  1364. err = libssh2_sftp_last_error(sshc->sftp_session);
  1365. sshc->actualcode = sftp_libssh2_error_to_CURLE(err);
  1366. failf(data, "Could not open remote file for reading: %s :: %d",
  1367. sftp_libssh2_strerror(err),
  1368. libssh2_session_last_errno(sshc->ssh_session));
  1369. Curl_safefree(sshc->readdir_filename);
  1370. sshc->readdir_filename = NULL;
  1371. Curl_safefree(sshc->readdir_longentry);
  1372. sshc->readdir_longentry = NULL;
  1373. state(conn, SSH_SFTP_CLOSE);
  1374. break;
  1375. }
  1376. break;
  1377. case SSH_SFTP_READDIR_LINK:
  1378. sshc->readdir_len = libssh2_sftp_readlink(sshc->sftp_session,
  1379. sshc->readdir_linkPath,
  1380. sshc->readdir_filename,
  1381. PATH_MAX);
  1382. if(sshc->readdir_len == LIBSSH2_ERROR_EAGAIN) {
  1383. break;
  1384. }
  1385. Curl_safefree(sshc->readdir_linkPath);
  1386. sshc->readdir_linkPath = NULL;
  1387. sshc->readdir_line = realloc(sshc->readdir_line,
  1388. sshc->readdir_totalLen + 4 +
  1389. sshc->readdir_len);
  1390. if(!sshc->readdir_line) {
  1391. Curl_safefree(sshc->readdir_filename);
  1392. sshc->readdir_filename = NULL;
  1393. Curl_safefree(sshc->readdir_longentry);
  1394. sshc->readdir_longentry = NULL;
  1395. state(conn, SSH_SFTP_CLOSE);
  1396. sshc->actualcode = CURLE_OUT_OF_MEMORY;
  1397. break;
  1398. }
  1399. sshc->readdir_currLen += snprintf(sshc->readdir_line +
  1400. sshc->readdir_currLen,
  1401. sshc->readdir_totalLen -
  1402. sshc->readdir_currLen,
  1403. " -> %s",
  1404. sshc->readdir_filename);
  1405. state(conn, SSH_SFTP_READDIR_BOTTOM);
  1406. break;
  1407. case SSH_SFTP_READDIR_BOTTOM:
  1408. sshc->readdir_currLen += snprintf(sshc->readdir_line +
  1409. sshc->readdir_currLen,
  1410. sshc->readdir_totalLen -
  1411. sshc->readdir_currLen, "\n");
  1412. result = Curl_client_write(conn, CLIENTWRITE_BODY,
  1413. sshc->readdir_line,
  1414. sshc->readdir_currLen);
  1415. if(result == CURLE_OK) {
  1416. /* output debug output if that is requested */
  1417. if(data->set.verbose) {
  1418. Curl_debug(data, CURLINFO_DATA_OUT, sshc->readdir_line,
  1419. sshc->readdir_currLen, conn);
  1420. }
  1421. data->req.bytecount += sshc->readdir_currLen;
  1422. }
  1423. Curl_safefree(sshc->readdir_line);
  1424. sshc->readdir_line = NULL;
  1425. if(result) {
  1426. state(conn, SSH_STOP);
  1427. }
  1428. else
  1429. state(conn, SSH_SFTP_READDIR);
  1430. break;
  1431. case SSH_SFTP_READDIR_DONE:
  1432. if(libssh2_sftp_closedir(sshc->sftp_handle) ==
  1433. LIBSSH2_ERROR_EAGAIN) {
  1434. break;
  1435. }
  1436. sshc->sftp_handle = NULL;
  1437. Curl_safefree(sshc->readdir_filename);
  1438. sshc->readdir_filename = NULL;
  1439. Curl_safefree(sshc->readdir_longentry);
  1440. sshc->readdir_longentry = NULL;
  1441. /* no data to transfer */
  1442. result = Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
  1443. state(conn, SSH_STOP);
  1444. break;
  1445. case SSH_SFTP_DOWNLOAD_INIT:
  1446. /*
  1447. * Work on getting the specified file
  1448. */
  1449. sshc->sftp_handle =
  1450. libssh2_sftp_open(sshc->sftp_session, sftp_scp->path,
  1451. LIBSSH2_FXF_READ, data->set.new_file_perms);
  1452. if(!sshc->sftp_handle) {
  1453. if(libssh2_session_last_errno(sshc->ssh_session) ==
  1454. LIBSSH2_ERROR_EAGAIN) {
  1455. break;
  1456. }
  1457. else {
  1458. err = libssh2_sftp_last_error(sshc->sftp_session);
  1459. failf(data, "Could not open remote file for reading: %s",
  1460. sftp_libssh2_strerror(err));
  1461. state(conn, SSH_SFTP_CLOSE);
  1462. sshc->actualcode = sftp_libssh2_error_to_CURLE(err);
  1463. break;
  1464. }
  1465. }
  1466. state(conn, SSH_SFTP_DOWNLOAD_STAT);
  1467. break;
  1468. case SSH_SFTP_DOWNLOAD_STAT:
  1469. {
  1470. LIBSSH2_SFTP_ATTRIBUTES attrs;
  1471. rc = libssh2_sftp_stat(sshc->sftp_session, sftp_scp->path, &attrs);
  1472. if(rc == LIBSSH2_ERROR_EAGAIN) {
  1473. break;
  1474. }
  1475. else if(rc) {
  1476. /*
  1477. * libssh2_sftp_open() didn't return an error, so maybe the server
  1478. * just doesn't support stat()
  1479. */
  1480. data->req.size = -1;
  1481. data->req.maxdownload = -1;
  1482. }
  1483. else {
  1484. data->req.size = attrs.filesize;
  1485. data->req.maxdownload = attrs.filesize;
  1486. Curl_pgrsSetDownloadSize(data, attrs.filesize);
  1487. }
  1488. /* We can resume if we can seek to the resume position */
  1489. if(data->state.resume_from) {
  1490. if(data->state.resume_from< 0) {
  1491. /* We're supposed to download the last abs(from) bytes */
  1492. if((curl_off_t)attrs.filesize < -data->state.resume_from) {
  1493. failf(data, "Offset (%"
  1494. FORMAT_OFF_T ") was beyond file size (%" FORMAT_OFF_T ")",
  1495. data->state.resume_from, attrs.filesize);
  1496. return CURLE_BAD_DOWNLOAD_RESUME;
  1497. }
  1498. /* download from where? */
  1499. data->state.resume_from = attrs.filesize - data->state.resume_from;
  1500. }
  1501. else {
  1502. if((curl_off_t)attrs.filesize < data->state.resume_from) {
  1503. failf(data, "Offset (%" FORMAT_OFF_T
  1504. ") was beyond file size (%" FORMAT_OFF_T ")",
  1505. data->state.resume_from, attrs.filesize);
  1506. return CURLE_BAD_DOWNLOAD_RESUME;
  1507. }
  1508. }
  1509. /* Does a completed file need to be seeked and started or closed ? */
  1510. /* Now store the number of bytes we are expected to download */
  1511. data->req.size = attrs.filesize - data->state.resume_from;
  1512. data->req.maxdownload = attrs.filesize - data->state.resume_from;
  1513. Curl_pgrsSetDownloadSize(data,
  1514. attrs.filesize - data->state.resume_from);
  1515. libssh2_sftp_seek(sshc->sftp_handle, data->state.resume_from);
  1516. }
  1517. }
  1518. /* Setup the actual download */
  1519. if(data->req.size == 0) {
  1520. /* no data to transfer */
  1521. result = Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
  1522. infof(data, "File already completely downloaded\n");
  1523. state(conn, SSH_STOP);
  1524. break;
  1525. }
  1526. else {
  1527. result = Curl_setup_transfer(conn, FIRSTSOCKET, data->req.size,
  1528. FALSE, NULL, -1, NULL);
  1529. }
  1530. if(result) {
  1531. state(conn, SSH_SFTP_CLOSE);
  1532. sshc->actualcode = result;
  1533. }
  1534. else {
  1535. state(conn, SSH_STOP);
  1536. }
  1537. break;
  1538. case SSH_SFTP_CLOSE:
  1539. if(sshc->sftp_handle) {
  1540. rc = libssh2_sftp_close(sshc->sftp_handle);
  1541. if(rc == LIBSSH2_ERROR_EAGAIN) {
  1542. break;
  1543. }
  1544. else if(rc < 0) {
  1545. infof(data, "Failed to close libssh2 file\n");
  1546. }
  1547. sshc->sftp_handle = NULL;
  1548. }
  1549. Curl_safefree(sftp_scp->path);
  1550. sftp_scp->path = NULL;
  1551. DEBUGF(infof(data, "SFTP DONE done\n"));
  1552. #if 0 /* PREV */
  1553. state(conn, SSH_SFTP_SHUTDOWN);
  1554. #endif
  1555. state(conn, SSH_STOP);
  1556. result = sshc->actualcode;
  1557. break;
  1558. case SSH_SFTP_SHUTDOWN:
  1559. /* during times we get here due to a broken transfer and then the
  1560. sftp_handle might not have been taken down so make sure that is done
  1561. before we proceed */
  1562. if(sshc->sftp_handle) {
  1563. rc = libssh2_sftp_close(sshc->sftp_handle);
  1564. if(rc == LIBSSH2_ERROR_EAGAIN) {
  1565. break;
  1566. }
  1567. else if(rc < 0) {
  1568. infof(data, "Failed to close libssh2 file\n");
  1569. }
  1570. sshc->sftp_handle = NULL;
  1571. }
  1572. if(sshc->sftp_session) {
  1573. rc = libssh2_sftp_shutdown(sshc->sftp_session);
  1574. if(rc == LIBSSH2_ERROR_EAGAIN) {
  1575. break;
  1576. }
  1577. else if(rc < 0) {
  1578. infof(data, "Failed to stop libssh2 sftp subsystem\n");
  1579. }
  1580. sshc->sftp_session = NULL;
  1581. }
  1582. Curl_safefree(sshc->homedir);
  1583. sshc->homedir = NULL;
  1584. state(conn, SSH_SESSION_DISCONNECT);
  1585. break;
  1586. case SSH_SCP_TRANS_INIT:
  1587. result = ssh_getworkingpath(conn, sshc->homedir, &sftp_scp->path);
  1588. if(result) {
  1589. sshc->actualcode = result;
  1590. state(conn, SSH_STOP);
  1591. break;
  1592. }
  1593. if(data->set.upload) {
  1594. if(data->set.infilesize < 0) {
  1595. failf(data, "SCP requires a known file size for upload");
  1596. sshc->actualcode = CURLE_UPLOAD_FAILED;
  1597. state(conn, SSH_SCP_CHANNEL_FREE);
  1598. break;
  1599. }
  1600. state(conn, SSH_SCP_UPLOAD_INIT);
  1601. }
  1602. else {
  1603. state(conn, SSH_SCP_DOWNLOAD_INIT);
  1604. }
  1605. break;
  1606. case SSH_SCP_UPLOAD_INIT:
  1607. /*
  1608. * libssh2 requires that the destination path is a full path that
  1609. * includes the destination file and name OR ends in a "/" . If this is
  1610. * not done the destination file will be named the same name as the last
  1611. * directory in the path.
  1612. */
  1613. sshc->ssh_channel =
  1614. libssh2_scp_send_ex(sshc->ssh_session, sftp_scp->path,
  1615. data->set.new_file_perms,
  1616. data->set.infilesize, 0, 0);
  1617. if(!sshc->ssh_channel) {
  1618. if(libssh2_session_last_errno(sshc->ssh_session) ==
  1619. LIBSSH2_ERROR_EAGAIN) {
  1620. break;
  1621. }
  1622. else {
  1623. int ssh_err;
  1624. char *err_msg;
  1625. ssh_err = libssh2_session_last_error(sshc->ssh_session,
  1626. &err_msg, NULL, 0);
  1627. failf(conn->data, "%s", err_msg);
  1628. state(conn, SSH_SCP_CHANNEL_FREE);
  1629. sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
  1630. break;
  1631. }
  1632. }
  1633. /* upload data */
  1634. result = Curl_setup_transfer(conn, -1, data->req.size, FALSE, NULL,
  1635. FIRSTSOCKET, NULL);
  1636. if(result) {
  1637. state(conn, SSH_SCP_CHANNEL_FREE);
  1638. sshc->actualcode = result;
  1639. }
  1640. else {
  1641. state(conn, SSH_STOP);
  1642. }
  1643. break;
  1644. case SSH_SCP_DOWNLOAD_INIT:
  1645. {
  1646. /*
  1647. * We must check the remote file; if it is a directory no values will
  1648. * be set in sb
  1649. */
  1650. struct stat sb;
  1651. curl_off_t bytecount;
  1652. /* clear the struct scp recv will fill in */
  1653. memset(&sb, 0, sizeof(struct stat));
  1654. /* get a fresh new channel from the ssh layer */
  1655. sshc->ssh_channel = libssh2_scp_recv(sshc->ssh_session,
  1656. sftp_scp->path, &sb);
  1657. if(!sshc->ssh_channel) {
  1658. if(libssh2_session_last_errno(sshc->ssh_session) ==
  1659. LIBSSH2_ERROR_EAGAIN) {
  1660. break;
  1661. }
  1662. else {
  1663. int ssh_err;
  1664. char *err_msg;
  1665. ssh_err = libssh2_session_last_error(sshc->ssh_session,
  1666. &err_msg, NULL, 0);
  1667. failf(conn->data, "%s", err_msg);
  1668. state(conn, SSH_SCP_CHANNEL_FREE);
  1669. sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
  1670. break;
  1671. }
  1672. }
  1673. /* download data */
  1674. bytecount = (curl_off_t)sb.st_size;
  1675. data->req.maxdownload = (curl_off_t)sb.st_size;
  1676. result = Curl_setup_transfer(conn, FIRSTSOCKET,
  1677. bytecount, FALSE, NULL, -1, NULL);
  1678. if(result) {
  1679. state(conn, SSH_SCP_CHANNEL_FREE);
  1680. sshc->actualcode = result;
  1681. }
  1682. else
  1683. state(conn, SSH_STOP);
  1684. }
  1685. break;
  1686. case SSH_SCP_DONE:
  1687. if(data->set.upload)
  1688. state(conn, SSH_SCP_SEND_EOF);
  1689. else
  1690. state(conn, SSH_SCP_CHANNEL_FREE);
  1691. break;
  1692. case SSH_SCP_SEND_EOF:
  1693. if(sshc->ssh_channel) {
  1694. rc = libssh2_channel_send_eof(sshc->ssh_channel);
  1695. if(rc == LIBSSH2_ERROR_EAGAIN) {
  1696. break;
  1697. }
  1698. else if(rc) {
  1699. infof(data, "Failed to send libssh2 channel EOF\n");
  1700. }
  1701. }
  1702. state(conn, SSH_SCP_WAIT_EOF);
  1703. break;
  1704. case SSH_SCP_WAIT_EOF:
  1705. if(sshc->ssh_channel) {
  1706. rc = libssh2_channel_wait_eof(sshc->ssh_channel);
  1707. if(rc == LIBSSH2_ERROR_EAGAIN) {
  1708. break;
  1709. }
  1710. else if(rc) {
  1711. infof(data, "Failed to get channel EOF: %d\n", rc);
  1712. }
  1713. }
  1714. state(conn, SSH_SCP_WAIT_CLOSE);
  1715. break;
  1716. case SSH_SCP_WAIT_CLOSE:
  1717. if(sshc->ssh_channel) {
  1718. rc = libssh2_channel_wait_closed(sshc->ssh_channel);
  1719. if(rc == LIBSSH2_ERROR_EAGAIN) {
  1720. break;
  1721. }
  1722. else if(rc) {
  1723. infof(data, "Channel failed to close: %d\n", rc);
  1724. }
  1725. }
  1726. state(conn, SSH_SCP_CHANNEL_FREE);
  1727. break;
  1728. case SSH_SCP_CHANNEL_FREE:
  1729. if(sshc->ssh_channel) {
  1730. rc = libssh2_channel_free(sshc->ssh_channel);
  1731. if(rc == LIBSSH2_ERROR_EAGAIN) {
  1732. break;
  1733. }
  1734. else if(rc < 0) {
  1735. infof(data, "Failed to free libssh2 scp subsystem\n");
  1736. }
  1737. sshc->ssh_channel = NULL;
  1738. }
  1739. DEBUGF(infof(data, "SCP DONE phase complete\n"));
  1740. #if 0 /* PREV */
  1741. state(conn, SSH_SESSION_DISCONNECT);
  1742. #endif
  1743. state(conn, SSH_STOP);
  1744. result = sshc->actualcode;
  1745. break;
  1746. case SSH_SESSION_DISCONNECT:
  1747. /* during weird times when we've been prematurely aborted, the channel
  1748. is still alive when we reach this state and we MUST kill the channel
  1749. properly first */
  1750. if(sshc->ssh_channel) {
  1751. rc = libssh2_channel_free(sshc->ssh_channel);
  1752. if(rc == LIBSSH2_ERROR_EAGAIN) {
  1753. break;
  1754. }
  1755. else if(rc < 0) {
  1756. infof(data, "Failed to free libssh2 scp subsystem\n");
  1757. }
  1758. sshc->ssh_channel = NULL;
  1759. }
  1760. if(sshc->ssh_session) {
  1761. rc = libssh2_session_disconnect(sshc->ssh_session, "Shutdown");
  1762. if(rc == LIBSSH2_ERROR_EAGAIN) {
  1763. break;
  1764. }
  1765. else if(rc < 0) {
  1766. infof(data, "Failed to disconnect libssh2 session\n");
  1767. }
  1768. }
  1769. Curl_safefree(sshc->homedir);
  1770. sshc->homedir = NULL;
  1771. state(conn, SSH_SESSION_FREE);
  1772. break;
  1773. case SSH_SESSION_FREE:
  1774. if(sshc->ssh_session) {
  1775. rc = libssh2_session_free(sshc->ssh_session);
  1776. if(rc == LIBSSH2_ERROR_EAGAIN) {
  1777. break;
  1778. }
  1779. else if(rc < 0) {
  1780. infof(data, "Failed to free libssh2 session\n");
  1781. }
  1782. sshc->ssh_session = NULL;
  1783. }
  1784. sshc->nextstate = SSH_NO_STATE;
  1785. state(conn, SSH_STOP);
  1786. result = sshc->actualcode;
  1787. break;
  1788. case SSH_QUIT:
  1789. /* fallthrough, just stop! */
  1790. default:
  1791. /* internal error */
  1792. sshc->nextstate = SSH_NO_STATE;
  1793. state(conn, SSH_STOP);
  1794. break;
  1795. }
  1796. return result;
  1797. }
  1798. /* called repeatedly until done from multi.c */
  1799. static CURLcode ssh_multi_statemach(struct connectdata *conn, bool *done)
  1800. {
  1801. struct ssh_conn *sshc = &conn->proto.sshc;
  1802. CURLcode result = CURLE_OK;
  1803. result = ssh_statemach_act(conn);
  1804. *done = (bool)(sshc->state == SSH_STOP);
  1805. return result;
  1806. }
  1807. static CURLcode ssh_easy_statemach(struct connectdata *conn)
  1808. {
  1809. struct ssh_conn *sshc = &conn->proto.sshc;
  1810. CURLcode result = CURLE_OK;
  1811. while((sshc->state != SSH_STOP) && !result)
  1812. result = ssh_statemach_act(conn);
  1813. return result;
  1814. }
  1815. /*
  1816. * SSH setup and connection
  1817. */
  1818. static CURLcode ssh_init(struct connectdata *conn)
  1819. {
  1820. struct SessionHandle *data = conn->data;
  1821. struct SSHPROTO *ssh;
  1822. struct ssh_conn *sshc = &conn->proto.sshc;
  1823. sshc->actualcode = CURLE_OK; /* reset error code */
  1824. sshc->secondCreateDirs =0; /* reset the create dir attempt state variable */
  1825. if(data->state.proto.ssh)
  1826. return CURLE_OK;
  1827. ssh = (struct SSHPROTO *)calloc(sizeof(struct SSHPROTO), 1);
  1828. if(!ssh)
  1829. return CURLE_OUT_OF_MEMORY;
  1830. data->state.proto.ssh = ssh;
  1831. return CURLE_OK;
  1832. }
  1833. /*
  1834. * Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to
  1835. * do protocol-specific actions at connect-time.
  1836. */
  1837. static CURLcode ssh_connect(struct connectdata *conn, bool *done)
  1838. {
  1839. #ifdef CURL_LIBSSH2_DEBUG
  1840. curl_socket_t sock;
  1841. #endif
  1842. struct ssh_conn *ssh;
  1843. CURLcode result;
  1844. struct SessionHandle *data = conn->data;
  1845. /* We default to persistent connections. We set this already in this connect
  1846. function to make the re-use checks properly be able to check this bit. */
  1847. conn->bits.close = FALSE;
  1848. /* If there already is a protocol-specific struct allocated for this
  1849. sessionhandle, deal with it */
  1850. Curl_reset_reqproto(conn);
  1851. result = ssh_init(conn);
  1852. if(result)
  1853. return result;
  1854. ssh = &conn->proto.sshc;
  1855. #ifdef CURL_LIBSSH2_DEBUG
  1856. if(conn->user) {
  1857. infof(data, "User: %s\n", conn->user);
  1858. }
  1859. if(conn->passwd) {
  1860. infof(data, "Password: %s\n", conn->passwd);
  1861. }
  1862. sock = conn->sock[FIRSTSOCKET];
  1863. #endif /* CURL_LIBSSH2_DEBUG */
  1864. ssh->ssh_session = libssh2_session_init_ex(libssh2_malloc, libssh2_free,
  1865. libssh2_realloc, conn);
  1866. if(ssh->ssh_session == NULL) {
  1867. failf(data, "Failure initialising ssh session");
  1868. return CURLE_FAILED_INIT;
  1869. }
  1870. #ifdef CURL_LIBSSH2_DEBUG
  1871. libssh2_trace(ssh->ssh_session, LIBSSH2_TRACE_CONN|LIBSSH2_TRACE_TRANS|
  1872. LIBSSH2_TRACE_KEX|LIBSSH2_TRACE_AUTH|LIBSSH2_TRACE_SCP|
  1873. LIBSSH2_TRACE_SFTP|LIBSSH2_TRACE_ERROR|
  1874. LIBSSH2_TRACE_PUBLICKEY);
  1875. infof(data, "SSH socket: %d\n", sock);
  1876. #endif /* CURL_LIBSSH2_DEBUG */
  1877. state(conn, SSH_S_STARTUP);
  1878. if(data->state.used_interface == Curl_if_multi)
  1879. result = ssh_multi_statemach(conn, done);
  1880. else {
  1881. result = ssh_easy_statemach(conn);
  1882. if(!result)
  1883. *done = TRUE;
  1884. }
  1885. return result;
  1886. }
  1887. /*
  1888. ***********************************************************************
  1889. *
  1890. * scp_perform()
  1891. *
  1892. * This is the actual DO function for SCP. Get a file according to
  1893. * the options previously setup.
  1894. */
  1895. static
  1896. CURLcode scp_perform(struct connectdata *conn,
  1897. bool *connected,
  1898. bool *dophase_done)
  1899. {
  1900. CURLcode result = CURLE_OK;
  1901. DEBUGF(infof(conn->data, "DO phase starts\n"));
  1902. *dophase_done = FALSE; /* not done yet */
  1903. /* start the first command in the DO phase */
  1904. state(conn, SSH_SCP_TRANS_INIT);
  1905. /* run the state-machine */
  1906. if(conn->data->state.used_interface == Curl_if_multi) {
  1907. result = ssh_multi_statemach(conn, dophase_done);
  1908. }
  1909. else {
  1910. result = ssh_easy_statemach(conn);
  1911. *dophase_done = TRUE; /* with the easy interface we are done here */
  1912. }
  1913. *connected = conn->bits.tcpconnect;
  1914. if(*dophase_done) {
  1915. DEBUGF(infof(conn->data, "DO phase is complete\n"));
  1916. }
  1917. return result;
  1918. }
  1919. /* called from multi.c while DOing */
  1920. static CURLcode scp_doing(struct connectdata *conn,
  1921. bool *dophase_done)
  1922. {
  1923. CURLcode result;
  1924. result = ssh_multi_statemach(conn, dophase_done);
  1925. if(*dophase_done) {
  1926. DEBUGF(infof(conn->data, "DO phase is complete\n"));
  1927. }
  1928. return result;
  1929. }
  1930. /*
  1931. * The DO function is generic for both protocols. There was previously two
  1932. * separate ones but this way means less duplicated code.
  1933. */
  1934. static CURLcode ssh_do(struct connectdata *conn, bool *done)
  1935. {
  1936. CURLcode res;
  1937. bool connected = 0;
  1938. struct SessionHandle *data = conn->data;
  1939. *done = FALSE; /* default to false */
  1940. /*
  1941. Since connections can be re-used between SessionHandles, this might be a
  1942. connection already existing but on a fresh SessionHandle struct so we must
  1943. make sure we have a good 'struct SSHPROTO' to play with. For new
  1944. connections, the struct SSHPROTO is allocated and setup in the
  1945. ssh_connect() function.
  1946. */
  1947. Curl_reset_reqproto(conn);
  1948. res = ssh_init(conn);
  1949. if(res)
  1950. return res;
  1951. data->req.size = -1; /* make sure this is unknown at this point */
  1952. Curl_pgrsSetUploadCounter(data, 0);
  1953. Curl_pgrsSetDownloadCounter(data, 0);
  1954. Curl_pgrsSetUploadSize(data, 0);
  1955. Curl_pgrsSetDownloadSize(data, 0);
  1956. if(conn->protocol & PROT_SCP)
  1957. res = scp_perform(conn, &connected, done);
  1958. else
  1959. res = sftp_perform(conn, &connected, done);
  1960. return res;
  1961. }
  1962. /* BLOCKING, but the function is using the state machine so the only reason this
  1963. is still blocking is that the multi interface code has no support for
  1964. disconnecting operations that takes a while */
  1965. static CURLcode scp_disconnect(struct connectdata *conn)
  1966. {
  1967. CURLcode result = CURLE_OK;
  1968. Curl_safefree(conn->data->state.proto.ssh);
  1969. conn->data->state.proto.ssh = NULL;
  1970. if(conn->proto.sshc.ssh_session) {
  1971. /* only if there's a session still around to use! */
  1972. state(conn, SSH_SESSION_DISCONNECT);
  1973. result = ssh_easy_statemach(conn);
  1974. }
  1975. return result;
  1976. }
  1977. /* generic done function for both SCP and SFTP called from their specific
  1978. done functions */
  1979. static CURLcode ssh_done(struct connectdata *conn, CURLcode status)
  1980. {
  1981. CURLcode result = CURLE_OK;
  1982. bool done = FALSE;
  1983. if(status == CURLE_OK) {
  1984. /* run the state-machine */
  1985. if(conn->data->state.used_interface == Curl_if_multi) {
  1986. result = ssh_multi_statemach(conn, &done);
  1987. }
  1988. else {
  1989. result = ssh_easy_statemach(conn);
  1990. done = TRUE;
  1991. }
  1992. }
  1993. else {
  1994. result = status;
  1995. done = TRUE;
  1996. }
  1997. if(done) {
  1998. struct SSHPROTO *sftp_scp = conn->data->state.proto.ssh;
  1999. Curl_safefree(sftp_scp->path);
  2000. sftp_scp->path = NULL;
  2001. Curl_pgrsDone(conn);
  2002. }
  2003. return result;
  2004. }
  2005. static CURLcode scp_done(struct connectdata *conn, CURLcode status,
  2006. bool premature)
  2007. {
  2008. (void)premature; /* not used */
  2009. if(status == CURLE_OK)
  2010. state(conn, SSH_SCP_DONE);
  2011. return ssh_done(conn, status);
  2012. }
  2013. /* return number of received (decrypted) bytes */
  2014. ssize_t Curl_scp_send(struct connectdata *conn, int sockindex,
  2015. const void *mem, size_t len)
  2016. {
  2017. ssize_t nwrite;
  2018. (void)sockindex; /* we only support SCP on the fixed known primary socket */
  2019. /* libssh2_channel_write() returns int! */
  2020. nwrite = (ssize_t)
  2021. libssh2_channel_write(conn->proto.sshc.ssh_channel, mem, len);
  2022. if(nwrite == LIBSSH2_ERROR_EAGAIN)
  2023. return 0;
  2024. return nwrite;
  2025. }
  2026. /*
  2027. * If the read would block (EWOULDBLOCK) we return -1. Otherwise we return
  2028. * a regular CURLcode value.
  2029. */
  2030. ssize_t Curl_scp_recv(struct connectdata *conn, int sockindex,
  2031. char *mem, size_t len)
  2032. {
  2033. ssize_t nread;
  2034. (void)sockindex; /* we only support SCP on the fixed known primary socket */
  2035. /* libssh2_channel_read() returns int */
  2036. nread = (ssize_t)
  2037. libssh2_channel_read(conn->proto.sshc.ssh_channel, mem, len);
  2038. return nread;
  2039. }
  2040. /*
  2041. * =============== SFTP ===============
  2042. */
  2043. /*
  2044. ***********************************************************************
  2045. *
  2046. * sftp_perform()
  2047. *
  2048. * This is the actual DO function for SFTP. Get a file/directory according to
  2049. * the options previously setup.
  2050. */
  2051. static
  2052. CURLcode sftp_perform(struct connectdata *conn,
  2053. bool *connected,
  2054. bool *dophase_done)
  2055. {
  2056. CURLcode result = CURLE_OK;
  2057. DEBUGF(infof(conn->data, "DO phase starts\n"));
  2058. *dophase_done = FALSE; /* not done yet */
  2059. /* start the first command in the DO phase */
  2060. state(conn, SSH_SFTP_QUOTE_INIT);
  2061. /* run the state-machine */
  2062. if(conn->data->state.used_interface == Curl_if_multi) {
  2063. result = ssh_multi_statemach(conn, dophase_done);
  2064. }
  2065. else {
  2066. result = ssh_easy_statemach(conn);
  2067. *dophase_done = TRUE; /* with the easy interface we are done here */
  2068. }
  2069. *connected = conn->bits.tcpconnect;
  2070. if(*dophase_done) {
  2071. DEBUGF(infof(conn->data, "DO phase is complete\n"));
  2072. }
  2073. return result;
  2074. }
  2075. /* called from multi.c while DOing */
  2076. static CURLcode sftp_doing(struct connectdata *conn,
  2077. bool *dophase_done)
  2078. {
  2079. CURLcode result;
  2080. result = ssh_multi_statemach(conn, dophase_done);
  2081. if(*dophase_done) {
  2082. DEBUGF(infof(conn->data, "DO phase is complete\n"));
  2083. }
  2084. return result;
  2085. }
  2086. /* BLOCKING, but the function is using the state machine so the only reason this
  2087. is still blocking is that the multi interface code has no support for
  2088. disconnecting operations that takes a while */
  2089. static CURLcode sftp_disconnect(struct connectdata *conn)
  2090. {
  2091. CURLcode result = CURLE_OK;
  2092. DEBUGF(infof(conn->data, "SSH DISCONNECT starts now\n"));
  2093. Curl_safefree(conn->data->state.proto.ssh);
  2094. conn->data->state.proto.ssh = NULL;
  2095. if(conn->proto.sshc.ssh_session) {
  2096. /* only if there's a session still around to use! */
  2097. state(conn, SSH_SFTP_SHUTDOWN);
  2098. result = ssh_easy_statemach(conn);
  2099. }
  2100. DEBUGF(infof(conn->data, "SSH DISCONNECT is done\n"));
  2101. return result;
  2102. }
  2103. static CURLcode sftp_done(struct connectdata *conn, CURLcode status,
  2104. bool premature)
  2105. {
  2106. struct ssh_conn *sshc = &conn->proto.sshc;
  2107. if(status == CURLE_OK) {
  2108. /* Before we shut down, see if there are any post-quote commands to send: */
  2109. if(!status && !premature && conn->data->set.postquote) {
  2110. sshc->nextstate = SSH_SFTP_CLOSE;
  2111. state(conn, SSH_SFTP_POSTQUOTE_INIT);
  2112. }
  2113. else
  2114. state(conn, SSH_SFTP_CLOSE);
  2115. }
  2116. return ssh_done(conn, status);
  2117. }
  2118. /* return number of sent bytes */
  2119. ssize_t Curl_sftp_send(struct connectdata *conn, int sockindex,
  2120. const void *mem, size_t len)
  2121. {
  2122. ssize_t nwrite; /* libssh2_sftp_write() used to return size_t in 0.14
  2123. but is changed to ssize_t in 0.15. These days we don't
  2124. support libssh2 0.15*/
  2125. (void)sockindex;
  2126. nwrite = libssh2_sftp_write(conn->proto.sshc.sftp_handle, mem, len);
  2127. if(nwrite == LIBSSH2_ERROR_EAGAIN)
  2128. return 0;
  2129. return nwrite;
  2130. }
  2131. /*
  2132. * Return number of received (decrypted) bytes
  2133. */
  2134. ssize_t Curl_sftp_recv(struct connectdata *conn, int sockindex,
  2135. char *mem, size_t len)
  2136. {
  2137. ssize_t nread;
  2138. (void)sockindex;
  2139. nread = libssh2_sftp_read(conn->proto.sshc.sftp_handle, mem, len);
  2140. return nread;
  2141. }
  2142. /* The get_pathname() function is being borrowed from OpenSSH sftp.c
  2143. version 4.6p1. */
  2144. /*
  2145. * Copyright (c) 2001-2004 Damien Miller <[email protected]>
  2146. *
  2147. * Permission to use, copy, modify, and distribute this software for any
  2148. * purpose with or without fee is hereby granted, provided that the above
  2149. * copyright notice and this permission notice appear in all copies.
  2150. *
  2151. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  2152. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  2153. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  2154. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  2155. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  2156. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  2157. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  2158. */
  2159. static CURLcode
  2160. get_pathname(const char **cpp, char **path)
  2161. {
  2162. const char *cp = *cpp, *end;
  2163. char quot;
  2164. u_int i, j;
  2165. static const char * const WHITESPACE = " \t\r\n";
  2166. cp += strspn(cp, WHITESPACE);
  2167. if(!*cp) {
  2168. *cpp = cp;
  2169. *path = NULL;
  2170. return CURLE_QUOTE_ERROR;
  2171. }
  2172. *path = malloc(strlen(cp) + 1);
  2173. if(*path == NULL)
  2174. return CURLE_OUT_OF_MEMORY;
  2175. /* Check for quoted filenames */
  2176. if(*cp == '\"' || *cp == '\'') {
  2177. quot = *cp++;
  2178. /* Search for terminating quote, unescape some chars */
  2179. for (i = j = 0; i <= strlen(cp); i++) {
  2180. if(cp[i] == quot) { /* Found quote */
  2181. i++;
  2182. (*path)[j] = '\0';
  2183. break;
  2184. }
  2185. if(cp[i] == '\0') { /* End of string */
  2186. /*error("Unterminated quote");*/
  2187. goto fail;
  2188. }
  2189. if(cp[i] == '\\') { /* Escaped characters */
  2190. i++;
  2191. if(cp[i] != '\'' && cp[i] != '\"' &&
  2192. cp[i] != '\\') {
  2193. /*error("Bad escaped character '\\%c'",
  2194. cp[i]);*/
  2195. goto fail;
  2196. }
  2197. }
  2198. (*path)[j++] = cp[i];
  2199. }
  2200. if(j == 0) {
  2201. /*error("Empty quotes");*/
  2202. goto fail;
  2203. }
  2204. *cpp = cp + i + strspn(cp + i, WHITESPACE);
  2205. }
  2206. else {
  2207. /* Read to end of filename */
  2208. end = strpbrk(cp, WHITESPACE);
  2209. if(end == NULL)
  2210. end = strchr(cp, '\0');
  2211. *cpp = end + strspn(end, WHITESPACE);
  2212. memcpy(*path, cp, end - cp);
  2213. (*path)[end - cp] = '\0';
  2214. }
  2215. return CURLE_OK;
  2216. fail:
  2217. Curl_safefree(*path);
  2218. *path = NULL;
  2219. return CURLE_QUOTE_ERROR;
  2220. }
  2221. static const char *sftp_libssh2_strerror(unsigned long err)
  2222. {
  2223. switch (err) {
  2224. case LIBSSH2_FX_NO_SUCH_FILE:
  2225. return "No such file or directory";
  2226. case LIBSSH2_FX_PERMISSION_DENIED:
  2227. return "Permission denied";
  2228. case LIBSSH2_FX_FAILURE:
  2229. return "Operation failed";
  2230. case LIBSSH2_FX_BAD_MESSAGE:
  2231. return "Bad message from SFTP server";
  2232. case LIBSSH2_FX_NO_CONNECTION:
  2233. return "Not connected to SFTP server";
  2234. case LIBSSH2_FX_CONNECTION_LOST:
  2235. return "Connection to SFTP server lost";
  2236. case LIBSSH2_FX_OP_UNSUPPORTED:
  2237. return "Operation not supported by SFTP server";
  2238. case LIBSSH2_FX_INVALID_HANDLE:
  2239. return "Invalid handle";
  2240. case LIBSSH2_FX_NO_SUCH_PATH:
  2241. return "No such file or directory";
  2242. case LIBSSH2_FX_FILE_ALREADY_EXISTS:
  2243. return "File already exists";
  2244. case LIBSSH2_FX_WRITE_PROTECT:
  2245. return "File is write protected";
  2246. case LIBSSH2_FX_NO_MEDIA:
  2247. return "No media";
  2248. case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
  2249. return "Disk full";
  2250. case LIBSSH2_FX_QUOTA_EXCEEDED:
  2251. return "User quota exceeded";
  2252. case LIBSSH2_FX_UNKNOWN_PRINCIPLE:
  2253. return "Unknown principle";
  2254. case LIBSSH2_FX_LOCK_CONFlICT:
  2255. return "File lock conflict";
  2256. case LIBSSH2_FX_DIR_NOT_EMPTY:
  2257. return "Directory not empty";
  2258. case LIBSSH2_FX_NOT_A_DIRECTORY:
  2259. return "Not a directory";
  2260. case LIBSSH2_FX_INVALID_FILENAME:
  2261. return "Invalid filename";
  2262. case LIBSSH2_FX_LINK_LOOP:
  2263. return "Link points to itself";
  2264. }
  2265. return "Unknown error in libssh2";
  2266. }
  2267. #endif /* USE_LIBSSH2 */