xref: /plan9/sys/src/cmd/auth/guard.srv.c (revision f54edc786b9c49b2c7ab1c0695cdc8c698b11f4d)
17c70c028SDavid du Colombier /*
27c70c028SDavid du Colombier  * guard service
37c70c028SDavid du Colombier  */
4219b2ee8SDavid du Colombier #include <u.h>
5219b2ee8SDavid du Colombier #include <libc.h>
6219b2ee8SDavid du Colombier #include <fcall.h>
77dd7cddfSDavid du Colombier #include <bio.h>
87dd7cddfSDavid du Colombier #include <ndb.h>
99a747e4fSDavid du Colombier #include <authsrv.h>
109a747e4fSDavid du Colombier #include "authcmdlib.h"
11219b2ee8SDavid du Colombier 
127c70c028SDavid du Colombier enum {
137c70c028SDavid du Colombier 	Pinlen = 4,
147c70c028SDavid du Colombier };
157c70c028SDavid du Colombier 
16219b2ee8SDavid du Colombier /*
17219b2ee8SDavid du Colombier  * c -> a	client
18219b2ee8SDavid du Colombier  * a -> c	challenge prompt
19219b2ee8SDavid du Colombier  * c -> a	KC'{challenge}
20219b2ee8SDavid du Colombier  * a -> c	OK or NO
21219b2ee8SDavid du Colombier  */
22219b2ee8SDavid du Colombier 
23219b2ee8SDavid du Colombier void	catchalarm(void*, char*);
24219b2ee8SDavid du Colombier void	getraddr(char*);
25219b2ee8SDavid du Colombier 
269a747e4fSDavid du Colombier char	user[ANAMELEN];
27219b2ee8SDavid du Colombier char	raddr[128];
287dd7cddfSDavid du Colombier int	debug;
297dd7cddfSDavid du Colombier Ndb	*db;
30219b2ee8SDavid du Colombier 
31219b2ee8SDavid du Colombier void
main(int argc,char * argv[])32219b2ee8SDavid du Colombier main(int argc, char *argv[])
33219b2ee8SDavid du Colombier {
34219b2ee8SDavid du Colombier 	int n;
357c70c028SDavid du Colombier 	long chal;
363ff48bf5SDavid du Colombier 	char *err;
377c70c028SDavid du Colombier 	char ukey[DESKEYLEN], resp[32], buf[NETCHLEN];
387c70c028SDavid du Colombier 	Ndb *db2;
39219b2ee8SDavid du Colombier 
40219b2ee8SDavid du Colombier 	ARGBEGIN{
417dd7cddfSDavid du Colombier 	case 'd':
427dd7cddfSDavid du Colombier 		debug = 1;
437dd7cddfSDavid du Colombier 		break;
44219b2ee8SDavid du Colombier 	}ARGEND;
45219b2ee8SDavid du Colombier 
467dd7cddfSDavid du Colombier 	db = ndbopen("/lib/ndb/auth");
477dd7cddfSDavid du Colombier 	if(db == 0)
4880ee5cbfSDavid du Colombier 		syslog(0, AUTHLOG, "no /lib/ndb/auth");
499a747e4fSDavid du Colombier 	db2 = ndbopen(0);
5080ee5cbfSDavid du Colombier 	if(db2 == 0)
5180ee5cbfSDavid du Colombier 		syslog(0, AUTHLOG, "no /lib/ndb/local");
5280ee5cbfSDavid du Colombier 	db = ndbcat(db, db2);
537c70c028SDavid du Colombier 	werrstr("");
547dd7cddfSDavid du Colombier 
55219b2ee8SDavid du Colombier 	strcpy(raddr, "unknown");
56219b2ee8SDavid du Colombier 	if(argc >= 1)
57219b2ee8SDavid du Colombier 		getraddr(argv[argc-1]);
58219b2ee8SDavid du Colombier 
59219b2ee8SDavid du Colombier 	argv0 = "guard";
607dd7cddfSDavid du Colombier 	srand((getpid()*1103515245)^time(0));
61219b2ee8SDavid du Colombier 	notify(catchalarm);
62219b2ee8SDavid du Colombier 
63219b2ee8SDavid du Colombier 	/*
64219b2ee8SDavid du Colombier 	 * read the host and client and get their keys
65219b2ee8SDavid du Colombier 	 */
66219b2ee8SDavid du Colombier 	if(readarg(0, user, sizeof user) < 0)
67219b2ee8SDavid du Colombier 		fail(0);
68219b2ee8SDavid du Colombier 
69219b2ee8SDavid du Colombier 	/*
70219b2ee8SDavid du Colombier 	 * challenge-response
71219b2ee8SDavid du Colombier 	 */
72219b2ee8SDavid du Colombier 	chal = lnrand(MAXNETCHAL);
73*f54edc78SDavid du Colombier 	snprint(buf, sizeof buf, "challenge: %lud\nresponse: ", chal);
74219b2ee8SDavid du Colombier 	n = strlen(buf) + 1;
75219b2ee8SDavid du Colombier 	if(write(1, buf, n) != n){
767dd7cddfSDavid du Colombier 		if(debug)
777dd7cddfSDavid du Colombier 			syslog(0, AUTHLOG, "g-fail %s@%s: %r sending chal",
787dd7cddfSDavid du Colombier 				user, raddr);
79219b2ee8SDavid du Colombier 		exits("replying to server");
80219b2ee8SDavid du Colombier 	}
81219b2ee8SDavid du Colombier 	alarm(3*60*1000);
827c70c028SDavid du Colombier 	werrstr("");
837dd7cddfSDavid du Colombier 	if(readarg(0, resp, sizeof resp) < 0){
847dd7cddfSDavid du Colombier 		if(debug)
857dd7cddfSDavid du Colombier 			syslog(0, AUTHLOG, "g-fail %s@%s: %r reading resp",
867dd7cddfSDavid du Colombier 				user, raddr);
87219b2ee8SDavid du Colombier 		fail(0);
887dd7cddfSDavid du Colombier 	}
89219b2ee8SDavid du Colombier 	alarm(0);
90219b2ee8SDavid du Colombier 
917c70c028SDavid du Colombier 	/* remove password login from guard.research.bell-labs.com, sucre, etc. */
927c70c028SDavid du Colombier //	if(!findkey(KEYDB,    user, ukey) || !netcheck(ukey, chal, resp))
937dd7cddfSDavid du Colombier 	if(!findkey(NETKEYDB, user, ukey) || !netcheck(ukey, chal, resp))
943ff48bf5SDavid du Colombier 	if((err = secureidcheck(user, resp)) != nil){
953ff48bf5SDavid du Colombier 		print("NO %s", err);
96219b2ee8SDavid du Colombier 		write(1, "NO", 2);
977c70c028SDavid du Colombier 		if(debug) {
987c70c028SDavid du Colombier 			char *r;
997c70c028SDavid du Colombier 
1007c70c028SDavid du Colombier 			/*
1017c70c028SDavid du Colombier 			 * don't log the entire response, since the first
1027c70c028SDavid du Colombier 			 * Pinlen digits may be the user's secure-id pin.
1037c70c028SDavid du Colombier 			 */
1047c70c028SDavid du Colombier 			if (strlen(resp) < Pinlen)
1057c70c028SDavid du Colombier 				r = strdup("<too short for pin>");
1067c70c028SDavid du Colombier 			else if (strlen(resp) == Pinlen)
1077c70c028SDavid du Colombier 				r = strdup("<pin only>");
1087c70c028SDavid du Colombier 			else
1097c70c028SDavid du Colombier 				r = smprint("%.*s%s", Pinlen,
1107c70c028SDavid du Colombier 					"******************", resp + Pinlen);
1117c70c028SDavid du Colombier 			syslog(0, AUTHLOG,
1127c70c028SDavid du Colombier 				"g-fail %s@%s: %s: resp %s to chal %lud",
1137c70c028SDavid du Colombier 				user, raddr, err, r, chal);
1147c70c028SDavid du Colombier 			free(r);
1157c70c028SDavid du Colombier 		}
116219b2ee8SDavid du Colombier 		fail(user);
117219b2ee8SDavid du Colombier 	}
118219b2ee8SDavid du Colombier 	write(1, "OK", 2);
1197dd7cddfSDavid du Colombier 	if(debug)
1207dd7cddfSDavid du Colombier 		syslog(0, AUTHLOG, "g-ok %s@%s", user, raddr);
121219b2ee8SDavid du Colombier 	succeed(user);
122219b2ee8SDavid du Colombier 	exits(0);
123219b2ee8SDavid du Colombier }
124219b2ee8SDavid du Colombier 
125219b2ee8SDavid du Colombier void
catchalarm(void * x,char * msg)126219b2ee8SDavid du Colombier catchalarm(void *x, char *msg)
127219b2ee8SDavid du Colombier {
128219b2ee8SDavid du Colombier 	USED(x, msg);
1297dd7cddfSDavid du Colombier 	if(debug)
1307dd7cddfSDavid du Colombier 		syslog(0, AUTHLOG, "g-timed out %s", raddr);
131219b2ee8SDavid du Colombier 	fail(0);
132219b2ee8SDavid du Colombier }
133219b2ee8SDavid du Colombier 
134219b2ee8SDavid du Colombier void
getraddr(char * dir)135219b2ee8SDavid du Colombier getraddr(char *dir)
136219b2ee8SDavid du Colombier {
137219b2ee8SDavid du Colombier 	int n, fd;
138219b2ee8SDavid du Colombier 	char *cp;
1399a747e4fSDavid du Colombier 	char file[128];
140219b2ee8SDavid du Colombier 
141219b2ee8SDavid du Colombier 	snprint(file, sizeof(file), "%s/remote", dir);
142219b2ee8SDavid du Colombier 	fd = open(file, OREAD);
143219b2ee8SDavid du Colombier 	if(fd < 0)
144219b2ee8SDavid du Colombier 		return;
145219b2ee8SDavid du Colombier 	n = read(fd, raddr, sizeof(raddr)-1);
146219b2ee8SDavid du Colombier 	close(fd);
147219b2ee8SDavid du Colombier 	if(n <= 0)
148219b2ee8SDavid du Colombier 		return;
149219b2ee8SDavid du Colombier 	raddr[n] = 0;
150219b2ee8SDavid du Colombier 	cp = strchr(raddr, '\n');
151219b2ee8SDavid du Colombier 	if(cp)
152219b2ee8SDavid du Colombier 		*cp = 0;
153219b2ee8SDavid du Colombier 	cp = strchr(raddr, '!');
154219b2ee8SDavid du Colombier 	if(cp)
155219b2ee8SDavid du Colombier 		*cp = 0;
156219b2ee8SDavid du Colombier }
157