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