9auth.c 3.8 KB

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