Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

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