netssh.c 73 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220
  1. /*
  2. * /net/ssh
  3. */
  4. #include <u.h>
  5. #include <libc.h>
  6. #include <fcall.h>
  7. #include <thread.h>
  8. #include <9p.h>
  9. #include <mp.h>
  10. #include <auth.h>
  11. #include <authsrv.h>
  12. #include <libsec.h>
  13. #include <ip.h>
  14. #include "netssh.h"
  15. extern int nokeyverify;
  16. void stclunk(Fid *);
  17. void stend(Srv *);
  18. void stflush(Req *);
  19. void stopen(Req *);
  20. void stread(Req *);
  21. void stwrite(Req *);
  22. Srv netsshsrv = {
  23. .open = stopen,
  24. .read = stread,
  25. .write = stwrite,
  26. .flush = stflush,
  27. .destroyfid = stclunk,
  28. .end = stend,
  29. };
  30. Cipher *cryptos[] = {
  31. &cipheraes128,
  32. &cipheraes192,
  33. &cipheraes256,
  34. // &cipherblowfish,
  35. &cipher3des,
  36. &cipherrc4,
  37. };
  38. Kex *kexes[] = {
  39. &dh1sha1,
  40. &dh14sha1,
  41. };
  42. PKA *pkas[3];
  43. char *macnames[] = {
  44. "hmac-sha1",
  45. };
  46. char *st_names[] = {
  47. [Empty] "Empty",
  48. [Allocated] "Allocated",
  49. [Initting] "Initting",
  50. [Listening] "Listening",
  51. [Opening] "Opening",
  52. [Negotiating] "Negotiating",
  53. [Authing] "Authing",
  54. [Established] "Established",
  55. [Eof] "Eof",
  56. [Closing] "Closing",
  57. [Closed] "Closed",
  58. };
  59. int debug;
  60. int kflag;
  61. char *mntpt = "/net";
  62. char uid[32];
  63. Conn *connections[MAXCONN];
  64. File *rootfile, *clonefile, *ctlfile, *keysfile;
  65. Ioproc *io9p;
  66. MBox keymbox;
  67. QLock availlck;
  68. Rendez availrend;
  69. SSHChan *alloc_chan(Conn *);
  70. Conn *alloc_conn(void);
  71. int auth_req(Packet *, Conn *);
  72. int client_auth(Conn *, Ioproc *);
  73. int dohandshake(Conn *, char *);
  74. char *factlookup(int, int, char *[]);
  75. void filedup(Req *, File *);
  76. void readdata(void *);
  77. void reader(void *);
  78. void readreqrem(void *);
  79. void send_kexinit(Conn *);
  80. void server(char *, char *);
  81. void shutdown(Conn *);
  82. void stlisconn(void *);
  83. void stlischan(void *);
  84. int validatekex(Conn *, Packet *);
  85. int validatekexc(Packet *);
  86. int validatekexs(Packet *);
  87. void writectlproc(void *);
  88. void writedataproc(void *);
  89. void writereqremproc(void *);
  90. static int deferredinit(Conn *c);
  91. static void
  92. sshlogint(Conn *c, char *file, char *p)
  93. {
  94. char *role, *id;
  95. if (c == nil)
  96. role = "";
  97. else if (c->role == Server)
  98. role = "server ";
  99. else
  100. role = "client ";
  101. if (c == nil)
  102. id = strdup("");
  103. else if (c->user || c->remote)
  104. id = smprint("user %s@%s id %d ", c->user, c->remote, c->id);
  105. else
  106. id = smprint("id %d ", c->id);
  107. syslog(0, file, "%s: %s%s%s", argv0, role, id, p);
  108. free(id);
  109. }
  110. void
  111. sshlog(Conn *c, char *fmt, ...)
  112. {
  113. va_list args;
  114. char *p;
  115. /* do this first in case fmt contains "%r" */
  116. va_start(args, fmt);
  117. p = vsmprint(fmt, args);
  118. va_end(args);
  119. sshlogint(c, "ssh", p);
  120. sshlogint(c, "sshdebug", p); /* log in both places */
  121. free(p);
  122. }
  123. void
  124. sshdebug(Conn *c, char *fmt, ...)
  125. {
  126. va_list args;
  127. char *p;
  128. if (!debug)
  129. return;
  130. /* do this first in case fmt contains "%r" */
  131. va_start(args, fmt);
  132. p = vsmprint(fmt, args);
  133. va_end(args);
  134. sshlogint(c, "sshdebug", p);
  135. free(p);
  136. }
  137. void
  138. usage(void)
  139. {
  140. fprint(2, "usage: %s [-dkv] [-m mntpt] [-s srvpt]\n", argv0);
  141. exits("usage");
  142. }
  143. void
  144. threadmain(int argc, char *argv[])
  145. {
  146. char *p, *srvpt = nil;
  147. quotefmtinstall();
  148. threadsetname("main");
  149. nokeyverify = 1; /* temporary until verification is fixed */
  150. ARGBEGIN {
  151. case '9':
  152. chatty9p = 1;
  153. break;
  154. case 'd':
  155. debug++;
  156. break;
  157. case 'k':
  158. kflag = 1;
  159. break;
  160. case 'm':
  161. mntpt = EARGF(usage());
  162. break;
  163. case 's':
  164. srvpt = EARGF(usage());
  165. break;
  166. case 'v':
  167. nokeyverify = 1;
  168. break;
  169. case 'V':
  170. nokeyverify = 0;
  171. break;
  172. default:
  173. usage();
  174. break;
  175. } ARGEND;
  176. p = getenv("nosshkeyverify");
  177. if (p && p[0] != '\0')
  178. nokeyverify = 1;
  179. free(p);
  180. if (readfile("/dev/user", uid, sizeof uid) <= 0)
  181. strcpy(uid, "none");
  182. keymbox.mchan = chancreate(4, 0);
  183. availrend.l = &availlck;
  184. dh_init(pkas);
  185. /* become a daemon */
  186. if (rfork(RFNOTEG) < 0)
  187. fprint(2, "%s: rfork(NOTEG) failed: %r\n", argv0);
  188. server(mntpt, srvpt);
  189. threadexits(nil);
  190. }
  191. int
  192. readio(Ioproc *io, int fd, void *buf, int n)
  193. {
  194. if (io)
  195. return ioread(io, fd, buf, n);
  196. else
  197. return read(fd, buf, n);
  198. }
  199. int
  200. writeio(Ioproc *io, int fd, void *buf, int n)
  201. {
  202. if (io)
  203. return iowrite(io, fd, buf, n);
  204. else
  205. return write(fd, buf, n);
  206. }
  207. int
  208. read9pmsg(int fd, void *abuf, uint n)
  209. {
  210. int m, len;
  211. uchar *buf;
  212. if (io9p == nil)
  213. io9p = ioproc();
  214. buf = abuf;
  215. /* read count */
  216. m = ioreadn(io9p, fd, buf, BIT32SZ);
  217. if(m != BIT32SZ){
  218. if(m < 0)
  219. return -1;
  220. return 0;
  221. }
  222. len = GBIT32(buf);
  223. if(len <= BIT32SZ || len > n){
  224. werrstr("bad length in 9P2000 message header");
  225. return -1;
  226. }
  227. len -= BIT32SZ;
  228. m = ioreadn(io9p, fd, buf+BIT32SZ, len);
  229. if(m < len)
  230. return 0;
  231. return BIT32SZ+m;
  232. }
  233. void
  234. stend(Srv *)
  235. {
  236. closeioproc(io9p);
  237. threadkillgrp(threadgetgrp());
  238. }
  239. void
  240. server(char *mntpt, char *srvpt)
  241. {
  242. Dir d;
  243. char *p;
  244. int fd;
  245. netsshsrv.tree = alloctree(uid, uid, 0777, nil);
  246. rootfile = createfile(netsshsrv.tree->root, "ssh", uid, 0555|DMDIR,
  247. (void*)Qroot);
  248. clonefile = createfile(rootfile, "clone", uid, 0666, (void*)Qclone);
  249. ctlfile = createfile(rootfile, "ctl", uid, 0666, (void*)Qctl);
  250. keysfile = createfile(rootfile, "keys", uid, 0600, (void *)Qreqrem);
  251. /*
  252. * needs to be MBEFORE in case there are previous, now defunct,
  253. * netssh processes mounted in mntpt.
  254. */
  255. threadpostmountsrv(&netsshsrv, srvpt, mntpt, MBEFORE);
  256. p = esmprint("%s/cs", mntpt);
  257. fd = open(p, OWRITE);
  258. free(p);
  259. if (fd >= 0) {
  260. fprint(fd, "add ssh");
  261. close(fd);
  262. }
  263. if (srvpt) {
  264. nulldir(&d);
  265. d.mode = 0666;
  266. p = esmprint("/srv/%s", srvpt);
  267. dirwstat(p, &d);
  268. free(p);
  269. }
  270. sshdebug(nil, "server started for %s", getuser());
  271. }
  272. static void
  273. respexit(Conn *c, Req *r, void *freeme, char *msg)
  274. {
  275. if (msg)
  276. sshdebug(c, "%s", msg);
  277. r->aux = 0;
  278. respond(r, msg);
  279. free(freeme);
  280. threadexits(nil); /* maybe use msg here */
  281. }
  282. void
  283. stopen(Req *r)
  284. {
  285. int lev, xconn, fd;
  286. uvlong qidpath;
  287. char *p;
  288. char buf[32];
  289. Conn *c;
  290. SSHChan *sc;
  291. qidpath = (uvlong)r->fid->file->aux;
  292. lev = qidpath >> Levshift;
  293. switch ((ulong)(qidpath & Qtypemask)) {
  294. default:
  295. respond(r, nil);
  296. break;
  297. case Qlisten:
  298. r->aux = (void *)threadcreate((lev == Connection?
  299. stlisconn: stlischan), r, Defstk);
  300. break;
  301. case Qclone:
  302. switch (lev) {
  303. case Top:
  304. /* should use dial(2) instead of diddling /net/tcp */
  305. p = esmprint("%s/tcp/clone", mntpt);
  306. fd = open(p, ORDWR);
  307. if (fd < 0) {
  308. sshdebug(nil, "stopen: open %s failed: %r", p);
  309. free(p);
  310. responderror(r);
  311. return;
  312. }
  313. free(p);
  314. c = alloc_conn();
  315. if (c == nil) {
  316. close(fd);
  317. respond(r, "no more connections");
  318. return;
  319. }
  320. c->ctlfd = fd;
  321. c->poisoned = 0;
  322. filedup(r, c->ctlfile);
  323. sshlog(c, "new connection on fd %d", fd);
  324. break;
  325. case Connection:
  326. xconn = (qidpath >> Connshift) & Connmask;
  327. c = connections[xconn];
  328. if (c == nil) {
  329. respond(r, "bad connection");
  330. return;
  331. }
  332. sc = alloc_chan(c);
  333. if (sc == nil) {
  334. respond(r, "no more channels");
  335. return;
  336. }
  337. filedup(r, sc->ctl);
  338. break;
  339. default:
  340. snprint(buf, sizeof buf, "bad level %d", lev);
  341. readstr(r, buf);
  342. break;
  343. }
  344. respond(r, nil);
  345. break;
  346. }
  347. }
  348. static void
  349. listerrexit(Req *r, Ioproc *io, Conn *cl)
  350. {
  351. r->aux = 0;
  352. responderror(r);
  353. closeioproc(io);
  354. shutdown(cl);
  355. threadexits(nil);
  356. }
  357. void
  358. stlisconn(void *a)
  359. {
  360. int xconn, fd, n;
  361. uvlong qidpath;
  362. char *msg;
  363. char buf[Numbsz], path[NETPATHLEN];
  364. Conn *c, *cl;
  365. Ioproc *io;
  366. Req *r;
  367. threadsetname("stlisconn");
  368. r = a;
  369. qidpath = (uvlong)r->fid->file->aux;
  370. xconn = (qidpath >> Connshift) & Connmask;
  371. cl = connections[xconn];
  372. if (cl == nil) {
  373. sshlog(cl, "bad connection");
  374. respond(r, "bad connection");
  375. threadexits("bad connection");
  376. }
  377. if (cl->poisoned) {
  378. sshdebug(cl, "stlisconn conn %d poisoned", xconn);
  379. r->aux = 0;
  380. respond(r, "top level listen conn poisoned");
  381. threadexits("top level listen conn poisoned");
  382. }
  383. if (cl->ctlfd < 0) {
  384. sshdebug(cl, "stlisconn conn %d ctlfd < 0; poisoned", xconn);
  385. r->aux = 0;
  386. respond(r, "top level listen with closed fd");
  387. shutdown(cl);
  388. cl->poisoned = 1; /* no more use until ctlfd is set */
  389. threadexits("top level listen with closed fd");
  390. }
  391. io = ioproc();
  392. /* read xconn's tcp conn's ctl file */
  393. seek(cl->ctlfd, 0, 0);
  394. n = ioread(io, cl->ctlfd, buf, sizeof buf - 1);
  395. if (n == 0) {
  396. sshlog(cl, "stlisconn read eof on fd %d", cl->ctlfd);
  397. listerrexit(r, io, cl);
  398. } else if (n < 0) {
  399. sshlog(cl, "stlisconn read failed on fd %d: %r", cl->ctlfd);
  400. listerrexit(r, io, cl);
  401. }
  402. buf[n] = '\0';
  403. cl->state = Listening;
  404. /* should use dial(2) instead of diddling /net/tcp */
  405. snprint(path, sizeof path, "%s/tcp/%s/listen", mntpt, buf);
  406. for(;;) {
  407. fd = ioopen(io, path, ORDWR);
  408. if (fd < 0)
  409. listerrexit(r, io, cl);
  410. c = alloc_conn();
  411. if (c)
  412. break;
  413. n = ioread(io, fd, buf, sizeof buf - 1);
  414. if (n <= 0)
  415. listerrexit(r, io, cl);
  416. buf[n] = '\0';
  417. msg = smprint("reject %s no available connections", buf);
  418. iowrite(io, fd, msg, strlen(msg));
  419. free(msg);
  420. close(fd); /* surely ioclose? */
  421. }
  422. c->ctlfd = fd;
  423. if (c->ctlfd < 0) {
  424. sshlog(cl, "stlisconn c->ctlfd < 0 for conn %d", xconn);
  425. threadexitsall("stlisconn c->ctlfd < 0");
  426. }
  427. c->poisoned = 0;
  428. c->stifle = 1; /* defer server; was for coexistence */
  429. filedup(r, c->ctlfile);
  430. sshdebug(c, "responding to listen open");
  431. r->aux = 0;
  432. respond(r, nil);
  433. closeioproc(io);
  434. threadexits(nil);
  435. }
  436. void
  437. stlischan(void *a)
  438. {
  439. Req *r;
  440. Packet *p2;
  441. Ioproc *io;
  442. Conn *c;
  443. SSHChan *sc;
  444. int i, n, xconn;
  445. uvlong qidpath;
  446. threadsetname("stlischan");
  447. r = a;
  448. qidpath = (uvlong)r->fid->file->aux;
  449. xconn = (qidpath >> Connshift) & Connmask;
  450. c = connections[xconn];
  451. if (c == nil) {
  452. respond(r, "bad channel");
  453. sshlog(c, "bad channel");
  454. threadexits(nil);
  455. }
  456. if (c->state == Closed || c->state == Closing)
  457. respexit(c, r, nil, "channel listen on closed connection");
  458. sc = c->chans[qidpath & Chanmask];
  459. qlock(&c->l);
  460. sc->lreq = r;
  461. for (i = 0; i < c->nchan; ++i)
  462. if (c->chans[i] && c->chans[i]->state == Opening &&
  463. c->chans[i]->ann && strcmp(c->chans[i]->ann, sc->ann) == 0)
  464. break;
  465. if (i >= c->nchan) {
  466. sc->state = Listening;
  467. rsleep(&sc->r);
  468. i = sc->waker;
  469. if (i < 0) {
  470. qunlock(&c->l);
  471. r->aux = 0;
  472. responderror(r);
  473. threadexits(nil);
  474. }
  475. } else
  476. rwakeup(&c->chans[i]->r);
  477. qunlock(&c->l);
  478. if (c->state == Closed || c->state == Closing || c->state == Eof)
  479. respexit(c, r, nil, "channel listen on closed connection");
  480. c->chans[i]->state = Established;
  481. p2 = new_packet(c);
  482. c->chans[i]->rwindow = Maxpayload;
  483. add_byte(p2, SSH_MSG_CHANNEL_OPEN_CONFIRMATION);
  484. hnputl(p2->payload + 1, c->chans[i]->otherid);
  485. hnputl(p2->payload + 5, c->chans[i]->id);
  486. hnputl(p2->payload + 9, Maxpayload);
  487. hnputl(p2->payload + 13, Maxrpcbuf);
  488. p2->rlength = 18;
  489. n = finish_packet(p2);
  490. filedup(r, c->chans[i]->ctl);
  491. io = ioproc();
  492. n = iowrite(io, c->datafd, p2->nlength, n);
  493. closeioproc(io);
  494. free(p2);
  495. sshdebug(c, "responding to chan listen open");
  496. r->aux = 0;
  497. if (n < 0)
  498. responderror(r);
  499. else
  500. respond(r, nil);
  501. threadexits(nil);
  502. }
  503. void
  504. getdata(Conn *c, SSHChan *sc, Req *r)
  505. {
  506. Packet *p;
  507. Plist *d;
  508. int n;
  509. n = r->ifcall.count;
  510. if (sc->dataq->rem < n)
  511. n = sc->dataq->rem;
  512. if (n > Maxrpcbuf)
  513. n = Maxrpcbuf;
  514. r->ifcall.offset = 0;
  515. readbuf(r, sc->dataq->st, n);
  516. sc->dataq->st += n;
  517. sc->dataq->rem -= n;
  518. sc->inrqueue -= n;
  519. if (sc->dataq->rem <= 0) {
  520. d = sc->dataq;
  521. sc->dataq = sc->dataq->next;
  522. if (d->pack->tlength > sc->rwindow)
  523. sc->rwindow = 0;
  524. else
  525. sc->rwindow -= d->pack->tlength;
  526. free(d->pack);
  527. free(d);
  528. }
  529. if (sc->rwindow < 16*1024) { /* magic. half-way, maybe? */
  530. sc->rwindow += Maxpayload;
  531. sshdebug(c, "increasing receive window to %lud, inq %lud\n",
  532. argv0, sc->rwindow, sc->inrqueue);
  533. p = new_packet(c);
  534. add_byte(p, SSH_MSG_CHANNEL_WINDOW_ADJUST);
  535. hnputl(p->payload+1, sc->otherid);
  536. hnputl(p->payload+5, Maxpayload);
  537. p->rlength += 8;
  538. n = finish_packet(p);
  539. iowrite(c->dio, c->datafd, p->nlength, n);
  540. free(p);
  541. }
  542. r->aux = 0;
  543. respond(r, nil);
  544. }
  545. void
  546. stread(Req *r)
  547. {
  548. Conn *c;
  549. SSHChan *sc;
  550. int n, lev, cnum, xconn;
  551. uvlong qidpath;
  552. char buf[Arbbufsz], path[NETPATHLEN];
  553. threadsetname("stread");
  554. qidpath = (uvlong)r->fid->file->aux;
  555. lev = qidpath >> Levshift;
  556. xconn = (qidpath >> Connshift) & Connmask;
  557. c = connections[xconn];
  558. if (c == nil) {
  559. if (lev != Top || (qidpath & Qtypemask) != Qreqrem) {
  560. respond(r, "Invalid connection");
  561. return;
  562. }
  563. cnum = 0;
  564. sc = nil;
  565. } else {
  566. cnum = qidpath & Chanmask;
  567. sc = c->chans[cnum];
  568. }
  569. switch ((ulong)(qidpath & Qtypemask)) {
  570. case Qctl:
  571. case Qlisten:
  572. if (r->ifcall.offset != 0) {
  573. respond(r, nil);
  574. break;
  575. }
  576. switch (lev) {
  577. case Top:
  578. readstr(r, st_names[c->state]);
  579. break;
  580. case Connection:
  581. case Subchannel:
  582. snprint(buf, sizeof buf, "%d", lev == Connection?
  583. xconn: cnum);
  584. readstr(r, buf);
  585. break;
  586. default:
  587. snprint(buf, sizeof buf, "stread error, level %d", lev);
  588. respond(r, buf);
  589. return;
  590. }
  591. respond(r, nil);
  592. break;
  593. case Qclone:
  594. if (r->ifcall.offset != 0) {
  595. respond(r, nil);
  596. break;
  597. }
  598. readstr(r, "Congratulations, you've achieved the impossible\n");
  599. respond(r, nil);
  600. break;
  601. case Qdata:
  602. if (lev == Top) {
  603. respond(r, nil);
  604. break;
  605. }
  606. if (lev == Connection) {
  607. if (0 && c->stifle) { /* was for coexistence */
  608. c->stifle = 0;
  609. if (deferredinit(c) < 0) {
  610. respond(r, "deferredinit failed");
  611. break;
  612. }
  613. }
  614. if (c->cap) /* auth capability? */
  615. readstr(r, c->cap);
  616. respond(r, nil);
  617. break;
  618. }
  619. r->aux = (void *)threadcreate(readdata, r, Defstk);
  620. break;
  621. case Qlocal:
  622. if (lev == Connection)
  623. if (c->ctlfd < 0)
  624. readstr(r, "::!0\n");
  625. else {
  626. n = pread(c->ctlfd, buf, 10, 0); // magic 10
  627. buf[n >= 0? n: 0] = '\0';
  628. snprint(path, sizeof path, "%s/tcp/%s/local",
  629. mntpt, buf);
  630. readfile(path, buf, sizeof buf);
  631. readstr(r, buf);
  632. }
  633. respond(r, nil);
  634. break;
  635. case Qreqrem:
  636. r->aux = (void *)threadcreate(readreqrem, r, Defstk);
  637. break;
  638. case Qstatus:
  639. switch (lev) {
  640. case Top:
  641. readstr(r, "Impossible");
  642. break;
  643. case Connection:
  644. readstr(r, (uint)c->state > Closed?
  645. "Unknown": st_names[c->state]);
  646. break;
  647. case Subchannel:
  648. readstr(r, (uint)sc->state > Closed?
  649. "Unknown": st_names[sc->state]);
  650. break;
  651. }
  652. respond(r, nil);
  653. break;
  654. case Qtcp:
  655. /* connection number of underlying tcp connection */
  656. if (lev == Connection)
  657. if (c->ctlfd < 0)
  658. readstr(r, "-1\n");
  659. else {
  660. n = pread(c->ctlfd, buf, 10, 0); /* magic 10 */
  661. buf[n >= 0? n: 0] = '\0';
  662. readstr(r, buf);
  663. }
  664. respond(r, nil);
  665. break;
  666. default:
  667. respond(r, nil);
  668. break;
  669. }
  670. }
  671. void
  672. readreqrem(void *a)
  673. {
  674. Ioproc *io;
  675. Req *r;
  676. Conn *c;
  677. SSHChan *sc;
  678. int fd, n, lev, cnum, xconn;
  679. uvlong qidpath;
  680. char buf[Arbbufsz], path[NETPATHLEN];
  681. threadsetname("readreqrem");
  682. r = a;
  683. qidpath = (uvlong)r->fid->file->aux;
  684. lev = qidpath >> Levshift;
  685. xconn = (qidpath >> Connshift) & Connmask;
  686. c = connections[xconn];
  687. if (c == nil) {
  688. if (lev != Top) {
  689. respond(r, "Invalid connection");
  690. return;
  691. }
  692. sc = nil;
  693. } else {
  694. cnum = qidpath & Chanmask;
  695. sc = c->chans[cnum];
  696. }
  697. switch (lev) {
  698. case Top:
  699. if (r->ifcall.offset == 0 && keymbox.state != Empty) {
  700. r->aux = 0;
  701. respond(r, "Key file collision"); /* WTF? */
  702. break;
  703. }
  704. if (r->ifcall.offset != 0) {
  705. readstr(r, keymbox.msg);
  706. r->aux = 0;
  707. respond(r, nil);
  708. if (r->ifcall.offset + r->ifcall.count >=
  709. strlen(keymbox.msg))
  710. keymbox.state = Empty;
  711. else
  712. keymbox.state = Allocated;
  713. break;
  714. }
  715. keymbox.state = Allocated;
  716. for(;;) {
  717. if (keymbox.msg == nil)
  718. if (recv(keymbox.mchan, nil) < 0) {
  719. r->aux = 0;
  720. responderror(r);
  721. keymbox.state = Empty;
  722. threadexits(nil);
  723. }
  724. if (keymbox.state == Empty)
  725. break;
  726. else if (keymbox.state == Allocated) {
  727. if (keymbox.msg) {
  728. readstr(r, keymbox.msg);
  729. if (r->ifcall.offset + r->ifcall.count
  730. >= strlen(keymbox.msg)) {
  731. free(keymbox.msg);
  732. keymbox.msg = nil;
  733. keymbox.state = Empty;
  734. }
  735. }
  736. break;
  737. }
  738. }
  739. r->aux = 0;
  740. respond(r, nil);
  741. break;
  742. case Connection:
  743. if (c->ctlfd >= 0) {
  744. io = ioproc();
  745. seek(c->ctlfd, 0, 0);
  746. n = ioread(io, c->ctlfd, buf, 10); /* magic 10 */
  747. if (n < 0) {
  748. r->aux = 0;
  749. responderror(r);
  750. closeioproc(io);
  751. break;
  752. }
  753. buf[n] = '\0';
  754. snprint(path, NETPATHLEN, "%s/tcp/%s/remote", mntpt, buf);
  755. if ((fd = ioopen(io, path, OREAD)) < 0 ||
  756. (n = ioread(io, fd, buf, Arbbufsz - 1)) < 0) {
  757. r->aux = 0;
  758. responderror(r);
  759. if (fd >= 0)
  760. ioclose(io, fd);
  761. closeioproc(io);
  762. break;
  763. }
  764. ioclose(io, fd);
  765. closeioproc(io);
  766. buf[n] = '\0';
  767. readstr(r, buf);
  768. } else
  769. readstr(r, "::!0\n");
  770. r->aux = 0;
  771. respond(r, nil);
  772. break;
  773. case Subchannel:
  774. if ((sc->state == Closed || sc->state == Closing ||
  775. sc->state == Eof) && sc->reqq == nil && sc->dataq == nil) {
  776. sshdebug(c, "sending EOF1 to channel request listener");
  777. r->aux = 0;
  778. respond(r, nil);
  779. break;
  780. }
  781. while (sc->reqq == nil) {
  782. if (recv(sc->reqchan, nil) < 0) {
  783. r->aux = 0;
  784. responderror(r);
  785. threadexits(nil);
  786. }
  787. if ((sc->state == Closed || sc->state == Closing ||
  788. sc->state == Eof) && sc->reqq == nil &&
  789. sc->dataq == nil) {
  790. sshdebug(c, "sending EOF2 to channel request "
  791. "listener");
  792. respexit(c, r, nil, nil);
  793. }
  794. }
  795. n = r->ifcall.count;
  796. if (sc->reqq->rem < n)
  797. n = sc->reqq->rem;
  798. if (n > Maxrpcbuf)
  799. n = Maxrpcbuf;
  800. r->ifcall.offset = 0;
  801. readbuf(r, sc->reqq->st, n);
  802. sc->reqq->st += n;
  803. sc->reqq->rem -= n;
  804. if (sc->reqq->rem <= 0) {
  805. Plist *d = sc->reqq;
  806. sc->reqq = sc->reqq->next;
  807. free(d->pack);
  808. free(d);
  809. }
  810. r->aux = 0;
  811. respond(r, nil);
  812. break;
  813. }
  814. threadexits(nil);
  815. }
  816. void
  817. readdata(void *a)
  818. {
  819. Req *r;
  820. Conn *c;
  821. SSHChan *sc;
  822. int cnum, xconn;
  823. uvlong qidpath;
  824. threadsetname("readdata");
  825. r = a;
  826. qidpath = (uvlong)r->fid->file->aux;
  827. xconn = (qidpath >> Connshift) & Connmask;
  828. c = connections[xconn];
  829. if (c == nil) {
  830. respond(r, "bad connection");
  831. sshlog(c, "bad connection");
  832. threadexits(nil);
  833. }
  834. cnum = qidpath & Chanmask;
  835. sc = c->chans[cnum];
  836. if (sc->dataq == nil && (sc->state == Closed || sc->state == Closing ||
  837. sc->state == Eof)) {
  838. sshdebug(c, "sending EOF1 to channel listener");
  839. r->aux = 0;
  840. respond(r, nil);
  841. threadexits(nil);
  842. }
  843. if (sc->dataq != nil) {
  844. getdata(c, sc, r);
  845. threadexits(nil);
  846. }
  847. while (sc->dataq == nil) {
  848. if (recv(sc->inchan, nil) < 0) {
  849. sshdebug(c, "got interrupt/error in readdata %r");
  850. r->aux = 0;
  851. responderror(r);
  852. threadexits(nil);
  853. }
  854. if (sc->dataq == nil && (sc->state == Closed ||
  855. sc->state == Closing || sc->state == Eof)) {
  856. sshdebug(c, "sending EOF2 to channel listener");
  857. r->aux = 0;
  858. respond(r, nil);
  859. threadexits(nil);
  860. }
  861. }
  862. getdata(c, sc, r);
  863. threadexits(nil);
  864. }
  865. void
  866. stwrite(Req *r)
  867. {
  868. Conn *c;
  869. SSHChan *ch;
  870. int lev, xconn;
  871. uvlong qidpath;
  872. threadsetname("stwrite");
  873. qidpath = (uvlong)r->fid->file->aux;
  874. lev = qidpath >> Levshift;
  875. xconn = (qidpath >> Connshift) & Connmask;
  876. c = connections[xconn];
  877. if (c == nil) {
  878. respond(r, "invalid connection");
  879. return;
  880. }
  881. ch = c->chans[qidpath & Chanmask];
  882. switch ((ulong)(qidpath & Qtypemask)) {
  883. case Qclone:
  884. case Qctl:
  885. r->aux = (void *)threadcreate(writectlproc, r, Defstk);
  886. break;
  887. case Qdata:
  888. r->ofcall.count = r->ifcall.count;
  889. if (lev == Top || lev == Connection ||
  890. c->state == Closed || c->state == Closing ||
  891. ch->state == Closed || ch->state == Closing) {
  892. respond(r, nil);
  893. break;
  894. }
  895. if (0 && c->stifle) { /* was for coexistence */
  896. c->stifle = 0;
  897. if (deferredinit(c) < 0) {
  898. respond(r, "deferredinit failed");
  899. break;
  900. }
  901. }
  902. r->aux = (void *)threadcreate(writedataproc, r, Defstk);
  903. break;
  904. case Qreqrem:
  905. r->aux = (void *)threadcreate(writereqremproc, r, Defstk);
  906. break;
  907. default:
  908. respond(r, nil);
  909. break;
  910. }
  911. }
  912. static int
  913. dialbyhand(Conn *c, int ntok, char *toks[])
  914. {
  915. /*
  916. * this uses /net/tcp to connect directly.
  917. * should use dial(2) instead of doing it by hand.
  918. */
  919. sshdebug(c, "tcp connect %s %s", toks[1], ntok > 3? toks[2]: "");
  920. return fprint(c->ctlfd, "connect %s %s", toks[1], ntok > 3? toks[2]: "");
  921. }
  922. static void
  923. userauth(Conn *c, Req *r, char *buf, int ntok, char *toks[])
  924. {
  925. int n;
  926. char *attrs[5];
  927. Packet *p;
  928. if (ntok < 3 || ntok > 4)
  929. respexit(c, r, buf, "bad connect command");
  930. if (!c->service)
  931. c->service = estrdup9p(toks[0]);
  932. if (c->user)
  933. free(c->user);
  934. c->user = estrdup9p(toks[2]);
  935. sshdebug(c, "userauth for user %s", c->user);
  936. if (ntok == 4 && strcmp(toks[1], "k") == 0) {
  937. if (c->authkey) {
  938. free(c->authkey);
  939. c->authkey = nil;
  940. }
  941. if (c->password)
  942. free(c->password);
  943. c->password = estrdup9p(toks[3]);
  944. sshdebug(c, "userauth got password");
  945. } else {
  946. if (c->password) {
  947. free(c->password);
  948. c->password = nil;
  949. }
  950. memset(attrs, 0, sizeof attrs);
  951. attrs[0] = "proto=rsa";
  952. attrs[1] = "!dk?";
  953. attrs[2] = smprint("user=%s", c->user);
  954. attrs[3] = smprint("sys=%s", c->remote);
  955. if (c->authkey)
  956. free(c->authkey);
  957. sshdebug(c, "userauth trying rsa");
  958. if (ntok == 3)
  959. c->authkey = factlookup(4, 2, attrs);
  960. else {
  961. attrs[4] = toks[3];
  962. c->authkey = factlookup(5, 2, attrs);
  963. }
  964. free(attrs[2]);
  965. free(attrs[3]);
  966. }
  967. if (!c->password && !c->authkey)
  968. respexit(c, r, buf, "no auth info");
  969. else if (c->state != Authing) {
  970. p = new_packet(c);
  971. add_byte(p, SSH_MSG_SERVICE_REQUEST);
  972. add_string(p, c->service);
  973. n = finish_packet(p);
  974. sshdebug(c, "sending msg svc req for %s", c->service);
  975. if (writeio(c->dio, c->datafd, p->nlength, n) != n) {
  976. sshdebug(c, "authing write failed: %r");
  977. free(p);
  978. r->aux = 0;
  979. responderror(r);
  980. free(buf);
  981. threadexits(nil);
  982. }
  983. free(p);
  984. } else
  985. if (client_auth(c, c->dio) < 0)
  986. respexit(c, r, buf, "ssh-userauth client auth failed");
  987. qlock(&c->l);
  988. if (c->state != Established) {
  989. sshdebug(c, "sleeping for auth");
  990. rsleep(&c->r);
  991. }
  992. qunlock(&c->l);
  993. if (c->state != Established)
  994. respexit(c, r, buf, "ssh-userath auth failed (not Established)");
  995. }
  996. void
  997. writectlproc(void *a)
  998. {
  999. Req *r;
  1000. Packet *p;
  1001. Conn *c;
  1002. SSHChan *ch;
  1003. char *tcpconn2, *buf, *toks[4];
  1004. int n, ntok, lev, xconn;
  1005. uvlong qidpath;
  1006. char path[NETPATHLEN], tcpconn[Numbsz];
  1007. threadsetname("writectlproc");
  1008. r = a;
  1009. qidpath = (uvlong)r->fid->file->aux;
  1010. lev = qidpath >> Levshift;
  1011. xconn = (qidpath >> Connshift) & Connmask;
  1012. c = connections[xconn];
  1013. if (c == nil) {
  1014. respond(r, "bad connection");
  1015. sshlog(c, "bad connection");
  1016. threadexits(nil);
  1017. }
  1018. ch = c->chans[qidpath & Chanmask];
  1019. if (r->ifcall.count <= Numbsz)
  1020. buf = emalloc9p(Numbsz + 1);
  1021. else
  1022. buf = emalloc9p(r->ifcall.count + 1);
  1023. memmove(buf, r->ifcall.data, r->ifcall.count);
  1024. buf[r->ifcall.count] = '\0';
  1025. sshdebug(c, "level %d writectl: %s", lev, buf);
  1026. ntok = tokenize(buf, toks, nelem(toks));
  1027. switch (lev) {
  1028. case Connection:
  1029. if (strcmp(toks[0], "id") == 0) { /* was for sshswitch */
  1030. if (ntok < 2)
  1031. respexit(c, r, buf, "bad id request");
  1032. strncpy(c->idstring, toks[1], sizeof c->idstring);
  1033. sshdebug(c, "id %s", toks[1]);
  1034. break;
  1035. }
  1036. if (strcmp(toks[0], "connect") == 0) {
  1037. if (ntok < 2)
  1038. respexit(c, r, buf, "bad connect request");
  1039. /*
  1040. * should use dial(2) instead of doing it by hand.
  1041. */
  1042. memset(tcpconn, '\0', sizeof(tcpconn));
  1043. pread(c->ctlfd, tcpconn, sizeof tcpconn, 0);
  1044. dialbyhand(c, ntok, toks);
  1045. c->role = Client;
  1046. /* Override the PKA list; we can take any in */
  1047. pkas[0] = &rsa_pka;
  1048. pkas[1] = &dss_pka;
  1049. pkas[2] = nil;
  1050. tcpconn2 = estrdup9p(tcpconn);
  1051. /* swap id strings, negotiate crypto */
  1052. if (dohandshake(c, tcpconn2) < 0) {
  1053. sshlog(c, "connect handshake failed: "
  1054. "tcp conn %s", tcpconn2);
  1055. free(tcpconn2);
  1056. respexit(c, r, buf, "connect handshake failed");
  1057. }
  1058. free(tcpconn2);
  1059. keymbox.state = Empty;
  1060. nbsendul(keymbox.mchan, 1);
  1061. break;
  1062. }
  1063. if (c->state == Closed || c->state == Closing)
  1064. respexit(c, r, buf, "connection closed");
  1065. if (strcmp(toks[0], "ssh-userauth") == 0)
  1066. userauth(c, r, buf, ntok, toks);
  1067. else if (strcmp(toks[0], "ssh-connection") == 0) {
  1068. /* your ad here */
  1069. } else if (strcmp(toks[0], "hangup") == 0) {
  1070. if (c->rpid >= 0)
  1071. threadint(c->rpid);
  1072. shutdown(c);
  1073. } else if (strcmp(toks[0], "announce") == 0) {
  1074. sshdebug(c, "got %s argument for announce", toks[1]);
  1075. write(c->ctlfd, r->ifcall.data, r->ifcall.count);
  1076. } else if (strcmp(toks[0], "accept") == 0) {
  1077. /* should use dial(2) instead of diddling /net/tcp */
  1078. memset(tcpconn, '\0', sizeof(tcpconn));
  1079. pread(c->ctlfd, tcpconn, sizeof tcpconn, 0);
  1080. fprint(c->ctlfd, "accept %s", tcpconn);
  1081. c->role = Server;
  1082. tcpconn2 = estrdup9p(tcpconn);
  1083. /* swap id strings, negotiate crypto */
  1084. if (dohandshake(c, tcpconn2) < 0) {
  1085. sshlog(c, "accept handshake failed: "
  1086. "tcp conn %s", tcpconn2);
  1087. free(tcpconn2);
  1088. shutdown(c);
  1089. respexit(c, r, buf, "accept handshake failed");
  1090. }
  1091. free(tcpconn2);
  1092. } else if (strcmp(toks[0], "reject") == 0) {
  1093. memset(tcpconn, '\0', sizeof(tcpconn));
  1094. pread(c->ctlfd, tcpconn, sizeof tcpconn, 0);
  1095. snprint(path, NETPATHLEN, "%s/tcp/%s/data", mntpt, tcpconn);
  1096. c->datafd = open(path, ORDWR);
  1097. p = new_packet(c);
  1098. add_byte(p, SSH_MSG_DISCONNECT);
  1099. add_byte(p, SSH_DISCONNECT_HOST_NOT_ALLOWED_TO_CONNECT);
  1100. add_string(p, toks[2]);
  1101. add_string(p, "EN");
  1102. n = finish_packet(p);
  1103. if (c->dio && c->datafd >= 0)
  1104. iowrite(c->dio, c->datafd, p->nlength, n);
  1105. free(p);
  1106. if (c->ctlfd >= 0)
  1107. fprint(c->ctlfd, "reject %s %s", buf, toks[2]);
  1108. if (c->rpid >= 0)
  1109. threadint(c->rpid);
  1110. shutdown(c);
  1111. }
  1112. break;
  1113. case Subchannel:
  1114. if (c->state == Closed || c->state == Closing)
  1115. respexit(c, r, buf, "channel closed");
  1116. if (strcmp(toks[0], "connect") == 0) {
  1117. p = new_packet(c);
  1118. add_byte(p, SSH_MSG_CHANNEL_OPEN);
  1119. sshdebug(c, "chan writectl: connect %s",
  1120. ntok > 1? toks[1]: "session");
  1121. add_string(p, ntok > 1? toks[1]: "session");
  1122. add_uint32(p, ch->id);
  1123. add_uint32(p, Maxpayload);
  1124. add_uint32(p, Maxrpcbuf);
  1125. /* more stuff if it's an x11 session */
  1126. n = finish_packet(p);
  1127. iowrite(c->dio, c->datafd, p->nlength, n);
  1128. free(p);
  1129. qlock(&c->l);
  1130. if (ch->otherid == -1)
  1131. rsleep(&ch->r);
  1132. qunlock(&c->l);
  1133. } else if (strcmp(toks[0], "global") == 0) {
  1134. /* your ad here */
  1135. } else if (strcmp(toks[0], "hangup") == 0) {
  1136. if (ch->state != Closed && ch->state != Closing) {
  1137. ch->state = Closing;
  1138. if (ch->otherid != -1) {
  1139. p = new_packet(c);
  1140. add_byte(p, SSH_MSG_CHANNEL_CLOSE);
  1141. add_uint32(p, ch->otherid);
  1142. n = finish_packet(p);
  1143. iowrite(c->dio, c->datafd, p->nlength, n);
  1144. free(p);
  1145. }
  1146. qlock(&c->l);
  1147. rwakeup(&ch->r);
  1148. qunlock(&c->l);
  1149. nbsendul(ch->inchan, 1);
  1150. nbsendul(ch->reqchan, 1);
  1151. }
  1152. for (n = 0; n < MAXCONN && (c->chans[n] == nil ||
  1153. c->chans[n]->state == Empty ||
  1154. c->chans[n]->state == Closing ||
  1155. c->chans[n]->state == Closed); ++n)
  1156. ;
  1157. if (n >= MAXCONN) {
  1158. if (c->rpid >= 0)
  1159. threadint(c->rpid);
  1160. shutdown(c);
  1161. }
  1162. } else if (strcmp(toks[0], "announce") == 0) {
  1163. sshdebug(c, "got argument `%s' for chan announce",
  1164. toks[1]);
  1165. free(ch->ann);
  1166. ch->ann = estrdup9p(toks[1]);
  1167. }
  1168. break;
  1169. }
  1170. r->ofcall.count = r->ifcall.count;
  1171. r->aux = 0;
  1172. respond(r, nil);
  1173. free(buf);
  1174. threadexits(nil);
  1175. }
  1176. void
  1177. writereqremproc(void *a)
  1178. {
  1179. Req *r;
  1180. Packet *p;
  1181. Conn *c;
  1182. SSHChan *ch;
  1183. char *cmd, *q, *buf, *toks[4];
  1184. int n, ntok, lev, xconn;
  1185. uvlong qidpath;
  1186. threadsetname("writereqremproc");
  1187. r = a;
  1188. qidpath = (uvlong)r->fid->file->aux;
  1189. lev = qidpath >> Levshift;
  1190. xconn = (qidpath >> Connshift) & Connmask;
  1191. c = connections[xconn];
  1192. if (c == nil) {
  1193. respond(r, "Invalid connection");
  1194. threadexits(nil);
  1195. }
  1196. ch = c->chans[qidpath & Chanmask];
  1197. if (r->ifcall.count <= 10)
  1198. buf = emalloc9p(10 + 1);
  1199. else
  1200. buf = emalloc9p(r->ifcall.count + 1);
  1201. memmove(buf, r->ifcall.data, r->ifcall.count);
  1202. buf[r->ifcall.count] = '\0';
  1203. sshdebug(c, "writereqrem: %s", buf);
  1204. ntok = tokenize(buf, toks, nelem(toks));
  1205. if (lev == Top) {
  1206. free(keymbox.msg);
  1207. keymbox.msg = buf;
  1208. nbsendul(keymbox.mchan, 1);
  1209. r->ofcall.count = r->ifcall.count;
  1210. respexit(c, r, nil, nil);
  1211. }
  1212. r->ofcall.count = r->ifcall.count;
  1213. if (c->state == Closed || c->state == Closing ||
  1214. ch->state == Closed || ch->state == Closing)
  1215. respexit(c, r, buf, nil);
  1216. p = new_packet(c);
  1217. if (strcmp(toks[0], "success") == 0) {
  1218. add_byte(p, SSH_MSG_CHANNEL_SUCCESS);
  1219. add_uint32(p, ch->otherid);
  1220. } else if (strcmp(toks[0], "failure") == 0) {
  1221. add_byte(p, SSH_MSG_CHANNEL_FAILURE);
  1222. add_uint32(p, ch->otherid);
  1223. } else if (strcmp(toks[0], "close") == 0) {
  1224. ch->state = Closing;
  1225. add_byte(p, SSH_MSG_CHANNEL_CLOSE);
  1226. add_uint32(p, ch->otherid);
  1227. } else if (strcmp(toks[0], "shell") == 0) {
  1228. ch->state = Established;
  1229. /*
  1230. * Some servers *cough*OpenSSH*cough* don't seem to be able
  1231. * to intelligently handle a shell with no pty.
  1232. */
  1233. add_byte(p, SSH_MSG_CHANNEL_REQUEST);
  1234. add_uint32(p, ch->otherid);
  1235. add_string(p, "pty-req");
  1236. add_byte(p, 0);
  1237. if (ntok == 1)
  1238. add_string(p, "dumb");
  1239. else
  1240. add_string(p, toks[1]);
  1241. add_uint32(p, 0);
  1242. add_uint32(p, 0);
  1243. add_uint32(p, 0);
  1244. add_uint32(p, 0);
  1245. add_string(p, "");
  1246. n = finish_packet(p);
  1247. iowrite(c->dio, c->datafd, p->nlength, n);
  1248. init_packet(p);
  1249. p->c = c;
  1250. add_byte(p, SSH_MSG_CHANNEL_REQUEST);
  1251. add_uint32(p, ch->otherid);
  1252. add_string(p, "shell");
  1253. add_byte(p, 0);
  1254. sshdebug(c, "sending shell request: rlength=%lud twindow=%lud",
  1255. p->rlength, ch->twindow);
  1256. } else if (strcmp(toks[0], "exec") == 0) {
  1257. ch->state = Established;
  1258. add_byte(p, SSH_MSG_CHANNEL_REQUEST);
  1259. add_uint32(p, ch->otherid);
  1260. add_string(p, "exec");
  1261. add_byte(p, 0);
  1262. cmd = emalloc9p(Bigbufsz);
  1263. q = seprint(cmd, cmd+Bigbufsz, "%s", toks[1]);
  1264. for (n = 2; n < ntok; ++n) {
  1265. q = seprint(q, cmd+Bigbufsz, " %q", toks[n]);
  1266. if (q == nil)
  1267. break;
  1268. }
  1269. add_string(p, cmd);
  1270. free(cmd);
  1271. } else
  1272. respexit(c, r, buf, "bad request command");
  1273. n = finish_packet(p);
  1274. iowrite(c->dio, c->datafd, p->nlength, n);
  1275. free(p);
  1276. respexit(c, r, buf, nil);
  1277. }
  1278. void
  1279. writedataproc(void *a)
  1280. {
  1281. Req *r;
  1282. Packet *p;
  1283. Conn *c;
  1284. SSHChan *ch;
  1285. int n, xconn;
  1286. uvlong qidpath;
  1287. threadsetname("writedataproc");
  1288. r = a;
  1289. qidpath = (uvlong)r->fid->file->aux;
  1290. xconn = (qidpath >> Connshift) & Connmask;
  1291. c = connections[xconn];
  1292. if (c == nil) {
  1293. respond(r, "Invalid connection");
  1294. threadexits(nil);
  1295. }
  1296. ch = c->chans[qidpath & Chanmask];
  1297. p = new_packet(c);
  1298. add_byte(p, SSH_MSG_CHANNEL_DATA);
  1299. hnputl(p->payload+1, ch->otherid);
  1300. p->rlength += 4;
  1301. add_block(p, r->ifcall.data, r->ifcall.count);
  1302. n = finish_packet(p);
  1303. if (ch->sent + p->rlength > ch->twindow) {
  1304. qlock(&ch->xmtlock);
  1305. while (ch->sent + p->rlength > ch->twindow)
  1306. rsleep(&ch->xmtrendez);
  1307. qunlock(&ch->xmtlock);
  1308. }
  1309. iowrite(c->dio, c->datafd, p->nlength, n);
  1310. respexit(c, r, p, nil);
  1311. }
  1312. /*
  1313. * Although this is named stclunk, it's attached to the destroyfid
  1314. * member of the Srv struct. It turns out there's no member
  1315. * called clunk. But if there are no other references, a 9P Tclunk
  1316. * will end up calling destroyfid.
  1317. */
  1318. void
  1319. stclunk(Fid *f)
  1320. {
  1321. Packet *p;
  1322. Conn *c;
  1323. SSHChan *sc;
  1324. int n, lev, cnum, chnum;
  1325. uvlong qidpath;
  1326. threadsetname("stclunk");
  1327. if (f == nil || f->file == nil)
  1328. return;
  1329. qidpath = (uvlong)f->file->aux;
  1330. lev = qidpath >> Levshift;
  1331. cnum = (qidpath >> Connshift) & Connmask;
  1332. chnum = qidpath & Chanmask;
  1333. c = connections[cnum];
  1334. sshdebug(c, "got clunk on file: %#llux %d %d %d: %s",
  1335. qidpath, lev, cnum, chnum, f->file->name);
  1336. /* qidpath test implies conn 0, chan 0 */
  1337. if (lev == Top && qidpath == Qreqrem) {
  1338. if (keymbox.state != Empty) {
  1339. keymbox.state = Empty;
  1340. // nbsendul(keymbox.mchan, 1);
  1341. }
  1342. keymbox.msg = nil;
  1343. return;
  1344. }
  1345. if (c == nil)
  1346. return;
  1347. if (lev == Connection && (qidpath & Qtypemask) == Qctl &&
  1348. (c->state == Opening || c->state == Negotiating ||
  1349. c->state == Authing)) {
  1350. for (n = 0; n < MAXCONN && (!c->chans[n] ||
  1351. c->chans[n]->state == Empty ||
  1352. c->chans[n]->state == Closed ||
  1353. c->chans[n]->state == Closing); ++n)
  1354. ;
  1355. if (n >= MAXCONN) {
  1356. if (c->rpid >= 0)
  1357. threadint(c->rpid);
  1358. shutdown(c);
  1359. }
  1360. return;
  1361. }
  1362. sc = c->chans[chnum];
  1363. if (lev != Subchannel)
  1364. return;
  1365. if ((qidpath & Qtypemask) == Qlisten && sc->state == Listening) {
  1366. qlock(&c->l);
  1367. if (sc->state != Closed) {
  1368. sc->state = Closed;
  1369. chanclose(sc->inchan);
  1370. chanclose(sc->reqchan);
  1371. }
  1372. qunlock(&c->l);
  1373. } else if ((qidpath & Qtypemask) == Qdata && sc->state != Empty &&
  1374. sc->state != Closed && sc->state != Closing) {
  1375. if (f->file != sc->data && f->file != sc->request) {
  1376. sshlog(c, "great evil is upon us; destroying a fid "
  1377. "we didn't create");
  1378. return;
  1379. }
  1380. p = new_packet(c);
  1381. add_byte(p, SSH_MSG_CHANNEL_CLOSE);
  1382. hnputl(p->payload+1, sc->otherid);
  1383. p->rlength += 4;
  1384. n = finish_packet(p);
  1385. sc->state = Closing;
  1386. iowrite(c->dio, c->datafd, p->nlength, n);
  1387. free(p);
  1388. qlock(&c->l);
  1389. rwakeup(&sc->r);
  1390. qunlock(&c->l);
  1391. nbsendul(sc->inchan, 1);
  1392. nbsendul(sc->reqchan, 1);
  1393. }
  1394. for (n = 0; n < MAXCONN && (!c->chans[n] ||
  1395. c->chans[n]->state == Empty || c->chans[n]->state == Closed ||
  1396. c->chans[n]->state == Closing); ++n)
  1397. ;
  1398. if (n >= MAXCONN) {
  1399. if (c->rpid >= 0)
  1400. threadint(c->rpid);
  1401. shutdown(c);
  1402. }
  1403. }
  1404. void
  1405. stflush(Req *r)
  1406. {
  1407. Req *or;
  1408. uvlong qidpath;
  1409. threadsetname("stflush");
  1410. or = r->oldreq;
  1411. qidpath = (uvlong)or->fid->file->aux;
  1412. sshdebug(nil, "got flush on file %#llux %lld %lld %lld: %s %#p",
  1413. argv0, qidpath, qidpath >> Levshift,
  1414. (qidpath >> Connshift) & Connmask, qidpath & Chanmask,
  1415. or->fid->file->name, or->aux);
  1416. if (!or->aux)
  1417. respond(or, "interrupted");
  1418. else if (or->ifcall.type == Topen && (qidpath & Qtypemask) == Qlisten ||
  1419. or->ifcall.type == Tread && (qidpath & Qtypemask) == Qdata &&
  1420. (qidpath >> Levshift) == Subchannel ||
  1421. or->ifcall.type == Tread && (qidpath & Qtypemask) == Qreqrem)
  1422. threadint((uintptr)or->aux);
  1423. else {
  1424. threadkill((uintptr)or->aux);
  1425. or->aux = 0;
  1426. respond(or, "interrupted");
  1427. }
  1428. respond(r, nil);
  1429. }
  1430. void
  1431. filedup(Req *r, File *src)
  1432. {
  1433. r->ofcall.qid = src->qid;
  1434. closefile(r->fid->file);
  1435. r->fid->file = src;
  1436. incref(src);
  1437. }
  1438. Conn *
  1439. alloc_conn(void)
  1440. {
  1441. int slevconn, i, s, firstnil;
  1442. char buf[Numbsz];
  1443. Conn *c;
  1444. static QLock aclock;
  1445. qlock(&aclock);
  1446. firstnil = -1;
  1447. for (i = 0; i < MAXCONN; ++i) {
  1448. if (connections[i] == nil) {
  1449. if (firstnil == -1)
  1450. firstnil = i;
  1451. continue;
  1452. }
  1453. s = connections[i]->state;
  1454. if (s == Empty || s == Closed)
  1455. break;
  1456. }
  1457. if (i >= MAXCONN) {
  1458. if (firstnil == -1) { /* all slots in use? */
  1459. qunlock(&aclock);
  1460. return nil;
  1461. }
  1462. /* no reusable slots, allocate a new Conn */
  1463. connections[firstnil] = emalloc9p(sizeof(Conn));
  1464. memset(connections[firstnil], 0, sizeof(Conn));
  1465. i = firstnil;
  1466. }
  1467. c = connections[i];
  1468. memset(&c->r, '\0', sizeof(Rendez));
  1469. c->r.l = &c->l;
  1470. c->dio = ioproc();
  1471. c->rio = nil;
  1472. c->state = Allocated;
  1473. c->role = Server;
  1474. c->id = i;
  1475. c->stifle = c->poisoned = 0;
  1476. c->user = c->service = nil;
  1477. c->inseq = c->nchan = c->outseq = 0;
  1478. c->cscrypt = c->csmac = c->ctlfd = c->datafd = c->decrypt =
  1479. c->encrypt = c->inmac = c->ncscrypt = c->ncsmac =
  1480. c->nsccrypt = c->nscmac = c->outmac = c->rpid = c->sccrypt =
  1481. c->scmac = c->tcpconn = -1;
  1482. if (c->e) {
  1483. mpfree(c->e);
  1484. c->e = nil;
  1485. }
  1486. if (c->x) {
  1487. mpfree(c->x);
  1488. c->x = nil;
  1489. }
  1490. snprint(buf, sizeof buf, "%d", i);
  1491. if (c->dir == nil) {
  1492. slevconn = Connection << Levshift | i << Connshift;
  1493. c->dir = createfile(rootfile, buf, uid, 0555|DMDIR,
  1494. (void *)(slevconn | Qroot));
  1495. c->clonefile = createfile(c->dir, "clone", uid, 0666,
  1496. (void *)(slevconn | Qclone));
  1497. c->ctlfile = createfile(c->dir, "ctl", uid, 0666,
  1498. (void *)(slevconn | Qctl));
  1499. c->datafile = createfile(c->dir, "data", uid, 0666,
  1500. (void *)(slevconn | Qdata));
  1501. c->listenfile = createfile(c->dir, "listen", uid, 0666,
  1502. (void *)(slevconn | Qlisten));
  1503. c->localfile = createfile(c->dir, "local", uid, 0444,
  1504. (void *)(slevconn | Qlocal));
  1505. c->remotefile = createfile(c->dir, "remote", uid, 0444,
  1506. (void *)(slevconn | Qreqrem));
  1507. c->statusfile = createfile(c->dir, "status", uid, 0444,
  1508. (void *)(slevconn | Qstatus));
  1509. c->tcpfile = createfile(c->dir, "tcp", uid, 0444,
  1510. (void *)(slevconn | Qtcp));
  1511. }
  1512. // c->skexinit = c->rkexinit = nil;
  1513. c->got_sessid = 0;
  1514. c->otherid = nil;
  1515. c->inik = c->outik = nil;
  1516. c->s2ccs = c->c2scs = c->enccs = c->deccs = nil;
  1517. qunlock(&aclock);
  1518. return c;
  1519. }
  1520. SSHChan *
  1521. alloc_chan(Conn *c)
  1522. {
  1523. int cnum, slcn;
  1524. char buf[Numbsz];
  1525. Plist *p, *next;
  1526. SSHChan *sc;
  1527. if (c->nchan >= MAXCONN)
  1528. return nil;
  1529. qlock(&c->l);
  1530. cnum = c->nchan;
  1531. if (c->chans[cnum] == nil) {
  1532. c->chans[cnum] = emalloc9p(sizeof(SSHChan));
  1533. memset(c->chans[cnum], 0, sizeof(SSHChan));
  1534. }
  1535. sc = c->chans[cnum];
  1536. snprint(buf, sizeof buf, "%d", cnum);
  1537. memset(&sc->r, '\0', sizeof(Rendez));
  1538. sc->r.l = &c->l;
  1539. sc->id = cnum;
  1540. sc->state = Empty;
  1541. sc->conn = c->id;
  1542. sc->otherid = sc->waker = -1;
  1543. sc->sent = sc->twindow = sc->rwindow = sc->inrqueue = 0;
  1544. sc->ann = nil;
  1545. sc->lreq = nil;
  1546. if (sc->dir == nil) {
  1547. slcn = Subchannel << Levshift | c->id << Connshift | cnum;
  1548. sc->dir = createfile(c->dir, buf, uid, 0555|DMDIR,
  1549. (void *)(slcn | Qroot));
  1550. sc->ctl = createfile(sc->dir, "ctl", uid, 0666,
  1551. (void *)(slcn | Qctl));
  1552. sc->data = createfile(sc->dir, "data", uid, 0666,
  1553. (void *)(slcn | Qdata));
  1554. sc->listen = createfile(sc->dir, "listen", uid, 0666,
  1555. (void *)(slcn | Qlisten));
  1556. sc->request = createfile(sc->dir, "request", uid, 0666,
  1557. (void *)(slcn | Qreqrem));
  1558. sc->status = createfile(sc->dir, "status", uid, 0444,
  1559. (void *)(slcn | Qstatus));
  1560. sc->tcp = createfile(sc->dir, "tcp", uid, 0444,
  1561. (void *)(slcn | Qtcp));
  1562. }
  1563. c->nchan++;
  1564. for (; sc->reqq != nil; sc->reqq = next) {
  1565. p = sc->reqq;
  1566. next = p->next;
  1567. free(p->pack);
  1568. free(p);
  1569. }
  1570. sc->dataq = sc->datatl = sc->reqtl = nil;
  1571. if (sc->inchan)
  1572. chanfree(sc->inchan);
  1573. sc->inchan = chancreate(4, 0);
  1574. if (sc->reqchan)
  1575. chanfree(sc->reqchan);
  1576. sc->reqchan = chancreate(4, 0);
  1577. memset(&sc->xmtrendez, '\0', sizeof(Rendez));
  1578. sc->xmtrendez.l = &sc->xmtlock;
  1579. qunlock(&c->l);
  1580. return sc;
  1581. }
  1582. static int
  1583. readlineio(Conn *, Ioproc *io, int fd, char *buf, int size)
  1584. {
  1585. int n;
  1586. char *p;
  1587. for (p = buf; p < buf + size - 1; p++) {
  1588. n = ioread(io, fd, p, 1);
  1589. if (n != 1 || *p == '\n') {
  1590. *p = '\0';
  1591. break;
  1592. }
  1593. }
  1594. return p - buf;
  1595. }
  1596. static char *
  1597. readremote(Conn *c, Ioproc *io, char *tcpconn)
  1598. {
  1599. int n, remfd;
  1600. char *p, *remote;
  1601. char path[Arbbufsz], buf[NETPATHLEN];
  1602. remote = nil;
  1603. snprint(path, sizeof path, "%s/tcp/%s/remote", mntpt, tcpconn);
  1604. remfd = ioopen(io, path, OREAD);
  1605. if (remfd < 0) {
  1606. sshlog(c, "readremote: can't open %s: %r", path);
  1607. return nil;
  1608. }
  1609. n = ioread(io, remfd, buf, sizeof buf - 1);
  1610. if (n > 0) {
  1611. buf[n] = 0;
  1612. p = strchr(buf, '!');
  1613. if (p)
  1614. *p = 0;
  1615. remote = estrdup9p(buf);
  1616. }
  1617. ioclose(io, remfd);
  1618. return remote;
  1619. }
  1620. static void
  1621. sendmyid(Conn *c, Ioproc *io)
  1622. {
  1623. char path[Arbbufsz];
  1624. snprint(path, sizeof path, "%s\r\n", MYID);
  1625. iowrite(io, c->datafd, path, strlen(path));
  1626. }
  1627. /* save and tidy up the remote id */
  1628. static void
  1629. stashremid(Conn *c, char *remid)
  1630. {
  1631. char *nl;
  1632. if (c->otherid)
  1633. free(c->otherid);
  1634. c->otherid = estrdup9p(remid);
  1635. nl = strchr(c->otherid, '\n');
  1636. if (nl)
  1637. *nl = '\0';
  1638. nl = strchr(c->otherid, '\r');
  1639. if (nl)
  1640. *nl = '\0';
  1641. }
  1642. static void
  1643. hangupconn(Conn *c)
  1644. {
  1645. hangup(c->ctlfd);
  1646. close(c->ctlfd);
  1647. close(c->datafd);
  1648. c->ctlfd = c->datafd = -1;
  1649. }
  1650. #ifdef COEXIST
  1651. static int
  1652. exchids(Conn *c, Ioproc *io, char *remid, int remsz)
  1653. {
  1654. int n;
  1655. /*
  1656. * exchange versions. server writes id, then reads;
  1657. * client reads id then writes (in theory).
  1658. */
  1659. if (c->role == Server) {
  1660. sendmyid(c, io);
  1661. n = readlineio(c, io, c->datafd, remid, remsz);
  1662. if (n < 5) /* can't be a valid SSH id string */
  1663. return -1;
  1664. sshdebug(c, "dohandshake: server, got `%s', sent `%s'", remid,
  1665. MYID);
  1666. } else {
  1667. /* client: read server's id */
  1668. n = readlineio(c, io, c->datafd, remid, remsz);
  1669. if (n < 5) /* can't be a valid SSH id string */
  1670. return -1;
  1671. sendmyid(c, io);
  1672. sshdebug(c, "dohandshake: client, got `%s' sent `%s'", remid, MYID);
  1673. if (remid[0] == '\0') {
  1674. sshlog(c, "dohandshake: client, empty remote id string;"
  1675. " out of sync");
  1676. return -1;
  1677. }
  1678. }
  1679. sshdebug(c, "remote id string `%s'", remid);
  1680. return 0;
  1681. }
  1682. /*
  1683. * negotiate the protocols.
  1684. * We don't do the full negotiation here, because we also have
  1685. * to handle a re-negotiation request from the other end.
  1686. * So we just kick it off and let the receiver process take it from there.
  1687. */
  1688. static int
  1689. negotiate(Conn *c)
  1690. {
  1691. send_kexinit(c);
  1692. qlock(&c->l);
  1693. if ((c->role == Client && c->state != Negotiating) ||
  1694. (c->role == Server && c->state != Established)) {
  1695. sshdebug(c, "awaiting establishment");
  1696. rsleep(&c->r);
  1697. }
  1698. qunlock(&c->l);
  1699. if (c->role == Server && c->state != Established ||
  1700. c->role == Client && c->state != Negotiating) {
  1701. sshdebug(c, "failed to establish");
  1702. return -1;
  1703. }
  1704. sshdebug(c, "established; crypto now on");
  1705. return 0;
  1706. }
  1707. /* this was deferred when trying to make coexistence with v1 work */
  1708. static int
  1709. deferredinit(Conn *c)
  1710. {
  1711. char remid[Arbbufsz];
  1712. Ioproc *io;
  1713. io = ioproc();
  1714. /*
  1715. * don't bother checking the remote's id string.
  1716. * as a client, we can cope with v1 if we don't verify the host key.
  1717. */
  1718. if (exchids(c, io, remid, sizeof remid) < 0 ||
  1719. 0 && c->role == Client && strncmp(remid, "SSH-2", 5) != 0 &&
  1720. strncmp(remid, "SSH-1.99", 8) != 0) {
  1721. /* not a protocol version we know; give up */
  1722. closeioproc(io);
  1723. hangupconn(c);
  1724. return -1;
  1725. }
  1726. closeioproc(io);
  1727. stashremid(c, remid);
  1728. c->state = Initting;
  1729. /* start the reader thread */
  1730. if (c->rpid < 0)
  1731. c->rpid = threadcreate(reader, c, Defstk);
  1732. return negotiate(c);
  1733. }
  1734. int
  1735. dohandshake(Conn *c, char *tcpconn)
  1736. {
  1737. int tcpdfd;
  1738. char *remote;
  1739. char path[Arbbufsz];
  1740. Ioproc *io;
  1741. io = ioproc();
  1742. /* read tcp conn's remote address into c->remote */
  1743. remote = readremote(c, io, tcpconn);
  1744. if (remote) {
  1745. free(c->remote);
  1746. c->remote = remote;
  1747. }
  1748. /* open tcp conn's data file */
  1749. c->tcpconn = atoi(tcpconn);
  1750. snprint(path, sizeof path, "%s/tcp/%s/data", mntpt, tcpconn);
  1751. tcpdfd = ioopen(io, path, ORDWR);
  1752. closeioproc(io);
  1753. if (tcpdfd < 0) {
  1754. sshlog(c, "dohandshake: can't open %s: %r", path);
  1755. return -1;
  1756. }
  1757. c->datafd = tcpdfd; /* underlying tcp data descriptor */
  1758. return deferredinit(c);
  1759. }
  1760. #endif /* COEXIST */
  1761. int
  1762. dohandshake(Conn *c, char *tcpconn)
  1763. {
  1764. int fd, n;
  1765. char *p, *othid;
  1766. char path[Arbbufsz], buf[NETPATHLEN];
  1767. Ioproc *io;
  1768. io = ioproc();
  1769. snprint(path, sizeof path, "%s/tcp/%s/remote", mntpt, tcpconn);
  1770. fd = ioopen(io, path, OREAD);
  1771. n = ioread(io, fd, buf, sizeof buf - 1);
  1772. if (n > 0) {
  1773. buf[n] = 0;
  1774. p = strchr(buf, '!');
  1775. if (p)
  1776. *p = 0;
  1777. free(c->remote);
  1778. c->remote = estrdup9p(buf);
  1779. }
  1780. ioclose(io, fd);
  1781. snprint(path, sizeof path, "%s/tcp/%s/data", mntpt, tcpconn);
  1782. fd = ioopen(io, path, ORDWR);
  1783. if (fd < 0) {
  1784. closeioproc(io);
  1785. return -1;
  1786. }
  1787. c->datafd = fd;
  1788. /* exchange versions--we're only doing SSH2, unfortunately */
  1789. snprint(path, sizeof path, "%s\r\n", MYID);
  1790. if (c->idstring && c->idstring[0])
  1791. strncpy(path, c->idstring, sizeof path);
  1792. else {
  1793. iowrite(io, fd, path, strlen(path));
  1794. p = path;
  1795. n = 0;
  1796. do {
  1797. if (ioread(io, fd, p, 1) < 0) {
  1798. fprint(2, "%s: short read in ID exchange: %r\n",
  1799. argv0);
  1800. break;
  1801. }
  1802. ++n;
  1803. } while (*p++ != '\n');
  1804. if (n < 5) { /* can't be a valid SSH id string */
  1805. close(fd);
  1806. goto err;
  1807. }
  1808. *p = 0;
  1809. }
  1810. sshdebug(c, "id string `%s'", path);
  1811. if (c->idstring[0] == '\0' &&
  1812. strncmp(path, "SSH-2", 5) != 0 &&
  1813. strncmp(path, "SSH-1.99", 8) != 0) {
  1814. /* not a protocol version we know; give up */
  1815. ioclose(io, fd);
  1816. goto err;
  1817. }
  1818. closeioproc(io);
  1819. if (c->otherid)
  1820. free(c->otherid);
  1821. c->otherid = othid = estrdup9p(path);
  1822. for (n = strlen(othid) - 1; othid[n] == '\r' || othid[n] == '\n'; --n)
  1823. othid[n] = '\0';
  1824. c->state = Initting;
  1825. /* start the reader thread */
  1826. if (c->rpid < 0)
  1827. c->rpid = threadcreate(reader, c, Defstk);
  1828. /*
  1829. * negotiate the protocols
  1830. * We don't do the full negotiation here, because we also have
  1831. * to handle a re-negotiation request from the other end. So
  1832. * we just kick it off and let the receiver process take it from there.
  1833. */
  1834. send_kexinit(c);
  1835. qlock(&c->l);
  1836. if ((c->role == Client && c->state != Negotiating) ||
  1837. (c->role == Server && c->state != Established))
  1838. rsleep(&c->r);
  1839. qunlock(&c->l);
  1840. if (c->role == Server && c->state != Established ||
  1841. c->role == Client && c->state != Negotiating)
  1842. return -1;
  1843. return 0;
  1844. err:
  1845. /* should use hangup in dial(2) instead of diddling /net/tcp */
  1846. snprint(path, sizeof path, "%s/tcp/%s/ctl", mntpt, tcpconn);
  1847. fd = ioopen(io, path, OWRITE);
  1848. iowrite(io, fd, "hangup", 6);
  1849. ioclose(io, fd);
  1850. closeioproc(io);
  1851. return -1;
  1852. }
  1853. void
  1854. send_kexinit(Conn *c)
  1855. {
  1856. Packet *ptmp;
  1857. char *buf, *p, *e;
  1858. int i, msglen;
  1859. sshdebug(c, "initializing kexinit packet");
  1860. if (c->skexinit != nil)
  1861. free(c->skexinit);
  1862. c->skexinit = new_packet(c);
  1863. buf = emalloc9p(Bigbufsz);
  1864. buf[0] = (uchar)SSH_MSG_KEXINIT;
  1865. add_packet(c->skexinit, buf, 1);
  1866. for (i = 0; i < 16; ++i)
  1867. buf[i] = fastrand();
  1868. add_packet(c->skexinit, buf, 16); /* cookie */
  1869. e = buf + Bigbufsz - 1;
  1870. p = seprint(buf, e, "%s", kexes[0]->name);
  1871. for (i = 1; i < nelem(kexes); ++i)
  1872. p = seprint(p, e, ",%s", kexes[i]->name);
  1873. sshdebug(c, "sent KEX algs: %s", buf);
  1874. add_string(c->skexinit, buf); /* Key exchange */
  1875. if (pkas[0] == nil)
  1876. add_string(c->skexinit, "");
  1877. else{
  1878. p = seprint(buf, e, "%s", pkas[0]->name);
  1879. for (i = 1; i < nelem(pkas) && pkas[i] != nil; ++i)
  1880. p = seprint(p, e, ",%s", pkas[i]->name);
  1881. sshdebug(c, "sent host key algs: %s", buf);
  1882. add_string(c->skexinit, buf); /* server's key algs */
  1883. }
  1884. p = seprint(buf, e, "%s", cryptos[0]->name);
  1885. for (i = 1; i < nelem(cryptos); ++i)
  1886. p = seprint(p, e, ",%s", cryptos[i]->name);
  1887. sshdebug(c, "sent crypto algs: %s", buf);
  1888. add_string(c->skexinit, buf); /* c->s crypto */
  1889. add_string(c->skexinit, buf); /* s->c crypto */
  1890. p = seprint(buf, e, "%s", macnames[0]);
  1891. for (i = 1; i < nelem(macnames); ++i)
  1892. p = seprint(p, e, ",%s", macnames[i]);
  1893. sshdebug(c, "sent MAC algs: %s", buf);
  1894. add_string(c->skexinit, buf); /* c->s mac */
  1895. add_string(c->skexinit, buf); /* s->c mac */
  1896. add_string(c->skexinit, "none"); /* c->s compression */
  1897. add_string(c->skexinit, "none"); /* s->c compression */
  1898. add_string(c->skexinit, ""); /* c->s languages */
  1899. add_string(c->skexinit, ""); /* s->c languages */
  1900. memset(buf, 0, 5);
  1901. add_packet(c->skexinit, buf, 5);
  1902. ptmp = new_packet(c);
  1903. memmove(ptmp, c->skexinit, sizeof(Packet));
  1904. msglen = finish_packet(ptmp);
  1905. if (c->dio && c->datafd >= 0)
  1906. iowrite(c->dio, c->datafd, ptmp->nlength, msglen);
  1907. free(ptmp);
  1908. free(buf);
  1909. }
  1910. static void
  1911. establish(Conn *c)
  1912. {
  1913. qlock(&c->l);
  1914. c->state = Established;
  1915. rwakeup(&c->r);
  1916. qunlock(&c->l);
  1917. }
  1918. static int
  1919. negotiating(Conn *c, Packet *p, Packet *p2, char *buf, int size)
  1920. {
  1921. int i, n;
  1922. USED(size);
  1923. switch (p->payload[0]) {
  1924. case SSH_MSG_DISCONNECT:
  1925. if (debug) {
  1926. get_string(p, p->payload + 5, buf, Arbbufsz, nil);
  1927. sshdebug(c, "got disconnect: %s", buf);
  1928. }
  1929. return -1;
  1930. case SSH_MSG_NEWKEYS:
  1931. /*
  1932. * If we're just updating, go straight to
  1933. * established, otherwise wait for auth'n.
  1934. */
  1935. i = c->encrypt;
  1936. memmove(c->c2siv, c->nc2siv, SHA1dlen*2);
  1937. memmove(c->s2civ, c->ns2civ, SHA1dlen*2);
  1938. memmove(c->c2sek, c->nc2sek, SHA1dlen*2);
  1939. memmove(c->s2cek, c->ns2cek, SHA1dlen*2);
  1940. memmove(c->c2sik, c->nc2sik, SHA1dlen*2);
  1941. memmove(c->s2cik, c->ns2cik, SHA1dlen*2);
  1942. c->cscrypt = c->ncscrypt;
  1943. c->sccrypt = c->nsccrypt;
  1944. c->csmac = c->ncsmac;
  1945. c->scmac = c->nscmac;
  1946. c->c2scs = cryptos[c->cscrypt]->init(c, 0);
  1947. c->s2ccs = cryptos[c->sccrypt]->init(c, 1);
  1948. if (c->role == Server) {
  1949. c->encrypt = c->sccrypt;
  1950. c->decrypt = c->cscrypt;
  1951. c->outmac = c->scmac;
  1952. c->inmac = c->csmac;
  1953. c->enccs = c->s2ccs;
  1954. c->deccs = c->c2scs;
  1955. c->outik = c->s2cik;
  1956. c->inik = c->c2sik;
  1957. } else{
  1958. c->encrypt = c->cscrypt;
  1959. c->decrypt = c->sccrypt;
  1960. c->outmac = c->csmac;
  1961. c->inmac = c->scmac;
  1962. c->enccs = c->c2scs;
  1963. c->deccs = c->s2ccs;
  1964. c->outik = c->c2sik;
  1965. c->inik = c->s2cik;
  1966. }
  1967. sshdebug(c, "using %s for encryption and %s for decryption",
  1968. cryptos[c->encrypt]->name, cryptos[c->decrypt]->name);
  1969. qlock(&c->l);
  1970. if (i != -1)
  1971. c->state = Established;
  1972. if (c->role == Client)
  1973. rwakeup(&c->r);
  1974. qunlock(&c->l);
  1975. break;
  1976. case SSH_MSG_KEXDH_INIT:
  1977. kexes[c->kexalg]->serverkex(c, p);
  1978. break;
  1979. case SSH_MSG_KEXDH_REPLY:
  1980. init_packet(p2);
  1981. p2->c = c;
  1982. if (kexes[c->kexalg]->clientkex2(c, p) < 0) {
  1983. add_byte(p2, SSH_MSG_DISCONNECT);
  1984. add_byte(p2, SSH_DISCONNECT_KEY_EXCHANGE_FAILED);
  1985. add_string(p2, "Key exchange failure");
  1986. add_string(p2, "");
  1987. n = finish_packet(p2);
  1988. iowrite(c->rio, c->datafd, p2->nlength, n);
  1989. shutdown(c);
  1990. free(p);
  1991. free(p2);
  1992. closeioproc(c->rio);
  1993. c->rio = nil;
  1994. c->rpid = -1;
  1995. qlock(&c->l);
  1996. rwakeup(&c->r);
  1997. qunlock(&c->l);
  1998. sshlog(c, "key exchange failure");
  1999. threadexits(nil);
  2000. }
  2001. add_byte(p2, SSH_MSG_NEWKEYS);
  2002. n = finish_packet(p2);
  2003. iowrite(c->rio, c->datafd, p2->nlength, n);
  2004. qlock(&c->l);
  2005. rwakeup(&c->r);
  2006. qunlock(&c->l);
  2007. break;
  2008. case SSH_MSG_SERVICE_REQUEST:
  2009. get_string(p, p->payload + 1, buf, Arbbufsz, nil);
  2010. sshdebug(c, "got service request: %s", buf);
  2011. if (strcmp(buf, "ssh-userauth") == 0 ||
  2012. strcmp(buf, "ssh-connection") == 0) {
  2013. init_packet(p2);
  2014. p2->c = c;
  2015. sshdebug(c, "connection");
  2016. add_byte(p2, SSH_MSG_SERVICE_ACCEPT);
  2017. add_string(p2, buf);
  2018. n = finish_packet(p2);
  2019. iowrite(c->rio, c->datafd, p2->nlength, n);
  2020. c->state = Authing;
  2021. } else{
  2022. init_packet(p2);
  2023. p2->c = c;
  2024. add_byte(p2, SSH_MSG_DISCONNECT);
  2025. add_byte(p2, SSH_DISCONNECT_SERVICE_NOT_AVAILABLE);
  2026. add_string(p2, "Unknown service type");
  2027. add_string(p2, "");
  2028. n = finish_packet(p2);
  2029. iowrite(c->rio, c->datafd, p2->nlength, n);
  2030. return -1;
  2031. }
  2032. break;
  2033. case SSH_MSG_SERVICE_ACCEPT:
  2034. get_string(p, p->payload + 1, buf, Arbbufsz, nil);
  2035. if (c->service && strcmp(c->service, "ssh-userauth") == 0) {
  2036. free(c->service);
  2037. c->service = estrdup9p("ssh-connection");
  2038. }
  2039. sshdebug(c, "got service accept: %s: responding with %s %s",
  2040. buf, c->user, c->service);
  2041. n = client_auth(c, c->rio);
  2042. c->state = Authing;
  2043. if (n < 0) {
  2044. qlock(&c->l);
  2045. rwakeup(&c->r);
  2046. qunlock(&c->l);
  2047. }
  2048. break;
  2049. }
  2050. return 0;
  2051. }
  2052. static void
  2053. nochans(Conn *c, Packet *p, Packet *p2)
  2054. {
  2055. int n;
  2056. init_packet(p2);
  2057. p2->c = c;
  2058. add_byte(p2, SSH_MSG_CHANNEL_OPEN_FAILURE);
  2059. add_block(p2, p->payload + 5, 4);
  2060. hnputl(p2->payload + p2->rlength - 1, 4);
  2061. p2->rlength += 4;
  2062. add_string(p2, "No available channels");
  2063. add_string(p2, "EN");
  2064. n = finish_packet(p2);
  2065. iowrite(c->rio, c->datafd, p2->nlength, n);
  2066. }
  2067. static int
  2068. established(Conn *c, Packet *p, Packet *p2, char *buf, int size)
  2069. {
  2070. int i, n, cnum;
  2071. uchar *q;
  2072. Plist *pl;
  2073. SSHChan *ch;
  2074. USED(size);
  2075. if (debug > 1) {
  2076. sshdebug(c, "in Established state, got:");
  2077. dump_packet(p);
  2078. }
  2079. switch (p->payload[0]) {
  2080. case SSH_MSG_DISCONNECT:
  2081. if (debug) {
  2082. get_string(p, p->payload + 5, buf, Arbbufsz, nil);
  2083. sshdebug(c, "got disconnect: %s", buf);
  2084. }
  2085. return -1;
  2086. case SSH_MSG_IGNORE:
  2087. case SSH_MSG_UNIMPLEMENTED:
  2088. break;
  2089. case SSH_MSG_DEBUG:
  2090. if (debug || p->payload[1]) {
  2091. get_string(p, p->payload + 2, buf, Arbbufsz, nil);
  2092. sshdebug(c, "got debug message: %s", buf);
  2093. }
  2094. break;
  2095. case SSH_MSG_KEXINIT:
  2096. send_kexinit(c);
  2097. if (c->rkexinit)
  2098. free(c->rkexinit);
  2099. c->rkexinit = new_packet(c);
  2100. memmove(c->rkexinit, p, sizeof(Packet));
  2101. if (validatekex(c, p) < 0) {
  2102. sshdebug(c, "kex crypto algorithm mismatch (Established)");
  2103. return -1;
  2104. }
  2105. sshdebug(c, "using %s Kex algorithm and %s PKA",
  2106. kexes[c->kexalg]->name, pkas[c->pkalg]->name);
  2107. c->state = Negotiating;
  2108. break;
  2109. case SSH_MSG_GLOBAL_REQUEST:
  2110. case SSH_MSG_REQUEST_SUCCESS:
  2111. case SSH_MSG_REQUEST_FAILURE:
  2112. break;
  2113. case SSH_MSG_CHANNEL_OPEN:
  2114. q = get_string(p, p->payload + 1, buf, Arbbufsz, nil);
  2115. sshdebug(c, "searching for a listener for channel type %s", buf);
  2116. ch = alloc_chan(c);
  2117. if (ch == nil) {
  2118. nochans(c, p, p2);
  2119. break;
  2120. }
  2121. sshdebug(c, "alloced channel %d for listener", ch->id);
  2122. qlock(&c->l);
  2123. ch->otherid = nhgetl(q);
  2124. ch->twindow = nhgetl(q+4);
  2125. sshdebug(c, "got lock in channel open");
  2126. for (i = 0; i < c->nchan; ++i)
  2127. if (c->chans[i] && c->chans[i]->state == Listening &&
  2128. c->chans[i]->ann &&
  2129. strcmp(c->chans[i]->ann, buf) == 0)
  2130. break;
  2131. if (i >= c->nchan) {
  2132. sshdebug(c, "no listener: sleeping");
  2133. ch->state = Opening;
  2134. if (ch->ann)
  2135. free(ch->ann);
  2136. ch->ann = estrdup9p(buf);
  2137. sshdebug(c, "waiting for someone to announce %s", ch->ann);
  2138. rsleep(&ch->r);
  2139. } else{
  2140. sshdebug(c, "found listener on channel %d", ch->id);
  2141. c->chans[i]->waker = ch->id;
  2142. rwakeup(&c->chans[i]->r);
  2143. }
  2144. qunlock(&c->l);
  2145. break;
  2146. case SSH_MSG_CHANNEL_OPEN_CONFIRMATION:
  2147. cnum = nhgetl(p->payload + 1);
  2148. ch = c->chans[cnum];
  2149. qlock(&c->l);
  2150. ch->otherid = nhgetl(p->payload+5);
  2151. ch->twindow = nhgetl(p->payload+9);
  2152. rwakeup(&ch->r);
  2153. qunlock(&c->l);
  2154. break;
  2155. case SSH_MSG_CHANNEL_OPEN_FAILURE:
  2156. cnum = nhgetl(p->payload + 1);
  2157. ch = c->chans[cnum];
  2158. qlock(&c->l);
  2159. rwakeup(&ch->r);
  2160. qunlock(&c->l);
  2161. return -1;
  2162. case SSH_MSG_CHANNEL_WINDOW_ADJUST:
  2163. cnum = nhgetl(p->payload + 1);
  2164. ch = c->chans[cnum];
  2165. ch->twindow += nhgetl(p->payload + 5);
  2166. sshdebug(c, "new twindow for channel: %d: %lud", cnum, ch->twindow);
  2167. qlock(&ch->xmtlock);
  2168. rwakeup(&ch->xmtrendez);
  2169. qunlock(&ch->xmtlock);
  2170. break;
  2171. case SSH_MSG_CHANNEL_DATA:
  2172. case SSH_MSG_CHANNEL_EXTENDED_DATA:
  2173. cnum = nhgetl(p->payload + 1);
  2174. ch = c->chans[cnum];
  2175. pl = emalloc9p(sizeof(Plist));
  2176. pl->pack = emalloc9p(sizeof(Packet));
  2177. memmove(pl->pack, p, sizeof(Packet));
  2178. if (p->payload[0] == SSH_MSG_CHANNEL_DATA) {
  2179. pl->rem = nhgetl(p->payload + 5);
  2180. pl->st = pl->pack->payload + 9;
  2181. } else {
  2182. pl->rem = nhgetl(p->payload + 9);
  2183. pl->st = pl->pack->payload + 13;
  2184. }
  2185. pl->next = nil;
  2186. if (ch->dataq == nil)
  2187. ch->dataq = pl;
  2188. else
  2189. ch->datatl->next = pl;
  2190. ch->datatl = pl;
  2191. ch->inrqueue += pl->rem;
  2192. nbsendul(ch->inchan, 1);
  2193. break;
  2194. case SSH_MSG_CHANNEL_EOF:
  2195. cnum = nhgetl(p->payload + 1);
  2196. ch = c->chans[cnum];
  2197. if (ch->state != Closed && ch->state != Closing) {
  2198. ch->state = Eof;
  2199. nbsendul(ch->inchan, 1);
  2200. nbsendul(ch->reqchan, 1);
  2201. }
  2202. break;
  2203. case SSH_MSG_CHANNEL_CLOSE:
  2204. cnum = nhgetl(p->payload + 1);
  2205. ch = c->chans[cnum];
  2206. if (ch->state != Closed && ch->state != Closing) {
  2207. init_packet(p2);
  2208. p2->c = c;
  2209. add_byte(p2, SSH_MSG_CHANNEL_CLOSE);
  2210. hnputl(p2->payload + 1, ch->otherid);
  2211. p2->rlength += 4;
  2212. n = finish_packet(p2);
  2213. iowrite(c->rio, c->datafd, p2->nlength, n);
  2214. }
  2215. qlock(&c->l);
  2216. if (ch->state != Closed) {
  2217. ch->state = Closed;
  2218. rwakeup(&ch->r);
  2219. nbsendul(ch->inchan, 1);
  2220. nbsendul(ch->reqchan, 1);
  2221. chanclose(ch->inchan);
  2222. chanclose(ch->reqchan);
  2223. }
  2224. qunlock(&c->l);
  2225. for (i = 0; i < MAXCONN && (!c->chans[i] ||
  2226. c->chans[i]->state == Empty || c->chans[i]->state == Closed);
  2227. ++i)
  2228. ;
  2229. if (i >= MAXCONN)
  2230. return -1;
  2231. break;
  2232. case SSH_MSG_CHANNEL_REQUEST:
  2233. cnum = nhgetl(p->payload + 1);
  2234. ch = c->chans[cnum];
  2235. sshdebug(c, "queueing channel request for channel: %d", cnum);
  2236. q = get_string(p, p->payload+5, buf, Arbbufsz, nil);
  2237. pl = emalloc9p(sizeof(Plist));
  2238. pl->pack = emalloc9p(sizeof(Packet));
  2239. n = snprint((char *)pl->pack->payload,
  2240. Maxpayload, "%s %c", buf, *q? 't': 'f');
  2241. sshdebug(c, "request message begins: %s",
  2242. (char *)pl->pack->payload);
  2243. memmove(pl->pack->payload + n, q + 1, p->rlength - (11 + n-2));
  2244. pl->rem = p->rlength - 11 + 2;
  2245. pl->st = pl->pack->payload;
  2246. pl->next = nil;
  2247. if (ch->reqq == nil)
  2248. ch->reqq = pl;
  2249. else
  2250. ch->reqtl->next = pl;
  2251. ch->reqtl = pl;
  2252. nbsendul(ch->reqchan, 1);
  2253. break;
  2254. case SSH_MSG_CHANNEL_SUCCESS:
  2255. case SSH_MSG_CHANNEL_FAILURE:
  2256. default:
  2257. break;
  2258. }
  2259. return 0;
  2260. }
  2261. static void
  2262. bail(Conn *c, Packet *p, Packet *p2, char *sts)
  2263. {
  2264. shutdown(c);
  2265. free(p);
  2266. free(p2);
  2267. if (c->rio) {
  2268. closeioproc(c->rio);
  2269. c->rio = nil;
  2270. }
  2271. c->rpid = -1;
  2272. threadexits(sts);
  2273. }
  2274. static void
  2275. reader0(Conn *c, Packet *p, Packet *p2)
  2276. {
  2277. int i, n, nl, np, nm, nb;
  2278. char buf[Arbbufsz];
  2279. nm = 0;
  2280. nb = 4;
  2281. if (c->decrypt != -1)
  2282. nb = cryptos[c->decrypt]->blklen;
  2283. sshdebug(c, "calling read for connection %d, state %d, nb %d, dc %d",
  2284. c->id, c->state, nb, c->decrypt);
  2285. if ((nl = ioreadn(c->rio, c->datafd, p->nlength, nb)) != nb) {
  2286. sshdebug(c, "reader for connection %d exiting, got %d: %r",
  2287. c->id, nl);
  2288. bail(c, p, p2, "reader exiting");
  2289. }
  2290. if (c->decrypt != -1)
  2291. cryptos[c->decrypt]->decrypt(c->deccs, p->nlength, nb);
  2292. p->rlength = nhgetl(p->nlength);
  2293. sshdebug(c, "got message length: %ld", p->rlength);
  2294. if (p->rlength > Maxpktpay) {
  2295. sshdebug(c, "absurd packet length: %ld, unrecoverable decrypt failure",
  2296. p->rlength);
  2297. bail(c, p, p2, "absurd packet length");
  2298. }
  2299. np = ioreadn(c->rio, c->datafd, p->nlength + nb, p->rlength + 4 - nb);
  2300. if (c->inmac != -1)
  2301. nm = ioreadn(c->rio, c->datafd, p->nlength + p->rlength + 4,
  2302. SHA1dlen); /* SHA1dlen was magic 20 */
  2303. n = nl + np + nm;
  2304. if (debug) {
  2305. sshdebug(c, "got message of %d bytes %d padding", n, p->pad_len);
  2306. if (p->payload[0] > SSH_MSG_CHANNEL_OPEN) {
  2307. i = nhgetl(p->payload+1);
  2308. if (c->chans[i])
  2309. sshdebug(c, " for channel %d win %lud",
  2310. i, c->chans[i]->rwindow);
  2311. else
  2312. sshdebug(c, " for invalid channel %d", i);
  2313. }
  2314. sshdebug(c, " first byte: %d", p->payload[0]);
  2315. }
  2316. /* SHA1dlen was magic 20 */
  2317. if (np != p->rlength + 4 - nb || c->inmac != -1 && nm != SHA1dlen) {
  2318. sshdebug(c, "got EOF/error on connection read: %d %d %r", np, nm);
  2319. bail(c, p, p2, "error or eof");
  2320. }
  2321. p->tlength = n;
  2322. p->rlength = n - 4;
  2323. if (undo_packet(p) < 0) {
  2324. sshdebug(c, "bad packet in connection %d: exiting", c->id);
  2325. bail(c, p, p2, "bad packet");
  2326. }
  2327. if (c->state == Initting) {
  2328. if (p->payload[0] != SSH_MSG_KEXINIT) {
  2329. sshdebug(c, "missing KEX init packet: %d", p->payload[0]);
  2330. bail(c, p, p2, "bad kex");
  2331. }
  2332. if (c->rkexinit)
  2333. free(c->rkexinit);
  2334. c->rkexinit = new_packet(c);
  2335. memmove(c->rkexinit, p, sizeof(Packet));
  2336. if (validatekex(c, p) < 0) {
  2337. sshdebug(c, "kex crypto algorithm mismatch (Initting)");
  2338. bail(c, p, p2, "bad kex");
  2339. }
  2340. sshdebug(c, "using %s Kex algorithm and %s PKA",
  2341. kexes[c->kexalg]->name, pkas[c->pkalg]->name);
  2342. if (c->role == Client)
  2343. kexes[c->kexalg]->clientkex1(c, p);
  2344. c->state = Negotiating;
  2345. } else if (c->state == Negotiating) {
  2346. if (negotiating(c, p, p2, buf, sizeof buf) < 0)
  2347. bail(c, p, p2, "negotiating");
  2348. } else if (c->state == Authing) {
  2349. switch (p->payload[0]) {
  2350. case SSH_MSG_DISCONNECT:
  2351. if (debug) {
  2352. get_string(p, p->payload + 5, buf, Arbbufsz, nil);
  2353. sshdebug(c, "got disconnect: %s", buf);
  2354. }
  2355. bail(c, p, p2, "msg disconnect");
  2356. case SSH_MSG_USERAUTH_REQUEST:
  2357. switch (auth_req(p, c)) {
  2358. case 0: /* success */
  2359. establish(c);
  2360. break;
  2361. case 1: /* ok to try again */
  2362. case -1: /* failure */
  2363. break;
  2364. case -2: /* can't happen, now at least */
  2365. bail(c, p, p2, "in userauth request");
  2366. }
  2367. break;
  2368. case SSH_MSG_USERAUTH_FAILURE:
  2369. qlock(&c->l);
  2370. rwakeup(&c->r);
  2371. qunlock(&c->l);
  2372. break;
  2373. case SSH_MSG_USERAUTH_SUCCESS:
  2374. establish(c);
  2375. break;
  2376. case SSH_MSG_USERAUTH_BANNER:
  2377. break;
  2378. }
  2379. } else if (c->state == Established) {
  2380. if (established(c, p, p2, buf, sizeof buf) < 0)
  2381. bail(c, p, p2, "from established state");
  2382. } else {
  2383. sshdebug(c, "connection %d in bad state, reader exiting", c->id);
  2384. bail(c, p, p2, "bad conn state");
  2385. }
  2386. }
  2387. void
  2388. reader(void *a)
  2389. {
  2390. Conn *c;
  2391. Packet *p, *p2;
  2392. threadsetname("reader");
  2393. c = a;
  2394. c->rpid = threadid();
  2395. sshdebug(c, "starting reader for connection %d, pid %d", c->id, c->rpid);
  2396. threadsetname("reader");
  2397. p = new_packet(c);
  2398. p2 = new_packet(c);
  2399. c->rio = ioproc();
  2400. for(;;)
  2401. reader0(c, p, p2);
  2402. }
  2403. int
  2404. validatekex(Conn *c, Packet *p)
  2405. {
  2406. if (c->role == Server)
  2407. return validatekexs(p);
  2408. else
  2409. return validatekexc(p);
  2410. }
  2411. int
  2412. validatekexs(Packet *p)
  2413. {
  2414. uchar *q;
  2415. char *toks[Maxtoks];
  2416. int i, j, n;
  2417. char *buf;
  2418. buf = emalloc9p(Bigbufsz);
  2419. q = p->payload + 17;
  2420. q = get_string(p, q, buf, Bigbufsz, nil);
  2421. sshdebug(nil, "received KEX algs: %s", buf);
  2422. n = gettokens(buf, toks, nelem(toks), ",");
  2423. for (i = 0; i < n; ++i)
  2424. for (j = 0; j < nelem(kexes); ++j)
  2425. if (strcmp(toks[i], kexes[j]->name) == 0)
  2426. goto foundk;
  2427. sshdebug(nil, "kex algs not in kexes");
  2428. free(buf);
  2429. return -1;
  2430. foundk:
  2431. p->c->kexalg = j;
  2432. q = get_string(p, q, buf, Bigbufsz, nil);
  2433. sshdebug(nil, "received host key algs: %s", buf);
  2434. n = gettokens(buf, toks, nelem(toks), ",");
  2435. for (i = 0; i < n; ++i)
  2436. for (j = 0; j < nelem(pkas) && pkas[j] != nil; ++j)
  2437. if (strcmp(toks[i], pkas[j]->name) == 0)
  2438. goto foundpka;
  2439. sshdebug(nil, "host key algs not in pkas");
  2440. free(buf);
  2441. return -1;
  2442. foundpka:
  2443. p->c->pkalg = j;
  2444. q = get_string(p, q, buf, Bigbufsz, nil);
  2445. sshdebug(nil, "received C2S crypto algs: %s", buf);
  2446. n = gettokens(buf, toks, nelem(toks), ",");
  2447. for (i = 0; i < n; ++i)
  2448. for (j = 0; j < nelem(cryptos); ++j)
  2449. if (strcmp(toks[i], cryptos[j]->name) == 0)
  2450. goto foundc1;
  2451. sshdebug(nil, "c2s crypto algs not in cryptos");
  2452. free(buf);
  2453. return -1;
  2454. foundc1:
  2455. p->c->ncscrypt = j;
  2456. q = get_string(p, q, buf, Bigbufsz, nil);
  2457. sshdebug(nil, "received S2C crypto algs: %s", buf);
  2458. n = gettokens(buf, toks, nelem(toks), ",");
  2459. for (i = 0; i < n; ++i)
  2460. for (j = 0; j < nelem(cryptos); ++j)
  2461. if (strcmp(toks[i], cryptos[j]->name) == 0)
  2462. goto foundc2;
  2463. sshdebug(nil, "s2c crypto algs not in cryptos");
  2464. free(buf);
  2465. return -1;
  2466. foundc2:
  2467. p->c->nsccrypt = j;
  2468. q = get_string(p, q, buf, Bigbufsz, nil);
  2469. sshdebug(nil, "received C2S MAC algs: %s", buf);
  2470. n = gettokens(buf, toks, nelem(toks), ",");
  2471. for (i = 0; i < n; ++i)
  2472. for (j = 0; j < nelem(macnames); ++j)
  2473. if (strcmp(toks[i], macnames[j]) == 0)
  2474. goto foundm1;
  2475. sshdebug(nil, "c2s mac algs not in cryptos");
  2476. free(buf);
  2477. return -1;
  2478. foundm1:
  2479. p->c->ncsmac = j;
  2480. q = get_string(p, q, buf, Bigbufsz, nil);
  2481. sshdebug(nil, "received S2C MAC algs: %s", buf);
  2482. n = gettokens(buf, toks, nelem(toks), ",");
  2483. for (i = 0; i < n; ++i)
  2484. for (j = 0; j < nelem(macnames); ++j)
  2485. if (strcmp(toks[i], macnames[j]) == 0)
  2486. goto foundm2;
  2487. sshdebug(nil, "s2c mac algs not in cryptos");
  2488. free(buf);
  2489. return -1;
  2490. foundm2:
  2491. p->c->nscmac = j;
  2492. q = get_string(p, q, buf, Bigbufsz, nil);
  2493. q = get_string(p, q, buf, Bigbufsz, nil);
  2494. q = get_string(p, q, buf, Bigbufsz, nil);
  2495. q = get_string(p, q, buf, Bigbufsz, nil);
  2496. free(buf);
  2497. if (*q)
  2498. return 1;
  2499. return 0;
  2500. }
  2501. int
  2502. validatekexc(Packet *p)
  2503. {
  2504. uchar *q;
  2505. char *toks[Maxtoks];
  2506. int i, j, n;
  2507. char *buf;
  2508. buf = emalloc9p(Bigbufsz);
  2509. q = p->payload + 17;
  2510. q = get_string(p, q, buf, Bigbufsz, nil);
  2511. n = gettokens(buf, toks, nelem(toks), ",");
  2512. for (j = 0; j < nelem(kexes); ++j)
  2513. for (i = 0; i < n; ++i)
  2514. if (strcmp(toks[i], kexes[j]->name) == 0)
  2515. goto foundk;
  2516. free(buf);
  2517. return -1;
  2518. foundk:
  2519. p->c->kexalg = j;
  2520. q = get_string(p, q, buf, Bigbufsz, nil);
  2521. n = gettokens(buf, toks, nelem(toks), ",");
  2522. for (j = 0; j < nelem(pkas) && pkas[j] != nil; ++j)
  2523. for (i = 0; i < n; ++i)
  2524. if (strcmp(toks[i], pkas[j]->name) == 0)
  2525. goto foundpka;
  2526. free(buf);
  2527. return -1;
  2528. foundpka:
  2529. p->c->pkalg = j;
  2530. q = get_string(p, q, buf, Bigbufsz, nil);
  2531. n = gettokens(buf, toks, nelem(toks), ",");
  2532. for (j = 0; j < nelem(cryptos); ++j)
  2533. for (i = 0; i < n; ++i)
  2534. if (strcmp(toks[i], cryptos[j]->name) == 0)
  2535. goto foundc1;
  2536. free(buf);
  2537. return -1;
  2538. foundc1:
  2539. p->c->ncscrypt = j;
  2540. q = get_string(p, q, buf, Bigbufsz, nil);
  2541. n = gettokens(buf, toks, nelem(toks), ",");
  2542. for (j = 0; j < nelem(cryptos); ++j)
  2543. for (i = 0; i < n; ++i)
  2544. if (strcmp(toks[i], cryptos[j]->name) == 0)
  2545. goto foundc2;
  2546. free(buf);
  2547. return -1;
  2548. foundc2:
  2549. p->c->nsccrypt = j;
  2550. q = get_string(p, q, buf, Bigbufsz, nil);
  2551. n = gettokens(buf, toks, nelem(toks), ",");
  2552. for (j = 0; j < nelem(macnames); ++j)
  2553. for (i = 0; i < n; ++i)
  2554. if (strcmp(toks[i], macnames[j]) == 0)
  2555. goto foundm1;
  2556. free(buf);
  2557. return -1;
  2558. foundm1:
  2559. p->c->ncsmac = j;
  2560. q = get_string(p, q, buf, Bigbufsz, nil);
  2561. n = gettokens(buf, toks, nelem(toks), ",");
  2562. for (j = 0; j < nelem(macnames); ++j)
  2563. for (i = 0; i < n; ++i)
  2564. if (strcmp(toks[i], macnames[j]) == 0)
  2565. goto foundm2;
  2566. free(buf);
  2567. return -1;
  2568. foundm2:
  2569. p->c->nscmac = j;
  2570. q = get_string(p, q, buf, Bigbufsz, nil);
  2571. q = get_string(p, q, buf, Bigbufsz, nil);
  2572. q = get_string(p, q, buf, Bigbufsz, nil);
  2573. q = get_string(p, q, buf, Bigbufsz, nil);
  2574. free(buf);
  2575. return *q != 0;
  2576. }
  2577. int
  2578. memrandom(void *p, int n)
  2579. {
  2580. uchar *cp;
  2581. for (cp = (uchar*)p; n > 0; n--)
  2582. *cp++ = fastrand();
  2583. return 0;
  2584. }
  2585. /*
  2586. * create a change uid capability
  2587. */
  2588. char*
  2589. mkcap(char *from, char *to)
  2590. {
  2591. int fd, fromtosz;
  2592. char *cap, *key;
  2593. uchar rand[SHA1dlen], hash[SHA1dlen];
  2594. fd = open("#¤/caphash", OWRITE);
  2595. if (fd < 0)
  2596. sshlog(nil, "can't open #¤/caphash: %r");
  2597. /* create the capability */
  2598. fromtosz = strlen(from) + 1 + strlen(to) + 1;
  2599. cap = emalloc9p(fromtosz + sizeof(rand)*3 + 1);
  2600. snprint(cap, fromtosz + sizeof(rand)*3 + 1, "%s@%s", from, to);
  2601. memrandom(rand, sizeof(rand));
  2602. key = cap + fromtosz;
  2603. enc64(key, sizeof(rand)*3, rand, sizeof(rand));
  2604. /* hash the capability */
  2605. hmac_sha1((uchar*)cap, strlen(cap), (uchar*)key, strlen(key), hash, nil);
  2606. /* give the kernel the hash */
  2607. key[-1] = '@';
  2608. sshdebug(nil, "writing `%.*s' to caphash", SHA1dlen, hash);
  2609. if (write(fd, hash, SHA1dlen) != SHA1dlen) {
  2610. close(fd);
  2611. free(cap);
  2612. return nil;
  2613. }
  2614. close(fd);
  2615. return cap;
  2616. }
  2617. /*
  2618. * ask keyfs (assumes we are on an auth server)
  2619. */
  2620. static AuthInfo *
  2621. keyfsauth(char *me, char *user, char *pw, char *key1, char *key2)
  2622. {
  2623. int fd;
  2624. char path[Arbpathlen];
  2625. AuthInfo *ai;
  2626. if (passtokey(key1, pw) == 0)
  2627. return nil;
  2628. snprint(path, Arbpathlen, "/mnt/keys/%s/key", user);
  2629. if ((fd = open(path, OREAD)) < 0) {
  2630. werrstr("Invalid user %s", user);
  2631. return nil;
  2632. }
  2633. if (read(fd, key2, DESKEYLEN) != DESKEYLEN) {
  2634. close(fd);
  2635. werrstr("Password mismatch 1");
  2636. return nil;
  2637. }
  2638. close(fd);
  2639. if (memcmp(key1, key2, DESKEYLEN) != 0) {
  2640. werrstr("Password mismatch 2");
  2641. return nil;
  2642. }
  2643. ai = emalloc9p(sizeof(AuthInfo));
  2644. ai->cuid = estrdup9p(user);
  2645. ai->suid = estrdup9p(me);
  2646. ai->cap = mkcap(me, user);
  2647. ai->nsecret = 0;
  2648. ai->secret = (uchar *)estrdup9p("");
  2649. return ai;
  2650. }
  2651. static void
  2652. userauthfailed(Packet *p2)
  2653. {
  2654. add_byte(p2, SSH_MSG_USERAUTH_FAILURE);
  2655. add_string(p2, "password,publickey");
  2656. add_byte(p2, 0);
  2657. }
  2658. static int
  2659. authreqpk(Packet *p, Packet *p2, Conn *c, char *user, uchar *q,
  2660. char *alg, char *blob, char *sig, char *service, char *me)
  2661. {
  2662. int n, thisway, nblob, nsig;
  2663. char method[32];
  2664. sshdebug(c, "auth_req publickey for user %s", user);
  2665. thisway = *q == '\0';
  2666. q = get_string(p, q+1, alg, Arbpathlen, nil);
  2667. q = get_string(p, q, blob, Blobsz, &nblob);
  2668. if (thisway) {
  2669. /*
  2670. * Should really check to see if this user can
  2671. * be authed this way.
  2672. */
  2673. for (n = 0; n < nelem(pkas) && pkas[n] != nil &&
  2674. strcmp(pkas[n]->name, alg) != 0; ++n)
  2675. ;
  2676. if (n >= nelem(pkas) || pkas[n] == nil) {
  2677. userauthfailed(p2);
  2678. return -1;
  2679. }
  2680. add_byte(p2, SSH_MSG_USERAUTH_PK_OK);
  2681. add_string(p2, alg);
  2682. add_block(p2, blob, nblob);
  2683. return 1;
  2684. }
  2685. get_string(p, q, sig, Blobsz, &nsig);
  2686. for (n = 0; n < nelem(pkas) && pkas[n] != nil &&
  2687. strcmp(pkas[n]->name, alg) != 0; ++n)
  2688. ;
  2689. if (n >= nelem(pkas) || pkas[n] == nil) {
  2690. userauthfailed(p2);
  2691. return -1;
  2692. }
  2693. add_block(p2, c->sessid, SHA1dlen);
  2694. add_byte(p2, SSH_MSG_USERAUTH_REQUEST);
  2695. add_string(p2, user);
  2696. add_string(p2, service);
  2697. add_string(p2, method);
  2698. add_byte(p2, 1);
  2699. add_string(p2, alg);
  2700. add_block(p2, blob, nblob);
  2701. if (pkas[n]->verify(c, p2->payload, p2->rlength - 1, user, sig, nsig)
  2702. == 0) {
  2703. init_packet(p2);
  2704. p2->c = c;
  2705. sshlog(c, "public key login failed");
  2706. userauthfailed(p2);
  2707. return -1;
  2708. }
  2709. free(c->cap);
  2710. c->cap = mkcap(me, user);
  2711. init_packet(p2);
  2712. p2->c = c;
  2713. sshlog(c, "logged in by public key");
  2714. add_byte(p2, SSH_MSG_USERAUTH_SUCCESS);
  2715. return 0;
  2716. }
  2717. int
  2718. auth_req(Packet *p, Conn *c)
  2719. {
  2720. int n, ret;
  2721. char *alg, *blob, *sig, *service, *me, *user, *pw, *path;
  2722. char key1[DESKEYLEN], key2[DESKEYLEN], method[32];
  2723. uchar *q;
  2724. AuthInfo *ai;
  2725. Packet *p2;
  2726. service = emalloc9p(Arbpathlen);
  2727. me = emalloc9p(Arbpathlen);
  2728. user = emalloc9p(Arbpathlen);
  2729. pw = emalloc9p(Arbpathlen);
  2730. alg = emalloc9p(Arbpathlen);
  2731. path = emalloc9p(Arbpathlen);
  2732. blob = emalloc9p(Blobsz);
  2733. sig = emalloc9p(Blobsz);
  2734. ret = -1; /* failure is default */
  2735. q = get_string(p, p->payload + 1, user, Arbpathlen, nil);
  2736. free(c->user);
  2737. c->user = estrdup9p(user);
  2738. q = get_string(p, q, service, Arbpathlen, nil);
  2739. q = get_string(p, q, method, sizeof method, nil);
  2740. sshdebug(c, "got userauth request: %s %s %s", user, service, method);
  2741. readfile("/dev/user", me, Arbpathlen);
  2742. p2 = new_packet(c);
  2743. if (strcmp(method, "publickey") == 0)
  2744. ret = authreqpk(p, p2, c, user, q, alg, blob, sig, service, me);
  2745. else if (strcmp(method, "password") == 0) {
  2746. get_string(p, q + 1, pw, Arbpathlen, nil);
  2747. // sshdebug(c, "%s", pw); /* bad idea to log passwords */
  2748. sshdebug(c, "auth_req password");
  2749. if (kflag)
  2750. ai = keyfsauth(me, user, pw, key1, key2);
  2751. else
  2752. ai = auth_userpasswd(user, pw);
  2753. if (ai == nil) {
  2754. sshlog(c, "login failed: %r");
  2755. userauthfailed(p2);
  2756. } else {
  2757. sshdebug(c, "auth successful: cuid %s suid %s cap %s",
  2758. ai->cuid, ai->suid, ai->cap);
  2759. free(c->cap);
  2760. if (strcmp(user, me) == 0)
  2761. c->cap = estrdup9p("n/a");
  2762. else
  2763. c->cap = estrdup9p(ai->cap);
  2764. sshlog(c, "logged in by password");
  2765. add_byte(p2, SSH_MSG_USERAUTH_SUCCESS);
  2766. auth_freeAI(ai);
  2767. ret = 0;
  2768. }
  2769. } else
  2770. userauthfailed(p2);
  2771. n = finish_packet(p2);
  2772. iowrite(c->dio, c->datafd, p2->nlength, n);
  2773. free(service);
  2774. free(me);
  2775. free(user);
  2776. free(pw);
  2777. free(alg);
  2778. free(blob);
  2779. free(sig);
  2780. free(path);
  2781. free(p2);
  2782. return ret;
  2783. }
  2784. int
  2785. client_auth(Conn *c, Ioproc *io)
  2786. {
  2787. Packet *p2, *p3, *p4;
  2788. char *r, *s;
  2789. mpint *ek, *nk;
  2790. int i, n;
  2791. sshdebug(c, "client_auth");
  2792. if (!c->password && !c->authkey)
  2793. return -1;
  2794. p2 = new_packet(c);
  2795. add_byte(p2, SSH_MSG_USERAUTH_REQUEST);
  2796. add_string(p2, c->user);
  2797. add_string(p2, c->service);
  2798. if (c->password) {
  2799. add_string(p2, "password");
  2800. add_byte(p2, 0);
  2801. add_string(p2, c->password);
  2802. sshdebug(c, "client_auth using password for svc %s", c->service);
  2803. } else {
  2804. sshdebug(c, "client_auth trying rsa public key");
  2805. add_string(p2, "publickey");
  2806. add_byte(p2, 1);
  2807. add_string(p2, "ssh-rsa");
  2808. r = strstr(c->authkey, " ek=");
  2809. s = strstr(c->authkey, " n=");
  2810. if (!r || !s) {
  2811. shutdown(c);
  2812. free(p2);
  2813. sshdebug(c, "client_auth no rsa key");
  2814. return -1;
  2815. }
  2816. ek = strtomp(r+4, nil, 16, nil);
  2817. nk = strtomp(s+3, nil, 16, nil);
  2818. p3 = new_packet(c);
  2819. add_string(p3, "ssh-rsa");
  2820. add_mp(p3, ek);
  2821. add_mp(p3, nk);
  2822. add_block(p2, p3->payload, p3->rlength-1);
  2823. p4 = new_packet(c);
  2824. add_block(p4, c->sessid, SHA1dlen);
  2825. add_byte(p4, SSH_MSG_USERAUTH_REQUEST);
  2826. add_string(p4, c->user);
  2827. add_string(p4, c->service);
  2828. add_string(p4, "publickey");
  2829. add_byte(p4, 1);
  2830. add_string(p4, "ssh-rsa");
  2831. add_block(p4, p3->payload, p3->rlength-1);
  2832. mpfree(ek);
  2833. mpfree(nk);
  2834. free(p3);
  2835. for (i = 0; pkas[i] && strcmp("ssh-rsa", pkas[i]->name) != 0;
  2836. ++i)
  2837. ;
  2838. sshdebug(c, "client_auth rsa signing alg %d: %r", i);
  2839. if ((p3 = pkas[i]->sign(c, p4->payload, p4->rlength-1)) == nil) {
  2840. sshdebug(c, "client_auth rsa signing failed: %r");
  2841. free(p4);
  2842. free(p2);
  2843. return -1;
  2844. }
  2845. add_block(p2, p3->payload, p3->rlength-1);
  2846. free(p3);
  2847. free(p4);
  2848. }
  2849. n = finish_packet(p2);
  2850. if (writeio(io, c->datafd, p2->nlength, n) != n)
  2851. sshdebug(c, "client_auth write failed: %r");
  2852. free(p2);
  2853. return 0;
  2854. }
  2855. /* should use auth_getkey or something similar */
  2856. char *
  2857. factlookup(int nattr, int nreq, char *attrs[])
  2858. {
  2859. Biobuf *bp;
  2860. char *buf, *toks[Maxtoks], *res, *q;
  2861. int ntok, nmatch, maxmatch;
  2862. int i, j;
  2863. res = nil;
  2864. bp = Bopen("/mnt/factotum/ctl", OREAD);
  2865. if (bp == nil)
  2866. return nil;
  2867. maxmatch = 0;
  2868. while (buf = Brdstr(bp, '\n', 1)) {
  2869. q = estrdup9p(buf);
  2870. ntok = gettokens(buf, toks, nelem(toks), " ");
  2871. nmatch = 0;
  2872. for (i = 0; i < nattr; ++i) {
  2873. for (j = 0; j < ntok; ++j)
  2874. if (strcmp(attrs[i], toks[j]) == 0) {
  2875. ++nmatch;
  2876. break;
  2877. }
  2878. if (i < nreq && j >= ntok)
  2879. break;
  2880. }
  2881. if (i >= nattr && nmatch > maxmatch) {
  2882. free(res);
  2883. res = q;
  2884. maxmatch = nmatch;
  2885. } else
  2886. free(q);
  2887. free(buf);
  2888. }
  2889. Bterm(bp);
  2890. return res;
  2891. }
  2892. void
  2893. shutdown(Conn *c)
  2894. {
  2895. Plist *p;
  2896. SSHChan *sc;
  2897. int i, ostate;
  2898. sshdebug(c, "shutting down connection %d", c->id);
  2899. ostate = c->state;
  2900. if (c->clonefile->ref <= 2 && c->ctlfile->ref <= 2 &&
  2901. c->datafile->ref <= 2 && c->listenfile->ref <= 2 &&
  2902. c->localfile->ref <= 2 && c->remotefile->ref <= 2 &&
  2903. c->statusfile->ref <= 2)
  2904. c->state = Closed;
  2905. else {
  2906. if (c->state != Closed)
  2907. c->state = Closing;
  2908. sshdebug(c, "clone %ld ctl %ld data %ld listen %ld "
  2909. "local %ld remote %ld status %ld",
  2910. c->clonefile->ref, c->ctlfile->ref, c->datafile->ref,
  2911. c->listenfile->ref, c->localfile->ref, c->remotefile->ref,
  2912. c->statusfile->ref);
  2913. }
  2914. if (ostate == Closed || ostate == Closing) {
  2915. c->state = Closed;
  2916. return;
  2917. }
  2918. if (c->role == Server && c->remote)
  2919. sshlog(c, "closing connection");
  2920. hangupconn(c);
  2921. if (c->dio) {
  2922. closeioproc(c->dio);
  2923. c->dio = nil;
  2924. }
  2925. c->decrypt = -1;
  2926. c->inmac = -1;
  2927. c->nchan = 0;
  2928. free(c->otherid);
  2929. free(c->s2ccs);
  2930. c->s2ccs = nil;
  2931. free(c->c2scs);
  2932. c->c2scs = nil;
  2933. free(c->remote);
  2934. c->remote = nil;
  2935. if (c->x) {
  2936. mpfree(c->x);
  2937. c->x = nil;
  2938. }
  2939. if (c->e) {
  2940. mpfree(c->e);
  2941. c->e = nil;
  2942. }
  2943. free(c->user);
  2944. c->user = nil;
  2945. free(c->service);
  2946. c->service = nil;
  2947. c->otherid = nil;
  2948. qlock(&c->l);
  2949. rwakeupall(&c->r);
  2950. qunlock(&c->l);
  2951. for (i = 0; i < MAXCONN; ++i) {
  2952. sc = c->chans[i];
  2953. if (sc == nil)
  2954. continue;
  2955. free(sc->ann);
  2956. sc->ann = nil;
  2957. if (sc->state != Empty && sc->state != Closed) {
  2958. sc->state = Closed;
  2959. sc->lreq = nil;
  2960. while (sc->dataq != nil) {
  2961. p = sc->dataq;
  2962. sc->dataq = p->next;
  2963. free(p->pack);
  2964. free(p);
  2965. }
  2966. while (sc->reqq != nil) {
  2967. p = sc->reqq;
  2968. sc->reqq = p->next;
  2969. free(p->pack);
  2970. free(p);
  2971. }
  2972. qlock(&c->l);
  2973. rwakeupall(&sc->r);
  2974. nbsendul(sc->inchan, 1);
  2975. nbsendul(sc->reqchan, 1);
  2976. chanclose(sc->inchan);
  2977. chanclose(sc->reqchan);
  2978. qunlock(&c->l);
  2979. }
  2980. }
  2981. qlock(&availlck);
  2982. rwakeup(&availrend);
  2983. qunlock(&availlck);
  2984. sshdebug(c, "done processing shutdown of connection %d", c->id);
  2985. }