Blob


1 #include "stdinc.h"
2 #include "9.h"
4 int
5 authRead(Fid* afid, void* data, int count)
6 {
7 AuthInfo *ai;
8 AuthRpc *rpc;
10 if((rpc = afid->rpc) == nil){
11 werrstr("not an auth fid");
12 return -1;
13 }
15 switch(auth_rpc(rpc, "read", nil, 0)){
16 default:
17 werrstr("fossil authRead: auth protocol not finished");
18 return -1;
19 case ARdone:
20 if((ai = auth_getinfo(rpc)) == nil){
21 werrstr("%r");
22 break;
23 }
24 if(ai->cuid == nil || *ai->cuid == '\0'){
25 werrstr("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 werrstr("unknown user %#q", afid->cuname);
37 break;
38 }
39 return 0;
40 case ARok:
41 if(count < rpc->narg){
42 werrstr("not enough data in auth read");
43 break;
44 }
45 memmove(data, rpc->arg, rpc->narg);
46 return rpc->narg;
47 case ARphase:
48 werrstr("%r");
49 break;
50 }
51 return -1;
52 }
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 }
63 int
64 authCheck(Fcall* t, Fid* fid, Fsys* fsys)
65 {
66 Con *con;
67 Fid *afid;
68 uchar buf[1];
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 rlock(&con->alock);
86 if(con->isconsole){
87 /* anything goes */
88 }else if((con->flags&ConNoneAllow) || con->aok){
89 static int noneprint;
91 if(noneprint++ < 10)
92 consPrint("attach %s as %s: allowing as none\n",
93 fsysGetName(fsys), fid->uname);
94 vtfree(fid->uname);
95 fid->uname = vtstrdup(unamenone);
96 }else{
97 runlock(&con->alock);
98 consPrint("attach %s as %s: connection not authenticated, not console\n",
99 fsysGetName(fsys), fid->uname);
100 werrstr("cannot attach as none before authentication");
101 return 0;
103 runlock(&con->alock);
105 if((fid->uid = uidByUname(fid->uname)) == nil){
106 consPrint("attach %s as %s: unknown uname\n",
107 fsysGetName(fsys), fid->uname);
108 werrstr("unknown user");
109 return 0;
111 return 1;
114 if((afid = fidGet(con, t->afid, 0)) == nil){
115 consPrint("attach %s as %s: bad afid\n",
116 fsysGetName(fsys), fid->uname);
117 werrstr("bad authentication fid");
118 return 0;
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 werrstr("bad authentication fid");
130 return 0;
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 werrstr("attach/auth mismatch");
138 return 0;
141 qlock(&afid->alock);
142 if(afid->cuname == nil){
143 if(authRead(afid, buf, 0) != 0 || afid->cuname == nil){
144 qunlock(&afid->alock);
145 consPrint("attach %s as %s: %r\n",
146 fsysGetName(fsys), fid->uname);
147 fidPut(afid);
148 werrstr("fossil authCheck: auth protocol not finished");
149 return 0;
152 qunlock(&afid->alock);
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 werrstr("unknown user");
160 return 0;
163 vtfree(fid->uname);
164 fid->uname = vtstrdup(afid->cuname);
165 fidPut(afid);
167 /*
168 * Allow "none" once the connection has been authenticated.
169 */
170 wlock(&con->alock);
171 con->aok = 1;
172 wunlock(&con->alock);
174 return 1;