ref: bf4f158707ebfeacb15826ad4283ff247d7d81ae
dir: /sys/src/cmd/auth/guard.srv.c/
/* * guard service */ #include <u.h> #include <libc.h> #include <fcall.h> #include <bio.h> #include <ndb.h> #include <libsec.h> #include <authsrv.h> #include "authcmdlib.h" enum { Pinlen = 4, }; /* * c -> a client * a -> c challenge prompt * c -> a KC'{challenge} * a -> c OK or NO */ void catchalarm(void*, char*); void getraddr(char*); char user[ANAMELEN]; char raddr[128]; int debug; Ndb *db; void main(int argc, char *argv[]) { int n; long chal; char *err; char ukey[DESKEYLEN], resp[32], buf[NETCHLEN]; Ndb *db2; ARGBEGIN{ case 'd': debug = 1; break; }ARGEND; db = ndbopen("/lib/ndb/auth"); if(db == 0) syslog(0, AUTHLOG, "no /lib/ndb/auth"); db2 = ndbopen(0); if(db2 == 0) syslog(0, AUTHLOG, "no /lib/ndb/local"); db = ndbcat(db, db2); werrstr(""); strcpy(raddr, "unknown"); if(argc >= 1) getraddr(argv[argc-1]); argv0 = "guard"; notify(catchalarm); /* * read the host and client and get their keys */ if(readarg(0, user, sizeof user) < 0) fail(0); /* * challenge-response */ chal = nfastrand(MAXNETCHAL); sprint(buf, "challenge: %lud\nresponse: ", chal); n = strlen(buf) + 1; if(write(1, buf, n) != n){ if(debug) syslog(0, AUTHLOG, "g-fail %s@%s: %r sending chal", user, raddr); exits("replying to server"); } alarm(3*60*1000); werrstr(""); if(readarg(0, resp, sizeof resp) < 0){ if(debug) syslog(0, AUTHLOG, "g-fail %s@%s: %r reading resp", user, raddr); fail(0); } alarm(0); /* remove password login from guard.research.bell-labs.com, sucre, etc. */ if(!finddeskey(NETKEYDB, user, ukey) || !netcheck(ukey, chal, resp)) if((err = secureidcheck(user, resp)) != nil){ print("NO %s", err); write(1, "NO", 2); if(debug) { char *r; /* * don't log the entire response, since the first * Pinlen digits may be the user's secure-id pin. */ if (strlen(resp) < Pinlen) r = strdup("<too short for pin>"); else if (strlen(resp) == Pinlen) r = strdup("<pin only>"); else r = smprint("%.*s%s", Pinlen, "******************", resp + Pinlen); syslog(0, AUTHLOG, "g-fail %s@%s: %s: resp %s to chal %lud", user, raddr, err, r, chal); free(r); } fail(user); } write(1, "OK", 2); if(debug) syslog(0, AUTHLOG, "g-ok %s@%s", user, raddr); succeed(user); exits(0); } void catchalarm(void *x, char *msg) { USED(x, msg); if(debug) syslog(0, AUTHLOG, "g-timed out %s", raddr); fail(0); } void getraddr(char *dir) { int n, fd; char *cp; char file[128]; snprint(file, sizeof(file), "%s/remote", dir); fd = open(file, OREAD); if(fd < 0) return; n = read(fd, raddr, sizeof(raddr)-1); close(fd); if(n <= 0) return; raddr[n] = 0; cp = strchr(raddr, '\n'); if(cp) *cp = 0; cp = strchr(raddr, '!'); if(cp) *cp = 0; }