auth_challenge.c 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  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 <authsrv.h>
  13. #include "authlocal.h"
  14. Chalstate*
  15. auth_challenge(char *fmt, ...)
  16. {
  17. char *p;
  18. va_list arg;
  19. Chalstate *c;
  20. quotefmtinstall(); /* just in case */
  21. va_start(arg, fmt);
  22. p = vsmprint(fmt, arg);
  23. va_end(arg);
  24. if(p == nil)
  25. return nil;
  26. c = mallocz(sizeof(*c), 1);
  27. if(c == nil){
  28. free(p);
  29. return nil;
  30. }
  31. if((c->afd = open("/mnt/factotum/rpc", ORDWR)) < 0){
  32. Error:
  33. auth_freechal(c);
  34. free(p);
  35. return nil;
  36. }
  37. if((c->rpc=auth_allocrpc(c->afd)) == nil
  38. || auth_rpc(c->rpc, "start", p, strlen(p)) != ARok
  39. || auth_rpc(c->rpc, "read", nil, 0) != ARok)
  40. goto Error;
  41. if(c->rpc->narg > sizeof(c->chal)-1){
  42. werrstr("buffer too small for challenge");
  43. goto Error;
  44. }
  45. memmove(c->chal, c->rpc->arg, c->rpc->narg);
  46. c->nchal = c->rpc->narg;
  47. free(p);
  48. return c;
  49. }
  50. AuthInfo*
  51. auth_response(Chalstate *c)
  52. {
  53. int ret;
  54. AuthInfo *ai;
  55. ai = nil;
  56. if(c->afd < 0){
  57. werrstr("auth_response: connection not open");
  58. return nil;
  59. }
  60. if(c->resp == nil){
  61. werrstr("auth_response: nil response");
  62. return nil;
  63. }
  64. if(c->nresp == 0){
  65. werrstr("auth_response: unspecified response length");
  66. return nil;
  67. }
  68. if(c->user){
  69. if(auth_rpc(c->rpc, "write", c->user, strlen(c->user)) != ARok){
  70. /*
  71. * if this fails we're out of phase with factotum.
  72. * give up.
  73. */
  74. goto Out;
  75. }
  76. }
  77. if(auth_rpc(c->rpc, "write", c->resp, c->nresp) != ARok){
  78. /*
  79. * don't close the connection -- maybe we'll try again.
  80. */
  81. return nil;
  82. }
  83. switch(ret = auth_rpc(c->rpc, "read", nil, 0)){
  84. case ARok:
  85. default:
  86. werrstr("factotum protocol botch %d %s", ret, c->rpc->ibuf);
  87. break;
  88. case ARdone:
  89. ai = auth_getinfo(c->rpc);
  90. break;
  91. }
  92. Out:
  93. close(c->afd);
  94. auth_freerpc(c->rpc);
  95. c->afd = -1;
  96. c->rpc = nil;
  97. return ai;
  98. }
  99. void
  100. auth_freechal(Chalstate *c)
  101. {
  102. if(c == nil)
  103. return;
  104. if(c->afd >= 0)
  105. close(c->afd);
  106. if(c->rpc != nil)
  107. auth_freerpc(c->rpc);
  108. memset(c, 0xBB, sizeof(*c));
  109. free(c);
  110. }