Blame


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 };
10 6e527fbc 2005-02-13 devnull
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;
16 6e527fbc 2005-02-13 devnull
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;
20 6e527fbc 2005-02-13 devnull
21 6e527fbc 2005-02-13 devnull void
22 6e527fbc 2005-02-13 devnull usage(void)
23 6e527fbc 2005-02-13 devnull {
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");
26 6e527fbc 2005-02-13 devnull }
27 6e527fbc 2005-02-13 devnull
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)
30 6e527fbc 2005-02-13 devnull {
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;
37 6e527fbc 2005-02-13 devnull
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;
41 6e527fbc 2005-02-13 devnull }
42 6e527fbc 2005-02-13 devnull memset(&aes, 0, sizeof aes);
43 6e527fbc 2005-02-13 devnull
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));
46 6e527fbc 2005-02-13 devnull
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;
53 6e527fbc 2005-02-13 devnull }
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;
64 6e527fbc 2005-02-13 devnull }
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;
69 6e527fbc 2005-02-13 devnull }
70 6e527fbc 2005-02-13 devnull
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;
79 6e527fbc 2005-02-13 devnull }
80 6e527fbc 2005-02-13 devnull if(buf == nil)
81 6e527fbc 2005-02-13 devnull write(1, s, n);
82 6e527fbc 2005-02-13 devnull else
83 6e527fbc 2005-02-13 devnull memmove((*buf)+i, s, n);
84 6e527fbc 2005-02-13 devnull }
85 6e527fbc 2005-02-13 devnull return 0;
86 6e527fbc 2005-02-13 devnull }
87 6e527fbc 2005-02-13 devnull
88 fa325e9b 2020-01-10 cross /* 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;
93 6e527fbc 2005-02-13 devnull }
94 6e527fbc 2005-02-13 devnull
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;
100 6e527fbc 2005-02-13 devnull }
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;
107 6e527fbc 2005-02-13 devnull }
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;
114 6e527fbc 2005-02-13 devnull }
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;
123 6e527fbc 2005-02-13 devnull }
124 6e527fbc 2005-02-13 devnull }else{
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;
128 6e527fbc 2005-02-13 devnull }
129 6e527fbc 2005-02-13 devnull ibr += n;
130 6e527fbc 2005-02-13 devnull }
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;
134 6e527fbc 2005-02-13 devnull }
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;
141 6e527fbc 2005-02-13 devnull }
142 6e527fbc 2005-02-13 devnull return 0;
143 6e527fbc 2005-02-13 devnull }
144 6e527fbc 2005-02-13 devnull
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)
149 6e527fbc 2005-02-13 devnull {
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;
155 6e527fbc 2005-02-13 devnull
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);
164 6e527fbc 2005-02-13 devnull
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));
167 6e527fbc 2005-02-13 devnull
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;
173 6e527fbc 2005-02-13 devnull }
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;
178 6e527fbc 2005-02-13 devnull }
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;
182 6e527fbc 2005-02-13 devnull }
183 6e527fbc 2005-02-13 devnull
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));
187 6e527fbc 2005-02-13 devnull
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;
198 6e527fbc 2005-02-13 devnull }
199 6e527fbc 2005-02-13 devnull }else{
200 fa325e9b 2020-01-10 cross 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;
204 6e527fbc 2005-02-13 devnull }
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;
211 6e527fbc 2005-02-13 devnull }
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);
218 6e527fbc 2005-02-13 devnull }
219 6e527fbc 2005-02-13 devnull conn->write(conn, b, n);
220 6e527fbc 2005-02-13 devnull }
221 6e527fbc 2005-02-13 devnull
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);
225 6e527fbc 2005-02-13 devnull
226 6e527fbc 2005-02-13 devnull return 0;
227 6e527fbc 2005-02-13 devnull }
228 6e527fbc 2005-02-13 devnull
229 6e527fbc 2005-02-13 devnull static int
230 6e527fbc 2005-02-13 devnull removefile(SConn *conn, char *rf)
231 6e527fbc 2005-02-13 devnull {
232 6e527fbc 2005-02-13 devnull char buf[Maxmsg];
233 6e527fbc 2005-02-13 devnull
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;
237 6e527fbc 2005-02-13 devnull }
238 6e527fbc 2005-02-13 devnull
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));
241 6e527fbc 2005-02-13 devnull
242 6e527fbc 2005-02-13 devnull return 0;
243 6e527fbc 2005-02-13 devnull }
244 6e527fbc 2005-02-13 devnull
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)
247 6e527fbc 2005-02-13 devnull {
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;
251 6e527fbc 2005-02-13 devnull
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;
266 6e527fbc 2005-02-13 devnull }else{
267 6e527fbc 2005-02-13 devnull write(1, memcur, len);
268 6e527fbc 2005-02-13 devnull break;
269 6e527fbc 2005-02-13 devnull }
270 6e527fbc 2005-02-13 devnull }
271 6e527fbc 2005-02-13 devnull free(memfile);
272 6e527fbc 2005-02-13 devnull }
273 6e527fbc 2005-02-13 devnull gf++;
274 6e527fbc 2005-02-13 devnull Gflag++;
275 6e527fbc 2005-02-13 devnull }
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;
281 6e527fbc 2005-02-13 devnull pf++;
282 6e527fbc 2005-02-13 devnull }
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;
288 6e527fbc 2005-02-13 devnull rf++;
289 6e527fbc 2005-02-13 devnull }
290 6e527fbc 2005-02-13 devnull
291 6e527fbc 2005-02-13 devnull c->conn->write(c->conn, (uchar*)"BYE", 3);
292 6e527fbc 2005-02-13 devnull rv = 0;
293 6e527fbc 2005-02-13 devnull
294 6e527fbc 2005-02-13 devnull Out:
295 6e527fbc 2005-02-13 devnull c->conn->free(c->conn);
296 6e527fbc 2005-02-13 devnull return rv;
297 6e527fbc 2005-02-13 devnull }
298 6e527fbc 2005-02-13 devnull
299 6e527fbc 2005-02-13 devnull static int
300 6e527fbc 2005-02-13 devnull chpasswd(AuthConn *c, char *id)
301 6e527fbc 2005-02-13 devnull {
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];
309 6e527fbc 2005-02-13 devnull
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)
319 6e527fbc 2005-02-13 devnull break;
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;
323 6e527fbc 2005-02-13 devnull }
324 6e527fbc 2005-02-13 devnull print("!password must be at least 7 characters\n");
325 6e527fbc 2005-02-13 devnull }
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;
332 6e527fbc 2005-02-13 devnull }
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;
336 6e527fbc 2005-02-13 devnull }
337 6e527fbc 2005-02-13 devnull
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);
344 6e527fbc 2005-02-13 devnull
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;
348 6e527fbc 2005-02-13 devnull }
349 6e527fbc 2005-02-13 devnull
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)
354 6e527fbc 2005-02-13 devnull break;
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;
359 6e527fbc 2005-02-13 devnull }
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);
363 6e527fbc 2005-02-13 devnull }
364 6e527fbc 2005-02-13 devnull free(list);
365 6e527fbc 2005-02-13 devnull c->conn->write(c->conn, (uchar*)"BYE", 3);
366 6e527fbc 2005-02-13 devnull rv = 0;
367 6e527fbc 2005-02-13 devnull
368 6e527fbc 2005-02-13 devnull Out:
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);
372 6e527fbc 2005-02-13 devnull }
373 6e527fbc 2005-02-13 devnull c->conn->free(c->conn);
374 6e527fbc 2005-02-13 devnull return rv;
375 6e527fbc 2005-02-13 devnull }
376 6e527fbc 2005-02-13 devnull
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)
379 6e527fbc 2005-02-13 devnull {
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;
383 6e527fbc 2005-02-13 devnull
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");
387 6e527fbc 2005-02-13 devnull }
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);
393 6e527fbc 2005-02-13 devnull }
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');
400 6e527fbc 2005-02-13 devnull if(nl){
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');
404 6e527fbc 2005-02-13 devnull if(nl)
405 6e527fbc 2005-02-13 devnull *nl = 0;
406 6e527fbc 2005-02-13 devnull }
407 6e527fbc 2005-02-13 devnull strecpy(c->pass, c->pass+sizeof c->pass, s);
408 6e527fbc 2005-02-13 devnull }
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;
416 6e527fbc 2005-02-13 devnull }
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;
420 6e527fbc 2005-02-13 devnull }
421 6e527fbc 2005-02-13 devnull ntry++;
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");
429 6e527fbc 2005-02-13 devnull }
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);
433 6e527fbc 2005-02-13 devnull }
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");
437 6e527fbc 2005-02-13 devnull }
438 6e527fbc 2005-02-13 devnull if(PAKclient(c->conn, id, c->pass, &S) >= 0)
439 6e527fbc 2005-02-13 devnull break;
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");
448 6e527fbc 2005-02-13 devnull }
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;
456 6e527fbc 2005-02-13 devnull }
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);
462 6e527fbc 2005-02-13 devnull else
463 6e527fbc 2005-02-13 devnull exits("missing PIN+SecureID on standard input");
464 6e527fbc 2005-02-13 devnull free(PINSTA);
465 6e527fbc 2005-02-13 devnull }else{
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);
472 6e527fbc 2005-02-13 devnull }
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);
478 6e527fbc 2005-02-13 devnull }
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;
484 6e527fbc 2005-02-13 devnull }
485 6e527fbc 2005-02-13 devnull return c;
486 6e527fbc 2005-02-13 devnull }
487 6e527fbc 2005-02-13 devnull
488 6e527fbc 2005-02-13 devnull int
489 6e527fbc 2005-02-13 devnull main(int argc, char **argv)
490 6e527fbc 2005-02-13 devnull {
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;
496 6e527fbc 2005-02-13 devnull
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);
504 6e527fbc 2005-02-13 devnull
505 6e527fbc 2005-02-13 devnull ARGBEGIN{
506 6e527fbc 2005-02-13 devnull case 'c':
507 6e527fbc 2005-02-13 devnull chpass = 1;
508 6e527fbc 2005-02-13 devnull break;
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();
518 6e527fbc 2005-02-13 devnull break;
519 6e527fbc 2005-02-13 devnull case 'i':
520 6e527fbc 2005-02-13 devnull pass_stdin = 1;
521 6e527fbc 2005-02-13 devnull break;
522 6e527fbc 2005-02-13 devnull case 'n':
523 6e527fbc 2005-02-13 devnull pass_nvram = 1;
524 6e527fbc 2005-02-13 devnull break;
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();
531 6e527fbc 2005-02-13 devnull break;
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();
538 6e527fbc 2005-02-13 devnull break;
539 6e527fbc 2005-02-13 devnull case 's':
540 6e527fbc 2005-02-13 devnull serve = EARGF(usage());
541 6e527fbc 2005-02-13 devnull break;
542 6e527fbc 2005-02-13 devnull case 'u':
543 6e527fbc 2005-02-13 devnull user = EARGF(usage());
544 6e527fbc 2005-02-13 devnull break;
545 6e527fbc 2005-02-13 devnull case 'v':
546 6e527fbc 2005-02-13 devnull verbose++;
547 6e527fbc 2005-02-13 devnull break;
548 6e527fbc 2005-02-13 devnull default:
549 6e527fbc 2005-02-13 devnull usage();
550 6e527fbc 2005-02-13 devnull break;
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;
555 6e527fbc 2005-02-13 devnull
556 6e527fbc 2005-02-13 devnull if(argc!=0 || user==nil)
557 6e527fbc 2005-02-13 devnull usage();
558 6e527fbc 2005-02-13 devnull
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");
562 6e527fbc 2005-02-13 devnull }
563 6e527fbc 2005-02-13 devnull
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");
569 6e527fbc 2005-02-13 devnull }
570 6e527fbc 2005-02-13 devnull if(chpass)
571 6e527fbc 2005-02-13 devnull rc = chpasswd(c, user);
572 6e527fbc 2005-02-13 devnull else
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");
577 6e527fbc 2005-02-13 devnull }
578 6e527fbc 2005-02-13 devnull exits("");
579 6e527fbc 2005-02-13 devnull return 0;
580 6e527fbc 2005-02-13 devnull }