ssh1login.c 46 KB

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