1*b985bfb9SDavid du Colombier #include "all.h"
2*b985bfb9SDavid du Colombier
3*b985bfb9SDavid du Colombier enum {
4*b985bfb9SDavid du Colombier ARgiveup = 100,
5*b985bfb9SDavid du Colombier };
6*b985bfb9SDavid du Colombier
7*b985bfb9SDavid du Colombier static uchar*
gstring(uchar * p,uchar * ep,char ** s)8*b985bfb9SDavid du Colombier gstring(uchar *p, uchar *ep, char **s)
9*b985bfb9SDavid du Colombier {
10*b985bfb9SDavid du Colombier uint n;
11*b985bfb9SDavid du Colombier
12*b985bfb9SDavid du Colombier if(p == nil)
13*b985bfb9SDavid du Colombier return nil;
14*b985bfb9SDavid du Colombier if(p+BIT16SZ > ep)
15*b985bfb9SDavid du Colombier return nil;
16*b985bfb9SDavid du Colombier n = GBIT16(p);
17*b985bfb9SDavid du Colombier p += BIT16SZ;
18*b985bfb9SDavid du Colombier if(p+n > ep)
19*b985bfb9SDavid du Colombier return nil;
20*b985bfb9SDavid du Colombier *s = malloc(n+1);
21*b985bfb9SDavid du Colombier memmove((*s), p, n);
22*b985bfb9SDavid du Colombier (*s)[n] = '\0';
23*b985bfb9SDavid du Colombier p += n;
24*b985bfb9SDavid du Colombier return p;
25*b985bfb9SDavid du Colombier }
26*b985bfb9SDavid du Colombier
27*b985bfb9SDavid du Colombier static uchar*
gcarray(uchar * p,uchar * ep,uchar ** s,int * np)28*b985bfb9SDavid du Colombier gcarray(uchar *p, uchar *ep, uchar **s, int *np)
29*b985bfb9SDavid du Colombier {
30*b985bfb9SDavid du Colombier uint n;
31*b985bfb9SDavid du Colombier
32*b985bfb9SDavid du Colombier if(p == nil)
33*b985bfb9SDavid du Colombier return nil;
34*b985bfb9SDavid du Colombier if(p+BIT16SZ > ep)
35*b985bfb9SDavid du Colombier return nil;
36*b985bfb9SDavid du Colombier n = GBIT16(p);
37*b985bfb9SDavid du Colombier p += BIT16SZ;
38*b985bfb9SDavid du Colombier if(p+n > ep)
39*b985bfb9SDavid du Colombier return nil;
40*b985bfb9SDavid du Colombier *s = malloc(n);
41*b985bfb9SDavid du Colombier if(*s == nil)
42*b985bfb9SDavid du Colombier return nil;
43*b985bfb9SDavid du Colombier memmove((*s), p, n);
44*b985bfb9SDavid du Colombier *np = n;
45*b985bfb9SDavid du Colombier p += n;
46*b985bfb9SDavid du Colombier return p;
47*b985bfb9SDavid du Colombier }
48*b985bfb9SDavid du Colombier
49*b985bfb9SDavid du Colombier static uchar*
convM2AI(uchar * p,int n,AuthInfo ** aip)50*b985bfb9SDavid du Colombier convM2AI(uchar *p, int n, AuthInfo **aip)
51*b985bfb9SDavid du Colombier {
52*b985bfb9SDavid du Colombier uchar *e = p+n;
53*b985bfb9SDavid du Colombier AuthInfo *ai;
54*b985bfb9SDavid du Colombier
55*b985bfb9SDavid du Colombier ai = mallocz(sizeof(*ai), 1);
56*b985bfb9SDavid du Colombier if(ai == nil)
57*b985bfb9SDavid du Colombier return nil;
58*b985bfb9SDavid du Colombier
59*b985bfb9SDavid du Colombier p = gstring(p, e, &ai->cuid);
60*b985bfb9SDavid du Colombier p = gstring(p, e, &ai->suid);
61*b985bfb9SDavid du Colombier p = gstring(p, e, &ai->cap);
62*b985bfb9SDavid du Colombier p = gcarray(p, e, &ai->secret, &ai->nsecret);
63*b985bfb9SDavid du Colombier if(p == nil)
64*b985bfb9SDavid du Colombier auth_freeAI(ai);
65*b985bfb9SDavid du Colombier else
66*b985bfb9SDavid du Colombier *aip = ai;
67*b985bfb9SDavid du Colombier return p;
68*b985bfb9SDavid du Colombier }
69*b985bfb9SDavid du Colombier
70*b985bfb9SDavid du Colombier static int
dorpc(AuthRpc * rpc,char * verb,char * val,int len,AuthGetkey * getkey)71*b985bfb9SDavid du Colombier dorpc(AuthRpc *rpc, char *verb, char *val, int len, AuthGetkey *getkey)
72*b985bfb9SDavid du Colombier {
73*b985bfb9SDavid du Colombier int ret;
74*b985bfb9SDavid du Colombier
75*b985bfb9SDavid du Colombier for(;;){
76*b985bfb9SDavid du Colombier if((ret = auth_rpc(rpc, verb, val, len)) != ARneedkey && ret != ARbadkey)
77*b985bfb9SDavid du Colombier return ret;
78*b985bfb9SDavid du Colombier if(getkey == nil)
79*b985bfb9SDavid du Colombier return ARgiveup; /* don't know how */
80*b985bfb9SDavid du Colombier if((*getkey)(rpc->arg) < 0)
81*b985bfb9SDavid du Colombier return ARgiveup; /* user punted */
82*b985bfb9SDavid du Colombier }
83*b985bfb9SDavid du Colombier }
84*b985bfb9SDavid du Colombier
85*b985bfb9SDavid du Colombier static int
doread(Session * s,Fid * f,void * buf,int n)86*b985bfb9SDavid du Colombier doread(Session *s, Fid *f, void *buf, int n)
87*b985bfb9SDavid du Colombier {
88*b985bfb9SDavid du Colombier s->f.fid = f - s->fids;
89*b985bfb9SDavid du Colombier s->f.offset = 0;
90*b985bfb9SDavid du Colombier s->f.count = n;
91*b985bfb9SDavid du Colombier if(xmesg(s, Tread) < 0)
92*b985bfb9SDavid du Colombier return -1;
93*b985bfb9SDavid du Colombier n = s->f.count;
94*b985bfb9SDavid du Colombier memmove(buf, s->f.data, n);
95*b985bfb9SDavid du Colombier return n;
96*b985bfb9SDavid du Colombier }
97*b985bfb9SDavid du Colombier
98*b985bfb9SDavid du Colombier static int
dowrite(Session * s,Fid * f,void * buf,int n)99*b985bfb9SDavid du Colombier dowrite(Session *s, Fid *f, void *buf, int n)
100*b985bfb9SDavid du Colombier {
101*b985bfb9SDavid du Colombier s->f.fid = f - s->fids;
102*b985bfb9SDavid du Colombier s->f.offset = 0;
103*b985bfb9SDavid du Colombier s->f.count = n;
104*b985bfb9SDavid du Colombier s->f.data = (char *)buf;
105*b985bfb9SDavid du Colombier if(xmesg(s, Twrite) < 0)
106*b985bfb9SDavid du Colombier return -1;
107*b985bfb9SDavid du Colombier return n;
108*b985bfb9SDavid du Colombier }
109*b985bfb9SDavid du Colombier
110*b985bfb9SDavid du Colombier /*
111*b985bfb9SDavid du Colombier * this just proxies what the factotum tells it to.
112*b985bfb9SDavid du Colombier */
113*b985bfb9SDavid du Colombier AuthInfo*
authproto(Session * s,Fid * f,AuthRpc * rpc,AuthGetkey * getkey,char * params)114*b985bfb9SDavid du Colombier authproto(Session *s, Fid *f, AuthRpc *rpc, AuthGetkey *getkey, char *params)
115*b985bfb9SDavid du Colombier {
116*b985bfb9SDavid du Colombier char *buf;
117*b985bfb9SDavid du Colombier int m, n, ret;
118*b985bfb9SDavid du Colombier AuthInfo *a;
119*b985bfb9SDavid du Colombier char oerr[ERRMAX];
120*b985bfb9SDavid du Colombier
121*b985bfb9SDavid du Colombier rerrstr(oerr, sizeof oerr);
122*b985bfb9SDavid du Colombier werrstr("UNKNOWN AUTH ERROR");
123*b985bfb9SDavid du Colombier
124*b985bfb9SDavid du Colombier if(dorpc(rpc, "start", params, strlen(params), getkey) != ARok){
125*b985bfb9SDavid du Colombier werrstr("fauth_proxy start: %r");
126*b985bfb9SDavid du Colombier return nil;
127*b985bfb9SDavid du Colombier }
128*b985bfb9SDavid du Colombier
129*b985bfb9SDavid du Colombier buf = malloc(AuthRpcMax);
130*b985bfb9SDavid du Colombier if(buf == nil)
131*b985bfb9SDavid du Colombier return nil;
132*b985bfb9SDavid du Colombier for(;;){
133*b985bfb9SDavid du Colombier switch(dorpc(rpc, "read", nil, 0, getkey)){
134*b985bfb9SDavid du Colombier case ARdone:
135*b985bfb9SDavid du Colombier free(buf);
136*b985bfb9SDavid du Colombier a = auth_getinfo(rpc);
137*b985bfb9SDavid du Colombier errstr(oerr, sizeof oerr); /* no error, restore whatever was there */
138*b985bfb9SDavid du Colombier return a;
139*b985bfb9SDavid du Colombier case ARok:
140*b985bfb9SDavid du Colombier if(dowrite(s, f, rpc->arg, rpc->narg) != rpc->narg){
141*b985bfb9SDavid du Colombier werrstr("auth_proxy write fd: %r");
142*b985bfb9SDavid du Colombier goto Error;
143*b985bfb9SDavid du Colombier }
144*b985bfb9SDavid du Colombier break;
145*b985bfb9SDavid du Colombier case ARphase:
146*b985bfb9SDavid du Colombier n = 0;
147*b985bfb9SDavid du Colombier memset(buf, 0, AuthRpcMax);
148*b985bfb9SDavid du Colombier while((ret = dorpc(rpc, "write", buf, n, getkey)) == ARtoosmall){
149*b985bfb9SDavid du Colombier if(atoi(rpc->arg) > AuthRpcMax)
150*b985bfb9SDavid du Colombier break;
151*b985bfb9SDavid du Colombier m = doread(s, f, buf+n, atoi(rpc->arg)-n);
152*b985bfb9SDavid du Colombier if(m <= 0){
153*b985bfb9SDavid du Colombier if(m == 0)
154*b985bfb9SDavid du Colombier werrstr("auth_proxy short read: %s", buf);
155*b985bfb9SDavid du Colombier goto Error;
156*b985bfb9SDavid du Colombier }
157*b985bfb9SDavid du Colombier n += m;
158*b985bfb9SDavid du Colombier }
159*b985bfb9SDavid du Colombier if(ret != ARok){
160*b985bfb9SDavid du Colombier werrstr("auth_proxy rpc write: %s: %r", buf);
161*b985bfb9SDavid du Colombier goto Error;
162*b985bfb9SDavid du Colombier }
163*b985bfb9SDavid du Colombier break;
164*b985bfb9SDavid du Colombier default:
165*b985bfb9SDavid du Colombier werrstr("auth_proxy rpc: %r");
166*b985bfb9SDavid du Colombier goto Error;
167*b985bfb9SDavid du Colombier }
168*b985bfb9SDavid du Colombier }
169*b985bfb9SDavid du Colombier Error:
170*b985bfb9SDavid du Colombier free(buf);
171*b985bfb9SDavid du Colombier return nil;
172*b985bfb9SDavid du Colombier }
173*b985bfb9SDavid du Colombier
174*b985bfb9SDavid du Colombier /* returns 0 if auth succeeded (or unneeded), -1 otherwise */
175*b985bfb9SDavid du Colombier int
authhostowner(Session * s)176*b985bfb9SDavid du Colombier authhostowner(Session *s)
177*b985bfb9SDavid du Colombier {
178*b985bfb9SDavid du Colombier Fid *af, *f;
179*b985bfb9SDavid du Colombier int rv = -1;
180*b985bfb9SDavid du Colombier int afd;
181*b985bfb9SDavid du Colombier AuthInfo *ai;
182*b985bfb9SDavid du Colombier AuthRpc *rpc;
183*b985bfb9SDavid du Colombier
184*b985bfb9SDavid du Colombier /* get a fid to authenticate over */
185*b985bfb9SDavid du Colombier f = nil;
186*b985bfb9SDavid du Colombier af = newfid(s);
187*b985bfb9SDavid du Colombier s->f.afid = af - s->fids;
188*b985bfb9SDavid du Colombier s->f.uname = getuser();
189*b985bfb9SDavid du Colombier s->f.aname = s->spec;
190*b985bfb9SDavid du Colombier if(xmesg(s, Tauth)){
191*b985bfb9SDavid du Colombier /* not needed */
192*b985bfb9SDavid du Colombier rv = 0;
193*b985bfb9SDavid du Colombier goto out;
194*b985bfb9SDavid du Colombier }
195*b985bfb9SDavid du Colombier
196*b985bfb9SDavid du Colombier quotefmtinstall(); /* just in case */
197*b985bfb9SDavid du Colombier
198*b985bfb9SDavid du Colombier afd = open("/mnt/factotum/rpc", ORDWR);
199*b985bfb9SDavid du Colombier if(afd < 0){
200*b985bfb9SDavid du Colombier werrstr("opening /mnt/factotum/rpc: %r");
201*b985bfb9SDavid du Colombier goto out;
202*b985bfb9SDavid du Colombier }
203*b985bfb9SDavid du Colombier
204*b985bfb9SDavid du Colombier rpc = auth_allocrpc(afd);
205*b985bfb9SDavid du Colombier if(rpc == nil)
206*b985bfb9SDavid du Colombier goto out;
207*b985bfb9SDavid du Colombier
208*b985bfb9SDavid du Colombier ai = authproto(s, af, rpc, auth_getkey, "proto=p9any role=client");
209*b985bfb9SDavid du Colombier if(ai != nil){
210*b985bfb9SDavid du Colombier rv = 0;
211*b985bfb9SDavid du Colombier auth_freeAI(ai);
212*b985bfb9SDavid du Colombier }
213*b985bfb9SDavid du Colombier auth_freerpc(rpc);
214*b985bfb9SDavid du Colombier close(afd);
215*b985bfb9SDavid du Colombier
216*b985bfb9SDavid du Colombier /* try attaching with the afid */
217*b985bfb9SDavid du Colombier chat("attaching as hostowner...");
218*b985bfb9SDavid du Colombier f = newfid(s);
219*b985bfb9SDavid du Colombier s->f.fid = f - s->fids;
220*b985bfb9SDavid du Colombier s->f.afid = af - s->fids;;
221*b985bfb9SDavid du Colombier s->f.uname = getuser();
222*b985bfb9SDavid du Colombier s->f.aname = s->spec;
223*b985bfb9SDavid du Colombier if(xmesg(s, Tattach) == 0)
224*b985bfb9SDavid du Colombier rv = 0;
225*b985bfb9SDavid du Colombier out:
226*b985bfb9SDavid du Colombier if(af != nil){
227*b985bfb9SDavid du Colombier putfid(s, af);
228*b985bfb9SDavid du Colombier s->f.fid = af - s->fids;
229*b985bfb9SDavid du Colombier xmesg(s, Tclunk);
230*b985bfb9SDavid du Colombier }
231*b985bfb9SDavid du Colombier if(f != nil){
232*b985bfb9SDavid du Colombier putfid(s, f);
233*b985bfb9SDavid du Colombier s->f.fid = f - s->fids;
234*b985bfb9SDavid du Colombier xmesg(s, Tclunk);
235*b985bfb9SDavid du Colombier }
236*b985bfb9SDavid du Colombier
237*b985bfb9SDavid du Colombier return rv;
238*b985bfb9SDavid du Colombier }
239*b985bfb9SDavid du Colombier
240