9auth.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  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("fossil authRead: 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. static int noneprint;
  84. if(noneprint++ < 10)
  85. consPrint("attach %s as %s: allowing as none\n",
  86. fsysGetName(fsys), fid->uname);
  87. vtMemFree(fid->uname);
  88. fid->uname = vtStrDup(unamenone);
  89. }else{
  90. vtRUnlock(con->alock);
  91. consPrint("attach %s as %s: connection not authenticated, not console\n",
  92. fsysGetName(fsys), fid->uname);
  93. vtSetError("cannot attach as none before authentication");
  94. return 0;
  95. }
  96. vtRUnlock(con->alock);
  97. if((fid->uid = uidByUname(fid->uname)) == nil){
  98. consPrint("attach %s as %s: unknown uname\n",
  99. fsysGetName(fsys), fid->uname);
  100. vtSetError("unknown user");
  101. return 0;
  102. }
  103. return 1;
  104. }
  105. if((afid = fidGet(con, t->afid, 0)) == nil){
  106. consPrint("attach %s as %s: bad afid\n", fsysGetName(fsys), fid->uname);
  107. vtSetError("bad authentication fid");
  108. return 0;
  109. }
  110. /*
  111. * Check valid afid;
  112. * check uname and aname match.
  113. */
  114. if(!(afid->qid.type & QTAUTH)){
  115. consPrint("attach %s as %s: afid not an auth file\n", fsysGetName(fsys),
  116. fid->uname);
  117. fidPut(afid);
  118. vtSetError("bad authentication fid");
  119. return 0;
  120. }
  121. if(strcmp(afid->uname, fid->uname) != 0 || afid->fsys != fsys){
  122. consPrint("attach %s as %s: afid is for %s as %s\n", fsysGetName(fsys),
  123. fid->uname, fsysGetName(afid->fsys), afid->uname);
  124. fidPut(afid);
  125. vtSetError("attach/auth mismatch");
  126. return 0;
  127. }
  128. vtLock(afid->alock);
  129. if(afid->cuname == nil){
  130. if(authRead(afid, buf, 0) != 0 || afid->cuname == nil){
  131. vtUnlock(afid->alock);
  132. consPrint("attach %s as %s: %R\n", fsysGetName(fsys), fid->uname);
  133. fidPut(afid);
  134. vtSetError("fossil authCheck: auth protocol not finished");
  135. return 0;
  136. }
  137. }
  138. vtUnlock(afid->alock);
  139. assert(fid->uid == nil);
  140. if((fid->uid = uidByUname(afid->cuname)) == nil){
  141. consPrint("attach %s as %s: unknown cuname %s\n", fsysGetName(fsys),
  142. fid->uname, afid->cuname);
  143. fidPut(afid);
  144. vtSetError("unknown user");
  145. return 0;
  146. }
  147. vtMemFree(fid->uname);
  148. fid->uname = vtStrDup(afid->cuname);
  149. fidPut(afid);
  150. /*
  151. * Allow "none" once the connection has been authenticated.
  152. */
  153. vtLock(con->alock);
  154. con->aok = 1;
  155. vtUnlock(con->alock);
  156. return 1;
  157. }