9auth.c (3921B)
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 werrstr("not an auth fid"); 12 return -1; 13 } 14 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 } 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 rlock(&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 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; 102 } 103 runlock(&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 werrstr("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 werrstr("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 werrstr("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 werrstr("attach/auth mismatch"); 138 return 0; 139 } 140 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; 150 } 151 } 152 qunlock(&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 werrstr("unknown user"); 160 return 0; 161 } 162 163 vtfree(fid->uname); 164 fid->uname = vtstrdup(afid->cuname); 165 fidPut(afid); 166 167 /* 168 * Allow "none" once the connection has been authenticated. 169 */ 170 wlock(&con->alock); 171 con->aok = 1; 172 wunlock(&con->alock); 173 174 return 1; 175 }