sshchan.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. /*
  2. * Abstraction of the various ways to handle the local end of an SSH
  3. * connection-layer channel.
  4. */
  5. #ifndef PUTTY_SSHCHAN_H
  6. #define PUTTY_SSHCHAN_H
  7. struct ChannelVtable {
  8. void (*free)(Channel *);
  9. /* Called for channel types that were created at the same time as
  10. * we sent an outgoing CHANNEL_OPEN, when the confirmation comes
  11. * back from the server indicating that the channel has been
  12. * opened, or the failure message indicating that it hasn't,
  13. * respectively. In the latter case, this must _not_ free the
  14. * Channel structure - the client will call the free method
  15. * separately. But it might do logging or other local cleanup. */
  16. void (*open_confirmation)(Channel *);
  17. void (*open_failed)(Channel *, const char *error_text);
  18. int (*send)(Channel *, int is_stderr, const void *buf, int len);
  19. void (*send_eof)(Channel *);
  20. void (*set_input_wanted)(Channel *, int wanted);
  21. char *(*log_close_msg)(Channel *);
  22. int (*want_close)(Channel *, int sent_local_eof, int rcvd_remote_eof);
  23. /* A method for every channel request we know of. All of these
  24. * return TRUE for success or FALSE for failure. */
  25. int (*rcvd_exit_status)(Channel *, int status);
  26. int (*rcvd_exit_signal)(
  27. Channel *chan, ptrlen signame, int core_dumped, ptrlen msg);
  28. int (*rcvd_exit_signal_numeric)(
  29. Channel *chan, int signum, int core_dumped, ptrlen msg);
  30. int (*run_shell)(Channel *chan);
  31. int (*run_command)(Channel *chan, ptrlen command);
  32. int (*run_subsystem)(Channel *chan, ptrlen subsys);
  33. int (*enable_x11_forwarding)(
  34. Channel *chan, int oneshot, ptrlen authproto, ptrlen authdata,
  35. unsigned screen_number);
  36. int (*enable_agent_forwarding)(Channel *chan);
  37. int (*allocate_pty)(
  38. Channel *chan, ptrlen termtype, unsigned width, unsigned height,
  39. unsigned pixwidth, unsigned pixheight, struct ssh_ttymodes modes);
  40. int (*set_env)(Channel *chan, ptrlen var, ptrlen value);
  41. int (*send_break)(Channel *chan, unsigned length);
  42. int (*send_signal)(Channel *chan, ptrlen signame);
  43. int (*change_window_size)(
  44. Channel *chan, unsigned width, unsigned height,
  45. unsigned pixwidth, unsigned pixheight);
  46. /* A method for signalling success/failure responses to channel
  47. * requests initiated from the SshChannel vtable with want_reply
  48. * true. */
  49. void (*request_response)(Channel *, int success);
  50. };
  51. struct Channel {
  52. const struct ChannelVtable *vt;
  53. unsigned initial_fixed_window_size;
  54. };
  55. #define chan_free(ch) ((ch)->vt->free(ch))
  56. #define chan_open_confirmation(ch) ((ch)->vt->open_confirmation(ch))
  57. #define chan_open_failed(ch, err) ((ch)->vt->open_failed(ch, err))
  58. #define chan_send(ch, err, buf, len) ((ch)->vt->send(ch, err, buf, len))
  59. #define chan_send_eof(ch) ((ch)->vt->send_eof(ch))
  60. #define chan_set_input_wanted(ch, wanted) \
  61. ((ch)->vt->set_input_wanted(ch, wanted))
  62. #define chan_log_close_msg(ch) ((ch)->vt->log_close_msg(ch))
  63. #define chan_want_close(ch, leof, reof) ((ch)->vt->want_close(ch, leof, reof))
  64. #define chan_rcvd_exit_status(ch, status) \
  65. ((ch)->vt->rcvd_exit_status(ch, status))
  66. #define chan_rcvd_exit_signal(ch, sig, core, msg) \
  67. ((ch)->vt->rcvd_exit_signal(ch, sig, core, msg))
  68. #define chan_rcvd_exit_signal_numeric(ch, sig, core, msg) \
  69. ((ch)->vt->rcvd_exit_signal_numeric(ch, sig, core, msg))
  70. #define chan_run_shell(ch) \
  71. ((ch)->vt->run_shell(ch))
  72. #define chan_run_command(ch, cmd) \
  73. ((ch)->vt->run_command(ch, cmd))
  74. #define chan_run_subsystem(ch, subsys) \
  75. ((ch)->vt->run_subsystem(ch, subsys))
  76. #define chan_enable_x11_forwarding(ch, oneshot, ap, ad, scr) \
  77. ((ch)->vt->enable_x11_forwarding(ch, oneshot, ap, ad, scr))
  78. #define chan_enable_agent_forwarding(ch) \
  79. ((ch)->vt->enable_agent_forwarding(ch))
  80. #define chan_allocate_pty(ch, termtype, w, h, pw, ph, modes) \
  81. ((ch)->vt->allocate_pty(ch, termtype, w, h, pw, ph, modes))
  82. #define chan_set_env(ch, var, value) \
  83. ((ch)->vt->set_env(ch, var, value))
  84. #define chan_send_break(ch, length) \
  85. ((ch)->vt->send_break(ch, length))
  86. #define chan_send_signal(ch, signame) \
  87. ((ch)->vt->send_signal(ch, signame))
  88. #define chan_change_window_size(ch, w, h, pw, ph) \
  89. ((ch)->vt->change_window_size(ch, w, h, pw, ph))
  90. #define chan_request_response(ch, success) \
  91. ((ch)->vt->request_response(ch, success))
  92. /*
  93. * Reusable methods you can put in vtables to give default handling of
  94. * some of those functions.
  95. */
  96. /* open_confirmation / open_failed for any channel it doesn't apply to */
  97. void chan_remotely_opened_confirmation(Channel *chan);
  98. void chan_remotely_opened_failure(Channel *chan, const char *errtext);
  99. /* want_close for any channel that wants the default behaviour of not
  100. * closing until both directions have had an EOF */
  101. int chan_default_want_close(Channel *, int, int);
  102. /* default implementations that refuse all the channel requests */
  103. int chan_no_exit_status(Channel *, int);
  104. int chan_no_exit_signal(Channel *, ptrlen, int, ptrlen);
  105. int chan_no_exit_signal_numeric(Channel *, int, int, ptrlen);
  106. int chan_no_run_shell(Channel *chan);
  107. int chan_no_run_command(Channel *chan, ptrlen command);
  108. int chan_no_run_subsystem(Channel *chan, ptrlen subsys);
  109. int chan_no_enable_x11_forwarding(
  110. Channel *chan, int oneshot, ptrlen authproto, ptrlen authdata,
  111. unsigned screen_number);
  112. int chan_no_enable_agent_forwarding(Channel *chan);
  113. int chan_no_allocate_pty(
  114. Channel *chan, ptrlen termtype, unsigned width, unsigned height,
  115. unsigned pixwidth, unsigned pixheight, struct ssh_ttymodes modes);
  116. int chan_no_set_env(Channel *chan, ptrlen var, ptrlen value);
  117. int chan_no_send_break(Channel *chan, unsigned length);
  118. int chan_no_send_signal(Channel *chan, ptrlen signame);
  119. int chan_no_change_window_size(
  120. Channel *chan, unsigned width, unsigned height,
  121. unsigned pixwidth, unsigned pixheight);
  122. /* default implementation that never expects to receive a response */
  123. void chan_no_request_response(Channel *, int);
  124. /*
  125. * Constructor for a trivial do-nothing implementation of
  126. * ChannelVtable. Used for 'zombie' channels, i.e. channels whose
  127. * proper local source of data has been shut down or otherwise stopped
  128. * existing, but the SSH side is still there and needs some kind of a
  129. * Channel implementation to talk to. In particular, the want_close
  130. * method for this channel always returns 'yes, please close this
  131. * channel asap', regardless of whether local and/or remote EOF have
  132. * been sent - indeed, even if _neither_ has.
  133. */
  134. Channel *zombiechan_new(void);
  135. /* ----------------------------------------------------------------------
  136. * This structure is owned by an SSH connection layer, and identifies
  137. * the connection layer's end of the channel, for the Channel
  138. * implementation to talk back to.
  139. */
  140. struct SshChannelVtable {
  141. int (*write)(SshChannel *c, int is_stderr, const void *, int);
  142. void (*write_eof)(SshChannel *c);
  143. void (*initiate_close)(SshChannel *c, const char *err);
  144. void (*unthrottle)(SshChannel *c, int bufsize);
  145. Conf *(*get_conf)(SshChannel *c);
  146. void (*window_override_removed)(SshChannel *c);
  147. void (*x11_sharing_handover)(SshChannel *c,
  148. ssh_sharing_connstate *share_cs,
  149. share_channel *share_chan,
  150. const char *peer_addr, int peer_port,
  151. int endian, int protomajor, int protominor,
  152. const void *initial_data, int initial_len);
  153. /*
  154. * All the outgoing channel requests we support. Each one has a
  155. * want_reply flag, which will cause a callback to
  156. * chan_request_response when the result is available.
  157. *
  158. * The ones that return 'int' use it to indicate that the SSH
  159. * protocol in use doesn't support this request at all.
  160. *
  161. * (It's also intentional that not all of them have a want_reply
  162. * flag: the ones that don't are because SSH-1 has no method for
  163. * signalling success or failure of that request, or because we
  164. * wouldn't do anything usefully different with the reply in any
  165. * case.)
  166. */
  167. void (*send_exit_status)(SshChannel *c, int status);
  168. void (*send_exit_signal)(
  169. SshChannel *c, ptrlen signame, int core_dumped, ptrlen msg);
  170. void (*send_exit_signal_numeric)(
  171. SshChannel *c, int signum, int core_dumped, ptrlen msg);
  172. void (*request_x11_forwarding)(
  173. SshChannel *c, int want_reply, const char *authproto,
  174. const char *authdata, int screen_number, int oneshot);
  175. void (*request_agent_forwarding)(
  176. SshChannel *c, int want_reply);
  177. void (*request_pty)(
  178. SshChannel *c, int want_reply, Conf *conf, int w, int h);
  179. int (*send_env_var)(
  180. SshChannel *c, int want_reply, const char *var, const char *value);
  181. void (*start_shell)(
  182. SshChannel *c, int want_reply);
  183. void (*start_command)(
  184. SshChannel *c, int want_reply, const char *command);
  185. int (*start_subsystem)(
  186. SshChannel *c, int want_reply, const char *subsystem);
  187. int (*send_serial_break)(
  188. SshChannel *c, int want_reply, int length); /* length=0 for default */
  189. int (*send_signal)(
  190. SshChannel *c, int want_reply, const char *signame);
  191. void (*send_terminal_size_change)(
  192. SshChannel *c, int w, int h);
  193. void (*hint_channel_is_simple)(SshChannel *c);
  194. };
  195. struct SshChannel {
  196. const struct SshChannelVtable *vt;
  197. ConnectionLayer *cl;
  198. };
  199. #define sshfwd_write(c, buf, len) ((c)->vt->write(c, FALSE, buf, len))
  200. #define sshfwd_write_ext(c, stderr, buf, len) \
  201. ((c)->vt->write(c, stderr, buf, len))
  202. #define sshfwd_write_eof(c) ((c)->vt->write_eof(c))
  203. #define sshfwd_initiate_close(c, err) ((c)->vt->initiate_close(c, err))
  204. #define sshfwd_unthrottle(c, bufsize) ((c)->vt->unthrottle(c, bufsize))
  205. #define sshfwd_get_conf(c) ((c)->vt->get_conf(c))
  206. #define sshfwd_window_override_removed(c) ((c)->vt->window_override_removed(c))
  207. #define sshfwd_x11_sharing_handover(c, cs, ch, pa, pp, e, pmaj, pmin, d, l) \
  208. ((c)->vt->x11_sharing_handover(c, cs, ch, pa, pp, e, pmaj, pmin, d, l))
  209. #define sshfwd_send_exit_status(c, status) \
  210. ((c)->vt->send_exit_status(c, status))
  211. #define sshfwd_send_exit_signal(c, sig, core, msg) \
  212. ((c)->vt->send_exit_signal(c, sig, core, msg))
  213. #define sshfwd_send_exit_signal_numeric(c, sig, core, msg) \
  214. ((c)->vt->send_exit_signal_numeric(c, sig, core, msg))
  215. #define sshfwd_request_x11_forwarding(c, wr, ap, ad, scr, oneshot) \
  216. ((c)->vt->request_x11_forwarding(c, wr, ap, ad, scr, oneshot))
  217. #define sshfwd_request_agent_forwarding(c, wr) \
  218. ((c)->vt->request_agent_forwarding(c, wr))
  219. #define sshfwd_request_pty(c, wr, conf, w, h) \
  220. ((c)->vt->request_pty(c, wr, conf, w, h))
  221. #define sshfwd_send_env_var(c, wr, var, value) \
  222. ((c)->vt->send_env_var(c, wr, var, value))
  223. #define sshfwd_start_shell(c, wr) \
  224. ((c)->vt->start_shell(c, wr))
  225. #define sshfwd_start_command(c, wr, cmd) \
  226. ((c)->vt->start_command(c, wr, cmd))
  227. #define sshfwd_start_subsystem(c, wr, subsys) \
  228. ((c)->vt->start_subsystem(c, wr, subsys))
  229. #define sshfwd_send_serial_break(c, wr, length) \
  230. ((c)->vt->send_serial_break(c, wr, length))
  231. #define sshfwd_send_signal(c, wr, sig) \
  232. ((c)->vt->send_signal(c, wr, sig))
  233. #define sshfwd_send_terminal_size_change(c, w, h) \
  234. ((c)->vt->send_terminal_size_change(c, w, h))
  235. #define sshfwd_hint_channel_is_simple(c) \
  236. ((c)->vt->hint_channel_is_simple(c))
  237. /* ----------------------------------------------------------------------
  238. * The 'main' or primary channel of the SSH connection is special,
  239. * because it's the one that's connected directly to parts of the
  240. * frontend such as the terminal and the specials menu. So it exposes
  241. * a richer API.
  242. */
  243. mainchan *mainchan_new(
  244. PacketProtocolLayer *ppl, ConnectionLayer *cl, Conf *conf,
  245. int term_width, int term_height, int is_simple, SshChannel **sc_out);
  246. void mainchan_get_specials(
  247. mainchan *mc, add_special_fn_t add_special, void *ctx);
  248. void mainchan_special_cmd(mainchan *mc, SessionSpecialCode code, int arg);
  249. void mainchan_terminal_size(mainchan *mc, int width, int height);
  250. #endif /* PUTTY_SSHCHAN_H */