mainchan.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560
  1. /*
  2. * SSH main session channel handling.
  3. */
  4. #include <assert.h>
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include "putty.h"
  8. #include "ssh.h"
  9. #include "sshppl.h"
  10. #include "sshchan.h"
  11. static void mainchan_free(Channel *chan);
  12. static void mainchan_open_confirmation(Channel *chan);
  13. static void mainchan_open_failure(Channel *chan, const char *errtext);
  14. static int mainchan_send(Channel *chan, int is_stderr, const void *, int);
  15. static void mainchan_send_eof(Channel *chan);
  16. static void mainchan_set_input_wanted(Channel *chan, int wanted);
  17. static char *mainchan_log_close_msg(Channel *chan);
  18. static int mainchan_rcvd_exit_status(Channel *chan, int status);
  19. static int mainchan_rcvd_exit_signal(
  20. Channel *chan, ptrlen signame, int core_dumped, ptrlen msg);
  21. static int mainchan_rcvd_exit_signal_numeric(
  22. Channel *chan, int signum, int core_dumped, ptrlen msg);
  23. static void mainchan_request_response(Channel *chan, int success);
  24. static const struct ChannelVtable mainchan_channelvt = {
  25. mainchan_free,
  26. mainchan_open_confirmation,
  27. mainchan_open_failure,
  28. mainchan_send,
  29. mainchan_send_eof,
  30. mainchan_set_input_wanted,
  31. mainchan_log_close_msg,
  32. chan_default_want_close,
  33. mainchan_rcvd_exit_status,
  34. mainchan_rcvd_exit_signal,
  35. mainchan_rcvd_exit_signal_numeric,
  36. chan_no_run_shell,
  37. chan_no_run_command,
  38. chan_no_run_subsystem,
  39. chan_no_enable_x11_forwarding,
  40. chan_no_enable_agent_forwarding,
  41. chan_no_allocate_pty,
  42. chan_no_set_env,
  43. chan_no_send_break,
  44. chan_no_send_signal,
  45. chan_no_change_window_size,
  46. mainchan_request_response,
  47. };
  48. typedef enum MainChanType {
  49. MAINCHAN_SESSION, MAINCHAN_DIRECT_TCPIP
  50. } MainChanType;
  51. typedef struct mainchan {
  52. SshChannel *sc;
  53. Conf *conf;
  54. PacketProtocolLayer *ppl;
  55. ConnectionLayer *cl;
  56. MainChanType type;
  57. int is_simple;
  58. int req_x11, req_agent, req_pty, req_cmd_primary, req_cmd_fallback;
  59. int n_req_env, n_env_replies, n_env_fails;
  60. int eof_pending, eof_sent, got_pty, ready;
  61. int term_width, term_height;
  62. Channel chan;
  63. } mainchan;
  64. mainchan *mainchan_new(
  65. PacketProtocolLayer *ppl, ConnectionLayer *cl, Conf *conf,
  66. int term_width, int term_height, int is_simple, SshChannel **sc_out)
  67. {
  68. mainchan *mc;
  69. if (conf_get_int(conf, CONF_ssh_no_shell))
  70. return NULL; /* no main channel at all */
  71. mc = snew(mainchan);
  72. memset(mc, 0, sizeof(mainchan));
  73. mc->ppl = ppl;
  74. mc->cl = cl;
  75. mc->conf = conf_copy(conf);
  76. mc->term_width = term_width;
  77. mc->term_height = term_height;
  78. mc->is_simple = is_simple;
  79. mc->sc = NULL;
  80. mc->chan.vt = &mainchan_channelvt;
  81. mc->chan.initial_fixed_window_size = 0;
  82. if (*conf_get_str(mc->conf, CONF_ssh_nc_host)) {
  83. const char *host = conf_get_str(mc->conf, CONF_ssh_nc_host);
  84. int port = conf_get_int(mc->conf, CONF_ssh_nc_port);
  85. mc->sc = ssh_lportfwd_open(cl, host, port, "main channel",
  86. NULL, &mc->chan);
  87. mc->type = MAINCHAN_DIRECT_TCPIP;
  88. } else {
  89. mc->sc = ssh_session_open(cl, &mc->chan);
  90. mc->type = MAINCHAN_SESSION;
  91. }
  92. if (sc_out) *sc_out = mc->sc;
  93. return mc;
  94. }
  95. static void mainchan_free(Channel *chan)
  96. {
  97. pinitassert(chan->vt == &mainchan_channelvt);
  98. mainchan *mc = container_of(chan, mainchan, chan);
  99. conf_free(mc->conf);
  100. sfree(mc);
  101. }
  102. static void mainchan_try_fallback_command(mainchan *mc);
  103. static void mainchan_ready(mainchan *mc);
  104. static void mainchan_open_confirmation(Channel *chan)
  105. {
  106. mainchan *mc = container_of(chan, mainchan, chan);
  107. PacketProtocolLayer *ppl = mc->ppl; /* for ppl_logevent */
  108. seat_update_specials_menu(mc->ppl->seat);
  109. ppl_logevent(("Opened main channel"));
  110. if (mc->is_simple)
  111. sshfwd_hint_channel_is_simple(mc->sc);
  112. if (mc->type == MAINCHAN_SESSION) {
  113. /*
  114. * Send the CHANNEL_REQUESTS for the main session channel.
  115. */
  116. char *key, *val, *cmd;
  117. struct X11Display *x11disp;
  118. struct X11FakeAuth *x11auth;
  119. int retry_cmd_now = FALSE;
  120. if (conf_get_int(mc->conf, CONF_x11_forward)) {
  121. char *x11_setup_err;
  122. if ((x11disp = x11_setup_display(
  123. conf_get_str(mc->conf, CONF_x11_display),
  124. mc->conf, &x11_setup_err)) == NULL) {
  125. ppl_logevent(("X11 forwarding not enabled: unable to"
  126. " initialise X display: %s", x11_setup_err));
  127. sfree(x11_setup_err);
  128. } else {
  129. x11auth = ssh_add_x11_display(
  130. mc->cl, conf_get_int(mc->conf, CONF_x11_auth), x11disp);
  131. sshfwd_request_x11_forwarding(
  132. mc->sc, TRUE, x11auth->protoname, x11auth->datastring,
  133. x11disp->screennum, FALSE);
  134. mc->req_x11 = TRUE;
  135. }
  136. }
  137. if (ssh_agent_forwarding_permitted(mc->cl)) {
  138. sshfwd_request_agent_forwarding(mc->sc, TRUE);
  139. mc->req_agent = TRUE;
  140. }
  141. if (!conf_get_int(mc->conf, CONF_nopty)) {
  142. sshfwd_request_pty(
  143. mc->sc, TRUE, mc->conf, mc->term_width, mc->term_height);
  144. mc->req_pty = TRUE;
  145. }
  146. for (val = conf_get_str_strs(mc->conf, CONF_environmt, NULL, &key);
  147. val != NULL;
  148. val = conf_get_str_strs(mc->conf, CONF_environmt, key, &key)) {
  149. sshfwd_send_env_var(mc->sc, TRUE, key, val);
  150. mc->n_req_env++;
  151. }
  152. if (mc->n_req_env)
  153. ppl_logevent(("Sent %d environment variables", mc->n_req_env));
  154. cmd = conf_get_str(mc->conf, CONF_remote_cmd);
  155. if (conf_get_int(mc->conf, CONF_ssh_subsys)) {
  156. retry_cmd_now = !sshfwd_start_subsystem(mc->sc, TRUE, cmd);
  157. } else if (*cmd) {
  158. sshfwd_start_command(mc->sc, TRUE, cmd);
  159. } else {
  160. sshfwd_start_shell(mc->sc, TRUE);
  161. }
  162. if (retry_cmd_now)
  163. mainchan_try_fallback_command(mc);
  164. else
  165. mc->req_cmd_primary = TRUE;
  166. } else {
  167. ssh_set_ldisc_option(mc->cl, LD_ECHO, TRUE);
  168. ssh_set_ldisc_option(mc->cl, LD_EDIT, TRUE);
  169. mainchan_ready(mc);
  170. }
  171. }
  172. static void mainchan_try_fallback_command(mainchan *mc)
  173. {
  174. const char *cmd = conf_get_str(mc->conf, CONF_remote_cmd2);
  175. if (conf_get_int(mc->conf, CONF_ssh_subsys2)) {
  176. sshfwd_start_subsystem(mc->sc, TRUE, cmd);
  177. } else {
  178. sshfwd_start_command(mc->sc, TRUE, cmd);
  179. }
  180. mc->req_cmd_fallback = TRUE;
  181. }
  182. static void mainchan_request_response(Channel *chan, int success)
  183. {
  184. pinitassert(chan->vt == &mainchan_channelvt);
  185. mainchan *mc = container_of(chan, mainchan, chan);
  186. PacketProtocolLayer *ppl = mc->ppl; /* for ppl_logevent */
  187. if (mc->req_x11) {
  188. mc->req_x11 = FALSE;
  189. if (success) {
  190. ppl_logevent(("X11 forwarding enabled"));
  191. ssh_enable_x_fwd(mc->cl);
  192. } else {
  193. ppl_logevent(("X11 forwarding refused"));
  194. }
  195. return;
  196. }
  197. if (mc->req_agent) {
  198. mc->req_agent = FALSE;
  199. if (success) {
  200. ppl_logevent(("Agent forwarding enabled"));
  201. ssh_enable_agent_fwd(mc->cl);
  202. } else {
  203. ppl_logevent(("Agent forwarding refused"));
  204. }
  205. return;
  206. }
  207. if (mc->req_pty) {
  208. mc->req_pty = FALSE;
  209. if (success) {
  210. ppl_logevent(("Allocated pty"));
  211. mc->got_pty = TRUE;
  212. } else {
  213. ppl_logevent(("Server refused to allocate pty"));
  214. ppl_printf(("Server refused to allocate pty\r\n"));
  215. ssh_set_ldisc_option(mc->cl, LD_ECHO, TRUE);
  216. ssh_set_ldisc_option(mc->cl, LD_EDIT, TRUE);
  217. }
  218. return;
  219. }
  220. if (mc->n_env_replies < mc->n_req_env) {
  221. int j = mc->n_env_replies++;
  222. if (!success) {
  223. ppl_logevent(("Server refused to set environment variable %s",
  224. conf_get_str_nthstrkey(mc->conf,
  225. CONF_environmt, j)));
  226. mc->n_env_fails++;
  227. }
  228. if (mc->n_env_replies == mc->n_req_env) {
  229. if (mc->n_env_fails == 0) {
  230. ppl_logevent(("All environment variables successfully set"));
  231. } else if (mc->n_env_fails == mc->n_req_env) {
  232. ppl_logevent(("All environment variables refused"));
  233. ppl_printf(("Server refused to set environment "
  234. "variables\r\n"));
  235. } else {
  236. ppl_printf(("Server refused to set all environment "
  237. "variables\r\n"));
  238. }
  239. }
  240. return;
  241. }
  242. if (mc->req_cmd_primary) {
  243. mc->req_cmd_primary = FALSE;
  244. if (success) {
  245. ppl_logevent(("Started a shell/command"));
  246. mainchan_ready(mc);
  247. } else if (*conf_get_str(mc->conf, CONF_remote_cmd2) || conf_get_int(mc->conf, CONF_force_remote_cmd2)) { // WINSCP
  248. ppl_logevent(("Primary command failed; attempting fallback"));
  249. mainchan_try_fallback_command(mc);
  250. } else {
  251. /*
  252. * If there's no remote_cmd2 configured, then we have no
  253. * fallback command, so we've run out of options.
  254. */
  255. ssh_sw_abort(mc->ppl->ssh,
  256. "Server refused to start a shell/command");
  257. }
  258. return;
  259. }
  260. if (mc->req_cmd_fallback) {
  261. mc->req_cmd_fallback = FALSE;
  262. if (success) {
  263. ppl_logevent(("Started a shell/command"));
  264. ssh_got_fallback_cmd(mc->ppl->ssh);
  265. mainchan_ready(mc);
  266. } else {
  267. ssh_sw_abort(mc->ppl->ssh,
  268. "Server refused to start a shell/command");
  269. }
  270. return;
  271. }
  272. }
  273. static void mainchan_ready(mainchan *mc)
  274. {
  275. mc->ready = TRUE;
  276. ssh_set_wants_user_input(mc->cl, TRUE);
  277. ssh_ppl_got_user_input(mc->ppl); /* in case any is already queued */
  278. /* If an EOF arrived before we were ready, handle it now. */
  279. if (mc->eof_pending) {
  280. mc->eof_pending = FALSE;
  281. mainchan_special_cmd(mc, SS_EOF, 0);
  282. }
  283. ssh_ldisc_update(mc->ppl->ssh);
  284. queue_idempotent_callback(&mc->ppl->ic_process_queue);
  285. }
  286. struct mainchan_open_failure_abort_ctx {
  287. Ssh *ssh;
  288. char *abort_message;
  289. };
  290. static void mainchan_open_failure_abort(void *vctx)
  291. {
  292. struct mainchan_open_failure_abort_ctx *ctx =
  293. (struct mainchan_open_failure_abort_ctx *)vctx;
  294. ssh_sw_abort(
  295. ctx->ssh, "Server refused to open main channel: %s",
  296. ctx->abort_message);
  297. sfree(ctx->abort_message);
  298. sfree(ctx);
  299. }
  300. static void mainchan_open_failure(Channel *chan, const char *errtext)
  301. {
  302. pinitassert(chan->vt == &mainchan_channelvt);
  303. mainchan *mc = container_of(chan, mainchan, chan);
  304. struct mainchan_open_failure_abort_ctx *ctx =
  305. snew(struct mainchan_open_failure_abort_ctx);
  306. ctx->ssh = mc->ppl->ssh;
  307. ctx->abort_message = dupstr(errtext);
  308. queue_toplevel_callback(get_log_callback_set(mc->cl->logctx), mainchan_open_failure_abort, ctx);
  309. }
  310. static int mainchan_send(Channel *chan, int is_stderr,
  311. const void *data, int length)
  312. {
  313. pinitassert(chan->vt == &mainchan_channelvt);
  314. mainchan *mc = container_of(chan, mainchan, chan);
  315. return seat_output(mc->ppl->seat, is_stderr, data, length);
  316. }
  317. static void mainchan_send_eof(Channel *chan)
  318. {
  319. pinitassert(chan->vt == &mainchan_channelvt);
  320. mainchan *mc = container_of(chan, mainchan, chan);
  321. PacketProtocolLayer *ppl = mc->ppl; /* for ppl_logevent */
  322. if (!mc->eof_sent & (seat_eof(mc->ppl->seat) || mc->got_pty)) {
  323. /*
  324. * Either seat_eof told us that the front end wants us to
  325. * close the outgoing side of the connection as soon as we see
  326. * EOF from the far end, or else we've unilaterally decided to
  327. * do that because we've allocated a remote pty and hence EOF
  328. * isn't a particularly meaningful concept.
  329. */
  330. sshfwd_write_eof(mc->sc);
  331. ppl_logevent(("Sent EOF message"));
  332. }
  333. mc->eof_sent = TRUE;
  334. ssh_set_wants_user_input(mc->cl, FALSE); /* now stop reading from stdin */
  335. }
  336. static void mainchan_set_input_wanted(Channel *chan, int wanted)
  337. {
  338. pinitassert(chan->vt == &mainchan_channelvt);
  339. mainchan *mc = container_of(chan, mainchan, chan);
  340. /*
  341. * This is the main channel of the SSH session, i.e. the one tied
  342. * to the standard input (or GUI) of the primary SSH client user
  343. * interface. So ssh->send_ok is how we control whether we're
  344. * reading from that input.
  345. */
  346. ssh_set_wants_user_input(mc->cl, wanted);
  347. }
  348. static char *mainchan_log_close_msg(Channel *chan)
  349. {
  350. return dupstr("Main session channel closed");
  351. }
  352. static int mainchan_rcvd_exit_status(Channel *chan, int status)
  353. {
  354. pinitassert(chan->vt == &mainchan_channelvt);
  355. mainchan *mc = container_of(chan, mainchan, chan);
  356. PacketProtocolLayer *ppl = mc->ppl; /* for ppl_logevent */
  357. ssh_got_exitcode(mc->ppl->ssh, status);
  358. ppl_logevent(("Session sent command exit status %d", status));
  359. return TRUE;
  360. }
  361. static void mainchan_log_exit_signal_common(
  362. mainchan *mc, const char *sigdesc,
  363. int core_dumped, ptrlen msg)
  364. {
  365. PacketProtocolLayer *ppl = mc->ppl; /* for ppl_logevent */
  366. const char *core_msg = core_dumped ? " (core dumped)" : "";
  367. const char *msg_pre = (msg.len ? " (" : "");
  368. const char *msg_post = (msg.len ? ")" : "");
  369. ppl_logevent(("Session exited on %s%s%s%.*s%s",
  370. sigdesc, core_msg, msg_pre, PTRLEN_PRINTF(msg), msg_post));
  371. }
  372. static int mainchan_rcvd_exit_signal(
  373. Channel *chan, ptrlen signame, int core_dumped, ptrlen msg)
  374. {
  375. pinitassert(chan->vt == &mainchan_channelvt);
  376. mainchan *mc = container_of(chan, mainchan, chan);
  377. int exitcode;
  378. char *signame_str;
  379. /*
  380. * Translate the signal description back into a locally meaningful
  381. * number, or 128 if the string didn't match any we recognise.
  382. */
  383. exitcode = 128;
  384. #define SIGNAL_SUB(s) \
  385. if (ptrlen_eq_string(signame, #s)) \
  386. exitcode = 128 + SIG ## s;
  387. #define SIGNAL_MAIN(s, text) SIGNAL_SUB(s)
  388. #define SIGNALS_LOCAL_ONLY
  389. #include "sshsignals.h"
  390. #undef SIGNAL_SUB
  391. #undef SIGNAL_MAIN
  392. #undef SIGNALS_LOCAL_ONLY
  393. ssh_got_exitcode(mc->ppl->ssh, exitcode);
  394. if (exitcode == 128)
  395. signame_str = dupprintf("unrecognised signal \"%.*s\"",
  396. PTRLEN_PRINTF(signame));
  397. else
  398. signame_str = dupprintf("signal SIG%.*s", PTRLEN_PRINTF(signame));
  399. mainchan_log_exit_signal_common(mc, signame_str, core_dumped, msg);
  400. sfree(signame_str);
  401. return TRUE;
  402. }
  403. static int mainchan_rcvd_exit_signal_numeric(
  404. Channel *chan, int signum, int core_dumped, ptrlen msg)
  405. {
  406. pinitassert(chan->vt == &mainchan_channelvt);
  407. mainchan *mc = container_of(chan, mainchan, chan);
  408. char *signum_str;
  409. ssh_got_exitcode(mc->ppl->ssh, 128 + signum);
  410. signum_str = dupprintf("signal %d", signum);
  411. mainchan_log_exit_signal_common(mc, signum_str, core_dumped, msg);
  412. sfree(signum_str);
  413. return TRUE;
  414. }
  415. void mainchan_get_specials(
  416. mainchan *mc, add_special_fn_t add_special, void *ctx)
  417. {
  418. /* FIXME: this _does_ depend on whether these services are supported */
  419. /* WINSCP (causes linker warning and we do not use these)
  420. add_special(ctx, "Break", SS_BRK, 0);
  421. #define SIGNAL_MAIN(name, desc) \
  422. add_special(ctx, "SIG" #name " (" desc ")", SS_SIG ## name, 0);
  423. #define SIGNAL_SUB(name)
  424. #include "sshsignals.h"
  425. #undef SIGNAL_MAIN
  426. #undef SIGNAL_SUB
  427. add_special(ctx, "More signals", SS_SUBMENU, 0);
  428. #define SIGNAL_MAIN(name, desc)
  429. #define SIGNAL_SUB(name) \
  430. add_special(ctx, "SIG" #name, SS_SIG ## name, 0);
  431. #include "sshsignals.h"
  432. #undef SIGNAL_MAIN
  433. #undef SIGNAL_SUB
  434. add_special(ctx, NULL, SS_EXITMENU, 0);
  435. */
  436. }
  437. static const char *ssh_signal_lookup(SessionSpecialCode code)
  438. {
  439. #define SIGNAL_SUB(name) \
  440. if (code == SS_SIG ## name) return #name;
  441. #define SIGNAL_MAIN(name, desc) SIGNAL_SUB(name)
  442. #include "sshsignals.h"
  443. #undef SIGNAL_MAIN
  444. #undef SIGNAL_SUB
  445. /* If none of those clauses matched, fail lookup. */
  446. return NULL;
  447. }
  448. void mainchan_special_cmd(mainchan *mc, SessionSpecialCode code, int arg)
  449. {
  450. PacketProtocolLayer *ppl = mc->ppl; /* for ppl_logevent */
  451. const char *signame;
  452. if (code == SS_EOF) {
  453. if (!mc->ready) {
  454. /*
  455. * Buffer the EOF to send as soon as the main channel is
  456. * fully set up.
  457. */
  458. mc->eof_pending = TRUE;
  459. } else if (!mc->eof_sent) {
  460. sshfwd_write_eof(mc->sc);
  461. mc->eof_sent = TRUE;
  462. }
  463. } else if (code == SS_BRK) {
  464. sshfwd_send_serial_break(
  465. mc->sc, FALSE, 0 /* default break length */);
  466. } else if ((signame = ssh_signal_lookup(code)) != NULL) {
  467. /* It's a signal. */
  468. sshfwd_send_signal(mc->sc, FALSE, signame);
  469. ppl_logevent(("Sent signal SIG%s", signame));
  470. }
  471. }
  472. void mainchan_terminal_size(mainchan *mc, int width, int height)
  473. {
  474. mc->term_width = width;
  475. mc->term_height = height;
  476. if (mc->req_pty || mc->got_pty)
  477. sshfwd_send_terminal_size_change(mc->sc, width, height);
  478. }