ssh1login.c 46 KB

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