Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include "stdinc.h"
2
#include "9.h"
3
 
4
int
5
authRead(Fid* afid, void* data, int count)
6
{
7
	AuthInfo *ai;
8
	AuthRpc *rpc;
9
 
10
	if((rpc = afid->rpc) == nil){
11
		vtSetError("not an auth fid");
12
		return -1;
13
	}
14
 
15
	switch(auth_rpc(rpc, "read", nil, 0)){
16
	default:
17
		vtSetError("fossil authRead: auth protocol not finished");
18
		return -1;
19
	case ARdone:
20
		if((ai = auth_getinfo(rpc)) == nil){
21
			vtSetError("%r");
22
			break;
23
		}
24
		if(ai->cuid == nil || *ai->cuid == '\0'){
25
			vtSetError("auth with no cuid");
26
			auth_freeAI(ai);
27
			break;
28
		}
29
		assert(afid->cuname == nil);
30
		afid->cuname = vtStrDup(ai->cuid);
31
		auth_freeAI(ai);
32
		if(Dflag)
33
			fprint(2, "authRead cuname %s\n", afid->cuname);
34
		assert(afid->uid == nil);
35
		if((afid->uid = uidByUname(afid->cuname)) == nil){
36
			vtSetError("unknown user %#q", afid->cuname);
37
			break;
38
		}
39
		return 0;
40
	case ARok:
41
		if(count < rpc->narg){
42
			vtSetError("not enough data in auth read");
43
			break;
44
		}
45
		memmove(data, rpc->arg, rpc->narg);
46
		return rpc->narg;
47
	case ARphase:
48
		vtSetError("%r");
49
		break;
50
	}
51
	return -1;
52
}
53
 
54
int
55
authWrite(Fid* afid, void* data, int count)
56
{
57
	assert(afid->rpc != nil);
58
	if(auth_rpc(afid->rpc, "write", data, count) != ARok)
59
		return -1;
60
	return count;
61
}
62
 
63
int
64
authCheck(Fcall* t, Fid* fid, Fsys* fsys)
65
{
66
	Con *con;
67
	Fid *afid;
68
	uchar buf[1];
69
 
70
	/*
71
	 * Can't lookup with FidWlock here as there may be
72
	 * protocol to do. Use a separate lock to protect altering
73
	 * the auth information inside afid.
74
	 */
75
	con = fid->con;
76
	if(t->afid == NOFID){
77
		/*
78
		 * If no authentication is asked for, allow
79
		 * "none" provided the connection has already
80
		 * been authenticatated.
81
		 *
82
		 * The console is allowed to attach without
83
		 * authentication.
84
		 */
85
		vtRLock(con->alock);
86
		if(con->isconsole){
87
			/* anything goes */
88
		}else if((con->flags&ConNoneAllow) || con->aok){
89
			static int noneprint;
90
 
91
			if(noneprint++ < 10)
92
				consPrint("attach %s as %s: allowing as none\n",
93
					fsysGetName(fsys), fid->uname);
94
			vtMemFree(fid->uname);
95
			fid->uname = vtStrDup(unamenone);
96
		}else{
97
			vtRUnlock(con->alock);
98
			consPrint("attach %s as %s: connection not authenticated, not console\n",
99
				fsysGetName(fsys), fid->uname);
100
			vtSetError("cannot attach as none before authentication");
101
			return 0;
102
		}
103
		vtRUnlock(con->alock);
104
 
105
		if((fid->uid = uidByUname(fid->uname)) == nil){
106
			consPrint("attach %s as %s: unknown uname\n",
107
				fsysGetName(fsys), fid->uname);
108
			vtSetError("unknown user");
109
			return 0;
110
		}
111
		return 1;
112
	}
113
 
114
	if((afid = fidGet(con, t->afid, 0)) == nil){
115
		consPrint("attach %s as %s: bad afid\n",
116
			fsysGetName(fsys), fid->uname);
117
		vtSetError("bad authentication fid");
118
		return 0;
119
	}
120
 
121
	/*
122
	 * Check valid afid;
123
	 * check uname and aname match.
124
	 */
125
	if(!(afid->qid.type & QTAUTH)){
126
		consPrint("attach %s as %s: afid not an auth file\n",
127
			fsysGetName(fsys), fid->uname);
128
		fidPut(afid);
129
		vtSetError("bad authentication fid");
130
		return 0;
131
	}
132
	if(strcmp(afid->uname, fid->uname) != 0 || afid->fsys != fsys){
133
		consPrint("attach %s as %s: afid is for %s as %s\n",
134
			fsysGetName(fsys), fid->uname,
135
			fsysGetName(afid->fsys), afid->uname);
136
		fidPut(afid);
137
		vtSetError("attach/auth mismatch");
138
		return 0;
139
	}
140
 
141
	vtLock(afid->alock);
142
	if(afid->cuname == nil){
143
		if(authRead(afid, buf, 0) != 0 || afid->cuname == nil){
144
			vtUnlock(afid->alock);
145
			consPrint("attach %s as %s: %R\n",
146
				fsysGetName(fsys), fid->uname);
147
			fidPut(afid);
148
			vtSetError("fossil authCheck: auth protocol not finished");
149
			return 0;
150
		}
151
	}
152
	vtUnlock(afid->alock);
153
 
154
	assert(fid->uid == nil);
155
	if((fid->uid = uidByUname(afid->cuname)) == nil){
156
		consPrint("attach %s as %s: unknown cuname %s\n",
157
			fsysGetName(fsys), fid->uname, afid->cuname);
158
		fidPut(afid);
159
		vtSetError("unknown user");
160
		return 0;
161
	}
162
 
163
	vtMemFree(fid->uname);
164
	fid->uname = vtStrDup(afid->cuname);
165
	fidPut(afid);
166
 
167
	/*
168
	 * Allow "none" once the connection has been authenticated.
169
	 */
170
	vtLock(con->alock);
171
	con->aok = 1;
172
	vtUnlock(con->alock);
173
 
174
	return 1;
175
}