ssh1login.c 47 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211
  1. /*
  2. * Packet protocol layer for the SSH-1 login phase (combining what
  3. * SSH-2 would think of as key exchange and user authentication).
  4. */
  5. #include <assert.h>
  6. #include "putty.h"
  7. #include "ssh.h"
  8. #include "sshbpp.h"
  9. #include "sshppl.h"
  10. #include "sshcr.h"
  11. struct ssh1_login_state {
  12. int crState;
  13. PacketProtocolLayer *successor_layer;
  14. Conf *conf;
  15. char *savedhost;
  16. int savedport;
  17. int try_agent_auth;
  18. int remote_protoflags;
  19. int local_protoflags;
  20. unsigned char session_key[32];
  21. char *username;
  22. agent_pending_query *auth_agent_query;
  23. int len;
  24. unsigned char *rsabuf;
  25. unsigned long supported_ciphers_mask, supported_auths_mask;
  26. int tried_publickey, tried_agent;
  27. int tis_auth_refused, ccard_auth_refused;
  28. unsigned char cookie[8];
  29. unsigned char session_id[16];
  30. int cipher_type;
  31. strbuf *publickey_blob;
  32. char *publickey_comment;
  33. int privatekey_available, privatekey_encrypted;
  34. prompts_t *cur_prompt;
  35. int userpass_ret;
  36. char c;
  37. int pwpkt_type;
  38. void *agent_response_to_free;
  39. ptrlen agent_response;
  40. BinarySource asrc[1]; /* response from SSH agent */
  41. int keyi, nkeys;
  42. int authed;
  43. struct RSAKey key;
  44. Bignum challenge;
  45. ptrlen comment;
  46. int dlgret;
  47. Filename *keyfile;
  48. struct RSAKey servkey, hostkey;
  49. int want_user_input;
  50. PacketProtocolLayer ppl;
  51. };
  52. static void ssh1_login_free(PacketProtocolLayer *);
  53. static void ssh1_login_process_queue(PacketProtocolLayer *);
  54. static void ssh1_login_dialog_callback(void *, int);
  55. static void ssh1_login_special_cmd(PacketProtocolLayer *ppl,
  56. SessionSpecialCode code, int arg);
  57. static int ssh1_login_want_user_input(PacketProtocolLayer *ppl);
  58. static void ssh1_login_got_user_input(PacketProtocolLayer *ppl);
  59. static void ssh1_login_reconfigure(PacketProtocolLayer *ppl, Conf *conf);
  60. static const struct PacketProtocolLayerVtable ssh1_login_vtable = {
  61. ssh1_login_free,
  62. ssh1_login_process_queue,
  63. ssh1_common_get_specials,
  64. ssh1_login_special_cmd,
  65. ssh1_login_want_user_input,
  66. ssh1_login_got_user_input,
  67. ssh1_login_reconfigure,
  68. NULL /* no layer names in SSH-1 */,
  69. };
  70. static void ssh1_login_agent_query(struct ssh1_login_state *s, strbuf *req);
  71. static void ssh1_login_agent_callback(void *loginv, void *reply, int replylen);
  72. PacketProtocolLayer *ssh1_login_new(
  73. Conf *conf, const char *host, int port,
  74. PacketProtocolLayer *successor_layer)
  75. {
  76. struct ssh1_login_state *s = snew(struct ssh1_login_state);
  77. memset(s, 0, sizeof(*s));
  78. s->ppl.vt = &ssh1_login_vtable;
  79. s->conf = conf_copy(conf);
  80. s->savedhost = dupstr(host);
  81. s->savedport = port;
  82. s->successor_layer = successor_layer;
  83. return &s->ppl;
  84. }
  85. static void ssh1_login_free(PacketProtocolLayer *ppl)
  86. {
  87. struct ssh1_login_state *s =
  88. container_of(ppl, struct ssh1_login_state, ppl);
  89. if (s->successor_layer)
  90. ssh_ppl_free(s->successor_layer);
  91. conf_free(s->conf);
  92. sfree(s->savedhost);
  93. sfree(s->rsabuf);
  94. sfree(s->username);
  95. if (s->publickey_blob)
  96. strbuf_free(s->publickey_blob);
  97. sfree(s->publickey_comment);
  98. if (s->cur_prompt)
  99. free_prompts(s->cur_prompt);
  100. sfree(s->agent_response_to_free);
  101. if (s->auth_agent_query)
  102. agent_cancel_query(s->auth_agent_query);
  103. sfree(s);
  104. }
  105. int ssh1_common_filter_queue(PacketProtocolLayer *ppl)
  106. {
  107. PktIn *pktin;
  108. ptrlen msg;
  109. while ((pktin = pq_peek(ppl->in_pq)) != NULL) {
  110. switch (pktin->type) {
  111. case SSH1_MSG_DISCONNECT:
  112. msg = get_string(pktin);
  113. ssh_remote_error(ppl->ssh,
  114. "Server sent disconnect message:\n\"%.*s\"",
  115. PTRLEN_PRINTF(msg));
  116. return TRUE; /* indicate that we've been freed */
  117. case SSH1_MSG_DEBUG:
  118. msg = get_string(pktin);
  119. ppl_logevent(("Remote debug message: %.*s", PTRLEN_PRINTF(msg)));
  120. pq_pop(ppl->in_pq);
  121. break;
  122. case SSH1_MSG_IGNORE:
  123. /* Do nothing, because we're ignoring it! Duhh. */
  124. pq_pop(ppl->in_pq);
  125. break;
  126. default:
  127. return FALSE;
  128. }
  129. }
  130. return FALSE;
  131. }
  132. static int ssh1_login_filter_queue(struct ssh1_login_state *s)
  133. {
  134. return ssh1_common_filter_queue(&s->ppl);
  135. }
  136. static PktIn *ssh1_login_pop(struct ssh1_login_state *s)
  137. {
  138. if (ssh1_login_filter_queue(s))
  139. return NULL;
  140. return pq_pop(s->ppl.in_pq);
  141. }
  142. static void ssh1_login_process_queue(PacketProtocolLayer *ppl)
  143. {
  144. struct ssh1_login_state *s =
  145. container_of(ppl, struct ssh1_login_state, ppl);
  146. PktIn *pktin;
  147. PktOut *pkt;
  148. int i;
  149. /* Filter centrally handled messages off the front of the queue on
  150. * every entry to this coroutine, no matter where we're resuming
  151. * from, even if we're _not_ looping on pq_pop. That way we can
  152. * still proactively handle those messages even if we're waiting
  153. * for a user response. */
  154. if (ssh1_login_filter_queue(s))
  155. return;
  156. crBegin(s->crState);
  157. crMaybeWaitUntilV((pktin = ssh1_login_pop(s)) != NULL);
  158. if (pktin->type != SSH1_SMSG_PUBLIC_KEY) {
  159. ssh_proto_error(s->ppl.ssh, "Public key packet not received");
  160. return;
  161. }
  162. ppl_logevent(("Received public keys"));
  163. {
  164. ptrlen pl = get_data(pktin, 8);
  165. memcpy(s->cookie, pl.ptr, pl.len);
  166. }
  167. get_rsa_ssh1_pub(pktin, &s->servkey, RSA_SSH1_EXPONENT_FIRST);
  168. get_rsa_ssh1_pub(pktin, &s->hostkey, RSA_SSH1_EXPONENT_FIRST);
  169. s->hostkey.comment = NULL; /* avoid confusing rsa_ssh1_fingerprint */
  170. /*
  171. * Log the host key fingerprint.
  172. */
  173. if (!get_err(pktin)) {
  174. char *fingerprint = rsa_ssh1_fingerprint(&s->hostkey);
  175. ppl_logevent(("Host key fingerprint is:"));
  176. ppl_logevent((" %s", fingerprint));
  177. sfree(fingerprint);
  178. }
  179. s->remote_protoflags = get_uint32(pktin);
  180. s->supported_ciphers_mask = get_uint32(pktin);
  181. s->supported_auths_mask = get_uint32(pktin);
  182. if (get_err(pktin)) {
  183. ssh_proto_error(s->ppl.ssh, "Bad SSH-1 public key packet");
  184. return;
  185. }
  186. if ((s->ppl.remote_bugs & BUG_CHOKES_ON_RSA))
  187. s->supported_auths_mask &= ~(1 << SSH1_AUTH_RSA);
  188. s->local_protoflags =
  189. s->remote_protoflags & SSH1_PROTOFLAGS_SUPPORTED;
  190. s->local_protoflags |= SSH1_PROTOFLAG_SCREEN_NUMBER;
  191. {
  192. struct MD5Context md5c;
  193. MD5Init(&md5c);
  194. for (i = (bignum_bitcount(s->hostkey.modulus) + 7) / 8; i-- ;)
  195. put_byte(&md5c, bignum_byte(s->hostkey.modulus, i));
  196. for (i = (bignum_bitcount(s->servkey.modulus) + 7) / 8; i-- ;)
  197. put_byte(&md5c, bignum_byte(s->servkey.modulus, i));
  198. put_data(&md5c, s->cookie, 8);
  199. MD5Final(s->session_id, &md5c);
  200. }
  201. for (i = 0; i < 32; i++)
  202. s->session_key[i] = random_byte();
  203. /*
  204. * Verify that the `bits' and `bytes' parameters match.
  205. */
  206. if (s->hostkey.bits > s->hostkey.bytes * 8 ||
  207. s->servkey.bits > s->servkey.bytes * 8) {
  208. ssh_proto_error(s->ppl.ssh, "SSH-1 public keys were badly formatted");
  209. return;
  210. }
  211. s->len = (s->hostkey.bytes > s->servkey.bytes ?
  212. s->hostkey.bytes : s->servkey.bytes);
  213. s->rsabuf = snewn(s->len, unsigned char);
  214. /*
  215. * Verify the host key.
  216. */
  217. {
  218. /*
  219. * First format the key into a string.
  220. */
  221. int len = rsastr_len(&s->hostkey);
  222. char *fingerprint;
  223. char *keystr = snewn(len, char);
  224. rsastr_fmt(keystr, &s->hostkey);
  225. fingerprint = rsa_ssh1_fingerprint(&s->hostkey);
  226. /* First check against manually configured host keys. */
  227. s->dlgret = verify_ssh_manual_host_key(s->conf, fingerprint, NULL);
  228. sfree(fingerprint);
  229. if (s->dlgret == 0) { /* did not match */
  230. sfree(keystr);
  231. ssh_proto_error(s->ppl.ssh, "Host key did not appear in manually "
  232. "configured list");
  233. return;
  234. } else if (s->dlgret < 0) { /* none configured; use standard handling */
  235. s->dlgret = seat_verify_ssh_host_key(
  236. s->ppl.seat, s->savedhost, s->savedport,
  237. "rsa", keystr, fingerprint, ssh1_login_dialog_callback, s);
  238. sfree(keystr);
  239. #ifdef FUZZING
  240. s->dlgret = 1;
  241. #endif
  242. crMaybeWaitUntilV(s->dlgret >= 0);
  243. if (s->dlgret == 0) {
  244. ssh_user_close(s->ppl.ssh,
  245. "User aborted at host key verification");
  246. return;
  247. }
  248. } else {
  249. sfree(keystr);
  250. }
  251. }
  252. for (i = 0; i < 32; i++) {
  253. s->rsabuf[i] = s->session_key[i];
  254. if (i < 16)
  255. s->rsabuf[i] ^= s->session_id[i];
  256. }
  257. {
  258. struct RSAKey *smaller = (s->hostkey.bytes > s->servkey.bytes ?
  259. &s->servkey : &s->hostkey);
  260. struct RSAKey *larger = (s->hostkey.bytes > s->servkey.bytes ?
  261. &s->hostkey : &s->servkey);
  262. if (!rsa_ssh1_encrypt(s->rsabuf, 32, smaller) ||
  263. !rsa_ssh1_encrypt(s->rsabuf, smaller->bytes, larger)) {
  264. ssh_proto_error(s->ppl.ssh, "SSH-1 public key encryptions failed "
  265. "due to bad formatting");
  266. return;
  267. }
  268. }
  269. ppl_logevent(("Encrypted session key"));
  270. {
  271. int cipher_chosen = 0, warn = 0;
  272. const char *cipher_string = NULL;
  273. int i;
  274. for (i = 0; !cipher_chosen && i < CIPHER_MAX; i++) {
  275. int next_cipher = conf_get_int_int(
  276. s->conf, CONF_ssh_cipherlist, i);
  277. if (next_cipher == CIPHER_WARN) {
  278. /* If/when we choose a cipher, warn about it */
  279. warn = 1;
  280. } else if (next_cipher == CIPHER_AES) {
  281. /* XXX Probably don't need to mention this. */
  282. ppl_logevent(("AES not supported in SSH-1, skipping"));
  283. } else {
  284. switch (next_cipher) {
  285. case CIPHER_3DES: s->cipher_type = SSH_CIPHER_3DES;
  286. cipher_string = "3DES"; break;
  287. case CIPHER_BLOWFISH: s->cipher_type = SSH_CIPHER_BLOWFISH;
  288. cipher_string = "Blowfish"; break;
  289. case CIPHER_DES: s->cipher_type = SSH_CIPHER_DES;
  290. cipher_string = "single-DES"; break;
  291. }
  292. if (s->supported_ciphers_mask & (1 << s->cipher_type))
  293. cipher_chosen = 1;
  294. }
  295. }
  296. if (!cipher_chosen) {
  297. if ((s->supported_ciphers_mask & (1 << SSH_CIPHER_3DES)) == 0) {
  298. ssh_proto_error(s->ppl.ssh, "Server violates SSH-1 protocol "
  299. "by not supporting 3DES encryption");
  300. } else {
  301. /* shouldn't happen */
  302. ssh_sw_abort(s->ppl.ssh, "No supported ciphers found");
  303. }
  304. return;
  305. }
  306. /* Warn about chosen cipher if necessary. */
  307. if (warn) {
  308. s->dlgret = seat_confirm_weak_crypto_primitive(
  309. s->ppl.seat, "cipher", cipher_string,
  310. ssh1_login_dialog_callback, s);
  311. crMaybeWaitUntilV(s->dlgret >= 0);
  312. if (s->dlgret == 0) {
  313. ssh_user_close(s->ppl.ssh, "User aborted at cipher warning");
  314. return;
  315. }
  316. }
  317. }
  318. switch (s->cipher_type) {
  319. case SSH_CIPHER_3DES:
  320. ppl_logevent(("Using 3DES encryption"));
  321. break;
  322. case SSH_CIPHER_DES:
  323. ppl_logevent(("Using single-DES encryption"));
  324. break;
  325. case SSH_CIPHER_BLOWFISH:
  326. ppl_logevent(("Using Blowfish encryption"));
  327. break;
  328. }
  329. pkt = ssh_bpp_new_pktout(s->ppl.bpp, SSH1_CMSG_SESSION_KEY);
  330. put_byte(pkt, s->cipher_type);
  331. put_data(pkt, s->cookie, 8);
  332. put_uint16(pkt, s->len * 8);
  333. put_data(pkt, s->rsabuf, s->len);
  334. put_uint32(pkt, s->local_protoflags);
  335. pq_push(s->ppl.out_pq, pkt);
  336. ppl_logevent(("Trying to enable encryption..."));
  337. sfree(s->rsabuf);
  338. s->rsabuf = NULL;
  339. /*
  340. * Force the BPP to synchronously marshal all packets up to and
  341. * including the SESSION_KEY into wire format, before we turn on
  342. * crypto.
  343. */
  344. ssh_bpp_handle_output(s->ppl.bpp);
  345. {
  346. const struct ssh1_cipheralg *cipher =
  347. (s->cipher_type == SSH_CIPHER_BLOWFISH ? &ssh1_blowfish :
  348. s->cipher_type == SSH_CIPHER_DES ? &ssh1_des : &ssh1_3des);
  349. ssh1_bpp_new_cipher(s->ppl.bpp, cipher, s->session_key);
  350. }
  351. if (s->servkey.modulus) {
  352. sfree(s->servkey.modulus);
  353. s->servkey.modulus = NULL;
  354. }
  355. if (s->servkey.exponent) {
  356. sfree(s->servkey.exponent);
  357. s->servkey.exponent = NULL;
  358. }
  359. if (s->hostkey.modulus) {
  360. sfree(s->hostkey.modulus);
  361. s->hostkey.modulus = NULL;
  362. }
  363. if (s->hostkey.exponent) {
  364. sfree(s->hostkey.exponent);
  365. s->hostkey.exponent = NULL;
  366. }
  367. crMaybeWaitUntilV((pktin = ssh1_login_pop(s)) != NULL);
  368. if (pktin->type != SSH1_SMSG_SUCCESS) {
  369. ssh_proto_error(s->ppl.ssh, "Encryption not successfully enabled");
  370. return;
  371. }
  372. ppl_logevent(("Successfully started encryption"));
  373. if ((s->username = get_remote_username(s->conf)) == NULL) {
  374. s->cur_prompt = new_prompts();
  375. s->cur_prompt->to_server = TRUE;
  376. s->cur_prompt->name = dupstr("SSH login name");
  377. add_prompt(s->cur_prompt, dupstr("login as: "), TRUE);
  378. s->userpass_ret = seat_get_userpass_input(
  379. s->ppl.seat, s->cur_prompt, NULL);
  380. while (1) {
  381. while (s->userpass_ret < 0 &&
  382. bufchain_size(s->ppl.user_input) > 0)
  383. s->userpass_ret = seat_get_userpass_input(
  384. s->ppl.seat, s->cur_prompt, s->ppl.user_input);
  385. if (s->userpass_ret >= 0)
  386. break;
  387. s->want_user_input = TRUE;
  388. crReturnV;
  389. s->want_user_input = FALSE;
  390. }
  391. if (!s->userpass_ret) {
  392. /*
  393. * Failed to get a username. Terminate.
  394. */
  395. ssh_user_close(s->ppl.ssh, "No username provided");
  396. return;
  397. }
  398. s->username = dupstr(s->cur_prompt->prompts[0]->result);
  399. free_prompts(s->cur_prompt);
  400. s->cur_prompt = NULL;
  401. }
  402. pkt = ssh_bpp_new_pktout(s->ppl.bpp, SSH1_CMSG_USER);
  403. put_stringz(pkt, s->username);
  404. pq_push(s->ppl.out_pq, pkt);
  405. ppl_logevent((WINSCP_BOM "Sent username \"%s\"", s->username));
  406. if ((flags & FLAG_VERBOSE) || (flags & FLAG_INTERACTIVE))
  407. ppl_printf(("Sent username \"%s\"\r\n", s->username));
  408. crMaybeWaitUntilV((pktin = ssh1_login_pop(s)) != NULL);
  409. if (!(s->supported_auths_mask & (1 << SSH1_AUTH_RSA))) {
  410. /* We must not attempt PK auth. Pretend we've already tried it. */
  411. s->tried_publickey = s->tried_agent = TRUE;
  412. } else {
  413. s->tried_publickey = s->tried_agent = FALSE;
  414. }
  415. s->tis_auth_refused = s->ccard_auth_refused = FALSE;
  416. /*
  417. * Load the public half of any configured keyfile for later use.
  418. */
  419. s->keyfile = conf_get_filename(s->conf, CONF_keyfile);
  420. if (!filename_is_null(s->keyfile)) {
  421. int keytype;
  422. ppl_logevent((WINSCP_BOM "Reading key file \"%.150s\"",
  423. filename_to_str(s->keyfile)));
  424. keytype = key_type(s->keyfile);
  425. if (keytype == SSH_KEYTYPE_SSH1 ||
  426. keytype == SSH_KEYTYPE_SSH1_PUBLIC) {
  427. const char *error;
  428. s->publickey_blob = strbuf_new();
  429. if (rsa_ssh1_loadpub(s->keyfile,
  430. BinarySink_UPCAST(s->publickey_blob),
  431. &s->publickey_comment, &error)) {
  432. s->privatekey_available = (keytype == SSH_KEYTYPE_SSH1);
  433. if (!s->privatekey_available)
  434. ppl_logevent(("Key file contains public key only"));
  435. s->privatekey_encrypted = rsa_ssh1_encrypted(s->keyfile, NULL);
  436. } else {
  437. ppl_logevent(("Unable to load key (%s)", error));
  438. ppl_printf((WINSCP_BOM "Unable to load key file \"%s\" (%s)\r\n",
  439. filename_to_str(s->keyfile), error));
  440. strbuf_free(s->publickey_blob);
  441. s->publickey_blob = NULL;
  442. }
  443. } else {
  444. ppl_logevent(("Unable to use this key file (%s)",
  445. key_type_to_str(keytype)));
  446. ppl_printf((WINSCP_BOM "Unable to use key file \"%s\" (%s)\r\n",
  447. filename_to_str(s->keyfile),
  448. key_type_to_str(keytype)));
  449. }
  450. }
  451. /* Check whether we're configured to try Pageant, and also whether
  452. * it's available. */
  453. s->try_agent_auth = (conf_get_int(s->conf, CONF_tryagent) &&
  454. agent_exists());
  455. while (pktin->type == SSH1_SMSG_FAILURE) {
  456. s->pwpkt_type = SSH1_CMSG_AUTH_PASSWORD;
  457. if (s->try_agent_auth && !s->tried_agent) {
  458. /*
  459. * Attempt RSA authentication using Pageant.
  460. */
  461. s->authed = FALSE;
  462. s->tried_agent = 1;
  463. ppl_logevent(("Pageant is running. Requesting keys."));
  464. /* Request the keys held by the agent. */
  465. {
  466. strbuf *request = strbuf_new_for_agent_query();
  467. put_byte(request, SSH1_AGENTC_REQUEST_RSA_IDENTITIES);
  468. ssh1_login_agent_query(s, request);
  469. strbuf_free(request);
  470. crMaybeWaitUntilV(!s->auth_agent_query);
  471. }
  472. BinarySource_BARE_INIT(
  473. s->asrc, s->agent_response.ptr, s->agent_response.len);
  474. get_uint32(s->asrc); /* skip length field */
  475. if (get_byte(s->asrc) == SSH1_AGENT_RSA_IDENTITIES_ANSWER) {
  476. s->nkeys = toint(get_uint32(s->asrc));
  477. if (s->nkeys < 0) {
  478. ppl_logevent(("Pageant reported negative key count %d",
  479. s->nkeys));
  480. s->nkeys = 0;
  481. }
  482. ppl_logevent(("Pageant has %d SSH-1 keys", s->nkeys));
  483. for (s->keyi = 0; s->keyi < s->nkeys; s->keyi++) {
  484. size_t start, end;
  485. start = s->asrc->pos;
  486. get_rsa_ssh1_pub(s->asrc, &s->key,
  487. RSA_SSH1_EXPONENT_FIRST);
  488. end = s->asrc->pos;
  489. s->comment = get_string(s->asrc);
  490. if (get_err(s->asrc)) {
  491. ppl_logevent(("Pageant key list packet was truncated"));
  492. break;
  493. }
  494. if (s->publickey_blob) {
  495. ptrlen keystr = make_ptrlen(
  496. (const char *)s->asrc->data + start, end - start);
  497. if (keystr.len == s->publickey_blob->len &&
  498. !memcmp(keystr.ptr, s->publickey_blob->s,
  499. s->publickey_blob->len)) {
  500. ppl_logevent(("Pageant key #%d matches "
  501. "configured key file", s->keyi));
  502. s->tried_publickey = 1;
  503. } else
  504. /* Skip non-configured key */
  505. continue;
  506. }
  507. ppl_logevent(("Trying Pageant key #%d", s->keyi));
  508. pkt = ssh_bpp_new_pktout(s->ppl.bpp, SSH1_CMSG_AUTH_RSA);
  509. put_mp_ssh1(pkt, s->key.modulus);
  510. pq_push(s->ppl.out_pq, pkt);
  511. crMaybeWaitUntilV((pktin = ssh1_login_pop(s))
  512. != NULL);
  513. if (pktin->type != SSH1_SMSG_AUTH_RSA_CHALLENGE) {
  514. ppl_logevent(("Key refused"));
  515. continue;
  516. }
  517. ppl_logevent(("Received RSA challenge"));
  518. s->challenge = get_mp_ssh1(pktin);
  519. if (get_err(pktin)) {
  520. freebn(s->challenge);
  521. ssh_proto_error(s->ppl.ssh, "Server's RSA challenge "
  522. "was badly formatted");
  523. return;
  524. }
  525. {
  526. strbuf *agentreq;
  527. const char *ret;
  528. agentreq = strbuf_new_for_agent_query();
  529. put_byte(agentreq, SSH1_AGENTC_RSA_CHALLENGE);
  530. put_uint32(agentreq, bignum_bitcount(s->key.modulus));
  531. put_mp_ssh1(agentreq, s->key.exponent);
  532. put_mp_ssh1(agentreq, s->key.modulus);
  533. put_mp_ssh1(agentreq, s->challenge);
  534. put_data(agentreq, s->session_id, 16);
  535. put_uint32(agentreq, 1); /* response format */
  536. ssh1_login_agent_query(s, agentreq);
  537. strbuf_free(agentreq);
  538. crMaybeWaitUntilV(!s->auth_agent_query);
  539. ret = s->agent_response.ptr;
  540. if (ret) {
  541. if (s->agent_response.len >= 5+16 &&
  542. ret[4] == SSH1_AGENT_RSA_RESPONSE) {
  543. ppl_logevent(("Sending Pageant's response"));
  544. pkt = ssh_bpp_new_pktout(
  545. s->ppl.bpp, SSH1_CMSG_AUTH_RSA_RESPONSE);
  546. put_data(pkt, ret + 5, 16);
  547. pq_push(s->ppl.out_pq, pkt);
  548. sfree((char *)ret);
  549. crMaybeWaitUntilV(
  550. (pktin = ssh1_login_pop(s))
  551. != NULL);
  552. if (pktin->type == SSH1_SMSG_SUCCESS) {
  553. ppl_logevent(("Pageant's response "
  554. "accepted"));
  555. if (flags & FLAG_VERBOSE) {
  556. ppl_printf(("Authenticated using RSA "
  557. "key \"%.*s\" from "
  558. "agent\r\n", PTRLEN_PRINTF(
  559. s->comment)));
  560. }
  561. s->authed = TRUE;
  562. } else
  563. ppl_logevent(("Pageant's response not "
  564. "accepted"));
  565. } else {
  566. ppl_logevent(("Pageant failed to answer "
  567. "challenge"));
  568. sfree((char *)ret);
  569. }
  570. } else {
  571. ppl_logevent(("No reply received from Pageant"));
  572. }
  573. }
  574. freebn(s->key.exponent);
  575. freebn(s->key.modulus);
  576. freebn(s->challenge);
  577. if (s->authed)
  578. break;
  579. }
  580. sfree(s->agent_response_to_free);
  581. s->agent_response_to_free = NULL;
  582. if (s->publickey_blob && !s->tried_publickey)
  583. ppl_logevent(("Configured key file not in Pageant"));
  584. } else {
  585. ppl_logevent(("Failed to get reply from Pageant"));
  586. }
  587. if (s->authed)
  588. break;
  589. }
  590. if (s->publickey_blob && s->privatekey_available &&
  591. !s->tried_publickey) {
  592. /*
  593. * Try public key authentication with the specified
  594. * key file.
  595. */
  596. int got_passphrase; /* need not be kept over crReturn */
  597. if (flags & FLAG_VERBOSE)
  598. ppl_printf((WINSCP_BOM "Trying public key authentication.\r\n"));
  599. ppl_logevent(("Trying public key \"%s\"",
  600. filename_to_str(s->keyfile)));
  601. s->tried_publickey = 1;
  602. got_passphrase = FALSE;
  603. while (!got_passphrase) {
  604. /*
  605. * Get a passphrase, if necessary.
  606. */
  607. int retd;
  608. char *passphrase = NULL; /* only written after crReturn */
  609. const char *error;
  610. if (!s->privatekey_encrypted) {
  611. if (flags & FLAG_VERBOSE)
  612. ppl_printf(("No passphrase required.\r\n"));
  613. passphrase = NULL;
  614. } else {
  615. s->cur_prompt = new_prompts(s->ppl.seat);
  616. s->cur_prompt->to_server = FALSE;
  617. s->cur_prompt->name = dupstr("SSH key passphrase");
  618. add_prompt(s->cur_prompt,
  619. dupprintf("Passphrase for key \"%.100s\": ",
  620. s->publickey_comment), FALSE);
  621. s->userpass_ret = seat_get_userpass_input(
  622. s->ppl.seat, s->cur_prompt, NULL);
  623. while (1) {
  624. while (s->userpass_ret < 0 &&
  625. bufchain_size(s->ppl.user_input) > 0)
  626. s->userpass_ret = seat_get_userpass_input(
  627. s->ppl.seat, s->cur_prompt, s->ppl.user_input);
  628. if (s->userpass_ret >= 0)
  629. break;
  630. s->want_user_input = TRUE;
  631. crReturnV;
  632. s->want_user_input = FALSE;
  633. }
  634. if (!s->userpass_ret) {
  635. /* Failed to get a passphrase. Terminate. */
  636. ssh_user_close(s->ppl.ssh,
  637. "User aborted at passphrase prompt");
  638. return;
  639. }
  640. passphrase = dupstr(s->cur_prompt->prompts[0]->result);
  641. free_prompts(s->cur_prompt);
  642. s->cur_prompt = NULL;
  643. }
  644. /*
  645. * Try decrypting key with passphrase.
  646. */
  647. retd = rsa_ssh1_loadkey(
  648. s->keyfile, &s->key, passphrase, &error);
  649. if (passphrase) {
  650. smemclr(passphrase, strlen(passphrase));
  651. sfree(passphrase);
  652. }
  653. if (retd == 1) {
  654. /* Correct passphrase. */
  655. got_passphrase = TRUE;
  656. } else if (retd == 0) {
  657. ppl_printf((WINSCP_BOM "Couldn't load private key from %s (%s).\r\n",
  658. filename_to_str(s->keyfile), error));
  659. got_passphrase = FALSE;
  660. break; /* go and try something else */
  661. } else if (retd == -1) {
  662. ppl_printf(("Wrong passphrase.\r\n"));
  663. got_passphrase = FALSE;
  664. /* and try again */
  665. } else {
  666. assert(0 && "unexpected return from rsa_ssh1_loadkey()");
  667. got_passphrase = FALSE; /* placate optimisers */
  668. }
  669. }
  670. if (got_passphrase) {
  671. /*
  672. * Send a public key attempt.
  673. */
  674. pkt = ssh_bpp_new_pktout(s->ppl.bpp, SSH1_CMSG_AUTH_RSA);
  675. put_mp_ssh1(pkt, s->key.modulus);
  676. pq_push(s->ppl.out_pq, pkt);
  677. crMaybeWaitUntilV((pktin = ssh1_login_pop(s))
  678. != NULL);
  679. if (pktin->type == SSH1_SMSG_FAILURE) {
  680. ppl_printf(("Server refused our public key.\r\n"));
  681. continue; /* go and try something else */
  682. }
  683. if (pktin->type != SSH1_SMSG_AUTH_RSA_CHALLENGE) {
  684. ssh_proto_error(s->ppl.ssh, "Received unexpected packet"
  685. " in response to offer of public key, "
  686. "type %d (%s)", pktin->type,
  687. ssh1_pkt_type(pktin->type));
  688. return;
  689. }
  690. {
  691. int i;
  692. unsigned char buffer[32];
  693. Bignum challenge, response;
  694. challenge = get_mp_ssh1(pktin);
  695. if (get_err(pktin)) {
  696. freebn(challenge);
  697. ssh_proto_error(s->ppl.ssh, "Server's RSA challenge "
  698. "was badly formatted");
  699. return;
  700. }
  701. response = rsa_ssh1_decrypt(challenge, &s->key);
  702. freebn(s->key.private_exponent);/* burn the evidence */
  703. for (i = 0; i < 32; i++) {
  704. buffer[i] = bignum_byte(response, 31 - i);
  705. }
  706. {
  707. struct MD5Context md5c;
  708. MD5Init(&md5c);
  709. put_data(&md5c, buffer, 32);
  710. put_data(&md5c, s->session_id, 16);
  711. MD5Final(buffer, &md5c);
  712. }
  713. pkt = ssh_bpp_new_pktout(
  714. s->ppl.bpp, SSH1_CMSG_AUTH_RSA_RESPONSE);
  715. put_data(pkt, buffer, 16);
  716. pq_push(s->ppl.out_pq, pkt);
  717. freebn(challenge);
  718. freebn(response);
  719. }
  720. crMaybeWaitUntilV((pktin = ssh1_login_pop(s))
  721. != NULL);
  722. if (pktin->type == SSH1_SMSG_FAILURE) {
  723. if (flags & FLAG_VERBOSE)
  724. ppl_printf(("Failed to authenticate with"
  725. " our public key.\r\n"));
  726. continue; /* go and try something else */
  727. } else if (pktin->type != SSH1_SMSG_SUCCESS) {
  728. ssh_proto_error(s->ppl.ssh, "Received unexpected packet"
  729. " in response to RSA authentication, "
  730. "type %d (%s)", pktin->type,
  731. ssh1_pkt_type(pktin->type));
  732. return;
  733. }
  734. break; /* we're through! */
  735. }
  736. }
  737. /*
  738. * Otherwise, try various forms of password-like authentication.
  739. */
  740. s->cur_prompt = new_prompts(s->ppl.seat);
  741. if (conf_get_int(s->conf, CONF_try_tis_auth) &&
  742. (s->supported_auths_mask & (1 << SSH1_AUTH_TIS)) &&
  743. !s->tis_auth_refused) {
  744. s->pwpkt_type = SSH1_CMSG_AUTH_TIS_RESPONSE;
  745. ppl_logevent(("Requested TIS authentication"));
  746. pkt = ssh_bpp_new_pktout(s->ppl.bpp, SSH1_CMSG_AUTH_TIS);
  747. pq_push(s->ppl.out_pq, pkt);
  748. crMaybeWaitUntilV((pktin = ssh1_login_pop(s)) != NULL);
  749. if (pktin->type == SSH1_SMSG_FAILURE) {
  750. ppl_logevent(("TIS authentication declined"));
  751. if (flags & FLAG_INTERACTIVE)
  752. ppl_printf(("TIS authentication refused.\r\n"));
  753. s->tis_auth_refused = 1;
  754. continue;
  755. } else if (pktin->type == SSH1_SMSG_AUTH_TIS_CHALLENGE) {
  756. ptrlen challenge;
  757. char *instr_suf, *prompt;
  758. challenge = get_string(pktin);
  759. if (get_err(pktin)) {
  760. ssh_proto_error(s->ppl.ssh, "TIS challenge packet was "
  761. "badly formed");
  762. return;
  763. }
  764. ppl_logevent(("Received TIS challenge"));
  765. s->cur_prompt->to_server = TRUE;
  766. s->cur_prompt->name = dupstr("SSH TIS authentication");
  767. /* Prompt heuristic comes from OpenSSH */
  768. if (memchr(challenge.ptr, '\n', challenge.len)) {
  769. instr_suf = dupstr("");
  770. prompt = mkstr(challenge);
  771. } else {
  772. instr_suf = mkstr(challenge);
  773. prompt = dupstr("Response: ");
  774. }
  775. s->cur_prompt->instruction =
  776. dupprintf("Using TIS authentication.%s%s",
  777. (*instr_suf) ? "\n" : "",
  778. instr_suf);
  779. s->cur_prompt->instr_reqd = TRUE;
  780. add_prompt(s->cur_prompt, prompt, FALSE);
  781. sfree(instr_suf);
  782. } else {
  783. ssh_proto_error(s->ppl.ssh, "Received unexpected packet"
  784. " in response to TIS authentication, "
  785. "type %d (%s)", pktin->type,
  786. ssh1_pkt_type(pktin->type));
  787. return;
  788. }
  789. }
  790. if (conf_get_int(s->conf, CONF_try_tis_auth) &&
  791. (s->supported_auths_mask & (1 << SSH1_AUTH_CCARD)) &&
  792. !s->ccard_auth_refused) {
  793. s->pwpkt_type = SSH1_CMSG_AUTH_CCARD_RESPONSE;
  794. ppl_logevent(("Requested CryptoCard authentication"));
  795. pkt = ssh_bpp_new_pktout(s->ppl.bpp, SSH1_CMSG_AUTH_CCARD);
  796. pq_push(s->ppl.out_pq, pkt);
  797. crMaybeWaitUntilV((pktin = ssh1_login_pop(s)) != NULL);
  798. if (pktin->type == SSH1_SMSG_FAILURE) {
  799. ppl_logevent(("CryptoCard authentication declined"));
  800. ppl_printf(("CryptoCard authentication refused.\r\n"));
  801. s->ccard_auth_refused = 1;
  802. continue;
  803. } else if (pktin->type == SSH1_SMSG_AUTH_CCARD_CHALLENGE) {
  804. ptrlen challenge;
  805. char *instr_suf, *prompt;
  806. challenge = get_string(pktin);
  807. if (get_err(pktin)) {
  808. ssh_proto_error(s->ppl.ssh, "CryptoCard challenge packet "
  809. "was badly formed");
  810. return;
  811. }
  812. ppl_logevent(("Received CryptoCard challenge"));
  813. s->cur_prompt->to_server = TRUE;
  814. s->cur_prompt->name = dupstr("SSH CryptoCard authentication");
  815. s->cur_prompt->name_reqd = FALSE;
  816. /* Prompt heuristic comes from OpenSSH */
  817. if (memchr(challenge.ptr, '\n', challenge.len)) {
  818. instr_suf = dupstr("");
  819. prompt = mkstr(challenge);
  820. } else {
  821. instr_suf = mkstr(challenge);
  822. prompt = dupstr("Response: ");
  823. }
  824. s->cur_prompt->instruction =
  825. dupprintf("Using CryptoCard authentication.%s%s",
  826. (*instr_suf) ? "\n" : "",
  827. instr_suf);
  828. s->cur_prompt->instr_reqd = TRUE;
  829. add_prompt(s->cur_prompt, prompt, FALSE);
  830. sfree(instr_suf);
  831. } else {
  832. ssh_proto_error(s->ppl.ssh, "Received unexpected packet"
  833. " in response to TIS authentication, "
  834. "type %d (%s)", pktin->type,
  835. ssh1_pkt_type(pktin->type));
  836. return;
  837. }
  838. }
  839. if (s->pwpkt_type == SSH1_CMSG_AUTH_PASSWORD) {
  840. if ((s->supported_auths_mask & (1 << SSH1_AUTH_PASSWORD)) == 0) {
  841. ssh_sw_abort(s->ppl.ssh, "No supported authentication methods "
  842. "available");
  843. return;
  844. }
  845. s->cur_prompt->to_server = TRUE;
  846. s->cur_prompt->name = dupstr("SSH password");
  847. add_prompt(s->cur_prompt, dupprintf("%s@%s's password: ",
  848. s->username, s->savedhost),
  849. FALSE);
  850. }
  851. /*
  852. * Show password prompt, having first obtained it via a TIS
  853. * or CryptoCard exchange if we're doing TIS or CryptoCard
  854. * authentication.
  855. */
  856. s->userpass_ret = seat_get_userpass_input(
  857. s->ppl.seat, s->cur_prompt, NULL);
  858. while (1) {
  859. while (s->userpass_ret < 0 &&
  860. bufchain_size(s->ppl.user_input) > 0)
  861. s->userpass_ret = seat_get_userpass_input(
  862. s->ppl.seat, s->cur_prompt, s->ppl.user_input);
  863. if (s->userpass_ret >= 0)
  864. break;
  865. s->want_user_input = TRUE;
  866. crReturnV;
  867. s->want_user_input = FALSE;
  868. }
  869. if (!s->userpass_ret) {
  870. /*
  871. * Failed to get a password (for example
  872. * because one was supplied on the command line
  873. * which has already failed to work). Terminate.
  874. */
  875. ssh_user_close(s->ppl.ssh, "User aborted at password prompt");
  876. return;
  877. }
  878. if (s->pwpkt_type == SSH1_CMSG_AUTH_PASSWORD) {
  879. /*
  880. * Defence against traffic analysis: we send a
  881. * whole bunch of packets containing strings of
  882. * different lengths. One of these strings is the
  883. * password, in a SSH1_CMSG_AUTH_PASSWORD packet.
  884. * The others are all random data in
  885. * SSH1_MSG_IGNORE packets. This way a passive
  886. * listener can't tell which is the password, and
  887. * hence can't deduce the password length.
  888. *
  889. * Anybody with a password length greater than 16
  890. * bytes is going to have enough entropy in their
  891. * password that a listener won't find it _that_
  892. * much help to know how long it is. So what we'll
  893. * do is:
  894. *
  895. * - if password length < 16, we send 15 packets
  896. * containing string lengths 1 through 15
  897. *
  898. * - otherwise, we let N be the nearest multiple
  899. * of 8 below the password length, and send 8
  900. * packets containing string lengths N through
  901. * N+7. This won't obscure the order of
  902. * magnitude of the password length, but it will
  903. * introduce a bit of extra uncertainty.
  904. *
  905. * A few servers can't deal with SSH1_MSG_IGNORE, at
  906. * least in this context. For these servers, we need
  907. * an alternative defence. We make use of the fact
  908. * that the password is interpreted as a C string:
  909. * so we can append a NUL, then some random data.
  910. *
  911. * A few servers can deal with neither SSH1_MSG_IGNORE
  912. * here _nor_ a padded password string.
  913. * For these servers we are left with no defences
  914. * against password length sniffing.
  915. */
  916. if (!(s->ppl.remote_bugs & BUG_CHOKES_ON_SSH1_IGNORE) &&
  917. !(s->ppl.remote_bugs & BUG_NEEDS_SSH1_PLAIN_PASSWORD)) {
  918. /*
  919. * The server can deal with SSH1_MSG_IGNORE, so
  920. * we can use the primary defence.
  921. */
  922. int bottom, top, pwlen, i;
  923. pwlen = strlen(s->cur_prompt->prompts[0]->result);
  924. if (pwlen < 16) {
  925. bottom = 0; /* zero length passwords are OK! :-) */
  926. top = 15;
  927. } else {
  928. bottom = pwlen & ~7;
  929. top = bottom + 7;
  930. }
  931. assert(pwlen >= bottom && pwlen <= top);
  932. for (i = bottom; i <= top; i++) {
  933. if (i == pwlen) {
  934. pkt = ssh_bpp_new_pktout(s->ppl.bpp, s->pwpkt_type);
  935. put_stringz(pkt, s->cur_prompt->prompts[0]->result);
  936. pq_push(s->ppl.out_pq, pkt);
  937. } else {
  938. int j;
  939. strbuf *random_data = strbuf_new();
  940. for (j = 0; j < i; j++)
  941. put_byte(random_data, random_byte());
  942. pkt = ssh_bpp_new_pktout(s->ppl.bpp, SSH1_MSG_IGNORE);
  943. put_stringsb(pkt, random_data);
  944. pq_push(s->ppl.out_pq, pkt);
  945. }
  946. }
  947. ppl_logevent(("Sending password with camouflage packets"));
  948. }
  949. else if (!(s->ppl.remote_bugs & BUG_NEEDS_SSH1_PLAIN_PASSWORD)) {
  950. /*
  951. * The server can't deal with SSH1_MSG_IGNORE
  952. * but can deal with padded passwords, so we
  953. * can use the secondary defence.
  954. */
  955. strbuf *padded_pw = strbuf_new();
  956. ppl_logevent(("Sending length-padded password"));
  957. pkt = ssh_bpp_new_pktout(s->ppl.bpp, s->pwpkt_type);
  958. put_asciz(padded_pw, s->cur_prompt->prompts[0]->result);
  959. do {
  960. put_byte(padded_pw, random_byte());
  961. } while (padded_pw->len % 64 != 0);
  962. put_stringsb(pkt, padded_pw);
  963. pq_push(s->ppl.out_pq, pkt);
  964. } else {
  965. /*
  966. * The server is believed unable to cope with
  967. * any of our password camouflage methods.
  968. */
  969. ppl_logevent(("Sending unpadded password"));
  970. pkt = ssh_bpp_new_pktout(s->ppl.bpp, s->pwpkt_type);
  971. put_stringz(pkt, s->cur_prompt->prompts[0]->result);
  972. pq_push(s->ppl.out_pq, pkt);
  973. }
  974. } else {
  975. pkt = ssh_bpp_new_pktout(s->ppl.bpp, s->pwpkt_type);
  976. put_stringz(pkt, s->cur_prompt->prompts[0]->result);
  977. pq_push(s->ppl.out_pq, pkt);
  978. }
  979. ppl_logevent(("Sent password"));
  980. free_prompts(s->cur_prompt);
  981. s->cur_prompt = NULL;
  982. crMaybeWaitUntilV((pktin = ssh1_login_pop(s)) != NULL);
  983. if (pktin->type == SSH1_SMSG_FAILURE) {
  984. if (flags & FLAG_VERBOSE)
  985. ppl_printf(("Access denied\r\n"));
  986. ppl_logevent(("Authentication refused"));
  987. } else if (pktin->type != SSH1_SMSG_SUCCESS) {
  988. ssh_proto_error(s->ppl.ssh, "Received unexpected packet"
  989. " in response to password authentication, type %d "
  990. "(%s)", pktin->type, ssh1_pkt_type(pktin->type));
  991. return;
  992. }
  993. }
  994. ppl_logevent(("Authentication successful"));
  995. if (conf_get_int(s->conf, CONF_compression)) {
  996. ppl_logevent(("Requesting compression"));
  997. pkt = ssh_bpp_new_pktout(s->ppl.bpp, SSH1_CMSG_REQUEST_COMPRESSION);
  998. put_uint32(pkt, 6); /* gzip compression level */
  999. pq_push(s->ppl.out_pq, pkt);
  1000. crMaybeWaitUntilV((pktin = ssh1_login_pop(s)) != NULL);
  1001. if (pktin->type == SSH1_SMSG_SUCCESS) {
  1002. /*
  1003. * We don't have to actually do anything here: the SSH-1
  1004. * BPP will take care of automatically starting the
  1005. * compression, by recognising our outgoing request packet
  1006. * and the success response. (Horrible, but it's the
  1007. * easiest way to avoid race conditions if other packets
  1008. * cross in transit.)
  1009. */
  1010. } else if (pktin->type == SSH1_SMSG_FAILURE) {
  1011. ppl_logevent(("Server refused to enable compression"));
  1012. ppl_printf(("Server refused to compress\r\n"));
  1013. } else {
  1014. ssh_proto_error(s->ppl.ssh, "Received unexpected packet"
  1015. " in response to compression request, type %d "
  1016. "(%s)", pktin->type, ssh1_pkt_type(pktin->type));
  1017. return;
  1018. }
  1019. }
  1020. ssh1_connection_set_local_protoflags(
  1021. s->successor_layer, s->local_protoflags);
  1022. {
  1023. PacketProtocolLayer *successor = s->successor_layer;
  1024. s->successor_layer = NULL; /* avoid freeing it ourself */
  1025. ssh_ppl_replace(&s->ppl, successor);
  1026. return; /* we've just freed s, so avoid even touching s->crState */
  1027. }
  1028. crFinishV;
  1029. }
  1030. static void ssh1_login_dialog_callback(void *loginv, int ret)
  1031. {
  1032. struct ssh1_login_state *s = (struct ssh1_login_state *)loginv;
  1033. s->dlgret = ret;
  1034. ssh_ppl_process_queue(&s->ppl);
  1035. }
  1036. static void ssh1_login_agent_query(struct ssh1_login_state *s, strbuf *req)
  1037. {
  1038. void *response;
  1039. int response_len;
  1040. sfree(s->agent_response_to_free);
  1041. s->agent_response_to_free = NULL;
  1042. s->auth_agent_query = agent_query(req, &response, &response_len,
  1043. ssh1_login_agent_callback, s);
  1044. if (!s->auth_agent_query)
  1045. ssh1_login_agent_callback(s, response, response_len);
  1046. }
  1047. static void ssh1_login_agent_callback(void *loginv, void *reply, int replylen)
  1048. {
  1049. struct ssh1_login_state *s = (struct ssh1_login_state *)loginv;
  1050. s->auth_agent_query = NULL;
  1051. s->agent_response_to_free = reply;
  1052. s->agent_response = make_ptrlen(reply, replylen);
  1053. queue_idempotent_callback(&s->ppl.ic_process_queue);
  1054. }
  1055. static void ssh1_login_special_cmd(PacketProtocolLayer *ppl,
  1056. SessionSpecialCode code, int arg)
  1057. {
  1058. struct ssh1_login_state *s =
  1059. container_of(ppl, struct ssh1_login_state, ppl);
  1060. PktOut *pktout;
  1061. if (code == SS_PING || code == SS_NOP) {
  1062. if (!(s->ppl.remote_bugs & BUG_CHOKES_ON_SSH1_IGNORE)) {
  1063. pktout = ssh_bpp_new_pktout(s->ppl.bpp, SSH1_MSG_IGNORE);
  1064. put_stringz(pktout, "");
  1065. pq_push(s->ppl.out_pq, pktout);
  1066. }
  1067. }
  1068. }
  1069. static int ssh1_login_want_user_input(PacketProtocolLayer *ppl)
  1070. {
  1071. struct ssh1_login_state *s =
  1072. container_of(ppl, struct ssh1_login_state, ppl);
  1073. return s->want_user_input;
  1074. }
  1075. static void ssh1_login_got_user_input(PacketProtocolLayer *ppl)
  1076. {
  1077. struct ssh1_login_state *s =
  1078. container_of(ppl, struct ssh1_login_state, ppl);
  1079. if (s->want_user_input)
  1080. queue_idempotent_callback(&s->ppl.ic_process_queue);
  1081. }
  1082. static void ssh1_login_reconfigure(PacketProtocolLayer *ppl, Conf *conf)
  1083. {
  1084. struct ssh1_login_state *s =
  1085. container_of(ppl, struct ssh1_login_state, ppl);
  1086. ssh_ppl_reconfigure(s->successor_layer, conf);
  1087. }