xref: /plan9-contrib/sys/src/9k/boot/doauthenticate.c (revision 9ef1f84b659abcb917c5c090acbce0772e494f21)
1*9ef1f84bSDavid du Colombier #include <u.h>
2*9ef1f84bSDavid du Colombier #include <libc.h>
3*9ef1f84bSDavid du Colombier #include <auth.h>
4*9ef1f84bSDavid du Colombier #include "../boot/boot.h"
5*9ef1f84bSDavid du Colombier 
6*9ef1f84bSDavid du Colombier static char *pbmsg = "AS protocol botch";
7*9ef1f84bSDavid du Colombier static char *ccmsg = "can't connect to AS";
8*9ef1f84bSDavid du Colombier 
9*9ef1f84bSDavid du Colombier long
readn(int fd,void * buf,long len)10*9ef1f84bSDavid du Colombier readn(int fd, void *buf, long len)
11*9ef1f84bSDavid du Colombier {
12*9ef1f84bSDavid du Colombier 	int m, n;
13*9ef1f84bSDavid du Colombier 	char *p;
14*9ef1f84bSDavid du Colombier 
15*9ef1f84bSDavid du Colombier 	p = buf;
16*9ef1f84bSDavid du Colombier 	for(n = 0; n < len; n += m){
17*9ef1f84bSDavid du Colombier 		m = read(fd, p+n, len-n);
18*9ef1f84bSDavid du Colombier 		if(m <= 0)
19*9ef1f84bSDavid du Colombier 			return -1;
20*9ef1f84bSDavid du Colombier 	}
21*9ef1f84bSDavid du Colombier 	return n;
22*9ef1f84bSDavid du Colombier }
23*9ef1f84bSDavid du Colombier 
24*9ef1f84bSDavid du Colombier static char*
fromauth(Method * mp,char * trbuf,char * tbuf)25*9ef1f84bSDavid du Colombier fromauth(Method *mp, char *trbuf, char *tbuf)
26*9ef1f84bSDavid du Colombier {
27*9ef1f84bSDavid du Colombier 	int afd;
28*9ef1f84bSDavid du Colombier 	char t;
29*9ef1f84bSDavid du Colombier 	char *msg;
30*9ef1f84bSDavid du Colombier 	static char error[2*ERRMAX];
31*9ef1f84bSDavid du Colombier 
32*9ef1f84bSDavid du Colombier 	if(mp->auth == 0)
33*9ef1f84bSDavid du Colombier 		fatal("no method for accessing auth server");
34*9ef1f84bSDavid du Colombier 	afd = (*mp->auth)();
35*9ef1f84bSDavid du Colombier 	if(afd < 0) {
36*9ef1f84bSDavid du Colombier 		sprint(error, "%s: %r", ccmsg);
37*9ef1f84bSDavid du Colombier 		return error;
38*9ef1f84bSDavid du Colombier 	}
39*9ef1f84bSDavid du Colombier 
40*9ef1f84bSDavid du Colombier 	if(write(afd, trbuf, TICKREQLEN) < 0 || read(afd, &t, 1) != 1){
41*9ef1f84bSDavid du Colombier 		close(afd);
42*9ef1f84bSDavid du Colombier 		sprint(error, "%s: %r", pbmsg);
43*9ef1f84bSDavid du Colombier 		return error;
44*9ef1f84bSDavid du Colombier 	}
45*9ef1f84bSDavid du Colombier 	switch(t){
46*9ef1f84bSDavid du Colombier 	case AuthOK:
47*9ef1f84bSDavid du Colombier 		msg = 0;
48*9ef1f84bSDavid du Colombier 		if(readn(afd, tbuf, 2*TICKETLEN) < 0) {
49*9ef1f84bSDavid du Colombier 			sprint(error, "%s: %r", pbmsg);
50*9ef1f84bSDavid du Colombier 			msg = error;
51*9ef1f84bSDavid du Colombier 		}
52*9ef1f84bSDavid du Colombier 		break;
53*9ef1f84bSDavid du Colombier 	case AuthErr:
54*9ef1f84bSDavid du Colombier 		if(readn(afd, error, ERRMAX) < 0) {
55*9ef1f84bSDavid du Colombier 			sprint(error, "%s: %r", pbmsg);
56*9ef1f84bSDavid du Colombier 			msg = error;
57*9ef1f84bSDavid du Colombier 		}
58*9ef1f84bSDavid du Colombier 		else {
59*9ef1f84bSDavid du Colombier 			error[ERRMAX-1] = 0;
60*9ef1f84bSDavid du Colombier 			msg = error;
61*9ef1f84bSDavid du Colombier 		}
62*9ef1f84bSDavid du Colombier 		break;
63*9ef1f84bSDavid du Colombier 	default:
64*9ef1f84bSDavid du Colombier 		msg = pbmsg;
65*9ef1f84bSDavid du Colombier 		break;
66*9ef1f84bSDavid du Colombier 	}
67*9ef1f84bSDavid du Colombier 
68*9ef1f84bSDavid du Colombier 	close(afd);
69*9ef1f84bSDavid du Colombier 	return msg;
70*9ef1f84bSDavid du Colombier }
71*9ef1f84bSDavid du Colombier 
72*9ef1f84bSDavid du Colombier void
doauthenticate(int fd,Method * mp)73*9ef1f84bSDavid du Colombier doauthenticate(int fd, Method *mp)
74*9ef1f84bSDavid du Colombier {
75*9ef1f84bSDavid du Colombier 	char *msg;
76*9ef1f84bSDavid du Colombier 	char trbuf[TICKREQLEN];
77*9ef1f84bSDavid du Colombier 	char tbuf[2*TICKETLEN];
78*9ef1f84bSDavid du Colombier 
79*9ef1f84bSDavid du Colombier 	print("session...");
80*9ef1f84bSDavid du Colombier 	if(fsession(fd, trbuf, sizeof trbuf) < 0)
81*9ef1f84bSDavid du Colombier 		fatal("session command failed");
82*9ef1f84bSDavid du Colombier 
83*9ef1f84bSDavid du Colombier 	/* no authentication required? */
84*9ef1f84bSDavid du Colombier 	memset(tbuf, 0, 2*TICKETLEN);
85*9ef1f84bSDavid du Colombier 	if(trbuf[0] == 0)
86*9ef1f84bSDavid du Colombier 		return;
87*9ef1f84bSDavid du Colombier 
88*9ef1f84bSDavid du Colombier 	/* try getting to an auth server */
89*9ef1f84bSDavid du Colombier 	print("getting ticket...");
90*9ef1f84bSDavid du Colombier 	msg = fromauth(mp, trbuf, tbuf);
91*9ef1f84bSDavid du Colombier 	print("authenticating...");
92*9ef1f84bSDavid du Colombier 	if(msg == 0)
93*9ef1f84bSDavid du Colombier 		if(fauth(fd, tbuf) >= 0)
94*9ef1f84bSDavid du Colombier 			return;
95*9ef1f84bSDavid du Colombier 
96*9ef1f84bSDavid du Colombier 	/* didn't work, go for the security hole */
97*9ef1f84bSDavid du Colombier 	fprint(2, "no authentication server (%s), using your key as server key\n", msg);
98*9ef1f84bSDavid du Colombier }
99*9ef1f84bSDavid du Colombier 
100*9ef1f84bSDavid du Colombier char*
checkkey(Method * mp,char * name,char * key)101*9ef1f84bSDavid du Colombier checkkey(Method *mp, char *name, char *key)
102*9ef1f84bSDavid du Colombier {
103*9ef1f84bSDavid du Colombier 	char *msg;
104*9ef1f84bSDavid du Colombier 	Ticketreq tr;
105*9ef1f84bSDavid du Colombier 	Ticket t;
106*9ef1f84bSDavid du Colombier 	char trbuf[TICKREQLEN];
107*9ef1f84bSDavid du Colombier 	char tbuf[TICKETLEN];
108*9ef1f84bSDavid du Colombier 
109*9ef1f84bSDavid du Colombier 	memset(&tr, 0, sizeof tr);
110*9ef1f84bSDavid du Colombier 	tr.type = AuthTreq;
111*9ef1f84bSDavid du Colombier 	strcpy(tr.authid, name);
112*9ef1f84bSDavid du Colombier 	strcpy(tr.hostid, name);
113*9ef1f84bSDavid du Colombier 	strcpy(tr.uid, name);
114*9ef1f84bSDavid du Colombier 	convTR2M(&tr, trbuf);
115*9ef1f84bSDavid du Colombier 	msg = fromauth(mp, trbuf, tbuf);
116*9ef1f84bSDavid du Colombier 	if(msg == ccmsg){
117*9ef1f84bSDavid du Colombier 		fprint(2, "boot: can't contact auth server, passwd unchecked\n");
118*9ef1f84bSDavid du Colombier 		return 0;
119*9ef1f84bSDavid du Colombier 	}
120*9ef1f84bSDavid du Colombier 	if(msg)
121*9ef1f84bSDavid du Colombier 		return msg;
122*9ef1f84bSDavid du Colombier 	convM2T(tbuf, &t, key);
123*9ef1f84bSDavid du Colombier 	if(t.num == AuthTc && strcmp(name, t.cuid)==0)
124*9ef1f84bSDavid du Colombier 		return 0;
125*9ef1f84bSDavid du Colombier 	return "no match";
126*9ef1f84bSDavid du Colombier }
127