ssh1login.c 47 KB

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