auth_proxy.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  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 <u.h>
  10. #include <libc.h>
  11. #include <fcall.h>
  12. #include <auth.h>
  13. #include "authlocal.h"
  14. enum {
  15. ARgiveup = 100,
  16. };
  17. static uint8_t*
  18. gstring(uint8_t *p, uint8_t *ep, char **s)
  19. {
  20. uint n;
  21. if(p == nil)
  22. return nil;
  23. if(p+BIT16SZ > ep)
  24. return nil;
  25. n = GBIT16(p);
  26. p += BIT16SZ;
  27. if(p+n > ep)
  28. return nil;
  29. *s = malloc(n+1);
  30. memmove((*s), p, n);
  31. (*s)[n] = '\0';
  32. p += n;
  33. return p;
  34. }
  35. static uint8_t*
  36. gcarray(uint8_t *p, uint8_t *ep, uint8_t **s, int *np)
  37. {
  38. uint n;
  39. if(p == nil)
  40. return nil;
  41. if(p+BIT16SZ > ep)
  42. return nil;
  43. n = GBIT16(p);
  44. p += BIT16SZ;
  45. if(p+n > ep)
  46. return nil;
  47. *s = malloc(n);
  48. if(*s == nil)
  49. return nil;
  50. memmove((*s), p, n);
  51. *np = n;
  52. p += n;
  53. return p;
  54. }
  55. void
  56. auth_freeAI(AuthInfo *ai)
  57. {
  58. if(ai == nil)
  59. return;
  60. free(ai->cuid);
  61. free(ai->suid);
  62. free(ai->cap);
  63. free(ai->secret);
  64. free(ai);
  65. }
  66. static uint8_t*
  67. convM2AI(uint8_t *p, int n, AuthInfo **aip)
  68. {
  69. uint8_t *e = p+n;
  70. AuthInfo *ai;
  71. ai = mallocz(sizeof(*ai), 1);
  72. if(ai == nil)
  73. return nil;
  74. p = gstring(p, e, &ai->cuid);
  75. p = gstring(p, e, &ai->suid);
  76. p = gstring(p, e, &ai->cap);
  77. p = gcarray(p, e, &ai->secret, &ai->nsecret);
  78. if(p == nil)
  79. auth_freeAI(ai);
  80. else
  81. *aip = ai;
  82. return p;
  83. }
  84. AuthInfo*
  85. auth_getinfo(AuthRpc *rpc)
  86. {
  87. AuthInfo *a;
  88. if(auth_rpc(rpc, "authinfo", nil, 0) != ARok)
  89. return nil;
  90. if(convM2AI((uint8_t*)rpc->arg, rpc->narg, &a) == nil){
  91. werrstr("bad auth info from factotum");
  92. return nil;
  93. }
  94. return a;
  95. }
  96. static int
  97. dorpc(AuthRpc *rpc, char *verb, char *val, int len, AuthGetkey *getkey)
  98. {
  99. int ret;
  100. for(;;){
  101. if((ret = auth_rpc(rpc, verb, val, len)) != ARneedkey && ret != ARbadkey)
  102. return ret;
  103. if(getkey == nil)
  104. return ARgiveup; /* don't know how */
  105. if((*getkey)(rpc->arg) < 0)
  106. return ARgiveup; /* user punted */
  107. }
  108. }
  109. /*
  110. * this just proxies what the factotum tells it to.
  111. */
  112. AuthInfo*
  113. fauth_proxy(int fd, AuthRpc *rpc, AuthGetkey *getkey, char *params)
  114. {
  115. char *buf;
  116. int m, n, ret;
  117. AuthInfo *a;
  118. char oerr[ERRMAX];
  119. if(rpc == nil){
  120. werrstr("fauth_proxy - no factotum");
  121. return nil;
  122. }
  123. rerrstr(oerr, sizeof oerr);
  124. werrstr("UNKNOWN AUTH ERROR");
  125. if(dorpc(rpc, "start", params, strlen(params), getkey) != ARok){
  126. werrstr("fauth_proxy start: %r");
  127. return nil;
  128. }
  129. buf = malloc(AuthRpcMax);
  130. if(buf == nil)
  131. return nil;
  132. for(;;){
  133. switch(dorpc(rpc, "read", nil, 0, getkey)){
  134. case ARdone:
  135. free(buf);
  136. a = auth_getinfo(rpc);
  137. /* no error, restore whatever was there */
  138. errstr(oerr, sizeof oerr);
  139. return a;
  140. case ARok:
  141. if(write(fd, rpc->arg, rpc->narg) != rpc->narg){
  142. werrstr("auth_proxy write fd: %r");
  143. goto Error;
  144. }
  145. break;
  146. case ARphase:
  147. n = 0;
  148. memset(buf, 0, AuthRpcMax);
  149. while((ret = dorpc(rpc, "write", buf, n, getkey)) == ARtoosmall){
  150. if(atoi(rpc->arg) > AuthRpcMax)
  151. break;
  152. m = read(fd, buf + n, atoi(rpc->arg) - n);
  153. if(m <= 0){
  154. if(m == 0)
  155. werrstr("auth_proxy short read: %s",
  156. buf);
  157. goto Error;
  158. }
  159. n += m;
  160. }
  161. if(ret != ARok){
  162. werrstr("auth_proxy rpc write: %s: %r", buf);
  163. goto Error;
  164. }
  165. break;
  166. default:
  167. werrstr("auth_proxy rpc: %r");
  168. goto Error;
  169. }
  170. }
  171. Error:
  172. free(buf);
  173. return nil;
  174. }
  175. AuthInfo*
  176. auth_proxy(int fd, AuthGetkey *getkey, char *fmt, ...)
  177. {
  178. int afd;
  179. char *p;
  180. va_list arg;
  181. AuthInfo *ai;
  182. AuthRpc *rpc;
  183. quotefmtinstall(); /* just in case */
  184. va_start(arg, fmt);
  185. p = vsmprint(fmt, arg);
  186. va_end(arg);
  187. ai = nil;
  188. afd = open("/mnt/factotum/rpc", ORDWR);
  189. if(afd < 0){
  190. werrstr("opening /mnt/factotum/rpc: %r");
  191. free(p);
  192. return nil;
  193. }
  194. rpc = auth_allocrpc(afd);
  195. if(rpc){
  196. ai = fauth_proxy(fd, rpc, getkey, p);
  197. auth_freerpc(rpc);
  198. }
  199. close(afd);
  200. free(p);
  201. return ai;
  202. }