connection2-server.c 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. /*
  2. * Server-specific parts of the SSH-2 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 "connection2.h"
  12. #include "server.h"
  13. void ssh2connection_server_configure(
  14. PacketProtocolLayer *ppl, const SftpServerVtable *sftpserver_vt,
  15. const SshServerConfig *ssc)
  16. {
  17. struct ssh2_connection_state *s =
  18. container_of(ppl, struct ssh2_connection_state, ppl);
  19. s->sftpserver_vt = sftpserver_vt;
  20. s->ssc = ssc;
  21. }
  22. static ChanopenResult chan_open_session(
  23. struct ssh2_connection_state *s, SshChannel *sc)
  24. {
  25. PacketProtocolLayer *ppl = &s->ppl; /* for ppl_logevent */
  26. ppl_logevent("Opened session channel");
  27. CHANOPEN_RETURN_SUCCESS(sesschan_new(sc, s->ppl.logctx,
  28. s->sftpserver_vt, s->ssc));
  29. }
  30. static ChanopenResult chan_open_direct_tcpip(
  31. struct ssh2_connection_state *s, SshChannel *sc,
  32. ptrlen dstaddr, int dstport, ptrlen peeraddr, int peerport)
  33. {
  34. PacketProtocolLayer *ppl = &s->ppl; /* for ppl_logevent */
  35. Channel *ch;
  36. char *dstaddr_str, *err;
  37. dstaddr_str = mkstr(dstaddr);
  38. ppl_logevent("Received request to connect to port %s:%d (from %.*s:%d)",
  39. dstaddr_str, dstport, PTRLEN_PRINTF(peeraddr), peerport);
  40. err = portfwdmgr_connect(
  41. s->portfwdmgr, &ch, dstaddr_str, dstport, sc, ADDRTYPE_UNSPEC);
  42. sfree(dstaddr_str);
  43. if (err != NULL) {
  44. ppl_logevent("Port open failed: %s", err);
  45. sfree(err);
  46. CHANOPEN_RETURN_FAILURE(
  47. SSH2_OPEN_CONNECT_FAILED, ("Connection failed"));
  48. }
  49. ppl_logevent("Port opened successfully");
  50. CHANOPEN_RETURN_SUCCESS(ch);
  51. }
  52. ChanopenResult ssh2_connection_parse_channel_open(
  53. struct ssh2_connection_state *s, ptrlen type,
  54. PktIn *pktin, SshChannel *sc)
  55. {
  56. if (ptrlen_eq_string(type, "session")) {
  57. return chan_open_session(s, sc);
  58. } else if (ptrlen_eq_string(type, "direct-tcpip")) {
  59. ptrlen dstaddr = get_string(pktin);
  60. int dstport = toint(get_uint32(pktin));
  61. ptrlen peeraddr = get_string(pktin);
  62. int peerport = toint(get_uint32(pktin));
  63. return chan_open_direct_tcpip(
  64. s, sc, dstaddr, dstport, peeraddr, peerport);
  65. } else {
  66. CHANOPEN_RETURN_FAILURE(
  67. SSH2_OPEN_UNKNOWN_CHANNEL_TYPE,
  68. ("Unsupported channel type requested"));
  69. }
  70. }
  71. bool ssh2_connection_parse_global_request(
  72. struct ssh2_connection_state *s, ptrlen type, PktIn *pktin)
  73. {
  74. if (ptrlen_eq_string(type, "tcpip-forward")) {
  75. char *host = mkstr(get_string(pktin));
  76. unsigned port = get_uint32(pktin);
  77. /* In SSH-2, the host/port we listen on are the same host/port
  78. * we want reported back to us when a connection comes in,
  79. * because that's what we tell the client */
  80. bool toret = portfwdmgr_listen(
  81. s->portfwdmgr, host, port, host, port, s->conf);
  82. sfree(host);
  83. return toret;
  84. } else if (ptrlen_eq_string(type, "cancel-tcpip-forward")) {
  85. char *host = mkstr(get_string(pktin));
  86. unsigned port = get_uint32(pktin);
  87. bool toret = portfwdmgr_unlisten(s->portfwdmgr, host, port);
  88. sfree(host);
  89. return toret;
  90. } else {
  91. /* Unrecognised request. */
  92. return false;
  93. }
  94. }
  95. PktOut *ssh2_portfwd_chanopen(
  96. struct ssh2_connection_state *s, struct ssh2_channel *c,
  97. const char *hostname, int port,
  98. const char *description, const SocketEndpointInfo *pi)
  99. {
  100. PacketProtocolLayer *ppl = &s->ppl; /* for ppl_logevent */
  101. PktOut *pktout;
  102. /*
  103. * In server mode, this function is called by portfwdmgr in
  104. * response to PortListeners that were set up by calling
  105. * portfwdmgr_listen, which means that the hostname and port
  106. * parameters will identify the listening socket on which a
  107. * connection just came in.
  108. */
  109. if (pi && pi->log_text)
  110. ppl_logevent("Forwarding connection to listening port %s:%d from %s",
  111. hostname, port, pi->log_text);
  112. else
  113. ppl_logevent("Forwarding connection to listening port %s:%d",
  114. hostname, port);
  115. pktout = ssh2_chanopen_init(c, "forwarded-tcpip");
  116. put_stringz(pktout, hostname);
  117. put_uint32(pktout, port);
  118. put_stringz(pktout, (pi && pi->addr_text ? pi->addr_text : "0.0.0.0"));
  119. put_uint32(pktout, (pi && pi->port >= 0 ? pi->port : 0));
  120. return pktout;
  121. }
  122. struct ssh_rportfwd *ssh2_rportfwd_alloc(
  123. ConnectionLayer *cl,
  124. const char *shost, int sport, const char *dhost, int dport,
  125. int addressfamily, const char *log_description, PortFwdRecord *pfr,
  126. ssh_sharing_connstate *share_ctx)
  127. {
  128. unreachable("Should never be called in the server");
  129. }
  130. void ssh2_rportfwd_remove(ConnectionLayer *cl, struct ssh_rportfwd *rpf)
  131. {
  132. unreachable("Should never be called in the server");
  133. }
  134. SshChannel *ssh2_session_open(ConnectionLayer *cl, Channel *chan)
  135. {
  136. unreachable("Should never be called in the server");
  137. }
  138. SshChannel *ssh2_serverside_x11_open(
  139. ConnectionLayer *cl, Channel *chan, const SocketEndpointInfo *pi)
  140. {
  141. struct ssh2_connection_state *s =
  142. container_of(cl, struct ssh2_connection_state, cl);
  143. PacketProtocolLayer *ppl = &s->ppl; /* for ppl_logevent */
  144. struct ssh2_channel *c = snew(struct ssh2_channel);
  145. PktOut *pktout;
  146. c->connlayer = s;
  147. ssh2_channel_init(c);
  148. c->halfopen = true;
  149. c->chan = chan;
  150. ppl_logevent("Forwarding X11 channel to client");
  151. pktout = ssh2_chanopen_init(c, "x11");
  152. put_stringz(pktout, (pi && pi->addr_text ? pi->addr_text : "0.0.0.0"));
  153. put_uint32(pktout, (pi && pi->port >= 0 ? pi->port : 0));
  154. pq_push(s->ppl.out_pq, pktout);
  155. return &c->sc;
  156. }
  157. SshChannel *ssh2_serverside_agent_open(ConnectionLayer *cl, Channel *chan)
  158. {
  159. struct ssh2_connection_state *s =
  160. container_of(cl, struct ssh2_connection_state, cl);
  161. PacketProtocolLayer *ppl = &s->ppl; /* for ppl_logevent */
  162. struct ssh2_channel *c = snew(struct ssh2_channel);
  163. PktOut *pktout;
  164. c->connlayer = s;
  165. ssh2_channel_init(c);
  166. c->halfopen = true;
  167. c->chan = chan;
  168. ppl_logevent("Forwarding SSH agent to client");
  169. pktout = ssh2_chanopen_init(c, "auth-agent@openssh.com");
  170. pq_push(s->ppl.out_pq, pktout);
  171. return &c->sc;
  172. }
  173. void ssh2channel_start_shell(SshChannel *sc, bool want_reply)
  174. {
  175. unreachable("Should never be called in the server");
  176. }
  177. void ssh2channel_start_command(
  178. SshChannel *sc, bool want_reply, const char *command)
  179. {
  180. unreachable("Should never be called in the server");
  181. }
  182. bool ssh2channel_start_subsystem(
  183. SshChannel *sc, bool want_reply, const char *subsystem)
  184. {
  185. unreachable("Should never be called in the server");
  186. }
  187. void ssh2channel_send_exit_status(SshChannel *sc, int status)
  188. {
  189. struct ssh2_channel *c = container_of(sc, struct ssh2_channel, sc);
  190. struct ssh2_connection_state *s = c->connlayer;
  191. PktOut *pktout = ssh2_chanreq_init(c, "exit-status", NULL, NULL);
  192. put_uint32(pktout, status);
  193. pq_push(s->ppl.out_pq, pktout);
  194. }
  195. void ssh2channel_send_exit_signal(
  196. SshChannel *sc, ptrlen signame, bool core_dumped, ptrlen msg)
  197. {
  198. struct ssh2_channel *c = container_of(sc, struct ssh2_channel, sc);
  199. struct ssh2_connection_state *s = c->connlayer;
  200. PktOut *pktout = ssh2_chanreq_init(c, "exit-signal", NULL, NULL);
  201. put_stringpl(pktout, signame);
  202. put_bool(pktout, core_dumped);
  203. put_stringpl(pktout, msg);
  204. put_stringz(pktout, ""); /* language tag */
  205. pq_push(s->ppl.out_pq, pktout);
  206. }
  207. void ssh2channel_send_exit_signal_numeric(
  208. SshChannel *sc, int signum, bool core_dumped, ptrlen msg)
  209. {
  210. struct ssh2_channel *c = container_of(sc, struct ssh2_channel, sc);
  211. struct ssh2_connection_state *s = c->connlayer;
  212. PktOut *pktout = ssh2_chanreq_init(c, "exit-signal", NULL, NULL);
  213. put_uint32(pktout, signum);
  214. put_bool(pktout, core_dumped);
  215. put_stringpl(pktout, msg);
  216. put_stringz(pktout, ""); /* language tag */
  217. pq_push(s->ppl.out_pq, pktout);
  218. }
  219. void ssh2channel_request_x11_forwarding(
  220. SshChannel *sc, bool want_reply, const char *authproto,
  221. const char *authdata, int screen_number, bool oneshot)
  222. {
  223. unreachable("Should never be called in the server");
  224. }
  225. void ssh2channel_request_agent_forwarding(SshChannel *sc, bool want_reply)
  226. {
  227. unreachable("Should never be called in the server");
  228. }
  229. void ssh2channel_request_pty(
  230. SshChannel *sc, bool want_reply, Conf *conf, int w, int h)
  231. {
  232. unreachable("Should never be called in the server");
  233. }
  234. bool ssh2channel_send_env_var(
  235. SshChannel *sc, bool want_reply, const char *var, const char *value)
  236. {
  237. unreachable("Should never be called in the server");
  238. }
  239. bool ssh2channel_send_serial_break(SshChannel *sc, bool want_reply, int length)
  240. {
  241. unreachable("Should never be called in the server");
  242. }
  243. bool ssh2channel_send_signal(
  244. SshChannel *sc, bool want_reply, const char *signame)
  245. {
  246. unreachable("Should never be called in the server");
  247. }
  248. void ssh2channel_send_terminal_size_change(SshChannel *sc, int w, int h)
  249. {
  250. unreachable("Should never be called in the server");
  251. }
  252. bool ssh2_connection_need_antispoof_prompt(struct ssh2_connection_state *s)
  253. {
  254. return false;
  255. }