auth_proxy.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  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. a = nil;
  83. if(convM2AI((uchar*)rpc->arg, rpc->narg, &a) == nil){
  84. werrstr("bad auth info from factotum");
  85. return nil;
  86. }
  87. return a;
  88. }
  89. static int
  90. dorpc(AuthRpc *rpc, char *verb, char *val, int len, AuthGetkey *getkey)
  91. {
  92. int ret;
  93. for(;;){
  94. if((ret = auth_rpc(rpc, verb, val, len)) != ARneedkey && ret != ARbadkey)
  95. return ret;
  96. if(getkey == 0)
  97. return ARgiveup; /* don't know how */
  98. if((*getkey)(rpc->arg) < 0)
  99. return ARgiveup; /* user punted */
  100. }
  101. }
  102. /*
  103. * this just proxies what the factotum tells it to.
  104. */
  105. AuthInfo*
  106. fauth_proxy(int fd, AuthRpc *rpc, AuthGetkey *getkey, char *params)
  107. {
  108. char *buf;
  109. int m, n, ret;
  110. AuthInfo *a;
  111. char oerr[ERRMAX];
  112. rerrstr(oerr, sizeof oerr);
  113. werrstr("UNKNOWN AUTH ERROR");
  114. if(dorpc(rpc, "start", params, strlen(params), getkey) != ARok){
  115. werrstr("fauth_proxy start: %r");
  116. return nil;
  117. }
  118. buf = malloc(AuthRpcMax);
  119. if(buf == nil)
  120. return nil;
  121. for(;;){
  122. switch(dorpc(rpc, "read", nil, 0, getkey)){
  123. case ARdone:
  124. free(buf);
  125. a = auth_getinfo(rpc);
  126. errstr(oerr, sizeof oerr); /* no error, restore whatever was there */
  127. return a;
  128. case ARok:
  129. if(write(fd, rpc->arg, rpc->narg) != rpc->narg){
  130. werrstr("auth_proxy write fd: %r");
  131. goto Error;
  132. }
  133. break;
  134. case ARphase:
  135. n = 0;
  136. memset(buf, 0, AuthRpcMax);
  137. while((ret = dorpc(rpc, "write", buf, n, getkey)) == ARtoosmall){
  138. if(atoi(rpc->arg) > AuthRpcMax)
  139. break;
  140. m = read(fd, buf+n, atoi(rpc->arg)-n);
  141. if(m <= 0){
  142. if(m == 0)
  143. werrstr("auth_proxy short read: %s", buf);
  144. goto Error;
  145. }
  146. n += m;
  147. }
  148. if(ret != ARok){
  149. werrstr("auth_proxy rpc write: %s: %r", buf);
  150. goto Error;
  151. }
  152. break;
  153. default:
  154. werrstr("auth_proxy rpc: %r");
  155. goto Error;
  156. }
  157. }
  158. Error:
  159. free(buf);
  160. return nil;
  161. }
  162. AuthInfo*
  163. auth_proxy(int fd, AuthGetkey *getkey, char *fmt, ...)
  164. {
  165. int afd;
  166. char *p;
  167. va_list arg;
  168. AuthInfo *ai;
  169. AuthRpc *rpc;
  170. quotefmtinstall(); /* just in case */
  171. va_start(arg, fmt);
  172. p = vsmprint(fmt, arg);
  173. va_end(arg);
  174. afd = open("/mnt/factotum/rpc", ORDWR);
  175. if(afd < 0){
  176. werrstr("opening /mnt/factotum/rpc: %r");
  177. free(p);
  178. return nil;
  179. }
  180. rpc = auth_allocrpc(afd);
  181. if(rpc == nil){
  182. free(p);
  183. return nil;
  184. }
  185. ai = fauth_proxy(fd, rpc, getkey, p);
  186. free(p);
  187. auth_freerpc(rpc);
  188. close(afd);
  189. return ai;
  190. }