xref: /plan9/sys/src/cmd/auth/guard.srv.c (revision f54edc786b9c49b2c7ab1c0695cdc8c698b11f4d)
1 /*
2  * guard service
3  */
4 #include <u.h>
5 #include <libc.h>
6 #include <fcall.h>
7 #include <bio.h>
8 #include <ndb.h>
9 #include <authsrv.h>
10 #include "authcmdlib.h"
11 
12 enum {
13 	Pinlen = 4,
14 };
15 
16 /*
17  * c -> a	client
18  * a -> c	challenge prompt
19  * c -> a	KC'{challenge}
20  * a -> c	OK or NO
21  */
22 
23 void	catchalarm(void*, char*);
24 void	getraddr(char*);
25 
26 char	user[ANAMELEN];
27 char	raddr[128];
28 int	debug;
29 Ndb	*db;
30 
31 void
main(int argc,char * argv[])32 main(int argc, char *argv[])
33 {
34 	int n;
35 	long chal;
36 	char *err;
37 	char ukey[DESKEYLEN], resp[32], buf[NETCHLEN];
38 	Ndb *db2;
39 
40 	ARGBEGIN{
41 	case 'd':
42 		debug = 1;
43 		break;
44 	}ARGEND;
45 
46 	db = ndbopen("/lib/ndb/auth");
47 	if(db == 0)
48 		syslog(0, AUTHLOG, "no /lib/ndb/auth");
49 	db2 = ndbopen(0);
50 	if(db2 == 0)
51 		syslog(0, AUTHLOG, "no /lib/ndb/local");
52 	db = ndbcat(db, db2);
53 	werrstr("");
54 
55 	strcpy(raddr, "unknown");
56 	if(argc >= 1)
57 		getraddr(argv[argc-1]);
58 
59 	argv0 = "guard";
60 	srand((getpid()*1103515245)^time(0));
61 	notify(catchalarm);
62 
63 	/*
64 	 * read the host and client and get their keys
65 	 */
66 	if(readarg(0, user, sizeof user) < 0)
67 		fail(0);
68 
69 	/*
70 	 * challenge-response
71 	 */
72 	chal = lnrand(MAXNETCHAL);
73 	snprint(buf, sizeof buf, "challenge: %lud\nresponse: ", chal);
74 	n = strlen(buf) + 1;
75 	if(write(1, buf, n) != n){
76 		if(debug)
77 			syslog(0, AUTHLOG, "g-fail %s@%s: %r sending chal",
78 				user, raddr);
79 		exits("replying to server");
80 	}
81 	alarm(3*60*1000);
82 	werrstr("");
83 	if(readarg(0, resp, sizeof resp) < 0){
84 		if(debug)
85 			syslog(0, AUTHLOG, "g-fail %s@%s: %r reading resp",
86 				user, raddr);
87 		fail(0);
88 	}
89 	alarm(0);
90 
91 	/* remove password login from guard.research.bell-labs.com, sucre, etc. */
92 //	if(!findkey(KEYDB,    user, ukey) || !netcheck(ukey, chal, resp))
93 	if(!findkey(NETKEYDB, user, ukey) || !netcheck(ukey, chal, resp))
94 	if((err = secureidcheck(user, resp)) != nil){
95 		print("NO %s", err);
96 		write(1, "NO", 2);
97 		if(debug) {
98 			char *r;
99 
100 			/*
101 			 * don't log the entire response, since the first
102 			 * Pinlen digits may be the user's secure-id pin.
103 			 */
104 			if (strlen(resp) < Pinlen)
105 				r = strdup("<too short for pin>");
106 			else if (strlen(resp) == Pinlen)
107 				r = strdup("<pin only>");
108 			else
109 				r = smprint("%.*s%s", Pinlen,
110 					"******************", resp + Pinlen);
111 			syslog(0, AUTHLOG,
112 				"g-fail %s@%s: %s: resp %s to chal %lud",
113 				user, raddr, err, r, chal);
114 			free(r);
115 		}
116 		fail(user);
117 	}
118 	write(1, "OK", 2);
119 	if(debug)
120 		syslog(0, AUTHLOG, "g-ok %s@%s", user, raddr);
121 	succeed(user);
122 	exits(0);
123 }
124 
125 void
catchalarm(void * x,char * msg)126 catchalarm(void *x, char *msg)
127 {
128 	USED(x, msg);
129 	if(debug)
130 		syslog(0, AUTHLOG, "g-timed out %s", raddr);
131 	fail(0);
132 }
133 
134 void
getraddr(char * dir)135 getraddr(char *dir)
136 {
137 	int n, fd;
138 	char *cp;
139 	char file[128];
140 
141 	snprint(file, sizeof(file), "%s/remote", dir);
142 	fd = open(file, OREAD);
143 	if(fd < 0)
144 		return;
145 	n = read(fd, raddr, sizeof(raddr)-1);
146 	close(fd);
147 	if(n <= 0)
148 		return;
149 	raddr[n] = 0;
150 	cp = strchr(raddr, '\n');
151 	if(cp)
152 		*cp = 0;
153 	cp = strchr(raddr, '!');
154 	if(cp)
155 		*cp = 0;
156 }
157