From: Mike Haertel <mike@ducky.net>
To: 9fans@cse.psu.edu
Subject: [9fans] auth protocol questions + proposed kfs improvement
Date: Thu, 1 Nov 2001 21:43:46 -0800 [thread overview]
Message-ID: <200111020543.fA25hkG02351@ducky.net> (raw)
What is the reason for the distinction between AuthTs and AuthTc
tickets, and AuthAs and AuthAc authenticators? This caused me
some grief in a recent project...
I wanted to modify kfs so that "listen il!*!17008" would work
on terminals as well as cpu servers, so that I could use the
local file system on my laptop as the boot file system for
the bitsy.
The problem, I found, is that the code in kfs relies on being
able to read /dev/key, and uses the key so obtained to verify
authentication protocol tickets by hand. But reading /dev/key
is only allowed on cpu servers (presumably it's disallowed on
terminals to prevent trojans from having access to your password).
So, I wanted to modify kfs to use /dev/authcheck to verify
the authentication protocol, rather than relying on being able
to read /dev/key.
Here's the new version of authorize() for /sys/src/cmd/disk/kfs/auth.c.
(The text of this email continues beyond the code...)
int
authorize(Chan *cp, Fcall *in, Fcall *ou)
{
Ticket t;
Authenticator a;
char authbuf[TICKETLEN + AUTHENTLEN + CHALLEN + 4];
int fd, try;
ulong bit;
if (cp == cons.srvchan) /* local channel already safe */
return 1;
if(noauth || wstatallow) /* set to allow entry during boot */
return 1;
if(strcmp(in->uname, "none") == 0)
return allownone || cp->auth;
if(in->type == Toattach)
return 0;
fd = open("#c/authcheck", ORDWR);
if (fd < 0) {
print("can't open #c/authcheck\n");
return 0;
}
memcpy(authbuf, in->ticket, TICKETLEN);
memcpy(authbuf + TICKETLEN, in->auth, AUTHENTLEN);
memcpy(authbuf + TICKETLEN + AUTHENTLEN, cp->chal, CHALLEN);
/*
* 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);
for (try = cp->idoffset; try < cp->idoffset + 16; ++try) {
authbuf[TICKETLEN + AUTHENTLEN + CHALLEN + 0] = try;
authbuf[TICKETLEN + AUTHENTLEN + CHALLEN + 1] = try >> 8;
authbuf[TICKETLEN + AUTHENTLEN + CHALLEN + 2] = try >> 16;
authbuf[TICKETLEN + AUTHENTLEN + CHALLEN + 3] = try >> 24;
if (write(fd, authbuf, sizeof authbuf) == sizeof authbuf)
break;
}
if (try == cp->idoffset + 16) {
unlock(&cp->idlock);
close(fd);
print("authcheck failed\n");
return 0;
}
bit = 1UL << (try - cp->idoffset);
if (cp->idvec & bit) {
unlock(&cp->idlock);
print("id %d reused (replay attack?)\n", try);
close(fd);
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 (read(fd, authbuf, TICKETLEN) != TICKETLEN) {
close(fd);
print("can't read decrypted ticket\n");
return 0;
}
close(fd);
convM2T(authbuf, &t, nil);
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);
a.id = try;
convA2M(&a, ou->rauth, t.key);
cp->auth = 1;
return 1;
}
Unfortunately, what I discovered is this doesn't work.
The reason it doesn't work is that /dev/authcheck only
works with AuthTc flavored tickets, and AuthAs flavored
authenticators.
So I replaced authcheck() in /sys/src/9/port/auth.c with
the following code.
(email *still* continues after this code...)
long
authcheck(Chan *c, char *a, int n)
{
Crypt *cp;
char *chal;
ulong id;
if(n != TICKETLEN+AUTHENTLEN && n != TICKETLEN+AUTHENTLEN+CHALLEN+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) {
if(strcmp(up->user, cp->t.cuid))
error(cp->t.cuid);
} else if (cp->t.num != AuthTs) {
error(Ebadarg);
}
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->t.num == AuthTc && cp->a.num != AuthAs
|| cp->t.num == AuthTs && cp->a.num != AuthAc
|| memcmp(chal, cp->a.chal, CHALLEN) || cp->a.id != id)
error(Eperm);
return n;
}
Now, /dev/authcheck works either with (AuthTc,AuthAs) or
(AuthTs,AuthAc) flavored ticket+authenticator pairs.
So, a couple of questions:
1. Is there any security reason why /dev/authcheck
didn't already work with AuthTs flavored tickets and AuthAc
flavored authenticators?
2. What is the reason for strcmp(up->user, cp->t.cuid)?
3. Repeating my original question, is there a security reason
for the distinction between AuthTs and AuthTc flavored tickets,
and the distinction between AuthAc and AuthAs flavored authenticators?
next reply other threads:[~2001-11-02 5:43 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2001-11-02 5:43 Mike Haertel [this message]
2001-11-02 7:09 Russ Cox
2001-11-02 19:23 ` Mike Haertel
2001-11-02 7:16 Russ Cox
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200111020543.fA25hkG02351@ducky.net \
--to=mike@ducky.net \
--cc=9fans@cse.psu.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).