#include "u.h" #include "../port/lib.h" #include "mem.h" #include "dat.h" #include "fns.h" #include "../port/error.h" #include char *eve; char evekey[DESKEYLEN]; char hostdomain[DOMLEN]; /* * return true if current user is eve */ int iseve(void) { return strcmp(eve, up->user) == 0; } long sysfversion(ulong *arg) { Fcall f; /* two Fcalls should be big enough for reply */ uchar *msg; char *vers; uint arglen, n, m, msize; Chan *c; uvlong oo; msize = arg[1]; vers = (char*)arg[2]; arglen = arg[3]; validaddr(arg[2], arglen, 1); /* check there's a NUL in the version string */ if(memchr(vers, 0, arglen) == 0) error(Ebadarg); c = fdtochan(arg[0], ORDWR, 0, 1); if(waserror()){ cclose(c); nexterror(); } if((c->flag&CMSG) && c->version!=nil) /* BUG: insufficient; should check compatibility */ goto Return; f.type = Tversion; f.tag = NOTAG; if(msize == 0) msize = IOHDRSZ+8192; /* reasonable default */ f.msize = msize; if(vers[0] == '\0') vers = VERSION9P; f.version = vers; msg = smalloc(8192+IOHDRSZ); if(waserror()){ free(msg); nexterror(); } n = convS2M(&f, msg, 8192+IOHDRSZ); if(n == 0) error("bad fversion conversion on send"); lock(c); oo = c->offset; c->offset += n; unlock(c); m = devtab[c->type]->write(c, msg, n, oo); if(m < n){ lock(c); c->offset -= n - m; unlock(c); error("short write in fversion"); } /* message sent; receive and decode reply */ m = devtab[c->type]->read(c, msg, 8192+IOHDRSZ, c->offset); if(m <= 0) error("EOF receiving fversion reply"); lock(c); c->offset += m; unlock(c); n = convM2S(msg, m, &f); if(n != m) error("bad fversion conversion on reply"); if(f.type != Rversion) error("unexpected reply type in fversion"); if(f.msize > msize) error("server tries to increase msize in fversion"); if(f.msize<256 || f.msize>1024*1024) error("nonsense value of msize in fversion"); kstrdup(&c->version, f.version); c->iounit = f.msize; free(msg); poperror(); Return: m = strlen(c->version); if(m > arglen) m = arglen; memmove((char*)arg[2], c->version, m); cclose(c); poperror(); return m; } long sysfsession(ulong *arg) { Fcall f; uchar *msg; uint authlen, n, m; Chan *c; uvlong oo; //BUG print("warning: stub fsession being used\n"); authlen = arg[2]; validaddr(arg[1], authlen, 1); c = fdtochan(arg[0], ORDWR, 0, 1); if(waserror()){ cclose(c); nexterror(); } if(c->flag & CMSG){ //BUG what to do? ((uchar*)arg[1])[0] = 0; poperror(); cclose(c); return 0; } f.type = Tsession; f.tag = NOTAG; f.nchal = 0; f.chal = (uchar*)""; msg = smalloc(8192+IOHDRSZ); if(waserror()){ free(msg); nexterror(); } n = convS2M(&f, msg, 8192+IOHDRSZ); if(n == 0) error("bad fsession conversion on send"); lock(c); oo = c->offset; c->offset += n; unlock(c); m = devtab[c->type]->write(c, msg, n, oo); if(m < n){ lock(c); c->offset -= n - m; unlock(c); error("short write in fsession"); } /* message sent; receive and decode reply */ m = devtab[c->type]->read(c, msg, 8192+IOHDRSZ, c->offset); if(m <= 0) error("EOF receiving fsession reply"); lock(c); c->offset += m; unlock(c); n = convM2S(msg, m, &f); if(n != m) error("bad fsession conversion on reply"); if(f.type != Rsession) error("unexpected reply type in fsession"); m = f.nchal; if(m > authlen) error(Eshort); //BUG print("auth stuff ignored; noauth by default\n"); ((uchar*)arg[1])[0] = 0; free(msg); poperror(); poperror(); cclose(c); return m; } long sysfauth(ulong *) { error("sysfauth unimplemented"); return -1; } /* * called by devcons() for key device */ long keyread(char *a, int n, long offset) { if(nuser, "none"); up->basepri = PriNormal; return n; } /* * called by devcons() for host owner/domain * * writing hostowner also sets user */ long hostownerwrite(char *a, int n) { char buf[128]; if(!iseve()) error(Eperm); if(n >= sizeof buf) error(Ebadarg); strncpy(buf, a, n+1); if(buf[0] == '\0') error(Ebadarg); renameuser(eve, buf); kstrdup(&eve, buf); kstrdup(&up->user, buf); up->basepri = PriNormal; 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; }