History

Add real factotum.

Russ Cox committed 21 years ago

Commit ab73f2b1 parent 06b602926 files · +1361 −58Browse files

Unified · Split

26 files
  1. Makefile +9 −10
  2. cpu.c +109 −9
  3. drawterm.h +2 −0
  4. exportfs/exportfs.c +3 −2
  5. exportfs/exportsrv.c +1 −0
  6. include/user.h +2 −0
  7. kern/Makefile +1 −0
  8. kern/devcons.c +20 −19
  9. kern/devlfd.c +126 −0
  10. kern/devroot.c +44 −16
  11. kern/devssl.c +6 −2
  12. kern/devtab.c +4 −0
  13. libauth/Makefile +21 −0
  14. libauth/attr.c +174 −0
  15. libauth/auth_attr.c +13 −0
  16. libauth/auth_challenge.c +117 −0
  17. libauth/auth_getuserpasswd.c +75 −0
  18. libauth/auth_proxy.c +212 −0
  19. libauth/auth_respond.c +73 −0
  20. libauth/auth_rpc.c +116 −0
  21. libauth/auth_userpasswd.c +50 −0
  22. libauth/authlocal.h +1 −0
  23. libauth/httpauth.c +51 −0
  24. main.c +2 −0
  25. posix-factotum.c +107 −0
  26. win32-factotum.c +22 −0
Makefile+9−10
@@ -8,27 +8,23 @@ OFILES=\ · 7 unmodified lines
88 readcons.$O\
99 secstore.$O\
1010 latin1.$O\
11+ $(OS)-factotum.$O\
1112
12−LIBS=\
13+LIBS1=\
1314 kern/libkern.a\
1415 exportfs/libexportfs.a\
16+ libauth/libauth.a\
1517 libauthsrv/libauthsrv.a\
1618 libsec/libsec.a\
1719 libmp/libmp.a\
1820 libmemdraw/libmemdraw.a\
1921 libmemlayer/libmemlayer.a\
2022 libdraw/libdraw.a\
21− libc/libc.a\
22− kern/libkern.a\
2323 gui-$(GUI)/libgui.a\
24− libmemdraw/libmemdraw.a\
25− libdraw/libdraw.a\
26− kern/libkern.a\
2724 libc/libc.a\
28− libmemdraw/libmemdraw.a\
29− libmemlayer/libmemlayer.a\
30− libdraw/libdraw.a\
31− libmachdep.a
25+
26+# stupid gcc
27+LIBS=$(LIBS1) $(LIBS1) $(LIBS1) libmachdep.a
3228
3329 $(TARG): $(OFILES) $(LIBS)
3430 $(CC) $(LDFLAGS) -o $(TARG) $(OFILES) $(LIBS) $(LDADD)
@@ -45,6 +41,9 @@ kern/libkern.a: · 10 unmodified lines
4541 exportfs/libexportfs.a:
4642 (cd exportfs; make)
4743
44+libauth/libauth.a:
45+ (cd libauth; make)
46+
4847 libauthsrv/libauthsrv.a:
4948 (cd libauthsrv; make)
5049
cpu.c+109−9
@@ -17,7 +17,6 @@ · 16 unmodified lines
1717 #define Maxfdata 8192
1818 #define MaxStr 128
1919
20−static char* getuser(void);
2120 static void fatal(int, char*, ...);
2221 static void catcher(void*, char*);
2322 static void usage(void);
@@ -98,7 +97,9 @@ cpumain(int argc, char **argv) · 74 unmodified lines
9897 close(fd);
9998 }
10099
101− user = readcons("user", getenv("USER"), 0);
100+ user = getenv("USER");
101+ if(user == nil)
102+ user = readcons("user", nil, 0);
102103 secstoreserver = nil;
103104 ARGBEGIN{
104105 case 'a':
@@ -126,6 +127,9 @@ cpumain(int argc, char **argv) · 21 unmodified lines
126127 }
127128 break;
128129 */
130+ case 'k':
131+ keyspec = EARGF(usage());
132+ break;
129133 case 'u':
130134 user = EARGF(usage());
131135 break;
@@ -136,6 +140,15 @@ cpumain(int argc, char **argv) · 4 unmodified lines
136140 usage();
137141 }ARGEND;
138142
143+ if((fd = dialfactotum()) < 0)
144+ fprint(2, "dial factotum: %r\n");
145+ else if(sysmount(fd, -1, "/mnt/factotum", MREPL, "") < 0)
146+ fprint(2, "mount factotum: %r\n");
147+ else if((fd = open("/mnt/factotum/ctl", OREAD)) < 0)
148+ fprint(2, "open /mnt/factotum/ctl: %r\n");
149+ else
150+ close(fd);
151+
139152 if(secstoreserver == nil)
140153 secstoreserver = authserver;
141154
@@ -436,6 +449,96 @@ gettickets(Ticketreq *tr, char *key, char *trbuf, char *tbuf) · 294 unmodified lines
436449 return mkserverticket(tr, key, tbuf);
437450 }
438451
452+/*
453+ * prompt user for a key. don't care about memory leaks, runs standalone
454+ */
455+static Attr*
456+promptforkey(char *params)
457+{
458+ char *v;
459+ int fd;
460+ Attr *a, *attr;
461+ char *def;
462+
463+ fd = open("/dev/cons", ORDWR);
464+ if(fd < 0)
465+ sysfatal("opening /dev/cons: %r");
466+
467+ attr = _parseattr(params);
468+ fprint(fd, "\n!Adding key:");
469+ for(a=attr; a; a=a->next)
470+ if(a->type != AttrQuery && a->name[0] != '!')
471+ fprint(fd, " %q=%q", a->name, a->val);
472+ fprint(fd, "\n");
473+
474+ for(a=attr; a; a=a->next){
475+ v = a->name;
476+ if(a->type != AttrQuery || v[0]=='!')
477+ continue;
478+ def = nil;
479+ if(strcmp(v, "user") == 0)
480+ def = getuser();
481+ a->val = readcons(v, def, 0);
482+ if(a->val == nil)
483+ sysfatal("user terminated key input");
484+ a->type = AttrNameval;
485+ }
486+ for(a=attr; a; a=a->next){
487+ v = a->name;
488+ if(a->type != AttrQuery || v[0]!='!')
489+ continue;
490+ def = nil;
491+ if(strcmp(v+1, "user") == 0)
492+ def = getuser();
493+ a->val = readcons(v+1, def, 1);
494+ if(a->val == nil)
495+ sysfatal("user terminated key input");
496+ a->type = AttrNameval;
497+ }
498+ fprint(fd, "!\n");
499+ close(fd);
500+ return attr;
501+}
502+
503+/*
504+ * send a key to the mounted factotum
505+ */
506+static int
507+sendkey(Attr *attr)
508+{
509+ int fd, rv;
510+ char buf[1024];
511+
512+ fd = open("/mnt/factotum/ctl", ORDWR);
513+ if(fd < 0)
514+ sysfatal("opening /mnt/factotum/ctl: %r");
515+ rv = fprint(fd, "key %A\n", attr);
516+ read(fd, buf, sizeof buf);
517+ close(fd);
518+ return rv;
519+}
520+
521+int
522+askuser(char *params)
523+{
524+ Attr *attr;
525+
526+ fmtinstall('A', _attrfmt);
527+
528+ attr = promptforkey(params);
529+ if(attr == nil)
530+ sysfatal("no key supplied");
531+ if(sendkey(attr) < 0)
532+ sysfatal("sending key to factotum: %r");
533+ return 0;
534+}
535+
536+AuthInfo*
537+p9anyfactotum(int fd, int afd)
538+{
539+ return auth_proxy(fd, askuser, "proto=p9any role=client %s", keyspec);
540+}
541+
439542 AuthInfo*
440543 p9any(int fd)
441544 {
@@ -444,11 +547,14 @@ p9any(int fd) · 2 unmodified lines
444547 char tbuf[TICKETLEN+TICKETLEN+AUTHENTLEN], trbuf[TICKREQLEN];
445548 char authkey[DESKEYLEN];
446549 Authenticator auth;
447− int i, v2, n;
550+ int afd, i, v2, n;
448551 Ticketreq tr;
449552 Ticket t;
450553 AuthInfo *ai;
451554
555+ if((afd = open("/mnt/factotum/ctl", ORDWR)) >= 0)
556+ return p9anyfactotum(fd, afd);
557+
452558 if((n = readstr(fd, buf, sizeof buf)) < 0)
453559 fatal(1, "cannot read p9any negotiation");
454560 bbuf = buf;
@@ -598,9 +704,3 @@ setamalg(char *s) · 143 unmodified lines
598704 return setam(s);
599705 }
600706
601−char*
602−getuser(void)
603−{
604− return getenv("USER");
605−}
606−
drawterm.h+2−0
@@ -8,3 +8,5 @@ extern int exportfs(int, int); · 7 unmodified lines
88 extern char *user;
99 extern char *getkey(char*, char*);
1010 extern char *findkey(char**, char*);
11+extern int dialfactotum(void);
12+extern char *getuser(void);
exportfs/exportfs.c+3−2
@@ -99,7 +99,7 @@ exportfs(int fd, int msgsz) · 98 unmodified lines
9999 fatal("convM2S format error");
100100 }
101101
102−//iprint("<- %F\n", &r->work);
102+if(0) iprint("<- %F\n", &r->work);
103103 DEBUG(DFD, "%F\n", &r->work);
104104 (fcalls[r->work.type])(r);
105105 }
@@ -110,6 +110,7 @@ reply(Fcall *r, Fcall *t, char *err) · 4 unmodified lines
110110 {
111111 uchar *data;
112112 int m, n;
113+static QLock lk;
113114
114115 t->tag = r->tag;
115116 t->fid = r->fid;
@@ -120,7 +121,7 @@ reply(Fcall *r, Fcall *t, char *err) · 4 unmodified lines
120121 else
121122 t->type = r->type + 1;
122123
123−//iprint("-> %F\n", t);
124+if(0) iprint("-> %F\n", t);
124125 DEBUG(DFD, "\t%F\n", t);
125126
126127 data = malloc(messagesize); /* not mallocz; no need to clear */
exportfs/exportsrv.c+1−0
@@ -431,6 +431,7 @@ slave(Fsrpc *f) · 430 unmodified lines
431431 Proc *p;
432432 int pid;
433433 static int nproc;
434+ static QLock lk;
434435
435436 for(;;) {
436437 for(p = Proclist; p; p = p->next) {
include/user.h+2−0
@@ -50,6 +50,8 @@ extern int dirwstat(char*, Dir*); · 49 unmodified lines
5050 extern int dirfwstat(int, Dir*);
5151 extern long dirread(int, Dir*, long);
5252
53+extern int lfdfd(int);
54+
5355 /*
5456 * network dialing and authentication
5557 */
kern/Makefile+1−0
@@ -13,6 +13,7 @@ OFILES=\ · 12 unmodified lines
1313 devfs-$(OS).$O\
1414 devip.$O\
1515 devip-$(OS).$O\
16+ devlfd.$O\
1617 devmnt.$O\
1718 devmouse.$O\
1819 devpipe.$O\
kern/devcons.c+20−19
@@ -175,25 +175,6 @@ print(char *fmt, ...) · 174 unmodified lines
175175 return n;
176176 }
177177
178−int
179−iprint(char *fmt, ...)
180−{
181− int n, s;
182− va_list arg;
183− char buf[PRINTSIZE];
184−
185− s = splhi();
186− va_start(arg, fmt);
187− n = vseprint(buf, buf+sizeof(buf), fmt, arg) - buf;
188− va_end(arg);
189− if(screenputs != nil && iprintscreenputs)
190− screenputs(buf, n);
191− uartputs(buf, n);
192− splx(s);
193−
194− return n;
195−}
196−
197178 void
198179 panic(char *fmt, ...)
199180 {
@@ -1208,3 +1189,23 @@ writebintime(char *buf, int n) · 1008 unmodified lines
12081189 }
12091190
12101191
1192+int
1193+iprint(char *fmt, ...)
1194+{
1195+ int n, s;
1196+ va_list arg;
1197+ char buf[PRINTSIZE];
1198+
1199+ s = splhi();
1200+ va_start(arg, fmt);
1201+ n = vseprint(buf, buf+sizeof(buf), fmt, arg) - buf;
1202+ va_end(arg);
1203+ if(screenputs != nil && iprintscreenputs)
1204+ screenputs(buf, n);
1205+#undef write
1206+ write(2, buf, n);
1207+ splx(s);
1208+
1209+ return n;
1210+}
1211+
kern/devlfd.c+126−0
@@ -0,0 +1,126 @@
1+#include "u.h"
2+#include <errno.h>
3+#include "lib.h"
4+#include "dat.h"
5+#include "fns.h"
6+#include "error.h"
7+
8+#undef pread
9+#undef pwrite
10+
11+Chan*
12+lfdchan(int fd)
13+{
14+ Chan *c;
15+
16+ c = newchan();
17+ c->type = devno('L', 0);
18+ c->aux = (void*)fd;
19+ c->name = newcname("fd");
20+ c->mode = ORDWR;
21+ c->qid.type = 0;
22+ c->qid.path = 0;
23+ c->qid.vers = 0;
24+ c->dev = 0;
25+ c->offset = 0;
26+ return c;
27+}
28+
29+int
30+lfdfd(int fd)
31+{
32+ return newfd(lfdchan(fd));
33+}
34+
35+static Chan*
36+lfdattach(char *x)
37+{
38+ USED(x);
39+
40+ error(Egreg);
41+ return nil;
42+}
43+
44+static Walkqid*
45+lfdwalk(Chan *c, Chan *nc, char **name, int nname)
46+{
47+ USED(c);
48+ USED(nc);
49+ USED(name);
50+ USED(nname);
51+
52+ error(Egreg);
53+ return nil;
54+}
55+
56+static int
57+lfdstat(Chan *c, uchar *dp, int n)
58+{
59+ USED(c);
60+ USED(dp);
61+ USED(n);
62+ error(Egreg);
63+ return -1;
64+}
65+
66+static Chan*
67+lfdopen(Chan *c, int omode)
68+{
69+ USED(c);
70+ USED(omode);
71+
72+ error(Egreg);
73+ return nil;
74+}
75+
76+static void
77+lfdclose(Chan *c)
78+{
79+ close((int)c->aux);
80+}
81+
82+static long
83+lfdread(Chan *c, void *buf, long n, vlong off)
84+{
85+ USED(off); /* can't pread on pipes */
86+ n = read((int)c->aux, buf, n);
87+ if(n < 0){
88+ iprint("error %d\n", errno);
89+ oserror();
90+ }
91+ return n;
92+}
93+
94+static long
95+lfdwrite(Chan *c, void *buf, long n, vlong off)
96+{
97+ USED(off); /* can't pread on pipes */
98+
99+ n = write((int)c->aux, buf, n);
100+ if(n < 0){
101+ iprint("error %d\n", errno);
102+ oserror();
103+ }
104+ return n;
105+}
106+
107+Dev lfddevtab = {
108+ 'L',
109+ "lfd",
110+
111+ devreset,
112+ devinit,
113+ devshutdown,
114+ lfdattach,
115+ lfdwalk,
116+ lfdstat,
117+ lfdopen,
118+ devcreate,
119+ lfdclose,
120+ lfdread,
121+ devbread,
122+ lfdwrite,
123+ devbwrite,
124+ devremove,
125+ devwstat,
126+};
kern/devroot.c+44−16
@@ -8,9 +8,12 @@ enum · 7 unmodified lines
88 {
99 Qdir = 0,
1010 Qboot = 0x1000,
11+ Qmnt = 0x2000,
12+ Qfactotum,
1113
1214 Nrootfiles = 32,
1315 Nbootfiles = 32,
16+ Nmntfiles = 2,
1417 };
1518
1619 typedef struct Dirlist Dirlist;
@@ -26,6 +29,7 @@ struct Dirlist · 9 unmodified lines
2629 static Dirtab rootdir[Nrootfiles] = {
2730 "#/", {Qdir, 0, QTDIR}, 0, DMDIR|0555,
2831 "boot", {Qboot, 0, QTDIR}, 0, DMDIR|0555,
32+ "mnt", {Qmnt, 0, QTDIR}, 0, DMDIR|0555,
2933 };
3034 static uchar *rootdata[Nrootfiles];
3135 static Dirlist rootlist =
@@ -33,7 +37,7 @@ static Dirlist rootlist = · 1 unmodified line
3337 0,
3438 rootdir,
3539 rootdata,
36− 2,
40+ 3,
3741 Nrootfiles
3842 };
3943
@@ -50,6 +54,19 @@ static Dirlist bootlist = · 10 unmodified lines
5054 Nbootfiles
5155 };
5256
57+static Dirtab mntdir[Nmntfiles] = {
58+ "mnt", {Qmnt, 0, QTDIR}, 0, DMDIR|0555,
59+ "factotum", {Qfactotum, 0, QTDIR}, 0, DMDIR|0555,
60+};
61+static Dirlist mntlist =
62+{
63+ Qmnt,
64+ mntdir,
65+ nil,
66+ 2,
67+ Nmntfiles
68+};
69+
5370 /*
5471 * add a file to the list
5572 */
@@ -97,7 +114,6 @@ rootreset(void) · 41 unmodified lines
97114 addrootdir("dev");
98115 addrootdir("env");
99116 addrootdir("fd");
100− addrootdir("mnt");
101117 addrootdir("net");
102118 addrootdir("net.alt");
103119 addrootdir("proc");
@@ -129,6 +145,13 @@ rootgen(Chan *c, char *name, Dirtab *dirt, int ndirt, int s, Dir *dp) · 25 unmodified lines
129145 return 1;
130146 }
131147 return devgen(c, name, rootlist.dir, rootlist.ndir, s, dp);
148+ case Qmnt:
149+ if(s == DEVDOTDOT){
150+ Qid tqiddir = {Qdir, 0, QTDIR};
151+ devdir(c, tqiddir, "#/", 0, eve, 0555, dp);
152+ return 1;
153+ }
154+ return devgen(c, name, mntlist.dir, mntlist.ndir, s, dp);
132155 case Qboot:
133156 if(s == DEVDOTDOT){
134157 Qid tqiddir = {Qdir, 0, QTDIR};
@@ -139,22 +162,25 @@ rootgen(Chan *c, char *name, Dirtab *dirt, int ndirt, int s, Dir *dp) · 4 unmodified lines
139162 default:
140163 if(s == DEVDOTDOT){
141164 Qid tqiddir = {Qdir, 0, QTDIR};
142− if((int)c->qid.path < Qboot)
143− devdir(c, tqiddir, "#/", 0, eve, 0555, dp);
144− else {
145− tqiddir.path = Qboot;
146− devdir(c, tqiddir, "#/", 0, eve, 0555, dp);
147− }
165+ tqiddir.path = c->qid.path&0xF000;
166+ devdir(c, tqiddir, "#/", 0, eve, 0555, dp);
148167 return 1;
149168 }
150169 if(s != 0)
151170 return -1;
152− if((int)c->qid.path < Qboot){
171+ switch((int)c->qid.path & 0xF000){
172+ case Qdir:
153173 t = c->qid.path-1;
154174 l = &rootlist;
155− }else{
175+ break;
176+ case Qboot:
156177 t = c->qid.path - Qboot - 1;
157178 l = &bootlist;
179+ break;
180+ case Qmnt:
181+ t = c->qid.path - Qmnt - 1;
182+ l = &mntlist;
183+ break;
158184 }
159185 if(t >= l->ndir)
160186 return -1;
@@ -209,17 +235,19 @@ rootread(Chan *c, void *buf, long n, vlong off) · 48 unmodified lines
209235 switch(t){
210236 case Qdir:
211237 case Qboot:
238+ case Qmnt:
212239 return devdirread(c, buf, n, nil, 0, rootgen);
213240 }
214241
215− if(t<Qboot)
216− l = &rootlist;
217− else{
218− t -= Qboot;
242+ if(t&Qboot)
219243 l = &bootlist;
220− }
221−
244+ else if(t&Qmnt)
245+ l = &mntlist;
246+ else
247+ l = &bootlist;
248+ t &= 0xFFF;
222249 t--;
250+
223251 if(t >= l->ndir)
224252 error(Egreg);
225253
kern/devssl.c+6−2
@@ -765,6 +765,7 @@ sslput(Dstate *s, Block * volatile b) · 764 unmodified lines
765765 int offset;
766766
767767 if(waserror()){
768+iprint("error: %s\n", up->errstr);
768769 if(b != nil)
769770 free(b);
770771 nexterror();
@@ -1071,8 +1072,9 @@ sslwrite(Chan *c, void *a, long n, vlong o) · 300 unmodified lines
10711072 nexterror();
10721073 }
10731074 qlock(&s->out.q);
1074−
10751075 p = a;
1076+if(0) iprint("write %d %.2ux %.2ux %.2ux %.2ux %.2ux %.2ux %.2ux %.2ux\n",
1077+ n, p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
10761078 e = p + n;
10771079 do {
10781080 m = e - p;
@@ -1092,7 +1094,9 @@ sslwrite(Chan *c, void *a, long n, vlong o) · 13 unmodified lines
10921094
10931095 p += m;
10941096 } while(p < e);
1095−
1097+ p = a;
1098+if(0) iprint("wrote %d %.2ux %.2ux %.2ux %.2ux %.2ux %.2ux %.2ux %.2ux\n",
1099+ n, p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
10961100 poperror();
10971101 qunlock(&s->out.q);
10981102 return n;
kern/devtab.c+4−0
@@ -12,6 +12,8 @@ extern Dev mousedevtab; · 11 unmodified lines
1212 extern Dev drawdevtab;
1313 extern Dev ipdevtab;
1414 extern Dev fsdevtab;
15+extern Dev mntdevtab;
16+extern Dev lfddevtab;
1517
1618 Dev *devtab[] = {
1719 &rootdevtab,
@@ -22,6 +24,8 @@ Dev *devtab[] = { · 4 unmodified lines
2224 &drawdevtab,
2325 &ipdevtab,
2426 &fsdevtab,
27+ &mntdevtab,
28+ &lfddevtab,
2529 0
2630 };
2731
libauth/Makefile+21−0
@@ -0,0 +1,21 @@
1+ROOT=..
2+include ../Make.config
3+
4+LIB=libauth.a
5+OFILES=\
6+ attr.$O\
7+ auth_attr.$O\
8+ auth_challenge.$O\
9+ auth_getuserpasswd.$O\
10+ auth_proxy.$O\
11+ auth_respond.$O\
12+ auth_rpc.$O\
13+ auth_userpasswd.$O\
14+
15+$(LIB): $(OFILES)
16+ $(AR) r $(LIB) $(OFILES)
17+ $(RANLIB) $(LIB)
18+
19+%.$O: %.c
20+ $(CC) $(CFLAGS) $*.c
21+
libauth/attr.c+174−0
@@ -0,0 +1,174 @@
1+#include <u.h>
2+#include <libc.h>
3+#include <auth.h>
4+
5+int
6+_attrfmt(Fmt *fmt)
7+{
8+ char *b, buf[1024], *ebuf;
9+ Attr *a;
10+
11+ ebuf = buf+sizeof buf;
12+ b = buf;
13+ strcpy(buf, " ");
14+ for(a=va_arg(fmt->args, Attr*); a; a=a->next){
15+ if(a->name == nil)
16+ continue;
17+ switch(a->type){
18+ case AttrQuery:
19+ b = seprint(b, ebuf, " %q?", a->name);
20+ break;
21+ case AttrNameval:
22+ b = seprint(b, ebuf, " %q=%q", a->name, a->val);
23+ break;
24+ case AttrDefault:
25+ b = seprint(b, ebuf, " %q:=%q", a->name, a->val);
26+ break;
27+ }
28+ }
29+ return fmtstrcpy(fmt, buf+1);
30+}
31+
32+Attr*
33+_copyattr(Attr *a)
34+{
35+ Attr **la, *na;
36+
37+ na = nil;
38+ la = &na;
39+ for(; a; a=a->next){
40+ *la = _mkattr(a->type, a->name, a->val, nil);
41+ setmalloctag(*la, getcallerpc(&a));
42+ la = &(*la)->next;
43+ }
44+ *la = nil;
45+ return na;
46+}
47+
48+Attr*
49+_delattr(Attr *a, char *name)
50+{
51+ Attr *fa;
52+ Attr **la;
53+
54+ for(la=&a; *la; ){
55+ if(strcmp((*la)->name, name) == 0){
56+ fa = *la;
57+ *la = (*la)->next;
58+ fa->next = nil;
59+ _freeattr(fa);
60+ }else
61+ la=&(*la)->next;
62+ }
63+ return a;
64+}
65+
66+Attr*
67+_findattr(Attr *a, char *n)
68+{
69+ for(; a; a=a->next)
70+ if(strcmp(a->name, n) == 0 && a->type != AttrQuery)
71+ return a;
72+ return nil;
73+}
74+
75+void
76+_freeattr(Attr *a)
77+{
78+ Attr *anext;
79+
80+ for(; a; a=anext){
81+ anext = a->next;
82+ free(a->name);
83+ free(a->val);
84+ a->name = (void*)~0;
85+ a->val = (void*)~0;
86+ a->next = (void*)~0;
87+ free(a);
88+ }
89+}
90+
91+Attr*
92+_mkattr(int type, char *name, char *val, Attr *next)
93+{
94+ Attr *a;
95+
96+ a = malloc(sizeof(*a));
97+ if(a==nil)
98+ sysfatal("_mkattr malloc: %r");
99+ a->type = type;
100+ a->name = strdup(name);
101+ a->val = strdup(val);
102+ if(a->name==nil || a->val==nil)
103+ sysfatal("_mkattr malloc: %r");
104+ a->next = next;
105+ setmalloctag(a, getcallerpc(&type));
106+ return a;
107+}
108+
109+static Attr*
110+cleanattr(Attr *a)
111+{
112+ Attr *fa;
113+ Attr **la;
114+
115+ for(la=&a; *la; ){
116+ if((*la)->type==AttrQuery && _findattr(a, (*la)->name)){
117+ fa = *la;
118+ *la = (*la)->next;
119+ fa->next = nil;
120+ _freeattr(fa);
121+ }else
122+ la=&(*la)->next;
123+ }
124+ return a;
125+}
126+
127+Attr*
128+_parseattr(char *s)
129+{
130+ char *p, *t, *tok[256];
131+ int i, ntok, type;
132+ Attr *a;
133+
134+ s = strdup(s);
135+ if(s == nil)
136+ sysfatal("_parseattr strdup: %r");
137+
138+ ntok = tokenize(s, tok, nelem(tok));
139+ a = nil;
140+ for(i=ntok-1; i>=0; i--){
141+ t = tok[i];
142+ if(p = strchr(t, '=')){
143+ *p++ = '\0';
144+ // if(p-2 >= t && p[-2] == ':'){
145+ // p[-2] = '\0';
146+ // type = AttrDefault;
147+ // }else
148+ type = AttrNameval;
149+ a = _mkattr(type, t, p, a);
150+ setmalloctag(a, getcallerpc(&s));
151+ }
152+ else if(t[strlen(t)-1] == '?'){
153+ t[strlen(t)-1] = '\0';
154+ a = _mkattr(AttrQuery, t, "", a);
155+ setmalloctag(a, getcallerpc(&s));
156+ }else{
157+ /* really a syntax error, but better to provide some indication */
158+ a = _mkattr(AttrNameval, t, "", a);
159+ setmalloctag(a, getcallerpc(&s));
160+ }
161+ }
162+ free(s);
163+ return cleanattr(a);
164+}
165+
166+char*
167+_strfindattr(Attr *a, char *n)
168+{
169+ a = _findattr(a, n);
170+ if(a == nil)
171+ return nil;
172+ return a->val;
173+}
174+
libauth/auth_attr.c+13−0
@@ -0,0 +1,13 @@
1+#include <u.h>
2+#include <libc.h>
3+#include <auth.h>
4+#include <authsrv.h>
5+#include "authlocal.h"
6+
7+Attr*
8+auth_attr(AuthRpc *rpc)
9+{
10+ if(auth_rpc(rpc, "attr", nil, 0) != ARok)
11+ return nil;
12+ return _parseattr(rpc->arg);
13+}
libauth/auth_challenge.c+117−0
@@ -0,0 +1,117 @@
1+#include <u.h>
2+#include <libc.h>
3+#include <auth.h>
4+#include <authsrv.h>
5+#include "authlocal.h"
6+
7+Chalstate*
8+auth_challenge(char *fmt, ...)
9+{
10+ char *p;
11+ va_list arg;
12+ Chalstate *c;
13+
14+ quotefmtinstall(); /* just in case */
15+ va_start(arg, fmt);
16+ p = vsmprint(fmt, arg);
17+ va_end(arg);
18+ if(p == nil)
19+ return nil;
20+
21+ c = mallocz(sizeof(*c), 1);
22+ if(c == nil){
23+ free(p);
24+ return nil;
25+ }
26+
27+ if((c->afd = open("/mnt/factotum/rpc", ORDWR)) < 0){
28+ Error:
29+ auth_freechal(c);
30+ free(p);
31+ return nil;
32+ }
33+
34+ if((c->rpc=auth_allocrpc(c->afd)) == nil
35+ || auth_rpc(c->rpc, "start", p, strlen(p)) != ARok
36+ || auth_rpc(c->rpc, "read", nil, 0) != ARok)
37+ goto Error;
38+
39+ if(c->rpc->narg > sizeof(c->chal)-1){
40+ werrstr("buffer too small for challenge");
41+ goto Error;
42+ }
43+ memmove(c->chal, c->rpc->arg, c->rpc->narg);
44+ c->nchal = c->rpc->narg;
45+ free(p);
46+ return c;
47+}
48+
49+AuthInfo*
50+auth_response(Chalstate *c)
51+{
52+ int ret;
53+ AuthInfo *ai;
54+
55+ ai = nil;
56+ if(c->afd < 0){
57+ werrstr("auth_response: connection not open");
58+ return nil;
59+ }
60+ if(c->resp == nil){
61+ werrstr("auth_response: nil response");
62+ return nil;
63+ }
64+ if(c->nresp == 0){
65+ werrstr("auth_response: unspecified response length");
66+ return nil;
67+ }
68+
69+ if(c->user){
70+ if(auth_rpc(c->rpc, "write", c->user, strlen(c->user)) != ARok){
71+ /*
72+ * if this fails we're out of phase with factotum.
73+ * give up.
74+ */
75+ goto Out;
76+ }
77+ }
78+
79+ if(auth_rpc(c->rpc, "write", c->resp, c->nresp) != ARok){
80+ /*
81+ * don't close the connection -- maybe we'll try again.
82+ */
83+ return nil;
84+ }
85+
86+ switch(ret = auth_rpc(c->rpc, "read", nil, 0)){
87+ case ARok:
88+ default:
89+ werrstr("factotum protocol botch %d %s", ret, c->rpc->ibuf);
90+ break;
91+ case ARdone:
92+ ai = auth_getinfo(c->rpc);
93+ break;
94+ }
95+
96+Out:
97+ close(c->afd);
98+ auth_freerpc(c->rpc);
99+ c->afd = -1;
100+ c->rpc = nil;
101+ return ai;
102+}
103+
104+void
105+auth_freechal(Chalstate *c)
106+{
107+ if(c == nil)
108+ return;
109+
110+ if(c->afd >= 0)
111+ close(c->afd);
112+ if(c->rpc != nil)
113+ auth_freerpc(c->rpc);
114+
115+ memset(c, 0xBB, sizeof(*c));
116+ free(c);
117+}
libauth/auth_getuserpasswd.c+75−0
@@ -0,0 +1,75 @@
1+#include <u.h>
2+#include <libc.h>
3+#include <auth.h>
4+#include "authlocal.h"
5+
6+enum {
7+ ARgiveup = 100,
8+};
9+
10+static int
11+dorpc(AuthRpc *rpc, char *verb, char *val, int len, AuthGetkey *getkey)
12+{
13+ int ret;
14+
15+ for(;;){
16+ if((ret = auth_rpc(rpc, verb, val, len)) != ARneedkey && ret != ARbadkey)
17+ return ret;
18+ if(getkey == nil)
19+ return ARgiveup; /* don't know how */
20+ if((*getkey)(rpc->arg) < 0)
21+ return ARgiveup; /* user punted */
22+ }
23+}
24+
25+UserPasswd*
26+auth_getuserpasswd(AuthGetkey *getkey, char *fmt, ...)
27+{
28+ AuthRpc *rpc;
29+ char *f[3], *p, *params;
30+ int fd;
31+ va_list arg;
32+ UserPasswd *up;
33+
34+ up = nil;
35+ rpc = nil;
36+ params = nil;
37+
38+ fd = open("/mnt/factotum/rpc", ORDWR);
39+ if(fd < 0)
40+ goto out;
41+ rpc = auth_allocrpc(fd);
42+ if(rpc == nil)
43+ goto out;
44+ quotefmtinstall(); /* just in case */
45+ va_start(arg, fmt);
46+ params = vsmprint(fmt, arg);
47+ va_end(arg);
48+ if(params == nil)
49+ goto out;
50+
51+ if(dorpc(rpc, "start", params, strlen(params), getkey) != ARok
52+ || dorpc(rpc, "read", nil, 0, getkey) != ARok)
53+ goto out;
54+
55+ rpc->arg[rpc->narg] = '\0';
56+ if(tokenize(rpc->arg, f, 2) != 2){
57+ werrstr("bad answer from factotum");
58+ goto out;
59+ }
60+ up = malloc(sizeof(*up)+rpc->narg+1);
61+ if(up == nil)
62+ goto out;
63+ p = (char*)&up[1];
64+ strcpy(p, f[0]);
65+ up->user = p;
66+ p += strlen(p)+1;
67+ strcpy(p, f[1]);
68+ up->passwd = p;
69+
70+out:
71+ free(params);
72+ auth_freerpc(rpc);
73+ close(fd);
74+ return up;
75+}
libauth/auth_proxy.c+212−0
@@ -0,0 +1,212 @@
1+#include <u.h>
2+#include <libc.h>
3+#include <fcall.h>
4+#include <auth.h>
5+#include "authlocal.h"
6+
7+enum {
8+ ARgiveup = 100,
9+};
10+
11+static uchar*
12+gstring(uchar *p, uchar *ep, char **s)
13+{
14+ uint n;
15+
16+ if(p == nil)
17+ return nil;
18+ if(p+BIT16SZ > ep)
19+ return nil;
20+ n = GBIT16(p);
21+ p += BIT16SZ;
22+ if(p+n > ep)
23+ return nil;
24+ *s = malloc(n+1);
25+ memmove((*s), p, n);
26+ (*s)[n] = '\0';
27+ p += n;
28+ return p;
29+}
30+
31+static uchar*
32+gcarray(uchar *p, uchar *ep, uchar **s, int *np)
33+{
34+ uint n;
35+
36+ if(p == nil)
37+ return nil;
38+ if(p+BIT16SZ > ep)
39+ return nil;
40+ n = GBIT16(p);
41+ p += BIT16SZ;
42+ if(p+n > ep)
43+ return nil;
44+ *s = malloc(n);
45+ if(*s == nil)
46+ return nil;
47+ memmove((*s), p, n);
48+ *np = n;
49+ p += n;
50+ return p;
51+}
52+
53+void
54+auth_freeAI(AuthInfo *ai)
55+{
56+ if(ai == nil)
57+ return;
58+ free(ai->cuid);
59+ free(ai->suid);
60+ free(ai->cap);
61+ free(ai->secret);
62+ free(ai);
63+}
64+
65+static uchar*
66+convM2AI(uchar *p, int n, AuthInfo **aip)
67+{
68+ uchar *e = p+n;
69+ AuthInfo *ai;
70+
71+ ai = mallocz(sizeof(*ai), 1);
72+ if(ai == nil)
73+ return nil;
74+
75+ p = gstring(p, e, &ai->cuid);
76+ p = gstring(p, e, &ai->suid);
77+ p = gstring(p, e, &ai->cap);
78+ p = gcarray(p, e, &ai->secret, &ai->nsecret);
79+ if(p == nil)
80+ auth_freeAI(ai);
81+ else
82+ *aip = ai;
83+ return p;
84+}
85+
86+AuthInfo*
87+auth_getinfo(AuthRpc *rpc)
88+{
89+ AuthInfo *a;
90+
91+ if(auth_rpc(rpc, "authinfo", nil, 0) != ARok)
92+ return nil;
93+ if(convM2AI((uchar*)rpc->arg, rpc->narg, &a) == nil){
94+ werrstr("bad auth info from factotum");
95+ return nil;
96+ }
97+ return a;
98+}
99+
100+static int
101+dorpc(AuthRpc *rpc, char *verb, char *val, int len, AuthGetkey *getkey)
102+{
103+ int ret;
104+
105+ for(;;){
106+ if((ret = auth_rpc(rpc, verb, val, len)) != ARneedkey && ret != ARbadkey)
107+ return ret;
108+ if(getkey == nil)
109+ return ARgiveup; /* don't know how */
110+ if((*getkey)(rpc->arg) < 0)
111+ return ARgiveup; /* user punted */
112+ }
113+}
114+
115+/*
116+ * this just proxies what the factotum tells it to.
117+ */
118+AuthInfo*
119+fauth_proxy(int fd, AuthRpc *rpc, AuthGetkey *getkey, char *params)
120+{
121+ char *buf;
122+ int m, n, ret;
123+ AuthInfo *a;
124+ char oerr[ERRMAX];
125+
126+ rerrstr(oerr, sizeof oerr);
127+ werrstr("UNKNOWN AUTH ERROR");
128+
129+ if(dorpc(rpc, "start", params, strlen(params), getkey) != ARok){
130+ werrstr("fauth_proxy start: %r");
131+ return nil;
132+ }
133+
134+ buf = malloc(AuthRpcMax);
135+ if(buf == nil)
136+ return nil;
137+ for(;;){
138+ switch(dorpc(rpc, "read", nil, 0, getkey)){
139+ case ARdone:
140+ free(buf);
141+ a = auth_getinfo(rpc);
142+ errstr(oerr, sizeof oerr); /* no error, restore whatever was there */
143+ return a;
144+ case ARok:
145+ if(write(fd, rpc->arg, rpc->narg) != rpc->narg){
146+ werrstr("auth_proxy write fd: %r");
147+ goto Error;
148+ }
149+ break;
150+ case ARphase:
151+ n = 0;
152+ memset(buf, 0, AuthRpcMax);
153+ while((ret = dorpc(rpc, "write", buf, n, getkey)) == ARtoosmall){
154+ if(atoi(rpc->arg) > AuthRpcMax)
155+ break;
156+ m = read(fd, buf+n, atoi(rpc->arg)-n);
157+ if(m <= 0){
158+ if(m == 0)
159+ werrstr("auth_proxy short read: %s", buf);
160+ goto Error;
161+ }
162+ n += m;
163+ }
164+ if(ret != ARok){
165+ werrstr("auth_proxy rpc write: %s: %r", buf);
166+ goto Error;
167+ }
168+ break;
169+ default:
170+ werrstr("auth_proxy rpc: %r");
171+ goto Error;
172+ }
173+ }
174+Error:
175+ free(buf);
176+ return nil;
177+}
178+
179+AuthInfo*
180+auth_proxy(int fd, AuthGetkey *getkey, char *fmt, ...)
181+{
182+ int afd;
183+ char *p;
184+ va_list arg;
185+ AuthInfo *ai;
186+ AuthRpc *rpc;
187+
188+ quotefmtinstall(); /* just in case */
189+ va_start(arg, fmt);
190+ p = vsmprint(fmt, arg);
191+ va_end(arg);
192+
193+ afd = open("/mnt/factotum/rpc", ORDWR);
194+ if(afd < 0){
195+ werrstr("opening /mnt/factotum/rpc: %r");
196+ free(p);
197+ return nil;
198+ }
199+
200+ rpc = auth_allocrpc(afd);
201+ if(rpc == nil){
202+ free(p);
203+ return nil;
204+ }
205+
206+ ai = fauth_proxy(fd, rpc, getkey, p);
207+ free(p);
208+ auth_freerpc(rpc);
209+ close(afd);
210+ return ai;
211+}
212+
libauth/auth_respond.c+73−0
@@ -0,0 +1,73 @@
1+#include <u.h>
2+#include <libc.h>
3+#include <auth.h>
4+#include <authsrv.h>
5+#include "authlocal.h"
6+
7+enum {
8+ ARgiveup = 100,
9+};
10+
11+static int
12+dorpc(AuthRpc *rpc, char *verb, char *val, int len, AuthGetkey *getkey)
13+{
14+ int ret;
15+
16+ for(;;){
17+ if((ret = auth_rpc(rpc, verb, val, len)) != ARneedkey && ret != ARbadkey)
18+ return ret;
19+ if(getkey == nil)
20+ return ARgiveup; /* don't know how */
21+ if((*getkey)(rpc->arg) < 0)
22+ return ARgiveup; /* user punted */
23+ }
24+}
25+
26+int
27+auth_respond(void *chal, uint nchal, char *user, uint nuser, void *resp, uint nresp, AuthGetkey *getkey, char *fmt, ...)
28+{
29+ char *p, *s;
30+ va_list arg;
31+ int afd;
32+ AuthRpc *rpc;
33+ Attr *a;
34+
35+ if((afd = open("/mnt/factotum/rpc", ORDWR)) < 0)
36+ return -1;
37+
38+ if((rpc = auth_allocrpc(afd)) == nil){
39+ close(afd);
40+ return -1;
41+ }
42+
43+ quotefmtinstall(); /* just in case */
44+ va_start(arg, fmt);
45+ p = vsmprint(fmt, arg);
46+ va_end(arg);
47+
48+ if(p==nil
49+ || dorpc(rpc, "start", p, strlen(p), getkey) != ARok
50+ || dorpc(rpc, "write", chal, nchal, getkey) != ARok
51+ || dorpc(rpc, "read", nil, 0, getkey) != ARok){
52+ free(p);
53+ close(afd);
54+ auth_freerpc(rpc);
55+ return -1;
56+ }
57+ free(p);
58+
59+ if(rpc->narg < nresp)
60+ nresp = rpc->narg;
61+ memmove(resp, rpc->arg, nresp);
62+
63+ if((a = auth_attr(rpc)) != nil
64+ && (s = _strfindattr(a, "user")) != nil && strlen(s) < nuser)
65+ strcpy(user, s);
66+ else if(nuser > 0)
67+ user[0] = '\0';
68+
69+ _freeattr(a);
70+ close(afd);
71+ auth_freerpc(rpc);
72+ return nresp;
73+}
libauth/auth_rpc.c+116−0
@@ -0,0 +1,116 @@
1+#include <u.h>
2+#include <libc.h>
3+#include <auth.h>
4+#include "authlocal.h"
5+
6+static struct {
7+ char *verb;
8+ int val;
9+} tab[] = {
10+ "ok", ARok,
11+ "done", ARdone,
12+ "error", ARerror,
13+ "needkey", ARneedkey,
14+ "badkey", ARbadkey,
15+ "phase", ARphase,
16+ "toosmall", ARtoosmall,
17+ "error", ARerror,
18+};
19+
20+static int
21+classify(char *buf, uint n, AuthRpc *rpc)
22+{
23+ int i, len;
24+
25+ for(i=0; i<nelem(tab); i++){
26+ len = strlen(tab[i].verb);
27+ if(n >= len && memcmp(buf, tab[i].verb, len) == 0 && (n==len || buf[len]==' ')){
28+ if(n==len){
29+ rpc->narg = 0;
30+ rpc->arg = "";
31+ }else{
32+ rpc->narg = n - (len+1);
33+ rpc->arg = (char*)buf+len+1;
34+ }
35+ return tab[i].val;
36+ }
37+ }
38+ werrstr("malformed rpc response: %s", buf);
39+ return ARrpcfailure;
40+}
41+
42+AuthRpc*
43+auth_allocrpc(int afd)
44+{
45+ AuthRpc *rpc;
46+
47+ rpc = mallocz(sizeof(*rpc), 1);
48+ if(rpc == nil)
49+ return nil;
50+ rpc->afd = afd;
51+ return rpc;
52+}
53+
54+void
55+auth_freerpc(AuthRpc *rpc)
56+{
57+ free(rpc);
58+}
59+
60+uint
61+auth_rpc(AuthRpc *rpc, char *verb, void *a, int na)
62+{
63+ int l, n, type;
64+ char *f[4];
65+
66+ l = strlen(verb);
67+ if(na+l+1 > AuthRpcMax){
68+ werrstr("rpc too big");
69+ return ARtoobig;
70+ }
71+
72+ memmove(rpc->obuf, verb, l);
73+ rpc->obuf[l] = ' ';
74+ memmove(rpc->obuf+l+1, a, na);
75+ if((n=write(rpc->afd, rpc->obuf, l+1+na)) != l+1+na){
76+ if(n >= 0)
77+ werrstr("auth_rpc short write");
78+ return ARrpcfailure;
79+ }
80+
81+ if((n=read(rpc->afd, rpc->ibuf, AuthRpcMax)) < 0)
82+ return ARrpcfailure;
83+ rpc->ibuf[n] = '\0';
84+
85+ /*
86+ * Set error string for good default behavior.
87+ */
88+ switch(type = classify(rpc->ibuf, n, rpc)){
89+ default:
90+ werrstr("unknown rpc type %d (bug in auth_rpc.c)", type);
91+ break;
92+ case ARok:
93+ break;
94+ case ARrpcfailure:
95+ break;
96+ case ARerror:
97+ if(rpc->narg == 0)
98+ werrstr("unspecified rpc error");
99+ else
100+ werrstr("%s", rpc->arg);
101+ break;
102+ case ARneedkey:
103+ werrstr("needkey %s", rpc->arg);
104+ break;
105+ case ARbadkey:
106+ if(getfields(rpc->arg, f, nelem(f), 0, "\n") < 2)
107+ werrstr("badkey %s", rpc->arg);
108+ else
109+ werrstr("badkey %s", f[1]);
110+ break;
111+ case ARphase:
112+ werrstr("phase error %s", rpc->arg);
113+ break;
114+ }
115+ return type;
116+}
libauth/auth_userpasswd.c+50−0
@@ -0,0 +1,50 @@
1+#include <u.h>
2+#include <libc.h>
3+#include <auth.h>
4+#include <authsrv.h>
5+#include "authlocal.h"
6+
7+/*
8+ * compute the proper response. We encrypt the ascii of
9+ * challenge number, with trailing binary zero fill.
10+ * This process was derived empirically.
11+ * this was copied from inet's guard.
12+ */
13+static void
14+netresp(char *key, long chal, char *answer)
15+{
16+ uchar buf[8];
17+
18+ memset(buf, 0, 8);
19+ sprint((char *)buf, "%lud", chal);
20+ if(encrypt(key, buf, 8) < 0)
21+ abort();
22+ chal = (buf[0]<<24)+(buf[1]<<16)+(buf[2]<<8)+buf[3];
23+ sprint(answer, "%.8lux", chal);
24+}
25+
26+AuthInfo*
27+auth_userpasswd(char *user, char *passwd)
28+{
29+ char key[DESKEYLEN], resp[16];
30+ AuthInfo *ai;
31+ Chalstate *ch;
32+
33+ /*
34+ * Probably we should have a factotum protocol
35+ * to check a raw password. For now, we use
36+ * p9cr, which is simplest to speak.
37+ */
38+ if((ch = auth_challenge("user=%q proto=p9cr role=server", user)) == nil)
39+ return nil;
40+
41+ passtokey(key, passwd);
42+ netresp(key, atol(ch->chal), resp);
43+ memset(key, 0, sizeof key);
44+
45+ ch->resp = resp;
46+ ch->nresp = strlen(resp);
47+ ai = auth_response(ch);
48+ auth_freechal(ch);
49+ return ai;
50+}
libauth/authlocal.h+1−0
@@ -0,0 +1 @@
1+extern AuthInfo* _fauth_proxy(int fd, AuthRpc *rpc, AuthGetkey *getkey, char *params);
libauth/httpauth.c+51−0
@@ -0,0 +1,51 @@
1+#include <u.h>
2+#include <libc.h>
3+#include <auth.h>
4+#include <authsrv.h>
5+
6+/* deprecated.
7+ This is the mechanism that put entries in /sys/lib/httpd.rewrite
8+ and passwords on the authserver in /sys/lib/httppasswords, which
9+ was awkward to administer. Instead, use local .httplogin files,
10+ which are implemented in sys/src/cmd/ip/httpd/authorize.c */
11+
12+int
13+httpauth(char *name, char *password)
14+{
15+ int afd;
16+ Ticketreq tr;
17+ Ticket t;
18+ char key[DESKEYLEN];
19+ char buf[512];
20+
21+ afd = authdial(nil, nil);
22+ if(afd < 0)
23+ return -1;
24+
25+ /* send ticket request to AS */
26+ memset(&tr, 0, sizeof(tr));
27+ strcpy(tr.uid, name);
28+ tr.type = AuthHttp;
29+ convTR2M(&tr, buf);
30+ if(write(afd, buf, TICKREQLEN) != TICKREQLEN){
31+ close(afd);
32+ return -1;
33+ }
34+ if(_asrdresp(afd, buf, TICKETLEN) < 0){
35+ close(afd);
36+ return -1;
37+ }
38+ close(afd);
39+
40+ /*
41+ * use password and try to decrypt the
42+ * ticket. If it doesn't work we've got a bad password,
43+ * give up.
44+ */
45+ passtokey(key, password);
46+ convM2T(buf, &t, key);
47+ if(t.num != AuthHr || strcmp(t.cuid, tr.uid))
48+ return -1;
49+
50+ return 0;
51+}
main.c+2−0
@@ -36,6 +36,8 @@ main(int argc, char **argv) · 35 unmodified lines
3636 char buf[1024], *s;
3737 int n;
3838
39+ eve = getuser();
40+
3941 sizebug();
4042 fmtinstall('r', errfmt);
4143
posix-factotum.c+107−0
@@ -0,0 +1,107 @@
1+#include <u.h>
2+#include <sys/socket.h>
3+#include <sys/un.h>
4+#include <pwd.h>
5+#include <libc.h>
6+#include <auth.h>
7+#include <fcall.h>
8+#include <authsrv.h>
9+#include <libsec.h>
10+#include "drawterm.h"
11+
12+#undef socket
13+#undef connect
14+#undef getenv
15+#undef access
16+
17+char*
18+getuser(void)
19+{
20+ static char user[64];
21+ struct passwd *pw;
22+
23+ pw = getpwuid(getuid());
24+ if(pw == nil)
25+ return "none";
26+ strecpy(user, user+sizeof user, pw->pw_name);
27+ return user;
28+}
29+/*
30+ * Absent other hints, it works reasonably well to use
31+ * the X11 display name as the name space identifier.
32+ * This is how sam's B has worked since the early days.
33+ * Since most programs using name spaces are also using X,
34+ * this still seems reasonable. Terminal-only sessions
35+ * can set $NAMESPACE.
36+ */
37+static char*
38+nsfromdisplay(void)
39+{
40+ int fd;
41+ Dir *d;
42+ char *disp, *p;
43+
44+ if((disp = getenv("DISPLAY")) == nil){
45+ werrstr("$DISPLAY not set");
46+ return nil;
47+ }
48+
49+ /* canonicalize: xxx:0.0 => xxx:0 */
50+ p = strrchr(disp, ':');
51+ if(p){
52+ p++;
53+ while(isdigit((uchar)*p))
54+ p++;
55+ if(strcmp(p, ".0") == 0)
56+ *p = 0;
57+ }
58+
59+ return smprint("/tmp/ns.%s.%s", getuser(), disp);
60+}
61+
62+char*
63+getns(void)
64+{
65+ char *ns;
66+
67+ ns = getenv("NAMESPACE");
68+ if(ns == nil)
69+ ns = nsfromdisplay();
70+ if(ns == nil){
71+ werrstr("$NAMESPACE not set, %r");
72+ return nil;
73+ }
74+ return ns;
75+}
76+
77+int
78+dialfactotum(void)
79+{
80+ int fd;
81+ struct sockaddr_un su;
82+ char *name;
83+
84+ name = smprint("%s/factotum", getns());
85+
86+ if(name == nil || access(name, 0) < 0)
87+ return -1;
88+ memset(&su, 0, sizeof su);
89+ su.sun_family = AF_UNIX;
90+ if(strlen(name)+1 > sizeof su.sun_path){
91+ werrstr("socket name too long");
92+ return -1;
93+ }
94+ strcpy(su.sun_path, name);
95+ if((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0){
96+ werrstr("socket: %r");
97+ return -1;
98+ }
99+ if(connect(fd, (struct sockaddr*)&su, sizeof su) < 0){
100+ werrstr("connect %s: %r", name);
101+ close(fd);
102+ return -1;
103+ }
104+
105+ return lfdfd(fd);
106+}
107+
win32-factotum.c+22−0
@@ -0,0 +1,22 @@
1+#include <u.h>
2+#include <libc.h>
3+#include <auth.h>
4+#include <fcall.h>
5+#include <authsrv.h>
6+#include <libsec.h>
7+#include "drawterm.h"
8+
9+#undef getenv
10+
11+char*
12+getuser(void)
13+{
14+ return getenv("USER");
15+}
16+
17+int
18+dialfactotum(void)
19+{
20+ return -1;
21+}
22+

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t