connection1-client.c 17 KB

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