summaryrefslogtreecommitdiff
path: root/sys/src/cmd/auth/authsrv.c
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2015-08-19 21:06:17 +0200
committercinap_lenrek <cinap_lenrek@felloff.net>2015-08-19 21:06:17 +0200
commit02cfcfeab46f36aad95263ed40d19df7bd5eddef (patch)
tree30f67204be8d474b2c761e8944c20d042df1a08b /sys/src/cmd/auth/authsrv.c
parentf785d4da07349c7bb250eb00a3f2bed3eb170828 (diff)
libauthsrv: generalize ticket service, not hardcoding ticket format and DES encryption
this is in preparation for replacing DES ticket encryption with something better. but first need to make the code stop making assumptions. the wire encoding of the Ticket might be variable length with TICKETLEN just giving an upper bound. the details will be handled by libauthsrv _asgetticket() and _asgetresp() funciotns. the Authenticator and Passwordreq structures are encrypted with the random ticket key. The encryption schmeme will depend on the Ticket format used, so we pass the Ticket* structure instead of the DES key. introduce Authkey structure that will hold all the required cryptographic keys instead of passing DES key.
Diffstat (limited to 'sys/src/cmd/auth/authsrv.c')
-rw-r--r--sys/src/cmd/auth/authsrv.c234
1 files changed, 121 insertions, 113 deletions
diff --git a/sys/src/cmd/auth/authsrv.c b/sys/src/cmd/auth/authsrv.c
index bef741a37..e6dd65867 100644
--- a/sys/src/cmd/auth/authsrv.c
+++ b/sys/src/cmd/auth/authsrv.c
@@ -30,22 +30,24 @@ void vnc(Ticketreq*);
int speaksfor(char*, char*);
void replyerror(char*, ...);
void getraddr(char*);
-void mkkey(char*);
+void mkkey(Authkey*);
+int samekey(Authkey*, Authkey*);
+void mkticket(Ticketreq*, Ticket*);
void randombytes(uchar*, int);
void nthash(uchar hash[MShashlen], char *passwd);
void lmhash(uchar hash[MShashlen], char *passwd);
void ntv2hash(uchar hash[MShashlen], char *passwd, char *user, char *dom);
void mschalresp(uchar resp[MSresplen], uchar hash[MShashlen], uchar chal[MSchallen]);
void desencrypt(uchar data[8], uchar key[7]);
-int tickauthreply(Ticketreq*, char*);
+int tickauthreply(Ticketreq*, Authkey*);
void safecpy(char*, char*, int);
-
void
main(int argc, char *argv[])
{
char buf[TICKREQLEN];
Ticketreq tr;
+ int n;
ARGBEGIN{
case 'd':
@@ -64,11 +66,10 @@ main(int argc, char *argv[])
srand(time(0)*getpid());
for(;;){
- if(readn(0, buf, TICKREQLEN) <= 0)
+ n = readn(0, buf, sizeof(buf));
+ if(n <= 0 || convM2TR(buf, n, &tr) <= 0)
exits(0);
-
- convM2TR(buf, &tr);
- switch(buf[0]){
+ switch(tr.type){
case AuthTreq:
ticketrequest(&tr);
break;
@@ -97,7 +98,7 @@ main(int argc, char *argv[])
vnc(&tr);
break;
default:
- syslog(0, AUTHLOG, "unknown ticket request type: %d", buf[0]);
+ syslog(0, AUTHLOG, "unknown ticket request type: %d", tr.type);
exits(0);
}
}
@@ -107,45 +108,39 @@ main(int argc, char *argv[])
int
ticketrequest(Ticketreq *tr)
{
- char akey[DESKEYLEN];
- char hkey[DESKEYLEN];
- Ticket t;
+ Authkey akey, hkey;
char tbuf[2*TICKETLEN+1];
+ Ticket t;
+ int n;
- if(findkey(KEYDB, tr->authid, akey) == 0){
+ if(!findkey(KEYDB, tr->authid, &akey)){
/* make one up so caller doesn't know it was wrong */
- mkkey(akey);
+ mkkey(&akey);
if(debug)
syslog(0, AUTHLOG, "tr-fail authid %s", raddr);
}
- if(findkey(KEYDB, tr->hostid, hkey) == 0){
+ if(!findkey(KEYDB, tr->hostid, &hkey)){
/* make one up so caller doesn't know it was wrong */
- mkkey(hkey);
+ mkkey(&hkey);
if(debug)
syslog(0, AUTHLOG, "tr-fail hostid %s(%s)", tr->hostid, raddr);
}
- memset(&t, 0, sizeof(t));
- memmove(t.chal, tr->chal, CHALLEN);
- strcpy(t.cuid, tr->uid);
- if(speaksfor(tr->hostid, tr->uid))
- strcpy(t.suid, tr->uid);
- else {
- mkkey(akey);
- mkkey(hkey);
+ mkticket(tr, &t);
+ if(!speaksfor(tr->hostid, tr->uid)){
+ mkkey(&akey);
+ mkkey(&hkey);
if(debug)
syslog(0, AUTHLOG, "tr-fail %s@%s(%s) -> %s@%s no speaks for",
tr->uid, tr->hostid, raddr, tr->uid, tr->authid);
}
-
- mkkey(t.key);
-
- tbuf[0] = AuthOK;
+ n = 0;
+ tbuf[n++] = AuthOK;
t.num = AuthTc;
- convT2M(&t, tbuf+1, hkey);
+ n += convT2M(&t, tbuf+n, sizeof(tbuf)-n, &hkey);
t.num = AuthTs;
- convT2M(&t, tbuf+1+TICKETLEN, akey);
- if(write(1, tbuf, 2*TICKETLEN+1) < 0){
+ n += convT2M(&t, tbuf+n, sizeof(tbuf)-n, &akey);
+ if(write(1, tbuf, n) < 0){
if(debug)
syslog(0, AUTHLOG, "tr-fail %s@%s(%s): hangup",
tr->uid, tr->hostid, raddr);
@@ -163,22 +158,23 @@ challengebox(Ticketreq *tr)
{
long chal;
char *key, *netkey;
- char kbuf[DESKEYLEN], nkbuf[DESKEYLEN], hkey[DESKEYLEN];
+ Authkey hkey;
+ char kbuf[DESKEYLEN], nkbuf[DESKEYLEN];
char buf[NETCHLEN+1];
char *err;
- key = findkey(KEYDB, tr->uid, kbuf);
- netkey = findkey(NETKEYDB, tr->uid, nkbuf);
- if(key == 0 && netkey == 0){
+ key = finddeskey(KEYDB, tr->uid, kbuf);
+ netkey = finddeskey(NETKEYDB, tr->uid, nkbuf);
+ if(key == nil && netkey == nil){
/* make one up so caller doesn't know it was wrong */
- mkkey(nkbuf);
+ randombytes((uchar*)nkbuf, DESKEYLEN);
netkey = nkbuf;
if(debug)
syslog(0, AUTHLOG, "cr-fail uid %s@%s", tr->uid, raddr);
}
- if(findkey(KEYDB, tr->hostid, hkey) == 0){
+ if(!findkey(KEYDB, tr->hostid, &hkey)){
/* make one up so caller doesn't know it was wrong */
- mkkey(hkey);
+ mkkey(&hkey);
if(debug)
syslog(0, AUTHLOG, "cr-fail hostid %s %s@%s", tr->hostid,
tr->uid, raddr);
@@ -195,8 +191,8 @@ challengebox(Ticketreq *tr)
exits(0);
if(readn(0, buf, NETCHLEN) < 0)
exits(0);
- if(!(key && netcheck(key, chal, buf))
- && !(netkey && netcheck(netkey, chal, buf))
+ if(!(key != nil && netcheck(key, chal, buf))
+ && !(netkey != nil && netcheck(netkey, chal, buf))
&& (err = secureidcheck(tr->uid, buf)) != nil){
replyerror("cr-fail %s %s %s", err, tr->uid, raddr);
logfail(tr->uid);
@@ -210,7 +206,7 @@ challengebox(Ticketreq *tr)
/*
* reply with ticket & authenticator
*/
- if(tickauthreply(tr, hkey) < 0){
+ if(tickauthreply(tr, &hkey) < 0){
if(debug)
syslog(0, AUTHLOG, "cr-fail %s@%s(%s): hangup",
tr->uid, tr->hostid, raddr);
@@ -229,36 +225,36 @@ changepasswd(Ticketreq *tr)
char tbuf[TICKETLEN+1];
char prbuf[PASSREQLEN];
Passwordreq pr;
- char okey[DESKEYLEN], nkey[DESKEYLEN];
+ Authkey okey, nkey;
char *err;
+ int n;
- if(findkey(KEYDB, tr->uid, okey) == 0){
+ if(!findkey(KEYDB, tr->uid, &okey)){
/* make one up so caller doesn't know it was wrong */
- mkkey(okey);
+ mkkey(&okey);
syslog(0, AUTHLOG, "cp-fail uid %s", raddr);
}
/* send back a ticket with a new key */
- memmove(t.chal, tr->chal, CHALLEN);
- mkkey(t.key);
- tbuf[0] = AuthOK;
+ mkticket(tr, &t);
t.num = AuthTp;
- safecpy(t.cuid, tr->uid, sizeof(t.cuid));
- safecpy(t.suid, tr->uid, sizeof(t.suid));
- convT2M(&t, tbuf+1, okey);
- write(1, tbuf, sizeof(tbuf));
+ n = 0;
+ tbuf[n++] = AuthOK;
+ n += convT2M(&t, tbuf+n, sizeof(tbuf)-n, &okey);
+ if(write(1, tbuf, n) != n)
+ exits(0);
/* loop trying passwords out */
for(;;){
- if(readn(0, prbuf, PASSREQLEN) < 0)
+ n = readn(0, prbuf, sizeof(prbuf));
+ if(n <= 0 || convM2PR(prbuf, n, &pr, &t) <= 0)
exits(0);
- convM2PR(prbuf, &pr, t.key);
if(pr.num != AuthPass){
replyerror("protocol botch1: %s", raddr);
exits(0);
}
- passtokey(nkey, pr.old);
- if(memcmp(nkey, okey, DESKEYLEN)){
+ passtokey(&nkey, pr.old);
+ if(!samekey(&nkey, &okey)){
replyerror("protocol botch2: %s", raddr);
continue;
}
@@ -268,13 +264,13 @@ changepasswd(Ticketreq *tr)
replyerror("%s %s", err, raddr);
continue;
}
- passtokey(nkey, pr.new);
+ passtokey(&nkey, pr.new);
}
if(pr.changesecret && setsecret(KEYDB, tr->uid, pr.secret) == 0){
replyerror("can't write secret %s", raddr);
continue;
}
- if(*pr.new && setkey(KEYDB, tr->uid, nkey) == 0){
+ if(*pr.new && setkey(KEYDB, tr->uid, &nkey) == 0){
replyerror("can't write key %s", raddr);
continue;
}
@@ -292,15 +288,14 @@ http(Ticketreq *tr)
{
Ticket t;
char tbuf[TICKETLEN+1];
- char key[DESKEYLEN];
+ Authkey key;
char *p;
Biobuf *b;
int n;
- randombytes((uchar*)key, DESKEYLEN);
-
/* use plan9 key when there is any */
- findkey(KEYDB, tr->uid, key);
+ if(!findkey(KEYDB, tr->uid, &key))
+ mkkey(&key);
n = strlen(tr->uid);
b = Bopen("/sys/lib/httppasswords", OREAD);
@@ -315,21 +310,20 @@ http(Ticketreq *tr)
p += n;
while(*p == ' ' || *p == '\t')
p++;
- passtokey(key, p);
+ passtokey(&key, p);
}
}
Bterm(b);
}
/* send back a ticket encrypted with the key */
+ mkticket(tr, &t);
randombytes((uchar*)t.chal, CHALLEN);
- mkkey(t.key);
- tbuf[0] = AuthOK;
t.num = AuthHr;
- safecpy(t.cuid, tr->uid, sizeof(t.cuid));
- safecpy(t.suid, tr->uid, sizeof(t.suid));
- convT2M(&t, tbuf+1, key);
- write(1, tbuf, sizeof(tbuf));
+ n = 0;
+ tbuf[n++] = AuthOK;
+ n += convT2M(&t, tbuf+n, sizeof(tbuf)-n, &key);
+ write(1, tbuf, n);
}
static char*
@@ -339,13 +333,13 @@ domainname(void)
static char *domain;
int n;
- if(domain)
+ if(domain != nil)
return domain;
if(*sysname)
return sysname;
domain = csgetvalue(0, "sys", sysname, "dom", nil);
- if(domain)
+ if(domain != nil)
return domain;
n = readfile("/dev/sysname", sysname, sizeof(sysname)-1);
@@ -373,12 +367,13 @@ h2b(char c)
void
apop(Ticketreq *tr, int type)
{
- int challen, i, tries;
- char *secret, *hkey, *p;
+ int challen, i, n, tries;
+ char *secret, *p;
+ Authkey hkey;
Ticketreq treq;
DigestState *s;
- char sbuf[SECRETLEN], hbuf[DESKEYLEN];
- char tbuf[TICKREQLEN];
+ char sbuf[SECRETLEN];
+ char trbuf[TICKREQLEN];
char buf[MD5dlen*2];
uchar digest[MD5dlen], resp[MD5dlen];
ulong rb[4];
@@ -401,9 +396,9 @@ apop(Ticketreq *tr, int type)
/*
* get ticket request
*/
- if(readn(0, tbuf, TICKREQLEN) < 0)
+ n = readn(0, trbuf, sizeof(trbuf));
+ if(n <= 0 || convM2TR(trbuf, n, &treq) <= 0)
exits(0);
- convM2TR(tbuf, &treq);
tr = &treq;
if(tr->type != type)
exits(0);
@@ -411,7 +406,7 @@ apop(Ticketreq *tr, int type)
/*
* read response
*/
- if(readn(0, buf, MD5dlen*2) < 0)
+ if(readn(0, buf, MD5dlen*2) != MD5dlen*2)
exits(0);
for(i = 0; i < MD5dlen; i++)
resp[i] = (h2b(buf[2*i])<<4)|h2b(buf[2*i+1]);
@@ -420,8 +415,7 @@ apop(Ticketreq *tr, int type)
* lookup
*/
secret = findsecret(KEYDB, tr->uid, sbuf);
- hkey = findkey(KEYDB, tr->hostid, hbuf);
- if(hkey == 0 || secret == 0){
+ if(!findkey(KEYDB, tr->hostid, &hkey) || secret == nil){
replyerror("apop-fail bad response %s", raddr);
logfail(tr->uid);
if(tries > 5)
@@ -455,7 +449,7 @@ apop(Ticketreq *tr, int type)
/*
* reply with ticket & authenticator
*/
- if(tickauthreply(tr, hkey) < 0)
+ if(tickauthreply(tr, &hkey) < 0)
exits(0);
if(debug){
@@ -493,10 +487,11 @@ uchar swizzletab[256] = {
void
vnc(Ticketreq *tr)
{
+ char *secret;
+ Authkey hkey;
uchar chal[VNCchallen+6];
uchar reply[VNCchallen];
- char *secret, *hkey;
- char sbuf[SECRETLEN], hbuf[DESKEYLEN];
+ char sbuf[SECRETLEN];
DESstate s;
int i;
@@ -514,18 +509,15 @@ vnc(Ticketreq *tr)
*/
memset(sbuf, 0, sizeof(sbuf));
secret = findsecret(KEYDB, tr->uid, sbuf);
- if(secret == 0){
+ if(secret == nil){
randombytes((uchar*)sbuf, sizeof(sbuf));
secret = sbuf;
}
for(i = 0; i < 8; i++)
secret[i] = swizzletab[(uchar)secret[i]];
- hkey = findkey(KEYDB, tr->hostid, hbuf);
- if(hkey == 0){
- randombytes((uchar*)hbuf, sizeof(hbuf));
- hkey = hbuf;
- }
+ if(!findkey(KEYDB, tr->hostid, &hkey))
+ mkkey(&hkey);
/*
* get response
@@ -548,7 +540,7 @@ vnc(Ticketreq *tr)
/*
* reply with ticket & authenticator
*/
- if(tickauthreply(tr, hkey) < 0)
+ if(tickauthreply(tr, &hkey) < 0)
exits(0);
if(debug)
@@ -558,9 +550,10 @@ vnc(Ticketreq *tr)
void
chap(Ticketreq *tr)
{
- char *secret, *hkey;
+ char *secret;
+ Authkey hkey;
DigestState *s;
- char sbuf[SECRETLEN], hbuf[DESKEYLEN];
+ char sbuf[SECRETLEN];
uchar digest[MD5dlen];
char chal[CHALLEN];
OChapreply reply;
@@ -582,8 +575,7 @@ chap(Ticketreq *tr)
* lookup
*/
secret = findsecret(KEYDB, tr->uid, sbuf);
- hkey = findkey(KEYDB, tr->hostid, hbuf);
- if(hkey == 0 || secret == 0){
+ if(!findkey(KEYDB, tr->hostid, &hkey) || secret == nil){
replyerror("chap-fail bad response %s", raddr);
logfail(tr->uid);
exits(0);
@@ -607,7 +599,7 @@ chap(Ticketreq *tr)
/*
* reply with ticket & authenticator
*/
- if(tickauthreply(tr, hkey) < 0)
+ if(tickauthreply(tr, &hkey) < 0)
exits(0);
if(debug)
@@ -671,8 +663,9 @@ static uchar ntblobsig[] = {0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
void
mschap(Ticketreq *tr)
{
- char *secret, *hkey;
- char sbuf[SECRETLEN], hbuf[DESKEYLEN], windom[128];
+ char *secret;
+ Authkey hkey;
+ char sbuf[SECRETLEN], windom[128];
uchar chal[CHALLEN], ntblob[1024];
uchar hash[MShashlen];
uchar hash2[MShashlen];
@@ -743,8 +736,7 @@ mschap(Ticketreq *tr)
* lookup
*/
secret = findsecret(KEYDB, tr->uid, sbuf);
- hkey = findkey(KEYDB, tr->hostid, hbuf);
- if(hkey == 0 || secret == 0){
+ if(!findkey(KEYDB, tr->hostid, &hkey) || secret == nil){
replyerror("mschap-fail bad response %s/%s(%s)",
tr->uid, tr->hostid, raddr);
logfail(tr->uid);
@@ -812,7 +804,7 @@ mschap(Ticketreq *tr)
/*
* reply with ticket & authenticator
*/
- if(tickauthreply(tr, hkey) < 0)
+ if(tickauthreply(tr, &hkey) < 0)
exits(0);
if(debug)
@@ -939,16 +931,16 @@ speaksfor(char *speaker, char *user)
if(strcmp(speaker, user) == 0)
return 1;
- if(db == 0)
+ if(db == nil)
return 0;
tp = ndbsearch(db, &s, "hostid", speaker);
- if(tp == 0)
+ if(tp == nil)
return 0;
ok = 0;
snprint(notuser, sizeof notuser, "!%s", user);
- for(ntp = tp; ntp; ntp = ntp->entry)
+ for(ntp = tp; ntp != nil; ntp = ntp->entry)
if(strcmp(ntp->attr, "uid") == 0){
if(strcmp(ntp->val, notuser) == 0){
ok = 0;
@@ -1003,9 +995,25 @@ getraddr(char *dir)
}
void
-mkkey(char *k)
+mkkey(Authkey *k)
+{
+ randombytes((uchar*)k->des, DESKEYLEN);
+}
+
+int
+samekey(Authkey *a, Authkey *b)
+{
+ return memcmp(a->des, b->des, DESKEYLEN) == 0;
+}
+
+void
+mkticket(Ticketreq *tr, Ticket *t)
{
- randombytes((uchar*)k, DESKEYLEN);
+ memset(t, 0, sizeof(Ticket));
+ memmove(t->chal, tr->chal, CHALLEN);
+ safecpy(t->cuid, tr->uid, sizeof(t->cuid));
+ safecpy(t->suid, tr->uid, sizeof(t->suid));
+ randombytes((uchar*)t->key, DESKEYLEN);
}
void
@@ -1024,25 +1032,24 @@ randombytes(uchar *buf, int len)
* reply with ticket and authenticator
*/
int
-tickauthreply(Ticketreq *tr, char *hkey)
+tickauthreply(Ticketreq *tr, Authkey *hkey)
{
Ticket t;
Authenticator a;
char buf[TICKETLEN+AUTHENTLEN+1];
+ int n;
- memset(&t, 0, sizeof(t));
- memmove(t.chal, tr->chal, CHALLEN);
- safecpy(t.cuid, tr->uid, sizeof t.cuid);
- safecpy(t.suid, tr->uid, sizeof t.suid);
- mkkey(t.key);
- buf[0] = AuthOK;
+ mkticket(tr, &t);
t.num = AuthTs;
- convT2M(&t, buf+1, hkey);
+ n = 0;
+ buf[n++] = AuthOK;
+ n += convT2M(&t, buf+n, sizeof(buf)-n, hkey);
+ memset(&a, 0, sizeof(a));
memmove(a.chal, t.chal, CHALLEN);
a.num = AuthAc;
a.id = 0;
- convA2M(&a, buf+TICKETLEN+1, t.key);
- if(write(1, buf, TICKETLEN+AUTHENTLEN+1) < 0)
+ n += convA2M(&a, buf+n, sizeof(buf)-n, &t);
+ if(write(1, buf, n) != n)
return -1;
return 0;
}
@@ -1053,3 +1060,4 @@ safecpy(char *to, char *from, int len)
strncpy(to, from, len);
to[len-1] = 0;
}
+