1 6e527fbc 2005-02-13 devnull /* network login client */
2 6e527fbc 2005-02-13 devnull #include <u.h>
3 6e527fbc 2005-02-13 devnull #include <libc.h>
4 6e527fbc 2005-02-13 devnull #include <mp.h>
5 6e527fbc 2005-02-13 devnull #include <libsec.h>
6 6e527fbc 2005-02-13 devnull #include <authsrv.h>
7 6e527fbc 2005-02-13 devnull #include "SConn.h"
8 6e527fbc 2005-02-13 devnull #include "secstore.h"
9 6e527fbc 2005-02-13 devnull enum{ CHK = 16, MAXFILES = 100 };
11 6e527fbc 2005-02-13 devnull typedef struct AuthConn{
12 6e527fbc 2005-02-13 devnull SConn *conn;
13 6e527fbc 2005-02-13 devnull char pass[64];
14 6e527fbc 2005-02-13 devnull int passlen;
15 6e527fbc 2005-02-13 devnull } AuthConn;
17 6e527fbc 2005-02-13 devnull int verbose;
18 6e527fbc 2005-02-13 devnull Nvrsafe nvr;
19 6e527fbc 2005-02-13 devnull char *SECSTORE_DIR;
22 6e527fbc 2005-02-13 devnull usage(void)
24 6e527fbc 2005-02-13 devnull fprint(2, "usage: secstore [-cin] [-g getfile] [-p putfile] [-r rmfile] [-s tcp!server!5356] [-u user] [-v]\n");
25 6e527fbc 2005-02-13 devnull exits("usage");
28 6e527fbc 2005-02-13 devnull static int
29 6e527fbc 2005-02-13 devnull getfile(SConn *conn, char *gf, uchar **buf, ulong *buflen, uchar *key, int nkey)
31 6e527fbc 2005-02-13 devnull int fd = -1;
32 6e527fbc 2005-02-13 devnull int i, n, nr, nw, len;
33 6e527fbc 2005-02-13 devnull char s[Maxmsg+1];
34 6e527fbc 2005-02-13 devnull uchar skey[SHA1dlen], ib[Maxmsg+CHK], *ibr, *ibw, *bufw, *bufe;
35 6e527fbc 2005-02-13 devnull AESstate aes;
36 6e527fbc 2005-02-13 devnull DigestState *sha;
38 6e527fbc 2005-02-13 devnull if(strchr(gf, '/')){
39 6e527fbc 2005-02-13 devnull fprint(2, "simple filenames, not paths like %s\n", gf);
40 6e527fbc 2005-02-13 devnull return -1;
42 6e527fbc 2005-02-13 devnull memset(&aes, 0, sizeof aes);
44 6e527fbc 2005-02-13 devnull snprint(s, Maxmsg, "GET %s\n", gf);
45 6e527fbc 2005-02-13 devnull conn->write(conn, (uchar*)s, strlen(s));
47 6e527fbc 2005-02-13 devnull /* get file size */
48 6e527fbc 2005-02-13 devnull s[0] = '\0';
49 6e527fbc 2005-02-13 devnull bufw = bufe = nil;
50 6e527fbc 2005-02-13 devnull if(readstr(conn, s) < 0){
51 6e527fbc 2005-02-13 devnull fprint(2, "remote: %s\n", s);
52 6e527fbc 2005-02-13 devnull return -1;
54 6e527fbc 2005-02-13 devnull len = atoi(s);
55 6e527fbc 2005-02-13 devnull if(len == -1){
56 6e527fbc 2005-02-13 devnull fprint(2, "remote file %s does not exist\n", gf);
57 6e527fbc 2005-02-13 devnull return -1;
58 6e527fbc 2005-02-13 devnull }else if(len == -3){
59 6e527fbc 2005-02-13 devnull fprint(2, "implausible filesize for %s\n", gf);
60 6e527fbc 2005-02-13 devnull return -1;
61 6e527fbc 2005-02-13 devnull }else if(len < 0){
62 6e527fbc 2005-02-13 devnull fprint(2, "GET refused for %s\n", gf);
63 6e527fbc 2005-02-13 devnull return -1;
65 6e527fbc 2005-02-13 devnull if(buf != nil){
66 6e527fbc 2005-02-13 devnull *buflen = len - AESbsize - CHK;
67 6e527fbc 2005-02-13 devnull *buf = bufw = emalloc(len);
68 6e527fbc 2005-02-13 devnull bufe = bufw + len;
71 6e527fbc 2005-02-13 devnull /* directory listing */
72 6e527fbc 2005-02-13 devnull if(strcmp(gf,".")==0){
73 6e527fbc 2005-02-13 devnull if(buf != nil)
74 6e527fbc 2005-02-13 devnull *buflen = len;
75 6e527fbc 2005-02-13 devnull for(i=0; i < len; i += n){
76 6e527fbc 2005-02-13 devnull if((n = conn->read(conn, (uchar*)s, Maxmsg)) <= 0){
77 6e527fbc 2005-02-13 devnull fprint(2, "empty file chunk\n");
78 6e527fbc 2005-02-13 devnull return -1;
80 6e527fbc 2005-02-13 devnull if(buf == nil)
81 6e527fbc 2005-02-13 devnull write(1, s, n);
83 6e527fbc 2005-02-13 devnull memmove((*buf)+i, s, n);
85 6e527fbc 2005-02-13 devnull return 0;
88 6e527fbc 2005-02-13 devnull /* conn is already encrypted against wiretappers,
89 6e527fbc 2005-02-13 devnull but gf is also encrypted against server breakin. */
90 6e527fbc 2005-02-13 devnull if(buf == nil && (fd =create(gf, OWRITE, 0600)) < 0){
91 6e527fbc 2005-02-13 devnull fprint(2, "can't open %s: %r\n", gf);
92 6e527fbc 2005-02-13 devnull return -1;
95 6e527fbc 2005-02-13 devnull ibr = ibw = ib;
96 6e527fbc 2005-02-13 devnull for(nr=0; nr < len;){
97 6e527fbc 2005-02-13 devnull if((n = conn->read(conn, ibw, Maxmsg)) <= 0){
98 6e527fbc 2005-02-13 devnull fprint(2, "empty file chunk n=%d nr=%d len=%d: %r\n", n, nr, len);
99 6e527fbc 2005-02-13 devnull return -1;
101 6e527fbc 2005-02-13 devnull nr += n;
102 6e527fbc 2005-02-13 devnull ibw += n;
103 6e527fbc 2005-02-13 devnull if(!aes.setup){ /* first time, read 16 byte IV */
104 6e527fbc 2005-02-13 devnull if(n < AESbsize){
105 6e527fbc 2005-02-13 devnull fprint(2, "no IV in file\n");
106 6e527fbc 2005-02-13 devnull return -1;
108 6e527fbc 2005-02-13 devnull sha = sha1((uchar*)"aescbc file", 11, nil, nil);
109 6e527fbc 2005-02-13 devnull sha1(key, nkey, skey, sha);
110 6e527fbc 2005-02-13 devnull setupAESstate(&aes, skey, AESbsize, ibr);
111 6e527fbc 2005-02-13 devnull memset(skey, 0, sizeof skey);
112 6e527fbc 2005-02-13 devnull ibr += AESbsize;
113 6e527fbc 2005-02-13 devnull n -= AESbsize;
115 6e527fbc 2005-02-13 devnull aesCBCdecrypt(ibw-n, n, &aes);
116 6e527fbc 2005-02-13 devnull n = ibw-ibr-CHK;
117 6e527fbc 2005-02-13 devnull if(n > 0){
118 6e527fbc 2005-02-13 devnull if(buf == nil){
119 6e527fbc 2005-02-13 devnull nw = write(fd, ibr, n);
120 6e527fbc 2005-02-13 devnull if(nw != n){
121 6e527fbc 2005-02-13 devnull fprint(2, "write error on %s", gf);
122 6e527fbc 2005-02-13 devnull return -1;
125 6e527fbc 2005-02-13 devnull assert(bufw+n <= bufe);
126 6e527fbc 2005-02-13 devnull memmove(bufw, ibr, n);
127 6e527fbc 2005-02-13 devnull bufw += n;
129 6e527fbc 2005-02-13 devnull ibr += n;
131 6e527fbc 2005-02-13 devnull memmove(ib, ibr, ibw-ibr);
132 6e527fbc 2005-02-13 devnull ibw = ib + (ibw-ibr);
133 6e527fbc 2005-02-13 devnull ibr = ib;
135 6e527fbc 2005-02-13 devnull if(buf == nil)
136 6e527fbc 2005-02-13 devnull close(fd);
137 6e527fbc 2005-02-13 devnull n = ibw-ibr;
138 6e527fbc 2005-02-13 devnull if((n != CHK) || (memcmp(ib, "XXXXXXXXXXXXXXXX", CHK) != 0)){
139 6e527fbc 2005-02-13 devnull fprint(2,"decrypted file failed to authenticate!\n");
140 6e527fbc 2005-02-13 devnull return -1;
142 6e527fbc 2005-02-13 devnull return 0;
145 cbeb0b26 2006-04-01 devnull /* This sends a file to the secstore disk that can, in an emergency, be */
146 cbeb0b26 2006-04-01 devnull /* decrypted by the program aescbc.c. */
147 6e527fbc 2005-02-13 devnull static int
148 6e527fbc 2005-02-13 devnull putfile(SConn *conn, char *pf, uchar *buf, ulong len, uchar *key, int nkey)
150 6e527fbc 2005-02-13 devnull int i, n, fd, ivo, bufi, done;
151 6e527fbc 2005-02-13 devnull char s[Maxmsg];
152 6e527fbc 2005-02-13 devnull uchar skey[SHA1dlen], b[CHK+Maxmsg], IV[AESbsize];
153 6e527fbc 2005-02-13 devnull AESstate aes;
154 6e527fbc 2005-02-13 devnull DigestState *sha;
156 6e527fbc 2005-02-13 devnull /* create initialization vector */
157 6e527fbc 2005-02-13 devnull srand(time(0)); /* doesn't need to be unpredictable */
158 6e527fbc 2005-02-13 devnull for(i=0; i<AESbsize; i++)
159 6e527fbc 2005-02-13 devnull IV[i] = 0xff & rand();
160 6e527fbc 2005-02-13 devnull sha = sha1((uchar*)"aescbc file", 11, nil, nil);
161 6e527fbc 2005-02-13 devnull sha1(key, nkey, skey, sha);
162 6e527fbc 2005-02-13 devnull setupAESstate(&aes, skey, AESbsize, IV);
163 6e527fbc 2005-02-13 devnull memset(skey, 0, sizeof skey);
165 6e527fbc 2005-02-13 devnull snprint(s, Maxmsg, "PUT %s\n", pf);
166 6e527fbc 2005-02-13 devnull conn->write(conn, (uchar*)s, strlen(s));
168 6e527fbc 2005-02-13 devnull if(buf == nil){
169 6e527fbc 2005-02-13 devnull /* get file size */
170 6e527fbc 2005-02-13 devnull if((fd = open(pf, OREAD)) < 0){
171 6e527fbc 2005-02-13 devnull fprint(2, "can't open %s: %r\n", pf);
172 6e527fbc 2005-02-13 devnull return -1;
174 6e527fbc 2005-02-13 devnull len = seek(fd, 0, 2);
175 6e527fbc 2005-02-13 devnull seek(fd, 0, 0);
176 6e527fbc 2005-02-13 devnull } else {
177 6e527fbc 2005-02-13 devnull fd = -1;
179 6e527fbc 2005-02-13 devnull if(len > MAXFILESIZE){
180 6e527fbc 2005-02-13 devnull fprint(2, "implausible filesize %ld for %s\n", len, pf);
181 6e527fbc 2005-02-13 devnull return -1;
184 6e527fbc 2005-02-13 devnull /* send file size */
185 6e527fbc 2005-02-13 devnull snprint(s, Maxmsg, "%ld", len+AESbsize+CHK);
186 6e527fbc 2005-02-13 devnull conn->write(conn, (uchar*)s, strlen(s));
188 6e527fbc 2005-02-13 devnull /* send IV and file+XXXXX in Maxmsg chunks */
189 6e527fbc 2005-02-13 devnull ivo = AESbsize;
190 6e527fbc 2005-02-13 devnull bufi = 0;
191 6e527fbc 2005-02-13 devnull memcpy(b, IV, ivo);
192 6e527fbc 2005-02-13 devnull for(done = 0; !done; ){
193 6e527fbc 2005-02-13 devnull if(buf == nil){
194 6e527fbc 2005-02-13 devnull n = read(fd, b+ivo, Maxmsg-ivo);
195 6e527fbc 2005-02-13 devnull if(n < 0){
196 6e527fbc 2005-02-13 devnull fprint(2, "read error on %s: %r\n", pf);
197 6e527fbc 2005-02-13 devnull return -1;
200 6e527fbc 2005-02-13 devnull if((n = len - bufi) > Maxmsg-ivo)
201 6e527fbc 2005-02-13 devnull n = Maxmsg-ivo;
202 6e527fbc 2005-02-13 devnull memcpy(b+ivo, buf+bufi, n);
203 6e527fbc 2005-02-13 devnull bufi += n;
205 6e527fbc 2005-02-13 devnull n += ivo;
206 6e527fbc 2005-02-13 devnull ivo = 0;
207 6e527fbc 2005-02-13 devnull if(n < Maxmsg){ /* EOF on input; append XX... */
208 6e527fbc 2005-02-13 devnull memset(b+n, 'X', CHK);
209 cbeb0b26 2006-04-01 devnull n += CHK; /* might push n>Maxmsg */
210 6e527fbc 2005-02-13 devnull done = 1;
212 6e527fbc 2005-02-13 devnull aesCBCencrypt(b, n, &aes);
213 6e527fbc 2005-02-13 devnull if(n > Maxmsg){
214 6e527fbc 2005-02-13 devnull assert(done==1);
215 6e527fbc 2005-02-13 devnull conn->write(conn, b, Maxmsg);
216 6e527fbc 2005-02-13 devnull n -= Maxmsg;
217 6e527fbc 2005-02-13 devnull memmove(b, b+Maxmsg, n);
219 6e527fbc 2005-02-13 devnull conn->write(conn, b, n);
222 6e527fbc 2005-02-13 devnull if(buf == nil)
223 6e527fbc 2005-02-13 devnull close(fd);
224 6e527fbc 2005-02-13 devnull fprint(2, "saved %ld bytes\n", len);
226 6e527fbc 2005-02-13 devnull return 0;
229 6e527fbc 2005-02-13 devnull static int
230 6e527fbc 2005-02-13 devnull removefile(SConn *conn, char *rf)
232 6e527fbc 2005-02-13 devnull char buf[Maxmsg];
234 6e527fbc 2005-02-13 devnull if(strchr(rf, '/')){
235 6e527fbc 2005-02-13 devnull fprint(2, "simple filenames, not paths like %s\n", rf);
236 6e527fbc 2005-02-13 devnull return -1;
239 6e527fbc 2005-02-13 devnull snprint(buf, Maxmsg, "RM %s\n", rf);
240 6e527fbc 2005-02-13 devnull conn->write(conn, (uchar*)buf, strlen(buf));
242 6e527fbc 2005-02-13 devnull return 0;
245 6e527fbc 2005-02-13 devnull static int
246 6e527fbc 2005-02-13 devnull cmd(AuthConn *c, char **gf, int *Gflag, char **pf, char **rf)
248 6e527fbc 2005-02-13 devnull ulong len;
249 6e527fbc 2005-02-13 devnull int rv = -1;
250 6e527fbc 2005-02-13 devnull uchar *memfile, *memcur, *memnext;
252 6e527fbc 2005-02-13 devnull while(*gf != nil){
253 6e527fbc 2005-02-13 devnull if(verbose)
254 6e527fbc 2005-02-13 devnull fprint(2, "get %s\n", *gf);
255 6e527fbc 2005-02-13 devnull if(getfile(c->conn, *gf, *Gflag ? &memfile : nil, &len, (uchar*)c->pass, c->passlen) < 0)
256 6e527fbc 2005-02-13 devnull goto Out;
257 6e527fbc 2005-02-13 devnull if(*Gflag){
258 cbeb0b26 2006-04-01 devnull /* write one line at a time, as required by /mnt/factotum/ctl */
259 6e527fbc 2005-02-13 devnull memcur = memfile;
260 6e527fbc 2005-02-13 devnull while(len>0){
261 6e527fbc 2005-02-13 devnull memnext = (uchar*)strchr((char*)memcur, '\n');
262 6e527fbc 2005-02-13 devnull if(memnext){
263 6e527fbc 2005-02-13 devnull write(1, memcur, memnext-memcur+1);
264 6e527fbc 2005-02-13 devnull len -= memnext-memcur+1;
265 6e527fbc 2005-02-13 devnull memcur = memnext+1;
267 6e527fbc 2005-02-13 devnull write(1, memcur, len);
271 6e527fbc 2005-02-13 devnull free(memfile);
274 6e527fbc 2005-02-13 devnull Gflag++;
276 6e527fbc 2005-02-13 devnull while(*pf != nil){
277 6e527fbc 2005-02-13 devnull if(verbose)
278 6e527fbc 2005-02-13 devnull fprint(2, "put %s\n", *pf);
279 6e527fbc 2005-02-13 devnull if(putfile(c->conn, *pf, nil, 0, (uchar*)c->pass, c->passlen) < 0)
280 6e527fbc 2005-02-13 devnull goto Out;
283 6e527fbc 2005-02-13 devnull while(*rf != nil){
284 6e527fbc 2005-02-13 devnull if(verbose)
285 6e527fbc 2005-02-13 devnull fprint(2, "rm %s\n", *rf);
286 6e527fbc 2005-02-13 devnull if(removefile(c->conn, *rf) < 0)
287 6e527fbc 2005-02-13 devnull goto Out;
291 6e527fbc 2005-02-13 devnull c->conn->write(c->conn, (uchar*)"BYE", 3);
295 6e527fbc 2005-02-13 devnull c->conn->free(c->conn);
296 6e527fbc 2005-02-13 devnull return rv;
299 6e527fbc 2005-02-13 devnull static int
300 6e527fbc 2005-02-13 devnull chpasswd(AuthConn *c, char *id)
302 6e527fbc 2005-02-13 devnull ulong len;
303 6e527fbc 2005-02-13 devnull int rv = -1, newpasslen = 0;
304 6e527fbc 2005-02-13 devnull mpint *H, *Hi;
305 6e527fbc 2005-02-13 devnull uchar *memfile;
306 6e527fbc 2005-02-13 devnull char *newpass, *passck;
307 6e527fbc 2005-02-13 devnull char *list, *cur, *next, *hexHi;
308 6e527fbc 2005-02-13 devnull char *f[8], prompt[128];
310 6e527fbc 2005-02-13 devnull H = mpnew(0);
311 6e527fbc 2005-02-13 devnull Hi = mpnew(0);
312 cbeb0b26 2006-04-01 devnull /* changing our password is vulnerable to connection failure */
313 6e527fbc 2005-02-13 devnull for(;;){
314 6e527fbc 2005-02-13 devnull snprint(prompt, sizeof(prompt), "new password for %s: ", id);
315 6e527fbc 2005-02-13 devnull newpass = readcons(prompt, nil, 1);
316 6e527fbc 2005-02-13 devnull if(newpass == nil)
317 6e527fbc 2005-02-13 devnull goto Out;
318 6e527fbc 2005-02-13 devnull if(strlen(newpass) >= 7)
320 6e527fbc 2005-02-13 devnull else if(strlen(newpass) == 0){
321 6e527fbc 2005-02-13 devnull fprint(2, "!password change aborted\n");
322 6e527fbc 2005-02-13 devnull goto Out;
324 6e527fbc 2005-02-13 devnull print("!password must be at least 7 characters\n");
326 6e527fbc 2005-02-13 devnull newpasslen = strlen(newpass);
327 6e527fbc 2005-02-13 devnull snprint(prompt, sizeof(prompt), "retype password: ");
328 6e527fbc 2005-02-13 devnull passck = readcons(prompt, nil, 1);
329 6e527fbc 2005-02-13 devnull if(passck == nil){
330 6e527fbc 2005-02-13 devnull fprint(2, "readcons failed\n");
331 6e527fbc 2005-02-13 devnull goto Out;
333 6e527fbc 2005-02-13 devnull if(strcmp(passck, newpass) != 0){
334 6e527fbc 2005-02-13 devnull fprint(2, "passwords didn't match\n");
335 6e527fbc 2005-02-13 devnull goto Out;
338 6e527fbc 2005-02-13 devnull c->conn->write(c->conn, (uchar*)"CHPASS", strlen("CHPASS"));
339 6e527fbc 2005-02-13 devnull hexHi = PAK_Hi(id, newpass, H, Hi);
340 6e527fbc 2005-02-13 devnull c->conn->write(c->conn, (uchar*)hexHi, strlen(hexHi));
341 6e527fbc 2005-02-13 devnull free(hexHi);
342 6e527fbc 2005-02-13 devnull mpfree(H);
343 6e527fbc 2005-02-13 devnull mpfree(Hi);
345 6e527fbc 2005-02-13 devnull if(getfile(c->conn, ".", (uchar **)(void*)&list, &len, nil, 0) < 0){
346 6e527fbc 2005-02-13 devnull fprint(2, "directory listing failed.\n");
347 6e527fbc 2005-02-13 devnull goto Out;
350 6e527fbc 2005-02-13 devnull /* Loop over files and reencrypt them; try to keep going after error */
351 6e527fbc 2005-02-13 devnull for(cur=list; (next=strchr(cur, '\n')) != nil; cur=next+1){
352 6e527fbc 2005-02-13 devnull *next = '\0';
353 6e527fbc 2005-02-13 devnull if(tokenize(cur, f, nelem(f))< 1)
355 6e527fbc 2005-02-13 devnull fprint(2, "reencrypting '%s'\n", f[0]);
356 6e527fbc 2005-02-13 devnull if(getfile(c->conn, f[0], &memfile, &len, (uchar*)c->pass, c->passlen) < 0){
357 6e527fbc 2005-02-13 devnull fprint(2, "getfile of '%s' failed\n", f[0]);
358 6e527fbc 2005-02-13 devnull continue;
360 6e527fbc 2005-02-13 devnull if(putfile(c->conn, f[0], memfile, len, (uchar*)newpass, newpasslen) < 0)
361 6e527fbc 2005-02-13 devnull fprint(2, "putfile of '%s' failed\n", f[0]);
362 6e527fbc 2005-02-13 devnull free(memfile);
364 6e527fbc 2005-02-13 devnull free(list);
365 6e527fbc 2005-02-13 devnull c->conn->write(c->conn, (uchar*)"BYE", 3);
369 6e527fbc 2005-02-13 devnull if(newpass != nil){
370 6e527fbc 2005-02-13 devnull memset(newpass, 0, newpasslen);
371 6e527fbc 2005-02-13 devnull free(newpass);
373 6e527fbc 2005-02-13 devnull c->conn->free(c->conn);
374 6e527fbc 2005-02-13 devnull return rv;
377 6e527fbc 2005-02-13 devnull static AuthConn*
378 6e527fbc 2005-02-13 devnull login(char *id, char *dest, int pass_stdin, int pass_nvram)
380 6e527fbc 2005-02-13 devnull AuthConn *c;
381 6e527fbc 2005-02-13 devnull int fd, n, ntry = 0;
382 6e527fbc 2005-02-13 devnull char *S, *PINSTA = nil, *nl, s[Maxmsg+1], *pass;
384 6e527fbc 2005-02-13 devnull if(dest == nil){
385 6e527fbc 2005-02-13 devnull fprint(2, "tried to login with nil dest\n");
386 6e527fbc 2005-02-13 devnull exits("nil dest");
388 6e527fbc 2005-02-13 devnull c = emalloc(sizeof(*c));
389 6e527fbc 2005-02-13 devnull if(pass_nvram){
390 6e527fbc 2005-02-13 devnull /* if(readnvram(&nvr, 0) < 0) */
391 6e527fbc 2005-02-13 devnull exits("readnvram: %r");
392 6e527fbc 2005-02-13 devnull strecpy(c->pass, c->pass+sizeof c->pass, nvr.config);
394 6e527fbc 2005-02-13 devnull if(pass_stdin){
395 cbeb0b26 2006-04-01 devnull n = readn(0, s, Maxmsg-2); /* so len(PINSTA)<Maxmsg-3 */
396 6e527fbc 2005-02-13 devnull if(n < 1)
397 6e527fbc 2005-02-13 devnull exits("no password on standard input");
398 6e527fbc 2005-02-13 devnull s[n] = 0;
399 6e527fbc 2005-02-13 devnull nl = strchr(s, '\n');
401 6e527fbc 2005-02-13 devnull *nl++ = 0;
402 6e527fbc 2005-02-13 devnull PINSTA = estrdup(nl);
403 6e527fbc 2005-02-13 devnull nl = strchr(PINSTA, '\n');
405 6e527fbc 2005-02-13 devnull *nl = 0;
407 6e527fbc 2005-02-13 devnull strecpy(c->pass, c->pass+sizeof c->pass, s);
409 6e527fbc 2005-02-13 devnull while(1){
410 6e527fbc 2005-02-13 devnull if(verbose)
411 6e527fbc 2005-02-13 devnull fprint(2, "dialing %s\n", dest);
412 6e527fbc 2005-02-13 devnull if((fd = dial(dest, nil, nil, nil)) < 0){
413 6e527fbc 2005-02-13 devnull fprint(2, "can't dial %s\n", dest);
414 6e527fbc 2005-02-13 devnull free(c);
415 6e527fbc 2005-02-13 devnull return nil;
417 6e527fbc 2005-02-13 devnull if((c->conn = newSConn(fd)) == nil){
418 6e527fbc 2005-02-13 devnull free(c);
419 6e527fbc 2005-02-13 devnull return nil;
422 6e527fbc 2005-02-13 devnull if(!pass_stdin && !pass_nvram){
423 6e527fbc 2005-02-13 devnull pass = readcons("secstore password", nil, 1);
424 6e527fbc 2005-02-13 devnull if(pass == nil)
425 6e527fbc 2005-02-13 devnull pass = estrdup("");
426 6e527fbc 2005-02-13 devnull if(strlen(pass) >= sizeof c->pass){
427 6e527fbc 2005-02-13 devnull fprint(2, "password too long, skipping secstore login\n");
428 6e527fbc 2005-02-13 devnull exits("password too long");
430 6e527fbc 2005-02-13 devnull strcpy(c->pass, pass);
431 6e527fbc 2005-02-13 devnull memset(pass, 0, strlen(pass));
432 6e527fbc 2005-02-13 devnull free(pass);
434 6e527fbc 2005-02-13 devnull if(c->pass[0]==0){
435 6e527fbc 2005-02-13 devnull fprint(2, "null password, skipping secstore login\n");
436 6e527fbc 2005-02-13 devnull exits("no password");
438 6e527fbc 2005-02-13 devnull if(PAKclient(c->conn, id, c->pass, &S) >= 0)
440 6e527fbc 2005-02-13 devnull c->conn->free(c->conn);
441 6e527fbc 2005-02-13 devnull if(pass_stdin)
442 6e527fbc 2005-02-13 devnull exits("invalid password on standard input");
443 6e527fbc 2005-02-13 devnull if(pass_nvram)
444 6e527fbc 2005-02-13 devnull exits("invalid password in nvram");
445 cbeb0b26 2006-04-01 devnull /* and let user try retyping the password */
446 6e527fbc 2005-02-13 devnull if(ntry==3)
447 6e527fbc 2005-02-13 devnull fprint(2, "Enter an empty password to quit.\n");
449 6e527fbc 2005-02-13 devnull c->passlen = strlen(c->pass);
450 6e527fbc 2005-02-13 devnull fprint(2, "server: %s\n", S);
451 6e527fbc 2005-02-13 devnull free(S);
452 6e527fbc 2005-02-13 devnull if(readstr(c->conn, s) < 0){
453 6e527fbc 2005-02-13 devnull c->conn->free(c->conn);
454 6e527fbc 2005-02-13 devnull free(c);
455 6e527fbc 2005-02-13 devnull return nil;
457 6e527fbc 2005-02-13 devnull if(strcmp(s, "STA") == 0){
458 6e527fbc 2005-02-13 devnull long sn;
459 6e527fbc 2005-02-13 devnull if(pass_stdin){
460 6e527fbc 2005-02-13 devnull if(PINSTA)
461 6e527fbc 2005-02-13 devnull strncpy(s+3, PINSTA, (sizeof s)-3);
463 6e527fbc 2005-02-13 devnull exits("missing PIN+SecureID on standard input");
464 6e527fbc 2005-02-13 devnull free(PINSTA);
466 6e527fbc 2005-02-13 devnull pass = readcons("STA PIN+SecureID", nil, 1);
467 6e527fbc 2005-02-13 devnull if(pass == nil)
468 6e527fbc 2005-02-13 devnull pass = estrdup("");
469 6e527fbc 2005-02-13 devnull strncpy(s+3, pass, (sizeof s)-4);
470 6e527fbc 2005-02-13 devnull memset(pass, 0, strlen(pass));
471 6e527fbc 2005-02-13 devnull free(pass);
473 6e527fbc 2005-02-13 devnull sn = strlen(s+3);
474 6e527fbc 2005-02-13 devnull if(verbose)
475 6e527fbc 2005-02-13 devnull fprint(2, "%ld\n", sn);
476 6e527fbc 2005-02-13 devnull c->conn->write(c->conn, (uchar*)s, sn+3);
477 6e527fbc 2005-02-13 devnull readstr(c->conn, s);
479 6e527fbc 2005-02-13 devnull if(strcmp(s, "OK") != 0){
480 6e527fbc 2005-02-13 devnull fprint(2, "%s\n", s);
481 6e527fbc 2005-02-13 devnull c->conn->free(c->conn);
482 6e527fbc 2005-02-13 devnull free(c);
483 6e527fbc 2005-02-13 devnull return nil;
485 6e527fbc 2005-02-13 devnull return c;
489 6e527fbc 2005-02-13 devnull main(int argc, char **argv)
491 6e527fbc 2005-02-13 devnull int chpass = 0, pass_stdin = 0, pass_nvram = 0, rc;
492 6e527fbc 2005-02-13 devnull int ngfile = 0, npfile = 0, nrfile = 0, Gflag[MAXFILES+1];
493 6e527fbc 2005-02-13 devnull char *gfile[MAXFILES], *pfile[MAXFILES], *rfile[MAXFILES];
494 6e527fbc 2005-02-13 devnull char *serve, *tcpserve, *user;
495 6e527fbc 2005-02-13 devnull AuthConn *c;
497 ce94dbe6 2005-02-13 devnull serve = getenv("secstore");
498 ce94dbe6 2005-02-13 devnull if(serve == nil)
499 ce94dbe6 2005-02-13 devnull serve = "secstore";
500 6e527fbc 2005-02-13 devnull user = getuser();
501 6e527fbc 2005-02-13 devnull memset(Gflag, 0, sizeof Gflag);
502 6e527fbc 2005-02-13 devnull fmtinstall('B', mpfmt);
503 6e527fbc 2005-02-13 devnull fmtinstall('H', encodefmt);
505 6e527fbc 2005-02-13 devnull ARGBEGIN{
506 6e527fbc 2005-02-13 devnull case 'c':
507 6e527fbc 2005-02-13 devnull chpass = 1;
509 6e527fbc 2005-02-13 devnull case 'G':
510 6e527fbc 2005-02-13 devnull Gflag[ngfile]++;
511 6e527fbc 2005-02-13 devnull /* fall through */
512 6e527fbc 2005-02-13 devnull case 'g':
513 6e527fbc 2005-02-13 devnull if(ngfile >= MAXFILES)
514 6e527fbc 2005-02-13 devnull exits("too many gfiles");
515 6e527fbc 2005-02-13 devnull gfile[ngfile++] = ARGF();
516 6e527fbc 2005-02-13 devnull if(gfile[ngfile-1] == nil)
517 6e527fbc 2005-02-13 devnull usage();
519 6e527fbc 2005-02-13 devnull case 'i':
520 6e527fbc 2005-02-13 devnull pass_stdin = 1;
522 6e527fbc 2005-02-13 devnull case 'n':
523 6e527fbc 2005-02-13 devnull pass_nvram = 1;
525 6e527fbc 2005-02-13 devnull case 'p':
526 6e527fbc 2005-02-13 devnull if(npfile >= MAXFILES)
527 6e527fbc 2005-02-13 devnull exits("too many pfiles");
528 6e527fbc 2005-02-13 devnull pfile[npfile++] = ARGF();
529 6e527fbc 2005-02-13 devnull if(pfile[npfile-1] == nil)
530 6e527fbc 2005-02-13 devnull usage();
532 6e527fbc 2005-02-13 devnull case 'r':
533 6e527fbc 2005-02-13 devnull if(nrfile >= MAXFILES)
534 6e527fbc 2005-02-13 devnull exits("too many rfiles");
535 6e527fbc 2005-02-13 devnull rfile[nrfile++] = ARGF();
536 6e527fbc 2005-02-13 devnull if(rfile[nrfile-1] == nil)
537 6e527fbc 2005-02-13 devnull usage();
539 6e527fbc 2005-02-13 devnull case 's':
540 6e527fbc 2005-02-13 devnull serve = EARGF(usage());
542 6e527fbc 2005-02-13 devnull case 'u':
543 6e527fbc 2005-02-13 devnull user = EARGF(usage());
545 6e527fbc 2005-02-13 devnull case 'v':
546 6e527fbc 2005-02-13 devnull verbose++;
548 6e527fbc 2005-02-13 devnull default:
549 6e527fbc 2005-02-13 devnull usage();
551 6e527fbc 2005-02-13 devnull }ARGEND;
552 6e527fbc 2005-02-13 devnull gfile[ngfile] = nil;
553 6e527fbc 2005-02-13 devnull pfile[npfile] = nil;
554 6e527fbc 2005-02-13 devnull rfile[nrfile] = nil;
556 6e527fbc 2005-02-13 devnull if(argc!=0 || user==nil)
557 6e527fbc 2005-02-13 devnull usage();
559 6e527fbc 2005-02-13 devnull if(chpass && (ngfile || npfile || nrfile)){
560 6e527fbc 2005-02-13 devnull fprint(2, "Get, put, and remove invalid with password change.\n");
561 6e527fbc 2005-02-13 devnull exits("usage");
564 ce94dbe6 2005-02-13 devnull tcpserve = netmkaddr(serve, "tcp", "secstore");
565 6e527fbc 2005-02-13 devnull c = login(user, tcpserve, pass_stdin, pass_nvram);
566 6e527fbc 2005-02-13 devnull if(c == nil){
567 6e527fbc 2005-02-13 devnull fprint(2, "secstore authentication failed\n");
568 6e527fbc 2005-02-13 devnull exits("secstore authentication failed");
570 6e527fbc 2005-02-13 devnull if(chpass)
571 6e527fbc 2005-02-13 devnull rc = chpasswd(c, user);
573 6e527fbc 2005-02-13 devnull rc = cmd(c, gfile, Gflag, pfile, rfile);
574 6e527fbc 2005-02-13 devnull if(rc < 0){
575 6e527fbc 2005-02-13 devnull fprint(2, "secstore cmd failed\n");
576 6e527fbc 2005-02-13 devnull exits("secstore cmd failed");
578 6e527fbc 2005-02-13 devnull exits("");
579 6e527fbc 2005-02-13 devnull return 0;