auth.c 2.5 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. /*
  10. * Network listening authentication.
  11. * This and all the other network-related
  12. * code is due to Richard Miller.
  13. */
  14. #include "all.h"
  15. #include "9p1.h"
  16. int allownone;
  17. Nvrsafe nvr;
  18. int didread;
  19. /*
  20. * create a challenge for a fid space
  21. */
  22. void
  23. mkchallenge(Chan *cp)
  24. {
  25. int i;
  26. if(!didread && readnvram(&nvr, 0) >= 0)
  27. didread = 1;
  28. srand(truerand());
  29. for(i = 0; i < CHALLEN; i++)
  30. cp->chal[i] = nrand(256);
  31. cp->idoffset = 0;
  32. cp->idvec = 0;
  33. }
  34. /*
  35. * match a challenge from an attach
  36. */
  37. Nvrsafe nvr;
  38. int
  39. authorize(Chan *cp, Oldfcall *in, Oldfcall *ou)
  40. {
  41. Ticket t;
  42. Authenticator a;
  43. int x;
  44. uint32_t bit;
  45. if (cp == cons.srvchan) /* local channel already safe */
  46. return 1;
  47. if(wstatallow) /* set to allow entry during boot */
  48. return 1;
  49. if(strcmp(in->uname, "none") == 0)
  50. return allownone || cp->authed;
  51. if(in->type == Toattach9p1)
  52. return 0;
  53. if(!didread)
  54. return 0;
  55. /* decrypt and unpack ticket */
  56. convM2T(in->ticket, &t, nvr.machkey);
  57. if(t.num != AuthTs){
  58. print("bad AuthTs num\n");
  59. return 0;
  60. }
  61. /* decrypt and unpack authenticator */
  62. convM2A(in->auth, &a, t.key);
  63. if(a.num != AuthAc){
  64. print("bad AuthAc num\n");
  65. return 0;
  66. }
  67. /* challenges must match */
  68. if(memcmp(a.chal, cp->chal, sizeof(a.chal)) != 0){
  69. print("bad challenge\n");
  70. return 0;
  71. }
  72. /*
  73. * the id must be in a valid range. the range is specified by a
  74. * lower bount (idoffset) and a bit vector (idvec) where a
  75. * bit set to 1 means unusable
  76. */
  77. lock(&cp->idlock);
  78. x = a.id - cp->idoffset;
  79. bit = 1<<x;
  80. if(x < 0 || x > 31 || (bit&cp->idvec)){
  81. unlock(&cp->idlock);
  82. return 0;
  83. }
  84. cp->idvec |= bit;
  85. /* normalize the vector */
  86. while(cp->idvec&0xffff0001){
  87. cp->idvec >>= 1;
  88. cp->idoffset++;
  89. }
  90. unlock(&cp->idlock);
  91. /* ticket name and attach name must match */
  92. if(memcmp(in->uname, t.cuid, sizeof(in->uname)) != 0){
  93. print("names don't match\n");
  94. return 0;
  95. }
  96. /* copy translated name into input record */
  97. memmove(in->uname, t.suid, sizeof(in->uname));
  98. /* craft a reply */
  99. a.num = AuthAs;
  100. memmove(a.chal, cp->rchal, CHALLEN);
  101. convA2M(&a, ou->rauth, t.key);
  102. cp->authed = 1;
  103. return 1;
  104. }