xref: /plan9/sys/src/cmd/auth/guard.srv.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 <fcall.h>
5*219b2ee8SDavid du Colombier #include "authsrv.h"
6*219b2ee8SDavid du Colombier 
7*219b2ee8SDavid du Colombier /*
8*219b2ee8SDavid du Colombier  * c -> a	client
9*219b2ee8SDavid du Colombier  * a -> c	challenge prompt
10*219b2ee8SDavid du Colombier  * c -> a	KC'{challenge}
11*219b2ee8SDavid du Colombier  * a -> c	OK or NO
12*219b2ee8SDavid du Colombier  */
13*219b2ee8SDavid du Colombier 
14*219b2ee8SDavid du Colombier void	catchalarm(void*, char*);
15*219b2ee8SDavid du Colombier void	getraddr(char*);
16*219b2ee8SDavid du Colombier 
17*219b2ee8SDavid du Colombier char	user[NAMELEN];
18*219b2ee8SDavid du Colombier char	raddr[128];
19*219b2ee8SDavid du Colombier 
20*219b2ee8SDavid du Colombier void
21*219b2ee8SDavid du Colombier main(int argc, char *argv[])
22*219b2ee8SDavid du Colombier {
23*219b2ee8SDavid du Colombier 	char ukey[DESKEYLEN], resp[32], buf[NETCHLEN];
24*219b2ee8SDavid du Colombier 	long chal;
25*219b2ee8SDavid du Colombier 	int n;
26*219b2ee8SDavid du Colombier 
27*219b2ee8SDavid du Colombier 	ARGBEGIN{
28*219b2ee8SDavid du Colombier 	}ARGEND;
29*219b2ee8SDavid du Colombier 
30*219b2ee8SDavid du Colombier 	strcpy(raddr, "unknown");
31*219b2ee8SDavid du Colombier 	if(argc >= 1)
32*219b2ee8SDavid du Colombier 		getraddr(argv[argc-1]);
33*219b2ee8SDavid du Colombier 
34*219b2ee8SDavid du Colombier 	argv0 = "guard";
35*219b2ee8SDavid du Colombier 	srand(getpid()*time(0));
36*219b2ee8SDavid du Colombier 	notify(catchalarm);
37*219b2ee8SDavid du Colombier 
38*219b2ee8SDavid du Colombier 	/*
39*219b2ee8SDavid du Colombier 	 * read the host and client and get their keys
40*219b2ee8SDavid du Colombier 	 */
41*219b2ee8SDavid du Colombier 	if(readarg(0, user, sizeof user) < 0)
42*219b2ee8SDavid du Colombier 		fail(0);
43*219b2ee8SDavid du Colombier 
44*219b2ee8SDavid du Colombier 	/*
45*219b2ee8SDavid du Colombier 	 * challenge-response
46*219b2ee8SDavid du Colombier 	 */
47*219b2ee8SDavid du Colombier 	chal = lnrand(MAXNETCHAL);
48*219b2ee8SDavid du Colombier 	sprint(buf, "challenge: %lud\nresponse: ", chal);
49*219b2ee8SDavid du Colombier 	n = strlen(buf) + 1;
50*219b2ee8SDavid du Colombier 	if(write(1, buf, n) != n){
51*219b2ee8SDavid du Colombier 		syslog(0, AUTHLOG, "g-fail %r replying to server");
52*219b2ee8SDavid du Colombier 		exits("replying to server");
53*219b2ee8SDavid du Colombier 	}
54*219b2ee8SDavid du Colombier 	alarm(3*60*1000);
55*219b2ee8SDavid du Colombier 	if(readarg(0, resp, sizeof resp) < 0)
56*219b2ee8SDavid du Colombier 		fail(0);
57*219b2ee8SDavid du Colombier 	alarm(0);
58*219b2ee8SDavid du Colombier 
59*219b2ee8SDavid du Colombier 	if(!findkey(NETKEYDB, user, ukey) || !netcheck(ukey, chal, resp)){
60*219b2ee8SDavid du Colombier 		if(!findkey(KEYDB, user, ukey) || !netcheck(ukey, chal, resp)){
61*219b2ee8SDavid du Colombier 			write(1, "NO", 2);
62*219b2ee8SDavid du Colombier 			syslog(0, AUTHLOG, "g-fail bad response %s", raddr);
63*219b2ee8SDavid du Colombier 			fail(user);
64*219b2ee8SDavid du Colombier 		}
65*219b2ee8SDavid du Colombier 	}
66*219b2ee8SDavid du Colombier 	write(1, "OK", 2);
67*219b2ee8SDavid du Colombier 	syslog(0, AUTHLOG, "g-ok %s %s", user, raddr);
68*219b2ee8SDavid du Colombier 	succeed(user);
69*219b2ee8SDavid du Colombier 	exits(0);
70*219b2ee8SDavid du Colombier }
71*219b2ee8SDavid du Colombier 
72*219b2ee8SDavid du Colombier void
73*219b2ee8SDavid du Colombier catchalarm(void *x, char *msg)
74*219b2ee8SDavid du Colombier {
75*219b2ee8SDavid du Colombier 	USED(x, msg);
76*219b2ee8SDavid du Colombier 	syslog(0, AUTHLOG, "user response timed out");
77*219b2ee8SDavid du Colombier 	fail(0);
78*219b2ee8SDavid du Colombier }
79*219b2ee8SDavid du Colombier 
80*219b2ee8SDavid du Colombier void
81*219b2ee8SDavid du Colombier getraddr(char *dir)
82*219b2ee8SDavid du Colombier {
83*219b2ee8SDavid du Colombier 	int n, fd;
84*219b2ee8SDavid du Colombier 	char *cp;
85*219b2ee8SDavid du Colombier 	char file[3*NAMELEN];
86*219b2ee8SDavid du Colombier 
87*219b2ee8SDavid du Colombier 	snprint(file, sizeof(file), "%s/remote", dir);
88*219b2ee8SDavid du Colombier 	fd = open(file, OREAD);
89*219b2ee8SDavid du Colombier 	if(fd < 0)
90*219b2ee8SDavid du Colombier 		return;
91*219b2ee8SDavid du Colombier 	n = read(fd, raddr, sizeof(raddr)-1);
92*219b2ee8SDavid du Colombier 	close(fd);
93*219b2ee8SDavid du Colombier 	if(n <= 0)
94*219b2ee8SDavid du Colombier 		return;
95*219b2ee8SDavid du Colombier 	raddr[n] = 0;
96*219b2ee8SDavid du Colombier 	cp = strchr(raddr, '\n');
97*219b2ee8SDavid du Colombier 	if(cp)
98*219b2ee8SDavid du Colombier 		*cp = 0;
99*219b2ee8SDavid du Colombier 	cp = strchr(raddr, '!');
100*219b2ee8SDavid du Colombier 	if(cp)
101*219b2ee8SDavid du Colombier 		*cp = 0;
102*219b2ee8SDavid du Colombier }
103