auth_rpc.c 2.4 KB

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