From fda9719950183738a9f02077c1d1e22da878a849 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Tue, 30 Mar 1993 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1993-03-30 --- boot/aux.c | 13 ++ boot/boot.c | 17 +- boot/boot.h | 18 +- boot/doauthenticate.c | 114 ++++++++++ boot/dosboot.c | 6 +- boot/key.c | 77 ++++--- boot/nopsession.c | 8 +- boot/settime.c | 11 +- boot/userpasswd.c | 61 ++--- pc/main.c | 35 +++ port/auth.c | 508 ++++++++++++++++++++++++++++++++++++++++++ port/chan.c | 4 + port/dev.c | 13 +- port/devcons.c | 153 ++++--------- port/devmnt.c | 60 ++--- port/lib.h | 1 - port/net.c | 29 +-- port/pgrp.c | 49 ---- port/portdat.h | 17 +- port/portfns.h | 13 ++ port/stfcall.c | 10 +- port/sysfile.c | 12 - port/sysproc.c | 4 - port/systab.h | 6 +- 24 files changed, 866 insertions(+), 373 deletions(-) create mode 100644 boot/doauthenticate.c create mode 100644 port/auth.c diff --git a/boot/aux.c b/boot/aux.c index 232be78985620355af0b388eba2e57520041d961..55ba8af27a79eead678b9611aec5fa6de53301ca 100644 --- a/boot/aux.c +++ b/boot/aux.c @@ -86,6 +86,19 @@ readfile(char *name, char *buf, int len) return 0; } +int +writefile(char *name, char *buf, int len) +{ + int f, n; + + f = open(name, OWRITE); + if(f < 0) + return -1; + n = write(f, buf, len); + close(f); + return (n != len) ? -1 : 0; +} + void setenv(char *name, char *val) { diff --git a/boot/boot.c b/boot/boot.c index ebfdd8f7cd25b1267b461adca15a61aed8c1bf0c..c2d13531bf163e3c2353e0d9341032458e828a97 100644 --- a/boot/boot.c +++ b/boot/boot.c @@ -1,5 +1,6 @@ #include #include +#include #include "../boot/boot.h" #define DEFSYS "bootes" @@ -12,7 +13,6 @@ char cputype[NAMELEN]; char terminal[NAMELEN]; char sys[2*NAMELEN]; char username[NAMELEN]; -char *sauth; char bootfile[3*NAMELEN]; char conffile[NAMELEN]; @@ -21,6 +21,7 @@ int fflag; int kflag; int aflag; int pflag; +int afd = -1; static void swapproc(void); static Method *rootserver(char*); @@ -94,9 +95,9 @@ boot(int argc, char *argv[]) fatal("can't connect to file server"); if(!islocal && !ishybrid){ nop(fd); - session(fd); if(cfs) fd = (*cfs)(fd); + doauthenticate(fd, mp); } srvcreate("boot", fd); @@ -105,12 +106,8 @@ boot(int argc, char *argv[]) */ if(bind("/", "/", MREPL) < 0) fatal("bind"); - sauth = ""; - if(mount(fd, "/", MAFTER|MCREATE, "", sauth) < 0){ - sauth = "any"; - if(mount(fd, "/", MAFTER|MCREATE, "", sauth) < 0) - fatal("mount"); - } + if(mount(fd, "/", MAFTER|MCREATE, "") < 0) + fatal("mount"); close(fd); if(cpuflag == 0) newkernel(); @@ -127,14 +124,16 @@ boot(int argc, char *argv[]) fd = (*mp->connect)(); if(fd < 0) break; - mount(fd, "/n/kfs", MAFTER|MCREATE, "", "") ; + mount(fd, "/n/kfs", MAFTER|MCREATE, "") ; close(fd); break; } } settime(islocal); + close(afd); swapproc(); + remove("#e/password"); sprint(cmd, "/%s/init", cputype); sprint(flags, "-%s%s%s", cpuflag ? "c" : "t", mflag ? "m" : "", aflag ? "a" : ""); diff --git a/boot/boot.h b/boot/boot.h index 95d569d5f1169ad14d7e232576c5cfa31346a1fb..443be55b72de3d4c5606c84186f49c387839d4db 100644 --- a/boot/boot.h +++ b/boot/boot.h @@ -11,21 +11,22 @@ struct Method extern char* bootdisk; extern int (*cfs)(int); extern int cpuflag; -extern char cputype[NAMELEN]; +extern char cputype[]; extern int fflag; extern int kflag; extern Method method[]; -extern char password[NAMELEN]; extern void (*pword)(int, Method*); -extern char sys[2*NAMELEN]; -extern char terminal[NAMELEN]; +extern char sys[]; +extern uchar hostkey[]; +extern char terminal[]; extern char username[NAMELEN]; -extern char bootfile[3*NAMELEN]; -extern char conffile[NAMELEN]; -extern char *sauth; +extern char bootfile[]; +extern char conffile[]; +extern int afd; /* libc equivalent */ extern int cache(int); +extern char* checkkey(Method*, char*, char*); extern int dkauth(void); extern int dkconnect(void); extern void fatal(char*); @@ -37,6 +38,7 @@ extern void nop(int); extern int outin(char*, char*, int); extern int plumb(char*, char*, int*, char*); extern int readfile(char*, char*, int); +extern int readn(int, char*, int); extern int sendmsg(int, char*); extern void session(int); extern void setenv(char*, char*); @@ -44,8 +46,10 @@ extern void settime(int); extern void srvcreate(char*, int); extern void userpasswd(int, Method*); extern void warning(char*); +extern int writefile(char*, char*, int); extern void boot(int, char **); extern void bboot(int, char **); +extern void doauthenticate(int, Method*); /* methods */ extern void config9600(Method*); diff --git a/boot/doauthenticate.c b/boot/doauthenticate.c new file mode 100644 index 0000000000000000000000000000000000000000..fc460754279dde58b098b442bf15b48a9fe427bf --- /dev/null +++ b/boot/doauthenticate.c @@ -0,0 +1,114 @@ +#include +#include +#include +#include <../boot/boot.h> + +static char *pbmsg = "AS protocol botch"; +static char *ccmsg = "can't connect to AS"; + +int +readn(int fd, char *buf, int len) +{ + int m, n; + + for(n = 0; n < len; n += m){ + m = read(fd, buf+n, len-n); + if(m <= 0) + return -1; + } + return n; +} + +static char* +fromauth(Method *mp, char *trbuf, char *tbuf) +{ + char t; + char *msg; + static char error[ERRLEN]; + + if(afd < 0){ + if(mp->auth == 0) + fatal("no method for accessing auth server"); + afd = (*mp->auth)(); + if(afd < 0) + return ccmsg; + } + if(write(afd, trbuf, TICKREQLEN) < 0 || read(afd, &t, 1) != 1){ + close(afd); + afd = -1; + return pbmsg; + } + switch(t){ + case AuthOK: + msg = 0; + if(readn(afd, tbuf, 2*TICKETLEN) < 0) + msg = pbmsg; + break; + case AuthErr: + if(readn(afd, error, ERRLEN) < 0) + msg = pbmsg; + else { + error[ERRLEN-1] = 0; + msg = error; + } + break; + default: + msg = pbmsg; + break; + } + return msg; +} + +void +doauthenticate(int fd, Method *mp) +{ + char *msg; + char trbuf[TICKREQLEN]; + char tbuf[2*TICKETLEN]; + + print("session..."); + if(fsession(fd, trbuf) < 0) + fatal("session command failed"); + + /* no authentication required? */ + memset(tbuf, 0, 2*TICKETLEN); + if(trbuf[0] == 0) + return; + + /* try getting to an auth server */ + msg = fromauth(mp, trbuf, tbuf); + if(msg == 0) + if(fauth(fd, tbuf) >= 0) + return; + + /* didn't work, go for the security hole */ + fprint(2, "no authentication server (%s), using your key as server key\n", msg); +} + +char* +checkkey(Method *mp, char *name, char *key) +{ + char *msg; + Ticketreq tr; + Ticket t; + char trbuf[TICKREQLEN]; + char tbuf[TICKETLEN]; + + memset(&tr, 0, sizeof tr); + tr.type = AuthTreq; + strcpy(tr.authid, name); + strcpy(tr.hostid, name); + strcpy(tr.uid, name); + convTR2M(&tr, trbuf); + msg = fromauth(mp, trbuf, tbuf); + if(msg) + return msg; + if(msg == ccmsg){ + fprint(2, "boot: can't contact auth server, passwd unchecked\n"); + return 0; + } + convM2T(tbuf, &t, key); + if(t.num == AuthTc && strcmp(name, t.cuid)==0) + return 0; + return "no match"; +} diff --git a/boot/dosboot.c b/boot/dosboot.c index 25cc4b6214d10ccd7b7e09e515c721ad4674d1bb..f3f9cefc57d1cb466b16a874748125fa10f7a15e 100644 --- a/boot/dosboot.c +++ b/boot/dosboot.c @@ -30,9 +30,9 @@ dosboot(void) */ if(bind("/", "/", MREPL) < 0) fatal("bind"); - if(mount(fd, "/", MAFTER|MCREATE, "#f/fd0disk", "") < 0) - if(mount(fd, "/", MAFTER|MCREATE, "#f/fd1disk", "") < 0) - if(mount(fd, "/", MAFTER|MCREATE, "#H/hd0dos", "") < 0) + if(mount(fd, "/", MAFTER|MCREATE, "#f/fd0disk") < 0) + if(mount(fd, "/", MAFTER|MCREATE, "#f/fd1disk") < 0) + if(mount(fd, "/", MAFTER|MCREATE, "#H/hd0dos") < 0) fatal("mount"); close(fd); diff --git a/boot/key.c b/boot/key.c index 64807ed3d4736c2c7b519814f0d64d659036a276..8220bf7da3b4cff4acff0807198ac7bb0290a5ce 100644 --- a/boot/key.c +++ b/boot/key.c @@ -3,50 +3,73 @@ #include #include <../boot/boot.h> +char *homsg = "can't set user name or key; please reboot"; + +getsafe(char *field, int len, uchar *sum, char *file, int pass) +{ + char buf[64]; + + if(nvcsum(field, len) != *sum){ + if(readfile(file, buf, sizeof(buf)) < 0){ + kflag |= 1; + return -1; + } + memset(field, 0, len); + if(pass) + passtokey(field, buf); + else + strncpy(field, buf, len-1); + } + return 0; +} + void key(int islocal, Method *mp) { + int fd; Nvrsafe safe; char password[20]; - int prompt, fd; USED(islocal); USED(mp); - prompt = kflag; fd = open("#r/nvram", ORDWR); - if(fd < 0){ - prompt = 1; - warning("can't open nvram"); + if(fd < 0 + || seek(fd, 1024+900, 0) < 0 + || read(fd, &safe, sizeof safe) != sizeof safe){ + memset(&safe, 0, sizeof(safe)); + warning("can't read nvram"); } - if(seek(fd, 1024+900, 0) < 0 - || read(fd, &safe, sizeof safe) != sizeof safe) - warning("can't read nvram key"); - -getp: - if(prompt){ + if(getsafe(safe.machkey, DESKEYLEN, &safe.machsum, "#e/password", 1) < 0) + warning("bad nvram key"); + if(getsafe(safe.authid, NAMELEN, &safe.authidsum, "#e/authid", 0) < 0) + warning("bad authentication id"); + if(getsafe(safe.authdom, DOMLEN, &safe.authdomsum, "#e/authdom", 0) < 0) + warning("bad authentication domain"); + if(kflag){ do getpasswd(password, sizeof password); while(!passtokey(safe.machkey, password)); - }else if(nvcsum(safe.machkey, DESKEYLEN) != safe.machsum){ - warning("bad nvram key"); - prompt = 1; - kflag = 1; - goto getp; - } - safe.machsum = nvcsum(safe.machkey, DESKEYLEN); - if(kflag){ + outin("authid", safe.authid, sizeof(safe.authid)); + outin("authdom", safe.authdom, sizeof(safe.authdom)); + safe.machsum = nvcsum(safe.machkey, DESKEYLEN); + safe.authidsum = nvcsum(safe.authid, sizeof(safe.authid)); + safe.authdomsum = nvcsum(safe.authdom, sizeof(safe.authdom)); if(seek(fd, 1024+900, 0) < 0 || write(fd, &safe, sizeof safe) != sizeof safe) warning("can't write key to nvram"); } close(fd); - fd = open("#c/key", OWRITE); - if(fd < 0){ - warning("can't open #c/key"); - return; - } - else if(write(fd, safe.machkey, DESKEYLEN) != DESKEYLEN) - warning("can't set #c/key"); - close(fd); + + /* set host's key */ + if(writefile("#c/key", safe.machkey, DESKEYLEN) < 0) + fatal("#c/key"); + + /* set host's owner (and uid of current process) */ + if(writefile("#c/hostowner", safe.authid, strlen(safe.authid)) < 0) + fatal("#c/hostowner"); + + /* set host's domain */ + if(writefile("#c/hostdomain", safe.authdom, strlen(safe.authdom)) < 0) + fatal("#c/hostdomain"); } diff --git a/boot/nopsession.c b/boot/nopsession.c index 2eeff09ce50d6f04151cbf4b9b056061cac7ba8c..8893ac35dba41d69b6c06ba09a876f324ebea066 100644 --- a/boot/nopsession.c +++ b/boot/nopsession.c @@ -1,5 +1,6 @@ #include #include +#include #include #include "../boot/boot.h" @@ -49,10 +50,3 @@ nop(int fd) print("nop"); rpc(fd, Tnop); } - -void -session(int fd) -{ - print("session"); - rpc(fd, Tsession); -} diff --git a/boot/settime.c b/boot/settime.c index 86e831c85cd4244ac3fe92254e456e0eddfe1eae..e602abe7cbc7e43f8b9452c6a87c97c81f1bf1e4 100644 --- a/boot/settime.c +++ b/boot/settime.c @@ -1,5 +1,6 @@ #include #include +#include #include #include "../boot/boot.h" @@ -40,11 +41,11 @@ settime(int islocal) f = open(timeserver, ORDWR); if(f < 0) return; - if(mount(f, "/n/boot", MREPL, "", sauth) < 0) - if(mount(f, "/n/boot", MREPL, "", "any") < 0){ - close(f); - return; - } + if(mount(f, "/n/boot", MREPL, "") < 0){ +warning("settime mount"); + close(f); + return; + } close(f); if(stat("/n/boot", dirbuf) < 0) fatal("stat"); diff --git a/boot/userpasswd.c b/boot/userpasswd.c index 75a5a0e5200809cd0c6633213c4c88af0882b214..f2b26ff8f42b1d239a173b6e4bdb2108bfb8e77a 100644 --- a/boot/userpasswd.c +++ b/boot/userpasswd.c @@ -8,65 +8,44 @@ char password[NAMELEN]; extern char *sauth; #endif asdf +char *homsg = "can't set user name or key; please reboot"; + /* * get/set user name and password. verify password with auth server. */ void userpasswd(int islocal, Method *mp) { - char key[7]; - char buf[8 + NAMELEN]; - int fd, crfd; + int fd; + char *msg; + char hostkey[DESKEYLEN]; if(*username == 0 || strcmp(username, "none") == 0){ strcpy(username, "none"); outin("user", username, sizeof(username)); } - crfd = fd = -1; + fd = -1; while(strcmp(username, "none") != 0){ getpasswd(password, sizeof password); - passtokey(key, password); - fd = open("#c/key", OWRITE); - if(fd < 0) - fatal("can't open #c/key; please reboot"); - if(write(fd, key, 7) != 7) - fatal("can't write #c/key; please reboot"); - close(fd); - crfd = open("#c/crypt", ORDWR); - if(crfd < 0) - fatal("can't open crypt file"); - write(crfd, "E", 1); + passtokey(hostkey, password); fd = -1; if(islocal) break; - if(mp->auth) - fd = (*mp->auth)(); - if(fd < 0){ - warning("password not checked!"); - break; - } - strncpy(buf+8, username, NAMELEN); - if(read(fd, buf, 8) != 8 - || write(crfd, buf, 8) != 8 - || read(crfd, buf, 8) != 8 - || write(fd, buf, 8 + NAMELEN) != 8 + NAMELEN){ - warning("password not checked!"); + msg = checkkey(mp, username, hostkey); + if(msg == 0) break; - } - if(read(fd, buf, 2) == 2 && buf[0]=='O' && buf[1]=='K') - break; - close(fd); + fprint(2, "?%s\n", msg); outin("user", username, sizeof(username)); } - close(fd); - close(crfd); - - /* set user now that we're sure */ - fd = open("#c/user", OWRITE|OTRUNC); - if(fd >= 0){ - if(write(fd, username, strlen(username)) < 0) - warning("write user name"); + if(fd > 0) close(fd); - }else - warning("open #c/user"); + + /* set host's key */ + if(writefile("#c/key", hostkey, DESKEYLEN) < 0) + fatal(homsg); + + /* set host's owner (and uid of current process) */ + if(writefile("#c/hostowner", username, strlen(username)) < 0) + fatal(homsg); + close(fd); } diff --git a/pc/main.c b/pc/main.c index 51422c346a517ef34a8cc37f0040bedd75aeb26d..4c42eea849e37dc39c09f1b7a9a5d414d7eb61f3 100644 --- a/pc/main.c +++ b/pc/main.c @@ -21,6 +21,15 @@ PCArch *knownarch[] = &generic, }; +/* where b.com leaves configuration info */ +#define BOOTARGS ((char*)(KZERO|1024)) +#define BOOTARGSLEN 1024 +#define MAXCONF 32 + +char *confname[MAXCONF]; +char *confval[MAXCONF]; +int nconf; + void main(void) { @@ -82,6 +91,7 @@ ulong garbage; void init0(void) { + int i; char tstr[32]; u->nerrlab = 0; @@ -102,6 +112,8 @@ init0(void) chandevinit(); if(!waserror()){ + for(i = 0; i < nconf; i++) + ksetenv(confname[i], confval[i]); strcpy(tstr, arch->id); strcat(tstr, " %s"); ksetterm(tstr); @@ -229,6 +241,8 @@ confinit(void) long x, i, j, *l; int pcnt; ulong ktop; + char *cp; + char *line[MAXCONF]; /* * the first 640k is the standard useful memory @@ -284,6 +298,27 @@ confinit(void) conf.topofmem = i*MB; + /* + * parse configuration args from dos file p9rc + */ + cp = BOOTARGS; /* where b.com leaves it's config */ + cp[BOOTARGSLEN-1] = 0; + i = getfields(cp, line, MAXCONF, '\n'); + for(j = 0; j < i; j++){ + cp = strchr(line[j], '\r'); + if(cp) + *cp = 0; + cp = strchr(line[j], '='); + if(cp == 0) + continue; + *cp++ = 0; + if(cp - line[j] >= NAMELEN+1) + *(line[j]+NAMELEN-1) = 0; + confname[nconf] = line[j]; + confval[nconf] = cp; + nconf++; + } + conf.monitor = 1; conf.nproc = 30 + i*5; conf.nswap = conf.nproc*80; diff --git a/port/auth.c b/port/auth.c new file mode 100644 index 0000000000000000000000000000000000000000..239a9ab10990008cc40c63b1edcaa6334e23dd77 --- /dev/null +++ b/port/auth.c @@ -0,0 +1,508 @@ +#include "u.h" +#include "../port/lib.h" +#include "mem.h" +#include "dat.h" +#include "fns.h" +#include "io.h" +#include "../port/error.h" + +typedef struct Crypt Crypt; +struct Crypt +{ + Crypt *next; + Ticket t; + Authenticator a; + char tbuf[TICKETLEN]; /* remote ticket */ +}; + +typedef struct Session Session; +struct Session +{ + Lock; + Crypt *cache; /* cache of tickets */ + char cchal[CHALLEN]; /* client challenge */ + char schal[CHALLEN]; /* server challenge */ + char authid[NAMELEN]; /* server encryption uid */ + char authdom[DOMLEN]; /* server encryption domain */ + ulong cid; /* challenge id */ +}; + +struct +{ + Lock; + Crypt *free; +} cryptalloc; + +char eve[NAMELEN] = "bootes"; +char evekey[DESKEYLEN]; +char hostdomain[DOMLEN]; + +/* + * return true if current user is eve + */ +int +iseve(void) +{ + return strcmp(eve, u->p->user) == 0; +} + +/* + * crypt entries are allocated from a pool rather than allocated using malloc so + * the memory can be protected from reading by devproc. The base and top of the + * crypt arena is stored in palloc for devproc. + */ +Crypt* +newcrypt(void) +{ + Crypt *c; + + lock(&cryptalloc); + if(cryptalloc.free) { + c = cryptalloc.free; + cryptalloc.free = c->next; + unlock(&cryptalloc); + memset(c, 0, sizeof(Crypt)); + return c; + } + + cryptalloc.free = xalloc(sizeof(Crypt)*conf.nproc); + if(cryptalloc.free == 0) + panic("newcrypt"); + + for(c = cryptalloc.free; c < cryptalloc.free+conf.nproc-1; c++) + c->next = c+1; + + palloc.cmembase = (ulong)cryptalloc.free; + palloc.cmemtop = palloc.cmembase+(sizeof(Crypt)*conf.nproc); + unlock(&cryptalloc); + return newcrypt(); +} + +void +freecrypt(Crypt *c) +{ + lock(&cryptalloc); + c->next = cryptalloc.free; + cryptalloc.free = c; + unlock(&cryptalloc); +} + +/* + * return the info received in the session message on this channel. + * if no session message has been exchanged, do it. + */ +long +sysfsession(ulong *arg) +{ + int i, n; + Chan *c; + Fcall *f; + char *buf; + Crypt *cp; + Session *s; + Ticketreq tr; + + validaddr(arg[1], TICKREQLEN, 1); + f = malloc(sizeof(Fcall)); + if(f == 0) + error(Enomem); + buf = malloc(MAXMSG); + if(buf == 0){ + free(f); + error(Enomem); + } + c = fdtochan(arg[0], OWRITE, 0, 1); + s = 0; + if(waserror()) { + if(s) + free(s); + close(c); + free(buf); + free(f); + nexterror(); + } + s = c->session; + if(s == 0){ + /* exchange a session message with the server */ + s = malloc(sizeof(Session)); + if(s == 0) + error(Enomem); + memset(s, 0, sizeof(Session)); + for(i = 0; i < CHALLEN; i++) + s->cchal[i] = nrand(256); + f->type = Tsession; + memmove(f->chal, s->cchal, CHALLEN); + n = convS2M(f, buf); + if((*devtab[c->type].write)(c, buf, n, 0) != n) + error(Emountrpc); + n = (*devtab[c->type].read)(c, buf, MAXMSG, 0); + if(convM2S(buf, f, n) == 0) + error(Emountrpc); + if(f->type == Rsession){ + memmove(s->schal, f->chal, CHALLEN); + memmove(s->authid, f->authid, NAMELEN); + memmove(s->authdom, f->authdom, DOMLEN); + } + s->cid = 0; + c->session = s; + } + + /* + * If server requires no ticket, or user is "none", or a ticket + * is already cached, zero the request type + */ + tr.type = AuthTreq; + if(strcmp(u->p->user, "none") == 0 || c->session->authid[0] == 0) + tr.type = 0; + else for(cp = s->cache; cp; cp = cp->next) + if(strcmp(cp->t.cuid, u->p->user) == 0){ + tr.type = 0; + break; + } + + /* create ticket request */ + memmove(tr.chal, c->session->schal, CHALLEN); + memmove(tr.authid, c->session->authid, NAMELEN); + memmove(tr.authdom, c->session->authdom, DOMLEN); + memmove(tr.uid, u->p->user, NAMELEN); + memmove(tr.hostid, eve, NAMELEN); + convTR2M(&tr, (char*)arg[1]); + + poperror(); + close(c); + free(buf); + free(f); + return 0; +} + +/* + * attach tickets to a session + */ +long +sysfauth(ulong *arg) +{ + Chan *c; + char *ta; + Session *s; + Crypt *cp, *ncp, **l; + char tbuf[2*TICKETLEN]; + + validaddr(arg[1], 2*TICKETLEN, 0); + c = fdtochan(arg[0], OWRITE, 0, 1); + s = c->session; + if(s == 0) + error("fauth must follow fsession"); + cp = newcrypt(); + if(waserror()){ + freecrypt(cp); + nexterror(); + } + + /* ticket supplied, use it */ + ta = (char*)arg[1]; + memmove(tbuf, ta, 2*TICKETLEN); + convM2T(tbuf, &cp->t, evekey); + if(cp->t.num != AuthTc) + error("bad AuthTc in ticket"); + if(strncmp(u->p->user, cp->t.cuid, NAMELEN) != 0) + error("bad uid in ticket"); + if(memcmp(cp->t.chal, s->schal, CHALLEN) != 0) + error("bad chal in ticket"); + memmove(cp->tbuf, tbuf+TICKETLEN, TICKETLEN); + + /* string onto local list, replace old version */ + lock(s); + l = &s->cache; + for(ncp = s->cache; ncp; ncp = *l){ + if(strcmp(ncp->t.cuid, u->p->user) == 0){ + *l = ncp->next; + freecrypt(ncp); + break; + } + l = &ncp->next; + } + cp->next = s->cache; + s->cache = cp; + unlock(s); + poperror(); + return 0; +} + +/* + * free a session created by fsession + */ +void +freesession(Session *s) +{ + Crypt *cp; + + for(cp = s->cache; cp; cp = cp->next) + freecrypt(cp); + free(s); +} + +/* + * called by mattach() to fill in the Tattach message + */ +ulong +authrequest(Session *s, Fcall *f) +{ + Crypt *cp; + ulong id, dofree; + + /* no authentication if user is "none" or if no ticket required by remote */ + if(s == 0 || s->authid[0] == 0 || strcmp(u->p->user, "none") == 0){ + memset(f->ticket, 0, TICKETLEN); + memset(f->auth, 0, AUTHENTLEN); + return 0; + } + + /* look for ticket in cache */ + dofree = 0; + for(cp = s->cache; cp; cp = cp->next) + if(strcmp(cp->t.cuid, u->p->user) == 0) + break; + if(cp == 0){ + /* + * create a ticket using hostkey, this solves the + * chicken and egg problem + */ + cp = newcrypt(); + cp->t.num = AuthTs; + memmove(cp->t.chal, s->schal, CHALLEN); + memmove(cp->t.cuid, u->p->user, NAMELEN); + memmove(cp->t.suid, u->p->user, NAMELEN); + memmove(cp->t.key, evekey, DESKEYLEN); + convT2M(&cp->t, f->ticket, evekey); + dofree = 1; + } else + memmove(f->ticket, cp->tbuf, TICKETLEN); + lock(s); + id = s->cid++; + unlock(s); + + /* create an authenticator */ + memmove(cp->a.chal, s->schal, CHALLEN); + cp->a.num = AuthAc; + cp->a.id = id; + convA2M(&cp->a, f->auth, cp->t.key); + if(dofree) + freecrypt(cp); + return id; +} + +/* + * called by mattach() to check the Rattach message + */ +void +authreply(Session *s, ulong id, Fcall *f) +{ + Crypt *cp; + + if(s == 0) + return; + + for(cp = s->cache; cp; cp = cp->next) + if(strcmp(cp->t.cuid, u->p->user) == 0) + break; + + /* we're getting around authentication */ + if(s == 0 || cp == 0 || s->authid[0] == 0 || strcmp(u->p->user, "none") == 0) + return; + + convM2A(f->rauth, &cp->a, cp->t.key); + if(cp->a.num != AuthAs){ + print("bad encryption type\n"); + error("server lies"); + } + if(memcmp(cp->a.chal, s->cchal, sizeof(cp->a.chal))){ + print("bad returned challenge\n"); + error("server lies"); + } + if(cp->a.id != id){ + print("bad returned id\n"); + error("server lies"); + } +} + +/* + * called by devcons() for #c/authenticate + * + * The protocol is + * 1) read ticket request from #c/authenticate + * 2) write ticket to #c/authenticate. if it matchs the challenge the + * user is changed to the suid field of the ticket + * 3) read authenticator (to confirm this is the server advertised) + */ +long +authread(Chan *c, char *a, int n) +{ + Crypt *cp; + int i; + Ticketreq tr; + + if(c->aux == 0){ + /* + * first read returns a ticket request + */ + if(n != TICKREQLEN) + error(Ebadarg); + c->aux = newcrypt(); + cp = c->aux; + memset(&tr, 0, sizeof(tr)); + tr.type = AuthTreq; + strcpy(tr.hostid, eve); + strcpy(tr.authid, eve); + strcpy(tr.authdom, hostdomain); + strcpy(tr.uid, u->p->user); + for(i = 0; i < CHALLEN; i++) + tr.chal[i] = nrand(256); + memmove(cp->a.chal, tr.chal, CHALLEN); + convTR2M(&tr, a); + } else { + /* + * subsequent read returns an authenticator + */ + if(n != AUTHENTLEN) + error(Ebadarg); + cp = c->aux; + cp->a.num = AuthAs; + memmove(cp->a.chal, cp->t.chal, CHALLEN); + cp->a.id = 0; + convA2M(&cp->a, a, cp->t.key); + freecrypt(cp); + c->aux = 0; + } + return n; +} + +long +authwrite(Chan *c, char *a, int n) +{ + Crypt *cp; + + if(n != TICKETLEN) + error(Ebadarg); + if(c->aux == 0) + error(Ebadarg); + cp = c->aux; + convM2T(a, &cp->t, evekey); + if(cp->t.num != AuthTs || memcmp(cp->a.chal, cp->t.chal, CHALLEN)) + error(Eperm); + memmove(u->p->user, cp->t.suid, NAMELEN); + return n; +} + +/* + * called by devcons() for #c/authcheck + * + * a write of a ticket+authenticator succeeds if they match + */ +long +authcheck(Chan *c, char *a, int n) +{ + Crypt *cp; + + if(n != TICKETLEN+AUTHENTLEN) + error(Ebadarg); + if(c->aux == 0) + c->aux = newcrypt(); + cp = c->aux; + convM2T(a, &cp->t, evekey); + if(cp->t.num != AuthTc || strcmp(u->p->user, cp->t.cuid)) + error(Ebadarg); + convM2A(a+TICKETLEN, &cp->a, cp->t.key); + if(cp->a.num != AuthAs || memcmp(cp->t.chal, cp->a.chal, CHALLEN)) + error(Eperm); + return n; +} + +void +authclose(Chan *c) +{ + if(c->aux) + freecrypt(c->aux); + c->aux = 0; +} + +/* + * called by devcons() for key device + */ +long +keyread(char *a, int n, long offset) +{ + if(n= NAMELEN) + error(Ebadarg); + if(strcmp(a, "none") != 0) + error(Eperm); + memset(u->p->user, 0, NAMELEN); + strcpy(u->p->user, "none"); + return n; +} + +/* + * called by devcons() for host owner/domain + * + * writing hostowner also sets user + */ +long +hostownerwrite(char *a, int n) +{ + char buf[NAMELEN]; + + if(!iseve()) + error(Eperm); + if(n >= NAMELEN) + error(Ebadarg); + memset(buf, 0, NAMELEN); + strncpy(buf, a, n); + if(buf[0] == 0) + error(Ebadarg); + memmove(eve, buf, NAMELEN); + memmove(u->p->user, buf, NAMELEN); + return n; +} + +long +hostdomainwrite(char *a, int n) +{ + char buf[DOMLEN]; + + if(!iseve()) + error(Eperm); + if(n >= DOMLEN) + error(Ebadarg); + memset(buf, 0, DOMLEN); + strncpy(buf, a, n); + if(buf[0] == 0) + error(Ebadarg); + memmove(hostdomain, buf, DOMLEN); + return n; +} diff --git a/port/chan.c b/port/chan.c index 77d40518efb248a3d2b329b91c0156951fdbfa80..0c849de978476195f78a2612197cfcb0835f19da 100644 --- a/port/chan.c +++ b/port/chan.c @@ -95,6 +95,10 @@ void chanfree(Chan *c) { c->flag = CFREE; + if(c->session){ + freesession(c->session); + c->session = 0; + } lock(&chanalloc); c->next = chanalloc.free; chanalloc.free = c; diff --git a/port/dev.c b/port/dev.c index 6f6365e772d0303d85d5db9f581f5a519561c998..745ff2b88b7d61766f5c54e8d8b1fe939ec673dd 100644 --- a/port/dev.c +++ b/port/dev.c @@ -126,10 +126,8 @@ devstat(Chan *c, char *db, Dirtab *tab, int ntab, Devgen *gen) int i; Dir dir; - for(i=0;; i++) { + for(i=0;; i++) switch((*gen)(c, tab, ntab, i, &dir)){ - case 0: - break; case -1: /* * given a channel, we cannot derive the directory name @@ -137,15 +135,17 @@ devstat(Chan *c, char *db, Dirtab *tab, int ntab, Devgen *gen) * by namec. */ if(c->qid.path & CHDIR){ - devdir(c, c->qid, ".", 0L, eve, CHDIR|0700, &dir); + devdir(c, c->qid, ".", 0L, eve, CHDIR|0775, &dir); convD2M(&dir, db); return; } print("%s %s: devstat %C %lux\n", u->p->text, u->p->user, - devchar[c->type], c->qid.path); + devchar[c->type], c->qid.path); error(Enonexist); + case 0: + break; case 1: - if(eqqid(c->qid, dir.qid)) { + if(eqqid(c->qid, dir.qid)){ if(c->flag&CMSG) dir.mode |= CHMOUNT; convD2M(&dir, db); @@ -153,7 +153,6 @@ devstat(Chan *c, char *db, Dirtab *tab, int ntab, Devgen *gen) } break; } - } } long diff --git a/port/devcons.c b/port/devcons.c index b2514b1b2c58184df2de9d433ad413c6a0ce1dfd..7c424dbf9911c2bcc6552eb921490c63d13ceb7e 100644 --- a/port/devcons.c +++ b/port/devcons.c @@ -21,8 +21,6 @@ KIOQ kbdq; static Ref ctl; /* number of opens to the control file */ static int raw; /* true if raw has been requested on a ctl file */ -char eve[NAMELEN] = "bootes"; -char evekey[DESKEYLEN]; char sysname[NAMELEN]; /* @@ -184,13 +182,8 @@ pprint(char *fmt, ...) return 0; c = u->p->fgrp->fd[2]; - if(c == 0 || (c->mode!=OWRITE && c->mode!=ORDWR)) + if(c==0 || (c->mode!=OWRITE && c->mode!=ORDWR)) return 0; - - /* Can't afford to take an error in notify */ - if(waserror()) - return 0; - n = sprint(buf, "%s %d: ", u->p->text, u->p->pid); n = doprint(buf+n, buf+sizeof(buf), fmt, (&fmt+1)) - buf; @@ -199,7 +192,7 @@ pprint(char *fmt, ...) lock(c); c->offset += n; unlock(c); - poperror(); + return n; } @@ -325,14 +318,16 @@ consactive(void) enum{ Qdir, - Qchal, + Qauth, + Qauthcheck, Qclock, Qcons, Qconsctl, Qcputime, - Qcrypt, Qhz, Qkey, + Qhostdomain, + Qhostowner, Qklog, Qlights, Qmsec, @@ -350,12 +345,14 @@ enum{ }; Dirtab consdir[]={ - "chal", {Qchal}, 8, 0666, + "authenticate", {Qauth}, 0, 0666, + "authcheck", {Qauthcheck}, 0, 0666, "clock", {Qclock}, 2*NUMSIZE, 0444, "cons", {Qcons}, 0, 0660, "consctl", {Qconsctl}, 0, 0220, "cputime", {Qcputime}, 6*NUMSIZE, 0444, - "crypt", {Qcrypt}, 0, 0666, + "hostdomain", {Qhostdomain}, DOMLEN, 0622, + "hostowner", {Qhostowner}, NAMELEN, 0622, "hz", {Qhz}, NUMSIZE, 0666, "key", {Qkey}, DESKEYLEN, 0622, "klog", {Qklog}, 0, 0444, @@ -371,7 +368,7 @@ Dirtab consdir[]={ "sysname", {Qsysname}, 0, 0664, "sysstat", {Qsysstat}, 0, 0666, "time", {Qtime}, NUMSIZE, 0664, - "user", {Quser}, 0, 0666, + "user", {Quser}, NAMELEN, 0664, }; #define NCONS (sizeof consdir/sizeof(Dirtab)) @@ -451,14 +448,14 @@ consstat(Chan *c, char *dp) Chan* consopen(Chan *c, int omode) { + c->aux = 0; switch(c->qid.path){ case Qconsctl: - if(strcmp(u->p->user, eve) != 0) + if(!iseve()) error(Eperm); incref(&ctl); break; } - c->aux = 0; return devopen(c, omode, consdir, NCONS, devgen); } @@ -473,15 +470,18 @@ void consclose(Chan *c) { /* last close of control file turns off raw */ - if(c->qid.path==Qconsctl && (c->flag&COPEN)){ - lock(&ctl); - if(--ctl.ref == 0) - raw = 0; - unlock(&ctl); + switch(c->qid.path){ + case Qconsctl: + if(c->flag&COPEN){ + lock(&ctl); + if(--ctl.ref == 0) + raw = 0; + unlock(&ctl); + } + case Qauth: + case Qauthcheck: + authclose(c); } - if(c->qid.path == Qcrypt && c->aux) - free(c->aux); - c->aux = 0; } long @@ -490,7 +490,7 @@ consread(Chan *c, void *buf, long n, ulong offset) int ch, i, k, id; ulong l; char *cbuf = buf; - char *chal, *b, *bp, *cb; + char *b, *bp; char tmp[128]; /* must be >= 6*NUMSIZE */ Mach *mp; @@ -591,34 +591,17 @@ consread(Chan *c, void *buf, long n, ulong offset) memmove(buf, tmp+k, n); return n; - case Qcrypt: - cb = c->aux; - if(!cb) - return 0; - if(n > MAXCRYPT) - n = MAXCRYPT; - memmove(buf, &cb[1], n); - return n; + case Qkey: + return keyread(buf, n, offset); - case Qchal: - if(offset!=0 || n!=8) - error(Ebadarg); - chal = u->p->pgrp->crypt->chal; - chal[0] = RXschal; - for(i=1; ip->user, eve)!=0 || !cpuserver) - error(Eperm); - memmove(buf, evekey, DESKEYLEN); - return n; + case Qhostowner: + return readstr(offset, buf, n, eve); + + case Qhostdomain: + return readstr(offset, buf, n, hostdomain); case Quser: return readstr(offset, buf, n, u->p->user); @@ -742,7 +725,7 @@ conswrite(Chan *c, void *va, long n, ulong offset) char cbuf[64]; char buf[256]; long l, bp; - char *a = va, *cb; + char *a = va; Mach *mp; int id, fd, ch; Chan *swc; @@ -801,63 +784,23 @@ conswrite(Chan *c, void *va, long n, ulong offset) boottime = strtoul(a, 0, 0)-TK2SEC(MACHP(0)->ticks); break; - case Qcrypt: - cb = c->aux; - if(!cb){ - /* first byte determines whether encrypting or decrypting */ - cb = c->aux = smalloc(MAXCRYPT+1); - cb[0] = 'E'; - } - if(n < 8){ - if(n != 1 || a[0] != 'E' && a[0] != 'D') - error(Ebadarg); - cb[0] = a[0]; - return 1; - } - if(n > MAXCRYPT) - n = MAXCRYPT; - memset(&cb[1], 0, MAXCRYPT); - memmove(&cb[1], a, n); - if(cb[0] == 'E') - encrypt(u->p->pgrp->crypt->key, &cb[1], n); - else - decrypt(u->p->pgrp->crypt->key, &cb[1], n); - break; - case Qkey: - if(n != DESKEYLEN) - error(Ebadarg); - memmove(u->p->pgrp->crypt->key, a, DESKEYLEN); - if(strcmp(u->p->user, eve) == 0) - memmove(evekey, a, DESKEYLEN); - break; + return keywrite(a, n); + + case Qhostowner: + return hostownerwrite(a, n); + + case Qhostdomain: + return hostdomainwrite(a, n); case Quser: - if(offset!=0 || n>=NAMELEN-1) - error(Ebadarg); - strncpy(buf, a, NAMELEN); - if(strcmp(buf, "none")==0 - || strcmp(buf, u->p->user)==0 - || strcmp(u->p->user, eve)==0) - memmove(u->p->user, buf, NAMELEN); - else - error(Eperm); - if(!cpuserver && strcmp(eve, "bootes")==0) - memmove(eve, u->p->user, NAMELEN); - break; + return userwrite(a, n); - case Qchal: - if(offset != 0) - error(Ebadarg); - if(n != 8+NAMELEN+DESKEYLEN) - error(Ebadarg); - decrypt(evekey, a, n); - if(memcmp(u->p->pgrp->crypt->chal, a, 8) != 0) - error(Eperm); - strncpy(u->p->user, a+8, NAMELEN); - u->p->user[NAMELEN-1] = '\0'; - memmove(u->p->pgrp->crypt->key, a+8+NAMELEN, DESKEYLEN); - break; + case Qauth: + return authwrite(c, a, n); + + case Qauthcheck: + return authcheck(c, a, n); case Qnull: break; diff --git a/port/devmnt.c b/port/devmnt.c index ce4c7733cfdcda92301dfbbcdd03beb64fc24f90..09312576998f1e2227091ab47896b5e1a53d21c1 100644 --- a/port/devmnt.c +++ b/port/devmnt.c @@ -48,8 +48,7 @@ struct Mntalloc #define MAXRPC (MAXFDATA+MAXMSG) #define limit(n, max) (n > max ? max : n) -Chan* mattach(Mnt*, char*, char*); -void mntauth(Mnt *, Mntrpc *, char *, ushort); +Chan* mattach(Mnt*, char*); Mnt* mntchk(Chan*); void mntdirfix(uchar*, Chan*); void mntdoclunk(Mnt *, Mntrpc *); @@ -96,7 +95,6 @@ mntattach(char *muxattach) struct bogus{ Chan *chan; char *spec; - char *serv; }bogus; bogus = *((struct bogus *)muxattach); @@ -110,7 +108,7 @@ mntattach(char *muxattach) unlock(&mntalloc); m->ref++; unlock(m); - return mattach(m, bogus.spec, bogus.serv); + return mattach(m, bogus.spec); } unlock(m); } @@ -157,8 +155,14 @@ mntattach(char *muxattach) nexterror(); } - c = mattach(m, bogus.spec, bogus.serv); + c = mattach(m, bogus.spec); + /* + * If exportfs mounts on behalf of a local devmnt, the mount + * point is folded onto the original channel to preserve a single + * fid/tag space. CHDIR is cleared by exportfs to indicate it + * is supplying the mount. + */ mc = m->c; if(mc->type == devno('M', 0) && (c->qid.path&CHDIR) == 0) { c->qid.path |= CHDIR; @@ -174,10 +178,11 @@ mntattach(char *muxattach) } Chan * -mattach(Mnt *m, char *spec, char *serv) +mattach(Mnt *m, char *spec) { Chan *c; Mntrpc *r; + ulong id; r = mntralloc(); c = devattach('M', spec); @@ -193,15 +198,13 @@ mattach(Mnt *m, char *spec, char *serv) nexterror(); } - memset(r->request.auth, 0, sizeof r->request.auth); - if(*serv) - mntauth(m, r, serv, c->fid); - r->request.type = Tattach; r->request.fid = c->fid; memmove(r->request.uname, u->p->user, NAMELEN); strncpy(r->request.aname, spec, NAMELEN); + id = authrequest(m->c->session, &r->request); mountrpc(m, r); + authreply(m->c->session, id, &r->reply); c->qid = r->reply.qid; c->mchan = m->c; @@ -211,43 +214,6 @@ mattach(Mnt *m, char *spec, char *serv) return c; } -void -mntauth(Mnt *m, Mntrpc *f, char *serv, ushort fid) -{ - int i; - Mntrpc *r; - uchar chal[AUTHLEN]; - - r = mntralloc(); - if(waserror()) { - mntfree(r); - return; - } - - r->request.type = Tauth; - r->request.fid = fid; - memmove(r->request.uname, u->p->user, NAMELEN); - chal[0] = FScchal; - for(i = 1; i < AUTHLEN; i++) - chal[i] = nrand(256); - - memmove(r->request.chal, chal, AUTHLEN); - strncpy(r->request.chal+AUTHLEN, serv, NAMELEN); - encrypt(u->p->pgrp->crypt->key, r->request.chal, AUTHLEN+NAMELEN); - - mountrpc(m, r); - - decrypt(u->p->pgrp->crypt->key, r->reply.chal, 2*AUTHLEN+2*DESKEYLEN); - chal[0] = FSctick; - poperror(); - if(memcmp(chal, r->reply.chal, AUTHLEN) != 0) { - mntfree(r); - error(Eperm); - } - memmove(f->request.auth, r->reply.chal+AUTHLEN+DESKEYLEN, AUTHLEN+DESKEYLEN); - mntfree(r); -} - Chan* mntclone(Chan *c, Chan *nc) { diff --git a/port/lib.h b/port/lib.h index 7fb60d78ee73741c8d4a43825a84d82147c532ca..cd609ec01d1aba4c7fd45060af2554b6f40bfbe8 100644 --- a/port/lib.h +++ b/port/lib.h @@ -99,7 +99,6 @@ typedef struct Waitmsg Waitmsg; #define ERRLEN 64 #define DIRLEN 116 #define NAMELEN 28 -#define DESKEYLEN 7 struct Qid { diff --git a/port/net.c b/port/net.c index 0d9728108bfd192853e7fb2aefc0a7764d7de56f..8fa71304d8735383518771937413685f63c8d001 100644 --- a/port/net.c +++ b/port/net.c @@ -136,34 +136,7 @@ netwalk(Chan *c, char *name, Network *np) void netstat(Chan *c, char *db, Network *np) { - int i; - Dir dir; - - for(i=0;; i++) - switch(netgen(c, (Dirtab*)np, 0, i, &dir)){ - case -1: - /* - * devices with interesting directories usually don't get - * here, which is good because we've lost the name by now. - */ - if(c->qid.path & CHDIR){ - devdir(c, c->qid, ".", 0L, eve, CHDIR|0555, &dir); - convD2M(&dir, db); - return; - } - print("netstat %C %lux\n", devchar[c->type], c->qid.path); - error(Enonexist); - case 0: - break; - case 1: - if(eqqid(c->qid, dir.qid)){ - if(c->flag&CMSG) - dir.mode |= CHMOUNT; - convD2M(&dir, db); - return; - } - break; - } + devstat(c, db, (Dirtab*)np, 1, netgen); } Chan * diff --git a/port/pgrp.c b/port/pgrp.c index f0138c5899a2636605bc3891c772f20c6d17f682..eb2a4fb59b3a4684756fa9522a8f533b7823ecdc 100644 --- a/port/pgrp.c +++ b/port/pgrp.c @@ -8,52 +8,6 @@ static Ref pgrpid; static Ref mountid; -struct -{ - Lock; - Crypt *free; -} cryptalloc; - -/* - * crypt entries are allocated from a pool rather than allocated using malloc so - * the memory can be protected from reading by devproc. The base and top of the - * crypt arena is stored in palloc for devproc. - */ -Crypt* -newcrypt(void) -{ - Crypt *c; - - lock(&cryptalloc); - if(cryptalloc.free) { - c = cryptalloc.free; - cryptalloc.free = c->next; - unlock(&cryptalloc); - return c; - } - - cryptalloc.free = xalloc(sizeof(Crypt)*conf.nproc); - if(cryptalloc.free == 0) - panic("newcrypt"); - - for(c = cryptalloc.free; c < cryptalloc.free+conf.nproc-1; c++) - c->next = c+1; - - palloc.cmembase = (ulong)cryptalloc.free; - palloc.cmemtop = palloc.cmembase+(sizeof(Crypt)*conf.nproc); - unlock(&cryptalloc); - return newcrypt(); -} - -void -freecrypt(Crypt *c) -{ - lock(&cryptalloc); - c->next = cryptalloc.free; - cryptalloc.free = c; - unlock(&cryptalloc); -} - void pgrpnote(ulong noteid, char *a, long n, int flag) { @@ -92,7 +46,6 @@ newpgrp(void) p = smalloc(sizeof(Pgrp)); p->ref = 1; - p->crypt = newcrypt(); p->pgrpid = incref(&pgrpid); return p; } @@ -116,7 +69,6 @@ closepgrp(Pgrp *p) } } qunlock(&p->debug); - freecrypt(p->crypt); free(p); } } @@ -129,7 +81,6 @@ pgrpcpy(Pgrp *to, Pgrp *from) rlock(&from->ns); - *to->crypt = *from->crypt; e = &from->mnthash[MNTHASH]; tom = to->mnthash; for(h = from->mnthash; h < e; h++) { diff --git a/port/portdat.h b/port/portdat.h index a4e9323696208185f662e948b4ef3f12ef786df7..29ae6b93ed5dd47da1cb2ce3fa52b7d3dbc98051 100644 --- a/port/portdat.h +++ b/port/portdat.h @@ -2,7 +2,6 @@ typedef struct Alarms Alarms; typedef struct Block Block; typedef struct Blist Blist; typedef struct Chan Chan; -typedef struct Crypt Crypt; typedef struct Dev Dev; typedef struct Dirtab Dirtab; typedef struct Egrp Egrp; @@ -34,6 +33,7 @@ typedef struct Ref Ref; typedef struct Rendez Rendez; typedef struct RWlock RWlock; typedef struct Sargs Sargs; +typedef struct Session Session; typedef struct Scsi Scsi; typedef struct Scsibuf Scsibuf; typedef struct Scsidata Scsidata; @@ -47,7 +47,8 @@ typedef void Streamopen(Queue*, Stream*); typedef void Streamclose(Queue*); typedef void Streamreset(void); -#include "fcall.h" +#include +#include struct Ref { @@ -171,13 +172,7 @@ struct Chan }; Chan *mchan; /* channel to mounted server */ Qid mqid; /* qid of root of mount point */ -}; - -struct Crypt -{ - char key[DESKEYLEN]; /* des encryption key */ - char chal[8]; /* challenge for setting user name */ - Crypt *next; + Session *session; }; struct Dev @@ -453,7 +448,6 @@ struct Pgrp Ref; /* also used as a lock when mounting */ Pgrp *next; /* free list */ ulong pgrpid; - Crypt *crypt; /* encryption key and challenge */ QLock debug; /* single access via devproc.c */ RWlock ns; /* Namespace many read/one write lock */ Mhead *mnthash[MNTHASH]; @@ -746,6 +740,7 @@ extern int cpuserver; extern Rune* devchar; extern Dev devtab[]; extern char eve[]; +extern char hostdomain[]; extern uchar initcode[]; extern FPsave initfp; extern KIOQ kbdq; @@ -783,8 +778,6 @@ enum RXschal = 0, RXstick = 1, - - AUTHLEN = 8, }; /* diff --git a/port/portfns.h b/port/portfns.h index 782dff32e3b20d66782945d523d4c907c22765c9..5ae0993e909439ed9dbcd6ffb22b63abd1427656 100644 --- a/port/portfns.h +++ b/port/portfns.h @@ -2,6 +2,12 @@ void alarmkproc(void*); Block* allocb(ulong); int anyready(void); Image* attachimage(int, Chan*, ulong, ulong); +long authcheck(Chan*, char*, int); +void authclose(Chan*); +long authread(Chan*, char*, int); +ulong authrequest(Session*, Fcall*); +void authreply(Session*, ulong, Fcall*); +long authwrite(Chan*, char*, int); void bitdebug(void); void bitdepth(void); void bitreverse(uchar*, int); @@ -75,6 +81,7 @@ int freebroken(void); void freechan(Chan*); void freepte(Segment*, Pte*); void freesegs(int); +void freesession(Session*); Block* getb(Blist*); int getc(IOQ*); void getcolor(ulong, ulong*, ulong*, ulong*); @@ -84,6 +91,8 @@ int gets(IOQ*, void*, int); void gotolabel(Label*); Block* grabq(Queue*); int haswaitq(void*); +long hostdomainwrite(char*, int); +long hostownerwrite(char*, int); int hwcursmove(int, int); int hwcursset(uchar*, uchar*, int, int); long ibrk(ulong, int); @@ -93,11 +102,14 @@ void initscsi(void); void initseg(void); void invalidateu(void); void isdir(Chan*); +int iseve(void); int ispages(void*); void kbdclock(void); int kbdcr2nl(IOQ*, int); int kbdputc(IOQ*, int); void kbdrepeat(int); +long keyread(char*, int, long); +long keywrite(char*, int); void kickpager(void); int kprint(char*, ...); void kproc(char*, void(*)(void*), void*); @@ -266,6 +278,7 @@ void unmount(Chan*, Chan*); void urpfillstats(Chan*, char*, int); void userinit(void); ulong userpc(void); +long userwrite(char*, int); void validaddr(ulong, ulong, int); void* vmemchr(void*, int, int); void wakeup(Rendez*); diff --git a/port/stfcall.c b/port/stfcall.c index 54d3a24263b6995e16306c557f3cd78ef2a5784a..aa8f67605e235ab3b8a03773eb9febedd88de965 100644 --- a/port/stfcall.c +++ b/port/stfcall.c @@ -24,14 +24,14 @@ static uchar msglen[256] = { [Tnop] 3, [Rnop] 3, - [Tsession] 3, - [Rsession] 3, + [Tsession] 3+CHALLEN, + [Rsession] 3+NAMELEN+DOMLEN+CHALLEN, [Terror] 0, [Rerror] 67, [Tflush] 5, [Rflush] 3, - [Tattach] 89, - [Rattach] 13, + [Tattach] 5+2*NAMELEN+TICKETLEN+AUTHENTLEN, + [Rattach] 13+AUTHENTLEN, [Tclone] 7, [Rclone] 5, [Twalk] 33, @@ -54,8 +54,6 @@ static uchar msglen[256] = [Rwstat] 5, [Tclwalk] 35, [Rclwalk] 13, - [Tauth] 69, - [Rauth] 35, }; static void diff --git a/port/sysfile.c b/port/sysfile.c index 2d9232ffea533bb385c36e77f5a9994d4072011f..86c5cfb6c2f4ea1b0376c5e8e0d053b6221293c6 100644 --- a/port/sysfile.c +++ b/port/sysfile.c @@ -84,13 +84,6 @@ openmode(ulong o) return o; } -long -sysfsession(ulong *arg) -{ - USED(arg); - return 0; -} - long syspipe(ulong *arg) { @@ -442,7 +435,6 @@ bindmount(ulong *arg, int ismount) struct{ Chan *chan; char *spec; - char *serv; }bogus; flag = arg[2]; @@ -462,11 +454,7 @@ bindmount(ulong *arg, int ismount) error(Ebadarg); bogus.spec = (char*)arg[3]; - validaddr(arg[4], 1, 0); - if(vmemchr((char*)arg[4], '\0', NAMELEN) == 0) - error(Ebadarg); - bogus.serv = (char*)arg[4]; ret = devno('M', 0); c0 = (*devtab[ret].attach)((char*)&bogus); diff --git a/port/sysproc.c b/port/sysproc.c index 3c763f9ab594dfb4032c88db444fbf094de7ab3f..9359e40cc674e06dab790f34186c1ae7dc69133c 100644 --- a/port/sysproc.c +++ b/port/sysproc.c @@ -42,8 +42,6 @@ sysrfork(ulong *arg) p->pgrp = newpgrp(); if(flag & RFNAMEG) pgrpcpy(p->pgrp, opg); - else - *p->pgrp->crypt = *opg->crypt; closepgrp(opg); } if(flag & (RFENVG|RFCENVG)) { @@ -126,8 +124,6 @@ sysrfork(ulong *arg) p->pgrp = newpgrp(); if(flag & RFNAMEG) pgrpcpy(p->pgrp, parent->pgrp); - else - *p->pgrp->crypt = *parent->pgrp->crypt; } else { p->pgrp = parent->pgrp; diff --git a/port/systab.h b/port/systab.h index fd9e53c1fde7ca8c20a23428b741cf7a636b646d..50d0116d0475d388ccfcab277327a96f5b51e4a6 100644 --- a/port/systab.h +++ b/port/systab.h @@ -13,7 +13,7 @@ Syscall sysalarm; Syscall sysexec; Syscall sysexits; Syscall sysfsession; -Syscall sys_x2; +Syscall sysfauth; Syscall sysfstat; Syscall syssegbrk; Syscall sysmount; @@ -53,7 +53,7 @@ Syscall *systab[]={ [EXEC] sysexec, [EXITS] sysexits, [FSESSION] sysfsession, - [_X2] sysdeath, + [FAUTH] sysfauth, [FSTAT] sysfstat, [SEGBRK] syssegbrk, [MOUNT] sysmount, @@ -93,7 +93,7 @@ char *sysctab[]={ [EXEC] "Exec", [EXITS] "Exits", [FSESSION] "Fsession", - [_X2] "_x2", + [FAUTH] "Fauth", [FSTAT] "Fstat", [SEGBRK] "Segbrk", [MOUNT] "Mount",