Blame


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