ssh1login.c 48 KB

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