userauth2-client.c 110 KB

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