]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/cwfs/auth.c
cwfs: fix network listener, relay auth errors. boot(8): split bootargs only on first...
[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                 auth_freerpc(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                 auth_freerpc(rpc);
119 }
120
121 int
122 authread(Chan *chan, File *file, uchar *data, int count)
123 {
124         AuthInfo *ai;
125         AuthRpc *rpc;
126
127         if((rpc = file->auth) == nil){
128                 snprint(chan->err, sizeof(chan->err),
129                         "not an auth fid");
130                 return -1;
131         }
132
133         switch(auth_rpc(rpc, "read", nil, 0)){
134         default:
135                 snprint(chan->err, sizeof(chan->err),
136                         "authread: auth protocol not finished");
137                 return -1;
138         case ARdone:
139                 if((ai = auth_getinfo(rpc)) == nil)
140                         goto Phase;
141                 file->uid = strtouid(ai->cuid);
142                 auth_freeAI(ai);
143                 if(file->uid < 0){
144                         snprint(chan->err, sizeof(chan->err),
145                                 "unknown user '%s'", ai->cuid);
146                         return -1;
147                 }
148                 return 0;
149         case ARok:
150                 if(count < rpc->narg){
151                         snprint(chan->err, sizeof(chan->err),
152                                 "not enough data in auth read");
153                         return -1;
154                 }
155                 memmove(data, rpc->arg, rpc->narg);
156                 return rpc->narg;
157         case ARphase:
158         Phase:
159                 rerrstr(chan->err, sizeof(chan->err));
160                 return -1;
161         }
162 }
163
164 int
165 authwrite(Chan *chan, File *file, uchar *data, int count)
166 {
167         AuthRpc *rpc;
168
169         if((rpc = file->auth) == nil){
170                 snprint(chan->err, sizeof(chan->err),
171                         "not an auth fid");
172                 return -1;
173         }
174         if(auth_rpc(rpc, "write", data, count) != ARok){
175                 rerrstr(chan->err, sizeof(chan->err));
176                 return -1;
177         }
178         return count;
179 }
180