connection2-client.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523
  1. /*
  2. * Client-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. static ChanopenResult chan_open_x11(
  13. struct ssh2_connection_state *s, SshChannel *sc,
  14. ptrlen peeraddr, int peerport)
  15. {
  16. #ifndef WINSCP
  17. PacketProtocolLayer *ppl = &s->ppl; /* for ppl_logevent */
  18. char *peeraddr_str;
  19. Channel *ch;
  20. ppl_logevent("Received X11 connect request from %.*s:%d",
  21. PTRLEN_PRINTF(peeraddr), peerport);
  22. if (!s->X11_fwd_enabled && !s->connshare) {
  23. CHANOPEN_RETURN_FAILURE(
  24. SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED,
  25. ("X11 forwarding is not enabled"));
  26. }
  27. peeraddr_str = peeraddr.ptr ? mkstr(peeraddr) : NULL;
  28. ch = x11_new_channel(
  29. s->x11authtree, sc, peeraddr_str, peerport, s->connshare != NULL);
  30. sfree(peeraddr_str);
  31. ppl_logevent("Opened X11 forward channel");
  32. CHANOPEN_RETURN_SUCCESS(ch);
  33. #else
  34. assert(false);
  35. CHANOPEN_RETURN_FAILURE(SSH2_OPEN_UNKNOWN_CHANNEL_TYPE, ("Unsupported"));
  36. #endif
  37. }
  38. static ChanopenResult chan_open_forwarded_tcpip(
  39. struct ssh2_connection_state *s, SshChannel *sc,
  40. ptrlen fwdaddr, int fwdport, ptrlen peeraddr, int peerport)
  41. {
  42. PacketProtocolLayer *ppl = &s->ppl; /* for ppl_logevent */
  43. struct ssh_rportfwd pf, *realpf;
  44. Channel *ch;
  45. char *err;
  46. ppl_logevent("Received remote port %.*s:%d open request from %.*s:%d",
  47. PTRLEN_PRINTF(fwdaddr), fwdport,
  48. PTRLEN_PRINTF(peeraddr), peerport);
  49. pf.shost = mkstr(fwdaddr);
  50. pf.sport = fwdport;
  51. realpf = find234(s->rportfwds, &pf, NULL);
  52. sfree(pf.shost);
  53. if (realpf == NULL) {
  54. CHANOPEN_RETURN_FAILURE(
  55. SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED,
  56. ("Remote port is not recognised"));
  57. }
  58. if (realpf->share_ctx) {
  59. /*
  60. * This port forwarding is on behalf of a connection-sharing
  61. * downstream.
  62. */
  63. CHANOPEN_RETURN_DOWNSTREAM(realpf->share_ctx);
  64. }
  65. err = portfwdmgr_connect(
  66. s->portfwdmgr, &ch, realpf->dhost, realpf->dport,
  67. sc, realpf->addressfamily);
  68. ppl_logevent("Attempting to forward remote port to %s:%d",
  69. realpf->dhost, realpf->dport);
  70. if (err != NULL) {
  71. ppl_logevent("Port open failed: %s", err);
  72. sfree(err);
  73. CHANOPEN_RETURN_FAILURE(
  74. SSH2_OPEN_CONNECT_FAILED,
  75. ("Port open failed"));
  76. }
  77. ppl_logevent("Forwarded port opened successfully");
  78. CHANOPEN_RETURN_SUCCESS(ch);
  79. }
  80. static ChanopenResult chan_open_auth_agent(
  81. struct ssh2_connection_state *s, SshChannel *sc)
  82. {
  83. if (!ssh_agent_forwarding_permitted(&s->cl)) {
  84. CHANOPEN_RETURN_FAILURE(
  85. SSH2_OPEN_ADMINISTRATIVELY_PROHIBITED,
  86. ("Agent forwarding is not enabled"));
  87. }
  88. /*
  89. * If possible, make a stream-oriented connection to the agent and
  90. * set up an ordinary port-forwarding type channel over it.
  91. */
  92. { // WINSCP
  93. Plug *plug;
  94. Channel *ch = portfwd_raw_new(&s->cl, &plug, true);
  95. Socket *skt = agent_connect(plug);
  96. if (!sk_socket_error(skt)) {
  97. portfwd_raw_setup(ch, skt, sc);
  98. CHANOPEN_RETURN_SUCCESS(ch);
  99. } else {
  100. struct callback_set *callback_set = get_callback_set(plug); // WINSCP
  101. portfwd_raw_free(ch);
  102. /*
  103. * Otherwise, fall back to the old-fashioned system of parsing the
  104. * forwarded data stream ourselves for message boundaries, and
  105. * passing each individual message to the one-off agent_query().
  106. */
  107. CHANOPEN_RETURN_SUCCESS(agentf_new(sc, callback_set));
  108. }
  109. } // WINSCP
  110. }
  111. ChanopenResult ssh2_connection_parse_channel_open(
  112. struct ssh2_connection_state *s, ptrlen type,
  113. PktIn *pktin, SshChannel *sc)
  114. {
  115. if (ptrlen_eq_string(type, "x11")) {
  116. ptrlen peeraddr = get_string(pktin);
  117. int peerport = get_uint32(pktin);
  118. return chan_open_x11(s, sc, peeraddr, peerport);
  119. } else if (ptrlen_eq_string(type, "forwarded-tcpip")) {
  120. ptrlen fwdaddr = get_string(pktin);
  121. int fwdport = toint(get_uint32(pktin));
  122. ptrlen peeraddr = get_string(pktin);
  123. int peerport = toint(get_uint32(pktin));
  124. return chan_open_forwarded_tcpip(
  125. s, sc, fwdaddr, fwdport, peeraddr, peerport);
  126. } else if (ptrlen_eq_string(type, "[email protected]")) {
  127. return chan_open_auth_agent(s, sc);
  128. } else {
  129. CHANOPEN_RETURN_FAILURE(
  130. SSH2_OPEN_UNKNOWN_CHANNEL_TYPE,
  131. ("Unsupported channel type requested"));
  132. }
  133. }
  134. bool ssh2_connection_parse_global_request(
  135. struct ssh2_connection_state *s, ptrlen type, PktIn *pktin)
  136. {
  137. /*
  138. * We don't know of any global requests that an SSH client needs
  139. * to honour.
  140. */
  141. return false;
  142. }
  143. PktOut *ssh2_portfwd_chanopen(
  144. struct ssh2_connection_state *s, struct ssh2_channel *c,
  145. const char *hostname, int port,
  146. const char *description, const SocketEndpointInfo *peerinfo)
  147. {
  148. PacketProtocolLayer *ppl = &s->ppl; /* for ppl_logevent */
  149. PktOut *pktout;
  150. /*
  151. * In client mode, this function is called by portfwdmgr in
  152. * response to PortListeners that were set up in
  153. * portfwdmgr_config, which means that the hostname and port
  154. * parameters will indicate the host we want to tell the server to
  155. * connect _to_.
  156. */
  157. ppl_logevent("Opening connection to %s:%d for %s",
  158. hostname, port, description);
  159. pktout = ssh2_chanopen_init(c, "direct-tcpip");
  160. {
  161. char *trimmed_host = host_strduptrim(hostname);
  162. put_stringz(pktout, trimmed_host);
  163. sfree(trimmed_host);
  164. }
  165. put_uint32(pktout, port);
  166. /*
  167. * We make up values for the originator data; partly it's too much
  168. * hassle to keep track, and partly I'm not convinced the server
  169. * should be told details like that about my local network
  170. * configuration. The "originator IP address" is syntactically a
  171. * numeric IP address, and some servers (e.g., Tectia) get upset
  172. * if it doesn't match this syntax.
  173. */
  174. put_stringz(pktout, "0.0.0.0");
  175. put_uint32(pktout, 0);
  176. return pktout;
  177. }
  178. static int ssh2_rportfwd_cmp(void *av, void *bv)
  179. {
  180. struct ssh_rportfwd *a = (struct ssh_rportfwd *) av;
  181. struct ssh_rportfwd *b = (struct ssh_rportfwd *) bv;
  182. int i;
  183. if ( (i = strcmp(a->shost, b->shost)) != 0)
  184. return i < 0 ? -1 : +1;
  185. if (a->sport > b->sport)
  186. return +1;
  187. if (a->sport < b->sport)
  188. return -1;
  189. return 0;
  190. }
  191. static void ssh2_rportfwd_globreq_response(struct ssh2_connection_state *s,
  192. PktIn *pktin, void *ctx)
  193. {
  194. PacketProtocolLayer *ppl = &s->ppl; /* for ppl_logevent */
  195. struct ssh_rportfwd *rpf = (struct ssh_rportfwd *)ctx;
  196. if (pktin->type == SSH2_MSG_REQUEST_SUCCESS) {
  197. ppl_logevent("Remote port forwarding from %s enabled",
  198. rpf->log_description);
  199. } else {
  200. ppl_logevent("Remote port forwarding from %s refused",
  201. rpf->log_description);
  202. { // WINSCP
  203. struct ssh_rportfwd *realpf = del234(s->rportfwds, rpf);
  204. assert(realpf == rpf);
  205. portfwdmgr_close(s->portfwdmgr, rpf->pfr);
  206. free_rportfwd(rpf);
  207. } // WINSCP
  208. }
  209. }
  210. struct ssh_rportfwd *ssh2_rportfwd_alloc(
  211. ConnectionLayer *cl,
  212. const char *shost, int sport, const char *dhost, int dport,
  213. int addressfamily, const char *log_description, PortFwdRecord *pfr,
  214. ssh_sharing_connstate *share_ctx)
  215. {
  216. struct ssh2_connection_state *s =
  217. container_of(cl, struct ssh2_connection_state, cl);
  218. struct ssh_rportfwd *rpf = snew(struct ssh_rportfwd);
  219. if (!s->rportfwds)
  220. s->rportfwds = newtree234(ssh2_rportfwd_cmp);
  221. rpf->shost = dupstr(shost);
  222. rpf->sport = sport;
  223. rpf->dhost = dupstr(dhost);
  224. rpf->dport = dport;
  225. rpf->addressfamily = addressfamily;
  226. rpf->log_description = dupstr(log_description);
  227. rpf->pfr = pfr;
  228. rpf->share_ctx = share_ctx;
  229. if (add234(s->rportfwds, rpf) != rpf) {
  230. free_rportfwd(rpf);
  231. return NULL;
  232. }
  233. if (!rpf->share_ctx) {
  234. PktOut *pktout = ssh_bpp_new_pktout(
  235. s->ppl.bpp, SSH2_MSG_GLOBAL_REQUEST);
  236. put_stringz(pktout, "tcpip-forward");
  237. put_bool(pktout, true); /* want reply */
  238. put_stringz(pktout, rpf->shost);
  239. put_uint32(pktout, rpf->sport);
  240. pq_push(s->ppl.out_pq, pktout);
  241. ssh2_queue_global_request_handler(
  242. s, ssh2_rportfwd_globreq_response, rpf);
  243. }
  244. return rpf;
  245. }
  246. void ssh2_rportfwd_remove(ConnectionLayer *cl, struct ssh_rportfwd *rpf)
  247. {
  248. struct ssh2_connection_state *s =
  249. container_of(cl, struct ssh2_connection_state, cl);
  250. if (rpf->share_ctx) {
  251. /*
  252. * We don't manufacture a cancel-tcpip-forward message for
  253. * remote port forwardings being removed on behalf of a
  254. * downstream; we just pass through the one the downstream
  255. * sent to us.
  256. */
  257. } else {
  258. PktOut *pktout = ssh_bpp_new_pktout(
  259. s->ppl.bpp, SSH2_MSG_GLOBAL_REQUEST);
  260. put_stringz(pktout, "cancel-tcpip-forward");
  261. put_bool(pktout, false); /* _don't_ want reply */
  262. put_stringz(pktout, rpf->shost);
  263. put_uint32(pktout, rpf->sport);
  264. pq_push(s->ppl.out_pq, pktout);
  265. }
  266. assert(s->rportfwds);
  267. { // WINSCP
  268. struct ssh_rportfwd *realpf = del234(s->rportfwds, rpf);
  269. assert(realpf == rpf);
  270. } // WINSCP
  271. free_rportfwd(rpf);
  272. }
  273. SshChannel *ssh2_session_open(ConnectionLayer *cl, Channel *chan)
  274. {
  275. struct ssh2_connection_state *s =
  276. container_of(cl, struct ssh2_connection_state, cl);
  277. PacketProtocolLayer *ppl = &s->ppl; /* for ppl_logevent */
  278. struct ssh2_channel *c = snew(struct ssh2_channel);
  279. PktOut *pktout;
  280. c->connlayer = s;
  281. ssh2_channel_init(c);
  282. c->halfopen = true;
  283. c->chan = chan;
  284. ppl_logevent("Opening main session channel");
  285. pktout = ssh2_chanopen_init(c, "session");
  286. pq_push(s->ppl.out_pq, pktout);
  287. return &c->sc;
  288. }
  289. SshChannel *ssh2_serverside_x11_open(
  290. ConnectionLayer *cl, Channel *chan, const SocketEndpointInfo *pi)
  291. {
  292. unreachable("Should never be called in the client");
  293. }
  294. SshChannel *ssh2_serverside_agent_open(ConnectionLayer *cl, Channel *chan)
  295. {
  296. unreachable("Should never be called in the client");
  297. }
  298. static void ssh2_channel_response(
  299. struct ssh2_channel *c, PktIn *pkt, void *ctx)
  300. {
  301. /* If pkt==NULL (because this handler has been called in response
  302. * to CHANNEL_CLOSE arriving while the request was still
  303. * outstanding), we treat that the same as CHANNEL_FAILURE. */
  304. chan_request_response(c->chan,
  305. pkt && pkt->type == SSH2_MSG_CHANNEL_SUCCESS);
  306. }
  307. void ssh2channel_start_shell(SshChannel *sc, bool want_reply)
  308. {
  309. struct ssh2_channel *c = container_of(sc, struct ssh2_channel, sc);
  310. struct ssh2_connection_state *s = c->connlayer;
  311. PktOut *pktout = ssh2_chanreq_init(
  312. c, "shell", want_reply ? ssh2_channel_response : NULL, NULL);
  313. pq_push(s->ppl.out_pq, pktout);
  314. }
  315. void ssh2channel_start_command(
  316. SshChannel *sc, bool want_reply, const char *command)
  317. {
  318. struct ssh2_channel *c = container_of(sc, struct ssh2_channel, sc);
  319. struct ssh2_connection_state *s = c->connlayer;
  320. PktOut *pktout = ssh2_chanreq_init(
  321. c, "exec", want_reply ? ssh2_channel_response : NULL, NULL);
  322. put_stringz(pktout, command);
  323. pq_push(s->ppl.out_pq, pktout);
  324. }
  325. bool ssh2channel_start_subsystem(
  326. SshChannel *sc, bool want_reply, const char *subsystem)
  327. {
  328. struct ssh2_channel *c = container_of(sc, struct ssh2_channel, sc);
  329. struct ssh2_connection_state *s = c->connlayer;
  330. PktOut *pktout = ssh2_chanreq_init(
  331. c, "subsystem", want_reply ? ssh2_channel_response : NULL, NULL);
  332. put_stringz(pktout, subsystem);
  333. pq_push(s->ppl.out_pq, pktout);
  334. return true;
  335. }
  336. void ssh2channel_send_exit_status(SshChannel *sc, int status)
  337. {
  338. unreachable("Should never be called in the client");
  339. }
  340. void ssh2channel_send_exit_signal(
  341. SshChannel *sc, ptrlen signame, bool core_dumped, ptrlen msg)
  342. {
  343. unreachable("Should never be called in the client");
  344. }
  345. void ssh2channel_send_exit_signal_numeric(
  346. SshChannel *sc, int signum, bool core_dumped, ptrlen msg)
  347. {
  348. unreachable("Should never be called in the client");
  349. }
  350. void ssh2channel_request_x11_forwarding(
  351. SshChannel *sc, bool want_reply, const char *authproto,
  352. const char *authdata, int screen_number, bool oneshot)
  353. {
  354. struct ssh2_channel *c = container_of(sc, struct ssh2_channel, sc);
  355. struct ssh2_connection_state *s = c->connlayer;
  356. PktOut *pktout = ssh2_chanreq_init(
  357. c, "x11-req", want_reply ? ssh2_channel_response : NULL, NULL);
  358. put_bool(pktout, oneshot);
  359. put_stringz(pktout, authproto);
  360. put_stringz(pktout, authdata);
  361. put_uint32(pktout, screen_number);
  362. pq_push(s->ppl.out_pq, pktout);
  363. }
  364. void ssh2channel_request_agent_forwarding(SshChannel *sc, bool want_reply)
  365. {
  366. struct ssh2_channel *c = container_of(sc, struct ssh2_channel, sc);
  367. struct ssh2_connection_state *s = c->connlayer;
  368. PktOut *pktout = ssh2_chanreq_init(
  369. c, "[email protected]",
  370. want_reply ? ssh2_channel_response : NULL, NULL);
  371. pq_push(s->ppl.out_pq, pktout);
  372. }
  373. void ssh2channel_request_pty(
  374. SshChannel *sc, bool want_reply, Conf *conf, int w, int h)
  375. {
  376. struct ssh2_channel *c = container_of(sc, struct ssh2_channel, sc);
  377. struct ssh2_connection_state *s = c->connlayer;
  378. strbuf *modebuf;
  379. PktOut *pktout = ssh2_chanreq_init(
  380. c, "pty-req", want_reply ? ssh2_channel_response : NULL, NULL);
  381. put_stringz(pktout, conf_get_str(conf, CONF_termtype));
  382. put_uint32(pktout, w);
  383. put_uint32(pktout, h);
  384. put_uint32(pktout, 0); /* pixel width */
  385. put_uint32(pktout, 0); /* pixel height */
  386. modebuf = strbuf_new();
  387. write_ttymodes_to_packet(
  388. BinarySink_UPCAST(modebuf), 2,
  389. get_ttymodes_from_conf(s->ppl.seat, conf));
  390. put_stringsb(pktout, modebuf);
  391. pq_push(s->ppl.out_pq, pktout);
  392. }
  393. bool ssh2channel_send_env_var(
  394. SshChannel *sc, bool want_reply, const char *var, const char *value)
  395. {
  396. struct ssh2_channel *c = container_of(sc, struct ssh2_channel, sc);
  397. struct ssh2_connection_state *s = c->connlayer;
  398. PktOut *pktout = ssh2_chanreq_init(
  399. c, "env", want_reply ? ssh2_channel_response : NULL, NULL);
  400. put_stringz(pktout, var);
  401. put_stringz(pktout, value);
  402. pq_push(s->ppl.out_pq, pktout);
  403. return true;
  404. }
  405. bool ssh2channel_send_serial_break(SshChannel *sc, bool want_reply, int length)
  406. {
  407. struct ssh2_channel *c = container_of(sc, struct ssh2_channel, sc);
  408. struct ssh2_connection_state *s = c->connlayer;
  409. PktOut *pktout = ssh2_chanreq_init(
  410. c, "break", want_reply ? ssh2_channel_response : NULL, NULL);
  411. put_uint32(pktout, length);
  412. pq_push(s->ppl.out_pq, pktout);
  413. return true;
  414. }
  415. bool ssh2channel_send_signal(
  416. SshChannel *sc, bool want_reply, const char *signame)
  417. {
  418. struct ssh2_channel *c = container_of(sc, struct ssh2_channel, sc);
  419. struct ssh2_connection_state *s = c->connlayer;
  420. PktOut *pktout = ssh2_chanreq_init(
  421. c, "signal", want_reply ? ssh2_channel_response : NULL, NULL);
  422. put_stringz(pktout, signame);
  423. pq_push(s->ppl.out_pq, pktout);
  424. return true;
  425. }
  426. void ssh2channel_send_terminal_size_change(SshChannel *sc, int w, int h)
  427. {
  428. struct ssh2_channel *c = container_of(sc, struct ssh2_channel, sc);
  429. struct ssh2_connection_state *s = c->connlayer;
  430. PktOut *pktout = ssh2_chanreq_init(c, "window-change", NULL, NULL);
  431. put_uint32(pktout, w);
  432. put_uint32(pktout, h);
  433. put_uint32(pktout, 0); /* pixel width */
  434. put_uint32(pktout, 0); /* pixel height */
  435. pq_push(s->ppl.out_pq, pktout);
  436. }
  437. bool ssh2_connection_need_antispoof_prompt(struct ssh2_connection_state *s)
  438. {
  439. seat_set_trust_status(s->ppl.seat, false);
  440. if (!seat_has_mixed_input_stream(s->ppl.seat))
  441. return false;
  442. if (seat_can_set_trust_status(s->ppl.seat))
  443. return false;
  444. if (ssh_is_bare(s->ppl.ssh))
  445. return false;
  446. return true;
  447. }