Unified · Split
| @@ -8,27 +8,23 @@ OFILES=\ · 7 unmodified lines | |||
| 8 | readcons.$O\ | 8 | readcons.$O\ |
| 9 | secstore.$O\ | 9 | secstore.$O\ |
| 10 | latin1.$O\ | 10 | latin1.$O\ |
| 11 | $(OS)-factotum.$O\ | ||
| 11 | 12 | ||
| 12 | LIBS=\ | 13 | LIBS1=\ |
| 13 | kern/libkern.a\ | 14 | kern/libkern.a\ |
| 14 | exportfs/libexportfs.a\ | 15 | exportfs/libexportfs.a\ |
| 16 | libauth/libauth.a\ | ||
| 15 | libauthsrv/libauthsrv.a\ | 17 | libauthsrv/libauthsrv.a\ |
| 16 | libsec/libsec.a\ | 18 | libsec/libsec.a\ |
| 17 | libmp/libmp.a\ | 19 | libmp/libmp.a\ |
| 18 | libmemdraw/libmemdraw.a\ | 20 | libmemdraw/libmemdraw.a\ |
| 19 | libmemlayer/libmemlayer.a\ | 21 | libmemlayer/libmemlayer.a\ |
| 20 | libdraw/libdraw.a\ | 22 | libdraw/libdraw.a\ |
| 21 | libc/libc.a\ | ||
| 22 | kern/libkern.a\ | ||
| 23 | gui-$(GUI)/libgui.a\ | 23 | gui-$(GUI)/libgui.a\ |
| 24 | libmemdraw/libmemdraw.a\ | ||
| 25 | libdraw/libdraw.a\ | ||
| 26 | kern/libkern.a\ | ||
| 27 | libc/libc.a\ | 24 | libc/libc.a\ |
| 28 | libmemdraw/libmemdraw.a\ | 25 | |
| 29 | libmemlayer/libmemlayer.a\ | 26 | # stupid gcc |
| 30 | libdraw/libdraw.a\ | 27 | LIBS=$(LIBS1) $(LIBS1) $(LIBS1) libmachdep.a |
| 31 | libmachdep.a | ||
| 32 | 28 | ||
| 33 | $(TARG): $(OFILES) $(LIBS) | 29 | $(TARG): $(OFILES) $(LIBS) |
| 34 | $(CC) $(LDFLAGS) -o $(TARG) $(OFILES) $(LIBS) $(LDADD) | 30 | $(CC) $(LDFLAGS) -o $(TARG) $(OFILES) $(LIBS) $(LDADD) |
| @@ -45,6 +41,9 @@ kern/libkern.a: · 10 unmodified lines | |||
| 45 | exportfs/libexportfs.a: | 41 | exportfs/libexportfs.a: |
| 46 | (cd exportfs; make) | 42 | (cd exportfs; make) |
| 47 | 43 | ||
| 44 | libauth/libauth.a: | ||
| 45 | (cd libauth; make) | ||
| 46 | |||
| 48 | libauthsrv/libauthsrv.a: | 47 | libauthsrv/libauthsrv.a: |
| 49 | (cd libauthsrv; make) | 48 | (cd libauthsrv; make) |
| 50 | 49 | ||
| @@ -17,7 +17,6 @@ · 16 unmodified lines | |||
| 17 | #define Maxfdata 8192 | 17 | #define Maxfdata 8192 |
| 18 | #define MaxStr 128 | 18 | #define MaxStr 128 |
| 19 | 19 | ||
| 20 | static char* getuser(void); | ||
| 21 | static void fatal(int, char*, ...); | 20 | static void fatal(int, char*, ...); |
| 22 | static void catcher(void*, char*); | 21 | static void catcher(void*, char*); |
| 23 | static void usage(void); | 22 | static void usage(void); |
| @@ -98,7 +97,9 @@ cpumain(int argc, char **argv) · 74 unmodified lines | |||
| 98 | close(fd); | 97 | close(fd); |
| 99 | } | 98 | } |
| 100 | 99 | ||
| 101 | user = readcons("user", getenv("USER"), 0); | 100 | user = getenv("USER"); |
| 101 | if(user == nil) | ||
| 102 | user = readcons("user", nil, 0); | ||
| 102 | secstoreserver = nil; | 103 | secstoreserver = nil; |
| 103 | ARGBEGIN{ | 104 | ARGBEGIN{ |
| 104 | case 'a': | 105 | case 'a': |
| @@ -126,6 +127,9 @@ cpumain(int argc, char **argv) · 21 unmodified lines | |||
| 126 | } | 127 | } |
| 127 | break; | 128 | break; |
| 128 | */ | 129 | */ |
| 130 | case 'k': | ||
| 131 | keyspec = EARGF(usage()); | ||
| 132 | break; | ||
| 129 | case 'u': | 133 | case 'u': |
| 130 | user = EARGF(usage()); | 134 | user = EARGF(usage()); |
| 131 | break; | 135 | break; |
| @@ -136,6 +140,15 @@ cpumain(int argc, char **argv) · 4 unmodified lines | |||
| 136 | usage(); | 140 | usage(); |
| 137 | }ARGEND; | 141 | }ARGEND; |
| 138 | 142 | ||
| 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 | |||
| 139 | if(secstoreserver == nil) | 152 | if(secstoreserver == nil) |
| 140 | secstoreserver = authserver; | 153 | secstoreserver = authserver; |
| 141 | 154 | ||
| @@ -436,6 +449,96 @@ gettickets(Ticketreq *tr, char *key, char *trbuf, char *tbuf) · 294 unmodified lines | |||
| 436 | return mkserverticket(tr, key, tbuf); | 449 | return mkserverticket(tr, key, tbuf); |
| 437 | } | 450 | } |
| 438 | 451 | ||
| 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 | |||
| 439 | AuthInfo* | 542 | AuthInfo* |
| 440 | p9any(int fd) | 543 | p9any(int fd) |
| 441 | { | 544 | { |
| @@ -444,11 +547,14 @@ p9any(int fd) · 2 unmodified lines | |||
| 444 | char tbuf[TICKETLEN+TICKETLEN+AUTHENTLEN], trbuf[TICKREQLEN]; | 547 | char tbuf[TICKETLEN+TICKETLEN+AUTHENTLEN], trbuf[TICKREQLEN]; |
| 445 | char authkey[DESKEYLEN]; | 548 | char authkey[DESKEYLEN]; |
| 446 | Authenticator auth; | 549 | Authenticator auth; |
| 447 | int i, v2, n; | 550 | int afd, i, v2, n; |
| 448 | Ticketreq tr; | 551 | Ticketreq tr; |
| 449 | Ticket t; | 552 | Ticket t; |
| 450 | AuthInfo *ai; | 553 | AuthInfo *ai; |
| 451 | 554 | ||
| 555 | if((afd = open("/mnt/factotum/ctl", ORDWR)) >= 0) | ||
| 556 | return p9anyfactotum(fd, afd); | ||
| 557 | |||
| 452 | if((n = readstr(fd, buf, sizeof buf)) < 0) | 558 | if((n = readstr(fd, buf, sizeof buf)) < 0) |
| 453 | fatal(1, "cannot read p9any negotiation"); | 559 | fatal(1, "cannot read p9any negotiation"); |
| 454 | bbuf = buf; | 560 | bbuf = buf; |
| @@ -598,9 +704,3 @@ setamalg(char *s) · 143 unmodified lines | |||
| 598 | return setam(s); | 704 | return setam(s); |
| 599 | } | 705 | } |
| 600 | 706 | ||
| 601 | char* | ||
| 602 | getuser(void) | ||
| 603 | { | ||
| 604 | return getenv("USER"); | ||
| 605 | } | ||
| 606 | |||
| @@ -8,3 +8,5 @@ extern int exportfs(int, int); · 7 unmodified lines | |||
| 8 | extern char *user; | 8 | extern char *user; |
| 9 | extern char *getkey(char*, char*); | 9 | extern char *getkey(char*, char*); |
| 10 | extern char *findkey(char**, char*); | 10 | extern char *findkey(char**, char*); |
| 11 | extern int dialfactotum(void); | ||
| 12 | extern char *getuser(void); | ||
| @@ -99,7 +99,7 @@ exportfs(int fd, int msgsz) · 98 unmodified lines | |||
| 99 | fatal("convM2S format error"); | 99 | fatal("convM2S format error"); |
| 100 | } | 100 | } |
| 101 | 101 | ||
| 102 | //iprint("<- %F\n", &r->work); | 102 | if(0) iprint("<- %F\n", &r->work); |
| 103 | DEBUG(DFD, "%F\n", &r->work); | 103 | DEBUG(DFD, "%F\n", &r->work); |
| 104 | (fcalls[r->work.type])(r); | 104 | (fcalls[r->work.type])(r); |
| 105 | } | 105 | } |
| @@ -110,6 +110,7 @@ reply(Fcall *r, Fcall *t, char *err) · 4 unmodified lines | |||
| 110 | { | 110 | { |
| 111 | uchar *data; | 111 | uchar *data; |
| 112 | int m, n; | 112 | int m, n; |
| 113 | static QLock lk; | ||
| 113 | 114 | ||
| 114 | t->tag = r->tag; | 115 | t->tag = r->tag; |
| 115 | t->fid = r->fid; | 116 | t->fid = r->fid; |
| @@ -120,7 +121,7 @@ reply(Fcall *r, Fcall *t, char *err) · 4 unmodified lines | |||
| 120 | else | 121 | else |
| 121 | t->type = r->type + 1; | 122 | t->type = r->type + 1; |
| 122 | 123 | ||
| 123 | //iprint("-> %F\n", t); | 124 | if(0) iprint("-> %F\n", t); |
| 124 | DEBUG(DFD, "\t%F\n", t); | 125 | DEBUG(DFD, "\t%F\n", t); |
| 125 | 126 | ||
| 126 | data = malloc(messagesize); /* not mallocz; no need to clear */ | 127 | data = malloc(messagesize); /* not mallocz; no need to clear */ |
| @@ -431,6 +431,7 @@ slave(Fsrpc *f) · 430 unmodified lines | |||
| 431 | Proc *p; | 431 | Proc *p; |
| 432 | int pid; | 432 | int pid; |
| 433 | static int nproc; | 433 | static int nproc; |
| 434 | static QLock lk; | ||
| 434 | 435 | ||
| 435 | for(;;) { | 436 | for(;;) { |
| 436 | for(p = Proclist; p; p = p->next) { | 437 | for(p = Proclist; p; p = p->next) { |
| @@ -50,6 +50,8 @@ extern int dirwstat(char*, Dir*); · 49 unmodified lines | |||
| 50 | extern int dirfwstat(int, Dir*); | 50 | extern int dirfwstat(int, Dir*); |
| 51 | extern long dirread(int, Dir*, long); | 51 | extern long dirread(int, Dir*, long); |
| 52 | 52 | ||
| 53 | extern int lfdfd(int); | ||
| 54 | |||
| 53 | /* | 55 | /* |
| 54 | * network dialing and authentication | 56 | * network dialing and authentication |
| 55 | */ | 57 | */ |
| @@ -13,6 +13,7 @@ OFILES=\ · 12 unmodified lines | |||
| 13 | devfs-$(OS).$O\ | 13 | devfs-$(OS).$O\ |
| 14 | devip.$O\ | 14 | devip.$O\ |
| 15 | devip-$(OS).$O\ | 15 | devip-$(OS).$O\ |
| 16 | devlfd.$O\ | ||
| 16 | devmnt.$O\ | 17 | devmnt.$O\ |
| 17 | devmouse.$O\ | 18 | devmouse.$O\ |
| 18 | devpipe.$O\ | 19 | devpipe.$O\ |
| @@ -175,25 +175,6 @@ print(char *fmt, ...) · 174 unmodified lines | |||
| 175 | return n; | 175 | return n; |
| 176 | } | 176 | } |
| 177 | 177 | ||
| 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 | |||
| 197 | void | 178 | void |
| 198 | panic(char *fmt, ...) | 179 | panic(char *fmt, ...) |
| 199 | { | 180 | { |
| @@ -1208,3 +1189,23 @@ writebintime(char *buf, int n) · 1008 unmodified lines | |||
| 1208 | } | 1189 | } |
| 1209 | 1190 | ||
| 1210 | 1191 | ||
| 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 | |||
| @@ -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 | }; | ||
| @@ -8,9 +8,12 @@ enum · 7 unmodified lines | |||
| 8 | { | 8 | { |
| 9 | Qdir = 0, | 9 | Qdir = 0, |
| 10 | Qboot = 0x1000, | 10 | Qboot = 0x1000, |
| 11 | Qmnt = 0x2000, | ||
| 12 | Qfactotum, | ||
| 11 | 13 | ||
| 12 | Nrootfiles = 32, | 14 | Nrootfiles = 32, |
| 13 | Nbootfiles = 32, | 15 | Nbootfiles = 32, |
| 16 | Nmntfiles = 2, | ||
| 14 | }; | 17 | }; |
| 15 | 18 | ||
| 16 | typedef struct Dirlist Dirlist; | 19 | typedef struct Dirlist Dirlist; |
| @@ -26,6 +29,7 @@ struct Dirlist · 9 unmodified lines | |||
| 26 | static Dirtab rootdir[Nrootfiles] = { | 29 | static Dirtab rootdir[Nrootfiles] = { |
| 27 | "#/", {Qdir, 0, QTDIR}, 0, DMDIR|0555, | 30 | "#/", {Qdir, 0, QTDIR}, 0, DMDIR|0555, |
| 28 | "boot", {Qboot, 0, QTDIR}, 0, DMDIR|0555, | 31 | "boot", {Qboot, 0, QTDIR}, 0, DMDIR|0555, |
| 32 | "mnt", {Qmnt, 0, QTDIR}, 0, DMDIR|0555, | ||
| 29 | }; | 33 | }; |
| 30 | static uchar *rootdata[Nrootfiles]; | 34 | static uchar *rootdata[Nrootfiles]; |
| 31 | static Dirlist rootlist = | 35 | static Dirlist rootlist = |
| @@ -33,7 +37,7 @@ static Dirlist rootlist = · 1 unmodified line | |||
| 33 | 0, | 37 | 0, |
| 34 | rootdir, | 38 | rootdir, |
| 35 | rootdata, | 39 | rootdata, |
| 36 | 2, | 40 | 3, |
| 37 | Nrootfiles | 41 | Nrootfiles |
| 38 | }; | 42 | }; |
| 39 | 43 | ||
| @@ -50,6 +54,19 @@ static Dirlist bootlist = · 10 unmodified lines | |||
| 50 | Nbootfiles | 54 | Nbootfiles |
| 51 | }; | 55 | }; |
| 52 | 56 | ||
| 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 | |||
| 53 | /* | 70 | /* |
| 54 | * add a file to the list | 71 | * add a file to the list |
| 55 | */ | 72 | */ |
| @@ -97,7 +114,6 @@ rootreset(void) · 41 unmodified lines | |||
| 97 | addrootdir("dev"); | 114 | addrootdir("dev"); |
| 98 | addrootdir("env"); | 115 | addrootdir("env"); |
| 99 | addrootdir("fd"); | 116 | addrootdir("fd"); |
| 100 | addrootdir("mnt"); | ||
| 101 | addrootdir("net"); | 117 | addrootdir("net"); |
| 102 | addrootdir("net.alt"); | 118 | addrootdir("net.alt"); |
| 103 | addrootdir("proc"); | 119 | addrootdir("proc"); |
| @@ -129,6 +145,13 @@ rootgen(Chan *c, char *name, Dirtab *dirt, int ndirt, int s, Dir *dp) · 25 unmodified lines | |||
| 129 | return 1; | 145 | return 1; |
| 130 | } | 146 | } |
| 131 | return devgen(c, name, rootlist.dir, rootlist.ndir, s, dp); | 147 | 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); | ||
| 132 | case Qboot: | 155 | case Qboot: |
| 133 | if(s == DEVDOTDOT){ | 156 | if(s == DEVDOTDOT){ |
| 134 | Qid tqiddir = {Qdir, 0, QTDIR}; | 157 | 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 | |||
| 139 | default: | 162 | default: |
| 140 | if(s == DEVDOTDOT){ | 163 | if(s == DEVDOTDOT){ |
| 141 | Qid tqiddir = {Qdir, 0, QTDIR}; | 164 | Qid tqiddir = {Qdir, 0, QTDIR}; |
| 142 | if((int)c->qid.path < Qboot) | 165 | tqiddir.path = c->qid.path&0xF000; |
| 143 | devdir(c, tqiddir, "#/", 0, eve, 0555, dp); | 166 | devdir(c, tqiddir, "#/", 0, eve, 0555, dp); |
| 144 | else { | ||
| 145 | tqiddir.path = Qboot; | ||
| 146 | devdir(c, tqiddir, "#/", 0, eve, 0555, dp); | ||
| 147 | } | ||
| 148 | return 1; | 167 | return 1; |
| 149 | } | 168 | } |
| 150 | if(s != 0) | 169 | if(s != 0) |
| 151 | return -1; | 170 | return -1; |
| 152 | if((int)c->qid.path < Qboot){ | 171 | switch((int)c->qid.path & 0xF000){ |
| 172 | case Qdir: | ||
| 153 | t = c->qid.path-1; | 173 | t = c->qid.path-1; |
| 154 | l = &rootlist; | 174 | l = &rootlist; |
| 155 | }else{ | 175 | break; |
| 176 | case Qboot: | ||
| 156 | t = c->qid.path - Qboot - 1; | 177 | t = c->qid.path - Qboot - 1; |
| 157 | l = &bootlist; | 178 | l = &bootlist; |
| 179 | break; | ||
| 180 | case Qmnt: | ||
| 181 | t = c->qid.path - Qmnt - 1; | ||
| 182 | l = &mntlist; | ||
| 183 | break; | ||
| 158 | } | 184 | } |
| 159 | if(t >= l->ndir) | 185 | if(t >= l->ndir) |
| 160 | return -1; | 186 | return -1; |
| @@ -209,17 +235,19 @@ rootread(Chan *c, void *buf, long n, vlong off) · 48 unmodified lines | |||
| 209 | switch(t){ | 235 | switch(t){ |
| 210 | case Qdir: | 236 | case Qdir: |
| 211 | case Qboot: | 237 | case Qboot: |
| 238 | case Qmnt: | ||
| 212 | return devdirread(c, buf, n, nil, 0, rootgen); | 239 | return devdirread(c, buf, n, nil, 0, rootgen); |
| 213 | } | 240 | } |
| 214 | 241 | ||
| 215 | if(t<Qboot) | 242 | if(t&Qboot) |
| 216 | l = &rootlist; | ||
| 217 | else{ | ||
| 218 | t -= Qboot; | ||
| 219 | l = &bootlist; | 243 | l = &bootlist; |
| 220 | } | 244 | else if(t&Qmnt) |
| 221 | 245 | l = &mntlist; | |
| 246 | else | ||
| 247 | l = &bootlist; | ||
| 248 | t &= 0xFFF; | ||
| 222 | t--; | 249 | t--; |
| 250 | |||
| 223 | if(t >= l->ndir) | 251 | if(t >= l->ndir) |
| 224 | error(Egreg); | 252 | error(Egreg); |
| 225 | 253 | ||
| @@ -765,6 +765,7 @@ sslput(Dstate *s, Block * volatile b) · 764 unmodified lines | |||
| 765 | int offset; | 765 | int offset; |
| 766 | 766 | ||
| 767 | if(waserror()){ | 767 | if(waserror()){ |
| 768 | iprint("error: %s\n", up->errstr); | ||
| 768 | if(b != nil) | 769 | if(b != nil) |
| 769 | free(b); | 770 | free(b); |
| 770 | nexterror(); | 771 | nexterror(); |
| @@ -1071,8 +1072,9 @@ sslwrite(Chan *c, void *a, long n, vlong o) · 300 unmodified lines | |||
| 1071 | nexterror(); | 1072 | nexterror(); |
| 1072 | } | 1073 | } |
| 1073 | qlock(&s->out.q); | 1074 | qlock(&s->out.q); |
| 1074 | |||
| 1075 | p = a; | 1075 | 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]); | ||
| 1076 | e = p + n; | 1078 | e = p + n; |
| 1077 | do { | 1079 | do { |
| 1078 | m = e - p; | 1080 | m = e - p; |
| @@ -1092,7 +1094,9 @@ sslwrite(Chan *c, void *a, long n, vlong o) · 13 unmodified lines | |||
| 1092 | 1094 | ||
| 1093 | p += m; | 1095 | p += m; |
| 1094 | } while(p < e); | 1096 | } 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]); | ||
| 1096 | poperror(); | 1100 | poperror(); |
| 1097 | qunlock(&s->out.q); | 1101 | qunlock(&s->out.q); |
| 1098 | return n; | 1102 | return n; |
| @@ -12,6 +12,8 @@ extern Dev mousedevtab; · 11 unmodified lines | |||
| 12 | extern Dev drawdevtab; | 12 | extern Dev drawdevtab; |
| 13 | extern Dev ipdevtab; | 13 | extern Dev ipdevtab; |
| 14 | extern Dev fsdevtab; | 14 | extern Dev fsdevtab; |
| 15 | extern Dev mntdevtab; | ||
| 16 | extern Dev lfddevtab; | ||
| 15 | 17 | ||
| 16 | Dev *devtab[] = { | 18 | Dev *devtab[] = { |
| 17 | &rootdevtab, | 19 | &rootdevtab, |
| @@ -22,6 +24,8 @@ Dev *devtab[] = { · 4 unmodified lines | |||
| 22 | &drawdevtab, | 24 | &drawdevtab, |
| 23 | &ipdevtab, | 25 | &ipdevtab, |
| 24 | &fsdevtab, | 26 | &fsdevtab, |
| 27 | &mntdevtab, | ||
| 28 | &lfddevtab, | ||
| 25 | 0 | 29 | 0 |
| 26 | }; | 30 | }; |
| 27 | 31 | ||
| @@ -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 | |||
| @@ -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 | |||
| @@ -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 | } | ||
| @@ -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 | } | ||
| @@ -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 | } | ||
| @@ -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 | |||
| @@ -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 | } | ||
| @@ -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 | } | ||
| @@ -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 | } | ||
| @@ -0,0 +1 @@ | |||
| 1 | extern AuthInfo* _fauth_proxy(int fd, AuthRpc *rpc, AuthGetkey *getkey, char *params); | ||
| @@ -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 | } | ||
| @@ -36,6 +36,8 @@ main(int argc, char **argv) · 35 unmodified lines | |||
| 36 | char buf[1024], *s; | 36 | char buf[1024], *s; |
| 37 | int n; | 37 | int n; |
| 38 | 38 | ||
| 39 | eve = getuser(); | ||
| 40 | |||
| 39 | sizebug(); | 41 | sizebug(); |
| 40 | fmtinstall('r', errfmt); | 42 | fmtinstall('r', errfmt); |
| 41 | 43 | ||
| @@ -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 | |||
| @@ -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 | |||