authhostowner.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. #include "all.h"
  2. enum {
  3. ARgiveup = 100,
  4. };
  5. static uchar*
  6. gstring(uchar *p, uchar *ep, char **s)
  7. {
  8. uint n;
  9. if(p == nil)
  10. return nil;
  11. if(p+BIT16SZ > ep)
  12. return nil;
  13. n = GBIT16(p);
  14. p += BIT16SZ;
  15. if(p+n > ep)
  16. return nil;
  17. *s = malloc(n+1);
  18. memmove((*s), p, n);
  19. (*s)[n] = '\0';
  20. p += n;
  21. return p;
  22. }
  23. static uchar*
  24. gcarray(uchar *p, uchar *ep, uchar **s, int *np)
  25. {
  26. uint n;
  27. if(p == nil)
  28. return nil;
  29. if(p+BIT16SZ > ep)
  30. return nil;
  31. n = GBIT16(p);
  32. p += BIT16SZ;
  33. if(p+n > ep)
  34. return nil;
  35. *s = malloc(n);
  36. if(*s == nil)
  37. return nil;
  38. memmove((*s), p, n);
  39. *np = n;
  40. p += n;
  41. return p;
  42. }
  43. static uchar*
  44. convM2AI(uchar *p, int n, AuthInfo **aip)
  45. {
  46. uchar *e = p+n;
  47. AuthInfo *ai;
  48. ai = mallocz(sizeof(*ai), 1);
  49. if(ai == nil)
  50. return nil;
  51. p = gstring(p, e, &ai->cuid);
  52. p = gstring(p, e, &ai->suid);
  53. p = gstring(p, e, &ai->cap);
  54. p = gcarray(p, e, &ai->secret, &ai->nsecret);
  55. if(p == nil)
  56. auth_freeAI(ai);
  57. else
  58. *aip = ai;
  59. return p;
  60. }
  61. static int
  62. dorpc(AuthRpc *rpc, char *verb, char *val, int len, AuthGetkey *getkey)
  63. {
  64. int ret;
  65. for(;;){
  66. if((ret = auth_rpc(rpc, verb, val, len)) != ARneedkey && ret != ARbadkey)
  67. return ret;
  68. if(getkey == nil)
  69. return ARgiveup; /* don't know how */
  70. if((*getkey)(rpc->arg) < 0)
  71. return ARgiveup; /* user punted */
  72. }
  73. }
  74. static int
  75. doread(Session *s, Fid *f, void *buf, int n)
  76. {
  77. s->f.fid = f - s->fids;
  78. s->f.offset = 0;
  79. s->f.count = n;
  80. if(xmesg(s, Tread) < 0)
  81. return -1;
  82. n = s->f.count;
  83. memmove(buf, s->f.data, n);
  84. return n;
  85. }
  86. static int
  87. dowrite(Session *s, Fid *f, void *buf, int n)
  88. {
  89. s->f.fid = f - s->fids;
  90. s->f.offset = 0;
  91. s->f.count = n;
  92. s->f.data = (char *)buf;
  93. if(xmesg(s, Twrite) < 0)
  94. return -1;
  95. return n;
  96. }
  97. /*
  98. * this just proxies what the factotum tells it to.
  99. */
  100. AuthInfo*
  101. authproto(Session *s, Fid *f, AuthRpc *rpc, AuthGetkey *getkey, char *params)
  102. {
  103. char *buf;
  104. int m, n, ret;
  105. AuthInfo *a;
  106. char oerr[ERRMAX];
  107. rerrstr(oerr, sizeof oerr);
  108. werrstr("UNKNOWN AUTH ERROR");
  109. if(dorpc(rpc, "start", params, strlen(params), getkey) != ARok){
  110. werrstr("fauth_proxy start: %r");
  111. return nil;
  112. }
  113. buf = malloc(AuthRpcMax);
  114. if(buf == nil)
  115. return nil;
  116. for(;;){
  117. switch(dorpc(rpc, "read", nil, 0, getkey)){
  118. case ARdone:
  119. free(buf);
  120. a = auth_getinfo(rpc);
  121. errstr(oerr, sizeof oerr); /* no error, restore whatever was there */
  122. return a;
  123. case ARok:
  124. if(dowrite(s, f, rpc->arg, rpc->narg) != rpc->narg){
  125. werrstr("auth_proxy write fd: %r");
  126. goto Error;
  127. }
  128. break;
  129. case ARphase:
  130. n = 0;
  131. memset(buf, 0, AuthRpcMax);
  132. while((ret = dorpc(rpc, "write", buf, n, getkey)) == ARtoosmall){
  133. if(atoi(rpc->arg) > AuthRpcMax)
  134. break;
  135. m = doread(s, f, buf+n, atoi(rpc->arg)-n);
  136. if(m <= 0){
  137. if(m == 0)
  138. werrstr("auth_proxy short read: %s", buf);
  139. goto Error;
  140. }
  141. n += m;
  142. }
  143. if(ret != ARok){
  144. werrstr("auth_proxy rpc write: %s: %r", buf);
  145. goto Error;
  146. }
  147. break;
  148. default:
  149. werrstr("auth_proxy rpc: %r");
  150. goto Error;
  151. }
  152. }
  153. Error:
  154. free(buf);
  155. return nil;
  156. }
  157. /* returns 0 if auth succeeded (or unneeded), -1 otherwise */
  158. int
  159. authhostowner(Session *s)
  160. {
  161. Fid *af, *f;
  162. int rv = -1;
  163. int afd;
  164. AuthInfo *ai;
  165. AuthRpc *rpc;
  166. /* get a fid to authenticate over */
  167. f = nil;
  168. af = newfid(s);
  169. s->f.afid = af - s->fids;
  170. s->f.uname = getuser();
  171. s->f.aname = s->spec;
  172. if(xmesg(s, Tauth)){
  173. /* not needed */
  174. rv = 0;
  175. goto out;
  176. }
  177. quotefmtinstall(); /* just in case */
  178. afd = open("/mnt/factotum/rpc", ORDWR);
  179. if(afd < 0){
  180. werrstr("opening /mnt/factotum/rpc: %r");
  181. goto out;
  182. }
  183. rpc = auth_allocrpc(afd);
  184. if(rpc == nil)
  185. goto out;
  186. ai = authproto(s, af, rpc, auth_getkey, "proto=p9any role=client");
  187. if(ai != nil){
  188. rv = 0;
  189. auth_freeAI(ai);
  190. }
  191. auth_freerpc(rpc);
  192. close(afd);
  193. /* try attaching with the afid */
  194. chat("attaching as hostowner...");
  195. f = newfid(s);
  196. s->f.fid = f - s->fids;
  197. s->f.afid = af - s->fids;;
  198. s->f.uname = getuser();
  199. s->f.aname = s->spec;
  200. if(xmesg(s, Tattach) == 0)
  201. rv = 0;
  202. out:
  203. if(af != nil){
  204. putfid(s, af);
  205. s->f.fid = af - s->fids;
  206. xmesg(s, Tclunk);
  207. }
  208. if(f != nil){
  209. putfid(s, f);
  210. s->f.fid = f - s->fids;
  211. xmesg(s, Tclunk);
  212. }
  213. return rv;
  214. }