]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/cwfs/auth.c
cwfs: fix auth filedescriptor leak
[plan9front.git] / sys / src / cmd / cwfs / auth.c
1 #include "all.h"
2 #include "io.h"
3 #include <authsrv.h>
4 #include <auth.h>
5
6 Nvrsafe nvr;
7
8 static int gotnvr;      /* flag: nvr contains nvram; it could be bad */
9
10 char*
11 nvrgetconfig(void)
12 {
13         return conf.confdev;
14 }
15
16 /*
17  * we shouldn't be writing nvram any more.
18  * the secstore/config field is now just secstore key.
19  */
20
21 int
22 nvrcheck(void)
23 {
24         uchar csum;
25
26         if (readnvram(&nvr, NVread) < 0) {
27                 fprint(2, "nvrcheck: can't read nvram\n");
28                 return 1;
29         } else
30                 gotnvr = 1;
31
32         if(chatty)
33                 print("nvr read\n");
34
35         csum = nvcsum(nvr.machkey, sizeof nvr.machkey);
36         if(csum != nvr.machsum) {
37                 fprint(2, "\n\n ** NVR key checksum is incorrect  **\n");
38                 fprint(2, " ** set password to allow attaches **\n\n");
39                 memset(nvr.machkey, 0, sizeof nvr.machkey);
40                 return 1;
41         }
42
43         return 0;
44 }
45
46 int
47 nvrsetconfig(char* word)
48 {
49         /* config block is on device `word' */
50         USED(word);
51         return 0;
52 }
53
54 int
55 conslock(void)
56 {
57         char *ln;
58         char nkey1[DESKEYLEN];
59         static char zeroes[DESKEYLEN];
60
61         if(memcmp(nvr.machkey, zeroes, DESKEYLEN) == 0) {
62                 print("no password set\n");
63                 return 0;
64         }
65
66         for(;;) {
67                 print("%s password:", service);
68                 /* could turn off echo here */
69
70                 if ((ln = Brdline(&bin, '\n')) == nil)
71                         return 0;
72                 ln[Blinelen(&bin)-1] = '\0';
73
74                 /* could turn on echo here */
75                 memset(nkey1, 0, DESKEYLEN);
76                 passtokey(nkey1, ln);
77                 if(memcmp(nkey1, nvr.machkey, DESKEYLEN) == 0) {
78                         prdate();
79                         break;
80                 }
81
82                 print("Bad password\n");
83                 delay(1000);
84         }
85         return 1;
86 }
87
88 static char *keyspec = "proto=p9any role=server";
89
90 void*
91 authnew(void)
92 {
93         AuthRpc *rpc;
94         int fd;
95
96         if(access("/mnt/factotum", 0) < 0)
97                 if((fd = open("/srv/factotum", ORDWR)) >= 0)
98                         mount(fd, -1, "/mnt", MBEFORE, "");
99         if((fd = open("/mnt/factotum/rpc", ORDWR)) < 0)
100                 return nil;
101         if((rpc = auth_allocrpc(fd)) == nil){
102                 close(fd);
103                 return nil;
104         }
105         if(auth_rpc(rpc, "start", keyspec, strlen(keyspec)) != ARok){
106                 authfree(rpc);
107                 return nil;
108         }
109         return rpc;
110 }
111
112 void
113 authfree(void *auth)
114 {
115         AuthRpc *rpc;
116
117         if(rpc = auth){
118                 close(rpc->afd);
119                 auth_freerpc(rpc);
120         }
121 }
122
123 int
124 authread(File *file, uchar *data, int count)
125 {
126         AuthInfo *ai;
127         AuthRpc *rpc;
128         Chan *chan;
129
130         chan = file->cp;
131         if((rpc = file->auth) == nil){
132                 snprint(chan->err, sizeof(chan->err),
133                         "not an auth fid");
134                 return -1;
135         }
136
137         switch(auth_rpc(rpc, "read", nil, 0)){
138         default:
139                 snprint(chan->err, sizeof(chan->err),
140                         "authread: auth protocol not finished");
141                 return -1;
142         case ARdone:
143                 if((ai = auth_getinfo(rpc)) == nil)
144                         goto Phase;
145                 file->uid = strtouid(ai->cuid);
146                 auth_freeAI(ai);
147                 if(file->uid < 0){
148                         snprint(chan->err, sizeof(chan->err),
149                                 "unknown user '%s'", ai->cuid);
150                         return -1;
151                 }
152                 return 0;
153         case ARok:
154                 if(count < rpc->narg){
155                         snprint(chan->err, sizeof(chan->err),
156                                 "not enough data in auth read");
157                         return -1;
158                 }
159                 memmove(data, rpc->arg, rpc->narg);
160                 return rpc->narg;
161         case ARphase:
162         Phase:
163                 rerrstr(chan->err, sizeof(chan->err));
164                 return -1;
165         }
166 }
167
168 int
169 authwrite(File *file, uchar *data, int count)
170 {
171         AuthRpc *rpc;
172         Chan *chan;
173
174         chan = file->cp;
175         if((rpc = file->auth) == nil){
176                 snprint(chan->err, sizeof(chan->err),
177                         "not an auth fid");
178                 return -1;
179         }
180         if(auth_rpc(rpc, "write", data, count) != ARok){
181                 rerrstr(chan->err, sizeof(chan->err));
182                 return -1;
183         }
184         return count;
185 }
186