#include "all.h"
#include "io.h"
#include <authsrv.h>
+#include <auth.h>
Nvrsafe nvr;
/*
* 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
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;
}
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;
-}