]> git.lizzy.rs Git - plan9front.git/blobdiff - sys/src/cmd/cwfs/auth.c
merge
[plan9front.git] / sys / src / cmd / cwfs / auth.c
index 4fba59ca835064a0ecf88d26139f07e68abf3f7e..e3d51be7e383d4ff6d4d9959ac4509c76c0aac8f 100644 (file)
@@ -1,6 +1,7 @@
 #include "all.h"
 #include "io.h"
 #include <authsrv.h>
+#include <auth.h>
 
 Nvrsafe        nvr;
 
@@ -15,7 +16,6 @@ nvrgetconfig(void)
 /*
  * we shouldn't be writing nvram any more.
  * the secstore/config field is now just secstore key.
- * we still use authid, authdom and machkey for authentication.
  */
 
 int
@@ -24,16 +24,18 @@ nvrcheck(void)
        uchar csum;
 
        if (readnvram(&nvr, NVread) < 0) {
-               print("nvrcheck: can't read nvram\n");
+               fprint(2, "nvrcheck: can't read nvram\n");
                return 1;
        } else
                gotnvr = 1;
-       print("nvr read\n");
+
+       if(chatty)
+               print("nvr read\n");
 
        csum = nvcsum(nvr.machkey, sizeof nvr.machkey);
        if(csum != nvr.machsum) {
-               print("\n\n ** NVR key checksum is incorrect  **\n");
-               print(" ** set password to allow attaches **\n\n");
+               fprint(2, "\n\n ** NVR key checksum is incorrect  **\n");
+               fprint(2, " ** set password to allow attaches **\n\n");
                memset(nvr.machkey, 0, sizeof nvr.machkey);
                return 1;
        }
@@ -83,244 +85,103 @@ conslock(void)
        return 1;
 }
 
-/*
- *  authentication specific to 9P2000
- */
-
-/* authentication states */
-enum
-{
-       HaveProtos=1,
-       NeedProto,
-       HaveOK,
-       NeedCchal,
-       HaveSinfo,
-       NeedTicket,
-       HaveSauthenticator,
-       SSuccess,
-};
-
-char *phasename[] =
-{
-[HaveProtos]   "HaveProtos",
-[NeedProto]    "NeedProto",
-[HaveOK]       "HaveOK",
-[NeedCchal]    "NeedCchal",
-[HaveSinfo]    "HaveSinfo",
-[NeedTicket]   "NeedTicket",
-[HaveSauthenticator]   "HaveSauthenticator",
-[SSuccess]     "SSuccess",
-};
+static char *keyspec = "proto=p9any role=server";
 
-/* authentication structure */
-struct Auth
+void*
+authnew(void)
 {
-       int     inuse;
-       char    uname[NAMELEN]; /* requestor's remote user name */
-       char    aname[NAMELEN]; /* requested aname */
-       Userid  uid;            /* uid decided on */
-       int     phase;
-       char    cchal[CHALLEN];
-       char    tbuf[TICKETLEN+AUTHENTLEN];     /* server ticket */
-       Ticket  t;
-       Ticketreq tr;
-};
+       AuthRpc *rpc;
+       int fd;
 
-Auth*  auths;
-Lock   authlock;
-
-void
-authinit(void)
-{
-       auths = malloc(conf.nauth * sizeof(*auths));
-}
-
-static int
-failure(Auth *s, char *why)
-{
-       int i;
-
-if(*why)print("authentication failed: %s: %s\n", phasename[s->phase], why);
-       srand((uintptr)s + time(nil));
-       for(i = 0; i < CHALLEN; i++)
-               s->tr.chal[i] = nrand(256);
-       s->uid = -1;
-       strncpy(s->tr.authid, nvr.authid, NAMELEN);
-       strncpy(s->tr.authdom, nvr.authdom, DOMLEN);
-       memmove(s->cchal, s->tr.chal, sizeof(s->cchal));
-       s->phase = HaveProtos;
-       return -1;
-}
-
-Auth*
-authnew(char *uname, char *aname)
-{
-       static int si = 0;
-       int i, nwrap;
-       Auth *s;
-
-       i = si;
-       nwrap = 0;
-       for(;;){
-               if(i < 0 || i >= conf.nauth){
-                       if(++nwrap > 1)
-                               return nil;
-                       i = 0;
-               }
-               s = &auths[i++];
-               if(s->inuse)
-                       continue;
-               lock(&authlock);
-               if(s->inuse == 0){
-                       s->inuse = 1;
-                       strncpy(s->uname, uname, NAMELEN-1);
-                       strncpy(s->aname, aname, NAMELEN-1);
-                       failure(s, "");
-                       si = i;
-                       unlock(&authlock);
-                       break;
-               }
-               unlock(&authlock);
+       if(access("/mnt/factotum", 0) < 0)
+               if((fd = open("/srv/factotum", ORDWR)) >= 0)
+                       mount(fd, -1, "/mnt", MBEFORE, "");
+       if((fd = open("/mnt/factotum/rpc", ORDWR)) < 0)
+               return nil;
+       if((rpc = auth_allocrpc(fd)) == nil){
+               close(fd);
+               return nil;
+       }
+       if(auth_rpc(rpc, "start", keyspec, strlen(keyspec)) != ARok){
+               authfree(rpc);
+               return nil;
        }
-       return s;
+       return rpc;
 }
 
 void
-authfree(Auth *s)
-{
-       if(s != nil)
-               s->inuse = 0;
-}
-
-int
-authread(File* file, uchar* data, int n)
+authfree(void *auth)
 {
-       Auth *s;
-       int m;
-
-       s = file->auth;
-       if(s == nil)
-               return -1;
+       AuthRpc *rpc;
 
-       switch(s->phase){
-       default:
-               return failure(s, "unexpected phase");
-       case HaveProtos:
-               m = snprint((char*)data, n, "v.2 p9sk1@%s", nvr.authdom) + 1;
-               s->phase = NeedProto;
-               break;
-       case HaveOK:
-               m = 3;
-               if(n < m)
-                       return failure(s, "read too short");
-               strcpy((char*)data, "OK");
-               s->phase = NeedCchal;
-               break;
-       case HaveSinfo:
-               m = TICKREQLEN;
-               if(n < m)
-                       return failure(s, "read too short");
-               convTR2M(&s->tr, (char*)data);
-               s->phase = NeedTicket;
-               break;
-       case HaveSauthenticator:
-               m = AUTHENTLEN;
-               if(n < m)
-                       return failure(s, "read too short");
-               memmove(data, s->tbuf+TICKETLEN, m);
-               s->phase = SSuccess;
-               break;
+       if(rpc = auth){
+               close(rpc->afd);
+               auth_freerpc(rpc);
        }
-       return m;
 }
 
 int
-authwrite(File* file, uchar *data, int n)
+authread(File *file, uchar *data, int count)
 {
-       Auth *s;
-       int m;
-       char *p, *d;
-       Authenticator a;
+       AuthInfo *ai;
+       AuthRpc *rpc;
+       Chan *chan;
 
-       s = file->auth;
-       if(s == nil)
+       chan = file->cp;
+       if((rpc = file->auth) == nil){
+               snprint(chan->err, sizeof(chan->err),
+                       "not an auth fid");
                return -1;
+       }
 
-       switch(s->phase){
+       switch(auth_rpc(rpc, "read", nil, 0)){
        default:
-               return failure(s, "unknown phase");
-       case NeedProto:
-               p = (char*)data;
-               if(p[n-1] != 0)
-                       return failure(s, "proto missing terminator");
-               d = strchr(p, ' ');
-               if(d == nil)
-                       return failure(s, "proto missing separator");
-               *d++ = 0;
-               if(strcmp(p, "p9sk1") != 0)
-                       return failure(s, "unknown proto");
-               if(strcmp(d, nvr.authdom) != 0)
-                       return failure(s, "unknown domain");
-               s->phase = HaveOK;
-               m = n;
-               break;
-       case NeedCchal:
-               m = CHALLEN;
-               if(n < m)
-                       return failure(s, "client challenge too short");
-               memmove(s->cchal, data, sizeof(s->cchal));
-               s->phase = HaveSinfo;
-               break;
-       case NeedTicket:
-               m = TICKETLEN+AUTHENTLEN;
-               if(n < m)
-                       return failure(s, "ticket+auth too short");
-
-               convM2T((char*)data, &s->t, nvr.machkey);
-               if(s->t.num != AuthTs
-               || memcmp(s->t.chal, s->tr.chal, sizeof(s->t.chal)) != 0)
-                       return failure(s, "bad ticket");
-
-               convM2A((char*)data+TICKETLEN, &a, s->t.key);
-               if(a.num != AuthAc
-               || memcmp(a.chal, s->tr.chal, sizeof(a.chal)) != 0
-               || a.id != 0)
-                       return failure(s, "bad authenticator");
-
-               /* at this point, we're convinced */
-               s->uid = strtouid(s->t.suid);
-               if(s->uid < 0)
-                       return failure(s, "unknown user");
-               if(cons.flags & authdebugflag)
-                       print("user %s = %d authenticated\n",
-                               s->t.suid, s->uid);
-
-               /* create an authenticator to send back */
-               a.num = AuthAs;
-               memmove(a.chal, s->cchal, sizeof(a.chal));
-               a.id = 0;
-               convA2M(&a, s->tbuf+TICKETLEN, s->t.key);
-
-               s->phase = HaveSauthenticator;
-               break;
+               snprint(chan->err, sizeof(chan->err),
+                       "authread: auth protocol not finished");
+               return -1;
+       case ARdone:
+               if((ai = auth_getinfo(rpc)) == nil)
+                       goto Phase;
+               file->uid = strtouid(ai->cuid);
+               if(file->uid < 0){
+                       snprint(chan->err, sizeof(chan->err),
+                               "unknown user '%s'", ai->cuid);
+                       auth_freeAI(ai);
+                       return -1;
+               }
+               auth_freeAI(ai);
+               return 0;
+       case ARok:
+               if(count < rpc->narg){
+                       snprint(chan->err, sizeof(chan->err),
+                               "not enough data in auth read");
+                       return -1;
+               }
+               memmove(data, rpc->arg, rpc->narg);
+               return rpc->narg;
+       case ARphase:
+       Phase:
+               rerrstr(chan->err, sizeof(chan->err));
+               return -1;
        }
-       return m;
 }
 
 int
-authuid(Auth* s)
+authwrite(File *file, uchar *data, int count)
 {
-       return s->uid;
-}
+       AuthRpc *rpc;
+       Chan *chan;
 
-char*
-authaname(Auth* s)
-{
-       return s->aname;
+       chan = file->cp;
+       if((rpc = file->auth) == nil){
+               snprint(chan->err, sizeof(chan->err),
+                       "not an auth fid");
+               return -1;
+       }
+       if(auth_rpc(rpc, "write", data, count) != ARok){
+               rerrstr(chan->err, sizeof(chan->err));
+               return -1;
+       }
+       return count;
 }
 
-char*
-authuname(Auth* s)
-{
-       return s->uname;
-}