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