xref: /plan9/sys/src/9/boot/doauthenticate.c (revision 9a747e4fd48b9f4522c70c07e8f882a15030f964)
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