1219b2ee8SDavid du Colombier #include <u.h>
2219b2ee8SDavid du Colombier #include <libc.h>
3219b2ee8SDavid du Colombier #include <auth.h>
47dd7cddfSDavid du Colombier #include "../boot/boot.h"
5219b2ee8SDavid du Colombier
6219b2ee8SDavid du Colombier static char *pbmsg = "AS protocol botch";
7219b2ee8SDavid du Colombier static char *ccmsg = "can't connect to AS";
8219b2ee8SDavid du Colombier
97dd7cddfSDavid du Colombier long
readn(int fd,void * buf,long len)107dd7cddfSDavid du Colombier readn(int fd, void *buf, long len)
11219b2ee8SDavid du Colombier {
12219b2ee8SDavid du Colombier int m, n;
137dd7cddfSDavid du Colombier char *p;
14219b2ee8SDavid du Colombier
157dd7cddfSDavid du Colombier p = buf;
16219b2ee8SDavid du Colombier for(n = 0; n < len; n += m){
177dd7cddfSDavid du Colombier m = read(fd, p+n, len-n);
18219b2ee8SDavid du Colombier if(m <= 0)
19219b2ee8SDavid du Colombier return -1;
20219b2ee8SDavid du Colombier }
21219b2ee8SDavid du Colombier return n;
22219b2ee8SDavid du Colombier }
23219b2ee8SDavid du Colombier
24219b2ee8SDavid du Colombier static char*
fromauth(Method * mp,char * trbuf,char * tbuf)25219b2ee8SDavid du Colombier fromauth(Method *mp, char *trbuf, char *tbuf)
26219b2ee8SDavid du Colombier {
277dd7cddfSDavid du Colombier int afd;
28219b2ee8SDavid du Colombier char t;
29219b2ee8SDavid du Colombier char *msg;
30*9a747e4fSDavid du Colombier static char error[2*ERRMAX];
31219b2ee8SDavid du Colombier
32219b2ee8SDavid du Colombier if(mp->auth == 0)
33219b2ee8SDavid du Colombier fatal("no method for accessing auth server");
34219b2ee8SDavid du Colombier afd = (*mp->auth)();
357dd7cddfSDavid du Colombier if(afd < 0) {
367dd7cddfSDavid du Colombier sprint(error, "%s: %r", ccmsg);
377dd7cddfSDavid du Colombier return error;
38219b2ee8SDavid du Colombier }
397dd7cddfSDavid du Colombier
40219b2ee8SDavid du Colombier if(write(afd, trbuf, TICKREQLEN) < 0 || read(afd, &t, 1) != 1){
41219b2ee8SDavid du Colombier close(afd);
427dd7cddfSDavid du Colombier sprint(error, "%s: %r", pbmsg);
437dd7cddfSDavid du Colombier return error;
44219b2ee8SDavid du Colombier }
45219b2ee8SDavid du Colombier switch(t){
46219b2ee8SDavid du Colombier case AuthOK:
47219b2ee8SDavid du Colombier msg = 0;
487dd7cddfSDavid du Colombier if(readn(afd, tbuf, 2*TICKETLEN) < 0) {
497dd7cddfSDavid du Colombier sprint(error, "%s: %r", pbmsg);
507dd7cddfSDavid du Colombier msg = error;
517dd7cddfSDavid du Colombier }
52219b2ee8SDavid du Colombier break;
53219b2ee8SDavid du Colombier case AuthErr:
54*9a747e4fSDavid du Colombier if(readn(afd, error, ERRMAX) < 0) {
557dd7cddfSDavid du Colombier sprint(error, "%s: %r", pbmsg);
567dd7cddfSDavid du Colombier msg = error;
577dd7cddfSDavid du Colombier }
58219b2ee8SDavid du Colombier else {
59*9a747e4fSDavid du Colombier error[ERRMAX-1] = 0;
60219b2ee8SDavid du Colombier msg = error;
61219b2ee8SDavid du Colombier }
62219b2ee8SDavid du Colombier break;
63219b2ee8SDavid du Colombier default:
64219b2ee8SDavid du Colombier msg = pbmsg;
65219b2ee8SDavid du Colombier break;
66219b2ee8SDavid du Colombier }
677dd7cddfSDavid du Colombier
687dd7cddfSDavid du Colombier close(afd);
69219b2ee8SDavid du Colombier return msg;
70219b2ee8SDavid du Colombier }
71219b2ee8SDavid du Colombier
72219b2ee8SDavid du Colombier void
doauthenticate(int fd,Method * mp)73219b2ee8SDavid du Colombier doauthenticate(int fd, Method *mp)
74219b2ee8SDavid du Colombier {
75219b2ee8SDavid du Colombier char *msg;
76219b2ee8SDavid du Colombier char trbuf[TICKREQLEN];
77219b2ee8SDavid du Colombier char tbuf[2*TICKETLEN];
78219b2ee8SDavid du Colombier
79219b2ee8SDavid du Colombier print("session...");
80*9a747e4fSDavid du Colombier if(fsession(fd, trbuf, sizeof trbuf) < 0)
81219b2ee8SDavid du Colombier fatal("session command failed");
82219b2ee8SDavid du Colombier
83219b2ee8SDavid du Colombier /* no authentication required? */
84219b2ee8SDavid du Colombier memset(tbuf, 0, 2*TICKETLEN);
85219b2ee8SDavid du Colombier if(trbuf[0] == 0)
86219b2ee8SDavid du Colombier return;
87219b2ee8SDavid du Colombier
88219b2ee8SDavid du Colombier /* try getting to an auth server */
89*9a747e4fSDavid du Colombier print("getting ticket...");
90219b2ee8SDavid du Colombier msg = fromauth(mp, trbuf, tbuf);
91*9a747e4fSDavid du Colombier print("authenticating...");
92219b2ee8SDavid du Colombier if(msg == 0)
93219b2ee8SDavid du Colombier if(fauth(fd, tbuf) >= 0)
94219b2ee8SDavid du Colombier return;
95219b2ee8SDavid du Colombier
96219b2ee8SDavid du Colombier /* didn't work, go for the security hole */
97219b2ee8SDavid du Colombier fprint(2, "no authentication server (%s), using your key as server key\n", msg);
98219b2ee8SDavid du Colombier }
99219b2ee8SDavid du Colombier
100219b2ee8SDavid du Colombier char*
checkkey(Method * mp,char * name,char * key)101219b2ee8SDavid du Colombier checkkey(Method *mp, char *name, char *key)
102219b2ee8SDavid du Colombier {
103219b2ee8SDavid du Colombier char *msg;
104219b2ee8SDavid du Colombier Ticketreq tr;
105219b2ee8SDavid du Colombier Ticket t;
106219b2ee8SDavid du Colombier char trbuf[TICKREQLEN];
107219b2ee8SDavid du Colombier char tbuf[TICKETLEN];
108219b2ee8SDavid du Colombier
109219b2ee8SDavid du Colombier memset(&tr, 0, sizeof tr);
110219b2ee8SDavid du Colombier tr.type = AuthTreq;
111219b2ee8SDavid du Colombier strcpy(tr.authid, name);
112219b2ee8SDavid du Colombier strcpy(tr.hostid, name);
113219b2ee8SDavid du Colombier strcpy(tr.uid, name);
114219b2ee8SDavid du Colombier convTR2M(&tr, trbuf);
115219b2ee8SDavid du Colombier msg = fromauth(mp, trbuf, tbuf);
116219b2ee8SDavid du Colombier if(msg == ccmsg){
117219b2ee8SDavid du Colombier fprint(2, "boot: can't contact auth server, passwd unchecked\n");
118219b2ee8SDavid du Colombier return 0;
119219b2ee8SDavid du Colombier }
120219b2ee8SDavid du Colombier if(msg)
121219b2ee8SDavid du Colombier return msg;
122219b2ee8SDavid du Colombier convM2T(tbuf, &t, key);
123219b2ee8SDavid du Colombier if(t.num == AuthTc && strcmp(name, t.cuid)==0)
124219b2ee8SDavid du Colombier return 0;
125219b2ee8SDavid du Colombier return "no match";
126219b2ee8SDavid du Colombier }
127