ssh1connection-client.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558
  1. /*
  2. * Client-specific parts of the SSH-1 connection layer.
  3. */
  4. #include <assert.h>
  5. #include "putty.h"
  6. #include "ssh.h"
  7. #include "sshbpp.h"
  8. #include "sshppl.h"
  9. #include "sshchan.h"
  10. #include "sshcr.h"
  11. #include "ssh1connection.h"
  12. // WINSCP
  13. #define queue_toplevel_callback(FN, CTX) queue_toplevel_callback(get_log_callback_set(CTX->cl.logctx), FN, CTX)
  14. void ssh1_connection_direction_specific_setup(
  15. struct ssh1_connection_state *s)
  16. {
  17. if (!s->mainchan) {
  18. /*
  19. * Start up the main session, by telling mainchan.c to do it
  20. * all just as it would in SSH-2, and translating those
  21. * concepts to SSH-1's non-channel-shaped idea of the main
  22. * session.
  23. */
  24. s->mainchan = mainchan_new(
  25. &s->ppl, &s->cl, s->conf, s->term_width, s->term_height,
  26. false /* is_simple */, NULL);
  27. }
  28. }
  29. typedef void (*sf_handler_fn_t)(struct ssh1_connection_state *s,
  30. bool success, void *ctx);
  31. struct outstanding_succfail {
  32. sf_handler_fn_t handler;
  33. void *ctx;
  34. struct outstanding_succfail *next;
  35. /*
  36. * The 'trivial' flag is set if this handler is in response to a
  37. * request for which the SSH-1 protocol doesn't actually specify a
  38. * response packet. The client of this system (mainchan.c) will
  39. * expect to get an acknowledgment regardless, so we arrange to
  40. * send that ack immediately after the rest of the queue empties.
  41. */
  42. bool trivial;
  43. };
  44. static void ssh1_connection_process_trivial_succfails(void *vs);
  45. static void ssh1_queue_succfail_handler(
  46. struct ssh1_connection_state *s, sf_handler_fn_t handler, void *ctx,
  47. bool trivial)
  48. {
  49. struct outstanding_succfail *osf = snew(struct outstanding_succfail);
  50. osf->handler = handler;
  51. osf->ctx = ctx;
  52. osf->trivial = trivial;
  53. osf->next = NULL;
  54. if (s->succfail_tail)
  55. s->succfail_tail->next = osf;
  56. else
  57. s->succfail_head = osf;
  58. s->succfail_tail = osf;
  59. /* In case this one was trivial and the queue was already empty,
  60. * we should make sure we run the handler promptly, and the
  61. * easiest way is to queue it anyway and then run a trivials pass
  62. * by callback. */
  63. queue_toplevel_callback(ssh1_connection_process_trivial_succfails, s);
  64. }
  65. static void ssh1_connection_process_succfail(
  66. struct ssh1_connection_state *s, bool success)
  67. {
  68. struct outstanding_succfail *prevhead = s->succfail_head;
  69. s->succfail_head = s->succfail_head->next;
  70. if (!s->succfail_head)
  71. s->succfail_tail = NULL;
  72. prevhead->handler(s, success, prevhead->ctx);
  73. sfree(prevhead);
  74. }
  75. static void ssh1_connection_process_trivial_succfails(void *vs)
  76. {
  77. struct ssh1_connection_state *s = (struct ssh1_connection_state *)vs;
  78. while (s->succfail_head && s->succfail_head->trivial)
  79. ssh1_connection_process_succfail(s, true);
  80. }
  81. bool ssh1_handle_direction_specific_packet(
  82. struct ssh1_connection_state *s, PktIn *pktin)
  83. {
  84. PacketProtocolLayer *ppl = &s->ppl; /* for ppl_logevent */
  85. PktOut *pktout;
  86. struct ssh1_channel *c;
  87. unsigned remid;
  88. struct ssh_rportfwd pf, *pfp;
  89. ptrlen host, data;
  90. int port;
  91. switch (pktin->type) {
  92. case SSH1_SMSG_SUCCESS:
  93. case SSH1_SMSG_FAILURE:
  94. if (!s->succfail_head) {
  95. ssh_remote_error(s->ppl.ssh,
  96. "Received %s with no outstanding request",
  97. ssh1_pkt_type(pktin->type));
  98. return true;
  99. }
  100. ssh1_connection_process_succfail(
  101. s, pktin->type == SSH1_SMSG_SUCCESS);
  102. queue_toplevel_callback(
  103. ssh1_connection_process_trivial_succfails, s);
  104. return true;
  105. case SSH1_SMSG_X11_OPEN:
  106. remid = get_uint32(pktin);
  107. /* Refuse if X11 forwarding is disabled. */
  108. if (!s->X11_fwd_enabled) {
  109. pktout = ssh_bpp_new_pktout(
  110. s->ppl.bpp, SSH1_MSG_CHANNEL_OPEN_FAILURE);
  111. put_uint32(pktout, remid);
  112. pq_push(s->ppl.out_pq, pktout);
  113. ppl_logevent("Rejected X11 connect request");
  114. } else {
  115. c = snew(struct ssh1_channel);
  116. c->connlayer = s;
  117. ssh1_channel_init(c);
  118. c->remoteid = remid;
  119. c->chan = x11_new_channel(s->x11authtree, &c->sc,
  120. NULL, -1, false);
  121. c->remoteid = remid;
  122. c->halfopen = false;
  123. pktout = ssh_bpp_new_pktout(
  124. s->ppl.bpp, SSH1_MSG_CHANNEL_OPEN_CONFIRMATION);
  125. put_uint32(pktout, c->remoteid);
  126. put_uint32(pktout, c->localid);
  127. pq_push(s->ppl.out_pq, pktout);
  128. ppl_logevent("Opened X11 forward channel");
  129. }
  130. return true;
  131. case SSH1_SMSG_AGENT_OPEN:
  132. remid = get_uint32(pktin);
  133. /* Refuse if agent forwarding is disabled. */
  134. if (!ssh_agent_forwarding_permitted(&s->cl)) {
  135. pktout = ssh_bpp_new_pktout(
  136. s->ppl.bpp, SSH1_MSG_CHANNEL_OPEN_FAILURE);
  137. put_uint32(pktout, remid);
  138. pq_push(s->ppl.out_pq, pktout);
  139. } else {
  140. c = snew(struct ssh1_channel);
  141. c->connlayer = s;
  142. ssh1_channel_init(c);
  143. c->remoteid = remid;
  144. c->halfopen = false;
  145. /*
  146. * If possible, make a stream-oriented connection to the
  147. * agent and set up an ordinary port-forwarding type
  148. * channel over it.
  149. */
  150. { // WINSCP
  151. Plug *plug;
  152. Channel *ch = portfwd_raw_new(&s->cl, &plug, true);
  153. Socket *skt = agent_connect(plug);
  154. if (!sk_socket_error(skt)) {
  155. portfwd_raw_setup(ch, skt, &c->sc);
  156. c->chan = ch;
  157. } else {
  158. portfwd_raw_free(ch);
  159. /*
  160. * Otherwise, fall back to the old-fashioned system of
  161. * parsing the forwarded data stream ourselves for
  162. * message boundaries, and passing each individual
  163. * message to the one-off agent_query().
  164. */
  165. c->chan = agentf_new(&c->sc);
  166. }
  167. pktout = ssh_bpp_new_pktout(
  168. s->ppl.bpp, SSH1_MSG_CHANNEL_OPEN_CONFIRMATION);
  169. put_uint32(pktout, c->remoteid);
  170. put_uint32(pktout, c->localid);
  171. pq_push(s->ppl.out_pq, pktout);
  172. } // WINSCP
  173. }
  174. return true;
  175. case SSH1_MSG_PORT_OPEN:
  176. remid = get_uint32(pktin);
  177. host = get_string(pktin);
  178. port = toint(get_uint32(pktin));
  179. pf.dhost = mkstr(host);
  180. pf.dport = port;
  181. pfp = find234(s->rportfwds, &pf, NULL);
  182. if (!pfp) {
  183. ppl_logevent("Rejected remote port open request for %s:%d",
  184. pf.dhost, port);
  185. pktout = ssh_bpp_new_pktout(
  186. s->ppl.bpp, SSH1_MSG_CHANNEL_OPEN_FAILURE);
  187. put_uint32(pktout, remid);
  188. pq_push(s->ppl.out_pq, pktout);
  189. } else {
  190. char *err;
  191. c = snew(struct ssh1_channel);
  192. c->connlayer = s;
  193. ppl_logevent("Received remote port open request for %s:%d",
  194. pf.dhost, port);
  195. err = portfwdmgr_connect(
  196. s->portfwdmgr, &c->chan, pf.dhost, port,
  197. &c->sc, pfp->addressfamily);
  198. if (err) {
  199. ppl_logevent("Port open failed: %s", err);
  200. sfree(err);
  201. ssh1_channel_free(c);
  202. pktout = ssh_bpp_new_pktout(
  203. s->ppl.bpp, SSH1_MSG_CHANNEL_OPEN_FAILURE);
  204. put_uint32(pktout, remid);
  205. pq_push(s->ppl.out_pq, pktout);
  206. } else {
  207. ssh1_channel_init(c);
  208. c->remoteid = remid;
  209. c->halfopen = false;
  210. pktout = ssh_bpp_new_pktout(
  211. s->ppl.bpp, SSH1_MSG_CHANNEL_OPEN_CONFIRMATION);
  212. put_uint32(pktout, c->remoteid);
  213. put_uint32(pktout, c->localid);
  214. pq_push(s->ppl.out_pq, pktout);
  215. ppl_logevent("Forwarded port opened successfully");
  216. }
  217. }
  218. sfree(pf.dhost);
  219. return true;
  220. case SSH1_SMSG_STDOUT_DATA:
  221. case SSH1_SMSG_STDERR_DATA:
  222. data = get_string(pktin);
  223. if (!get_err(pktin)) {
  224. int bufsize = seat_output(
  225. s->ppl.seat, pktin->type == SSH1_SMSG_STDERR_DATA,
  226. data.ptr, data.len);
  227. if (!s->stdout_throttling && bufsize > SSH1_BUFFER_LIMIT) {
  228. s->stdout_throttling = true;
  229. ssh_throttle_conn(s->ppl.ssh, +1);
  230. }
  231. }
  232. return true;
  233. case SSH1_SMSG_EXIT_STATUS: {
  234. int exitcode = get_uint32(pktin);
  235. ppl_logevent("Server sent command exit status %d", exitcode);
  236. ssh_got_exitcode(s->ppl.ssh, exitcode);
  237. s->session_terminated = true;
  238. return true;
  239. }
  240. default:
  241. return false;
  242. }
  243. }
  244. static void ssh1mainchan_succfail_wantreply(struct ssh1_connection_state *s,
  245. bool success, void *ctx)
  246. {
  247. chan_request_response(s->mainchan_chan, success);
  248. }
  249. static void ssh1mainchan_succfail_nowantreply(struct ssh1_connection_state *s,
  250. bool success, void *ctx)
  251. {
  252. }
  253. static void ssh1mainchan_queue_response(struct ssh1_connection_state *s,
  254. bool want_reply, bool trivial)
  255. {
  256. sf_handler_fn_t handler = (want_reply ? ssh1mainchan_succfail_wantreply :
  257. ssh1mainchan_succfail_nowantreply);
  258. ssh1_queue_succfail_handler(s, handler, NULL, trivial);
  259. }
  260. static void ssh1mainchan_request_x11_forwarding(
  261. SshChannel *sc, bool want_reply, const char *authproto,
  262. const char *authdata, int screen_number, bool oneshot)
  263. {
  264. struct ssh1_connection_state *s =
  265. container_of(sc, struct ssh1_connection_state, mainchan_sc);
  266. PktOut *pktout;
  267. pktout = ssh_bpp_new_pktout(s->ppl.bpp, SSH1_CMSG_X11_REQUEST_FORWARDING);
  268. put_stringz(pktout, authproto);
  269. put_stringz(pktout, authdata);
  270. if (s->local_protoflags & SSH1_PROTOFLAG_SCREEN_NUMBER)
  271. put_uint32(pktout, screen_number);
  272. pq_push(s->ppl.out_pq, pktout);
  273. ssh1mainchan_queue_response(s, want_reply, false);
  274. }
  275. static void ssh1mainchan_request_agent_forwarding(
  276. SshChannel *sc, bool want_reply)
  277. {
  278. struct ssh1_connection_state *s =
  279. container_of(sc, struct ssh1_connection_state, mainchan_sc);
  280. PktOut *pktout;
  281. pktout = ssh_bpp_new_pktout(
  282. s->ppl.bpp, SSH1_CMSG_AGENT_REQUEST_FORWARDING);
  283. pq_push(s->ppl.out_pq, pktout);
  284. ssh1mainchan_queue_response(s, want_reply, false);
  285. }
  286. static void ssh1mainchan_request_pty(
  287. SshChannel *sc, bool want_reply, Conf *conf, int w, int h)
  288. {
  289. struct ssh1_connection_state *s =
  290. container_of(sc, struct ssh1_connection_state, mainchan_sc);
  291. PktOut *pktout;
  292. pktout = ssh_bpp_new_pktout(s->ppl.bpp, SSH1_CMSG_REQUEST_PTY);
  293. put_stringz(pktout, conf_get_str(s->conf, CONF_termtype));
  294. put_uint32(pktout, h);
  295. put_uint32(pktout, w);
  296. put_uint32(pktout, 0); /* width in pixels */
  297. put_uint32(pktout, 0); /* height in pixels */
  298. write_ttymodes_to_packet(
  299. BinarySink_UPCAST(pktout), 1,
  300. get_ttymodes_from_conf(s->ppl.seat, conf));
  301. pq_push(s->ppl.out_pq, pktout);
  302. ssh1mainchan_queue_response(s, want_reply, false);
  303. }
  304. static bool ssh1mainchan_send_env_var(
  305. SshChannel *sc, bool want_reply, const char *var, const char *value)
  306. {
  307. return false; /* SSH-1 doesn't support this at all */
  308. }
  309. static void ssh1mainchan_start_shell(SshChannel *sc, bool want_reply)
  310. {
  311. struct ssh1_connection_state *s =
  312. container_of(sc, struct ssh1_connection_state, mainchan_sc);
  313. PktOut *pktout;
  314. pktout = ssh_bpp_new_pktout(s->ppl.bpp, SSH1_CMSG_EXEC_SHELL);
  315. pq_push(s->ppl.out_pq, pktout);
  316. ssh1mainchan_queue_response(s, want_reply, true);
  317. }
  318. static void ssh1mainchan_start_command(
  319. SshChannel *sc, bool want_reply, const char *command)
  320. {
  321. struct ssh1_connection_state *s =
  322. container_of(sc, struct ssh1_connection_state, mainchan_sc);
  323. PktOut *pktout;
  324. pktout = ssh_bpp_new_pktout(s->ppl.bpp, SSH1_CMSG_EXEC_CMD);
  325. put_stringz(pktout, command);
  326. pq_push(s->ppl.out_pq, pktout);
  327. ssh1mainchan_queue_response(s, want_reply, true);
  328. }
  329. static bool ssh1mainchan_start_subsystem(
  330. SshChannel *sc, bool want_reply, const char *subsystem)
  331. {
  332. return false; /* SSH-1 doesn't support this at all */
  333. }
  334. static bool ssh1mainchan_send_serial_break(
  335. SshChannel *sc, bool want_reply, int length)
  336. {
  337. return false; /* SSH-1 doesn't support this at all */
  338. }
  339. static bool ssh1mainchan_send_signal(
  340. SshChannel *sc, bool want_reply, const char *signame)
  341. {
  342. return false; /* SSH-1 doesn't support this at all */
  343. }
  344. static void ssh1mainchan_send_terminal_size_change(
  345. SshChannel *sc, int w, int h)
  346. {
  347. struct ssh1_connection_state *s =
  348. container_of(sc, struct ssh1_connection_state, mainchan_sc);
  349. PktOut *pktout;
  350. pktout = ssh_bpp_new_pktout(s->ppl.bpp, SSH1_CMSG_WINDOW_SIZE);
  351. put_uint32(pktout, h);
  352. put_uint32(pktout, w);
  353. put_uint32(pktout, 0); /* width in pixels */
  354. put_uint32(pktout, 0); /* height in pixels */
  355. pq_push(s->ppl.out_pq, pktout);
  356. }
  357. static void ssh1mainchan_hint_channel_is_simple(SshChannel *sc)
  358. {
  359. }
  360. static size_t ssh1mainchan_write(
  361. SshChannel *sc, bool is_stderr, const void *data, size_t len)
  362. {
  363. struct ssh1_connection_state *s =
  364. container_of(sc, struct ssh1_connection_state, mainchan_sc);
  365. PktOut *pktout;
  366. pktout = ssh_bpp_new_pktout(s->ppl.bpp, SSH1_CMSG_STDIN_DATA);
  367. put_string(pktout, data, len);
  368. pq_push(s->ppl.out_pq, pktout);
  369. return 0;
  370. }
  371. static void ssh1mainchan_write_eof(SshChannel *sc)
  372. {
  373. struct ssh1_connection_state *s =
  374. container_of(sc, struct ssh1_connection_state, mainchan_sc);
  375. PktOut *pktout;
  376. pktout = ssh_bpp_new_pktout(s->ppl.bpp, SSH1_CMSG_EOF);
  377. pq_push(s->ppl.out_pq, pktout);
  378. }
  379. static const SshChannelVtable ssh1mainchan_vtable = {
  380. // WINSCP
  381. /*.write =*/ ssh1mainchan_write,
  382. /*.write_eof =*/ ssh1mainchan_write_eof,
  383. NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, // WINSCP
  384. /*.request_x11_forwarding =*/ ssh1mainchan_request_x11_forwarding,
  385. /*.request_agent_forwarding =*/ ssh1mainchan_request_agent_forwarding,
  386. /*.request_pty =*/ ssh1mainchan_request_pty,
  387. /*.send_env_var =*/ ssh1mainchan_send_env_var,
  388. /*.start_shell =*/ ssh1mainchan_start_shell,
  389. /*.start_command =*/ ssh1mainchan_start_command,
  390. /*.start_subsystem =*/ ssh1mainchan_start_subsystem,
  391. /*.send_serial_break =*/ ssh1mainchan_send_serial_break,
  392. /*.send_signal =*/ ssh1mainchan_send_signal,
  393. /*.send_terminal_size_change =*/ ssh1mainchan_send_terminal_size_change,
  394. /*.hint_channel_is_simple =*/ ssh1mainchan_hint_channel_is_simple,
  395. /* other methods are NULL */
  396. };
  397. static void ssh1_session_confirm_callback(void *vctx)
  398. {
  399. struct ssh1_connection_state *s = (struct ssh1_connection_state *)vctx;
  400. chan_open_confirmation(s->mainchan_chan);
  401. }
  402. SshChannel *ssh1_session_open(ConnectionLayer *cl, Channel *chan)
  403. {
  404. struct ssh1_connection_state *s =
  405. container_of(cl, struct ssh1_connection_state, cl);
  406. s->mainchan_sc.vt = &ssh1mainchan_vtable;
  407. s->mainchan_sc.cl = &s->cl;
  408. s->mainchan_chan = chan;
  409. queue_toplevel_callback(ssh1_session_confirm_callback, s);
  410. return &s->mainchan_sc;
  411. }
  412. static void ssh1_rportfwd_response(struct ssh1_connection_state *s,
  413. bool success, void *ctx)
  414. {
  415. PacketProtocolLayer *ppl = &s->ppl; /* for ppl_logevent */
  416. struct ssh_rportfwd *rpf = (struct ssh_rportfwd *)ctx;
  417. if (success) {
  418. ppl_logevent("Remote port forwarding from %s enabled",
  419. rpf->log_description);
  420. } else {
  421. ppl_logevent("Remote port forwarding from %s refused",
  422. rpf->log_description);
  423. { // WINSCP
  424. struct ssh_rportfwd *realpf = del234(s->rportfwds, rpf);
  425. assert(realpf == rpf);
  426. portfwdmgr_close(s->portfwdmgr, rpf->pfr);
  427. free_rportfwd(rpf);
  428. } // WINSCP
  429. }
  430. }
  431. struct ssh_rportfwd *ssh1_rportfwd_alloc(
  432. ConnectionLayer *cl,
  433. const char *shost, int sport, const char *dhost, int dport,
  434. int addressfamily, const char *log_description, PortFwdRecord *pfr,
  435. ssh_sharing_connstate *share_ctx)
  436. {
  437. struct ssh1_connection_state *s =
  438. container_of(cl, struct ssh1_connection_state, cl);
  439. struct ssh_rportfwd *rpf = snew(struct ssh_rportfwd);
  440. rpf->shost = dupstr(shost);
  441. rpf->sport = sport;
  442. rpf->dhost = dupstr(dhost);
  443. rpf->dport = dport;
  444. rpf->addressfamily = addressfamily;
  445. rpf->log_description = dupstr(log_description);
  446. rpf->pfr = pfr;
  447. if (add234(s->rportfwds, rpf) != rpf) {
  448. free_rportfwd(rpf);
  449. return NULL;
  450. }
  451. { // WINSCP
  452. PktOut *pktout = ssh_bpp_new_pktout(
  453. s->ppl.bpp, SSH1_CMSG_PORT_FORWARD_REQUEST);
  454. put_uint32(pktout, rpf->sport);
  455. put_stringz(pktout, rpf->dhost);
  456. put_uint32(pktout, rpf->dport);
  457. pq_push(s->ppl.out_pq, pktout);
  458. } // WINSCP
  459. ssh1_queue_succfail_handler(s, ssh1_rportfwd_response, rpf, false);
  460. return rpf;
  461. }
  462. SshChannel *ssh1_serverside_x11_open(
  463. ConnectionLayer *cl, Channel *chan, const SocketPeerInfo *pi)
  464. {
  465. unreachable("Should never be called in the client");
  466. }
  467. SshChannel *ssh1_serverside_agent_open(ConnectionLayer *cl, Channel *chan)
  468. {
  469. unreachable("Should never be called in the client");
  470. }
  471. bool ssh1_connection_need_antispoof_prompt(struct ssh1_connection_state *s)
  472. {
  473. return !seat_set_trust_status(s->ppl.seat, false);
  474. }