ssh1login.c 47 KB

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