userauth2-client.c 110 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729
  1. /*
  2. * Packet protocol layer for the client side of the SSH-2 userauth
  3. * protocol (RFC 4252).
  4. */
  5. #include <assert.h>
  6. #include "putty.h"
  7. #include "ssh.h"
  8. #include "bpp.h"
  9. #include "ppl.h"
  10. #include "sshcr.h"
  11. #ifndef NO_GSSAPI
  12. #include "gssc.h"
  13. #include "gss.h"
  14. #endif
  15. #define BANNER_LIMIT 131072
  16. typedef struct agent_key {
  17. strbuf *blob, *comment;
  18. ptrlen algorithm;
  19. } agent_key;
  20. struct ssh2_userauth_state {
  21. int crState;
  22. PacketProtocolLayer *transport_layer, *successor_layer;
  23. Filename *keyfile, *detached_cert_file;
  24. bool show_banner, tryagent, notrivialauth, change_username;
  25. char *hostname, *fullhostname;
  26. int port;
  27. char *default_username;
  28. bool try_ki_auth, try_gssapi_auth, try_gssapi_kex_auth, gssapi_fwd;
  29. char *loghost; // WINSCP
  30. bool change_password; // WINSCP
  31. ptrlen session_id;
  32. enum {
  33. AUTH_TYPE_NONE,
  34. AUTH_TYPE_PUBLICKEY,
  35. AUTH_TYPE_PUBLICKEY_OFFER_LOUD,
  36. AUTH_TYPE_PUBLICKEY_OFFER_QUIET,
  37. AUTH_TYPE_PASSWORD,
  38. AUTH_TYPE_GSSAPI, /* always QUIET */
  39. AUTH_TYPE_KEYBOARD_INTERACTIVE,
  40. AUTH_TYPE_KEYBOARD_INTERACTIVE_QUIET
  41. } type;
  42. bool need_pw, can_pubkey, can_passwd, can_keyb_inter;
  43. SeatPromptResult spr;
  44. bool tried_pubkey_config, done_agent;
  45. struct ssh_connection_shared_gss_state *shgss;
  46. #ifndef NO_GSSAPI
  47. bool can_gssapi;
  48. bool can_gssapi_keyex_auth;
  49. bool tried_gssapi;
  50. bool tried_gssapi_keyex_auth;
  51. time_t gss_cred_expiry;
  52. Ssh_gss_buf gss_buf;
  53. Ssh_gss_buf gss_rcvtok, gss_sndtok;
  54. Ssh_gss_stat gss_stat;
  55. #endif
  56. bool suppress_wait_for_response_packet;
  57. strbuf *last_methods_string;
  58. bool kbd_inter_refused;
  59. prompts_t *cur_prompt;
  60. uint32_t num_prompts;
  61. const char *username;
  62. char *locally_allocated_username;
  63. char *password;
  64. bool got_username;
  65. strbuf *publickey_blob, *detached_cert_blob, *cert_pubkey_diagnosed;
  66. bool privatekey_available, privatekey_encrypted;
  67. char *publickey_algorithm;
  68. char *publickey_comment;
  69. void *agent_response_to_free;
  70. ptrlen agent_response;
  71. BinarySource asrc[1]; /* for reading SSH agent response */
  72. size_t agent_keys_len;
  73. agent_key *agent_keys;
  74. size_t agent_key_index, agent_key_limit;
  75. ptrlen agent_keyalg;
  76. unsigned signflags;
  77. int len;
  78. PktOut *pktout;
  79. bool is_trivial_auth;
  80. agent_pending_query *auth_agent_query;
  81. bufchain banner;
  82. bufchain_sink banner_bs;
  83. StripCtrlChars *banner_scc;
  84. bool banner_scc_initialised;
  85. char *authplugin_cmd;
  86. Socket *authplugin;
  87. uint32_t authplugin_version;
  88. Plug authplugin_plug;
  89. bufchain authplugin_bc;
  90. strbuf *authplugin_incoming_msg;
  91. size_t authplugin_backlog;
  92. bool authplugin_eof;
  93. bool authplugin_ki_active;
  94. StripCtrlChars *ki_scc;
  95. bool ki_scc_initialised;
  96. bool ki_printed_header;
  97. Seat *seat; // WINSCP
  98. PacketProtocolLayer ppl;
  99. };
  100. static void ssh2_userauth_free(PacketProtocolLayer *);
  101. static void ssh2_userauth_process_queue(PacketProtocolLayer *);
  102. static bool ssh2_userauth_get_specials(
  103. PacketProtocolLayer *ppl, add_special_fn_t add_special, void *ctx);
  104. static void ssh2_userauth_special_cmd(PacketProtocolLayer *ppl,
  105. SessionSpecialCode code, int arg);
  106. static void ssh2_userauth_reconfigure(PacketProtocolLayer *ppl, Conf *conf);
  107. static void ssh2_userauth_agent_query(struct ssh2_userauth_state *, strbuf *);
  108. static void ssh2_userauth_agent_callback(void *, void *, int);
  109. static void ssh2_userauth_add_sigblob(
  110. struct ssh2_userauth_state *s, PktOut *pkt, ptrlen pkblob, ptrlen sigblob);
  111. static void ssh2_userauth_add_alg_and_publickey(
  112. struct ssh2_userauth_state *s, PktOut *pkt, ptrlen alg, ptrlen pkblob);
  113. static void ssh2_userauth_add_session_id(
  114. struct ssh2_userauth_state *s, strbuf *sigdata);
  115. #ifndef NO_GSSAPI
  116. static PktOut *ssh2_userauth_gss_packet(
  117. struct ssh2_userauth_state *s, const char *authtype);
  118. #endif
  119. static bool ssh2_userauth_ki_setup_prompts(
  120. struct ssh2_userauth_state *s, BinarySource *src, bool plugin);
  121. static bool ssh2_userauth_ki_run_prompts(struct ssh2_userauth_state *s);
  122. static void ssh2_userauth_ki_write_responses(
  123. struct ssh2_userauth_state *s, BinarySink *bs);
  124. static void ssh2_userauth_final_output(PacketProtocolLayer *ppl);
  125. static void ssh2_userauth_print_banner(struct ssh2_userauth_state *s);
  126. static ptrlen workaround_rsa_sha2_cert_userauth(
  127. struct ssh2_userauth_state *s, ptrlen id);
  128. static const PacketProtocolLayerVtable ssh2_userauth_vtable = {
  129. // WINSCP
  130. /*.free =*/ ssh2_userauth_free,
  131. /*.process_queue =*/ ssh2_userauth_process_queue,
  132. /*.get_specials =*/ ssh2_userauth_get_specials,
  133. /*.special_cmd =*/ ssh2_userauth_special_cmd,
  134. /*.reconfigure =*/ ssh2_userauth_reconfigure,
  135. /*.queued_data_size =*/ ssh_ppl_default_queued_data_size,
  136. /*.final_output =*/ ssh2_userauth_final_output,
  137. /*.name =*/ "ssh-userauth",
  138. NULL, // WINSCP
  139. };
  140. PacketProtocolLayer *ssh2_userauth_new(
  141. PacketProtocolLayer *successor_layer,
  142. const char *hostname, int port, const char *fullhostname,
  143. Filename *keyfile, Filename *detached_cert_file,
  144. bool show_banner, bool tryagent, bool notrivialauth,
  145. const char *default_username, bool change_username,
  146. bool try_ki_auth, bool try_gssapi_auth, bool try_gssapi_kex_auth,
  147. bool gssapi_fwd, struct ssh_connection_shared_gss_state *shgss,
  148. const char *authplugin_cmd,
  149. const char * loghost, bool change_password, Seat *seat) // WINSCP
  150. {
  151. struct ssh2_userauth_state *s = snew(struct ssh2_userauth_state);
  152. memset(s, 0, sizeof(*s));
  153. s->seat = seat;
  154. s->ppl.vt = &ssh2_userauth_vtable;
  155. s->successor_layer = successor_layer;
  156. s->hostname = dupstr(hostname);
  157. s->port = port;
  158. s->fullhostname = dupstr(fullhostname);
  159. s->keyfile = filename_copy(keyfile);
  160. s->detached_cert_file = filename_copy(detached_cert_file);
  161. s->show_banner = show_banner;
  162. s->tryagent = tryagent;
  163. s->notrivialauth = notrivialauth;
  164. s->default_username = dupstr(default_username);
  165. s->change_username = change_username;
  166. s->try_ki_auth = try_ki_auth;
  167. s->try_gssapi_auth = try_gssapi_auth;
  168. s->try_gssapi_kex_auth = try_gssapi_kex_auth;
  169. s->gssapi_fwd = gssapi_fwd;
  170. s->shgss = shgss;
  171. s->last_methods_string = strbuf_new();
  172. s->is_trivial_auth = true;
  173. s->loghost = dupstr(loghost); // WINSCP
  174. s->change_password = change_password;
  175. bufchain_init(&s->banner);
  176. bufchain_sink_init(&s->banner_bs, &s->banner);
  177. s->authplugin_cmd = dupstr(authplugin_cmd);
  178. bufchain_init(&s->authplugin_bc);
  179. return &s->ppl;
  180. }
  181. void ssh2_userauth_set_transport_layer(PacketProtocolLayer *userauth,
  182. PacketProtocolLayer *transport)
  183. {
  184. struct ssh2_userauth_state *s =
  185. container_of(userauth, struct ssh2_userauth_state, ppl);
  186. s->transport_layer = transport;
  187. }
  188. static void ssh2_userauth_free(PacketProtocolLayer *ppl)
  189. {
  190. struct ssh2_userauth_state *s =
  191. container_of(ppl, struct ssh2_userauth_state, ppl);
  192. bufchain_clear(&s->banner);
  193. if (s->successor_layer)
  194. ssh_ppl_free(s->successor_layer);
  195. if (s->agent_keys) {
  196. size_t i; // WINSCP
  197. for (i = 0; i < s->agent_keys_len; i++) {
  198. strbuf_free(s->agent_keys[i].blob);
  199. strbuf_free(s->agent_keys[i].comment);
  200. }
  201. sfree(s->agent_keys);
  202. }
  203. sfree(s->agent_response_to_free);
  204. if (s->auth_agent_query)
  205. agent_cancel_query(s->auth_agent_query);
  206. filename_free(s->keyfile);
  207. filename_free(s->detached_cert_file);
  208. sfree(s->default_username);
  209. sfree(s->locally_allocated_username);
  210. sfree(s->hostname);
  211. sfree(s->fullhostname);
  212. if (s->cur_prompt)
  213. free_prompts(s->cur_prompt);
  214. sfree(s->publickey_comment);
  215. sfree(s->publickey_algorithm);
  216. if (s->publickey_blob)
  217. strbuf_free(s->publickey_blob);
  218. if (s->detached_cert_blob)
  219. strbuf_free(s->detached_cert_blob);
  220. if (s->cert_pubkey_diagnosed)
  221. strbuf_free(s->cert_pubkey_diagnosed);
  222. strbuf_free(s->last_methods_string);
  223. sfree(s->loghost);
  224. if (s->banner_scc)
  225. stripctrl_free(s->banner_scc);
  226. if (s->ki_scc)
  227. stripctrl_free(s->ki_scc);
  228. sfree(s->authplugin_cmd);
  229. if (s->authplugin)
  230. sk_close(s->authplugin);
  231. bufchain_clear(&s->authplugin_bc);
  232. if (s->authplugin_incoming_msg)
  233. strbuf_free(s->authplugin_incoming_msg);
  234. sfree(s);
  235. }
  236. static void ssh2_userauth_handle_banner_packet(struct ssh2_userauth_state *s,
  237. PktIn *pktin)
  238. {
  239. if (!s->show_banner)
  240. return;
  241. { // WINSCP
  242. ptrlen string = get_string(pktin);
  243. if (string.len > BANNER_LIMIT - bufchain_size(&s->banner))
  244. string.len = BANNER_LIMIT - bufchain_size(&s->banner);
  245. if (!s->banner_scc_initialised) {
  246. s->banner_scc = seat_stripctrl_new(
  247. s->ppl.seat, BinarySink_UPCAST(&s->banner_bs), SIC_BANNER);
  248. if (s->banner_scc)
  249. stripctrl_enable_line_limiting(s->banner_scc);
  250. s->banner_scc_initialised = true;
  251. }
  252. if (s->banner_scc)
  253. put_datapl(s->banner_scc, string);
  254. else
  255. put_datapl(&s->banner_bs, string);
  256. } // WINSCP
  257. }
  258. static void ssh2_userauth_filter_queue(struct ssh2_userauth_state *s)
  259. {
  260. PktIn *pktin;
  261. while ((pktin = pq_peek(s->ppl.in_pq)) != NULL) {
  262. switch (pktin->type) {
  263. case SSH2_MSG_USERAUTH_BANNER:
  264. ssh2_userauth_handle_banner_packet(s, pktin);
  265. pq_pop(s->ppl.in_pq);
  266. break;
  267. default:
  268. return;
  269. }
  270. }
  271. }
  272. static PktIn *ssh2_userauth_pop(struct ssh2_userauth_state *s)
  273. {
  274. ssh2_userauth_filter_queue(s);
  275. return pq_pop(s->ppl.in_pq);
  276. }
  277. static bool ssh2_userauth_signflags(struct ssh2_userauth_state *s,
  278. unsigned *signflags, const char **algname)
  279. {
  280. *signflags = 0; /* default */
  281. { // WINSCP
  282. const ssh_keyalg *alg = find_pubkey_alg(*algname);
  283. if (!alg)
  284. return false; /* we don't know how to upgrade this */
  285. { // WINSCP
  286. unsigned supported_flags = ssh_keyalg_supported_flags(alg);
  287. if (s->ppl.bpp->ext_info_rsa_sha512_ok &&
  288. (supported_flags & SSH_AGENT_RSA_SHA2_512)) {
  289. *signflags = SSH_AGENT_RSA_SHA2_512;
  290. } else if (s->ppl.bpp->ext_info_rsa_sha256_ok &&
  291. (supported_flags & SSH_AGENT_RSA_SHA2_256)) {
  292. *signflags = SSH_AGENT_RSA_SHA2_256;
  293. } else {
  294. return false;
  295. }
  296. *algname = ssh_keyalg_alternate_ssh_id(alg, *signflags);
  297. return true;
  298. } // WINSCP
  299. } // WINSCP
  300. }
  301. static void authplugin_plug_log(Plug *plug, Socket *sock, PlugLogType type,
  302. SockAddr *addr, int port,
  303. const char *err_msg, int err_code)
  304. {
  305. struct ssh2_userauth_state *s = container_of(
  306. plug, struct ssh2_userauth_state, authplugin_plug);
  307. PacketProtocolLayer *ppl = &s->ppl; /* for ppl_logevent */
  308. if (type == PLUGLOG_PROXY_MSG)
  309. ppl_logevent("%s", err_msg);
  310. }
  311. static void authplugin_plug_closing(
  312. Plug *plug, PlugCloseType type, const char *error_msg)
  313. {
  314. struct ssh2_userauth_state *s = container_of(
  315. plug, struct ssh2_userauth_state, authplugin_plug);
  316. s->authplugin_eof = true;
  317. queue_idempotent_callback(&s->ppl.ic_process_queue);
  318. }
  319. static void authplugin_plug_receive(
  320. Plug *plug, int urgent, const char *data, size_t len)
  321. {
  322. struct ssh2_userauth_state *s = container_of(
  323. plug, struct ssh2_userauth_state, authplugin_plug);
  324. bufchain_add(&s->authplugin_bc, data, len);
  325. queue_idempotent_callback(&s->ppl.ic_process_queue);
  326. }
  327. static void authplugin_plug_sent(Plug *plug, size_t bufsize)
  328. {
  329. struct ssh2_userauth_state *s = container_of(
  330. plug, struct ssh2_userauth_state, authplugin_plug);
  331. s->authplugin_backlog = bufsize;
  332. queue_idempotent_callback(&s->ppl.ic_process_queue);
  333. }
  334. static const PlugVtable authplugin_plugvt = {
  335. /*.log =*/ authplugin_plug_log,
  336. /*.closing =*/ authplugin_plug_closing,
  337. /*.receive =*/ authplugin_plug_receive,
  338. /*.sent =*/ authplugin_plug_sent,
  339. NULL, // WINSCP
  340. };
  341. static strbuf *authplugin_newmsg(uint8_t type)
  342. {
  343. strbuf *amsg = strbuf_new_nm();
  344. put_uint32(amsg, 0); /* fill in later */
  345. put_byte(amsg, type);
  346. return amsg;
  347. }
  348. static void authplugin_send_free(struct ssh2_userauth_state *s, strbuf *amsg)
  349. {
  350. PUT_32BIT_MSB_FIRST(amsg->u, amsg->len - 4);
  351. assert(s->authplugin);
  352. s->authplugin_backlog = sk_write(s->authplugin, amsg->u, amsg->len);
  353. strbuf_free(amsg);
  354. }
  355. static bool authplugin_expect_msg(struct ssh2_userauth_state *s,
  356. unsigned *type, BinarySource *src)
  357. {
  358. if (s->authplugin_eof) {
  359. *type = PLUGIN_EOF;
  360. return true;
  361. }
  362. { // WINSCP
  363. uint8_t len[4];
  364. if (!bufchain_try_fetch(&s->authplugin_bc, len, 4))
  365. return false;
  366. { // WINSCP
  367. size_t size = GET_32BIT_MSB_FIRST(len);
  368. if (bufchain_size(&s->authplugin_bc) - 4 < size)
  369. return false;
  370. if (s->authplugin_incoming_msg) {
  371. strbuf_clear(s->authplugin_incoming_msg);
  372. } else {
  373. s->authplugin_incoming_msg = strbuf_new_nm();
  374. }
  375. bufchain_consume(&s->authplugin_bc, 4); /* eat length field */
  376. bufchain_fetch_consume(
  377. &s->authplugin_bc, strbuf_append(s->authplugin_incoming_msg, size),
  378. size);
  379. BinarySource_BARE_INIT_PL(
  380. src, ptrlen_from_strbuf(s->authplugin_incoming_msg));
  381. *type = get_byte(src);
  382. if (get_err(src))
  383. *type = PLUGIN_NOTYPE;
  384. return true;
  385. } // WINSCP
  386. } // WINSCP
  387. }
  388. static void authplugin_bad_packet(struct ssh2_userauth_state *s,
  389. unsigned type, const char *fmt, ...)
  390. {
  391. strbuf *msg = strbuf_new();
  392. switch (type) {
  393. case PLUGIN_EOF:
  394. put_dataz(msg, "Unexpected end of file from auth helper plugin");
  395. break;
  396. case PLUGIN_NOTYPE:
  397. put_dataz(msg, "Received malformed packet from auth helper plugin "
  398. "(too short to have a type code)");
  399. break;
  400. default:
  401. put_fmt(msg, "Received unknown message type %u "
  402. "from auth helper plugin", type);
  403. break;
  404. #define CASEDECL(name, value) \
  405. case name: \
  406. put_fmt(msg, "Received unexpected %s message from auth helper " \
  407. "plugin", #name); \
  408. break;
  409. AUTHPLUGIN_MSG_NAMES(CASEDECL);
  410. #undef CASEDECL
  411. }
  412. if (fmt) {
  413. put_dataz(msg, " (");
  414. { // WINSCP
  415. va_list ap;
  416. va_start(ap, fmt);
  417. put_fmt(msg, fmt, ap);
  418. va_end(ap);
  419. put_dataz(msg, ")");
  420. } // WINSCP
  421. }
  422. ssh_sw_abort(s->ppl.ssh, "%s", msg->s);
  423. strbuf_free(msg);
  424. }
  425. static void ssh2_userauth_process_queue(PacketProtocolLayer *ppl)
  426. {
  427. struct ssh2_userauth_state *s =
  428. container_of(ppl, struct ssh2_userauth_state, ppl);
  429. PktIn *pktin;
  430. ssh2_userauth_filter_queue(s); /* no matter why we were called */
  431. crBegin(s->crState);
  432. #ifndef NO_GSSAPI
  433. s->tried_gssapi = false;
  434. s->tried_gssapi_keyex_auth = false;
  435. #endif
  436. /*
  437. * Misc one-time setup for authentication.
  438. */
  439. s->publickey_blob = NULL;
  440. s->session_id = ssh2_transport_get_session_id(s->transport_layer);
  441. /*
  442. * Load the public half of any configured public key file for
  443. * later use.
  444. */
  445. if (!filename_is_null(s->keyfile)) {
  446. int keytype;
  447. ppl_logevent(WINSCP_BOM "Reading key file \"%s\"",
  448. filename_to_str(s->keyfile));
  449. keytype = key_type(s->keyfile);
  450. if (keytype == SSH_KEYTYPE_SSH2 ||
  451. keytype == SSH_KEYTYPE_SSH2_PUBLIC_RFC4716 ||
  452. keytype == SSH_KEYTYPE_SSH2_PUBLIC_OPENSSH) {
  453. const char *error;
  454. s->publickey_blob = strbuf_new();
  455. if (ppk_loadpub_f(s->keyfile, &s->publickey_algorithm,
  456. BinarySink_UPCAST(s->publickey_blob),
  457. &s->publickey_comment, &error)) {
  458. s->privatekey_available = (keytype == SSH_KEYTYPE_SSH2);
  459. if (!s->privatekey_available)
  460. ppl_logevent("Key file contains public key only");
  461. s->privatekey_encrypted = ppk_encrypted_f(s->keyfile, NULL);
  462. } else {
  463. ppl_logevent("Unable to load key (%s)", error);
  464. ppl_printf(WINSCP_BOM "Unable to load key file \"%s\" (%s)\r\n",
  465. filename_to_str(s->keyfile), error);
  466. strbuf_free(s->publickey_blob);
  467. s->publickey_blob = NULL;
  468. }
  469. } else {
  470. ppl_logevent("Unable to use this key file (%s)",
  471. key_type_to_str(keytype));
  472. ppl_printf(WINSCP_BOM "Unable to use key file \"%s\" (%s)\r\n",
  473. filename_to_str(s->keyfile),
  474. key_type_to_str(keytype));
  475. s->publickey_blob = NULL;
  476. }
  477. }
  478. /*
  479. * If the user provided a detached certificate file, load that.
  480. */
  481. if (!filename_is_null(s->detached_cert_file)) {
  482. char *cert_error = NULL;
  483. strbuf *cert_blob = strbuf_new();
  484. char *algname = NULL;
  485. char *comment = NULL;
  486. ppl_logevent(WINSCP_BOM "Reading certificate file \"%s\"",
  487. filename_to_str(s->detached_cert_file));
  488. { // WINSCP
  489. int keytype = key_type(s->detached_cert_file);
  490. if (!(keytype == SSH_KEYTYPE_SSH2_PUBLIC_RFC4716 ||
  491. keytype == SSH_KEYTYPE_SSH2_PUBLIC_OPENSSH)) {
  492. cert_error = dupstr(key_type_to_str(keytype));
  493. goto cert_load_done;
  494. }
  495. { // WINSCP
  496. const char *error;
  497. bool success = ppk_loadpub_f(
  498. s->detached_cert_file, &algname,
  499. BinarySink_UPCAST(cert_blob), &comment, &error);
  500. if (!success) {
  501. cert_error = dupstr(error);
  502. goto cert_load_done;
  503. }
  504. { // WINSCP
  505. const ssh_keyalg *certalg = find_pubkey_alg(algname);
  506. if (!certalg) {
  507. cert_error = dupprintf(
  508. "unrecognised certificate type '%s'", algname);
  509. goto cert_load_done;
  510. }
  511. if (!certalg->is_certificate) {
  512. cert_error = dupprintf(
  513. "key type '%s' is not a certificate", certalg->ssh_id);
  514. goto cert_load_done;
  515. }
  516. /* OK, store the certificate blob to substitute for the
  517. * public blob in all publickey auth packets. */
  518. if (s->detached_cert_blob)
  519. strbuf_free(s->detached_cert_blob);
  520. s->detached_cert_blob = cert_blob;
  521. cert_blob = NULL; /* prevent free */
  522. cert_load_done:
  523. if (cert_error) {
  524. ppl_logevent("Unable to use this certificate file (%s)",
  525. cert_error);
  526. ppl_printf(
  527. WINSCP_BOM "Unable to use certificate file \"%s\" (%s)\r\n",
  528. filename_to_str(s->detached_cert_file), cert_error);
  529. sfree(cert_error);
  530. }
  531. if (cert_blob)
  532. strbuf_free(cert_blob);
  533. sfree(algname);
  534. sfree(comment);
  535. } // WINSCP
  536. } // WINSCP
  537. } // WINSCP
  538. }
  539. /*
  540. * Find out about any keys Pageant has (but if there's a public
  541. * key configured, filter out all others).
  542. */
  543. if (s->tryagent && agent_exists()) {
  544. ppl_logevent("Pageant is running. Requesting keys.");
  545. /* Request the keys held by the agent. */
  546. {
  547. strbuf *request = strbuf_new_for_agent_query();
  548. put_byte(request, SSH2_AGENTC_REQUEST_IDENTITIES);
  549. ssh2_userauth_agent_query(s, request);
  550. strbuf_free(request);
  551. crWaitUntilV(!s->auth_agent_query);
  552. }
  553. BinarySource_BARE_INIT_PL(s->asrc, s->agent_response);
  554. get_uint32(s->asrc); /* skip length field */
  555. if (get_byte(s->asrc) == SSH2_AGENT_IDENTITIES_ANSWER) {
  556. size_t nkeys = get_uint32(s->asrc);
  557. size_t origpos = s->asrc->pos;
  558. /*
  559. * Check that the agent response is well formed.
  560. */
  561. { // WINSCP
  562. size_t i; // WINSCP
  563. for (i = 0; i < nkeys; i++) {
  564. get_string(s->asrc); /* blob */
  565. get_string(s->asrc); /* comment */
  566. if (get_err(s->asrc)) {
  567. ppl_logevent("Pageant's response was truncated");
  568. goto done_agent_query;
  569. }
  570. }
  571. } // WINSCP
  572. /*
  573. * Copy the list of public-key blobs out of the Pageant
  574. * response.
  575. */
  576. BinarySource_REWIND_TO(s->asrc, origpos);
  577. s->agent_keys_len = nkeys;
  578. s->agent_keys = snewn(s->agent_keys_len, agent_key);
  579. { // WINSCP
  580. size_t i; // WINSCP
  581. for (i = 0; i < nkeys; i++) {
  582. s->agent_keys[i].blob = strbuf_dup(get_string(s->asrc));
  583. s->agent_keys[i].comment = strbuf_dup(get_string(s->asrc));
  584. { // WINSCP
  585. /* Also, extract the algorithm string from the start
  586. * of the public-key blob. */
  587. s->agent_keys[i].algorithm = pubkey_blob_to_alg_name(
  588. ptrlen_from_strbuf(s->agent_keys[i].blob));
  589. } // WINSCP
  590. }
  591. } // WINSCP
  592. ppl_logevent("Pageant has %"SIZEu" SSH-2 keys", nkeys);
  593. if (s->publickey_blob) {
  594. /*
  595. * If we've been given a specific public key blob,
  596. * filter the list of keys to try from the agent down
  597. * to only that one, or none if it's not there.
  598. */
  599. ptrlen our_blob = ptrlen_from_strbuf(s->publickey_blob);
  600. size_t i;
  601. for (i = 0; i < nkeys; i++) {
  602. if (ptrlen_eq_ptrlen(our_blob, ptrlen_from_strbuf(
  603. s->agent_keys[i].blob)))
  604. break;
  605. }
  606. if (i < nkeys) {
  607. ppl_logevent("Pageant key #%"SIZEu" matches "
  608. "configured key file", i);
  609. s->agent_key_index = i;
  610. s->agent_key_limit = i+1;
  611. } else {
  612. ppl_logevent("Configured key file not in Pageant");
  613. s->agent_key_index = 0;
  614. s->agent_key_limit = 0;
  615. }
  616. } else {
  617. /*
  618. * Otherwise, try them all.
  619. */
  620. s->agent_key_index = 0;
  621. s->agent_key_limit = nkeys;
  622. }
  623. } else {
  624. ppl_logevent("Failed to get reply from Pageant");
  625. }
  626. done_agent_query:;
  627. }
  628. s->got_username = false;
  629. if (*s->authplugin_cmd) {
  630. s->authplugin_plug.vt = &authplugin_plugvt;
  631. s->authplugin = platform_start_subprocess(
  632. s->authplugin_cmd, &s->authplugin_plug, "plugin");
  633. ppl_logevent("Started authentication plugin: %s", s->authplugin_cmd);
  634. }
  635. if (s->authplugin) {
  636. strbuf *amsg = authplugin_newmsg(PLUGIN_INIT);
  637. put_uint32(amsg, PLUGIN_PROTOCOL_MAX_VERSION);
  638. put_stringz(amsg, s->hostname);
  639. put_uint32(amsg, s->port);
  640. put_stringz(amsg, s->username ? s->username : "");
  641. authplugin_send_free(s, amsg);
  642. { // WINSCP
  643. BinarySource src[1];
  644. unsigned type;
  645. crMaybeWaitUntilV(authplugin_expect_msg(s, &type, src));
  646. switch (type) {
  647. case PLUGIN_INIT_RESPONSE: {
  648. s->authplugin_version = get_uint32(src);
  649. { // WINSCP
  650. ptrlen username = get_string(src);
  651. if (get_err(src)) {
  652. ssh_sw_abort(s->ppl.ssh, "Received malformed "
  653. "PLUGIN_INIT_RESPONSE from auth helper plugin");
  654. return;
  655. }
  656. if (s->authplugin_version > PLUGIN_PROTOCOL_MAX_VERSION) {
  657. ssh_sw_abort(s->ppl.ssh, "Auth helper plugin announced "
  658. "unsupported version number %"PRIu32,
  659. s->authplugin_version);
  660. return;
  661. }
  662. if (username.len) {
  663. sfree(s->default_username);
  664. s->default_username = mkstr(username);
  665. ppl_logevent("Authentication plugin set username '%s'",
  666. s->default_username);
  667. }
  668. } // WINSCP
  669. break;
  670. }
  671. case PLUGIN_INIT_FAILURE: {
  672. ptrlen message = get_string(src);
  673. if (get_err(src)) {
  674. ssh_sw_abort(s->ppl.ssh, "Received malformed "
  675. "PLUGIN_INIT_FAILURE from auth helper plugin");
  676. return;
  677. }
  678. /* This is a controlled error, so we need not completely
  679. * abandon the connection. Instead, inform the user, and
  680. * proceed as if the plugin was not present */
  681. ppl_printf("Authentication plugin failed to initialise:\r\n");
  682. seat_set_trust_status(s->ppl.seat, false);
  683. ppl_printf("%.*s\r\n", PTRLEN_PRINTF(message));
  684. seat_set_trust_status(s->ppl.seat, true);
  685. sk_close(s->authplugin);
  686. s->authplugin = NULL;
  687. break;
  688. }
  689. default:
  690. authplugin_bad_packet(s, type, "expected PLUGIN_INIT_RESPONSE or "
  691. "PLUGIN_INIT_FAILURE");
  692. return;
  693. }
  694. } // WINSCP
  695. }
  696. /*
  697. * We repeat this whole loop, including the username prompt,
  698. * until we manage a successful authentication. If the user
  699. * types the wrong _password_, they can be sent back to the
  700. * beginning to try another username, if this is configured on.
  701. * (If they specify a username in the config, they are never
  702. * asked, even if they do give a wrong password.)
  703. *
  704. * I think this best serves the needs of
  705. *
  706. * - the people who have no configuration, no keys, and just
  707. * want to try repeated (username,password) pairs until they
  708. * type both correctly
  709. *
  710. * - people who have keys and configuration but occasionally
  711. * need to fall back to passwords
  712. *
  713. * - people with a key held in Pageant, who might not have
  714. * logged in to a particular machine before; so they want to
  715. * type a username, and then _either_ their key will be
  716. * accepted, _or_ they will type a password. If they mistype
  717. * the username they will want to be able to get back and
  718. * retype it!
  719. */
  720. while (1) {
  721. /*
  722. * Get a username.
  723. */
  724. if (s->got_username && !s->change_username) {
  725. /*
  726. * We got a username last time round this loop, and
  727. * with change_username turned off we don't try to get
  728. * it again.
  729. */
  730. } else if ((s->username = s->default_username) == NULL) {
  731. s->cur_prompt = ssh_ppl_new_prompts(&s->ppl);
  732. s->cur_prompt->utf8 = true;
  733. s->cur_prompt->to_server = true;
  734. s->cur_prompt->from_server = false;
  735. s->cur_prompt->name = dupstr("SSH login name");
  736. add_prompt(s->cur_prompt, dupstr("login as: "), true);
  737. s->spr = seat_get_userpass_input(
  738. ppl_get_iseat(&s->ppl), s->cur_prompt);
  739. while (s->spr.kind == SPRK_INCOMPLETE) {
  740. crReturnV;
  741. s->spr = seat_get_userpass_input(
  742. ppl_get_iseat(&s->ppl), s->cur_prompt);
  743. }
  744. if (spr_is_abort(s->spr)) {
  745. /*
  746. * seat_get_userpass_input() failed to get a username.
  747. * Terminate.
  748. */
  749. free_prompts(s->cur_prompt);
  750. s->cur_prompt = NULL;
  751. ssh_spr_close(s->ppl.ssh, s->spr, "username prompt");
  752. return;
  753. }
  754. sfree(s->locally_allocated_username); /* for change_username */
  755. s->username = s->locally_allocated_username =
  756. prompt_get_result(s->cur_prompt->prompts[0]);
  757. free_prompts(s->cur_prompt);
  758. s->cur_prompt = NULL;
  759. } else {
  760. if (seat_verbose(s->ppl.seat) || seat_interactive(s->ppl.seat))
  761. ppl_printf(WINSCP_BOM "Using username \"%s\".\r\n", s->username);
  762. }
  763. s->got_username = true;
  764. /*
  765. * Send an authentication request using method "none": (a)
  766. * just in case it succeeds, and (b) so that we know what
  767. * authentication methods we can usefully try next.
  768. */
  769. s->ppl.bpp->pls->actx = SSH2_PKTCTX_NOAUTH;
  770. s->pktout = ssh_bpp_new_pktout(s->ppl.bpp, SSH2_MSG_USERAUTH_REQUEST);
  771. put_stringz(s->pktout, s->username);
  772. put_stringz(s->pktout, s->successor_layer->vt->name);
  773. put_stringz(s->pktout, "none"); /* method */
  774. pq_push(s->ppl.out_pq, s->pktout);
  775. s->type = AUTH_TYPE_NONE;
  776. s->tried_pubkey_config = false;
  777. s->kbd_inter_refused = false;
  778. s->done_agent = false;
  779. while (1) {
  780. /*
  781. * Wait for the result of the last authentication request,
  782. * unless the request terminated for some reason on our
  783. * own side.
  784. */
  785. if (s->suppress_wait_for_response_packet) {
  786. pktin = NULL;
  787. s->suppress_wait_for_response_packet = false;
  788. } else {
  789. crMaybeWaitUntilV((pktin = ssh2_userauth_pop(s)) != NULL);
  790. }
  791. /*
  792. * Now is a convenient point to spew any banner material
  793. * that we've accumulated. (This should ensure that when
  794. * we exit the auth loop, we haven't any left to deal
  795. * with.)
  796. *
  797. * Don't show the banner if we're operating in non-verbose
  798. * non-interactive mode. (It's probably a script, which
  799. * means nobody will read the banner _anyway_, and
  800. * moreover the printing of the banner will screw up
  801. * processing on the output of (say) plink.)
  802. *
  803. * The banner data has been sanitised already by this
  804. * point, but we still need to precede and follow it with
  805. * anti-spoofing header lines.
  806. */
  807. ssh2_userauth_print_banner(s);
  808. { // WINSCP
  809. } // WINSCP
  810. if (pktin && pktin->type == SSH2_MSG_USERAUTH_SUCCESS) {
  811. ppl_logevent("Access granted");
  812. goto userauth_success;
  813. }
  814. if (pktin && pktin->type != SSH2_MSG_USERAUTH_FAILURE &&
  815. s->type != AUTH_TYPE_GSSAPI) {
  816. ssh_proto_error(s->ppl.ssh, "Received unexpected packet "
  817. "in response to authentication request, "
  818. "type %d (%s)", pktin->type,
  819. ssh2_pkt_type(s->ppl.bpp->pls->kctx,
  820. s->ppl.bpp->pls->actx,
  821. pktin->type));
  822. return;
  823. }
  824. /*
  825. * OK, we're now sitting on a USERAUTH_FAILURE message, so
  826. * we can look at the string in it and know what we can
  827. * helpfully try next.
  828. */
  829. if (pktin && pktin->type == SSH2_MSG_USERAUTH_FAILURE) {
  830. ptrlen methods = get_string(pktin);
  831. bool partial_success = get_bool(pktin);
  832. if (!partial_success) {
  833. /*
  834. * We have received an unequivocal Access
  835. * Denied. This can translate to a variety of
  836. * messages, or no message at all.
  837. *
  838. * For forms of authentication which are attempted
  839. * implicitly, by which I mean without printing
  840. * anything in the window indicating that we're
  841. * trying them, we should never print 'Access
  842. * denied'.
  843. *
  844. * If we do print a message saying that we're
  845. * attempting some kind of authentication, it's OK
  846. * to print a followup message saying it failed -
  847. * but the message may sometimes be more specific
  848. * than simply 'Access denied'.
  849. *
  850. * Additionally, if we'd just tried password
  851. * authentication, we should break out of this
  852. * whole loop so as to go back to the username
  853. * prompt (iff we're configured to allow
  854. * username change attempts).
  855. */
  856. if (s->type == AUTH_TYPE_NONE) {
  857. /* do nothing */
  858. } else if (s->type == AUTH_TYPE_PUBLICKEY_OFFER_LOUD ||
  859. s->type == AUTH_TYPE_PUBLICKEY_OFFER_QUIET) {
  860. if (s->type == AUTH_TYPE_PUBLICKEY_OFFER_LOUD)
  861. ppl_printf("Server refused our key\r\n");
  862. ppl_logevent("Server refused our key");
  863. } else if (s->type == AUTH_TYPE_PUBLICKEY) {
  864. /* This _shouldn't_ happen except by a
  865. * protocol bug causing client and server to
  866. * disagree on what is a correct signature. */
  867. ppl_printf("Server refused public-key signature"
  868. " despite accepting key!\r\n");
  869. ppl_logevent("Server refused public-key signature"
  870. " despite accepting key!");
  871. } else if (s->type==AUTH_TYPE_KEYBOARD_INTERACTIVE_QUIET) {
  872. /* quiet, so no ppl_printf */
  873. ppl_logevent("Server refused keyboard-interactive "
  874. "authentication");
  875. } else if (s->type==AUTH_TYPE_GSSAPI) {
  876. /* always quiet, so no ppl_printf */
  877. /* also, the code down in the GSSAPI block has
  878. * already logged this in the Event Log */
  879. } else if (s->type == AUTH_TYPE_KEYBOARD_INTERACTIVE) {
  880. ppl_logevent("Keyboard-interactive authentication "
  881. "failed");
  882. ppl_printf("Access denied\r\n");
  883. } else {
  884. assert(s->type == AUTH_TYPE_PASSWORD);
  885. ppl_logevent("Password authentication failed");
  886. ppl_printf("Access denied\r\n");
  887. if (s->change_username) {
  888. /* XXX perhaps we should allow
  889. * keyboard-interactive to do this too? */
  890. goto try_new_username;
  891. }
  892. }
  893. } else {
  894. ppl_printf("Further authentication required\r\n");
  895. ppl_logevent("Further authentication required");
  896. }
  897. /*
  898. * Save the methods string for use in error messages.
  899. */
  900. strbuf_clear(s->last_methods_string);
  901. put_datapl(s->last_methods_string, methods);
  902. #ifdef WINSCP
  903. ppl_logevent("Server offered these authentication methods: %s", s->last_methods_string->s);
  904. #endif
  905. /*
  906. * Scan it for method identifiers we know about.
  907. */
  908. { // WINSCP
  909. bool srv_pubkey = false, srv_passwd = false;
  910. bool srv_keyb_inter = false;
  911. #ifndef NO_GSSAPI
  912. bool srv_gssapi = false, srv_gssapi_keyex_auth = false;
  913. #endif
  914. ptrlen method; // WINSCP
  915. for (; get_commasep_word(&methods, &method) ;) {
  916. if (ptrlen_eq_string(method, "publickey"))
  917. srv_pubkey = true;
  918. else if (ptrlen_eq_string(method, "password"))
  919. srv_passwd = true;
  920. else if (ptrlen_eq_string(method, "keyboard-interactive"))
  921. srv_keyb_inter = true;
  922. #ifndef NO_GSSAPI
  923. else if (ptrlen_eq_string(method, "gssapi-with-mic"))
  924. srv_gssapi = true;
  925. else if (ptrlen_eq_string(method, "gssapi-keyex"))
  926. srv_gssapi_keyex_auth = true;
  927. #endif
  928. }
  929. /*
  930. * And combine those flags with our own configuration
  931. * and context to set the main can_foo variables.
  932. */
  933. s->can_pubkey = srv_pubkey;
  934. s->can_passwd = srv_passwd;
  935. s->can_keyb_inter = s->try_ki_auth && srv_keyb_inter;
  936. #ifndef NO_GSSAPI
  937. s->can_gssapi = s->try_gssapi_auth && srv_gssapi &&
  938. s->shgss->libs->nlibraries > 0;
  939. s->can_gssapi_keyex_auth = s->try_gssapi_kex_auth &&
  940. srv_gssapi_keyex_auth &&
  941. s->shgss->libs->nlibraries > 0 && s->shgss->ctx;
  942. #endif
  943. } // WINSCP
  944. }
  945. s->ppl.bpp->pls->actx = SSH2_PKTCTX_NOAUTH;
  946. #ifndef NO_GSSAPI
  947. if (s->can_gssapi_keyex_auth && !s->tried_gssapi_keyex_auth) {
  948. /* gssapi-keyex authentication */
  949. s->type = AUTH_TYPE_GSSAPI;
  950. s->tried_gssapi_keyex_auth = true;
  951. s->ppl.bpp->pls->actx = SSH2_PKTCTX_GSSAPI;
  952. if (s->shgss->lib->gsslogmsg)
  953. ppl_logevent("%s", s->shgss->lib->gsslogmsg);
  954. ppl_logevent("Trying gssapi-keyex...");
  955. s->pktout = ssh2_userauth_gss_packet(s, "gssapi-keyex");
  956. pq_push(s->ppl.out_pq, s->pktout);
  957. s->shgss->lib->release_cred(s->shgss->lib, &s->shgss->ctx);
  958. s->shgss->ctx = NULL;
  959. continue;
  960. } else
  961. #endif /* NO_GSSAPI */
  962. if (s->can_pubkey && !s->done_agent &&
  963. s->agent_key_index < s->agent_key_limit) {
  964. /*
  965. * Attempt public-key authentication using a key from Pageant.
  966. */
  967. s->agent_keyalg = s->agent_keys[s->agent_key_index].algorithm;
  968. { // WINSCP
  969. char *alg_tmp = mkstr(s->agent_keyalg);
  970. const char *newalg = alg_tmp;
  971. if (ssh2_userauth_signflags(s, &s->signflags, &newalg))
  972. s->agent_keyalg = ptrlen_from_asciz(newalg);
  973. sfree(alg_tmp);
  974. s->ppl.bpp->pls->actx = SSH2_PKTCTX_PUBLICKEY;
  975. ppl_logevent("Trying Pageant key #%"SIZEu, s->agent_key_index);
  976. /* See if server will accept it */
  977. s->pktout = ssh_bpp_new_pktout(
  978. s->ppl.bpp, SSH2_MSG_USERAUTH_REQUEST);
  979. put_stringz(s->pktout, s->username);
  980. put_stringz(s->pktout, s->successor_layer->vt->name);
  981. put_stringz(s->pktout, "publickey");
  982. /* method */
  983. put_bool(s->pktout, false); /* no signature included */
  984. ssh2_userauth_add_alg_and_publickey(
  985. s, s->pktout, s->agent_keyalg, ptrlen_from_strbuf(
  986. s->agent_keys[s->agent_key_index].blob));
  987. pq_push(s->ppl.out_pq, s->pktout);
  988. s->type = AUTH_TYPE_PUBLICKEY_OFFER_QUIET;
  989. crMaybeWaitUntilV((pktin = ssh2_userauth_pop(s)) != NULL);
  990. if (pktin->type != SSH2_MSG_USERAUTH_PK_OK) {
  991. /* Offer of key refused, presumably via
  992. * USERAUTH_FAILURE. Requeue for the next iteration. */
  993. pq_push_front(s->ppl.in_pq, pktin);
  994. } else {
  995. strbuf *agentreq, *sigdata;
  996. ptrlen comment = ptrlen_from_strbuf(
  997. s->agent_keys[s->agent_key_index].comment);
  998. if (seat_verbose(s->ppl.seat))
  999. ppl_printf("Authenticating with public key "
  1000. "\"%.*s\" from agent\r\n",
  1001. PTRLEN_PRINTF(comment));
  1002. /*
  1003. * Server is willing to accept the key.
  1004. * Construct a SIGN_REQUEST.
  1005. */
  1006. s->pktout = ssh_bpp_new_pktout(
  1007. s->ppl.bpp, SSH2_MSG_USERAUTH_REQUEST);
  1008. put_stringz(s->pktout, s->username);
  1009. put_stringz(s->pktout, s->successor_layer->vt->name);
  1010. put_stringz(s->pktout, "publickey");
  1011. /* method */
  1012. put_bool(s->pktout, true); /* signature included */
  1013. ssh2_userauth_add_alg_and_publickey(
  1014. s, s->pktout, s->agent_keyalg, ptrlen_from_strbuf(
  1015. s->agent_keys[s->agent_key_index].blob));
  1016. /* Ask agent for signature. */
  1017. agentreq = strbuf_new_for_agent_query();
  1018. put_byte(agentreq, SSH2_AGENTC_SIGN_REQUEST);
  1019. put_stringpl(agentreq, ptrlen_from_strbuf(
  1020. s->agent_keys[s->agent_key_index].blob));
  1021. /* Now the data to be signed... */
  1022. sigdata = strbuf_new();
  1023. ssh2_userauth_add_session_id(s, sigdata);
  1024. put_data(sigdata, s->pktout->data + 5,
  1025. s->pktout->length - 5);
  1026. put_stringsb(agentreq, sigdata);
  1027. /* And finally the flags word. */
  1028. put_uint32(agentreq, s->signflags);
  1029. ssh2_userauth_agent_query(s, agentreq);
  1030. strbuf_free(agentreq);
  1031. crWaitUntilV(!s->auth_agent_query);
  1032. if (s->agent_response.ptr) {
  1033. ptrlen sigblob;
  1034. BinarySource src[1];
  1035. BinarySource_BARE_INIT(src, s->agent_response.ptr,
  1036. s->agent_response.len);
  1037. get_uint32(src); /* skip length field */
  1038. if (get_byte(src) == SSH2_AGENT_SIGN_RESPONSE &&
  1039. (sigblob = get_string(src), !get_err(src))) {
  1040. ppl_logevent("Sending Pageant's response");
  1041. ssh2_userauth_add_sigblob(
  1042. s, s->pktout,
  1043. ptrlen_from_strbuf(
  1044. s->agent_keys[s->agent_key_index].blob),
  1045. sigblob);
  1046. pq_push(s->ppl.out_pq, s->pktout);
  1047. s->type = AUTH_TYPE_PUBLICKEY;
  1048. s->is_trivial_auth = false;
  1049. } else {
  1050. ppl_logevent("Pageant refused signing request");
  1051. ppl_printf("Pageant failed to "
  1052. "provide a signature\r\n");
  1053. s->suppress_wait_for_response_packet = true;
  1054. ssh_free_pktout(s->pktout);
  1055. }
  1056. } else {
  1057. ppl_logevent("Pageant failed to respond to "
  1058. "signing request");
  1059. ppl_printf("Pageant failed to "
  1060. "respond to signing request\r\n");
  1061. s->suppress_wait_for_response_packet = true;
  1062. ssh_free_pktout(s->pktout);
  1063. }
  1064. }
  1065. /* Do we have any keys left to try? */
  1066. if (++s->agent_key_index >= s->agent_key_limit)
  1067. s->done_agent = true;
  1068. } // WINSCP
  1069. } else if (s->can_pubkey && s->publickey_blob &&
  1070. s->privatekey_available && !s->tried_pubkey_config) {
  1071. ssh2_userkey *key; /* not live over crReturn */
  1072. char *passphrase; /* not live over crReturn */
  1073. s->ppl.bpp->pls->actx = SSH2_PKTCTX_PUBLICKEY;
  1074. s->tried_pubkey_config = true;
  1075. /*
  1076. * Try the public key supplied in the configuration.
  1077. *
  1078. * First, try to upgrade its algorithm.
  1079. */
  1080. { // WINSCP
  1081. const char *newalg = s->publickey_algorithm;
  1082. if (ssh2_userauth_signflags(s, &s->signflags, &newalg)) {
  1083. sfree(s->publickey_algorithm);
  1084. s->publickey_algorithm = dupstr(newalg);
  1085. }
  1086. /*
  1087. * Offer the public blob to see if the server is willing to
  1088. * accept it.
  1089. */
  1090. s->pktout = ssh_bpp_new_pktout(
  1091. s->ppl.bpp, SSH2_MSG_USERAUTH_REQUEST);
  1092. put_stringz(s->pktout, s->username);
  1093. put_stringz(s->pktout, s->successor_layer->vt->name);
  1094. put_stringz(s->pktout, "publickey"); /* method */
  1095. put_bool(s->pktout, false);
  1096. /* no signature included */
  1097. ssh2_userauth_add_alg_and_publickey(
  1098. s, s->pktout, ptrlen_from_asciz(s->publickey_algorithm),
  1099. ptrlen_from_strbuf(s->publickey_blob));
  1100. pq_push(s->ppl.out_pq, s->pktout);
  1101. ppl_logevent("Offered public key");
  1102. crMaybeWaitUntilV((pktin = ssh2_userauth_pop(s)) != NULL);
  1103. if (pktin->type != SSH2_MSG_USERAUTH_PK_OK) {
  1104. /* Key refused. Give up. */
  1105. pq_push_front(s->ppl.in_pq, pktin);
  1106. s->type = AUTH_TYPE_PUBLICKEY_OFFER_LOUD;
  1107. continue; /* process this new message */
  1108. }
  1109. ppl_logevent("Offer of public key accepted");
  1110. /*
  1111. * Actually attempt a serious authentication using
  1112. * the key.
  1113. */
  1114. if (seat_verbose(s->ppl.seat))
  1115. ppl_printf("Authenticating with public key \"%s\"\r\n",
  1116. s->publickey_comment);
  1117. key = NULL;
  1118. while (!key) {
  1119. const char *error; /* not live over crReturn */
  1120. if (s->privatekey_encrypted) {
  1121. /*
  1122. * Get a passphrase from the user.
  1123. */
  1124. s->cur_prompt = ssh_ppl_new_prompts(&s->ppl);
  1125. s->cur_prompt->to_server = false;
  1126. s->cur_prompt->from_server = false;
  1127. s->cur_prompt->name = dupstr("SSH key passphrase");
  1128. add_prompt(s->cur_prompt,
  1129. dupprintf("Passphrase for key \"%s\": ",
  1130. s->publickey_comment),
  1131. false);
  1132. s->spr = seat_get_userpass_input(
  1133. ppl_get_iseat(&s->ppl), s->cur_prompt);
  1134. while (s->spr.kind == SPRK_INCOMPLETE) {
  1135. crReturnV;
  1136. s->spr = seat_get_userpass_input(
  1137. ppl_get_iseat(&s->ppl), s->cur_prompt);
  1138. }
  1139. if (spr_is_abort(s->spr)) {
  1140. /* Failed to get a passphrase. Terminate. */
  1141. free_prompts(s->cur_prompt);
  1142. s->cur_prompt = NULL;
  1143. ssh_bpp_queue_disconnect(
  1144. s->ppl.bpp, "Unable to authenticate",
  1145. SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER);
  1146. ssh_spr_close(s->ppl.ssh, s->spr,
  1147. "passphrase prompt");
  1148. return;
  1149. }
  1150. passphrase =
  1151. prompt_get_result(s->cur_prompt->prompts[0]);
  1152. free_prompts(s->cur_prompt);
  1153. s->cur_prompt = NULL;
  1154. } else {
  1155. passphrase = NULL; /* no passphrase needed */
  1156. }
  1157. /*
  1158. * Try decrypting the key.
  1159. */
  1160. key = ppk_load_f(s->keyfile, passphrase, &error);
  1161. if (passphrase) {
  1162. /* burn the evidence */
  1163. smemclr(passphrase, strlen(passphrase));
  1164. sfree(passphrase);
  1165. }
  1166. if (key == SSH2_WRONG_PASSPHRASE || key == NULL) {
  1167. if (passphrase &&
  1168. (key == SSH2_WRONG_PASSPHRASE)) {
  1169. ppl_printf("Wrong passphrase\r\n");
  1170. key = NULL;
  1171. /* and loop again */
  1172. } else {
  1173. ppl_printf("Unable to load private key (%s)\r\n",
  1174. error);
  1175. key = NULL;
  1176. s->suppress_wait_for_response_packet = true;
  1177. break; /* try something else */
  1178. }
  1179. } else {
  1180. /* FIXME: if we ever support variable signature
  1181. * flags, this is somewhere they'll need to be
  1182. * put */
  1183. char *invalid = ssh_key_invalid(key->key, 0);
  1184. if (invalid) {
  1185. ppl_printf("Cannot use this private key (%s)\r\n",
  1186. invalid);
  1187. ssh_key_free(key->key);
  1188. sfree(key->comment);
  1189. sfree(key);
  1190. sfree(invalid);
  1191. key = NULL;
  1192. s->suppress_wait_for_response_packet = true;
  1193. break; /* try something else */
  1194. }
  1195. }
  1196. }
  1197. if (key) {
  1198. strbuf *pkblob, *sigdata, *sigblob;
  1199. /*
  1200. * We have loaded the private key and the server
  1201. * has announced that it's willing to accept it.
  1202. * Hallelujah. Generate a signature and send it.
  1203. */
  1204. s->pktout = ssh_bpp_new_pktout(
  1205. s->ppl.bpp, SSH2_MSG_USERAUTH_REQUEST);
  1206. put_stringz(s->pktout, s->username);
  1207. put_stringz(s->pktout, s->successor_layer->vt->name);
  1208. put_stringz(s->pktout, "publickey"); /* method */
  1209. put_bool(s->pktout, true); /* signature follows */
  1210. pkblob = strbuf_new();
  1211. ssh_key_public_blob(key->key, BinarySink_UPCAST(pkblob));
  1212. ssh2_userauth_add_alg_and_publickey(
  1213. s, s->pktout,
  1214. ptrlen_from_asciz(s->publickey_algorithm),
  1215. ptrlen_from_strbuf(pkblob));
  1216. /*
  1217. * The data to be signed is:
  1218. *
  1219. * string session-id
  1220. *
  1221. * followed by everything so far placed in the
  1222. * outgoing packet.
  1223. */
  1224. sigdata = strbuf_new();
  1225. ssh2_userauth_add_session_id(s, sigdata);
  1226. put_data(sigdata, s->pktout->data + 5,
  1227. s->pktout->length - 5);
  1228. sigblob = strbuf_new();
  1229. ssh_key_sign(key->key, ptrlen_from_strbuf(sigdata),
  1230. s->signflags, BinarySink_UPCAST(sigblob));
  1231. strbuf_free(sigdata);
  1232. ssh2_userauth_add_sigblob(
  1233. s, s->pktout, ptrlen_from_strbuf(pkblob),
  1234. ptrlen_from_strbuf(sigblob));
  1235. strbuf_free(pkblob);
  1236. strbuf_free(sigblob);
  1237. pq_push(s->ppl.out_pq, s->pktout);
  1238. ppl_logevent("Sent public key signature");
  1239. s->type = AUTH_TYPE_PUBLICKEY;
  1240. ssh_key_free(key->key);
  1241. sfree(key->comment);
  1242. sfree(key);
  1243. s->is_trivial_auth = false;
  1244. }
  1245. } // WINSCP
  1246. #ifndef NO_GSSAPI
  1247. } else if (s->can_gssapi && !s->tried_gssapi) {
  1248. /* gssapi-with-mic authentication */
  1249. ptrlen data;
  1250. s->type = AUTH_TYPE_GSSAPI;
  1251. s->tried_gssapi = true;
  1252. s->ppl.bpp->pls->actx = SSH2_PKTCTX_GSSAPI;
  1253. if (s->shgss->lib->gsslogmsg)
  1254. ppl_logevent("%s", s->shgss->lib->gsslogmsg);
  1255. /* Sending USERAUTH_REQUEST with "gssapi-with-mic" method */
  1256. ppl_logevent("Trying gssapi-with-mic...");
  1257. s->pktout = ssh_bpp_new_pktout(
  1258. s->ppl.bpp, SSH2_MSG_USERAUTH_REQUEST);
  1259. put_stringz(s->pktout, s->username);
  1260. put_stringz(s->pktout, s->successor_layer->vt->name);
  1261. put_stringz(s->pktout, "gssapi-with-mic");
  1262. ppl_logevent("Attempting GSSAPI authentication");
  1263. /* add mechanism info */
  1264. s->shgss->lib->indicate_mech(s->shgss->lib, &s->gss_buf);
  1265. /* number of GSSAPI mechanisms */
  1266. put_uint32(s->pktout, 1);
  1267. /* length of OID + 2 */
  1268. put_uint32(s->pktout, s->gss_buf.length + 2);
  1269. put_byte(s->pktout, SSH2_GSS_OIDTYPE);
  1270. /* length of OID */
  1271. put_byte(s->pktout, s->gss_buf.length);
  1272. put_data(s->pktout, s->gss_buf.value, s->gss_buf.length);
  1273. pq_push(s->ppl.out_pq, s->pktout);
  1274. crMaybeWaitUntilV((pktin = ssh2_userauth_pop(s)) != NULL);
  1275. if (pktin->type != SSH2_MSG_USERAUTH_GSSAPI_RESPONSE) {
  1276. ppl_logevent("GSSAPI authentication request refused");
  1277. pq_push_front(s->ppl.in_pq, pktin);
  1278. continue;
  1279. }
  1280. /* check returned packet ... */
  1281. data = get_string(pktin);
  1282. s->gss_rcvtok.value = (char *)data.ptr;
  1283. s->gss_rcvtok.length = data.len;
  1284. if (s->gss_rcvtok.length != s->gss_buf.length + 2 ||
  1285. ((char *)s->gss_rcvtok.value)[0] != SSH2_GSS_OIDTYPE ||
  1286. ((char *)s->gss_rcvtok.value)[1] != s->gss_buf.length ||
  1287. memcmp((char *)s->gss_rcvtok.value + 2,
  1288. s->gss_buf.value,s->gss_buf.length) ) {
  1289. ppl_logevent("GSSAPI authentication - wrong response "
  1290. "from server");
  1291. continue;
  1292. }
  1293. /* Import server name if not cached from KEX */
  1294. if (s->shgss->srv_name == GSS_C_NO_NAME) {
  1295. // WINSCP
  1296. char * fullhostname = s->fullhostname;
  1297. if (s->loghost[0] != '\0')
  1298. {
  1299. fullhostname = s->loghost;
  1300. }
  1301. // /WINSCP
  1302. s->gss_stat = s->shgss->lib->import_name(
  1303. s->shgss->lib, fullhostname, &s->shgss->srv_name); // WINSCP
  1304. if (s->gss_stat != SSH_GSS_OK) {
  1305. if (s->gss_stat == SSH_GSS_BAD_HOST_NAME)
  1306. ppl_logevent("GSSAPI import name failed -"
  1307. " Bad service name");
  1308. else
  1309. ppl_logevent("GSSAPI import name failed");
  1310. continue;
  1311. }
  1312. }
  1313. /* Allocate our gss_ctx */
  1314. s->gss_stat = s->shgss->lib->acquire_cred(
  1315. s->shgss->lib, &s->shgss->ctx, NULL);
  1316. if (s->gss_stat != SSH_GSS_OK) {
  1317. ppl_logevent("GSSAPI authentication failed to get "
  1318. "credentials");
  1319. /* The failure was on our side, so the server
  1320. * won't be sending a response packet indicating
  1321. * failure. Avoid waiting for it next time round
  1322. * the loop. */
  1323. s->suppress_wait_for_response_packet = true;
  1324. continue;
  1325. }
  1326. /* initial tokens are empty */
  1327. SSH_GSS_CLEAR_BUF(&s->gss_rcvtok);
  1328. SSH_GSS_CLEAR_BUF(&s->gss_sndtok);
  1329. /* now enter the loop */
  1330. do {
  1331. /*
  1332. * When acquire_cred yields no useful expiration, go with
  1333. * the service ticket expiration.
  1334. */
  1335. s->gss_stat = s->shgss->lib->init_sec_context(
  1336. s->shgss->lib,
  1337. &s->shgss->ctx,
  1338. s->shgss->srv_name,
  1339. s->gssapi_fwd,
  1340. &s->gss_rcvtok,
  1341. &s->gss_sndtok,
  1342. NULL,
  1343. NULL);
  1344. if (s->gss_stat!=SSH_GSS_S_COMPLETE &&
  1345. s->gss_stat!=SSH_GSS_S_CONTINUE_NEEDED) {
  1346. ppl_logevent("GSSAPI authentication initialisation "
  1347. "failed");
  1348. if (s->shgss->lib->display_status(
  1349. s->shgss->lib, s->shgss->ctx, &s->gss_buf)
  1350. == SSH_GSS_OK) {
  1351. ppl_logevent("%s", (char *)s->gss_buf.value);
  1352. sfree(s->gss_buf.value);
  1353. }
  1354. pq_push_front(s->ppl.in_pq, pktin);
  1355. break;
  1356. }
  1357. ppl_logevent("GSSAPI authentication initialised");
  1358. /*
  1359. * Client and server now exchange tokens until GSSAPI
  1360. * no longer says CONTINUE_NEEDED
  1361. */
  1362. if (s->gss_sndtok.length != 0) {
  1363. s->is_trivial_auth = false;
  1364. s->pktout =
  1365. ssh_bpp_new_pktout(
  1366. s->ppl.bpp, SSH2_MSG_USERAUTH_GSSAPI_TOKEN);
  1367. put_string(s->pktout,
  1368. s->gss_sndtok.value, s->gss_sndtok.length);
  1369. pq_push(s->ppl.out_pq, s->pktout);
  1370. s->shgss->lib->free_tok(s->shgss->lib, &s->gss_sndtok);
  1371. }
  1372. if (s->gss_stat == SSH_GSS_S_CONTINUE_NEEDED) {
  1373. crMaybeWaitUntilV((pktin = ssh2_userauth_pop(s)) != NULL);
  1374. if (pktin->type == SSH2_MSG_USERAUTH_GSSAPI_ERRTOK) {
  1375. /*
  1376. * Per RFC 4462 section 3.9, this packet
  1377. * type MUST immediately precede an
  1378. * ordinary USERAUTH_FAILURE.
  1379. *
  1380. * We currently don't know how to do
  1381. * anything with the GSSAPI error token
  1382. * contained in this packet, so we ignore
  1383. * it and just wait for the following
  1384. * FAILURE.
  1385. */
  1386. crMaybeWaitUntilV(
  1387. (pktin = ssh2_userauth_pop(s)) != NULL);
  1388. if (pktin->type != SSH2_MSG_USERAUTH_FAILURE) {
  1389. ssh_proto_error(
  1390. s->ppl.ssh, "Received unexpected packet "
  1391. "after SSH_MSG_USERAUTH_GSSAPI_ERRTOK "
  1392. "(expected SSH_MSG_USERAUTH_FAILURE): "
  1393. "type %d (%s)", pktin->type,
  1394. ssh2_pkt_type(s->ppl.bpp->pls->kctx,
  1395. s->ppl.bpp->pls->actx,
  1396. pktin->type));
  1397. return;
  1398. }
  1399. }
  1400. if (pktin->type == SSH2_MSG_USERAUTH_FAILURE) {
  1401. ppl_logevent("GSSAPI authentication failed");
  1402. s->gss_stat = SSH_GSS_FAILURE;
  1403. pq_push_front(s->ppl.in_pq, pktin);
  1404. break;
  1405. } else if (pktin->type !=
  1406. SSH2_MSG_USERAUTH_GSSAPI_TOKEN) {
  1407. ppl_logevent("GSSAPI authentication -"
  1408. " bad server response");
  1409. s->gss_stat = SSH_GSS_FAILURE;
  1410. break;
  1411. }
  1412. data = get_string(pktin);
  1413. s->gss_rcvtok.value = (char *)data.ptr;
  1414. s->gss_rcvtok.length = data.len;
  1415. }
  1416. } while (s-> gss_stat == SSH_GSS_S_CONTINUE_NEEDED);
  1417. if (s->gss_stat != SSH_GSS_OK) {
  1418. s->shgss->lib->release_cred(s->shgss->lib, &s->shgss->ctx);
  1419. continue;
  1420. }
  1421. ppl_logevent("GSSAPI authentication loop finished OK");
  1422. /* Now send the MIC */
  1423. s->pktout = ssh2_userauth_gss_packet(s, "gssapi-with-mic");
  1424. pq_push(s->ppl.out_pq, s->pktout);
  1425. s->shgss->lib->release_cred(s->shgss->lib, &s->shgss->ctx);
  1426. continue;
  1427. #endif
  1428. } else if (s->can_keyb_inter && !s->kbd_inter_refused) {
  1429. /*
  1430. * Keyboard-interactive authentication.
  1431. */
  1432. s->type = AUTH_TYPE_KEYBOARD_INTERACTIVE;
  1433. s->ppl.bpp->pls->actx = SSH2_PKTCTX_KBDINTER;
  1434. s->pktout = ssh_bpp_new_pktout(
  1435. s->ppl.bpp, SSH2_MSG_USERAUTH_REQUEST);
  1436. put_stringz(s->pktout, s->username);
  1437. put_stringz(s->pktout, s->successor_layer->vt->name);
  1438. put_stringz(s->pktout, "keyboard-interactive");
  1439. /* method */
  1440. put_stringz(s->pktout, ""); /* lang */
  1441. put_stringz(s->pktout, ""); /* submethods */
  1442. pq_push(s->ppl.out_pq, s->pktout);
  1443. ppl_logevent("Attempting keyboard-interactive authentication");
  1444. if (s->authplugin) {
  1445. strbuf *amsg = authplugin_newmsg(PLUGIN_PROTOCOL);
  1446. put_stringz(amsg, "keyboard-interactive");
  1447. authplugin_send_free(s, amsg);
  1448. { // WINSCP
  1449. BinarySource src[1];
  1450. unsigned type;
  1451. crMaybeWaitUntilV(authplugin_expect_msg(s, &type, src));
  1452. switch (type) {
  1453. case PLUGIN_PROTOCOL_REJECT: {
  1454. ptrlen message = PTRLEN_LITERAL("");
  1455. if (s->authplugin_version >= 2) {
  1456. /* draft protocol didn't include a message here */
  1457. message = get_string(src);
  1458. }
  1459. if (get_err(src)) {
  1460. ssh_sw_abort(s->ppl.ssh, "Received malformed "
  1461. "PLUGIN_PROTOCOL_REJECT from auth "
  1462. "helper plugin");
  1463. return;
  1464. }
  1465. if (message.len) {
  1466. /* If the plugin sent a message about
  1467. * _why_ it didn't want to do k-i, pass
  1468. * that message on to the user. (It might
  1469. * say, for example, what went wrong when
  1470. * it tried to open its config file.) */
  1471. ppl_printf("Authentication plugin failed to set "
  1472. "up keyboard-interactive "
  1473. "authentication:\r\n");
  1474. seat_set_trust_status(s->ppl.seat, false);
  1475. ppl_printf("%.*s\r\n", PTRLEN_PRINTF(message));
  1476. seat_set_trust_status(s->ppl.seat, true);
  1477. ppl_logevent("Authentication plugin declined to "
  1478. "help with keyboard-interactive: "
  1479. "%.*s", PTRLEN_PRINTF(message));
  1480. } else {
  1481. ppl_logevent("Authentication plugin declined to "
  1482. "help with keyboard-interactive");
  1483. }
  1484. s->authplugin_ki_active = false;
  1485. break;
  1486. }
  1487. case PLUGIN_PROTOCOL_ACCEPT:
  1488. s->authplugin_ki_active = true;
  1489. ppl_logevent("Authentication plugin agreed to help "
  1490. "with keyboard-interactive");
  1491. break;
  1492. default:
  1493. authplugin_bad_packet(
  1494. s, type, "expected PLUGIN_PROTOCOL_ACCEPT or "
  1495. "PLUGIN_PROTOCOL_REJECT");
  1496. return;
  1497. }
  1498. } // WINSCP
  1499. } else {
  1500. s->authplugin_ki_active = false;
  1501. }
  1502. if (!s->ki_scc_initialised) {
  1503. s->ki_scc = seat_stripctrl_new(
  1504. s->ppl.seat, NULL, SIC_KI_PROMPTS);
  1505. if (s->ki_scc)
  1506. stripctrl_enable_line_limiting(s->ki_scc);
  1507. s->ki_scc_initialised = true;
  1508. }
  1509. crMaybeWaitUntilV((pktin = ssh2_userauth_pop(s)) != NULL);
  1510. if (pktin->type != SSH2_MSG_USERAUTH_INFO_REQUEST) {
  1511. /* Server is not willing to do keyboard-interactive
  1512. * at all (or, bizarrely but legally, accepts the
  1513. * user without actually issuing any prompts).
  1514. * Give up on it entirely. */
  1515. pq_push_front(s->ppl.in_pq, pktin);
  1516. s->type = AUTH_TYPE_KEYBOARD_INTERACTIVE_QUIET;
  1517. s->kbd_inter_refused = true; /* don't try it again */
  1518. continue;
  1519. }
  1520. s->ki_printed_header = false;
  1521. /*
  1522. * Loop while we still have prompts to send to the user.
  1523. */
  1524. if (!s->authplugin_ki_active) {
  1525. /*
  1526. * The simple case: INFO_REQUESTs are passed on to
  1527. * the user, and responses are sent straight back
  1528. * to the SSH server.
  1529. */
  1530. while (pktin->type == SSH2_MSG_USERAUTH_INFO_REQUEST) {
  1531. if (!ssh2_userauth_ki_setup_prompts(
  1532. s, BinarySource_UPCAST(pktin), false))
  1533. return;
  1534. crMaybeWaitUntilV(ssh2_userauth_ki_run_prompts(s));
  1535. if (spr_is_abort(s->spr)) {
  1536. /*
  1537. * Failed to get responses. Terminate.
  1538. */
  1539. free_prompts(s->cur_prompt);
  1540. s->cur_prompt = NULL;
  1541. ssh_bpp_queue_disconnect(
  1542. s->ppl.bpp, "Unable to authenticate",
  1543. SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER);
  1544. ssh_spr_close(s->ppl.ssh, s->spr, "keyboard-"
  1545. "interactive authentication prompt");
  1546. return;
  1547. }
  1548. /*
  1549. * Send the response(s) to the server.
  1550. */
  1551. s->pktout = ssh_bpp_new_pktout(
  1552. s->ppl.bpp, SSH2_MSG_USERAUTH_INFO_RESPONSE);
  1553. ssh2_userauth_ki_write_responses(
  1554. s, BinarySink_UPCAST(s->pktout));
  1555. s->pktout->minlen = 256;
  1556. pq_push(s->ppl.out_pq, s->pktout);
  1557. /*
  1558. * Get the next packet in case it's another
  1559. * INFO_REQUEST.
  1560. */
  1561. crMaybeWaitUntilV(
  1562. (pktin = ssh2_userauth_pop(s)) != NULL);
  1563. }
  1564. } else {
  1565. /*
  1566. * The case where a plugin is involved:
  1567. * INFO_REQUEST from the server is sent to the
  1568. * plugin, which sends responses that we hand back
  1569. * to the server. But in the meantime, the plugin
  1570. * might send USER_REQUEST for us to pass to the
  1571. * user, and then we send responses to that.
  1572. */
  1573. while (pktin->type == SSH2_MSG_USERAUTH_INFO_REQUEST) {
  1574. strbuf *amsg = authplugin_newmsg(
  1575. PLUGIN_KI_SERVER_REQUEST);
  1576. put_datapl(amsg, get_data(pktin, get_avail(pktin)));
  1577. authplugin_send_free(s, amsg);
  1578. { // WINSCP
  1579. BinarySource src[1];
  1580. unsigned type;
  1581. while (true) {
  1582. crMaybeWaitUntilV(authplugin_expect_msg(
  1583. s, &type, src));
  1584. if (type != PLUGIN_KI_USER_REQUEST)
  1585. break;
  1586. if (!ssh2_userauth_ki_setup_prompts(s, src, true))
  1587. return;
  1588. crMaybeWaitUntilV(ssh2_userauth_ki_run_prompts(s));
  1589. if (spr_is_abort(s->spr)) {
  1590. /*
  1591. * Failed to get responses. Terminate.
  1592. */
  1593. free_prompts(s->cur_prompt);
  1594. s->cur_prompt = NULL;
  1595. ssh_bpp_queue_disconnect(
  1596. s->ppl.bpp, "Unable to authenticate",
  1597. SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER);
  1598. ssh_spr_close(
  1599. s->ppl.ssh, s->spr, "keyboard-"
  1600. "interactive authentication prompt");
  1601. return;
  1602. }
  1603. /*
  1604. * Send the responses on to the plugin.
  1605. */
  1606. { // WINSCP
  1607. strbuf *amsg = authplugin_newmsg(
  1608. PLUGIN_KI_USER_RESPONSE);
  1609. ssh2_userauth_ki_write_responses(
  1610. s, BinarySink_UPCAST(amsg));
  1611. authplugin_send_free(s, amsg);
  1612. } // WINSCP
  1613. }
  1614. if (type != PLUGIN_KI_SERVER_RESPONSE) {
  1615. authplugin_bad_packet(
  1616. s, type, "expected PLUGIN_KI_SERVER_RESPONSE "
  1617. "or PLUGIN_PROTOCOL_USER_REQUEST");
  1618. return;
  1619. }
  1620. s->pktout = ssh_bpp_new_pktout(
  1621. s->ppl.bpp, SSH2_MSG_USERAUTH_INFO_RESPONSE);
  1622. put_datapl(s->pktout, get_data(src, get_avail(src)));
  1623. s->pktout->minlen = 256;
  1624. pq_push(s->ppl.out_pq, s->pktout);
  1625. /*
  1626. * Get the next packet in case it's another
  1627. * INFO_REQUEST.
  1628. */
  1629. crMaybeWaitUntilV(
  1630. (pktin = ssh2_userauth_pop(s)) != NULL);
  1631. } // WINSCP
  1632. }
  1633. }
  1634. /*
  1635. * Print our trailer line, if we printed a header.
  1636. */
  1637. if (s->ki_printed_header) {
  1638. seat_set_trust_status(s->ppl.seat, true);
  1639. seat_antispoof_msg(
  1640. ppl_get_iseat(&s->ppl),
  1641. (s->authplugin_ki_active ?
  1642. "End of keyboard-interactive prompts from plugin" :
  1643. "End of keyboard-interactive prompts from server"));
  1644. }
  1645. /*
  1646. * We should have SUCCESS or FAILURE now.
  1647. */
  1648. pq_push_front(s->ppl.in_pq, pktin);
  1649. if (s->authplugin_ki_active) {
  1650. /*
  1651. * As our last communication with the plugin, tell
  1652. * it whether the k-i authentication succeeded.
  1653. */
  1654. int plugin_msg = -1;
  1655. if (pktin->type == SSH2_MSG_USERAUTH_SUCCESS) {
  1656. plugin_msg = PLUGIN_AUTH_SUCCESS;
  1657. } else if (pktin->type == SSH2_MSG_USERAUTH_FAILURE) {
  1658. /*
  1659. * Peek in the failure packet to see if it's a
  1660. * partial success.
  1661. */
  1662. BinarySource src[1];
  1663. BinarySource_BARE_INIT(
  1664. src, get_ptr(pktin), get_avail(pktin));
  1665. get_string(pktin); /* skip methods */
  1666. { // WINSCP
  1667. bool partial_success = get_bool(pktin);
  1668. if (!get_err(src)) {
  1669. plugin_msg = partial_success ?
  1670. PLUGIN_AUTH_SUCCESS : PLUGIN_AUTH_FAILURE;
  1671. }
  1672. } // WINSCP
  1673. }
  1674. if (plugin_msg >= 0) {
  1675. strbuf *amsg = authplugin_newmsg(plugin_msg);
  1676. authplugin_send_free(s, amsg);
  1677. /* Wait until we've actually sent it, in case
  1678. * we close the connection to the plugin
  1679. * before that outgoing message has left our
  1680. * own buffers */
  1681. crMaybeWaitUntilV(s->authplugin_backlog == 0);
  1682. }
  1683. }
  1684. } else if (s->can_passwd) {
  1685. s->is_trivial_auth = false;
  1686. { // WINSCP
  1687. /*
  1688. * Plain old password authentication.
  1689. */
  1690. bool changereq_first_time; /* not live over crReturn */
  1691. s->ppl.bpp->pls->actx = SSH2_PKTCTX_PASSWORD;
  1692. // WINSCP
  1693. if (s->change_password)
  1694. {
  1695. s->password = dupstr("");
  1696. s->type = AUTH_TYPE_PASSWORD;
  1697. }
  1698. else
  1699. {
  1700. // no indentation to ease merges
  1701. // /WINSCP
  1702. s->cur_prompt = ssh_ppl_new_prompts(&s->ppl);
  1703. s->cur_prompt->utf8 = true;
  1704. s->cur_prompt->to_server = true;
  1705. s->cur_prompt->from_server = false;
  1706. s->cur_prompt->name = dupstr("SSH password");
  1707. add_prompt(s->cur_prompt, dupprintf("%s@%s's password: ",
  1708. s->username, s->hostname),
  1709. false);
  1710. s->spr = seat_get_userpass_input(
  1711. ppl_get_iseat(&s->ppl), s->cur_prompt);
  1712. while (s->spr.kind == SPRK_INCOMPLETE) {
  1713. crReturnV;
  1714. s->spr = seat_get_userpass_input(
  1715. ppl_get_iseat(&s->ppl), s->cur_prompt);
  1716. }
  1717. if (spr_is_abort(s->spr)) {
  1718. /*
  1719. * Failed to get responses. Terminate.
  1720. */
  1721. free_prompts(s->cur_prompt);
  1722. s->cur_prompt = NULL;
  1723. ssh_bpp_queue_disconnect(
  1724. s->ppl.bpp, "Unable to authenticate",
  1725. SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER);
  1726. ssh_spr_close(s->ppl.ssh, s->spr, "password prompt");
  1727. return;
  1728. }
  1729. /*
  1730. * Squirrel away the password. (We may need it later if
  1731. * asked to change it.)
  1732. */
  1733. s->password = prompt_get_result(s->cur_prompt->prompts[0]);
  1734. free_prompts(s->cur_prompt);
  1735. s->cur_prompt = NULL;
  1736. /*
  1737. * Send the password packet.
  1738. *
  1739. * We pad out the password packet to 256 bytes to make
  1740. * it harder for an attacker to find the length of the
  1741. * user's password.
  1742. *
  1743. * Anyone using a password longer than 256 bytes
  1744. * probably doesn't have much to worry about from
  1745. * people who find out how long their password is!
  1746. */
  1747. s->pktout = ssh_bpp_new_pktout(
  1748. s->ppl.bpp, SSH2_MSG_USERAUTH_REQUEST);
  1749. put_stringz(s->pktout, s->username);
  1750. put_stringz(s->pktout, s->successor_layer->vt->name);
  1751. put_stringz(s->pktout, "password");
  1752. put_bool(s->pktout, false);
  1753. put_stringz(s->pktout, s->password);
  1754. s->pktout->minlen = 256;
  1755. pq_push(s->ppl.out_pq, s->pktout);
  1756. ppl_logevent("Sent password");
  1757. s->type = AUTH_TYPE_PASSWORD;
  1758. /*
  1759. * Wait for next packet, in case it's a password change
  1760. * request.
  1761. */
  1762. crMaybeWaitUntilV((pktin = ssh2_userauth_pop(s)) != NULL);
  1763. } // WINSCP
  1764. changereq_first_time = true;
  1765. while ((pktin->type == SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ) ||
  1766. s->change_password) { // WINSCP
  1767. /*
  1768. * We're being asked for a new password
  1769. * (perhaps not for the first time).
  1770. * Loop until the server accepts it.
  1771. */
  1772. bool got_new = false; /* not live over crReturn */
  1773. ptrlen prompt; /* not live over crReturn */
  1774. if (!s->change_password) // WINSCP
  1775. {
  1776. const char *msg;
  1777. if (changereq_first_time)
  1778. msg = "Server requested password change";
  1779. else
  1780. msg = "Server rejected new password";
  1781. ppl_logevent("%s", msg);
  1782. ppl_printf("%s\r\n", msg);
  1783. }
  1784. s->change_password = false; // WINSCP
  1785. prompt = get_string(pktin);
  1786. s->cur_prompt = ssh_ppl_new_prompts(&s->ppl);
  1787. s->cur_prompt->utf8 = true;
  1788. s->cur_prompt->to_server = true;
  1789. s->cur_prompt->from_server = false;
  1790. s->cur_prompt->name = dupstr("New SSH password");
  1791. s->cur_prompt->instruction = mkstr(prompt);
  1792. s->cur_prompt->instr_reqd = true;
  1793. /*
  1794. * There's no explicit requirement in the protocol
  1795. * for the "old" passwords in the original and
  1796. * password-change messages to be the same, and
  1797. * apparently some Cisco kit supports password change
  1798. * by the user entering a blank password originally
  1799. * and the real password subsequently, so,
  1800. * reluctantly, we prompt for the old password again.
  1801. *
  1802. * (On the other hand, some servers don't even bother
  1803. * to check this field.)
  1804. */
  1805. add_prompt(s->cur_prompt,
  1806. dupstr("Current password (blank for previously entered password): "),
  1807. false);
  1808. add_prompt(s->cur_prompt, dupstr("Enter new password: "),
  1809. false);
  1810. add_prompt(s->cur_prompt, dupstr("Confirm new password: "),
  1811. false);
  1812. /*
  1813. * Loop until the user manages to enter the same
  1814. * password twice.
  1815. */
  1816. while (!got_new) {
  1817. s->spr = seat_get_userpass_input(
  1818. ppl_get_iseat(&s->ppl), s->cur_prompt);
  1819. while (s->spr.kind == SPRK_INCOMPLETE) {
  1820. crReturnV;
  1821. s->spr = seat_get_userpass_input(
  1822. ppl_get_iseat(&s->ppl), s->cur_prompt);
  1823. }
  1824. if (spr_is_abort(s->spr)) {
  1825. /*
  1826. * Failed to get responses. Terminate.
  1827. */
  1828. /* burn the evidence */
  1829. free_prompts(s->cur_prompt);
  1830. s->cur_prompt = NULL;
  1831. smemclr(s->password, strlen(s->password));
  1832. sfree(s->password);
  1833. ssh_bpp_queue_disconnect(
  1834. s->ppl.bpp, "Unable to authenticate",
  1835. SSH2_DISCONNECT_AUTH_CANCELLED_BY_USER);
  1836. ssh_spr_close(s->ppl.ssh, s->spr,
  1837. "password-change prompt");
  1838. return;
  1839. }
  1840. /*
  1841. * If the user specified a new original password
  1842. * (IYSWIM), overwrite any previously specified
  1843. * one.
  1844. * (A side effect is that the user doesn't have to
  1845. * re-enter it if they louse up the new password.)
  1846. */
  1847. if (s->cur_prompt->prompts[0]->result->s[0]) {
  1848. smemclr(s->password, strlen(s->password));
  1849. /* burn the evidence */
  1850. sfree(s->password);
  1851. s->password = prompt_get_result(
  1852. s->cur_prompt->prompts[0]);
  1853. }
  1854. /*
  1855. * Check the two new passwords match.
  1856. */
  1857. got_new = !strcmp(
  1858. prompt_get_result_ref(s->cur_prompt->prompts[1]),
  1859. prompt_get_result_ref(s->cur_prompt->prompts[2]));
  1860. if (!got_new)
  1861. /* They don't. Silly user. */
  1862. ppl_printf("Passwords do not match\r\n");
  1863. }
  1864. /*
  1865. * Send the new password (along with the old one).
  1866. * (see above for padding rationale)
  1867. */
  1868. s->pktout = ssh_bpp_new_pktout(
  1869. s->ppl.bpp, SSH2_MSG_USERAUTH_REQUEST);
  1870. put_stringz(s->pktout, s->username);
  1871. put_stringz(s->pktout, s->successor_layer->vt->name);
  1872. put_stringz(s->pktout, "password");
  1873. put_bool(s->pktout, true);
  1874. put_stringz(s->pktout, s->password);
  1875. put_stringz(s->pktout, prompt_get_result_ref(
  1876. s->cur_prompt->prompts[1]));
  1877. free_prompts(s->cur_prompt);
  1878. s->cur_prompt = NULL;
  1879. s->pktout->minlen = 256;
  1880. pq_push(s->ppl.out_pq, s->pktout);
  1881. ppl_logevent("Sent new password");
  1882. /*
  1883. * Now see what the server has to say about it.
  1884. * (If it's CHANGEREQ again, it's not happy with the
  1885. * new password.)
  1886. */
  1887. crMaybeWaitUntilV((pktin = ssh2_userauth_pop(s)) != NULL);
  1888. changereq_first_time = false;
  1889. }
  1890. /*
  1891. * We need to reexamine the current pktin at the top
  1892. * of the loop. Either:
  1893. * - we weren't asked to change password at all, in
  1894. * which case it's a SUCCESS or FAILURE with the
  1895. * usual meaning
  1896. * - we sent a new password, and the server was
  1897. * either OK with it (SUCCESS or FAILURE w/partial
  1898. * success) or unhappy with the _old_ password
  1899. * (FAILURE w/o partial success)
  1900. * In any of these cases, we go back to the top of
  1901. * the loop and start again.
  1902. */
  1903. pq_push_front(s->ppl.in_pq, pktin);
  1904. /*
  1905. * We don't need the old password any more, in any
  1906. * case. Burn the evidence.
  1907. */
  1908. smemclr(s->password, strlen(s->password));
  1909. sfree(s->password);
  1910. } // WINSCP
  1911. } else {
  1912. ssh_bpp_queue_disconnect(
  1913. s->ppl.bpp,
  1914. "No supported authentication methods available",
  1915. SSH2_DISCONNECT_NO_MORE_AUTH_METHODS_AVAILABLE);
  1916. ssh_sw_abort(s->ppl.ssh, "No supported authentication methods "
  1917. "available (server sent: %s)",
  1918. s->last_methods_string->s);
  1919. return;
  1920. }
  1921. }
  1922. try_new_username:;
  1923. }
  1924. userauth_success:
  1925. if (s->notrivialauth && s->is_trivial_auth) {
  1926. ssh_proto_error(s->ppl.ssh, "Authentication was trivial! "
  1927. "Abandoning session as specified in configuration.");
  1928. return;
  1929. }
  1930. /*
  1931. * We've just received USERAUTH_SUCCESS, and we haven't sent
  1932. * any packets since. Signal the transport layer to consider
  1933. * doing an immediate rekey, if it has any reason to want to.
  1934. */
  1935. ssh2_transport_notify_auth_done(s->transport_layer);
  1936. /*
  1937. * Finally, hand over to our successor layer, and return
  1938. * immediately without reaching the crFinishV: ssh_ppl_replace
  1939. * will have freed us, so crFinishV's zeroing-out of crState would
  1940. * be a use-after-free bug.
  1941. */
  1942. {
  1943. PacketProtocolLayer *successor = s->successor_layer;
  1944. s->successor_layer = NULL; /* avoid freeing it ourself */
  1945. ssh_ppl_replace(&s->ppl, successor);
  1946. return; /* we've just freed s, so avoid even touching s->crState */
  1947. }
  1948. crFinishV;
  1949. }
  1950. static void ssh2_userauth_print_banner(struct ssh2_userauth_state *s)
  1951. {
  1952. if (bufchain_size(&s->banner) &&
  1953. (seat_verbose(s->ppl.seat) || seat_interactive(s->ppl.seat))) {
  1954. if (s->banner_scc) {
  1955. seat_antispoof_msg(
  1956. ppl_get_iseat(&s->ppl),
  1957. "Pre-authentication banner message from server:");
  1958. seat_set_trust_status(s->ppl.seat, false);
  1959. }
  1960. { // WINSCP
  1961. bool mid_line = false;
  1962. while (bufchain_size(&s->banner) > 0) {
  1963. // WINSCP: consume banner buffer before calling seat_banner_pl.
  1964. // As we might get disconnected, while the banner is displaying,
  1965. // and ssh_remote_error calls here via ssh2_userauth_final_output,
  1966. // so we might get into loop
  1967. ptrlen data = bufchain_prefix(&s->banner);
  1968. char * buf = smalloc(data.len);
  1969. bufchain_fetch(&s->banner, buf, data.len);
  1970. mid_line =
  1971. (((const char *)data.ptr)[data.len-1] != '\n');
  1972. bufchain_consume(&s->banner, data.len);
  1973. seat_banner_pl(ppl_get_iseat(&s->ppl), make_ptrlen(buf, data.len));
  1974. sfree(buf);
  1975. }
  1976. bufchain_clear(&s->banner);
  1977. if (mid_line)
  1978. seat_banner_pl(ppl_get_iseat(&s->ppl),
  1979. PTRLEN_LITERAL("\r\n"));
  1980. if (s->banner_scc) {
  1981. seat_set_trust_status(s->ppl.seat, true);
  1982. seat_antispoof_msg(ppl_get_iseat(&s->ppl),
  1983. "End of banner message from server");
  1984. }
  1985. } // WINSCP
  1986. }
  1987. }
  1988. static bool ssh2_userauth_ki_setup_prompts(
  1989. struct ssh2_userauth_state *s, BinarySource *src, bool plugin)
  1990. {
  1991. ptrlen name, inst;
  1992. strbuf *sb;
  1993. /*
  1994. * We've got a fresh USERAUTH_INFO_REQUEST. Get the preamble and
  1995. * start building a prompt.
  1996. */
  1997. name = get_string(src);
  1998. inst = get_string(src);
  1999. get_string(src); /* skip language tag */
  2000. s->cur_prompt = ssh_ppl_new_prompts(&s->ppl);
  2001. s->cur_prompt->utf8 = true;
  2002. s->cur_prompt->to_server = true;
  2003. s->cur_prompt->from_server = true;
  2004. /*
  2005. * Get any prompt(s) from the packet.
  2006. */
  2007. s->num_prompts = get_uint32(src);
  2008. { // WINSCP
  2009. uint32_t i; // WINSCP
  2010. for (i = 0; i < s->num_prompts; i++) {
  2011. s->is_trivial_auth = false;
  2012. { // WINSCP
  2013. ptrlen prompt = get_string(src);
  2014. bool echo = get_bool(src);
  2015. if (get_err(src)) {
  2016. ssh_proto_error(s->ppl.ssh, "%s sent truncated %s packet",
  2017. plugin ? "Plugin" : "Server",
  2018. plugin ? "PLUGIN_KI_USER_REQUEST" :
  2019. "SSH_MSG_USERAUTH_INFO_REQUEST");
  2020. return false;
  2021. }
  2022. sb = strbuf_new();
  2023. if (!prompt.len) {
  2024. put_fmt(sb, "<%s failed to send prompt>: ",
  2025. plugin ? "plugin" : "server");
  2026. } else if (s->ki_scc) {
  2027. stripctrl_retarget(s->ki_scc, BinarySink_UPCAST(sb));
  2028. put_datapl(s->ki_scc, prompt);
  2029. stripctrl_retarget(s->ki_scc, NULL);
  2030. } else {
  2031. put_datapl(sb, prompt);
  2032. }
  2033. add_prompt(s->cur_prompt, strbuf_to_str(sb), echo);
  2034. } // WINSCP
  2035. }
  2036. } // WINSCP
  2037. /*
  2038. * Make the header strings. This includes the 'name' (optional
  2039. * dialog-box title) and 'instruction' from the server.
  2040. *
  2041. * First, display our disambiguating header line if this is the
  2042. * first time round the loop - _unless_ the server has sent a
  2043. * completely empty k-i packet with no prompts _or_ text, which
  2044. * apparently some do. In that situation there's no need to alert
  2045. * the user that the following text is server- supplied, because,
  2046. * well, _what_ text?
  2047. *
  2048. * We also only do this if we got a stripctrl, because if we
  2049. * didn't, that suggests this is all being done via dialog boxes
  2050. * anyway.
  2051. */
  2052. if (!s->ki_printed_header && s->ki_scc &&
  2053. (s->num_prompts || name.len || inst.len)) {
  2054. seat_antispoof_msg(
  2055. ppl_get_iseat(&s->ppl),
  2056. (plugin ?
  2057. "Keyboard-interactive authentication prompts from plugin:" :
  2058. "Keyboard-interactive authentication prompts from server:"));
  2059. s->ki_printed_header = true;
  2060. seat_set_trust_status(s->ppl.seat, false);
  2061. }
  2062. sb = strbuf_new();
  2063. if (name.len) {
  2064. put_datapl(sb, PTRLEN_LITERAL("SSH server: ")); // WINSCP
  2065. if (s->ki_scc) {
  2066. stripctrl_retarget(s->ki_scc, BinarySink_UPCAST(sb));
  2067. put_datapl(s->ki_scc, name);
  2068. stripctrl_retarget(s->ki_scc, NULL);
  2069. } else {
  2070. put_datapl(sb, name);
  2071. }
  2072. s->cur_prompt->name_reqd = true;
  2073. } else {
  2074. if (plugin)
  2075. put_datapl(sb, PTRLEN_LITERAL(
  2076. "Communication with authentication plugin"));
  2077. else
  2078. put_datapl(sb, PTRLEN_LITERAL("SSH server authentication"));
  2079. s->cur_prompt->name_reqd = false;
  2080. }
  2081. s->cur_prompt->name = strbuf_to_str(sb);
  2082. sb = strbuf_new();
  2083. if (inst.len) {
  2084. if (s->ki_scc) {
  2085. stripctrl_retarget(s->ki_scc, BinarySink_UPCAST(sb));
  2086. put_datapl(s->ki_scc, inst);
  2087. stripctrl_retarget(s->ki_scc, NULL);
  2088. } else {
  2089. put_datapl(sb, inst);
  2090. }
  2091. s->cur_prompt->instr_reqd = true;
  2092. } else {
  2093. s->cur_prompt->instr_reqd = false;
  2094. }
  2095. if (sb->len)
  2096. s->cur_prompt->instruction = strbuf_to_str(sb);
  2097. else
  2098. strbuf_free(sb);
  2099. return true;
  2100. }
  2101. static bool ssh2_userauth_ki_run_prompts(struct ssh2_userauth_state *s)
  2102. {
  2103. s->spr = seat_get_userpass_input(
  2104. ppl_get_iseat(&s->ppl), s->cur_prompt);
  2105. return s->spr.kind != SPRK_INCOMPLETE;
  2106. }
  2107. static void ssh2_userauth_ki_write_responses(
  2108. struct ssh2_userauth_state *s, BinarySink *bs)
  2109. {
  2110. put_uint32(bs, s->num_prompts);
  2111. { // WINSCP
  2112. uint32_t i;
  2113. for (i = 0; i < s->num_prompts; i++)
  2114. put_stringz(bs, prompt_get_result_ref(s->cur_prompt->prompts[i]));
  2115. } // WINSCP
  2116. /*
  2117. * Free the prompts structure from this iteration. If there's
  2118. * another, a new one will be allocated when we return to the top
  2119. * of this while loop.
  2120. */
  2121. free_prompts(s->cur_prompt);
  2122. s->cur_prompt = NULL;
  2123. }
  2124. static void ssh2_userauth_add_session_id(
  2125. struct ssh2_userauth_state *s, strbuf *sigdata)
  2126. {
  2127. if (s->ppl.remote_bugs & BUG_SSH2_PK_SESSIONID) {
  2128. put_datapl(sigdata, s->session_id);
  2129. } else {
  2130. put_stringpl(sigdata, s->session_id);
  2131. }
  2132. }
  2133. static void ssh2_userauth_agent_query(
  2134. struct ssh2_userauth_state *s, strbuf *req)
  2135. {
  2136. void *response;
  2137. int response_len;
  2138. sfree(s->agent_response_to_free);
  2139. s->agent_response_to_free = NULL;
  2140. s->auth_agent_query = agent_query(req, &response, &response_len,
  2141. ssh2_userauth_agent_callback, s, get_seat_callback_set(s->seat)); // WINSCP
  2142. if (!s->auth_agent_query)
  2143. ssh2_userauth_agent_callback(s, response, response_len);
  2144. }
  2145. static void ssh2_userauth_agent_callback(void *uav, void *reply, int replylen)
  2146. {
  2147. struct ssh2_userauth_state *s = (struct ssh2_userauth_state *)uav;
  2148. s->auth_agent_query = NULL;
  2149. s->agent_response_to_free = reply;
  2150. s->agent_response = make_ptrlen(reply, replylen);
  2151. queue_idempotent_callback(&s->ppl.ic_process_queue);
  2152. }
  2153. /*
  2154. * Helper function to add the algorithm and public key strings to a
  2155. * "publickey" auth packet. Deals with overriding both strings if the
  2156. * user has provided a detached certificate which matches the public
  2157. * key in question.
  2158. */
  2159. static void ssh2_userauth_add_alg_and_publickey(
  2160. struct ssh2_userauth_state *s, PktOut *pkt, ptrlen alg, ptrlen pkblob)
  2161. {
  2162. PacketProtocolLayer *ppl = &s->ppl; /* for ppl_logevent */
  2163. if (s->detached_cert_blob) {
  2164. ptrlen detached_cert_pl = ptrlen_from_strbuf(s->detached_cert_blob);
  2165. strbuf *certbase = NULL, *pkbase = NULL;
  2166. bool done = false;
  2167. const ssh_keyalg *pkalg = find_pubkey_alg_len(alg);
  2168. ssh_key *certkey = NULL, *pk = NULL;
  2169. strbuf *fail_reason = strbuf_new();
  2170. bool verbose = true;
  2171. /*
  2172. * Whether or not we send the certificate, we're likely to
  2173. * generate a log message about it. But we don't want to log
  2174. * once for the offer and once for the real auth attempt, so
  2175. * we de-duplicate by remembering the last public key this
  2176. * function saw. */
  2177. if (!s->cert_pubkey_diagnosed)
  2178. s->cert_pubkey_diagnosed = strbuf_new();
  2179. if (ptrlen_eq_ptrlen(ptrlen_from_strbuf(s->cert_pubkey_diagnosed),
  2180. pkblob)) {
  2181. verbose = false;
  2182. } else {
  2183. /* Log this time, but arrange that we don't mention it next time */
  2184. strbuf_clear(s->cert_pubkey_diagnosed);
  2185. put_datapl(s->cert_pubkey_diagnosed, pkblob);
  2186. }
  2187. /*
  2188. * Check that the public key we're replacing is compatible
  2189. * with the certificate, in that they should have the same
  2190. * base public key.
  2191. */
  2192. { // WINSCP
  2193. const ssh_keyalg *certalg = pubkey_blob_to_alg(detached_cert_pl);
  2194. assert(certalg); /* we checked this before setting s->detached_blob */
  2195. assert(certalg->is_certificate); /* and this too */
  2196. certkey = ssh_key_new_pub(certalg, detached_cert_pl);
  2197. if (!certkey) {
  2198. put_fmt(fail_reason, "certificate key file is invalid");
  2199. goto no_match;
  2200. }
  2201. certbase = strbuf_new();
  2202. ssh_key_public_blob(ssh_key_base_key(certkey),
  2203. BinarySink_UPCAST(certbase));
  2204. if (ptrlen_eq_ptrlen(pkblob, ptrlen_from_strbuf(certbase)))
  2205. goto match; /* yes, a match! */
  2206. /*
  2207. * If we reach here, the certificate's base key was not
  2208. * identical to the key we're given. But it might still be
  2209. * identical to the _base_ key of the key we're given, if we
  2210. * were using a differently certified version of the same key.
  2211. * In that situation, the detached cert should still override.
  2212. */
  2213. if (!pkalg) {
  2214. put_fmt(fail_reason, "unable to identify algorithm of base key");
  2215. goto no_match;
  2216. }
  2217. pk = ssh_key_new_pub(pkalg, pkblob);
  2218. if (!pk) {
  2219. put_fmt(fail_reason, "base public key is invalid");
  2220. goto no_match;
  2221. }
  2222. pkbase = strbuf_new();
  2223. ssh_key_public_blob(ssh_key_base_key(pk), BinarySink_UPCAST(pkbase));
  2224. if (ptrlen_eq_ptrlen(ptrlen_from_strbuf(pkbase),
  2225. ptrlen_from_strbuf(certbase)))
  2226. goto match; /* yes, a match on 2nd attempt! */
  2227. /* Give up; we've tried to match these keys up and failed. */
  2228. put_fmt(fail_reason, "base public key does not match certificate");
  2229. goto no_match;
  2230. match:
  2231. /*
  2232. * The two keys match, so insert the detached certificate into
  2233. * the output packet in place of the public key we were given.
  2234. *
  2235. * However, we need to be a bit careful with the algorithm
  2236. * name: we might need to upgrade it to one that matches the
  2237. * original algorithm name. (If we were asked to add an
  2238. * ssh-rsa key but were given algorithm name "rsa-sha2-512",
  2239. * then instead of the certificate's algorithm name
  2240. * ssh-rsa-cert-v01@... we need to write the corresponding
  2241. * SHA-512 name rsa-sha2-512-cert-v01@... .)
  2242. */
  2243. if (verbose) {
  2244. ppl_logevent(WINSCP_BOM "Sending public key with certificate from \"%s\"",
  2245. filename_to_str(s->detached_cert_file));
  2246. }
  2247. {
  2248. /* Strip off any existing certificate-nature from pkalg,
  2249. * for the case where we're replacing a cert embedded in
  2250. * the key with the detached one. The second argument of
  2251. * ssh_keyalg_related_alg is expected to be one of the
  2252. * bare key algorithms, or nothing useful will happen. */
  2253. const ssh_keyalg *pkalg_base =
  2254. pkalg->base_alg ? pkalg->base_alg : pkalg;
  2255. /* Construct an algorithm string that includes both the
  2256. * signature subtype (e.g. rsa-sha2-512) and the
  2257. * certificate-ness. Exception: in earlier versions of
  2258. * OpenSSH we don't want to do that, and must send just
  2259. * ssh-rsa-cert-... even when we're delivering a non-SHA-1
  2260. * signature. */
  2261. const ssh_keyalg *output_alg =
  2262. ssh_keyalg_related_alg(certalg, pkalg_base);
  2263. ptrlen output_id = ptrlen_from_asciz(output_alg->ssh_id);
  2264. output_id = workaround_rsa_sha2_cert_userauth(s, output_id);
  2265. put_stringpl(pkt, output_id);
  2266. }
  2267. put_stringpl(pkt, ptrlen_from_strbuf(s->detached_cert_blob));
  2268. done = true;
  2269. goto out;
  2270. no_match:
  2271. /* Log that we didn't send the certificate, if this public key
  2272. * isn't the same one as last call to this function. (Need to
  2273. * avoid verbosely logging once for the offer and once for the
  2274. * real auth attempt.) */
  2275. if (verbose) {
  2276. ppl_logevent(WINSCP_BOM "Not substituting certificate \"%s\" for public "
  2277. "key: %s", filename_to_str(s->detached_cert_file),
  2278. fail_reason->s);
  2279. if (s->publickey_blob) {
  2280. /* If the user provided a specific key file to use (i.e.
  2281. * this wasn't just a key we picked opportunistically out
  2282. * of an agent), then they probably _care_ that we didn't
  2283. * send the certificate, so we should make a loud error
  2284. * message about it as well as just commenting in the
  2285. * Event Log. */
  2286. ppl_printf(WINSCP_BOM "Unable to use certificate \"%s\" with public "
  2287. "key \"%s\": %s\r\n",
  2288. filename_to_str(s->detached_cert_file),
  2289. filename_to_str(s->keyfile),
  2290. fail_reason->s);
  2291. }
  2292. }
  2293. out:
  2294. /* Whether we did that or not, free our stuff. */
  2295. if (certbase)
  2296. strbuf_free(certbase);
  2297. if (pkbase)
  2298. strbuf_free(pkbase);
  2299. if (certkey)
  2300. ssh_key_free(certkey);
  2301. if (pk)
  2302. ssh_key_free(pk);
  2303. strbuf_free(fail_reason);
  2304. /* And if we did, don't fall through to the alternative below */
  2305. if (done)
  2306. return;
  2307. } // WINSCP
  2308. }
  2309. /* In all other cases, basically just put in what we were given -
  2310. * except for the same bug workaround as above. */
  2311. alg = workaround_rsa_sha2_cert_userauth(s, alg);
  2312. put_stringpl(pkt, alg);
  2313. put_stringpl(pkt, pkblob);
  2314. }
  2315. static ptrlen workaround_rsa_sha2_cert_userauth(
  2316. struct ssh2_userauth_state *s, ptrlen id)
  2317. {
  2318. if (!(s->ppl.remote_bugs & BUG_RSA_SHA2_CERT_USERAUTH))
  2319. return id;
  2320. /*
  2321. * No need to try to do this in a general way based on the
  2322. * relations between ssh_keyalgs; we know there are a limited
  2323. * number of affected versions of OpenSSH, so this doesn't have to
  2324. * be futureproof against later additions to the family.
  2325. */
  2326. if (ptrlen_eq_string(id, "[email protected]") ||
  2327. ptrlen_eq_string(id, "[email protected]"))
  2328. return PTRLEN_LITERAL("[email protected]");
  2329. return id;
  2330. }
  2331. /*
  2332. * Helper function to add an SSH-2 signature blob to a packet. Expects
  2333. * to be shown the public key blob as well as the signature blob.
  2334. * Normally just appends the sig blob unmodified as a string, except
  2335. * that it optionally breaks it open and fiddle with it to work around
  2336. * BUG_SSH2_RSA_PADDING.
  2337. */
  2338. static void ssh2_userauth_add_sigblob(
  2339. struct ssh2_userauth_state *s, PktOut *pkt, ptrlen pkblob, ptrlen sigblob)
  2340. {
  2341. BinarySource pk[1], sig[1];
  2342. BinarySource_BARE_INIT_PL(pk, pkblob);
  2343. BinarySource_BARE_INIT_PL(sig, sigblob);
  2344. /* dmemdump(pkblob, pkblob_len); */
  2345. /* dmemdump(sigblob, sigblob_len); */
  2346. /*
  2347. * See if this is in fact an ssh-rsa signature and a buggy
  2348. * server; otherwise we can just do this the easy way.
  2349. */
  2350. if ((s->ppl.remote_bugs & BUG_SSH2_RSA_PADDING) &&
  2351. ptrlen_eq_string(get_string(pk), "ssh-rsa") &&
  2352. ptrlen_eq_string(get_string(sig), "ssh-rsa")) {
  2353. ptrlen mod_mp, sig_mp;
  2354. size_t sig_prefix_len;
  2355. /*
  2356. * Find the modulus and signature integers.
  2357. */
  2358. get_string(pk); /* skip over exponent */
  2359. mod_mp = get_string(pk); /* remember modulus */
  2360. sig_prefix_len = sig->pos;
  2361. sig_mp = get_string(sig);
  2362. if (get_err(pk) || get_err(sig))
  2363. goto give_up;
  2364. /*
  2365. * Find the byte length of the modulus, not counting leading
  2366. * zeroes.
  2367. */
  2368. while (mod_mp.len > 0 && *(const char *)mod_mp.ptr == 0) {
  2369. mod_mp.len--;
  2370. mod_mp.ptr = (const char *)mod_mp.ptr + 1;
  2371. }
  2372. /* debug("modulus length is %d\n", len); */
  2373. /* debug("signature length is %d\n", siglen); */
  2374. if (mod_mp.len > sig_mp.len) {
  2375. strbuf *substr = strbuf_new();
  2376. put_data(substr, sigblob.ptr, sig_prefix_len);
  2377. put_uint32(substr, mod_mp.len);
  2378. put_padding(substr, mod_mp.len - sig_mp.len, 0);
  2379. put_datapl(substr, sig_mp);
  2380. put_stringsb(pkt, substr);
  2381. return;
  2382. }
  2383. /* Otherwise fall through and do it the easy way. We also come
  2384. * here as a fallback if we discover above that the key blob
  2385. * is misformatted in some way. */
  2386. give_up:;
  2387. }
  2388. put_stringpl(pkt, sigblob);
  2389. }
  2390. #ifndef NO_GSSAPI
  2391. static PktOut *ssh2_userauth_gss_packet(
  2392. struct ssh2_userauth_state *s, const char *authtype)
  2393. {
  2394. strbuf *sb;
  2395. PktOut *p;
  2396. Ssh_gss_buf buf;
  2397. Ssh_gss_buf mic;
  2398. /*
  2399. * The mic is computed over the session id + intended
  2400. * USERAUTH_REQUEST packet.
  2401. */
  2402. sb = strbuf_new();
  2403. put_stringpl(sb, s->session_id);
  2404. put_byte(sb, SSH2_MSG_USERAUTH_REQUEST);
  2405. put_stringz(sb, s->username);
  2406. put_stringz(sb, s->successor_layer->vt->name);
  2407. put_stringz(sb, authtype);
  2408. /* Compute the mic */
  2409. buf.value = sb->s;
  2410. buf.length = sb->len;
  2411. s->shgss->lib->get_mic(s->shgss->lib, s->shgss->ctx, &buf, &mic);
  2412. strbuf_free(sb);
  2413. /* Now we can build the real packet */
  2414. if (strcmp(authtype, "gssapi-with-mic") == 0) {
  2415. p = ssh_bpp_new_pktout(s->ppl.bpp, SSH2_MSG_USERAUTH_GSSAPI_MIC);
  2416. } else {
  2417. p = ssh_bpp_new_pktout(s->ppl.bpp, SSH2_MSG_USERAUTH_REQUEST);
  2418. put_stringz(p, s->username);
  2419. put_stringz(p, s->successor_layer->vt->name);
  2420. put_stringz(p, authtype);
  2421. }
  2422. put_string(p, mic.value, mic.length);
  2423. return p;
  2424. }
  2425. #endif
  2426. static bool ssh2_userauth_get_specials(
  2427. PacketProtocolLayer *ppl, add_special_fn_t add_special, void *ctx)
  2428. {
  2429. /* No specials provided by this layer. */
  2430. return false;
  2431. }
  2432. static void ssh2_userauth_special_cmd(PacketProtocolLayer *ppl,
  2433. SessionSpecialCode code, int arg)
  2434. {
  2435. /* No specials provided by this layer. */
  2436. }
  2437. static void ssh2_userauth_reconfigure(PacketProtocolLayer *ppl, Conf *conf)
  2438. {
  2439. struct ssh2_userauth_state *s =
  2440. container_of(ppl, struct ssh2_userauth_state, ppl);
  2441. ssh_ppl_reconfigure(s->successor_layer, conf);
  2442. }
  2443. static void ssh2_userauth_final_output(PacketProtocolLayer *ppl)
  2444. {
  2445. struct ssh2_userauth_state *s =
  2446. container_of(ppl, struct ssh2_userauth_state, ppl);
  2447. /*
  2448. * Check for any unconsumed banner packets that might have landed
  2449. * in our queue just before the server closed the connection, and
  2450. * add them to our banner buffer.
  2451. */
  2452. PktIn *pktin; // WINSCP
  2453. for (pktin = pq_first(s->ppl.in_pq); pktin != NULL;
  2454. pktin = pq_next(s->ppl.in_pq, pktin)) {
  2455. if (pktin->type == SSH2_MSG_USERAUTH_BANNER)
  2456. ssh2_userauth_handle_banner_packet(s, pktin);
  2457. }
  2458. /* And now make sure we've shown the banner, before exiting */
  2459. ssh2_userauth_print_banner(s);
  2460. }