auth_rpc.c 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <auth.h>
  4. #include "authlocal.h"
  5. static struct {
  6. char *verb;
  7. int val;
  8. } tab[] = {
  9. "ok", ARok,
  10. "done", ARdone,
  11. "error", ARerror,
  12. "needkey", ARneedkey,
  13. "badkey", ARbadkey,
  14. "phase", ARphase,
  15. "toosmall", ARtoosmall,
  16. "error", ARerror,
  17. };
  18. static int
  19. classify(char *buf, uint n, AuthRpc *rpc)
  20. {
  21. int i, len;
  22. for(i=0; i<nelem(tab); i++){
  23. len = strlen(tab[i].verb);
  24. if(n >= len && memcmp(buf, tab[i].verb, len) == 0 && (n==len || buf[len]==' ')){
  25. if(n==len){
  26. rpc->narg = 0;
  27. rpc->arg = "";
  28. }else{
  29. rpc->narg = n - (len+1);
  30. rpc->arg = (char*)buf+len+1;
  31. }
  32. return tab[i].val;
  33. }
  34. }
  35. werrstr("malformed rpc response: %s", buf);
  36. return ARrpcfailure;
  37. }
  38. AuthRpc*
  39. auth_allocrpc(int afd)
  40. {
  41. AuthRpc *rpc;
  42. rpc = mallocz(sizeof(*rpc), 1);
  43. if(rpc == nil)
  44. return nil;
  45. rpc->afd = afd;
  46. return rpc;
  47. }
  48. void
  49. auth_freerpc(AuthRpc *rpc)
  50. {
  51. free(rpc);
  52. }
  53. uint
  54. auth_rpc(AuthRpc *rpc, char *verb, void *a, int na)
  55. {
  56. int l, n, type;
  57. char *f[4];
  58. l = strlen(verb);
  59. if(na+l+1 > AuthRpcMax){
  60. werrstr("rpc too big");
  61. return ARtoobig;
  62. }
  63. memmove(rpc->obuf, verb, l);
  64. rpc->obuf[l] = ' ';
  65. memmove(rpc->obuf+l+1, a, na);
  66. if((n=write(rpc->afd, rpc->obuf, l+1+na)) != l+1+na){
  67. if(n >= 0)
  68. werrstr("auth_rpc short write");
  69. return ARrpcfailure;
  70. }
  71. if((n=read(rpc->afd, rpc->ibuf, AuthRpcMax)) < 0)
  72. return ARrpcfailure;
  73. rpc->ibuf[n] = '\0';
  74. /*
  75. * Set error string for good default behavior.
  76. */
  77. switch(type = classify(rpc->ibuf, n, rpc)){
  78. default:
  79. werrstr("unknown rpc type %d (bug in auth_rpc.c)", type);
  80. break;
  81. case ARok:
  82. break;
  83. case ARrpcfailure:
  84. break;
  85. case ARerror:
  86. if(rpc->narg == 0)
  87. werrstr("unspecified rpc error");
  88. else
  89. werrstr("%s", rpc->arg);
  90. break;
  91. case ARneedkey:
  92. werrstr("needkey %s", rpc->arg);
  93. break;
  94. case ARbadkey:
  95. if(getfields(rpc->arg, f, nelem(f), 0, "\n") < 2)
  96. werrstr("badkey %s", rpc->arg);
  97. else
  98. werrstr("badkey %s", f[1]);
  99. break;
  100. case ARphase:
  101. werrstr("phase error %s", rpc->arg);
  102. break;
  103. }
  104. return type;
  105. }