libssh2.c 118 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800
  1. /***************************************************************************
  2. * _ _ ____ _
  3. * Project ___| | | | _ \| |
  4. * / __| | | | |_) | |
  5. * | (__| |_| | _ <| |___
  6. * \___|\___/|_| \_\_____|
  7. *
  8. * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, 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 https://curl.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. * SPDX-License-Identifier: curl
  22. *
  23. ***************************************************************************/
  24. /* #define CURL_LIBSSH2_DEBUG */
  25. #include "curl_setup.h"
  26. #ifdef USE_LIBSSH2
  27. #include <limits.h>
  28. #ifdef HAVE_FCNTL_H
  29. #include <fcntl.h>
  30. #endif
  31. #ifdef HAVE_NETINET_IN_H
  32. #include <netinet/in.h>
  33. #endif
  34. #ifdef HAVE_ARPA_INET_H
  35. #include <arpa/inet.h>
  36. #endif
  37. #ifdef HAVE_NETDB_H
  38. #include <netdb.h>
  39. #endif
  40. #ifdef __VMS
  41. #include <in.h>
  42. #include <inet.h>
  43. #endif
  44. #include <curl/curl.h>
  45. #include "urldata.h"
  46. #include "sendf.h"
  47. #include "hostip.h"
  48. #include "progress.h"
  49. #include "transfer.h"
  50. #include "escape.h"
  51. #include "http.h" /* for HTTP proxy tunnel stuff */
  52. #include "ssh.h"
  53. #include "url.h"
  54. #include "speedcheck.h"
  55. #include "getinfo.h"
  56. #include "strdup.h"
  57. #include "strcase.h"
  58. #include "vtls/vtls.h"
  59. #include "cfilters.h"
  60. #include "connect.h"
  61. #include "inet_ntop.h"
  62. #include "parsedate.h" /* for the week day and month names */
  63. #include "sockaddr.h" /* required for Curl_sockaddr_storage */
  64. #include "strtoofft.h"
  65. #include "multiif.h"
  66. #include "select.h"
  67. #include "warnless.h"
  68. #include "curl_path.h"
  69. #include <curl_base64.h> /* for base64 encoding/decoding */
  70. #include <curl_sha256.h>
  71. /* The last 3 #include files should be in this order */
  72. #include "curl_printf.h"
  73. #include "curl_memory.h"
  74. #include "memdebug.h"
  75. #if LIBSSH2_VERSION_NUM >= 0x010206
  76. /* libssh2_sftp_statvfs and friends were added in 1.2.6 */
  77. #define HAS_STATVFS_SUPPORT 1
  78. #endif
  79. #define sftp_libssh2_realpath(s,p,t,m) \
  80. libssh2_sftp_symlink_ex((s), (p), curlx_uztoui(strlen(p)), \
  81. (t), (m), LIBSSH2_SFTP_REALPATH)
  82. /* Local functions: */
  83. static const char *sftp_libssh2_strerror(unsigned long err);
  84. static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc);
  85. static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc);
  86. static LIBSSH2_FREE_FUNC(my_libssh2_free);
  87. static CURLcode ssh_force_knownhost_key_type(struct Curl_easy *data);
  88. static CURLcode ssh_connect(struct Curl_easy *data, bool *done);
  89. static CURLcode ssh_multi_statemach(struct Curl_easy *data, bool *done);
  90. static CURLcode ssh_do(struct Curl_easy *data, bool *done);
  91. static CURLcode scp_done(struct Curl_easy *data, CURLcode c, bool premature);
  92. static CURLcode scp_doing(struct Curl_easy *data, bool *dophase_done);
  93. static CURLcode scp_disconnect(struct Curl_easy *data,
  94. struct connectdata *conn, bool dead_connection);
  95. static CURLcode sftp_done(struct Curl_easy *data, CURLcode, bool premature);
  96. static CURLcode sftp_doing(struct Curl_easy *data, bool *dophase_done);
  97. static CURLcode sftp_disconnect(struct Curl_easy *data,
  98. struct connectdata *conn, bool dead);
  99. static CURLcode sftp_perform(struct Curl_easy *data, bool *connected,
  100. bool *dophase_done);
  101. static int ssh_getsock(struct Curl_easy *data, struct connectdata *conn,
  102. curl_socket_t *sock);
  103. static CURLcode ssh_setup_connection(struct Curl_easy *data,
  104. struct connectdata *conn);
  105. static void ssh_attach(struct Curl_easy *data, struct connectdata *conn);
  106. /*
  107. * SCP protocol handler.
  108. */
  109. const struct Curl_handler Curl_handler_scp = {
  110. "SCP", /* scheme */
  111. ssh_setup_connection, /* setup_connection */
  112. ssh_do, /* do_it */
  113. scp_done, /* done */
  114. ZERO_NULL, /* do_more */
  115. ssh_connect, /* connect_it */
  116. ssh_multi_statemach, /* connecting */
  117. scp_doing, /* doing */
  118. ssh_getsock, /* proto_getsock */
  119. ssh_getsock, /* doing_getsock */
  120. ZERO_NULL, /* domore_getsock */
  121. ssh_getsock, /* perform_getsock */
  122. scp_disconnect, /* disconnect */
  123. ZERO_NULL, /* write_resp */
  124. ZERO_NULL, /* write_resp_hd */
  125. ZERO_NULL, /* connection_check */
  126. ssh_attach, /* attach */
  127. PORT_SSH, /* defport */
  128. CURLPROTO_SCP, /* protocol */
  129. CURLPROTO_SCP, /* family */
  130. PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION
  131. | PROTOPT_NOURLQUERY /* flags */
  132. };
  133. /*
  134. * SFTP protocol handler.
  135. */
  136. const struct Curl_handler Curl_handler_sftp = {
  137. "SFTP", /* scheme */
  138. ssh_setup_connection, /* setup_connection */
  139. ssh_do, /* do_it */
  140. sftp_done, /* done */
  141. ZERO_NULL, /* do_more */
  142. ssh_connect, /* connect_it */
  143. ssh_multi_statemach, /* connecting */
  144. sftp_doing, /* doing */
  145. ssh_getsock, /* proto_getsock */
  146. ssh_getsock, /* doing_getsock */
  147. ZERO_NULL, /* domore_getsock */
  148. ssh_getsock, /* perform_getsock */
  149. sftp_disconnect, /* disconnect */
  150. ZERO_NULL, /* write_resp */
  151. ZERO_NULL, /* write_resp_hd */
  152. ZERO_NULL, /* connection_check */
  153. ssh_attach, /* attach */
  154. PORT_SSH, /* defport */
  155. CURLPROTO_SFTP, /* protocol */
  156. CURLPROTO_SFTP, /* family */
  157. PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION
  158. | PROTOPT_NOURLQUERY /* flags */
  159. };
  160. static void
  161. kbd_callback(const char *name, int name_len, const char *instruction,
  162. int instruction_len, int num_prompts,
  163. const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts,
  164. LIBSSH2_USERAUTH_KBDINT_RESPONSE *responses,
  165. void **abstract)
  166. {
  167. struct Curl_easy *data = (struct Curl_easy *)*abstract;
  168. #ifdef CURL_LIBSSH2_DEBUG
  169. fprintf(stderr, "name=%s\n", name);
  170. fprintf(stderr, "name_len=%d\n", name_len);
  171. fprintf(stderr, "instruction=%s\n", instruction);
  172. fprintf(stderr, "instruction_len=%d\n", instruction_len);
  173. fprintf(stderr, "num_prompts=%d\n", num_prompts);
  174. #else
  175. (void)name;
  176. (void)name_len;
  177. (void)instruction;
  178. (void)instruction_len;
  179. #endif /* CURL_LIBSSH2_DEBUG */
  180. if(num_prompts == 1) {
  181. struct connectdata *conn = data->conn;
  182. responses[0].text = strdup(conn->passwd);
  183. responses[0].length =
  184. responses[0].text == NULL ? 0 : curlx_uztoui(strlen(conn->passwd));
  185. }
  186. (void)prompts;
  187. } /* kbd_callback */
  188. static CURLcode sftp_libssh2_error_to_CURLE(unsigned long err)
  189. {
  190. switch(err) {
  191. case LIBSSH2_FX_OK:
  192. return CURLE_OK;
  193. case LIBSSH2_FX_NO_SUCH_FILE:
  194. case LIBSSH2_FX_NO_SUCH_PATH:
  195. return CURLE_REMOTE_FILE_NOT_FOUND;
  196. case LIBSSH2_FX_PERMISSION_DENIED:
  197. case LIBSSH2_FX_WRITE_PROTECT:
  198. case LIBSSH2_FX_LOCK_CONFlICT:
  199. return CURLE_REMOTE_ACCESS_DENIED;
  200. case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
  201. case LIBSSH2_FX_QUOTA_EXCEEDED:
  202. return CURLE_REMOTE_DISK_FULL;
  203. case LIBSSH2_FX_FILE_ALREADY_EXISTS:
  204. return CURLE_REMOTE_FILE_EXISTS;
  205. case LIBSSH2_FX_DIR_NOT_EMPTY:
  206. return CURLE_QUOTE_ERROR;
  207. default:
  208. break;
  209. }
  210. return CURLE_SSH;
  211. }
  212. static CURLcode libssh2_session_error_to_CURLE(int err)
  213. {
  214. switch(err) {
  215. /* Ordered by order of appearance in libssh2.h */
  216. case LIBSSH2_ERROR_NONE:
  217. return CURLE_OK;
  218. /* This is the error returned by libssh2_scp_recv2
  219. * on unknown file */
  220. case LIBSSH2_ERROR_SCP_PROTOCOL:
  221. return CURLE_REMOTE_FILE_NOT_FOUND;
  222. case LIBSSH2_ERROR_SOCKET_NONE:
  223. return CURLE_COULDNT_CONNECT;
  224. case LIBSSH2_ERROR_ALLOC:
  225. return CURLE_OUT_OF_MEMORY;
  226. case LIBSSH2_ERROR_SOCKET_SEND:
  227. return CURLE_SEND_ERROR;
  228. case LIBSSH2_ERROR_HOSTKEY_INIT:
  229. case LIBSSH2_ERROR_HOSTKEY_SIGN:
  230. case LIBSSH2_ERROR_PUBLICKEY_UNRECOGNIZED:
  231. case LIBSSH2_ERROR_PUBLICKEY_UNVERIFIED:
  232. return CURLE_PEER_FAILED_VERIFICATION;
  233. case LIBSSH2_ERROR_PASSWORD_EXPIRED:
  234. return CURLE_LOGIN_DENIED;
  235. case LIBSSH2_ERROR_SOCKET_TIMEOUT:
  236. case LIBSSH2_ERROR_TIMEOUT:
  237. return CURLE_OPERATION_TIMEDOUT;
  238. case LIBSSH2_ERROR_EAGAIN:
  239. return CURLE_AGAIN;
  240. }
  241. return CURLE_SSH;
  242. }
  243. /* These functions are made to use the libcurl memory functions - NOT the
  244. debugmem functions, as that leads us to trigger on libssh2 memory leaks
  245. that are not ours to care for */
  246. static LIBSSH2_ALLOC_FUNC(my_libssh2_malloc)
  247. {
  248. (void)abstract; /* arg not used */
  249. return Curl_cmalloc(count);
  250. }
  251. static LIBSSH2_REALLOC_FUNC(my_libssh2_realloc)
  252. {
  253. (void)abstract; /* arg not used */
  254. return Curl_crealloc(ptr, count);
  255. }
  256. static LIBSSH2_FREE_FUNC(my_libssh2_free)
  257. {
  258. (void)abstract; /* arg not used */
  259. if(ptr) /* ssh2 agent sometimes call free with null ptr */
  260. Curl_cfree(ptr);
  261. }
  262. /*
  263. * SSH State machine related code
  264. */
  265. /* This is the ONLY way to change SSH state! */
  266. static void state(struct Curl_easy *data, sshstate nowstate)
  267. {
  268. struct connectdata *conn = data->conn;
  269. struct ssh_conn *sshc = &conn->proto.sshc;
  270. #if defined(DEBUGBUILD) && !defined(CURL_DISABLE_VERBOSE_STRINGS)
  271. /* for debug purposes */
  272. static const char * const names[] = {
  273. "SSH_STOP",
  274. "SSH_INIT",
  275. "SSH_S_STARTUP",
  276. "SSH_HOSTKEY",
  277. "SSH_AUTHLIST",
  278. "SSH_AUTH_PKEY_INIT",
  279. "SSH_AUTH_PKEY",
  280. "SSH_AUTH_PASS_INIT",
  281. "SSH_AUTH_PASS",
  282. "SSH_AUTH_AGENT_INIT",
  283. "SSH_AUTH_AGENT_LIST",
  284. "SSH_AUTH_AGENT",
  285. "SSH_AUTH_HOST_INIT",
  286. "SSH_AUTH_HOST",
  287. "SSH_AUTH_KEY_INIT",
  288. "SSH_AUTH_KEY",
  289. "SSH_AUTH_GSSAPI",
  290. "SSH_AUTH_DONE",
  291. "SSH_SFTP_INIT",
  292. "SSH_SFTP_REALPATH",
  293. "SSH_SFTP_QUOTE_INIT",
  294. "SSH_SFTP_POSTQUOTE_INIT",
  295. "SSH_SFTP_QUOTE",
  296. "SSH_SFTP_NEXT_QUOTE",
  297. "SSH_SFTP_QUOTE_STAT",
  298. "SSH_SFTP_QUOTE_SETSTAT",
  299. "SSH_SFTP_QUOTE_SYMLINK",
  300. "SSH_SFTP_QUOTE_MKDIR",
  301. "SSH_SFTP_QUOTE_RENAME",
  302. "SSH_SFTP_QUOTE_RMDIR",
  303. "SSH_SFTP_QUOTE_UNLINK",
  304. "SSH_SFTP_QUOTE_STATVFS",
  305. "SSH_SFTP_GETINFO",
  306. "SSH_SFTP_FILETIME",
  307. "SSH_SFTP_TRANS_INIT",
  308. "SSH_SFTP_UPLOAD_INIT",
  309. "SSH_SFTP_CREATE_DIRS_INIT",
  310. "SSH_SFTP_CREATE_DIRS",
  311. "SSH_SFTP_CREATE_DIRS_MKDIR",
  312. "SSH_SFTP_READDIR_INIT",
  313. "SSH_SFTP_READDIR",
  314. "SSH_SFTP_READDIR_LINK",
  315. "SSH_SFTP_READDIR_BOTTOM",
  316. "SSH_SFTP_READDIR_DONE",
  317. "SSH_SFTP_DOWNLOAD_INIT",
  318. "SSH_SFTP_DOWNLOAD_STAT",
  319. "SSH_SFTP_CLOSE",
  320. "SSH_SFTP_SHUTDOWN",
  321. "SSH_SCP_TRANS_INIT",
  322. "SSH_SCP_UPLOAD_INIT",
  323. "SSH_SCP_DOWNLOAD_INIT",
  324. "SSH_SCP_DOWNLOAD",
  325. "SSH_SCP_DONE",
  326. "SSH_SCP_SEND_EOF",
  327. "SSH_SCP_WAIT_EOF",
  328. "SSH_SCP_WAIT_CLOSE",
  329. "SSH_SCP_CHANNEL_FREE",
  330. "SSH_SESSION_DISCONNECT",
  331. "SSH_SESSION_FREE",
  332. "QUIT"
  333. };
  334. /* a precaution to make sure the lists are in sync */
  335. DEBUGASSERT(sizeof(names)/sizeof(names[0]) == SSH_LAST);
  336. if(sshc->state != nowstate) {
  337. infof(data, "SFTP %p state change from %s to %s",
  338. (void *)sshc, names[sshc->state], names[nowstate]);
  339. }
  340. #endif
  341. sshc->state = nowstate;
  342. }
  343. #ifdef HAVE_LIBSSH2_KNOWNHOST_API
  344. static int sshkeycallback(CURL *easy,
  345. const struct curl_khkey *knownkey, /* known */
  346. const struct curl_khkey *foundkey, /* found */
  347. enum curl_khmatch match,
  348. void *clientp)
  349. {
  350. (void)easy;
  351. (void)knownkey;
  352. (void)foundkey;
  353. (void)clientp;
  354. /* we only allow perfect matches, and we reject everything else */
  355. return (match != CURLKHMATCH_OK) ? CURLKHSTAT_REJECT : CURLKHSTAT_FINE;
  356. }
  357. #endif
  358. /*
  359. * Earlier libssh2 versions did not have the ability to seek to 64-bit
  360. * positions with 32-bit size_t.
  361. */
  362. #ifdef HAVE_LIBSSH2_SFTP_SEEK64
  363. #define SFTP_SEEK(x,y) libssh2_sftp_seek64(x, (libssh2_uint64_t)y)
  364. #else
  365. #define SFTP_SEEK(x,y) libssh2_sftp_seek(x, (size_t)y)
  366. #endif
  367. /*
  368. * Earlier libssh2 versions did not do SCP properly beyond 32-bit sizes on
  369. * 32-bit architectures so we check of the necessary function is present.
  370. */
  371. #ifndef HAVE_LIBSSH2_SCP_SEND64
  372. #define SCP_SEND(a,b,c,d) libssh2_scp_send_ex(a, b, (int)(c), (size_t)d, 0, 0)
  373. #else
  374. #define SCP_SEND(a,b,c,d) libssh2_scp_send64(a, b, (int)(c), \
  375. (libssh2_int64_t)d, 0, 0)
  376. #endif
  377. /*
  378. * libssh2 1.2.8 fixed the problem with 32-bit ints used for sockets on win64.
  379. */
  380. #ifdef HAVE_LIBSSH2_SESSION_HANDSHAKE
  381. #define session_startup(x,y) libssh2_session_handshake(x, y)
  382. #else
  383. #define session_startup(x,y) libssh2_session_startup(x, (int)y)
  384. #endif
  385. static enum curl_khtype convert_ssh2_keytype(int sshkeytype)
  386. {
  387. enum curl_khtype keytype = CURLKHTYPE_UNKNOWN;
  388. switch(sshkeytype) {
  389. case LIBSSH2_HOSTKEY_TYPE_RSA:
  390. keytype = CURLKHTYPE_RSA;
  391. break;
  392. case LIBSSH2_HOSTKEY_TYPE_DSS:
  393. keytype = CURLKHTYPE_DSS;
  394. break;
  395. #ifdef LIBSSH2_HOSTKEY_TYPE_ECDSA_256
  396. case LIBSSH2_HOSTKEY_TYPE_ECDSA_256:
  397. keytype = CURLKHTYPE_ECDSA;
  398. break;
  399. #endif
  400. #ifdef LIBSSH2_HOSTKEY_TYPE_ECDSA_384
  401. case LIBSSH2_HOSTKEY_TYPE_ECDSA_384:
  402. keytype = CURLKHTYPE_ECDSA;
  403. break;
  404. #endif
  405. #ifdef LIBSSH2_HOSTKEY_TYPE_ECDSA_521
  406. case LIBSSH2_HOSTKEY_TYPE_ECDSA_521:
  407. keytype = CURLKHTYPE_ECDSA;
  408. break;
  409. #endif
  410. #ifdef LIBSSH2_HOSTKEY_TYPE_ED25519
  411. case LIBSSH2_HOSTKEY_TYPE_ED25519:
  412. keytype = CURLKHTYPE_ED25519;
  413. break;
  414. #endif
  415. }
  416. return keytype;
  417. }
  418. static CURLcode ssh_knownhost(struct Curl_easy *data)
  419. {
  420. int sshkeytype = 0;
  421. size_t keylen = 0;
  422. int rc = 0;
  423. CURLcode result = CURLE_OK;
  424. #ifdef HAVE_LIBSSH2_KNOWNHOST_API
  425. if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
  426. /* we are asked to verify the host against a file */
  427. struct connectdata *conn = data->conn;
  428. struct ssh_conn *sshc = &conn->proto.sshc;
  429. struct libssh2_knownhost *host = NULL;
  430. const char *remotekey = libssh2_session_hostkey(sshc->ssh_session,
  431. &keylen, &sshkeytype);
  432. int keycheck = LIBSSH2_KNOWNHOST_CHECK_FAILURE;
  433. int keybit = 0;
  434. if(remotekey) {
  435. /*
  436. * A subject to figure out is what hostname we need to pass in here.
  437. * What hostname does OpenSSH store in its file if an IDN name is
  438. * used?
  439. */
  440. enum curl_khmatch keymatch;
  441. curl_sshkeycallback func =
  442. data->set.ssh_keyfunc ? data->set.ssh_keyfunc : sshkeycallback;
  443. struct curl_khkey knownkey;
  444. struct curl_khkey *knownkeyp = NULL;
  445. struct curl_khkey foundkey;
  446. switch(sshkeytype) {
  447. case LIBSSH2_HOSTKEY_TYPE_RSA:
  448. keybit = LIBSSH2_KNOWNHOST_KEY_SSHRSA;
  449. break;
  450. case LIBSSH2_HOSTKEY_TYPE_DSS:
  451. keybit = LIBSSH2_KNOWNHOST_KEY_SSHDSS;
  452. break;
  453. #ifdef LIBSSH2_HOSTKEY_TYPE_ECDSA_256
  454. case LIBSSH2_HOSTKEY_TYPE_ECDSA_256:
  455. keybit = LIBSSH2_KNOWNHOST_KEY_ECDSA_256;
  456. break;
  457. #endif
  458. #ifdef LIBSSH2_HOSTKEY_TYPE_ECDSA_384
  459. case LIBSSH2_HOSTKEY_TYPE_ECDSA_384:
  460. keybit = LIBSSH2_KNOWNHOST_KEY_ECDSA_384;
  461. break;
  462. #endif
  463. #ifdef LIBSSH2_HOSTKEY_TYPE_ECDSA_521
  464. case LIBSSH2_HOSTKEY_TYPE_ECDSA_521:
  465. keybit = LIBSSH2_KNOWNHOST_KEY_ECDSA_521;
  466. break;
  467. #endif
  468. #ifdef LIBSSH2_HOSTKEY_TYPE_ED25519
  469. case LIBSSH2_HOSTKEY_TYPE_ED25519:
  470. keybit = LIBSSH2_KNOWNHOST_KEY_ED25519;
  471. break;
  472. #endif
  473. default:
  474. infof(data, "unsupported key type, cannot check knownhosts");
  475. keybit = 0;
  476. break;
  477. }
  478. if(!keybit)
  479. /* no check means failure! */
  480. rc = CURLKHSTAT_REJECT;
  481. else {
  482. #ifdef HAVE_LIBSSH2_KNOWNHOST_CHECKP
  483. keycheck = libssh2_knownhost_checkp(sshc->kh,
  484. conn->host.name,
  485. (conn->remote_port != PORT_SSH) ?
  486. conn->remote_port : -1,
  487. remotekey, keylen,
  488. LIBSSH2_KNOWNHOST_TYPE_PLAIN|
  489. LIBSSH2_KNOWNHOST_KEYENC_RAW|
  490. keybit,
  491. &host);
  492. #else
  493. keycheck = libssh2_knownhost_check(sshc->kh,
  494. conn->host.name,
  495. remotekey, keylen,
  496. LIBSSH2_KNOWNHOST_TYPE_PLAIN|
  497. LIBSSH2_KNOWNHOST_KEYENC_RAW|
  498. keybit,
  499. &host);
  500. #endif
  501. infof(data, "SSH host check: %d, key: %s", keycheck,
  502. (keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH) ?
  503. host->key : "<none>");
  504. /* setup 'knownkey' */
  505. if(keycheck <= LIBSSH2_KNOWNHOST_CHECK_MISMATCH) {
  506. knownkey.key = host->key;
  507. knownkey.len = 0;
  508. knownkey.keytype = convert_ssh2_keytype(sshkeytype);
  509. knownkeyp = &knownkey;
  510. }
  511. /* setup 'foundkey' */
  512. foundkey.key = remotekey;
  513. foundkey.len = keylen;
  514. foundkey.keytype = convert_ssh2_keytype(sshkeytype);
  515. /*
  516. * if any of the LIBSSH2_KNOWNHOST_CHECK_* defines and the
  517. * curl_khmatch enum are ever modified, we need to introduce a
  518. * translation table here!
  519. */
  520. keymatch = (enum curl_khmatch)keycheck;
  521. /* Ask the callback how to behave */
  522. Curl_set_in_callback(data, TRUE);
  523. rc = func(data, knownkeyp, /* from the knownhosts file */
  524. &foundkey, /* from the remote host */
  525. keymatch, data->set.ssh_keyfunc_userp);
  526. Curl_set_in_callback(data, FALSE);
  527. }
  528. }
  529. else
  530. /* no remotekey means failure! */
  531. rc = CURLKHSTAT_REJECT;
  532. switch(rc) {
  533. default: /* unknown return codes will equal reject */
  534. case CURLKHSTAT_REJECT:
  535. state(data, SSH_SESSION_FREE);
  536. FALLTHROUGH();
  537. case CURLKHSTAT_DEFER:
  538. /* DEFER means bail out but keep the SSH_HOSTKEY state */
  539. result = sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
  540. break;
  541. case CURLKHSTAT_FINE_REPLACE:
  542. /* remove old host+key that does not match */
  543. if(host)
  544. libssh2_knownhost_del(sshc->kh, host);
  545. FALLTHROUGH();
  546. case CURLKHSTAT_FINE:
  547. case CURLKHSTAT_FINE_ADD_TO_FILE:
  548. /* proceed */
  549. if(keycheck != LIBSSH2_KNOWNHOST_CHECK_MATCH) {
  550. /* the found host+key did not match but has been told to be fine
  551. anyway so we add it in memory */
  552. int addrc = libssh2_knownhost_add(sshc->kh,
  553. conn->host.name, NULL,
  554. remotekey, keylen,
  555. LIBSSH2_KNOWNHOST_TYPE_PLAIN|
  556. LIBSSH2_KNOWNHOST_KEYENC_RAW|
  557. keybit, NULL);
  558. if(addrc)
  559. infof(data, "WARNING: adding the known host %s failed",
  560. conn->host.name);
  561. else if(rc == CURLKHSTAT_FINE_ADD_TO_FILE ||
  562. rc == CURLKHSTAT_FINE_REPLACE) {
  563. /* now we write the entire in-memory list of known hosts to the
  564. known_hosts file */
  565. int wrc =
  566. libssh2_knownhost_writefile(sshc->kh,
  567. data->set.str[STRING_SSH_KNOWNHOSTS],
  568. LIBSSH2_KNOWNHOST_FILE_OPENSSH);
  569. if(wrc) {
  570. infof(data, "WARNING: writing %s failed",
  571. data->set.str[STRING_SSH_KNOWNHOSTS]);
  572. }
  573. }
  574. }
  575. break;
  576. }
  577. }
  578. #else /* HAVE_LIBSSH2_KNOWNHOST_API */
  579. (void)data;
  580. #endif
  581. return result;
  582. }
  583. static CURLcode ssh_check_fingerprint(struct Curl_easy *data)
  584. {
  585. struct connectdata *conn = data->conn;
  586. struct ssh_conn *sshc = &conn->proto.sshc;
  587. const char *pubkey_md5 = data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5];
  588. const char *pubkey_sha256 = data->set.str[STRING_SSH_HOST_PUBLIC_KEY_SHA256];
  589. infof(data, "SSH MD5 public key: %s",
  590. pubkey_md5 != NULL ? pubkey_md5 : "NULL");
  591. infof(data, "SSH SHA256 public key: %s",
  592. pubkey_sha256 != NULL ? pubkey_sha256 : "NULL");
  593. if(pubkey_sha256) {
  594. const char *fingerprint = NULL;
  595. char *fingerprint_b64 = NULL;
  596. size_t fingerprint_b64_len;
  597. size_t pub_pos = 0;
  598. size_t b64_pos = 0;
  599. #ifdef LIBSSH2_HOSTKEY_HASH_SHA256
  600. /* The fingerprint points to static storage (!), do not free() it. */
  601. fingerprint = libssh2_hostkey_hash(sshc->ssh_session,
  602. LIBSSH2_HOSTKEY_HASH_SHA256);
  603. #else
  604. const char *hostkey;
  605. size_t len = 0;
  606. unsigned char hash[32];
  607. hostkey = libssh2_session_hostkey(sshc->ssh_session, &len, NULL);
  608. if(hostkey) {
  609. if(!Curl_sha256it(hash, (const unsigned char *) hostkey, len))
  610. fingerprint = (char *) hash;
  611. }
  612. #endif
  613. if(!fingerprint) {
  614. failf(data,
  615. "Denied establishing ssh session: sha256 fingerprint "
  616. "not available");
  617. state(data, SSH_SESSION_FREE);
  618. sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
  619. return sshc->actualcode;
  620. }
  621. /* The length of fingerprint is 32 bytes for SHA256.
  622. * See libssh2_hostkey_hash documentation. */
  623. if(Curl_base64_encode(fingerprint, 32, &fingerprint_b64,
  624. &fingerprint_b64_len) != CURLE_OK) {
  625. state(data, SSH_SESSION_FREE);
  626. sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
  627. return sshc->actualcode;
  628. }
  629. if(!fingerprint_b64) {
  630. failf(data, "sha256 fingerprint could not be encoded");
  631. state(data, SSH_SESSION_FREE);
  632. sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
  633. return sshc->actualcode;
  634. }
  635. infof(data, "SSH SHA256 fingerprint: %s", fingerprint_b64);
  636. /* Find the position of any = padding characters in the public key */
  637. while((pubkey_sha256[pub_pos] != '=') && pubkey_sha256[pub_pos]) {
  638. pub_pos++;
  639. }
  640. /* Find the position of any = padding characters in the base64 coded
  641. * hostkey fingerprint */
  642. while((fingerprint_b64[b64_pos] != '=') && fingerprint_b64[b64_pos]) {
  643. b64_pos++;
  644. }
  645. /* Before we authenticate we check the hostkey's sha256 fingerprint
  646. * against a known fingerprint, if available.
  647. */
  648. if((pub_pos != b64_pos) ||
  649. strncmp(fingerprint_b64, pubkey_sha256, pub_pos)) {
  650. failf(data,
  651. "Denied establishing ssh session: mismatch sha256 fingerprint. "
  652. "Remote %s is not equal to %s", fingerprint_b64, pubkey_sha256);
  653. free(fingerprint_b64);
  654. state(data, SSH_SESSION_FREE);
  655. sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
  656. return sshc->actualcode;
  657. }
  658. free(fingerprint_b64);
  659. infof(data, "SHA256 checksum match");
  660. }
  661. if(pubkey_md5) {
  662. char md5buffer[33];
  663. const char *fingerprint = NULL;
  664. fingerprint = libssh2_hostkey_hash(sshc->ssh_session,
  665. LIBSSH2_HOSTKEY_HASH_MD5);
  666. if(fingerprint) {
  667. /* The fingerprint points to static storage (!), do not free() it. */
  668. int i;
  669. for(i = 0; i < 16; i++) {
  670. msnprintf(&md5buffer[i*2], 3, "%02x", (unsigned char) fingerprint[i]);
  671. }
  672. infof(data, "SSH MD5 fingerprint: %s", md5buffer);
  673. }
  674. /* This does NOT verify the length of 'pubkey_md5' separately, which will
  675. make the comparison below fail unless it is exactly 32 characters */
  676. if(!fingerprint || !strcasecompare(md5buffer, pubkey_md5)) {
  677. if(fingerprint) {
  678. failf(data,
  679. "Denied establishing ssh session: mismatch md5 fingerprint. "
  680. "Remote %s is not equal to %s", md5buffer, pubkey_md5);
  681. }
  682. else {
  683. failf(data,
  684. "Denied establishing ssh session: md5 fingerprint "
  685. "not available");
  686. }
  687. state(data, SSH_SESSION_FREE);
  688. sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
  689. return sshc->actualcode;
  690. }
  691. infof(data, "MD5 checksum match");
  692. }
  693. if(!pubkey_md5 && !pubkey_sha256) {
  694. if(data->set.ssh_hostkeyfunc) {
  695. size_t keylen = 0;
  696. int sshkeytype = 0;
  697. int rc = 0;
  698. /* we handle the process to the callback */
  699. const char *remotekey = libssh2_session_hostkey(sshc->ssh_session,
  700. &keylen, &sshkeytype);
  701. if(remotekey) {
  702. enum curl_khtype keytype = convert_ssh2_keytype(sshkeytype);
  703. Curl_set_in_callback(data, TRUE);
  704. rc = data->set.ssh_hostkeyfunc(data->set.ssh_hostkeyfunc_userp,
  705. (int)keytype, remotekey, keylen);
  706. Curl_set_in_callback(data, FALSE);
  707. if(rc!= CURLKHMATCH_OK) {
  708. state(data, SSH_SESSION_FREE);
  709. sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
  710. return sshc->actualcode;
  711. }
  712. }
  713. else {
  714. state(data, SSH_SESSION_FREE);
  715. sshc->actualcode = CURLE_PEER_FAILED_VERIFICATION;
  716. return sshc->actualcode;
  717. }
  718. return CURLE_OK;
  719. }
  720. else {
  721. return ssh_knownhost(data);
  722. }
  723. }
  724. else {
  725. /* as we already matched, we skip the check for known hosts */
  726. return CURLE_OK;
  727. }
  728. }
  729. /*
  730. * ssh_force_knownhost_key_type() will check the known hosts file and try to
  731. * force a specific public key type from the server if an entry is found.
  732. */
  733. static CURLcode ssh_force_knownhost_key_type(struct Curl_easy *data)
  734. {
  735. CURLcode result = CURLE_OK;
  736. #ifdef HAVE_LIBSSH2_KNOWNHOST_API
  737. #ifdef LIBSSH2_KNOWNHOST_KEY_ED25519
  738. static const char * const hostkey_method_ssh_ed25519
  739. = "ssh-ed25519";
  740. #endif
  741. #ifdef LIBSSH2_KNOWNHOST_KEY_ECDSA_521
  742. static const char * const hostkey_method_ssh_ecdsa_521
  743. = "ecdsa-sha2-nistp521";
  744. #endif
  745. #ifdef LIBSSH2_KNOWNHOST_KEY_ECDSA_384
  746. static const char * const hostkey_method_ssh_ecdsa_384
  747. = "ecdsa-sha2-nistp384";
  748. #endif
  749. #ifdef LIBSSH2_KNOWNHOST_KEY_ECDSA_256
  750. static const char * const hostkey_method_ssh_ecdsa_256
  751. = "ecdsa-sha2-nistp256";
  752. #endif
  753. static const char * const hostkey_method_ssh_rsa
  754. = "ssh-rsa";
  755. static const char * const hostkey_method_ssh_rsa_all
  756. = "rsa-sha2-256,rsa-sha2-512,ssh-rsa";
  757. static const char * const hostkey_method_ssh_dss
  758. = "ssh-dss";
  759. const char *hostkey_method = NULL;
  760. struct connectdata *conn = data->conn;
  761. struct ssh_conn *sshc = &conn->proto.sshc;
  762. struct libssh2_knownhost* store = NULL;
  763. const char *kh_name_end = NULL;
  764. size_t kh_name_size = 0;
  765. int port = 0;
  766. bool found = FALSE;
  767. if(sshc->kh && !data->set.str[STRING_SSH_HOST_PUBLIC_KEY_MD5]) {
  768. /* lets try to find our host in the known hosts file */
  769. while(!libssh2_knownhost_get(sshc->kh, &store, store)) {
  770. /* For non-standard ports, the name will be enclosed in */
  771. /* square brackets, followed by a colon and the port */
  772. if(store) {
  773. if(store->name) {
  774. if(store->name[0] == '[') {
  775. kh_name_end = strstr(store->name, "]:");
  776. if(!kh_name_end) {
  777. infof(data, "Invalid host pattern %s in %s",
  778. store->name, data->set.str[STRING_SSH_KNOWNHOSTS]);
  779. continue;
  780. }
  781. port = atoi(kh_name_end + 2);
  782. if(kh_name_end && (port == conn->remote_port)) {
  783. kh_name_size = strlen(store->name) - 1 - strlen(kh_name_end);
  784. if(strncmp(store->name + 1,
  785. conn->host.name, kh_name_size) == 0) {
  786. found = TRUE;
  787. break;
  788. }
  789. }
  790. }
  791. else if(strcmp(store->name, conn->host.name) == 0) {
  792. found = TRUE;
  793. break;
  794. }
  795. }
  796. else {
  797. found = TRUE;
  798. break;
  799. }
  800. }
  801. }
  802. if(found) {
  803. int rc;
  804. infof(data, "Found host %s in %s",
  805. conn->host.name, data->set.str[STRING_SSH_KNOWNHOSTS]);
  806. switch(store->typemask & LIBSSH2_KNOWNHOST_KEY_MASK) {
  807. #ifdef LIBSSH2_KNOWNHOST_KEY_ED25519
  808. case LIBSSH2_KNOWNHOST_KEY_ED25519:
  809. hostkey_method = hostkey_method_ssh_ed25519;
  810. break;
  811. #endif
  812. #ifdef LIBSSH2_KNOWNHOST_KEY_ECDSA_521
  813. case LIBSSH2_KNOWNHOST_KEY_ECDSA_521:
  814. hostkey_method = hostkey_method_ssh_ecdsa_521;
  815. break;
  816. #endif
  817. #ifdef LIBSSH2_KNOWNHOST_KEY_ECDSA_384
  818. case LIBSSH2_KNOWNHOST_KEY_ECDSA_384:
  819. hostkey_method = hostkey_method_ssh_ecdsa_384;
  820. break;
  821. #endif
  822. #ifdef LIBSSH2_KNOWNHOST_KEY_ECDSA_256
  823. case LIBSSH2_KNOWNHOST_KEY_ECDSA_256:
  824. hostkey_method = hostkey_method_ssh_ecdsa_256;
  825. break;
  826. #endif
  827. case LIBSSH2_KNOWNHOST_KEY_SSHRSA:
  828. #ifdef HAVE_LIBSSH2_VERSION
  829. if(libssh2_version(0x010900))
  830. /* since 1.9.0 libssh2_session_method_pref() works as expected */
  831. hostkey_method = hostkey_method_ssh_rsa_all;
  832. else
  833. #endif
  834. /* old libssh2 which cannot correctly remove unsupported methods due
  835. * to bug in src/kex.c or does not support the new methods anyways.
  836. */
  837. hostkey_method = hostkey_method_ssh_rsa;
  838. break;
  839. case LIBSSH2_KNOWNHOST_KEY_SSHDSS:
  840. hostkey_method = hostkey_method_ssh_dss;
  841. break;
  842. case LIBSSH2_KNOWNHOST_KEY_RSA1:
  843. failf(data, "Found host key type RSA1 which is not supported");
  844. return CURLE_SSH;
  845. default:
  846. failf(data, "Unknown host key type: %i",
  847. (store->typemask & LIBSSH2_KNOWNHOST_KEY_MASK));
  848. return CURLE_SSH;
  849. }
  850. infof(data, "Set \"%s\" as SSH hostkey type", hostkey_method);
  851. rc = libssh2_session_method_pref(sshc->ssh_session,
  852. LIBSSH2_METHOD_HOSTKEY, hostkey_method);
  853. if(rc) {
  854. char *errmsg = NULL;
  855. int errlen;
  856. libssh2_session_last_error(sshc->ssh_session, &errmsg, &errlen, 0);
  857. failf(data, "libssh2: %s", errmsg);
  858. result = libssh2_session_error_to_CURLE(rc);
  859. }
  860. }
  861. else {
  862. infof(data, "Did not find host %s in %s",
  863. conn->host.name, data->set.str[STRING_SSH_KNOWNHOSTS]);
  864. }
  865. }
  866. #endif /* HAVE_LIBSSH2_KNOWNHOST_API */
  867. return result;
  868. }
  869. static CURLcode sftp_quote(struct Curl_easy *data,
  870. struct ssh_conn *sshc,
  871. struct SSHPROTO *sshp)
  872. {
  873. const char *cp;
  874. CURLcode result = CURLE_OK;
  875. /*
  876. * Support some of the "FTP" commands
  877. *
  878. * 'sshc->quote_item' is already verified to be non-NULL before it
  879. * switched to this state.
  880. */
  881. char *cmd = sshc->quote_item->data;
  882. sshc->acceptfail = FALSE;
  883. /* if a command starts with an asterisk, which a legal SFTP command never
  884. can, the command will be allowed to fail without it causing any
  885. aborts or cancels etc. It will cause libcurl to act as if the command
  886. is successful, whatever the server responds. */
  887. if(cmd[0] == '*') {
  888. cmd++;
  889. sshc->acceptfail = TRUE;
  890. }
  891. if(strcasecompare("pwd", cmd)) {
  892. /* output debug output if that is requested */
  893. char *tmp = aprintf("257 \"%s\" is current directory.\n", sshp->path);
  894. if(!tmp)
  895. return CURLE_OUT_OF_MEMORY;
  896. Curl_debug(data, CURLINFO_HEADER_OUT, (char *)"PWD\n", 4);
  897. Curl_debug(data, CURLINFO_HEADER_IN, tmp, strlen(tmp));
  898. /* this sends an FTP-like "header" to the header callback so that the
  899. current directory can be read very similar to how it is read when
  900. using ordinary FTP. */
  901. result = Curl_client_write(data, CLIENTWRITE_HEADER, tmp, strlen(tmp));
  902. free(tmp);
  903. if(!result)
  904. state(data, SSH_SFTP_NEXT_QUOTE);
  905. return result;
  906. }
  907. /*
  908. * the arguments following the command must be separated from the
  909. * command with a space so we can check for it unconditionally
  910. */
  911. cp = strchr(cmd, ' ');
  912. if(!cp) {
  913. failf(data, "Syntax error command '%s', missing parameter", cmd);
  914. return result;
  915. }
  916. /*
  917. * also, every command takes at least one argument so we get that
  918. * first argument right now
  919. */
  920. result = Curl_get_pathname(&cp, &sshc->quote_path1, sshc->homedir);
  921. if(result) {
  922. if(result != CURLE_OUT_OF_MEMORY)
  923. failf(data, "Syntax error: Bad first parameter to '%s'", cmd);
  924. return result;
  925. }
  926. /*
  927. * SFTP is a binary protocol, so we do not send text commands to the server.
  928. * Instead, we scan for commands used by OpenSSH's sftp program and call the
  929. * appropriate libssh2 functions.
  930. */
  931. if(strncasecompare(cmd, "chgrp ", 6) ||
  932. strncasecompare(cmd, "chmod ", 6) ||
  933. strncasecompare(cmd, "chown ", 6) ||
  934. strncasecompare(cmd, "atime ", 6) ||
  935. strncasecompare(cmd, "mtime ", 6)) {
  936. /* attribute change */
  937. /* sshc->quote_path1 contains the mode to set */
  938. /* get the destination */
  939. result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir);
  940. if(result) {
  941. if(result != CURLE_OUT_OF_MEMORY)
  942. failf(data, "Syntax error in %s: Bad second parameter", cmd);
  943. Curl_safefree(sshc->quote_path1);
  944. return result;
  945. }
  946. memset(&sshp->quote_attrs, 0, sizeof(LIBSSH2_SFTP_ATTRIBUTES));
  947. state(data, SSH_SFTP_QUOTE_STAT);
  948. return result;
  949. }
  950. if(strncasecompare(cmd, "ln ", 3) ||
  951. strncasecompare(cmd, "symlink ", 8)) {
  952. /* symbolic linking */
  953. /* sshc->quote_path1 is the source */
  954. /* get the destination */
  955. result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir);
  956. if(result) {
  957. if(result != CURLE_OUT_OF_MEMORY)
  958. failf(data, "Syntax error in ln/symlink: Bad second parameter");
  959. Curl_safefree(sshc->quote_path1);
  960. return result;
  961. }
  962. state(data, SSH_SFTP_QUOTE_SYMLINK);
  963. return result;
  964. }
  965. else if(strncasecompare(cmd, "mkdir ", 6)) {
  966. /* create dir */
  967. state(data, SSH_SFTP_QUOTE_MKDIR);
  968. return result;
  969. }
  970. else if(strncasecompare(cmd, "rename ", 7)) {
  971. /* rename file */
  972. /* first param is the source path */
  973. /* second param is the dest. path */
  974. result = Curl_get_pathname(&cp, &sshc->quote_path2, sshc->homedir);
  975. if(result) {
  976. if(result != CURLE_OUT_OF_MEMORY)
  977. failf(data, "Syntax error in rename: Bad second parameter");
  978. Curl_safefree(sshc->quote_path1);
  979. return result;
  980. }
  981. state(data, SSH_SFTP_QUOTE_RENAME);
  982. return result;
  983. }
  984. else if(strncasecompare(cmd, "rmdir ", 6)) {
  985. /* delete dir */
  986. state(data, SSH_SFTP_QUOTE_RMDIR);
  987. return result;
  988. }
  989. else if(strncasecompare(cmd, "rm ", 3)) {
  990. state(data, SSH_SFTP_QUOTE_UNLINK);
  991. return result;
  992. }
  993. #ifdef HAS_STATVFS_SUPPORT
  994. else if(strncasecompare(cmd, "statvfs ", 8)) {
  995. state(data, SSH_SFTP_QUOTE_STATVFS);
  996. return result;
  997. }
  998. #endif
  999. failf(data, "Unknown SFTP command");
  1000. Curl_safefree(sshc->quote_path1);
  1001. Curl_safefree(sshc->quote_path2);
  1002. return CURLE_QUOTE_ERROR;
  1003. }
  1004. static CURLcode
  1005. sftp_upload_init(struct Curl_easy *data,
  1006. struct ssh_conn *sshc,
  1007. struct SSHPROTO *sshp,
  1008. bool *blockp)
  1009. {
  1010. unsigned long flags;
  1011. /*
  1012. * NOTE!!! libssh2 requires that the destination path is a full path
  1013. * that includes the destination file and name OR ends in a "/"
  1014. * If this is not done the destination file will be named the
  1015. * same name as the last directory in the path.
  1016. */
  1017. if(data->state.resume_from) {
  1018. LIBSSH2_SFTP_ATTRIBUTES attrs;
  1019. if(data->state.resume_from < 0) {
  1020. int rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshp->path,
  1021. curlx_uztoui(strlen(sshp->path)),
  1022. LIBSSH2_SFTP_STAT, &attrs);
  1023. if(rc == LIBSSH2_ERROR_EAGAIN) {
  1024. *blockp = TRUE;
  1025. return CURLE_OK;
  1026. }
  1027. if(rc) {
  1028. data->state.resume_from = 0;
  1029. }
  1030. else {
  1031. curl_off_t size = attrs.filesize;
  1032. if(size < 0) {
  1033. failf(data, "Bad file size (%" FMT_OFF_T ")", size);
  1034. return CURLE_BAD_DOWNLOAD_RESUME;
  1035. }
  1036. data->state.resume_from = attrs.filesize;
  1037. }
  1038. }
  1039. }
  1040. if(data->set.remote_append)
  1041. /* Try to open for append, but create if nonexisting */
  1042. flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_APPEND;
  1043. else if(data->state.resume_from > 0)
  1044. /* If we have restart position then open for append */
  1045. flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_APPEND;
  1046. else
  1047. /* Clear file before writing (normal behavior) */
  1048. flags = LIBSSH2_FXF_WRITE|LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC;
  1049. sshc->sftp_handle =
  1050. libssh2_sftp_open_ex(sshc->sftp_session, sshp->path,
  1051. curlx_uztoui(strlen(sshp->path)),
  1052. flags, (long)data->set.new_file_perms,
  1053. LIBSSH2_SFTP_OPENFILE);
  1054. if(!sshc->sftp_handle) {
  1055. unsigned long sftperr;
  1056. int rc = libssh2_session_last_errno(sshc->ssh_session);
  1057. if(LIBSSH2_ERROR_EAGAIN == rc) {
  1058. *blockp = TRUE;
  1059. return CURLE_OK;
  1060. }
  1061. if(LIBSSH2_ERROR_SFTP_PROTOCOL == rc)
  1062. /* only when there was an SFTP protocol error can we extract
  1063. the sftp error! */
  1064. sftperr = libssh2_sftp_last_error(sshc->sftp_session);
  1065. else
  1066. sftperr = LIBSSH2_FX_OK; /* not an sftp error at all */
  1067. if(sshc->secondCreateDirs) {
  1068. state(data, SSH_SFTP_CLOSE);
  1069. sshc->actualcode = sftperr != LIBSSH2_FX_OK ?
  1070. sftp_libssh2_error_to_CURLE(sftperr) : CURLE_SSH;
  1071. failf(data, "Creating the dir/file failed: %s",
  1072. sftp_libssh2_strerror(sftperr));
  1073. return CURLE_OK;
  1074. }
  1075. if(((sftperr == LIBSSH2_FX_NO_SUCH_FILE) ||
  1076. (sftperr == LIBSSH2_FX_FAILURE) ||
  1077. (sftperr == LIBSSH2_FX_NO_SUCH_PATH)) &&
  1078. (data->set.ftp_create_missing_dirs &&
  1079. (strlen(sshp->path) > 1))) {
  1080. /* try to create the path remotely */
  1081. sshc->secondCreateDirs = 1;
  1082. state(data, SSH_SFTP_CREATE_DIRS_INIT);
  1083. return CURLE_OK;
  1084. }
  1085. state(data, SSH_SFTP_CLOSE);
  1086. sshc->actualcode = sftperr != LIBSSH2_FX_OK ?
  1087. sftp_libssh2_error_to_CURLE(sftperr) : CURLE_SSH;
  1088. if(!sshc->actualcode) {
  1089. /* Sometimes, for some reason libssh2_sftp_last_error() returns zero
  1090. even though libssh2_sftp_open() failed previously! We need to
  1091. work around that! */
  1092. sshc->actualcode = CURLE_SSH;
  1093. sftperr = LIBSSH2_FX_OK;
  1094. }
  1095. failf(data, "Upload failed: %s (%lu/%d)",
  1096. sftperr != LIBSSH2_FX_OK ?
  1097. sftp_libssh2_strerror(sftperr) : "ssh error",
  1098. sftperr, rc);
  1099. return sshc->actualcode;
  1100. }
  1101. /* If we have a restart point then we need to seek to the correct
  1102. position. */
  1103. if(data->state.resume_from > 0) {
  1104. int seekerr = CURL_SEEKFUNC_OK;
  1105. /* Let's read off the proper amount of bytes from the input. */
  1106. if(data->set.seek_func) {
  1107. Curl_set_in_callback(data, TRUE);
  1108. seekerr = data->set.seek_func(data->set.seek_client,
  1109. data->state.resume_from, SEEK_SET);
  1110. Curl_set_in_callback(data, FALSE);
  1111. }
  1112. if(seekerr != CURL_SEEKFUNC_OK) {
  1113. curl_off_t passed = 0;
  1114. if(seekerr != CURL_SEEKFUNC_CANTSEEK) {
  1115. failf(data, "Could not seek stream");
  1116. return CURLE_FTP_COULDNT_USE_REST;
  1117. }
  1118. /* seekerr == CURL_SEEKFUNC_CANTSEEK (cannot seek to offset) */
  1119. do {
  1120. char scratch[4*1024];
  1121. size_t readthisamountnow =
  1122. (data->state.resume_from - passed >
  1123. (curl_off_t)sizeof(scratch)) ?
  1124. sizeof(scratch) : curlx_sotouz(data->state.resume_from - passed);
  1125. size_t actuallyread;
  1126. Curl_set_in_callback(data, TRUE);
  1127. actuallyread = data->state.fread_func(scratch, 1,
  1128. readthisamountnow,
  1129. data->state.in);
  1130. Curl_set_in_callback(data, FALSE);
  1131. passed += actuallyread;
  1132. if((actuallyread == 0) || (actuallyread > readthisamountnow)) {
  1133. /* this checks for greater-than only to make sure that the
  1134. CURL_READFUNC_ABORT return code still aborts */
  1135. failf(data, "Failed to read data");
  1136. return CURLE_FTP_COULDNT_USE_REST;
  1137. }
  1138. } while(passed < data->state.resume_from);
  1139. }
  1140. /* now, decrease the size of the read */
  1141. if(data->state.infilesize > 0) {
  1142. data->state.infilesize -= data->state.resume_from;
  1143. data->req.size = data->state.infilesize;
  1144. Curl_pgrsSetUploadSize(data, data->state.infilesize);
  1145. }
  1146. SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
  1147. }
  1148. if(data->state.infilesize > 0) {
  1149. data->req.size = data->state.infilesize;
  1150. Curl_pgrsSetUploadSize(data, data->state.infilesize);
  1151. }
  1152. /* upload data */
  1153. Curl_xfer_setup1(data, CURL_XFER_SEND, -1, FALSE);
  1154. /* not set by Curl_xfer_setup to preserve keepon bits */
  1155. data->conn->sockfd = data->conn->writesockfd;
  1156. /* store this original bitmask setup to use later on if we cannot
  1157. figure out a "real" bitmask */
  1158. sshc->orig_waitfor = data->req.keepon;
  1159. /* we want to use the _sending_ function even when the socket turns
  1160. out readable as the underlying libssh2 sftp send function will deal
  1161. with both accordingly */
  1162. data->state.select_bits = CURL_CSELECT_OUT;
  1163. /* since we do not really wait for anything at this point, we want the
  1164. state machine to move on as soon as possible so we set a very short
  1165. timeout here */
  1166. Curl_expire(data, 0, EXPIRE_RUN_NOW);
  1167. state(data, SSH_STOP);
  1168. return CURLE_OK;
  1169. }
  1170. static CURLcode
  1171. sftp_pkey_init(struct Curl_easy *data,
  1172. struct ssh_conn *sshc)
  1173. {
  1174. /*
  1175. * Check the supported auth types in the order I feel is most secure
  1176. * with the requested type of authentication
  1177. */
  1178. sshc->authed = FALSE;
  1179. if((data->set.ssh_auth_types & CURLSSH_AUTH_PUBLICKEY) &&
  1180. (strstr(sshc->authlist, "publickey") != NULL)) {
  1181. bool out_of_memory = FALSE;
  1182. sshc->rsa_pub = sshc->rsa = NULL;
  1183. if(data->set.str[STRING_SSH_PRIVATE_KEY])
  1184. sshc->rsa = strdup(data->set.str[STRING_SSH_PRIVATE_KEY]);
  1185. else {
  1186. /* To ponder about: should really the lib be messing about with the
  1187. HOME environment variable etc? */
  1188. char *home = curl_getenv("HOME");
  1189. struct_stat sbuf;
  1190. /* If no private key file is specified, try some common paths. */
  1191. if(home) {
  1192. /* Try ~/.ssh first. */
  1193. sshc->rsa = aprintf("%s/.ssh/id_rsa", home);
  1194. if(!sshc->rsa)
  1195. out_of_memory = TRUE;
  1196. else if(stat(sshc->rsa, &sbuf)) {
  1197. Curl_safefree(sshc->rsa);
  1198. sshc->rsa = aprintf("%s/.ssh/id_dsa", home);
  1199. if(!sshc->rsa)
  1200. out_of_memory = TRUE;
  1201. else if(stat(sshc->rsa, &sbuf)) {
  1202. Curl_safefree(sshc->rsa);
  1203. }
  1204. }
  1205. free(home);
  1206. }
  1207. if(!out_of_memory && !sshc->rsa) {
  1208. /* Nothing found; try the current dir. */
  1209. sshc->rsa = strdup("id_rsa");
  1210. if(sshc->rsa && stat(sshc->rsa, &sbuf)) {
  1211. Curl_safefree(sshc->rsa);
  1212. sshc->rsa = strdup("id_dsa");
  1213. if(sshc->rsa && stat(sshc->rsa, &sbuf)) {
  1214. Curl_safefree(sshc->rsa);
  1215. /* Out of guesses. Set to the empty string to avoid
  1216. * surprising info messages. */
  1217. sshc->rsa = strdup("");
  1218. }
  1219. }
  1220. }
  1221. }
  1222. /*
  1223. * Unless the user explicitly specifies a public key file, let
  1224. * libssh2 extract the public key from the private key file.
  1225. * This is done by simply passing sshc->rsa_pub = NULL.
  1226. */
  1227. if(data->set.str[STRING_SSH_PUBLIC_KEY]
  1228. /* treat empty string the same way as NULL */
  1229. && data->set.str[STRING_SSH_PUBLIC_KEY][0]) {
  1230. sshc->rsa_pub = strdup(data->set.str[STRING_SSH_PUBLIC_KEY]);
  1231. if(!sshc->rsa_pub)
  1232. out_of_memory = TRUE;
  1233. }
  1234. if(out_of_memory || !sshc->rsa) {
  1235. Curl_safefree(sshc->rsa);
  1236. Curl_safefree(sshc->rsa_pub);
  1237. state(data, SSH_SESSION_FREE);
  1238. sshc->actualcode = CURLE_OUT_OF_MEMORY;
  1239. return CURLE_OUT_OF_MEMORY;
  1240. }
  1241. sshc->passphrase = data->set.ssl.key_passwd;
  1242. if(!sshc->passphrase)
  1243. sshc->passphrase = "";
  1244. if(sshc->rsa_pub)
  1245. infof(data, "Using SSH public key file '%s'", sshc->rsa_pub);
  1246. infof(data, "Using SSH private key file '%s'", sshc->rsa);
  1247. state(data, SSH_AUTH_PKEY);
  1248. }
  1249. else {
  1250. state(data, SSH_AUTH_PASS_INIT);
  1251. }
  1252. return CURLE_OK;
  1253. }
  1254. static CURLcode
  1255. sftp_quote_stat(struct Curl_easy *data,
  1256. struct ssh_conn *sshc,
  1257. struct SSHPROTO *sshp,
  1258. bool *blockp)
  1259. {
  1260. char *cmd = sshc->quote_item->data;
  1261. sshc->acceptfail = FALSE;
  1262. /* if a command starts with an asterisk, which a legal SFTP command never
  1263. can, the command will be allowed to fail without it causing any aborts or
  1264. cancels etc. It will cause libcurl to act as if the command is
  1265. successful, whatever the server responds. */
  1266. if(cmd[0] == '*') {
  1267. cmd++;
  1268. sshc->acceptfail = TRUE;
  1269. }
  1270. if(!strncasecompare(cmd, "chmod", 5)) {
  1271. /* Since chown and chgrp only set owner OR group but libssh2 wants to set
  1272. * them both at once, we need to obtain the current ownership first. This
  1273. * takes an extra protocol round trip.
  1274. */
  1275. int rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
  1276. curlx_uztoui(strlen(sshc->quote_path2)),
  1277. LIBSSH2_SFTP_STAT,
  1278. &sshp->quote_attrs);
  1279. if(rc == LIBSSH2_ERROR_EAGAIN) {
  1280. *blockp = TRUE;
  1281. return CURLE_OK;
  1282. }
  1283. if(rc && !sshc->acceptfail) { /* get those attributes */
  1284. unsigned long sftperr = libssh2_sftp_last_error(sshc->sftp_session);
  1285. failf(data, "Attempt to get SFTP stats failed: %s",
  1286. sftp_libssh2_strerror(sftperr));
  1287. goto fail;
  1288. }
  1289. }
  1290. /* Now set the new attributes... */
  1291. if(strncasecompare(cmd, "chgrp", 5)) {
  1292. sshp->quote_attrs.gid = strtoul(sshc->quote_path1, NULL, 10);
  1293. sshp->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
  1294. if(sshp->quote_attrs.gid == 0 && !ISDIGIT(sshc->quote_path1[0]) &&
  1295. !sshc->acceptfail) {
  1296. failf(data, "Syntax error: chgrp gid not a number");
  1297. goto fail;
  1298. }
  1299. }
  1300. else if(strncasecompare(cmd, "chmod", 5)) {
  1301. sshp->quote_attrs.permissions = strtoul(sshc->quote_path1, NULL, 8);
  1302. sshp->quote_attrs.flags = LIBSSH2_SFTP_ATTR_PERMISSIONS;
  1303. /* permissions are octal */
  1304. if(sshp->quote_attrs.permissions == 0 &&
  1305. !ISDIGIT(sshc->quote_path1[0])) {
  1306. failf(data, "Syntax error: chmod permissions not a number");
  1307. goto fail;
  1308. }
  1309. }
  1310. else if(strncasecompare(cmd, "chown", 5)) {
  1311. sshp->quote_attrs.uid = strtoul(sshc->quote_path1, NULL, 10);
  1312. sshp->quote_attrs.flags = LIBSSH2_SFTP_ATTR_UIDGID;
  1313. if(sshp->quote_attrs.uid == 0 && !ISDIGIT(sshc->quote_path1[0]) &&
  1314. !sshc->acceptfail) {
  1315. failf(data, "Syntax error: chown uid not a number");
  1316. goto fail;
  1317. }
  1318. }
  1319. else if(strncasecompare(cmd, "atime", 5) ||
  1320. strncasecompare(cmd, "mtime", 5)) {
  1321. time_t date = Curl_getdate_capped(sshc->quote_path1);
  1322. bool fail = FALSE;
  1323. if(date == -1) {
  1324. failf(data, "incorrect date format for %.*s", 5, cmd);
  1325. fail = TRUE;
  1326. }
  1327. #if SIZEOF_TIME_T > SIZEOF_LONG
  1328. if(date > 0xffffffff) {
  1329. /* if 'long' cannot old >32-bit, this date cannot be sent */
  1330. failf(data, "date overflow");
  1331. fail = TRUE;
  1332. }
  1333. #endif
  1334. if(fail)
  1335. goto fail;
  1336. if(strncasecompare(cmd, "atime", 5))
  1337. sshp->quote_attrs.atime = (unsigned long)date;
  1338. else /* mtime */
  1339. sshp->quote_attrs.mtime = (unsigned long)date;
  1340. sshp->quote_attrs.flags = LIBSSH2_SFTP_ATTR_ACMODTIME;
  1341. }
  1342. /* Now send the completed structure... */
  1343. state(data, SSH_SFTP_QUOTE_SETSTAT);
  1344. return CURLE_OK;
  1345. fail:
  1346. Curl_safefree(sshc->quote_path1);
  1347. Curl_safefree(sshc->quote_path2);
  1348. return CURLE_QUOTE_ERROR;
  1349. }
  1350. static CURLcode
  1351. sftp_download_stat(struct Curl_easy *data,
  1352. struct ssh_conn *sshc,
  1353. struct SSHPROTO *sshp,
  1354. bool *blockp)
  1355. {
  1356. LIBSSH2_SFTP_ATTRIBUTES attrs;
  1357. int rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshp->path,
  1358. curlx_uztoui(strlen(sshp->path)),
  1359. LIBSSH2_SFTP_STAT, &attrs);
  1360. if(rc == LIBSSH2_ERROR_EAGAIN) {
  1361. *blockp = TRUE;
  1362. return CURLE_OK;
  1363. }
  1364. if(rc ||
  1365. !(attrs.flags & LIBSSH2_SFTP_ATTR_SIZE) ||
  1366. (attrs.filesize == 0)) {
  1367. /*
  1368. * libssh2_sftp_open() did not return an error, so maybe the server
  1369. * just does not support stat()
  1370. * OR the server does not return a file size with a stat()
  1371. * OR file size is 0
  1372. */
  1373. data->req.size = -1;
  1374. data->req.maxdownload = -1;
  1375. Curl_pgrsSetDownloadSize(data, -1);
  1376. }
  1377. else {
  1378. curl_off_t size = attrs.filesize;
  1379. if(size < 0) {
  1380. failf(data, "Bad file size (%" FMT_OFF_T ")", size);
  1381. return CURLE_BAD_DOWNLOAD_RESUME;
  1382. }
  1383. if(data->state.use_range) {
  1384. curl_off_t from, to;
  1385. char *ptr;
  1386. char *ptr2;
  1387. CURLofft to_t;
  1388. CURLofft from_t;
  1389. from_t = curlx_strtoofft(data->state.range, &ptr, 10, &from);
  1390. if(from_t == CURL_OFFT_FLOW)
  1391. return CURLE_RANGE_ERROR;
  1392. while(*ptr && (ISBLANK(*ptr) || (*ptr == '-')))
  1393. ptr++;
  1394. to_t = curlx_strtoofft(ptr, &ptr2, 10, &to);
  1395. if(to_t == CURL_OFFT_FLOW)
  1396. return CURLE_RANGE_ERROR;
  1397. if((to_t == CURL_OFFT_INVAL) /* no "to" value given */
  1398. || (to >= size)) {
  1399. to = size - 1;
  1400. }
  1401. if(from_t) {
  1402. /* from is relative to end of file */
  1403. from = size - to;
  1404. to = size - 1;
  1405. }
  1406. if(from > size) {
  1407. failf(data, "Offset (%" FMT_OFF_T ") was beyond file size (%"
  1408. FMT_OFF_T ")", from, (curl_off_t)attrs.filesize);
  1409. return CURLE_BAD_DOWNLOAD_RESUME;
  1410. }
  1411. if(from > to) {
  1412. from = to;
  1413. size = 0;
  1414. }
  1415. else {
  1416. if((to - from) == CURL_OFF_T_MAX)
  1417. return CURLE_RANGE_ERROR;
  1418. size = to - from + 1;
  1419. }
  1420. SFTP_SEEK(sshc->sftp_handle, from);
  1421. }
  1422. data->req.size = size;
  1423. data->req.maxdownload = size;
  1424. Curl_pgrsSetDownloadSize(data, size);
  1425. }
  1426. /* We can resume if we can seek to the resume position */
  1427. if(data->state.resume_from) {
  1428. if(data->state.resume_from < 0) {
  1429. /* We are supposed to download the last abs(from) bytes */
  1430. if((curl_off_t)attrs.filesize < -data->state.resume_from) {
  1431. failf(data, "Offset (%" FMT_OFF_T ") was beyond file size (%"
  1432. FMT_OFF_T ")",
  1433. data->state.resume_from, (curl_off_t)attrs.filesize);
  1434. return CURLE_BAD_DOWNLOAD_RESUME;
  1435. }
  1436. /* download from where? */
  1437. data->state.resume_from += attrs.filesize;
  1438. }
  1439. else {
  1440. if((curl_off_t)attrs.filesize < data->state.resume_from) {
  1441. failf(data, "Offset (%" FMT_OFF_T
  1442. ") was beyond file size (%" FMT_OFF_T ")",
  1443. data->state.resume_from, (curl_off_t)attrs.filesize);
  1444. return CURLE_BAD_DOWNLOAD_RESUME;
  1445. }
  1446. }
  1447. /* Now store the number of bytes we are expected to download */
  1448. data->req.size = attrs.filesize - data->state.resume_from;
  1449. data->req.maxdownload = attrs.filesize - data->state.resume_from;
  1450. Curl_pgrsSetDownloadSize(data,
  1451. attrs.filesize - data->state.resume_from);
  1452. SFTP_SEEK(sshc->sftp_handle, data->state.resume_from);
  1453. }
  1454. /* Setup the actual download */
  1455. if(data->req.size == 0) {
  1456. /* no data to transfer */
  1457. Curl_xfer_setup_nop(data);
  1458. infof(data, "File already completely downloaded");
  1459. state(data, SSH_STOP);
  1460. return CURLE_OK;
  1461. }
  1462. Curl_xfer_setup1(data, CURL_XFER_RECV, data->req.size, FALSE);
  1463. /* not set by Curl_xfer_setup to preserve keepon bits */
  1464. data->conn->writesockfd = data->conn->sockfd;
  1465. /* we want to use the _receiving_ function even when the socket turns
  1466. out writableable as the underlying libssh2 recv function will deal
  1467. with both accordingly */
  1468. data->state.select_bits = CURL_CSELECT_IN;
  1469. state(data, SSH_STOP);
  1470. return CURLE_OK;
  1471. }
  1472. static CURLcode sftp_readdir(struct Curl_easy *data,
  1473. struct ssh_conn *sshc,
  1474. struct SSHPROTO *sshp,
  1475. bool *blockp)
  1476. {
  1477. CURLcode result = CURLE_OK;
  1478. int rc = libssh2_sftp_readdir_ex(sshc->sftp_handle,
  1479. sshp->readdir_filename, CURL_PATH_MAX,
  1480. sshp->readdir_longentry, CURL_PATH_MAX,
  1481. &sshp->readdir_attrs);
  1482. if(rc == LIBSSH2_ERROR_EAGAIN) {
  1483. *blockp = TRUE;
  1484. return result;
  1485. }
  1486. if(rc > 0) {
  1487. size_t readdir_len = (size_t) rc;
  1488. sshp->readdir_filename[readdir_len] = '\0';
  1489. if(data->set.list_only) {
  1490. result = Curl_client_write(data, CLIENTWRITE_BODY,
  1491. sshp->readdir_filename,
  1492. readdir_len);
  1493. if(!result)
  1494. result = Curl_client_write(data, CLIENTWRITE_BODY,
  1495. (char *)"\n", 1);
  1496. if(result)
  1497. return result;
  1498. }
  1499. else {
  1500. result = Curl_dyn_add(&sshp->readdir, sshp->readdir_longentry);
  1501. if(!result) {
  1502. if((sshp->readdir_attrs.flags & LIBSSH2_SFTP_ATTR_PERMISSIONS) &&
  1503. ((sshp->readdir_attrs.permissions & LIBSSH2_SFTP_S_IFMT) ==
  1504. LIBSSH2_SFTP_S_IFLNK)) {
  1505. Curl_dyn_init(&sshp->readdir_link, CURL_PATH_MAX);
  1506. result = Curl_dyn_addf(&sshp->readdir_link, "%s%s", sshp->path,
  1507. sshp->readdir_filename);
  1508. state(data, SSH_SFTP_READDIR_LINK);
  1509. }
  1510. else {
  1511. state(data, SSH_SFTP_READDIR_BOTTOM);
  1512. }
  1513. }
  1514. return result;
  1515. }
  1516. }
  1517. else if(rc == 0) {
  1518. state(data, SSH_SFTP_READDIR_DONE);
  1519. }
  1520. else if(rc < 0) {
  1521. unsigned long sftperr = libssh2_sftp_last_error(sshc->sftp_session);
  1522. result = sftp_libssh2_error_to_CURLE(sftperr);
  1523. sshc->actualcode = result ? result : CURLE_SSH;
  1524. failf(data, "Could not open remote file for reading: %s :: %d",
  1525. sftp_libssh2_strerror(sftperr),
  1526. libssh2_session_last_errno(sshc->ssh_session));
  1527. state(data, SSH_SFTP_CLOSE);
  1528. }
  1529. return result;
  1530. }
  1531. /*
  1532. * ssh_statemachine() runs the SSH state machine as far as it can without
  1533. * blocking and without reaching the end. The data the pointer 'block' points
  1534. * to will be set to TRUE if the libssh2 function returns LIBSSH2_ERROR_EAGAIN
  1535. * meaning it wants to be called again when the socket is ready
  1536. */
  1537. static CURLcode ssh_statemachine(struct Curl_easy *data, bool *block)
  1538. {
  1539. CURLcode result = CURLE_OK;
  1540. struct connectdata *conn = data->conn;
  1541. struct SSHPROTO *sshp = data->req.p.ssh;
  1542. struct ssh_conn *sshc = &conn->proto.sshc;
  1543. int rc = LIBSSH2_ERROR_NONE;
  1544. *block = 0; /* we are not blocking by default */
  1545. do {
  1546. switch(sshc->state) {
  1547. case SSH_INIT:
  1548. sshc->secondCreateDirs = 0;
  1549. sshc->nextstate = SSH_NO_STATE;
  1550. sshc->actualcode = CURLE_OK;
  1551. /* Set libssh2 to non-blocking, since everything internally is
  1552. non-blocking */
  1553. libssh2_session_set_blocking(sshc->ssh_session, 0);
  1554. result = ssh_force_knownhost_key_type(data);
  1555. if(result) {
  1556. state(data, SSH_SESSION_FREE);
  1557. sshc->actualcode = result;
  1558. break;
  1559. }
  1560. state(data, SSH_S_STARTUP);
  1561. FALLTHROUGH();
  1562. case SSH_S_STARTUP:
  1563. rc = session_startup(sshc->ssh_session, conn->sock[FIRSTSOCKET]);
  1564. if(rc == LIBSSH2_ERROR_EAGAIN) {
  1565. break;
  1566. }
  1567. if(rc) {
  1568. char *err_msg = NULL;
  1569. (void)libssh2_session_last_error(sshc->ssh_session, &err_msg, NULL, 0);
  1570. failf(data, "Failure establishing ssh session: %d, %s", rc, err_msg);
  1571. state(data, SSH_SESSION_FREE);
  1572. sshc->actualcode = CURLE_FAILED_INIT;
  1573. break;
  1574. }
  1575. state(data, SSH_HOSTKEY);
  1576. FALLTHROUGH();
  1577. case SSH_HOSTKEY:
  1578. /*
  1579. * Before we authenticate we should check the hostkey's fingerprint
  1580. * against our known hosts. How that is handled (reading from file,
  1581. * whatever) is up to us.
  1582. */
  1583. result = ssh_check_fingerprint(data);
  1584. if(!result)
  1585. state(data, SSH_AUTHLIST);
  1586. /* ssh_check_fingerprint sets state appropriately on error */
  1587. break;
  1588. case SSH_AUTHLIST:
  1589. /*
  1590. * Figure out authentication methods
  1591. * NB: As soon as we have provided a username to an openssh server we
  1592. * must never change it later. Thus, always specify the correct username
  1593. * here, even though the libssh2 docs kind of indicate that it should be
  1594. * possible to get a 'generic' list (not user-specific) of authentication
  1595. * methods, presumably with a blank username. That will not work in my
  1596. * experience.
  1597. * So always specify it here.
  1598. */
  1599. sshc->authlist = libssh2_userauth_list(sshc->ssh_session,
  1600. conn->user,
  1601. curlx_uztoui(strlen(conn->user)));
  1602. if(!sshc->authlist) {
  1603. if(libssh2_userauth_authenticated(sshc->ssh_session)) {
  1604. sshc->authed = TRUE;
  1605. infof(data, "SSH user accepted with no authentication");
  1606. state(data, SSH_AUTH_DONE);
  1607. break;
  1608. }
  1609. rc = libssh2_session_last_errno(sshc->ssh_session);
  1610. if(rc == LIBSSH2_ERROR_EAGAIN)
  1611. rc = LIBSSH2_ERROR_EAGAIN;
  1612. else {
  1613. state(data, SSH_SESSION_FREE);
  1614. sshc->actualcode = libssh2_session_error_to_CURLE(rc);
  1615. }
  1616. break;
  1617. }
  1618. infof(data, "SSH authentication methods available: %s",
  1619. sshc->authlist);
  1620. state(data, SSH_AUTH_PKEY_INIT);
  1621. break;
  1622. case SSH_AUTH_PKEY_INIT:
  1623. result = sftp_pkey_init(data, sshc);
  1624. break;
  1625. case SSH_AUTH_PKEY:
  1626. /* The function below checks if the files exists, no need to stat() here.
  1627. */
  1628. rc = libssh2_userauth_publickey_fromfile_ex(sshc->ssh_session,
  1629. conn->user,
  1630. curlx_uztoui(
  1631. strlen(conn->user)),
  1632. sshc->rsa_pub,
  1633. sshc->rsa, sshc->passphrase);
  1634. if(rc == LIBSSH2_ERROR_EAGAIN) {
  1635. break;
  1636. }
  1637. Curl_safefree(sshc->rsa_pub);
  1638. Curl_safefree(sshc->rsa);
  1639. if(rc == 0) {
  1640. sshc->authed = TRUE;
  1641. infof(data, "Initialized SSH public key authentication");
  1642. state(data, SSH_AUTH_DONE);
  1643. }
  1644. else {
  1645. char *err_msg = NULL;
  1646. char unknown[] = "Reason unknown (-1)";
  1647. if(rc == -1) {
  1648. /* No error message has been set and the last set error message, if
  1649. any, is from a previous error so ignore it. #11837 */
  1650. err_msg = unknown;
  1651. }
  1652. else {
  1653. (void)libssh2_session_last_error(sshc->ssh_session,
  1654. &err_msg, NULL, 0);
  1655. }
  1656. infof(data, "SSH public key authentication failed: %s", err_msg);
  1657. state(data, SSH_AUTH_PASS_INIT);
  1658. rc = 0; /* clear rc and continue */
  1659. }
  1660. break;
  1661. case SSH_AUTH_PASS_INIT:
  1662. if((data->set.ssh_auth_types & CURLSSH_AUTH_PASSWORD) &&
  1663. (strstr(sshc->authlist, "password") != NULL)) {
  1664. state(data, SSH_AUTH_PASS);
  1665. }
  1666. else {
  1667. state(data, SSH_AUTH_HOST_INIT);
  1668. rc = 0; /* clear rc and continue */
  1669. }
  1670. break;
  1671. case SSH_AUTH_PASS:
  1672. rc = libssh2_userauth_password_ex(sshc->ssh_session, conn->user,
  1673. curlx_uztoui(strlen(conn->user)),
  1674. conn->passwd,
  1675. curlx_uztoui(strlen(conn->passwd)),
  1676. NULL);
  1677. if(rc == LIBSSH2_ERROR_EAGAIN) {
  1678. break;
  1679. }
  1680. if(rc == 0) {
  1681. sshc->authed = TRUE;
  1682. infof(data, "Initialized password authentication");
  1683. state(data, SSH_AUTH_DONE);
  1684. }
  1685. else {
  1686. state(data, SSH_AUTH_HOST_INIT);
  1687. rc = 0; /* clear rc and continue */
  1688. }
  1689. break;
  1690. case SSH_AUTH_HOST_INIT:
  1691. if((data->set.ssh_auth_types & CURLSSH_AUTH_HOST) &&
  1692. (strstr(sshc->authlist, "hostbased") != NULL)) {
  1693. state(data, SSH_AUTH_HOST);
  1694. }
  1695. else {
  1696. state(data, SSH_AUTH_AGENT_INIT);
  1697. }
  1698. break;
  1699. case SSH_AUTH_HOST:
  1700. state(data, SSH_AUTH_AGENT_INIT);
  1701. break;
  1702. case SSH_AUTH_AGENT_INIT:
  1703. #ifdef HAVE_LIBSSH2_AGENT_API
  1704. if((data->set.ssh_auth_types & CURLSSH_AUTH_AGENT)
  1705. && (strstr(sshc->authlist, "publickey") != NULL)) {
  1706. /* Connect to the ssh-agent */
  1707. /* The agent could be shared by a curl thread i believe
  1708. but nothing obvious as keys can be added/removed at any time */
  1709. if(!sshc->ssh_agent) {
  1710. sshc->ssh_agent = libssh2_agent_init(sshc->ssh_session);
  1711. if(!sshc->ssh_agent) {
  1712. infof(data, "Could not create agent object");
  1713. state(data, SSH_AUTH_KEY_INIT);
  1714. break;
  1715. }
  1716. }
  1717. rc = libssh2_agent_connect(sshc->ssh_agent);
  1718. if(rc == LIBSSH2_ERROR_EAGAIN)
  1719. break;
  1720. if(rc < 0) {
  1721. infof(data, "Failure connecting to agent");
  1722. state(data, SSH_AUTH_KEY_INIT);
  1723. rc = 0; /* clear rc and continue */
  1724. }
  1725. else {
  1726. state(data, SSH_AUTH_AGENT_LIST);
  1727. }
  1728. }
  1729. else
  1730. #endif /* HAVE_LIBSSH2_AGENT_API */
  1731. state(data, SSH_AUTH_KEY_INIT);
  1732. break;
  1733. case SSH_AUTH_AGENT_LIST:
  1734. #ifdef HAVE_LIBSSH2_AGENT_API
  1735. rc = libssh2_agent_list_identities(sshc->ssh_agent);
  1736. if(rc == LIBSSH2_ERROR_EAGAIN)
  1737. break;
  1738. if(rc < 0) {
  1739. infof(data, "Failure requesting identities to agent");
  1740. state(data, SSH_AUTH_KEY_INIT);
  1741. rc = 0; /* clear rc and continue */
  1742. }
  1743. else {
  1744. state(data, SSH_AUTH_AGENT);
  1745. sshc->sshagent_prev_identity = NULL;
  1746. }
  1747. #endif
  1748. break;
  1749. case SSH_AUTH_AGENT:
  1750. #ifdef HAVE_LIBSSH2_AGENT_API
  1751. /* as prev_identity evolves only after an identity user auth finished we
  1752. can safely request it again as long as EAGAIN is returned here or by
  1753. libssh2_agent_userauth */
  1754. rc = libssh2_agent_get_identity(sshc->ssh_agent,
  1755. &sshc->sshagent_identity,
  1756. sshc->sshagent_prev_identity);
  1757. if(rc == LIBSSH2_ERROR_EAGAIN)
  1758. break;
  1759. if(rc == 0) {
  1760. rc = libssh2_agent_userauth(sshc->ssh_agent, conn->user,
  1761. sshc->sshagent_identity);
  1762. if(rc < 0) {
  1763. if(rc != LIBSSH2_ERROR_EAGAIN) {
  1764. /* tried and failed? go to next identity */
  1765. sshc->sshagent_prev_identity = sshc->sshagent_identity;
  1766. }
  1767. break;
  1768. }
  1769. }
  1770. if(rc < 0)
  1771. infof(data, "Failure requesting identities to agent");
  1772. else if(rc == 1)
  1773. infof(data, "No identity would match");
  1774. if(rc == LIBSSH2_ERROR_NONE) {
  1775. sshc->authed = TRUE;
  1776. infof(data, "Agent based authentication successful");
  1777. state(data, SSH_AUTH_DONE);
  1778. }
  1779. else {
  1780. state(data, SSH_AUTH_KEY_INIT);
  1781. rc = 0; /* clear rc and continue */
  1782. }
  1783. #endif
  1784. break;
  1785. case SSH_AUTH_KEY_INIT:
  1786. if((data->set.ssh_auth_types & CURLSSH_AUTH_KEYBOARD)
  1787. && (strstr(sshc->authlist, "keyboard-interactive") != NULL)) {
  1788. state(data, SSH_AUTH_KEY);
  1789. }
  1790. else {
  1791. state(data, SSH_AUTH_DONE);
  1792. }
  1793. break;
  1794. case SSH_AUTH_KEY:
  1795. /* Authentication failed. Continue with keyboard-interactive now. */
  1796. rc = libssh2_userauth_keyboard_interactive_ex(sshc->ssh_session,
  1797. conn->user,
  1798. curlx_uztoui(
  1799. strlen(conn->user)),
  1800. &kbd_callback);
  1801. if(rc == LIBSSH2_ERROR_EAGAIN) {
  1802. break;
  1803. }
  1804. if(rc == 0) {
  1805. sshc->authed = TRUE;
  1806. infof(data, "Initialized keyboard interactive authentication");
  1807. }
  1808. state(data, SSH_AUTH_DONE);
  1809. break;
  1810. case SSH_AUTH_DONE:
  1811. if(!sshc->authed) {
  1812. failf(data, "Authentication failure");
  1813. state(data, SSH_SESSION_FREE);
  1814. sshc->actualcode = CURLE_LOGIN_DENIED;
  1815. break;
  1816. }
  1817. /*
  1818. * At this point we have an authenticated ssh session.
  1819. */
  1820. infof(data, "Authentication complete");
  1821. Curl_pgrsTime(data, TIMER_APPCONNECT); /* SSH is connected */
  1822. conn->sockfd = conn->sock[FIRSTSOCKET];
  1823. conn->writesockfd = CURL_SOCKET_BAD;
  1824. if(conn->handler->protocol == CURLPROTO_SFTP) {
  1825. state(data, SSH_SFTP_INIT);
  1826. break;
  1827. }
  1828. infof(data, "SSH CONNECT phase done");
  1829. state(data, SSH_STOP);
  1830. break;
  1831. case SSH_SFTP_INIT:
  1832. /*
  1833. * Start the libssh2 sftp session
  1834. */
  1835. sshc->sftp_session = libssh2_sftp_init(sshc->ssh_session);
  1836. if(!sshc->sftp_session) {
  1837. char *err_msg = NULL;
  1838. if(libssh2_session_last_errno(sshc->ssh_session) ==
  1839. LIBSSH2_ERROR_EAGAIN) {
  1840. rc = LIBSSH2_ERROR_EAGAIN;
  1841. break;
  1842. }
  1843. (void)libssh2_session_last_error(sshc->ssh_session,
  1844. &err_msg, NULL, 0);
  1845. failf(data, "Failure initializing sftp session: %s", err_msg);
  1846. state(data, SSH_SESSION_FREE);
  1847. sshc->actualcode = CURLE_FAILED_INIT;
  1848. break;
  1849. }
  1850. state(data, SSH_SFTP_REALPATH);
  1851. break;
  1852. case SSH_SFTP_REALPATH:
  1853. /*
  1854. * Get the "home" directory
  1855. */
  1856. rc = sftp_libssh2_realpath(sshc->sftp_session, ".",
  1857. sshp->readdir_filename, CURL_PATH_MAX);
  1858. if(rc == LIBSSH2_ERROR_EAGAIN) {
  1859. break;
  1860. }
  1861. if(rc > 0) {
  1862. /* It seems that this string is not always NULL terminated */
  1863. sshp->readdir_filename[rc] = '\0';
  1864. sshc->homedir = strdup(sshp->readdir_filename);
  1865. if(!sshc->homedir) {
  1866. state(data, SSH_SFTP_CLOSE);
  1867. sshc->actualcode = CURLE_OUT_OF_MEMORY;
  1868. break;
  1869. }
  1870. data->state.most_recent_ftp_entrypath = sshc->homedir;
  1871. }
  1872. else {
  1873. /* Return the error type */
  1874. unsigned long sftperr = libssh2_sftp_last_error(sshc->sftp_session);
  1875. if(sftperr)
  1876. result = sftp_libssh2_error_to_CURLE(sftperr);
  1877. else
  1878. /* in this case, the error was not in the SFTP level but for example
  1879. a time-out or similar */
  1880. result = CURLE_SSH;
  1881. sshc->actualcode = result;
  1882. DEBUGF(infof(data, "error = %lu makes libcurl = %d",
  1883. sftperr, (int)result));
  1884. state(data, SSH_STOP);
  1885. break;
  1886. }
  1887. /* This is the last step in the SFTP connect phase. Do note that while
  1888. we get the homedir here, we get the "workingpath" in the DO action
  1889. since the homedir will remain the same between request but the
  1890. working path will not. */
  1891. DEBUGF(infof(data, "SSH CONNECT phase done"));
  1892. state(data, SSH_STOP);
  1893. break;
  1894. case SSH_SFTP_QUOTE_INIT:
  1895. result = Curl_getworkingpath(data, sshc->homedir, &sshp->path);
  1896. if(result) {
  1897. sshc->actualcode = result;
  1898. state(data, SSH_STOP);
  1899. break;
  1900. }
  1901. if(data->set.quote) {
  1902. infof(data, "Sending quote commands");
  1903. sshc->quote_item = data->set.quote;
  1904. state(data, SSH_SFTP_QUOTE);
  1905. }
  1906. else {
  1907. state(data, SSH_SFTP_GETINFO);
  1908. }
  1909. break;
  1910. case SSH_SFTP_POSTQUOTE_INIT:
  1911. if(data->set.postquote) {
  1912. infof(data, "Sending quote commands");
  1913. sshc->quote_item = data->set.postquote;
  1914. state(data, SSH_SFTP_QUOTE);
  1915. }
  1916. else {
  1917. state(data, SSH_STOP);
  1918. }
  1919. break;
  1920. case SSH_SFTP_QUOTE:
  1921. /* Send quote commands */
  1922. result = sftp_quote(data, sshc, sshp);
  1923. if(result) {
  1924. state(data, SSH_SFTP_CLOSE);
  1925. sshc->nextstate = SSH_NO_STATE;
  1926. sshc->actualcode = result;
  1927. }
  1928. break;
  1929. case SSH_SFTP_NEXT_QUOTE:
  1930. Curl_safefree(sshc->quote_path1);
  1931. Curl_safefree(sshc->quote_path2);
  1932. sshc->quote_item = sshc->quote_item->next;
  1933. if(sshc->quote_item) {
  1934. state(data, SSH_SFTP_QUOTE);
  1935. }
  1936. else {
  1937. if(sshc->nextstate != SSH_NO_STATE) {
  1938. state(data, sshc->nextstate);
  1939. sshc->nextstate = SSH_NO_STATE;
  1940. }
  1941. else {
  1942. state(data, SSH_SFTP_GETINFO);
  1943. }
  1944. }
  1945. break;
  1946. case SSH_SFTP_QUOTE_STAT:
  1947. result = sftp_quote_stat(data, sshc, sshp, block);
  1948. if(result) {
  1949. state(data, SSH_SFTP_CLOSE);
  1950. sshc->nextstate = SSH_NO_STATE;
  1951. sshc->actualcode = result;
  1952. }
  1953. break;
  1954. case SSH_SFTP_QUOTE_SETSTAT:
  1955. rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshc->quote_path2,
  1956. curlx_uztoui(strlen(sshc->quote_path2)),
  1957. LIBSSH2_SFTP_SETSTAT,
  1958. &sshp->quote_attrs);
  1959. if(rc == LIBSSH2_ERROR_EAGAIN) {
  1960. break;
  1961. }
  1962. if(rc && !sshc->acceptfail) {
  1963. unsigned long sftperr = libssh2_sftp_last_error(sshc->sftp_session);
  1964. Curl_safefree(sshc->quote_path1);
  1965. Curl_safefree(sshc->quote_path2);
  1966. failf(data, "Attempt to set SFTP stats failed: %s",
  1967. sftp_libssh2_strerror(sftperr));
  1968. state(data, SSH_SFTP_CLOSE);
  1969. sshc->nextstate = SSH_NO_STATE;
  1970. sshc->actualcode = CURLE_QUOTE_ERROR;
  1971. break;
  1972. }
  1973. state(data, SSH_SFTP_NEXT_QUOTE);
  1974. break;
  1975. case SSH_SFTP_QUOTE_SYMLINK:
  1976. rc = libssh2_sftp_symlink_ex(sshc->sftp_session, sshc->quote_path1,
  1977. curlx_uztoui(strlen(sshc->quote_path1)),
  1978. sshc->quote_path2,
  1979. curlx_uztoui(strlen(sshc->quote_path2)),
  1980. LIBSSH2_SFTP_SYMLINK);
  1981. if(rc == LIBSSH2_ERROR_EAGAIN) {
  1982. break;
  1983. }
  1984. if(rc && !sshc->acceptfail) {
  1985. unsigned long sftperr = libssh2_sftp_last_error(sshc->sftp_session);
  1986. Curl_safefree(sshc->quote_path1);
  1987. Curl_safefree(sshc->quote_path2);
  1988. failf(data, "symlink command failed: %s",
  1989. sftp_libssh2_strerror(sftperr));
  1990. state(data, SSH_SFTP_CLOSE);
  1991. sshc->nextstate = SSH_NO_STATE;
  1992. sshc->actualcode = CURLE_QUOTE_ERROR;
  1993. break;
  1994. }
  1995. state(data, SSH_SFTP_NEXT_QUOTE);
  1996. break;
  1997. case SSH_SFTP_QUOTE_MKDIR:
  1998. rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sshc->quote_path1,
  1999. curlx_uztoui(strlen(sshc->quote_path1)),
  2000. (long)data->set.new_directory_perms);
  2001. if(rc == LIBSSH2_ERROR_EAGAIN) {
  2002. break;
  2003. }
  2004. if(rc && !sshc->acceptfail) {
  2005. unsigned long sftperr = libssh2_sftp_last_error(sshc->sftp_session);
  2006. Curl_safefree(sshc->quote_path1);
  2007. failf(data, "mkdir command failed: %s",
  2008. sftp_libssh2_strerror(sftperr));
  2009. state(data, SSH_SFTP_CLOSE);
  2010. sshc->nextstate = SSH_NO_STATE;
  2011. sshc->actualcode = CURLE_QUOTE_ERROR;
  2012. break;
  2013. }
  2014. state(data, SSH_SFTP_NEXT_QUOTE);
  2015. break;
  2016. case SSH_SFTP_QUOTE_RENAME:
  2017. rc = libssh2_sftp_rename_ex(sshc->sftp_session, sshc->quote_path1,
  2018. curlx_uztoui(strlen(sshc->quote_path1)),
  2019. sshc->quote_path2,
  2020. curlx_uztoui(strlen(sshc->quote_path2)),
  2021. LIBSSH2_SFTP_RENAME_OVERWRITE |
  2022. LIBSSH2_SFTP_RENAME_ATOMIC |
  2023. LIBSSH2_SFTP_RENAME_NATIVE);
  2024. if(rc == LIBSSH2_ERROR_EAGAIN) {
  2025. break;
  2026. }
  2027. if(rc && !sshc->acceptfail) {
  2028. unsigned long sftperr = libssh2_sftp_last_error(sshc->sftp_session);
  2029. Curl_safefree(sshc->quote_path1);
  2030. Curl_safefree(sshc->quote_path2);
  2031. failf(data, "rename command failed: %s",
  2032. sftp_libssh2_strerror(sftperr));
  2033. state(data, SSH_SFTP_CLOSE);
  2034. sshc->nextstate = SSH_NO_STATE;
  2035. sshc->actualcode = CURLE_QUOTE_ERROR;
  2036. break;
  2037. }
  2038. state(data, SSH_SFTP_NEXT_QUOTE);
  2039. break;
  2040. case SSH_SFTP_QUOTE_RMDIR:
  2041. rc = libssh2_sftp_rmdir_ex(sshc->sftp_session, sshc->quote_path1,
  2042. curlx_uztoui(strlen(sshc->quote_path1)));
  2043. if(rc == LIBSSH2_ERROR_EAGAIN) {
  2044. break;
  2045. }
  2046. if(rc && !sshc->acceptfail) {
  2047. unsigned long sftperr = libssh2_sftp_last_error(sshc->sftp_session);
  2048. Curl_safefree(sshc->quote_path1);
  2049. failf(data, "rmdir command failed: %s",
  2050. sftp_libssh2_strerror(sftperr));
  2051. state(data, SSH_SFTP_CLOSE);
  2052. sshc->nextstate = SSH_NO_STATE;
  2053. sshc->actualcode = CURLE_QUOTE_ERROR;
  2054. break;
  2055. }
  2056. state(data, SSH_SFTP_NEXT_QUOTE);
  2057. break;
  2058. case SSH_SFTP_QUOTE_UNLINK:
  2059. rc = libssh2_sftp_unlink_ex(sshc->sftp_session, sshc->quote_path1,
  2060. curlx_uztoui(strlen(sshc->quote_path1)));
  2061. if(rc == LIBSSH2_ERROR_EAGAIN) {
  2062. break;
  2063. }
  2064. if(rc && !sshc->acceptfail) {
  2065. unsigned long sftperr = libssh2_sftp_last_error(sshc->sftp_session);
  2066. Curl_safefree(sshc->quote_path1);
  2067. failf(data, "rm command failed: %s", sftp_libssh2_strerror(sftperr));
  2068. state(data, SSH_SFTP_CLOSE);
  2069. sshc->nextstate = SSH_NO_STATE;
  2070. sshc->actualcode = CURLE_QUOTE_ERROR;
  2071. break;
  2072. }
  2073. state(data, SSH_SFTP_NEXT_QUOTE);
  2074. break;
  2075. #ifdef HAS_STATVFS_SUPPORT
  2076. case SSH_SFTP_QUOTE_STATVFS:
  2077. {
  2078. LIBSSH2_SFTP_STATVFS statvfs;
  2079. rc = libssh2_sftp_statvfs(sshc->sftp_session, sshc->quote_path1,
  2080. curlx_uztoui(strlen(sshc->quote_path1)),
  2081. &statvfs);
  2082. if(rc == LIBSSH2_ERROR_EAGAIN) {
  2083. break;
  2084. }
  2085. if(rc && !sshc->acceptfail) {
  2086. unsigned long sftperr = libssh2_sftp_last_error(sshc->sftp_session);
  2087. Curl_safefree(sshc->quote_path1);
  2088. failf(data, "statvfs command failed: %s",
  2089. sftp_libssh2_strerror(sftperr));
  2090. state(data, SSH_SFTP_CLOSE);
  2091. sshc->nextstate = SSH_NO_STATE;
  2092. sshc->actualcode = CURLE_QUOTE_ERROR;
  2093. break;
  2094. }
  2095. else if(rc == 0) {
  2096. #ifdef _MSC_VER
  2097. #define CURL_LIBSSH2_VFS_SIZE_MASK "I64u"
  2098. #else
  2099. #define CURL_LIBSSH2_VFS_SIZE_MASK "llu"
  2100. #endif
  2101. char *tmp = aprintf("statvfs:\n"
  2102. "f_bsize: %" CURL_LIBSSH2_VFS_SIZE_MASK "\n"
  2103. "f_frsize: %" CURL_LIBSSH2_VFS_SIZE_MASK "\n"
  2104. "f_blocks: %" CURL_LIBSSH2_VFS_SIZE_MASK "\n"
  2105. "f_bfree: %" CURL_LIBSSH2_VFS_SIZE_MASK "\n"
  2106. "f_bavail: %" CURL_LIBSSH2_VFS_SIZE_MASK "\n"
  2107. "f_files: %" CURL_LIBSSH2_VFS_SIZE_MASK "\n"
  2108. "f_ffree: %" CURL_LIBSSH2_VFS_SIZE_MASK "\n"
  2109. "f_favail: %" CURL_LIBSSH2_VFS_SIZE_MASK "\n"
  2110. "f_fsid: %" CURL_LIBSSH2_VFS_SIZE_MASK "\n"
  2111. "f_flag: %" CURL_LIBSSH2_VFS_SIZE_MASK "\n"
  2112. "f_namemax: %" CURL_LIBSSH2_VFS_SIZE_MASK "\n",
  2113. statvfs.f_bsize, statvfs.f_frsize,
  2114. statvfs.f_blocks, statvfs.f_bfree,
  2115. statvfs.f_bavail, statvfs.f_files,
  2116. statvfs.f_ffree, statvfs.f_favail,
  2117. statvfs.f_fsid, statvfs.f_flag,
  2118. statvfs.f_namemax);
  2119. if(!tmp) {
  2120. result = CURLE_OUT_OF_MEMORY;
  2121. state(data, SSH_SFTP_CLOSE);
  2122. sshc->nextstate = SSH_NO_STATE;
  2123. break;
  2124. }
  2125. result = Curl_client_write(data, CLIENTWRITE_HEADER, tmp, strlen(tmp));
  2126. free(tmp);
  2127. if(result) {
  2128. state(data, SSH_SFTP_CLOSE);
  2129. sshc->nextstate = SSH_NO_STATE;
  2130. sshc->actualcode = result;
  2131. }
  2132. }
  2133. state(data, SSH_SFTP_NEXT_QUOTE);
  2134. break;
  2135. }
  2136. #endif
  2137. case SSH_SFTP_GETINFO:
  2138. {
  2139. if(data->set.get_filetime) {
  2140. state(data, SSH_SFTP_FILETIME);
  2141. }
  2142. else {
  2143. state(data, SSH_SFTP_TRANS_INIT);
  2144. }
  2145. break;
  2146. }
  2147. case SSH_SFTP_FILETIME:
  2148. {
  2149. LIBSSH2_SFTP_ATTRIBUTES attrs;
  2150. rc = libssh2_sftp_stat_ex(sshc->sftp_session, sshp->path,
  2151. curlx_uztoui(strlen(sshp->path)),
  2152. LIBSSH2_SFTP_STAT, &attrs);
  2153. if(rc == LIBSSH2_ERROR_EAGAIN) {
  2154. break;
  2155. }
  2156. if(rc == 0) {
  2157. data->info.filetime = (time_t)attrs.mtime;
  2158. }
  2159. state(data, SSH_SFTP_TRANS_INIT);
  2160. break;
  2161. }
  2162. case SSH_SFTP_TRANS_INIT:
  2163. if(data->state.upload)
  2164. state(data, SSH_SFTP_UPLOAD_INIT);
  2165. else {
  2166. if(sshp->path[strlen(sshp->path)-1] == '/')
  2167. state(data, SSH_SFTP_READDIR_INIT);
  2168. else
  2169. state(data, SSH_SFTP_DOWNLOAD_INIT);
  2170. }
  2171. break;
  2172. case SSH_SFTP_UPLOAD_INIT:
  2173. result = sftp_upload_init(data, sshc, sshp, block);
  2174. if(result) {
  2175. state(data, SSH_SFTP_CLOSE);
  2176. sshc->nextstate = SSH_NO_STATE;
  2177. sshc->actualcode = result;
  2178. }
  2179. break;
  2180. case SSH_SFTP_CREATE_DIRS_INIT:
  2181. if(strlen(sshp->path) > 1) {
  2182. sshc->slash_pos = sshp->path + 1; /* ignore the leading '/' */
  2183. state(data, SSH_SFTP_CREATE_DIRS);
  2184. }
  2185. else {
  2186. state(data, SSH_SFTP_UPLOAD_INIT);
  2187. }
  2188. break;
  2189. case SSH_SFTP_CREATE_DIRS:
  2190. sshc->slash_pos = strchr(sshc->slash_pos, '/');
  2191. if(sshc->slash_pos) {
  2192. *sshc->slash_pos = 0;
  2193. infof(data, "Creating directory '%s'", sshp->path);
  2194. state(data, SSH_SFTP_CREATE_DIRS_MKDIR);
  2195. break;
  2196. }
  2197. state(data, SSH_SFTP_UPLOAD_INIT);
  2198. break;
  2199. case SSH_SFTP_CREATE_DIRS_MKDIR:
  2200. /* 'mode' - parameter is preliminary - default to 0644 */
  2201. rc = libssh2_sftp_mkdir_ex(sshc->sftp_session, sshp->path,
  2202. curlx_uztoui(strlen(sshp->path)),
  2203. (long)data->set.new_directory_perms);
  2204. if(rc == LIBSSH2_ERROR_EAGAIN) {
  2205. break;
  2206. }
  2207. *sshc->slash_pos = '/';
  2208. ++sshc->slash_pos;
  2209. if(rc < 0) {
  2210. /*
  2211. * Abort if failure was not that the dir already exists or the
  2212. * permission was denied (creation might succeed further down the
  2213. * path) - retry on unspecific FAILURE also
  2214. */
  2215. unsigned long sftperr = libssh2_sftp_last_error(sshc->sftp_session);
  2216. if((sftperr != LIBSSH2_FX_FILE_ALREADY_EXISTS) &&
  2217. (sftperr != LIBSSH2_FX_FAILURE) &&
  2218. (sftperr != LIBSSH2_FX_PERMISSION_DENIED)) {
  2219. result = sftp_libssh2_error_to_CURLE(sftperr);
  2220. state(data, SSH_SFTP_CLOSE);
  2221. sshc->actualcode = result ? result : CURLE_SSH;
  2222. break;
  2223. }
  2224. rc = 0; /* clear rc and continue */
  2225. }
  2226. state(data, SSH_SFTP_CREATE_DIRS);
  2227. break;
  2228. case SSH_SFTP_READDIR_INIT:
  2229. Curl_pgrsSetDownloadSize(data, -1);
  2230. if(data->req.no_body) {
  2231. state(data, SSH_STOP);
  2232. break;
  2233. }
  2234. /*
  2235. * This is a directory that we are trying to get, so produce a directory
  2236. * listing
  2237. */
  2238. sshc->sftp_handle =
  2239. libssh2_sftp_open_ex(sshc->sftp_session, sshp->path,
  2240. curlx_uztoui(strlen(sshp->path)),
  2241. 0, 0, LIBSSH2_SFTP_OPENDIR);
  2242. if(!sshc->sftp_handle) {
  2243. unsigned long sftperr;
  2244. if(libssh2_session_last_errno(sshc->ssh_session) ==
  2245. LIBSSH2_ERROR_EAGAIN) {
  2246. rc = LIBSSH2_ERROR_EAGAIN;
  2247. break;
  2248. }
  2249. sftperr = libssh2_sftp_last_error(sshc->sftp_session);
  2250. failf(data, "Could not open directory for reading: %s",
  2251. sftp_libssh2_strerror(sftperr));
  2252. state(data, SSH_SFTP_CLOSE);
  2253. result = sftp_libssh2_error_to_CURLE(sftperr);
  2254. sshc->actualcode = result ? result : CURLE_SSH;
  2255. break;
  2256. }
  2257. Curl_dyn_init(&sshp->readdir, CURL_PATH_MAX * 2);
  2258. state(data, SSH_SFTP_READDIR);
  2259. break;
  2260. case SSH_SFTP_READDIR:
  2261. result = sftp_readdir(data, sshc, sshp, block);
  2262. if(result) {
  2263. sshc->actualcode = result;
  2264. state(data, SSH_SFTP_CLOSE);
  2265. }
  2266. break;
  2267. case SSH_SFTP_READDIR_LINK:
  2268. rc =
  2269. libssh2_sftp_symlink_ex(sshc->sftp_session,
  2270. Curl_dyn_ptr(&sshp->readdir_link),
  2271. (unsigned int)
  2272. Curl_dyn_len(&sshp->readdir_link),
  2273. sshp->readdir_filename,
  2274. CURL_PATH_MAX, LIBSSH2_SFTP_READLINK);
  2275. if(rc == LIBSSH2_ERROR_EAGAIN) {
  2276. break;
  2277. }
  2278. Curl_dyn_free(&sshp->readdir_link);
  2279. /* append filename and extra output */
  2280. result = Curl_dyn_addf(&sshp->readdir, " -> %s", sshp->readdir_filename);
  2281. if(result) {
  2282. state(data, SSH_SFTP_CLOSE);
  2283. sshc->actualcode = result;
  2284. break;
  2285. }
  2286. state(data, SSH_SFTP_READDIR_BOTTOM);
  2287. break;
  2288. case SSH_SFTP_READDIR_BOTTOM:
  2289. result = Curl_dyn_addn(&sshp->readdir, "\n", 1);
  2290. if(!result)
  2291. result = Curl_client_write(data, CLIENTWRITE_BODY,
  2292. Curl_dyn_ptr(&sshp->readdir),
  2293. Curl_dyn_len(&sshp->readdir));
  2294. if(result) {
  2295. Curl_dyn_free(&sshp->readdir);
  2296. state(data, SSH_STOP);
  2297. }
  2298. else {
  2299. Curl_dyn_reset(&sshp->readdir);
  2300. state(data, SSH_SFTP_READDIR);
  2301. }
  2302. break;
  2303. case SSH_SFTP_READDIR_DONE:
  2304. if(libssh2_sftp_closedir(sshc->sftp_handle) ==
  2305. LIBSSH2_ERROR_EAGAIN) {
  2306. rc = LIBSSH2_ERROR_EAGAIN;
  2307. break;
  2308. }
  2309. sshc->sftp_handle = NULL;
  2310. /* no data to transfer */
  2311. Curl_xfer_setup_nop(data);
  2312. state(data, SSH_STOP);
  2313. break;
  2314. case SSH_SFTP_DOWNLOAD_INIT:
  2315. /*
  2316. * Work on getting the specified file
  2317. */
  2318. sshc->sftp_handle =
  2319. libssh2_sftp_open_ex(sshc->sftp_session, sshp->path,
  2320. curlx_uztoui(strlen(sshp->path)),
  2321. LIBSSH2_FXF_READ, (long)data->set.new_file_perms,
  2322. LIBSSH2_SFTP_OPENFILE);
  2323. if(!sshc->sftp_handle) {
  2324. unsigned long sftperr;
  2325. if(libssh2_session_last_errno(sshc->ssh_session) ==
  2326. LIBSSH2_ERROR_EAGAIN) {
  2327. rc = LIBSSH2_ERROR_EAGAIN;
  2328. break;
  2329. }
  2330. sftperr = libssh2_sftp_last_error(sshc->sftp_session);
  2331. failf(data, "Could not open remote file for reading: %s",
  2332. sftp_libssh2_strerror(sftperr));
  2333. state(data, SSH_SFTP_CLOSE);
  2334. result = sftp_libssh2_error_to_CURLE(sftperr);
  2335. sshc->actualcode = result ? result : CURLE_SSH;
  2336. break;
  2337. }
  2338. state(data, SSH_SFTP_DOWNLOAD_STAT);
  2339. break;
  2340. case SSH_SFTP_DOWNLOAD_STAT:
  2341. result = sftp_download_stat(data, sshc, sshp, block);
  2342. if(result) {
  2343. state(data, SSH_SFTP_CLOSE);
  2344. sshc->nextstate = SSH_NO_STATE;
  2345. sshc->actualcode = result;
  2346. }
  2347. break;
  2348. case SSH_SFTP_CLOSE:
  2349. if(sshc->sftp_handle) {
  2350. rc = libssh2_sftp_close(sshc->sftp_handle);
  2351. if(rc == LIBSSH2_ERROR_EAGAIN) {
  2352. break;
  2353. }
  2354. if(rc < 0) {
  2355. char *err_msg = NULL;
  2356. (void)libssh2_session_last_error(sshc->ssh_session,
  2357. &err_msg, NULL, 0);
  2358. infof(data, "Failed to close libssh2 file: %d %s", rc, err_msg);
  2359. }
  2360. sshc->sftp_handle = NULL;
  2361. }
  2362. Curl_safefree(sshp->path);
  2363. DEBUGF(infof(data, "SFTP DONE done"));
  2364. /* Check if nextstate is set and move .nextstate could be POSTQUOTE_INIT
  2365. After nextstate is executed, the control should come back to
  2366. SSH_SFTP_CLOSE to pass the correct result back */
  2367. if(sshc->nextstate != SSH_NO_STATE &&
  2368. sshc->nextstate != SSH_SFTP_CLOSE) {
  2369. state(data, sshc->nextstate);
  2370. sshc->nextstate = SSH_SFTP_CLOSE;
  2371. }
  2372. else {
  2373. state(data, SSH_STOP);
  2374. result = sshc->actualcode;
  2375. }
  2376. break;
  2377. case SSH_SFTP_SHUTDOWN:
  2378. /* during times we get here due to a broken transfer and then the
  2379. sftp_handle might not have been taken down so make sure that is done
  2380. before we proceed */
  2381. if(sshc->sftp_handle) {
  2382. rc = libssh2_sftp_close(sshc->sftp_handle);
  2383. if(rc == LIBSSH2_ERROR_EAGAIN) {
  2384. break;
  2385. }
  2386. if(rc < 0) {
  2387. char *err_msg = NULL;
  2388. (void)libssh2_session_last_error(sshc->ssh_session, &err_msg,
  2389. NULL, 0);
  2390. infof(data, "Failed to close libssh2 file: %d %s", rc, err_msg);
  2391. }
  2392. sshc->sftp_handle = NULL;
  2393. }
  2394. if(sshc->sftp_session) {
  2395. rc = libssh2_sftp_shutdown(sshc->sftp_session);
  2396. if(rc == LIBSSH2_ERROR_EAGAIN) {
  2397. break;
  2398. }
  2399. if(rc < 0) {
  2400. infof(data, "Failed to stop libssh2 sftp subsystem");
  2401. }
  2402. sshc->sftp_session = NULL;
  2403. }
  2404. Curl_safefree(sshc->homedir);
  2405. data->state.most_recent_ftp_entrypath = NULL;
  2406. state(data, SSH_SESSION_DISCONNECT);
  2407. break;
  2408. case SSH_SCP_TRANS_INIT:
  2409. result = Curl_getworkingpath(data, sshc->homedir, &sshp->path);
  2410. if(result) {
  2411. sshc->actualcode = result;
  2412. state(data, SSH_STOP);
  2413. break;
  2414. }
  2415. if(data->state.upload) {
  2416. if(data->state.infilesize < 0) {
  2417. failf(data, "SCP requires a known file size for upload");
  2418. sshc->actualcode = CURLE_UPLOAD_FAILED;
  2419. state(data, SSH_SCP_CHANNEL_FREE);
  2420. break;
  2421. }
  2422. state(data, SSH_SCP_UPLOAD_INIT);
  2423. }
  2424. else {
  2425. state(data, SSH_SCP_DOWNLOAD_INIT);
  2426. }
  2427. break;
  2428. case SSH_SCP_UPLOAD_INIT:
  2429. /*
  2430. * libssh2 requires that the destination path is a full path that
  2431. * includes the destination file and name OR ends in a "/" . If this is
  2432. * not done the destination file will be named the same name as the last
  2433. * directory in the path.
  2434. */
  2435. sshc->ssh_channel =
  2436. SCP_SEND(sshc->ssh_session, sshp->path, data->set.new_file_perms,
  2437. data->state.infilesize);
  2438. if(!sshc->ssh_channel) {
  2439. int ssh_err;
  2440. char *err_msg = NULL;
  2441. if(libssh2_session_last_errno(sshc->ssh_session) ==
  2442. LIBSSH2_ERROR_EAGAIN) {
  2443. rc = LIBSSH2_ERROR_EAGAIN;
  2444. break;
  2445. }
  2446. ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
  2447. &err_msg, NULL, 0));
  2448. failf(data, "%s", err_msg);
  2449. state(data, SSH_SCP_CHANNEL_FREE);
  2450. sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
  2451. /* Map generic errors to upload failed */
  2452. if(sshc->actualcode == CURLE_SSH ||
  2453. sshc->actualcode == CURLE_REMOTE_FILE_NOT_FOUND)
  2454. sshc->actualcode = CURLE_UPLOAD_FAILED;
  2455. break;
  2456. }
  2457. /* upload data */
  2458. data->req.size = data->state.infilesize;
  2459. Curl_pgrsSetUploadSize(data, data->state.infilesize);
  2460. Curl_xfer_setup1(data, CURL_XFER_SEND, -1, FALSE);
  2461. /* not set by Curl_xfer_setup to preserve keepon bits */
  2462. conn->sockfd = conn->writesockfd;
  2463. if(result) {
  2464. state(data, SSH_SCP_CHANNEL_FREE);
  2465. sshc->actualcode = result;
  2466. }
  2467. else {
  2468. /* store this original bitmask setup to use later on if we cannot
  2469. figure out a "real" bitmask */
  2470. sshc->orig_waitfor = data->req.keepon;
  2471. /* we want to use the _sending_ function even when the socket turns
  2472. out readable as the underlying libssh2 scp send function will deal
  2473. with both accordingly */
  2474. data->state.select_bits = CURL_CSELECT_OUT;
  2475. state(data, SSH_STOP);
  2476. }
  2477. break;
  2478. case SSH_SCP_DOWNLOAD_INIT:
  2479. {
  2480. curl_off_t bytecount;
  2481. /*
  2482. * We must check the remote file; if it is a directory no values will
  2483. * be set in sb
  2484. */
  2485. /*
  2486. * If support for >2GB files exists, use it.
  2487. */
  2488. /* get a fresh new channel from the ssh layer */
  2489. #if LIBSSH2_VERSION_NUM < 0x010700
  2490. struct stat sb;
  2491. memset(&sb, 0, sizeof(struct stat));
  2492. sshc->ssh_channel = libssh2_scp_recv(sshc->ssh_session,
  2493. sshp->path, &sb);
  2494. #else
  2495. libssh2_struct_stat sb;
  2496. memset(&sb, 0, sizeof(libssh2_struct_stat));
  2497. sshc->ssh_channel = libssh2_scp_recv2(sshc->ssh_session,
  2498. sshp->path, &sb);
  2499. #endif
  2500. if(!sshc->ssh_channel) {
  2501. int ssh_err;
  2502. char *err_msg = NULL;
  2503. if(libssh2_session_last_errno(sshc->ssh_session) ==
  2504. LIBSSH2_ERROR_EAGAIN) {
  2505. rc = LIBSSH2_ERROR_EAGAIN;
  2506. break;
  2507. }
  2508. ssh_err = (int)(libssh2_session_last_error(sshc->ssh_session,
  2509. &err_msg, NULL, 0));
  2510. failf(data, "%s", err_msg);
  2511. state(data, SSH_SCP_CHANNEL_FREE);
  2512. sshc->actualcode = libssh2_session_error_to_CURLE(ssh_err);
  2513. break;
  2514. }
  2515. /* download data */
  2516. bytecount = (curl_off_t)sb.st_size;
  2517. data->req.maxdownload = (curl_off_t)sb.st_size;
  2518. Curl_xfer_setup1(data, CURL_XFER_RECV, bytecount, FALSE);
  2519. /* not set by Curl_xfer_setup to preserve keepon bits */
  2520. conn->writesockfd = conn->sockfd;
  2521. /* we want to use the _receiving_ function even when the socket turns
  2522. out writableable as the underlying libssh2 recv function will deal
  2523. with both accordingly */
  2524. data->state.select_bits = CURL_CSELECT_IN;
  2525. if(result) {
  2526. state(data, SSH_SCP_CHANNEL_FREE);
  2527. sshc->actualcode = result;
  2528. }
  2529. else
  2530. state(data, SSH_STOP);
  2531. }
  2532. break;
  2533. case SSH_SCP_DONE:
  2534. if(data->state.upload)
  2535. state(data, SSH_SCP_SEND_EOF);
  2536. else
  2537. state(data, SSH_SCP_CHANNEL_FREE);
  2538. break;
  2539. case SSH_SCP_SEND_EOF:
  2540. if(sshc->ssh_channel) {
  2541. rc = libssh2_channel_send_eof(sshc->ssh_channel);
  2542. if(rc == LIBSSH2_ERROR_EAGAIN) {
  2543. break;
  2544. }
  2545. if(rc) {
  2546. char *err_msg = NULL;
  2547. (void)libssh2_session_last_error(sshc->ssh_session,
  2548. &err_msg, NULL, 0);
  2549. infof(data, "Failed to send libssh2 channel EOF: %d %s",
  2550. rc, err_msg);
  2551. }
  2552. }
  2553. state(data, SSH_SCP_WAIT_EOF);
  2554. break;
  2555. case SSH_SCP_WAIT_EOF:
  2556. if(sshc->ssh_channel) {
  2557. rc = libssh2_channel_wait_eof(sshc->ssh_channel);
  2558. if(rc == LIBSSH2_ERROR_EAGAIN) {
  2559. break;
  2560. }
  2561. if(rc) {
  2562. char *err_msg = NULL;
  2563. (void)libssh2_session_last_error(sshc->ssh_session,
  2564. &err_msg, NULL, 0);
  2565. infof(data, "Failed to get channel EOF: %d %s", rc, err_msg);
  2566. }
  2567. }
  2568. state(data, SSH_SCP_WAIT_CLOSE);
  2569. break;
  2570. case SSH_SCP_WAIT_CLOSE:
  2571. if(sshc->ssh_channel) {
  2572. rc = libssh2_channel_wait_closed(sshc->ssh_channel);
  2573. if(rc == LIBSSH2_ERROR_EAGAIN) {
  2574. break;
  2575. }
  2576. if(rc) {
  2577. char *err_msg = NULL;
  2578. (void)libssh2_session_last_error(sshc->ssh_session,
  2579. &err_msg, NULL, 0);
  2580. infof(data, "Channel failed to close: %d %s", rc, err_msg);
  2581. }
  2582. }
  2583. state(data, SSH_SCP_CHANNEL_FREE);
  2584. break;
  2585. case SSH_SCP_CHANNEL_FREE:
  2586. if(sshc->ssh_channel) {
  2587. rc = libssh2_channel_free(sshc->ssh_channel);
  2588. if(rc == LIBSSH2_ERROR_EAGAIN) {
  2589. break;
  2590. }
  2591. if(rc < 0) {
  2592. char *err_msg = NULL;
  2593. (void)libssh2_session_last_error(sshc->ssh_session,
  2594. &err_msg, NULL, 0);
  2595. infof(data, "Failed to free libssh2 scp subsystem: %d %s",
  2596. rc, err_msg);
  2597. }
  2598. sshc->ssh_channel = NULL;
  2599. }
  2600. DEBUGF(infof(data, "SCP DONE phase complete"));
  2601. #if 0 /* PREV */
  2602. state(data, SSH_SESSION_DISCONNECT);
  2603. #endif
  2604. state(data, SSH_STOP);
  2605. result = sshc->actualcode;
  2606. break;
  2607. case SSH_SESSION_DISCONNECT:
  2608. /* during weird times when we have been prematurely aborted, the channel
  2609. is still alive when we reach this state and we MUST kill the channel
  2610. properly first */
  2611. if(sshc->ssh_channel) {
  2612. rc = libssh2_channel_free(sshc->ssh_channel);
  2613. if(rc == LIBSSH2_ERROR_EAGAIN) {
  2614. break;
  2615. }
  2616. if(rc < 0) {
  2617. char *err_msg = NULL;
  2618. (void)libssh2_session_last_error(sshc->ssh_session,
  2619. &err_msg, NULL, 0);
  2620. infof(data, "Failed to free libssh2 scp subsystem: %d %s",
  2621. rc, err_msg);
  2622. }
  2623. sshc->ssh_channel = NULL;
  2624. }
  2625. if(sshc->ssh_session) {
  2626. rc = libssh2_session_disconnect(sshc->ssh_session, "Shutdown");
  2627. if(rc == LIBSSH2_ERROR_EAGAIN) {
  2628. break;
  2629. }
  2630. if(rc < 0) {
  2631. char *err_msg = NULL;
  2632. (void)libssh2_session_last_error(sshc->ssh_session,
  2633. &err_msg, NULL, 0);
  2634. infof(data, "Failed to disconnect libssh2 session: %d %s",
  2635. rc, err_msg);
  2636. }
  2637. }
  2638. Curl_safefree(sshc->homedir);
  2639. data->state.most_recent_ftp_entrypath = NULL;
  2640. state(data, SSH_SESSION_FREE);
  2641. break;
  2642. case SSH_SESSION_FREE:
  2643. #ifdef HAVE_LIBSSH2_KNOWNHOST_API
  2644. if(sshc->kh) {
  2645. libssh2_knownhost_free(sshc->kh);
  2646. sshc->kh = NULL;
  2647. }
  2648. #endif
  2649. #ifdef HAVE_LIBSSH2_AGENT_API
  2650. if(sshc->ssh_agent) {
  2651. rc = libssh2_agent_disconnect(sshc->ssh_agent);
  2652. if(rc == LIBSSH2_ERROR_EAGAIN) {
  2653. break;
  2654. }
  2655. if(rc < 0) {
  2656. char *err_msg = NULL;
  2657. (void)libssh2_session_last_error(sshc->ssh_session,
  2658. &err_msg, NULL, 0);
  2659. infof(data, "Failed to disconnect from libssh2 agent: %d %s",
  2660. rc, err_msg);
  2661. }
  2662. libssh2_agent_free(sshc->ssh_agent);
  2663. sshc->ssh_agent = NULL;
  2664. /* NB: there is no need to free identities, they are part of internal
  2665. agent stuff */
  2666. sshc->sshagent_identity = NULL;
  2667. sshc->sshagent_prev_identity = NULL;
  2668. }
  2669. #endif
  2670. if(sshc->ssh_session) {
  2671. rc = libssh2_session_free(sshc->ssh_session);
  2672. if(rc == LIBSSH2_ERROR_EAGAIN) {
  2673. break;
  2674. }
  2675. if(rc < 0) {
  2676. char *err_msg = NULL;
  2677. (void)libssh2_session_last_error(sshc->ssh_session,
  2678. &err_msg, NULL, 0);
  2679. infof(data, "Failed to free libssh2 session: %d %s", rc, err_msg);
  2680. }
  2681. sshc->ssh_session = NULL;
  2682. }
  2683. /* worst-case scenario cleanup */
  2684. DEBUGASSERT(sshc->ssh_session == NULL);
  2685. DEBUGASSERT(sshc->ssh_channel == NULL);
  2686. DEBUGASSERT(sshc->sftp_session == NULL);
  2687. DEBUGASSERT(sshc->sftp_handle == NULL);
  2688. #ifdef HAVE_LIBSSH2_KNOWNHOST_API
  2689. DEBUGASSERT(sshc->kh == NULL);
  2690. #endif
  2691. #ifdef HAVE_LIBSSH2_AGENT_API
  2692. DEBUGASSERT(sshc->ssh_agent == NULL);
  2693. #endif
  2694. Curl_safefree(sshc->rsa_pub);
  2695. Curl_safefree(sshc->rsa);
  2696. Curl_safefree(sshc->quote_path1);
  2697. Curl_safefree(sshc->quote_path2);
  2698. Curl_safefree(sshc->homedir);
  2699. /* the code we are about to return */
  2700. result = sshc->actualcode;
  2701. memset(sshc, 0, sizeof(struct ssh_conn));
  2702. connclose(conn, "SSH session free");
  2703. sshc->state = SSH_SESSION_FREE; /* current */
  2704. sshc->nextstate = SSH_NO_STATE;
  2705. state(data, SSH_STOP);
  2706. break;
  2707. case SSH_QUIT:
  2708. default:
  2709. /* internal error */
  2710. sshc->nextstate = SSH_NO_STATE;
  2711. state(data, SSH_STOP);
  2712. break;
  2713. }
  2714. } while(!rc && (sshc->state != SSH_STOP));
  2715. if(rc == LIBSSH2_ERROR_EAGAIN) {
  2716. /* we would block, we need to wait for the socket to be ready (in the
  2717. right direction too)! */
  2718. *block = TRUE;
  2719. }
  2720. return result;
  2721. }
  2722. /* called by the multi interface to figure out what socket(s) to wait for and
  2723. for what actions in the DO_DONE, PERFORM and WAITPERFORM states */
  2724. static int ssh_getsock(struct Curl_easy *data,
  2725. struct connectdata *conn,
  2726. curl_socket_t *sock)
  2727. {
  2728. int bitmap = GETSOCK_BLANK;
  2729. (void)data;
  2730. sock[0] = conn->sock[FIRSTSOCKET];
  2731. if(conn->waitfor & KEEP_RECV)
  2732. bitmap |= GETSOCK_READSOCK(FIRSTSOCKET);
  2733. if(conn->waitfor & KEEP_SEND)
  2734. bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET);
  2735. return bitmap;
  2736. }
  2737. /*
  2738. * When one of the libssh2 functions has returned LIBSSH2_ERROR_EAGAIN this
  2739. * function is used to figure out in what direction and stores this info so
  2740. * that the multi interface can take advantage of it. Make sure to call this
  2741. * function in all cases so that when it _does not_ return EAGAIN we can
  2742. * restore the default wait bits.
  2743. */
  2744. static void ssh_block2waitfor(struct Curl_easy *data, bool block)
  2745. {
  2746. struct connectdata *conn = data->conn;
  2747. struct ssh_conn *sshc = &conn->proto.sshc;
  2748. int dir = 0;
  2749. if(block) {
  2750. dir = libssh2_session_block_directions(sshc->ssh_session);
  2751. if(dir) {
  2752. /* translate the libssh2 define bits into our own bit defines */
  2753. conn->waitfor = ((dir&LIBSSH2_SESSION_BLOCK_INBOUND) ? KEEP_RECV : 0) |
  2754. ((dir&LIBSSH2_SESSION_BLOCK_OUTBOUND) ? KEEP_SEND : 0);
  2755. }
  2756. }
  2757. if(!dir)
  2758. /* It did not block or libssh2 did not reveal in which direction, put back
  2759. the original set */
  2760. conn->waitfor = sshc->orig_waitfor;
  2761. }
  2762. /* called repeatedly until done from multi.c */
  2763. static CURLcode ssh_multi_statemach(struct Curl_easy *data, bool *done)
  2764. {
  2765. struct connectdata *conn = data->conn;
  2766. struct ssh_conn *sshc = &conn->proto.sshc;
  2767. CURLcode result = CURLE_OK;
  2768. bool block; /* we store the status and use that to provide a ssh_getsock()
  2769. implementation */
  2770. do {
  2771. result = ssh_statemachine(data, &block);
  2772. *done = (sshc->state == SSH_STOP);
  2773. /* if there is no error, it is not done and it did not EWOULDBLOCK, then
  2774. try again */
  2775. } while(!result && !*done && !block);
  2776. ssh_block2waitfor(data, block);
  2777. return result;
  2778. }
  2779. static CURLcode ssh_block_statemach(struct Curl_easy *data,
  2780. struct connectdata *conn,
  2781. bool disconnect)
  2782. {
  2783. struct ssh_conn *sshc = &conn->proto.sshc;
  2784. CURLcode result = CURLE_OK;
  2785. struct curltime dis = Curl_now();
  2786. while((sshc->state != SSH_STOP) && !result) {
  2787. bool block;
  2788. timediff_t left = 1000;
  2789. struct curltime now = Curl_now();
  2790. result = ssh_statemachine(data, &block);
  2791. if(result)
  2792. break;
  2793. if(!disconnect) {
  2794. if(Curl_pgrsUpdate(data))
  2795. return CURLE_ABORTED_BY_CALLBACK;
  2796. result = Curl_speedcheck(data, now);
  2797. if(result)
  2798. break;
  2799. left = Curl_timeleft(data, NULL, FALSE);
  2800. if(left < 0) {
  2801. failf(data, "Operation timed out");
  2802. return CURLE_OPERATION_TIMEDOUT;
  2803. }
  2804. }
  2805. else if(Curl_timediff(now, dis) > 1000) {
  2806. /* disconnect timeout */
  2807. failf(data, "Disconnect timed out");
  2808. result = CURLE_OK;
  2809. break;
  2810. }
  2811. if(block) {
  2812. int dir = libssh2_session_block_directions(sshc->ssh_session);
  2813. curl_socket_t sock = conn->sock[FIRSTSOCKET];
  2814. curl_socket_t fd_read = CURL_SOCKET_BAD;
  2815. curl_socket_t fd_write = CURL_SOCKET_BAD;
  2816. if(LIBSSH2_SESSION_BLOCK_INBOUND & dir)
  2817. fd_read = sock;
  2818. if(LIBSSH2_SESSION_BLOCK_OUTBOUND & dir)
  2819. fd_write = sock;
  2820. /* wait for the socket to become ready */
  2821. (void)Curl_socket_check(fd_read, CURL_SOCKET_BAD, fd_write,
  2822. left > 1000 ? 1000 : left);
  2823. }
  2824. }
  2825. return result;
  2826. }
  2827. /*
  2828. * SSH setup and connection
  2829. */
  2830. static CURLcode ssh_setup_connection(struct Curl_easy *data,
  2831. struct connectdata *conn)
  2832. {
  2833. struct SSHPROTO *ssh;
  2834. (void)conn;
  2835. data->req.p.ssh = ssh = calloc(1, sizeof(struct SSHPROTO));
  2836. if(!ssh)
  2837. return CURLE_OUT_OF_MEMORY;
  2838. return CURLE_OK;
  2839. }
  2840. static Curl_recv scp_recv, sftp_recv;
  2841. static Curl_send scp_send, sftp_send;
  2842. #ifndef CURL_DISABLE_PROXY
  2843. static ssize_t ssh_tls_recv(libssh2_socket_t sock, void *buffer,
  2844. size_t length, int flags, void **abstract)
  2845. {
  2846. struct Curl_easy *data = (struct Curl_easy *)*abstract;
  2847. ssize_t nread;
  2848. CURLcode result;
  2849. struct connectdata *conn = data->conn;
  2850. Curl_recv *backup = conn->recv[0];
  2851. struct ssh_conn *ssh = &conn->proto.sshc;
  2852. int socknum = Curl_conn_sockindex(data, sock);
  2853. (void)flags;
  2854. /* swap in the TLS reader function for this call only, and then swap back
  2855. the SSH one again */
  2856. conn->recv[0] = ssh->tls_recv;
  2857. result = Curl_conn_recv(data, socknum, buffer, length, &nread);
  2858. conn->recv[0] = backup;
  2859. if(result == CURLE_AGAIN)
  2860. return -EAGAIN; /* magic return code for libssh2 */
  2861. else if(result)
  2862. return -1; /* generic error */
  2863. Curl_debug(data, CURLINFO_DATA_IN, (char *)buffer, (size_t)nread);
  2864. return nread;
  2865. }
  2866. static ssize_t ssh_tls_send(libssh2_socket_t sock, const void *buffer,
  2867. size_t length, int flags, void **abstract)
  2868. {
  2869. struct Curl_easy *data = (struct Curl_easy *)*abstract;
  2870. size_t nwrite;
  2871. CURLcode result;
  2872. struct connectdata *conn = data->conn;
  2873. Curl_send *backup = conn->send[0];
  2874. struct ssh_conn *ssh = &conn->proto.sshc;
  2875. int socknum = Curl_conn_sockindex(data, sock);
  2876. (void)flags;
  2877. /* swap in the TLS writer function for this call only, and then swap back
  2878. the SSH one again */
  2879. conn->send[0] = ssh->tls_send;
  2880. result = Curl_conn_send(data, socknum, buffer, length, FALSE, &nwrite);
  2881. conn->send[0] = backup;
  2882. if(result == CURLE_AGAIN)
  2883. return -EAGAIN; /* magic return code for libssh2 */
  2884. else if(result)
  2885. return -1; /* error */
  2886. Curl_debug(data, CURLINFO_DATA_OUT, (char *)buffer, nwrite);
  2887. return (ssize_t)nwrite;
  2888. }
  2889. #endif
  2890. /*
  2891. * Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to
  2892. * do protocol-specific actions at connect-time.
  2893. */
  2894. static CURLcode ssh_connect(struct Curl_easy *data, bool *done)
  2895. {
  2896. #ifdef CURL_LIBSSH2_DEBUG
  2897. curl_socket_t sock;
  2898. #endif
  2899. struct ssh_conn *sshc;
  2900. CURLcode result;
  2901. struct connectdata *conn = data->conn;
  2902. /* initialize per-handle data if not already */
  2903. if(!data->req.p.ssh) {
  2904. result = ssh_setup_connection(data, conn);
  2905. if(result)
  2906. return result;
  2907. }
  2908. /* We default to persistent connections. We set this already in this connect
  2909. function to make the reuse checks properly be able to check this bit. */
  2910. connkeep(conn, "SSH default");
  2911. sshc = &conn->proto.sshc;
  2912. #ifdef CURL_LIBSSH2_DEBUG
  2913. if(conn->user) {
  2914. infof(data, "User: %s", conn->user);
  2915. }
  2916. if(conn->passwd) {
  2917. infof(data, "Password: %s", conn->passwd);
  2918. }
  2919. sock = conn->sock[FIRSTSOCKET];
  2920. #endif /* CURL_LIBSSH2_DEBUG */
  2921. /* libcurl MUST to set custom memory functions so that the kbd_callback
  2922. function's memory allocations can be properly freed */
  2923. sshc->ssh_session = libssh2_session_init_ex(my_libssh2_malloc,
  2924. my_libssh2_free,
  2925. my_libssh2_realloc, data);
  2926. if(!sshc->ssh_session) {
  2927. failf(data, "Failure initialising ssh session");
  2928. return CURLE_FAILED_INIT;
  2929. }
  2930. /* Set the packet read timeout if the libssh2 version supports it */
  2931. #if LIBSSH2_VERSION_NUM >= 0x010B00
  2932. if(data->set.server_response_timeout > 0) {
  2933. libssh2_session_set_read_timeout(sshc->ssh_session,
  2934. (long)(data->set.server_response_timeout / 1000));
  2935. }
  2936. #endif
  2937. #ifndef CURL_DISABLE_PROXY
  2938. if(conn->http_proxy.proxytype == CURLPROXY_HTTPS) {
  2939. /*
  2940. Setup libssh2 callbacks to make it read/write TLS from the socket.
  2941. ssize_t
  2942. recvcb(libssh2_socket_t sock, void *buffer, size_t length,
  2943. int flags, void **abstract);
  2944. ssize_t
  2945. sendcb(libssh2_socket_t sock, const void *buffer, size_t length,
  2946. int flags, void **abstract);
  2947. */
  2948. #if LIBSSH2_VERSION_NUM >= 0x010b01
  2949. infof(data, "Uses HTTPS proxy");
  2950. libssh2_session_callback_set2(sshc->ssh_session,
  2951. LIBSSH2_CALLBACK_RECV,
  2952. (libssh2_cb_generic *)ssh_tls_recv);
  2953. libssh2_session_callback_set2(sshc->ssh_session,
  2954. LIBSSH2_CALLBACK_SEND,
  2955. (libssh2_cb_generic *)ssh_tls_send);
  2956. #else
  2957. /*
  2958. * This crazy union dance is here to avoid assigning a void pointer a
  2959. * function pointer as it is invalid C. The problem is of course that
  2960. * libssh2 has such an API...
  2961. */
  2962. union receive {
  2963. void *recvp;
  2964. ssize_t (*recvptr)(libssh2_socket_t, void *, size_t, int, void **);
  2965. };
  2966. union transfer {
  2967. void *sendp;
  2968. ssize_t (*sendptr)(libssh2_socket_t, const void *, size_t, int, void **);
  2969. };
  2970. union receive sshrecv;
  2971. union transfer sshsend;
  2972. sshrecv.recvptr = ssh_tls_recv;
  2973. sshsend.sendptr = ssh_tls_send;
  2974. infof(data, "Uses HTTPS proxy");
  2975. libssh2_session_callback_set(sshc->ssh_session,
  2976. LIBSSH2_CALLBACK_RECV, sshrecv.recvp);
  2977. libssh2_session_callback_set(sshc->ssh_session,
  2978. LIBSSH2_CALLBACK_SEND, sshsend.sendp);
  2979. #endif
  2980. /* Store the underlying TLS recv/send function pointers to be used when
  2981. reading from the proxy */
  2982. sshc->tls_recv = conn->recv[FIRSTSOCKET];
  2983. sshc->tls_send = conn->send[FIRSTSOCKET];
  2984. }
  2985. #endif /* CURL_DISABLE_PROXY */
  2986. if(conn->handler->protocol & CURLPROTO_SCP) {
  2987. conn->recv[FIRSTSOCKET] = scp_recv;
  2988. conn->send[FIRSTSOCKET] = scp_send;
  2989. }
  2990. else {
  2991. conn->recv[FIRSTSOCKET] = sftp_recv;
  2992. conn->send[FIRSTSOCKET] = sftp_send;
  2993. }
  2994. if(data->set.ssh_compression) {
  2995. #if LIBSSH2_VERSION_NUM >= 0x010208
  2996. if(libssh2_session_flag(sshc->ssh_session, LIBSSH2_FLAG_COMPRESS, 1) < 0)
  2997. #endif
  2998. infof(data, "Failed to enable compression for ssh session");
  2999. }
  3000. #ifdef HAVE_LIBSSH2_KNOWNHOST_API
  3001. if(data->set.str[STRING_SSH_KNOWNHOSTS]) {
  3002. int rc;
  3003. sshc->kh = libssh2_knownhost_init(sshc->ssh_session);
  3004. if(!sshc->kh) {
  3005. libssh2_session_free(sshc->ssh_session);
  3006. sshc->ssh_session = NULL;
  3007. return CURLE_FAILED_INIT;
  3008. }
  3009. /* read all known hosts from there */
  3010. rc = libssh2_knownhost_readfile(sshc->kh,
  3011. data->set.str[STRING_SSH_KNOWNHOSTS],
  3012. LIBSSH2_KNOWNHOST_FILE_OPENSSH);
  3013. if(rc < 0)
  3014. infof(data, "Failed to read known hosts from %s",
  3015. data->set.str[STRING_SSH_KNOWNHOSTS]);
  3016. }
  3017. #endif /* HAVE_LIBSSH2_KNOWNHOST_API */
  3018. #ifdef CURL_LIBSSH2_DEBUG
  3019. libssh2_trace(sshc->ssh_session, ~0);
  3020. infof(data, "SSH socket: %d", (int)sock);
  3021. #endif /* CURL_LIBSSH2_DEBUG */
  3022. state(data, SSH_INIT);
  3023. result = ssh_multi_statemach(data, done);
  3024. return result;
  3025. }
  3026. /*
  3027. ***********************************************************************
  3028. *
  3029. * scp_perform()
  3030. *
  3031. * This is the actual DO function for SCP. Get a file according to
  3032. * the options previously setup.
  3033. */
  3034. static
  3035. CURLcode scp_perform(struct Curl_easy *data,
  3036. bool *connected,
  3037. bool *dophase_done)
  3038. {
  3039. CURLcode result = CURLE_OK;
  3040. DEBUGF(infof(data, "DO phase starts"));
  3041. *dophase_done = FALSE; /* not done yet */
  3042. /* start the first command in the DO phase */
  3043. state(data, SSH_SCP_TRANS_INIT);
  3044. /* run the state-machine */
  3045. result = ssh_multi_statemach(data, dophase_done);
  3046. *connected = Curl_conn_is_connected(data->conn, FIRSTSOCKET);
  3047. if(*dophase_done) {
  3048. DEBUGF(infof(data, "DO phase is complete"));
  3049. }
  3050. return result;
  3051. }
  3052. /* called from multi.c while DOing */
  3053. static CURLcode scp_doing(struct Curl_easy *data,
  3054. bool *dophase_done)
  3055. {
  3056. CURLcode result;
  3057. result = ssh_multi_statemach(data, dophase_done);
  3058. if(*dophase_done) {
  3059. DEBUGF(infof(data, "DO phase is complete"));
  3060. }
  3061. return result;
  3062. }
  3063. /*
  3064. * The DO function is generic for both protocols. There was previously two
  3065. * separate ones but this way means less duplicated code.
  3066. */
  3067. static CURLcode ssh_do(struct Curl_easy *data, bool *done)
  3068. {
  3069. CURLcode result;
  3070. bool connected = FALSE;
  3071. struct connectdata *conn = data->conn;
  3072. struct ssh_conn *sshc = &conn->proto.sshc;
  3073. *done = FALSE; /* default to false */
  3074. data->req.size = -1; /* make sure this is unknown at this point */
  3075. sshc->actualcode = CURLE_OK; /* reset error code */
  3076. sshc->secondCreateDirs = 0; /* reset the create dir attempt state
  3077. variable */
  3078. Curl_pgrsSetUploadCounter(data, 0);
  3079. Curl_pgrsSetDownloadCounter(data, 0);
  3080. Curl_pgrsSetUploadSize(data, -1);
  3081. Curl_pgrsSetDownloadSize(data, -1);
  3082. if(conn->handler->protocol & CURLPROTO_SCP)
  3083. result = scp_perform(data, &connected, done);
  3084. else
  3085. result = sftp_perform(data, &connected, done);
  3086. return result;
  3087. }
  3088. /* BLOCKING, but the function is using the state machine so the only reason
  3089. this is still blocking is that the multi interface code has no support for
  3090. disconnecting operations that takes a while */
  3091. static CURLcode scp_disconnect(struct Curl_easy *data,
  3092. struct connectdata *conn,
  3093. bool dead_connection)
  3094. {
  3095. CURLcode result = CURLE_OK;
  3096. struct ssh_conn *sshc = &conn->proto.sshc;
  3097. (void) dead_connection;
  3098. if(sshc->ssh_session) {
  3099. /* only if there is a session still around to use! */
  3100. state(data, SSH_SESSION_DISCONNECT);
  3101. result = ssh_block_statemach(data, conn, TRUE);
  3102. }
  3103. return result;
  3104. }
  3105. /* generic done function for both SCP and SFTP called from their specific
  3106. done functions */
  3107. static CURLcode ssh_done(struct Curl_easy *data, CURLcode status)
  3108. {
  3109. CURLcode result = CURLE_OK;
  3110. struct SSHPROTO *sshp = data->req.p.ssh;
  3111. struct connectdata *conn = data->conn;
  3112. if(!status)
  3113. /* run the state-machine */
  3114. result = ssh_block_statemach(data, conn, FALSE);
  3115. else
  3116. result = status;
  3117. Curl_safefree(sshp->path);
  3118. Curl_dyn_free(&sshp->readdir);
  3119. if(Curl_pgrsDone(data))
  3120. return CURLE_ABORTED_BY_CALLBACK;
  3121. data->req.keepon = 0; /* clear all bits */
  3122. return result;
  3123. }
  3124. static CURLcode scp_done(struct Curl_easy *data, CURLcode status,
  3125. bool premature)
  3126. {
  3127. (void)premature; /* not used */
  3128. if(!status)
  3129. state(data, SSH_SCP_DONE);
  3130. return ssh_done(data, status);
  3131. }
  3132. static ssize_t scp_send(struct Curl_easy *data, int sockindex,
  3133. const void *mem, size_t len, bool eos, CURLcode *err)
  3134. {
  3135. ssize_t nwrite;
  3136. struct connectdata *conn = data->conn;
  3137. struct ssh_conn *sshc = &conn->proto.sshc;
  3138. (void)sockindex; /* we only support SCP on the fixed known primary socket */
  3139. (void)eos;
  3140. /* libssh2_channel_write() returns int! */
  3141. nwrite = (ssize_t) libssh2_channel_write(sshc->ssh_channel, mem, len);
  3142. ssh_block2waitfor(data, (nwrite == LIBSSH2_ERROR_EAGAIN));
  3143. if(nwrite == LIBSSH2_ERROR_EAGAIN) {
  3144. *err = CURLE_AGAIN;
  3145. nwrite = 0;
  3146. }
  3147. else if(nwrite < LIBSSH2_ERROR_NONE) {
  3148. *err = libssh2_session_error_to_CURLE((int)nwrite);
  3149. nwrite = -1;
  3150. }
  3151. return nwrite;
  3152. }
  3153. static ssize_t scp_recv(struct Curl_easy *data, int sockindex,
  3154. char *mem, size_t len, CURLcode *err)
  3155. {
  3156. ssize_t nread;
  3157. struct connectdata *conn = data->conn;
  3158. struct ssh_conn *sshc = &conn->proto.sshc;
  3159. (void)sockindex; /* we only support SCP on the fixed known primary socket */
  3160. /* libssh2_channel_read() returns int */
  3161. nread = (ssize_t) libssh2_channel_read(sshc->ssh_channel, mem, len);
  3162. ssh_block2waitfor(data, (nread == LIBSSH2_ERROR_EAGAIN));
  3163. if(nread == LIBSSH2_ERROR_EAGAIN) {
  3164. *err = CURLE_AGAIN;
  3165. nread = -1;
  3166. }
  3167. return nread;
  3168. }
  3169. /*
  3170. * =============== SFTP ===============
  3171. */
  3172. /*
  3173. ***********************************************************************
  3174. *
  3175. * sftp_perform()
  3176. *
  3177. * This is the actual DO function for SFTP. Get a file/directory according to
  3178. * the options previously setup.
  3179. */
  3180. static
  3181. CURLcode sftp_perform(struct Curl_easy *data,
  3182. bool *connected,
  3183. bool *dophase_done)
  3184. {
  3185. CURLcode result = CURLE_OK;
  3186. DEBUGF(infof(data, "DO phase starts"));
  3187. *dophase_done = FALSE; /* not done yet */
  3188. /* start the first command in the DO phase */
  3189. state(data, SSH_SFTP_QUOTE_INIT);
  3190. /* run the state-machine */
  3191. result = ssh_multi_statemach(data, dophase_done);
  3192. *connected = Curl_conn_is_connected(data->conn, FIRSTSOCKET);
  3193. if(*dophase_done) {
  3194. DEBUGF(infof(data, "DO phase is complete"));
  3195. }
  3196. return result;
  3197. }
  3198. /* called from multi.c while DOing */
  3199. static CURLcode sftp_doing(struct Curl_easy *data,
  3200. bool *dophase_done)
  3201. {
  3202. CURLcode result = ssh_multi_statemach(data, dophase_done);
  3203. if(*dophase_done) {
  3204. DEBUGF(infof(data, "DO phase is complete"));
  3205. }
  3206. return result;
  3207. }
  3208. /* BLOCKING, but the function is using the state machine so the only reason
  3209. this is still blocking is that the multi interface code has no support for
  3210. disconnecting operations that takes a while */
  3211. static CURLcode sftp_disconnect(struct Curl_easy *data,
  3212. struct connectdata *conn, bool dead_connection)
  3213. {
  3214. CURLcode result = CURLE_OK;
  3215. struct ssh_conn *sshc = &conn->proto.sshc;
  3216. (void) dead_connection;
  3217. DEBUGF(infof(data, "SSH DISCONNECT starts now"));
  3218. if(sshc->ssh_session) {
  3219. /* only if there is a session still around to use! */
  3220. state(data, SSH_SFTP_SHUTDOWN);
  3221. result = ssh_block_statemach(data, conn, TRUE);
  3222. }
  3223. DEBUGF(infof(data, "SSH DISCONNECT is done"));
  3224. return result;
  3225. }
  3226. static CURLcode sftp_done(struct Curl_easy *data, CURLcode status,
  3227. bool premature)
  3228. {
  3229. struct connectdata *conn = data->conn;
  3230. struct ssh_conn *sshc = &conn->proto.sshc;
  3231. if(!status) {
  3232. /* Post quote commands are executed after the SFTP_CLOSE state to avoid
  3233. errors that could happen due to open file handles during POSTQUOTE
  3234. operation */
  3235. if(!premature && data->set.postquote && !conn->bits.retry)
  3236. sshc->nextstate = SSH_SFTP_POSTQUOTE_INIT;
  3237. state(data, SSH_SFTP_CLOSE);
  3238. }
  3239. return ssh_done(data, status);
  3240. }
  3241. /* return number of sent bytes */
  3242. static ssize_t sftp_send(struct Curl_easy *data, int sockindex,
  3243. const void *mem, size_t len, bool eos, CURLcode *err)
  3244. {
  3245. ssize_t nwrite;
  3246. struct connectdata *conn = data->conn;
  3247. struct ssh_conn *sshc = &conn->proto.sshc;
  3248. (void)sockindex;
  3249. (void)eos;
  3250. nwrite = libssh2_sftp_write(sshc->sftp_handle, mem, len);
  3251. ssh_block2waitfor(data, (nwrite == LIBSSH2_ERROR_EAGAIN));
  3252. if(nwrite == LIBSSH2_ERROR_EAGAIN) {
  3253. *err = CURLE_AGAIN;
  3254. nwrite = 0;
  3255. }
  3256. else if(nwrite < LIBSSH2_ERROR_NONE) {
  3257. *err = libssh2_session_error_to_CURLE((int)nwrite);
  3258. nwrite = -1;
  3259. }
  3260. return nwrite;
  3261. }
  3262. /*
  3263. * Return number of received (decrypted) bytes
  3264. * or <0 on error
  3265. */
  3266. static ssize_t sftp_recv(struct Curl_easy *data, int sockindex,
  3267. char *mem, size_t len, CURLcode *err)
  3268. {
  3269. ssize_t nread;
  3270. struct connectdata *conn = data->conn;
  3271. struct ssh_conn *sshc = &conn->proto.sshc;
  3272. (void)sockindex;
  3273. nread = libssh2_sftp_read(sshc->sftp_handle, mem, len);
  3274. ssh_block2waitfor(data, (nread == LIBSSH2_ERROR_EAGAIN));
  3275. if(nread == LIBSSH2_ERROR_EAGAIN) {
  3276. *err = CURLE_AGAIN;
  3277. nread = -1;
  3278. }
  3279. else if(nread < 0) {
  3280. *err = libssh2_session_error_to_CURLE((int)nread);
  3281. }
  3282. return nread;
  3283. }
  3284. static const char *sftp_libssh2_strerror(unsigned long err)
  3285. {
  3286. switch(err) {
  3287. case LIBSSH2_FX_NO_SUCH_FILE:
  3288. return "No such file or directory";
  3289. case LIBSSH2_FX_PERMISSION_DENIED:
  3290. return "Permission denied";
  3291. case LIBSSH2_FX_FAILURE:
  3292. return "Operation failed";
  3293. case LIBSSH2_FX_BAD_MESSAGE:
  3294. return "Bad message from SFTP server";
  3295. case LIBSSH2_FX_NO_CONNECTION:
  3296. return "Not connected to SFTP server";
  3297. case LIBSSH2_FX_CONNECTION_LOST:
  3298. return "Connection to SFTP server lost";
  3299. case LIBSSH2_FX_OP_UNSUPPORTED:
  3300. return "Operation not supported by SFTP server";
  3301. case LIBSSH2_FX_INVALID_HANDLE:
  3302. return "Invalid handle";
  3303. case LIBSSH2_FX_NO_SUCH_PATH:
  3304. return "No such file or directory";
  3305. case LIBSSH2_FX_FILE_ALREADY_EXISTS:
  3306. return "File already exists";
  3307. case LIBSSH2_FX_WRITE_PROTECT:
  3308. return "File is write protected";
  3309. case LIBSSH2_FX_NO_MEDIA:
  3310. return "No media";
  3311. case LIBSSH2_FX_NO_SPACE_ON_FILESYSTEM:
  3312. return "Disk full";
  3313. case LIBSSH2_FX_QUOTA_EXCEEDED:
  3314. return "User quota exceeded";
  3315. case LIBSSH2_FX_UNKNOWN_PRINCIPLE:
  3316. return "Unknown principle";
  3317. case LIBSSH2_FX_LOCK_CONFlICT:
  3318. return "File lock conflict";
  3319. case LIBSSH2_FX_DIR_NOT_EMPTY:
  3320. return "Directory not empty";
  3321. case LIBSSH2_FX_NOT_A_DIRECTORY:
  3322. return "Not a directory";
  3323. case LIBSSH2_FX_INVALID_FILENAME:
  3324. return "Invalid filename";
  3325. case LIBSSH2_FX_LINK_LOOP:
  3326. return "Link points to itself";
  3327. }
  3328. return "Unknown error in libssh2";
  3329. }
  3330. CURLcode Curl_ssh_init(void)
  3331. {
  3332. #ifdef HAVE_LIBSSH2_INIT
  3333. if(libssh2_init(0)) {
  3334. DEBUGF(fprintf(stderr, "Error: libssh2_init failed\n"));
  3335. return CURLE_FAILED_INIT;
  3336. }
  3337. #endif
  3338. return CURLE_OK;
  3339. }
  3340. void Curl_ssh_cleanup(void)
  3341. {
  3342. #ifdef HAVE_LIBSSH2_EXIT
  3343. (void)libssh2_exit();
  3344. #endif
  3345. }
  3346. void Curl_ssh_version(char *buffer, size_t buflen)
  3347. {
  3348. (void)msnprintf(buffer, buflen, "libssh2/%s", CURL_LIBSSH2_VERSION);
  3349. }
  3350. /* The SSH session is associated with the *CONNECTION* but the callback user
  3351. * pointer is an easy handle pointer. This function allows us to reassign the
  3352. * user pointer to the *CURRENT* (new) easy handle.
  3353. */
  3354. static void ssh_attach(struct Curl_easy *data, struct connectdata *conn)
  3355. {
  3356. DEBUGASSERT(data);
  3357. DEBUGASSERT(conn);
  3358. if(conn->handler->protocol & PROTO_FAMILY_SSH) {
  3359. struct ssh_conn *sshc = &conn->proto.sshc;
  3360. if(sshc->ssh_session) {
  3361. /* only re-attach if the session already exists */
  3362. void **abstract = libssh2_session_abstract(sshc->ssh_session);
  3363. *abstract = data;
  3364. }
  3365. }
  3366. }
  3367. #endif /* USE_LIBSSH2 */