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