M boot/aux.c => boot/aux.c +13 -0
@@ 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)
{
M boot/boot.c => boot/boot.c +8 -9
@@ 1,5 1,6 @@
#include <u.h>
#include <libc.h>
+#include <auth.h>
#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" : "");
M boot/boot.h => boot/boot.h +11 -7
@@ 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*);
A boot/doauthenticate.c => boot/doauthenticate.c +114 -0
@@ 0,0 1,114 @@
+#include <u.h>
+#include <libc.h>
+#include <auth.h>
+#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";
+}
M boot/dosboot.c => boot/dosboot.c +3 -3
@@ 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);
M boot/key.c => boot/key.c +50 -27
@@ 3,50 3,73 @@
#include <auth.h>
#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");
}
M boot/nopsession.c => boot/nopsession.c +1 -7
@@ 1,5 1,6 @@
#include <u.h>
#include <libc.h>
+#include <auth.h>
#include <fcall.h>
#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);
-}
M boot/settime.c => boot/settime.c +6 -5
@@ 1,5 1,6 @@
#include <u.h>
#include <libc.h>
+#include <auth.h>
#include <fcall.h>
#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");
M boot/userpasswd.c => boot/userpasswd.c +20 -41
@@ 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);
}
M pc/main.c => pc/main.c +35 -0
@@ 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;
A port/auth.c => port/auth.c +508 -0
@@ 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<DESKEYLEN || offset != 0)
+ error(Ebadarg);
+ if(!iseve())
+ error(Eperm);
+ memmove(a, evekey, DESKEYLEN);
+ return DESKEYLEN;
+}
+
+long
+keywrite(char *a, int n)
+{
+ if(n != DESKEYLEN)
+ error(Ebadarg);
+ if(!iseve())
+ error(Eperm);
+ memmove(evekey, a, DESKEYLEN);
+ return DESKEYLEN;
+}
+
+/*
+ * called by devcons() for user device
+ *
+ * anyone can become none
+ */
+long
+userwrite(char *a, int n)
+{
+ 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;
+}
M port/chan.c => port/chan.c +4 -0
@@ 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;
M port/dev.c => port/dev.c +6 -7
@@ 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
M port/devcons.c => port/devcons.c +48 -105
@@ 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; i<AUTHLEN; i++)
- chal[i] = nrand(256);
- memmove(buf, chal, 8);
- encrypt(evekey, buf, 8);
- chal[0] = RXstick;
- return n;
+ case Qauth:
+ return authread(c, cbuf, n);
- case Qkey:
- if(offset!=0 || n!=DESKEYLEN)
- error(Ebadarg);
- if(strcmp(u->p->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;
M port/devmnt.c => port/devmnt.c +13 -47
@@ 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)
{
M port/lib.h => port/lib.h +0 -1
@@ 99,7 99,6 @@ typedef struct Waitmsg Waitmsg;
#define ERRLEN 64
#define DIRLEN 116
#define NAMELEN 28
-#define DESKEYLEN 7
struct Qid
{
M port/net.c => port/net.c +1 -28
@@ 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 *
M port/pgrp.c => port/pgrp.c +0 -49
@@ 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++) {
M port/portdat.h => port/portdat.h +5 -12
@@ 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 <auth.h>
+#include <fcall.h>
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,
};
/*
M port/portfns.h => port/portfns.h +13 -0
@@ 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*);
M port/stfcall.c => port/stfcall.c +4 -6
@@ 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
M port/sysfile.c => port/sysfile.c +0 -12
@@ 85,13 85,6 @@ openmode(ulong o)
}
long
-sysfsession(ulong *arg)
-{
- USED(arg);
- return 0;
-}
-
-long
syspipe(ulong *arg)
{
int fd[2];
@@ 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);
M port/sysproc.c => port/sysproc.c +0 -4
@@ 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;
M port/systab.h => port/systab.h +3 -3
@@ 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",