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