9auth.c 4.3 KB

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