ssh1login.c 46 KB

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