auth.c 2.1 KB

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