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