userauth2-client.c 110 KB

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