auth_proxy.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  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. rerrstr(oerr, sizeof oerr);
  112. werrstr("UNKNOWN AUTH ERROR");
  113. if(dorpc(rpc, "start", params, strlen(params), getkey) != ARok){
  114. werrstr("fauth_proxy start: %r");
  115. return nil;
  116. }
  117. buf = malloc(AuthRpcMax);
  118. if(buf == nil)
  119. return nil;
  120. for(;;){
  121. switch(dorpc(rpc, "read", nil, 0, getkey)){
  122. case ARdone:
  123. free(buf);
  124. a = auth_getinfo(rpc);
  125. errstr(oerr, sizeof oerr); /* no error, restore whatever was there */
  126. return a;
  127. case ARok:
  128. if(write(fd, rpc->arg, rpc->narg) != rpc->narg){
  129. werrstr("auth_proxy write fd: %r");
  130. goto Error;
  131. }
  132. break;
  133. case ARphase:
  134. n = 0;
  135. memset(buf, 0, AuthRpcMax);
  136. while((ret = dorpc(rpc, "write", buf, n, getkey)) == ARtoosmall){
  137. if(atoi(rpc->arg) > AuthRpcMax)
  138. break;
  139. m = read(fd, buf+n, atoi(rpc->arg)-n);
  140. if(m <= 0){
  141. if(m == 0)
  142. werrstr("auth_proxy short read: %s", buf);
  143. goto Error;
  144. }
  145. n += m;
  146. }
  147. if(ret != ARok){
  148. werrstr("auth_proxy rpc write: %s: %r", buf);
  149. goto Error;
  150. }
  151. break;
  152. default:
  153. werrstr("auth_proxy rpc: %r");
  154. goto Error;
  155. }
  156. }
  157. Error:
  158. free(buf);
  159. return nil;
  160. }
  161. AuthInfo*
  162. auth_proxy(int fd, AuthGetkey *getkey, char *fmt, ...)
  163. {
  164. int afd;
  165. char *p;
  166. va_list arg;
  167. AuthInfo *ai;
  168. AuthRpc *rpc;
  169. quotefmtinstall(); /* just in case */
  170. va_start(arg, fmt);
  171. p = vsmprint(fmt, arg);
  172. va_end(arg);
  173. afd = open("/mnt/factotum/rpc", ORDWR);
  174. if(afd < 0){
  175. werrstr("opening /mnt/factotum/rpc: %r");
  176. free(p);
  177. return nil;
  178. }
  179. rpc = auth_allocrpc(afd);
  180. if(rpc == nil){
  181. free(p);
  182. return nil;
  183. }
  184. ai = fauth_proxy(fd, rpc, getkey, p);
  185. free(p);
  186. auth_freerpc(rpc);
  187. close(afd);
  188. return ai;
  189. }