sshshare.c 79 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194
  1. /*
  2. * Support for SSH connection sharing, i.e. permitting one PuTTY to
  3. * open its own channels over the SSH session being run by another.
  4. */
  5. /*
  6. * Discussion and technical documentation
  7. * ======================================
  8. *
  9. * The basic strategy for PuTTY's implementation of SSH connection
  10. * sharing is to have a single 'upstream' PuTTY process, which manages
  11. * the real SSH connection and all the cryptography, and then zero or
  12. * more 'downstream' PuTTYs, which never talk to the real host but
  13. * only talk to the upstream through local IPC (Unix-domain sockets or
  14. * Windows named pipes).
  15. *
  16. * The downstreams communicate with the upstream using a protocol
  17. * derived from SSH itself, which I'll document in detail below. In
  18. * brief, though: the downstream->upstream protocol uses a trivial
  19. * binary packet protocol (just length/type/data) to encapsulate
  20. * unencrypted SSH messages, and downstreams talk to the upstream more
  21. * or less as if it was an SSH server itself. (So downstreams can
  22. * themselves open multiple SSH channels, for example, by sending
  23. * multiple SSH2_MSG_CHANNEL_OPENs; they can send CHANNEL_REQUESTs of
  24. * their choice within each channel, and they handle their own
  25. * WINDOW_ADJUST messages.)
  26. *
  27. * The upstream would ideally handle these downstreams by just putting
  28. * their messages into the queue for proper SSH-2 encapsulation and
  29. * encryption and sending them straight on to the server. However,
  30. * that's not quite feasible as written, because client-side channel
  31. * IDs could easily conflict (between multiple downstreams, or between
  32. * a downstream and the upstream). To protect against that, the
  33. * upstream rewrites the client-side channel IDs in messages it passes
  34. * on to the server, so that it's performing what you might describe
  35. * as 'channel-number NAT'. Then the upstream remembers which of its
  36. * own channel IDs are channels it's managing itself, and which are
  37. * placeholders associated with a particular downstream, so that when
  38. * replies come in from the server they can be sent on to the relevant
  39. * downstream (after un-NATting the channel number, of course).
  40. *
  41. * Global requests from downstreams are only accepted if the upstream
  42. * knows what to do about them; currently the only such requests are
  43. * the ones having to do with remote-to-local port forwarding (in
  44. * which, again, the upstream remembers that some of the forwardings
  45. * it's asked the server to set up were on behalf of particular
  46. * downstreams, and sends the incoming CHANNEL_OPENs to those
  47. * downstreams when connections come in).
  48. *
  49. * Other fiddly pieces of this mechanism are X forwarding and
  50. * (OpenSSH-style) agent forwarding. Both of these have a fundamental
  51. * problem arising from the protocol design: that the CHANNEL_OPEN
  52. * from the server introducing a forwarded connection does not carry
  53. * any indication of which session channel gave rise to it; so if
  54. * session channels from multiple downstreams enable those forwarding
  55. * methods, it's hard for the upstream to know which downstream to
  56. * send the resulting connections back to.
  57. *
  58. * For X forwarding, we can work around this in a really painful way
  59. * by using the fake X11 authorisation data sent to the server as part
  60. * of the forwarding setup: upstream ensures that every X forwarding
  61. * request carries distinguishable fake auth data, and then when X
  62. * connections come in it waits to see the auth data in the X11 setup
  63. * message before it decides which downstream to pass the connection
  64. * on to.
  65. *
  66. * For agent forwarding, that workaround is unavailable. As a result,
  67. * this system (and, as far as I can think of, any other system too)
  68. * has the fundamental constraint that it can only forward one SSH
  69. * agent - it can't forward two agents to different session channels.
  70. * So downstreams can request agent forwarding if they like, but if
  71. * they do, they'll get whatever SSH agent is known to the upstream
  72. * (if any) forwarded to their sessions.
  73. *
  74. * Downstream-to-upstream protocol
  75. * -------------------------------
  76. *
  77. * Here I document in detail the protocol spoken between PuTTY
  78. * downstreams and upstreams over local IPC. The IPC mechanism can
  79. * vary between host platforms, but the protocol is the same.
  80. *
  81. * The protocol commences with a version exchange which is exactly
  82. * like the SSH-2 one, in that each side sends a single line of text
  83. * of the form
  84. *
  85. * <protocol>-<version>-<softwareversion> [comments] \r\n
  86. *
  87. * The only difference is that in real SSH-2, <protocol> is the string
  88. * "SSH", whereas in this protocol the string is
  89. * "[email protected]".
  90. *
  91. * (The SSH RFCs allow many protocol-level identifier namespaces to be
  92. * extended by implementors without central standardisation as long as
  93. * they suffix "@" and a domain name they control to their new ids.
  94. * RFC 4253 does not define this particular name to be changeable at
  95. * all, but I like to think this is obviously how it would have done
  96. * so if the working group had foreseen the need :-)
  97. *
  98. * Thereafter, all data exchanged consists of a sequence of binary
  99. * packets concatenated end-to-end, each of which is of the form
  100. *
  101. * uint32 length of packet, N
  102. * byte[N] N bytes of packet data
  103. *
  104. * and, since these are SSH-2 messages, the first data byte is taken
  105. * to be the packet type code.
  106. *
  107. * These messages are interpreted as those of an SSH connection, after
  108. * userauth completes, and without any repeat key exchange.
  109. * Specifically, any message from the SSH Connection Protocol is
  110. * permitted, and also SSH_MSG_IGNORE, SSH_MSG_DEBUG,
  111. * SSH_MSG_DISCONNECT and SSH_MSG_UNIMPLEMENTED from the SSH Transport
  112. * Protocol.
  113. *
  114. * This protocol imposes a few additional requirements, over and above
  115. * those of the standard SSH Connection Protocol:
  116. *
  117. * Message sizes are not permitted to exceed 0x4010 (16400) bytes,
  118. * including their length header.
  119. *
  120. * When the server (i.e. really the PuTTY upstream) sends
  121. * SSH_MSG_CHANNEL_OPEN with channel type "x11", and the client
  122. * (downstream) responds with SSH_MSG_CHANNEL_OPEN_CONFIRMATION, that
  123. * confirmation message MUST include an initial window size of at
  124. * least 256. (Rationale: this is a bit of a fudge which makes it
  125. * easier, by eliminating the possibility of nasty edge cases, for an
  126. * upstream to arrange not to pass the CHANNEL_OPEN on to downstream
  127. * until after it's seen the X11 auth data to decide which downstream
  128. * it needs to go to.)
  129. */
  130. #include <stdio.h>
  131. #include <stdlib.h>
  132. #include <assert.h>
  133. #include <limits.h>
  134. #include <errno.h>
  135. #include "putty.h"
  136. #include "tree234.h"
  137. #include "ssh.h"
  138. struct ssh_sharing_state {
  139. char *sockname; /* the socket name, kept for cleanup */
  140. Socket *listensock; /* the master listening Socket */
  141. tree234 *connections; /* holds ssh_sharing_connstates */
  142. unsigned nextid; /* preferred id for next connstate */
  143. ConnectionLayer *cl; /* instance of the ssh connection layer */
  144. char *server_verstring; /* server version string after "SSH-" */
  145. const Plug_vtable *plugvt;
  146. };
  147. struct share_globreq;
  148. struct ssh_sharing_connstate {
  149. unsigned id; /* used to identify this downstream in log messages */
  150. Socket *sock; /* the Socket for this connection */
  151. struct ssh_sharing_state *parent;
  152. int crLine; /* coroutine state for share_receive */
  153. int sent_verstring, got_verstring, curr_packetlen;
  154. unsigned char recvbuf[0x4010];
  155. int recvlen;
  156. /*
  157. * Assorted state we have to remember about this downstream, so
  158. * that we can clean it up appropriately when the downstream goes
  159. * away.
  160. */
  161. /* Channels which don't have a downstream id, i.e. we've passed a
  162. * CHANNEL_OPEN down from the server but not had an
  163. * OPEN_CONFIRMATION or OPEN_FAILURE back. If downstream goes
  164. * away, we respond to all of these with OPEN_FAILURE. */
  165. tree234 *halfchannels; /* stores 'struct share_halfchannel' */
  166. /* Channels which do have a downstream id. We need to index these
  167. * by both server id and upstream id, so we can find a channel
  168. * when handling either an upward or a downward message referring
  169. * to it. */
  170. tree234 *channels_by_us; /* stores 'struct share_channel' */
  171. tree234 *channels_by_server; /* stores 'struct share_channel' */
  172. /* Another class of channel which doesn't have a downstream id.
  173. * The difference between these and halfchannels is that xchannels
  174. * do have an *upstream* id, because upstream has already accepted
  175. * the channel request from the server. This arises in the case of
  176. * X forwarding, where we have to accept the request and read the
  177. * X authorisation data before we know whether the channel needs
  178. * to be forwarded to a downstream. */
  179. tree234 *xchannels_by_us; /* stores 'struct share_xchannel' */
  180. tree234 *xchannels_by_server; /* stores 'struct share_xchannel' */
  181. /* Remote port forwarding requests in force. */
  182. tree234 *forwardings; /* stores 'struct share_forwarding' */
  183. /* Global requests we've sent on to the server, pending replies. */
  184. struct share_globreq *globreq_head, *globreq_tail;
  185. const Plug_vtable *plugvt;
  186. };
  187. struct share_halfchannel {
  188. unsigned server_id;
  189. };
  190. /* States of a share_channel. */
  191. enum {
  192. OPEN,
  193. SENT_CLOSE,
  194. RCVD_CLOSE,
  195. /* Downstream has sent CHANNEL_OPEN but server hasn't replied yet.
  196. * If downstream goes away when a channel is in this state, we
  197. * must wait for the server's response before starting to send
  198. * CLOSE. Channels in this state are also not held in
  199. * channels_by_server, because their server_id field is
  200. * meaningless. */
  201. UNACKNOWLEDGED
  202. };
  203. struct share_channel {
  204. unsigned downstream_id, upstream_id, server_id;
  205. int downstream_maxpkt;
  206. int state;
  207. /*
  208. * Some channels (specifically, channels on which downstream has
  209. * sent "x11-req") have the additional function of storing a set
  210. * of downstream X authorisation data and a handle to an upstream
  211. * fake set.
  212. */
  213. struct X11FakeAuth *x11_auth_upstream;
  214. int x11_auth_proto;
  215. char *x11_auth_data;
  216. int x11_auth_datalen;
  217. int x11_one_shot;
  218. };
  219. struct share_forwarding {
  220. char *host;
  221. int port;
  222. int active; /* has the server sent REQUEST_SUCCESS? */
  223. struct ssh_rportfwd *rpf;
  224. };
  225. struct share_xchannel_message {
  226. struct share_xchannel_message *next;
  227. int type;
  228. unsigned char *data;
  229. int datalen;
  230. };
  231. struct share_xchannel {
  232. unsigned upstream_id, server_id;
  233. /*
  234. * xchannels come in two flavours: live and dead. Live ones are
  235. * waiting for an OPEN_CONFIRMATION or OPEN_FAILURE from
  236. * downstream; dead ones have had an OPEN_FAILURE, so they only
  237. * exist as a means of letting us conveniently respond to further
  238. * channel messages from the server until such time as the server
  239. * sends us CHANNEL_CLOSE.
  240. */
  241. int live;
  242. /*
  243. * When we receive OPEN_CONFIRMATION, we will need to send a
  244. * WINDOW_ADJUST to the server to synchronise the windows. For
  245. * this purpose we need to know what window we have so far offered
  246. * the server. We record this as exactly the value in the
  247. * OPEN_CONFIRMATION that upstream sent us, adjusted by the amount
  248. * by which the two X greetings differed in length.
  249. */
  250. int window;
  251. /*
  252. * Linked list of SSH messages from the server relating to this
  253. * channel, which we queue up until downstream sends us an
  254. * OPEN_CONFIRMATION and we can belatedly send them all on.
  255. */
  256. struct share_xchannel_message *msghead, *msgtail;
  257. };
  258. enum {
  259. GLOBREQ_TCPIP_FORWARD,
  260. GLOBREQ_CANCEL_TCPIP_FORWARD
  261. };
  262. struct share_globreq {
  263. struct share_globreq *next;
  264. int type;
  265. int want_reply;
  266. struct share_forwarding *fwd;
  267. };
  268. static int share_connstate_cmp(void *av, void *bv)
  269. {
  270. const struct ssh_sharing_connstate *a =
  271. (const struct ssh_sharing_connstate *)av;
  272. const struct ssh_sharing_connstate *b =
  273. (const struct ssh_sharing_connstate *)bv;
  274. if (a->id < b->id)
  275. return -1;
  276. else if (a->id > b->id)
  277. return +1;
  278. else
  279. return 0;
  280. }
  281. static unsigned share_find_unused_id
  282. (struct ssh_sharing_state *sharestate, unsigned first)
  283. {
  284. int low_orig, low, mid, high, high_orig;
  285. struct ssh_sharing_connstate *cs;
  286. unsigned ret;
  287. /*
  288. * Find the lowest unused downstream ID greater or equal to
  289. * 'first'.
  290. *
  291. * Begin by seeing if 'first' itself is available. If it is, we'll
  292. * just return it; if it's already in the tree, we'll find the
  293. * tree index where it appears and use that for the next stage.
  294. */
  295. {
  296. struct ssh_sharing_connstate dummy;
  297. dummy.id = first;
  298. cs = findrelpos234(sharestate->connections, &dummy, NULL,
  299. REL234_GE, &low_orig);
  300. if (!cs)
  301. return first;
  302. }
  303. /*
  304. * Now binary-search using the counted B-tree, to find the largest
  305. * ID which is in a contiguous sequence from the beginning of that
  306. * range.
  307. */
  308. low = low_orig;
  309. high = high_orig = count234(sharestate->connections);
  310. while (high - low > 1) {
  311. mid = (high + low) / 2;
  312. cs = index234(sharestate->connections, mid);
  313. if (cs->id == first + (mid - low_orig))
  314. low = mid; /* this one is still in the sequence */
  315. else
  316. high = mid; /* this one is past the end */
  317. }
  318. /*
  319. * Now low is the tree index of the largest ID in the initial
  320. * sequence. So the return value is one more than low's id, and we
  321. * know low's id is given by the formula in the binary search loop
  322. * above.
  323. *
  324. * (If an SSH connection went on for _enormously_ long, we might
  325. * reach a point where all ids from 'first' to UINT_MAX were in
  326. * use. In that situation the formula below would wrap round by
  327. * one and return zero, which is conveniently the right way to
  328. * signal 'no id available' from this function.)
  329. */
  330. ret = first + (low - low_orig) + 1;
  331. {
  332. struct ssh_sharing_connstate dummy;
  333. dummy.id = ret;
  334. assert(NULL == find234(sharestate->connections, &dummy, NULL));
  335. }
  336. return ret;
  337. }
  338. static int share_halfchannel_cmp(void *av, void *bv)
  339. {
  340. const struct share_halfchannel *a = (const struct share_halfchannel *)av;
  341. const struct share_halfchannel *b = (const struct share_halfchannel *)bv;
  342. if (a->server_id < b->server_id)
  343. return -1;
  344. else if (a->server_id > b->server_id)
  345. return +1;
  346. else
  347. return 0;
  348. }
  349. static int share_channel_us_cmp(void *av, void *bv)
  350. {
  351. const struct share_channel *a = (const struct share_channel *)av;
  352. const struct share_channel *b = (const struct share_channel *)bv;
  353. if (a->upstream_id < b->upstream_id)
  354. return -1;
  355. else if (a->upstream_id > b->upstream_id)
  356. return +1;
  357. else
  358. return 0;
  359. }
  360. static int share_channel_server_cmp(void *av, void *bv)
  361. {
  362. const struct share_channel *a = (const struct share_channel *)av;
  363. const struct share_channel *b = (const struct share_channel *)bv;
  364. if (a->server_id < b->server_id)
  365. return -1;
  366. else if (a->server_id > b->server_id)
  367. return +1;
  368. else
  369. return 0;
  370. }
  371. static int share_xchannel_us_cmp(void *av, void *bv)
  372. {
  373. const struct share_xchannel *a = (const struct share_xchannel *)av;
  374. const struct share_xchannel *b = (const struct share_xchannel *)bv;
  375. if (a->upstream_id < b->upstream_id)
  376. return -1;
  377. else if (a->upstream_id > b->upstream_id)
  378. return +1;
  379. else
  380. return 0;
  381. }
  382. static int share_xchannel_server_cmp(void *av, void *bv)
  383. {
  384. const struct share_xchannel *a = (const struct share_xchannel *)av;
  385. const struct share_xchannel *b = (const struct share_xchannel *)bv;
  386. if (a->server_id < b->server_id)
  387. return -1;
  388. else if (a->server_id > b->server_id)
  389. return +1;
  390. else
  391. return 0;
  392. }
  393. static int share_forwarding_cmp(void *av, void *bv)
  394. {
  395. const struct share_forwarding *a = (const struct share_forwarding *)av;
  396. const struct share_forwarding *b = (const struct share_forwarding *)bv;
  397. int i;
  398. if ((i = strcmp(a->host, b->host)) != 0)
  399. return i;
  400. else if (a->port < b->port)
  401. return -1;
  402. else if (a->port > b->port)
  403. return +1;
  404. else
  405. return 0;
  406. }
  407. static void share_xchannel_free(struct share_xchannel *xc)
  408. {
  409. while (xc->msghead) {
  410. struct share_xchannel_message *tmp = xc->msghead;
  411. xc->msghead = tmp->next;
  412. sfree(tmp);
  413. }
  414. sfree(xc);
  415. }
  416. static void share_connstate_free(struct ssh_sharing_connstate *cs)
  417. {
  418. struct share_halfchannel *hc;
  419. struct share_xchannel *xc;
  420. struct share_channel *chan;
  421. struct share_forwarding *fwd;
  422. while ((hc = (struct share_halfchannel *)
  423. delpos234(cs->halfchannels, 0)) != NULL)
  424. sfree(hc);
  425. freetree234(cs->halfchannels);
  426. /* All channels live in 'channels_by_us' but only some in
  427. * 'channels_by_server', so we use the former to find the list of
  428. * ones to free */
  429. freetree234(cs->channels_by_server);
  430. while ((chan = (struct share_channel *)
  431. delpos234(cs->channels_by_us, 0)) != NULL)
  432. sfree(chan);
  433. freetree234(cs->channels_by_us);
  434. /* But every xchannel is in both trees, so it doesn't matter which
  435. * we use to free them. */
  436. while ((xc = (struct share_xchannel *)
  437. delpos234(cs->xchannels_by_us, 0)) != NULL)
  438. share_xchannel_free(xc);
  439. freetree234(cs->xchannels_by_us);
  440. freetree234(cs->xchannels_by_server);
  441. while ((fwd = (struct share_forwarding *)
  442. delpos234(cs->forwardings, 0)) != NULL)
  443. sfree(fwd);
  444. freetree234(cs->forwardings);
  445. while (cs->globreq_head) {
  446. struct share_globreq *globreq = cs->globreq_head;
  447. cs->globreq_head = cs->globreq_head->next;
  448. sfree(globreq);
  449. }
  450. if (cs->sock)
  451. sk_close(cs->sock);
  452. sfree(cs);
  453. }
  454. void sharestate_free(ssh_sharing_state *sharestate)
  455. {
  456. struct ssh_sharing_connstate *cs;
  457. platform_ssh_share_cleanup(sharestate->sockname);
  458. while ((cs = (struct ssh_sharing_connstate *)
  459. delpos234(sharestate->connections, 0)) != NULL) {
  460. share_connstate_free(cs);
  461. }
  462. freetree234(sharestate->connections);
  463. if (sharestate->listensock) {
  464. sk_close(sharestate->listensock);
  465. sharestate->listensock = NULL;
  466. }
  467. sfree(sharestate->server_verstring);
  468. sfree(sharestate->sockname);
  469. sfree(sharestate);
  470. }
  471. static struct share_halfchannel *share_add_halfchannel
  472. (struct ssh_sharing_connstate *cs, unsigned server_id)
  473. {
  474. struct share_halfchannel *hc = snew(struct share_halfchannel);
  475. hc->server_id = server_id;
  476. if (add234(cs->halfchannels, hc) != hc) {
  477. /* Duplicate?! */
  478. sfree(hc);
  479. return NULL;
  480. } else {
  481. return hc;
  482. }
  483. }
  484. static struct share_halfchannel *share_find_halfchannel
  485. (struct ssh_sharing_connstate *cs, unsigned server_id)
  486. {
  487. struct share_halfchannel dummyhc;
  488. dummyhc.server_id = server_id;
  489. return find234(cs->halfchannels, &dummyhc, NULL);
  490. }
  491. static void share_remove_halfchannel(struct ssh_sharing_connstate *cs,
  492. struct share_halfchannel *hc)
  493. {
  494. del234(cs->halfchannels, hc);
  495. sfree(hc);
  496. }
  497. static struct share_channel *share_add_channel
  498. (struct ssh_sharing_connstate *cs, unsigned downstream_id,
  499. unsigned upstream_id, unsigned server_id, int state, int maxpkt)
  500. {
  501. struct share_channel *chan = snew(struct share_channel);
  502. chan->downstream_id = downstream_id;
  503. chan->upstream_id = upstream_id;
  504. chan->server_id = server_id;
  505. chan->state = state;
  506. chan->downstream_maxpkt = maxpkt;
  507. chan->x11_auth_upstream = NULL;
  508. chan->x11_auth_data = NULL;
  509. chan->x11_auth_proto = -1;
  510. chan->x11_auth_datalen = 0;
  511. chan->x11_one_shot = 0;
  512. if (add234(cs->channels_by_us, chan) != chan) {
  513. sfree(chan);
  514. return NULL;
  515. }
  516. if (chan->state != UNACKNOWLEDGED) {
  517. if (add234(cs->channels_by_server, chan) != chan) {
  518. del234(cs->channels_by_us, chan);
  519. sfree(chan);
  520. return NULL;
  521. }
  522. }
  523. return chan;
  524. }
  525. static void share_channel_set_server_id(struct ssh_sharing_connstate *cs,
  526. struct share_channel *chan,
  527. unsigned server_id, int newstate)
  528. {
  529. chan->server_id = server_id;
  530. chan->state = newstate;
  531. assert(newstate != UNACKNOWLEDGED);
  532. add234(cs->channels_by_server, chan);
  533. }
  534. static struct share_channel *share_find_channel_by_upstream
  535. (struct ssh_sharing_connstate *cs, unsigned upstream_id)
  536. {
  537. struct share_channel dummychan;
  538. dummychan.upstream_id = upstream_id;
  539. return find234(cs->channels_by_us, &dummychan, NULL);
  540. }
  541. static struct share_channel *share_find_channel_by_server
  542. (struct ssh_sharing_connstate *cs, unsigned server_id)
  543. {
  544. struct share_channel dummychan;
  545. dummychan.server_id = server_id;
  546. return find234(cs->channels_by_server, &dummychan, NULL);
  547. }
  548. static void share_remove_channel(struct ssh_sharing_connstate *cs,
  549. struct share_channel *chan)
  550. {
  551. del234(cs->channels_by_us, chan);
  552. del234(cs->channels_by_server, chan);
  553. if (chan->x11_auth_upstream)
  554. ssh_remove_sharing_x11_display(cs->parent->cl,
  555. chan->x11_auth_upstream);
  556. sfree(chan->x11_auth_data);
  557. sfree(chan);
  558. }
  559. static struct share_xchannel *share_add_xchannel
  560. (struct ssh_sharing_connstate *cs,
  561. unsigned upstream_id, unsigned server_id)
  562. {
  563. struct share_xchannel *xc = snew(struct share_xchannel);
  564. xc->upstream_id = upstream_id;
  565. xc->server_id = server_id;
  566. xc->live = TRUE;
  567. xc->msghead = xc->msgtail = NULL;
  568. if (add234(cs->xchannels_by_us, xc) != xc) {
  569. sfree(xc);
  570. return NULL;
  571. }
  572. if (add234(cs->xchannels_by_server, xc) != xc) {
  573. del234(cs->xchannels_by_us, xc);
  574. sfree(xc);
  575. return NULL;
  576. }
  577. return xc;
  578. }
  579. static struct share_xchannel *share_find_xchannel_by_upstream
  580. (struct ssh_sharing_connstate *cs, unsigned upstream_id)
  581. {
  582. struct share_xchannel dummyxc;
  583. dummyxc.upstream_id = upstream_id;
  584. return find234(cs->xchannels_by_us, &dummyxc, NULL);
  585. }
  586. static struct share_xchannel *share_find_xchannel_by_server
  587. (struct ssh_sharing_connstate *cs, unsigned server_id)
  588. {
  589. struct share_xchannel dummyxc;
  590. dummyxc.server_id = server_id;
  591. return find234(cs->xchannels_by_server, &dummyxc, NULL);
  592. }
  593. static void share_remove_xchannel(struct ssh_sharing_connstate *cs,
  594. struct share_xchannel *xc)
  595. {
  596. del234(cs->xchannels_by_us, xc);
  597. del234(cs->xchannels_by_server, xc);
  598. share_xchannel_free(xc);
  599. }
  600. static struct share_forwarding *share_add_forwarding
  601. (struct ssh_sharing_connstate *cs,
  602. const char *host, int port)
  603. {
  604. struct share_forwarding *fwd = snew(struct share_forwarding);
  605. fwd->host = dupstr(host);
  606. fwd->port = port;
  607. fwd->active = FALSE;
  608. if (add234(cs->forwardings, fwd) != fwd) {
  609. /* Duplicate?! */
  610. sfree(fwd);
  611. return NULL;
  612. }
  613. return fwd;
  614. }
  615. static struct share_forwarding *share_find_forwarding
  616. (struct ssh_sharing_connstate *cs, const char *host, int port)
  617. {
  618. struct share_forwarding dummyfwd, *ret;
  619. dummyfwd.host = dupstr(host);
  620. dummyfwd.port = port;
  621. ret = find234(cs->forwardings, &dummyfwd, NULL);
  622. sfree(dummyfwd.host);
  623. return ret;
  624. }
  625. static void share_remove_forwarding(struct ssh_sharing_connstate *cs,
  626. struct share_forwarding *fwd)
  627. {
  628. del234(cs->forwardings, fwd);
  629. sfree(fwd);
  630. }
  631. static void logeventf(Frontend *frontend, const char *fmt, ...)
  632. {
  633. va_list ap;
  634. char *buf;
  635. va_start(ap, fmt);
  636. buf = dupvprintf(fmt, ap);
  637. va_end(ap);
  638. logevent(frontend, buf);
  639. sfree(buf);
  640. }
  641. static void log_downstream(struct ssh_sharing_connstate *cs,
  642. const char *logfmt, ...)
  643. {
  644. va_list ap;
  645. char *buf;
  646. va_start(ap, logfmt);
  647. buf = dupvprintf(logfmt, ap);
  648. va_end(ap);
  649. logeventf(cs->parent->cl->frontend,
  650. "Connection sharing downstream #%u: %s", cs->id, buf);
  651. sfree(buf);
  652. }
  653. static void log_general(struct ssh_sharing_state *sharestate,
  654. const char *logfmt, ...)
  655. {
  656. va_list ap;
  657. char *buf;
  658. va_start(ap, logfmt);
  659. buf = dupvprintf(logfmt, ap);
  660. va_end(ap);
  661. logeventf(sharestate->cl->frontend, "Connection sharing: %s", buf);
  662. sfree(buf);
  663. }
  664. static void send_packet_to_downstream(struct ssh_sharing_connstate *cs,
  665. int type, const void *pkt, int pktlen,
  666. struct share_channel *chan)
  667. {
  668. strbuf *packet;
  669. if (!cs->sock) /* throw away all packets destined for a dead downstream */
  670. return;
  671. if (type == SSH2_MSG_CHANNEL_DATA) {
  672. /*
  673. * Special case which we take care of at a low level, so as to
  674. * be sure to apply it in all cases. On rare occasions we
  675. * might find that we have a channel for which the
  676. * downstream's maximum packet size exceeds the max packet
  677. * size we presented to the server on its behalf. (This can
  678. * occur in X11 forwarding, where we have to send _our_
  679. * CHANNEL_OPEN_CONFIRMATION before we discover which if any
  680. * downstream the channel is destined for, so if that
  681. * downstream turns out to present a smaller max packet size
  682. * then we're in this situation.)
  683. *
  684. * If that happens, we just chop up the packet into pieces and
  685. * send them as separate CHANNEL_DATA packets.
  686. */
  687. BinarySource src[1];
  688. unsigned channel;
  689. ptrlen data;
  690. BinarySource_BARE_INIT(src, pkt, pktlen);
  691. channel = get_uint32(src);
  692. data = get_string(src);
  693. do {
  694. int this_len = (data.len > chan->downstream_maxpkt ?
  695. chan->downstream_maxpkt : data.len);
  696. packet = strbuf_new();
  697. put_uint32(packet, 0); /* placeholder for length field */
  698. put_byte(packet, type);
  699. put_uint32(packet, channel);
  700. put_uint32(packet, this_len);
  701. put_data(packet, data.ptr, this_len);
  702. data.ptr = (const char *)data.ptr + this_len;
  703. data.len -= this_len;
  704. PUT_32BIT(packet->s, packet->len-4);
  705. sk_write(cs->sock, packet->s, packet->len);
  706. strbuf_free(packet);
  707. } while (data.len > 0);
  708. } else {
  709. /*
  710. * Just do the obvious thing.
  711. */
  712. packet = strbuf_new();
  713. put_uint32(packet, 0); /* placeholder for length field */
  714. put_byte(packet, type);
  715. put_data(packet, pkt, pktlen);
  716. PUT_32BIT(packet->s, packet->len-4);
  717. sk_write(cs->sock, packet->s, packet->len);
  718. strbuf_free(packet);
  719. }
  720. }
  721. static void share_try_cleanup(struct ssh_sharing_connstate *cs)
  722. {
  723. int i;
  724. struct share_halfchannel *hc;
  725. struct share_channel *chan;
  726. struct share_forwarding *fwd;
  727. /*
  728. * Any half-open channels, i.e. those for which we'd received
  729. * CHANNEL_OPEN from the server but not passed back a response
  730. * from downstream, should be responded to with OPEN_FAILURE.
  731. */
  732. while ((hc = (struct share_halfchannel *)
  733. index234(cs->halfchannels, 0)) != NULL) {
  734. static const char reason[] = "PuTTY downstream no longer available";
  735. static const char lang[] = "en";
  736. strbuf *packet;
  737. packet = strbuf_new();
  738. put_uint32(packet, hc->server_id);
  739. put_uint32(packet, SSH2_OPEN_CONNECT_FAILED);
  740. put_stringz(packet, reason);
  741. put_stringz(packet, lang);
  742. ssh_send_packet_from_downstream(
  743. cs->parent->cl, cs->id, SSH2_MSG_CHANNEL_OPEN_FAILURE,
  744. packet->s, packet->len,
  745. "cleanup after downstream went away");
  746. strbuf_free(packet);
  747. share_remove_halfchannel(cs, hc);
  748. }
  749. /*
  750. * Any actually open channels should have a CHANNEL_CLOSE sent for
  751. * them, unless we've already done so. We won't be able to
  752. * actually clean them up until CHANNEL_CLOSE comes back from the
  753. * server, though (unless the server happens to have sent a CLOSE
  754. * already).
  755. *
  756. * Another annoying exception is UNACKNOWLEDGED channels, i.e.
  757. * we've _sent_ a CHANNEL_OPEN to the server but not received an
  758. * OPEN_CONFIRMATION or OPEN_FAILURE. We must wait for a reply
  759. * before closing the channel, because until we see that reply we
  760. * won't have the server's channel id to put in the close message.
  761. */
  762. for (i = 0; (chan = (struct share_channel *)
  763. index234(cs->channels_by_us, i)) != NULL; i++) {
  764. strbuf *packet;
  765. if (chan->state != SENT_CLOSE && chan->state != UNACKNOWLEDGED) {
  766. packet = strbuf_new();
  767. put_uint32(packet, chan->server_id);
  768. ssh_send_packet_from_downstream(
  769. cs->parent->cl, cs->id, SSH2_MSG_CHANNEL_CLOSE,
  770. packet->s, packet->len,
  771. "cleanup after downstream went away");
  772. strbuf_free(packet);
  773. if (chan->state != RCVD_CLOSE) {
  774. chan->state = SENT_CLOSE;
  775. } else {
  776. /* In this case, we _can_ clear up the channel now. */
  777. ssh_delete_sharing_channel(cs->parent->cl, chan->upstream_id);
  778. share_remove_channel(cs, chan);
  779. i--; /* don't accidentally skip one as a result */
  780. }
  781. }
  782. }
  783. /*
  784. * Any remote port forwardings we're managing on behalf of this
  785. * downstream should be cancelled. Again, we must defer those for
  786. * which we haven't yet seen REQUEST_SUCCESS/FAILURE.
  787. *
  788. * We take a fire-and-forget approach during cleanup, not
  789. * bothering to set want_reply.
  790. */
  791. for (i = 0; (fwd = (struct share_forwarding *)
  792. index234(cs->forwardings, i)) != NULL; i++) {
  793. if (fwd->active) {
  794. strbuf *packet = strbuf_new();
  795. put_stringz(packet, "cancel-tcpip-forward");
  796. put_bool(packet, FALSE); /* !want_reply */
  797. put_stringz(packet, fwd->host);
  798. put_uint32(packet, fwd->port);
  799. ssh_send_packet_from_downstream(
  800. cs->parent->cl, cs->id, SSH2_MSG_GLOBAL_REQUEST,
  801. packet->s, packet->len,
  802. "cleanup after downstream went away");
  803. strbuf_free(packet);
  804. ssh_rportfwd_remove(cs->parent->cl, fwd->rpf);
  805. share_remove_forwarding(cs, fwd);
  806. i--; /* don't accidentally skip one as a result */
  807. }
  808. }
  809. if (count234(cs->halfchannels) == 0 &&
  810. count234(cs->channels_by_us) == 0 &&
  811. count234(cs->forwardings) == 0) {
  812. struct ssh_sharing_state *sharestate = cs->parent;
  813. /*
  814. * Now we're _really_ done, so we can get rid of cs completely.
  815. */
  816. del234(sharestate->connections, cs);
  817. log_downstream(cs, "disconnected");
  818. share_connstate_free(cs);
  819. /*
  820. * And if this was the last downstream, notify the connection
  821. * layer, because it might now be time to wind up the whole
  822. * SSH connection.
  823. */
  824. if (count234(sharestate->connections) == 0 && sharestate->cl)
  825. ssh_sharing_no_more_downstreams(sharestate->cl);
  826. }
  827. }
  828. static void share_begin_cleanup(struct ssh_sharing_connstate *cs)
  829. {
  830. sk_close(cs->sock);
  831. cs->sock = NULL;
  832. share_try_cleanup(cs);
  833. }
  834. static void share_disconnect(struct ssh_sharing_connstate *cs,
  835. const char *message)
  836. {
  837. strbuf *packet = strbuf_new();
  838. put_uint32(packet, SSH2_DISCONNECT_PROTOCOL_ERROR);
  839. put_stringz(packet, message);
  840. put_stringz(packet, "en"); /* language */
  841. send_packet_to_downstream(cs, SSH2_MSG_DISCONNECT,
  842. packet->s, packet->len, NULL);
  843. strbuf_free(packet);
  844. share_begin_cleanup(cs);
  845. }
  846. static void share_closing(Plug *plug, const char *error_msg, int error_code,
  847. int calling_back)
  848. {
  849. struct ssh_sharing_connstate *cs = FROMFIELD(
  850. plug, struct ssh_sharing_connstate, plugvt);
  851. if (error_msg) {
  852. #ifdef BROKEN_PIPE_ERROR_CODE
  853. /*
  854. * Most of the time, we log what went wrong when a downstream
  855. * disappears with a socket error. One exception, though, is
  856. * receiving EPIPE when we haven't received a protocol version
  857. * string from the downstream, because that can happen as a result
  858. * of plink -shareexists (opening the connection and instantly
  859. * closing it again without bothering to read our version string).
  860. * So that one case is not treated as a log-worthy error.
  861. */
  862. if (error_code == BROKEN_PIPE_ERROR_CODE && !cs->got_verstring)
  863. /* do nothing */;
  864. else
  865. #endif
  866. log_downstream(cs, "Socket error: %s", error_msg);
  867. }
  868. share_begin_cleanup(cs);
  869. }
  870. /*
  871. * Append a message to the end of an xchannel's queue.
  872. */
  873. static void share_xchannel_add_message(
  874. struct share_xchannel *xc, int type, const void *data, int len)
  875. {
  876. struct share_xchannel_message *msg;
  877. /*
  878. * Allocate the 'struct share_xchannel_message' and the actual
  879. * data in one unit.
  880. */
  881. msg = snew_plus(struct share_xchannel_message, len);
  882. msg->data = snew_plus_get_aux(msg);
  883. msg->datalen = len;
  884. msg->type = type;
  885. memcpy(msg->data, data, len);
  886. /*
  887. * Queue it in the xchannel.
  888. */
  889. if (xc->msgtail)
  890. xc->msgtail->next = msg;
  891. else
  892. xc->msghead = msg;
  893. msg->next = NULL;
  894. xc->msgtail = msg;
  895. }
  896. void share_dead_xchannel_respond(struct ssh_sharing_connstate *cs,
  897. struct share_xchannel *xc)
  898. {
  899. /*
  900. * Handle queued incoming messages from the server destined for an
  901. * xchannel which is dead (i.e. downstream sent OPEN_FAILURE).
  902. */
  903. int delete = FALSE;
  904. while (xc->msghead) {
  905. struct share_xchannel_message *msg = xc->msghead;
  906. xc->msghead = msg->next;
  907. if (msg->type == SSH2_MSG_CHANNEL_REQUEST && msg->datalen > 4) {
  908. /*
  909. * A CHANNEL_REQUEST is responded to by sending
  910. * CHANNEL_FAILURE, if it has want_reply set.
  911. */
  912. BinarySource src[1];
  913. BinarySource_BARE_INIT(src, msg->data, msg->datalen);
  914. get_uint32(src); /* skip channel id */
  915. get_string(src); /* skip request type */
  916. if (get_bool(src)) {
  917. strbuf *packet = strbuf_new();
  918. put_uint32(packet, xc->server_id);
  919. ssh_send_packet_from_downstream
  920. (cs->parent->cl, cs->id, SSH2_MSG_CHANNEL_FAILURE,
  921. packet->s, packet->len,
  922. "downstream refused X channel open");
  923. strbuf_free(packet);
  924. }
  925. } else if (msg->type == SSH2_MSG_CHANNEL_CLOSE) {
  926. /*
  927. * On CHANNEL_CLOSE we can discard the channel completely.
  928. */
  929. delete = TRUE;
  930. }
  931. sfree(msg);
  932. }
  933. xc->msgtail = NULL;
  934. if (delete) {
  935. ssh_delete_sharing_channel(cs->parent->cl, xc->upstream_id);
  936. share_remove_xchannel(cs, xc);
  937. }
  938. }
  939. void share_xchannel_confirmation(struct ssh_sharing_connstate *cs,
  940. struct share_xchannel *xc,
  941. struct share_channel *chan,
  942. unsigned downstream_window)
  943. {
  944. strbuf *packet;
  945. /*
  946. * Send all the queued messages downstream.
  947. */
  948. while (xc->msghead) {
  949. struct share_xchannel_message *msg = xc->msghead;
  950. xc->msghead = msg->next;
  951. if (msg->datalen >= 4)
  952. PUT_32BIT(msg->data, chan->downstream_id);
  953. send_packet_to_downstream(cs, msg->type,
  954. msg->data, msg->datalen, chan);
  955. sfree(msg);
  956. }
  957. /*
  958. * Send a WINDOW_ADJUST back upstream, to synchronise the window
  959. * size downstream thinks it's presented with the one we've
  960. * actually presented.
  961. */
  962. packet = strbuf_new();
  963. put_uint32(packet, xc->server_id);
  964. put_uint32(packet, downstream_window - xc->window);
  965. ssh_send_packet_from_downstream(
  966. cs->parent->cl, cs->id, SSH2_MSG_CHANNEL_WINDOW_ADJUST,
  967. packet->s, packet->len,
  968. "window adjustment after downstream accepted X channel");
  969. strbuf_free(packet);
  970. }
  971. void share_xchannel_failure(struct ssh_sharing_connstate *cs,
  972. struct share_xchannel *xc)
  973. {
  974. /*
  975. * If downstream refuses to open our X channel at all for some
  976. * reason, we must respond by sending an emergency CLOSE upstream.
  977. */
  978. strbuf *packet = strbuf_new();
  979. put_uint32(packet, xc->server_id);
  980. ssh_send_packet_from_downstream(
  981. cs->parent->cl, cs->id, SSH2_MSG_CHANNEL_CLOSE,
  982. packet->s, packet->len,
  983. "downstream refused X channel open");
  984. strbuf_free(packet);
  985. /*
  986. * Now mark the xchannel as dead, and respond to anything sent on
  987. * it until we see CLOSE for it in turn.
  988. */
  989. xc->live = FALSE;
  990. share_dead_xchannel_respond(cs, xc);
  991. }
  992. void share_setup_x11_channel(ssh_sharing_connstate *cs, share_channel *chan,
  993. unsigned upstream_id, unsigned server_id,
  994. unsigned server_currwin, unsigned server_maxpkt,
  995. unsigned client_adjusted_window,
  996. const char *peer_addr, int peer_port, int endian,
  997. int protomajor, int protominor,
  998. const void *initial_data, int initial_len)
  999. {
  1000. struct share_xchannel *xc;
  1001. void *greeting;
  1002. int greeting_len;
  1003. strbuf *packet;
  1004. /*
  1005. * Create an xchannel containing data we've already received from
  1006. * the X client, and preload it with a CHANNEL_DATA message
  1007. * containing our own made-up authorisation greeting and any
  1008. * additional data sent from the server so far.
  1009. */
  1010. xc = share_add_xchannel(cs, upstream_id, server_id);
  1011. greeting = x11_make_greeting(endian, protomajor, protominor,
  1012. chan->x11_auth_proto,
  1013. chan->x11_auth_data, chan->x11_auth_datalen,
  1014. peer_addr, peer_port, &greeting_len);
  1015. packet = strbuf_new();
  1016. put_uint32(packet, 0); /* leave the channel id field unfilled - we
  1017. * don't know the downstream id yet */
  1018. put_uint32(packet, greeting_len + initial_len);
  1019. put_data(packet, greeting, greeting_len);
  1020. put_data(packet, initial_data, initial_len);
  1021. sfree(greeting);
  1022. share_xchannel_add_message(xc, SSH2_MSG_CHANNEL_DATA,
  1023. packet->s, packet->len);
  1024. strbuf_free(packet);
  1025. xc->window = client_adjusted_window + greeting_len;
  1026. /*
  1027. * Send on a CHANNEL_OPEN to downstream.
  1028. */
  1029. packet = strbuf_new();
  1030. put_stringz(packet, "x11");
  1031. put_uint32(packet, server_id);
  1032. put_uint32(packet, server_currwin);
  1033. put_uint32(packet, server_maxpkt);
  1034. put_stringz(packet, peer_addr);
  1035. put_uint32(packet, peer_port);
  1036. send_packet_to_downstream(cs, SSH2_MSG_CHANNEL_OPEN,
  1037. packet->s, packet->len, NULL);
  1038. strbuf_free(packet);
  1039. /*
  1040. * If this was a once-only X forwarding, clean it up now.
  1041. */
  1042. if (chan->x11_one_shot) {
  1043. ssh_remove_sharing_x11_display(cs->parent->cl,
  1044. chan->x11_auth_upstream);
  1045. chan->x11_auth_upstream = NULL;
  1046. sfree(chan->x11_auth_data);
  1047. chan->x11_auth_proto = -1;
  1048. chan->x11_auth_datalen = 0;
  1049. chan->x11_one_shot = 0;
  1050. }
  1051. }
  1052. void share_got_pkt_from_server(ssh_sharing_connstate *cs, int type,
  1053. const void *vpkt, int pktlen)
  1054. {
  1055. const unsigned char *pkt = (const unsigned char *)vpkt;
  1056. struct share_globreq *globreq;
  1057. size_t id_pos;
  1058. unsigned upstream_id, server_id;
  1059. struct share_channel *chan;
  1060. struct share_xchannel *xc;
  1061. BinarySource src[1];
  1062. BinarySource_BARE_INIT(src, pkt, pktlen);
  1063. switch (type) {
  1064. case SSH2_MSG_REQUEST_SUCCESS:
  1065. case SSH2_MSG_REQUEST_FAILURE:
  1066. globreq = cs->globreq_head;
  1067. assert(globreq); /* should match the queue in ssh.c */
  1068. if (globreq->type == GLOBREQ_TCPIP_FORWARD) {
  1069. if (type == SSH2_MSG_REQUEST_FAILURE) {
  1070. share_remove_forwarding(cs, globreq->fwd);
  1071. } else {
  1072. globreq->fwd->active = TRUE;
  1073. }
  1074. } else if (globreq->type == GLOBREQ_CANCEL_TCPIP_FORWARD) {
  1075. if (type == SSH2_MSG_REQUEST_SUCCESS) {
  1076. share_remove_forwarding(cs, globreq->fwd);
  1077. }
  1078. }
  1079. if (globreq->want_reply) {
  1080. send_packet_to_downstream(cs, type, pkt, pktlen, NULL);
  1081. }
  1082. cs->globreq_head = globreq->next;
  1083. sfree(globreq);
  1084. if (cs->globreq_head == NULL)
  1085. cs->globreq_tail = NULL;
  1086. if (!cs->sock) {
  1087. /* Retry cleaning up this connection, in case that reply
  1088. * was the last thing we were waiting for. */
  1089. share_try_cleanup(cs);
  1090. }
  1091. break;
  1092. case SSH2_MSG_CHANNEL_OPEN:
  1093. get_string(src);
  1094. server_id = get_uint32(src);
  1095. assert(!get_err(src));
  1096. share_add_halfchannel(cs, server_id);
  1097. send_packet_to_downstream(cs, type, pkt, pktlen, NULL);
  1098. break;
  1099. case SSH2_MSG_CHANNEL_OPEN_CONFIRMATION:
  1100. case SSH2_MSG_CHANNEL_OPEN_FAILURE:
  1101. case SSH2_MSG_CHANNEL_CLOSE:
  1102. case SSH2_MSG_CHANNEL_WINDOW_ADJUST:
  1103. case SSH2_MSG_CHANNEL_DATA:
  1104. case SSH2_MSG_CHANNEL_EXTENDED_DATA:
  1105. case SSH2_MSG_CHANNEL_EOF:
  1106. case SSH2_MSG_CHANNEL_REQUEST:
  1107. case SSH2_MSG_CHANNEL_SUCCESS:
  1108. case SSH2_MSG_CHANNEL_FAILURE:
  1109. /*
  1110. * All these messages have the recipient channel id as the
  1111. * first uint32 field in the packet. Substitute the downstream
  1112. * channel id for our one and pass the packet downstream.
  1113. */
  1114. id_pos = src->pos;
  1115. upstream_id = get_uint32(src);
  1116. if ((chan = share_find_channel_by_upstream(cs, upstream_id)) != NULL) {
  1117. /*
  1118. * The normal case: this id refers to an open channel.
  1119. */
  1120. unsigned char *rewritten = snewn(pktlen, unsigned char);
  1121. memcpy(rewritten, pkt, pktlen);
  1122. PUT_32BIT(rewritten + id_pos, chan->downstream_id);
  1123. send_packet_to_downstream(cs, type, rewritten, pktlen, chan);
  1124. sfree(rewritten);
  1125. /*
  1126. * Update the channel state, for messages that need it.
  1127. */
  1128. if (type == SSH2_MSG_CHANNEL_OPEN_CONFIRMATION) {
  1129. if (chan->state == UNACKNOWLEDGED && pktlen >= 8) {
  1130. share_channel_set_server_id(cs, chan, GET_32BIT(pkt+4),
  1131. OPEN);
  1132. if (!cs->sock) {
  1133. /* Retry cleaning up this connection, so that we
  1134. * can send an immediate CLOSE on this channel for
  1135. * which we now know the server id. */
  1136. share_try_cleanup(cs);
  1137. }
  1138. }
  1139. } else if (type == SSH2_MSG_CHANNEL_OPEN_FAILURE) {
  1140. ssh_delete_sharing_channel(cs->parent->cl, chan->upstream_id);
  1141. share_remove_channel(cs, chan);
  1142. } else if (type == SSH2_MSG_CHANNEL_CLOSE) {
  1143. if (chan->state == SENT_CLOSE) {
  1144. ssh_delete_sharing_channel(cs->parent->cl,
  1145. chan->upstream_id);
  1146. share_remove_channel(cs, chan);
  1147. if (!cs->sock) {
  1148. /* Retry cleaning up this connection, in case this
  1149. * channel closure was the last thing we were
  1150. * waiting for. */
  1151. share_try_cleanup(cs);
  1152. }
  1153. } else {
  1154. chan->state = RCVD_CLOSE;
  1155. }
  1156. }
  1157. } else if ((xc = share_find_xchannel_by_upstream(cs, upstream_id))
  1158. != NULL) {
  1159. /*
  1160. * The unusual case: this id refers to an xchannel. Add it
  1161. * to the xchannel's queue.
  1162. */
  1163. share_xchannel_add_message(xc, type, pkt, pktlen);
  1164. /* If the xchannel is dead, then also respond to it (which
  1165. * may involve deleting the channel). */
  1166. if (!xc->live)
  1167. share_dead_xchannel_respond(cs, xc);
  1168. }
  1169. break;
  1170. default:
  1171. assert(!"This packet type should never have come from ssh.c");
  1172. break;
  1173. }
  1174. }
  1175. static void share_got_pkt_from_downstream(struct ssh_sharing_connstate *cs,
  1176. int type,
  1177. unsigned char *pkt, int pktlen)
  1178. {
  1179. ptrlen request_name;
  1180. struct share_forwarding *fwd;
  1181. size_t id_pos;
  1182. unsigned maxpkt;
  1183. unsigned old_id, new_id, server_id;
  1184. struct share_globreq *globreq;
  1185. struct share_channel *chan;
  1186. struct share_halfchannel *hc;
  1187. struct share_xchannel *xc;
  1188. strbuf *packet;
  1189. char *err = NULL;
  1190. BinarySource src[1];
  1191. size_t wantreplypos;
  1192. int orig_wantreply;
  1193. BinarySource_BARE_INIT(src, pkt, pktlen);
  1194. switch (type) {
  1195. case SSH2_MSG_DISCONNECT:
  1196. /*
  1197. * This message stops here: if downstream is disconnecting
  1198. * from us, that doesn't mean we want to disconnect from the
  1199. * SSH server. Close the downstream connection and start
  1200. * cleanup.
  1201. */
  1202. share_begin_cleanup(cs);
  1203. break;
  1204. case SSH2_MSG_GLOBAL_REQUEST:
  1205. /*
  1206. * The only global requests we understand are "tcpip-forward"
  1207. * and "cancel-tcpip-forward". Since those require us to
  1208. * maintain state, we must assume that other global requests
  1209. * will probably require that too, and so we don't forward on
  1210. * any request we don't understand.
  1211. */
  1212. request_name = get_string(src);
  1213. wantreplypos = src->pos;
  1214. orig_wantreply = get_bool(src);
  1215. if (ptrlen_eq_string(request_name, "tcpip-forward")) {
  1216. ptrlen hostpl;
  1217. char *host;
  1218. int port;
  1219. struct ssh_rportfwd *rpf;
  1220. /*
  1221. * Pick the packet apart to find the want_reply field and
  1222. * the host/port we're going to ask to listen on.
  1223. */
  1224. hostpl = get_string(src);
  1225. port = toint(get_uint32(src));
  1226. if (get_err(src)) {
  1227. err = dupprintf("Truncated GLOBAL_REQUEST packet");
  1228. goto confused;
  1229. }
  1230. host = mkstr(hostpl);
  1231. /*
  1232. * See if we can allocate space in ssh.c's tree of remote
  1233. * port forwardings. If we can't, it's because another
  1234. * client sharing this connection has already allocated
  1235. * the identical port forwarding, so we take it on
  1236. * ourselves to manufacture a failure packet and send it
  1237. * back to downstream.
  1238. */
  1239. rpf = ssh_rportfwd_alloc(
  1240. cs->parent->cl, host, port, NULL, 0, 0, NULL, NULL, cs);
  1241. if (!rpf) {
  1242. if (orig_wantreply) {
  1243. send_packet_to_downstream(cs, SSH2_MSG_REQUEST_FAILURE,
  1244. "", 0, NULL);
  1245. }
  1246. } else {
  1247. /*
  1248. * We've managed to make space for this forwarding
  1249. * locally. Pass the request on to the SSH server, but
  1250. * set want_reply even if it wasn't originally set, so
  1251. * that we know whether this forwarding needs to be
  1252. * cleaned up if downstream goes away.
  1253. */
  1254. pkt[wantreplypos] = 1;
  1255. ssh_send_packet_from_downstream
  1256. (cs->parent->cl, cs->id, type, pkt, pktlen,
  1257. orig_wantreply ? NULL : "upstream added want_reply flag");
  1258. fwd = share_add_forwarding(cs, host, port);
  1259. ssh_sharing_queue_global_request(cs->parent->cl, cs);
  1260. if (fwd) {
  1261. globreq = snew(struct share_globreq);
  1262. globreq->next = NULL;
  1263. if (cs->globreq_tail)
  1264. cs->globreq_tail->next = globreq;
  1265. else
  1266. cs->globreq_head = globreq;
  1267. globreq->fwd = fwd;
  1268. globreq->want_reply = orig_wantreply;
  1269. globreq->type = GLOBREQ_TCPIP_FORWARD;
  1270. fwd->rpf = rpf;
  1271. }
  1272. }
  1273. sfree(host);
  1274. } else if (ptrlen_eq_string(request_name, "cancel-tcpip-forward")) {
  1275. ptrlen hostpl;
  1276. char *host;
  1277. int port;
  1278. struct share_forwarding *fwd;
  1279. /*
  1280. * Pick the packet apart to find the want_reply field and
  1281. * the host/port we're going to ask to listen on.
  1282. */
  1283. hostpl = get_string(src);
  1284. port = toint(get_uint32(src));
  1285. if (get_err(src)) {
  1286. err = dupprintf("Truncated GLOBAL_REQUEST packet");
  1287. goto confused;
  1288. }
  1289. host = mkstr(hostpl);
  1290. /*
  1291. * Look up the existing forwarding with these details.
  1292. */
  1293. fwd = share_find_forwarding(cs, host, port);
  1294. if (!fwd) {
  1295. if (orig_wantreply) {
  1296. send_packet_to_downstream(cs, SSH2_MSG_REQUEST_FAILURE,
  1297. "", 0, NULL);
  1298. }
  1299. } else {
  1300. /*
  1301. * Tell ssh.c to stop sending us channel-opens for
  1302. * this forwarding.
  1303. */
  1304. ssh_rportfwd_remove(cs->parent->cl, fwd->rpf);
  1305. /*
  1306. * Pass the cancel request on to the SSH server, but
  1307. * set want_reply even if it wasn't originally set, so
  1308. * that _we_ know whether the forwarding has been
  1309. * deleted even if downstream doesn't want to know.
  1310. */
  1311. pkt[wantreplypos] = 1;
  1312. ssh_send_packet_from_downstream
  1313. (cs->parent->cl, cs->id, type, pkt, pktlen,
  1314. orig_wantreply ? NULL : "upstream added want_reply flag");
  1315. ssh_sharing_queue_global_request(cs->parent->cl, cs);
  1316. /*
  1317. * And queue a globreq so that when the reply comes
  1318. * back we know to cancel it.
  1319. */
  1320. globreq = snew(struct share_globreq);
  1321. globreq->next = NULL;
  1322. if (cs->globreq_tail)
  1323. cs->globreq_tail->next = globreq;
  1324. else
  1325. cs->globreq_head = globreq;
  1326. globreq->fwd = fwd;
  1327. globreq->want_reply = orig_wantreply;
  1328. globreq->type = GLOBREQ_CANCEL_TCPIP_FORWARD;
  1329. }
  1330. sfree(host);
  1331. } else {
  1332. /*
  1333. * Request we don't understand. Manufacture a failure
  1334. * message if an answer was required.
  1335. */
  1336. if (orig_wantreply)
  1337. send_packet_to_downstream(cs, SSH2_MSG_REQUEST_FAILURE,
  1338. "", 0, NULL);
  1339. }
  1340. break;
  1341. case SSH2_MSG_CHANNEL_OPEN:
  1342. /* Sender channel id comes after the channel type string */
  1343. get_string(src);
  1344. id_pos = src->pos;
  1345. old_id = get_uint32(src);
  1346. new_id = ssh_alloc_sharing_channel(cs->parent->cl, cs);
  1347. get_uint32(src); /* skip initial window size */
  1348. maxpkt = get_uint32(src);
  1349. if (get_err(src)) {
  1350. err = dupprintf("Truncated CHANNEL_OPEN packet");
  1351. goto confused;
  1352. }
  1353. share_add_channel(cs, old_id, new_id, 0, UNACKNOWLEDGED, maxpkt);
  1354. PUT_32BIT(pkt + id_pos, new_id);
  1355. ssh_send_packet_from_downstream(cs->parent->cl, cs->id,
  1356. type, pkt, pktlen, NULL);
  1357. break;
  1358. case SSH2_MSG_CHANNEL_OPEN_CONFIRMATION:
  1359. if (pktlen < 16) {
  1360. err = dupprintf("Truncated CHANNEL_OPEN_CONFIRMATION packet");
  1361. goto confused;
  1362. }
  1363. server_id = get_uint32(src);
  1364. id_pos = src->pos;
  1365. old_id = get_uint32(src);
  1366. get_uint32(src); /* skip initial window size */
  1367. maxpkt = get_uint32(src);
  1368. if (get_err(src)) {
  1369. err = dupprintf("Truncated CHANNEL_OPEN_CONFIRMATION packet");
  1370. goto confused;
  1371. }
  1372. /* This server id may refer to either a halfchannel or an xchannel. */
  1373. hc = NULL, xc = NULL; /* placate optimiser */
  1374. if ((hc = share_find_halfchannel(cs, server_id)) != NULL) {
  1375. new_id = ssh_alloc_sharing_channel(cs->parent->cl, cs);
  1376. } else if ((xc = share_find_xchannel_by_server(cs, server_id))
  1377. != NULL) {
  1378. new_id = xc->upstream_id;
  1379. } else {
  1380. err = dupprintf("CHANNEL_OPEN_CONFIRMATION packet cited unknown channel %u", (unsigned)server_id);
  1381. goto confused;
  1382. }
  1383. PUT_32BIT(pkt + id_pos, new_id);
  1384. chan = share_add_channel(cs, old_id, new_id, server_id, OPEN, maxpkt);
  1385. if (hc) {
  1386. ssh_send_packet_from_downstream(cs->parent->cl, cs->id,
  1387. type, pkt, pktlen, NULL);
  1388. share_remove_halfchannel(cs, hc);
  1389. } else if (xc) {
  1390. unsigned downstream_window = GET_32BIT(pkt + 8);
  1391. if (downstream_window < 256) {
  1392. err = dupprintf("Initial window size for x11 channel must be at least 256 (got %u)", downstream_window);
  1393. goto confused;
  1394. }
  1395. share_xchannel_confirmation(cs, xc, chan, downstream_window);
  1396. share_remove_xchannel(cs, xc);
  1397. }
  1398. break;
  1399. case SSH2_MSG_CHANNEL_OPEN_FAILURE:
  1400. server_id = get_uint32(src);
  1401. if (get_err(src)) {
  1402. err = dupprintf("Truncated CHANNEL_OPEN_FAILURE packet");
  1403. goto confused;
  1404. }
  1405. /* This server id may refer to either a halfchannel or an xchannel. */
  1406. if ((hc = share_find_halfchannel(cs, server_id)) != NULL) {
  1407. ssh_send_packet_from_downstream(cs->parent->cl, cs->id,
  1408. type, pkt, pktlen, NULL);
  1409. share_remove_halfchannel(cs, hc);
  1410. } else if ((xc = share_find_xchannel_by_server(cs, server_id))
  1411. != NULL) {
  1412. share_xchannel_failure(cs, xc);
  1413. } else {
  1414. err = dupprintf("CHANNEL_OPEN_FAILURE packet cited unknown channel %u", (unsigned)server_id);
  1415. goto confused;
  1416. }
  1417. break;
  1418. case SSH2_MSG_CHANNEL_WINDOW_ADJUST:
  1419. case SSH2_MSG_CHANNEL_DATA:
  1420. case SSH2_MSG_CHANNEL_EXTENDED_DATA:
  1421. case SSH2_MSG_CHANNEL_EOF:
  1422. case SSH2_MSG_CHANNEL_CLOSE:
  1423. case SSH2_MSG_CHANNEL_REQUEST:
  1424. case SSH2_MSG_CHANNEL_SUCCESS:
  1425. case SSH2_MSG_CHANNEL_FAILURE:
  1426. case SSH2_MSG_IGNORE:
  1427. case SSH2_MSG_DEBUG:
  1428. server_id = get_uint32(src);
  1429. if (type == SSH2_MSG_CHANNEL_REQUEST) {
  1430. request_name = get_string(src);
  1431. /*
  1432. * Agent forwarding requests from downstream are treated
  1433. * specially. Because OpenSSHD doesn't let us enable agent
  1434. * forwarding independently per session channel, and in
  1435. * particular because the OpenSSH-defined agent forwarding
  1436. * protocol does not mark agent-channel requests with the
  1437. * id of the session channel they originate from, the only
  1438. * way we can implement agent forwarding in a
  1439. * connection-shared PuTTY is to forward the _upstream_
  1440. * agent. Hence, we unilaterally deny agent forwarding
  1441. * requests from downstreams if we aren't prepared to
  1442. * forward an agent ourselves.
  1443. *
  1444. * (If we are, then we dutifully pass agent forwarding
  1445. * requests upstream. OpenSSHD has the curious behaviour
  1446. * that all but the first such request will be rejected,
  1447. * but all session channels opened after the first request
  1448. * get agent forwarding enabled whether they ask for it or
  1449. * not; but that's not our concern, since other SSH
  1450. * servers supporting the same piece of protocol might in
  1451. * principle at least manage to enable agent forwarding on
  1452. * precisely the channels that requested it, even if the
  1453. * subsequent CHANNEL_OPENs still can't be associated with
  1454. * a parent session channel.)
  1455. */
  1456. if (ptrlen_eq_string(request_name, "[email protected]") &&
  1457. !ssh_agent_forwarding_permitted(cs->parent->cl)) {
  1458. chan = share_find_channel_by_server(cs, server_id);
  1459. if (chan) {
  1460. packet = strbuf_new();
  1461. put_uint32(packet, chan->downstream_id);
  1462. send_packet_to_downstream(
  1463. cs, SSH2_MSG_CHANNEL_FAILURE,
  1464. packet->s, packet->len, NULL);
  1465. strbuf_free(packet);
  1466. } else {
  1467. char *buf = dupprintf("Agent forwarding request for "
  1468. "unrecognised channel %u", server_id);
  1469. share_disconnect(cs, buf);
  1470. sfree(buf);
  1471. return;
  1472. }
  1473. break;
  1474. }
  1475. /*
  1476. * Another thing we treat specially is X11 forwarding
  1477. * requests. For these, we have to make up another set of
  1478. * X11 auth data, and enter it into our SSH connection's
  1479. * list of possible X11 authorisation credentials so that
  1480. * when we see an X11 channel open request we can know
  1481. * whether it's one to handle locally or one to pass on to
  1482. * a downstream, and if the latter, which one.
  1483. */
  1484. if (ptrlen_eq_string(request_name, "x11-req")) {
  1485. int want_reply, single_connection, screen;
  1486. ptrlen auth_data;
  1487. int auth_proto;
  1488. chan = share_find_channel_by_server(cs, server_id);
  1489. if (!chan) {
  1490. char *buf = dupprintf("X11 forwarding request for "
  1491. "unrecognised channel %u", server_id);
  1492. share_disconnect(cs, buf);
  1493. sfree(buf);
  1494. return;
  1495. }
  1496. /*
  1497. * Pick apart the whole message to find the downstream
  1498. * auth details.
  1499. */
  1500. want_reply = get_bool(src);
  1501. single_connection = get_bool(src);
  1502. auth_proto = x11_identify_auth_proto(get_string(src));
  1503. auth_data = get_string(src);
  1504. screen = toint(get_uint32(src));
  1505. if (get_err(src)) {
  1506. err = dupprintf("Truncated CHANNEL_REQUEST(\"x11-req\")"
  1507. " packet");
  1508. goto confused;
  1509. }
  1510. if (auth_proto < 0) {
  1511. /* Reject due to not understanding downstream's
  1512. * requested authorisation method. */
  1513. packet = strbuf_new();
  1514. put_uint32(packet, chan->downstream_id);
  1515. send_packet_to_downstream(
  1516. cs, SSH2_MSG_CHANNEL_FAILURE,
  1517. packet->s, packet->len, NULL);
  1518. strbuf_free(packet);
  1519. break;
  1520. }
  1521. chan->x11_auth_proto = auth_proto;
  1522. chan->x11_auth_data = x11_dehexify(auth_data,
  1523. &chan->x11_auth_datalen);
  1524. chan->x11_auth_upstream =
  1525. ssh_add_sharing_x11_display(cs->parent->cl, auth_proto,
  1526. cs, chan);
  1527. chan->x11_one_shot = single_connection;
  1528. /*
  1529. * Now construct a replacement X forwarding request,
  1530. * containing our own auth data, and send that to the
  1531. * server.
  1532. */
  1533. packet = strbuf_new();
  1534. put_uint32(packet, server_id);
  1535. put_stringz(packet, "x11-req");
  1536. put_bool(packet, want_reply);
  1537. put_bool(packet, single_connection);
  1538. put_stringz(packet, chan->x11_auth_upstream->protoname);
  1539. put_stringz(packet, chan->x11_auth_upstream->datastring);
  1540. put_uint32(packet, screen);
  1541. ssh_send_packet_from_downstream(
  1542. cs->parent->cl, cs->id, SSH2_MSG_CHANNEL_REQUEST,
  1543. packet->s, packet->len, NULL);
  1544. strbuf_free(packet);
  1545. break;
  1546. }
  1547. }
  1548. ssh_send_packet_from_downstream(cs->parent->cl, cs->id,
  1549. type, pkt, pktlen, NULL);
  1550. if (type == SSH2_MSG_CHANNEL_CLOSE && pktlen >= 4) {
  1551. chan = share_find_channel_by_server(cs, server_id);
  1552. if (chan) {
  1553. if (chan->state == RCVD_CLOSE) {
  1554. ssh_delete_sharing_channel(cs->parent->cl,
  1555. chan->upstream_id);
  1556. share_remove_channel(cs, chan);
  1557. } else {
  1558. chan->state = SENT_CLOSE;
  1559. }
  1560. }
  1561. }
  1562. break;
  1563. default:
  1564. err = dupprintf("Unexpected packet type %d\n", type);
  1565. goto confused;
  1566. /*
  1567. * Any other packet type is unexpected. In particular, we
  1568. * never pass GLOBAL_REQUESTs downstream, so we never expect
  1569. * to see SSH2_MSG_REQUEST_{SUCCESS,FAILURE}.
  1570. */
  1571. confused:
  1572. assert(err != NULL);
  1573. share_disconnect(cs, err);
  1574. sfree(err);
  1575. break;
  1576. }
  1577. }
  1578. /*
  1579. * Coroutine macros similar to, but simplified from, those in ssh.c.
  1580. */
  1581. #define crBegin(v) { int *crLine = &v; switch(v) { case 0:;
  1582. #define crFinishV } *crLine = 0; return; }
  1583. #define crGetChar(c) do \
  1584. { \
  1585. while (len == 0) { \
  1586. *crLine =__LINE__; return; case __LINE__:; \
  1587. } \
  1588. len--; \
  1589. (c) = (unsigned char)*data++; \
  1590. } while (0)
  1591. static void share_receive(Plug *plug, int urgent, char *data, int len)
  1592. {
  1593. ssh_sharing_connstate *cs = FROMFIELD(
  1594. plug, ssh_sharing_connstate, plugvt);
  1595. static const char expected_verstring_prefix[] =
  1596. "[email protected]";
  1597. unsigned char c;
  1598. crBegin(cs->crLine);
  1599. /*
  1600. * First read the version string from downstream.
  1601. */
  1602. cs->recvlen = 0;
  1603. while (1) {
  1604. crGetChar(c);
  1605. if (c == '\012')
  1606. break;
  1607. if (cs->recvlen >= sizeof(cs->recvbuf)) {
  1608. char *buf = dupprintf("Version string far too long\n");
  1609. share_disconnect(cs, buf);
  1610. sfree(buf);
  1611. goto dead;
  1612. }
  1613. cs->recvbuf[cs->recvlen++] = c;
  1614. }
  1615. /*
  1616. * Now parse the version string to make sure it's at least vaguely
  1617. * sensible, and log it.
  1618. */
  1619. if (cs->recvlen < sizeof(expected_verstring_prefix)-1 ||
  1620. memcmp(cs->recvbuf, expected_verstring_prefix,
  1621. sizeof(expected_verstring_prefix) - 1)) {
  1622. char *buf = dupprintf("Version string did not have expected prefix\n");
  1623. share_disconnect(cs, buf);
  1624. sfree(buf);
  1625. goto dead;
  1626. }
  1627. if (cs->recvlen > 0 && cs->recvbuf[cs->recvlen-1] == '\015')
  1628. cs->recvlen--; /* trim off \r before \n */
  1629. log_downstream(cs, "Downstream version string: %.*s",
  1630. cs->recvlen, cs->recvbuf);
  1631. cs->got_verstring = TRUE;
  1632. /*
  1633. * Loop round reading packets.
  1634. */
  1635. while (1) {
  1636. cs->recvlen = 0;
  1637. while (cs->recvlen < 4) {
  1638. crGetChar(c);
  1639. cs->recvbuf[cs->recvlen++] = c;
  1640. }
  1641. cs->curr_packetlen = toint(GET_32BIT(cs->recvbuf) + 4);
  1642. if (cs->curr_packetlen < 5 ||
  1643. cs->curr_packetlen > sizeof(cs->recvbuf)) {
  1644. char *buf = dupprintf("Bad packet length %u\n",
  1645. (unsigned)cs->curr_packetlen);
  1646. share_disconnect(cs, buf);
  1647. sfree(buf);
  1648. goto dead;
  1649. }
  1650. while (cs->recvlen < cs->curr_packetlen) {
  1651. crGetChar(c);
  1652. cs->recvbuf[cs->recvlen++] = c;
  1653. }
  1654. share_got_pkt_from_downstream(cs, cs->recvbuf[4],
  1655. cs->recvbuf + 5, cs->recvlen - 5);
  1656. }
  1657. dead:;
  1658. crFinishV;
  1659. }
  1660. static void share_sent(Plug *plug, int bufsize)
  1661. {
  1662. /* ssh_sharing_connstate *cs = FROMFIELD(
  1663. plug, ssh_sharing_connstate, plugvt); */
  1664. /*
  1665. * We do nothing here, because we expect that there won't be a
  1666. * need to throttle and unthrottle the connection to a downstream.
  1667. * It should automatically throttle itself: if the SSH server
  1668. * sends huge amounts of data on all channels then it'll run out
  1669. * of window until our downstream sends it back some
  1670. * WINDOW_ADJUSTs.
  1671. */
  1672. }
  1673. static void share_listen_closing(Plug *plug, const char *error_msg,
  1674. int error_code, int calling_back)
  1675. {
  1676. ssh_sharing_state *sharestate = FROMFIELD(plug, ssh_sharing_state, plugvt);
  1677. if (error_msg)
  1678. log_general(sharestate, "listening socket: %s", error_msg);
  1679. sk_close(sharestate->listensock);
  1680. sharestate->listensock = NULL;
  1681. }
  1682. static void share_send_verstring(ssh_sharing_connstate *cs)
  1683. {
  1684. char *fullstring = dupcat("[email protected]",
  1685. cs->parent->server_verstring, "\015\012", NULL);
  1686. sk_write(cs->sock, fullstring, strlen(fullstring));
  1687. sfree(fullstring);
  1688. cs->sent_verstring = TRUE;
  1689. }
  1690. int share_ndownstreams(ssh_sharing_state *sharestate)
  1691. {
  1692. return count234(sharestate->connections);
  1693. }
  1694. void share_activate(ssh_sharing_state *sharestate,
  1695. const char *server_verstring)
  1696. {
  1697. /*
  1698. * Indication from ssh.c that we are now ready to begin serving
  1699. * any downstreams that have already connected to us.
  1700. */
  1701. struct ssh_sharing_connstate *cs;
  1702. int i;
  1703. /*
  1704. * Trim the server's version string down to just the software
  1705. * version component, removing "SSH-2.0-" or whatever at the
  1706. * front.
  1707. */
  1708. for (i = 0; i < 2; i++) {
  1709. server_verstring += strcspn(server_verstring, "-");
  1710. if (*server_verstring)
  1711. server_verstring++;
  1712. }
  1713. sharestate->server_verstring = dupstr(server_verstring);
  1714. for (i = 0; (cs = (struct ssh_sharing_connstate *)
  1715. index234(sharestate->connections, i)) != NULL; i++) {
  1716. assert(!cs->sent_verstring);
  1717. share_send_verstring(cs);
  1718. }
  1719. }
  1720. static const Plug_vtable ssh_sharing_conn_plugvt = {
  1721. NULL, /* no log function, because that's for outgoing connections */
  1722. share_closing,
  1723. share_receive,
  1724. share_sent,
  1725. NULL /* no accepting function, because we've already done it */
  1726. };
  1727. static int share_listen_accepting(Plug *plug,
  1728. accept_fn_t constructor, accept_ctx_t ctx)
  1729. {
  1730. struct ssh_sharing_state *sharestate = FROMFIELD(
  1731. plug, struct ssh_sharing_state, plugvt);
  1732. struct ssh_sharing_connstate *cs;
  1733. const char *err;
  1734. char *peerinfo;
  1735. /*
  1736. * A new downstream has connected to us.
  1737. */
  1738. cs = snew(struct ssh_sharing_connstate);
  1739. cs->plugvt = &ssh_sharing_conn_plugvt;
  1740. cs->parent = sharestate;
  1741. if ((cs->id = share_find_unused_id(sharestate, sharestate->nextid)) == 0 &&
  1742. (cs->id = share_find_unused_id(sharestate, 1)) == 0) {
  1743. sfree(cs);
  1744. return 1;
  1745. }
  1746. sharestate->nextid = cs->id + 1;
  1747. if (sharestate->nextid == 0)
  1748. sharestate->nextid++; /* only happens in VERY long-running upstreams */
  1749. cs->sock = constructor(ctx, &cs->plugvt);
  1750. if ((err = sk_socket_error(cs->sock)) != NULL) {
  1751. sfree(cs);
  1752. return err != NULL;
  1753. }
  1754. sk_set_frozen(cs->sock, 0);
  1755. add234(cs->parent->connections, cs);
  1756. cs->sent_verstring = FALSE;
  1757. if (sharestate->server_verstring)
  1758. share_send_verstring(cs);
  1759. cs->got_verstring = FALSE;
  1760. cs->recvlen = 0;
  1761. cs->crLine = 0;
  1762. cs->halfchannels = newtree234(share_halfchannel_cmp);
  1763. cs->channels_by_us = newtree234(share_channel_us_cmp);
  1764. cs->channels_by_server = newtree234(share_channel_server_cmp);
  1765. cs->xchannels_by_us = newtree234(share_xchannel_us_cmp);
  1766. cs->xchannels_by_server = newtree234(share_xchannel_server_cmp);
  1767. cs->forwardings = newtree234(share_forwarding_cmp);
  1768. cs->globreq_head = cs->globreq_tail = NULL;
  1769. peerinfo = sk_peer_info(cs->sock);
  1770. log_downstream(cs, "connected%s%s",
  1771. peerinfo ? " from " : "", peerinfo ? peerinfo : "");
  1772. sfree(peerinfo);
  1773. return 0;
  1774. }
  1775. /* Per-application overrides for what roles we can take (e.g. pscp
  1776. * will never be an upstream) */
  1777. extern const int share_can_be_downstream;
  1778. extern const int share_can_be_upstream;
  1779. /*
  1780. * Decide on the string used to identify the connection point between
  1781. * upstream and downstream (be it a Windows named pipe or a
  1782. * Unix-domain socket or whatever else).
  1783. *
  1784. * I wondered about making this a SHA hash of all sorts of pieces of
  1785. * the PuTTY configuration - essentially everything PuTTY uses to know
  1786. * where and how to make a connection, including all the proxy details
  1787. * (or rather, all the _relevant_ ones - only including settings that
  1788. * other settings didn't prevent from having any effect), plus the
  1789. * username. However, I think it's better to keep it really simple:
  1790. * the connection point identifier is derived from the hostname and
  1791. * port used to index the host-key cache (not necessarily where we
  1792. * _physically_ connected to, in cases involving proxies or
  1793. * CONF_loghost), plus the username if one is specified.
  1794. *
  1795. * The per-platform code will quite likely hash or obfuscate this name
  1796. * in turn, for privacy from other users; failing that, it might
  1797. * transform it to avoid dangerous filename characters and so on. But
  1798. * that doesn't matter to us: for us, the point is that two session
  1799. * configurations which return the same string from this function will
  1800. * be treated as potentially shareable with each other.
  1801. */
  1802. char *ssh_share_sockname(const char *host, int port, Conf *conf)
  1803. {
  1804. char *username = get_remote_username(conf);
  1805. char *sockname;
  1806. if (port == 22) {
  1807. if (username)
  1808. sockname = dupprintf("%s@%s", username, host);
  1809. else
  1810. sockname = dupprintf("%s", host);
  1811. } else {
  1812. if (username)
  1813. sockname = dupprintf("%s@%s:%d", username, host, port);
  1814. else
  1815. sockname = dupprintf("%s:%d", host, port);
  1816. }
  1817. sfree(username);
  1818. return sockname;
  1819. }
  1820. int ssh_share_test_for_upstream(const char *host, int port, Conf *conf)
  1821. {
  1822. char *sockname, *logtext, *ds_err, *us_err;
  1823. int result;
  1824. Socket *sock;
  1825. sockname = ssh_share_sockname(host, port, conf);
  1826. sock = NULL;
  1827. logtext = ds_err = us_err = NULL;
  1828. result = platform_ssh_share(sockname, conf, nullplug, (Plug *)NULL, &sock,
  1829. &logtext, &ds_err, &us_err, FALSE, TRUE);
  1830. sfree(logtext);
  1831. sfree(ds_err);
  1832. sfree(us_err);
  1833. sfree(sockname);
  1834. if (result == SHARE_NONE) {
  1835. assert(sock == NULL);
  1836. return FALSE;
  1837. } else {
  1838. assert(result == SHARE_DOWNSTREAM);
  1839. sk_close(sock);
  1840. return TRUE;
  1841. }
  1842. }
  1843. static const Plug_vtable ssh_sharing_listen_plugvt = {
  1844. NULL, /* no log function, because that's for outgoing connections */
  1845. share_listen_closing,
  1846. NULL, /* no receive function on a listening socket */
  1847. NULL, /* no sent function on a listening socket */
  1848. share_listen_accepting
  1849. };
  1850. void ssh_connshare_provide_connlayer(ssh_sharing_state *sharestate,
  1851. ConnectionLayer *cl)
  1852. {
  1853. sharestate->cl = cl;
  1854. }
  1855. /*
  1856. * Init function for connection sharing. We either open a listening
  1857. * socket and become an upstream, or connect to an existing one and
  1858. * become a downstream, or do neither. We are responsible for deciding
  1859. * which of these to do (including checking the Conf to see if
  1860. * connection sharing is even enabled in the first place). If we
  1861. * become a downstream, we return the Socket with which we connected
  1862. * to the upstream; otherwise (whether or not we have established an
  1863. * upstream) we return NULL.
  1864. */
  1865. Socket *ssh_connection_sharing_init(
  1866. const char *host, int port, Conf *conf, Frontend *frontend,
  1867. Plug *sshplug, ssh_sharing_state **state)
  1868. {
  1869. int result, can_upstream, can_downstream;
  1870. char *logtext, *ds_err, *us_err;
  1871. char *sockname;
  1872. Socket *sock, *toret = NULL;
  1873. struct ssh_sharing_state *sharestate;
  1874. if (!conf_get_int(conf, CONF_ssh_connection_sharing))
  1875. return NULL; /* do not share anything */
  1876. can_upstream = share_can_be_upstream &&
  1877. conf_get_int(conf, CONF_ssh_connection_sharing_upstream);
  1878. can_downstream = share_can_be_downstream &&
  1879. conf_get_int(conf, CONF_ssh_connection_sharing_downstream);
  1880. if (!can_upstream && !can_downstream)
  1881. return NULL;
  1882. sockname = ssh_share_sockname(host, port, conf);
  1883. /*
  1884. * Create a data structure for the listening plug if we turn out
  1885. * to be an upstream.
  1886. */
  1887. sharestate = snew(struct ssh_sharing_state);
  1888. sharestate->plugvt = &ssh_sharing_listen_plugvt;
  1889. sharestate->listensock = NULL;
  1890. sharestate->cl = NULL;
  1891. /*
  1892. * Now hand off to a per-platform routine that either connects to
  1893. * an existing upstream (using 'ssh' as the plug), establishes our
  1894. * own upstream (using 'sharestate' as the plug), or forks off a
  1895. * separate upstream and then connects to that. It will return a
  1896. * code telling us which kind of socket it put in 'sock'.
  1897. */
  1898. sock = NULL;
  1899. logtext = ds_err = us_err = NULL;
  1900. result = platform_ssh_share(
  1901. sockname, conf, sshplug, &sharestate->plugvt, &sock, &logtext,
  1902. &ds_err, &us_err, can_upstream, can_downstream);
  1903. switch (result) {
  1904. case SHARE_NONE:
  1905. /*
  1906. * We aren't sharing our connection at all (e.g. something
  1907. * went wrong setting the socket up). Free the upstream
  1908. * structure and return NULL.
  1909. */
  1910. if (logtext) {
  1911. /* For this result, if 'logtext' is not NULL then it is an
  1912. * error message indicating a reason why connection sharing
  1913. * couldn't be set up _at all_ */
  1914. logeventf(frontend,
  1915. "Could not set up connection sharing: %s", logtext);
  1916. } else {
  1917. /* Failing that, ds_err and us_err indicate why we
  1918. * couldn't be a downstream and an upstream respectively */
  1919. if (ds_err)
  1920. logeventf(frontend, "Could not set up connection sharing"
  1921. " as downstream: %s", ds_err);
  1922. if (us_err)
  1923. logeventf(frontend, "Could not set up connection sharing"
  1924. " as upstream: %s", us_err);
  1925. }
  1926. assert(sock == NULL);
  1927. *state = NULL;
  1928. sfree(sharestate);
  1929. sfree(sockname);
  1930. break;
  1931. case SHARE_DOWNSTREAM:
  1932. /*
  1933. * We are downstream, so free sharestate which it turns out we
  1934. * don't need after all, and return the downstream socket as a
  1935. * replacement for an ordinary SSH connection.
  1936. */
  1937. /* 'logtext' is a local endpoint address */
  1938. logeventf(frontend,
  1939. "Using existing shared connection at %s", logtext);
  1940. *state = NULL;
  1941. sfree(sharestate);
  1942. sfree(sockname);
  1943. toret = sock;
  1944. break;
  1945. case SHARE_UPSTREAM:
  1946. /*
  1947. * We are upstream. Set up sharestate properly and pass a copy
  1948. * to the caller; return NULL, to tell ssh.c that it has to
  1949. * make an ordinary connection after all.
  1950. */
  1951. /* 'logtext' is a local endpoint address */
  1952. logeventf(frontend, "Sharing this connection at %s", logtext);
  1953. *state = sharestate;
  1954. sharestate->listensock = sock;
  1955. sharestate->connections = newtree234(share_connstate_cmp);
  1956. sharestate->server_verstring = NULL;
  1957. sharestate->sockname = sockname;
  1958. sharestate->nextid = 1;
  1959. break;
  1960. }
  1961. sfree(logtext);
  1962. sfree(ds_err);
  1963. sfree(us_err);
  1964. return toret;
  1965. }