## diffname port/auth.c 1993/0330
## diff -e /dev/null /n/bootesdump/1993/0330/sys/src/9/port/auth.c
0a
#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;
}
.
## diffname port/auth.c 1993/0402
## diff -e /n/bootesdump/1993/0330/sys/src/9/port/auth.c /n/bootesdump/1993/0402/sys/src/9/port/auth.c
413a
if(strcmp(u->p->user, cp->t.cuid))
error(cp->t.cuid);
.
412c
if(cp->t.num != AuthTc)
.
138a
if(n == 2 && buf[0] == 'O' && buf[1] == 'K')
goto dkhack;
.
137a
dkhack:
.
## diffname port/auth.c 1993/0403
## diff -e /n/bootesdump/1993/0402/sys/src/9/port/auth.c /n/bootesdump/1993/0403/sys/src/9/port/auth.c
310a
unlock(s);
.
307a
lock(s);
.
283,285d
267a
id = s->cid++;
unlock(s);
.
264a
lock(s);
.
243a
}
.
242c
for(cp = s->cache; cp; cp = next) {
next = cp->next;
.
240c
Crypt *cp, *next;
.
132a
f->tag = NOTAG;
.
## diffname port/auth.c 1993/0407
## diff -e /n/bootesdump/1993/0403/sys/src/9/port/auth.c /n/bootesdump/1993/0407/sys/src/9/port/auth.c
177,178c
poperror();
.
175d
150d
131,148c
/*
* Exchange a session message with the server.
* If an error occurs reading or writing,
* assume this is a mount of a mount and turn off
* authentication.
*/
if(!waserror()){
for(i = 0; i < CHALLEN; i++)
s->cchal[i] = nrand(256);
f.tag = NOTAG;
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, sizeof buf, 0);
if(n == 2 && buf[0] == 'O' && buf[1] == 'K')
n = (*devtab[c->type].read)(c, buf, sizeof buf, 0);
poperror();
if(convM2S(buf, &f, n) == 0){
free(s);
error(Emountrpc);
}
switch(f.type){
case Rsession:
memmove(s->schal, f.chal, CHALLEN);
memmove(s->authid, f.authid, NAMELEN);
memmove(s->authdom, f.authdom, DOMLEN);
break;
case Rerror:
free(s);
error(f.ename);
default:
free(s);
error(Emountrpc);
}
.
126c
/*
* no session exchanged yet
*/
.
123a
/*
* if two processes get here at the same
* time with no session exchanged, we have
* a race.
*/
.
120,121d
115,118c
if(waserror()){
.
106,113d
103a
Fcall f;
char buf[MAXMSG];
.
99,100d
## diffname port/auth.c 1993/0408
## diff -e /n/bootesdump/1993/0407/sys/src/9/port/auth.c /n/bootesdump/1993/0408/sys/src/9/port/auth.c
181,183c
memmove(tr.chal, s->schal, CHALLEN);
memmove(tr.authid, s->authid, NAMELEN);
memmove(tr.authdom, s->authdom, DOMLEN);
.
174,178c
else{
lock(s);
for(cp = s->cache; cp; cp = cp->next)
if(strcmp(cp->t.cuid, u->p->user) == 0){
tr.type = 0;
break;
}
unlock(s);
}
.
172c
if(strcmp(u->p->user, "none") == 0 || s->authid[0] == 0)
.
165a
unlock(&s->send);
.
164c
s->valid = 1;
.
160c
unlock(s);
.
157c
unlock(s);
.
147c
unlock(s);
.
126a
/* back off if someone else is doing an fsession */
while(!canlock(&s->send))
sched();
if(s->valid == 0){
.
125c
}
c->session = s;
}
unlock(c);
.
123c
if(s == 0){
unlock(c);
.
119,121d
112,116c
/* add a session structure to the channel if it has none */
lock(c);
.
27a
int valid;
.
21a
Lock send;
.
## diffname port/auth.c 1993/0411
## diff -e /n/bootesdump/1993/0408/sys/src/9/port/auth.c /n/bootesdump/1993/0411/sys/src/9/port/auth.c
165c
unlock(&s->send);
.
162c
unlock(&s->send);
.
152c
unlock(&s->send);
.
## diffname port/auth.c 1993/0427
## diff -e /n/bootesdump/1993/0411/sys/src/9/port/auth.c /n/bootesdump/1993/0427/sys/src/9/port/auth.c
165a
print("error using %d bytes %ux %ux %ux\n", n, buf[0], buf[1], buf[2]);
.
152a
print("error converting %d bytes %ux %ux %ux\n", n, buf[0], buf[1], buf[2]);
.
## diffname port/auth.c 1993/0428
## diff -e /n/bootesdump/1993/0427/sys/src/9/port/auth.c /n/bootesdump/1993/0428/sys/src/9/port/auth.c
451a
return n;
}
/*
* called by devcons() for #c/authenticator
*
* a read after a write of a ticket returns an authenticator
* for that ticket.
*/
long
authentwrite(Chan *c, char *a, int n)
{
Crypt *cp;
if(n != TICKETLEN)
error(Ebadarg);
if(c->aux == 0)
c->aux = newcrypt();
cp = c->aux;
memmove(cp->tbuf, a, TICKETLEN);
convM2T(cp->tbuf, &cp->t, evekey);
if(cp->t.num != AuthTc || strcmp(cp->t.cuid, u->p->user)){
freecrypt(cp);
c->aux = 0;
error(Ebadarg);
}
return n;
}
long
authentread(Chan *c, char *a, int n)
{
Crypt *cp;
cp = c->aux;
if(cp == 0)
error("authenticator read must follow a write");
cp->a.num = AuthAc;
memmove(cp->a.chal, cp->t.chal, CHALLEN);
cp->a.id = 0;
convA2M(&cp->a, cp->tbuf, cp->t.key);
memmove(a, cp->tbuf, AUTHENTLEN);
.
449c
memmove(cp->tbuf, a+TICKETLEN, AUTHENTLEN);
convM2A(cp->tbuf, &cp->a, cp->t.key);
.
444c
memmove(cp->tbuf, a, TICKETLEN);
convM2T(cp->tbuf, &cp->t, evekey);
.
424a
memmove(cp->tbuf, a+TICKETLEN, AUTHENTLEN);
convM2A(cp->tbuf, &cp->a, cp->t.key);
if(cp->a.num != AuthAc || memcmp(cp->a.chal, cp->t.chal, CHALLEN))
error(Eperm);
.
422c
memmove(cp->tbuf, a, TICKETLEN);
convM2T(cp->tbuf, &cp->t, evekey);
.
417c
if(n != TICKETLEN+AUTHENTLEN)
.
405c
convA2M(&cp->a, cp->tbuf, cp->t.key);
memmove(a, cp->tbuf, AUTHENTLEN);
.
401a
.
384a
.
366,367c
* 2) write ticket+authenticator to #c/authenticate. if it matches
* the challenge the user is changed to the suid field of the ticket
.
167d
153d
## diffname port/auth.c 1993/0501
## diff -e /n/bootesdump/1993/0428/sys/src/9/port/auth.c /n/fornaxdump/1993/0501/sys/src/brazil/port/auth.c
584c
memmove(up->user, buf, NAMELEN);
.
560,561c
memset(up->user, 0, NAMELEN);
strcpy(up->user, "none");
.
470,514d
466d
461,463c
convM2A(a+TICKETLEN, &cp->a, cp->t.key);
.
459c
if(strcmp(up->user, cp->t.cuid))
.
454,456c
convM2T(a, &cp->t, evekey);
.
429,435c
memmove(up->user, cp->t.suid, NAMELEN);
.
424,426c
convM2T(a, &cp->t, evekey);
.
419c
if(n != TICKETLEN)
.
405,407c
convA2M(&cp->a, a, cp->t.key);
.
401d
389c
strcpy(tr.uid, up->user);
.
383d
364,365c
* 2) write ticket to #c/authenticate. if it matchs the challenge the
* user is changed to the suid field of the ticket
.
341c
if(s == 0 || cp == 0 || s->authid[0] == 0 || strcmp(up->user, "none") == 0)
.
336c
if(strcmp(cp->t.cuid, up->user) == 0)
.
305,306c
memmove(cp->t.cuid, up->user, NAMELEN);
memmove(cp->t.suid, up->user, NAMELEN);
.
291c
if(strcmp(cp->t.cuid, up->user) == 0)
.
281c
if(s == 0 || s->authid[0] == 0 || strcmp(up->user, "none") == 0){
.
242c
if(strcmp(ncp->t.cuid, up->user) == 0){
.
232c
if(strncmp(up->user, cp->t.cuid, NAMELEN) != 0)
.
191,194c
memmove(tr.chal, c->session->schal, CHALLEN);
memmove(tr.authid, c->session->authid, NAMELEN);
memmove(tr.authdom, c->session->authdom, DOMLEN);
memmove(tr.uid, up->user, NAMELEN);
.
180,188c
else for(cp = s->cache; cp; cp = cp->next)
if(strcmp(cp->t.cuid, up->user) == 0){
tr.type = 0;
break;
}
.
178c
if(strcmp(up->user, "none") == 0 || c->session->authid[0] == 0)
.
171d
169c
c->session = s;
.
165c
free(s);
.
162c
free(s);
.
152c
free(s);
.
149c
goto dkhack;
.
146a
dkhack:
.
127,131d
122,125c
memset(s, 0, sizeof(Session));
.
119,120c
if(s == 0)
.
117a
/*
* no session exchanged yet
*/
.
114,115c
/*
* if two processes get here at the same
* time with no session exchanged, we have
* a race.
*/
.
48c
return strcmp(eve, up->user) == 0;
.
29d
22d
18d
## diffname port/auth.c 1993/0731
## diff -e /n/fornaxdump/1993/0501/sys/src/brazil/port/auth.c /n/fornaxdump/1993/0731/sys/src/brazil/port/auth.c
439a
return n;
}
/*
* called by devcons() for #c/authenticator
*
* a read after a write of a ticket (or ticket+id) returns an authenticator
* for that ticket.
*/
long
authentwrite(Chan *c, char *a, int n)
{
Crypt *cp;
if(n != TICKETLEN && n != TICKETLEN+4)
error(Ebadarg);
if(c->aux == 0)
c->aux = newcrypt();
cp = c->aux;
memmove(cp->tbuf, a, TICKETLEN);
convM2T(cp->tbuf, &cp->t, evekey);
if(cp->t.num != AuthTc || strcmp(cp->t.cuid, up->user)){
freecrypt(cp);
c->aux = 0;
error(Ebadarg);
}
if(n == TICKETLEN+4){
uchar *p = (uchar *)&a[TICKETLEN];
cp->a.id = p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24);
}else
cp->a.id = 0;
return n;
}
long
authentread(Chan *c, char *a, int n)
{
Crypt *cp;
cp = c->aux;
if(cp == 0)
error("authenticator read must follow a write");
cp->a.num = AuthAc;
memmove(cp->a.chal, cp->t.chal, CHALLEN);
convA2M(&cp->a, cp->tbuf, cp->t.key);
memmove(a, cp->tbuf, AUTHENTLEN);
.
437,438c
memmove(cp->tbuf, a+TICKETLEN, AUTHENTLEN);
convM2A(cp->tbuf, &cp->a, cp->t.key);
if(n == TICKETLEN+AUTHENTLEN+CHALLEN+4){
uchar *p = (uchar *)&a[TICKETLEN+AUTHENTLEN+CHALLEN];
id = p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24);
chal = &a[TICKETLEN+AUTHENTLEN];
}else{
id = 0;
chal = cp->t.chal;
}
if(cp->a.num != AuthAs || memcmp(chal, cp->a.chal, CHALLEN) || cp->a.id != id)
.
432c
memmove(cp->tbuf, a, TICKETLEN);
convM2T(cp->tbuf, &cp->t, evekey);
.
427c
if(n != TICKETLEN+AUTHENTLEN && n != TICKETLEN+AUTHENTLEN+CHALLEN+4)
.
425a
char *chal;
ulong id;
.
420c
* a write of a ticket+authenticator [+challenge+id] succeeds if they match
.
412a
memmove(cp->tbuf, a+TICKETLEN, AUTHENTLEN);
convM2A(cp->tbuf, &cp->a, cp->t.key);
if(cp->a.num != AuthAc || memcmp(cp->a.chal, cp->t.chal, CHALLEN))
error(Eperm);
.
410c
memmove(cp->tbuf, a, TICKETLEN);
convM2T(cp->tbuf, &cp->t, evekey);
.
405c
if(n != TICKETLEN+AUTHENTLEN)
.
393c
convA2M(&cp->a, cp->tbuf, cp->t.key);
memmove(a, cp->tbuf, AUTHENTLEN);
.
389a
.
372a
.
354,355c
* 2) write ticket+authenticator to #c/authenticate. if it matches
* the challenge the user is changed to the suid field of the ticket
.
181,183c
memmove(tr.chal, s->schal, CHALLEN);
memmove(tr.authid, s->authid, NAMELEN);
memmove(tr.authdom, s->authdom, DOMLEN);
.
174,178c
else{
lock(s);
for(cp = s->cache; cp; cp = cp->next)
if(strcmp(cp->t.cuid, up->user) == 0){
tr.type = 0;
break;
}
unlock(s);
}
.
172c
if(strcmp(up->user, "none") == 0 || s->authid[0] == 0)
.
165a
unlock(&s->send);
.
164c
s->valid = 1;
.
160c
unlock(&s->send);
.
157c
unlock(&s->send);
.
147c
unlock(&s->send);
.
144c
n = (*devtab[c->type].read)(c, buf, sizeof buf, 0);
.
141d
125a
/* back off if someone else is doing an fsession */
while(!canlock(&s->send))
sched();
if(s->valid == 0){
.
124c
}
c->session = s;
}
unlock(c);
.
122c
if(s == 0){
unlock(c);
.
118,120d
111,115c
/* add a session structure to the channel if it has none */
lock(c);
.
26a
int valid;
.
20a
Lock send;
.
17a
typedef struct Session Session;
.
## diffname port/auth.c 1994/0624
## diff -e /n/fornaxdump/1993/0731/sys/src/brazil/port/auth.c /n/fornaxdump/1994/0624/sys/src/brazil/port/auth.c
6d
## diffname port/auth.c 1994/0915
## diff -e /n/fornaxdump/1994/0624/sys/src/brazil/port/auth.c /n/fornaxdump/1994/0915/sys/src/brazil/port/auth.c
598a
up->basepri = PriNormal;
.
575a
up->basepri = PriNormal;
.
## diffname port/auth.c 1994/1027
## diff -e /n/fornaxdump/1994/0915/sys/src/brazil/port/auth.c /n/fornaxdump/1994/1027/sys/src/brazil/port/auth.c
597a
renameuser(eve, buf);
.
37c
char eve[NAMELEN];
.
## diffname port/auth.c 1995/0102
## diff -e /n/fornaxdump/1994/1027/sys/src/brazil/port/auth.c /n/fornaxdump/1995/0102/sys/src/brazil/port/auth.c
601c
up->nice = NiceNormal;
.
576c
up->nice = NiceNormal;
.
## diffname port/auth.c 1995/0106
## diff -e /n/fornaxdump/1995/0102/sys/src/brazil/port/auth.c /n/fornaxdump/1995/0106/sys/src/brazil/port/auth.c
128a
}
.
127c
while(!canlock(&s->send)) {
up->yield = 1;
.
## diffname port/auth.c 1995/0110
## diff -e /n/fornaxdump/1995/0106/sys/src/brazil/port/auth.c /n/fornaxdump/1995/0110/sys/src/brazil/port/auth.c
603c
up->basepri = PriNormal;
.
578c
up->basepri = PriNormal;
.
130d
127,128c
while(!canlock(&s->send))
.
## diffname port/auth.c 1995/0113
## diff -e /n/fornaxdump/1995/0110/sys/src/brazil/port/auth.c /n/fornaxdump/1995/0113/sys/src/brazil/port/auth.c
545c
if(!cpuserver || !iseve())
.
## diffname port/auth.c 1995/0414
## diff -e /n/fornaxdump/1995/0113/sys/src/brazil/port/auth.c /n/fornaxdump/1995/0414/sys/src/brazil/port/auth.c
130c
if(s->valid == 0 && (c->flag & CMSG) == 0){
.
## diffname port/auth.c 1997/0327
## diff -e /n/fornaxdump/1995/0414/sys/src/brazil/port/auth.c /n/emeliedump/1997/0327/sys/src/brazil/port/auth.c
198c
cclose(c);
.
149c
n = devtab[c->type]->read(c, buf, sizeof buf, 0);
.
147c
n = devtab[c->type]->read(c, buf, sizeof buf, 0);
.
145c
if(devtab[c->type]->write(c, buf, n, 0) != n)
.
109c
cclose(c);
.
## diffname port/auth.c 1998/0404
## diff -e /n/emeliedump/1997/0327/sys/src/brazil/port/auth.c /n/emeliedump/1998/0404/sys/src/brazil/port/auth.c
525c
if(n >= AUTHENTLEN)
memmove(a, cp->tbuf, AUTHENTLEN);
if(n >= AUTHENTLEN + TICKETLEN)
convT2M(&cp->t, a+AUTHENTLEN, nil);
.
480a
* reading authcheck after writing into it yields the
* nonce key
*/
long
authcheckread(Chan *c, char *a, int n)
{
Crypt *cp;
cp = c->aux;
if(cp == nil)
error(Ebadarg);
if(n < TICKETLEN))
error(Ebadarg);
convT2M(&cp->t, a, nil);
return sizeof(cp->t);
}
/*
.
## diffname port/auth.c 1998/0406
## diff -e /n/emeliedump/1998/0404/sys/src/brazil/port/auth.c /n/emeliedump/1998/0406/sys/src/brazil/port/auth.c
492c
if(n < TICKETLEN)
.
## diffname port/auth.c 1998/0407
## diff -e /n/emeliedump/1998/0406/sys/src/brazil/port/auth.c /n/emeliedump/1998/0407/sys/src/brazil/port/auth.c
530a
/*
* create an authenticator and return it and optionally the
* unencripted ticket
*/
.
482c
* unencrypted ticket
.
## diffname port/auth.c 1998/0422
## diff -e /n/emeliedump/1998/0407/sys/src/brazil/port/auth.c /n/emeliedump/1998/0422/sys/src/brazil/port/auth.c
550,552d
407a
if(n >= AUTHENTLEN + TICKETLEN)
convT2M(&cp->t, a+AUTHENTLEN, nil);
.
398c
if(n < AUTHENTLEN)
.
## diffname port/auth.c 1998/0512
## diff -e /n/emeliedump/1998/0422/sys/src/brazil/port/auth.c /n/emeliedump/1998/0512/sys/src/brazil/port/auth.c
352c
}
.
173c
/*
.
## diffname port/auth.c 1999/0331
## diff -e /n/emeliedump/1998/0512/sys/src/brazil/port/auth.c /n/emeliedump/1999/0331/sys/src/brazil/port/auth.c
251a
cclose(c);
.
221a
cclose(c);
.
219a
}
.
218c
if(s == 0){
cclose(c);
.
## diffname port/auth.c 1999/1224
## diff -e /n/emeliedump/1999/0331/sys/src/brazil/port/auth.c /n/emeliedump/1999/1224/sys/src/9/port/auth.c
540c
* unencrypted ticket
.
## diffname port/auth.c 2000/0710
## diff -e /n/emeliedump/1999/1224/sys/src/9/port/auth.c /n/emeliedump/2000/0710/sys/src/9/port/auth.c
603c
if(!iseve() || strcmp(a, "none") != 0)
.
## diffname port/auth.c 2001/0503
## diff -e /n/emeliedump/2000/0710/sys/src/9/port/auth.c /n/emeliedump/2001/0503/sys/src/9/port/auth.c
357c
if(a.id != id){
.
353c
if(memcmp(a.chal, s->cchal, sizeof(a.chal))){
.
348,349c
convM2A(f->rauth, &a, cp->t.key);
if(a.num != AuthAs){
.
332a
Authenticator a;
.
318,321c
memmove(a.chal, s->schal, CHALLEN);
a.num = AuthAc;
a.id = id;
convA2M(&a, f->auth, cp->t.key);
.
280a
Authenticator a;
.
## diffname port/auth.c 2001/0527
## diff -e /n/emeliedump/2001/0503/sys/src/9/port/auth.c /n/emeliedump/2001/0527/sys/src/9/port/auth.c
632,633c
kstrdup(&eve, buf);
kstrdup(&up->user, buf);
.
630a
.
627,629c
strncpy(buf, a, n+1);
if(buf[0] == '\0')
.
625c
if(n >= sizeof buf)
.
621c
char buf[128];
.
607,608c
kstrdup(&up->user, "none");
.
603,604d
490,570d
456,486c
error("sysfauth unimplemented");
return -1;
.
454c
sysfauth(ulong *)
.
448,452d
439,445c
free(msg);
poperror();
poperror();
cclose(c);
return m;
.
434,437c
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;
.
428,432c
lock(c);
c->offset += m;
unlock(c);
.
423,426c
/* message sent; receive and decode reply */
m = devtab[c->type]->read(c, msg, MAXMSG, c->offset);
if(m <= 0)
error("EOF receiving fsession reply");
.
420,421d
390,418c
if(m < n){
lock(c);
c->offset -= n - m;
unlock(c);
error("short write in fsession");
.
381,388c
m = devtab[c->type]->write(c, msg, n, oo);
.
365,379c
lock(c);
oo = c->offset;
c->offset += n;
unlock(c);
.
355,363c
n = convS2M(&f, msg, MAXMSG);
if(n == 0)
error("bad fsession conversion on send");
.
292,353c
f.type = Tsession;
f.tag = NOTAG;
f.nchal = 0;
f.chal = (uchar*)"";
msg = smalloc(MAXMSG);
if(waserror()){
free(msg);
nexterror();
.
229,288c
if(c->flag & CMSG){
//BUG what to do?
((uchar*)arg[1])[0] = 0;
poperror();
cclose(c);
.
225d
215,222c
//BUG print("warning: stub fsession being used\n");
authlen = arg[2];
validaddr(arg[1], authlen, 1);
c = fdtochan(arg[0], ORDWR, 0, 1);
.
210,213c
uvlong oo;
.
208a
Fcall f;
uchar *msg;
uint authlen, n, m;
.
207c
sysfsession(ulong *arg)
.
203,205d
200c
return m;
.
197a
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);
.
190,196c
lock(c);
c->offset += m;
unlock(c);
.
173,188c
/* message sent; receive and decode reply */
m = devtab[c->type]->read(c, msg, MAXMSG, c->offset);
if(m <= 0)
error("EOF receiving fversion reply");
.
171d
130,169c
if(m < n){
lock(c);
c->offset -= n - m;
unlock(c);
error("short write in fversion");
.
126,128c
m = devtab[c->type]->write(c, msg, n, oo);
.
123a
n = convS2M(&f, msg, MAXMSG);
if(n == 0)
error("bad fversion conversion on send");
lock(c);
oo = c->offset;
c->offset += n;
.
113,122c
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(MAXMSG);
if(waserror()){
free(msg);
nexterror();
.
106,107c
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);
.
100,104c
uvlong oo;
.
98c
Fcall f; /* two Fcalls should be big enough for reply */
uchar *msg;
char *vers;
uint arglen, n, m, msize;
.
96c
sysfversion(ulong *arg)
.
50,94d
17,37c
char *eve;
.
8,15c
#include <auth.h>
.
## diffname port/auth.c 2001/0529
## diff -e /n/emeliedump/2001/0527/sys/src/9/port/auth.c /n/emeliedump/2001/0529/sys/src/9/port/auth.c
168c
m = devtab[c->type]->read(c, msg, 8192+IOHDRSZ, c->offset);
.
149c
n = convS2M(&f, msg, 8192+IOHDRSZ);
.
144c
msg = smalloc(8192+IOHDRSZ);
.
81c
m = devtab[c->type]->read(c, msg, 8192+IOHDRSZ, c->offset);
.
62c
n = convS2M(&f, msg, 8192+IOHDRSZ);
.
57c
msg = smalloc(8192+IOHDRSZ);
.
## diffname port/auth.c 2001/0807
## diff -e /n/emeliedump/2001/0529/sys/src/9/port/auth.c /n/emeliedump/2001/0807/sys/src/9/port/auth.c
197,198c
Chan *c;
uint authlen, rauthlen;
int n;
authlen = arg[2];
validaddr(arg[1], authlen, 1);
rauthlen = arg[4];
validaddr(arg[3], rauthlen, 1);
c = fdtochan(arg[0], ORDWR, 0, 1);
if(waserror()){
cclose(c);
nexterror();
}
n = mntauth(c, (uchar*)arg[1], authlen, (uchar*)arg[3], rauthlen);
poperror();
cclose(c);
return n;
.
195c
sysfauth(ulong *arg)
.
191c
return n;
.
188a
}
long
sysfsession(ulong *arg)
{
Chan *c;
uint authlen, n;
authlen = arg[2];
validaddr(arg[1], authlen, 1);
c = fdtochan(arg[0], ORDWR, 0, 1);
if(waserror()){
cclose(c);
nexterror();
}
if(c->session == nil){
if(c->flag&CMSG)
error("session on mounted channel");
sendsession(c);
}
n = strlen(c->session->authlist)+1;
if(n > authlen)
error(Eshort);
memmove((uchar*)arg[1], c->session->authlist, n);
.
181,185c
c->session = allocsession(f.authlist);
.
176a
print("rsession conv returns %d\n", n);
.
170a
print("rsession rcvd\n");
.
158a
print("session sent\n");
.
142,143d
123,139d
119,120c
uint n, m;
.
114,115c
void
sendsession(Chan *c)
.
13a
struct Session
{
char *authlist;
};
Session*
allocsession(char *authlist)
{
Session *s;
s = smalloc(sizeof(*s));
s->authlist = nil;
kstrdup(&s->authlist, authlist);
return s;
}
void
freesession(Session *s)
{
if(s == nil)
return;
free(s->authlist);
free(s);
}
.
## diffname port/auth.c 2001/0808
## diff -e /n/emeliedump/2001/0807/sys/src/9/port/auth.c /n/emeliedump/2001/0808/sys/src/9/port/auth.c
229,248c
error("sysfauth unimplemented");
return -1;
.
227c
sysfauth(ulong *)
.
222,223c
return m;
.
193,219d
189c
m = f.nchal;
if(m > authlen)
error(Eshort);
//BUG print("auth stuff ignored; noauth by default\n");
((uchar*)arg[1])[0] = 0;
.
184d
177d
164d
148a
f.nchal = 0;
f.chal = (uchar*)"";
.
146a
//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;
}
.
144c
uint authlen, n, m;
Chan *c;
.
139,140c
long
sysfsession(ulong *arg)
.
14,38d
## diffname port/auth.c 2001/0819
## diff -e /n/emeliedump/2001/0808/sys/src/9/port/auth.c /n/emeliedump/2001/0819/sys/src/9/port/auth.c
160,198c
return fd;
.
158c
/* always mark it close on exec */
ac->flag |= CCEXEC;
.
153,156c
fd = newfd(ac);
if(fd < 0)
error(Enofd);
poperror(); /* ac */
poperror(); /* c */
.
149,151d
146c
cclose(ac);
.
132,144c
ac = mntauth(c, aname);
.
123,125c
if(arg[2] == 0)
error(Ebadarg);
validaddr(arg[1], arg[2], 1);
((uchar*)arg[1])[0] = '\0';
return 0;
}
long
sysfauth(ulong *arg)
{
Chan *c, *ac;
char *aname;
int fd;
validaddr(arg[1], 1, 0);
aname = (char*)arg[1];
validname(aname, 0);
.
117,121c
/* deprecated; backwards compatibility only */
.
115c
sys_fsession(ulong *arg)
.
49,108d
46,47c
m = mntversion(c, vers, msize, arglen);
.
38c
if(arglen==0 || memchr(vers, 0, arglen)==0)
.
31d
29c
uint arglen, m, msize;
.
26,27d
## diffname port/auth.c 2001/0925
## diff -e /n/emeliedump/2001/0819/sys/src/9/port/auth.c /n/emeliedump/2001/0925/sys/src/9/port/auth.c
8c
#include <authsrv.h>
.
## diffname port/auth.c 2001/0929
## diff -e /n/emeliedump/2001/0925/sys/src/9/port/auth.c /n/emeliedump/2001/0929/sys/src/9/port/auth.c
97,121d
## diffname port/auth.c 2001/0930
## diff -e /n/emeliedump/2001/0929/sys/src/9/port/auth.c /n/emeliedump/2001/0930/sys/src/9/port/auth.c
104c
if(strcmp(a, "none") != 0)
.
## diffname port/auth.c 2002/0115
## diff -e /n/emeliedump/2001/0930/sys/src/9/port/auth.c /n/emeliedump/2002/0115/sys/src/9/port/auth.c
11d
## diffname port/auth.c 2002/0221
## diff -e /n/emeliedump/2002/0115/sys/src/9/port/auth.c /n/emeliedump/2002/0221/sys/src/9/port/auth.c
124,126c
memmove(buf, a, n);
buf[n] = 0;
.
122c
if(n <= 0 || n >= sizeof buf)
.
## diffname port/auth.c 2002/0410
## diff -e /n/emeliedump/2002/0221/sys/src/9/port/auth.c /n/emeliedump/2002/0410/sys/src/9/port/auth.c
103c
if(n!=4 || strncmp(a, "none", 4)!=0)
.
## diffname port/auth.c 2002/0517
## diff -e /n/emeliedump/2002/0410/sys/src/9/port/auth.c /n/emeliedump/2002/0517/sys/src/9/port/auth.c
87d
77a
/* at this point ac is responsible for keeping c alive */
cclose(c);
poperror(); /* c */
.
## diffname port/auth.c 2002/0831
## diff -e /n/emeliedump/2002/0517/sys/src/9/port/auth.c /n/emeliedump/2002/0831/sys/src/9/port/auth.c
70c
validname(aname, 1);
.
|