connection2.h 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. #ifndef PUTTY_SSH2CONNECTION_H
  2. #define PUTTY_SSH2CONNECTION_H
  3. struct outstanding_channel_request;
  4. struct outstanding_global_request;
  5. struct ssh2_connection_state {
  6. int crState;
  7. ssh_sharing_state *connshare;
  8. char *peer_verstring;
  9. mainchan *mainchan;
  10. SshChannel *mainchan_sc;
  11. bool ldisc_opts[LD_N_OPTIONS];
  12. int session_attempt, session_status;
  13. int term_width, term_height;
  14. bool want_user_input;
  15. bufchain *user_input;
  16. bool ready; // WINSCP
  17. bool ssh_is_simple;
  18. bool persistent;
  19. bool started;
  20. Conf *conf;
  21. tree234 *channels; /* indexed by local id */
  22. bool all_channels_throttled;
  23. bool X11_fwd_enabled;
  24. // tree234 *x11authtree; WINSCP
  25. bool got_pty;
  26. tree234 *rportfwds;
  27. PortFwdManager *portfwdmgr;
  28. bool portfwdmgr_configured;
  29. prompts_t *antispoof_prompt;
  30. SeatPromptResult antispoof_ret;
  31. const SftpServerVtable *sftpserver_vt;
  32. const SshServerConfig *ssc;
  33. /*
  34. * These store the list of global requests that we're waiting for
  35. * replies to. (REQUEST_FAILURE doesn't come with any indication
  36. * of what message caused it, so we have to keep track of the
  37. * queue ourselves.)
  38. */
  39. struct outstanding_global_request *globreq_head, *globreq_tail;
  40. ConnectionLayer cl;
  41. PacketProtocolLayer ppl;
  42. };
  43. typedef void (*gr_handler_fn_t)(struct ssh2_connection_state *s,
  44. PktIn *pktin, void *ctx);
  45. void ssh2_queue_global_request_handler(
  46. struct ssh2_connection_state *s, gr_handler_fn_t handler, void *ctx);
  47. struct ssh2_channel {
  48. struct ssh2_connection_state *connlayer;
  49. unsigned remoteid, localid;
  50. int type;
  51. /* True if we opened this channel but server hasn't confirmed. */
  52. bool halfopen;
  53. /* Bitmap of whether we've sent/received CHANNEL_EOF and
  54. * CHANNEL_CLOSE. */
  55. #define CLOSES_SENT_EOF 1
  56. #define CLOSES_SENT_CLOSE 2
  57. #define CLOSES_RCVD_EOF 4
  58. #define CLOSES_RCVD_CLOSE 8
  59. int closes;
  60. /*
  61. * This flag indicates that an EOF is pending on the outgoing side
  62. * of the channel: that is, wherever we're getting the data for
  63. * this channel has sent us some data followed by EOF. We can't
  64. * actually send the EOF until we've finished sending the data, so
  65. * we set this flag instead to remind us to do so once our buffer
  66. * is clear.
  67. */
  68. bool pending_eof;
  69. /*
  70. * True if this channel is causing the underlying connection to be
  71. * throttled.
  72. */
  73. bool throttling_conn;
  74. /*
  75. * True if we currently have backed-up data on the direction of
  76. * this channel pointing out of the SSH connection, and therefore
  77. * would prefer the 'Channel' implementation not to read further
  78. * local input if possible.
  79. */
  80. bool throttled_by_backlog;
  81. bufchain outbuffer, errbuffer;
  82. unsigned remwindow, remmaxpkt;
  83. /* locwindow is signed so we can cope with excess data. */
  84. int locwindow, locmaxwin;
  85. /*
  86. * remlocwin is the amount of local window that we think
  87. * the remote end had available to it after it sent the
  88. * last data packet or window adjust ack.
  89. */
  90. int remlocwin;
  91. /*
  92. * These store the list of channel requests that we're waiting for
  93. * replies to. (CHANNEL_FAILURE doesn't come with any indication
  94. * of what message caused it, so we have to keep track of the
  95. * queue ourselves.)
  96. */
  97. struct outstanding_channel_request *chanreq_head, *chanreq_tail;
  98. enum { THROTTLED, UNTHROTTLING, UNTHROTTLED } throttle_state;
  99. ssh_sharing_connstate *sharectx; /* sharing context, if this is a
  100. * downstream channel */
  101. Channel *chan; /* handle the client side of this channel, if not */
  102. SshChannel sc; /* entry point for chan to talk back to */
  103. };
  104. typedef void (*cr_handler_fn_t)(struct ssh2_channel *, PktIn *, void *);
  105. void ssh2_channel_init(struct ssh2_channel *c);
  106. PktOut *ssh2_chanreq_init(struct ssh2_channel *c, const char *type,
  107. cr_handler_fn_t handler, void *ctx);
  108. typedef enum ChanopenOutcome {
  109. CHANOPEN_RESULT_FAILURE,
  110. CHANOPEN_RESULT_SUCCESS,
  111. CHANOPEN_RESULT_DOWNSTREAM,
  112. } ChanopenOutcome;
  113. typedef struct ChanopenResult {
  114. ChanopenOutcome outcome;
  115. union {
  116. struct {
  117. char *wire_message; /* must be freed by recipient */
  118. unsigned reason_code;
  119. } failure;
  120. struct {
  121. Channel *channel;
  122. } success;
  123. struct {
  124. ssh_sharing_connstate *share_ctx;
  125. } downstream;
  126. } u;
  127. } ChanopenResult;
  128. PktOut *ssh2_chanopen_init(struct ssh2_channel *c, const char *type);
  129. PktOut *ssh2_portfwd_chanopen(
  130. struct ssh2_connection_state *s, struct ssh2_channel *c,
  131. const char *hostname, int port,
  132. const char *description, const SocketEndpointInfo *peerinfo);
  133. struct ssh_rportfwd *ssh2_rportfwd_alloc(
  134. ConnectionLayer *cl,
  135. const char *shost, int sport, const char *dhost, int dport,
  136. int addressfamily, const char *log_description, PortFwdRecord *pfr,
  137. ssh_sharing_connstate *share_ctx);
  138. void ssh2_rportfwd_remove(
  139. ConnectionLayer *cl, struct ssh_rportfwd *rpf);
  140. SshChannel *ssh2_session_open(ConnectionLayer *cl, Channel *chan);
  141. SshChannel *ssh2_serverside_x11_open(
  142. ConnectionLayer *cl, Channel *chan, const SocketEndpointInfo *pi);
  143. SshChannel *ssh2_serverside_agent_open(ConnectionLayer *cl, Channel *chan);
  144. void ssh2channel_send_exit_status(SshChannel *c, int status);
  145. void ssh2channel_send_exit_signal(
  146. SshChannel *c, ptrlen signame, bool core_dumped, ptrlen msg);
  147. void ssh2channel_send_exit_signal_numeric(
  148. SshChannel *c, int signum, bool core_dumped, ptrlen msg);
  149. void ssh2channel_request_x11_forwarding(
  150. SshChannel *c, bool want_reply, const char *authproto,
  151. const char *authdata, int screen_number, bool oneshot);
  152. void ssh2channel_request_agent_forwarding(SshChannel *c, bool want_reply);
  153. void ssh2channel_request_pty(
  154. SshChannel *c, bool want_reply, Conf *conf, int w, int h);
  155. bool ssh2channel_send_env_var(
  156. SshChannel *c, bool want_reply, const char *var, const char *value);
  157. void ssh2channel_start_shell(SshChannel *c, bool want_reply);
  158. void ssh2channel_start_command(
  159. SshChannel *c, bool want_reply, const char *command);
  160. bool ssh2channel_start_subsystem(
  161. SshChannel *c, bool want_reply, const char *subsystem);
  162. bool ssh2channel_send_env_var(
  163. SshChannel *c, bool want_reply, const char *var, const char *value);
  164. bool ssh2channel_send_serial_break(
  165. SshChannel *c, bool want_reply, int length);
  166. bool ssh2channel_send_signal(
  167. SshChannel *c, bool want_reply, const char *signame);
  168. void ssh2channel_send_terminal_size_change(SshChannel *c, int w, int h);
  169. #define CHANOPEN_RETURN_FAILURE(code, msgparams) do \
  170. { \
  171. ChanopenResult toret; \
  172. toret.outcome = CHANOPEN_RESULT_FAILURE; \
  173. toret.u.failure.reason_code = code; \
  174. toret.u.failure.wire_message = dupprintf msgparams; \
  175. return toret; \
  176. } while (0)
  177. #define CHANOPEN_RETURN_SUCCESS(chan) do \
  178. { \
  179. ChanopenResult toret; \
  180. toret.outcome = CHANOPEN_RESULT_SUCCESS; \
  181. toret.u.success.channel = chan; \
  182. return toret; \
  183. } while (0)
  184. #define CHANOPEN_RETURN_DOWNSTREAM(shctx) do \
  185. { \
  186. ChanopenResult toret; \
  187. toret.outcome = CHANOPEN_RESULT_DOWNSTREAM; \
  188. toret.u.downstream.share_ctx = shctx; \
  189. return toret; \
  190. } while (0)
  191. ChanopenResult ssh2_connection_parse_channel_open(
  192. struct ssh2_connection_state *s, ptrlen type,
  193. PktIn *pktin, SshChannel *sc);
  194. bool ssh2_connection_parse_global_request(
  195. struct ssh2_connection_state *s, ptrlen type, PktIn *pktin);
  196. bool ssh2_connection_need_antispoof_prompt(struct ssh2_connection_state *s);
  197. #endif /* PUTTY_SSH2CONNECTION_H */