auth_proxy.c 3.6 KB

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