URI:
       t9auth.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       t9auth.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 }