/* * Network listening authentication. * This and all the other network-related * code is due to Richard Miller. */#include "all.h"#include "9p1.h"int allownone;Nvrsafe nvr;int didread;/* * create a challenge for a fid space */voidmkchallenge(Chan *cp){ int i; if(!didread && readnvram(&nvr, 0) >= 0) didread = 1; srand(truerand()); for(i = 0; i < CHALLEN; i++) cp->chal[i] = nrand(256); cp->idoffset = 0; cp->idvec = 0;}/* * match a challenge from an attach */Nvrsafe nvr;intauthorize(Chan *cp, Oldfcall *in, Oldfcall *ou){ Ticket t; Authenticator a; int x; ulong bit; if (cp == cons.srvchan) /* local channel already safe */ return 1; if(wstatallow) /* set to allow entry during boot */ return 1; if(strcmp(in->uname, "none") == 0) return allownone || cp->authed; if(in->type == Toattach9p1) return 0; if(!didread) return 0; /* decrypt and unpack ticket */ convM2T(in->ticket, &t, nvr.machkey); if(t.num != AuthTs){print("bad AuthTs num\n"); return 0; } /* decrypt and unpack authenticator */ convM2A(in->auth, &a, t.key); if(a.num != AuthAc){print("bad AuthAc num\n"); return 0; } /* challenges must match */ if(memcmp(a.chal, cp->chal, sizeof(a.chal)) != 0){print("bad challenge\n"); return 0; } /* * the id must be in a valid range. the range is specified by a * lower bount (idoffset) and a bit vector (idvec) where a * bit set to 1 means unusable */ lock(&cp->idlock); x = a.id - cp->idoffset; bit = 1<<x; if(x < 0 || x > 31 || (bit&cp->idvec)){ unlock(&cp->idlock); return 0; } cp->idvec |= bit; /* normalize the vector */ while(cp->idvec&0xffff0001){ cp->idvec >>= 1; cp->idoffset++; } unlock(&cp->idlock); /* ticket name and attach name must match */ if(memcmp(in->uname, t.cuid, sizeof(in->uname)) != 0){print("names don't match\n"); return 0; } /* copy translated name into input record */ memmove(in->uname, t.suid, sizeof(in->uname)); /* craft a reply */ a.num = AuthAs; memmove(a.chal, cp->rchal, CHALLEN); convA2M(&a, ou->rauth, t.key); cp->authed = 1; return 1;}
/*
* Network listening authentication.
* This and all the other network-related
* code is due to Richard Miller.
*/
#include "all.h"
#include "9p1.h"
int allownone;
Nvrsafe nvr;
int didread;
/*
* create a challenge for a fid space
*/
void
mkchallenge(Chan *cp)
{
int i;
if(!didread && readnvram(&nvr, 0) >= 0)
didread = 1;
srand(truerand());
for(i = 0; i < CHALLEN; i++)
cp->chal[i] = nrand(256);
cp->idoffset = 0;
cp->idvec = 0;
}
/*
* match a challenge from an attach
*/
Nvrsafe nvr;
int
authorize(Chan *cp, Oldfcall *in, Oldfcall *ou)
{
Ticket t;
Authenticator a;
int x;
ulong bit;
if (cp == cons.srvchan) /* local channel already safe */
return 1;
if(wstatallow) /* set to allow entry during boot */
return 1;
if(strcmp(in->uname, "none") == 0)
return allownone || cp->authed;
if(in->type == Toattach9p1)
return 0;
if(!didread)
return 0;
/* decrypt and unpack ticket */
convM2T(in->ticket, &t, nvr.machkey);
if(t.num != AuthTs){
print("bad AuthTs num\n");
return 0;
}
/* decrypt and unpack authenticator */
convM2A(in->auth, &a, t.key);
if(a.num != AuthAc){
print("bad AuthAc num\n");
return 0;
}
/* challenges must match */
if(memcmp(a.chal, cp->chal, sizeof(a.chal)) != 0){
print("bad challenge\n");
return 0;
}
/*
* the id must be in a valid range. the range is specified by a
* lower bount (idoffset) and a bit vector (idvec) where a
* bit set to 1 means unusable
*/
lock(&cp->idlock);
x = a.id - cp->idoffset;
bit = 1<<x;
if(x < 0 || x > 31 || (bit&cp->idvec)){
unlock(&cp->idlock);
return 0;
}
cp->idvec |= bit;
/* normalize the vector */
while(cp->idvec&0xffff0001){
cp->idvec >>= 1;
cp->idoffset++;
}
unlock(&cp->idlock);
/* ticket name and attach name must match */
if(memcmp(in->uname, t.cuid, sizeof(in->uname)) != 0){
print("names don't match\n");
return 0;
}
/* copy translated name into input record */
memmove(in->uname, t.suid, sizeof(in->uname));
/* craft a reply */
a.num = AuthAs;
memmove(a.chal, cp->rchal, CHALLEN);
convA2M(&a, ou->rauth, t.key);
cp->authed = 1;
return 1;
}