sshshare.c 78 KB

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